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
Cx* components — all visual styling lives in cx-* classes inside chaozcode.css. (You CAN use Tailwind around them in your own JSX.)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.width / height / top / left / margin / padding). Use transform: translate3d() / scale() / scaleX(). Compositor-only → 60fps even on mid-tier mobile.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.
<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.
| Path | Use it when | Build step | Tree-shakeable | SSR |
|---|---|---|---|---|
| 1 CSS-only | Plain HTML, Astro, Hugo, Jekyll, MPA | None | n/a | ✅ |
| 2 ESM importmap | React in modern browsers, no bundler | None | — | — |
| 3 UMD script | Legacy browsers, CMS embeds, WordPress | None | — | — |
| 4 npm | Next.js / Vite / Remix / Astro+React | Yes | ✅ | ✅ |
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) -->
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"
}
}
?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.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>
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
// 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.
// 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()] })
---
// 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>
<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().
<!-- 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>
// 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>
)
}
12 themes baked into mads.css. Switch globally via data-theme on <html>, or per-subtree by setting it on any wrapper.
| Theme | Vibe | Best for |
|---|---|---|
midnight (default) | Deep navy / purple | Dashboards, dev tools |
cyber | Neon cyan / magenta | Gaming, AI, sci-fi |
terra | Warm earth tones | Editorial, content |
aurora | Teal → violet gradient | Marketing, hero |
mono | High-contrast grayscale | Accessibility-first |
candy | Soft pastels | Consumer, kids |
light | Off-white | Print-style docs |
dark | Deep black | OLED, reading |
matrix · solar · nord · dracula | Classic dev themes | IDE-inspired UIs |
// 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'
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' })
import { getContrastRatio, contrastVerdict, validateThemeContrast } from '@chaozcode/mads'
getContrastRatio('#ffffff', '#050817') // 19.74
contrastVerdict(19.74) // 'AAA'
validateThemeContrast('cyber') // { pass: true, failures: [] }
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.
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.
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.
| Component | Class | Props | Snippet |
|---|---|---|---|
CxContainer | cx-container | — | Wraps a region in container-query context. |
CxStack | cx-stack | gap: xs|sm|md|lg|xl | Vertical flow. |
CxRow | cx-row | min: 120..320, align, justify, gap | Auto-stacks below min. |
CxGrid | cx-grid | min: 140..320 or cols: 2|3|4|12 | Auto-fit columns. |
CxSidebar | cx-sidebar | width: 200|240|280|320, side | Sidebar + main; wraps when narrow. |
CxCluster | cx-cluster | gap, justify | Inline items that wrap (chips, tags). |
CxCenter | cx-center | max: sm|md|lg|xl, fill | Centers content both axes. |
CxCover | cx-cover | minHeight | Hero 3-zone (top/center/bottom). |
CxFrame | cx-frame | ratio: 16:9 (default) | Aspect-ratio container. |
CxSplit | cx-split | gap | 50/50 → stacks below 640px container. |
<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 */
All motion is compositor-only (transform / opacity / filter). Animate-on-mount with utility classes; opt-in physics on hover/active.
| Class | Effect | Best for |
|---|---|---|
cx-animate-fade-up | Opacity + 12px slide | Cards on mount |
cx-animate-fade-in | Opacity only | Modal content |
cx-animate-scale-in | 0.94 → 1 scale + opacity | Popovers |
cx-animate-bounce-in | 0.85 → 1.02 → 1 spring | Toasts, achievements |
cx-animate-spring | Premium reveal with blur | Hero text |
cx-animate-slide-left/right | 32px horizontal slide | Drawers |
cx-animate-zoom-in | 0.85 + 8px blur clear | Lightbox |
cx-animate-reveal | Up + scale + blur clear | Section transitions |
| Class | Effect |
|---|---|
cx-animate-overshoot | Springs past target then settles |
cx-animate-settle | Critically-damped descent (no oscillation) |
cx-animate-elastic | Decaying oscillation back to origin |
cx-animate-pop | 0.6 → 1.08 → 1 punch |
cx-animate-drop-in | Falls from above with bounce-back |
cx-animate-flip-x · flip-y | 3D card flip on entry |
cx-animate-blur-in | 10px blur clears |
cx-animate-rubber-band | X/Y squash-stretch attention-getter |
cx-animate-jelly | Soft squash on action confirmation |
| Class | Effect |
|---|---|
cx-animate-damped | Damped oscillation decaying to rest |
cx-animate-gravity-drop | Accelerates downward then absorbs |
cx-animate-recoil | Push back from impact, then settle |
cx-animate-fling-left · fling-right | Momentum exit with opacity fade |
cx-animate-inertia | Fast-in, slow-stop (for swiped panels) |
cx-animate-shake-x · shake-y | A11y attention jitter |
cx-animate-vibrate | Micro-shake (sub-pixel) for active state |
cx-animate-wobble-soft | Gentle tilt + slide acknowledgement |
cx-animate-bob | Vertical idle bob (loop) |
cx-animate-heartbeat | Emergency/error pulse (loop) |
cx-animate-push-back | Z-axis recoil INTO page (with perspective) |
| Class | Effect |
|---|---|
cx-text-holographic-soft | 5-stop gradient sweep on text (gentler than original holographic) |
cx-text-iridescent | Pearlescent pastel shimmer |
cx-text-aurora | Aurora gradient sweep (premium hero text) |
cx-border-gradient | Animated conic-gradient border (CSS @property + mask trick) |
cx-glow-stack | Layered radial halo bloom on hover |
cx-shimmer-soft | Gentle loading shimmer (low-CPU alternative to skeleton) |
cx-page-enter-gentle | Quieter page-enter (subtle opacity + scale) |
cx-section-divider | Animated underline with light sweep |
<!-- 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>
<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>
<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 -->
<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 */
--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 */
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.
| Class | Variable | Value | Use case |
|---|---|---|---|
cx-z-base | --cx-z-base | 0 | Default flow |
cx-z-raised | --cx-z-raised | 10 | Cards on hover |
cx-z-sticky | --cx-z-sticky | 100 | Sticky headers/footers |
cx-z-dropdown | --cx-z-dropdown | 200 | Click-catchers, inline menus |
cx-z-popover | --cx-z-popover | 500 | Popovers, context menus |
cx-z-tooltip | --cx-z-tooltip | 900 | Tooltips |
cx-z-overlay | --cx-z-overlay | 1000 | Generic floating panels |
cx-z-drawer | --cx-z-drawer | 1100 | Sheets, drawers |
cx-z-modal | --cx-z-modal | 1500 | Modals, dialogs, lightboxes |
cx-z-toast | --cx-z-toast | 2000 | Toast notifications |
cx-z-skiplink | --cx-z-skiplink | 9000 | Skip-to-content link |
z-index numbers. Use the scale. Fragmented z-50 / z-99 / z-9999 across components creates layering chaos that's nearly impossible to debug.<!-- 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>
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>
)
}
Drawer, Sheet, ContextMenu all accept a scope prop:
| scope | Behavior | Use case |
|---|---|---|
"viewport" (default) | Portals to <body>, fixed position, full-screen, escapes ancestor stacking contexts | App-level modals/drawers/menus |
"parent" | Renders in place inside nearest position:relative ancestor; NO portal | App-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>
// 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>
Every visual decision is a CSS custom property. Override on :root or any subtree. JS mirrors live in MADS_TOKENS from @chaozcode/mads.
| Group | Examples |
|---|---|
| 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-* |
| 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 / KPI | cx-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 / drawer | Modal / Drawer from @chaozcode/mads/components |
| Toast notifications | CxToastStack + useToast |
| Loading skeleton | <div className="cx-skeleton" /> or Skeleton component |
| Tabs | Tabs component (role="tabpanel" auto-animates) |
| Command palette (⌘K) | CommandPalette |
| Data grid | DataGrid |
| Avatar with status | <Avatar status="online" /> |
| Breadcrumbs | <Breadcrumbs items={[…]} /> |
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).
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.
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'.
Fix: load React UMD BEFORE mads.umd.js.
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].
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.
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.
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.
| Entry | Path | Min+gz | What's in |
|---|---|---|---|
| CSS-only | /latest/mads.css | ~58 KB | All visuals, themes, motion, layout |
| Design system ESM | /latest/design-system.mjs | ~12 KB | CxButton, CxCard, CxInput, layout, theme |
| Components ESM | /latest/components.mjs | ~81 KB | All 217 React components |
| Patterns ESM | /latest/patterns.mjs | ~14 KB | Hero, login, pricing, dashboard layouts |
| UMD bundle | /latest/mads.umd.js | ~95 KB | All-in-one, exposes window.MADS |
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).
Same as Claude. Add function calling for theme switches via window.MADS.setTheme(themeId) if you wire tools.
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
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}.
gixChaoz-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.
# 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
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.
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 · path | Purpose |
|---|---|
POST /sdsn/route | Route a single task to the optimal ML agent |
POST /sdsn/batch-route | Route N tasks in one call |
POST /sdsn/feedback | Submit feedback to improve routing |
GET /sdsn/metrics | JSON metrics |
GET /sdsn/prometheus | Prometheus scrape target |
GET /sdsn/health | Health 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
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
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
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)
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./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.
Click → live preview of the integration modes: