@nxuss/lemma 1.37.0 → 1.38.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (65) hide show
  1. package/README.md +6 -2
  2. package/bin/brain-ingest.js +22 -0
  3. package/bin/doctor.js +31 -4
  4. package/bin/init.js +92 -51
  5. package/dashboard/dist/assets/index-CLXWgzTm.css +1 -0
  6. package/dashboard/dist/assets/{index-Clf3qR64.js → index-CoMIMxyC.js} +66 -66
  7. package/dashboard/dist/index.html +2 -2
  8. package/dist/cjs/cli/hostHooks.d.ts +13 -1
  9. package/dist/cjs/cli/hostHooks.d.ts.map +1 -1
  10. package/dist/cjs/cli/hostHooks.js +34 -4
  11. package/dist/cjs/cli/hostHooks.js.map +1 -1
  12. package/dist/cjs/cli/lemma-proxy.d.ts.map +1 -1
  13. package/dist/cjs/cli/lemma-proxy.js +21 -4
  14. package/dist/cjs/cli/lemma-proxy.js.map +1 -1
  15. package/dist/cjs/mcp/index.js +33 -10
  16. package/dist/cjs/mcp/index.js.map +1 -1
  17. package/dist/cjs/mcp/prompts.d.ts +1 -1
  18. package/dist/cjs/mcp/prompts.d.ts.map +1 -1
  19. package/dist/cjs/mcp/prompts.js +2 -0
  20. package/dist/cjs/mcp/prompts.js.map +1 -1
  21. package/dist/cjs/mcp/workspaceShared.d.ts.map +1 -1
  22. package/dist/cjs/mcp/workspaceShared.js +6 -9
  23. package/dist/cjs/mcp/workspaceShared.js.map +1 -1
  24. package/dist/cjs/proxy/ProjectRegistry.d.ts +24 -0
  25. package/dist/cjs/proxy/ProjectRegistry.d.ts.map +1 -1
  26. package/dist/cjs/proxy/ProjectRegistry.js +50 -3
  27. package/dist/cjs/proxy/ProjectRegistry.js.map +1 -1
  28. package/dist/cjs/subconscious/HostRecall.d.ts +10 -1
  29. package/dist/cjs/subconscious/HostRecall.d.ts.map +1 -1
  30. package/dist/cjs/subconscious/HostRecall.js +68 -6
  31. package/dist/cjs/subconscious/HostRecall.js.map +1 -1
  32. package/dist/cjs/subconscious/recallDigest.d.ts +34 -0
  33. package/dist/cjs/subconscious/recallDigest.d.ts.map +1 -0
  34. package/dist/cjs/subconscious/recallDigest.js +82 -0
  35. package/dist/cjs/subconscious/recallDigest.js.map +1 -0
  36. package/dist/esm/cli/hostHooks.d.ts +13 -1
  37. package/dist/esm/cli/hostHooks.d.ts.map +1 -1
  38. package/dist/esm/cli/hostHooks.js +32 -3
  39. package/dist/esm/cli/hostHooks.js.map +1 -1
  40. package/dist/esm/cli/lemma-proxy.d.ts.map +1 -1
  41. package/dist/esm/cli/lemma-proxy.js +21 -4
  42. package/dist/esm/cli/lemma-proxy.js.map +1 -1
  43. package/dist/esm/mcp/index.js +33 -10
  44. package/dist/esm/mcp/index.js.map +1 -1
  45. package/dist/esm/mcp/prompts.d.ts +1 -1
  46. package/dist/esm/mcp/prompts.d.ts.map +1 -1
  47. package/dist/esm/mcp/prompts.js +2 -0
  48. package/dist/esm/mcp/prompts.js.map +1 -1
  49. package/dist/esm/mcp/workspaceShared.d.ts.map +1 -1
  50. package/dist/esm/mcp/workspaceShared.js +6 -9
  51. package/dist/esm/mcp/workspaceShared.js.map +1 -1
  52. package/dist/esm/proxy/ProjectRegistry.d.ts +24 -0
  53. package/dist/esm/proxy/ProjectRegistry.d.ts.map +1 -1
  54. package/dist/esm/proxy/ProjectRegistry.js +49 -2
  55. package/dist/esm/proxy/ProjectRegistry.js.map +1 -1
  56. package/dist/esm/subconscious/HostRecall.d.ts +10 -1
  57. package/dist/esm/subconscious/HostRecall.d.ts.map +1 -1
  58. package/dist/esm/subconscious/HostRecall.js +66 -5
  59. package/dist/esm/subconscious/HostRecall.js.map +1 -1
  60. package/dist/esm/subconscious/recallDigest.d.ts +34 -0
  61. package/dist/esm/subconscious/recallDigest.d.ts.map +1 -0
  62. package/dist/esm/subconscious/recallDigest.js +76 -0
  63. package/dist/esm/subconscious/recallDigest.js.map +1 -0
  64. package/package.json +1 -1
  65. package/dashboard/dist/assets/index-BoeQau6n.css +0 -1
package/README.md CHANGED
@@ -87,8 +87,12 @@ Without a license, Pro tools aren't advertised to the model at all. Full list:
87
87
  | Claude Desktop / any MCP client | `{ "command": "npx", "args": ["-y", "@nxuss/lemma", "mcp"] }` |
88
88
 
89
89
  `lemma init` also installs the hooks that feed the Brain (git `post-commit` / `post-merge` /
90
- `post-checkout`, and post-tool hooks for Claude Code, Codex, Cursor and OpenCode). Existing hooks
91
- are kept; `--no-hooks` skips them. Health check: `lemma doctor`.
90
+ `post-checkout`, and post-tool hooks for Claude Code, Codex, Cursor and OpenCode). In Claude Code
91
+ it adds a `SessionStart` briefing and a prompt-time recall too, and pre-approves the read and
92
+ memory tools so using them never costs a permission prompt. Existing hooks are kept; `--no-hooks`
93
+ skips them. An install from an older version gets the missing Claude Code hooks the next time the
94
+ MCP server starts; re-run `lemma init` after upgrading to refresh the agent rules. Health check:
95
+ `lemma doctor`.
92
96
 
93
97
  ### CLI
94
98
 
@@ -99,8 +99,30 @@ function promptSubmit() {
99
99
  if (out) process.stdout.write(out);
100
100
  }
101
101
 
