Files
greyhaven-design-system/public/htmx.html
Mathieu Virbel 90930d8f78 feat(htmx-css): ToggleGroup support + padding/primary parity
Generator (scripts/generate-htmx-css.ts): track `viaVariants` per slot so
slots that compose another component's variant system (e.g. ToggleGroupItem
via toggleVariants) inherit the referenced CVA's base + variant rules under
their own selector. Previously toggle-group-item's CSS contained only its
override classes, shipping with no padding/height/hover/active state.

Toggle (components/ui/toggle.tsx):
  - data-[state=on] now uses bg-primary (orange) instead of bg-accent (grey),
    matching every other "commit" affordance in the palette.
  - Horizontal padding aligned with Button: px-4/px-3/px-6 per size, plus
    has-[>svg]:px-* for icon-only toggles.

ToggleGroup (components/ui/toggle-group.tsx): drop min-w-0 flex-1 shrink-0
from the item override. Items now size to content instead of being clamped
into equal narrow columns where longer labels overflowed the bg box.

Showcase: add ToggleGroup section to the React page (component-matrix.tsx)
and 1:1 HTMX mirror (public/htmx.html) with a new JS bridge branch for
single/multi-select. compare-all.sh extended with the new section; 22/22
pass at ≥99.97%.

Docs: GAPS.md captures the generator gap, overflow root cause, color
rationale, and padding parity with before/after numbers.
2026-04-24 14:43:55 -06:00

