tio-design-make-experiments 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/ATTRIBUTIONS.md +3 -0
- package/README.md +11 -0
- package/guidelines/Guidelines.md +61 -0
- package/index.html +15 -0
- package/package.json +91 -0
- package/postcss.config.mjs +15 -0
- package/src/app/App.tsx +6 -0
- package/src/app/components/design-system/Buttons.tsx +623 -0
- package/src/app/components/design-system/Cards.tsx +123 -0
- package/src/app/components/design-system/Charts.tsx +135 -0
- package/src/app/components/design-system/ColorPalette.tsx +86 -0
- package/src/app/components/design-system/CopyButton.tsx +102 -0
- package/src/app/components/design-system/Forms.tsx +409 -0
- package/src/app/components/design-system/Icons.tsx +140 -0
- package/src/app/components/design-system/ListItems.tsx +234 -0
- package/src/app/components/design-system/Navigation.tsx +344 -0
- package/src/app/components/design-system/Patterns.tsx +235 -0
- package/src/app/components/design-system/PopoverMenu.tsx +81 -0
- package/src/app/components/design-system/SectionHeader.tsx +22 -0
- package/src/app/components/design-system/Spacing.tsx +109 -0
- package/src/app/components/design-system/StatusIndicators.tsx +194 -0
- package/src/app/components/design-system/Typography.tsx +88 -0
- package/src/app/components/figma/ImageWithFallback.tsx +27 -0
- package/src/app/components/ui/accordion.tsx +66 -0
- package/src/app/components/ui/alert-dialog.tsx +157 -0
- package/src/app/components/ui/alert.tsx +66 -0
- package/src/app/components/ui/aspect-ratio.tsx +11 -0
- package/src/app/components/ui/avatar.tsx +53 -0
- package/src/app/components/ui/badge.tsx +46 -0
- package/src/app/components/ui/breadcrumb.tsx +109 -0
- package/src/app/components/ui/button.tsx +58 -0
- package/src/app/components/ui/calendar.tsx +75 -0
- package/src/app/components/ui/card.tsx +92 -0
- package/src/app/components/ui/carousel.tsx +241 -0
- package/src/app/components/ui/chart.tsx +353 -0
- package/src/app/components/ui/checkbox.tsx +32 -0
- package/src/app/components/ui/collapsible.tsx +33 -0
- package/src/app/components/ui/command.tsx +177 -0
- package/src/app/components/ui/context-menu.tsx +252 -0
- package/src/app/components/ui/dialog.tsx +135 -0
- package/src/app/components/ui/drawer.tsx +132 -0
- package/src/app/components/ui/dropdown-menu.tsx +257 -0
- package/src/app/components/ui/form.tsx +168 -0
- package/src/app/components/ui/hover-card.tsx +44 -0
- package/src/app/components/ui/input-otp.tsx +77 -0
- package/src/app/components/ui/input.tsx +21 -0
- package/src/app/components/ui/label.tsx +24 -0
- package/src/app/components/ui/menubar.tsx +276 -0
- package/src/app/components/ui/navigation-menu.tsx +168 -0
- package/src/app/components/ui/pagination.tsx +127 -0
- package/src/app/components/ui/popover.tsx +48 -0
- package/src/app/components/ui/progress.tsx +31 -0
- package/src/app/components/ui/radio-group.tsx +45 -0
- package/src/app/components/ui/resizable.tsx +56 -0
- package/src/app/components/ui/scroll-area.tsx +58 -0
- package/src/app/components/ui/select.tsx +189 -0
- package/src/app/components/ui/separator.tsx +28 -0
- package/src/app/components/ui/sheet.tsx +139 -0
- package/src/app/components/ui/sidebar.tsx +726 -0
- package/src/app/components/ui/skeleton.tsx +13 -0
- package/src/app/components/ui/slider.tsx +63 -0
- package/src/app/components/ui/sonner.tsx +25 -0
- package/src/app/components/ui/switch.tsx +31 -0
- package/src/app/components/ui/table.tsx +116 -0
- package/src/app/components/ui/tabs.tsx +66 -0
- package/src/app/components/ui/textarea.tsx +18 -0
- package/src/app/components/ui/toggle-group.tsx +73 -0
- package/src/app/components/ui/toggle.tsx +47 -0
- package/src/app/components/ui/tooltip.tsx +61 -0
- package/src/app/components/ui/use-mobile.ts +21 -0
- package/src/app/components/ui/utils.ts +6 -0
- package/src/app/pages/DesignSystem.tsx +189 -0
- package/src/app/pages/Team.tsx +168 -0
- package/src/app/routes.tsx +14 -0
- package/src/assets/6276cd19433d265f363bddc7f52f4937da9b1dd4.png +0 -0
- package/src/assets/9d7a018c9a6938d439d9059f82753d232ce63804.png +0 -0
- package/src/imports/Buttons-3-409.tsx +46 -0
- package/src/imports/Buttons-3-962.tsx +155 -0
- package/src/imports/ButtonsAndActions.tsx +139 -0
- package/src/imports/Dashboard.tsx +1914 -0
- package/src/imports/DesignSystem.tsx +6008 -0
- package/src/imports/Forms.tsx +1088 -0
- package/src/imports/Navigation-17-3259.tsx +564 -0
- package/src/imports/Navigation-18-957.tsx +873 -0
- package/src/imports/Wireframe.tsx +112 -0
- package/src/imports/svg-1ifosis1tx.ts +3 -0
- package/src/imports/svg-5spfd.tsx +1 -0
- package/src/imports/svg-6180by7m37.ts +3 -0
- package/src/imports/svg-guy0p.tsx +1 -0
- package/src/imports/svg-hm2n0.tsx +2 -0
- package/src/imports/svg-j8o95ccqq7.ts +26 -0
- package/src/imports/svg-liuy2nykz3.ts +10 -0
- package/src/imports/svg-pp9c3.tsx +1 -0
- package/src/imports/svg-pr0k9194w9.ts +33 -0
- package/src/imports/svg-umftvfphsk.ts +48 -0
- package/src/imports/svg-vbi95q76mb.ts +23 -0
- package/src/imports/svg-vxjpl.tsx +1 -0
- package/src/imports/svg-wl30wxxv53.ts +3 -0
- package/src/main.tsx +7 -0
- package/src/styles/fonts.css +1 -0
- package/src/styles/forms.css +181 -0
- package/src/styles/header.css +48 -0
- package/src/styles/index.css +7 -0
- package/src/styles/navlinks.css +112 -0
- package/src/styles/popover.css +48 -0
- package/src/styles/tailwind.css +4 -0
- package/src/styles/theme.css +312 -0
- package/vite.config.ts +38 -0
|
@@ -0,0 +1,623 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import svgPaths from "../../../imports/svg-umftvfphsk";
|
|
3
|
+
import figmaSvg from "../../../imports/svg-1ifosis1tx";
|
|
4
|
+
import { SectionHeader } from "./SectionHeader";
|
|
5
|
+
import { CopyButton } from "./CopyButton";
|
|
6
|
+
|
|
7
|
+
/* ─── Icon helpers ─── */
|
|
8
|
+
function CheckCircleIcon({ className = "fill-primary-foreground" }: { className?: string }) {
|
|
9
|
+
return (
|
|
10
|
+
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" className="shrink-0">
|
|
11
|
+
<path d={figmaSvg.p2819d400} className={className} />
|
|
12
|
+
</svg>
|
|
13
|
+
);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function PlusIcon({ className = "fill-primary-foreground" }: { className?: string }) {
|
|
17
|
+
return (
|
|
18
|
+
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" className="shrink-0">
|
|
19
|
+
<path d={svgPaths.p185c8f80} className={className} />
|
|
20
|
+
</svg>
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function MoreIcon({ className = "fill-muted-foreground" }: { className?: string }) {
|
|
25
|
+
return (
|
|
26
|
+
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" className="shrink-0">
|
|
27
|
+
<path d={svgPaths.p5e64f80} className={className} />
|
|
28
|
+
</svg>
|
|
29
|
+
);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function TriangleLeftIcon({ className = "fill-muted-foreground" }: { className?: string }) {
|
|
33
|
+
return (
|
|
34
|
+
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" className="shrink-0">
|
|
35
|
+
<path d="M15 16L5 10L15 4V16Z" className={className} />
|
|
36
|
+
</svg>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/* ─── State card wrapper ─── */
|
|
41
|
+
function StateCard({
|
|
42
|
+
state,
|
|
43
|
+
classes,
|
|
44
|
+
children,
|
|
45
|
+
}: {
|
|
46
|
+
state: string;
|
|
47
|
+
classes: string;
|
|
48
|
+
children: React.ReactNode;
|
|
49
|
+
}) {
|
|
50
|
+
return (
|
|
51
|
+
<div className="group/state bg-card rounded-xl p-5 flex flex-col gap-4 relative min-w-0">
|
|
52
|
+
<div className="absolute top-2 right-2 opacity-0 group-hover/state:opacity-100 transition-opacity z-10">
|
|
53
|
+
<CopyButton token={classes} />
|
|
54
|
+
</div>
|
|
55
|
+
<span className="font-['Source_Sans_3',sans-serif] text-[11px] text-muted-foreground uppercase tracking-wider">
|
|
56
|
+
{state}
|
|
57
|
+
</span>
|
|
58
|
+
<div className="flex items-center justify-center min-h-12 pointer-events-none">
|
|
59
|
+
{children}
|
|
60
|
+
</div>
|
|
61
|
+
<div className="pt-3 border-t border-border">
|
|
62
|
+
<p className="font-['Source_Sans_3',sans-serif] text-[11px] text-muted-foreground/60 font-mono leading-tight break-all">
|
|
63
|
+
{classes}
|
|
64
|
+
</p>
|
|
65
|
+
</div>
|
|
66
|
+
</div>
|
|
67
|
+
);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/* ─── Sub-section heading ─── */
|
|
71
|
+
function SubSection({
|
|
72
|
+
title,
|
|
73
|
+
description,
|
|
74
|
+
children,
|
|
75
|
+
}: {
|
|
76
|
+
title: string;
|
|
77
|
+
description?: string;
|
|
78
|
+
children: React.ReactNode;
|
|
79
|
+
}) {
|
|
80
|
+
return (
|
|
81
|
+
<div className="mb-12">
|
|
82
|
+
<div className="mb-4">
|
|
83
|
+
<p className="font-['Source_Sans_3',sans-serif] text-[14px] text-muted-foreground uppercase tracking-wider">
|
|
84
|
+
{title}
|
|
85
|
+
</p>
|
|
86
|
+
{description && (
|
|
87
|
+
<p className="font-['Source_Sans_3',sans-serif] text-[12px] text-muted-foreground/60 mt-1">
|
|
88
|
+
{description}
|
|
89
|
+
</p>
|
|
90
|
+
)}
|
|
91
|
+
</div>
|
|
92
|
+
{children}
|
|
93
|
+
</div>
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/* ════════════════════════════════════════════════════
|
|
98
|
+
Main export
|
|
99
|
+
════════════════════════════════════════════════════ */
|
|
100
|
+
export function Buttons() {
|
|
101
|
+
return (
|
|
102
|
+
<section>
|
|
103
|
+
<SectionHeader
|
|
104
|
+
title="Buttons"
|
|
105
|
+
description="All button variants, interactive states, and their corresponding class tokens"
|
|
106
|
+
/>
|
|
107
|
+
|
|
108
|
+
{/* ──────── 1. PRIMARY FILLED ──────── */}
|
|
109
|
+
<SubSection
|
|
110
|
+
title="Primary Filled · .btn-primary"
|
|
111
|
+
description="Main CTA — bg-primary + text-primary-foreground, pill shape. Hover transforms to bg-link-hover + text-link-hover-foreground."
|
|
112
|
+
>
|
|
113
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 gap-4">
|
|
114
|
+
<StateCard state="Default" classes="btn-primary">
|
|
115
|
+
<button className="btn-primary">
|
|
116
|
+
<CheckCircleIcon className="fill-primary-foreground" />
|
|
117
|
+
<span>Primary</span>
|
|
118
|
+
</button>
|
|
119
|
+
</StateCard>
|
|
120
|
+
|
|
121
|
+
<StateCard state="Hover" classes="hover:bg-link-hover hover:text-link-hover-foreground">
|
|
122
|
+
<button className="btn bg-link-hover text-link-hover-foreground h-10 px-5 rounded-full">
|
|
123
|
+
<CheckCircleIcon className="fill-link-hover-foreground" />
|
|
124
|
+
<span>Hover</span>
|
|
125
|
+
</button>
|
|
126
|
+
</StateCard>
|
|
127
|
+
|
|
128
|
+
<StateCard state="Active / Pressed" classes="active:bg-link-hover/90 active:scale-[0.98]">
|
|
129
|
+
<button className="btn bg-link-hover/90 text-link-hover-foreground h-10 px-5 rounded-full scale-[0.98]">
|
|
130
|
+
<CheckCircleIcon className="fill-link-hover-foreground" />
|
|
131
|
+
<span>Pressed</span>
|
|
132
|
+
</button>
|
|
133
|
+
</StateCard>
|
|
134
|
+
|
|
135
|
+
<StateCard state="Focus" classes="focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background outline-none">
|
|
136
|
+
<button className="btn bg-primary text-primary-foreground h-10 px-5 rounded-full ring-2 ring-ring ring-offset-2 ring-offset-background">
|
|
137
|
+
<CheckCircleIcon className="fill-primary-foreground" />
|
|
138
|
+
<span>Focus</span>
|
|
139
|
+
</button>
|
|
140
|
+
</StateCard>
|
|
141
|
+
|
|
142
|
+
<StateCard state="Disabled" classes="disabled:opacity-50 disabled:cursor-not-allowed">
|
|
143
|
+
<button disabled className="btn-primary opacity-50 cursor-not-allowed">
|
|
144
|
+
<CheckCircleIcon className="fill-primary-foreground" />
|
|
145
|
+
<span>Disabled</span>
|
|
146
|
+
</button>
|
|
147
|
+
</StateCard>
|
|
148
|
+
</div>
|
|
149
|
+
</SubSection>
|
|
150
|
+
|
|
151
|
+
{/* ──────── 2. PRIMARY FILLED — no icon ──────── */}
|
|
152
|
+
<SubSection
|
|
153
|
+
title="Primary Filled — Text Only · .btn-primary"
|
|
154
|
+
description="Same pill CTA without an icon prefix."
|
|
155
|
+
>
|
|
156
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 gap-4">
|
|
157
|
+
<StateCard state="Default" classes="btn-primary">
|
|
158
|
+
<button className="btn-primary">
|
|
159
|
+
<span>Re-run check</span>
|
|
160
|
+
</button>
|
|
161
|
+
</StateCard>
|
|
162
|
+
|
|
163
|
+
<StateCard state="Hover" classes="hover:bg-link-hover hover:text-link-hover-foreground">
|
|
164
|
+
<button className="btn bg-link-hover text-link-hover-foreground h-10 px-5 rounded-full">
|
|
165
|
+
<span>Re-run check</span>
|
|
166
|
+
</button>
|
|
167
|
+
</StateCard>
|
|
168
|
+
|
|
169
|
+
<StateCard state="Active / Pressed" classes="active:bg-link-hover/90 active:scale-[0.98]">
|
|
170
|
+
<button className="btn bg-link-hover/90 text-link-hover-foreground h-10 px-5 rounded-full scale-[0.98]">
|
|
171
|
+
<span>Re-run check</span>
|
|
172
|
+
</button>
|
|
173
|
+
</StateCard>
|
|
174
|
+
|
|
175
|
+
<StateCard state="Focus" classes="focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background outline-none">
|
|
176
|
+
<button className="btn bg-primary text-primary-foreground h-10 px-5 rounded-full ring-2 ring-ring ring-offset-2 ring-offset-background">
|
|
177
|
+
<span>Re-run check</span>
|
|
178
|
+
</button>
|
|
179
|
+
</StateCard>
|
|
180
|
+
|
|
181
|
+
<StateCard state="Disabled" classes="disabled:opacity-50 disabled:cursor-not-allowed">
|
|
182
|
+
<button disabled className="btn-primary opacity-50 cursor-not-allowed">
|
|
183
|
+
<span>Re-run check</span>
|
|
184
|
+
</button>
|
|
185
|
+
</StateCard>
|
|
186
|
+
</div>
|
|
187
|
+
</SubSection>
|
|
188
|
+
|
|
189
|
+
{/* ──────── 3. OUTLINE PRIMARY ──────── */}
|
|
190
|
+
<SubSection
|
|
191
|
+
title="Outline — Primary · .btn-outline-primary"
|
|
192
|
+
description="border-primary + text-primary on transparent. Hover transforms to solid bg-link-hover."
|
|
193
|
+
>
|
|
194
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 gap-4">
|
|
195
|
+
<StateCard state="Default" classes="btn-outline-primary">
|
|
196
|
+
<button className="btn-outline-primary">
|
|
197
|
+
<CheckCircleIcon className="fill-primary" />
|
|
198
|
+
<span>Primary</span>
|
|
199
|
+
</button>
|
|
200
|
+
</StateCard>
|
|
201
|
+
|
|
202
|
+
<StateCard state="Hover" classes="hover:bg-link-hover hover:text-link-hover-foreground hover:border-transparent">
|
|
203
|
+
<button className="btn bg-link-hover text-link-hover-foreground h-10 px-5 rounded-full">
|
|
204
|
+
<CheckCircleIcon className="fill-link-hover-foreground" />
|
|
205
|
+
<span>Hover</span>
|
|
206
|
+
</button>
|
|
207
|
+
</StateCard>
|
|
208
|
+
|
|
209
|
+
<StateCard state="Active / Pressed" classes="active:bg-link-hover/90 active:border-transparent active:scale-[0.98]">
|
|
210
|
+
<button className="btn bg-link-hover/90 text-link-hover-foreground h-10 px-5 rounded-full scale-[0.98]">
|
|
211
|
+
<CheckCircleIcon className="fill-link-hover-foreground" />
|
|
212
|
+
<span>Pressed</span>
|
|
213
|
+
</button>
|
|
214
|
+
</StateCard>
|
|
215
|
+
|
|
216
|
+
<StateCard state="Focus" classes="focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background outline-none">
|
|
217
|
+
<button className="btn border border-primary text-primary h-10 px-5 rounded-full ring-2 ring-ring ring-offset-2 ring-offset-background">
|
|
218
|
+
<CheckCircleIcon className="fill-primary" />
|
|
219
|
+
<span>Focus</span>
|
|
220
|
+
</button>
|
|
221
|
+
</StateCard>
|
|
222
|
+
|
|
223
|
+
<StateCard state="Disabled" classes="disabled:opacity-50 disabled:cursor-not-allowed">
|
|
224
|
+
<button disabled className="btn-outline-primary opacity-50 cursor-not-allowed">
|
|
225
|
+
<CheckCircleIcon className="fill-primary" />
|
|
226
|
+
<span>Disabled</span>
|
|
227
|
+
</button>
|
|
228
|
+
</StateCard>
|
|
229
|
+
</div>
|
|
230
|
+
</SubSection>
|
|
231
|
+
|
|
232
|
+
{/* ──────── 4. OUTLINE MUTED ──────── */}
|
|
233
|
+
<SubSection
|
|
234
|
+
title="Outline — Muted · .btn-outline-muted"
|
|
235
|
+
description="border-border + text-primary, rounded-lg shape. Hover transforms to solid bg-link-hover."
|
|
236
|
+
>
|
|
237
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 gap-4">
|
|
238
|
+
<StateCard state="Default" classes="btn-outline-muted">
|
|
239
|
+
<button className="btn-outline-muted">
|
|
240
|
+
<span>Re-run test</span>
|
|
241
|
+
</button>
|
|
242
|
+
</StateCard>
|
|
243
|
+
|
|
244
|
+
<StateCard state="Hover" classes="hover:bg-link-hover hover:text-link-hover-foreground hover:border-transparent">
|
|
245
|
+
<button className="btn bg-link-hover text-link-hover-foreground h-10 px-5 rounded-lg">
|
|
246
|
+
<span>Re-run test</span>
|
|
247
|
+
</button>
|
|
248
|
+
</StateCard>
|
|
249
|
+
|
|
250
|
+
<StateCard state="Active / Pressed" classes="active:bg-link-hover/90 active:border-transparent active:scale-[0.98]">
|
|
251
|
+
<button className="btn bg-link-hover/90 text-link-hover-foreground h-10 px-5 rounded-lg scale-[0.98]">
|
|
252
|
+
<span>Re-run test</span>
|
|
253
|
+
</button>
|
|
254
|
+
</StateCard>
|
|
255
|
+
|
|
256
|
+
<StateCard state="Focus" classes="focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background outline-none">
|
|
257
|
+
<button className="btn border border-border text-primary h-10 px-5 rounded-lg ring-2 ring-ring ring-offset-2 ring-offset-background">
|
|
258
|
+
<span>Re-run test</span>
|
|
259
|
+
</button>
|
|
260
|
+
</StateCard>
|
|
261
|
+
|
|
262
|
+
<StateCard state="Disabled" classes="disabled:opacity-50 disabled:cursor-not-allowed">
|
|
263
|
+
<button disabled className="btn-outline-muted opacity-50 cursor-not-allowed">
|
|
264
|
+
<span>Re-run test</span>
|
|
265
|
+
</button>
|
|
266
|
+
</StateCard>
|
|
267
|
+
</div>
|
|
268
|
+
</SubSection>
|
|
269
|
+
|
|
270
|
+
{/* ──────── 5. ICON BUTTON — Circular ──────── */}
|
|
271
|
+
<SubSection
|
|
272
|
+
title="Icon Button — Circular · .btn-icon"
|
|
273
|
+
description="border-muted-foreground, rounded-full. Hover transforms to solid bg-link-hover."
|
|
274
|
+
>
|
|
275
|
+
<div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-4">
|
|
276
|
+
<StateCard state="Default" classes="btn-icon">
|
|
277
|
+
<button className="btn-icon">
|
|
278
|
+
<MoreIcon />
|
|
279
|
+
</button>
|
|
280
|
+
</StateCard>
|
|
281
|
+
|
|
282
|
+
<StateCard state="Hover" classes="hover:bg-link-hover hover:border-transparent">
|
|
283
|
+
<button className="btn bg-link-hover size-10 rounded-full">
|
|
284
|
+
<MoreIcon className="fill-link-hover-foreground" />
|
|
285
|
+
</button>
|
|
286
|
+
</StateCard>
|
|
287
|
+
|
|
288
|
+
<StateCard state="Active / Pressed" classes="active:bg-link-hover/90 active:border-transparent active:scale-95">
|
|
289
|
+
<button className="btn bg-link-hover/90 size-10 rounded-full scale-95">
|
|
290
|
+
<MoreIcon className="fill-link-hover-foreground" />
|
|
291
|
+
</button>
|
|
292
|
+
</StateCard>
|
|
293
|
+
|
|
294
|
+
<StateCard state="Focus" classes="focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background outline-none">
|
|
295
|
+
<button className="btn border border-muted-foreground size-10 rounded-full ring-2 ring-ring ring-offset-2 ring-offset-background">
|
|
296
|
+
<MoreIcon />
|
|
297
|
+
</button>
|
|
298
|
+
</StateCard>
|
|
299
|
+
|
|
300
|
+
<StateCard state="Disabled" classes="disabled:opacity-40 disabled:cursor-not-allowed">
|
|
301
|
+
<button disabled className="btn-icon opacity-40 cursor-not-allowed">
|
|
302
|
+
<MoreIcon />
|
|
303
|
+
</button>
|
|
304
|
+
</StateCard>
|
|
305
|
+
</div>
|
|
306
|
+
</SubSection>
|
|
307
|
+
|
|
308
|
+
{/* ──────── 6. GHOST BUTTON ──────── */}
|
|
309
|
+
<SubSection
|
|
310
|
+
title="Ghost Button · .btn-ghost"
|
|
311
|
+
description="No border or background, text-muted-foreground. Hover shows bg-link-hover."
|
|
312
|
+
>
|
|
313
|
+
<div className="grid grid-cols-2 sm:grid-cols-3 lg:grid-cols-5 gap-4">
|
|
314
|
+
<StateCard state="Default" classes="btn-ghost">
|
|
315
|
+
<button className="btn-ghost">
|
|
316
|
+
<TriangleLeftIcon />
|
|
317
|
+
</button>
|
|
318
|
+
</StateCard>
|
|
319
|
+
|
|
320
|
+
<StateCard state="Hover" classes="hover:bg-link-hover hover:text-link-hover-foreground">
|
|
321
|
+
<button className="btn bg-link-hover size-10 rounded-md">
|
|
322
|
+
<TriangleLeftIcon className="fill-link-hover-foreground" />
|
|
323
|
+
</button>
|
|
324
|
+
</StateCard>
|
|
325
|
+
|
|
326
|
+
<StateCard state="Active / Pressed" classes="active:bg-link-hover/90 active:scale-95">
|
|
327
|
+
<button className="btn bg-link-hover/90 size-10 rounded-md scale-95">
|
|
328
|
+
<TriangleLeftIcon className="fill-link-hover-foreground" />
|
|
329
|
+
</button>
|
|
330
|
+
</StateCard>
|
|
331
|
+
|
|
332
|
+
<StateCard state="Focus" classes="focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background outline-none rounded-md">
|
|
333
|
+
<button className="btn size-10 rounded-md ring-2 ring-ring ring-offset-2 ring-offset-background">
|
|
334
|
+
<TriangleLeftIcon />
|
|
335
|
+
</button>
|
|
336
|
+
</StateCard>
|
|
337
|
+
|
|
338
|
+
<StateCard state="Disabled" classes="disabled:opacity-30 disabled:cursor-not-allowed">
|
|
339
|
+
<button disabled className="btn-ghost opacity-30 cursor-not-allowed">
|
|
340
|
+
<TriangleLeftIcon />
|
|
341
|
+
</button>
|
|
342
|
+
</StateCard>
|
|
343
|
+
</div>
|
|
344
|
+
</SubSection>
|
|
345
|
+
|
|
346
|
+
{/* ──────── 7. NAV CTA ──────── */}
|
|
347
|
+
<SubSection
|
|
348
|
+
title="Navigation CTA · .btn-nav-cta"
|
|
349
|
+
description="Header bar primary action — bg-primary, compact pill. Hover transforms to bg-link-hover."
|
|
350
|
+
>
|
|
351
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-5 gap-4">
|
|
352
|
+
<StateCard state="Default" classes="btn-nav-cta">
|
|
353
|
+
<button className="btn-nav-cta">
|
|
354
|
+
<PlusIcon className="fill-primary-foreground" />
|
|
355
|
+
<span>New Test Session</span>
|
|
356
|
+
</button>
|
|
357
|
+
</StateCard>
|
|
358
|
+
|
|
359
|
+
<StateCard state="Hover" classes="hover:bg-link-hover hover:text-link-hover-foreground">
|
|
360
|
+
<button className="btn bg-link-hover text-link-hover-foreground px-4 rounded-full" style={{ height: "2.125rem" }}>
|
|
361
|
+
<PlusIcon className="fill-link-hover-foreground" />
|
|
362
|
+
<span>New Test Session</span>
|
|
363
|
+
</button>
|
|
364
|
+
</StateCard>
|
|
365
|
+
|
|
366
|
+
<StateCard state="Active / Pressed" classes="active:bg-link-hover/90 active:scale-[0.98]">
|
|
367
|
+
<button className="btn bg-link-hover/90 text-link-hover-foreground px-4 rounded-full scale-[0.98]" style={{ height: "2.125rem" }}>
|
|
368
|
+
<PlusIcon className="fill-link-hover-foreground" />
|
|
369
|
+
<span>New Test Session</span>
|
|
370
|
+
</button>
|
|
371
|
+
</StateCard>
|
|
372
|
+
|
|
373
|
+
<StateCard state="Focus" classes="focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background outline-none">
|
|
374
|
+
<button className="btn-nav-cta ring-2 ring-ring ring-offset-2 ring-offset-background">
|
|
375
|
+
<PlusIcon className="fill-primary-foreground" />
|
|
376
|
+
<span>New Test Session</span>
|
|
377
|
+
</button>
|
|
378
|
+
</StateCard>
|
|
379
|
+
|
|
380
|
+
<StateCard state="Disabled" classes="disabled:opacity-50 disabled:cursor-not-allowed">
|
|
381
|
+
<button disabled className="btn-nav-cta opacity-50 cursor-not-allowed">
|
|
382
|
+
<PlusIcon className="fill-primary-foreground" />
|
|
383
|
+
<span>New Test Session</span>
|
|
384
|
+
</button>
|
|
385
|
+
</StateCard>
|
|
386
|
+
</div>
|
|
387
|
+
</SubSection>
|
|
388
|
+
|
|
389
|
+
{/* ──────── 8. XL ACTION CARDS ──────── */}
|
|
390
|
+
<SubSection
|
|
391
|
+
title="XL Action Cards"
|
|
392
|
+
description="Large card-sized buttons for empty-state and workflow CTAs."
|
|
393
|
+
>
|
|
394
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
|
395
|
+
<StateCard state="XL Outline — Default" classes="w-56">
|
|
396
|
+
<button className="btn-xl-outline w-full">
|
|
397
|
+
<div className="pb-4">
|
|
398
|
+
<svg width="60" height="60" viewBox="0 0 60 60" fill="none">
|
|
399
|
+
<g clipPath="url(#clip_xl_plus_d)">
|
|
400
|
+
<path d={svgPaths.p2455100} fill="currentColor" />
|
|
401
|
+
</g>
|
|
402
|
+
<defs>
|
|
403
|
+
<clipPath id="clip_xl_plus_d"><rect fill="white" height="60" width="60" /></clipPath>
|
|
404
|
+
</defs>
|
|
405
|
+
</svg>
|
|
406
|
+
</div>
|
|
407
|
+
<span>Create New Test Session</span>
|
|
408
|
+
</button>
|
|
409
|
+
</StateCard>
|
|
410
|
+
|
|
411
|
+
<StateCard state="XL Filled — Default" classes="w-56">
|
|
412
|
+
<button className="btn-xl-filled w-full">
|
|
413
|
+
<div className="pb-4">
|
|
414
|
+
<svg width="60" height="60" viewBox="0 0 60 60" fill="none">
|
|
415
|
+
<g clipPath="url(#clip_xl_run_d)">
|
|
416
|
+
<path d={svgPaths.p2af2dd00} fill="currentColor" />
|
|
417
|
+
</g>
|
|
418
|
+
<defs>
|
|
419
|
+
<clipPath id="clip_xl_run_d"><rect fill="white" height="60" width="60" /></clipPath>
|
|
420
|
+
</defs>
|
|
421
|
+
</svg>
|
|
422
|
+
</div>
|
|
423
|
+
<span>Start test</span>
|
|
424
|
+
</button>
|
|
425
|
+
</StateCard>
|
|
426
|
+
|
|
427
|
+
<StateCard state="XL — Disabled" classes="w-56">
|
|
428
|
+
<button className="btn-xl-outline w-full" disabled>
|
|
429
|
+
<div className="pb-4">
|
|
430
|
+
<svg width="48" height="60" viewBox="0 0 48 60" fill="none">
|
|
431
|
+
<g clipPath="url(#clip_xl_rev_dis)">
|
|
432
|
+
<path d={svgPaths.p1981c800} fill="currentColor" />
|
|
433
|
+
</g>
|
|
434
|
+
<defs>
|
|
435
|
+
<clipPath id="clip_xl_rev_dis"><rect fill="white" height="60" width="48" /></clipPath>
|
|
436
|
+
</defs>
|
|
437
|
+
</svg>
|
|
438
|
+
</div>
|
|
439
|
+
<span>Show report</span>
|
|
440
|
+
</button>
|
|
441
|
+
</StateCard>
|
|
442
|
+
</div>
|
|
443
|
+
</SubSection>
|
|
444
|
+
|
|
445
|
+
{/* ──────── 9. INTERACTIVE DEMO ──────── */}
|
|
446
|
+
<SubSection
|
|
447
|
+
title="Interactive Demo"
|
|
448
|
+
description="Live buttons using the CSS component classes. Hover to see the --link-hover transformation."
|
|
449
|
+
>
|
|
450
|
+
<div className="bg-card rounded-2xl p-8">
|
|
451
|
+
<p className="font-['Source_Sans_3',sans-serif] text-[12px] text-muted-foreground/60 uppercase tracking-wider mb-6">
|
|
452
|
+
Try interacting with these buttons
|
|
453
|
+
</p>
|
|
454
|
+
<div className="flex flex-wrap gap-4 items-center">
|
|
455
|
+
<button className="btn-primary hover:[&_svg_path]:fill-link-hover-foreground">
|
|
456
|
+
<CheckCircleIcon className="fill-primary-foreground transition-colors duration-200" />
|
|
457
|
+
<span>Primary Filled</span>
|
|
458
|
+
</button>
|
|
459
|
+
|
|
460
|
+
<button className="btn-primary">
|
|
461
|
+
<span>Text Only</span>
|
|
462
|
+
</button>
|
|
463
|
+
|
|
464
|
+
<button className="btn-outline-primary hover:[&_svg_path]:fill-link-hover-foreground">
|
|
465
|
+
<CheckCircleIcon className="fill-primary transition-colors duration-200" />
|
|
466
|
+
<span>Outline Primary</span>
|
|
467
|
+
</button>
|
|
468
|
+
|
|
469
|
+
<button className="btn-outline-muted">
|
|
470
|
+
<span>Outline Muted</span>
|
|
471
|
+
</button>
|
|
472
|
+
|
|
473
|
+
<button className="btn-icon hover:[&_svg_path]:fill-link-hover-foreground">
|
|
474
|
+
<MoreIcon className="transition-colors duration-200" />
|
|
475
|
+
</button>
|
|
476
|
+
|
|
477
|
+
<button className="btn-ghost hover:[&_svg_path]:fill-link-hover-foreground">
|
|
478
|
+
<TriangleLeftIcon className="transition-colors duration-200" />
|
|
479
|
+
</button>
|
|
480
|
+
|
|
481
|
+
<button disabled className="btn-primary">
|
|
482
|
+
<span>Disabled</span>
|
|
483
|
+
</button>
|
|
484
|
+
</div>
|
|
485
|
+
</div>
|
|
486
|
+
</SubSection>
|
|
487
|
+
|
|
488
|
+
{/* ──────── 10. CLASS REFERENCE TABLE ──────── */}
|
|
489
|
+
<SubSection
|
|
490
|
+
title="Quick Reference"
|
|
491
|
+
description="CSS component classes and their state tokens — all hover states use --link-hover."
|
|
492
|
+
>
|
|
493
|
+
<div className="overflow-x-auto">
|
|
494
|
+
<table className="w-full border-collapse">
|
|
495
|
+
<thead>
|
|
496
|
+
<tr className="border-b border-border">
|
|
497
|
+
{["Variant", "CSS Class", "Hover", "Active", "Focus", "Disabled"].map(
|
|
498
|
+
(h) => (
|
|
499
|
+
<th
|
|
500
|
+
key={h}
|
|
501
|
+
className="font-['Source_Sans_3',sans-serif] text-[11px] text-muted-foreground uppercase tracking-wider py-3 px-3 text-left"
|
|
502
|
+
style={{ fontWeight: 600 }}
|
|
503
|
+
>
|
|
504
|
+
{h}
|
|
505
|
+
</th>
|
|
506
|
+
),
|
|
507
|
+
)}
|
|
508
|
+
</tr>
|
|
509
|
+
</thead>
|
|
510
|
+
<tbody>
|
|
511
|
+
{[
|
|
512
|
+
{
|
|
513
|
+
variant: "Primary Filled",
|
|
514
|
+
cssClass: ".btn-primary",
|
|
515
|
+
hover: "hover:bg-link-hover hover:text-link-hover-foreground",
|
|
516
|
+
active: "active:bg-link-hover/90 active:scale-[0.98]",
|
|
517
|
+
focus: "focus-visible:ring-2 ring-ring",
|
|
518
|
+
disabled: "disabled:opacity-50",
|
|
519
|
+
},
|
|
520
|
+
{
|
|
521
|
+
variant: "Outline Primary",
|
|
522
|
+
cssClass: ".btn-outline-primary",
|
|
523
|
+
hover: "hover:bg-link-hover hover:text-link-hover-foreground hover:border-transparent",
|
|
524
|
+
active: "active:bg-link-hover/90 active:scale-[0.98]",
|
|
525
|
+
focus: "focus-visible:ring-2 ring-ring",
|
|
526
|
+
disabled: "disabled:opacity-50",
|
|
527
|
+
},
|
|
528
|
+
{
|
|
529
|
+
variant: "Outline Muted",
|
|
530
|
+
cssClass: ".btn-outline-muted",
|
|
531
|
+
hover: "hover:bg-link-hover hover:text-link-hover-foreground hover:border-transparent",
|
|
532
|
+
active: "active:bg-link-hover/90 active:scale-[0.98]",
|
|
533
|
+
focus: "focus-visible:ring-2 ring-ring",
|
|
534
|
+
disabled: "disabled:opacity-50",
|
|
535
|
+
},
|
|
536
|
+
{
|
|
537
|
+
variant: "Icon Circle",
|
|
538
|
+
cssClass: ".btn-icon",
|
|
539
|
+
hover: "hover:bg-link-hover hover:border-transparent",
|
|
540
|
+
active: "active:bg-link-hover/90 active:scale-95",
|
|
541
|
+
focus: "focus-visible:ring-2 ring-ring",
|
|
542
|
+
disabled: "disabled:opacity-40",
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
variant: "Ghost",
|
|
546
|
+
cssClass: ".btn-ghost",
|
|
547
|
+
hover: "hover:bg-link-hover hover:text-link-hover-foreground",
|
|
548
|
+
active: "active:bg-link-hover/90 active:scale-95",
|
|
549
|
+
focus: "focus-visible:ring-2 ring-ring",
|
|
550
|
+
disabled: "disabled:opacity-30",
|
|
551
|
+
},
|
|
552
|
+
{
|
|
553
|
+
variant: "Nav CTA",
|
|
554
|
+
cssClass: ".btn-nav-cta",
|
|
555
|
+
hover: "hover:bg-link-hover hover:text-link-hover-foreground",
|
|
556
|
+
active: "active:bg-link-hover/90 active:scale-[0.98]",
|
|
557
|
+
focus: "focus-visible:ring-2 ring-ring",
|
|
558
|
+
disabled: "disabled:opacity-50",
|
|
559
|
+
},
|
|
560
|
+
].map((row) => (
|
|
561
|
+
<tr
|
|
562
|
+
key={row.variant}
|
|
563
|
+
className="border-b border-secondary group/row"
|
|
564
|
+
>
|
|
565
|
+
<td className="font-['Source_Sans_3',sans-serif] text-[13px] text-foreground py-3 px-3 whitespace-nowrap">
|
|
566
|
+
{row.variant}
|
|
567
|
+
</td>
|
|
568
|
+
{[row.cssClass, row.hover, row.active, row.focus, row.disabled].map(
|
|
569
|
+
(val, i) => (
|
|
570
|
+
<td key={i} className="py-3 px-3">
|
|
571
|
+
<div className="flex items-center gap-1.5">
|
|
572
|
+
<code className="font-mono text-[11px] text-primary/80 bg-secondary px-2 py-0.5 rounded-sm">
|
|
573
|
+
{val}
|
|
574
|
+
</code>
|
|
575
|
+
<div className="opacity-0 group-hover/row:opacity-100 transition-opacity">
|
|
576
|
+
<CopyButton token={val} />
|
|
577
|
+
</div>
|
|
578
|
+
</div>
|
|
579
|
+
</td>
|
|
580
|
+
),
|
|
581
|
+
)}
|
|
582
|
+
</tr>
|
|
583
|
+
))}
|
|
584
|
+
</tbody>
|
|
585
|
+
</table>
|
|
586
|
+
</div>
|
|
587
|
+
|
|
588
|
+
{/* Variable reference */}
|
|
589
|
+
<div className="mt-6 bg-card rounded-xl p-5">
|
|
590
|
+
<p className="font-['Source_Sans_3',sans-serif] text-[11px] text-muted-foreground uppercase tracking-wider mb-3">
|
|
591
|
+
CSS Variables Used
|
|
592
|
+
</p>
|
|
593
|
+
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-3">
|
|
594
|
+
{[
|
|
595
|
+
{ name: "--link-hover", value: "#7954ff", desc: "Hover background for all buttons" },
|
|
596
|
+
{ name: "--link-hover-foreground", value: "#ffffff", desc: "Hover text/icon color" },
|
|
597
|
+
{ name: "--primary", value: "#78eac1", desc: "Default button background" },
|
|
598
|
+
{ name: "--primary-foreground", value: "#1d1d1d", desc: "Default button text on primary" },
|
|
599
|
+
{ name: "--border", value: "#2e2e2e", desc: "Muted outline border" },
|
|
600
|
+
{ name: "--ring", value: "#7954ff", desc: "Focus ring color" },
|
|
601
|
+
].map(({ name, value, desc }) => (
|
|
602
|
+
<div key={name} className="group/var flex items-start gap-3 bg-secondary/50 rounded-lg px-3 py-2">
|
|
603
|
+
<div
|
|
604
|
+
className="size-5 rounded-sm shrink-0 mt-0.5 border border-border"
|
|
605
|
+
style={{ backgroundColor: value }}
|
|
606
|
+
/>
|
|
607
|
+
<div className="min-w-0 flex-1">
|
|
608
|
+
<div className="flex items-center gap-1.5">
|
|
609
|
+
<code className="font-mono text-[12px] text-primary">{name}</code>
|
|
610
|
+
<div className="opacity-0 group-hover/var:opacity-100 transition-opacity">
|
|
611
|
+
<CopyButton token={name} />
|
|
612
|
+
</div>
|
|
613
|
+
</div>
|
|
614
|
+
<p className="font-['Source_Sans_3',sans-serif] text-[11px] text-muted-foreground/60">{desc}</p>
|
|
615
|
+
</div>
|
|
616
|
+
</div>
|
|
617
|
+
))}
|
|
618
|
+
</div>
|
|
619
|
+
</div>
|
|
620
|
+
</SubSection>
|
|
621
|
+
</section>
|
|
622
|
+
);
|
|
623
|
+
}
|