Chaoz-MADS · Integration Guide

Drop the full Chaoz-MADS design system into any web app in under 30 seconds. 524 components · 12 themes · 50+ motion primitives · 10 layout primitives. Single source of truth — every framework adapter (React/Vue/Svelte/vanilla) consumes the same cx-* classes, so output is byte-identical visually.

CDN: design.chaozcode.com/latest/ · Manifest: /manifest.json · Integrity: /integrity.json · npm: @chaozcode/mads

For AI coding agents: the design system has 3 hard rules that supersede defaults:
  1. NEVER mix Tailwind utilities inside Cx* components — all visual styling lives in cx-* classes inside chaozcode.css. (You CAN use Tailwind around them in your own JSX.)
  2. NEVER auto-detect prefers-reduced-motion. Motion is on by default; consumers opt in via setReducedMotion(true) → sets [data-reduce-motion] on <html>. iOS Low Power Mode firing this OS query was killing animation for users who never asked for it.
  3. NEVER animate layout properties (width / height / top / left / margin / padding). Use transform: translate3d() / scale() / scaleX(). Compositor-only → 60fps even on mid-tier mobile.

Contents

One-line install (auto-detects framework)

Run this in your project root. The installer detects Next.js / Vite / Astro / Svelte / Remix / plain Node / plain HTML and drops in the right starting files + AI-coding-agent rules (.cursorrules + .github/copilot-instructions.md).

curl -fsSL https://design.chaozcode.com/install.sh | bash

Force a specific mode: bash -s -- --react, --next, --astro, --svelte, --remix, or --html.

Zero-install HTML snippet (paste anywhere)

<link rel="stylesheet" href="https://design.chaozcode.com/latest/mads.css">
<script src="https://design.chaozcode.com/latest/bootstrap.js"></script>

Two lines unlock all 1,598+ CSS classes, 12 themes, 50+ motion primitives, 10 layout primitives, and the ESM importmap for React imports. Pin to /v2.0.33/ for immutable production caching.

Pick a path

PathUse it whenBuild stepTree-shakeableSSR
1 CSS-onlyPlain HTML, Astro, Hugo, Jekyll, MPANonen/a
2 ESM importmapReact in modern browsers, no bundlerNone
3 UMD scriptLegacy browsers, CMS embeds, WordPressNone
4 npmNext.js / Vite / Remix / Astro+ReactYes

1 CSS-only · plain HTML

Drop the stylesheet in. Every cx-* class works in any HTML / Vue / Svelte / Angular / Astro template — no JS required.

<!DOCTYPE html>
<html data-cx data-theme="midnight">
<head>
  <link rel="stylesheet" href="https://design.chaozcode.com/latest/mads.css">
</head>
<body>
  <header class="cx-row" data-justify="between" style="padding:1rem">
    <strong class="cx-text-gradient cx-text-gradient-purple">NimbusOps</strong>
    <button class="cx-btn cx-btn-primary cx-btn-sm">Get started</button>
  </header>
  <main class="cx-stack" data-gap="md" style="padding:1rem">
    <div class="cx-card cx-card-frosted" style="padding:1rem">
      <h2 class="cx-fluid-h2">Search</h2>
      <input class="cx-input" placeholder="Try cx-* classes…" />
    </div>
    <div class="cx-grid" data-min="220">
      <div class="cx-stat-card"><div class="cx-stat-card-label">Revenue</div><div class="cx-stat-card-value cx-text-gradient cx-text-gradient-purple">$48,290</div></div>
      <div class="cx-stat-card"><div class="cx-stat-card-label">Active</div><div class="cx-stat-card-value cx-text-gradient cx-text-gradient-cyan">2,847</div></div>
      <div class="cx-stat-card"><div class="cx-stat-card-label">API</div><div class="cx-stat-card-value">14.2M</div></div>
    </div>
  </main>
</body>
</html>

For theme cycling, sticky-toolbar etc., add bootstrap.js:

<script src="https://design.chaozcode.com/latest/bootstrap.js"></script>
<!-- exposes window.MADS.setTheme('cyber'), .setDirection('rtl'), .setDensity('compact'), .setReducedMotion(true) -->

2 ESM importmap · React with no build step

Modern browsers (Chrome 89+, Safari 16.4+, Firefox 108+) support <script type="importmap">. Map react and @chaozcode/mads to CDN URLs and import like a normal npm package.

<!DOCTYPE html>
<html data-cx>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
  <link rel="stylesheet" href="https://design.chaozcode.com/latest/mads.css">
  <script src="https://design.chaozcode.com/latest/bootstrap.js"></script>
</head>
<body>
<div id="root">Loading…</div>
<script type="module">
import { createRoot } from 'react-dom/client'
import React, { createElement as h } from 'react'
import {
  CxButton, CxCard, CxCardHeader, CxCardContent,
  CxInput, CxStack, CxRow, CxGrid, CxSidebar,
  useTheme, useReducedMotion, setTheme,
} from '@chaozcode/mads'