1095 lines
86 KiB
HTML

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Greyhaven Design System — HTMX</title>
<!-- Source Serif 4 — same source Next.js uses via next/font/google -->
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Source+Serif+4:ital,wght@0,200..900;1,200..900&display=swap" rel="stylesheet">
<link href="/htmx.css" rel="stylesheet">
<script>
(function() {
var stored = localStorage.getItem('theme');
if (stored === 'dark' || (!stored && window.matchMedia('(prefers-color-scheme: dark)').matches)) {
document.documentElement.classList.add('dark');
}
})();
function toggleTheme() {
var isDark = document.documentElement.classList.toggle('dark');
localStorage.setItem('theme', isDark ? 'dark' : 'light');
}
</script>
</head>
<body>
<div class="min-h-screen bg-background text-foreground">
<!-- Header — mirrors app/page.tsx header -->
<header class="border-b border-border bg-background sticky top-0 z-10">
<div class="container mx-auto px-6 py-6 flex items-center justify-between">
<!-- Same Greyhaven wordmark SVG as the React page -->
<svg width="1818" height="448" viewBox="0 0 1818 448" fill="none" xmlns="http://www.w3.org/2000/svg" class="h-[41px] w-auto">
<g clip-path="url(#clip0_13_1414)">
<path d="M625.8 313.476L623.156 286.907C614.009 302.244 592.449 317.924 559.067 317.924C504.436 317.924 455.996 277.76 455.996 208.662C455.996 139.564 507.08 99.7111 561.4 99.7111C612.204 99.7111 644.684 128.956 655.884 163.489L622.502 176.182C615.409 152.569 594.751 132.471 561.369 132.471C527.987 132.471 491.991 156.676 491.991 208.662C491.991 260.649 525.062 285.444 561.089 285.444C603.307 285.444 619.267 256.511 621.04 238.498H551.942V207.48H654.422V313.476H625.769H625.8Z" class="fill-foreground"/>
<path d="M771.649 203.622C767.822 203.031 763.964 202.751 760.418 202.751C733.849 202.751 721.747 218.089 721.747 244.969V313.476H687.493V169.68H720.876V192.702C727.658 177.053 743.618 167.907 762.502 167.907C766.64 167.907 770.187 168.498 771.649 168.778V203.622Z" class="fill-foreground"/>
<path d="M919.582 272.44C911.898 297.547 889.156 317.924 854.622 317.924C815.64 317.924 781.107 289.582 781.107 240.862C781.107 195.378 814.769 165.262 851.076 165.262C895.378 165.262 921.356 194.507 921.356 239.96C921.356 245.56 920.764 250.289 920.453 250.88H815.329C816.2 272.72 833.342 288.369 854.591 288.369C875.84 288.369 885.889 277.449 890.618 263.262L919.551 272.409L919.582 272.44ZM886.822 225.773C886.231 208.942 875 193.884 851.387 193.884C829.827 193.884 817.444 210.404 816.262 225.773H886.822Z" class="fill-foreground"/>
<path d="M949.542 371.653L984.107 296.364L922.693 169.68H961.365L1002.71 260.618L1041.38 169.68H1077.69L986.16 371.653H949.542Z" class="fill-foreground"/>
<path d="M1128.09 313.476H1093.84V99.68H1128.09V183.556C1137.83 170.862 1154.07 165.542 1169.12 165.542C1204.56 165.542 1221.67 190.929 1221.67 222.538V313.476H1187.42V228.418C1187.42 210.684 1179.45 196.529 1157.89 196.529C1139.01 196.529 1128.65 210.684 1128.06 229.009V313.476H1128.09Z" class="fill-foreground"/>
<path d="M1288.56 231.093L1325.46 225.493C1333.73 224.311 1336.1 220.173 1336.1 215.164C1336.1 203.062 1327.82 193.324 1308.94 193.324C1290.05 193.324 1280.88 204.836 1279.41 219.302L1248.12 212.209C1250.76 187.413 1273.22 165.262 1308.66 165.262C1352.96 165.262 1369.79 190.369 1369.79 218.991V290.453C1369.79 303.458 1371.28 312.013 1371.56 313.476H1339.68C1339.4 312.573 1338.21 306.693 1338.21 295.151C1331.43 306.071 1317.24 317.893 1293.91 317.893C1263.8 317.893 1245.19 297.236 1245.19 274.493C1245.19 248.796 1264.08 234.64 1288.59 231.093H1288.56ZM1336.1 253.836V247.333L1298.61 252.933C1287.97 254.707 1279.41 260.618 1279.41 272.44C1279.41 282.178 1286.79 291.044 1300.38 291.044C1319.58 291.044 1336.1 281.898 1336.1 253.836Z" class="fill-foreground"/>
<path d="M1465.52 313.476H1431.27L1372.81 169.68H1410.61L1448.69 272.44L1485.9 169.68H1521.92L1465.52 313.476Z" class="fill-foreground"/>
<path d="M1663.08 272.44C1655.39 297.547 1632.65 317.924 1598.12 317.924C1559.13 317.924 1524.6 289.582 1524.6 240.862C1524.6 195.378 1558.26 165.262 1594.57 165.262C1638.87 165.262 1664.85 194.507 1664.85 239.96C1664.85 245.56 1664.26 250.289 1663.95 250.88H1558.82C1559.69 272.72 1576.84 288.369 1598.08 288.369C1619.33 288.369 1629.38 277.449 1634.11 263.262L1663.04 272.409L1663.08 272.44ZM1630.28 225.773C1629.69 208.942 1618.46 193.884 1594.85 193.884C1573.29 193.884 1560.91 210.404 1559.72 225.773H1630.28Z" class="fill-foreground"/>
<path d="M1724.12 313.476H1689.86V169.68H1723.24V188.876C1732.7 172.356 1749.81 165.542 1765.77 165.542C1800.9 165.542 1817.73 190.929 1817.73 222.538V313.476H1783.48V228.418C1783.48 210.684 1775.51 196.529 1753.95 196.529C1734.48 196.529 1724.12 211.587 1724.12 230.471V313.444V313.476Z" class="fill-foreground"/>
<path d="M345.582 100.551L287.498 66.4533H284.356L232.462 96.9111V34.0978L174.378 0H171.236L113.151 34.0978V96.9111L61.2578 66.4533H58.1156L0 100.551V102.791V347.013L58.0844 381.609H61.2578L113.12 350.747V413.467L171.204 448.062H174.378L232.462 413.467V350.747L284.324 381.609H287.498L345.582 347.013V100.551ZM59.6711 72.7378L111.627 103.258L59.6711 134.182L7.71556 103.258L59.6711 72.7378ZM6.22222 109.604L56.56 139.564V308.436L6.22222 337.991V109.604ZM56.56 315.653V373.427L7.71556 344.338L56.56 315.653ZM62.7822 373.427V315.653L111.627 344.338L62.7822 373.427ZM113.12 337.991L62.7822 308.436V139.564L113.12 109.604V337.991ZM226.24 102.791V163.333L175.902 133.778V73.1422L226.24 43.1822V102.791ZM172.791 200.604L120.836 169.68L172.791 139.16L224.747 169.68L172.791 200.604ZM175.902 65.8933V8.12L224.747 36.8044L175.902 65.8933ZM169.68 8.12V65.8933L120.836 36.8044L169.68 8.12ZM119.342 43.1511L169.68 73.1111V133.747L119.342 163.302V43.1511ZM119.342 176.027L169.68 205.987V374.858L119.342 404.413V176.027ZM169.68 382.076V439.849L120.836 410.76L169.68 382.076ZM175.902 439.849V382.076L224.747 410.76L175.902 439.849ZM226.24 404.413L175.902 374.858V205.987L226.24 176.027V404.413ZM289.022 74.5733L337.867 103.258L289.022 132.347V74.5733ZM282.8 74.5733V132.347L233.956 103.258L282.8 74.5733ZM232.462 109.604L282.8 139.564V308.436L232.462 337.991V109.604ZM285.911 375.293L233.956 344.338L285.911 313.818L337.867 344.338L285.911 375.293ZM339.36 337.991L289.022 308.436V139.564L339.36 109.604V337.991Z" class="fill-foreground"/>
</g>
<defs><clipPath id="clip0_13_1414"><rect width="1817.73" height="448" fill="white"/></clipPath></defs>
</svg>
<button data-slot="button" data-variant="outline" data-size="icon" onclick="toggleTheme()" class="rounded-md bg-transparent" aria-label="Toggle theme">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-moon"><path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"/></svg>
<span class="sr-only">Toggle theme</span>
</button>
</div>
</header>
<!-- Main -->
<main class="container mx-auto px-6 py-8">
<!-- Section 1: Color Tokens — 1:1 copy of components/design-system/color-swatches.tsx -->
<section class="mb-16" id="section-color">
<div class="mb-8">
<h3 class="font-serif text-3xl font-semibold tracking-tight mb-3">Color Tokens</h3>
<p class="text-muted-foreground font-sans text-base max-w-2xl">A restrained set of warm greys, off-black, and muted neutrals, with orange as the only accent.</p>
</div>
<div class="space-y-10">
<!-- Primary Scheme -->
<div>
<h4 class="font-sans text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-4">
Primary Scheme
</h4>
<div class="grid grid-cols-1 sm:grid-cols-3 gap-4">
<div class="border border-border rounded-md overflow-hidden">
<div class="h-24 flex items-end p-3" style="background-color: #F9F9F7">
<span class="font-sans text-xs font-medium text-foreground">#F9F9F7</span>
</div>
<div class="p-3 bg-card">
<p class="font-sans text-sm font-medium">Off-white</p>
<p class="font-mono text-xs text-muted-foreground">--card</p>
</div>
</div>
<div class="border border-border rounded-md overflow-hidden">
<div class="h-24 flex items-end p-3" style="background-color: #161614">
<span class="font-sans text-xs font-medium text-white">#161614</span>
</div>
<div class="p-3 bg-card">
<p class="font-sans text-sm font-medium">Off-black</p>
<p class="font-mono text-xs text-muted-foreground">--foreground</p>
</div>
</div>
<div class="border border-border rounded-md overflow-hidden">
<div class="h-24 flex items-end p-3" style="background-color: #D95E2A">
<span class="font-sans text-xs font-medium text-white">#D95E2A</span>
</div>
<div class="p-3 bg-card">
<p class="font-sans text-sm font-medium">Orange</p>
<p class="font-mono text-xs text-muted-foreground">--primary</p>
</div>
</div>
</div>
</div>
<!-- Grey Scale -->
<div>
<h4 class="font-sans text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-4">
Grey Scale
</h4>
<div class="grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-7 gap-3">
<div class="border border-border rounded-md overflow-hidden">
<div class="h-16 flex items-end p-2" style="background-color: #F0F0EC">
<span class="font-mono text-xs text-foreground">#F0F0EC</span>
</div>
<div class="p-2 bg-card"><p class="font-sans text-xs font-medium truncate">Grey 1 (5%)</p></div>
</div>
<div class="border border-border rounded-md overflow-hidden">
<div class="h-16 flex items-end p-2" style="background-color: #DDDDD7">
<span class="font-mono text-xs text-foreground">#DDDDD7</span>
</div>
<div class="p-2 bg-card"><p class="font-sans text-xs font-medium truncate">Grey 2 (10%)</p></div>
</div>
<div class="border border-border rounded-md overflow-hidden">
<div class="h-16 flex items-end p-2" style="background-color: #C4C4BD">
<span class="font-mono text-xs text-foreground">#C4C4BD</span>
</div>
<div class="p-2 bg-card"><p class="font-sans text-xs font-medium truncate">Grey 3 (20%)</p></div>
</div>
<div class="border border-border rounded-md overflow-hidden">
<div class="h-16 flex items-end p-2" style="background-color: #A6A69F">
<span class="font-mono text-xs text-foreground">#A6A69F</span>
</div>
<div class="p-2 bg-card"><p class="font-sans text-xs font-medium truncate">Grey 4 (50%)</p></div>
</div>
<div class="border border-border rounded-md overflow-hidden">
<div class="h-16 flex items-end p-2" style="background-color: #7F7F79">
<span class="font-mono text-xs text-white">#7F7F79</span>
</div>
<div class="p-2 bg-card"><p class="font-sans text-xs font-medium truncate">Grey 5 (60%)</p></div>
</div>
<div class="border border-border rounded-md overflow-hidden">
<div class="h-16 flex items-end p-2" style="background-color: #575753">
<span class="font-mono text-xs text-white">#575753</span>
</div>
<div class="p-2 bg-card"><p class="font-sans text-xs font-medium truncate">Grey 7 (70%)</p></div>
</div>
<div class="border border-border rounded-md overflow-hidden">
<div class="h-16 flex items-end p-2" style="background-color: #2F2F2C">
<span class="font-mono text-xs text-white">#2F2F2C</span>
</div>
<div class="p-2 bg-card"><p class="font-sans text-xs font-medium truncate">Grey 8 (80%)</p></div>
</div>
</div>
</div>
<!-- Semantic Tokens -->
<div>
<h4 class="font-sans text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-4">
Semantic Tokens
</h4>
<div class="grid grid-cols-2 sm:grid-cols-4 lg:grid-cols-8 gap-3">
<div class="border border-border rounded-md overflow-hidden">
<div class="h-16 flex items-end p-2 bg-background">
<span class="font-sans text-xs text-foreground">Background</span>
</div>
<div class="p-2 bg-card"><p class="font-mono text-xs text-muted-foreground truncate">bg-background</p></div>
</div>
<div class="border border-border rounded-md overflow-hidden">
<div class="h-16 flex items-end p-2 bg-foreground">
<span class="font-sans text-xs text-white">Foreground</span>
</div>
<div class="p-2 bg-card"><p class="font-mono text-xs text-muted-foreground truncate">bg-foreground</p></div>
</div>
<div class="border border-border rounded-md overflow-hidden">
<div class="h-16 flex items-end p-2 bg-card">
<span class="font-sans text-xs text-foreground">Card</span>
</div>
<div class="p-2 bg-card"><p class="font-mono text-xs text-muted-foreground truncate">bg-card</p></div>
</div>
<div class="border border-border rounded-md overflow-hidden">
<div class="h-16 flex items-end p-2 bg-muted">
<span class="font-sans text-xs text-foreground">Muted</span>
</div>
<div class="p-2 bg-card"><p class="font-mono text-xs text-muted-foreground truncate">bg-muted</p></div>
</div>
<div class="border border-border rounded-md overflow-hidden">
<div class="h-16 flex items-end p-2 bg-secondary">
<span class="font-sans text-xs text-foreground">Secondary</span>
</div>
<div class="p-2 bg-card"><p class="font-mono text-xs text-muted-foreground truncate">bg-secondary</p></div>
</div>
<div class="border border-border rounded-md overflow-hidden">
<div class="h-16 flex items-end p-2 bg-primary">
<span class="font-sans text-xs text-white">Primary</span>
</div>
<div class="p-2 bg-card"><p class="font-mono text-xs text-muted-foreground truncate">bg-primary</p></div>
</div>
<div class="border border-border rounded-md overflow-hidden">
<div class="h-16 flex items-end p-2 bg-accent">
<span class="font-sans text-xs text-foreground">Accent</span>
</div>
<div class="p-2 bg-card"><p class="font-mono text-xs text-muted-foreground truncate">bg-accent</p></div>
</div>
<div class="border border-border rounded-md overflow-hidden">
<div class="h-16 flex items-end p-2 bg-border">
<span class="font-sans text-xs text-foreground">Border</span>
</div>
<div class="p-2 bg-card"><p class="font-mono text-xs text-muted-foreground truncate">bg-border</p></div>
</div>
</div>
</div>
</div>
</section>
<!-- Section 2: Typography — 1:1 copy of components/design-system/typography-samples.tsx -->
<section class="mb-16" id="section-typography">
<div class="mb-8">
<h3 class="font-serif text-3xl font-semibold tracking-tight mb-3">Typography</h3>
<p class="text-muted-foreground font-sans text-base max-w-2xl">Source Serif Pro for explanation and human-readable detail. Aspekta (displayed as Inter) for structure, navigation, and UI.</p>
</div>
<div class="space-y-10">
<!-- Serif - Source Serif Pro -->
<div class="border border-border rounded-md p-6 bg-card">
<div class="flex items-center gap-3 mb-6">
<span class="font-sans text-xs font-semibold uppercase tracking-wide text-primary bg-primary/10 px-2 py-1 rounded">
Primary
</span>
<h4 class="font-sans text-sm font-semibold text-muted-foreground">
Source Serif Pro — Reading &amp; Explanation
</h4>
</div>
<div class="space-y-6">
<div>
<p class="font-sans text-xs text-muted-foreground uppercase tracking-wide mb-2">Display / H1</p>
<p class="font-serif text-4xl font-semibold tracking-tight">
Local-first AI systems shaped by real work
</p>
</div>
<div>
<p class="font-sans text-xs text-muted-foreground uppercase tracking-wide mb-2">Heading / H2</p>
<p class="font-serif text-2xl font-semibold tracking-tight">
Built where work happens. Contained end to end.
</p>
</div>
<div>
<p class="font-sans text-xs text-muted-foreground uppercase tracking-wide mb-2">Heading / H3</p>
<p class="font-serif text-xl font-medium">
Systems run inside the perimeter. Nothing leaks.
</p>
</div>
<div>
<p class="font-sans text-xs text-muted-foreground uppercase tracking-wide mb-2">Body</p>
<p class="font-serif text-base leading-relaxed text-muted-foreground max-w-2xl">
Real work is messy, distributed, and embedded in internal systems. Cloud AI often
cannot operate there. Useful AI runs inside the environment and supports human
decision-making — not abstract it away. We sit with the operators, map the steps,
and build a system that mirrors what actually happens.
</p>
</div>
<div>
<p class="font-sans text-xs text-muted-foreground uppercase tracking-wide mb-2">Small / Caption</p>
<p class="font-serif text-sm text-muted-foreground">
Powered by Monadical&apos;s internal, open-source stack hardened over eight years.
</p>
</div>
</div>
</div>
<!-- Sans - Aspekta -->
<div class="border border-border rounded-md p-6 bg-card">
<div class="flex items-center gap-3 mb-6">
<span class="font-sans text-xs font-semibold uppercase tracking-wide text-muted-foreground bg-muted px-2 py-1 rounded">
Secondary
</span>
<h4 class="font-sans text-sm font-semibold text-muted-foreground">
Aspekta — UI, Navigation &amp; Labels
</h4>
</div>
<div class="space-y-6">
<div>
<p class="font-sans text-xs text-muted-foreground uppercase tracking-wide mb-2">Navigation</p>
<div class="flex gap-6">
<span class="font-sans text-sm font-medium">Overview</span>
<span class="font-sans text-sm font-medium text-primary">Documentation</span>
<span class="font-sans text-sm font-medium">Support</span>
<span class="font-sans text-sm font-medium">Contact</span>
</div>
</div>
<div>
<p class="font-sans text-xs text-muted-foreground uppercase tracking-wide mb-2">Button Text</p>
<div class="flex gap-4">
<span class="font-sans text-sm font-semibold">Get Started</span>
<span class="font-sans text-sm font-medium">Learn More</span>
<span class="font-sans text-xs font-semibold uppercase tracking-wide">View All</span>
</div>
</div>
<div>
<p class="font-sans text-xs text-muted-foreground uppercase tracking-wide mb-2">Labels &amp; Form Elements</p>
<div class="flex flex-wrap gap-4">
<span class="font-sans text-sm font-medium">Email Address</span>
<span class="font-sans text-xs text-muted-foreground">Optional</span>
<span class="font-sans text-xs font-medium text-destructive">Required field</span>
</div>
</div>
<div>
<p class="font-sans text-xs text-muted-foreground uppercase tracking-wide mb-2">Status &amp; Metadata</p>
<div class="flex flex-wrap gap-4">
<span class="font-sans text-xs font-medium bg-primary/10 text-primary px-2 py-0.5 rounded">Active</span>
<span class="font-sans text-xs font-medium bg-muted text-muted-foreground px-2 py-0.5 rounded">Pending</span>
<span class="font-sans text-xs text-muted-foreground">Last updated: 2 hours ago</span>
</div>
</div>
</div>
</div>
<!-- Font Stack Reference -->
<div class="grid grid-cols-1 md:grid-cols-2 gap-4">
<div class="border border-border rounded-md p-4 bg-card">
<p class="font-sans text-xs text-muted-foreground uppercase tracking-wide mb-2">Serif Stack</p>
<p class="font-mono text-xs text-muted-foreground">
'Source Serif Pro', 'Source Serif 4', Georgia, serif
</p>
</div>
<div class="border border-border rounded-md p-4 bg-card">
<p class="font-sans text-xs text-muted-foreground uppercase tracking-wide mb-2">Sans Stack</p>
<p class="font-mono text-xs text-muted-foreground">
'Aspekta', ui-sans-serif, system-ui, sans-serif
</p>
</div>
</div>
</div>
</section>
<!-- Section 3: Component Library — 1:1 copy of components/design-system/component-matrix.tsx -->
<section class="mb-16" id="section-components">
<div class="mb-8">
<h3 class="font-serif text-3xl font-semibold tracking-tight mb-3">Component Library</h3>
<p class="text-muted-foreground font-sans text-base max-w-2xl">Interactive elements with consistent styling across all states: default, hover, active, disabled.</p>
</div>
<div class="space-y-10">
<!-- Buttons - All Variants -->
<div id="sub-buttons-variants">
<h4 class="font-sans text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-4">
Buttons — Variants
</h4>
<div class="border border-border rounded-md p-6 bg-card">
<div class="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4">
<div class="space-y-2">
<p class="font-sans text-xs text-muted-foreground">Primary</p>
<button data-slot="button">Primary</button>
</div>
<div class="space-y-2">
<p class="font-sans text-xs text-muted-foreground">Secondary</p>
<button data-slot="button" data-variant="secondary">Secondary</button>
</div>
<div class="space-y-2">
<p class="font-sans text-xs text-muted-foreground">Outline</p>
<button data-slot="button" data-variant="outline">Outline</button>
</div>
<div class="space-y-2">
<p class="font-sans text-xs text-muted-foreground">Ghost</p>
<button data-slot="button" data-variant="ghost">Ghost</button>
</div>
<div class="space-y-2">
<p class="font-sans text-xs text-muted-foreground">Link</p>
<button data-slot="button" data-variant="link">Link</button>
</div>
<div class="space-y-2">
<p class="font-sans text-xs text-muted-foreground">Destructive</p>
<button data-slot="button" data-variant="destructive">Destructive</button>
</div>
</div>
</div>
</div>
<!-- Buttons - Sizes -->
<div id="sub-buttons-sizes">
<h4 class="font-sans text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-4">
Buttons — Sizes
</h4>
<div class="border border-border rounded-md p-6 bg-card">
<div class="flex flex-wrap items-end gap-4">
<div class="space-y-2">
<p class="font-sans text-xs text-muted-foreground">Small</p>
<button data-slot="button" data-size="sm">Small</button>
</div>
<div class="space-y-2">
<p class="font-sans text-xs text-muted-foreground">Default</p>
<button data-slot="button" data-size="default">Default</button>
</div>
<div class="space-y-2">
<p class="font-sans text-xs text-muted-foreground">Large</p>
<button data-slot="button" data-size="lg">Large</button>
</div>
</div>
</div>
</div>
<!-- Buttons - States -->
<div id="sub-buttons-states">
<h4 class="font-sans text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-4">
Buttons — States
</h4>
<div class="border border-border rounded-md p-6 bg-card">
<div class="space-y-6">
<div>
<p class="font-sans text-xs text-muted-foreground mb-3">Primary</p>
<div class="flex flex-wrap gap-3">
<button data-slot="button">Default</button>
<button data-slot="button" class="bg-primary/90">Hover</button>
<button data-slot="button" class="bg-primary/80">Active</button>
<button data-slot="button" class="ring-2 ring-ring ring-offset-2">Focus</button>
<button data-slot="button" disabled>Disabled</button>
</div>
</div>
<div>
<p class="font-sans text-xs text-muted-foreground mb-3">Outline</p>
<div class="flex flex-wrap gap-3">
<button data-slot="button" data-variant="outline">Default</button>
<button data-slot="button" data-variant="outline" class="bg-accent/10">Hover</button>
<button data-slot="button" data-variant="outline" class="ring-2 ring-ring ring-offset-2 bg-transparent">Focus</button>
<button data-slot="button" data-variant="outline" disabled>Disabled</button>
</div>
</div>
<div>
<p class="font-sans text-xs text-muted-foreground mb-3">Destructive</p>
<div class="flex flex-wrap gap-3">
<button data-slot="button" data-variant="destructive">Default</button>
<button data-slot="button" data-variant="destructive" class="bg-destructive/90">Hover</button>
<button data-slot="button" data-variant="destructive" class="ring-2 ring-destructive/50 ring-offset-2">Focus</button>
<button data-slot="button" data-variant="destructive" disabled>Disabled</button>
</div>
</div>
</div>
</div>
</div>
<!-- Icon Buttons -->
<div id="sub-icon-buttons">
<h4 class="font-sans text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-4">
Icon Buttons
</h4>
<div class="border border-border rounded-md p-6 bg-card">
<div class="space-y-6">
<div>
<p class="font-sans text-xs text-muted-foreground mb-3">Variants</p>
<div class="flex flex-wrap gap-3">
<button data-slot="button" data-size="icon"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus h-4 w-4"><path d="M5 12h14"/><path d="M12 5v14"/></svg></button>
<button data-slot="button" data-variant="secondary" data-size="icon"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-settings h-4 w-4"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></svg></button>
<button data-slot="button" data-variant="outline" data-size="icon"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-search h-4 w-4"><path d="m21 21-4.34-4.34"/><circle cx="11" cy="11" r="8"/></svg></button>
<button data-slot="button" data-variant="ghost" data-size="icon"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-x h-4 w-4"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg></button>
<button data-slot="button" data-variant="destructive" data-size="icon"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-trash2 h-4 w-4"><path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/><line x1="10" x2="10" y1="11" y2="17"/><line x1="14" x2="14" y1="11" y2="17"/></svg></button>
</div>
</div>
<div>
<p class="font-sans text-xs text-muted-foreground mb-3">Sizes</p>
<div class="flex flex-wrap items-center gap-3">
<button data-slot="button" data-size="icon-sm" data-variant="outline"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus h-4 w-4"><path d="M5 12h14"/><path d="M12 5v14"/></svg></button>
<button data-slot="button" data-size="icon" data-variant="outline"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus h-4 w-4"><path d="M5 12h14"/><path d="M12 5v14"/></svg></button>
<button data-slot="button" data-size="icon-lg" data-variant="outline"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus h-4 w-4"><path d="M5 12h14"/><path d="M12 5v14"/></svg></button>
</div>
</div>
<div>
<p class="font-sans text-xs text-muted-foreground mb-3">Disabled</p>
<div class="flex flex-wrap gap-3">
<button data-slot="button" data-size="icon" disabled><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus h-4 w-4"><path d="M5 12h14"/><path d="M12 5v14"/></svg></button>
<button data-slot="button" data-variant="outline" data-size="icon" disabled><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-settings h-4 w-4"><path d="M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z"/><circle cx="12" cy="12" r="3"/></svg></button>
<button data-slot="button" data-variant="ghost" data-size="icon" disabled><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-x h-4 w-4"><path d="M18 6 6 18"/><path d="m6 6 12 12"/></svg></button>
</div>
</div>
</div>
</div>
</div>
<!-- Buttons with Icons -->
<div id="sub-buttons-with-icons">
<h4 class="font-sans text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-4">
Buttons with Icons
</h4>
<div class="border border-border rounded-md p-6 bg-card">
<div class="space-y-6">
<div>
<p class="font-sans text-xs text-muted-foreground mb-3">Leading Icon</p>
<div class="flex flex-wrap gap-3">
<button data-slot="button"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus h-4 w-4"><path d="M5 12h14"/><path d="M12 5v14"/></svg> Create New</button>
<button data-slot="button" data-variant="secondary"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-download h-4 w-4"><path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/></svg> Download</button>
<button data-slot="button" data-variant="outline"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-mail h-4 w-4"><rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg> Send Email</button>
<button data-slot="button" data-variant="destructive"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-trash2 h-4 w-4"><path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/><line x1="10" x2="10" y1="11" y2="17"/><line x1="14" x2="14" y1="11" y2="17"/></svg> Delete</button>
</div>
</div>
<div>
<p class="font-sans text-xs text-muted-foreground mb-3">Trailing Icon</p>
<div class="flex flex-wrap gap-3">
<button data-slot="button">Continue <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-right h-4 w-4"><path d="m9 18 6-6-6-6"/></svg></button>
<button data-slot="button" data-variant="outline">Next Step <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-right h-4 w-4"><path d="m9 18 6-6-6-6"/></svg></button>
<button data-slot="button" data-variant="secondary">Submit <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-send h-4 w-4"><path d="m22 2-7 20-4-9-9-4Z"/><path d="M22 2 11 13"/></svg></button>
</div>
</div>
<div>
<p class="font-sans text-xs text-muted-foreground mb-3">Sizes with Icons</p>
<div class="flex flex-wrap items-center gap-3">
<button data-slot="button" data-size="sm"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus h-3.5 w-3.5"><path d="M5 12h14"/><path d="M12 5v14"/></svg> Small</button>
<button data-slot="button" data-size="default"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus h-4 w-4"><path d="M5 12h14"/><path d="M12 5v14"/></svg> Default</button>
<button data-slot="button" data-size="lg"><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-plus h-5 w-5"><path d="M5 12h14"/><path d="M12 5v14"/></svg> Large</button>
</div>
</div>
</div>
</div>
</div>
<!-- Badges - Core Variants -->
<div id="sub-badges-core">
<h4 class="font-sans text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-4">
Badges — Core Variants
</h4>
<div class="border border-border rounded-md p-6 bg-card">
<div class="flex flex-wrap gap-3">
<span data-slot="badge">Default</span>
<span data-slot="badge" data-variant="secondary">Secondary</span>
<span data-slot="badge" data-variant="muted">Muted</span>
<span data-slot="badge" data-variant="outline">Outline</span>
</div>
</div>
</div>
<!-- Badges - Tag & Value -->
<div id="sub-badges-tag">
<h4 class="font-sans text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-4">
Badges — Tag &amp; Value
</h4>
<div class="border border-border rounded-md p-6 bg-card">
<div class="flex flex-wrap gap-3">
<span data-slot="badge" data-variant="tag">Tag</span>
<span data-slot="badge" data-variant="tag">Category</span>
<span data-slot="badge" data-variant="value">42</span>
<span data-slot="badge" data-variant="value">$1,234</span>
<span data-slot="badge" data-variant="value">100%</span>
</div>
</div>
</div>
<!-- Badges - Semantic -->
<div id="sub-badges-semantic">
<h4 class="font-sans text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-4">
Badges — Semantic
</h4>
<div class="border border-border rounded-md p-6 bg-card">
<div class="flex flex-wrap gap-3">
<span data-slot="badge" data-variant="success">Success</span>
<span data-slot="badge" data-variant="warning">Warning</span>
<span data-slot="badge" data-variant="destructive">Danger</span>
<span data-slot="badge" data-variant="info">Info</span>
</div>
</div>
</div>
<!-- Badges - Channel Pills -->
<div id="sub-badges-channel">
<h4 class="font-sans text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-4">
Badges — Channel Pills
</h4>
<div class="border border-border rounded-md p-6 bg-card">
<div class="flex flex-wrap gap-3">
<span data-slot="badge" data-variant="whatsapp">WhatsApp</span>
<span data-slot="badge" data-variant="email">Email</span>
<span data-slot="badge" data-variant="telegram">Telegram</span>
<span data-slot="badge" data-variant="zulip">Zulip</span>
<span data-slot="badge" data-variant="platform">Platform</span>
</div>
</div>
</div>
<!-- Badges on Muted Surface -->
<div id="sub-badges-muted">
<h4 class="font-sans text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-4">
Badges — On Muted Surface
</h4>
<div class="border border-border rounded-md p-6 bg-muted">
<div class="flex flex-wrap gap-3">
<span data-slot="badge">Default</span>
<span data-slot="badge" data-variant="secondary">Secondary</span>
<span data-slot="badge" data-variant="outline">Outline</span>
<span data-slot="badge" data-variant="tag">Tag</span>
<span data-slot="badge" data-variant="success">Success</span>
<span data-slot="badge" data-variant="info">Info</span>
</div>
</div>
</div>
<!-- Inputs -->
<div id="sub-inputs">
<h4 class="font-sans text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-4">
Inputs
</h4>
<div class="border border-border rounded-md p-6 bg-card">
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<div class="space-y-3">
<p class="font-sans text-xs text-muted-foreground">Default</p>
<input data-slot="input" type="text" placeholder="Enter your email">
</div>
<div class="space-y-3">
<p class="font-sans text-xs text-muted-foreground">With Value</p>
<input data-slot="input" type="text" value="user@greyhaven.ai">
</div>
<div class="space-y-3">
<p class="font-sans text-xs text-muted-foreground">Disabled</p>
<input data-slot="input" type="text" placeholder="Disabled input" disabled>
</div>
</div>
<div class="mt-6 pt-6 border-t border-border">
<p class="font-sans text-xs text-muted-foreground mb-3">Textarea</p>
<div class="grid grid-cols-1 md:grid-cols-2 gap-6">
<textarea data-slot="textarea" placeholder="Describe your project requirements..."></textarea>
<textarea data-slot="textarea" placeholder="Disabled textarea" disabled></textarea>
</div>
</div>
</div>
</div>
<!-- Select -->
<div id="sub-select">
<h4 class="font-sans text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-4">
Select
</h4>
<div class="border border-border rounded-md p-6 bg-card">
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<div class="space-y-3">
<p class="font-sans text-xs text-muted-foreground">Default</p>
<button type="button" role="combobox" aria-expanded="false" aria-autocomplete="none" dir="ltr" data-state="closed" data-placeholder="" data-slot="select-trigger" data-size="default">
<span data-slot="select-value" style="pointer-events:none">Select an option</span>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-down size-4 opacity-50"><path d="m6 9 6 6 6-6"/></svg>
</button>
</div>
<div class="space-y-3">
<p class="font-sans text-xs text-muted-foreground">With Value</p>
<button type="button" role="combobox" aria-expanded="false" aria-autocomplete="none" dir="ltr" data-state="closed" data-slot="select-trigger" data-size="default">
<span data-slot="select-value" style="pointer-events:none">Option 2</span>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-down size-4 opacity-50"><path d="m6 9 6 6 6-6"/></svg>
</button>
</div>
<div class="space-y-3">
<p class="font-sans text-xs text-muted-foreground">Disabled</p>
<button type="button" role="combobox" aria-expanded="false" aria-autocomplete="none" dir="ltr" data-state="closed" disabled data-disabled="" data-placeholder="" data-slot="select-trigger" data-size="default">
<span data-slot="select-value" style="pointer-events:none">Disabled</span>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-down size-4 opacity-50"><path d="m6 9 6 6 6-6"/></svg>
</button>
</div>
</div>
</div>
</div>
<!-- Checkboxes & Switches -->
<div id="sub-checkboxes-switches">
<h4 class="font-sans text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-4">
Checkboxes &amp; Switches
</h4>
<div class="border border-border rounded-md p-6 bg-card">
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
<div class="space-y-4">
<p class="font-sans text-xs text-muted-foreground">Checkboxes</p>
<div class="space-y-3">
<div class="flex items-center gap-2">
<button type="button" role="checkbox" aria-checked="false" data-state="unchecked" value="on" class="peer" data-slot="checkbox" id="check1"></button>
<label for="check1" data-slot="label" class="font-sans text-sm">Unchecked</label>
</div>
<div class="flex items-center gap-2">
<button type="button" role="checkbox" aria-checked="true" data-state="checked" value="on" class="peer" data-slot="checkbox" id="check2">
<span data-state="checked" data-slot="checkbox-indicator" style="pointer-events:none">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-check size-3.5"><path d="M20 6 9 17l-5-5"/></svg>
</span>
</button>
<label for="check2" data-slot="label" class="font-sans text-sm">Checked</label>
</div>
<div class="flex items-center gap-2">
<button type="button" role="checkbox" aria-checked="false" data-state="unchecked" data-disabled="" disabled value="on" class="peer" data-slot="checkbox" id="check3"></button>
<label for="check3" data-slot="label" class="font-sans text-sm text-muted-foreground">Disabled</label>
</div>
</div>
</div>
<div class="space-y-4">
<p class="font-sans text-xs text-muted-foreground">Switches</p>
<div class="space-y-3">
<div class="flex items-center gap-2">
<button type="button" role="switch" aria-checked="false" data-state="unchecked" value="on" class="peer" data-slot="switch" id="switch1">
<span data-state="unchecked" data-slot="switch-thumb" style="pointer-events:none"></span>
</button>
<label for="switch1" data-slot="label" class="font-sans text-sm">Off</label>
</div>
<div class="flex items-center gap-2">
<button type="button" role="switch" aria-checked="true" data-state="checked" value="on" class="peer" data-slot="switch" id="switch2">
<span data-state="checked" data-slot="switch-thumb" style="pointer-events:none"></span>
</button>
<label for="switch2" data-slot="label" class="font-sans text-sm">On</label>
</div>
<div class="flex items-center gap-2">
<button type="button" role="switch" aria-checked="false" data-state="unchecked" data-disabled="" disabled value="on" class="peer" data-slot="switch" id="switch3">
<span data-state="unchecked" data-slot="switch-thumb" style="pointer-events:none"></span>
</button>
<label for="switch3" data-slot="label" class="font-sans text-sm text-muted-foreground">Disabled</label>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Tabs -->
<div id="sub-tabs">
<h4 class="font-sans text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-4">
Tabs
</h4>
<div class="border border-border rounded-md p-6 bg-card">
<div dir="ltr" data-slot="tabs" class="w-full">
<div role="tablist" aria-orientation="horizontal" data-slot="tabs-list">
<button type="button" role="tab" aria-selected="true" data-state="active" data-slot="tabs-trigger" tabindex="-1" data-orientation="horizontal">Overview</button>
<button type="button" role="tab" aria-selected="false" data-state="inactive" data-slot="tabs-trigger" tabindex="-1" data-orientation="horizontal">Analytics</button>
<button type="button" role="tab" aria-selected="false" data-state="inactive" data-slot="tabs-trigger" tabindex="-1" data-orientation="horizontal">Settings</button>
<button type="button" role="tab" aria-selected="false" data-state="inactive" data-disabled="" disabled data-slot="tabs-trigger" tabindex="-1" data-orientation="horizontal">Disabled</button>
</div>
<div data-state="active" data-orientation="horizontal" role="tabpanel" tabindex="0" data-slot="tabs-content" class="mt-4" style="animation-duration:0s">
<p class="font-serif text-muted-foreground">
Overview content. This tab demonstrates the default active state.
</p>
</div>
<div data-state="inactive" data-orientation="horizontal" role="tabpanel" hidden tabindex="0" data-slot="tabs-content" class="mt-4"></div>
<div data-state="inactive" data-orientation="horizontal" role="tabpanel" hidden tabindex="0" data-slot="tabs-content" class="mt-4"></div>
</div>
</div>
</div>
<!-- Toggle Group -->
<div id="sub-toggle-group">
<h4 class="font-sans text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-4">
Toggle Group
</h4>
<div class="border border-border rounded-md p-6 bg-card">
<div class="grid grid-cols-1 md:grid-cols-2 gap-8">
<div class="space-y-4">
<div>
<p class="font-sans text-xs text-muted-foreground mb-2">Single, outline</p>
<div data-slot="toggle-group" data-variant="outline" data-type="single" role="group" aria-label="Theme">
<button type="button" data-slot="toggle-group-item" data-variant="outline" data-state="off" data-value="system" aria-label="System">System</button>
<button type="button" data-slot="toggle-group-item" data-variant="outline" data-state="on" data-value="light" aria-label="Light">Light</button>
<button type="button" data-slot="toggle-group-item" data-variant="outline" data-state="off" data-value="dark" aria-label="Dark">Dark</button>
</div>
</div>
<div>
<p class="font-sans text-xs text-muted-foreground mb-2">Single, default</p>
<div data-slot="toggle-group" data-type="single" role="group" aria-label="Layout">
<button type="button" data-slot="toggle-group-item" data-state="off" data-value="list" aria-label="List">List</button>
<button type="button" data-slot="toggle-group-item" data-state="on" data-value="grid" aria-label="Grid">Grid</button>
<button type="button" data-slot="toggle-group-item" data-state="off" data-value="board" aria-label="Board" disabled data-disabled="">Board</button>
</div>
</div>
<div>
<p class="font-sans text-xs text-muted-foreground mb-2">Multiple</p>
<div data-slot="toggle-group" data-variant="outline" data-type="multiple" role="group" aria-label="Text formatting">
<button type="button" data-slot="toggle-group-item" data-variant="outline" data-state="on" data-value="bold" aria-label="Bold">Bold</button>
<button type="button" data-slot="toggle-group-item" data-variant="outline" data-state="off" data-value="italic" aria-label="Italic">Italic</button>
<button type="button" data-slot="toggle-group-item" data-variant="outline" data-state="off" data-value="underline" aria-label="Underline">Underline</button>
</div>
</div>
</div>
<div class="space-y-4">
<div>
<p class="font-sans text-xs text-muted-foreground mb-2">Small</p>
<div data-slot="toggle-group" data-variant="outline" data-type="single" role="group" aria-label="Theme (sm)">
<button type="button" data-slot="toggle-group-item" data-variant="outline" data-size="sm" data-state="off" data-value="system">System</button>
<button type="button" data-slot="toggle-group-item" data-variant="outline" data-size="sm" data-state="on" data-value="light">Light</button>
<button type="button" data-slot="toggle-group-item" data-variant="outline" data-size="sm" data-state="off" data-value="dark">Dark</button>
</div>
</div>
<div>
<p class="font-sans text-xs text-muted-foreground mb-2">Default</p>
<div data-slot="toggle-group" data-variant="outline" data-type="single" role="group" aria-label="Theme (default)">
<button type="button" data-slot="toggle-group-item" data-variant="outline" data-state="off" data-value="system">System</button>
<button type="button" data-slot="toggle-group-item" data-variant="outline" data-state="on" data-value="light">Light</button>
<button type="button" data-slot="toggle-group-item" data-variant="outline" data-state="off" data-value="dark">Dark</button>
</div>
</div>
<div>
<p class="font-sans text-xs text-muted-foreground mb-2">Large</p>
<div data-slot="toggle-group" data-variant="outline" data-type="single" role="group" aria-label="Theme (lg)">
<button type="button" data-slot="toggle-group-item" data-variant="outline" data-size="lg" data-state="off" data-value="system">System</button>
<button type="button" data-slot="toggle-group-item" data-variant="outline" data-size="lg" data-state="on" data-value="light">Light</button>
<button type="button" data-slot="toggle-group-item" data-variant="outline" data-size="lg" data-state="off" data-value="dark">Dark</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Tooltips -->
<div id="sub-tooltips">
<h4 class="font-sans text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-4">
Tooltips
</h4>
<div class="border border-border rounded-md p-6 bg-card">
<div class="flex gap-4">
<button data-slot="button" data-variant="outline" type="button" aria-describedby="" data-state="closed">Hover me</button>
<button data-slot="button" data-variant="secondary" type="button" aria-describedby="" data-state="closed">More info</button>
</div>
</div>
</div>
</div>
</section>
<!-- Section 4: Real-World Examples — 1:1 copy of app/page.tsx Real-World section -->
<section class="mb-16" id="section-realworld">
<div class="mb-8">
<h3 class="font-serif text-3xl font-semibold tracking-tight mb-3">Real-World Examples</h3>
<p class="text-muted-foreground font-sans text-base max-w-2xl">Complete UI patterns demonstrating how components work together in production.</p>
</div>
<div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
<!-- Consultation Form -->
<div id="sub-sample-form">
<h4 class="font-sans text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-4">
Consultation Request Form
</h4>
<div data-slot="card" class="max-w-xl">
<div data-slot="card-header">
<div data-slot="card-title" class="font-serif text-xl">Request a Consultation</div>
<div data-slot="card-description" class="font-sans">
Tell us about your operational requirements. We'll assess whether a contained
AI system can help.
</div>
</div>
<div data-slot="card-content">
<form class="space-y-6" onsubmit="event.preventDefault()">
<!-- Name -->
<div class="space-y-2">
<label for="name" data-slot="label" class="font-sans text-sm font-medium">Full Name</label>
<input id="name" data-slot="input" type="text" placeholder="Enter your name">
</div>
<!-- Email -->
<div class="space-y-2">
<label for="email" data-slot="label" class="font-sans text-sm font-medium">Work Email</label>
<input id="email" data-slot="input" type="email" placeholder="you@company.com">
<p class="font-sans text-xs text-muted-foreground">We'll use this to schedule a call.</p>
</div>
<!-- Organization -->
<div class="space-y-2">
<label for="organization" data-slot="label" class="font-sans text-sm font-medium">Organization</label>
<input id="organization" data-slot="input" type="text" placeholder="Company or team name">
</div>
<!-- Industry -->
<div class="space-y-2">
<label for="industry" data-slot="label" class="font-sans text-sm font-medium">Industry</label>
<button type="button" role="combobox" id="industry" aria-expanded="false" aria-autocomplete="none" dir="ltr" data-state="closed" data-placeholder="" data-slot="select-trigger" data-size="default">
<span data-slot="select-value" style="pointer-events:none">Select your industry</span>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-down size-4 opacity-50"><path d="m6 9 6 6 6-6"/></svg>
</button>
</div>
<!-- Project Description -->
<div class="space-y-2">
<label for="description" data-slot="label" class="font-sans text-sm font-medium">Project Description</label>
<textarea id="description" data-slot="textarea" placeholder="Describe the process or workflow you want to improve. What are the current pain points?" class="min-h-[120px]"></textarea>
<p class="font-sans text-xs text-muted-foreground">Be specific about constraints: data sensitivity, existing systems, compliance requirements.</p>
</div>
<!-- Agreement -->
<div class="flex items-start gap-3">
<button type="button" role="checkbox" aria-checked="false" data-state="unchecked" value="on" class="peer" data-slot="checkbox" id="agreement"></button>
<div class="space-y-1">
<label for="agreement" data-slot="label" class="font-sans text-sm leading-relaxed">I understand that Greyhaven builds custom systems. Initial consultations focus on technical feasibility.</label>
</div>
</div>
<!-- Submit -->
<div class="flex gap-3">
<button type="submit" data-slot="button" disabled>Submit Request</button>
<button type="button" data-slot="button" data-variant="outline">Cancel</button>
</div>
</form>
</div>
</div>
</div>
<!-- Settings Card -->
<div id="sub-settings-card">
<h4 class="font-sans text-sm font-semibold uppercase tracking-wide text-muted-foreground mb-4">
System Settings
</h4>
<div data-slot="card" class="max-w-xl">
<div data-slot="card-header">
<div data-slot="card-title" class="font-serif text-xl">System Configuration</div>
<div data-slot="card-description" class="font-sans">
Configure your contained AI deployment. All settings remain within your environment.
</div>
</div>
<div data-slot="card-content" class="space-y-6">
<!-- Notifications -->
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="flex h-9 w-9 items-center justify-center rounded-md bg-muted">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-bell h-4 w-4 text-muted-foreground"><path d="M10.268 21a2 2 0 0 0 3.464 0"/><path d="M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326"/></svg>
</div>
<div>
<label for="notifications" data-slot="label" class="font-sans text-sm font-medium">System Notifications</label>
<p class="font-sans text-xs text-muted-foreground">Receive alerts for system events and anomalies</p>
</div>
</div>
<button type="button" role="switch" aria-checked="true" data-state="checked" value="on" class="peer" data-slot="switch" id="notifications">
<span data-state="checked" data-slot="switch-thumb" style="pointer-events:none"></span>
</button>
</div>
<div data-orientation="horizontal" role="none" data-slot="separator"></div>
<!-- Audit Logs -->
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="flex h-9 w-9 items-center justify-center rounded-md bg-muted">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-eye h-4 w-4 text-muted-foreground"><path d="M2.062 12.348a1 1 0 0 1 0-.696 10.75 10.75 0 0 1 19.876 0 1 1 0 0 1 0 .696 10.75 10.75 0 0 1-19.876 0"/><circle cx="12" cy="12" r="3"/></svg>
</div>
<div>
<label for="audit-logs" data-slot="label" class="font-sans text-sm font-medium">Audit Logging</label>
<p class="font-sans text-xs text-muted-foreground">Record all system actions for compliance</p>
</div>
</div>
<button type="button" role="switch" aria-checked="true" data-state="checked" value="on" class="peer" data-slot="switch" id="audit-logs">
<span data-state="checked" data-slot="switch-thumb" style="pointer-events:none"></span>
</button>
</div>
<div data-orientation="horizontal" role="none" data-slot="separator"></div>
<!-- Data Retention -->
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="flex h-9 w-9 items-center justify-center rounded-md bg-muted">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-database h-4 w-4 text-muted-foreground"><ellipse cx="12" cy="5" rx="9" ry="3"/><path d="M3 5V19A9 3 0 0 0 21 19V5"/><path d="M3 12A9 3 0 0 0 21 12"/></svg>
</div>
<div>
<label for="data-retention" data-slot="label" class="font-sans text-sm font-medium">Extended Retention</label>
<p class="font-sans text-xs text-muted-foreground">Keep processed data beyond 30 days</p>
</div>
</div>
<button type="button" role="switch" aria-checked="false" data-state="unchecked" value="on" class="peer" data-slot="switch" id="data-retention">
<span data-state="unchecked" data-slot="switch-thumb" style="pointer-events:none"></span>
</button>
</div>
<div data-orientation="horizontal" role="none" data-slot="separator"></div>
<!-- Security Level -->
<div class="flex items-center justify-between">
<div class="flex items-center gap-3">
<div class="flex h-9 w-9 items-center justify-center rounded-md bg-muted">
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-shield h-4 w-4 text-muted-foreground"><path d="M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z"/></svg>
</div>
<div>
<label for="security-level" data-slot="label" class="font-sans text-sm font-medium">Security Profile</label>
<p class="font-sans text-xs text-muted-foreground">Isolation and access control level</p>
</div>
</div>
<button type="button" role="combobox" id="security-level" aria-expanded="false" aria-autocomplete="none" dir="ltr" data-state="closed" data-slot="select-trigger" data-size="default" class="w-32">
<span data-slot="select-value" style="pointer-events:none">Strict</span>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-chevron-down size-4 opacity-50"><path d="m6 9 6 6 6-6"/></svg>
</button>
</div>
<div data-orientation="horizontal" role="none" data-slot="separator"></div>
<!-- Actions -->
<div class="flex gap-3 pt-2">
<button type="button" data-slot="button">Save Changes</button>
<button type="button" data-slot="button" data-variant="outline">Reset to Defaults</button>
</div>
</div>
</div>
</div>
</div>
</section>
</main>
<!-- Footer — mirrors app/page.tsx footer -->
<footer class="border-t border-border py-8 bg-background">
<div class="container mx-auto px-6">
<div class="flex flex-col md:flex-row items-center justify-between gap-4">
<p class="text-sm text-muted-foreground font-sans">
Greyhaven Component Library v1.0
</p>
<div class="flex gap-6 font-sans text-sm">
<a href="https://www.figma.com/slides/4batSeN5uxKYZZhizqOUIt/greyhaven---brand-guidelines?node-id=1-391&t=15wmJ30uBUDhIQXA-1" target="_blank" rel="noopener noreferrer" class="text-muted-foreground hover:text-primary transition-colors">
Brand Guidelines
</a>
<a href="https://github.com/Monadical-SAS" target="_blank" rel="noopener noreferrer" class="text-muted-foreground hover:text-primary transition-colors">
GitHub
</a>
</div>
</div>
</div>
</footer>
</div>
<script>
// Minimal interactive bridge for the static data-slot CSS layer.
// Mirrors Radix's initial render DOM (already emitted on the page) and
// toggles the `data-state` / `aria-*` attributes on user interaction so the
// component CSS transitions into its active/checked/open state. This is the
// JS layer React's Radix primitives would otherwise provide.
//
// Components handled here:
// [data-slot="checkbox"] — click → toggle unchecked ↔ checked
// [data-slot="switch"] — click → toggle unchecked ↔ checked
// [data-slot="tabs-trigger"] — click → activate this tab, deactivate siblings,
// show the matching [data-slot="tabs-content"]
//
// Skipped here (would need popper + portal):
// [data-slot="select-trigger"] — full listbox still requires Alpine/HTMX.
// [data-slot="tooltip-trigger"] — positioning needs a popper solution.
document.addEventListener('click', (e) => {
const el = e.target.closest('[data-slot]');
if (!el || el.disabled) return;
const slot = el.getAttribute('data-slot');
if (slot === 'checkbox') {
const next = el.getAttribute('data-state') === 'checked' ? 'unchecked' : 'checked';
el.setAttribute('data-state', next);
el.setAttribute('aria-checked', next === 'checked' ? 'true' : 'false');
let ind = el.querySelector('[data-slot="checkbox-indicator"]');
if (next === 'checked') {
if (!ind) {
ind = document.createElement('span');
ind.setAttribute('data-slot', 'checkbox-indicator');
ind.setAttribute('style', 'pointer-events:none');
ind.innerHTML = '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="size-3.5"><path d="M20 6 9 17l-5-5"/></svg>';
el.appendChild(ind);
}
ind.setAttribute('data-state', 'checked');
} else if (ind) {
ind.remove();
}
} else if (slot === 'switch') {
const next = el.getAttribute('data-state') === 'checked' ? 'unchecked' : 'checked';
el.setAttribute('data-state', next);
el.setAttribute('aria-checked', next === 'checked' ? 'true' : 'false');
const thumb = el.querySelector('[data-slot="switch-thumb"]');
if (thumb) thumb.setAttribute('data-state', next);
} else if (slot === 'toggle-group-item') {
const group = el.closest('[data-slot="toggle-group"]');
if (!group) return;
const multi = group.getAttribute('data-type') === 'multiple';
const next = el.getAttribute('data-state') === 'on' ? 'off' : 'on';
if (multi) {
el.setAttribute('data-state', next);
} else {
// Single-select: activate this, deactivate siblings. Don't deselect the active one.
group.querySelectorAll('[data-slot="toggle-group-item"]').forEach((it) => {
it.setAttribute('data-state', it === el ? 'on' : 'off');
});
}
} else if (slot === 'tabs-trigger') {
const list = el.closest('[data-slot="tabs-list"]');
const tabs = el.closest('[data-slot="tabs"]');
if (!list || !tabs) return;
list.querySelectorAll('[data-slot="tabs-trigger"]').forEach((t) => {
t.setAttribute('data-state', 'inactive');
t.setAttribute('aria-selected', 'false');
});
el.setAttribute('data-state', 'active');
el.setAttribute('aria-selected', 'true');
const idx = Array.from(list.children).indexOf(el);
const contents = tabs.querySelectorAll('[data-slot="tabs-content"]');
contents.forEach((c, i) => {
const active = i === idx;
c.setAttribute('data-state', active ? 'active' : 'inactive');
if (active) c.removeAttribute('hidden');
else c.setAttribute('hidden', '');
});
}
});
</script>
</body>
</html>