@rimelight/ui 0.0.9 → 0.0.10

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rimelight/ui",
3
- "version": "0.0.9",
3
+ "version": "0.0.10",
4
4
  "private": false,
5
5
  "description": "Rimelight Entertainment UI Library.",
6
6
  "homepage": "https://rimelight.com/docs",
@@ -36,9 +36,13 @@
36
36
  "./integrations": "./src/integrations/index.ts",
37
37
  "./integrations/vue-entrypoint": "./src/integrations/vue-entrypoint.ts",
38
38
  "./integrations/*": "./src/integrations/*",
39
+ "./plugins/*": "./src/plugins/*",
39
40
  "./middleware": "./src/middleware/index.ts",
40
41
  "./middleware/*": "./src/middleware/*",
41
42
  "./nuxt": "./src/nuxt.ts",
43
+ "./preset": "./src/preset.ts",
44
+ "./preset/*": "./src/preset/*",
45
+ "./package-managers": "./src/plugins/starlightAddons/PackageManagers.astro",
42
46
  "./*": "./src/*"
43
47
  },
44
48
  "publishConfig": {
@@ -49,11 +53,14 @@
49
53
  "@iconify-json/lucide": "^1.2.102",
50
54
  "@nuxt/ui": "4.6.1",
51
55
  "@tailwindcss/vite": "^4.2.3",
56
+ "@unocss/astro": "^66.6.8",
52
57
  "css-variants": "2.3.5",
53
58
  "defu": "6.1.6",
54
59
  "embla-carousel": "8.6.0",
55
60
  "tailwind-merge": "^3.3.1",
56
61
  "tailwindcss": "^4.2.3",
62
+ "turndown": "^7.2.4",
63
+ "turndown-plugin-gfm": "^1.0.2",
57
64
  "unplugin-icons": "23.0.1"
58
65
  },
59
66
  "devDependencies": {
@@ -62,12 +69,14 @@
62
69
  "@e18e/eslint-plugin": "0.3.0",
63
70
  "@types/node": "25.5.2",
64
71
  "@unocss/eslint-plugin": "66.6.8",
65
- "astro": "6.1.4",
72
+ "astro": "6.1.8",
66
73
  "eslint-plugin-regexp": "3.1.0",
67
74
  "unocss": "66.6.8",
68
- "vite-plus": "0.1.18"
75
+ "vite-plugin-virtual": "^0.5.0",
76
+ "vite-plus": "0.1.19"
69
77
  },
70
78
  "peerDependencies": {
79
+ "@astrojs/starlight": ">=0.5.0",
71
80
  "astro": ">=6.0.0",
72
81
  "vue": ">=3.4.0"
73
82
  },
@@ -2,7 +2,7 @@
2
2
  import { scv, cx } from "css-variants"
3
3
  import { twMerge } from "tailwind-merge"
4
4
  import defu from "defu"
5
- import { buttonTheme } from "@/themes/button.theme.ts"
5
+ import { buttonTheme } from "../../themes/button.theme.ts"
6
6
  import { getUIConfig } from "virtual:rimelight-ui"
7
7
 