function App() {
  const [theme] = useTheme()
  return h(CxStack, { gap: 'md', style: { padding: '1.25rem' } },
    h(CxCard, { variant: 'frosted' },
      h(CxCardHeader, null, h('h2', null, 'Hello from Chaoz-MADS')),
      h(CxCardContent, null,
        h(CxRow, { min: 200 },
          h(CxButton, { variant: 'primary', onClick: () => setTheme('cyber') }, 'Cyber'),
          h(CxButton, { variant: 'ghost',   onClick: () => setTheme('midnight') }, 'Midnight'),
        ),
        h(CxInput, { placeholder: 'Current theme: ' + theme }),
      ),
    ),
  )
}
createRoot(document.getElementById('root')).render(h(App))
</script>
</body>
</html>

The bootstrap.js tag above auto-injects this importmap:

{
  "imports": {
    "react":             "https://esm.sh/react@18",
    "react-dom":         "https://esm.sh/react-dom@18?external=react,react-dom",
    "react-dom/client":  "https://esm.sh/react-dom@18/client?external=react,react-dom",
    "react/jsx-runtime": "https://esm.sh/react@18/jsx-runtime",
    "framer-motion":     "https://esm.sh/framer-motion@12?external=react,react-dom",
    "lucide-react":      "https://esm.sh/lucide-react@0.469?external=react,react-dom",
    "@chaozcode/mads":             "https://design.chaozcode.com/latest/design-system.mjs",
    "@chaozcode/mads/components":  "https://design.chaozcode.com/latest/components.mjs",
    "@chaozcode/mads/patterns":    "https://design.chaozcode.com/latest/patterns.mjs"
  }
}
Required for CDN: the ?external=react,react-dom suffix on framer-motion and lucide-react is mandatory. Without it, esm.sh bundles its own React copy → multiple React instances → useContext null. Note: framer-motion is an optional peer dep — only include it if you use motion/fx/creative components.

3 UMD · classic <script> tags

Legacy browsers, WordPress, embeds. Loads React + framer-motion globals, then exposes window.MADS.

<link rel="stylesheet" href="https://design.chaozcode.com/latest/mads.css">
<script crossorigin src="https://unpkg.com/react@18/umd/react.production.min.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></script>
<script crossorigin src="https://unpkg.com/framer-motion@12/dist/framer-motion.umd.js"></script>
<script src="https://design.chaozcode.com/latest/mads.umd.js"></script>

<div id="root"></div>
<script>
  const { CxButton, CxCard, CxRow, useTheme } = window.MADS;
  const e = React.createElement;
  ReactDOM.createRoot(document.getElementById('root')).render(
    e(CxCard, { variant: 'frosted' },
      e(CxRow, null,
        e(CxButton, { variant: 'primary' }, 'Hello'),
        e(CxButton, { variant: 'ghost'   }, 'World'),
      ),
    ),
  );
</script>

4 npm install · build-time

npm install @chaozcode/mads react react-dom lucide-react
npm install framer-motion   # optional — only needed for motion/fx/creative components
# or
pnpm add @chaozcode/mads react react-dom lucide-react
pnpm add framer-motion      # optional
// my-app.tsx
import '@chaozcode/mads/styles'                  // mads.css
import {
  // Layout primitives
  CxContainer, CxStack, CxRow, CxGrid, CxSidebar,
  CxCluster, CxCenter, CxCover, CxFrame, CxSplit,
  // Primitives
  CxButton, CxCard, CxCardHeader, CxCardContent, CxCardFooter,
  CxInput, CxTextarea, CxInputGroup,
  // Theme API
  THEMES, setTheme, useTheme, useReducedMotion,
  useDirection, useDensity,
  // A11y helpers
  getContrastRatio, contrastVerdict, validateThemeContrast,
  // Tokens (CSS-var fallbacks, perfect for theming)
  MADS_TOKENS, VARIANTS, SIZES, BREAKPOINTS,
  // Widgets
  SettingsPanel, ThemeCustomizer,
} from '@chaozcode/mads'

import {
  Kanban, Timeline, ChatBubble, Accordion,
  CommandPalette, Sparkline, ProgressBar, DataGrid,
} from '@chaozcode/mads/components'              // all 524 components

import {
  CxHero, CxLoginCard, CxPricingTable,
  CxAppShell, CxDashboardLayout,
} from '@chaozcode/mads/patterns'                 // production layouts

Framework recipes

Next.js 14 / 15 (App Router)
// app/layout.tsx
import '@chaozcode/mads/styles'
import type { ReactNode } from 'react'

export default function Layout({ children }: { children: ReactNode }) {
  return (
    <html lang="en" data-cx data-theme="midnight">
      <body>{children}</body>
    </html>
  )
}

// app/page.tsx
'use client'
import { CxCard, CxButton, useTheme } from '@chaozcode/mads'
export default function Home() {
  const [theme, setTheme] = useTheme()
  return <CxCard variant="frosted">Theme: {theme}</CxCard>
}

Server Components: import non-hook primitives directly. Mark with 'use client' only where hooks (useTheme, useReducedMotion) appear.

Vite + React
// main.tsx
import '@chaozcode/mads/styles'
import { createRoot } from 'react-dom/client'
import App from './App'
createRoot(document.getElementById('root')!).render(<App/>)

