velloo 0.0.0 → 0.2.0
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/BUN-LICENSE.md +91 -0
- package/LICENSE +202 -0
- package/NOTICE +9 -0
- package/README.md +288 -2
- package/THIRD-PARTY-NOTICES.md +467 -0
- package/assets/elsewhere-alps-9fqhv029.jpg +0 -0
- package/assets/elsewhere-bali-vp60g115.jpg +0 -0
- package/assets/elsewhere-forest-xgn23zrj.jpg +0 -0
- package/assets/elsewhere-japan-qs7qkbr2.jpg +0 -0
- package/assets/elsewhere-kyoto-map-n2bvkrya.svg +1 -0
- package/assets/elsewhere-kyoto-qemtn6nk.jpg +0 -0
- package/assets/elsewhere-room-g1gaw7cs.jpg +0 -0
- package/canvas/apple-touch-icon.png +0 -0
- package/canvas/assets/index-BCvDZiBo.css +2 -0
- package/canvas/assets/index-ClaBqcaS.js +28 -0
- package/canvas/assets/lucide-all-iIF-pmzN.js +1 -0
- package/canvas/assets/radix-C3HaOB-d.js +41 -0
- package/canvas/assets/react-D0Ec-185.js +9 -0
- package/canvas/assets/rolldown-runtime-hePW80VL.js +1 -0
- package/canvas/assets/vendor-CKmQ-Zst.js +53 -0
- package/canvas/favicon.ico +0 -0
- package/canvas/favicon.svg +12 -0
- package/canvas/fonts/OFL-1.1.txt +93 -0
- package/canvas/fonts/poppins-700.woff2 +0 -0
- package/canvas/icon-192.png +0 -0
- package/canvas/icon-512.png +0 -0
- package/canvas/index.html +22 -0
- package/canvas/site.webmanifest +11 -0
- package/chunk-08sv3k41.js +4 -0
- package/chunk-0fe83yzt.js +2 -0
- package/chunk-0t68szgr.js +3 -0
- package/chunk-1h55s5he.js +2 -0
- package/chunk-2c7jbx46.js +2 -0
- package/chunk-2smsg2ct.js +7 -0
- package/chunk-308ynsxd.js +2 -0
- package/chunk-3e8vez4d.js +1229 -0
- package/chunk-40xgcth8.js +63 -0
- package/chunk-4dn75m6t.js +3 -0
- package/chunk-4fj5tahv.js +3 -0
- package/chunk-6nqghjda.js +3 -0
- package/chunk-6tx68d90.js +3 -0
- package/chunk-6w6ch4ce.js +2 -0
- package/chunk-735ezz23.js +86 -0
- package/chunk-7eq7nx37.js +7 -0
- package/chunk-7eyb8yrf.js +6 -0
- package/chunk-80fjfyha.js +86 -0
- package/chunk-80r93t2e.js +4 -0
- package/chunk-94vx1yb0.js +3 -0
- package/chunk-9vg3yafz.js +3 -0
- package/chunk-a84n72m2.js +4 -0
- package/chunk-ampmdzz4.js +10 -0
- package/chunk-avns4dbf.js +2 -0
- package/chunk-ayrb3qnm.js +3 -0
- package/chunk-bwnvcncx.js +3 -0
- package/chunk-ccszg02q.js +5 -0
- package/chunk-cvn689d5.js +3 -0
- package/chunk-cxe6jjwj.js +3 -0
- package/chunk-dg6z4vdd.js +3 -0
- package/chunk-dgwjpbp9.js +3 -0
- package/chunk-dy41n60j.js +52 -0
- package/chunk-ek71z2fv.js +226 -0
- package/chunk-er1fxb7d.js +2 -0
- package/chunk-eyr8hrzf.js +2 -0
- package/chunk-fjbzk4sw.js +3 -0
- package/chunk-fsbsksga.js +3 -0
- package/chunk-h6gchare.js +3 -0
- package/chunk-hcb68zt7.js +85 -0
- package/chunk-hggap8fq.js +3 -0
- package/chunk-j11fyeqh.js +2 -0
- package/chunk-jb21jkp1.js +8 -0
- package/chunk-jfx9xjmr.js +18 -0
- package/chunk-jr0ss0mm.js +303 -0
- package/chunk-jrsknzjt.js +3 -0
- package/chunk-jv0xggh0.js +2 -0
- package/chunk-k17gfwq3.js +2 -0
- package/chunk-mh2pr7cq.js +5 -0
- package/chunk-mnapdp1y.js +2 -0
- package/chunk-mzhdrawd.js +3 -0
- package/chunk-n9gs6yx9.js +2 -0
- package/chunk-ngnymg2q.js +3 -0
- package/chunk-nwx5700b.js +3 -0
- package/chunk-pjtg3wnm.js +4 -0
- package/chunk-pp86v6m6.js +3 -0
- package/chunk-r22epxz2.js +3 -0
- package/chunk-rgasy862.js +5 -0
- package/chunk-rpwpeph5.js +3 -0
- package/chunk-s23gtejf.js +3 -0
- package/chunk-sjgqnykd.js +6 -0
- package/chunk-sn3x2m0m.js +6 -0
- package/chunk-t448rrfr.js +2 -0
- package/chunk-tdsk5wxa.js +451 -0
- package/chunk-v40fn08f.js +442 -0
- package/chunk-vbk1qhdz.js +3 -0
- package/chunk-vdkrbzh1.js +2 -0
- package/chunk-vgmr98cv.js +40 -0
- package/chunk-vsv8z729.js +6 -0
- package/chunk-x4f4k9pp.js +26 -0
- package/chunk-xt5ayg7g.js +4 -0
- package/chunk-ydhwv29b.js +244 -0
- package/chunk-zb6hc1y0.js +2 -0
- package/cli.js +3 -0
- package/launcher.cjs +97 -0
- package/package.json +58 -5
- package/pkgs/helpers/src/box.tsx +21 -0
- package/pkgs/helpers/src/cn.ts +32 -0
- package/pkgs/helpers/src/descriptors.ts +270 -0
- package/pkgs/helpers/src/divider.tsx +123 -0
- package/pkgs/helpers/src/gradient.tsx +90 -0
- package/pkgs/helpers/src/heading.tsx +20 -0
- package/pkgs/helpers/src/icon-data.ts +8009 -0
- package/pkgs/helpers/src/icon.tsx +53 -0
- package/pkgs/helpers/src/image.tsx +111 -0
- package/pkgs/helpers/src/index.ts +29 -0
- package/pkgs/helpers/src/layer.tsx +61 -0
- package/pkgs/helpers/src/lowering.ts +53 -0
- package/pkgs/helpers/src/paths.ts +47 -0
- package/pkgs/helpers/src/placeholder.tsx +88 -0
- package/pkgs/helpers/src/prose.tsx +42 -0
- package/pkgs/helpers/src/registry.ts +41 -0
- package/pkgs/helpers/src/svg.tsx +62 -0
- package/pkgs/helpers/src/text.tsx +16 -0
- package/pkgs/provider-antd/src/index.ts +78 -0
- package/pkgs/provider-antd/src/intro.ts +14 -0
- package/pkgs/provider-antd/src/manifest.ts +439 -0
- package/pkgs/provider-antd/src/overlays.ts +176 -0
- package/pkgs/provider-antd/src/registry.ts +104 -0
- package/pkgs/provider-antd/src/render-pass.ts +43 -0
- package/pkgs/provider-antd/src/tailwind-entry.css +21 -0
- package/pkgs/provider-antd/src/theme.ts +132 -0
- package/pkgs/provider-antd/src/version.ts +8 -0
- package/pkgs/provider-chakra/src/index.ts +80 -0
- package/pkgs/provider-chakra/src/intro.ts +14 -0
- package/pkgs/provider-chakra/src/manifest.ts +421 -0
- package/pkgs/provider-chakra/src/overlays.ts +246 -0
- package/pkgs/provider-chakra/src/registry.ts +227 -0
- package/pkgs/provider-chakra/src/render-pass.ts +55 -0
- package/pkgs/provider-chakra/src/tailwind-entry.css +21 -0
- package/pkgs/provider-chakra/src/theme.ts +180 -0
- package/pkgs/provider-chakra/src/version.ts +8 -0
- package/pkgs/provider-mui/src/index.ts +117 -0
- package/pkgs/provider-mui/src/intro.ts +12 -0
- package/pkgs/provider-mui/src/manifest.ts +263 -0
- package/pkgs/provider-mui/src/overlays.ts +124 -0
- package/pkgs/provider-mui/src/registry.ts +120 -0
- package/pkgs/provider-mui/src/render-pass.ts +36 -0
- package/pkgs/provider-mui/src/tailwind-entry.css +21 -0
- package/pkgs/provider-mui/src/theme.ts +129 -0
- package/pkgs/provider-mui/src/version.ts +8 -0
- package/pkgs/provider-none/src/components-inline.tsx +204 -0
- package/pkgs/provider-none/src/components.tsx +155 -0
- package/pkgs/provider-none/src/index.ts +57 -0
- package/pkgs/provider-none/src/intro.ts +18 -0
- package/pkgs/provider-none/src/manifest.ts +163 -0
- package/pkgs/provider-none/src/registry-inline.ts +36 -0
- package/pkgs/provider-none/src/registry.ts +39 -0
- package/pkgs/provider-none/src/tailwind-entry.css +57 -0
- package/pkgs/provider-none/src/version.ts +10 -0
- package/pkgs/schema/src/annotation.ts +120 -0
- package/pkgs/schema/src/asset.ts +66 -0
- package/pkgs/schema/src/board.ts +71 -0
- package/pkgs/schema/src/comment.ts +107 -0
- package/pkgs/schema/src/config.ts +185 -0
- package/pkgs/schema/src/css-sanitize.ts +56 -0
- package/pkgs/schema/src/extension.ts +105 -0
- package/pkgs/schema/src/fonts.ts +690 -0
- package/pkgs/schema/src/frame.ts +40 -0
- package/pkgs/schema/src/icon-name.ts +21 -0
- package/pkgs/schema/src/ids.ts +14 -0
- package/pkgs/schema/src/index.ts +169 -0
- package/pkgs/schema/src/migrate.ts +297 -0
- package/pkgs/schema/src/node.ts +229 -0
- package/pkgs/schema/src/paths.ts +28 -0
- package/pkgs/schema/src/repo.ts +134 -0
- package/pkgs/schema/src/screen.ts +30 -0
- package/pkgs/schema/src/snippet-resolve.ts +193 -0
- package/pkgs/schema/src/snippet.ts +104 -0
- package/pkgs/schema/src/svg-sanitize.ts +487 -0
- package/pkgs/schema/src/theme.ts +218 -0
- package/pkgs/schema/src/typeset.ts +693 -0
- package/pkgs/schema/src/validate-ids.ts +46 -0
- package/pkgs/schema/src/viewport.ts +8 -0
- package/pkgs/shadcn-snapshot/dist/manifest.json +8109 -0
- package/pkgs/shadcn-snapshot/src/components/canvas-portal.tsx +55 -0
- package/pkgs/shadcn-snapshot/src/components/ui/accordion.tsx +122 -0
- package/pkgs/shadcn-snapshot/src/components/ui/alert-dialog.tsx +164 -0
- package/pkgs/shadcn-snapshot/src/components/ui/alert.tsx +74 -0
- package/pkgs/shadcn-snapshot/src/components/ui/aspect-ratio.tsx +13 -0
- package/pkgs/shadcn-snapshot/src/components/ui/attachment.tsx +197 -0
- package/pkgs/shadcn-snapshot/src/components/ui/avatar.tsx +100 -0
- package/pkgs/shadcn-snapshot/src/components/ui/badge.tsx +50 -0
- package/pkgs/shadcn-snapshot/src/components/ui/breadcrumb.tsx +109 -0
- package/pkgs/shadcn-snapshot/src/components/ui/bubble.tsx +130 -0
- package/pkgs/shadcn-snapshot/src/components/ui/button-group.tsx +82 -0
- package/pkgs/shadcn-snapshot/src/components/ui/button.tsx +72 -0
- package/pkgs/shadcn-snapshot/src/components/ui/calendar.tsx +229 -0
- package/pkgs/shadcn-snapshot/src/components/ui/card.tsx +92 -0
- package/pkgs/shadcn-snapshot/src/components/ui/carousel.tsx +235 -0
- package/pkgs/shadcn-snapshot/src/components/ui/chart-option.ts +250 -0
- package/pkgs/shadcn-snapshot/src/components/ui/chart.tsx +177 -0
- package/pkgs/shadcn-snapshot/src/components/ui/checkbox.tsx +41 -0
- package/pkgs/shadcn-snapshot/src/components/ui/collapsible.tsx +32 -0
- package/pkgs/shadcn-snapshot/src/components/ui/combobox.tsx +196 -0
- package/pkgs/shadcn-snapshot/src/components/ui/context-menu.tsx +227 -0
- package/pkgs/shadcn-snapshot/src/components/ui/dialog.tsx +131 -0
- package/pkgs/shadcn-snapshot/src/components/ui/direction.tsx +24 -0
- package/pkgs/shadcn-snapshot/src/components/ui/drawer.tsx +112 -0
- package/pkgs/shadcn-snapshot/src/components/ui/dropdown-menu.tsx +205 -0
- package/pkgs/shadcn-snapshot/src/components/ui/empty.tsx +98 -0
- package/pkgs/shadcn-snapshot/src/components/ui/field.tsx +228 -0
- package/pkgs/shadcn-snapshot/src/components/ui/hover-card.tsx +51 -0
- package/pkgs/shadcn-snapshot/src/components/ui/input-group.tsx +148 -0
- package/pkgs/shadcn-snapshot/src/components/ui/input.tsx +43 -0
- package/pkgs/shadcn-snapshot/src/components/ui/item.tsx +187 -0
- package/pkgs/shadcn-snapshot/src/components/ui/kbd.tsx +30 -0
- package/pkgs/shadcn-snapshot/src/components/ui/label.tsx +25 -0
- package/pkgs/shadcn-snapshot/src/components/ui/marker.tsx +71 -0
- package/pkgs/shadcn-snapshot/src/components/ui/menubar.tsx +243 -0
- package/pkgs/shadcn-snapshot/src/components/ui/message.tsx +89 -0
- package/pkgs/shadcn-snapshot/src/components/ui/native-select.tsx +60 -0
- package/pkgs/shadcn-snapshot/src/components/ui/navigation-menu.tsx +165 -0
- package/pkgs/shadcn-snapshot/src/components/ui/pagination.tsx +117 -0
- package/pkgs/shadcn-snapshot/src/components/ui/popover.tsx +66 -0
- package/pkgs/shadcn-snapshot/src/components/ui/progress.tsx +35 -0
- package/pkgs/shadcn-snapshot/src/components/ui/radio-group.tsx +48 -0
- package/pkgs/shadcn-snapshot/src/components/ui/scroll-area.tsx +59 -0
- package/pkgs/shadcn-snapshot/src/components/ui/select.tsx +180 -0
- package/pkgs/shadcn-snapshot/src/components/ui/separator.tsx +32 -0
- package/pkgs/shadcn-snapshot/src/components/ui/sheet.tsx +107 -0
- package/pkgs/shadcn-snapshot/src/components/ui/skeleton.tsx +17 -0
- package/pkgs/shadcn-snapshot/src/components/ui/slider.tsx +68 -0
- package/pkgs/shadcn-snapshot/src/components/ui/sonner.tsx +91 -0
- package/pkgs/shadcn-snapshot/src/components/ui/spinner.tsx +21 -0
- package/pkgs/shadcn-snapshot/src/components/ui/switch.tsx +41 -0
- package/pkgs/shadcn-snapshot/src/components/ui/table.tsx +93 -0
- package/pkgs/shadcn-snapshot/src/components/ui/tabs.tsx +84 -0
- package/pkgs/shadcn-snapshot/src/components/ui/textarea.tsx +24 -0
- package/pkgs/shadcn-snapshot/src/components/ui/toggle-group.tsx +94 -0
- package/pkgs/shadcn-snapshot/src/components/ui/toggle.tsx +50 -0
- package/pkgs/shadcn-snapshot/src/components/ui/tooltip.tsx +47 -0
- package/pkgs/shadcn-snapshot/src/examples.ts +36 -0
- package/pkgs/shadcn-snapshot/src/groups.ts +87 -0
- package/pkgs/shadcn-snapshot/src/index.ts +43 -0
- package/pkgs/shadcn-snapshot/src/lib/utils.ts +4 -0
- package/pkgs/shadcn-snapshot/src/manifest.ts +12 -0
- package/pkgs/shadcn-snapshot/src/notes.ts +97 -0
- package/pkgs/shadcn-snapshot/src/paths.ts +47 -0
- package/pkgs/shadcn-snapshot/src/registry-files.ts +293 -0
- package/pkgs/shadcn-snapshot/src/registry.ts +631 -0
- package/pkgs/shadcn-snapshot/src/shadcn-tailwind.css +632 -0
- package/pkgs/shadcn-snapshot/src/tailwind-entry.css +159 -0
- package/pkgs/shadcn-snapshot/src/version.ts +8 -0
- package/plugins/claude/velloo/.claude-plugin/plugin.json +6 -0
- package/plugins/claude/velloo/agents/velloo-design-reviewer.md +33 -0
- package/plugins/claude/velloo/agents/velloo-designer.md +39 -0
- package/plugins/claude/velloo/commands/design.md +11 -0
- package/plugins/claude/velloo/commands/implement.md +10 -0
- package/plugins/claude/velloo/commands/review.md +8 -0
- package/plugins/gemini/GEMINI.md +31 -0
- package/plugins/gemini/commands/velloo/design.toml +10 -0
- package/plugins/gemini/commands/velloo/implement.toml +9 -0
- package/plugins/gemini/gemini-extension.json +9 -0
- package/skills/velloo-brand/SKILL.md +124 -0
- package/skills/velloo-design/SKILL.md +144 -0
- package/skills/velloo-design-system/SKILL.md +90 -0
- package/skills/velloo-implement/SKILL.md +101 -0
- package/skills/velloo-logo/SKILL.md +93 -0
- package/skills/velloo-setup/SKILL.md +156 -0
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import type { ComponentDescriptor, Manifest, PropDescriptor } from "@velloo/provider";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Hand-authored MUI manifest for the shipped registry — curated to the props an
|
|
5
|
+
* agent actually sets (variant/color/size, the `sx` style channel, children),
|
|
6
|
+
* which reads far better than a generated dump of MUI's vast type surface. A
|
|
7
|
+
* ts-morph `.d.ts` generator remains an option for breadth, but the curated
|
|
8
|
+
* manifest is the chosen default; this stays the source of truth.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
const sx: PropDescriptor = {
|
|
12
|
+
name: "sx",
|
|
13
|
+
type: "SxProps | undefined",
|
|
14
|
+
optional: true,
|
|
15
|
+
control: "string",
|
|
16
|
+
};
|
|
17
|
+
const children: PropDescriptor = {
|
|
18
|
+
name: "children",
|
|
19
|
+
type: "ReactNode",
|
|
20
|
+
optional: true,
|
|
21
|
+
control: "string",
|
|
22
|
+
};
|
|
23
|
+
const enumProp = (name: string, values: string[], defaultValue?: string): PropDescriptor => ({
|
|
24
|
+
name,
|
|
25
|
+
type: values.map((v) => `"${v}"`).join(" | "),
|
|
26
|
+
optional: true,
|
|
27
|
+
control: "enum",
|
|
28
|
+
enumValues: values,
|
|
29
|
+
defaultValue,
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
function ui(
|
|
33
|
+
id: string,
|
|
34
|
+
props: PropDescriptor[],
|
|
35
|
+
notes?: string,
|
|
36
|
+
example?: Record<string, unknown>,
|
|
37
|
+
): ComponentDescriptor {
|
|
38
|
+
return {
|
|
39
|
+
id,
|
|
40
|
+
category: "ui",
|
|
41
|
+
source: "mui",
|
|
42
|
+
props: [...props, sx],
|
|
43
|
+
designModeNotes: notes,
|
|
44
|
+
example,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const className: PropDescriptor = {
|
|
49
|
+
name: "className",
|
|
50
|
+
type: "string | undefined",
|
|
51
|
+
optional: true,
|
|
52
|
+
control: "string",
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
/** A reused framework-neutral velloo helper (source "velloo") — styled via className, not sx. */
|
|
56
|
+
function helper(
|
|
57
|
+
id: string,
|
|
58
|
+
props: PropDescriptor[],
|
|
59
|
+
notes?: string,
|
|
60
|
+
example?: Record<string, unknown>,
|
|
61
|
+
): ComponentDescriptor {
|
|
62
|
+
return {
|
|
63
|
+
id,
|
|
64
|
+
category: "ui",
|
|
65
|
+
source: "velloo",
|
|
66
|
+
props: [...props, className],
|
|
67
|
+
designModeNotes: notes,
|
|
68
|
+
example,
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export const MUI_MANIFEST: Manifest = [
|
|
73
|
+
ui("Box", [children], "Generic layout primitive; style via sx."),
|
|
74
|
+
ui(
|
|
75
|
+
"Stack",
|
|
76
|
+
[children, enumProp("direction", ["row", "column"], "column")],
|
|
77
|
+
"Flex layout; set spacing via sx or the spacing prop.",
|
|
78
|
+
),
|
|
79
|
+
ui(
|
|
80
|
+
"Container",
|
|
81
|
+
[children, enumProp("maxWidth", ["xs", "sm", "md", "lg", "xl"], "lg")],
|
|
82
|
+
"Centers + max-widths content.",
|
|
83
|
+
),
|
|
84
|
+
ui("Paper", [children, enumProp("variant", ["elevation", "outlined"], "elevation")]),
|
|
85
|
+
ui("Card", [children, enumProp("variant", ["elevation", "outlined"], "elevation")]),
|
|
86
|
+
ui("CardContent", [children]),
|
|
87
|
+
ui("CardHeader", [
|
|
88
|
+
{ name: "title", type: "ReactNode", optional: true, control: "string" },
|
|
89
|
+
{ name: "subheader", type: "ReactNode", optional: true, control: "string" },
|
|
90
|
+
]),
|
|
91
|
+
ui("CardActions", [children]),
|
|
92
|
+
ui(
|
|
93
|
+
"Button",
|
|
94
|
+
[
|
|
95
|
+
children,
|
|
96
|
+
enumProp("variant", ["text", "outlined", "contained"], "text"),
|
|
97
|
+
enumProp("color", ["primary", "secondary", "success", "error", "inherit"], "primary"),
|
|
98
|
+
enumProp("size", ["small", "medium", "large"], "medium"),
|
|
99
|
+
],
|
|
100
|
+
"Action button.",
|
|
101
|
+
{ variant: "contained", color: "primary", children: "Submit" },
|
|
102
|
+
),
|
|
103
|
+
ui(
|
|
104
|
+
"Typography",
|
|
105
|
+
[
|
|
106
|
+
children,
|
|
107
|
+
enumProp(
|
|
108
|
+
"variant",
|
|
109
|
+
[
|
|
110
|
+
"h1",
|
|
111
|
+
"h2",
|
|
112
|
+
"h3",
|
|
113
|
+
"h4",
|
|
114
|
+
"h5",
|
|
115
|
+
"h6",
|
|
116
|
+
"subtitle1",
|
|
117
|
+
"subtitle2",
|
|
118
|
+
"body1",
|
|
119
|
+
"body2",
|
|
120
|
+
"caption",
|
|
121
|
+
"overline",
|
|
122
|
+
],
|
|
123
|
+
"body1",
|
|
124
|
+
),
|
|
125
|
+
enumProp("color", ["text.primary", "text.secondary", "primary", "error"]),
|
|
126
|
+
],
|
|
127
|
+
"All text. Pick variant for the type scale; this is MUI's Heading + Text.",
|
|
128
|
+
{ variant: "h4", children: "Team analytics" },
|
|
129
|
+
),
|
|
130
|
+
ui("TextField", [
|
|
131
|
+
enumProp("variant", ["outlined", "filled", "standard"], "outlined"),
|
|
132
|
+
{ name: "label", type: "string", optional: true, control: "string" },
|
|
133
|
+
{ name: "placeholder", type: "string", optional: true, control: "string" },
|
|
134
|
+
]),
|
|
135
|
+
ui("Chip", [
|
|
136
|
+
{ name: "label", type: "ReactNode", optional: true, control: "string" },
|
|
137
|
+
enumProp("variant", ["filled", "outlined"], "filled"),
|
|
138
|
+
enumProp("color", ["default", "primary", "success", "warning", "error"], "default"),
|
|
139
|
+
enumProp("size", ["small", "medium"], "medium"),
|
|
140
|
+
]),
|
|
141
|
+
ui("Divider", []),
|
|
142
|
+
ui("Avatar", [children, { name: "src", type: "string", optional: true, control: "string" }]),
|
|
143
|
+
ui("LinearProgress", [
|
|
144
|
+
{ name: "value", type: "number", optional: true, control: "number" },
|
|
145
|
+
enumProp("variant", ["determinate", "indeterminate"], "indeterminate"),
|
|
146
|
+
]),
|
|
147
|
+
ui("AppBar", [
|
|
148
|
+
children,
|
|
149
|
+
enumProp("position", ["fixed", "static", "sticky"], "fixed"),
|
|
150
|
+
enumProp("color", ["primary", "default", "transparent", "inherit"], "primary"),
|
|
151
|
+
]),
|
|
152
|
+
ui("Toolbar", [children]),
|
|
153
|
+
ui("IconButton", [children, enumProp("size", ["small", "medium", "large"], "medium")]),
|
|
154
|
+
ui("Link", [children, { name: "href", type: "string", optional: true, control: "string" }]),
|
|
155
|
+
ui("List", [children]),
|
|
156
|
+
ui("ListItem", [children]),
|
|
157
|
+
ui("ListItemText", [
|
|
158
|
+
{ name: "primary", type: "ReactNode", optional: true, control: "string" },
|
|
159
|
+
{ name: "secondary", type: "ReactNode", optional: true, control: "string" },
|
|
160
|
+
]),
|
|
161
|
+
ui("Table", [children]),
|
|
162
|
+
ui("TableHead", [children]),
|
|
163
|
+
ui("TableBody", [children]),
|
|
164
|
+
ui("TableRow", [children]),
|
|
165
|
+
ui("TableCell", [children, enumProp("align", ["left", "center", "right"], "left")]),
|
|
166
|
+
ui("Tabs", [
|
|
167
|
+
children,
|
|
168
|
+
{ name: "value", type: "number | string", optional: true, control: "string" },
|
|
169
|
+
]),
|
|
170
|
+
ui("Tab", [{ name: "label", type: "ReactNode", optional: true, control: "string" }]),
|
|
171
|
+
ui("Badge", [
|
|
172
|
+
children,
|
|
173
|
+
{ name: "badgeContent", type: "ReactNode", optional: true, control: "string" },
|
|
174
|
+
]),
|
|
175
|
+
ui("Checkbox", [{ name: "checked", type: "boolean", optional: true, control: "boolean" }]),
|
|
176
|
+
ui("Switch", [{ name: "checked", type: "boolean", optional: true, control: "boolean" }]),
|
|
177
|
+
ui("Select", [children, enumProp("variant", ["outlined", "filled", "standard"], "outlined")]),
|
|
178
|
+
ui("MenuItem", [
|
|
179
|
+
children,
|
|
180
|
+
{ name: "value", type: "string | number", optional: true, control: "string" },
|
|
181
|
+
]),
|
|
182
|
+
ui("Tooltip", [
|
|
183
|
+
children,
|
|
184
|
+
{ name: "title", type: "ReactNode", optional: true, control: "string" },
|
|
185
|
+
]),
|
|
186
|
+
ui("Alert", [children, enumProp("severity", ["success", "info", "warning", "error"], "success")]),
|
|
187
|
+
|
|
188
|
+
// Overlay surface — canvas-safe: rendered OPEN + inline in design mode (no
|
|
189
|
+
// portal/backdrop), so build the content directly inside them.
|
|
190
|
+
ui(
|
|
191
|
+
"Dialog",
|
|
192
|
+
[children, enumProp("maxWidth", ["xs", "sm", "md", "lg", "xl"], "sm")],
|
|
193
|
+
"Modal dialog surface — renders open + inline in design mode. Fill it with DialogTitle / DialogContent / DialogActions.",
|
|
194
|
+
{ maxWidth: "sm" },
|
|
195
|
+
),
|
|
196
|
+
ui("DialogTitle", [children], "The dialog's heading row."),
|
|
197
|
+
ui("DialogContent", [children], "The dialog's body."),
|
|
198
|
+
ui("DialogContentText", [children], "Secondary text inside DialogContent."),
|
|
199
|
+
ui("DialogActions", [children], "The dialog's button row (right-aligned)."),
|
|
200
|
+
ui(
|
|
201
|
+
"Menu",
|
|
202
|
+
[children],
|
|
203
|
+
"A menu surface holding MenuItems — renders open + inline in design mode.",
|
|
204
|
+
),
|
|
205
|
+
ui("Popover", [children], "A popover surface — renders open + inline in design mode."),
|
|
206
|
+
ui("Drawer", [children], "A side panel — renders inline as a fixed-width column in design mode."),
|
|
207
|
+
ui(
|
|
208
|
+
"Snackbar",
|
|
209
|
+
[children, { name: "message", type: "ReactNode", optional: true, control: "string" }],
|
|
210
|
+
"A toast — renders inline as a dark pill in design mode. Use `message` or children.",
|
|
211
|
+
{ message: "Saved" },
|
|
212
|
+
),
|
|
213
|
+
|
|
214
|
+
// Framework-neutral velloo helpers (MUI bundles no icon set; @mui/icons-material
|
|
215
|
+
// isn't shipped). source:"velloo" — sized/styled via props (NOT sx/Tailwind: a
|
|
216
|
+
// MUI folder has no JIT). `Icon` emits a lucide-react import in codegen.
|
|
217
|
+
helper(
|
|
218
|
+
"Icon",
|
|
219
|
+
[
|
|
220
|
+
{ name: "name", type: "string", optional: false, control: "icon" },
|
|
221
|
+
{ name: "size", type: "number", optional: true, control: "number" },
|
|
222
|
+
],
|
|
223
|
+
"A lucide icon — MUI has no bundled icon set. Set the pixel `size` prop (not Tailwind). `name` is a lucide id (PascalCase or kebab). Emits a `lucide-react` import.",
|
|
224
|
+
{ name: "ArrowRight", size: 20 },
|
|
225
|
+
),
|
|
226
|
+
helper(
|
|
227
|
+
"Image",
|
|
228
|
+
[
|
|
229
|
+
{ name: "src", type: "string", optional: false, control: "string" },
|
|
230
|
+
{ name: "alt", type: "string", optional: false, control: "string" },
|
|
231
|
+
],
|
|
232
|
+
"An image. Use velloo assets (`/assets/…`) or a URL.",
|
|
233
|
+
),
|
|
234
|
+
helper(
|
|
235
|
+
"Placeholder",
|
|
236
|
+
[{ name: "label", type: "string", optional: true, control: "string" }],
|
|
237
|
+
"A labeled placeholder box for imagery you haven't authored yet (avatars, hero shots).",
|
|
238
|
+
),
|
|
239
|
+
helper(
|
|
240
|
+
"SVG",
|
|
241
|
+
[
|
|
242
|
+
{ name: "content", type: "string", optional: false, control: "string" },
|
|
243
|
+
{ name: "viewBox", type: "string", optional: false, control: "string" },
|
|
244
|
+
],
|
|
245
|
+
"Raw inline SVG markup.",
|
|
246
|
+
),
|
|
247
|
+
helper("Layer", [children], "An absolutely-positioned overlay layer for stacked composition."),
|
|
248
|
+
helper(
|
|
249
|
+
"Gradient",
|
|
250
|
+
[{ name: "from", type: "string", optional: true, control: "color" }],
|
|
251
|
+
"A gradient fill block.",
|
|
252
|
+
),
|
|
253
|
+
helper(
|
|
254
|
+
"Prose",
|
|
255
|
+
[
|
|
256
|
+
children,
|
|
257
|
+
{ name: "preset", type: "string", optional: true, control: "string" },
|
|
258
|
+
{ name: "as", type: "string", optional: true, control: "string" },
|
|
259
|
+
],
|
|
260
|
+
"A long-form content region. Everything inside — Typography, headings, lists, quotes, code, tables — picks up the theme typeset's proportions and vertical rhythm automatically. `preset` selects a named typeset (see set_typeset). Reach for this for articles, docs, and marketing copy instead of setting sizes block by block.",
|
|
261
|
+
{ as: "article" },
|
|
262
|
+
),
|
|
263
|
+
];
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import Box from "@mui/material/Box";
|
|
2
|
+
import DialogActions from "@mui/material/DialogActions";
|
|
3
|
+
import DialogContent from "@mui/material/DialogContent";
|
|
4
|
+
import DialogContentText from "@mui/material/DialogContentText";
|
|
5
|
+
import DialogTitle from "@mui/material/DialogTitle";
|
|
6
|
+
import Paper from "@mui/material/Paper";
|
|
7
|
+
import { createElement, type ReactElement, type ReactNode } from "react";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Canvas-safe MUI overlays. MUI's Dialog/Menu/Popover/Drawer/Snackbar portal to
|
|
11
|
+
* `document.body` and default to closed — in design mode we want them rendered
|
|
12
|
+
* **open + inline** (in normal flow, no escaping portal, no fixed backdrop) so a
|
|
13
|
+
* screenshot shows their surface. These shims render the overlay's *content* in
|
|
14
|
+
* a Paper inline; the open/anchor/transition machinery is dropped. The
|
|
15
|
+
* sub-parts (DialogTitle/Content/Actions) are MUI's real components — they're
|
|
16
|
+
* plain styled boxes that already render inline — re-exported as-is.
|
|
17
|
+
*
|
|
18
|
+
* Mirrors the shadcn snapshot's pinned-open overlay stance.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
type Props = Record<string, unknown> & { children?: ReactNode };
|
|
22
|
+
|
|
23
|
+
/** Pass-through props every node carries — className for styling, data-node-path for canvas selection. */
|
|
24
|
+
function chrome(props: Props): { className?: string; "data-node-path"?: string } {
|
|
25
|
+
// Only the keys that are actually present: the return type says these may be
|
|
26
|
+
// *absent*, and under `exactOptionalPropertyTypes` an explicit `undefined` is
|
|
27
|
+
// a different thing from an omitted key.
|
|
28
|
+
const className = typeof props.className === "string" ? props.className : undefined;
|
|
29
|
+
const nodePath = props["data-node-path"];
|
|
30
|
+
return {
|
|
31
|
+
...(className !== undefined ? { className } : {}),
|
|
32
|
+
...(typeof nodePath === "string" ? { "data-node-path": nodePath } : {}),
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
function mergeSx(base: Record<string, unknown>, sx: unknown): Record<string, unknown> {
|
|
37
|
+
return sx && typeof sx === "object" && !Array.isArray(sx) ? { ...base, ...sx } : base;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const DIALOG_WIDTH: Record<string, number> = { xs: 360, sm: 480, md: 600, lg: 800, xl: 960 };
|
|
41
|
+
|
|
42
|
+
/** The dialog surface, rendered inline (open, no portal/backdrop). */
|
|
43
|
+
export function Dialog(props: Props): ReactElement {
|
|
44
|
+
const width = typeof props.maxWidth === "string" ? (DIALOG_WIDTH[props.maxWidth] ?? 600) : 600;
|
|
45
|
+
return createElement(
|
|
46
|
+
Paper,
|
|
47
|
+
{
|
|
48
|
+
...chrome(props),
|
|
49
|
+
elevation: 8,
|
|
50
|
+
sx: mergeSx(
|
|
51
|
+
{ width: "100%", maxWidth: width, mx: "auto", my: 2, borderRadius: 2, overflow: "hidden" },
|
|
52
|
+
props.sx,
|
|
53
|
+
),
|
|
54
|
+
},
|
|
55
|
+
props.children,
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** A menu surface (a Paper holding MenuItems), rendered inline. */
|
|
60
|
+
export function Menu(props: Props): ReactElement {
|
|
61
|
+
return createElement(
|
|
62
|
+
Paper,
|
|
63
|
+
{
|
|
64
|
+
...chrome(props),
|
|
65
|
+
elevation: 3,
|
|
66
|
+
sx: mergeSx({ display: "inline-block", minWidth: 180, py: 1, borderRadius: 1.5 }, props.sx),
|
|
67
|
+
},
|
|
68
|
+
props.children,
|
|
69
|
+
);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** A popover surface, rendered inline. */
|
|
73
|
+
export function Popover(props: Props): ReactElement {
|
|
74
|
+
return createElement(
|
|
75
|
+
Paper,
|
|
76
|
+
{
|
|
77
|
+
...chrome(props),
|
|
78
|
+
elevation: 3,
|
|
79
|
+
sx: mergeSx({ display: "inline-block", p: 2, borderRadius: 1.5 }, props.sx),
|
|
80
|
+
},
|
|
81
|
+
props.children,
|
|
82
|
+
);
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** A side-drawer panel, rendered inline as a fixed-width column. */
|
|
86
|
+
export function Drawer(props: Props): ReactElement {
|
|
87
|
+
return createElement(
|
|
88
|
+
Paper,
|
|
89
|
+
{
|
|
90
|
+
...chrome(props),
|
|
91
|
+
elevation: 2,
|
|
92
|
+
square: true,
|
|
93
|
+
sx: mergeSx({ width: 280, height: "100%", p: 2 }, props.sx),
|
|
94
|
+
},
|
|
95
|
+
props.children,
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/** A toast, rendered inline as a dark pill. `message` or children. */
|
|
100
|
+
export function Snackbar(props: Props): ReactElement {
|
|
101
|
+
const body = props.message !== undefined ? (props.message as ReactNode) : props.children;
|
|
102
|
+
return createElement(
|
|
103
|
+
Box,
|
|
104
|
+
{
|
|
105
|
+
...chrome(props),
|
|
106
|
+
sx: mergeSx(
|
|
107
|
+
{
|
|
108
|
+
display: "inline-flex",
|
|
109
|
+
alignItems: "center",
|
|
110
|
+
px: 2,
|
|
111
|
+
py: 1.25,
|
|
112
|
+
bgcolor: "grey.900",
|
|
113
|
+
color: "common.white",
|
|
114
|
+
borderRadius: 1,
|
|
115
|
+
fontSize: 14,
|
|
116
|
+
},
|
|
117
|
+
props.sx,
|
|
118
|
+
),
|
|
119
|
+
},
|
|
120
|
+
body,
|
|
121
|
+
);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
export { DialogActions, DialogContent, DialogContentText, DialogTitle };
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import Alert from "@mui/material/Alert";
|
|
2
|
+
import AppBar from "@mui/material/AppBar";
|
|
3
|
+
import Avatar from "@mui/material/Avatar";
|
|
4
|
+
import Badge from "@mui/material/Badge";
|
|
5
|
+
import Box from "@mui/material/Box";
|
|
6
|
+
import Button from "@mui/material/Button";
|
|
7
|
+
import Card from "@mui/material/Card";
|
|
8
|
+
import CardActions from "@mui/material/CardActions";
|
|
9
|
+
import CardContent from "@mui/material/CardContent";
|
|
10
|
+
import CardHeader from "@mui/material/CardHeader";
|
|
11
|
+
import Checkbox from "@mui/material/Checkbox";
|
|
12
|
+
import Chip from "@mui/material/Chip";
|
|
13
|
+
import Container from "@mui/material/Container";
|
|
14
|
+
import Divider from "@mui/material/Divider";
|
|
15
|
+
import IconButton from "@mui/material/IconButton";
|
|
16
|
+
import LinearProgress from "@mui/material/LinearProgress";
|
|
17
|
+
import Link from "@mui/material/Link";
|
|
18
|
+
import List from "@mui/material/List";
|
|
19
|
+
import ListItem from "@mui/material/ListItem";
|
|
20
|
+
import ListItemText from "@mui/material/ListItemText";
|
|
21
|
+
import MenuItem from "@mui/material/MenuItem";
|
|
22
|
+
import Paper from "@mui/material/Paper";
|
|
23
|
+
import Select from "@mui/material/Select";
|
|
24
|
+
import Stack from "@mui/material/Stack";
|
|
25
|
+
import Switch from "@mui/material/Switch";
|
|
26
|
+
import Tab from "@mui/material/Tab";
|
|
27
|
+
import Table from "@mui/material/Table";
|
|
28
|
+
import TableBody from "@mui/material/TableBody";
|
|
29
|
+
import TableCell from "@mui/material/TableCell";
|
|
30
|
+
import TableHead from "@mui/material/TableHead";
|
|
31
|
+
import TableRow from "@mui/material/TableRow";
|
|
32
|
+
import Tabs from "@mui/material/Tabs";
|
|
33
|
+
import TextField from "@mui/material/TextField";
|
|
34
|
+
import Toolbar from "@mui/material/Toolbar";
|
|
35
|
+
import Tooltip from "@mui/material/Tooltip";
|
|
36
|
+
import Typography from "@mui/material/Typography";
|
|
37
|
+
import { helpersRegistry } from "@velloo/helpers";
|
|
38
|
+
import type { ComponentRegistry } from "@velloo/provider";
|
|
39
|
+
import {
|
|
40
|
+
Dialog,
|
|
41
|
+
DialogActions,
|
|
42
|
+
DialogContent,
|
|
43
|
+
DialogContentText,
|
|
44
|
+
DialogTitle,
|
|
45
|
+
Drawer,
|
|
46
|
+
Menu,
|
|
47
|
+
Popover,
|
|
48
|
+
Snackbar,
|
|
49
|
+
} from "./overlays.ts";
|
|
50
|
+
|
|
51
|
+
const REUSED_HELPER_IDS = [
|
|
52
|
+
"Icon",
|
|
53
|
+
"Image",
|
|
54
|
+
"Placeholder",
|
|
55
|
+
"SVG",
|
|
56
|
+
"Layer",
|
|
57
|
+
"Gradient",
|
|
58
|
+
"Prose",
|
|
59
|
+
] as const;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The runtime registry for MUI-native folders: design `$ref` ids → real MUI
|
|
63
|
+
* components. SSR'd in-process via the adapter's emotion render pass. The
|
|
64
|
+
* overlay surface (Dialog/Menu/Popover/Drawer/Snackbar) is canvas-safe-wrapped
|
|
65
|
+
* in `overlays.ts` — rendered open + inline so a screenshot shows it; their
|
|
66
|
+
* sub-parts (DialogTitle/Content/Actions) are MUI's real inline components.
|
|
67
|
+
* Tooltip is a passthrough (it renders its child inline in SSR).
|
|
68
|
+
*/
|
|
69
|
+
export const registry: ComponentRegistry = {
|
|
70
|
+
Alert,
|
|
71
|
+
AppBar,
|
|
72
|
+
Avatar,
|
|
73
|
+
Badge,
|
|
74
|
+
Box,
|
|
75
|
+
Button,
|
|
76
|
+
Card,
|
|
77
|
+
CardActions,
|
|
78
|
+
CardContent,
|
|
79
|
+
CardHeader,
|
|
80
|
+
Checkbox,
|
|
81
|
+
Chip,
|
|
82
|
+
Container,
|
|
83
|
+
Dialog,
|
|
84
|
+
DialogActions,
|
|
85
|
+
DialogContent,
|
|
86
|
+
DialogContentText,
|
|
87
|
+
DialogTitle,
|
|
88
|
+
Divider,
|
|
89
|
+
Drawer,
|
|
90
|
+
IconButton,
|
|
91
|
+
LinearProgress,
|
|
92
|
+
Link,
|
|
93
|
+
List,
|
|
94
|
+
ListItem,
|
|
95
|
+
ListItemText,
|
|
96
|
+
Menu,
|
|
97
|
+
MenuItem,
|
|
98
|
+
Paper,
|
|
99
|
+
Popover,
|
|
100
|
+
Select,
|
|
101
|
+
Snackbar,
|
|
102
|
+
Stack,
|
|
103
|
+
Switch,
|
|
104
|
+
Tab,
|
|
105
|
+
Table,
|
|
106
|
+
TableBody,
|
|
107
|
+
TableCell,
|
|
108
|
+
TableHead,
|
|
109
|
+
TableRow,
|
|
110
|
+
Tabs,
|
|
111
|
+
TextField,
|
|
112
|
+
Toolbar,
|
|
113
|
+
Tooltip,
|
|
114
|
+
Typography,
|
|
115
|
+
// Framework-neutral velloo helpers MUI has no equivalent for — chiefly `Icon`
|
|
116
|
+
// (lucide; MUI's own @mui/icons-material isn't bundled) + imagery/composition
|
|
117
|
+
// helpers. Reused verbatim from `@velloo/helpers`, like provider-none. They
|
|
118
|
+
// size via props (`Icon size`), not Tailwind — the JIT is off on a MUI folder.
|
|
119
|
+
...helpersRegistry(REUSED_HELPER_IDS),
|
|
120
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import createCache from "@emotion/cache";
|
|
2
|
+
import { CacheProvider } from "@emotion/react";
|
|
3
|
+
import createEmotionServer from "@emotion/server/create-instance";
|
|
4
|
+
import { ThemeProvider } from "@mui/material/styles";
|
|
5
|
+
import type { RenderPass } from "@velloo/provider";
|
|
6
|
+
import type { Theme as VellooTheme } from "@velloo/schema";
|
|
7
|
+
import { createElement } from "react";
|
|
8
|
+
import { muiThemeFrom } from "./theme.ts";
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* A fresh emotion + MUI render pass for one SSR. `wrap` nests the tree under a
|
|
12
|
+
* per-render emotion CacheProvider + a MUI ThemeProvider built from velloo's
|
|
13
|
+
* tokens; `css(html)` extracts exactly the emotion rules the rendered markup
|
|
14
|
+
* uses. The renderer injects that CSS into a `data-velloo-adapter` <style>.
|
|
15
|
+
*
|
|
16
|
+
* SSR works in-process because @mui/material is a velloo dependency, so it links
|
|
17
|
+
* the shared monorepo React — no dual-React hazard.
|
|
18
|
+
*/
|
|
19
|
+
export function makeRenderPass(theme: VellooTheme, dark = false): RenderPass {
|
|
20
|
+
const cache = createCache({ key: "vmui", prepend: true });
|
|
21
|
+
const server = createEmotionServer(cache);
|
|
22
|
+
const muiTheme = muiThemeFrom(theme, dark);
|
|
23
|
+
return {
|
|
24
|
+
wrap: (element) =>
|
|
25
|
+
createElement(
|
|
26
|
+
CacheProvider,
|
|
27
|
+
{ value: cache },
|
|
28
|
+
createElement(ThemeProvider, { theme: muiTheme }, element),
|
|
29
|
+
),
|
|
30
|
+
css: (html) =>
|
|
31
|
+
server
|
|
32
|
+
.extractCriticalToChunks(html)
|
|
33
|
+
.styles.map((s) => s.css)
|
|
34
|
+
.join(""),
|
|
35
|
+
};
|
|
36
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* MUI styles components via emotion (the `sx` prop), not Tailwind utility
|
|
3
|
+
* classes — so this entry mostly exists to satisfy the JIT contract. It still
|
|
4
|
+
* imports Tailwind + declares the token @theme so any stray utility class (or a
|
|
5
|
+
* `style`-channel escape hatch) resolves, and the canvas base reads themed.
|
|
6
|
+
*/
|
|
7
|
+
@import "tailwindcss";
|
|
8
|
+
|
|
9
|
+
@theme {
|
|
10
|
+
--color-background: oklch(1 0 0);
|
|
11
|
+
--color-foreground: oklch(0.145 0 0);
|
|
12
|
+
--color-primary: oklch(0.205 0 0);
|
|
13
|
+
--color-primary-foreground: oklch(0.985 0 0);
|
|
14
|
+
--font-sans: system-ui, -apple-system, sans-serif;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
html, body {
|
|
18
|
+
background: var(--color-background);
|
|
19
|
+
color: var(--color-foreground);
|
|
20
|
+
font-family: var(--font-sans);
|
|
21
|
+
}
|