102
+ // SessionStart hook (Claude Code): the Brain's briefing and the Lemma playbook, in context
103
+ // before the first prompt — no tool call for the agent to remember or skip.
104
+ function sessionStart() {
105
+ const dist = path.join(__dirname, '..', 'dist', 'cjs');
106
+ let sessionBriefing, formatHostOutput;
107
+ try {
108
+ ({ sessionBriefing } = require(path.join(dist, 'subconscious', 'HostRecall.js')));
109
+ ({ formatHostOutput } = require(path.join(dist, 'subconscious', 'HostAdapters.js')));
110
+ } catch {
111
+ return;
112
+ }
113
+ let payload = {};
114
+ try {
115
+ payload = JSON.parse(readStdin()) || {};
116
+ } catch {
117
+ // No payload is fine: the briefing only needs a directory.
118
+ }
119
+ const out = formatHostOutput('claude', sessionBriefing(payload, payload.cwd), 'SessionStart');
120
+ if (out) process.stdout.write(out);
121
+ }
122
+
102
123
  function main() {
103
124
  const args = process.argv.slice(2);
125
+ if (args.includes('--session-start')) return sessionStart();
104
126
  if (args.includes('--prompt-submit')) return promptSubmit();
105
127
  if (args.includes('--hook-result')) return hookResult(args);
106
128
  const maxIndex = args.indexOf('--max');
package/bin/doctor.js CHANGED
@@ -3,7 +3,7 @@
3
3
 
4
4
  /**
5
5
  * Lemma doctor — verifies the Lemma wiring on this machine / project:
6
- * wrapper, project skill, user skill (muse), and AGENTS.md block.
6
+ * wrapper, project skill, user skill (muse), AGENTS.md block, and Claude Code hooks/permissions.
7
7
  *
8
8
  * Usage: `lemma doctor` (exit 0 = usable, exit 1 = wrapper broken).
9
9
  */
@@ -111,10 +111,37 @@ async function main() {
111
111
  const agentsPath = path.join(cwd, 'AGENTS.md');
112
112
  if (!fs.existsSync(agentsPath) || !fs.readFileSync(agentsPath, 'utf8').includes('@nxuss/lemma')) {
113
113
  warn('no Lemma block in ./AGENTS.md — run `lemma init`');
114
- } else if (fs.readFileSync(agentsPath, 'utf8').includes('At session')) {
115
- ok('AGENTS.md block current (session-start guard)');
114
+ } else if (fs.readFileSync(agentsPath, 'utf8').includes('## Triggers')) {
115
+ ok('AGENTS.md block current (trigger-based rules)');
116
116
  } else {
117
- warn('AGENTS.md block is stale (pre Muse guard) — re-run `lemma init`');
117
+ warn('AGENTS.md block is stale (pre trigger rules) — re-run `lemma init`');
118
+ }
119
+
120
+ // 5. Claude Code hooks + permissions — what makes the Brain speak without being asked.
121
+ const claudeLocal = path.join(cwd, '.claude', 'settings.local.json');
122
+ let claudeSettings = null;
123
+ try {
124
+ claudeSettings = JSON.parse(fs.readFileSync(claudeLocal, 'utf8'));
125
+ } catch {
126
+ // missing or unreadable — reported below
127
+ }
128
+ if (!claudeSettings) {
129
+ warn('no .claude/settings.local.json — run `lemma init` for Claude Code hooks');
130
+ } else {
131
+ const hooksText = JSON.stringify(claudeSettings.hooks || {});
132
+ const missing = [
133
+ ['PostToolUse', 'lemma-brain-ingest --hook-result'],
134
+ ['UserPromptSubmit', 'lemma-brain-ingest --prompt-submit'],
135
+ ['SessionStart', 'lemma-brain-ingest --session-start'],
136
+ ].filter(([, mark]) => !hooksText.includes(mark)).map(([event]) => event);
137
+ if (missing.length === 0) ok('Claude Code hooks current (PostToolUse, UserPromptSubmit, SessionStart)');
138
+ else warn(`Claude Code hooks missing: ${missing.join(', ')} — re-run \`lemma init\` (or restart the MCP server: it repairs an existing install)`);
139
+
140
+ const allow = (claudeSettings.permissions && claudeSettings.permissions.allow) || [];
141
+ const core = ['search_memory', 'get_memory', 'verify_memory', 'store_memory', 'update_memory', 'read_workspace_file', 'search_workspace'];
142
+ const unallowed = core.filter((t) => !allow.includes(`mcp__lemma__${t}`) && !allow.includes('mcp__lemma'));
143
+ if (unallowed.length === 0) ok('core Lemma tools pre-approved (no permission prompt)');
144
+ else warn(`core Lemma tools still prompt for permission: ${unallowed.join(', ')} — re-run \`lemma init\``);
118
145
  }
119
146
 
120
147
  process.stdout.write(`\n ${DIM}Brain: ~/.lemma-cache/lemma_brain.json · proxy: lemma-proxy.cjs status${RESET}\n\n`);
package/bin/init.js CHANGED
@@ -260,17 +260,41 @@ function loadLemmaToolNames() {
260
260
  }
261
261
 
262
262
  const LEMMA_TOOL_NAMES = loadLemmaToolNames();
263
- const LEMMA_MCP_TOOLS = LEMMA_TOOL_NAMES.map((name) => `mcp__lemma__${name}`);
263
+ // Pre-approved in Claude Code: reading, searching and the Brain's lifecycle — local, and nothing
264
+ // a native Read/Grep couldn't already do. Tools that write code (apply_workspace_patch,
265
+ // surgical_ast_insert), run commands (run_workspace_command), delete (forget_memory), reach
266
+ // infrastructure (terraform/okd/jenkins) or dispatch arbitrary tools (lemma_toolbox) still ask.
267
+ const LEMMA_PREAPPROVED_TOOLS = [
268
+ 'search_memory', 'get_memory', 'verify_memory', 'store_memory', 'update_memory', 'refresh_memory',
269
+ 'downvote_memory', 'read_workspace_file', 'list_workspace_dir', 'search_workspace', 'smart_file_slice',
270
+ 'get_ast_hologram', 'get_symbol_surgical_context', 'output_region', 'get_project_onboarding',
271
+ 'state_hash_cache', 'smarter_cache', 'token_receipt', 'get_routing_advice',
272
+ ].map((name) => `mcp__lemma__${name}`);
264
273
 
265
274
  const CLAUDE_MD_CONTENT = `# Lemma MCP — Cómo usar las herramientas de este proyecto
266
275
 
267
- Tienes conectado el servidor MCP \`lemma\`. Úsalo cuando aporte algo real — caché verificable,
268
- scrubbing de secretos, contexto de proyecto ya indexado — no como sustituto automático de tus
269
- herramientas nativas en cada caso. Si una tool de Lemma no encaja con lo que necesitas hacer,
270
- usa la herramienta nativa; una regla que te obliga a usar la tool equivocada para ahorrar
271
- tokens sale más cara que los tokens que ahorra.
276
+ Tienes conectado el servidor MCP \`lemma\`. Lo que hace que las herramientas nativas no pueden
277
+ es **recordar entre sesiones**: el Brain guarda fixes y decisiones verificadas, y avisa cuando el
278
+ código del que dependen cambió. Ese valor solo existe si se consulta y se alimenta, así que estos
279
+ momentos no son opcionales:
272
280
 
273
- ## Por defecto, para esto sí conviene usar Lemma
281
+ ## Disparadores — haz esto siempre
282
+
283
+ | Cuando… | Llama | Por qué no basta lo nativo |
284
+ |---|---|---|
285
+ | Vas a investigar un bug, un error o un "¿por qué X?" | \`mcp__lemma__search_memory\` con el texto del error o la pregunta | Puede que ya esté resuelto; \`grep\` no encuentra lo que se aprendió en otra sesión |
286
+ | Un aviso 🧠 de Lemma nombra memorias | \`mcp__lemma__get_memory\` de la primera | El aviso trae solo el titular; el cuerpo tiene los archivos y el porqué |
287
+ | Un fix quedó verificado (tests pasan, build ok, el usuario confirmó) | \`mcp__lemma__store_memory\` con \`filePaths\` | Si no se guarda, la próxima sesión lo vuelve a investigar desde cero |
288
+ | Una memoria resultó desactualizada o incorrecta | \`mcp__lemma__update_memory\` / \`forget_memory\` | Guardar otra al lado deja dos versiones y la búsqueda mezcla ambas |
289
+ | Vas a leer código que aún no ubicaste, o que puede tener secretos | \`mcp__lemma__search_workspace\` / \`read_workspace_file\` | Enmascaran API keys antes de que entren a tu contexto |
290
+
291
+ Si las tools de Lemma te llegan diferidas (solo el nombre), cárgalas en **una sola** llamada a
292
+ ToolSearch: \`select:mcp__lemma__search_memory,mcp__lemma__get_memory,mcp__lemma__verify_memory,mcp__lemma__store_memory,mcp__lemma__update_memory,mcp__lemma__read_workspace_file,mcp__lemma__search_workspace\`.
293
+
294
+ Fuera de esos momentos usa tu criterio: para un archivo chico que ya ubicaste, \`Read\` nativo
295
+ cuesta menos que el ida y vuelta, y para procesos, puertos o git Lemma no tiene nada que aportar.
296
+
297
+ ## Referencia: qué tool para qué
274
298
 
275
299
  | Tarea | Tool de Lemma | Por qué |
276
300
  |---|---|---|
@@ -312,14 +336,13 @@ No le pidas que pegue archivos, logs o documentación que puedes obtener tú: ag
312
336
 
313
337
  ## Al iniciar en este proyecto
314
338
 
315
- 1. Llama \`mcp__lemma__get_project_onboarding\` para orientarte con el contexto ya indexado.
316
- 2. Si el problema se parece a algo ya resuelto, llama \`mcp__lemma__search_memory\`.
317
- 3. No lo trates como un hecho hasta verificarlo contra el estado actual del código.
339
+ El hook \`SessionStart\` de Lemma ya te dio un resumen del Brain al arrancar (si no lo ves,
340
+ \`lemma doctor\` dice qué falta). Para más contexto: \`mcp__lemma__get_project_onboarding\`.
341
+ Lo que venga del Brain no es un hecho hasta verificarlo contra el estado actual del código.
318
342
 
319
- ## Al reportar o investigar un bug
343
+ ## Al investigar un bug, además
320
344
 
321
- 1. \`mcp__lemma__search_memory\` con el mensaje de error, por si ya se resolvió algo parecido.
322
- 2. \`lemma_toolbox\` → \`get_telepathic_hints\` con el archivo relevante para contexto de runtime.
345
+ \`lemma_toolbox\` → \`get_telepathic_hints\` con el archivo relevante para contexto de runtime.
323
346
 
324
347
  ## Una sola regla dura
325
348
 
@@ -342,6 +365,13 @@ function configureClaudeCode() {
342
365
  const existingMd = fs.readFileSync(claudeMdPath, 'utf8');
343
366
  if (!existingMd.includes('@nxuss/lemma')) {
344
367
  fs.appendFileSync(claudeMdPath, '\n---\n\n' + CLAUDE_MD_CONTENT, 'utf8');
368
+ } else if (!existingMd.includes('## Disparadores')) {
369
+ // An older Lemma block ("úsalo cuando aporte algo real") — replace it in place with the
370
+ // trigger-based one, keeping whatever the user wrote around it.
371
+ const lemmaBlockRegex = /# Lemma MCP — Cómo usar[\s\S]*?\*Auto-generado por `lemma init` — @nxuss\/lemma\*/;
372
+ if (lemmaBlockRegex.test(existingMd)) {
373
+ fs.writeFileSync(claudeMdPath, existingMd.replace(lemmaBlockRegex, CLAUDE_MD_CONTENT.trim()), 'utf8');
374
+ }
345
375
  }
346
376
  } else {
347
377
  fs.writeFileSync(claudeMdPath, CLAUDE_MD_CONTENT, 'utf8');
@@ -363,11 +393,17 @@ function configureClaudeCode() {
363
393
  );
364
394
  settings.enableAllProjectMcpServers = true;
365
395
 
366
- // Rebuild Lemma tool permissions from the current catalog while preserving non-Lemma tools.
367
- const preservedTools = (settings.allowedTools || []).filter(
368
- (tool) => !tool.startsWith('mcp__lemma__')
369
- );
370
- settings.allowedTools = [...preservedTools, ...LEMMA_MCP_TOOLS];
396
+ // Pre-approve the core tools in permissions.allow — the key Claude Code reads from settings
397
+ // files. Earlier versions wrote the whole catalog to a top-level `allowedTools`, which left the
398
+ // tools the playbook asks for (get_memory, update_memory, ...) prompting on every call: a
399
+ // prompt per call is reason enough for an agent to fall back to its native tools. Lemma's
400
+ // entries are dropped from the legacy key; anything else in it is the user's and stays.
401
+ const legacy = (settings.allowedTools || []).filter((tool) => !tool.startsWith('mcp__lemma__'));
402
+ if (legacy.length > 0) settings.allowedTools = legacy;
403
+ else delete settings.allowedTools;
404
+ settings.permissions = settings.permissions && typeof settings.permissions === 'object' ? settings.permissions : {};
405
+ const allow = Array.isArray(settings.permissions.allow) ? settings.permissions.allow : [];
406
+ settings.permissions.allow = Array.from(new Set([...allow, ...LEMMA_PREAPPROVED_TOOLS]));
371
407
 
372
408
  fs.writeFileSync(settingsPath, JSON.stringify(settings, null, 2), 'utf8');
373
409
 
@@ -428,13 +464,13 @@ function configureClaudeCodeGateway(anthropicApiKey) {
428
464
  return { activated: true, settingsPath: claudeSettingsPath };
429
465
  }
430
466
 
431
- const LEMMA_RULES_CONTENT = `# Lemma MCP — Autonomous Behaviors
467
+ const LEMMA_RULES_CONTENT = `# Lemma MCP — When to use it
432
468
 
433
- > ⚠️ MANDATORY RULES — Follow without exception **for MCP-native clients**.
434
-
435
- The MCP server \`lemma\` is connected. For clients with native MCP support
436
- (Claude Code, Cursor, Codex, Windsurf, Kiro, OpenCode), NEVER use native tools
437
- when a Lemma equivalent exists.
469
+ The MCP server \`lemma\` is connected. What it does that your native tools can't is
470
+ **remember across sessions**: the Brain keeps verified fixes and decisions and flags them when
471
+ the code they depend on changes. That only pays off if it is consulted and fed, so the moments
472
+ below are not optional for MCP-native clients (Claude Code, Cursor, Codex, Windsurf, Kiro,
473
+ OpenCode).
438
474
 
439
475
  > **Muse Code:** you DO NOT have native \`mcp__lemma__*\` tools. At session
440
476
  > start, load the \`lemma\` skill (user scope if present, else
@@ -444,36 +480,34 @@ when a Lemma equivalent exists.
444
480
  > hard block; use \`lemma call\` when it actually helps. If no \`lemma\` skill
445
481
  > is installed, tell the user to run \`npx @nxuss/lemma init\`.
446
482
 
447
- ## Mandatory Substitutions (MCP-native clients only)
483
+ ## Triggers — always do these
484
+
485
+ | When… | Call | Why native isn't enough |
486
+ |---|---|---|
487
+ | Session start | \`get_project_onboarding\`, then \`search_memory\` with the task topic | The Brain may already hold the answer |
488
+ | Investigating a bug, an error, or a "why does X" | \`search_memory\` with the error text or question | grep can't find what was learned in another session |
489
+ | A 🧠 Lemma note names memories | \`get_memory\` on the top one | The note carries the headline; the body has the files and the reason |
490
+ | A fix is verified (tests pass, build ok, user confirmed) | \`store_memory\` with \`filePaths\` | Unsaved, the next session investigates it from scratch |
491
+ | A memory turned out outdated or wrong | \`update_memory\` / \`forget_memory\` | A near-duplicate leaves two versions and search mixes them |
492
+ | Reading code you haven't located yet, or that may hold secrets | \`search_workspace\` / \`read_workspace_file\` | They mask API keys before they reach your context |
493
+ | Applying a generated patch | \`validate_patch_sandbox\` first | Validate before writing, not after |
448
494
 
449
- ## Mandatory Substitutions
495
+ Outside those moments, use judgment: for a small file you already located, a native read costs
496
+ less than the round-trip, and for processes, ports or git Lemma has nothing to add.
450
497
 
451
- | ❌ NEVER use | ✅ ALWAYS use instead |
452
- |---|---|
453
- | Read / cat / open file | \`read_workspace_file\` |
454
- | Write / save file | \`write_workspace_file\` |
455
- | Create new file | \`create_workspace_file\` |
456
- | List / ls directory | \`list_workspace_dir\` |
457
- | Search / grep in files | \`search_workspace\` |
458
- | Search your own memory | \`search_memory\` |
459
- | Persist solutions | \`store_memory\` |
460
- | Project context | \`get_project_onboarding\` |
461
- | Runtime/bug context | \`get_telepathic_hints\` |
462
- | Apply a patch | \`validate_patch_sandbox\` first |
463
-
464
- ## Mandatory Flow — Session Start
465
-
466
- 1. Call \`get_project_onboarding\` — understand the project
467
- 2. Call \`search_memory\` with the task topic — recall past solutions
468
- 3. When done: call \`store_memory\` with the solution
498
+ ## Bug Reporting
499
+
500
+ 1. Call \`search_memory\` with the error message
501
+ 2. Call \`get_telepathic_hints\` (via \`lemma_toolbox\`) with the relevant file
469
502
 
470
503
  > Muse: use \`lemma call <tool>\` (or \`node ./lemma-proxy.cjs call <tool>\` in this repo — see \`.agents/skills/lemma/SKILL.md\`).
471
504
 
472
- ## Bug Reporting
505
+ ## One hard rule
473
506
 
474
- 1. Call \`get_telepathic_hints\` with the relevant file
475
- 2. Call \`search_memory\` with the error message
507
+ Any answer that depends on a cache hit, an auto-suggested fix, or a file compressed for your own
508
+ context must be delivered with the real information and without hiding where it came from.
476
509
 
510
+ ---
477
511
  *Auto-generated by \`lemma init\` — @nxuss/lemma*
478
512
  `;
479
513
 
@@ -491,8 +525,9 @@ function updateAgentsMd() {
491
525
  const existing = fs.readFileSync(agentsMdPath, 'utf8');
492
526
  if (!existing.includes('@nxuss/lemma')) {
493
527
  fs.appendFileSync(agentsMdPath, '\n---\n\n' + LEMMA_RULES_CONTENT, 'utf8');
494
- } else if (!existing.includes('Muse Code:') || !existing.includes('MCP-native clients')) {
495
- // Migrate old Lemma AGENTS.md (pre-Muse guard) to new version with Muse compatibility
528
+ } else if (!existing.includes('## Triggers')) {
529
+ // Migrate an older Lemma block (pre-Muse guard, or the "never use native tools" table) to
530
+ // the trigger-based rules
496
531
  // Replace the old block in-place to preserve any user content above it
497
532
  const lemmaBlockRegex = /# Lemma MCP[\s\S]*?\*Auto-generated by `lemma init` — @nxuss\/lemma\*/;
498
533
  if (lemmaBlockRegex.test(existing)) {
@@ -527,6 +562,12 @@ function updateWindsurfRules() {
527
562
  const existing = fs.readFileSync(wsRulesPath, 'utf8');
528
563
  if (!existing.includes('@nxuss/lemma')) {
529
564
  fs.appendFileSync(wsRulesPath, '\n---\n\n' + LEMMA_RULES_CONTENT, 'utf8');
565
+ } else if (!existing.includes('## Triggers')) {
566
+ // Same in-place migration as AGENTS.md: the older block was the "never use native" table.
567
+ const lemmaBlockRegex = /# Lemma MCP[\s\S]*?\*Auto-generated by `lemma init` — @nxuss\/lemma\*/;
568
+ if (lemmaBlockRegex.test(existing)) {
569
+ fs.writeFileSync(wsRulesPath, existing.replace(lemmaBlockRegex, LEMMA_RULES_CONTENT.trim()), 'utf8');
570
+ }
530
571
  }
531
572
  } else {
532
573
  fs.writeFileSync(wsRulesPath, LEMMA_RULES_CONTENT, 'utf8');
@@ -754,7 +795,7 @@ function ensureKiroMigratesAgentsMd() {
754
795
  try {
755
796
  if (fs.existsSync(agentsMdPath)) {
756
797
  const existing = fs.readFileSync(agentsMdPath, 'utf8');
757
- if (existing.includes('@nxuss/lemma') && (!existing.includes('Muse Code:') || !existing.includes('MCP-native clients'))) {
798
+ if (existing.includes('@nxuss/lemma') && !existing.includes('## Triggers')) {
758
799
  const lemmaBlockRegex = /# Lemma MCP[\s\S]*?\*Auto-generated by `lemma init` — @nxuss\/lemma\*/;
759
800
  if (lemmaBlockRegex.test(existing)) {
760
801
  const updated = existing.replace(lemmaBlockRegex, LEMMA_RULES_CONTENT.trim());
@@ -1171,4 +1212,4 @@ if (require.main === module) {
1171
1212
  });
1172
1213
  }
1173
1214
 
1174
- module.exports = { main, configureMuse, configureMuseUserSkill, updateAgentsMd, MUSE_SKILL_CONTENT, LEMMA_RULES_CONTENT, installProxyDaemon, removeProxyDaemon, parseInitArgs, createEnvFile, installBrainFeeds };
1215
+ module.exports = { main, configureMuse, configureMuseUserSkill, updateAgentsMd, configureClaudeCode, MUSE_SKILL_CONTENT, LEMMA_RULES_CONTENT, CLAUDE_MD_CONTENT, installProxyDaemon, removeProxyDaemon, parseInitArgs, createEnvFile, installBrainFeeds };
@@ -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:ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji",Segoe UI Symbol,"Noto Color Emoji";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:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,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}.visible{visibility:visible}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.left-5{left:1.25rem}.right-3{right:.75rem}.top-0{top:0}.top-1\/2{top:50%}.z-10{z-index:10}.z-50{z-index:50}.mx-4{margin-left:1rem;margin-right:1rem}.mx-auto{margin-left:auto;margin-right:auto}.mb-1{margin-bottom:.25rem}.mb-2{margin-bottom:.5rem}.mb-3{margin-bottom:.75rem}.mb-4{margin-bottom:1rem}.mb-5{margin-bottom:1.25rem}.ml-1{margin-left:.25rem}.ml-2{margin-left:.5rem}.ml-5{margin-left:1.25rem}.ml-auto{margin-left:auto}.mr-1{margin-right:.25rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-1\.5{margin-top:.375rem}.mt-2{margin-top:.5rem}.mt-2\.5{margin-top:.625rem}.mt-3{margin-top:.75rem}.mt-4{margin-top:1rem}.mt-5{margin-top:1.25rem}.line-clamp-3{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:3}.line-clamp-6{overflow:hidden;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:6}.block{display:block}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.hidden{display:none}.h-1{height:.25rem}.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-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-48{height:12rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-72{height:18rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-auto{height:auto}.h-full{height:100%}.max-h-28{max-height:7rem}.max-h-\[520px\]{max-height:520px}.max-h-\[560px\]{max-height:560px}.max-h-\[640px\]{max-height:640px}.min-h-0{min-height:0px}.min-h-\[320px\]{min-height:320px}.min-h-\[420px\]{min-height:420px}.min-h-screen{min-height:100vh}.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-20{width:5rem}.w-24{width:6rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-40{width:10rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-64{width:16rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-9{width:2.25rem}.w-full{width:100%}.min-w-0{min-width:0px}.max-w-2xl{max-width:42rem}.max-w-4xl{max-width:56rem}.max-w-\[1400px\]{max-width:1400px}.max-w-\[180px\]{max-width:180px}.max-w-\[200px\]{max-width:200px}.max-w-\[220px\]{max-width:220px}.max-w-lg{max-width:32rem}.max-w-md{max-width:28rem}.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-shrink-0{flex-shrink:0}.-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))}@keyframes pulse{50%{opacity:.5}}.animate-pulse{animation:pulse 2s cubic-bezier(.4,0,.6,1) infinite}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.list-disc{list-style-type:disc}.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))}.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}.items-baseline{align-items:baseline}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-2{gap:.5rem}.gap-2\.5{gap:.625rem}.gap-3{gap:.75rem}.gap-3\.5{gap:.875rem}.gap-4{gap:1rem}.gap-6{gap:1.5rem}.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-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * 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))}.divide-y>:not([hidden])~:not([hidden]){--tw-divide-y-reverse: 0;border-top-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)));border-bottom-width:calc(1px * var(--tw-divide-y-reverse))}.divide-gray-50>:not([hidden])~:not([hidden]){--tw-divide-opacity: 1;border-color:rgb(249 250 251 / var(--tw-divide-opacity, 1))}.divide-white\/5>:not([hidden])~:not([hidden]){border-color:#ffffff0d}.self-center{align-self:center}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-\[8px\]{border-radius:8px}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-none{border-radius:0}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-l{border-left-width:1px}.border-r{border-right-width:1px}.border-t{border-top-width:1px}.border-amber-200{--tw-border-opacity: 1;border-color:rgb(253 230 138 / var(--tw-border-opacity, 1))}.border-amber-400\/20{border-color:#fbbf2433}.border-amber-500\/20{border-color:#f59e0b33}.border-amber-500\/40{border-color:#f59e0b66}.border-blue-100{--tw-border-opacity: 1;border-color:rgb(219 234 254 / var(--tw-border-opacity, 1))}.border-blue-200{--tw-border-opacity: 1;border-color:rgb(191 219 254 / var(--tw-border-opacity, 1))}.border-cyan-200{--tw-border-opacity: 1;border-color:rgb(165 243 252 / var(--tw-border-opacity, 1))}.border-cyan-500\/20{border-color:#06b6d433}.border-emerald-100{--tw-border-opacity: 1;border-color:rgb(209 250 229 / var(--tw-border-opacity, 1))}.border-emerald-200{--tw-border-opacity: 1;border-color:rgb(167 243 208 / var(--tw-border-opacity, 1))}.border-emerald-400\/25{border-color:#34d39940}.border-emerald-400\/40{border-color:#34d39966}.border-emerald-500\/20{border-color:#10b98133}.border-emerald-500\/25{border-color:#10b98140}.border-emerald-500\/30{border-color:#10b9814d}.border-emerald-500\/40{border-color:#10b98166}.border-gray-200{--tw-border-opacity: 1;border-color:rgb(229 231 235 / var(--tw-border-opacity, 1))}.border-gray-700\/50{border-color:#37415180}.border-gray-800{--tw-border-opacity: 1;border-color:rgb(31 41 55 / var(--tw-border-opacity, 1))}.border-gray-800\/80{border-color:#1f2937cc}.border-indigo-200{--tw-border-opacity: 1;border-color:rgb(199 210 254 / var(--tw-border-opacity, 1))}.border-indigo-500\/10{border-color:#6366f11a}.border-indigo-500\/20{border-color:#6366f133}.border-indigo-500\/40{border-color:#6366f166}.border-lime-200{--tw-border-opacity: 1;border-color:rgb(217 249 157 / var(--tw-border-opacity, 1))}.border-orange-200{--tw-border-opacity: 1;border-color:rgb(254 215 170 / var(--tw-border-opacity, 1))}.border-pink-200{--tw-border-opacity: 1;border-color:rgb(251 207 232 / var(--tw-border-opacity, 1))}.border-purple-200{--tw-border-opacity: 1;border-color:rgb(233 213 255 / var(--tw-border-opacity, 1))}.border-purple-500\/30{border-color:#a855f74d}.border-red-100{--tw-border-opacity: 1;border-color:rgb(254 226 226 / var(--tw-border-opacity, 1))}.border-red-200{--tw-border-opacity: 1;border-color:rgb(254 202 202 / var(--tw-border-opacity, 1))}.border-red-500\/20{border-color:#ef444433}.border-rose-500\/20{border-color:#f43f5e33}.border-rose-500\/30{border-color:#f43f5e4d}.border-sky-500\/25{border-color:#0ea5e940}.border-teal-200{--tw-border-opacity: 1;border-color:rgb(153 246 228 / var(--tw-border-opacity, 1))}.border-transparent{border-color:transparent}.border-violet-100{--tw-border-opacity: 1;border-color:rgb(237 233 254 / var(--tw-border-opacity, 1))}.border-violet-500\/20{border-color:#8b5cf633}.border-white\/10{border-color:#ffffff1a}.border-white\/5{border-color:#ffffff0d}.border-white\/\[0\.07\]{border-color:#ffffff12}.border-white\/\[0\.08\]{border-color:#ffffff14}.border-white\/\[0\.1\]{border-color:#ffffff1a}.border-yellow-200{--tw-border-opacity: 1;border-color:rgb(254 240 138 / var(--tw-border-opacity, 1))}.bg-\[\#07090c\]{--tw-bg-opacity: 1;background-color:rgb(7 9 12 / var(--tw-bg-opacity, 1))}.bg-\[\#090c10\]{--tw-bg-opacity: 1;background-color:rgb(9 12 16 / var(--tw-bg-opacity, 1))}.bg-\[\#0a0d11\]{--tw-bg-opacity: 1;background-color:rgb(10 13 17 / var(--tw-bg-opacity, 1))}.bg-\[\#0f141a\]{--tw-bg-opacity: 1;background-color:rgb(15 20 26 / var(--tw-bg-opacity, 1))}.bg-amber-100{--tw-bg-opacity: 1;background-color:rgb(254 243 199 / var(--tw-bg-opacity, 1))}.bg-amber-400{--tw-bg-opacity: 1;background-color:rgb(251 191 36 / var(--tw-bg-opacity, 1))}.bg-amber-400\/10{background-color:#fbbf241a}.bg-amber-400\/70{background-color:#fbbf24b3}.bg-amber-50{--tw-bg-opacity: 1;background-color:rgb(255 251 235 / var(--tw-bg-opacity, 1))}.bg-amber-500{--tw-bg-opacity: 1;background-color:rgb(245 158 11 / var(--tw-bg-opacity, 1))}.bg-amber-500\/10{background-color:#f59e0b1a}.bg-amber-500\/20{background-color:#f59e0b33}.bg-amber-500\/\[0\.06\]{background-color:#f59e0b0f}.bg-amber-600{--tw-bg-opacity: 1;background-color:rgb(217 119 6 / var(--tw-bg-opacity, 1))}.bg-black{--tw-bg-opacity: 1;background-color:rgb(0 0 0 / var(--tw-bg-opacity, 1))}.bg-black\/20{background-color:#0003}.bg-black\/30{background-color:#0000004d}.bg-black\/60{background-color:#0009}.bg-blue-100{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.bg-blue-50{--tw-bg-opacity: 1;background-color:rgb(239 246 255 / var(--tw-bg-opacity, 1))}.bg-blue-500{--tw-bg-opacity: 1;background-color:rgb(59 130 246 / var(--tw-bg-opacity, 1))}.bg-blue-600{--tw-bg-opacity: 1;background-color:rgb(37 99 235 / var(--tw-bg-opacity, 1))}.bg-cyan-100{--tw-bg-opacity: 1;background-color:rgb(207 250 254 / var(--tw-bg-opacity, 1))}.bg-cyan-50{--tw-bg-opacity: 1;background-color:rgb(236 254 255 / var(--tw-bg-opacity, 1))}.bg-cyan-500{--tw-bg-opacity: 1;background-color:rgb(6 182 212 / var(--tw-bg-opacity, 1))}.bg-cyan-500\/10{background-color:#06b6d41a}.bg-emerald-100{--tw-bg-opacity: 1;background-color:rgb(209 250 229 / var(--tw-bg-opacity, 1))}.bg-emerald-400{--tw-bg-opacity: 1;background-color:rgb(52 211 153 / var(--tw-bg-opacity, 1))}.bg-emerald-400\/10{background-color:#34d3991a}.bg-emerald-400\/15{background-color:#34d39926}.bg-emerald-400\/\[0\.06\]{background-color:#34d3990f}.bg-emerald-50{--tw-bg-opacity: 1;background-color:rgb(236 253 245 / var(--tw-bg-opacity, 1))}.bg-emerald-500{--tw-bg-opacity: 1;background-color:rgb(16 185 129 / var(--tw-bg-opacity, 1))}.bg-emerald-500\/10{background-color:#10b9811a}.bg-emerald-500\/15{background-color:#10b98126}.bg-emerald-500\/20{background-color:#10b98133}.bg-emerald-600{--tw-bg-opacity: 1;background-color:rgb(5 150 105 / var(--tw-bg-opacity, 1))}.bg-gray-100{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.bg-gray-400{--tw-bg-opacity: 1;background-color:rgb(156 163 175 / var(--tw-bg-opacity, 1))}.bg-gray-50{--tw-bg-opacity: 1;background-color:rgb(249 250 251 / var(--tw-bg-opacity, 1))}.bg-gray-800{--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.bg-gray-900{--tw-bg-opacity: 1;background-color:rgb(17 24 39 / var(--tw-bg-opacity, 1))}.bg-gray-900\/60{background-color:#11182799}.bg-gray-950{--tw-bg-opacity: 1;background-color:rgb(3 7 18 / var(--tw-bg-opacity, 1))}.bg-indigo-100{--tw-bg-opacity: 1;background-color:rgb(224 231 255 / var(--tw-bg-opacity, 1))}.bg-indigo-50{--tw-bg-opacity: 1;background-color:rgb(238 242 255 / var(--tw-bg-opacity, 1))}.bg-indigo-500{--tw-bg-opacity: 1;background-color:rgb(99 102 241 / var(--tw-bg-opacity, 1))}.bg-indigo-500\/10{background-color:#6366f11a}.bg-indigo-500\/5{background-color:#6366f10d}.bg-indigo-600{--tw-bg-opacity: 1;background-color:rgb(79 70 229 / var(--tw-bg-opacity, 1))}.bg-indigo-600\/10{background-color:#4f46e51a}.bg-lime-100{--tw-bg-opacity: 1;background-color:rgb(236 252 203 / var(--tw-bg-opacity, 1))}.bg-lime-50{--tw-bg-opacity: 1;background-color:rgb(247 254 231 / var(--tw-bg-opacity, 1))}.bg-lime-500{--tw-bg-opacity: 1;background-color:rgb(132 204 22 / var(--tw-bg-opacity, 1))}.bg-orange-100{--tw-bg-opacity: 1;background-color:rgb(255 237 213 / var(--tw-bg-opacity, 1))}.bg-orange-50{--tw-bg-opacity: 1;background-color:rgb(255 247 237 / var(--tw-bg-opacity, 1))}.bg-orange-500{--tw-bg-opacity: 1;background-color:rgb(249 115 22 / var(--tw-bg-opacity, 1))}.bg-pink-100{--tw-bg-opacity: 1;background-color:rgb(252 231 243 / var(--tw-bg-opacity, 1))}.bg-pink-50{--tw-bg-opacity: 1;background-color:rgb(253 242 248 / var(--tw-bg-opacity, 1))}.bg-pink-500{--tw-bg-opacity: 1;background-color:rgb(236 72 153 / var(--tw-bg-opacity, 1))}.bg-purple-100{--tw-bg-opacity: 1;background-color:rgb(243 232 255 / var(--tw-bg-opacity, 1))}.bg-purple-50{--tw-bg-opacity: 1;background-color:rgb(250 245 255 / var(--tw-bg-opacity, 1))}.bg-purple-500{--tw-bg-opacity: 1;background-color:rgb(168 85 247 / var(--tw-bg-opacity, 1))}.bg-purple-500\/20{background-color:#a855f733}.bg-red-100{--tw-bg-opacity: 1;background-color:rgb(254 226 226 / var(--tw-bg-opacity, 1))}.bg-red-400{--tw-bg-opacity: 1;background-color:rgb(248 113 113 / var(--tw-bg-opacity, 1))}.bg-red-50{--tw-bg-opacity: 1;background-color:rgb(254 242 242 / var(--tw-bg-opacity, 1))}.bg-red-500{--tw-bg-opacity: 1;background-color:rgb(239 68 68 / var(--tw-bg-opacity, 1))}.bg-red-500\/10{background-color:#ef44441a}.bg-rose-500{--tw-bg-opacity: 1;background-color:rgb(244 63 94 / var(--tw-bg-opacity, 1))}.bg-rose-500\/10{background-color:#f43f5e1a}.bg-rose-500\/\[0\.05\]{background-color:#f43f5e0d}.bg-sky-500\/15{background-color:#0ea5e926}.bg-slate-400{--tw-bg-opacity: 1;background-color:rgb(148 163 184 / var(--tw-bg-opacity, 1))}.bg-slate-600{--tw-bg-opacity: 1;background-color:rgb(71 85 105 / var(--tw-bg-opacity, 1))}.bg-slate-900\/40{background-color:#0f172a66}.bg-slate-900\/60{background-color:#0f172a99}.bg-slate-900\/90{background-color:#0f172ae6}.bg-teal-100{--tw-bg-opacity: 1;background-color:rgb(204 251 241 / var(--tw-bg-opacity, 1))}.bg-teal-50{--tw-bg-opacity: 1;background-color:rgb(240 253 250 / var(--tw-bg-opacity, 1))}.bg-teal-500{--tw-bg-opacity: 1;background-color:rgb(20 184 166 / var(--tw-bg-opacity, 1))}.bg-transparent{background-color:transparent}.bg-violet-50{--tw-bg-opacity: 1;background-color:rgb(245 243 255 / var(--tw-bg-opacity, 1))}.bg-violet-500\/10{background-color:#8b5cf61a}.bg-white{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.bg-white\/5{background-color:#ffffff0d}.bg-white\/\[0\.02\]{background-color:#ffffff05}.bg-white\/\[0\.03\]{background-color:#ffffff08}.bg-white\/\[0\.05\]{background-color:#ffffff0d}.bg-yellow-100{--tw-bg-opacity: 1;background-color:rgb(254 249 195 / var(--tw-bg-opacity, 1))}.bg-yellow-50{--tw-bg-opacity: 1;background-color:rgb(254 252 232 / var(--tw-bg-opacity, 1))}.bg-yellow-500{--tw-bg-opacity: 1;background-color:rgb(234 179 8 / var(--tw-bg-opacity, 1))}.bg-opacity-50{--tw-bg-opacity: .5}.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))}.from-cyan-500{--tw-gradient-from: #06b6d4 var(--tw-gradient-from-position);--tw-gradient-to: rgb(6 182 212 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-indigo-400{--tw-gradient-from: #818cf8 var(--tw-gradient-from-position);--tw-gradient-to: rgb(129 140 248 / 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-purple-500{--tw-gradient-from: #a855f7 var(--tw-gradient-from-position);--tw-gradient-to: rgb(168 85 247 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.from-violet-500{--tw-gradient-from: #8b5cf6 var(--tw-gradient-from-position);--tw-gradient-to: rgb(139 92 246 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), var(--tw-gradient-to)}.via-purple-500{--tw-gradient-to: rgb(168 85 247 / 0) var(--tw-gradient-to-position);--tw-gradient-stops: var(--tw-gradient-from), #a855f7 var(--tw-gradient-via-position), var(--tw-gradient-to)}.to-cyan-400{--tw-gradient-to: #22d3ee var(--tw-gradient-to-position)}.to-pink-500{--tw-gradient-to: #ec4899 var(--tw-gradient-to-position)}.to-pink-600{--tw-gradient-to: #db2777 var(--tw-gradient-to-position)}.to-purple-500{--tw-gradient-to: #a855f7 var(--tw-gradient-to-position)}.to-purple-600{--tw-gradient-to: #9333ea var(--tw-gradient-to-position)}.to-violet-500{--tw-gradient-to: #8b5cf6 var(--tw-gradient-to-position)}.p-0\.5{padding:.125rem}.p-1{padding:.25rem}.p-1\.5{padding:.375rem}.p-2{padding:.5rem}.p-2\.5{padding:.625rem}.p-3{padding:.75rem}.p-3\.5{padding:.875rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-7{padding:1.75rem}.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-2\.5{padding-left:.625rem;padding-right:.625rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-3\.5{padding-left:.875rem;padding-right:.875rem}.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-7{padding-left:1.75rem;padding-right:1.75rem}.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-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-5{padding-top:1.25rem;padding-bottom:1.25rem}.py-6{padding-top:1.5rem;padding-bottom:1.5rem}.py-8{padding-top:2rem;padding-bottom:2rem}.py-\[7px\]{padding-top:7px;padding-bottom:7px}.py-px{padding-top:1px;padding-bottom:1px}.pb-0\.5{padding-bottom:.125rem}.pb-3{padding-bottom:.75rem}.pb-8{padding-bottom:2rem}.pl-14{padding-left:3.5rem}.pl-5{padding-left:1.25rem}.pl-6{padding-left:1.5rem}.pr-4{padding-right:1rem}.pt-1{padding-top:.25rem}.pt-4{padding-top:1rem}.text-left{text-align:left}.text-center{text-align:center}.text-right{text-align:right}.font-mono{font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\[10\.5px\]{font-size:10.5px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.text-\[22px\]{font-size:22px}.text-\[28px\]{font-size:28px}.text-\[36px\]{font-size:36px}.text-\[48px\]{font-size:48px}.text-\[64px\]{font-size:64px}.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-extrabold{font-weight:800}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing: tabular-nums;font-variant-numeric:var(--tw-ordinal) var(--tw-slashed-zero) var(--tw-numeric-figure) var(--tw-numeric-spacing) var(--tw-numeric-fraction)}.leading-none{line-height:1}.leading-relaxed{line-height:1.625}.leading-tight{line-height:1.25}.tracking-\[-0\.03em\]{letter-spacing:-.03em}.tracking-\[0\.08em\]{letter-spacing:.08em}.tracking-\[0\.14em\]{letter-spacing:.14em}.tracking-normal{letter-spacing:0em}.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-amber-200\/70{color:#fde68ab3}.text-amber-200\/90{color:#fde68ae6}.text-amber-300{--tw-text-opacity: 1;color:rgb(252 211 77 / var(--tw-text-opacity, 1))}.text-amber-300\/80{color:#fcd34dcc}.text-amber-400{--tw-text-opacity: 1;color:rgb(251 191 36 / var(--tw-text-opacity, 1))}.text-amber-600{--tw-text-opacity: 1;color:rgb(217 119 6 / var(--tw-text-opacity, 1))}.text-amber-700{--tw-text-opacity: 1;color:rgb(180 83 9 / var(--tw-text-opacity, 1))}.text-black{--tw-text-opacity: 1;color:rgb(0 0 0 / 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-blue-600{--tw-text-opacity: 1;color:rgb(37 99 235 / var(--tw-text-opacity, 1))}.text-blue-700{--tw-text-opacity: 1;color:rgb(29 78 216 / var(--tw-text-opacity, 1))}.text-cyan-400{--tw-text-opacity: 1;color:rgb(34 211 238 / var(--tw-text-opacity, 1))}.text-cyan-700{--tw-text-opacity: 1;color:rgb(14 116 144 / var(--tw-text-opacity, 1))}.text-emerald-200{--tw-text-opacity: 1;color:rgb(167 243 208 / var(--tw-text-opacity, 1))}.text-emerald-300{--tw-text-opacity: 1;color:rgb(110 231 183 / 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-emerald-700{--tw-text-opacity: 1;color:rgb(4 120 87 / var(--tw-text-opacity, 1))}.text-gray-100{--tw-text-opacity: 1;color:rgb(243 244 246 / var(--tw-text-opacity, 1))}.text-gray-300{--tw-text-opacity: 1;color:rgb(209 213 219 / var(--tw-text-opacity, 1))}.text-gray-400{--tw-text-opacity: 1;color:rgb(156 163 175 / var(--tw-text-opacity, 1))}.text-gray-500{--tw-text-opacity: 1;color:rgb(107 114 128 / var(--tw-text-opacity, 1))}.text-gray-600{--tw-text-opacity: 1;color:rgb(75 85 99 / var(--tw-text-opacity, 1))}.text-gray-700{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.text-gray-800{--tw-text-opacity: 1;color:rgb(31 41 55 / var(--tw-text-opacity, 1))}.text-gray-900{--tw-text-opacity: 1;color:rgb(17 24 39 / var(--tw-text-opacity, 1))}.text-green-600{--tw-text-opacity: 1;color:rgb(22 163 74 / var(--tw-text-opacity, 1))}.text-indigo-400{--tw-text-opacity: 1;color:rgb(129 140 248 / var(--tw-text-opacity, 1))}.text-indigo-700{--tw-text-opacity: 1;color:rgb(67 56 202 / var(--tw-text-opacity, 1))}.text-lime-700{--tw-text-opacity: 1;color:rgb(77 124 15 / var(--tw-text-opacity, 1))}.text-orange-500{--tw-text-opacity: 1;color:rgb(249 115 22 / var(--tw-text-opacity, 1))}.text-orange-700{--tw-text-opacity: 1;color:rgb(194 65 12 / var(--tw-text-opacity, 1))}.text-pink-700{--tw-text-opacity: 1;color:rgb(190 24 93 / var(--tw-text-opacity, 1))}.text-purple-400{--tw-text-opacity: 1;color:rgb(192 132 252 / var(--tw-text-opacity, 1))}.text-purple-700{--tw-text-opacity: 1;color:rgb(126 34 206 / var(--tw-text-opacity, 1))}.text-red-400{--tw-text-opacity: 1;color:rgb(248 113 113 / var(--tw-text-opacity, 1))}.text-red-600{--tw-text-opacity: 1;color:rgb(220 38 38 / var(--tw-text-opacity, 1))}.text-red-700{--tw-text-opacity: 1;color:rgb(185 28 28 / var(--tw-text-opacity, 1))}.text-rose-200\/90{color:#fecdd3e6}.text-rose-300{--tw-text-opacity: 1;color:rgb(253 164 175 / var(--tw-text-opacity, 1))}.text-rose-300\/70{color:#fda4afb3}.text-rose-400{--tw-text-opacity: 1;color:rgb(251 113 133 / var(--tw-text-opacity, 1))}.text-rose-400\/80{color:#fb7185cc}.text-rose-400\/90{color:#fb7185e6}.text-sky-400{--tw-text-opacity: 1;color:rgb(56 189 248 / var(--tw-text-opacity, 1))}.text-slate-200{--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}.text-slate-300{--tw-text-opacity: 1;color:rgb(203 213 225 / var(--tw-text-opacity, 1))}.text-slate-400{--tw-text-opacity: 1;color:rgb(148 163 184 / var(--tw-text-opacity, 1))}.text-slate-500{--tw-text-opacity: 1;color:rgb(100 116 139 / var(--tw-text-opacity, 1))}.text-slate-600{--tw-text-opacity: 1;color:rgb(71 85 105 / var(--tw-text-opacity, 1))}.text-slate-700{--tw-text-opacity: 1;color:rgb(51 65 85 / var(--tw-text-opacity, 1))}.text-teal-700{--tw-text-opacity: 1;color:rgb(15 118 110 / var(--tw-text-opacity, 1))}.text-violet-300{--tw-text-opacity: 1;color:rgb(196 181 253 / var(--tw-text-opacity, 1))}.text-violet-400{--tw-text-opacity: 1;color:rgb(167 139 250 / var(--tw-text-opacity, 1))}.text-violet-500{--tw-text-opacity: 1;color:rgb(139 92 246 / var(--tw-text-opacity, 1))}.text-violet-700{--tw-text-opacity: 1;color:rgb(109 40 217 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.text-yellow-700{--tw-text-opacity: 1;color:rgb(161 98 7 / var(--tw-text-opacity, 1))}.placeholder-slate-500::-moz-placeholder{--tw-placeholder-opacity: 1;color:rgb(100 116 139 / var(--tw-placeholder-opacity, 1))}.placeholder-slate-500::placeholder{--tw-placeholder-opacity: 1;color:rgb(100 116 139 / var(--tw-placeholder-opacity, 1))}.accent-rose-500{accent-color:#f43f5e}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.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_20px_rgba\(79\,70\,229\,0\.15\)\]{--tw-shadow: 0 0 20px rgba(79,70,229,.15);--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-\[0_0_30px_rgba\(99\,102\,241\,0\.4\)\]{--tw-shadow: 0 0 30px rgba(99,102,241,.4);--tw-shadow-colored: 0 0 30px 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_8px_rgba\(52\,211\,153\,0\.6\)\]{--tw-shadow: 0 0 8px rgba(52,211,153,.6);--tw-shadow-colored: 0 0 8px 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)}.ring{--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(3px + 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)}.ring-2{--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)}.ring-amber-200{--tw-ring-opacity: 1;--tw-ring-color: rgb(253 230 138 / var(--tw-ring-opacity, 1))}.ring-emerald-200{--tw-ring-opacity: 1;--tw-ring-color: rgb(167 243 208 / var(--tw-ring-opacity, 1))}.ring-indigo-300{--tw-ring-opacity: 1;--tw-ring-color: rgb(165 180 252 / var(--tw-ring-opacity, 1))}.ring-red-200{--tw-ring-opacity: 1;--tw-ring-color: rgb(254 202 202 / var(--tw-ring-opacity, 1))}.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}.duration-100{transition-duration:.1s}.duration-150{transition-duration:.15s}.duration-200{transition-duration:.2s}.duration-300{transition-duration:.3s}:root{font-family:Outfit,system-ui,-apple-system,sans-serif;line-height:1.5;font-weight:400;color-scheme:dark;color:#e8edf2;background-color:#07090c;font-synthesis:none;text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;--signal: #34d399;--ink: #f2f5f7;--muted: #8b95a1;--faint: #5b6470;--hairline: rgba(255, 255, 255, .08);--panel: #0c1015}body{margin:0;min-width:320px;min-height:100vh;background-color:#07090c;color:#e8edf2}#root{width:100%;min-height:100vh}::-moz-selection{background:#34d39947;color:#fff}::selection{background:#34d39947;color:#fff}.panel-card{background-color:var(--panel);border:1px solid var(--hairline);border-radius:10px;overflow:hidden}.panel-title{font-size:14px;font-weight:650;color:var(--ink);letter-spacing:-.01em}.panel-desc{font-size:12.5px;color:var(--muted);margin-top:2px;line-height:1.5}.mono{font-family:ui-monospace,SF Mono,Cascadia Code,Menlo,Consolas,monospace;font-feature-settings:"tnum" 1,"zero" 1}.display-figure{font-weight:800;letter-spacing:-.045em;line-height:.95;color:#fff}.eyebrow{font-family:ui-monospace,SF Mono,Menlo,Consolas,monospace;font-size:11px;font-weight:500;letter-spacing:.14em;text-transform:uppercase;color:var(--signal)}.section-rule{border-top:1px solid var(--hairline)}.section-index{font-family:ui-monospace,SF Mono,Menlo,Consolas,monospace;font-size:11px;color:var(--faint)}.section-anchor{scroll-margin-top:132px}.ticker-track{display:flex;gap:0;width:-moz-max-content;width:max-content;animation:ticker-scroll 36s linear infinite}@keyframes ticker-scroll{0%{transform:translate(0)}to{transform:translate(-50%)}}.ticker-cell{display:inline-flex;align-items:baseline;gap:8px;padding:0 22px;border-right:1px solid var(--hairline);white-space:nowrap}.live-dot{width:7px;height:7px;border-radius:999px;background:var(--signal);box-shadow:0 0 10px #34d399e6;align-self:center}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:#ffffff1f;border-radius:999px}::-webkit-scrollbar-thumb:hover{background:#fff3}.recharts-cartesian-grid line{stroke:#ffffff0f}.recharts-tooltip-wrapper{filter:drop-shadow(0 10px 20px rgba(0,0,0,.4))}.recharts-default-tooltip{background-color:#0c1015f2!important;border-radius:10px!important;border-color:#ffffff1a!important}:focus-visible{outline:2px solid rgba(52,211,153,.7);outline-offset:2px}@media (prefers-reduced-motion: reduce){*,*:before,*:after{animation-duration:.01ms!important;transition-duration:.01ms!important}}.last\:border-0:last-child{border-width:0px}.last\:border-b-0:last-child{border-bottom-width:0px}.hover\:border-white\/10:hover{border-color:#ffffff1a}.hover\:bg-amber-400:hover{--tw-bg-opacity: 1;background-color:rgb(251 191 36 / var(--tw-bg-opacity, 1))}.hover\:bg-amber-500:hover{--tw-bg-opacity: 1;background-color:rgb(245 158 11 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-100:hover{--tw-bg-opacity: 1;background-color:rgb(219 234 254 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-700:hover{--tw-bg-opacity: 1;background-color:rgb(29 78 216 / var(--tw-bg-opacity, 1))}.hover\:bg-emerald-400:hover{--tw-bg-opacity: 1;background-color:rgb(52 211 153 / var(--tw-bg-opacity, 1))}.hover\:bg-emerald-500:hover{--tw-bg-opacity: 1;background-color:rgb(16 185 129 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-100:hover{--tw-bg-opacity: 1;background-color:rgb(243 244 246 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-200:hover{--tw-bg-opacity: 1;background-color:rgb(229 231 235 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-700:hover{--tw-bg-opacity: 1;background-color:rgb(55 65 81 / var(--tw-bg-opacity, 1))}.hover\:bg-gray-800:hover{--tw-bg-opacity: 1;background-color:rgb(31 41 55 / var(--tw-bg-opacity, 1))}.hover\:bg-indigo-100:hover{--tw-bg-opacity: 1;background-color:rgb(224 231 255 / var(--tw-bg-opacity, 1))}.hover\:bg-indigo-500:hover{--tw-bg-opacity: 1;background-color:rgb(99 102 241 / var(--tw-bg-opacity, 1))}.hover\:bg-rose-400:hover{--tw-bg-opacity: 1;background-color:rgb(251 113 133 / var(--tw-bg-opacity, 1))}.hover\:bg-violet-50\/50:hover{background-color:#f5f3ff80}.hover\:bg-white:hover{--tw-bg-opacity: 1;background-color:rgb(255 255 255 / var(--tw-bg-opacity, 1))}.hover\:bg-white\/10:hover{background-color:#ffffff1a}.hover\:bg-white\/5:hover{background-color:#ffffff0d}.hover\:bg-white\/\[0\.04\]:hover{background-color:#ffffff0a}.hover\:bg-white\/\[0\.05\]:hover{background-color:#ffffff0d}.hover\:bg-white\/\[0\.06\]:hover{background-color:#ffffff0f}.hover\:bg-white\/\[0\.08\]:hover{background-color:#ffffff14}.hover\:text-gray-200:hover{--tw-text-opacity: 1;color:rgb(229 231 235 / var(--tw-text-opacity, 1))}.hover\:text-gray-700:hover{--tw-text-opacity: 1;color:rgb(55 65 81 / var(--tw-text-opacity, 1))}.hover\:text-indigo-300:hover{--tw-text-opacity: 1;color:rgb(165 180 252 / var(--tw-text-opacity, 1))}.hover\:text-slate-100:hover{--tw-text-opacity: 1;color:rgb(241 245 249 / var(--tw-text-opacity, 1))}.hover\:text-slate-200:hover{--tw-text-opacity: 1;color:rgb(226 232 240 / var(--tw-text-opacity, 1))}.hover\:text-white:hover{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.focus\:border-emerald-400\/40:focus{border-color:#34d39966}.focus\:border-indigo-500\/50:focus{border-color:#6366f180}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.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-indigo-500\/50:focus{--tw-ring-color: rgb(99 102 241 / .5)}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-20:disabled{opacity:.2}.disabled\:opacity-50:disabled{opacity:.5}.group:hover .group-hover\:line-clamp-none{overflow:visible;display:block;-webkit-box-orient:horizontal;-webkit-line-clamp:none}.group:hover .group-hover\:text-emerald-400{--tw-text-opacity: 1;color:rgb(52 211 153 / var(--tw-text-opacity, 1))}.group:hover .group-hover\:text-indigo-300{--tw-text-opacity: 1;color:rgb(165 180 252 / var(--tw-text-opacity, 1))}.group:hover .group-hover\:text-indigo-400{--tw-text-opacity: 1;color:rgb(129 140 248 / var(--tw-text-opacity, 1))}.group:hover .group-hover\:text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}@media (min-width: 640px){.sm\:inline-flex{display:inline-flex}.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:border-l{border-left-width:1px}.sm\:border-t-0{border-top-width:0px}}@media (min-width: 768px){.md\:block{display:block}.md\:flex{display:flex}.md\:hidden{display:none}.md\:p-9{padding:2.25rem}.md\:text-\[64px\]{font-size:64px}.md\:text-\[96px\]{font-size:96px}}@media (min-width: 1024px){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:border-l{border-left-width:1px}.lg\:border-t-0{border-top-width:0px}}@media (min-width: 1280px){.xl\:col-span-12{grid-column:span 12 / span 12}.xl\:col-span-3{grid-column:span 3 / span 3}.xl\:col-span-4{grid-column:span 4 / span 4}.xl\:col-span-5{grid-column:span 5 / span 5}.xl\:col-span-7{grid-column:span 7 / span 7}.xl\:grid-cols-12{grid-template-columns:repeat(12,minmax(0,1fr))}.xl\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}