// vite.config.ts — optional, only if you also use Tailwind v4
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import tailwind from '@tailwindcss/vite'
export default defineConfig({ plugins: [react(), tailwind()] })
Astro (SSR-safe)
---
// src/pages/index.astro
import '@chaozcode/mads/styles'
---
<html data-cx data-theme="midnight">
<body>
  <div class="cx-card cx-card-frosted" style="padding:1rem">
    <h1 class="cx-fluid-h1">Astro + MADS</h1>
    <!-- For React components, use a client island: -->
    <CxButton client:visible variant="primary">Click</CxButton>
  </div>
</body>
</html>
Vue 3 (CSS-only, no React)
<script setup>
import '@chaozcode/mads/styles'
const theme = ref('midnight')
</script>
<template>
  <html :data-theme="theme">
    <button class="cx-btn cx-btn-primary">Click</button>
    <div class="cx-card cx-card-frosted">...</div>
  </html>
</template>

Theme API works imperatively: document.documentElement.setAttribute('data-theme', 'cyber') or use window.MADS.setTheme().

Svelte 5
<!-- App.svelte -->
<script>
  import '@chaozcode/mads/styles'
</script>
<svelte:head><html data-cx data-theme="midnight" /></svelte:head>
<div class="cx-card cx-card-frosted">
  <button class="cx-btn cx-btn-primary">Hello</button>
</div>
Remix / Tanstack Start
// app/root.tsx
import madsCSS from '@chaozcode/mads/styles?url'
export const links = () => [{ rel: 'stylesheet', href: madsCSS }]
export default function App() {
  return (
    <html data-cx data-theme="midnight"><body><Outlet/></body></html>
  )
}

Theme + motion API

12 themes baked into mads.css. Switch globally via data-theme on <html>, or per-subtree by setting it on any wrapper.

ThemeVibeBest for
midnight (default)Deep navy / purpleDashboards, dev tools
cyberNeon cyan / magentaGaming, AI, sci-fi
terraWarm earth tonesEditorial, content
auroraTeal → violet gradientMarketing, hero
monoHigh-contrast grayscaleAccessibility-first
candySoft pastelsConsumer, kids
lightOff-whitePrint-style docs
darkDeep blackOLED, reading
matrix · solar · nord · draculaClassic dev themesIDE-inspired UIs

Imperative API (any framework)

// Auto-exposed by bootstrap.js (window.MADS)
MADS.setTheme('cyber')          // any of 12 ids
MADS.setReducedMotion(true)     // opt-in, default OFF
MADS.setDirection('rtl')        // 'ltr' | 'rtl'
MADS.setDensity('compact')      // 'compact' | 'cozy' | 'comfortable'

// npm import (same API)
import { setTheme, setReducedMotion, setDirection, setDensity } from '@chaozcode/mads'

React hooks

import { useTheme, useReducedMotion, useDirection, useDensity, useThemeOverrides } from '@chaozcode/mads'

const [theme, setTheme] = useTheme()                // 'midnight' | 'cyber' | …
const [reduce, setReduce] = useReducedMotion()      // boolean, opt-in
const [dir, setDir] = useDirection()                // 'ltr' | 'rtl'
const [density, setDensity] = useDensity()          // 'compact' | 'cozy' | 'comfortable'

// Custom token overrides
import { setThemeOverrides, clearThemeOverrides, exportThemeCss, uploadThemeCss } from '@chaozcode/mads'
setThemeOverrides({ accent: '#ff6b35', radius: '0.25rem' })
const css = exportThemeCss()                        // serialized override CSS
await uploadThemeCss(css, { endpoint: '/api/theme' })

Contrast helpers (WCAG)

import { getContrastRatio, contrastVerdict, validateThemeContrast } from '@chaozcode/mads'

getContrastRatio('#ffffff', '#050817')   // 19.74
contrastVerdict(19.74)                    // 'AAA'
validateThemeContrast('cyber')            // { pass: true, failures: [] }

Per-app theme scopes (v1.7.2 · portal-aware v1.7.3)

Multi-app installs — chaozcode.com hosts BBS, Memory Spine, ChaozPilot, ThirdEye — give each embedded app its own accent color without forking the global theme. Wrap the app in <AppThemeBoundary>; cx-* tokens cascade through [data-app="…"] CSS scopes. Portaled overlays (Modal/Drawer/Toast) inherit the scope via React context, so a modal opened inside a BBS boundary still renders BBS-cyan even though it portals to <body>.

import { AppThemeBoundary, setAppTheme, useAppTheme } from '@chaozcode/mads'

// Declarative — static overrides
<AppThemeBoundary appId="bbs" overrides={{ accent: "#06b6d4" }}>
  <BbsApp />
</AppThemeBoundary>

// Imperative — anywhere, any framework
setAppTheme('bbs', { accent: '#06b6d4', brand: '#0891b2' })

// React hook — reactive read/write per app
const [overrides, setOverrides, clear] = useAppTheme('bbs')

// Restore everything persisted to localStorage on page load
import { hydrateAppThemes } from '@chaozcode/mads'
hydrateAppThemes()

