@thewhateverapp/tile-sdk 0.13.31 → 0.13.33

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 (102) hide show
  1. package/dist/react/index.d.ts.map +1 -1
  2. package/dist/react/index.js +1 -0
  3. package/dist/spec/host/OverlayHost.d.ts +68 -0
  4. package/dist/spec/host/OverlayHost.d.ts.map +1 -0
  5. package/dist/spec/host/OverlayHost.js +143 -0
  6. package/dist/spec/host/index.d.ts +7 -0
  7. package/dist/spec/host/index.d.ts.map +1 -0
  8. package/dist/spec/host/index.js +6 -0
  9. package/dist/spec/index.d.ts +29 -0
  10. package/dist/spec/index.d.ts.map +1 -0
  11. package/dist/spec/index.js +81 -0
  12. package/dist/spec/registry/ComponentRegistry.d.ts +208 -0
  13. package/dist/spec/registry/ComponentRegistry.d.ts.map +1 -0
  14. package/dist/spec/registry/ComponentRegistry.js +227 -0
  15. package/dist/spec/registry/composites/BottomSheet.d.ts +33 -0
  16. package/dist/spec/registry/composites/BottomSheet.d.ts.map +1 -0
  17. package/dist/spec/registry/composites/BottomSheet.js +98 -0
  18. package/dist/spec/registry/composites/CountdownCTA.d.ts +35 -0
  19. package/dist/spec/registry/composites/CountdownCTA.d.ts.map +1 -0
  20. package/dist/spec/registry/composites/CountdownCTA.js +91 -0
  21. package/dist/spec/registry/composites/Poll.d.ts +39 -0
  22. package/dist/spec/registry/composites/Poll.d.ts.map +1 -0
  23. package/dist/spec/registry/composites/Poll.js +76 -0
  24. package/dist/spec/registry/composites/Prediction.d.ts +37 -0
  25. package/dist/spec/registry/composites/Prediction.d.ts.map +1 -0
  26. package/dist/spec/registry/composites/Prediction.js +116 -0
  27. package/dist/spec/registry/composites/index.d.ts +33 -0
  28. package/dist/spec/registry/composites/index.d.ts.map +1 -0
  29. package/dist/spec/registry/composites/index.js +36 -0
  30. package/dist/spec/registry/index.d.ts +15 -0
  31. package/dist/spec/registry/index.d.ts.map +1 -0
  32. package/dist/spec/registry/index.js +24 -0
  33. package/dist/spec/registry/primitives/Button.d.ts +30 -0
  34. package/dist/spec/registry/primitives/Button.d.ts.map +1 -0
  35. package/dist/spec/registry/primitives/Button.js +62 -0
  36. package/dist/spec/registry/primitives/Divider.d.ts +22 -0
  37. package/dist/spec/registry/primitives/Divider.d.ts.map +1 -0
  38. package/dist/spec/registry/primitives/Divider.js +56 -0
  39. package/dist/spec/registry/primitives/Image.d.ts +27 -0
  40. package/dist/spec/registry/primitives/Image.d.ts.map +1 -0
  41. package/dist/spec/registry/primitives/Image.js +36 -0
  42. package/dist/spec/registry/primitives/ProgressBar.d.ts +28 -0
  43. package/dist/spec/registry/primitives/ProgressBar.d.ts.map +1 -0
  44. package/dist/spec/registry/primitives/ProgressBar.js +50 -0
  45. package/dist/spec/registry/primitives/Row.d.ts +26 -0
  46. package/dist/spec/registry/primitives/Row.d.ts.map +1 -0
  47. package/dist/spec/registry/primitives/Row.js +50 -0
  48. package/dist/spec/registry/primitives/Spacer.d.ts +18 -0
  49. package/dist/spec/registry/primitives/Spacer.d.ts.map +1 -0
  50. package/dist/spec/registry/primitives/Spacer.js +25 -0
  51. package/dist/spec/registry/primitives/Stack.d.ts +22 -0
  52. package/dist/spec/registry/primitives/Stack.d.ts.map +1 -0
  53. package/dist/spec/registry/primitives/Stack.js +41 -0
  54. package/dist/spec/registry/primitives/Text.d.ts +26 -0
  55. package/dist/spec/registry/primitives/Text.d.ts.map +1 -0
  56. package/dist/spec/registry/primitives/Text.js +33 -0
  57. package/dist/spec/registry/primitives/index.d.ts +45 -0
  58. package/dist/spec/registry/primitives/index.d.ts.map +1 -0
  59. package/dist/spec/registry/primitives/index.js +55 -0
  60. package/dist/spec/renderer/BindingResolver.d.ts +35 -0
  61. package/dist/spec/renderer/BindingResolver.d.ts.map +1 -0
  62. package/dist/spec/renderer/BindingResolver.js +131 -0
  63. package/dist/spec/renderer/CaptionTrack.d.ts +22 -0
  64. package/dist/spec/renderer/CaptionTrack.d.ts.map +1 -0
  65. package/dist/spec/renderer/CaptionTrack.js +83 -0
  66. package/dist/spec/renderer/LayoutRenderer.d.ts +24 -0
  67. package/dist/spec/renderer/LayoutRenderer.d.ts.map +1 -0
  68. package/dist/spec/renderer/LayoutRenderer.js +66 -0
  69. package/dist/spec/renderer/OverlayCue.d.ts +20 -0
  70. package/dist/spec/renderer/OverlayCue.d.ts.map +1 -0
  71. package/dist/spec/renderer/OverlayCue.js +161 -0
  72. package/dist/spec/renderer/index.d.ts +10 -0
  73. package/dist/spec/renderer/index.d.ts.map +1 -0
  74. package/dist/spec/renderer/index.js +13 -0
  75. package/dist/spec/runtime/ActionRouter.d.ts +33 -0
  76. package/dist/spec/runtime/ActionRouter.d.ts.map +1 -0
  77. package/dist/spec/runtime/ActionRouter.js +84 -0
  78. package/dist/spec/runtime/OverlayRuntime.d.ts +84 -0
  79. package/dist/spec/runtime/OverlayRuntime.d.ts.map +1 -0
  80. package/dist/spec/runtime/OverlayRuntime.js +216 -0
  81. package/dist/spec/runtime/StateManager.d.ts +31 -0
  82. package/dist/spec/runtime/StateManager.d.ts.map +1 -0
  83. package/dist/spec/runtime/StateManager.js +60 -0
  84. package/dist/spec/runtime/TimeSync.d.ts +47 -0
  85. package/dist/spec/runtime/TimeSync.d.ts.map +1 -0
  86. package/dist/spec/runtime/TimeSync.js +140 -0
  87. package/dist/spec/runtime/index.d.ts +10 -0
  88. package/dist/spec/runtime/index.d.ts.map +1 -0
  89. package/dist/spec/runtime/index.js +13 -0
  90. package/dist/spec/schema.d.ts +889 -0
  91. package/dist/spec/schema.d.ts.map +1 -0
  92. package/dist/spec/schema.js +284 -0
  93. package/dist/spec/theme/ThemeProvider.d.ts +151 -0
  94. package/dist/spec/theme/ThemeProvider.d.ts.map +1 -0
  95. package/dist/spec/theme/ThemeProvider.js +227 -0
  96. package/dist/spec/theme/index.d.ts +7 -0
  97. package/dist/spec/theme/index.d.ts.map +1 -0
  98. package/dist/spec/theme/index.js +12 -0
  99. package/dist/spec/types.d.ts +322 -0
  100. package/dist/spec/types.d.ts.map +1 -0
  101. package/dist/spec/types.js +36 -0
  102. package/package.json +8 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/spec/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,284 @@