8
8
  const button = scv({
@@ -2,7 +2,7 @@
2
2
  import { scv, cx } from "css-variants"
3
3
  import { twMerge } from "tailwind-merge"
4
4
  import defu from "defu"
5
- import { buttonTheme } from "@/themes/button.theme.ts"
5
+ import { buttonTheme } from "../../themes/button.theme.ts"
6
6
  import { getUIConfig } from "virtual:rimelight-ui"
7
7
 
8
8
  const button = scv({
@@ -60,6 +60,13 @@ const {
60
60
  href
61
61
  } = defineProps<RLVButtonProps>()
62
62
 
63
+ defineSlots<{
64
+ /**
65
+ * The default slot for the button content (e.g., text, icons).
66
+ */
67
+ default(props: {}): any
68
+ }>()
69
+
63
70
  const globalConfig = getUIConfig()
64
71
 
65
72
  const mergedUI = defu(
@@ -43,6 +43,21 @@ const {
43
43
  ui: uiProp
44
44
  } = defineProps<RLVHeaderProps>()
45
45
 
46
+ defineSlots<{
47
+ /**
48
+ * Content to display on the left side of the header (e.g., Logo).
49
+ */
50
+ left(props: {}): any
51
+ /**
52
+ * Content to display in the center of the header (e.g., Navigation Links).
53
+ */
54
+ center(props: {}): any
55
+ /**
56
+ * Content to display on the right side of the header (e.g., User Menu, Theme Toggle).
57
+ */
58
+ right(props: {}): any
59
+ }>()
60
+
46
61
  const mergedUI = useUi("header", uiProp as Record<string, unknown> | undefined)
47
62
 
48
63
  const resolvedClasses = computed(() => {
@@ -1,3 +1,5 @@
1
1
  export * from "./sri"
2
2
  export { ui } from "./ui"
3
3
  export type { UIOptions, UIConfigOverrides } from "./ui"
4
+ export { default as starlightAddons } from "../plugins/starlightAddons"
5
+ export type { StarlightAddonsConfig } from "../plugins/starlightAddons"
@@ -1,4 +1,5 @@
1
1
  import type { AstroIntegration } from "astro"
2
+ import UnoCSS from "unocss/astro"
2
3
  import vue from "@astrojs/vue"
3
4
  import uiPlugin from "@nuxt/ui/vite"
4
5
  import defu from "defu"
@@ -104,6 +105,7 @@ export function ui(options: UIOptions = {}): AstroIntegration[] {
104
105
  }
105
106
 
106
107
  return [
108
+ UnoCSS(),
107
109
  vue({
108
110
  appEntrypoint: "@rimelight/ui/integrations/vue-entrypoint"
109
111
  }),
@@ -0,0 +1,45 @@
1
+ ---
2
+ import { Tabs, TabItem } from "@astrojs/starlight/components"
3
+ import { Code as AstroCode } from "astro:components"
4
+
5
+ interface Props {
6
+ pkg: string
7
+ type?: "add" | "create" | "install" | "remove" | "run"
8
+ dev?: boolean
9
+ }
10
+
11
+ const { pkg, type = "add", dev = false } = Astro.props
12
+
13
+ const commands: Record<string, Record<string, string>> = {
14
+ npm: { add: "npm i", create: "npm create", install: "npm install", remove: "npm uninstall", run: "npm run", devOption: "-D" },
15
+ yarn: { add: "yarn add", create: "yarn create", install: "yarn install", remove: "yarn remove", run: "yarn run", devOption: "-D" },
16
+ pnpm: { add: "pnpm add", create: "pnpm create", install: "pnpm install", remove: "pnpm remove", run: "pnpm run", devOption: "-D" },
17
+ bun: { add: "bun add", create: "bun create", install: "bun install", remove: "bun remove", run: "bun run", devOption: "-d" },
18
+ }
19
+
20
+ function getCommand(manager: string, cmdType: string, pkgName: string, devFlag: boolean): string {
21
+ const mgrCmds = commands[manager]
22
+ if (!mgrCmds) return ""
23
+ let cmd = mgrCmds[cmdType]
24
+ if (!cmd) return ""
25
+ if (cmdType === "add" && devFlag && mgrCmds.devOption) cmd += " " + mgrCmds.devOption
26
+ if (pkgName && cmdType !== "install") cmd += " " + pkgName
27
+ return cmd
28
+ }
29
+
30
+ const managers = ["npm", "pnpm", "yarn", "bun"]
31
+ const singleManager = managers[0]
32
+ const command = getCommand(singleManager, type, pkg, dev)
33
+ ---
34
+
35
+ {managers.length === 1 ? (
36
+ <AstroCode code={command} lang="sh" />
37
+ ) : (
38
+ <Tabs syncKey="package-managers">
39
+ {managers.map((manager: string) => (
40
+ <TabItem label={manager}>
41
+ <AstroCode code={getCommand(manager, type, pkg, dev)} lang="sh" />
42
+ </TabItem>
43
+ ))}
44
+ </Tabs>
45
+ )}
@@ -0,0 +1,114 @@
1
+ ---
2
+ import DefaultPageTitle from "@astrojs/starlight/components/PageTitle.astro";
3
+ import config from "virtual:rimelight-starlight-addons-config";
4
+
5
+ const { copy = true, share = true } = config ?? {};
6
+
7
+ const currentUrl = Astro.url.href;
8
+ const currentTitle = (Astro.locals as any).starlightRoute?.entry?.data?.title || "";
9
+ ---
10
+
11
+ <DefaultPageTitle />
12
+ {(copy || share) && (
13
+ <div class="rl-addons">
14
+ {copy && (
15
+ <button class="rl-addon-btn" id="rl-copy-markdown" title="Copy Markdown">
16
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="14" height="14" x="8" y="8" rx="2" ry="2"/><path d="M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2"/></svg>
17
+ </button>
18
+ )}
19
+ {share && (
20
+ <button class="rl-addon-btn" id="rl-share" title="Share">
21
+ <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="18" cy="5" r="3"/><circle cx="6" cy="12" r="3"/><circle cx="18" cy="19" r="3"/><line x1="8.59" x2="15.42" y1="13.51" y2="17.49"/><line x1="15.41" x2="8.59" y1="6.51" y2="10.49"/></svg>
22
+ </button>
23
+ )}
24
+ </div>
25
+ )}
26
+
27
+ <style>
28
+ .rl-addons {
29
+ display: flex;
30
+ gap: 0.5rem;
31
+ align-items: center;
32
+ }
33
+
34
+ .rl-addon-btn {
35
+ background-color: var(--sl-color-gray-6);
36
+ color: var(--sl-color-white);
37
+ border: 1px solid var(--sl-color-gray-5);
38
+ padding: 0.5rem;
39
+ border-radius: 0.25rem;
40
+ cursor: pointer;
41
+ display: flex;
42
+ align-items: center;
43
+ justify-content: center;
44
+ transition: background-color 0.2s ease;
45
+ height: 2rem;
46
+ width: 2rem;
47
+ }
48
+
49
+ .rl-addon-btn:hover {
50
+ background-color: var(--sl-color-gray-5);
51
+ }
52
+
53
+ .rl-addon-btn:disabled {
54
+ opacity: 0.7;
55
+ cursor: not-allowed;
56
+ }
57
+ </style>
58
+
59
+ <script>
60
+ import TurndownService from "turndown";
61
+ import { gfm } from "turndown-plugin-gfm";
62
+
63
+ const turndown = new TurndownService({
64
+ headingStyle: "atx",
65
+ codeBlockStyle: "fenced",
66
+ bulletListMarker: "-",
67
+ });
68
+ turndown.use(gfm);
69
+
70
+ const copyBtn = document.getElementById("rl-copy-markdown");
71
+ const shareBtn = document.getElementById("rl-share");
72
+
73
+ if (copyBtn) {
74
+ copyBtn.addEventListener("click", async () => {
75
+ try {
76
+ copyBtn.disabled = true;
77
+ const contentEl = document.querySelector("main .sl-markdown-content");
78
+ if (!contentEl) {
79
+ throw new Error("Content not found");
80
+ }
81
+ const clone = contentEl.cloneNode(true);
82
+ clone.querySelectorAll("script, style, noscript, .sl-anchor-link, [data-pagefind-ignore]").forEach(el => el.remove());
83
+ const markdown = turndown.turndown(clone as HTMLElement);
84
+ await navigator.clipboard.writeText(markdown);
85
+ copyBtn.classList.add("copied");
86
+ setTimeout(() => copyBtn.classList.remove("copied"), 2000);
87
+ } catch (err) {
88
+ console.error("Failed to copy:", err);
89
+ } finally {
90
+ copyBtn.disabled = false;
91
+ }
92
+ });
93
+ }
94
+
95
+ if (shareBtn) {
96
+ shareBtn.addEventListener("click", async () => {
97
+ if (navigator.share) {
98
+ try {
99
+ await navigator.share({ title: document.title, url: window.location.href });
100
+ } catch (err) {
101
+ if (err.name !== "AbortError") {
102
+ console.error("Share failed:", err);
103
+ }
104
+ }
105
+ } else {
106
+ try {
107
+ await navigator.clipboard.writeText(window.location.href);
108
+ } catch (err) {
109
+ console.error("Failed to copy link:", err);
110
+ }
111
+ }
112
+ });
113
+ }
114
+ </script>
@@ -0,0 +1,69 @@
1
+ import type { StarlightPlugin } from "@astrojs/starlight/types"
2
+ import virtual from "vite-plugin-virtual"
3
+ import path from "node:path"
4
+ import { fileURLToPath } from "node:url"
5
+
6
+ const __dirname = path.dirname(fileURLToPath(import.meta.url))
7
+
8
+ export interface StarlightAddonsConfig {
9
+ copy?: boolean
10
+ share?: boolean
11
+ pkgManagers?: string[]
12
+ }
13
+
14
+ export interface PackageManagersProps {
15
+ pkg: string
16
+ type?: "add" | "create" | "install" | "remove" | "run"
17
+ dev?: boolean
18
+ }
19
+
20
+ export default function starlightAddons(userConfig?: StarlightAddonsConfig): StarlightPlugin {
21
+ const defaultConfig: StarlightAddonsConfig = {
22
+ copy: true,
23
+ share: true,
24
+ pkgManagers: ["npm"]
25
+ }
26
+
27
+ const config: StarlightAddonsConfig = {
28
+ ...defaultConfig,
29
+ ...userConfig
30
+ }
31
+
32
+ return {
33
+ name: "rimelight-ui-starlight-addons",
34
+ hooks: {
35
+ "config:setup"({ addIntegration, updateConfig, logger }) {
36
+ if (
37
+ !config.copy &&
38
+ !config.share &&
39
+ (!config.pkgManagers || config.pkgManagers.length === 0)
40
+ ) {
41
+ logger.warn("StarlightAddons: Nothing enabled.")
42
+ }
43
+
44
+ addIntegration({
45
+ name: "rimelight-ui-starlight-addons-integration",
46
+ hooks: {
47
+ "astro:config:setup": ({ updateConfig: updateAstroConfig }) => {
48
+ updateAstroConfig({
49
+ vite: {
50
+ plugins: [
51
+ virtual({
52
+ "virtual:rimelight-starlight-addons-config": `export default ${JSON.stringify(config)}`
53
+ })
54
+ ]
55
+ }
56
+ })
57
+ }
58
+ }
59
+ })
60
+
61
+ updateConfig({
62
+ components: {
63
+ PageTitle: path.join(__dirname, "PageTitle.astro")
64
+ }
65
+ })
66
+ }
67
+ }
68
+ }
69
+ }
package/src/preset.ts ADDED
@@ -0,0 +1,408 @@
1
+ import {
2
+ definePreset,
3
+ presetTypography,
4
+ presetWind4,
5
+ transformerDirectives,
6
+ transformerVariantGroup
7
+ } from "unocss"
8
+
9
+ export default definePreset(() => {
10
+ return {
11
+ name: "rimelight-ui",
12
+ presets: [
13
+ presetWind4(),
14
+ presetTypography({
15
+ cssExtend: {
16
+ "h1,h2,h3,h4,h5,h6": {
17
+ "font-family": "var(--font-sans), system-ui, sans-serif"
18
+ },
19
+ "p,li,blockquote,code": {
20
+ "font-family": "var(--font-sans), system-ui, sans-serif"
21
+ },
22
+ "pre,code": {
23
+ "font-family": "var(--font-mono), monospace"
24
+ }
25
+ }
26
+ })
27
+ ],
28
+ transformers: [transformerDirectives(), transformerVariantGroup()],
29
+
30
+ // Enable CSS Cascade Layers for better specificity control
31
+ outputToCssLayers: true,
32
+ layers: {
33
+ theme: 1,
34
+ preflights: 2,
35
+ shortcuts: 3,
36
+ default: 4
37
+ },
38
+
39
+ // Tighten content scanning for better performance
40
+ content: {
41
+ pipeline: {
42
+ include: [
43
+ /\.(vue|svelte|[jt]sx|mdx?|astro|elm|php|phtml|html)($|\?)/,
44
+ "src/**/*.{js,ts,jsx,tsx,vue,svelte,astro}",
45
+ "../ui/src/**/*.{js,ts,jsx,tsx,vue,svelte,astro}"
46
+ ]
47
+ },
48
+ filesystem: ["../ui/src/**/*", "src/components/**/*", "src/pages/**/*"]
49
+ },
50
+
51
+ shortcuts: {
52
+ // Layout & Components
53
+ "container": "mx-auto w-full max-w-90rem px-md",
54
+ "sr-only":
55
+ "absolute w-px h-px p-0 m-0 overflow-hidden clip-rect-1-1-1-1 whitespace-nowrap border-0"
56
+ },
57
+ rules: [
58
+ [
59
+ /^clip-rect-(\d+)-(\d+)-(\d+)-(\d+)$/,
60
+ ([, t, r, b, l]) => ({ clip: `rect(${t}px, ${r}px, ${b}px, ${l}px)` })
61
+ ],
62
+ [
63
+ /^([hw])-((?:6xs|5xs|4xs|3xs|2xs|xs|sm|md|lg|xl|2xl|3xl|4xl|5xl|6xl))$/,
64
+ ([, prop, s], { theme }) => {
65
+ if (!s) return
66
+ const val = (theme as { spacing?: Record<string, string> }).spacing?.[s]
67
+ if (!val) return
68
+ return prop === "h" ? { height: val } : { width: val }
69
+ }
70
+ ]
71
+ ],
72
+
73
+ theme: {
74
+ spacing: {
75
+ // 2px
76
+ "6xs": "0.125rem",
77
+ // 4px
78
+ "5xs": "0.25rem",
79
+ // 6px
80
+ "4xs": "0.375rem",
81
+ // 8px
82
+ "3xs": "0.5rem",
83
+ // 10px
84
+ "2xs": "0.625rem",
85
+ // 12px
86
+ "xs": "0.75rem",
87
+ // 14px
88
+ "sm": "0.875rem",
89
+ // 16px
90
+ "md": "1rem",
91
+ // 20px
92
+ "lg": "1.25rem",
93
+ // 24px
94
+ "xl": "1.5rem",
95
+ // 32px
96
+ "2xl": "2rem",
97
+ // 48px
98
+ "3xl": "3rem",
99
+ // 64px
100
+ "4xl": "4rem",
101
+ // 96px
102
+ "5xl": "6rem",
103
+ // 128px
104
+ "6xl": "8rem"
105
+ },
106
+ colors: {
107
+ "background": "var(--background)",
108
+ "foreground": "var(--foreground)",
109
+ "card": {
110
+ DEFAULT: "var(--card)",
111
+ foreground: "var(--card-foreground)"
112
+ },
113
+ "popover": {
114
+ DEFAULT: "var(--popover)",
115
+ foreground: "var(--popover-foreground)"
116
+ },
117
+ "primary": {
118
+ DEFAULT: "var(--primary)",
119
+ foreground: "var(--primary-foreground)",
120
+ accent: "var(--primary-accent)"
121
+ },
122
+ "secondary": {
123
+ DEFAULT: "var(--secondary)",
124
+ foreground: "var(--secondary-foreground)",
125
+ accent: "var(--secondary-accent)"
126
+ },
127
+ "muted": {
128
+ DEFAULT: "var(--muted)",
129
+ foreground: "var(--muted-foreground)"
130
+ },
131
+ "accent": {
132
+ DEFAULT: "var(--accent)",
133
+ foreground: "var(--accent-foreground)"
134
+ },
135
+ "info": {
136
+ DEFAULT: "var(--info)",
137
+ foreground: "var(--info-foreground)"
138
+ },
139
+ "success": {
140
+ DEFAULT: "var(--success)",
141
+ foreground: "var(--success-foreground)"
142
+ },
143
+ "warning": {
144
+ DEFAULT: "var(--warning)",
145
+ foreground: "var(--warning-foreground)"
146
+ },
147
+ "error": {
148
+ DEFAULT: "var(--error)",
149
+ foreground: "var(--error-foreground)"
150
+ },
151
+ "commentary": {
152
+ DEFAULT: "var(--commentary)",
153
+ foreground: "var(--commentary-foreground)"
154
+ },
155
+ "ideation": {
156
+ DEFAULT: "var(--ideation)",
157
+ foreground: "var(--ideation-foreground)"
158
+ },
159
+ "source": {
160
+ DEFAULT: "var(--source)",
161
+ foreground: "var(--source-foreground)"
162
+ },
163
+ "border": "var(--border)",
164
+ "input": "var(--input)",
165
+ "outline": "var(--outline)",
166
+ "ring": "var(--ring)",
167
+ "destructive": {
168
+ DEFAULT: "var(--destructive)",
169
+ subtle: "var(--color-destructive-subtle)"
170
+ },
171
+ "sidebar": {
172
+ DEFAULT: "var(--sidebar)",
173
+ foreground: "var(--sidebar-foreground)",
174
+ primary: {
175
+ DEFAULT: "var(--sidebar-primary)",
176
+ foreground: "var(--sidebar-primary-foreground)"
177
+ },
178
+ accent: {
179
+ DEFAULT: "var(--sidebar-accent)",
180
+ foreground: "var(--sidebar-accent-foreground)"
181
+ },
182
+ border: "var(--sidebar-border)",
183
+ ring: "var(--sidebar-ring)"
184
+ },
185
+ "chart": {
186
+ "1": "var(--chart-1)",
187
+ "2": "var(--chart-2)",
188
+ "3": "var(--chart-3)",
189
+ "4": "var(--chart-4)",
190
+ "5": "var(--chart-5)"
191
+ },
192
+ "hover": "var(--color-hover)",
193
+ "surface": "var(--color-surface)",
194
+ "muted-strong": "var(--color-muted-strong)",
195
+ "foreground-secondary": "var(--color-foreground-secondary)",
196
+ "foreground-tertiary": "var(--color-foreground-tertiary)",
197
+ "placeholder": "var(--color-placeholder)",
198
+ "input-border": "var(--color-input-border)",
199
+ "accent-subtle": "var(--color-accent-subtle)"
200
+ },
201
+ radius: {
202
+ "xs": "calc(var(--radius) - 0.375rem)",
203
+ "sm": "calc(var(--radius) - 0.25rem)",
204
+ "md": "calc(var(--radius) - 0.125rem)",
205
+ "lg": "var(--radius)",
206
+ "xl": "calc(var(--radius) + 0.25rem)",
207
+ "2xl": "calc(var(--radius) + 0.5rem)",
208
+ "3xl": "calc(var(--radius) + 1rem)"
209
+ },
210
+ animation: {
211
+ keyframes: {
212
+ "accordion-down":
213
+ "{ from { height: 0; } to { height: var(--starwind-accordion-content-height); } }",
214
+ "accordion-up":
215
+ "{ from { height: var(--starwind-accordion-content-height); } to { height: 0; } }",
216
+ "marquee": "{ from { transform: translateX(0); } to { transform: translateX(-100%); } }"
217
+ },
218
+ durations: {
219
+ "accordion-down": "0.2s",
220
+ "accordion-up": "0.2s",
221
+ "marquee": "30s"
222
+ },
223
+ timingFns: {
224
+ "accordion-down": "ease-out",
225
+ "accordion-up": "ease-out",
226
+ "marquee": "linear"
227
+ },
228
+ counts: { marquee: "infinite" }
229
+ }
230
+ },
231
+
232
+ preflights: [
233
+ {
234
+ getCSS: () => `
235
+ :root {
236
+ --background: #ffffff;
237
+ --foreground: #030712;
238
+ --card: #ffffff;
239
+ --card-foreground: #030712;
240
+ --popover: #ffffff;
241
+ --popover-foreground: #030712;
242
+ --primary: #f97316;
243
+ --primary-foreground: #f9fafb;
244
+ --primary-accent: #ea580c;
245
+ --secondary: #8b5cf6;
246
+ --secondary-foreground: #f9fafb;
247
+ --secondary-accent: #7c3aed;
248
+ --muted: #f3f4f6;
249
+ --muted-foreground: #4b5563;
250
+ --accent: #f3f4f6;
251
+ --accent-foreground: #111827;
252
+ --info: #3b82f6;
253
+ --info-foreground: #ffffff;
254
+ --success: #22c55e;
255
+ --success-foreground: #ffffff;
256
+ --warning: #f59e0b;
257
+ --warning-foreground: #000000;
258
+ --error: #ef4444;
259
+ --error-foreground: #f9fafb;
260
+ --commentary: #ec4899;
261
+ --commentary-foreground: #f9fafb;
262
+ --ideation: #8b5cf6;
263
+ --ideation-foreground: #f9fafb;
264
+ --source: #38bdf8;
265
+ --source-foreground: #0f172a;
266
+ --border: #e5e7eb;
267
+ --input: #e5e7eb;
268
+ --outline: #9ca3af;
269
+ --ring: #9ca3af;
270
+ --radius: 0.625rem;
271
+ --sidebar: #f9fafb;
272
+ --sidebar-foreground: #030712;
273
+ --sidebar-primary: #1d4ed8;
274
+ --sidebar-primary-foreground: #f9fafb;
275
+ --sidebar-accent: #f3f4f6;
276
+ --sidebar-accent-foreground: #111827;
277
+ --sidebar-border: #e5e7eb;
278
+ --sidebar-ring: #9ca3af;
279
+ --chart-1: #3b82f6;
280
+ --chart-2: #6366f1;
281
+ --chart-3: #8b5cf6;
282
+ --chart-4: #a855f7;
283
+ --chart-5: #ec4899;
284
+ --destructive: #ef4444;
285
+ --color-surface: #ffffff;
286
+ --color-muted-strong: #e5e7eb;
287
+ --color-foreground-secondary: #4b5563;
288
+ --color-foreground-tertiary: #6b7280;
289
+ --color-placeholder: #9ca3af;
290
+ --color-input-border: #d1d5db;
291
+ --color-hover: #f3f4f6;
292
+ --color-destructive-subtle: #fef2f2;
293
+ --color-accent-subtle: #eff6ff;
294
+ --font-sans: "Noto Sans", sans-serif;
295
+ --font-serif: "Noto Serif", serif;
296
+ --font-mono: "Noto Sans Mono", monospace;
297
+ }
298
+
299
+ .dark {
300
+ --background: #030712;
301
+ --foreground: #f9fafb;
302
+ --card: #111827;
303
+ --card-foreground: #f9fafb;
304
+ --popover: #1f2937;
305
+ --popover-foreground: #f9fafb;
306
+ --primary: #f97316;
307
+ --primary-foreground: #f9fafb;
308
+ --primary-accent: #fb923c;
309
+ --secondary: #8b5cf6;
310
+ --secondary-foreground: #f9fafb;
311
+ --secondary-accent: #a78bfa;
312
+ --muted: #1f2937;
313
+ --muted-foreground: #9ca3af;
314
+ --accent: #374151;
315
+ --accent-foreground: #f3f4f6;
316
+ --info: #3b82f6;
317
+ --info-foreground: #ffffff;
318
+ --success: #22c55e;
319
+ --success-foreground: #ffffff;
320
+ --warning: #f59e0b;
321
+ --warning-foreground: #000000;
322
+ --error: #ef4444;
323
+ --error-foreground: #f9fafb;
324
+ --commentary: #f472b6;
325
+ --commentary-foreground: #0f172a;
326
+ --ideation: #a78bfa;
327
+ --ideation-foreground: #0f172a;
328
+ --source: #7dd3fc;
329
+ --source-foreground: #0f172a;
330
+ --border: rgba(249, 250, 251, 0.1);
331
+ --input: rgba(249, 250, 251, 0.15);
332
+ --outline: #6b7280;
333
+ --ring: #6b7280;
334
+ --sidebar: #111827;
335
+ --sidebar-foreground: #f9fafb;
336
+ --sidebar-primary: #1d4ed8;
337
+ --sidebar-primary-foreground: #f9fafb;
338
+ --sidebar-accent: #1f2937;
339
+ --sidebar-accent-foreground: #f3f4f6;
340
+ --sidebar-border: #1f2937;
341
+ --sidebar-ring: #6b7280;
342
+ --chart-1: #60a5fa;
343
+ --chart-2: #818cf8;
344
+ --chart-3: #a78bfa;
345
+ --chart-4: #c084fc;
346
+ --chart-5: #f472b6;
347
+ --destructive: #f87171;
348
+ --color-surface: #1f2937;
349
+ --color-muted-strong: #374151;
350
+ --color-foreground-secondary: #d1d5db;
351
+ --color-foreground-tertiary: #9ca3af;
352
+ --color-placeholder: #6b7280;
353
+ --color-input-border: #4b5563;
354
+ --color-hover: #374151;
355
+ --color-destructive-subtle: #451a1a;
356
+ --color-accent-subtle: #1e293b;
357
+ }
358
+
359
+ * {
360
+ border-color: var(--border);
361
+ outline-color: rgba(156, 163, 175, 0.5);
362
+ }
363
+
364
+ body {
365
+ background-color: var(--background);
366
+ color: var(--foreground);
367
+ font-family: var(--font-sans);
368
+ }
369
+
370
+ button {
371
+ cursor: pointer;
372
+ }
373
+
374
+ ::selection {
375
+ background-color: var(--primary);
376
+ color: var(--primary-foreground);
377
+ }
378
+
379
+ @view-transition {
380
+ navigation: auto;
381
+ }
382
+ `
383
+ }
384
+ ],
385
+
386
+ async configResolved(config) {
387
+ // Only log in dev mode and only once per process
388
+ if (process.env.NODE_ENV === "development" && !process.env.UNO_CONFIG_LOGGED) {
389
+ process.env.UNO_CONFIG_LOGGED = "true"
390
+
391
+ console.log(
392
+ `[UnoCSS] Config resolved. Presets: ${config.presets.map((p) => p.name).join(", ")}`
393
+ )
394
+ console.log(`[UnoCSS] Total rules: ${config.rules.length}`)
395
+ console.log(`[UnoCSS] Total shortcuts: ${Object.keys(config.shortcuts).length}`)
396
+
397
+ // Collision Detection: Identify potential conflicting regex rules
398
+ const ruleNames = config.rules.map((r) => (Array.isArray(r) ? r[0].toString() : "dynamic"))
399
+ const duplicates = ruleNames.filter((item, index) => ruleNames.indexOf(item) !== index)
400
+ const filteredDuplicates = duplicates.filter((d) => d !== "/^(.+?)-(\\$.+)$/")
401
+
402
+ if (filteredDuplicates.length > 0) {
403
+ console.warn(`[UnoCSS] Potential Rule Collisions: ${filteredDuplicates.join(", ")}`)
404
+ }
405
+ }
406
+ }
407
+ }
408
+ })
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Theme configuration for the Button component. Defines the slots, base styles, and an extensive
3
+ * set of variants including color logic.
4
+ */
1
5
  export const buttonTheme = {
2
6
  slots: ["root"],
3
7
  base: {
@@ -1,3 +1,7 @@
1
+ /**
2
+ * Theme configuration for the Header component. Defines the slots, base styles, and variants for
3
+ * layout management.
4
+ */
1
5
  export const headerTheme = {
2
6
  slots: ["root", "container", "left", "center", "right"],
3
7
  base: {