Token surface mirrors ThemeOverrides — accent, brand, success, danger, bgSurface, textPrimary, radius, etc. Scopes persist to localStorage by default; pass persist={false} for ephemeral previews.

Custom icons pipeline (v1.7.5)

Pluggable icon catalog with namespaces. Built-in brand icons auto-register under mads:; consumers add their own under any prefix. <CxIcon name="…"> resolves registry → lucide-react (1000+) → fallback.

import { registerIcon, registerIcons, CxIcon, useIcons } from '@chaozcode/mads'

// Single
registerIcon('bbs:flame', FlameSvg, { source: 'bbs', tags: ['fire', 'priority'] })

// Bulk with shared meta
registerIcons({
  'bbs:thread':   ThreadSvg,
  'bbs:lock':     LockSvg,
  'bbs:bookmark': BookmarkSvg,
}, { source: 'bbs' })

// Render anywhere — three resolution layers
<CxIcon name="bbs:flame" size={20} color="var(--cx-accent)" />   // registry
<CxIcon name="lucide:Server" size={16} />                       // lucide
<CxIcon name="Activity" />                                       // bare lucide (no prefix)
<CxIcon name="unknown" fallback="Square" />                     // fallback

// Vite ?react query auto-converts SVG files to components
import FlameSvg from './icons/flame.svg?react'
registerIcon('bbs:flame', FlameSvg)

// Icon-picker / management UI
const bbsIcons = useIcons('bbs:')                  // string prefix filter
const danger   = useIcons(i => i.meta?.tags?.includes('danger'))

Namespace convention /^[a-zA-Z][a-zA-Z0-9_-]*:[a-zA-Z][a-zA-Z0-9_.-]*$/ — e.g. mads:LogoIcon, bbs:flame. Invalid names warn and no-op. Live picker at /components/settings → Custom Icons.

Layout primitives (v1.5.0)

Container-query-based — every primitive adapts to its container width, not the viewport. Lets a sidebar widget and a full-width panel share the same component and still render correctly.

ComponentClassPropsSnippet
CxContainercx-containerWraps a region in container-query context.
CxStackcx-stackgap: xs|sm|md|lg|xlVertical flow.
CxRowcx-rowmin: 120..320, align, justify, gapAuto-stacks below min.
CxGridcx-gridmin: 140..320 or cols: 2|3|4|12Auto-fit columns.
CxSidebarcx-sidebarwidth: 200|240|280|320, sideSidebar + main; wraps when narrow.
CxClustercx-clustergap, justifyInline items that wrap (chips, tags).
CxCentercx-centermax: sm|md|lg|xl, fillCenters content both axes.
CxCovercx-coverminHeightHero 3-zone (top/center/bottom).
CxFramecx-frameratio: 16:9 (default)Aspect-ratio container.
CxSplitcx-splitgap50/50 → stacks below 640px container.

Fluid typography (calibrated to compact-professional)

<h1 class="cx-fluid-h1">...</h1>   /* clamp(1.35rem, 3vw, 1.85rem) */
<h2 class="cx-fluid-h2">...</h2>   /* clamp(1.1rem, 2.4vw, 1.4rem) */
<p  class="cx-fluid-body">...</p>  /* clamp(0.78rem, 1.4vw, 0.875rem) */
<label class="cx-fluid-label">...</label>  /* uppercase 0.6rem-0.68rem */

Motion engine (v1.7.0 · physics + beauty complete)

All motion is compositor-only (transform / opacity / filter). Animate-on-mount with utility classes; opt-in physics on hover/active.

Entry animations

ClassEffectBest for
cx-animate-fade-upOpacity + 12px slideCards on mount
cx-animate-fade-inOpacity onlyModal content
cx-animate-scale-in0.94 → 1 scale + opacityPopovers
cx-animate-bounce-in0.85 → 1.02 → 1 springToasts, achievements
cx-animate-springPremium reveal with blurHero text
cx-animate-slide-left/right32px horizontal slideDrawers
cx-animate-zoom-in0.85 + 8px blur clearLightbox
cx-animate-revealUp + scale + blur clearSection transitions

v1.6.0 physics utilities

ClassEffect
cx-animate-overshootSprings past target then settles
cx-animate-settleCritically-damped descent (no oscillation)
cx-animate-elasticDecaying oscillation back to origin
cx-animate-pop0.6 → 1.08 → 1 punch
cx-animate-drop-inFalls from above with bounce-back
cx-animate-flip-x · flip-y3D card flip on entry
cx-animate-blur-in10px blur clears
cx-animate-rubber-bandX/Y squash-stretch attention-getter
cx-animate-jellySoft squash on action confirmation

v1.7.0 physics completion

ClassEffect
cx-animate-dampedDamped oscillation decaying to rest
cx-animate-gravity-dropAccelerates downward then absorbs
cx-animate-recoilPush back from impact, then settle
cx-animate-fling-left · fling-rightMomentum exit with opacity fade
cx-animate-inertiaFast-in, slow-stop (for swiped panels)
cx-animate-shake-x · shake-yA11y attention jitter
cx-animate-vibrateMicro-shake (sub-pixel) for active state
cx-animate-wobble-softGentle tilt + slide acknowledgement
cx-animate-bobVertical idle bob (loop)
cx-animate-heartbeatEmergency/error pulse (loop)
cx-animate-push-backZ-axis recoil INTO page (with perspective)

