@decido/shell 4.0.2 → 4.0.3

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.
Files changed (37) hide show
  1. package/dist/CenterComposite-RPEGBKQU.mjs +1697 -0
  2. package/dist/DebugPanel-KEKDMHDN.mjs +14 -0
  3. package/dist/MorphShell-FKDBB7E5.mjs +14 -0
  4. package/dist/PlaygroundAppSidebar-ALYJJGAO.mjs +9 -0
  5. package/dist/PlaygroundChat-MI2KXMK6.mjs +15 -0
  6. package/dist/PlaygroundTerminal-5AV4BJAI.mjs +7 -0
  7. package/dist/PluginSandbox-WMNAUQOJ.mjs +188 -0
  8. package/dist/ReactFlowEditor-RTF2652X.mjs +3574 -0
  9. package/dist/ReactFlowEditor-ZW5MCN5Y.css +561 -0
  10. package/dist/TimelineEditor-N4HRMHTB.mjs +226 -0
  11. package/dist/WidgetSlotPanel-KJI4CHHD.mjs +11 -0
  12. package/dist/chunk-2YMI4N5I.mjs +2004 -0
  13. package/dist/chunk-3BZX7LF2.mjs +139 -0
  14. package/dist/chunk-3P4P3M54.mjs +136 -0
  15. package/dist/chunk-F3OTFHNO.mjs +40 -0
  16. package/dist/chunk-IMHORBTL.mjs +48 -0
  17. package/dist/chunk-JF5QSJYT.mjs +295 -0
  18. package/dist/chunk-LWMMFTJC.mjs +382 -0
  19. package/dist/chunk-MSVEFEXE.mjs +179 -0
  20. package/dist/chunk-OCHGY2MN.mjs +1662 -0
  21. package/dist/chunk-PMYAM764.mjs +813 -0
  22. package/dist/chunk-Q64KZXPK.mjs +43 -0
  23. package/dist/chunk-QHQW2HMU.mjs +155 -0
  24. package/dist/chunk-RWZ4BOIN.mjs +385 -0
  25. package/dist/chunk-UHT6FIYF.mjs +195 -0
  26. package/dist/chunk-UJCSKKID.mjs +30 -0
  27. package/dist/chunk-V3CYNPGL.mjs +8758 -0
  28. package/dist/chunk-VBPGEFNM.mjs +2381 -0
  29. package/dist/chunk-XMSU6UWD.mjs +158 -0
  30. package/dist/chunk-ZCCCBHE6.mjs +55 -0
  31. package/dist/index.css +561 -0
  32. package/dist/index.js +65130 -0
  33. package/dist/index.mjs +40248 -0
  34. package/dist/useIntentLens-LEQCAXCK.mjs +13 -0
  35. package/dist/useSuggestionsStore-4L2AIZ2D.mjs +7 -0
  36. package/dist/wasm-QFXGEYGP.mjs +81 -0
  37. package/package.json +17 -18
