@crouton-kit/humanloop 0.3.29 → 0.3.31

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.
@@ -1,6 +1,7 @@
1
1
  import { existsSync, lstatSync, readFileSync, realpathSync } from 'node:fs';
2
2
  import { dirname, resolve, sep } from 'node:path';
3
3
  import { z } from 'zod';
4
+ import { INTERACTION_KINDS } from '../types.js';
4
5
  import { checkMarkdown } from '../render/termrender.js';
5
6
  // ── zod v4 building blocks ────────────────────────────────────────────────────
6
7
  // v4 notes: .nonempty() → .min(1); error messages use {error: 'string'} per check.
@@ -29,7 +30,7 @@ const interactionSchema = z.object({
29
30
  multiSelect: z.boolean().optional(),
30
31
  allowFreetext: z.boolean().optional(),
31
32
  freetextLabel: z.string().optional(),
32
- kind: z.enum(['notify', 'decision', 'context', 'error']).optional(),
33
+ kind: z.enum(INTERACTION_KINDS).optional(),
33
34
  preAnswered: preAnswerSchema.optional(),
34
35
  });
35
36
  const deckSourceSchema = z.object({
@@ -65,12 +66,16 @@ export const deckSchema = z.object({
65
66
  }
66
67
  });
67
68
  // ── C2 bodyPath defense + inlining ────────────────────────────────────────────
68
- export function inlineBodyPath(deckPath, bodyPath) {
69
- const deckDir = dirname(deckPath);
70
- const joined = resolve(deckDir, bodyPath);
69
+ /**
70
+ * Read `bodyPath` (relative to `dir`, the interaction directory a deck.json
71
+ * lives/will live in) with the traversal/symlink defenses a file read off an
72
+ * agent-supplied relative path needs.
73
+ */
74
+ function readBodyPathFile(dir, bodyPath) {
75
+ const joined = resolve(dir, bodyPath);
71
76
  // STEP 1: existence + lstat BEFORE realpath to catch symlinks and directories.
72
77
  if (!existsSync(joined)) {
73
- throw new Error(`bodyPath does not exist: '${bodyPath}' (resolved against deck dir '${deckDir}'). bodyPath is interpreted relative to the deck JSON's directory; place the body file there and use a relative path (e.g. "completion-summary.md").`);
78
+ throw new Error(`bodyPath does not exist: '${bodyPath}' (resolved against deck dir '${dir}'). bodyPath is interpreted relative to the deck JSON's directory; place the body file there and use a relative path (e.g. "completion-summary.md").`);
74
79
  }
75
80
  const stat = lstatSync(joined);
76
81
  if (!stat.isFile()) {
@@ -80,7 +85,7 @@ export function inlineBodyPath(deckPath, bodyPath) {
80
85
  // STEP 2: realpath both sides, prefix-check (defense-in-depth for .. traversal).
81
86
  // realpathSync is safe here: lstat already confirmed the path exists.
82
87
  const realResolved = realpathSync(joined);
83
- const realDeckDir = realpathSync(deckDir);
88
+ const realDeckDir = realpathSync(dir);
84
89
  const prefix = realDeckDir + sep;
85
90
  if (realResolved !== realDeckDir && !realResolved.startsWith(prefix)) {
86
91
  throw new Error(`bodyPath '${bodyPath}' escapes the deck's directory ('${realDeckDir}'). bodyPath is resolved relative to the deck JSON file and must stay inside its directory (no '..', absolute paths pointing elsewhere, or symlinks out). Fix: write the deck JSON next to the body file (e.g. both inside $SISYPHUS_SESSION_DIR/context/) and use a relative path like "completion-summary.md".`);
@@ -88,6 +93,29 @@ export function inlineBodyPath(deckPath, bodyPath) {
88
93
  // STEP 3: read. lstat confirmed regular file; realpath confirmed in-tree.
89
94
  return readFileSync(joined, 'utf-8');
90
95
  }
96
+ /**
97
+ * The ONE canonical `bodyPath` → `body` normalization boundary. Resolves every
98
+ * interaction's `bodyPath` (relative to `dir`, the interaction directory) into
99
+ * `body` and strips `bodyPath` from the result.
100
+ *
101
+ * Call this once, right before a deck is (re)written to `<dir>/deck.json` —
102
+ * `hl deck ask`, `hl deck update`, and the public `ask()` API all do — so
103
+ * every reader downstream (the terminal TUI's render + its live-reload
104
+ * poller, the browser server's `/api/interaction`) only ever sees a plain
105
+ * `body` and never has to special-case `bodyPath` itself. `parseDeck` (below)
106
+ * reuses this same function when reading a deck straight off disk.
107
+ */
108
+ export function resolveDeckBodyPaths(deck, dir) {
109
+ const interactions = deck.interactions.map((interaction) => {
110
+ if (interaction.bodyPath === undefined)
111
+ return interaction;
112
+ const body = readBodyPathFile(dir, interaction.bodyPath);
113
+ // Drop bodyPath from persisted deck.json/decisions.json (recipe §1.8).
114
+ const { bodyPath: _drop, ...rest } = interaction;
115
+ return { ...rest, body };
116
+ });
117
+ return { ...deck, interactions };
118
+ }
91
119
  // ── public entry points ───────────────────────────────────────────────────────
92
120
  export function parseDeck(deckPath) {
93
121
  const raw = readFileSync(deckPath, 'utf-8');
@@ -99,22 +127,16 @@ export function parseDeck(deckPath) {
99
127
  throw new Error('deck is not valid JSON');
100
128
  }
101
129
  const parsed = deckSchema.parse(json);
102
- const inlinedInteractions = parsed.interactions.map(interaction => {
103
- let body = interaction.body;
104
- if (interaction.bodyPath !== undefined) {
105
- body = inlineBodyPath(deckPath, interaction.bodyPath);
106
- }
107
- if (body !== undefined) {
108
- const check = checkMarkdown(body);
130
+ const resolved = resolveDeckBodyPaths(parsed, dirname(deckPath));
131
+ for (const interaction of resolved.interactions) {
132
+ if (interaction.body !== undefined) {
133
+ const check = checkMarkdown(interaction.body);
109
134
  if (!check.ok) {
110
135
  throw new Error(check.error);
111
136
  }
112
137
  }
113
- // Drop bodyPath from persisted decisions.json (recipe §1.8).
114
- const { bodyPath: _drop, ...rest } = interaction;
115
- return body !== undefined ? { ...rest, body } : { ...rest };
116
- });
117
- return { ...parsed, interactions: inlinedInteractions };
138
+ }
139
+ return resolved;
118
140
  }
119
141
  export function validateDeck(parsed) {
120
142
  return deckSchema.parse(parsed);
package/dist/index.d.ts CHANGED
@@ -7,7 +7,7 @@ export { ask, notify, inbox } from './api.js';
7
7
  export { display } from './surfaces/display.js';
8
8
  export { scanInbox } from './inbox/scan.js';
9
9
  export { renderMarkdown, checkMarkdown, ensureRenderer, isRendererReady, } from './render/termrender.js';
10
- export { parseDeck, validateDeck, deckSchema } from './inbox/deck-schema.js';
10
+ export { parseDeck, validateDeck, deckSchema, resolveDeckBodyPaths } from './inbox/deck-schema.js';
11
11
  export { notifyDeck } from './inbox/deck-factories.js';
12
12
  export type { NotifyDeckOpts } from './inbox/deck-factories.js';
13
13
  export { deckPath, responsePath, progressPath, visualsDir, interactionState, isResolved, isClaimed, atomicWriteJson, readJson, writeResponse, writeProgress, clearProgress, } from './inbox/convention.js';
package/dist/index.js CHANGED
@@ -10,7 +10,7 @@ export { scanInbox } from './inbox/scan.js';
10
10
  // (sisyphus md-render / ask-schema) route markdown through these.
11
11
  export { renderMarkdown, checkMarkdown, ensureRenderer, isRendererReady, } from './render/termrender.js';
12
12
  // Canonical deck schema + parsing/validation (consumers stop forking it).
13
- export { parseDeck, validateDeck, deckSchema } from './inbox/deck-schema.js';
13
+ export { parseDeck, validateDeck, deckSchema, resolveDeckBodyPaths } from './inbox/deck-schema.js';
14
14
  // Deck factories — pure builders for common deck shapes (sugar for SDK consumers
15
15
  // who want validated Yes/No or notify decks without inline construction).
16
16
  export { notifyDeck } from './inbox/deck-factories.js';
@@ -1 +1 @@
1
- export declare const TERMRENDER_VERSION = "4.10.3";
1
+ export declare const TERMRENDER_VERSION = "4.10.5";
@@ -1 +1 @@
1
- export const TERMRENDER_VERSION = '4.10.3';
1
+ export const TERMRENDER_VERSION = '4.10.5';
package/dist/tui/app.js CHANGED
@@ -4,12 +4,14 @@ import { spawnSync } from 'node:child_process';
4
4
  import { tmpdir } from 'node:os';
5
5
  import { randomUUID } from 'node:crypto';
6
6
  import { setupTerminal, restoreTerminal, parseKeypress, getTerminalSize } from './terminal.js';
7
- import { diffFrame, renderOverview, renderItemReview, renderFinal, clampItemReviewScroll } from './render.js';
7
+ import { diffFrame, renderOverview, renderItemReview, renderFinal, renderHandoff, clampItemReviewScroll } from './render.js';
8
8
  import { handleKeypress, assignShortcuts } from './input.js';
9
9
  import { readConversation } from '../conversation/reader.js';
10
10
  import { defaultGenerateVisual } from '../visuals/generate.js';
11
11
  import { validateDeck } from '../inbox/deck-schema.js';
12
12
  import { progressPath as progressPathFor, deckPath as deckPathFor, writeResponse, clearProgress } from '../inbox/convention.js';
13
+ import { startWebServer } from '../browser/server.js';
14
+ import { openBrowser } from '../browser/open.js';
13
15
  /** Validate an arbitrary parsed value as a Deck. Delegates to the canonical
14
16
  * Zod validator in `inbox/deck-schema.ts` (the single source of truth shared
15
17
  * with sisyphus). Kept exported for back-compat. */
@@ -278,6 +280,18 @@ export async function resolveInteractionDir(dir, deck, opts = {}) {
278
280
  // returned envelope/summary describes what was answered, not the kickoff.
279
281
  let currentDeck = deck;
280
282
  let deckWatch = null;
283
+ // Guards finalize() against running twice. The server already makes
284
+ // /api/submit single-assignment (only the first accepted submit fires
285
+ // onSubmit), but finalize() is also reachable via onComplete/onExit/a
286
+ // hard Ctrl+C during handoff — this is defense-in-depth so a second call
287
+ // from any path is a no-op instead of double-tearing-down (stop() twice,
288
+ // removeListener on an already-removed listener) and resolving the outer
289
+ // promise a second time.
290
+ let finalized = false;
291
+ // Set while the panel has handed control to the browser (the `w` keybind
292
+ // below). Non-null means: the panel renders nothing, the host renders the
293
+ // handoff screen instead, and only the take-back key reaches this loop.
294
+ let handoff = null;
281
295
  const flushHost = (lines) => {
282
296
  const { cols: currentCols, rows: currentRows } = getTerminalSize();
283
297
  const { writes, nextPrevFrame } = diffFrame(prevFrameLocal, lines, currentRows, currentCols);
@@ -291,23 +305,45 @@ export async function resolveInteractionDir(dir, deck, opts = {}) {
291
305
  // model no longer matches the screen: re-layout at the new size, clear
292
306
  // everything, and redraw from scratch.
293
307
  const onResize = () => {
308
+ const { cols: c, rows: r } = getTerminalSize();
309
+ if (handoff !== null) {
310
+ prevFrameLocal = [];
311
+ process.stdout.write('\x1b[2J\x1b[H');
312
+ flushHost(renderHandoff(handoff.url, c, r));
313
+ return;
314
+ }
294
315
  if (panel === null)
295
316
  return;
296
- const { cols: c, rows: r } = getTerminalSize();
297
317
  const lines = panel.handleResize(c, r);
298
318
  prevFrameLocal = [];
299
319
  process.stdout.write('\x1b[2J\x1b[H');
300
320
  flushHost(lines);
301
321
  };
302
- const finalize = (responses) => {
322
+ // `written` is set when the browser (not this function) already wrote
323
+ // response.json via the web server's /api/submit — the canonical write
324
+ // happens exactly once, whichever surface produced it; this just converges
325
+ // the terminal side and resolves the promise with what's already on disk.
326
+ const finalize = (responses, written) => {
327
+ if (finalized)
328
+ return;
329
+ finalized = true;
303
330
  if (deckWatch !== null) {
304
331
  clearInterval(deckWatch);
305
332
  deckWatch = null;
306
333
  }
334
+ if (handoff !== null) {
335
+ const h = handoff;
336
+ handoff = null;
337
+ void h.stop();
338
+ }
307
339
  restoreTerminal();
308
340
  process.stdin.removeListener('data', onData);
309
341
  process.stdout.removeListener('resize', onResize);
310
342
  panel?.unmount();
343
+ if (written !== undefined) {
344
+ resolve({ responses, completedAt: written.completedAt, responsePath: written.responsePath, deck: currentDeck });
345
+ return;
346
+ }
311
347
  const completedAt = new Date().toISOString();
312
348
  // Resolved supersedes in-progress: write response.json, drop progress.json.
313
349
  const rp = writeResponse(dir, responses, completedAt, currentDeck);
@@ -357,6 +393,12 @@ export async function resolveInteractionDir(dir, deck, opts = {}) {
357
393
  deckWatch = setInterval(() => {
358
394
  if (panel === null)
359
395
  return;
396
+ // Deck reload is deferred while handed off — the browser already fetched
397
+ // a snapshot and applying loadDeck() here would repaint the (currently
398
+ // hidden) panel over the handoff screen. Re-checked on the next tick
399
+ // after take-back, so a `hl deck update` mid-handoff is not lost.
400
+ if (handoff !== null)
401
+ return;
360
402
  const m = deckMtime();
361
403
  if (m === 0 || m === lastDeckMtime)
362
404
  return;
@@ -457,8 +499,77 @@ export async function resolveInteractionDir(dir, deck, opts = {}) {
457
499
  flushHost(lines);
458
500
  }
459
501
  };
502
+ // Start the local web server over this interaction dir, open a browser
503
+ // tab on it, and park the panel: from here the browser is the sole editor
504
+ // (browser-authoritative handoff — no two-way sync). `onSubmit` fires once
505
+ // the browser's POST has already written response.json; finalize() is
506
+ // told so via `written` and does not write it again.
507
+ const enterHandoff = async () => {
508
+ if (handoff !== null)
509
+ return;
510
+ let server;
511
+ try {
512
+ server = await startWebServer({
513
+ dir,
514
+ deck: currentDeck,
515
+ onSubmit: (responses, completedAt, responsePath) => {
516
+ finalize(responses, { responsePath, completedAt });
517
+ },
518
+ });
519
+ }
520
+ catch (err) {
521
+ // Failed to bind (e.g. no loopback available) — stay in the normal TUI;
522
+ // nothing was torn down, so surface the error as a one-line footer.
523
+ const { cols: c, rows: r } = getTerminalSize();
524
+ const lines = panel.render();
525
+ while (lines.length < r)
526
+ lines.push('');
527
+ lines[r - 1] = ` Could not start the browser surface: ${err instanceof Error ? err.message : String(err)}`.slice(0, c);
528
+ flushHost(lines);
529
+ return;
530
+ }
531
+ handoff = server;
532
+ const { cols: c, rows: r } = getTerminalSize();
533
+ prevFrameLocal = [];
534
+ process.stdout.write('\x1b[2J\x1b[H');
535
+ flushHost(renderHandoff(server.url, c, r));
536
+ openBrowser(server.url);
537
+ };
538
+ // Reclaim control: tell any open browser tab it's now read-only, stop the
539
+ // server, and restore the live panel exactly as the human left it.
540
+ const takeBack = () => {
541
+ if (handoff === null)
542
+ return;
543
+ const h = handoff;
544
+ handoff = null;
545
+ // Deck's requestTakeBack() is just an awaited flush-broadcast of
546
+ // taken-back (no ack-wait, deck has no autosave/dirty state to flush) —
547
+ // so this stays effectively instant. Kept async and NOT awaited before
548
+ // the render/flush below so the terminal repaint never blocks on it.
549
+ void (async () => {
550
+ await h.requestTakeBack();
551
+ await h.stop();
552
+ })();
553
+ prevFrameLocal = [];
554
+ process.stdout.write('\x1b[2J\x1b[H');
555
+ flushHost(panel.render());
556
+ };
460
557
  onData = (data) => {
461
558
  const { input: inp, key } = parseKeypress(data);
559
+ if (handoff !== null) {
560
+ // Handed off: the panel gets no keys at all. Only take-back (and a
561
+ // hard Ctrl+C exit, mirroring the panel's own exit-on-partial) reach
562
+ // the host while the browser is the sole editor.
563
+ if (inp === 'w') {
564
+ takeBack();
565
+ return;
566
+ }
567
+ if (key.ctrl && inp === 'c') {
568
+ finalize(lastResponses);
569
+ return;
570
+ }
571
+ return;
572
+ }
462
573
  if (key.ctrl && inp === 'o') {
463
574
  const buf = panel.getInputBuffer();
464
575
  if (buf !== undefined) {
@@ -466,6 +577,14 @@ export async function resolveInteractionDir(dir, deck, opts = {}) {
466
577
  return;
467
578
  }
468
579
  }
580
+ // 'w' hands the current interaction off to the browser. Gated on
581
+ // canAcceptHostKeys() (not mid comment/freetext) so it never shadows a
582
+ // literal 'w' typed into a buffer; 'w' is also reserved from option
583
+ // auto-shortcuts (see assignShortcuts) so it never collides with a pick.
584
+ if (inp === 'w' && panel.canAcceptHostKeys()) {
585
+ void enterHandoff();
586
+ return;
587
+ }
469
588
  panel.handleKey(inp, key);
470
589
  flushHost(panel.render());
471
590
  };
package/dist/tui/input.js CHANGED
@@ -1,4 +1,7 @@
1
- const RESERVED = new Set(['c', 'r', 'n', 'p', 'q', 'j', 'k', 'u', 'd', ' ']);
1
+ // 'w' is reserved for the host-level "open in browser" handoff (see
2
+ // tui/app.ts resolveInteractionDir) — never auto-assignable as an option
3
+ // shortcut, or pressing it would race the handoff against picking that option.
4
+ const RESERVED = new Set(['c', 'r', 'n', 'p', 'q', 'j', 'k', 'u', 'd', 'w', ' ']);
2
5
  export function assignShortcuts(interactions) {
3
6
  for (const it of interactions) {
4
7
  const used = new Set(it.options.map((o) => o.shortcut).filter((s) => s !== undefined));
@@ -23,4 +23,11 @@ export declare function renderInputBuffer(buffer: string, cursor: number, maxWid
23
23
  export declare function clampItemReviewScroll(state: TuiState, cols: number, rows: number): void;
24
24
  export declare function renderItemReview(state: TuiState, cols: number, rows: number): string[];
25
25
  export declare function renderFinal(state: TuiState, cols: number, rows: number): string[];
26
+ /**
27
+ * Rendered while the deck panel has handed control to the browser (see the
28
+ * `w` handoff in `resolveInteractionDir`). Purely informational — no keys are
29
+ * routed to the panel while this is on screen; the host intercepts the
30
+ * take-back key itself.
31
+ */
32
+ export declare function renderHandoff(url: string, cols: number, rows: number): string[];
26
33
  export declare function responseSummary(r: InteractionResponse, interaction: Interaction): string;
@@ -401,6 +401,31 @@ export function renderFinal(state, cols, rows) {
401
401
  lines.push('');
402
402
  return centerHorizontal(lines.slice(0, rows), cols, maxW + 2);
403
403
  }
404
+ /**
405
+ * Rendered while the deck panel has handed control to the browser (see the
406
+ * `w` handoff in `resolveInteractionDir`). Purely informational — no keys are
407
+ * routed to the panel while this is on screen; the host intercepts the
408
+ * take-back key itself.
409
+ */
410
+ export function renderHandoff(url, cols, rows) {
411
+ const maxW = Math.min(cols - 4, 68);
412
+ const lines = [];
413
+ lines.push('');
414
+ lines.push(` ${BOLD}${CYAN} Handed off to the browser ${RESET}`);
415
+ lines.push(` ${DIM}${hline(maxW)}${RESET}`);
416
+ lines.push('');
417
+ lines.push(` ${DIM}Open (or already opened):${RESET}`);
418
+ lines.push(` ${CYAN}${truncate(url, maxW)}${RESET}`);
419
+ lines.push('');
420
+ lines.push(` ${ITALIC}${DIM}The browser is the sole editor now — submit there.${RESET}`);
421
+ lines.push(` ${ITALIC}${DIM}This pane will converge automatically once it submits.${RESET}`);
422
+ lines.push('');
423
+ lines.push(` ${DIM}${hline(maxW)}${RESET}`);
424
+ lines.push(` ${YELLOW}w${RESET} take back control`);
425
+ while (lines.length < rows)
426
+ lines.push('');
427
+ return centerHorizontal(lines.slice(0, rows), cols, maxW + 2);
428
+ }
404
429
  export function responseSummary(r, interaction) {
405
430
  if (r.selectedOptionIds !== undefined) {
406
431
  const oc = r.optionComments;
package/dist/types.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { Key } from './tui/terminal.js';
2
- export type InteractionKind = 'notify' | 'decision' | 'context' | 'error' | 'review';
2
+ export declare const INTERACTION_KINDS: readonly ["notify", "decision", "context", "error", "review"];
3
+ export type InteractionKind = (typeof INTERACTION_KINDS)[number];
3
4
  export interface InteractionOption {
4
5
  id: string;
5
6
  label: string;
package/dist/types.js CHANGED
@@ -1,2 +1,6 @@
1
1
  // ── v2 shapes (v1 schema dropped per cycle-16 user pivot — humanloop is v2-only) ──
2
- export {};
2
+ // Single source of truth for the interaction-kind enum: the Zod deck schema
3
+ // (`src/inbox/deck-schema.ts`) and the CLI's JSON schema (`src/cli.ts`) both
4
+ // derive their enum values from this array so a new kind can't drift between
5
+ // the type and the two validation surfaces the way `'review'` once did.
6
+ export const INTERACTION_KINDS = ['notify', 'decision', 'context', 'error', 'review'];
@@ -0,0 +1,2 @@
1
+ /*! tailwindcss v4.3.2 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0;--tw-content:""}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-200:oklch(88.5% .062 18.334);--color-red-500:oklch(63.7% .237 25.331);--color-red-900:oklch(39.6% .141 25.723);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-700:oklch(55.5% .163 48.998);--color-amber-900:oklch(41.4% .112 45.904);--color-emerald-200:oklch(90.5% .093 164.15);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-600:oklch(59.6% .145 163.225);--color-emerald-700:oklch(50.8% .118 165.612);--color-emerald-900:oklch(37.8% .077 168.94);--color-slate-200:oklch(92.9% .013 255.508);--color-slate-500:oklch(55.4% .046 257.417);--color-slate-900:oklch(20.8% .042 265.755);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--container-lg:32rem;--container-3xl:48rem;--container-5xl:64rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--leading-snug:1.375;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}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;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*{border-color:var(--border);outline-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){*{outline-color:color-mix(in oklab, var(--ring) 50%, transparent)}}body{background-color:var(--background);color:var(--foreground)}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.visible{visibility:visible}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:0}.z-50{z-index:50}.container{width:100%}@media (width>=40rem){.container{max-width:40rem}}@media (width>=48rem){.container{max-width:48rem}}@media (width>=64rem){.container{max-width:64rem}}@media (width>=80rem){.container{max-width:80rem}}@media (width>=96rem){.container{max-width:96rem}}.mx-auto{margin-inline:auto}.prose{color:var(--tw-prose-body);max-width:65ch}.prose :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-lead);margin-top:1.2em;margin-bottom:1.2em;font-size:1.25em;line-height:1.6}.prose :where(a):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-links);font-weight:500;text-decoration:underline}.prose :where(strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-bold);font-weight:600}.prose :where(a strong):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(blockquote strong):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(thead th strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:decimal}.prose :where(ol[type=A]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=A s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-alpha}.prose :where(ol[type=a s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-alpha}.prose :where(ol[type=I]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type=I s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:upper-roman}.prose :where(ol[type=i s]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:lower-roman}.prose :where(ol[type="1"]):not(:where([class~=not-prose],[class~=not-prose] *)){list-style-type:decimal}.prose :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em;padding-inline-start:1.625em;list-style-type:disc}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-counters);font-weight:400}.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *))::marker{color:var(--tw-prose-bullets)}.prose :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.25em;font-weight:600}.prose :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){border-color:var(--tw-prose-hr);border-top-width:1px;margin-top:3em;margin-bottom:3em}.prose :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-quotes);border-inline-start-width:.25rem;border-inline-start-color:var(--tw-prose-quote-borders);quotes:"“""”""‘""’";margin-top:1.6em;margin-bottom:1.6em;padding-inline-start:1em;font-style:italic;font-weight:500}.prose :where(blockquote p:first-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):before{content:open-quote}.prose :where(blockquote p:last-of-type):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:close-quote}.prose :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:0;margin-bottom:.888889em;font-size:2.25em;font-weight:800;line-height:1.11111}.prose :where(h1 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:900}.prose :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:2em;margin-bottom:1em;font-size:1.5em;font-weight:700;line-height:1.33333}.prose :where(h2 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:800}.prose :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.6em;margin-bottom:.6em;font-size:1.25em;font-weight:600;line-height:1.6}.prose :where(h3 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.prose :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);margin-top:1.5em;margin-bottom:.5em;font-weight:600;line-height:1.5}.prose :where(h4 strong):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-weight:700}.prose :where(img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em;display:block}.prose :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-kbd);box-shadow:0 0 0 1px var(--tw-prose-kbd-shadows), 0 3px 0 var(--tw-prose-kbd-shadows);padding-top:.1875em;padding-inline-end:.375em;padding-bottom:.1875em;border-radius:.3125rem;padding-inline-start:.375em;font-family:inherit;font-size:.875em;font-weight:500}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-code);font-size:.875em;font-weight:600}.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.prose :where(code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:"`"}.prose :where(a code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h1 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.875em}.prose :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit;font-size:.9em}.prose :where(h4 code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(blockquote code):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(thead th code):not(:where([class~=not-prose],[class~=not-prose] *)){color:inherit}.prose :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-pre-code);background-color:var(--tw-prose-pre-bg);padding-top:.857143em;padding-inline-end:1.14286em;padding-bottom:.857143em;border-radius:.375rem;margin-top:1.71429em;margin-bottom:1.71429em;padding-inline-start:1.14286em;font-size:.875em;font-weight:400;line-height:1.71429;overflow-x:auto}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)){font-weight:inherit;color:inherit;font-size:inherit;font-family:inherit;line-height:inherit;background-color:#0000;border-width:0;border-radius:0;padding:0}.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):before,.prose :where(pre code):not(:where([class~=not-prose],[class~=not-prose] *)):after{content:none}.prose :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){table-layout:auto;width:100%;margin-top:2em;margin-bottom:2em;font-size:.875em;line-height:1.71429}.prose :where(thead):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-th-borders)}.prose :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-headings);vertical-align:bottom;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em;font-weight:600}.prose :where(tbody tr):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:1px;border-bottom-color:var(--tw-prose-td-borders)}.prose :where(tbody tr:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){border-bottom-width:0}.prose :where(tbody td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:baseline}.prose :where(tfoot):not(:where([class~=not-prose],[class~=not-prose] *)){border-top-width:1px;border-top-color:var(--tw-prose-th-borders)}.prose :where(tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){vertical-align:top}.prose :where(th,td):not(:where([class~=not-prose],[class~=not-prose] *)){text-align:start}.prose :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){color:var(--tw-prose-captions);margin-top:.857143em;font-size:.875em;line-height:1.42857}.prose{--tw-prose-body:oklch(37.3% .034 259.733);--tw-prose-headings:oklch(21% .034 264.665);--tw-prose-lead:oklch(44.6% .03 256.802);--tw-prose-links:oklch(21% .034 264.665);--tw-prose-bold:oklch(21% .034 264.665);--tw-prose-counters:oklch(55.1% .027 264.364);--tw-prose-bullets:oklch(87.2% .01 258.338);--tw-prose-hr:oklch(92.8% .006 264.531);--tw-prose-quotes:oklch(21% .034 264.665);--tw-prose-quote-borders:oklch(92.8% .006 264.531);--tw-prose-captions:oklch(55.1% .027 264.364);--tw-prose-kbd:oklch(21% .034 264.665);--tw-prose-kbd-shadows:oklab(21% -.00316127 -.0338527/.1);--tw-prose-code:oklch(21% .034 264.665);--tw-prose-pre-code:oklch(92.8% .006 264.531);--tw-prose-pre-bg:oklch(27.8% .033 256.848);--tw-prose-th-borders:oklch(87.2% .01 258.338);--tw-prose-td-borders:oklch(92.8% .006 264.531);--tw-prose-invert-body:oklch(87.2% .01 258.338);--tw-prose-invert-headings:#fff;--tw-prose-invert-lead:oklch(70.7% .022 261.325);--tw-prose-invert-links:#fff;--tw-prose-invert-bold:#fff;--tw-prose-invert-counters:oklch(70.7% .022 261.325);--tw-prose-invert-bullets:oklch(44.6% .03 256.802);--tw-prose-invert-hr:oklch(37.3% .034 259.733);--tw-prose-invert-quotes:oklch(96.7% .003 264.542);--tw-prose-invert-quote-borders:oklch(37.3% .034 259.733);--tw-prose-invert-captions:oklch(70.7% .022 261.325);--tw-prose-invert-kbd:#fff;--tw-prose-invert-kbd-shadows:#ffffff1a;--tw-prose-invert-code:#fff;--tw-prose-invert-pre-code:oklch(87.2% .01 258.338);--tw-prose-invert-pre-bg:#00000080;--tw-prose-invert-th-borders:oklch(44.6% .03 256.802);--tw-prose-invert-td-borders:oklch(37.3% .034 259.733);font-size:1rem;line-height:1.75}.prose :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;margin-bottom:.5em}.prose :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.375em}.prose :where(.prose>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(.prose>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(.prose>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em}.prose :where(.prose>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.25em}.prose :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.75em;margin-bottom:.75em}.prose :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.25em;margin-bottom:1.25em}.prose :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.5em;padding-inline-start:1.625em}.prose :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.571429em;padding-inline-end:.571429em;padding-bottom:.571429em;padding-inline-start:.571429em}.prose :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2em;margin-bottom:2em}.prose :where(.prose>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose :where(.prose>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.prose-sm{font-size:.875rem;line-height:1.71429}.prose-sm :where(p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.14286em;margin-bottom:1.14286em}.prose-sm :where([class~=lead]):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.888889em;margin-bottom:.888889em;font-size:1.28571em;line-height:1.55556}.prose-sm :where(blockquote):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.33333em;margin-bottom:1.33333em;padding-inline-start:1.11111em}.prose-sm :where(h1):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:.8em;font-size:2.14286em;line-height:1.2}.prose-sm :where(h2):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.6em;margin-bottom:.8em;font-size:1.42857em;line-height:1.4}.prose-sm :where(h3):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.55556em;margin-bottom:.444444em;font-size:1.28571em;line-height:1.55556}.prose-sm :where(h4):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.42857em;margin-bottom:.571429em;line-height:1.42857}.prose-sm :where(img):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-sm :where(picture):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.71429em;margin-bottom:1.71429em}.prose-sm :where(picture>img):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-sm :where(video):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.71429em;margin-bottom:1.71429em}.prose-sm :where(kbd):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.142857em;padding-inline-end:.357143em;padding-bottom:.142857em;border-radius:.3125rem;padding-inline-start:.357143em;font-size:.857143em}.prose-sm :where(code):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.857143em}.prose-sm :where(h2 code):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.9em}.prose-sm :where(h3 code):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.888889em}.prose-sm :where(pre):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.666667em;padding-inline-end:1em;padding-bottom:.666667em;border-radius:.25rem;margin-top:1.66667em;margin-bottom:1.66667em;padding-inline-start:1em;font-size:.857143em;line-height:1.66667}.prose-sm :where(ol):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-sm :where(ul):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.14286em;margin-bottom:1.14286em;padding-inline-start:1.57143em}.prose-sm :where(li):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.285714em;margin-bottom:.285714em}.prose-sm :where(ol>li):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-sm :where(ul>li):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:.428571em}.prose-sm :where(.prose-sm>ul>li p):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.571429em;margin-bottom:.571429em}.prose-sm :where(.prose-sm>ul>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.14286em}.prose-sm :where(.prose-sm>ul>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.14286em}.prose-sm :where(.prose-sm>ol>li>p:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.14286em}.prose-sm :where(.prose-sm>ol>li>p:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:1.14286em}.prose-sm :where(ul ul,ul ol,ol ul,ol ol):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.571429em;margin-bottom:.571429em}.prose-sm :where(dl):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.14286em;margin-bottom:1.14286em}.prose-sm :where(dt):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.14286em}.prose-sm :where(dd):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.285714em;padding-inline-start:1.57143em}.prose-sm :where(hr):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:2.85714em;margin-bottom:2.85714em}.prose-sm :where(hr+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-sm :where(h2+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-sm :where(h3+*):not(:where([class~=not-prose],[class~=not-prose] *)),.prose-sm :where(h4+*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-sm :where(table):not(:where([class~=not-prose],[class~=not-prose] *)){font-size:.857143em;line-height:1.5}.prose-sm :where(thead th):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:1em;padding-bottom:.666667em;padding-inline-start:1em}.prose-sm :where(thead th:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-sm :where(thead th:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-sm :where(tbody td,tfoot td):not(:where([class~=not-prose],[class~=not-prose] *)){padding-top:.666667em;padding-inline-end:1em;padding-bottom:.666667em;padding-inline-start:1em}.prose-sm :where(tbody td:first-child,tfoot td:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-start:0}.prose-sm :where(tbody td:last-child,tfoot td:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){padding-inline-end:0}.prose-sm :where(figure):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:1.71429em;margin-bottom:1.71429em}.prose-sm :where(figure>*):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0;margin-bottom:0}.prose-sm :where(figcaption):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:.666667em;font-size:.857143em;line-height:1.33333}.prose-sm :where(.prose-sm>:first-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-top:0}.prose-sm :where(.prose-sm>:last-child):not(:where([class~=not-prose],[class~=not-prose] *)){margin-bottom:0}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mb-1{margin-bottom:var(--spacing)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.ml-auto{margin-left:auto}.block{display:block}.flex{display:flex}.grid{display:grid}.inline{display:inline}.inline-flex{display:inline-flex}.field-sizing-content{field-sizing:content}.size-3\.5{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.max-h-24{max-height:calc(var(--spacing) * 24)}.max-h-\[45vh\]{max-height:45vh}.max-h-\[62vh\]{max-height:62vh}.min-h-16{min-height:calc(var(--spacing) * 16)}.min-h-screen{min-height:100vh}.w-fit{width:fit-content}.w-full{width:100%}.max-w-3xl{max-width:var(--container-3xl)}.max-w-5xl{max-width:var(--container-5xl)}.max-w-lg{max-width:var(--container-lg)}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.min-w-0{min-width:0}.flex-1{flex:1}.shrink-0{flex-shrink:0}.cursor-pointer{cursor:pointer}.resize-y{resize:vertical}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-content-center{place-content:center}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-\[4px\]{border-radius:4px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) - 2px)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l-4{border-left-style:var(--tw-border-style);border-left-width:4px}.border-amber-500\/50{border-color:#f99c0080}@supports (color:color-mix(in lab, red, red)){.border-amber-500\/50{border-color:color-mix(in oklab, var(--color-amber-500) 50%, transparent)}}.border-border{border-color:var(--border)}.border-destructive\/50{border-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.border-destructive\/50{border-color:color-mix(in oklab, var(--destructive) 50%, transparent)}}.border-emerald-500\/50{border-color:#00bb7f80}@supports (color:color-mix(in lab, red, red)){.border-emerald-500\/50{border-color:color-mix(in oklab, var(--color-emerald-500) 50%, transparent)}}.border-input{border-color:var(--input)}.border-red-500\/50{border-color:#fb2c3680}@supports (color:color-mix(in lab, red, red)){.border-red-500\/50{border-color:color-mix(in oklab, var(--color-red-500) 50%, transparent)}}.border-ring{border-color:var(--ring)}.border-slate-500\/50{border-color:#62748e80}@supports (color:color-mix(in lab, red, red)){.border-slate-500\/50{border-color:color-mix(in oklab, var(--color-slate-500) 50%, transparent)}}.border-transparent{border-color:#0000}.bg-accent\/60{background-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.bg-accent\/60{background-color:color-mix(in oklab, var(--accent) 60%, transparent)}}.bg-amber-500\/10{background-color:#f99c001a}@supports (color:color-mix(in lab, red, red)){.bg-amber-500\/10{background-color:color-mix(in oklab, var(--color-amber-500) 10%, transparent)}}.bg-background{background-color:var(--background)}.bg-black\/40{background-color:#0006}@supports (color:color-mix(in lab, red, red)){.bg-black\/40{background-color:color-mix(in oklab, var(--color-black) 40%, transparent)}}.bg-card{background-color:var(--card)}.bg-destructive,.bg-destructive\/10{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.bg-destructive\/10{background-color:color-mix(in oklab, var(--destructive) 10%, transparent)}}.bg-emerald-500\/10{background-color:#00bb7f1a}@supports (color:color-mix(in lab, red, red)){.bg-emerald-500\/10{background-color:color-mix(in oklab, var(--color-emerald-500) 10%, transparent)}}.bg-muted{background-color:var(--muted)}.bg-primary{background-color:var(--primary)}.bg-red-500\/10{background-color:#fb2c361a}@supports (color:color-mix(in lab, red, red)){.bg-red-500\/10{background-color:color-mix(in oklab, var(--color-red-500) 10%, transparent)}}.bg-secondary{background-color:var(--secondary)}.bg-slate-500\/10{background-color:#62748e1a}@supports (color:color-mix(in lab, red, red)){.bg-slate-500\/10{background-color:color-mix(in oklab, var(--color-slate-500) 10%, transparent)}}.bg-transparent{background-color:#0000}.fill-muted-foreground\/40{fill:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.fill-muted-foreground\/40{fill:color-mix(in oklab, var(--muted-foreground) 40%, transparent)}}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-5{padding:calc(var(--spacing) * 5)}.p-8{padding:calc(var(--spacing) * 8)}.px-1{padding-inline:var(--spacing)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.pt-3{padding-top:calc(var(--spacing) * 3)}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-amber-700{color:var(--color-amber-700)}.text-amber-900{color:var(--color-amber-900)}.text-current{color:currentColor}.text-destructive{color:var(--destructive)}.text-emerald-600{color:var(--color-emerald-600)}.text-emerald-700{color:var(--color-emerald-700)}.text-emerald-900{color:var(--color-emerald-900)}.text-foreground{color:var(--foreground)}.text-muted-foreground,.text-muted-foreground\/50{color:var(--muted-foreground)}@supports (color:color-mix(in lab, red, red)){.text-muted-foreground\/50{color:color-mix(in oklab, var(--muted-foreground) 50%, transparent)}}.text-primary{color:var(--primary)}.text-primary-foreground{color:var(--primary-foreground)}.text-red-900{color:var(--color-red-900)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-slate-900{color:var(--color-slate-900)}.text-white{color:var(--color-white)}.lowercase{text-transform:lowercase}.italic{font-style:italic}.underline-offset-2{text-underline-offset:2px}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-60{opacity:.6}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[color\,box-shadow\]{transition-property:color,box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-none{transition-property:none}.outline-none{--tw-outline-style:none;outline-style:none}.running{animation-play-state:running}.group-focus-within\:opacity-100:is(:where(.group):focus-within *){opacity:1}@media (hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}.placeholder\:text-muted-foreground::placeholder{color:var(--muted-foreground)}@media (hover:hover){.hover\:bg-accent:hover{background-color:var(--accent)}.hover\:bg-destructive\/90:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-destructive\/90:hover{background-color:color-mix(in oklab, var(--destructive) 90%, transparent)}}.hover\:bg-primary\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab, var(--primary) 90%, transparent)}}.hover\:bg-secondary\/80:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab, var(--secondary) 80%, transparent)}}.hover\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:underline:hover{text-decoration-line:underline}}.focus-visible\:border-ring:focus-visible{border-color:var(--ring)}.focus-visible\:opacity-100:focus-visible{opacity:1}.focus-visible\:ring-\[3px\]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(3px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-destructive\/20:focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-destructive\/20:focus-visible{--tw-ring-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.has-\[\>svg\]\:px-2\.5:has(>svg){padding-inline:calc(var(--spacing) * 2.5)}.has-\[\>svg\]\:px-3:has(>svg){padding-inline:calc(var(--spacing) * 3)}.has-\[\>svg\]\:px-4:has(>svg){padding-inline:calc(var(--spacing) * 4)}.aria-invalid\:border-destructive[aria-invalid=true]{border-color:var(--destructive)}.aria-invalid\:ring-destructive\/20[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.aria-invalid\:ring-destructive\/20[aria-invalid=true]{--tw-ring-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.data-\[state\=checked\]\:border-primary[data-state=checked]{border-color:var(--primary)}.data-\[state\=checked\]\:bg-primary[data-state=checked]{background-color:var(--primary)}.data-\[state\=checked\]\:text-primary-foreground[data-state=checked]{color:var(--primary-foreground)}@media (width>=48rem){.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}@media (width>=64rem){.lg\:grid-cols-\[minmax\(0\,1fr\)_320px\]{grid-template-columns:minmax(0,1fr) 320px}}.dark\:bg-destructive\/60:is(.dark *){background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:bg-destructive\/60:is(.dark *){background-color:color-mix(in oklab, var(--destructive) 60%, transparent)}}.dark\:bg-input\/30:is(.dark *){background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\:bg-input\/30:is(.dark *){background-color:color-mix(in oklab, var(--input) 30%, transparent)}}.dark\:text-amber-200:is(.dark *){color:var(--color-amber-200)}.dark\:text-amber-400:is(.dark *){color:var(--color-amber-400)}.dark\:text-emerald-200:is(.dark *){color:var(--color-emerald-200)}.dark\:text-emerald-400:is(.dark *){color:var(--color-emerald-400)}.dark\:text-red-200:is(.dark *){color:var(--color-red-200)}.dark\:text-slate-200:is(.dark *){color:var(--color-slate-200)}.dark\:prose-invert:is(.dark *){--tw-prose-body:var(--tw-prose-invert-body);--tw-prose-headings:var(--tw-prose-invert-headings);--tw-prose-lead:var(--tw-prose-invert-lead);--tw-prose-links:var(--tw-prose-invert-links);--tw-prose-bold:var(--tw-prose-invert-bold);--tw-prose-counters:var(--tw-prose-invert-counters);--tw-prose-bullets:var(--tw-prose-invert-bullets);--tw-prose-hr:var(--tw-prose-invert-hr);--tw-prose-quotes:var(--tw-prose-invert-quotes);--tw-prose-quote-borders:var(--tw-prose-invert-quote-borders);--tw-prose-captions:var(--tw-prose-invert-captions);--tw-prose-kbd:var(--tw-prose-invert-kbd);--tw-prose-kbd-shadows:var(--tw-prose-invert-kbd-shadows);--tw-prose-code:var(--tw-prose-invert-code);--tw-prose-pre-code:var(--tw-prose-invert-pre-code);--tw-prose-pre-bg:var(--tw-prose-invert-pre-bg);--tw-prose-th-borders:var(--tw-prose-invert-th-borders);--tw-prose-td-borders:var(--tw-prose-invert-td-borders)}.dark\:focus-visible\:ring-destructive\/40:is(.dark *):focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:focus-visible\:ring-destructive\/40:is(.dark *):focus-visible{--tw-ring-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.dark\:aria-invalid\:ring-destructive\/40:is(.dark *)[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:aria-invalid\:ring-destructive\/40:is(.dark *)[aria-invalid=true]{--tw-ring-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.dark\:data-\[state\=checked\]\:bg-primary:is(.dark *)[data-state=checked]{background-color:var(--primary)}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4 svg:not([class*=size-]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&\>svg\]\:pointer-events-none>svg{pointer-events:none}.\[\&\>svg\]\:size-3>svg{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}@media (hover:hover){a.\[a\&\]\:hover\:bg-accent:hover{background-color:var(--accent)}a.\[a\&\]\:hover\:bg-destructive\/90:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){a.\[a\&\]\:hover\:bg-destructive\/90:hover{background-color:color-mix(in oklab, var(--destructive) 90%, transparent)}}a.\[a\&\]\:hover\:bg-primary\/90:hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){a.\[a\&\]\:hover\:bg-primary\/90:hover{background-color:color-mix(in oklab, var(--primary) 90%, transparent)}}a.\[a\&\]\:hover\:bg-secondary\/90:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){a.\[a\&\]\:hover\:bg-secondary\/90:hover{background-color:color-mix(in oklab, var(--secondary) 90%, transparent)}}a.\[a\&\]\:hover\:text-accent-foreground:hover{color:var(--accent-foreground)}a.\[a\&\]\:hover\:underline:hover{text-decoration-line:underline}}}@property --tw-animation-delay{syntax:"*";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:"*";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:"*";inherits:false}@property --tw-animation-fill-mode{syntax:"*";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:"*";inherits:false;initial-value:0}:root{--radius:.625rem;--background:oklch(100% 0 0);--foreground:oklch(14.5% 0 0);--card:oklch(100% 0 0);--card-foreground:oklch(14.5% 0 0);--popover:oklch(100% 0 0);--popover-foreground:oklch(14.5% 0 0);--primary:oklch(20.5% 0 0);--primary-foreground:oklch(98.5% 0 0);--secondary:oklch(97% 0 0);--secondary-foreground:oklch(20.5% 0 0);--muted:oklch(97% 0 0);--muted-foreground:oklch(55.6% 0 0);--accent:oklch(97% 0 0);--accent-foreground:oklch(20.5% 0 0);--destructive:oklch(57.7% .245 27.325);--border:oklch(92.2% 0 0);--input:oklch(92.2% 0 0);--ring:oklch(70.8% 0 0)}.dark{--background:oklch(14.5% 0 0);--foreground:oklch(98.5% 0 0);--card:oklch(20.5% 0 0);--card-foreground:oklch(98.5% 0 0);--popover:oklch(20.5% 0 0);--popover-foreground:oklch(98.5% 0 0);--primary:oklch(92.2% 0 0);--primary-foreground:oklch(20.5% 0 0);--secondary:oklch(26.9% 0 0);--secondary-foreground:oklch(98.5% 0 0);--muted:oklch(26.9% 0 0);--muted-foreground:oklch(70.8% 0 0);--accent:oklch(26.9% 0 0);--accent-foreground:oklch(98.5% 0 0);--destructive:oklch(70.4% .191 22.216);--border:oklch(100% 0 0/.1);--input:oklch(100% 0 0/.15);--ring:oklch(55.6% 0 0)}.markdown-body{--tw-prose-body:var(--foreground);--tw-prose-headings:var(--foreground);--tw-prose-lead:var(--muted-foreground);--tw-prose-links:var(--primary);--tw-prose-bold:var(--foreground);--tw-prose-counters:var(--muted-foreground);--tw-prose-bullets:var(--muted-foreground);--tw-prose-hr:var(--border);--tw-prose-quotes:var(--foreground);--tw-prose-quote-borders:var(--border);--tw-prose-captions:var(--muted-foreground);--tw-prose-code:var(--foreground);--tw-prose-pre-code:var(--foreground);--tw-prose-pre-bg:var(--muted);--tw-prose-th-borders:var(--border);--tw-prose-td-borders:var(--border)}.markdown-body code:not(pre code){border-radius:calc(var(--radius) - 4px);background-color:var(--muted);padding-inline:var(--spacing);padding-block:calc(var(--spacing) * .5);font-family:var(--font-mono);font-size:.875em}.markdown-body code:not(pre code):before,.markdown-body code:not(pre code):after{content:var(--tw-content);--tw-content:none;content:none}.markdown-body pre{border-radius:calc(var(--radius) - 2px);border-style:var(--tw-border-style);border-width:1px;border-color:var(--border)}.markdown-body pre code.hljs{background-color:#0000;padding:0}.markdown-body table{width:100%;display:block;overflow-x:auto}.hljs{color:var(--foreground)}.hljs-comment,.hljs-quote{color:var(--muted-foreground);font-style:italic}.hljs-keyword,.hljs-selector-tag,.hljs-literal,.hljs-section,.hljs-link{color:oklch(60% .19 292)}.hljs-string,.hljs-attr,.hljs-addition,.hljs-meta-string{color:oklch(64% .15 155)}.hljs-number,.hljs-symbol,.hljs-bullet{color:oklch(70% .17 60)}.hljs-title,.hljs-name,.hljs-title.function_,.hljs-title.class_{color:oklch(62% .19 250)}.hljs-variable,.hljs-template-variable,.hljs-attribute{color:oklch(65% .18 20)}.hljs-built_in,.hljs-type{color:oklch(62% .15 200)}.hljs-emphasis{font-style:italic}.hljs-strong{font-weight:700}.review-document{cursor:text}.review-source-span{border-radius:2px}.review-source-comment{background-color:oklch(70% .17 60/.25);box-shadow:inset 0 -2px oklch(70% .17 60/.6)}.review-source-active{background-color:oklch(62% .19 250/.22)}.review-source-comment.review-source-active{background-color:oklch(66% .19 300/.28)}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-content{syntax:"*";inherits:false;initial-value:""}