v1.7.0 beauty FX

ClassEffect
cx-text-holographic-soft5-stop gradient sweep on text (gentler than original holographic)
cx-text-iridescentPearlescent pastel shimmer
cx-text-auroraAurora gradient sweep (premium hero text)
cx-border-gradientAnimated conic-gradient border (CSS @property + mask trick)
cx-glow-stackLayered radial halo bloom on hover
cx-shimmer-softGentle loading shimmer (low-CPU alternative to skeleton)
cx-page-enter-gentleQuieter page-enter (subtle opacity + scale)
cx-section-dividerAnimated underline with light sweep

Hover physics (opt-in)

<!-- v1.6.0 -->
<button class="cx-btn cx-btn-primary cx-hover-pop">Pop</button>
<div class="cx-card cx-card-frosted cx-hover-tilt-3d">3D tilt</div>
<div class="cx-card cx-hover-shimmer-y">Shimmer vertical</div>
<div class="cx-card cx-hover-jelly">Jelly squash</div>
<div class="cx-card cx-hover-rubber">Rubber band</div>
<button class="cx-btn cx-hover-glow">Glow halo</button>

<!-- v1.7.0 -->
<button class="cx-btn cx-hover-shake">Shake on hover</button>
<div class="cx-card cx-hover-wobble">Wobble</div>
<button class="cx-btn cx-hover-vibrate">Sub-pixel vibrate</button>
<div class="cx-card cx-hover-magnetic">Magnetic lift</div>
<div class="cx-card cx-hover-lift-3d">3D lift + perspective rotate</div>
<button class="cx-btn cx-hover-push-back">Push-back on active</button>
<div class="cx-card cx-hover-sticky">Sticky resistance hover</div>
<div class="cx-card cx-hover-bob">Hover to start vertical bob loop</div>

Loops / idle motion

<div class="cx-loop-breathe">Subtle scale 1.015 every 4s</div>
<div class="cx-loop-pulse-soft cx-pause-on-hover">Gentle pulse, pauses on hover</div>
<svg class="cx-loop-spin-slow">...</svg>             /* 12s linear */
<div class="cx-loop-float">Hovering element</div>

Auto-stagger

<div data-stagger>
  <div class="cx-card">Card 1</div>   <!-- delays: 0ms -->
  <div class="cx-card">Card 2</div>   <!-- delays: 45ms -->
  <div class="cx-card">Card 3</div>   <!-- delays: 90ms -->
</div>
<div data-stagger="fast">...</div>     <!-- 28ms step -->
<div data-stagger="slow">...</div>     <!-- 70ms step -->

Duration / delay modifiers

<div class="cx-animate-fade-up cx-dur-slow cx-delay-200">...</div>
   /* dur: fast | base | slow | slower | slowest */
   /* delay: 0 | 50 | 100 | 200 | 300 | 500 */

Easing primitives (CSS variables)

--cx-ease            cubic-bezier(0.4, 0, 0.2, 1)         /* material standard */
--cx-ease-out        cubic-bezier(0.22, 1, 0.36, 1)       /* decelerate */
--cx-ease-in-out     cubic-bezier(0.65, 0, 0.35, 1)       /* smooth */
--cx-ease-spring     cubic-bezier(0.34, 1.56, 0.64, 1)    /* overshoot */
--cx-ease-spring-soft cubic-bezier(0.16, 1.18, 0.5, 1)    /* gentle bounce */
--cx-ease-bounce     cubic-bezier(0.68, -0.6, 0.32, 1.6)  /* big bounce */
--cx-ease-overshoot  cubic-bezier(0.18, 1.32, 0.48, 0.97) /* expressive overshoot */
--cx-ease-snap       cubic-bezier(0.05, 0.7, 0.1, 1)      /* premium arrival */
--cx-ease-anticipate cubic-bezier(0.68,-0.55, 0.27, 1.55) /* pulls back first */
--cx-ease-drag       cubic-bezier(0.2, 0, 0, 1)           /* release fling */

Overlay system (v1.7.0)

Every floating UI piece must portal via MadsPortal to escape ancestor stacking contexts. Any ancestor with transform / filter / opacity<1 / isolation / will-change / backdrop-filter creates a local stacking context that traps position:fixed descendants — your modal/popover ends up "rendering inside the parent frame" instead of floating above the page.

All 11 library overlays already portal: Modal, Drawer, Sheet, Popover, Tooltip, ContextMenu, DropdownMenu, CommandPalette, ConfirmDialog, Toast, CxToastStack. For custom overlays use the utility classes below or wrap with MadsPortal directly.

Z-index scale (single source of truth)