@@ -0,0 +1,139 @@
1
+ // src/store/useUIComponentStore.ts
2
+ import { create } from "zustand";
3
+ import { persist } from "zustand/middleware";
4
+ var BUILT_IN_COMPONENTS = [
5
+ {
6
+ id: "builtin_status_card",
7
+ name: "Status Card",
8
+ category: "card",
9
+ schema: {
10
+ type: "div",
11
+ props: { className: "bg-zinc-900/80 border border-border-default rounded-xl p-4 backdrop-blur-xs" },
12
+ children: [
13
+ { type: "div", props: { className: "flex items-center gap-2 mb-2" }, children: [
14
+ { type: "span", props: { className: "w-2 h-2 rounded-full bg-emerald-400 animate-pulse" } },
15
+ { type: "span", props: { className: "text-xs font-mono text-text-secondary uppercase tracking-wider" }, children: "{{title}}" }
16
+ ] },
17
+ { type: "h3", props: { className: "text-2xl font-bold text-white" }, children: "{{value}}" },
18
+ { type: "p", props: { className: "text-xs text-text-muted mt-1" }, children: "{{subtitle}}" }
19
+ ]
20
+ },
21
+ dataContract: {
22
+ inputs: { title: { type: "string", description: "Card title" }, value: { type: "string", description: "Main value" }, subtitle: { type: "string", description: "Description" } },
23
+ outputs: {}
24
+ },
25
+ tags: ["status", "metric", "dashboard"],
26
+ source: "built-in",
27
+ createdAt: Date.now(),
28
+ updatedAt: Date.now()
29
+ },
30
+ {
31
+ id: "builtin_alert_banner",
32
+ name: "Alert Banner",
33
+ category: "alert",
34
+ schema: {
35
+ type: "div",
36
+ props: { className: "flex items-center gap-3 p-3 rounded-lg border border-amber-500/20 bg-amber-500/5" },
37
+ children: [
38
+ { type: "span", props: { className: "text-amber-400 text-lg" }, children: "\u26A0\uFE0F" },
39
+ { type: "div", children: [
40
+ { type: "p", props: { className: "text-sm font-semibold text-amber-200" }, children: "{{title}}" },
41
+ { type: "p", props: { className: "text-xs text-amber-300/70" }, children: "{{message}}" }
42
+ ] }
43
+ ]
44
+ },
45
+ dataContract: {
46
+ inputs: { title: { type: "string", description: "Alert title" }, message: { type: "string", description: "Alert message" } },
47
+ outputs: {}
48
+ },
49
+ tags: ["alert", "warning", "notification"],
50
+ source: "built-in",
51
+ createdAt: Date.now(),
52
+ updatedAt: Date.now()
53
+ },
54
+ {
55
+ id: "builtin_input_form",
56
+ name: "Text Input Form",
57
+ category: "form",
58
+ schema: {
59
+ type: "div",
60
+ props: { className: "bg-zinc-900/80 border border-border-default rounded-xl p-4 space-y-3" },
61
+ children: [
62
+ { type: "label", props: { className: "text-sm text-text-primary font-medium" }, children: "{{label}}" },
63
+ { type: "input", props: { className: "w-full bg-zinc-800 border border-border-default rounded-lg px-3 py-2 text-white text-sm focus:border-purple-500/50 outline-hidden transition-colors", placeholder: "{{placeholder}}" }, onAction: { command: "engine:setVariable", payload: { target: "{{variableKey}}" } } },
64
+ { type: "button", props: { className: "w-full py-2 bg-purple-500 hover:bg-purple-400 text-white text-sm font-medium rounded-lg transition-colors" }, children: "{{buttonText}}", onAction: { command: "engine:completeNode", payload: { handle: "success" } } }
65
+ ]
66
+ },
67
+ dataContract: {
68
+ inputs: { label: { type: "string", description: "Input label" }, placeholder: { type: "string", description: "Placeholder text" }, variableKey: { type: "string", description: "Target variable key" }, buttonText: { type: "string", description: "Submit button text" } },
69
+ outputs: { value: { type: "string" } }
70
+ },
71
+ tags: ["form", "input", "interactive"],
72
+ source: "built-in",
73
+ createdAt: Date.now(),
74
+ updatedAt: Date.now()
75
+ },
76
+ {
77
+ id: "builtin_data_table",
78
+ name: "Data Table",
79
+ category: "table",
80
+ schema: {
81
+ type: "div",
82
+ props: { className: "bg-zinc-900/80 border border-border-default rounded-xl overflow-hidden" },
83
+ children: [
84
+ { type: "div", props: { className: "px-4 py-3 border-b border-border-subtle" }, children: [
85
+ { type: "h4", props: { className: "text-sm font-semibold text-white" }, children: "{{title}}" }
86
+ ] },
87
+ { type: "table", props: { className: "w-full" }, children: [
88
+ { type: "thead", children: [
89
+ { type: "tr", props: { className: "text-xs text-text-muted uppercase" }, children: "{{headers}}" }
90
+ ] },
91
+ { type: "tbody", props: { className: "text-sm text-text-primary" }, children: "{{rows}}" }
92
+ ] }
93
+ ]
94
+ },
95
+ dataContract: {
96
+ inputs: { title: { type: "string", description: "Table title" }, headers: { type: "string", description: "Column headers" }, rows: { type: "string", description: "Table rows data" } },
97
+ outputs: {}
98
+ },
99
+ tags: ["table", "data", "list"],
100
+ source: "built-in",
101
+ createdAt: Date.now(),
102
+ updatedAt: Date.now()
103
+ }
104
+ ];
105
+ var useUIComponentStore = create()(
106
+ persist(
107
+ (set, get) => ({
108
+ components: Object.fromEntries(BUILT_IN_COMPONENTS.map((c) => [c.id, c])),
109
+ addComponent: (component) => set((state) => ({
110
+ components: { ...state.components, [component.id]: component }
111
+ })),
112
+ removeComponent: (id) => set((state) => {
113
+ const { [id]: _, ...rest } = state.components;
114
+ return { components: rest };
115
+ }),
116
+ updateComponent: (id, updates) => set((state) => {
117
+ const existing = state.components[id];
118
+ if (!existing) return state;
119
+ return {
120
+ components: {
121
+ ...state.components,
122
+ [id]: { ...existing, ...updates, updatedAt: Date.now() }
123
+ }
124
+ };
125
+ }),
126
+ getByCategory: (category) => {
127
+ return Object.values(get().components).filter((c) => c.category === category);
128
+ },
129
+ getBySource: (source) => {
130
+ return Object.values(get().components).filter((c) => c.source === source);
131
+ }
132
+ }),
133
+ { name: "decido-ui-components" }
134
+ )
135
+ );
136
+
137
+ export {
138
+ useUIComponentStore
139
+ };
@@ -0,0 +1,136 @@
1
+ // src/store/useDebugPanelStore.ts
2
+ import { create } from "zustand";
3
+ var MAX_LOG_ENTRIES = 500;
4
+ var _logId = 0;
5
+ var useDebugPanelStore = create((set, get) => ({
6
+ isOpen: false,
7
+ activeTab: "logs",
8
+ logEntries: [],
9
+ logFilters: {
10
+ levels: /* @__PURE__ */ new Set(["info", "warn", "error", "debug"]),
11
+ categories: /* @__PURE__ */ new Set()
12
+ },
13
+ allCategories: /* @__PURE__ */ new Set(),
14
+ errorCount: 0,
15
+ togglePanel: () => set((s) => ({ isOpen: !s.isOpen })),
16
+ setOpen: (open) => set({ isOpen: open }),
17
+ setActiveTab: (tab) => set({ activeTab: tab }),
18
+ addLogEntry: (entry) => {
19
+ const id = ++_logId;
20
+ const newEntry = { ...entry, id };
21
+ set((s) => {
22
+ const entries = [...s.logEntries, newEntry];
23
+ if (entries.length > MAX_LOG_ENTRIES) entries.splice(0, entries.length - MAX_LOG_ENTRIES);
24
+ const allCats = new Set(s.allCategories);
25
+ entry.categories.forEach((c) => allCats.add(c));
26
+ return {
27
+ logEntries: entries,
28
+ allCategories: allCats,
29
+ errorCount: entry.level === "error" ? s.errorCount + 1 : s.errorCount
30
+ };
31
+ });
32
+ },
33
+ clearLogs: () => set({ logEntries: [], errorCount: 0 }),
34
+ toggleLevel: (level) => set((s) => {
35
+ const levels = new Set(s.logFilters.levels);
36
+ if (levels.has(level)) levels.delete(level);
37
+ else levels.add(level);
38
+ return { logFilters: { ...s.logFilters, levels } };
39
+ }),
40
+ toggleCategory: (category) => set((s) => {
41
+ const categories = new Set(s.logFilters.categories);
42
+ if (categories.has(category)) categories.delete(category);
43
+ else categories.add(category);
44
+ return { logFilters: { ...s.logFilters, categories } };
45
+ }),
46
+ resetFilters: () => set({
47
+ logFilters: {
48
+ levels: /* @__PURE__ */ new Set(["info", "warn", "error", "debug"]),
49
+ categories: /* @__PURE__ */ new Set()
50
+ }
51
+ })
52
+ }));
53
+
54
+ // src/store/useActionTimelineStore.ts
55
+ import { create as create2 } from "zustand";
56
+ var MAX_EVENTS = 200;
57
+ var _evtId = 0;
58
+ var useActionTimelineStore = create2((set, get) => ({
59
+ events: [],
60
+ isPaused: false,
61
+ filter: "",
62
+ addEvent: (event) => {
63
+ if (get().isPaused) return;
64
+ const id = ++_evtId;
65
+ set((s) => {
66
+ const events = [...s.events, { ...event, id }];
67
+ return { events: events.length > MAX_EVENTS ? events.slice(-MAX_EVENTS) : events };
68
+ });
69
+ },
70
+ clear: () => set({ events: [] }),
71
+ togglePause: () => set((s) => ({ isPaused: !s.isPaused })),
72
+ setFilter: (filter) => set({ filter })
73
+ }));
74
+
75
+ // src/lib/debugLogger.ts
76
+ var _logCount = 0;
77
+ var _logResetTimer = null;
78
+ var MAX_LOGS_PER_SEC = 50;
79
+ function _getTimestamp() {
80
+ const now = /* @__PURE__ */ new Date();
81
+ return `${String(now.getHours()).padStart(2, "0")}:${String(now.getMinutes()).padStart(2, "0")}:${String(now.getSeconds()).padStart(2, "0")}.${String(now.getMilliseconds()).padStart(3, "0")}`;
82
+ }
83
+ function _emit(level, categories, message, data) {
84
+ if (_logCount >= MAX_LOGS_PER_SEC) return;
85
+ _logCount++;
86
+ if (!_logResetTimer) {
87
+ _logResetTimer = setTimeout(() => {
88
+ _logCount = 0;
89
+ _logResetTimer = null;
90
+ }, 1e3);
91
+ }
92
+ const ts = _getTimestamp();
93
+ useDebugPanelStore.getState().addLogEntry({
94
+ timestamp: ts,
95
+ level,
96
+ categories,
97
+ message,
98
+ data
99
+ });
100
+ const cat = categories[0] || "system";
101
+ const actionName = message.split(" ")[0] || message;
102
+ useActionTimelineStore.getState().addEvent({
103
+ timestamp: ts,
104
+ storeName: cat,
105
+ actionName,
106
+ data,
107
+ level: level === "debug" ? "info" : level
108
+ });
109
+ }
110
+ function _createCategoryLogger(category) {
111
+ return (message, data, level = "info") => {
112
+ _emit(level, [category], message, data);
113
+ };
114
+ }
115
+ var dlog = {
116
+ morph: _createCategoryLogger("morph"),
117
+ chat: _createCategoryLogger("chat"),
118
+ gemini: _createCategoryLogger("gemini"),
119
+ network: _createCategoryLogger("network"),
120
+ shell: _createCategoryLogger("shell"),
121
+ engine: _createCategoryLogger("engine"),
122
+ layout: _createCategoryLogger("layout"),
123
+ store: _createCategoryLogger("store"),
124
+ system: _createCategoryLogger("system"),
125
+ // Convenience: log with explicit level
126
+ info: (category, message, data) => _emit("info", [category], message, data),
127
+ warn: (category, message, data) => _emit("warn", [category], message, data),
128
+ error: (category, message, data) => _emit("error", [category], message, data),
129
+ debug: (category, message, data) => _emit("debug", [category], message, data)
130
+ };
131
+
132
+ export {
133
+ useDebugPanelStore,
134
+ useActionTimelineStore,
135
+ dlog
136
+ };
@@ -0,0 +1,40 @@
1
+ // src/store/useSuggestionsStore.ts
2
+ import { create } from "zustand";
3
+ import { persist } from "zustand/middleware";
4
+ var useSuggestionsStore = create()(
5
+ persist(
6
+ (set, get) => ({
7
+ seeds: [
8
+ "Expl\xEDcame c\xF3mo funciona este flujo",
9
+ "Crea un grafo de onboarding",
10
+ "Analiza el rendimiento del sistema"
11
+ ],
12
+ generated: [],
13
+ pluginSuggestions: {},
14
+ addSeed: (seed) => set((s) => ({ seeds: [...s.seeds, seed] })),
15
+ removeSeed: (index) => set((s) => ({ seeds: s.seeds.filter((_, i) => i !== index) })),
16
+ updateSeed: (index, value) => set((s) => ({
17
+ seeds: s.seeds.map((seed, i) => i === index ? value : seed)
18
+ })),
19
+ setGenerated: (suggestions) => set({ generated: suggestions }),
20
+ registerPluginSuggestions: (pluginId, items) => set((s) => ({
21
+ pluginSuggestions: { ...s.pluginSuggestions, [pluginId]: items }
22
+ })),
23
+ unregisterPluginSuggestions: (pluginId) => set((s) => {
24
+ const next = { ...s.pluginSuggestions };
25
+ delete next[pluginId];
26
+ return { pluginSuggestions: next };
27
+ }),
28
+ getAllSuggestions: () => {
29
+ const s = get();
30
+ const plugin = Object.values(s.pluginSuggestions).flat();
31
+ return [...s.generated, ...s.seeds, ...plugin];
32
+ }
33
+ }),
34
+ { name: "decido-suggestions-store" }
35
+ )
36
+ );
37
+
38
+ export {
39
+ useSuggestionsStore
40
+ };
@@ -0,0 +1,48 @@
1
+ // src/store/useShellRegistry.ts
2
+ import React from "react";
3
+ var shellMetaRegistry = /* @__PURE__ */ new Map();
4
+ var DEFAULT_SHELL_META = {
5
+ "markdown": { icon: "\u{1F4DD}", color: "#10b981", label: "Markdown" },
6
+ "iframe": { icon: "\u{1F5A5}\uFE0F", color: "#6b7280", label: "iFrame" },
7
+ "nexusai-preview": { icon: "\u{1F310}", color: "#3b82f6", label: "Web Preview" },
8
+ "shell-vscode": { icon: "\u{1F4BB}", color: "#007acc", label: "VS Code" },
9
+ "shell-canvas": { icon: "\u{1F5BC}\uFE0F", color: "#f59e0b", label: "Canvas" },
10
+ "shell-theme-editor": { icon: "\u{1F3A8}", color: "#a855f7", label: "Theme Editor" }
11
+ };
12
+ var shellRegistry = /* @__PURE__ */ new Map();
13
+ function registerShell(type, component, meta) {
14
+ shellRegistry.set(type, component);
15
+ if (meta) shellMetaRegistry.set(type, meta);
16
+ else if (DEFAULT_SHELL_META[type]) shellMetaRegistry.set(type, DEFAULT_SHELL_META[type]);
17
+ }
18
+ function resolveShell(type) {
19
+ return shellRegistry.get(type);
20
+ }
21
+ function isShellRegistered(type) {
22
+ return shellRegistry.has(type);
23
+ }
24
+ function getRegisteredShellTypes() {
25
+ return Array.from(shellRegistry.keys());
26
+ }
27
+ function getShellMeta(type) {
28
+ return shellMetaRegistry.get(type) || { icon: "\u{1F4E6}", color: "#71717a", label: type };
29
+ }
30
+ function registerMorphComponentCompat(id, component) {
31
+ const WrappedComponent = (props) => {
32
+ return React.createElement(component, { ...props.data || {}, ...props });
33
+ };
34
+ shellRegistry.set(id, WrappedComponent);
35
+ }
36
+ function getMorphComponentCompat(id) {
37
+ return shellRegistry.get(id);
38
+ }
39
+
40
+ export {
41
+ registerShell,
42
+ resolveShell,
43
+ isShellRegistered,
44
+ getRegisteredShellTypes,
45
+ getShellMeta,
46
+ registerMorphComponentCompat,
47
+ getMorphComponentCompat
48
+ };
@@ -0,0 +1,295 @@
1
+ // src/store/useThemeStore.ts
2
+ import { create } from "zustand";
3
+ import { persist } from "zustand/middleware";
4
+ var DEFAULT_META = {
5
+ "radius-xs": "4px",
6
+ "radius-sm": "6px",
7
+ "radius-md": "10px",
8
+ "radius-lg": "16px",
9
+ "radius-xl": "24px",
10
+ "blur-xs": "4px",
11
+ "blur-sm": "8px",
12
+ "blur-md": "16px",
13
+ "blur-lg": "24px",
14
+ "blur-xl": "40px",
15
+ "font-sans": "'Inter', 'system-ui', sans-serif",
16
+ "font-mono": "'JetBrains Mono', 'Fira Code', monospace"
17
+ };
18
+ var THEME_DECIDO_DARK = {
19
+ id: "decido-dark",
20
+ name: "Decido Dark",
21
+ description: "Tema por defecto \u2014 oscuro con acentos p\xFArpura y cyan",
22
+ preview: { bg: "#0a0a0f", accent: "#a855f7", text: "#e8e8f0" },
23
+ tokens: {
24
+ "surface-primary": "#0a0a0f",
25
+ "surface-secondary": "#12121a",
26
+ "surface-tertiary": "#1a1a26",
27
+ "surface-elevated": "#22222e",
28
+ "surface-glass": "rgba(255, 255, 255, 0.03)",
29
+ "surface-overlay": "rgba(0, 0, 0, 0.6)",
30
+ "text-primary": "#e8e8f0",
31
+ "text-secondary": "#9898b0",
32
+ "text-muted": "#5a5a72",
33
+ "text-inverse": "#0a0a0f",
34
+ "accent-blue": "#4a9eff",
35
+ "accent-purple": "#a855f7",
36
+ "accent-green": "#34d399",
37
+ "accent-red": "#f87171",
38
+ "accent-amber": "#fbbf24",
39
+ "accent-cyan": "#22d3ee",
40
+ "border-subtle": "rgba(255, 255, 255, 0.06)",
41
+ "border-default": "rgba(255, 255, 255, 0.1)",
42
+ "border-strong": "rgba(255, 255, 255, 0.2)",
43
+ "border-glow": "rgba(168, 85, 247, 0.5)",
44
+ "status-ok": "#34d399",
45
+ "status-warn": "#fbbf24",
46
+ "status-error": "#f87171",
47
+ "status-info": "#4a9eff"
48
+ },
49
+ meta: DEFAULT_META
50
+ };
51
+ var THEME_MIDNIGHT_BLUE = {
52
+ id: "midnight-blue",
53
+ name: "Midnight Blue",
54
+ description: "Azul profundo con tonos slate",
55
+ preview: { bg: "#0b1120", accent: "#3b82f6", text: "#f1f5f9" },
56
+ tokens: {
57
+ "surface-primary": "#0b1120",
58
+ "surface-secondary": "#111827",
59
+ "surface-tertiary": "#1e293b",
60
+ "surface-elevated": "#273548",
61
+ "surface-glass": "rgba(30, 41, 59, 0.5)",
62
+ "surface-overlay": "rgba(11, 17, 32, 0.7)",
63
+ "text-primary": "#f1f5f9",
64
+ "text-secondary": "#94a3b8",
65
+ "text-muted": "#64748b",
66
+ "text-inverse": "#0b1120",
67
+ "accent-blue": "#3b82f6",
68
+ "accent-purple": "#8b5cf6",
69
+ "accent-green": "#22c55e",
70
+ "accent-red": "#ef4444",
71
+ "accent-amber": "#f59e0b",
72
+ "accent-cyan": "#06b6d4",
73
+ "border-subtle": "rgba(148, 163, 184, 0.06)",
74
+ "border-default": "rgba(148, 163, 184, 0.12)",
75
+ "border-strong": "rgba(148, 163, 184, 0.25)",
76
+ "border-glow": "rgba(59, 130, 246, 0.5)",
77
+ "status-ok": "#22c55e",
78
+ "status-warn": "#f59e0b",
79
+ "status-error": "#ef4444",
80
+ "status-info": "#3b82f6"
81
+ },
82
+ meta: DEFAULT_META
83
+ };
84
+ var THEME_EMERALD_NOIR = {
85
+ id: "emerald-noir",
86
+ name: "Emerald Noir",
87
+ description: "Oscuro con acentos esmeralda",
88
+ preview: { bg: "#0a0f0d", accent: "#34d399", text: "#ecfdf5" },
89
+ tokens: {
90
+ "surface-primary": "#0a0f0d",
91
+ "surface-secondary": "#0f1a15",
92
+ "surface-tertiary": "#162620",
93
+ "surface-elevated": "#1e332b",
94
+ "surface-glass": "rgba(22, 38, 32, 0.5)",
95
+ "surface-overlay": "rgba(10, 15, 13, 0.7)",
96
+ "text-primary": "#ecfdf5",
97
+ "text-secondary": "#a7f3d0",
98
+ "text-muted": "#6ee7b7",
99
+ "text-inverse": "#0a0f0d",
100
+ "accent-blue": "#2dd4bf",
101
+ "accent-purple": "#a78bfa",
102
+ "accent-green": "#34d399",
103
+ "accent-red": "#fb7185",
104
+ "accent-amber": "#fbbf24",
105
+ "accent-cyan": "#2dd4bf",
106
+ "border-subtle": "rgba(167, 243, 208, 0.06)",
107
+ "border-default": "rgba(167, 243, 208, 0.12)",
108
+ "border-strong": "rgba(167, 243, 208, 0.25)",
109
+ "border-glow": "rgba(52, 211, 153, 0.5)",
110
+ "status-ok": "#34d399",
111
+ "status-warn": "#fbbf24",
112
+ "status-error": "#fb7185",
113
+ "status-info": "#2dd4bf"
114
+ },
115
+ meta: DEFAULT_META
116
+ };
117
+ var THEME_ROSE_GOLD = {
118
+ id: "rose-gold",
119
+ name: "Rose Gold",
120
+ description: "Elegante con tonos rosa y dorado",
121
+ preview: { bg: "#120a0d", accent: "#f472b6", text: "#fdf2f8" },
122
+ tokens: {
123
+ "surface-primary": "#120a0d",
124
+ "surface-secondary": "#1a1015",
125
+ "surface-tertiary": "#26161e",
126
+ "surface-elevated": "#331c28",
127
+ "surface-glass": "rgba(38, 22, 30, 0.5)",
128
+ "surface-overlay": "rgba(18, 10, 13, 0.7)",
129
+ "text-primary": "#fdf2f8",
130
+ "text-secondary": "#f9a8d4",
131
+ "text-muted": "#f472b6",
132
+ "text-inverse": "#120a0d",
133
+ "accent-blue": "#e879f9",
134
+ "accent-purple": "#f472b6",
135
+ "accent-green": "#34d399",
136
+ "accent-red": "#fb7185",
137
+ "accent-amber": "#fcd34d",
138
+ "accent-cyan": "#e879f9",
139
+ "border-subtle": "rgba(249, 168, 212, 0.06)",
140
+ "border-default": "rgba(249, 168, 212, 0.12)",
141
+ "border-strong": "rgba(249, 168, 212, 0.25)",
142
+ "border-glow": "rgba(244, 114, 182, 0.5)",
143
+ "status-ok": "#34d399",
144
+ "status-warn": "#fcd34d",
145
+ "status-error": "#fb7185",
146
+ "status-info": "#e879f9"
147
+ },
148
+ meta: DEFAULT_META
149
+ };
150
+ var THEME_OLED_PURE = {
151
+ id: "oled-pure",
152
+ name: "OLED Pure",
153
+ description: "Negro absoluto para pantallas OLED",
154
+ preview: { bg: "#000000", accent: "#a855f7", text: "#ffffff" },
155
+ tokens: {
156
+ "surface-primary": "#000000",
157
+ "surface-secondary": "#0a0a0a",
158
+ "surface-tertiary": "#141414",
159
+ "surface-elevated": "#1e1e1e",
160
+ "surface-glass": "rgba(255, 255, 255, 0.02)",
161
+ "surface-overlay": "rgba(0, 0, 0, 0.8)",
162
+ "text-primary": "#ffffff",
163
+ "text-secondary": "#a0a0a0",
164
+ "text-muted": "#666666",
165
+ "text-inverse": "#000000",
166
+ "accent-blue": "#4a9eff",
167
+ "accent-purple": "#a855f7",
168
+ "accent-green": "#34d399",
169
+ "accent-red": "#f87171",
170
+ "accent-amber": "#fbbf24",
171
+ "accent-cyan": "#22d3ee",
172
+ "border-subtle": "rgba(255, 255, 255, 0.04)",
173
+ "border-default": "rgba(255, 255, 255, 0.08)",
174
+ "border-strong": "rgba(255, 255, 255, 0.15)",
175
+ "border-glow": "rgba(168, 85, 247, 0.5)",
176
+ "status-ok": "#4ade80",
177
+ "status-warn": "#fbbf24",
178
+ "status-error": "#f87171",
179
+ "status-info": "#4a9eff"
180
+ },
181
+ meta: DEFAULT_META
182
+ };
183
+ var THEME_DECIDO_LIGHT = {
184
+ id: "decido-light",
185
+ name: "Decido Light",
186
+ description: "Tema claro premium \u2014 ideal para trabajo diurno",
187
+ preview: { bg: "#f8f9fb", accent: "#6366f1", text: "#1a1a2e" },
188
+ tokens: {
189
+ "surface-primary": "#f8f9fb",
190
+ "surface-secondary": "#ffffff",
191
+ "surface-tertiary": "#eef0f4",
192
+ "surface-elevated": "#ffffff",
193
+ "surface-glass": "rgba(0, 0, 0, 0.03)",
194
+ "surface-overlay": "rgba(0, 0, 0, 0.4)",
195
+ "text-primary": "#1a1a2e",
196
+ "text-secondary": "#64648c",
197
+ "text-muted": "#9898b0",
198
+ "text-inverse": "#ffffff",
199
+ "accent-blue": "#3b82f6",
200
+ "accent-purple": "#6366f1",
201
+ "accent-green": "#10b981",
202
+ "accent-red": "#ef4444",
203
+ "accent-amber": "#f59e0b",
204
+ "accent-cyan": "#06b6d4",
205
+ "border-subtle": "rgba(0, 0, 0, 0.06)",
206
+ "border-default": "rgba(0, 0, 0, 0.12)",
207
+ "border-strong": "rgba(0, 0, 0, 0.2)",
208
+ "border-glow": "rgba(99, 102, 241, 0.4)",
209
+ "status-ok": "#10b981",
210
+ "status-warn": "#f59e0b",
211
+ "status-error": "#ef4444",
212
+ "status-info": "#3b82f6"
213
+ },
214
+ meta: DEFAULT_META
215
+ };
216
+ var THEME_PRESETS = [
217
+ THEME_DECIDO_DARK,
218
+ THEME_DECIDO_LIGHT,
219
+ THEME_MIDNIGHT_BLUE,
220
+ THEME_EMERALD_NOIR,
221
+ THEME_ROSE_GOLD,
222
+ THEME_OLED_PURE
223
+ ];
224
+ function injectTokens(tokens, meta) {
225
+ const root = document.documentElement;
226
+ Object.entries(tokens).forEach(([key, value]) => {
227
+ root.style.setProperty(`--ds-${key}`, value);
228
+ });
229
+ Object.entries(meta).forEach(([key, value]) => {
230
+ root.style.setProperty(`--ds-${key}`, value);
231
+ });
232
+ }
233
+ var useTheme = create()(
234
+ persist(
235
+ (set, get) => ({
236
+ currentThemeId: "decido-dark",
237
+ customPresets: [],
238
+ setTheme: (themeId) => {
239
+ set({ currentThemeId: themeId });
240
+ const preset = get().getCurrentPreset();
241
+ injectTokens(preset.tokens, preset.meta);
242
+ },
243
+ setToken: (name, value) => {
244
+ document.documentElement.style.setProperty(`--ds-${name}`, value);
245
+ },
246
+ addPreset: (preset) => {
247
+ set((s) => ({
248
+ customPresets: [...s.customPresets.filter((p) => p.id !== preset.id), preset]
249
+ }));
250
+ },
251
+ inject: () => {
252
+ const preset = get().getCurrentPreset();
253
+ injectTokens(preset.tokens, preset.meta);
254
+ },
255
+ exportCSS: () => {
256
+ const preset = get().getCurrentPreset();
257
+ const lines = [`:root {`];
258
+ Object.entries(preset.tokens).forEach(([k, v]) => {
259
+ lines.push(` --ds-${k}: ${v};`);
260
+ });
261
+ Object.entries(preset.meta).forEach(([k, v]) => {
262
+ lines.push(` --ds-${k}: ${v};`);
263
+ });
264
+ lines.push(`}`);
265
+ return lines.join("\n");
266
+ },
267
+ getCurrentPreset: () => {
268
+ const { currentThemeId, customPresets } = get();
269
+ return [...THEME_PRESETS, ...customPresets].find((p) => p.id === currentThemeId) ?? THEME_DECIDO_DARK;
270
+ },
271
+ getAllPresets: () => {
272
+ return [...THEME_PRESETS, ...get().customPresets];
273
+ }
274
+ }),
275
+ {
276
+ name: "decido-aura-theme",
277
+ onRehydrateStorage: () => (state) => {
278
+ if (state) {
279
+ setTimeout(() => state.inject(), 0);
280
+ }
281
+ }
282
+ }
283
+ )
284
+ );
285
+
286
+ export {
287
+ THEME_DECIDO_DARK,
288
+ THEME_MIDNIGHT_BLUE,
289
+ THEME_EMERALD_NOIR,
290
+ THEME_ROSE_GOLD,
291
+ THEME_OLED_PURE,
292
+ THEME_DECIDO_LIGHT,
293
+ THEME_PRESETS,
294
+ useTheme
295
+ };