@realtimex/realtimex-alchemy 1.0.67 → 1.0.69

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/dist/CHANGELOG.md CHANGED
@@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [1.0.69] - 2026-01-28
9
+
10
+ ### Added
11
+ - **Onboarding**: Implemented "Zero-Config" auto-discovery. The app now automatically detects and configures all available browser profiles (Chrome, Edge, Brave, Arc, Firefox) upon first launch or when no sources are set.
12
+ - **Settings**: Added a manual "Auto-discover Sources" button in Sync Settings to re-scan for new browser profiles at any time.
13
+
14
+ ### Improved
15
+ - **Browser Mining**: Enhanced the `BrowserPathDetector` to scan all available profiles (e.g., "Person 1", "Work", "Default") instead of just the default one, ensuring comprehensive history mining.
16
+ - **UI**: Added a welcoming "Empty State" to the Discovery tab that guides new users to run their first sync with a single click.
17
+
18
+ ## [1.0.68] - 2026-01-28
19
+
20
+ ### Fixed
21
+ - **Migration**: Updated migration scripts (`migrate.sh`, `migrate.ts`) to allow `npx` to automatically download the Supabase CLI if it's missing. This resolves initialization issues in environments where the CLI isn't pre-installed.
22
+
8
23
  ## [1.0.67] - 2026-01-28
9
24
 
10
25
  ### Improved