ClassVariableValueUse case
cx-z-base--cx-z-base0Default flow
cx-z-raised--cx-z-raised10Cards on hover
cx-z-sticky--cx-z-sticky100Sticky headers/footers
cx-z-dropdown--cx-z-dropdown200Click-catchers, inline menus
cx-z-popover--cx-z-popover500Popovers, context menus
cx-z-tooltip--cx-z-tooltip900Tooltips
cx-z-overlay--cx-z-overlay1000Generic floating panels
cx-z-drawer--cx-z-drawer1100Sheets, drawers
cx-z-modal--cx-z-modal1500Modals, dialogs, lightboxes
cx-z-toast--cx-z-toast2000Toast notifications
cx-z-skiplink--cx-z-skiplink9000Skip-to-content link
Never inline z-index numbers. Use the scale. Fragmented z-50 / z-99 / z-9999 across components creates layering chaos that's nearly impossible to debug.

Overlay utility classes

<!-- Modal pattern -->
<div class="cx-overlay-backdrop"></div>
<div role="dialog" class="cx-overlay-modal">…</div>

<!-- Drawer (data-side: left | right | top | bottom) -->
<div role="dialog" class="cx-overlay-drawer" data-side="right">…</div>

<!-- Popover / Dropdown / Tooltip (consumer positions via inline style) -->
<div role="dialog" class="cx-overlay-popover"  style="top: 120px; left: 80px">…</div>
<div role="menu"   class="cx-overlay-dropdown" style="top: 120px; left: 80px">…</div>
<div role="tooltip" class="cx-overlay-tooltip"  style="top: 120px; left: 80px">…</div>

<!-- Toast stack (consumer renders toasts as children) -->
<div class="cx-overlay-toast-stack">
  <div class="cx-card">Saved!</div>
</div>

<!-- A11y skip link -->
<a href="#main" class="cx-skip-link">Skip to content</a>

MadsPortal — universal escape hatch

import { MadsPortal } from '@chaozcode/mads/components'

function MyCustomOverlay({ open }) {
  if (!open) return null
  return (
    <MadsPortal>
      <div role="dialog" className="cx-z-modal cx-overlay-backdrop">
        <div className="cx-overlay-modal">…</div>
      </div>
    </MadsPortal>
  )
}

Dual-scope overlays — inside vs. outside window

Drawer, Sheet, ContextMenu all accept a scope prop:

scopeBehaviorUse case
"viewport" (default)Portals to <body>, fixed position, full-screen, escapes ancestor stacking contextsApp-level modals/drawers/menus
"parent"Renders in place inside nearest position:relative ancestor; NO portalApp-shell sidebar that should NOT cover the page
<CxAppShell>
  <CxAppShell.Main style={{ position: 'relative' }}>
    <Drawer open={open} scope="parent" side="right">
      Slides within the main column only.
    </Drawer>
  </CxAppShell.Main>
</CxAppShell>

Popover / DropdownMenu — dual calling conventions

// NEW API (recommended)
<Popover trigger={<Button>Open</Button>}>
  <div>Popover content</div>
</Popover>

// LEGACY API (still supported)
<Popover content={<div>Popover content</div>}>
  <Button>Open</Button>
</Popover>

Design tokens

Every visual decision is a CSS custom property. Override on :root or any subtree. JS mirrors live in MADS_TOKENS from @chaozcode/mads.

GroupExamples
Color--cx-accent, --cx-bg-base, --cx-text-primary, --cx-border
Status--cx-color-success, --cx-color-danger, --cx-color-warning, --cx-color-info
Spacing--cx-space-0..12 (4px base)
Radius--cx-radius-sm..3xl, --cx-radius-full
Shadow--cx-shadow-sm..xl, --cx-glow-sm..lg
Z-index--cx-z-base..tooltip (0 → 3000)
Motion--cx-duration-instant..slower, --cx-ease-*

LLM cheat sheet · intent → component

I want…Use
Primary call-to-action button<CxButton variant="primary">
Destructive action<CxButton variant="danger">
Secondary chrome control<CxButton variant="ghost" size="sm">
Container with subtle border<CxCard variant="default">
Glassmorphic surface<CxCard variant="frosted"> or <CxCard variant="glass">
Stat tile / KPIcx-stat-card with cx-stat-card-label + cx-stat-card-value
Form input<CxInput type=… variant="default|error">
4-column dashboard<CxRow min={200}> with 4 children
Card gallery, fluid count<CxGrid min={220}>
Sidebar + main<CxSidebar width={240}> (first child = sidebar, last = main)
Tag/chip row<CxCluster> with <span className="cx-badge">
Hero pattern<CxCover>
16:9 video container<CxFrame ratio="16:9">
Status pill<span className="cx-badge"> + status color
Code block<pre className="cx-code">
Modal / drawerModal / Drawer from @chaozcode/mads/components
Toast notificationsCxToastStack + useToast
Loading skeleton<div className="cx-skeleton" /> or Skeleton component
TabsTabs component (role="tabpanel" auto-animates)
Command palette (⌘K)CommandPalette
Data gridDataGrid
Avatar with status<Avatar status="online" />
Breadcrumbs<Breadcrumbs items={[…]} />

29 component categories

foundation · buttons · badges · forms · cards · data · plan-modules · dataviz · feedback · navigation · overlays · advanced · fx · beauty · revolution · creative · devops · infrastructure · proforms · utilities · auth · calendar · chat · ecommerce · files · settings · social · motion · terminal

