conductor-board 2.2.0 → 2.4.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.
package/bin/cli.js CHANGED
@@ -113,12 +113,16 @@ if (command === "clean") {
113
113
  }
114
114
 
115
115
  // status-writer commands (for agents — keep the board live as you work)
116
- if (["step", "gate", "heartbeat", "loop", "loop-scope", "status-init", "suggest", "knowledge"].includes(command)) {
116
+ if (["step", "gate", "heartbeat", "overview", "comment", "directives", "resolve", "loop", "loop-scope", "status-init", "suggest", "knowledge"].includes(command)) {
117
117
  const w = await import("../cli/writer.js");
118
118
  const fn = {
119
119
  step: w.runStep,
120
120
  gate: w.runGate,
121
121
  heartbeat: w.runHeartbeat,
122
+ overview: w.runOverview,
123
+ comment: w.runComment,
124
+ directives: w.runDirectives,
125
+ resolve: w.runResolve,
122
126
  loop: w.runLoop,
123
127
  "loop-scope": w.runLoopScope,
124
128
  "status-init": w.runStatusInit,
package/cli/complete.js CHANGED
@@ -99,6 +99,32 @@ export async function runComplete(args) {
99
99
  }
100
100
  }
101
101
 
102
+ // Loop-coverage guard: a loop step can't be completed while any frontloaded iteration is
103
+ // still incomplete — this catches skipped pages (an item left pending or only partly done),
104
+ // so you can never silently lose loop coverage. (§ "Loops": do every iteration, in order.)
105
+ if (!loopPath && step.type === "loop") {
106
+ try {
107
+ const status = JSON.parse(fs.readFileSync(statusPath, "utf8"));
108
+ const iters = (status.steps && status.steps[stepId] && status.steps[stepId].iterations) || {};
109
+ const subIds = (step.steps || []).map((s) => s && s.id).filter(Boolean);
110
+ const incomplete = [];
111
+ for (const [item, subs] of Object.entries(iters)) {
112
+ const missing = subIds.filter((sid) => !(subs && subs[sid] && subs[sid].status === "done"));
113
+ if (missing.length) incomplete.push(`${item} (missing: ${missing.join(", ")})`);
114
+ }
115
+ if (incomplete.length) {
116
+ console.error(
117
+ red(`\n ✕ Loop "${stepId}" has ${incomplete.length} incomplete iteration(s) — finish them before completing the loop:`),
118
+ );
119
+ for (const i of incomplete) console.error(red(` - ${i}`));
120
+ console.error(dim(" Every frontloaded iteration must finish all its sub-steps; none may be skipped or reordered away."));
121
+ return false;
122
+ }
123
+ } catch {
124
+ /* if status is unreadable, fall through to the normal gate flow */
125
+ }
126
+ }
127
+
102
128
  const soft = [];
103
129
  const hard = [];
104
130
  for (const g of step.gate || []) {
package/cli/writer.js CHANGED
@@ -127,6 +127,9 @@ export async function runHeartbeat(args) {
127
127
  confidence: typeof flag(args, ["--insight-confidence"]) === "string" ? flag(args, ["--insight-confidence"]) : "medium",
128
128
  };
129
129
  }
130
+ // --card opens a new activity card (a coherent unit of work: one intent, one target).
131
+ // This beat's note is the card's title; following beats (no --card) are its detail.
132
+ if (args.includes("--card")) entry.card = true;
130
133
  if (args.includes("--final")) {
131
134
  entry.finalBeat = true;
132
135
  const to = flag(args, ["--to"]);
@@ -148,7 +151,120 @@ export async function runHeartbeat(args) {
148
151
  (step.heartbeat = step.heartbeat || []).push(entry);
149
152
  }
150
153
  save(sp, s);
151
- return ok(`${id}${typeof sub === "string" ? `/${it}/${sub}` : ""} ${note.length > 50 ? note.slice(0, 50) + "…" : note}`);
154
+ // When this beat opens a card, surface its id so a parallel summarizer can target it later.
155
+ const cardTag = entry.card ? ` [card ${entry.at}]` : "";
156
+ return ok(`${id}${typeof sub === "string" ? `/${it}/${sub}` : ""} ♥ ${note.length > 50 ? note.slice(0, 50) + "…" : note}${cardTag}`);
157
+ }
158
+
159
+ // conductor-board overview <step> "summary" [--card <cardId>]
160
+ //
161
+ // Attach a synthesized OVERVIEW to an activity card — written by a parallel agent that
162
+ // summarizes the card's heartbeats once it closes. The board shows the overview by default
163
+ // with a toggle to the raw beats. Without --card, targets the most-recently CLOSED card
164
+ // (the second-to-last card opener; the last opener is the still-open card).
165
+ export async function runOverview(args) {
166
+ const sp = statusPathOf(args);
167
+ const [id, text] = positionals(args);
168
+ if (!id || !text) return fail('usage: conductor-board overview <step> "summary" [--card <cardId>]');
169
+ const s = load(sp);
170
+ if (!s) return fail("no status.json — run status-init first");
171
+ const step = s.steps[id];
172
+ if (!step) return fail(`no step "${id}"`);
173
+ let cardId = flag(args, ["--card"]);
174
+ if (typeof cardId !== "string") {
175
+ const openers = (step.heartbeat || []).filter((h) => h && h.card).map((h) => h.at);
176
+ cardId = openers.length >= 2 ? openers[openers.length - 2] : openers[openers.length - 1];
177
+ if (!cardId) return fail(`no cards on step "${id}" to summarize`);
178
+ }
179
+ step.cardOverviews = step.cardOverviews || {};
180
+ step.cardOverviews[cardId] = text;
181
+ save(sp, s);
182
+ return ok(`${id} ▸ overview saved for card ${cardId}`);
183
+ }
184
+
185
+ // ── developer notes / directives — the flow-manager feedback loop ────────────────
186
+ // A note the developer leaves on a card. Promoted with --directive it becomes a steering
187
+ // signal the next run's Phase 0 improve-pass MUST resolve (applied-with-how or deferred-with-why).
188
+
189
+ // conductor-board comment <step> "text" --card <cardId> [--card-title "…"] [--directive --scope SC]
190
+ // Appends a note (a card can hold several) with an audit history. Edits/removals are board-driven.
191
+ export async function runComment(args) {
192
+ const sp = statusPathOf(args);
193
+ const [id, text] = positionals(args);
194
+ const cardId = flag(args, ["--card"]);
195
+ if (!id || !text || typeof cardId !== "string")
196
+ return fail('usage: conductor-board comment <step> "text" --card <cardId> [--card-title "…"] [--directive --scope SC]');
197
+ const s = load(sp);
198
+ if (!s) return fail("no status.json — run status-init first");
199
+ s.developer_notes = Array.isArray(s.developer_notes) ? s.developer_notes : [];
200
+ const directive = args.includes("--directive");
201
+ const scope = flag(args, ["--scope"]);
202
+ const cardTitle = flag(args, ["--card-title"]);
203
+ const at = now();
204
+ s.developer_notes.push({
205
+ id: `${cardId}:${Date.now()}`,
206
+ at,
207
+ updated_at: at,
208
+ step: id,
209
+ card: cardId,
210
+ card_title: typeof cardTitle === "string" ? cardTitle : undefined,
211
+ text,
212
+ directive,
213
+ scope: typeof scope === "string" ? scope : undefined,
214
+ status: "open",
215
+ history: [{ at, action: "created", to: text }],
216
+ });
217
+ save(sp, s);
218
+ return ok(`${id} ▸ ${directive ? "directive" : "note"} on card ${cardId}: ${text.slice(0, 40)}${text.length > 40 ? "…" : ""}`);
219
+ }
220
+
221
+ // conductor-board directives [--open] [--step <id>] — list directives (for the Phase 0 ACK pass).
222
+ // Prints the card-title FOOTNOTE so the agent knows which activity each directive is about.
223
+ export async function runDirectives(args) {
224
+ const sp = statusPathOf(args);
225
+ const s = load(sp);
226
+ if (!s) return fail("no status.json — run status-init first");
227
+ const openOnly = args.includes("--open");
228
+ const stepF = flag(args, ["--step"]);
229
+ let notes = (Array.isArray(s.developer_notes) ? s.developer_notes : []).filter(
230
+ (n) => n && n.directive && n.status !== "removed",
231
+ );
232
+ if (openOnly) notes = notes.filter((n) => n.status === "open");
233
+ if (typeof stepF === "string") notes = notes.filter((n) => n.step === stepF);
234
+ if (notes.length === 0) {
235
+ console.log(openOnly ? "No open directives." : "No directives.");
236
+ return true;
237
+ }
238
+ for (const n of notes) {
239
+ const tag = n.status === "open" ? "● open" : n.status === "applied" ? "✓ applied" : "– deferred";
240
+ const where = n.card_title ? `“${n.card_title}”` : `card ${n.card}`;
241
+ console.log(`${tag} [${n.step}] ${where} (${n.scope || "this-conductor"})`);
242
+ console.log(` ${n.text}`);
243
+ if (n.resolution) console.log(` ↳ ${n.resolution}`);
244
+ const edits = (n.history || []).filter((h) => h.action === "edited").length;
245
+ console.log(` id=${n.id}${edits ? ` · edited ${edits}×` : ""}`);
246
+ }
247
+ return true;
248
+ }
249
+
250
+ // conductor-board resolve <cardId> --applied "how" | --deferred "why"
251
+ export async function runResolve(args) {
252
+ const sp = statusPathOf(args);
253
+ const [cardId] = positionals(args);
254
+ const applied = flag(args, ["--applied"]);
255
+ const deferred = flag(args, ["--deferred"]);
256
+ if (!cardId || (typeof applied !== "string" && typeof deferred !== "string"))
257
+ return fail('usage: conductor-board resolve <cardId> --applied "how" | --deferred "why"');
258
+ const s = load(sp);
259
+ if (!s) return fail("no status.json — run status-init first");
260
+ const note = (Array.isArray(s.developer_notes) ? s.developer_notes : []).find((n) => n && n.id === cardId);
261
+ if (!note) return fail(`no developer note on card "${cardId}"`);
262
+ note.status = typeof applied === "string" ? "applied" : "deferred";
263
+ note.resolution = typeof applied === "string" ? applied : deferred;
264
+ note.resolved_at = now();
265
+ if (typeof s.run_id === "string") note.resolved_run = s.run_id;
266
+ save(sp, s);
267
+ return ok(`${note.status} directive on card ${cardId}`);
152
268
  }
153
269
 
154
270
  // conductor-board loop-scope <loopId> <item...> [--note "..."]
@@ -338,72 +454,95 @@ export async function runStatusInit(args) {
338
454
  const runId =
339
455
  (typeof flag(args, ["--run-id"]) === "string" && flag(args, ["--run-id"])) ||
340
456
  now().replace(/\.\d+Z$/, "").replace(/:/g, "-");
341
- const steps = {};
457
+ const wfName = doc.name || "workflow";
342
458
 
343
- // Phase 0 (§10.2): auto-inject improvement cards from PROVEN this-conductor
344
- // knowledge BEFORE the workflow steps. Entries with current/proposed apply
345
- // automatically; structural ones (new_step/remove_step/reorder) are flagged
346
- // for human approval. A _validate card closes the phase.
347
- const STRUCTURAL = new Set(["new_step", "remove_step", "reorder"]);
348
- const knowledge = (Array.isArray(doc.knowledge) ? doc.knowledge : []).filter(
349
- (k) => k && typeof k === "object" && k.title,
350
- );
351
- const slug = (t) => String(t).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 40);
352
- const seen = new Set();
353
-
354
- // _improve::read-knowledge leads the phase: read + categorize the knowledge.
355
- if (knowledge.length > 0) {
356
- const cat = (s) => knowledge.filter((k) => (k.status || "emerging") === s).length;
357
- const cross = knowledge.filter((k) => (k.scope || "this-conductor") !== "this-conductor").length;
358
- steps["_improve::read-knowledge"] = {
359
- status: "pending",
360
- gate: "pending",
361
- attempt: 1,
362
- improve: {
363
- title: "Read knowledge",
364
- kind: "read-knowledge",
365
- note:
366
- `${cat("proven")} proven · ${cat("emerging")} emerging · ${cat("applied")} applied · ` +
367
- `${cross} cross-cutting`,
368
- },
369
- };
459
+ // §6.2 every run gets a human name: {workflow}-run-{N}-{timestamp}. N is the
460
+ // count of archived runs + 1; the timestamp is the run id trimmed to minutes.
461
+ const nameSlug = String(wfName).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "");
462
+ const historyDir = path.join(path.dirname(sp), "history");
463
+ let priorRuns = 0;
464
+ try {
465
+ priorRuns = fs.readdirSync(historyDir).filter((f) => f.endsWith(".json")).length;
466
+ } catch {
467
+ /* no history yet */
370
468
  }
469
+ const tsShort = runId.replace(/-\d{2}$/, ""); // 2026-06-04T12-30-00 → 2026-06-04T12-30
470
+ const runName =
471
+ (typeof flag(args, ["--run-name"]) === "string" && flag(args, ["--run-name"])) ||
472
+ `${nameSlug}-run-${priorRuns + 1}-${tsShort}`;
371
473
 
474
+ // §6.1 — auto_improve (default on). When off, the Phase 0 self-improvement
475
+ // pass is fully disabled: no improvement cards injected at all.
476
+ const autoImprove = doc.auto_improve !== false;
477
+
478
+ const steps = {};
372
479
  let improvements = 0;
373
- for (const k of knowledge) {
374
- if ((k.status || "emerging") !== "proven") continue;
375
- if ((k.scope || "this-conductor") !== "this-conductor") continue;
376
- const structural = STRUCTURAL.has(k.type);
377
- const textChange = k.current && k.proposed;
378
- if (!structural && !textChange) continue; // proven but nothing actionable
379
- let id = `_improve::${slug(k.title)}`;
380
- while (seen.has(id)) id += "-x";
381
- seen.add(id);
382
- steps[id] = {
383
- status: "pending",
384
- gate: "pending",
385
- attempt: 1,
386
- improve: {
387
- step: k.step,
388
- title: k.title,
389
- current: k.current,
390
- proposed: k.proposed,
391
- note: k.note,
392
- observed: k.observed || 1,
393
- scope: k.scope || "this-conductor",
394
- structural,
395
- kind: k.type || "instruction",
396
- },
397
- };
398
- improvements += 1;
399
- }
400
- if (improvements > 0) {
401
- steps["_improve::validate"] = {
402
- status: "pending",
403
- gate: "pending",
404
- attempt: 1,
405
- improve: { title: "Validate conductor", kind: "validate" },
406
- };
480
+
481
+ if (autoImprove) {
482
+ // Phase 0 (§10.2): auto-inject improvement cards from PROVEN this-conductor
483
+ // knowledge BEFORE the workflow steps. Entries with current/proposed apply
484
+ // automatically; structural ones (new_step/remove_step/reorder) are flagged
485
+ // for human approval. A _validate card closes the phase.
486
+ const STRUCTURAL = new Set(["new_step", "remove_step", "reorder"]);
487
+ const knowledge = (Array.isArray(doc.knowledge) ? doc.knowledge : []).filter(
488
+ (k) => k && typeof k === "object" && k.title,
489
+ );
490
+ const slug = (t) => String(t).toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-|-$/g, "").slice(0, 40);
491
+ const seen = new Set();
492
+
493
+ // _improve::read-knowledge leads the phase: read + categorize the knowledge.
494
+ if (knowledge.length > 0) {
495
+ const cat = (s) => knowledge.filter((k) => (k.status || "emerging") === s).length;
496
+ const cross = knowledge.filter((k) => (k.scope || "this-conductor") !== "this-conductor").length;
497
+ steps["_improve::read-knowledge"] = {
498
+ status: "pending",
499
+ gate: "pending",
500
+ attempt: 1,
501
+ improve: {
502
+ title: "Read knowledge",
503
+ kind: "read-knowledge",
504
+ note:
505
+ `${cat("proven")} proven · ${cat("emerging")} emerging · ${cat("applied")} applied · ` +
506
+ `${cross} cross-cutting`,
507
+ },
508
+ };
509
+ }
510
+
511
+ for (const k of knowledge) {
512
+ if ((k.status || "emerging") !== "proven") continue;
513
+ if ((k.scope || "this-conductor") !== "this-conductor") continue;
514
+ const structural = STRUCTURAL.has(k.type);
515
+ const textChange = k.current && k.proposed;
516
+ if (!structural && !textChange) continue; // proven but nothing actionable
517
+ let id = `_improve::${slug(k.title)}`;
518
+ while (seen.has(id)) id += "-x";
519
+ seen.add(id);
520
+ steps[id] = {
521
+ status: "pending",
522
+ gate: "pending",
523
+ attempt: 1,
524
+ improve: {
525
+ step: k.step,
526
+ title: k.title,
527
+ current: k.current,
528
+ proposed: k.proposed,
529
+ note: k.note,
530
+ observed: k.observed || 1,
531
+ scope: k.scope || "this-conductor",
532
+ structural,
533
+ kind: k.type || "instruction",
534
+ },
535
+ };
536
+ improvements += 1;
537
+ }
538
+ if (improvements > 0) {
539
+ steps["_improve::validate"] = {
540
+ status: "pending",
541
+ gate: "pending",
542
+ attempt: 1,
543
+ improve: { title: "Validate conductor", kind: "validate" },
544
+ };
545
+ }
407
546
  }
408
547
 
409
548
  for (const st of doc.steps || []) {
@@ -414,8 +553,10 @@ export async function runStatusInit(args) {
414
553
  : { status: "pending", gate: "pending", attempt: 1 };
415
554
  }
416
555
  const status = {
417
- workflow: doc.name || "workflow",
556
+ workflow: wfName,
418
557
  run_id: runId,
558
+ run_name: runName,
559
+ auto_improve: autoImprove,
419
560
  status: "running",
420
561
  goal: (doc.description || "").trim().replace(/\s+/g, " "),
421
562
  current_step: null,
@@ -0,0 +1 @@
1
+ /*! tailwindcss v4.3.0 | MIT License | https://tailwindcss.com */@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-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction: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-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial}}}@layer theme{:root,:host{--font-sans:-apple-system, BlinkMacSystemFont, "Inter", ui-sans-serif, system-ui, sans-serif;--font-mono:"JetBrains Mono", ui-monospace, "SF Mono", "Fira Code", Menlo, monospace;--spacing:.25rem;--container-md:28rem;--container-2xl:42rem;--container-3xl:48rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--font-weight-medium:500;--font-weight-semibold:600;--tracking-wide:.025em;--leading-snug:1.375;--leading-relaxed:1.625;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--blur-sm:8px;--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);--color-ink:#09090b;--color-ink-2:#0d0d10;--color-panel:#131316;--color-panel-2:#1a1a20;--color-line:#1c1c22;--color-line-2:#2a2a32;--color-chalk:#ebebef;--color-mist-2:#b6b6c0;--color-mist:#8b8b97;--color-dim:#404050;--color-mint:#4ade80;--color-green:#4ade80;--color-amber:#fbbf24;--color-rose:#f87171;--color-cyan:#8b8b97;--color-iris:#8b8b97;--color-heart:#ff6b8a}}@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%;-moz-tab-size:4;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;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]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:root{color-scheme:dark}body{background:var(--color-ink);color:var(--color-chalk);font-family:var(--font-sans);-webkit-font-smoothing:antialiased;margin:0}::selection{background:#ebebef38}@supports (color:color-mix(in lab,red,red)){::selection{background:color-mix(in oklab,var(--color-chalk) 22%,transparent)}}::selection{color:#fff}::-webkit-scrollbar{width:9px;height:9px}::-webkit-scrollbar-track{background:0 0}::-webkit-scrollbar-thumb{background:var(--color-line-2);border:2px solid var(--color-ink);border-radius:99px}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.inset-0{inset:calc(var(--spacing) * 0)}.inset-x-0{inset-inline:calc(var(--spacing) * 0)}.inset-y-0{inset-block:calc(var(--spacing) * 0)}.-top-1{top:calc(var(--spacing) * -1)}.top-0\.5{top:calc(var(--spacing) * .5)}.top-2\.5{top:calc(var(--spacing) * 2.5)}.top-3{top:calc(var(--spacing) * 3)}.-right-1{right:calc(var(--spacing) * -1)}.right-4{right:calc(var(--spacing) * 4)}.bottom-3{bottom:calc(var(--spacing) * 3)}.bottom-4{bottom:calc(var(--spacing) * 4)}.-left-7{left:calc(var(--spacing) * -7)}.left-0\.5{left:calc(var(--spacing) * .5)}.left-1\/2{left:50%}.left-4{left:calc(var(--spacing) * 4)}.left-\[11px\]{left:11px}.z-10{z-index:10}.z-40{z-index:40}.z-50{z-index:50}.mx-auto{margin-inline:auto}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:calc(var(--spacing) * 1)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-2\.5{margin-top:calc(var(--spacing) * 2.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mt-\[3px\]{margin-top:3px}.mt-px{margin-top:1px}.mb-1{margin-bottom:calc(var(--spacing) * 1)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-4{margin-bottom:calc(var(--spacing) * 4)}.mb-5{margin-bottom:calc(var(--spacing) * 5)}.ml-0\.5{margin-left:calc(var(--spacing) * .5)}.ml-1{margin-left:calc(var(--spacing) * 1)}.ml-3{margin-left:calc(var(--spacing) * 3)}.ml-5{margin-left:calc(var(--spacing) * 5)}.ml-auto{margin-left:auto}.line-clamp-1{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.h-1{height:calc(var(--spacing) * 1)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-3{height:calc(var(--spacing) * 3)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-9{height:calc(var(--spacing) * 9)}.h-11{height:calc(var(--spacing) * 11)}.h-12{height:calc(var(--spacing) * 12)}.h-40{height:calc(var(--spacing) * 40)}.h-\[18px\]{height:18px}.h-\[22px\]{height:22px}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-\[28rem\]{max-height:28rem}.max-h-\[80vh\]{max-height:80vh}.min-h-0{min-height:calc(var(--spacing) * 0)}.w-1{width:calc(var(--spacing) * 1)}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-9{width:calc(var(--spacing) * 9)}.w-12{width:calc(var(--spacing) * 12)}.w-32{width:calc(var(--spacing) * 32)}.w-\[22px\]{width:22px}.w-\[min\(640px\,92vw\)\]{width:min(640px,92vw)}.w-full{width:100%}.w-px{width:1px}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-\[1400px\]{max-width:1400px}.max-w-md{max-width:var(--container-md)}.min-w-0{min-width:calc(var(--spacing) * 0)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.animate-pulse{animation:var(--animate-pulse)}.cursor-col-resize{cursor:col-resize}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.cursor-row-resize{cursor:row-resize}.resize{resize:both}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.place-items-center{place-items:center}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * .5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * .5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-6>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 6) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 6) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-y-1{row-gap:calc(var(--spacing) * 1)}.gap-y-4{row-gap:calc(var(--spacing) * 4)}.self-center{align-self:center}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-amber\/25{border-color:#fbbf2440}@supports (color:color-mix(in lab,red,red)){.border-amber\/25{border-color:color-mix(in oklab,var(--color-amber) 25%,transparent)}}.border-amber\/40{border-color:#fbbf2466}@supports (color:color-mix(in lab,red,red)){.border-amber\/40{border-color:color-mix(in oklab,var(--color-amber) 40%,transparent)}}.border-cyan\/20{border-color:#8b8b9733}@supports (color:color-mix(in lab,red,red)){.border-cyan\/20{border-color:color-mix(in oklab,var(--color-cyan) 20%,transparent)}}.border-cyan\/25{border-color:#8b8b9740}@supports (color:color-mix(in lab,red,red)){.border-cyan\/25{border-color:color-mix(in oklab,var(--color-cyan) 25%,transparent)}}.border-cyan\/40{border-color:#8b8b9766}@supports (color:color-mix(in lab,red,red)){.border-cyan\/40{border-color:color-mix(in oklab,var(--color-cyan) 40%,transparent)}}.border-cyan\/50{border-color:#8b8b9780}@supports (color:color-mix(in lab,red,red)){.border-cyan\/50{border-color:color-mix(in oklab,var(--color-cyan) 50%,transparent)}}.border-iris\/30{border-color:#8b8b974d}@supports (color:color-mix(in lab,red,red)){.border-iris\/30{border-color:color-mix(in oklab,var(--color-iris) 30%,transparent)}}.border-iris\/50{border-color:#8b8b9780}@supports (color:color-mix(in lab,red,red)){.border-iris\/50{border-color:color-mix(in oklab,var(--color-iris) 50%,transparent)}}.border-line{border-color:var(--color-line)}.border-line-2{border-color:var(--color-line-2)}.border-line\/50{border-color:#1c1c2280}@supports (color:color-mix(in lab,red,red)){.border-line\/50{border-color:color-mix(in oklab,var(--color-line) 50%,transparent)}}.border-line\/60{border-color:#1c1c2299}@supports (color:color-mix(in lab,red,red)){.border-line\/60{border-color:color-mix(in oklab,var(--color-line) 60%,transparent)}}.border-line\/70{border-color:#1c1c22b3}@supports (color:color-mix(in lab,red,red)){.border-line\/70{border-color:color-mix(in oklab,var(--color-line) 70%,transparent)}}.border-mint\/25{border-color:#4ade8040}@supports (color:color-mix(in lab,red,red)){.border-mint\/25{border-color:color-mix(in oklab,var(--color-mint) 25%,transparent)}}.border-mint\/30{border-color:#4ade804d}@supports (color:color-mix(in lab,red,red)){.border-mint\/30{border-color:color-mix(in oklab,var(--color-mint) 30%,transparent)}}.border-mint\/40{border-color:#4ade8066}@supports (color:color-mix(in lab,red,red)){.border-mint\/40{border-color:color-mix(in oklab,var(--color-mint) 40%,transparent)}}.border-mint\/60{border-color:#4ade8099}@supports (color:color-mix(in lab,red,red)){.border-mint\/60{border-color:color-mix(in oklab,var(--color-mint) 60%,transparent)}}.border-rose\/30{border-color:#f871714d}@supports (color:color-mix(in lab,red,red)){.border-rose\/30{border-color:color-mix(in oklab,var(--color-rose) 30%,transparent)}}.bg-amber{background-color:var(--color-amber)}.bg-amber\/10{background-color:#fbbf241a}@supports (color:color-mix(in lab,red,red)){.bg-amber\/10{background-color:color-mix(in oklab,var(--color-amber) 10%,transparent)}}.bg-amber\/15{background-color:#fbbf2426}@supports (color:color-mix(in lab,red,red)){.bg-amber\/15{background-color:color-mix(in oklab,var(--color-amber) 15%,transparent)}}.bg-chalk{background-color:var(--color-chalk)}.bg-cyan\/15{background-color:#8b8b9726}@supports (color:color-mix(in lab,red,red)){.bg-cyan\/15{background-color:color-mix(in oklab,var(--color-cyan) 15%,transparent)}}.bg-cyan\/\[0\.06\]{background-color:#8b8b970f}@supports (color:color-mix(in lab,red,red)){.bg-cyan\/\[0\.06\]{background-color:color-mix(in oklab,var(--color-cyan) 6%,transparent)}}.bg-cyan\/\[0\.08\]{background-color:#8b8b9714}@supports (color:color-mix(in lab,red,red)){.bg-cyan\/\[0\.08\]{background-color:color-mix(in oklab,var(--color-cyan) 8%,transparent)}}.bg-dim{background-color:var(--color-dim)}.bg-ink{background-color:var(--color-ink)}.bg-ink-2{background-color:var(--color-ink-2)}.bg-ink-2\/90{background-color:#0d0d10e6}@supports (color:color-mix(in lab,red,red)){.bg-ink-2\/90{background-color:color-mix(in oklab,var(--color-ink-2) 90%,transparent)}}.bg-ink\/40{background-color:#09090b66}@supports (color:color-mix(in lab,red,red)){.bg-ink\/40{background-color:color-mix(in oklab,var(--color-ink) 40%,transparent)}}.bg-ink\/50{background-color:#09090b80}@supports (color:color-mix(in lab,red,red)){.bg-ink\/50{background-color:color-mix(in oklab,var(--color-ink) 50%,transparent)}}.bg-ink\/60{background-color:#09090b99}@supports (color:color-mix(in lab,red,red)){.bg-ink\/60{background-color:color-mix(in oklab,var(--color-ink) 60%,transparent)}}.bg-ink\/70{background-color:#09090bb3}@supports (color:color-mix(in lab,red,red)){.bg-ink\/70{background-color:color-mix(in oklab,var(--color-ink) 70%,transparent)}}.bg-ink\/90{background-color:#09090be6}@supports (color:color-mix(in lab,red,red)){.bg-ink\/90{background-color:color-mix(in oklab,var(--color-ink) 90%,transparent)}}.bg-iris\/10{background-color:#8b8b971a}@supports (color:color-mix(in lab,red,red)){.bg-iris\/10{background-color:color-mix(in oklab,var(--color-iris) 10%,transparent)}}.bg-iris\/15{background-color:#8b8b9726}@supports (color:color-mix(in lab,red,red)){.bg-iris\/15{background-color:color-mix(in oklab,var(--color-iris) 15%,transparent)}}.bg-line{background-color:var(--color-line)}.bg-line-2{background-color:var(--color-line-2)}.bg-line-2\/40{background-color:#2a2a3266}@supports (color:color-mix(in lab,red,red)){.bg-line-2\/40{background-color:color-mix(in oklab,var(--color-line-2) 40%,transparent)}}.bg-line-2\/60{background-color:#2a2a3299}@supports (color:color-mix(in lab,red,red)){.bg-line-2\/60{background-color:color-mix(in oklab,var(--color-line-2) 60%,transparent)}}.bg-line-2\/70{background-color:#2a2a32b3}@supports (color:color-mix(in lab,red,red)){.bg-line-2\/70{background-color:color-mix(in oklab,var(--color-line-2) 70%,transparent)}}.bg-mint{background-color:var(--color-mint)}.bg-mint\/10{background-color:#4ade801a}@supports (color:color-mix(in lab,red,red)){.bg-mint\/10{background-color:color-mix(in oklab,var(--color-mint) 10%,transparent)}}.bg-mint\/15{background-color:#4ade8026}@supports (color:color-mix(in lab,red,red)){.bg-mint\/15{background-color:color-mix(in oklab,var(--color-mint) 15%,transparent)}}.bg-mint\/70{background-color:#4ade80b3}@supports (color:color-mix(in lab,red,red)){.bg-mint\/70{background-color:color-mix(in oklab,var(--color-mint) 70%,transparent)}}.bg-mist{background-color:var(--color-mist)}.bg-panel{background-color:var(--color-panel)}.bg-panel-2{background-color:var(--color-panel-2)}.bg-panel\/40{background-color:#13131666}@supports (color:color-mix(in lab,red,red)){.bg-panel\/40{background-color:color-mix(in oklab,var(--color-panel) 40%,transparent)}}.bg-panel\/60{background-color:#13131699}@supports (color:color-mix(in lab,red,red)){.bg-panel\/60{background-color:color-mix(in oklab,var(--color-panel) 60%,transparent)}}.bg-rose{background-color:var(--color-rose)}.bg-rose\/10{background-color:#f871711a}@supports (color:color-mix(in lab,red,red)){.bg-rose\/10{background-color:color-mix(in oklab,var(--color-rose) 10%,transparent)}}.p-3{padding:calc(var(--spacing) * 3)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.px-0{padding-inline:calc(var(--spacing) * 0)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.px-8{padding-inline:calc(var(--spacing) * 8)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-px{padding-block:1px}.pt-0\.5{padding-top:calc(var(--spacing) * .5)}.pt-1{padding-top:calc(var(--spacing) * 1)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-2\.5{padding-top:calc(var(--spacing) * 2.5)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pr-0\.5{padding-right:calc(var(--spacing) * .5)}.pr-1\.5{padding-right:calc(var(--spacing) * 1.5)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pb-0\.5{padding-bottom:calc(var(--spacing) * .5)}.pb-1{padding-bottom:calc(var(--spacing) * 1)}.pb-1\.5{padding-bottom:calc(var(--spacing) * 1.5)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-2\.5{padding-left:calc(var(--spacing) * 2.5)}.pl-6{padding-left:calc(var(--spacing) * 6)}.pl-7{padding-left:calc(var(--spacing) * 7)}.pl-\[18px\]{padding-left:18px}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.font-mono{font-family:var(--font-mono)}.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-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.85em\]{font-size:.85em}.text-\[9\.5px\]{font-size:9.5px}.text-\[9px\]{font-size:9px}.text-\[10\.5px\]{font-size:10.5px}.text-\[10px\]{font-size:10px}.text-\[11\.5px\]{font-size:11.5px}.text-\[11px\]{font-size:11px}.text-\[12\.5px\]{font-size:12.5px}.text-\[12px\]{font-size:12px}.text-\[13px\]{font-size:13px}.text-\[14px\]{font-size:14px}.text-\[15px\]{font-size:15px}.leading-\[18px\]{--tw-leading:18px;line-height:18px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.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-\[0\.12em\]{--tw-tracking:.12em;letter-spacing:.12em}.tracking-\[0\.15em\]{--tw-tracking:.15em;letter-spacing:.15em}.tracking-\[0\.16em\]{--tw-tracking:.16em;letter-spacing:.16em}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.text-amber{color:var(--color-amber)}.text-amber\/80{color:#fbbf24cc}@supports (color:color-mix(in lab,red,red)){.text-amber\/80{color:color-mix(in oklab,var(--color-amber) 80%,transparent)}}.text-amber\/90{color:#fbbf24e6}@supports (color:color-mix(in lab,red,red)){.text-amber\/90{color:color-mix(in oklab,var(--color-amber) 90%,transparent)}}.text-chalk{color:var(--color-chalk)}.text-cyan{color:var(--color-cyan)}.text-dim{color:var(--color-dim)}.text-iris{color:var(--color-iris)}.text-line-2{color:var(--color-line-2)}.text-mint{color:var(--color-mint)}.text-mint\/80{color:#4ade80cc}@supports (color:color-mix(in lab,red,red)){.text-mint\/80{color:color-mix(in oklab,var(--color-mint) 80%,transparent)}}.text-mint\/90{color:#4ade80e6}@supports (color:color-mix(in lab,red,red)){.text-mint\/90{color:color-mix(in oklab,var(--color-mint) 90%,transparent)}}.text-mist{color:var(--color-mist)}.text-mist-2{color:var(--color-mist-2)}.text-rose{color:var(--color-rose)}.text-rose\/80{color:#f87171cc}@supports (color:color-mix(in lab,red,red)){.text-rose\/80{color:color-mix(in oklab,var(--color-rose) 80%,transparent)}}.uppercase{text-transform:uppercase}.italic{font-style:italic}.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,)}.line-through{text-decoration-line:line-through}.underline-offset-2{text-underline-offset:2px}.accent-mint{accent-color:var(--color-mint)}.opacity-0{opacity:0}.opacity-70{opacity:.7}.opacity-80{opacity:.8}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);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)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.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{--tw-backdrop-blur:blur(8px);-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(var(--blur-sm));-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,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-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))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-300{--tw-duration:.3s;transition-duration:.3s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}@media(hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}.group-hover\/bar\:text-chalk:is(:where(.group\/bar):hover *){color:var(--color-chalk)}.hover\:border-line-2:hover{border-color:var(--color-line-2)}.hover\:border-mint\/50:hover{border-color:#4ade8080}@supports (color:color-mix(in lab,red,red)){.hover\:border-mint\/50:hover{border-color:color-mix(in oklab,var(--color-mint) 50%,transparent)}}.hover\:border-mist\/40:hover{border-color:#8b8b9766}@supports (color:color-mix(in lab,red,red)){.hover\:border-mist\/40:hover{border-color:color-mix(in oklab,var(--color-mist) 40%,transparent)}}.hover\:bg-cyan\/10:hover{background-color:#8b8b971a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-cyan\/10:hover{background-color:color-mix(in oklab,var(--color-cyan) 10%,transparent)}}.hover\:bg-line-2\/70:hover{background-color:#2a2a32b3}@supports (color:color-mix(in lab,red,red)){.hover\:bg-line-2\/70:hover{background-color:color-mix(in oklab,var(--color-line-2) 70%,transparent)}}.hover\:bg-mint\/15:hover{background-color:#4ade8026}@supports (color:color-mix(in lab,red,red)){.hover\:bg-mint\/15:hover{background-color:color-mix(in oklab,var(--color-mint) 15%,transparent)}}.hover\:bg-mint\/25:hover{background-color:#4ade8040}@supports (color:color-mix(in lab,red,red)){.hover\:bg-mint\/25:hover{background-color:color-mix(in oklab,var(--color-mint) 25%,transparent)}}.hover\:bg-panel:hover{background-color:var(--color-panel)}.hover\:bg-panel-2:hover{background-color:var(--color-panel-2)}.hover\:bg-panel-2\/50:hover{background-color:#1a1a2080}@supports (color:color-mix(in lab,red,red)){.hover\:bg-panel-2\/50:hover{background-color:color-mix(in oklab,var(--color-panel-2) 50%,transparent)}}.hover\:bg-panel-2\/60:hover{background-color:#1a1a2099}@supports (color:color-mix(in lab,red,red)){.hover\:bg-panel-2\/60:hover{background-color:color-mix(in oklab,var(--color-panel-2) 60%,transparent)}}.hover\:bg-panel-2\/70:hover{background-color:#1a1a20b3}@supports (color:color-mix(in lab,red,red)){.hover\:bg-panel-2\/70:hover{background-color:color-mix(in oklab,var(--color-panel-2) 70%,transparent)}}.hover\:bg-panel\/40:hover{background-color:#13131666}@supports (color:color-mix(in lab,red,red)){.hover\:bg-panel\/40:hover{background-color:color-mix(in oklab,var(--color-panel) 40%,transparent)}}.hover\:bg-rose\/10:hover{background-color:#f871711a}@supports (color:color-mix(in lab,red,red)){.hover\:bg-rose\/10:hover{background-color:color-mix(in oklab,var(--color-rose) 10%,transparent)}}.hover\:text-chalk:hover{color:var(--color-chalk)}.hover\:text-mist:hover{color:var(--color-mist)}.hover\:text-rose:hover{color:var(--color-rose)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:border-mist\/40:focus{border-color:#8b8b9766}@supports (color:color-mix(in lab,red,red)){.focus\:border-mist\/40:focus{border-color:color-mix(in oklab,var(--color-mist) 40%,transparent)}}.disabled\:opacity-40:disabled{opacity:.4}@media(min-width:40rem){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media(min-width:64rem){.lg\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}}}.led{border-radius:50%;flex-shrink:0;width:6px;height:6px;transition:background-color .35s,box-shadow .35s,opacity .35s;display:inline-block}.led-running{background-color:var(--color-green);animation:1.9s ease-in-out infinite led-running}@keyframes led-running{0%,to{background-color:#4ade80;box-shadow:0 0 7px #4ade8073}50%{background-color:#e9fff1;box-shadow:0 0 10px #d6ffe699}}.led-gate{background-color:var(--color-green);animation:1.5s ease-in-out infinite led-gate}@keyframes led-gate{0%,to{background-color:#4ade80;box-shadow:0 0 7px #4ade8066}50%{background-color:#fbbf24;box-shadow:0 0 9px #fbbf2480}}.led-failed{background-color:var(--color-rose);animation:1.5s ease-in-out infinite led-error}@keyframes led-error{0%,to{background-color:#f87171;box-shadow:0 0 8px #f8717180}50%{background-color:#4ade80;box-shadow:0 0 8px #4ade8073}}.led-done{background:var(--color-green);opacity:.5}.led-pending{background:var(--color-dim)}.led-stalled{background:var(--color-amber);box-shadow:0 0 8px #fbbf244d}@keyframes heart-rest{0%{transform:scale(1)}7%{transform:scale(1.15)}14%{transform:scale(1)}21%{transform:scale(1.09)}28%{transform:scale(1)}to{transform:scale(1)}}.heart-rest{transform-origin:50%;animation:1.15s ease-in-out infinite heart-rest}@keyframes heart-strong{0%{transform:scale(1)}45%{transform:scale(1.15)}to{transform:scale(1)}}.heart-strong{transform-origin:50%;animation:.42s ease-out heart-strong}.heart-weak{transform-origin:50%;opacity:.55;animation:2.4s ease-in-out infinite heart-rest}@keyframes stall-breathe{0%,to{opacity:.45}50%{opacity:1}}.stall-breathe{animation:2.1s ease-in-out infinite stall-breathe}@keyframes beat-flash{0%{box-shadow:0 0 color-mix(in oklab,var(--color-mint) 55%,transparent)}45%{box-shadow:0 0 0 3px color-mix(in oklab,var(--color-mint) 28%,transparent)}to{box-shadow:0 0 #0000}}.beat-flash{animation:.75s ease-out beat-flash}@keyframes beat-flash-faint{0%{box-shadow:0 0 color-mix(in oklab,var(--color-chalk) 20%,transparent)}45%{box-shadow:0 0 0 2px color-mix(in oklab,var(--color-chalk) 9%,transparent)}to{box-shadow:0 0 #0000}}.beat-flash-faint{animation:.75s ease-out beat-flash-faint}@keyframes tw-blink{0%,49%{opacity:1}50%,to{opacity:0}}.tw-cursor{animation:.53s step-end infinite tw-blink}.board-scroll{scrollbar-width:thin;scrollbar-color:var(--color-line-2) transparent}.board-scroll::-webkit-scrollbar{width:6px}.board-scroll::-webkit-scrollbar-track{background:0 0}.board-scroll::-webkit-scrollbar-thumb{background:var(--color-line-2);border:none;border-radius:99px}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@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-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{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-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}}