package/dist/api/index.js CHANGED
@@ -175,10 +175,23 @@ app.post('/api/mine', async (req, res) => {
175
175
  //.eq('user_id', ...) // RLS handles this implicitly usually, but we pick the first row found
176
176
  .limit(1)
177
177
  .single();
178
- if (!settings) {
179
- throw new Error('Alchemy Engine settings not found. Please save settings in the UI first.');
178
+ let enabledSources = (settings.custom_browser_paths || []).filter((s) => s.enabled);
179
+ // ZERO-CONFIG SAFETY NET: If no sources are enabled, try to auto-discover
180
+ if (enabledSources.length === 0) {
181
+ console.log('[API] No sources configured. Attempting auto-discovery...');
182
+ const detector = new BrowserPathDetector();
183
+ const discovered = detector.getAutoDetectedSources();
184
+ if (discovered.length > 0) {
185
+ console.log(`[API] Auto-discovered ${discovered.length} browser profiles. Updating settings...`);
186
+ // Update settings in background
187
+ await supabase
188
+ .from('alchemy_settings')
189
+ .update({ custom_browser_paths: discovered })
190
+ .eq('user_id', settings.user_id);
191
+ settings.custom_browser_paths = discovered;
192
+ enabledSources = discovered;
193
+ }
180
194
  }
181
- const enabledSources = (settings.custom_browser_paths || []).filter((s) => s.enabled);
182
195
  // Emit: Sync Starting
183
196
  await processingEvents.log({
184
197
  eventType: 'info',
@@ -247,17 +260,28 @@ app.post('/api/mine', async (req, res) => {
247
260
  res.status(500).json({ error: error.message });
248
261
  }
249
262
  });
250
- // Browser path detection
263
+ // Browser path detection (backwards-compatible: one path per browser type)
251
264
  app.get('/api/browser-paths/detect', async (req, res) => {
252
265
  try {
253
266
  const detector = new BrowserPathDetector();
254
- const results = detector.detectAll();
267
+ const results = detector.detectFirstPerBrowser();
255
268
  res.json(results);
256
269
  }
257
270
  catch (error) {
258
271
  res.status(500).json({ error: error.message });
259
272
  }
260
273
  });
274
+ // Browser path auto-discovery
275
+ app.get('/api/browser-paths/auto-discover', async (req, res) => {
276
+ try {
277
+ const detector = new BrowserPathDetector();
278
+ const sources = detector.getAutoDetectedSources();
279
+ res.json({ success: true, sources });
280
+ }
281
+ catch (error) {
282
+ res.status(500).json({ success: false, error: error.message });
283
+ }
284
+ });
261
285
  // Browser path validation
262
286
  app.post('/api/browser-paths/validate', async (req, res) => {
263
287
  const { path: filePath } = req.body;
@@ -11,99 +11,150 @@ export class BrowserPathDetector {
11
11
  this.homeDir = os.homedir();
12
12
  }
13
13
  /**
14
- * Get default browser history paths based on platform
14
+ * Get base data directories for browsers based on platform
15
15
  */
16
- getDefaultPaths() {
16
+ getBaseDataDirs() {
17
17
  if (this.platform === 'darwin') {
18
- // macOS
19
18
  return {
20
- chrome: [
21
- path.join(this.homeDir, 'Library/Application Support/Google/Chrome/Default/History'),
22
- path.join(this.homeDir, 'Library/Application Support/Google/Chrome/Profile 1/History'),
23
- ],
24
- firefox: [
25
- // Firefox uses profiles with random names
26
- path.join(this.homeDir, 'Library/Application Support/Firefox/Profiles'),
27
- ],
28
- safari: [
29
- path.join(this.homeDir, 'Library/Safari/History.db'),
30
- ],
31
- edge: [
32
- path.join(this.homeDir, 'Library/Application Support/Microsoft Edge/Default/History'),
33
- ],
34
- brave: [
35
- path.join(this.homeDir, 'Library/Application Support/BraveSoftware/Brave-Browser/Default/History'),
36
- ],
37
- arc: [
38
- path.join(this.homeDir, 'Library/Application Support/Arc/User Data/Default/History'),
39
- ],
19
+ chrome: [path.join(this.homeDir, 'Library/Application Support/Google/Chrome')],
20
+ firefox: [path.join(this.homeDir, 'Library/Application Support/Firefox/Profiles')],
21
+ safari: [path.join(this.homeDir, 'Library/Safari')],
22
+ edge: [path.join(this.homeDir, 'Library/Application Support/Microsoft Edge')],
23
+ brave: [path.join(this.homeDir, 'Library/Application Support/BraveSoftware/Brave-Browser')],
24
+ arc: [path.join(this.homeDir, 'Library/Application Support/Arc/User Data')],
40
25
  custom: [],
41
26
  };
42
27
  }
43
28
  else if (this.platform === 'win32') {
44
- // Windows
45
29
  const appData = process.env.APPDATA || '';
46
30
  const localAppData = process.env.LOCALAPPDATA || '';
47
31
  return {
48
- chrome: [
49
- path.join(localAppData, 'Google\\Chrome\\User Data\\Default\\History'),
50
- ],
51
- firefox: [
52
- path.join(appData, 'Mozilla\\Firefox\\Profiles'),
53
- ],
32
+ chrome: [path.join(localAppData, 'Google\\Chrome\\User Data')],
33
+ firefox: [path.join(appData, 'Mozilla\\Firefox\\Profiles')],
54
34
  safari: [],
55
- edge: [
56
- path.join(localAppData, 'Microsoft\\Edge\\User Data\\Default\\History'),
57
- ],
58
- brave: [
59
- path.join(localAppData, 'BraveSoftware\\Brave-Browser\\User Data\\Default\\History'),
60
- ],
35
+ edge: [path.join(localAppData, 'Microsoft\\Edge\\User Data')],
36
+ brave: [path.join(localAppData, 'BraveSoftware\\Brave-Browser\\User Data')],
61
37
  arc: [],
62
38
  custom: [],
63
39
  };
64
40
  }
65
41
  else {
66
- // Linux
67
42
  return {
68
- chrome: [
69
- path.join(this.homeDir, '.config/google-chrome/Default/History'),
70
- ],
71
- firefox: [
72
- path.join(this.homeDir, '.mozilla/firefox'),
73
- ],
43
+ chrome: [path.join(this.homeDir, '.config/google-chrome')],
44
+ firefox: [path.join(this.homeDir, '.mozilla/firefox')],
74
45
  safari: [],
75
- edge: [
76
- path.join(this.homeDir, '.config/microsoft-edge/Default/History'),
77
- ],
78
- brave: [
79
- path.join(this.homeDir, '.config/BraveSoftware/Brave-Browser/Default/History'),
80
- ],
46
+ edge: [path.join(this.homeDir, '.config/microsoft-edge')],
47
+ brave: [path.join(this.homeDir, '.config/BraveSoftware/Brave-Browser')],
81
48
  arc: [],
82
49
  custom: [],
83
50
  };
84
51
  }
85
52
  }
86
53
  /**
87
- * Find Firefox profile directories and locate places.sqlite
54
+ * Detect all available browser history paths across all profiles
88
55
  */
89
- findFirefoxHistory(profilesDir) {
90
- try {
91
- if (!fs.existsSync(profilesDir))
92
- return null;
93
- const profiles = fs.readdirSync(profilesDir);
94
- for (const profile of profiles) {
95
- if (profile.endsWith('.default') || profile.includes('default-release')) {
96
- const historyPath = path.join(profilesDir, profile, 'places.sqlite');
97
- if (fs.existsSync(historyPath)) {
98
- return historyPath;
56
+ detectAll() {
57
+ const baseDirs = this.getBaseDataDirs();
58
+ const results = {};
59
+ for (const [browser, dirs] of Object.entries(baseDirs)) {
60
+ if (browser === 'custom')
61
+ continue;
62
+ const browserType = browser;
63
+ for (const baseDir of dirs) {
64
+ if (!fs.existsSync(baseDir))
65
+ continue;
66
+ if (browserType === 'safari') {
67
+ // Safari is usually just one file
68
+ const safariPath = path.join(baseDir, 'History.db');
69
+ if (fs.existsSync(safariPath)) {
70
+ results['safari_default'] = {
71
+ browser: 'safari',
72
+ path: safariPath,
73
+ found: true,
74
+ ...this.validateSQLitePath(safariPath)
75
+ };
76
+ }
77
+ continue;
78
+ }
79
+ if (browserType === 'firefox') {
80
+ // Firefox profile scanning
81
+ try {
82
+ const profiles = fs.readdirSync(baseDir);
83
+ for (const profileName of profiles) {
84
+ const profilePath = path.join(baseDir, profileName);
85
+ const historyPath = path.join(profilePath, 'places.sqlite');
86
+ if (fs.existsSync(historyPath)) {
87
+ const validation = this.validateSQLitePath(historyPath);
88
+ if (validation.valid) {
89
+ results[`firefox_${profileName}`] = {
90
+ browser: 'firefox',
91
+ path: historyPath,
92
+ found: true,
93
+ ...validation
94
+ };
95
+ }
96
+ }
97
+ }
98
+ }
99
+ catch (e) {
100
+ console.error(`Error scanning Firefox profiles in ${baseDir}:`, e);
101
+ }
102
+ continue;
103
+ }
104
+ // Chromium-based (Chrome, Edge, Brave, Arc)
105
+ try {
106
+ const profileEntries = fs.readdirSync(baseDir);
107
+ for (const entryName of profileEntries) {
108
+ // Profiles are usually "Default" or "Profile X"
109
+ if (entryName === 'Default' || entryName.startsWith('Profile ')) {
110
+ const historyPath = path.join(baseDir, entryName, 'History');
111
+ if (fs.existsSync(historyPath)) {
112
+ const validation = this.validateSQLitePath(historyPath);
113
+ if (validation.valid) {
114
+ results[`${browserType}_${entryName.toLowerCase().replace(' ', '_')}`] = {
115
+ browser: browserType,
116
+ path: historyPath,
117
+ found: true,
118
+ ...validation
119
+ };
120
+ }
121
+ }
122
+ }
99
123
  }
100
124
  }
125
+ catch (e) {
126
+ console.error(`Error scanning ${browserType} profiles in ${baseDir}:`, e);
127
+ }
101
128
  }
102
129
  }
103
- catch (err) {
104
- console.error('Error finding Firefox history:', err);
105
- }
106
- return null;
130
+ return results;
131
+ }
132
+ /**
133
+ * Helper to convert detected paths to ready-to-use BrowserSources
134
+ */
135
+ getAutoDetectedSources() {
136
+ const detected = this.detectAll();
137
+ return Object.entries(detected)
138
+ .filter(([_, info]) => info.valid)
139
+ .map(([key, info]) => {
140
+ let label = '';
141
+ const browserName = info.browser.charAt(0).toUpperCase() + info.browser.slice(1);
142
+ // Extract profile name for label
143
+ if (key.includes('_')) {
144
+ const profilePart = key.split('_').slice(1).join(' ');
145
+ const profileLabel = profilePart.charAt(0).toUpperCase() + profilePart.slice(1);
146
+ label = `${browserName} (${profileLabel})`;
147
+ }
148
+ else {
149
+ label = `${browserName} (Default)`;
150
+ }
151
+ return {
152
+ browser: info.browser,
153
+ path: info.path,
154
+ enabled: true,
155
+ label
156
+ };
157
+ });
107
158
  }
108
159
  /**
109
160
  * Validate if a file is a valid SQLite database
@@ -153,54 +204,36 @@ export class BrowserPathDetector {
153
204
  }
154
205
  }
155
206
  /**
156
- * Detect all available browser history paths
207
+ * Detect a specific browser's history path (Legacy support)
157
208
  */
158
- detectAll() {
159
- const defaultPaths = this.getDefaultPaths();
160
- const results = {};
161
- for (const [browser, paths] of Object.entries(defaultPaths)) {
162
- if (browser === 'custom')
163
- continue;
164
- const browserType = browser;
165
- let foundPath = null;
166
- if (browserType === 'firefox' && paths.length > 0) {
167
- // Special handling for Firefox
168
- foundPath = this.findFirefoxHistory(paths[0]);
169
- }
170
- else {
171
- // Check each potential path
172
- for (const p of paths) {
173
- if (fs.existsSync(p)) {
174
- foundPath = p;
175
- break;
176
- }
177
- }
178
- }
179
- if (foundPath) {
180
- const validation = this.validateSQLitePath(foundPath);
181
- results[browserType] = {
182
- browser: browserType,
183
- path: foundPath,
184
- found: true,
185
- valid: validation.valid,
186
- error: validation.error,
187
- };
209
+ detect(browser) {
210
+ const all = this.detectAll();
211
+ // Return first valid profile for this browser if exists
212
+ const match = Object.values(all).find(p => p.browser === browser && p.valid);
213
+ return match || { browser, path: '', found: false };
214
+ }
215
+ /**
216
+ * Backwards-compatible method: Returns one path per browser type (first valid profile found)
217
+ * Used by legacy UI components that expect Record<BrowserType, BrowserPath>
218
+ */
219
+ detectFirstPerBrowser() {
220
+ const all = this.detectAll();
221
+ const result = {};
222
+ const browserTypes = ['chrome', 'firefox', 'safari', 'edge', 'brave', 'arc'];
223
+ for (const browserType of browserTypes) {
224
+ // Find first valid path for this browser type
225
+ const match = Object.values(all).find(p => p.browser === browserType && p.valid);
226
+ if (match) {
227
+ result[browserType] = match;
188
228
  }
189
229
  else {
190
- results[browserType] = {
230
+ result[browserType] = {
191
231
  browser: browserType,
192
232
  path: '',
193
- found: false,
233
+ found: false
194
234
  };
195
235
  }
196
236
  }
197
- return results;
198
- }
199
- /**
200
- * Detect a specific browser's history path
201
- */
202
- detect(browser) {
203
- const all = this.detectAll();
204
- return all[browser] || { browser, path: '', found: false };
237
+ return result;
205
238
  }
206
239
  }
@@ -0,0 +1 @@
1
+ *,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Outfit,system-ui,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:JetBrains Mono,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}body{background-color:var(--bg);color:var(--fg);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-family:Outfit,system-ui,sans-serif}::-moz-selection{background-color:var(--selection-bg)}::selection{background-color:var(--selection-bg)}.glass{background-color:var(--glass-bg);border-radius:1rem;border-width:1px;border-color:var(--border);--tw-backdrop-blur: blur(24px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.glow-primary{box-shadow:0 0 20px var(--glow-color)}.custom-scrollbar::-webkit-scrollbar{width:6px}.custom-scrollbar::-webkit-scrollbar-track{background-color:transparent}.custom-scrollbar::-webkit-scrollbar-thumb{border-radius:9999px;background-color:var(--border)}.custom-scrollbar::-webkit-scrollbar-thumb:hover{background-color:#f7f8ff33}input:-webkit-autofill,input:-webkit-autofill:hover,input:-webkit-autofill:focus,input:-webkit-autofill:active{-webkit-box-shadow:0 0 0 1000px var(--surface) inset!important;-webkit-text-fill-color:var(--fg)!important;caret-color:var(--fg)!important}.scrollbar-on-hover::-webkit-scrollbar{width:6px;height:6px}.scrollbar-on-hover::-webkit-scrollbar-track{background-color:transparent}.scrollbar-on-hover::-webkit-scrollbar-thumb{background-color:transparent;-webkit-transition:background-color .2s;transition:background-color .2s}.scrollbar-on-hover:hover::-webkit-scrollbar-thumb{border-radius:9999px;background-color:var(--border)}.scrollbar-on-hover:hover::-webkit-scrollbar-thumb:hover{background-color:#f7f8ff33}.pointer-events-none{pointer-events:none}.pointer-events-auto{pointer-events:auto}.visible{visibility:visible}.collapse{visibility:collapse}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.-right-1{right:-.25rem}.-top-1{top:-.25rem}.bottom-32{bottom:8rem}.bottom-6{bottom:1.5rem}.bottom-full{bottom:100%}.left-0{left:0}.left-3{left:.75rem}.right-0{right:0}.right-2{right:.5rem}.right-3{right:.75rem}.right-4{right:1rem}.right-6{right:1.5rem}.top-0{top:0}.top-1\/2{top:50%}.top-12{top:3rem}.top-2{top:.5rem}.top-2\.5{top:.625rem}.top-3{top:.75rem}.top-4{top:1rem}.top-full{top:100%}.z-0{z-index:0}.z-10{z-index:10}.z-40{z-index:40}.z-50{z-index:50}.z-\[100\]{z-index:100}.z-\[60\]{z-index:60}.z-\[70\]{z-index:70}.z-\[9999\]{z-index:9999}.col-span-2{grid-column:span 2 / span 2}.m-2{margin:.5rem}.m-4{margin:1rem}.-mx-4{margin-left:-1rem;margin-right:-1rem}.mx-2{margin-left:.5rem;margin-right:.5rem}.mx-auto{margin-left:auto;margin-right:auto}.my-2{margin-top:.5rem;margin-bottom:.5rem}.mb-0\.5{margin-bottom:.125rem}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mb-8{margin-bottom:2rem}.ml-0{margin-left:0}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-4{margin-left:1rem}.ml-auto{margin-left:auto}.mr-0{margin-right:0}.mr-2{margin-right:.5rem}.mt-0{margin-top:0}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-6{margin-top:1.5rem}.mt-8{margin-top:2rem}.line-clamp-1{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:1}.line-clamp-2{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2}.line-clamp-3{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3}.block{display:block}.inline{display:inline}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-1\.5{height:.375rem}.h-10{height:2.5rem}.h-12{height:3rem}.h-14{height:3.5rem}.h-16{height:4rem}.h-2{height:.5rem}.h-24{height:6rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-32{height:8rem}.h-4{height:1rem}.h-40{height:10rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-64{height:16rem}.h-8{height:2rem}.h-80{height:20rem}.h-96{height:24rem}.h-\[85vh\]{height:85vh}.h-full{height:100%}.h-screen{height:100vh}.max-h-96{max-height:24rem}.max-h-\[200px\]{max-height:200px}.max-h-\[280px\]{max-height:280px}.max-h-\[600px\]{max-height:600px}.max-h-\[80vh\]{max-height:80vh}.max-h-\[85vh\]{max-height:85vh}.max-h-\[90vh\]{max-height:90vh}.max-h-\[calc\(80vh-88px\)\]{max-height:calc(80vh - 88px)}.min-h-\[120px\]{min-height:120px}.min-h-\[24px\]{min-height:24px}.w-1\.5{width:.375rem}.w-10{width:2.5rem}.w-12{width:3rem}.w-14{width:3.5rem}.w-16{width:4rem}.w-2{width:.5rem}.w-24{width:6rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-32{width:8rem}.w-4{width:1rem}.w-48{width:12rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-8{width:2rem}.w-80{width:20rem}.w-\[120px\]{width:120px}.w-\[450px\]{width:450px}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-px{width:1px}.w-screen{width:100vw}.min-w-0{min-width:0px}.min-w-\[20px\]{min-width:20px}.min-w-\[300px\]{min-width:300px}.min-w-\[40px\]{min-width:40px}.min-w-max{min-width:-moz-max-content;min-width:max-content}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-4xl{max-width:56rem}.max-w-5xl{max-width:64rem}.max-w-7xl{max-width:80rem}.max-w-\[240px\]{max-width:240px}.max-w-\[85\%\]{max-width:85%}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.max-w-none{max-width:none}.max-w-sm{max-width:24rem}.max-w-xl{max-width:36rem}.max-w-xs{max-width:20rem}.flex-1{flex:1 1 0%}.flex-\[2\]{flex:2}.flex-none{flex:none}.flex-shrink-0,.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-x-1\/2{--tw-translate-x: 50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-rotate-90{--tw-rotate: -90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-180{--tw-rotate: 180deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.scale-105{--tw-scale-x: 1.05;--tw-scale-y: 1.05;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}@keyframes bounce{0%,to{transform:translateY(-25%);animation-timing-function:cubic-bezier(.8,0,1,1)}50%{transform:none;animation-timing-function:cubic-bezier(0,0,.2,1)}}.animate-bounce{animation:bounce 1s infinite}@keyframes ping{75%,to{transform:scale(2);opacity:0}}.animate-ping{animation:ping 1s cubic-bezier(0,0,.2,1) infinite}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:spin 1s linear infinite}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize-none{resize:none}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.flex-row{flex-direction:row}.flex-row-reverse{flex-direction:row-reverse}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.justify-start{justify-content:flex-start}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.gap-8{gap:2rem}.space-y-0\.5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.125rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.125rem * var(--tw-space-y-reverse))}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-10>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2.5rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem * var(--tw-space-y-reverse))}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-3xl{border-radius:1.5rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.rounded-tl-none{border-top-left-radius:0}.rounded-tr-none{border-top-right-radius:0}.border{border-width:1px}.border-2{border-width:2px}.border-4{border-width:4px}.border-b{border-bottom-width:1px}.border-b-2{border-bottom-width:2px}.border-l{border-left-width:1px}.border-l-2{border-left-width:2px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-none{border-style:none}.border-amber-500\/10{border-color:#f59e0b1a}.border-blue-400{--tw-border-opacity: 1;border-color:rgb(96 165 250 / var(--tw-border-opacity, 1))}.border-blue-400\/30{border-color:#60a5fa4d}.border-blue-500\/20{border-color:#3b82f633}.border-blue-500\/30{border-color:#3b82f64d}.border-border{border-color:var(--border)}.border-cyan-500\/30{border-color:#06b6d44d}.border-emerald-500\/20{border-color:#10b98133}.border-gray-400\/30{border-color:#9ca3af4d}.border-gray-500\/30{border-color:#6b72804d}.border-green-500\/20{border-color:#22c55e33}.border-green-500\/30{border-color:#22c55e4d}.border-orange-500\/20{border-color:#f9731633}.border-orange-500\/30{border-color:#f973164d}.border-primary{border-color:var(--primary)}.border-purple-500\/30{border-color:#a855f74d}.border-red-500\/20{border-color:#ef444433}.border-red-500\/30{border-color:#ef44444d}.border-teal-500\/30{border-color:#14b8a64d}.border-white\/10{border-color:#ffffff1a}.border-white\/30{border-color:#ffffff4d}.border-white\/5{border-color:#ffffff0d}.border-yellow-400\/30{border-color:#facc154d}.border-yellow-500\/20{border-color:#eab30833}.border-yellow-500\/30{border-color:#eab3084d}.border-t-primary{border-top-color:var(--primary)}.border-t-transparent{border-top-color:transparent}.border-t-white{--tw-border-opacity: 1;border-top-color:rgb(255 255 255 / var(--tw-border-opacity, 1))}.bg-amber-500\/5{background-color:#f59e0b0d}.bg-bg{background-color:var(--bg)}.bg-black\/20{background-color:#0003}.bg-black\/30{background-color:#0000004d}.bg-black\/40{background-color:#0006}.bg-black\/5{background-color:#0000000d}.bg-black\/50{background-color:#00000080}.bg-black\/60{background-color:#0009}.bg-blue-400\/20{background-color:#60a5fa33}.bg-blue-500\/10{background-color:#3b82f61a}.bg-blue-500\/20{background-color:#3b82f633}.bg-border{background-color:var(--border)}.bg-cyan-500\/20{background-color:#06b6d433}.bg-emerald-500\/10{background-color:#10b9811a}.bg-emerald-500\/20{background-color:#10b98133}.bg-emerald-500\/5{background-color:#10b9810d}.bg-error{background-color:var(--error)}.bg-gray-400\/20{background-color:#9ca3af33}.bg-gray-500\/20{background-color:#6b728033}.bg-green-500{--tw-bg-opacity: 1;background-color:rgb(34 197 94 / var(--tw-bg-opacity, 1))}.bg-green-500\/10{background-color:#22c55e1a}.bg-green-500\/20{background-color:#22c55e33}.bg-orange-400{--tw-bg-opacity: 1;background-color:rgb(251 146 60 / var(--tw-bg-opacity, 1))}.bg-orange-500{--tw-bg-opacity: 1;background-color:rgb(249 115 22 / var(--tw-bg-opacity, 1))}.bg-orange-500\/10{background-color:#f973161a}.bg-orange-500\/20{background-color:#f9731633}.bg-primary{background-color:var(--primary)}.bg-purple-500\/20{background-color:#a855f733}.bg-red-500\/10{background-color:#ef44441a}.bg-red-500\/20{background-color:#ef444433}.bg-surface{background-color:var(--surface)}.bg-teal-500\/20{background-color:#14b8a633}.bg-transparent{background-color:transparent}.bg-white\/5{background-color:#ffffff0d}.bg-yellow-400\/20{background-color:#facc1533}.bg-yellow-500\/10{background-color:#eab3081a}.bg-yellow-500\/5{background-color:#eab3080d}.bg-gradient-to-br{background-image:linear-gradient(to bottom right,var(--tw-gradient-stops))}.bg-gradient-to-r{background-image:linear-gradient(to right,var(--tw-gradient-stops))}.bg-gradient-to-t{background-image:linear-gradient(to top,var(--tw-gradient-stops))}.from-accent{--tw-gradient-from: var(--accent) var(--tw-gradient-from-position);--tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-bg{--tw-gradient-from: var(--bg) var(--tw-gradient-from-position);--tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-indigo-500{--tw-gradient-from: #6366f1 var(--tw-gradient-from-position);--tw-gradient-to: rgb(99 102 241 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-orange-500{--tw-gradient-from: #f97316 var(--tw-gradient-from-position);--tw-gradient-to: rgb(249 115 22 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-primary{--tw-gradient-from: var(--primary) var(--tw-gradient-from-position);--tw-gradient-to: rgb(255 255 255 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.to-accent{--tw-gradient-to: var(--accent) var(--tw-gradient-to-position)}.to-primary{--tw-gradient-to: var(--primary) var(--tw-gradient-to-position)}.to-purple-600{--tw-gradient-to: #9333ea var(--tw-gradient-to-position)}.to-red-500{--tw-gradient-to: #ef4444 var(--tw-gradient-to-position)}.to-red-600{--tw-gradient-to: #dc2626 var(--tw-gradient-to-position)}.bg-clip-text{-webkit-background-clip:text;background-clip:text}.fill-current{fill:currentColor}.object-cover{-o-object-fit:cover;object-fit:cover}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-12{padding:3rem}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-3{padding:.75rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-1{padding-left:.25rem;padding-right:.25rem}.px-1\.5{padding-left:.375rem;padding-right:.375rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.px-8{padding-left:2rem;padding-right:2rem}.py-0\.5{padding-top:.125rem;padding-bottom:.125rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-12{padding-top:3rem;padding-bottom:3rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-20{padding-top:5rem;padding-bottom:5rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-3\.5{padding-top:.875rem;padding-bottom:.875rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pb-12{padding-bottom:3rem}.pb-2{padding-bottom:.5rem}.pb-3{padding-bottom:.75rem}.pb-4{padding-bottom:1rem}.pl-10{padding-left:2.5rem}.pl-2{padding-left:.5rem}.pl-3{padding-left:.75rem}.pl-4{padding-left:1rem}.pl-9{padding-left:2.25rem}.pr-10{padding-right:2.5rem}.pr-4{padding-right:1rem}.pt-1{padding-top:.25rem}.pt-2{padding-top:.5rem}.pt-4{padding-top:1rem}.pt-6{padding-top:1.5rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.align-top{vertical-align:top}.font-mono{font-family:JetBrains Mono,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-3xl{font-size:1.875rem;line-height:2.25rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[9px\]{font-size:9px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xl{font-size:1.25rem;line-height:1.75rem}.text-xs{font-size:.75rem;line-height:1rem}.font-black{font-weight:900}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.lowercase{text-transform:lowercase}.italic{font-style:italic}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-tight{line-height:1.25}.tracking-\[0\.2em\]{letter-spacing:.2em}.tracking-tight{letter-spacing:-.025em}.tracking-tighter{letter-spacing:-.05em}.tracking-wide{letter-spacing:.025em}.tracking-wider{letter-spacing:.05em}.tracking-widest{letter-spacing:.1em}.text-accent{color:var(--accent)}.text-amber-400{--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.text-amber-500{--tw-text-opacity: 1;color:rgb(245 158 11 / var(--tw-text-opacity, 1))}.text-blue-400{--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.text-blue-500{--tw-text-opacity: 1;color:rgb(59 130 246 / var(--tw-text-opacity, 1))}.text-current{color:currentColor}.text-cyan-400{--tw-text-opacity: 1;color:rgb(34 211 238 / var(--tw-text-opacity, 1))}.text-cyan-500{--tw-text-opacity: 1;color:rgb(6 182 212 / var(--tw-text-opacity, 1))}.text-emerald-400{--tw-text-opacity: 1;color:rgb(52 211 153 / var(--tw-text-opacity, 1))}.text-emerald-500{--tw-text-opacity: 1;color:rgb(16 185 129 / var(--tw-text-opacity, 1))}.text-error{color:var(--error)}.text-fg{color:var(--fg)}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-green-400{--tw-text-opacity: 1;color:rgb(74 222 128 / var(--tw-text-opacity, 1))}.text-green-500{--tw-text-opacity: 1;color:rgb(34 197 94 / var(--tw-text-opacity, 1))}.text-orange-400{--tw-text-opacity: 1;color:rgb(251 146 60 / var(--tw-text-opacity, 1))}.text-orange-500{--tw-text-opacity: 1;color:rgb(249 115 22 / var(--tw-text-opacity, 1))}.text-primary{color:var(--primary)}.text-purple-400{--tw-text-opacity: 1;color:rgb(192 132 252 / var(--tw-text-opacity, 1))}.text-purple-500{--tw-text-opacity: 1;color:rgb(168 85 247 / var(--tw-text-opacity, 1))}.text-red-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.text-success{color:var(--success)}.text-teal-400{--tw-text-opacity: 1;color:rgb(45 212 191 / var(--tw-text-opacity, 1))}.text-transparent{color:transparent}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-yellow-400{--tw-text-opacity: 1;color:rgb(250 204 21 / var(--tw-text-opacity, 1))}.text-yellow-500{--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.underline{text-decoration-line:underline}.accent-primary{accent-color:var(--primary)}.opacity-0{opacity:0}.opacity-20{opacity:.2}.opacity-40{opacity:.4}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.opacity-75{opacity:.75}.opacity-80{opacity:.8}.shadow-2xl{--tw-shadow: 0 25px 50px -12px rgb(0 0 0 / .25);--tw-shadow-colored: 0 25px 50px -12px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_0_15px_rgba\(239\,68\,68\,0\.1\)\]{--tw-shadow: 0 0 15px rgba(239,68,68,.1);--tw-shadow-colored: 0 0 15px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-\[0_0_20px_rgba\(234\,179\,8\,0\.1\)\]{--tw-shadow: 0 0 20px rgba(234,179,8,.1);--tw-shadow-colored: 0 0 20px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-inner{--tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / .05);--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.ring-1{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.blur-3xl{--tw-blur: blur(64px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.blur-md{--tw-blur: blur(12px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.blur-xl{--tw-blur: blur(24px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.grayscale{--tw-grayscale: grayscale(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur-md{--tw-backdrop-blur: blur(12px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-xl{--tw-backdrop-blur: blur(24px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-opacity{transition-property:opacity;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}.duration-500{transition-duration:.5s}:root{--bg: oklch(15% .02 280);--fg: oklch(98% .01 280);--primary: oklch(65% .25 280);--accent: oklch(85% .2 90);--surface: oklch(20% .02 280);--border: oklch(42% .04 280 / .5);--success: oklch(75% .15 150);--error: oklch(65% .2 25);--glass-bg: oklch(25% .03 280 / .4);--glow-color: oklch(65% .25 280 / .3);--selection-bg: oklch(65% .25 280 / .3);--border-hover: oklch(50% .15 280 / .8)}:root[data-theme=light]{--bg: oklch(98% .003 280);--fg: oklch(15% .02 280);--primary: oklch(50% .25 280);--accent: oklch(60% .2 50);--surface: oklch(99% .002 280);--border: oklch(75% .03 280 / .6);--success: oklch(45% .15 150);--error: oklch(50% .2 25);--glass-bg: oklch(99% .002 280 / .75);--glow-color: oklch(50% .25 280 / .2);--selection-bg: oklch(50% .25 280 / .25);--border-hover: oklch(60% .15 280 / .9)}@keyframes pulse-gold{0%{box-shadow:0 0 #fac70066;box-shadow:0 0 oklch(85% .2 90 / .4)}70%{box-shadow:0 0 0 10px #fac70000;box-shadow:0 0 0 10px oklch(85% .2 90 / 0)}to{box-shadow:0 0 #fac70000;box-shadow:0 0 oklch(85% .2 90 / 0)}}.animate-pulse-gold{animation:pulse-gold 2s infinite}h1,h2,h3,h4{letter-spacing:-.025em}.font-mono{font-family:JetBrains Mono,monospace}.before\:mr-2:before{content:var(--tw-content);margin-right:.5rem}.before\:text-primary:before{content:var(--tw-content);color:var(--primary)}.before\:content-\[\'•\'\]:before{--tw-content: "•";content:var(--tw-content)}.first\:mt-0:first-child{margin-top:0}.last\:mb-0:last-child{margin-bottom:0}.autofill\:bg-surface:-webkit-autofill{background-color:var(--surface)}.autofill\:bg-surface:autofill{background-color:var(--surface)}.autofill\:text-fg:-webkit-autofill{color:var(--fg)}.autofill\:text-fg:autofill{color:var(--fg)}.focus-within\:ring-2:focus-within{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.hover\:z-10:hover{z-index:10}.hover\:scale-105:hover{--tw-scale-x: 1.05;--tw-scale-y: 1.05;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:scale-\[1\.01\]:hover{--tw-scale-x: 1.01;--tw-scale-y: 1.01;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:scale-\[1\.02\]:hover{--tw-scale-x: 1.02;--tw-scale-y: 1.02;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:border-\[var\(--border-hover\)\]:hover{border-color:var(--border-hover)}.hover\:bg-bg:hover{background-color:var(--bg)}.hover\:bg-black\/10:hover{background-color:#0000001a}.hover\:bg-blue-500\/20:hover{background-color:#3b82f633}.hover\:bg-error:hover{background-color:var(--error)}.hover\:bg-orange-500:hover{--tw-bg-opacity: 1;background-color:rgb(249 115 22 / var(--tw-bg-opacity, 1))}.hover\:bg-red-500\/10:hover{background-color:#ef44441a}.hover\:bg-red-500\/20:hover{background-color:#ef444433}.hover\:bg-surface:hover{background-color:var(--surface)}.hover\:bg-white\/10:hover{background-color:#ffffff1a}.hover\:bg-white\/5:hover{background-color:#ffffff0d}.hover\:bg-yellow-500\/20:hover{background-color:#eab30833}.hover\:text-accent:hover{color:var(--accent)}.hover\:text-blue-400:hover{--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.hover\:text-error:hover{color:var(--error)}.hover\:text-fg:hover{color:var(--fg)}.hover\:text-primary:hover{color:var(--primary)}.hover\:text-red-400:hover{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.hover\:text-yellow-500:hover{--tw-text-opacity: 1;color:rgb(234 179 8 / var(--tw-text-opacity, 1))}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-lg:hover{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus\:border-\[var\(--border-hover\)\]:focus{border-color:var(--border-hover)}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-0:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-1:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-2:focus{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus\:ring-green-500\/30:focus{--tw-ring-color: rgb(34 197 94 / .3)}.focus\:ring-red-500\/30:focus{--tw-ring-color: rgb(239 68 68 / .3)}.focus-visible\:opacity-100:focus-visible{opacity:1}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-red-500\/40:focus-visible{--tw-ring-color: rgb(239 68 68 / .4)}.active\:scale-95:active{--tw-scale-x: .95;--tw-scale-y: .95;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-30:disabled{opacity:.3}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:grayscale:disabled{--tw-grayscale: grayscale(100%);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.disabled\:hover\:scale-100:hover:disabled{--tw-scale-x: 1;--tw-scale-y: 1;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:block{display:block}.group\/btn:hover .group-hover\/btn\:translate-x-0\.5{--tw-translate-x: .125rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.group:hover .group-hover\:text-accent{color:var(--accent)}.group:hover .group-hover\:text-blue-400{--tw-text-opacity: 1;color:rgb(96 165 250 / var(--tw-text-opacity, 1))}.group:hover .group-hover\:text-primary{color:var(--primary)}.group:hover .group-hover\:opacity-100{opacity:1}@media(min-width:640px){.sm\:inline{display:inline}.sm\:h-12{height:3rem}.sm\:w-12{width:3rem}}@media(min-width:768px){.md\:w-2\/3{width:66.666667%}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(min-width:1024px){.lg\:w-1\/2{width:50%}.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}@media(min-width:1280px){.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}