Browse each at design.chaozcode.com/components. New in v1.9.0: plan-modules — 12 primitives for rendering any plan (PlanHero, PlanStatTile, PlanKeyValue, PlanStatusDot, PlanCodeSnippet, PlanPhaseCard, PlanTaskRow, PlanOutcomeRow, PlanGapCard, PlanConnBox, PlanFlowDiagram, PlanSectionTabs).

Common errors & fixes

❌ "Cannot read properties of null (reading 'useContext')"

Cause: two React instances. Happens when framer-motion or lucide-react on esm.sh bundles its own React.

Fix: add ?external=react,react-dom on every package that has React as a peer dep. The shipped bootstrap.js already does this.

❌ Components render unstyled (no purple, no border-radius)

Cause: mads.css not loaded or loaded after a CSS reset that resets cx-*.

Fix: load mads.css AFTER any reset/normalize. Or import via npm import '@chaozcode/mads/styles'.

❌ "ReferenceError: regeneratorRuntime is not defined" (UMD)

Fix: load React UMD BEFORE mads.umd.js.

❌ iOS Low Power Mode killed all animation

Cause: a downstream CSS used @media (prefers-reduced-motion: reduce) which iOS Low Power Mode fires.

Fix: don't use that query. Reduce-motion is opt-in via setReducedMotion(true)[data-reduce-motion].

❌ Sidebar renders empty space at top on mobile

Cause: @media block declared before the .sidebar base rule, so source-order made base position: sticky win over the media query's position: fixed. The sidebar stayed in-flow despite transform: translateX(-100%).

Fix: place @media (max-width: ...) blocks AFTER all base rules in your stylesheet.

❌ Tailwind utilities not flowing into the React bundle

Cause: missing tailwindcss() Vite plugin in lib-mode vite.config.ts. mads.css ships without utilities → DataGrid/Checkbox/Toggle break in consumers.

Fix: plugins: [react(), tailwindcss(), dts({...})] in BOTH showcase and lib configs.

❌ Hydration mismatch with theme

Cause: SSR renders default theme, client renders saved theme. Mismatch flash.

Fix: inject the theme as an HTML attribute on the server (e.g., from a cookie). The MADS bootstrap reads data-theme on <html> without flicker.

Bundle sizes

EntryPathMin+gzWhat's in
CSS-only/latest/mads.css~58 KBAll visuals, themes, motion, layout
Design system ESM/latest/design-system.mjs~12 KBCxButton, CxCard, CxInput, layout, theme
Components ESM/latest/components.mjs~81 KBAll 217 React components
Patterns ESM/latest/patterns.mjs~14 KBHero, login, pricing, dashboard layouts
UMD bundle/latest/mads.umd.js~95 KBAll-in-one, exposes window.MADS

Model-specific notes

Claude (Sonnet/Opus 4.x)

Paste this preamble into your system prompt for high-fidelity output:

You're building UI with @chaozcode/mads. Hard rules:
- Use cx-* classes (never Tailwind inside Cx* components).
- Layout: CxRow (auto-stacks below `min`), CxGrid (auto-fit columns), CxSidebar (sidebar+main wraps).
- Surfaces: CxCard variant=frosted|glass|stat. Containers: cx-stat-card, cx-feature-card.
- Motion is on by default. Use cx-animate-fade-up | cx-animate-pop | cx-hover-tilt-3d.
- Skip prefers-reduced-motion media queries — use [data-reduce-motion] (opt-in).
- Animate transform/opacity only — never width/height/padding.
- For status: cx-badge + cx-color-success|danger|warning|info.
- Density target: text-[10px] labels, 0.5rem gaps, tight padding (compact-professional).

GPT-4o / o1

Same as Claude. Add function calling for theme switches via window.MADS.setTheme(themeId) if you wire tools.

Cursor / Copilot in-editor

Save this as .cursorrules or .github/copilot-instructions.md:

# Chaoz-MADS rules
- Import from '@chaozcode/mads' for primitives, '@chaozcode/mads/components' for everything else
- Wrap pages in CxStack/CxRow/CxGrid; never use raw CSS Grid/Flex when a primitive exists
- Hover/active uses cx-hover-* — never inline JS-driven CSS
- Forms: CxInput, CxTextarea, CxInputGroup — never raw <input> with Tailwind
- Always set data-theme on <html> (default "midnight")
- Skip prefers-reduced-motion @media — use [data-reduce-motion] opt-in flag

Gemini / Llama / Mistral

These models tend to invent class names. Pin them with the JSON-LD manifest at the top of this page or this single sentence:

Only emit class names from this list: cx-btn, cx-btn-{primary|secondary|ghost|outline|danger|success},
cx-card, cx-card-{frosted|glass|glassUltra|hover|stat}, cx-input, cx-textarea, cx-badge, cx-row,
cx-grid, cx-sidebar, cx-stack, cx-cluster, cx-frame, cx-split, cx-stat-card, cx-stat-card-{label,value},
cx-text-{primary|secondary|muted}, cx-text-gradient, cx-text-gradient-{purple|cyan|gold|green},
cx-fluid-{h1|h2|h3|body|small|micro|label}, cx-animate-{fade-up|fade-in|scale-in|bounce-in|pop|overshoot|settle|elastic|rubber-band|jelly},
cx-hover-{pop|tilt-3d|jelly|rubber|glow|shimmer-y|lift}, cx-loop-{breathe|pulse-soft|float|spin-slow}.