1
+ /**
2
+ * Overlay Spec Zod Schema
3
+ *
4
+ * Validates spec JSON at runtime for safety and error reporting.
5
+ */
6
+ import { z } from 'zod';
7
+ // =============================================================================
8
+ // Primitive Schemas
9
+ // =============================================================================
10
+ const SizeSchema = z.enum(['xs', 'sm', 'md', 'lg', 'xl', '2xl']);
11
+ const WeightSchema = z.enum(['normal', 'medium', 'semibold', 'bold']);
12
+ const ColorSchema = z.enum(['primary', 'secondary', 'success', 'warning', 'error', 'muted', 'white', 'black']);
13
+ const VariantSchema = z.enum(['solid', 'outline', 'ghost', 'link']);
14
+ const AlignSchema = z.enum(['left', 'center', 'right']);
15
+ const JustifySchema = z.enum(['start', 'center', 'end', 'between', 'around']);
16
+ // =============================================================================
17
+ // Binding Schema
18
+ // =============================================================================
19
+ const BindingSchema = z.object({
20
+ $bind: z.string(),
21
+ fallback: z.unknown().optional(),
22
+ format: z.string().optional(),
23
+ });
24
+ // =============================================================================
25
+ // Action Schema
26
+ // =============================================================================
27
+ const ActionTypeSchema = z.enum([
28
+ 'emit',
29
+ 'setState',
30
+ 'sequence',
31
+ 'openTile',
32
+ 'openFull',
33
+ 'navigate',
34
+ 'dismiss',
35
+ 'fx',
36
+ ]);
37
+ const ActionSchema = z.object({
38
+ $action: ActionTypeSchema,
39
+ payload: z.record(z.unknown()).optional(),
40
+ });
41
+ // =============================================================================
42
+ // Prop Value Schema (recursive)
43
+ // =============================================================================
44
+ const PropValueSchema = z.lazy(() => z.union([
45
+ z.string(),
46
+ z.number(),
47
+ z.boolean(),
48
+ z.null(),
49
+ BindingSchema,
50
+ ActionSchema,
51
+ z.array(PropValueSchema),
52
+ z.record(PropValueSchema),
53
+ ]));
54
+ // =============================================================================
55
+ // Condition Schema (recursive)
56
+ // =============================================================================
57
+ const ConditionSchema = z.lazy(() => z.union([
58
+ // Binding condition
59
+ z.object({ $bind: z.string() }),
60
+ // Comparison condition
61
+ z.object({
62
+ op: z.enum(['eq', 'neq', 'gt', 'gte', 'lt', 'lte', 'in', 'notIn']),
63
+ left: PropValueSchema,
64
+ right: PropValueSchema,
65
+ }),
66
+ // Logical condition
67
+ z.object({
68
+ op: z.enum(['and', 'or', 'not']),
69
+ conditions: z.array(ConditionSchema),
70
+ }),
71
+ ]));
72
+ // =============================================================================
73
+ // Sync Configuration
74
+ // =============================================================================
75
+ const TimeTransformSchema = z.object({
76
+ offsetMs: z.number().optional(),
77
+ scale: z.number().optional(),
78
+ });
79
+ const SyncConfigSchema = z.object({
80
+ timebase: z.enum(['player', 'wallClock']),
81
+ tick: z.enum(['raf', 'timeupdate']),
82
+ toleranceMs: z.number().min(0).max(1000),
83
+ onSeek: z.literal('recompute'),
84
+ transform: TimeTransformSchema.optional(),
85
+ freezeWhen: ConditionSchema.optional(),
86
+ });
87
+ // =============================================================================
88
+ // State Configuration
89
+ // =============================================================================
90
+ const StateConfigSchema = z.object({
91
+ local: z.record(z.unknown()),
92
+ });
93
+ // =============================================================================
94
+ // Caption Track
95
+ // =============================================================================
96
+ const CaptionSegmentSchema = z.object({
97
+ startMs: z.number().min(0),
98
+ endMs: z.number().min(0),
99
+ text: z.string(),
100
+ speaker: z.string().optional(),
101
+ });
102
+ const CaptionStyleSchema = z.object({
103
+ position: z.enum(['top', 'bottom', 'center']),
104
+ size: SizeSchema,
105
+ background: z.enum(['none', 'solid', 'gradient']).optional(),
106
+ color: z.string().optional(),
107
+ });
108
+ const CaptionTrackSchema = z.object({
109
+ segments: z.array(CaptionSegmentSchema),
110
+ style: CaptionStyleSchema,
111
+ });
112
+ // =============================================================================
113
+ // Layout Node (recursive)
114
+ // =============================================================================
115
+ const LayoutNodeSchema = z.lazy(() => z.object({
116
+ type: z.string().min(1),
117
+ props: z.record(PropValueSchema).optional(),
118
+ children: z.array(LayoutNodeSchema).optional(),
119
+ key: z.string().optional(),
120
+ }));
121
+ // =============================================================================
122
+ // Placement
123
+ // =============================================================================
124
+ const TilePlacementSchema = z.object({
125
+ lane: z.enum(['top', 'center', 'bottom']),
126
+ inset: z.number().optional(),
127
+ align: AlignSchema.optional(),
128
+ });
129
+ const FullPlacementSchema = z.object({
130
+ type: z.enum(['fullscreen', 'inset', 'positioned']),
131
+ insets: z
132
+ .object({
133
+ top: z.number().optional(),
134
+ right: z.number().optional(),
135
+ bottom: z.number().optional(),
136
+ left: z.number().optional(),
137
+ })
138
+ .optional(),
139
+ position: z
140
+ .object({
141
+ x: z.union([z.number(), z.string()]),
142
+ y: z.union([z.number(), z.string()]),
143
+ })
144
+ .optional(),
145
+ });
146
+ const PlacementSchema = z.union([TilePlacementSchema, FullPlacementSchema]);
147
+ // =============================================================================
148
+ // Dismiss Policy
149
+ // =============================================================================
150
+ const DismissTriggerSchema = z.enum([
151
+ 'tap-outside',
152
+ 'swipe-down',
153
+ 'timeout',
154
+ 'action',
155
+ 'time-window-end',
156
+ ]);
157
+ const DismissPolicySchema = z.object({
158
+ on: z.array(DismissTriggerSchema),
159
+ animation: z.enum(['fade', 'slide', 'none']).optional(),
160
+ durationMs: z.number().min(0).optional(),
161
+ });
162
+ // =============================================================================
163
+ // Time Window
164
+ // =============================================================================
165
+ const TimeWindowSchema = z.object({
166
+ startMs: z.number().min(0).optional(),
167
+ endMs: z.number().min(0).optional(),
168
+ });
169
+ // =============================================================================
170
+ // Overlay Cue
171
+ // =============================================================================
172
+ const OverlayCueSchema = z.object({
173
+ id: z.string().min(1),
174
+ window: TimeWindowSchema,
175
+ visibleWhen: ConditionSchema.optional(),
176
+ placement: PlacementSchema,
177
+ dismiss: DismissPolicySchema.optional(),
178
+ layout: LayoutNodeSchema,
179
+ zIndex: z.number().optional(),
180
+ });
181
+ // =============================================================================
182
+ // Tracks Configuration
183
+ // =============================================================================
184
+ const TracksConfigSchema = z.object({
185
+ captions: CaptionTrackSchema.optional(),
186
+ overlays: z.array(OverlayCueSchema),
187
+ });
188
+ // =============================================================================
189
+ // Subscription Declaration
190
+ // =============================================================================
191
+ const SubscriptionDeclarationSchema = z.object({
192
+ id: z.string().min(1),
193
+ type: z.enum(['realtime', 'keyspace', 'host']),
194
+ channel: z.string().min(1),
195
+ target: z.string().min(1),
196
+ transform: z.string().optional(),
197
+ });
198
+ // =============================================================================
199
+ // Spec Metadata
200
+ // =============================================================================
201
+ const SpecMetaSchema = z.object({
202
+ title: z.string().optional(),
203
+ author: z.string().optional(),
204
+ description: z.string().optional(),
205
+ version: z.string().optional(),
206
+ });
207
+ // =============================================================================
208
+ // Main Overlay Spec Schema
209
+ // =============================================================================
210
+ export const OverlaySpecSchema = z.object({
211
+ specVersion: z.literal('1.0'),
212
+ id: z.string().min(1),
213
+ surface: z.enum(['tile', 'full']),
214
+ meta: SpecMetaSchema.optional(),
215
+ sync: SyncConfigSchema,
216
+ state: StateConfigSchema,
217
+ tracks: TracksConfigSchema,
218
+ subscriptions: z.array(SubscriptionDeclarationSchema).optional(),
219
+ });
220
+ // =============================================================================
221
+ // Validation Functions
222
+ // =============================================================================
223
+ export function validateSpec(spec) {
224
+ const result = OverlaySpecSchema.safeParse(spec);
225
+ if (result.success) {
226
+ return { success: true, data: result.data };
227
+ }
228
+ return { success: false, errors: result.error };
229
+ }
230
+ export function parseSpec(spec) {
231
+ return OverlaySpecSchema.parse(spec);
232
+ }
233
+ /**
234
+ * Validate spec against a profile (tile or full)
235
+ */
236
+ export function validateAgainstProfile(spec, profile) {
237
+ const errors = [];
238
+ // Check overlay count
239
+ if (spec.tracks.overlays.length > profile.maxOverlays) {
240
+ errors.push(`Too many overlays: ${spec.tracks.overlays.length} (max ${profile.maxOverlays})`);
241
+ }
242
+ // Check text lengths in captions
243
+ if (spec.tracks.captions) {
244
+ for (const segment of spec.tracks.captions.segments) {
245
+ if (segment.text.length > profile.maxTextLength) {
246
+ errors.push(`Caption text too long: ${segment.text.length} chars (max ${profile.maxTextLength})`);
247
+ }
248
+ }
249
+ }
250
+ // Check for navigation actions if not allowed
251
+ if (!profile.allowNavigation) {
252
+ for (const cue of spec.tracks.overlays) {
253
+ if (hasNavigationAction(cue.layout)) {
254
+ errors.push(`Navigation actions not allowed in ${profile.name} profile`);
255
+ }
256
+ }
257
+ }
258
+ return { valid: errors.length === 0, errors };
259
+ }
260
+ function hasNavigationAction(node) {
261
+ if (node.props) {
262
+ for (const value of Object.values(node.props)) {
263
+ if (typeof value === 'object' &&
264
+ value !== null &&
265
+ '$action' in value &&
266
+ (value.$action === 'navigate' ||
267
+ value.$action === 'openFull')) {
268
+ return true;
269
+ }
270
+ }
271
+ }
272
+ if (node.children) {
273
+ for (const child of node.children) {
274
+ if (hasNavigationAction(child)) {
275
+ return true;
276
+ }
277
+ }
278
+ }
279
+ return false;
280
+ }
281
+ // =============================================================================
282
+ // Exports
283
+ // =============================================================================
284
+ export { SizeSchema, WeightSchema, ColorSchema, VariantSchema, AlignSchema, JustifySchema, BindingSchema, ActionSchema, PropValueSchema, ConditionSchema, LayoutNodeSchema, PlacementSchema, OverlayCueSchema, CaptionTrackSchema, };
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Theme Provider
3
+ *
4
+ * Provides theming context for overlay spec components.
5
+ * AI agents can generate custom themes to style overlays.
6
+ */
7
+ import { type ReactNode } from 'react';
8
+ export interface OverlayTheme {
9
+ /** Theme name/identifier */
10
+ name?: string;
11
+ /** Color palette */
12
+ colors: ThemeColors;
13
+ /** Typography */
14
+ typography: ThemeTypography;
15
+ /** Spacing scale */
16
+ spacing: ThemeSpacing;
17
+ /** Border radius */
18
+ radius: ThemeRadius;
19
+ /** Component-specific overrides */
20
+ components?: ThemeComponents;
21
+ }
22
+ export interface ThemeColors {
23
+ /** Primary brand color */
24
+ primary: string;
25
+ /** Primary color for text on primary background */
26
+ primaryForeground: string;
27
+ /** Secondary/muted color */
28
+ secondary: string;
29
+ secondaryForeground: string;
30
+ /** Background colors */
31
+ background: string;
32
+ backgroundMuted: string;
33
+ backgroundOverlay: string;
34
+ /** Foreground/text colors */
35
+ foreground: string;
36
+ foregroundMuted: string;
37
+ /** Semantic colors */
38
+ success: string;
39
+ warning: string;
40
+ error: string;
41
+ /** Border color */
42
+ border: string;
43
+ }
44
+ export interface ThemeTypography {
45
+ /** Font family for body text */
46
+ fontFamily: string;
47
+ /** Font family for headings */
48
+ fontFamilyHeading?: string;
49
+ /** Base font size */
50
+ fontSizeBase: string;
51
+ /** Size scale */
52
+ fontSizes: {
53
+ xs: string;
54
+ sm: string;
55
+ md: string;
56
+ lg: string;
57
+ xl: string;
58
+ '2xl': string;
59
+ };
60
+ /** Weight scale */
61
+ fontWeights: {
62
+ normal: number;
63
+ medium: number;
64
+ semibold: number;
65
+ bold: number;
66
+ };
67
+ /** Line heights */
68
+ lineHeights: {
69
+ tight: number;
70
+ normal: number;
71
+ relaxed: number;
72
+ };
73
+ }
74
+ export interface ThemeSpacing {
75
+ xs: string;
76
+ sm: string;
77
+ md: string;
78
+ lg: string;
79
+ xl: string;
80
+ '2xl': string;
81
+ }
82
+ export interface ThemeRadius {
83
+ none: string;
84
+ sm: string;
85
+ md: string;
86
+ lg: string;
87
+ full: string;
88
+ }
89
+ export interface ThemeComponents {
90
+ /** Caption-specific styling */
91
+ caption?: {
92
+ background?: string;
93
+ textColor?: string;
94
+ speakerColor?: string;
95
+ backdropBlur?: boolean;
96
+ borderRadius?: string;
97
+ padding?: string;
98
+ };
99
+ /** Button overrides */
100
+ button?: {
101
+ borderRadius?: string;
102
+ fontWeight?: number;
103
+ };
104
+ /** Card/container overrides */
105
+ card?: {
106
+ background?: string;
107
+ borderRadius?: string;
108
+ shadow?: string;
109
+ };
110
+ /** Progress bar overrides */
111
+ progressBar?: {
112
+ trackColor?: string;
113
+ height?: string;
114
+ };
115
+ }
116
+ export declare const defaultTheme: OverlayTheme;
117
+ export declare const darkTheme: OverlayTheme;
118
+ export declare const lightTheme: OverlayTheme;
119
+ export declare const neonTheme: OverlayTheme;
120
+ export declare const warmTheme: OverlayTheme;
121
+ export declare const coolTheme: OverlayTheme;
122
+ export interface ThemeProviderProps {
123
+ /** Theme to use */
124
+ theme?: Partial<OverlayTheme>;
125
+ /** Base theme to extend */
126
+ baseTheme?: OverlayTheme;
127
+ children: ReactNode;
128
+ }
129
+ /**
130
+ * Provides theme context to overlay components.
131
+ */
132
+ export declare function ThemeProvider({ theme, baseTheme, children, }: ThemeProviderProps): JSX.Element;
133
+ /**
134
+ * Get the current theme.
135
+ */
136
+ export declare function useTheme(): OverlayTheme;
137
+ /**
138
+ * Get theme colors.
139
+ */
140
+ export declare function useThemeColors(): ThemeColors;
141
+ /**
142
+ * Get a specific color from the theme.
143
+ */
144
+ export declare function useThemeColor(color: keyof ThemeColors | 'primary' | 'secondary' | 'success' | 'warning' | 'error'): string;
145
+ /**
146
+ * Generates CSS custom properties from a theme.
147
+ * Can be injected into a style tag for CSS-based theming.
148
+ */
149
+ export declare function generateThemeCSS(theme: OverlayTheme): string;
150
+ export default ThemeProvider;
151
+ //# sourceMappingURL=ThemeProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ThemeProvider.d.ts","sourceRoot":"","sources":["../../../src/spec/theme/ThemeProvider.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,227 @@
1
+ /**
2
+ * Theme Provider
3
+ *
4
+ * Provides theming context for overlay spec components.
5
+ * AI agents can generate custom themes to style overlays.
6
+ */
7
+ import React, { createContext, useContext, useMemo } from 'react';
8
+ // =============================================================================
9
+ // Default Theme
10
+ // =============================================================================
11
+ export const defaultTheme = {
12
+ name: 'default',
13
+ colors: {
14
+ primary: '#a855f7', // purple-500
15
+ primaryForeground: '#ffffff',
16
+ secondary: '#6b7280', // gray-500
17
+ secondaryForeground: '#ffffff',
18
+ background: '#1f2937', // gray-800
19
+ backgroundMuted: '#374151', // gray-700
20
+ backgroundOverlay: 'rgba(0, 0, 0, 0.6)',
21
+ foreground: '#ffffff',
22
+ foregroundMuted: '#9ca3af', // gray-400
23
+ success: '#22c55e', // green-500
24
+ warning: '#eab308', // yellow-500
25
+ error: '#ef4444', // red-500
26
+ border: '#4b5563', // gray-600
27
+ },
28
+ typography: {
29
+ fontFamily: 'system-ui, -apple-system, sans-serif',
30
+ fontSizeBase: '16px',
31
+ fontSizes: {
32
+ xs: '0.75rem',
33
+ sm: '0.875rem',
34
+ md: '1rem',
35
+ lg: '1.125rem',
36
+ xl: '1.25rem',
37
+ '2xl': '1.5rem',
38
+ },
39
+ fontWeights: {
40
+ normal: 400,
41
+ medium: 500,
42
+ semibold: 600,
43
+ bold: 700,
44
+ },
45
+ lineHeights: {
46
+ tight: 1.25,
47
+ normal: 1.5,
48
+ relaxed: 1.75,
49
+ },
50
+ },
51
+ spacing: {
52
+ xs: '0.25rem',
53
+ sm: '0.5rem',
54
+ md: '1rem',
55
+ lg: '1.5rem',
56
+ xl: '2rem',
57
+ '2xl': '2.5rem',
58
+ },
59
+ radius: {
60
+ none: '0',
61
+ sm: '0.25rem',
62
+ md: '0.5rem',
63
+ lg: '0.75rem',
64
+ full: '9999px',
65
+ },
66
+ components: {
67
+ caption: {
68
+ backdropBlur: true,
69
+ },
70
+ },
71
+ };
72
+ // =============================================================================
73
+ // Dark/Light Presets
74
+ // =============================================================================
75
+ export const darkTheme = {
76
+ ...defaultTheme,
77
+ name: 'dark',
78
+ };
79
+ export const lightTheme = {
80
+ ...defaultTheme,
81
+ name: 'light',
82
+ colors: {
83
+ ...defaultTheme.colors,
84
+ background: '#f9fafb', // gray-50
85
+ backgroundMuted: '#f3f4f6', // gray-100
86
+ backgroundOverlay: 'rgba(255, 255, 255, 0.9)',
87
+ foreground: '#111827', // gray-900
88
+ foregroundMuted: '#6b7280', // gray-500
89
+ border: '#e5e7eb', // gray-200
90
+ },
91
+ };
92
+ // =============================================================================
93
+ // Vibrant Theme Presets (for AI to use)
94
+ // =============================================================================
95
+ export const neonTheme = {
96
+ ...defaultTheme,
97
+ name: 'neon',
98
+ colors: {
99
+ ...defaultTheme.colors,
100
+ primary: '#00ff88',
101
+ primaryForeground: '#000000',
102
+ background: '#0a0a0a',
103
+ backgroundOverlay: 'rgba(0, 0, 0, 0.85)',
104
+ success: '#00ff88',
105
+ warning: '#ffff00',
106
+ error: '#ff0055',
107
+ },
108
+ };
109
+ export const warmTheme = {
110
+ ...defaultTheme,
111
+ name: 'warm',
112
+ colors: {
113
+ ...defaultTheme.colors,
114
+ primary: '#f97316', // orange-500
115
+ background: '#292524', // stone-800
116
+ backgroundMuted: '#44403c', // stone-700
117
+ foregroundMuted: '#a8a29e', // stone-400
118
+ border: '#57534e', // stone-600
119
+ },
120
+ };
121
+ export const coolTheme = {
122
+ ...defaultTheme,
123
+ name: 'cool',
124
+ colors: {
125
+ ...defaultTheme.colors,
126
+ primary: '#06b6d4', // cyan-500
127
+ background: '#0c4a6e', // sky-900
128
+ backgroundMuted: '#075985', // sky-800
129
+ foregroundMuted: '#7dd3fc', // sky-300
130
+ border: '#0284c7', // sky-600
131
+ },
132
+ };
133
+ // =============================================================================
134
+ // Theme Context
135
+ // =============================================================================
136
+ const ThemeContext = createContext(defaultTheme);
137
+ /**
138
+ * Provides theme context to overlay components.
139
+ */
140
+ export function ThemeProvider({ theme, baseTheme = defaultTheme, children, }) {
141
+ const mergedTheme = useMemo(() => {
142
+ if (!theme)
143
+ return baseTheme;
144
+ return {
145
+ ...baseTheme,
146
+ ...theme,
147
+ colors: { ...baseTheme.colors, ...theme.colors },
148
+ typography: { ...baseTheme.typography, ...theme.typography },
149
+ spacing: { ...baseTheme.spacing, ...theme.spacing },
150
+ radius: { ...baseTheme.radius, ...theme.radius },
151
+ components: { ...baseTheme.components, ...theme.components },
152
+ };
153
+ }, [theme, baseTheme]);
154
+ return (React.createElement(ThemeContext.Provider, { value: mergedTheme }, children));
155
+ }
156
+ // =============================================================================
157
+ // Hooks
158
+ // =============================================================================
159
+ /**
160
+ * Get the current theme.
161
+ */
162
+ export function useTheme() {
163
+ return useContext(ThemeContext);
164
+ }
165
+ /**
166
+ * Get theme colors.
167
+ */
168
+ export function useThemeColors() {
169
+ return useTheme().colors;
170
+ }
171
+ /**
172
+ * Get a specific color from the theme.
173
+ */
174
+ export function useThemeColor(color) {
175
+ const colors = useThemeColors();
176
+ return colors[color] ?? colors.primary;
177
+ }
178
+ // =============================================================================
179
+ // CSS Variable Injection
180
+ // =============================================================================
181
+ /**
182
+ * Generates CSS custom properties from a theme.
183
+ * Can be injected into a style tag for CSS-based theming.
184
+ */
185
+ export function generateThemeCSS(theme) {
186
+ return `
187
+ :root {
188
+ /* Colors */
189
+ --overlay-color-primary: ${theme.colors.primary};
190
+ --overlay-color-primary-fg: ${theme.colors.primaryForeground};
191
+ --overlay-color-secondary: ${theme.colors.secondary};
192
+ --overlay-color-secondary-fg: ${theme.colors.secondaryForeground};
193
+ --overlay-color-background: ${theme.colors.background};
194
+ --overlay-color-background-muted: ${theme.colors.backgroundMuted};
195
+ --overlay-color-background-overlay: ${theme.colors.backgroundOverlay};
196
+ --overlay-color-foreground: ${theme.colors.foreground};
197
+ --overlay-color-foreground-muted: ${theme.colors.foregroundMuted};
198
+ --overlay-color-success: ${theme.colors.success};
199
+ --overlay-color-warning: ${theme.colors.warning};
200
+ --overlay-color-error: ${theme.colors.error};
201
+ --overlay-color-border: ${theme.colors.border};
202
+
203
+ /* Typography */
204
+ --overlay-font-family: ${theme.typography.fontFamily};
205
+ --overlay-font-size-xs: ${theme.typography.fontSizes.xs};
206
+ --overlay-font-size-sm: ${theme.typography.fontSizes.sm};
207
+ --overlay-font-size-md: ${theme.typography.fontSizes.md};
208
+ --overlay-font-size-lg: ${theme.typography.fontSizes.lg};
209
+ --overlay-font-size-xl: ${theme.typography.fontSizes.xl};
210
+ --overlay-font-size-2xl: ${theme.typography.fontSizes['2xl']};
211
+
212
+ /* Spacing */
213
+ --overlay-spacing-xs: ${theme.spacing.xs};
214
+ --overlay-spacing-sm: ${theme.spacing.sm};
215
+ --overlay-spacing-md: ${theme.spacing.md};
216
+ --overlay-spacing-lg: ${theme.spacing.lg};
217
+ --overlay-spacing-xl: ${theme.spacing.xl};
218
+
219
+ /* Radius */
220
+ --overlay-radius-sm: ${theme.radius.sm};
221
+ --overlay-radius-md: ${theme.radius.md};
222
+ --overlay-radius-lg: ${theme.radius.lg};
223
+ --overlay-radius-full: ${theme.radius.full};
224
+ }
225
+ `.trim();
226
+ }
227
+ export default ThemeProvider;
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Theme Module Index
3
+ *
4
+ * Exports theme provider and presets for overlay styling.
5
+ */
6
+ export { ThemeProvider, useTheme, useThemeColors, useThemeColor, generateThemeCSS, defaultTheme, darkTheme, lightTheme, neonTheme, warmTheme, coolTheme, type OverlayTheme, type ThemeColors, type ThemeTypography, type ThemeSpacing, type ThemeRadius, type ThemeComponents, type ThemeProviderProps, } from './ThemeProvider';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/spec/theme/index.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAEL,aAAa,EACb,QAAQ,EACR,cAAc,EACd,aAAa,EACb,gBAAgB,EAGhB,YAAY,EAGZ,SAAS,EACT,UAAU,EACV,SAAS,EACT,SAAS,EACT,SAAS,EAGT,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,YAAY,EACjB,KAAK,WAAW,EAChB,KAAK,eAAe,EACpB,KAAK,kBAAkB,GACxB,MAAM,iBAAiB,CAAC"}