Source control — chaozcode native git via gix

Chaoz-MADS lives on the chaozcode native git server (not GitHub). The canonical bare repos sit at /var/git/admin/Chaoz-MADS.git (admin) and /var/www/chaozcode/users/1/gitchaoz/Chaoz-MADS.git (user-1 gitchaoz mirror).

Use the GitChaozOxide (gix) CLI for commits + pushes — it adds a security pre-scan (secrets, large files), Memory Spine telemetry, and ML-routed diff summaries.

Daily commit / push

# Repo health
gix chaoz status              # branch + working-tree state with metrics
gix chaoz dashboard           # commits, security, Memory Spine vectors
gix chaoz report              # full markdown audit report

# Commit + push flow
gix chaoz add <files>          # stage with telemetry
gix chaoz commit -m "msg"     # commit with secret pre-scan + Memory Spine log
gix chaoz push                # security pre-flight + push to origin
gix chaoz push --dry-run      # secret-scan only, don't actually push
git push chaozcode master     # mirror to /var/git/admin/ canonical

# Other useful ops
gix chaoz pull                # fetch + merge with logging
gix chaoz diff                # AI-powered impact summary via ML Router
gix chaoz scan                # security scan for secrets + large files
gix chaoz benchmark           # repo performance benchmarks
gix chaoz hooks install       # pre-commit security + post-push logging hooks

CI/CD — local, ML-aware, multi-platform (gix chaoz pipeline)

gix chaoz pipeline init full        # scaffold .chaoz/pipeline.yml
                                    # templates: web | mobile | desktop | full | minimal
gix chaoz pipeline validate         # syntax-check
gix chaoz pipeline run              # run pipeline locally
gix chaoz pipeline status           # recent runs (from Memory Spine)
gix chaoz pipeline logs             # live-tail running pipeline
gix chaoz pipeline watch -p 8903    # webhook listener — triggers runs on git push events

gix chaoz deploy web                # deploy to web target
gix chaoz deploy --dry-run all      # plan multi-platform deploy

No CI cloud needed — pipelines run locally with ML-routed agent selection + Memory Spine logging. watch mode makes the local box a CI server.

SDSN HTTP REST API (gix chaoz serve)

gix chaoz serve --port 8902         # start the SDSN router (default 127.0.0.1:8902)

Exposes REST endpoints any consumer can hit cross-language, cross-host:

Method · pathPurpose
POST /sdsn/routeRoute a single task to the optimal ML agent
POST /sdsn/batch-routeRoute N tasks in one call
POST /sdsn/feedbackSubmit feedback to improve routing
GET /sdsn/metricsJSON metrics
GET /sdsn/prometheusPrometheus scrape target
GET /sdsn/healthHealth probe
# ML-route a task without spawning a CLI:
curl -s http://127.0.0.1:8902/sdsn/route -X POST \
  -H 'Content-Type: application/json' \
  -d '{"task":"Refactor Modal close animation"}'

# Or use the CLI shortcut:
gix chaoz dispatch "Refactor Modal close animation" --top-n 3

Memory Spine queries

gix chaoz memory stats              # vector count + backend
gix chaoz memory tail               # recent git operations
gix chaoz memory search "v1.7.0"    # full-text + vector search past operations

Sessions (long-running ops)

gix chaoz session start <name>       # named THERO session for multi-step work
gix chaoz session list              # active sessions
gix chaoz session log <name>         # session event log

Powerful gix-native git ops (faster than git)

Beyond chaoz, the gix CLI ships native Rust replacements for heavy git plumbing — useful at scale:

gix verify                          # full integrity check (faster than git fsck)
gix fsck                            # missing-object check
gix odb stats                       # object database stats
gix commit-graph verify             # commit-graph integrity
gix archive                         # worktree archives (tar/zip)
gix corpus                          # analytics across many repos at once
gix blame <file>                     # per-line blame (parallelized)
gix worktree                        # worktree management
gix merge-base <a> <b>               # find merge base
gix is-clean / is-changed            # exit-status repo state checks (CI-friendly)
Plain git still works for every operation; gix chaoz is the value-add wrapper with security + telemetry + AI summaries + CI/CD + REST API. Use whichever fits your flow — they all edit the same refs.

Versioning & SRI

/latest/mads.css        ← always-current (rolling)
/v2.0.33/mads.css        ← pinned (v2.0.33)
/v1.5.0/mads.css        ← pinned (older)

Same versioning applies to .mjs / .umd.js / manifest.json
<link rel="stylesheet"
      href="https://design.chaozcode.com/v2.0.33/mads.css"
      integrity="sha384-…"
      crossorigin="anonymous">

Hashes are auto-published at /integrity.json.

Test in this browser

Click → live preview of the integration modes:

🎨 CSS-only demo
All cx-* classes, no JS
🧪 External React test
ESM importmap → React components
📐 react-demo
Full 16-page React app importing 217 components
📝 static-demo
Pure HTML, no build, every cx-* class