mainflow 0.11.1 → 0.12.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/dist/cli.js CHANGED
@@ -1,9 +1,9 @@
1
1
  #!/usr/bin/env node
2
- import { A as setSessionStatus, C as updateTask, D as readSession, F as sessionBriefing, G as planIssue, H as closeIssue, J as setFindingStatus, K as reopenIssue, M as startSession, O as setSessionArchived, P as updateAction, S as supersedeDecision, U as createFinding, V as appendOps, W as createIssue, X as HubError, Y as setIssueArchived, Z as loadHub, _ as setArchived, b as setMainlineStatus, c as migrateHub, d as addRepo, et as MAINLINE_FILE, f as createDecision, g as initHub, h as dropChecklistItem, l as acceptDecision, m as createTask, ot as findHubRoot, p as createMainline, q as setFindingArchived, rt as WriteError, tt as TASK_FILE, u as addHub, v as setChecklistItem, w as addAction, y as setCriterion } from "./host-ByGN9mGS.js";
2
+ import { $ as HubError, A as readSession, C as setMainlineStatus, D as addAction, E as updateTask, F as startSession, G as closeIssue, J as planIssue, K as createFinding, L as updateAction, N as setSessionStatus, Q as setIssueArchived, R as sessionBriefing, S as setCriterion, T as supersedeDecision, W as appendOps, X as setFindingArchived, Y as reopenIssue, Z as setFindingStatus, _ as createTask, at as MAINLINE_FILE, b as setArchived, ct as WriteError, dt as findHubRoot, et as loadHub, f as acceptDecision, g as createMainline, h as createDecision, j as setSessionArchived, l as migrateHub, m as addRepo, ot as TASK_FILE, p as addHub, q as createIssue, v as dropChecklistItem, x as setChecklistItem, y as initHub } from "./host-Dwf1wLMd.js";
3
3
  import { t as listProgress } from "./progress-1BfPg2zN.js";
4
4
  import { COMMAND_SPECS, OPTIONS } from "./facts.js";
5
5
  import { runHook } from "./hooks.js";
6
- import { c as CLI_VERSION, r as launchUi, s as startUiInBackground } from "./launch-B9QrvwZQ.js";
6
+ import { l as CLI_VERSION, r as launchUi, s as startUiInBackground } from "./launch-D5K564tw.js";
7
7
  import { readFileSync, realpathSync } from "node:fs";
8
8
  import { join, relative } from "node:path";
9
9
  import { fileURLToPath } from "node:url";
@@ -124,6 +124,8 @@ function parseLocal(input) {
124
124
  }
125
125
  return null;
126
126
  }
127
+ /** The reference a blocked task waits for, when its whole `waitingFor` text is one; free text such as 使用者 gives undefined. */
128
+ const waitingForRef = (waitingFor) => waitingFor && parseRef(waitingFor) ? waitingFor : void 0;
127
129
  /** The mainline a reference sits in, or undefined for hub-level issues and findings. */
128
130
  const refMainline = (ref) => "mainline" in ref ? ref.mainline : void 0;
129
131
  /** The example reference for a kind, used in error messages. */
@@ -382,7 +384,10 @@ const taskSchema = z.object({
382
384
  repo: z.string().min(1).nullable().optional(),
383
385
  startedAt: date.optional(),
384
386
  checklist: z.array(checklistItemSchema),
385
- /** Why a blocked task cannot move, what it waits for, and which signal says the wait is over */
387
+ /**
388
+ * Why a blocked task cannot move, what it waits for, and which signal says the wait is over. `waitingFor`
389
+ * is free text, or a reference such as m031/t002 when the whole text is one (see waitingForRef).
390
+ */
386
391
  blockedBy: z.object({
387
392
  reason: text,
388
393
  waitingFor: text.optional(),
@@ -508,4 +513,4 @@ function parseOpsLine(line) {
508
513
  return parsed.success ? parsed.data : null;
509
514
  }
510
515
  //#endregion
511
- export { mainlineSchema as A, TASK_SECTIONS as C, findingSchema as D, decisionSchema as E, refMainline as F, sessionSchema as I, taskSchema as L, parseOpsLine as M, parseRef as N, formatOpsEntry as O, refExample as P, TASK_REQUIRED_SECTIONS as S, configSchema as T, PRIORITIES as _, DECISION_STATUS as a, SESSION_STATUS as b, FINDING_STATUS as c, ISSUE_SECTIONS as d, ISSUE_STATUS as f, MERGE_STATES as g, MAINLINE_STATUS as h, DECISION_SECTIONS as i, opsEntrySchema as j, issueSchema as k, FORMAT_VERSION as l, MAINLINE_SECTIONS as m, CLOSED_STATUS as n, DEFAULT_CATEGORIES as o, LINK_RELS as p, DECIDERS as r, FINDING_SECTIONS as s, CHECKLIST_REF as t, ID_PATTERNS as u, REF_EXAMPLES as v, WORK_STATUS as w, SLUG as x, RESERVED_HUB_NAMES as y };
516
+ export { mainlineSchema as A, TASK_SECTIONS as C, findingSchema as D, decisionSchema as E, refMainline as F, sessionSchema as I, taskSchema as L, parseOpsLine as M, parseRef as N, formatOpsEntry as O, refExample as P, waitingForRef as R, TASK_REQUIRED_SECTIONS as S, configSchema as T, PRIORITIES as _, DECISION_STATUS as a, SESSION_STATUS as b, FINDING_STATUS as c, ISSUE_SECTIONS as d, ISSUE_STATUS as f, MERGE_STATES as g, MAINLINE_STATUS as h, DECISION_SECTIONS as i, opsEntrySchema as j, issueSchema as k, FORMAT_VERSION as l, MAINLINE_SECTIONS as m, CLOSED_STATUS as n, DEFAULT_CATEGORIES as o, LINK_RELS as p, DECIDERS as r, FINDING_SECTIONS as s, CHECKLIST_REF as t, ID_PATTERNS as u, REF_EXAMPLES as v, WORK_STATUS as w, SLUG as x, RESERVED_HUB_NAMES as y };
package/dist/facts.js CHANGED
@@ -1,4 +1,4 @@
1
- import { C as TASK_SECTIONS, S as TASK_REQUIRED_SECTIONS, _ as PRIORITIES, a as DECISION_STATUS, b as SESSION_STATUS, c as FINDING_STATUS, d as ISSUE_SECTIONS, f as ISSUE_STATUS, g as MERGE_STATES, h as MAINLINE_STATUS, i as DECISION_SECTIONS, l as FORMAT_VERSION, m as MAINLINE_SECTIONS, n as CLOSED_STATUS, o as DEFAULT_CATEGORIES, p as LINK_RELS, r as DECIDERS, s as FINDING_SECTIONS, t as CHECKLIST_REF, u as ID_PATTERNS, w as WORK_STATUS, x as SLUG } from "./dist-D2NK-QQP.js";
1
+ import { C as TASK_SECTIONS, S as TASK_REQUIRED_SECTIONS, _ as PRIORITIES, a as DECISION_STATUS, b as SESSION_STATUS, c as FINDING_STATUS, d as ISSUE_SECTIONS, f as ISSUE_STATUS, g as MERGE_STATES, h as MAINLINE_STATUS, i as DECISION_SECTIONS, l as FORMAT_VERSION, m as MAINLINE_SECTIONS, n as CLOSED_STATUS, o as DEFAULT_CATEGORIES, p as LINK_RELS, r as DECIDERS, s as FINDING_SECTIONS, t as CHECKLIST_REF, u as ID_PATTERNS, w as WORK_STATUS, x as SLUG } from "./dist-BQmXEfAf.js";
2
2
  //#region src/facts.ts
3
3
  const COMMAND_SPECS = {
4
4
  init: {
@@ -477,7 +477,7 @@ const FIELDS = {
477
477
  field("repo", false, "主要動到的倉庫,名稱需在 config.yaml 登記"),
478
478
  field("startedAt", false, "第一次轉為 doing 時由 CLI 寫入"),
479
479
  field("checklist", true, "checklist 項目清單,每項的欄位見 checklistItem"),
480
- field("blockedBy", false, "卡住時的原因、等待對象與繼續的訊號,blocked 時必填"),
480
+ field("blockedBy", false, "卡住時的原因、等待對象與繼續的訊號,blocked 時必填;等待對象整串是參照時(例如 m031/t002)會檢查它存在"),
481
481
  field("branch", false, "工作所在的分支"),
482
482
  field("worktree", false, "worktree 的路徑"),
483
483
  field("base", false, "分支基於哪個 commit"),
package/dist/hooks.js CHANGED
@@ -1,4 +1,4 @@
1
- import { A as setSessionStatus, B as mayDecorate, D as readSession, F as sessionBriefing, I as turnReminder, L as decorateReply, R as endsWithMarker, T as ensureSession, X as HubError, Z as loadHub, at as currentBranch, i as hostName, it as DATA_DIR, j as settleSession, k as setSessionInfo, ot as findHubRoot, st as worktreesOf, z as headerLine } from "./host-ByGN9mGS.js";
1
+ import { $ as HubError, A as readSession, B as decorateReply, H as headerLine, M as setSessionInfo, N as setSessionStatus, O as ensureSession, P as settleSession, R as sessionBriefing, U as mayDecorate, V as endsWithMarker, dt as findHubRoot, et as loadHub, ft as worktreesOf, i as hostName, lt as DATA_DIR, ut as currentBranch, z as turnReminder } from "./host-Dwf1wLMd.js";
2
2
  import { appendFileSync, existsSync, readFileSync } from "node:fs";
3
3
  import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
4
4
  //#region src/hooks.ts
@@ -1,4 +1,4 @@
1
- import { A as mainlineSchema, C as TASK_SECTIONS, D as findingSchema, E as decisionSchema, F as refMainline, I as sessionSchema, L as taskSchema, M as parseOpsLine, N as parseRef, O as formatOpsEntry, P as refExample, S as TASK_REQUIRED_SECTIONS, T as configSchema, b as SESSION_STATUS, c as FINDING_STATUS, d as ISSUE_SECTIONS, g as MERGE_STATES, h as MAINLINE_STATUS, i as DECISION_SECTIONS, j as opsEntrySchema, k as issueSchema, m as MAINLINE_SECTIONS, n as CLOSED_STATUS, o as DEFAULT_CATEGORIES, r as DECIDERS, s as FINDING_SECTIONS, t as CHECKLIST_REF, v as REF_EXAMPLES, w as WORK_STATUS, x as SLUG, y as RESERVED_HUB_NAMES } from "./dist-D2NK-QQP.js";
1
+ import { A as mainlineSchema, C as TASK_SECTIONS, D as findingSchema, E as decisionSchema, F as refMainline, I as sessionSchema, L as taskSchema, M as parseOpsLine, N as parseRef, O as formatOpsEntry, P as refExample, R as waitingForRef, S as TASK_REQUIRED_SECTIONS, T as configSchema, b as SESSION_STATUS, c as FINDING_STATUS, d as ISSUE_SECTIONS, g as MERGE_STATES, h as MAINLINE_STATUS, i as DECISION_SECTIONS, j as opsEntrySchema, k as issueSchema, m as MAINLINE_SECTIONS, n as CLOSED_STATUS, o as DEFAULT_CATEGORIES, r as DECIDERS, s as FINDING_SECTIONS, t as CHECKLIST_REF, v as REF_EXAMPLES, w as WORK_STATUS, x as SLUG, y as RESERVED_HUB_NAMES } from "./dist-BQmXEfAf.js";
2
2
  import { appendFileSync, closeSync, existsSync, lstatSync, mkdirSync, openSync, readFileSync, readdirSync, readlinkSync, realpathSync, renameSync, rmSync, statSync, symlinkSync, writeFileSync, writeSync } from "node:fs";
3
3
  import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
4
4
  import { spawn, spawnSync } from "node:child_process";
@@ -311,6 +311,113 @@ function linksInto(hub, hubName) {
311
311
  return out;
312
312
  }
313
313
  //#endregion
314
+ //#region ../core/dist/deps.js
315
+ const MET = /* @__PURE__ */ new Set([
316
+ "done",
317
+ "closed",
318
+ "accepted",
319
+ "superseded",
320
+ "obsolete"
321
+ ]);
322
+ const depState = (target) => !target ? "unknown" : MET.has(target.status) ? "met" : target.status === "dropped" ? "dropped" : "pending";
323
+ function dependencyGraph(hub) {
324
+ const own = refIndex(hub);
325
+ const others = new Map((hub.remotes ?? []).flatMap((r) => r.hub ? [[r.name, refIndex(r.hub)]] : []));
326
+ /** A reference as this hub writes it: this hub's own prefix is dropped, another hub's is kept. */
327
+ const normal = (ref) => parseRef(ref)?.hub === hub.config.hub ? ref.slice(ref.indexOf(":") + 1) : ref;
328
+ const target = (ref) => {
329
+ const hubName = parseRef(ref)?.hub;
330
+ return hubName === void 0 ? own.get(ref) : others.get(hubName)?.get(ref.slice(ref.indexOf(":") + 1));
331
+ };
332
+ const edges = [];
333
+ const edge = (from, to, source, extra) => edges.push({
334
+ from,
335
+ to,
336
+ source,
337
+ state: depState(target(to)),
338
+ ...extra
339
+ });
340
+ const links = (from, file, list) => list?.forEach((l, i) => l.rel === "depends-on" && edge(from, normal(l.to), "link", {
341
+ file,
342
+ field: `links.${i}.to`,
343
+ ...l.note ? { note: l.note } : {}
344
+ }));
345
+ for (const m of hub.mainlines) {
346
+ links(m.id, m.file, m.links);
347
+ for (const d of m.decisions) links(`${m.id}/${d.id}`, d.file, d.links);
348
+ for (const t of m.tasks) {
349
+ links(`${m.id}/${t.id}`, t.file, t.links);
350
+ t.dependsOn?.forEach((dep, i) => edge(`${m.id}/${t.id}`, `${m.id}/${dep}`, "task", {
351
+ file: t.file,
352
+ field: `dependsOn.${i}`
353
+ }));
354
+ }
355
+ }
356
+ for (const d of [...hub.issues, ...hub.findings]) links(d.id, d.file, d.links);
357
+ for (const remote of hub.remotes ?? []) {
358
+ if (!remote.hub) continue;
359
+ for (const { to, link } of linksInto(remote.hub, hub.config.hub)) if (link.rel === "depends-on") edge(`${remote.name}:${link.from}`, to, "link", link.note ? { note: link.note } : {});
360
+ }
361
+ return {
362
+ edges,
363
+ cycles: findCycles(edges)
364
+ };
365
+ }
366
+ /** Cycles among this hub's own documents, each once, starting from its smallest reference. */
367
+ function findCycles(edges) {
368
+ const next = /* @__PURE__ */ new Map();
369
+ for (const e of edges) if (!e.from.includes(":") && !e.to.includes(":")) next.set(e.from, [...next.get(e.from) ?? [], e.to]);
370
+ const state = /* @__PURE__ */ new Map();
371
+ const stack = [];
372
+ const cycles = /* @__PURE__ */ new Map();
373
+ const visit = (node) => {
374
+ state.set(node, "open");
375
+ stack.push(node);
376
+ for (const to of next.get(node) ?? []) if (state.get(to) === "open") {
377
+ const loop = stack.slice(stack.indexOf(to));
378
+ const start = loop.indexOf([...loop].sort()[0]);
379
+ const ordered = [...loop.slice(start), ...loop.slice(0, start)];
380
+ cycles.set(ordered.join(" "), [...ordered, ordered[0]]);
381
+ } else if (!state.has(to)) visit(to);
382
+ stack.pop();
383
+ state.set(node, "closed");
384
+ };
385
+ for (const node of [...next.keys()].sort()) if (!state.has(node)) visit(node);
386
+ return [...cycles.values()];
387
+ }
388
+ /** The mainline a reference sits in, keeping another hub's prefix; undefined for issues and findings. */
389
+ function mainlineOf(ref) {
390
+ const parsed = parseRef(ref);
391
+ const m = parsed ? refMainline(parsed) : void 0;
392
+ return m && (parsed.hub ? `${parsed.hub}:${m}` : m);
393
+ }
394
+ /** Dependencies lifted to mainlines, for a map of how mainlines wait for one another. */
395
+ function mainlineEdges(graph) {
396
+ const out = /* @__PURE__ */ new Map();
397
+ for (const e of graph.edges) {
398
+ const from = mainlineOf(e.from);
399
+ const to = mainlineOf(e.to);
400
+ if (!from || !to || from === to) continue;
401
+ const key = `${from} ${to}`;
402
+ const entry = out.get(key) ?? {
403
+ from,
404
+ to,
405
+ state: e.state,
406
+ edges: []
407
+ };
408
+ entry.edges.push(e);
409
+ const states = entry.edges.map((x) => x.state);
410
+ entry.state = [
411
+ "pending",
412
+ "unknown",
413
+ "dropped",
414
+ "met"
415
+ ].find((s) => states.includes(s));
416
+ out.set(key, entry);
417
+ }
418
+ return [...out.values()];
419
+ }
420
+ //#endregion
314
421
  //#region ../core/dist/templates.js
315
422
  const body = (headings) => ["", ...headings.flatMap((h) => [`## ${h}`, ""])].join("\n");
316
423
  const MAINLINE_BODY = body(MAINLINE_SECTIONS);
@@ -553,6 +660,21 @@ function loadHub(root, options = {}) {
553
660
  unreadable,
554
661
  problems
555
662
  });
663
+ const deps = dependencyGraph({
664
+ config,
665
+ mainlines,
666
+ issues: hubIssues,
667
+ findings,
668
+ remotes
669
+ });
670
+ for (const cycle of deps.cycles) {
671
+ const first = deps.edges.find((e) => e.from === cycle[0] && e.to === cycle[1]);
672
+ problems.push({
673
+ file: first.file,
674
+ field: first.field,
675
+ message: `dependency cycle ${cycle.join(" → ")}; drop one of these dependencies`
676
+ });
677
+ }
556
678
  return {
557
679
  root,
558
680
  config,
@@ -686,6 +808,12 @@ function checkReferences(input) {
686
808
  for (const t of m.tasks) {
687
809
  add(t.file, t, `${m.id}/${t.id}`, m.id);
688
810
  items(t.file, "checklist", t.checklist);
811
+ const waiting = waitingForRef(t.blockedBy?.waitingFor);
812
+ if (waiting) pending.push({
813
+ ref: waiting,
814
+ file: t.file,
815
+ field: "blockedBy.waitingFor"
816
+ });
689
817
  }
690
818
  }
691
819
  for (const i of issues) add(i.file, i, i.id);
@@ -1605,6 +1733,44 @@ function supersedeDecision(root, refInput, by, expectedVersion) {
1605
1733
  }, expectedVersion);
1606
1734
  }
1607
1735
  //#endregion
1736
+ //#region ../core/dist/archive.js
1737
+ /** The entities that carry `archivedAt`; tasks and decisions follow their mainline instead. */
1738
+ const ARCHIVE_KINDS = [
1739
+ "mainline",
1740
+ "issue",
1741
+ "finding",
1742
+ "session"
1743
+ ];
1744
+ const ARCHIVERS = {
1745
+ mainline: setArchived,
1746
+ issue: setIssueArchived,
1747
+ finding: setFindingArchived,
1748
+ session: setSessionArchived
1749
+ };
1750
+ /**
1751
+ * Archive or unarchive several entities of one kind. Each file is written on its own: one that fails, such
1752
+ * as an ID that no longer exists, is reported and the others still change, because a selection in the
1753
+ * interface can go stale while it is open.
1754
+ */
1755
+ function setArchivedMany(root, kind, ids, archived) {
1756
+ const archiver = ARCHIVERS[kind];
1757
+ if (!archiver) throw new WriteError(`kind must be one of: ${ARCHIVE_KINDS.join(", ")}`);
1758
+ const result = {
1759
+ done: [],
1760
+ failed: []
1761
+ };
1762
+ for (const id of new Set(ids)) try {
1763
+ archiver(root, id, archived);
1764
+ result.done.push(id);
1765
+ } catch (error) {
1766
+ result.failed.push({
1767
+ id,
1768
+ error: error instanceof Error ? error.message : String(error)
1769
+ });
1770
+ }
1771
+ return result;
1772
+ }
1773
+ //#endregion
1608
1774
  //#region ../core/dist/migrate.js
1609
1775
  const drop = (o, ...keys) => keys.forEach((k) => delete o[k]);
1610
1776
  const dropNull = (o, ...keys) => keys.forEach((k) => o[k] === null && delete o[k]);
@@ -1842,6 +2008,20 @@ async function syncHost(root, hub, port, options = {}) {
1842
2008
  };
1843
2009
  return { url: `https://${hostName(hub)}` };
1844
2010
  }
2011
+ /**
2012
+ * Remove {hub}.mainflow.localhost when the hub rooted at `root` is gone, so a dangling link does not stop Caddy
2013
+ * from loading every other site. Only a link that points into `root` is removed; the reload failure, if any,
2014
+ * is returned for the caller to log.
2015
+ */
2016
+ function removeHostLink(root, hub, reload = reloadCaddy) {
2017
+ const sites = caddySites();
2018
+ if (!sites) return null;
2019
+ const link = join(sites, `mainflow-${hub}.caddy`);
2020
+ if (!lstatSync(link, { throwIfNoEntry: false })?.isSymbolicLink()) return null;
2021
+ if (!resolve(dirname(link), readlinkSync(link)).startsWith(resolve(root) + "/")) return null;
2022
+ rmSync(link);
2023
+ return reload(sites);
2024
+ }
1845
2025
  /** The macOS app's bundle identifier, from apps/macos/scripts/package.sh. */
1846
2026
  const APP_BUNDLE_ID = "space.carlos.mainflow";
1847
2027
  /** Close the tabs Safari and Chrome opened on this hub's /open route; each browser only when it is running. */
@@ -1874,4 +2054,4 @@ function openInApp(hub, target, closeAfterMs = 150) {
1874
2054
  return true;
1875
2055
  }
1876
2056
  //#endregion
1877
- export { refIndex as $, setSessionStatus as A, mayDecorate as B, updateTask as C, readSession as D, loadSessions as E, sessionBriefing as F, planIssue as G, closeIssue as H, turnReminder as I, setFindingStatus as J, reopenIssue as K, decorateReply as L, startSession as M, transcriptPath as N, setSessionArchived as O, updateAction as P, linksInto as Q, endsWithMarker as R, supersedeDecision as S, ensureSession as T, createFinding as U, appendOps as V, createIssue as W, HubError as X, setIssueArchived as Y, loadHub as Z, setArchived as _, openInApp as a, currentBranch as at, setMainlineStatus as b, migrateHub as c, addRepo as d, MAINLINE_FILE as et, createDecision as f, initHub as g, dropChecklistItem as h, hostName as i, DATA_DIR as it, settleSession as j, setSessionInfo as k, acceptDecision as l, createTask as m, DEFAULT_UI_PORT as n, ConflictError as nt, siteBlock as o, findHubRoot as ot, createMainline as p, setFindingArchived as q, caddySites as r, WriteError as rt, syncHost as s, worktreesOf as st, APP_BUNDLE_ID as t, TASK_FILE as tt, addHub as u, setChecklistItem as v, addAction as w, setMainlineTitle as x, setCriterion as y, headerLine as z };
2057
+ export { HubError as $, readSession as A, decorateReply as B, setMainlineStatus as C, addAction as D, updateTask as E, startSession as F, closeIssue as G, headerLine as H, transcriptPath as I, planIssue as J, createFinding as K, updateAction as L, setSessionInfo as M, setSessionStatus as N, ensureSession as O, settleSession as P, setIssueArchived as Q, sessionBriefing as R, setCriterion as S, supersedeDecision as T, mayDecorate as U, endsWithMarker as V, appendOps as W, setFindingArchived as X, reopenIssue as Y, setFindingStatus as Z, createTask as _, openInApp as a, MAINLINE_FILE as at, setArchived as b, syncHost as c, WriteError as ct, setArchivedMany as d, findHubRoot as dt, loadHub as et, acceptDecision as f, worktreesOf as ft, createMainline as g, createDecision as h, hostName as i, refIndex as it, setSessionArchived as j, loadSessions as k, migrateHub as l, DATA_DIR as lt, addRepo as m, DEFAULT_UI_PORT as n, mainlineEdges as nt, removeHostLink as o, TASK_FILE as ot, addHub as p, createIssue as q, caddySites as r, linksInto as rt, siteBlock as s, ConflictError as st, APP_BUNDLE_ID as t, dependencyGraph as tt, ARCHIVE_KINDS as u, currentBranch as ut, dropChecklistItem as v, setMainlineTitle as w, setChecklistItem as x, initHub as y, turnReminder as z };
package/dist/host.d.ts CHANGED
@@ -21,6 +21,12 @@ export type HostResult = {
21
21
  * different hub of the same name stops here: overwriting it would silently take that hub's host name.
22
22
  */
23
23
  export declare function syncHost(root: string, hub: string, port: number, options?: HostOptions): Promise<HostResult>;
24
+ /**
25
+ * Remove {hub}.mainflow.localhost when the hub rooted at `root` is gone, so a dangling link does not stop Caddy
26
+ * from loading every other site. Only a link that points into `root` is removed; the reload failure, if any,
27
+ * is returned for the caller to log.
28
+ */
29
+ export declare function removeHostLink(root: string, hub: string, reload?: (sites: string) => string | null): string | null;
24
30
  /** The macOS app's bundle identifier, from apps/macos/scripts/package.sh. */
25
31
  export declare const APP_BUNDLE_ID = "space.carlos.mainflow";
26
32
  /**
package/dist/host.js CHANGED
@@ -1,2 +1,2 @@
1
- import { a as openInApp, i as hostName, n as DEFAULT_UI_PORT, o as siteBlock, r as caddySites, s as syncHost, t as APP_BUNDLE_ID } from "./host-ByGN9mGS.js";
2
- export { APP_BUNDLE_ID, DEFAULT_UI_PORT, caddySites, hostName, openInApp, siteBlock, syncHost };
1
+ import { a as openInApp, c as syncHost, i as hostName, n as DEFAULT_UI_PORT, o as removeHostLink, r as caddySites, s as siteBlock, t as APP_BUNDLE_ID } from "./host-Dwf1wLMd.js";
2
+ export { APP_BUNDLE_ID, DEFAULT_UI_PORT, caddySites, hostName, openInApp, removeHostLink, siteBlock, syncHost };
@@ -1,5 +1,5 @@
1
- import { it as DATA_DIR, n as DEFAULT_UI_PORT, rt as WriteError, s as syncHost } from "./host-ByGN9mGS.js";
2
- import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
1
+ import { c as syncHost, ct as WriteError, i as hostName, lt as DATA_DIR, n as DEFAULT_UI_PORT, o as removeHostLink } from "./host-Dwf1wLMd.js";
2
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
3
  import { join } from "node:path";
4
4
  import { spawn, spawnSync } from "node:child_process";
5
5
  import { createServer } from "node:net";
@@ -111,7 +111,7 @@ async function choosePort(hub, candidates, probe = networkProbe) {
111
111
  */
112
112
  function startUiInBackground(root) {
113
113
  const cli = process.argv[1];
114
- if (!cli) return;
114
+ if (!cli || process.env.MAINFLOW_NO_BACKGROUND_UI === "1") return;
115
115
  spawn(process.execPath, [
116
116
  cli,
117
117
  "ui",
@@ -122,6 +122,20 @@ function startUiInBackground(root) {
122
122
  stdio: "ignore"
123
123
  }).on("error", () => {}).unref();
124
124
  }
125
+ /**
126
+ * Call `onGone` once the hub's config.yaml disappears, checking every `everyMs`. A server started for a hub in a
127
+ * directory that is later deleted, such as a test's, then stops instead of holding its port forever. The timer
128
+ * does not keep the process alive by itself.
129
+ */
130
+ function watchHubGone(root, onGone, everyMs = 3e4) {
131
+ const timer = setInterval(() => {
132
+ if (existsSync(join(root, ".mainflow", "config.yaml"))) return;
133
+ clearInterval(timer);
134
+ onGone();
135
+ }, everyMs);
136
+ timer.unref();
137
+ return timer;
138
+ }
125
139
  /** Open a URL in the default browser without waiting for it. */
126
140
  function openUrl(url) {
127
141
  const [command, ...args] = process.platform === "darwin" ? ["open", url] : process.platform === "win32" ? [
@@ -162,13 +176,20 @@ async function launchUi(root, hub, configured, options) {
162
176
  }
163
177
  let server;
164
178
  if (!reuse) {
165
- const { serveUi } = await import("./ui-BY65lR7x.js");
179
+ const { serveUi } = await import("./ui-CLMrfnhR.js");
166
180
  server = await serveUi(root, choice.port);
167
181
  writeUiRecord(root, {
168
182
  port: choice.port,
169
183
  pid: process.pid,
170
184
  version: CLI_VERSION
171
185
  });
186
+ const started = server;
187
+ watchHubGone(root, () => {
188
+ const failure = removeHostLink(root, hub);
189
+ if (failure) log(`! caddy reload failed after removing ${hostName(hub)}: ${failure}`);
190
+ started.close();
191
+ process.exit(0);
192
+ });
172
193
  }
173
194
  const host = await syncHost(root, hub, choice.port, options.host);
174
195
  if (host.url === null) log(`! host name not available: ${host.reason}`);
@@ -181,4 +202,4 @@ async function launchUi(root, hub, configured, options) {
181
202
  };
182
203
  }
183
204
  //#endregion
184
- export { portCandidates as a, CLI_VERSION as c, networkProbe as i, choosePort as n, readUiRecord as o, launchUi as r, startUiInBackground as s, PORT_SPAN as t };
205
+ export { portCandidates as a, watchHubGone as c, networkProbe as i, CLI_VERSION as l, choosePort as n, readUiRecord as o, launchUi as r, startUiInBackground as s, PORT_SPAN as t };
package/dist/launch.d.ts CHANGED
@@ -51,6 +51,12 @@ export declare function choosePort(hub: string, candidates: number[], probe?: Po
51
51
  * pinned version serves its interface.
52
52
  */
53
53
  export declare function startUiInBackground(root: string): void;
54
+ /**
55
+ * Call `onGone` once the hub's config.yaml disappears, checking every `everyMs`. A server started for a hub in a
56
+ * directory that is later deleted, such as a test's, then stops instead of holding its port forever. The timer
57
+ * does not keep the process alive by itself.
58
+ */
59
+ export declare function watchHubGone(root: string, onGone: () => void, everyMs?: number): NodeJS.Timeout;
54
60
  export interface LaunchOptions {
55
61
  port?: string;
56
62
  open: boolean;
package/dist/launch.js CHANGED
@@ -1,2 +1,2 @@
1
- import { a as portCandidates, i as networkProbe, n as choosePort, o as readUiRecord, r as launchUi, s as startUiInBackground, t as PORT_SPAN } from "./launch-B9QrvwZQ.js";
2
- export { PORT_SPAN, choosePort, launchUi, networkProbe, portCandidates, readUiRecord, startUiInBackground };
1
+ import { a as portCandidates, c as watchHubGone, i as networkProbe, n as choosePort, o as readUiRecord, r as launchUi, s as startUiInBackground, t as PORT_SPAN } from "./launch-D5K564tw.js";
2
+ export { PORT_SPAN, choosePort, launchUi, networkProbe, portCandidates, readUiRecord, startUiInBackground, watchHubGone };
@@ -1,6 +1,6 @@
1
- import { $ as refIndex, C as updateTask, D as readSession, E as loadSessions, N as transcriptPath, O as setSessionArchived, Q as linksInto, Y as setIssueArchived, Z as loadHub, _ as setArchived, a as openInApp, b as setMainlineStatus, it as DATA_DIR, nt as ConflictError, q as setFindingArchived, rt as WriteError, v as setChecklistItem, x as setMainlineTitle, y as setCriterion } from "./host-ByGN9mGS.js";
1
+ import { A as readSession, C as setMainlineStatus, E as updateTask, I as transcriptPath, Q as setIssueArchived, S as setCriterion, X as setFindingArchived, a as openInApp, b as setArchived, ct as WriteError, d as setArchivedMany, et as loadHub, it as refIndex, j as setSessionArchived, k as loadSessions, lt as DATA_DIR, nt as mainlineEdges, rt as linksInto, st as ConflictError, tt as dependencyGraph, u as ARCHIVE_KINDS, w as setMainlineTitle, x as setChecklistItem } from "./host-Dwf1wLMd.js";
2
2
  import { t as listProgress } from "./progress-1BfPg2zN.js";
3
- import { c as CLI_VERSION } from "./launch-B9QrvwZQ.js";
3
+ import { l as CLI_VERSION } from "./launch-D5K564tw.js";
4
4
  import { createRequire } from "node:module";
5
5
  import { closeSync, existsSync, openSync, readFileSync, readSync, statSync, watch } from "node:fs";
6
6
  import { basename, dirname, extname, join, normalize, relative, sep } from "node:path";
@@ -226,7 +226,9 @@ function relationsView(hub) {
226
226
  const own = refIndex(hub);
227
227
  const indexes = new Map(hub.remotes.flatMap((r) => r.hub ? [[r.name, refIndex(r.hub)]] : []));
228
228
  const targets = {};
229
- for (const ref of prefixedRefs(hub)) {
229
+ const graph = dependencyGraph(hub);
230
+ const depRefs = graph.edges.flatMap((e) => [e.from, e.to]);
231
+ for (const ref of /* @__PURE__ */ new Set([...prefixedRefs(hub), ...depRefs.filter((r) => r.includes(":"))])) {
230
232
  const colon = ref.indexOf(":");
231
233
  const name = ref.slice(0, colon);
232
234
  const found = name === hub.config.hub ? own.get(ref.slice(colon + 1)) : indexes.get(name)?.get(ref.slice(colon + 1));
@@ -255,7 +257,10 @@ function relationsView(hub) {
255
257
  ...r.unavailable ? { reason: r.unavailable } : {}
256
258
  })),
257
259
  targets,
258
- backlinks
260
+ backlinks,
261
+ deps: graph.edges,
262
+ mainlineDeps: mainlineEdges(graph),
263
+ cycles: graph.cycles
259
264
  };
260
265
  }
261
266
  const pick = (t) => t ? {
@@ -369,6 +374,11 @@ function createApp(root) {
369
374
  problems
370
375
  });
371
376
  });
377
+ app.post("/api/archive", async (c) => {
378
+ const { kind, ids, archived } = await c.req.json();
379
+ if (!ARCHIVE_KINDS.includes(kind) || !Array.isArray(ids)) return c.json({ error: `kind must be one of ${ARCHIVE_KINDS.join(", ")} and ids a list` }, 400);
380
+ return c.json(setArchivedMany(root, kind, ids, archived));
381
+ });
372
382
  app.post("/api/sessions/:id/archive", async (c) => {
373
383
  const { archived } = await c.req.json();
374
384
  return c.json(setSessionArchived(root, c.req.param("id"), archived));
@@ -0,0 +1 @@
1
+ .overlay[data-v-8755e91b]{z-index:50;background:#00000040;justify-content:center;align-items:flex-start;padding-top:12vh;display:flex;position:fixed;inset:0}.palette[data-v-8755e91b]{background:var(--popover);width:min(560px,92vw);color:var(--popover-foreground);border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden;box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}.search[data-v-8755e91b]{border:0;border-bottom:1px solid var(--border);background:0 0;outline:none;width:100%;padding:14px 16px;font-size:15px}.search[data-v-8755e91b]::placeholder{color:var(--muted-foreground)}ul[data-v-8755e91b]{max-height:50vh;margin:0;padding:6px;list-style:none;overflow:auto}li[data-v-8755e91b]{border-radius:var(--radius-md);cursor:pointer;justify-content:space-between;gap:12px;padding:7px 10px;display:flex}li.active[data-v-8755e91b]{background:var(--accent)}.hint[data-v-8755e91b]{color:var(--muted-foreground);white-space:nowrap;font-size:12px}.label[data-v-8755e91b]{text-overflow:ellipsis;white-space:nowrap;align-items:center;gap:8px;min-width:0;display:flex;overflow:hidden}.none[data-v-8755e91b]{color:var(--muted-foreground);cursor:default}.layout[data-v-235a54c2]{grid-template-columns:232px minmax(0,1fr);height:100vh;display:grid}.layout.collapsed[data-v-235a54c2]{grid-template-columns:56px minmax(0,1fr)}.sidebar[data-v-235a54c2]{background:var(--sidebar);border-right:1px solid var(--border);flex-direction:column;gap:2px;padding:12px 8px;display:flex;overflow:auto}.brand[data-v-235a54c2]{justify-content:space-between;align-items:center;gap:8px;padding:2px 4px 10px 8px;font-weight:600;display:flex}.collapsed .brand[data-v-235a54c2]{justify-content:center;padding-left:4px}.icon-toggle[data-v-235a54c2]{border-radius:var(--radius-md);width:28px;height:28px;color:var(--muted-foreground);background:0 0;border:0;place-items:center;display:grid}.icon-toggle[data-v-235a54c2]:hover{background:var(--accent);color:var(--foreground)}.search[data-v-235a54c2]{border:1px solid var(--input);background:var(--background);border-radius:var(--radius-md);height:32px;color:var(--muted-foreground);box-shadow:var(--shadow-xs,0 1px 2px 0 #0000000d);align-items:center;gap:8px;margin:0 0 10px;padding:0 8px;display:flex}.collapsed .search[data-v-235a54c2]{justify-content:center;padding:0}kbd[data-v-235a54c2]{font:11px var(--font-mono);color:var(--muted-foreground)}.nav[data-v-235a54c2]{border-radius:var(--radius-md);height:32px;color:var(--foreground);align-items:center;gap:8px;padding:0 8px;display:flex}.collapsed .nav[data-v-235a54c2]{justify-content:center;padding:0}.nav[data-v-235a54c2]:hover{background:var(--accent)}.nav.current[data-v-235a54c2]{background:var(--accent);font-weight:500}.nav.sub[data-v-235a54c2]{color:var(--muted-foreground);font-size:12px}.nav.sub.current[data-v-235a54c2]{color:var(--foreground)}.nav .count[data-v-235a54c2]{color:var(--muted-foreground);margin-left:auto;font-size:12px}.nav-label[data-v-235a54c2]{color:var(--muted-foreground);padding:14px 8px 4px;font-size:12px;font-weight:500}.main[data-v-235a54c2]{min-width:0;min-height:0;overflow:auto}.error[data-v-235a54c2]{border:1px solid var(--border);border-radius:var(--radius-lg);align-items:center;gap:8px;margin:12px 16px;padding:8px 12px;display:flex}.menu-toggle[data-v-235a54c2]{display:none}@media (width<=720px){.layout[data-v-235a54c2],.layout.collapsed[data-v-235a54c2]{grid-template-rows:auto minmax(0,1fr);grid-template-columns:minmax(0,1fr)}.sidebar[data-v-235a54c2]{border-right:0;border-bottom:1px solid var(--border);padding:8px 12px;position:relative;overflow:visible}.brand[data-v-235a54c2]{padding:0}.collapse-toggle[data-v-235a54c2]{display:none}.menu-toggle[data-v-235a54c2]{display:grid}.sidebar[data-v-235a54c2]>:not(.brand){display:none}.sidebar.menu-open[data-v-235a54c2]>:not(.brand){display:flex}.sidebar.menu-open[data-v-235a54c2]{box-shadow:0 10px 15px -3px #0000001a,0 4px 6px -4px #0000001a}}.peek-panel[data-v-36a42a88]{width:var(--panel-width);max-width:calc(100% - 360px);animation:.2s ease-out peek-in-36a42a88;position:relative}.peek-panel.flex-1[data-v-36a42a88]{width:auto;max-width:none}@keyframes peek-in-36a42a88{0%{opacity:0;transform:translate(8px)}to{opacity:1;transform:none}}@media (prefers-reduced-motion:reduce){.peek-panel[data-v-36a42a88]{animation:none}}@media (width<=1100px){.peek-panel[data-v-36a42a88]{inset-block:0;z-index:20;width:min(var(--panel-width), 100%);max-width:none;position:absolute;right:0}}@media (width<=720px){.peek-panel[data-v-36a42a88]{width:100%}}@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-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--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-duration:initial;--tw-ease:initial;--tw-content:"";--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}}}@layer theme{:root,:host{--font-mono:ui-monospace, "SF Mono", Menlo, monospace;--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--container-lg:32rem;--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);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--tracking-widest:.1em;--leading-relaxed:1.625;--radius-xs:.125rem;--radius-sm:calc(var(--radius) * .6);--radius-md:calc(var(--radius) * .8);--radius-lg:var(--radius);--shadow-xs:0 1px 2px 0 #0000000d;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:-apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang TC", "Noto Sans TC", sans-serif;--default-mono-font-family:ui-monospace, "SF Mono", Menlo, monospace}}@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,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, 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:where(:not(iframe)){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}:root{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark}@media (prefers-color-scheme:dark){:root{--lightningcss-light: ;--lightningcss-dark:initial}}*{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);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,PingFang TC,Noto Sans TC,sans-serif;font-size:13px;line-height:var(--tw-leading,20px);color:var(--foreground);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}}@layer components{[data-peek]{cursor:pointer}[data-peek][aria-current=true]{background:var(--muted)}[data-peek].is-cursor{outline:2px solid var(--ring)}@supports (color:color-mix(in lab, red, red)){[data-peek].is-cursor{outline:2px solid color-mix(in srgb, var(--ring) 50%, transparent)}}[data-peek].is-cursor{outline-offset:-2px}.prose{overflow-wrap:anywhere;font-size:14px;line-height:1.7}.prose>*+*{margin-top:.75em}.prose h1,.prose h2,.prose h3,.prose h4{font-weight:600;line-height:1.4}.prose h1{font-size:18px}.prose h2{margin-top:1.4em;font-size:15px}.prose h3,.prose h4{margin-top:1.2em;font-size:14px}.prose ul{padding-left:1.4em;list-style:outside}.prose ol{padding-left:1.4em;list-style:decimal}.prose li:has(>input[type=checkbox]){margin-left:-1.4em;list-style:none}.prose li>input[type=checkbox]{vertical-align:-2px;width:14px;height:14px;accent-color:var(--primary);margin:0 .5em 0 0}.prose a{text-decoration:underline;-webkit-text-decoration-color:var(--border);-webkit-text-decoration-color:var(--border);-webkit-text-decoration-color:var(--border);text-decoration-color:var(--border);text-underline-offset:4px}.prose a:hover{-webkit-text-decoration-color:var(--foreground);-webkit-text-decoration-color:var(--foreground);-webkit-text-decoration-color:var(--foreground);text-decoration-color:var(--foreground)}.prose code{font-family:var(--font-mono);background:var(--muted);border-radius:var(--radius-sm);padding:1px 4px;font-size:12px}.prose pre{font-family:var(--font-mono);background:var(--muted);font-size:12px}@supports (color:color-mix(in lab, red, red)){.prose pre{background:color-mix(in srgb, var(--muted) 50%, transparent)}}.prose pre{border:1px solid var(--border);border-radius:var(--radius-lg);padding:12px;overflow:auto}.prose pre code{background:0 0;padding:0}.prose table{border-collapse:collapse;font-size:13px}.prose th,.prose td{border-bottom:1px solid var(--border);text-align:left;padding:6px 12px 6px 0}.prose th{color:var(--muted-foreground);font-size:12px;font-weight:500}.prose blockquote{color:var(--muted-foreground);padding-left:1em}}@layer utilities{.\@container\/card-header{container:card-header/inline-size}.\@container{container-type:inline-size}.pointer-events-auto{pointer-events:auto}.pointer-events-none{pointer-events:none}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.inset-0{inset:0}.inset-x-0{inset-inline:0}.inset-y-0{inset-block:0}.top-0{top:0}.top-1\/2{top:50%}.top-2{top:calc(var(--spacing) * 2)}.top-4{top:calc(var(--spacing) * 4)}.top-9{top:calc(var(--spacing) * 9)}.top-\[50\%\]{top:50%}.right-0{right:0}.right-4{right:calc(var(--spacing) * 4)}.bottom-0{bottom:0}.bottom-4{bottom:calc(var(--spacing) * 4)}.-left-1{left:calc(var(--spacing) * -1)}.left-0{left:0}.left-2{left:calc(var(--spacing) * 2)}.left-2\.5{left:calc(var(--spacing) * 2.5)}.left-\[50\%\]{left:50%}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.z-\[5\]{z-index:5}.col-start-2{grid-column-start:2}.row-span-2{grid-row:span 2/span 2}.row-start-1{grid-row-start:1}.m-0{margin:0}.-mx-1{margin-inline:calc(var(--spacing) * -1)}.-mx-2{margin-inline:calc(var(--spacing) * -2)}.mx-auto{margin-inline:auto}.my-1{margin-block:var(--spacing)}.my-8{margin-block:calc(var(--spacing) * 8)}.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)}.mt-auto{margin-top:auto}.mt-px{margin-top:1px}.mr-1{margin-right:var(--spacing)}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-1{margin-bottom:var(--spacing)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.-ml-1{margin-left:calc(var(--spacing) * -1)}.-ml-2{margin-left:calc(var(--spacing) * -2)}.ml-1{margin-left:var(--spacing)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-12{margin-left:calc(var(--spacing) * 12)}.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{display:inline}.inline-flex{display:inline-flex}.inline-grid{display:inline-grid}.table{display:table}.table-caption{display:table-caption}.table-cell{display:table-cell}.table-row{display:table-row}.size-2{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.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-5{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.size-10{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.size-full{width:100%;height:100%}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-4{height:calc(var(--spacing) * 4)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-11{height:calc(var(--spacing) * 11)}.h-\[22px\]{height:22px}.h-\[480px\]{height:480px}.h-\[calc\(100\%-1px\)\]{height:calc(100% - 1px)}.h-auto{height:auto}.h-full{height:100%}.h-px{height:1px}.max-h-\(--reka-dropdown-menu-content-available-height\){max-height:var(--reka-dropdown-menu-content-available-height)}.max-h-80{max-height:calc(var(--spacing) * 80)}.min-h-0{min-height:0}.min-h-4{min-height:calc(var(--spacing) * 4)}.min-h-7{min-height:calc(var(--spacing) * 7)}.min-h-8{min-height:calc(var(--spacing) * 8)}.w-2{width:calc(var(--spacing) * 2)}.w-3\/4{width:75%}.w-4{width:calc(var(--spacing) * 4)}.w-12{width:calc(var(--spacing) * 12)}.w-14{width:calc(var(--spacing) * 14)}.w-16{width:calc(var(--spacing) * 16)}.w-20{width:calc(var(--spacing) * 20)}.w-28{width:calc(var(--spacing) * 28)}.w-40{width:calc(var(--spacing) * 40)}.w-44{width:calc(var(--spacing) * 44)}.w-48{width:calc(var(--spacing) * 48)}.w-56{width:calc(var(--spacing) * 56)}.w-64{width:calc(var(--spacing) * 64)}.w-72{width:calc(var(--spacing) * 72)}.w-fit{width:fit-content}.w-full{width:100%}.w-px{width:1px}.max-w-\(--reka-dropdown-menu-content-available-width\){max-width:var(--reka-dropdown-menu-content-available-width)}.max-w-0{max-width:0}.max-w-5xl{max-width:var(--container-5xl)}.max-w-40{max-width:calc(var(--spacing) * 40)}.max-w-48{max-width:calc(var(--spacing) * 48)}.max-w-56{max-width:calc(var(--spacing) * 56)}.max-w-64{max-width:calc(var(--spacing) * 64)}.max-w-72{max-width:calc(var(--spacing) * 72)}.max-w-\[calc\(100\%-2rem\)\]{max-width:calc(100% - 2rem)}.max-w-full{max-width:100%}.max-w-lg{max-width:var(--container-lg)}.min-w-0{min-width:0}.min-w-7{min-width:calc(var(--spacing) * 7)}.min-w-48{min-width:calc(var(--spacing) * 48)}.min-w-\[8rem\]{min-width:8rem}.flex-1{flex:1}.flex-none{flex:none}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.caption-bottom{caption-side:bottom}.origin-\(--reka-dropdown-menu-content-transform-origin\){transform-origin:var(--reka-dropdown-menu-content-transform-origin)}.translate-x-\[-50\%\]{--tw-translate-x:-50%;translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-y-1\/2{--tw-translate-y:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-\[-50\%\]{--tw-translate-y:-50%;translate:var(--tw-translate-x) var(--tw-translate-y)}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-col-resize{cursor:col-resize}.cursor-default{cursor:default}.cursor-pointer{cursor:pointer}.cursor-text{cursor:text}.auto-rows-min{grid-auto-rows:min-content}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-\[0_1fr\]{grid-template-columns:0 1fr}.grid-cols-\[16px_96px_minmax\(0\,1fr\)\]{grid-template-columns:16px 96px minmax(0,1fr)}.grid-cols-\[auto_1fr\]{grid-template-columns:auto 1fr}.grid-cols-\[repeat\(auto-fill\,minmax\(300px\,1fr\)\)\]{grid-template-columns:repeat(auto-fill,minmax(300px,1fr))}.grid-rows-\[auto_auto\]{grid-template-rows:auto auto}.flex-col{flex-direction:column}.flex-col-reverse{flex-direction:column-reverse}.flex-wrap{flex-wrap:wrap}.place-content-center{place-content:center}.place-items-center{place-items: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}.justify-start{justify-content:flex-start}.gap-0\.5{gap:calc(var(--spacing) * .5)}.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)}.gap-8{gap:calc(var(--spacing) * 8)}.gap-10{gap:calc(var(--spacing) * 10)}.gap-x-2{column-gap:calc(var(--spacing) * 2)}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-x-8{column-gap:calc(var(--spacing) * 8)}.gap-y-0\.5{row-gap:calc(var(--spacing) * .5)}.gap-y-1{row-gap:var(--spacing)}.self-start{align-self:flex-start}.justify-self-end{justify-self:flex-end}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded-\[4px\]{border-radius:4px}.rounded-full{border-radius:2147483647px}.rounded-lg{border-radius:var(--radius)}.rounded-md{border-radius:calc(var(--radius) * .8)}.rounded-none{border-radius:0}.rounded-sm{border-radius:calc(var(--radius) * .6)}.rounded-xl{border-radius:calc(var(--radius) * 1.4)}.rounded-xs{border-radius:var(--radius-xs)}.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-border{border-color:var(--border)}.border-input{border-color:var(--input)}.border-transparent{border-color:#0000}.bg-accent{background-color:var(--accent)}.bg-background{background-color:var(--background)}.bg-black\/80{background-color:#000c}@supports (color:color-mix(in lab, red, red)){.bg-black\/80{background-color:color-mix(in oklab, var(--color-black) 80%, transparent)}}.bg-border{background-color:var(--border)}.bg-card{background-color:var(--card)}.bg-destructive{background-color:var(--destructive)}.bg-muted,.bg-muted\/50{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.bg-muted\/50{background-color:color-mix(in oklab, var(--muted) 50%, transparent)}}.bg-popover{background-color:var(--popover)}.bg-primary,.bg-primary\/20{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.bg-primary\/20{background-color:color-mix(in oklab, var(--primary) 20%, transparent)}}.bg-secondary{background-color:var(--secondary)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.fill-current{fill:currentColor}.p-0{padding:0}.p-0\.5{padding:calc(var(--spacing) * .5)}.p-0\.75{padding:calc(var(--spacing) * .75)}.p-1{padding:var(--spacing)}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.px-0{padding-inline:0}.px-1{padding-inline:var(--spacing)}.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-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-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.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)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-10{padding-block:calc(var(--spacing) * 10)}.py-16{padding-block:calc(var(--spacing) * 16)}.pt-1{padding-top:var(--spacing)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pt-6{padding-top:calc(var(--spacing) * 6)}.pr-0{padding-right:0}.pr-1{padding-right:var(--spacing)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-6{padding-right:calc(var(--spacing) * 6)}.pb-1{padding-bottom:var(--spacing)}.pb-2{padding-bottom:calc(var(--spacing) * 2)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.pb-6{padding-bottom:calc(var(--spacing) * 6)}.pb-8{padding-bottom:calc(var(--spacing) * 8)}.pb-10{padding-bottom:calc(var(--spacing) * 10)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-6{padding-left:calc(var(--spacing) * 6)}.pl-8{padding-left:calc(var(--spacing) * 8)}.pl-12{padding-left:calc(var(--spacing) * 12)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-\[-2px\]{vertical-align:-2px}.align-baseline{vertical-align:baseline}.align-middle{vertical-align:middle}.font-mono{font-family:ui-monospace,SF Mono,Menlo,monospace}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-body{font-size:13px;line-height:var(--tw-leading,20px)}.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-title{font-size:22px;line-height:var(--tw-leading,30px)}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.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)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.text-accent-foreground{color:var(--accent-foreground)}.text-card-foreground{color:var(--card-foreground)}.text-current{color:currentColor}.text-destructive{color:var(--destructive)}.text-foreground{color:var(--foreground)}.text-muted-foreground{color:var(--muted-foreground)}.text-popover-foreground{color:var(--popover-foreground)}.text-primary{color:var(--primary)}.text-primary-foreground{color:var(--primary-foreground)}.text-priority-p0{color:var(--priority-p0)}.text-priority-p1{color:var(--priority-p1)}.text-priority-p3{color:var(--priority-p3)}.text-secondary-foreground{color:var(--secondary-foreground)}.text-status-doing{color:var(--status-doing)}.text-status-done{color:var(--status-done)}.text-status-off{color:var(--status-off)}.text-status-todo{color:var(--status-todo)}.text-status-waiting{color:var(--status-waiting)}.text-warning{color:var(--warning)}.text-white{color:var(--color-white)}.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{text-decoration-line:underline}.decoration-border{-webkit-text-decoration-color:var(--border);-webkit-text-decoration-color:var(--border);-webkit-text-decoration-color:var(--border);text-decoration-color:var(--border)}.underline-offset-4{text-underline-offset:4px}.opacity-0{opacity:0}.opacity-70{opacity:.7}.opacity-100{opacity:1}.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-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px 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)}.ring-1{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + 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)}.ring-ring{--tw-ring-color:var(--ring)}.ring-offset-background{--tw-ring-offset-color:var(--background)}.outline-hidden{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.outline-hidden{outline-offset:2px;outline:2px solid #0000}}.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,)}.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}.duration-200{--tw-duration:.2s;transition-duration:.2s}.duration-\[120ms\]{--tw-duration:.12s;transition-duration:.12s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.select-text{-webkit-user-select:text;user-select:text}.paused{animation-play-state:paused}.running{animation-play-state:running}@media (hover:hover){.group-hover\/copy\:opacity-100:is(:where(.group\/copy):hover *),.group-hover\/row\:opacity-100:is(:where(.group\/row):hover *),.group-hover\/sort\:opacity-100:is(:where(.group\/sort):hover *){opacity:1}}.group-data-\[variant\=line\]\/tabs-list\:bg-transparent:is(:where(.group\/tabs-list)[data-variant=line] *){background-color:#0000}.group-data-\[variant\=line\]\/tabs-list\:text-foreground\/60:is(:where(.group\/tabs-list)[data-variant=line] *){color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.group-data-\[variant\=line\]\/tabs-list\:text-foreground\/60:is(:where(.group\/tabs-list)[data-variant=line] *){color:color-mix(in oklab, var(--foreground) 60%, transparent)}}.selection\:bg-primary ::selection{background-color:var(--primary)}.selection\:bg-primary::selection{background-color:var(--primary)}.selection\:text-primary-foreground ::selection{color:var(--primary-foreground)}.selection\:text-primary-foreground::selection{color:var(--primary-foreground)}.file\:inline-flex::file-selector-button{display:inline-flex}.file\:h-7::file-selector-button{height:calc(var(--spacing) * 7)}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\:text-foreground::file-selector-button{color:var(--foreground)}.placeholder\:text-muted-foreground::placeholder{color:var(--muted-foreground)}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:inset-x-0:after{content:var(--tw-content);inset-inline:0}.after\:-bottom-px:after{content:var(--tw-content);bottom:-1px}.after\:h-0\.5:after{content:var(--tw-content);height:calc(var(--spacing) * .5)}.after\:bg-foreground:after{content:var(--tw-content);background-color:var(--foreground)}.after\:opacity-0:after{content:var(--tw-content);opacity:0}.after\:transition-opacity:after{content:var(--tw-content);transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.focus-within\:opacity-100:focus-within{opacity:1}.focus-within\:ring-3:focus-within{--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-within\:ring-ring\/50:focus-within{--tw-ring-color:var(--ring)}@supports (color:color-mix(in lab, red, red)){.focus-within\:ring-ring\/50:focus-within{--tw-ring-color:color-mix(in oklab, var(--ring) 50%, transparent)}}@media (hover:hover){.hover\:bg-accent:hover,.hover\:bg-accent\/50:hover{background-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-accent\/50:hover{background-color:color-mix(in oklab, var(--accent) 50%, transparent)}}.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-muted\/50:hover{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-muted\/50:hover{background-color:color-mix(in oklab, var(--muted) 50%, 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:hover,.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\:bg-transparent:hover{background-color:#0000}.hover\:text-accent-foreground:hover{color:var(--accent-foreground)}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:underline:hover{text-decoration-line:underline}.hover\:decoration-foreground:hover{-webkit-text-decoration-color:var(--foreground);-webkit-text-decoration-color:var(--foreground);-webkit-text-decoration-color:var(--foreground);text-decoration-color:var(--foreground)}.hover\:opacity-100:hover{opacity:1}.group-data-\[variant\=line\]\/tabs-list\:hover\:text-foreground:is(:where(.group\/tabs-list)[data-variant=line] *):hover{color:var(--foreground)}}.focus\:bg-accent:focus{background-color:var(--accent)}.focus\:text-accent-foreground:focus{color:var(--accent-foreground)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + 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\:ring-ring:focus{--tw-ring-color:var(--ring)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus\:outline-hidden:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.focus\:outline-hidden:focus{outline-offset:2px;outline:2px solid #0000}}.focus-visible\:border-ring:focus-visible{border-color:var(--ring)}.focus-visible\:opacity-100:focus-visible{opacity:1}.focus-visible\:ring-3: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)}}.focus-visible\:outline-1:focus-visible{outline-style:var(--tw-outline-style);outline-width:1px}.focus-visible\:outline-ring:focus-visible{outline-color:var(--ring)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.has-data-\[slot\=card-action\]\:grid-cols-\[1fr_auto\]:has([data-slot=card-action]){grid-template-columns:1fr auto}.has-\[\>svg\]\:grid-cols-\[calc\(var\(--spacing\)\*4\)_1fr\]:has(>svg){grid-template-columns:calc(var(--spacing) * 4) 1fr}.has-\[\>svg\]\:gap-x-3:has(>svg){column-gap:calc(var(--spacing) * 3)}.has-\[\>svg\]\:px-1\.5:has(>svg){padding-inline:calc(var(--spacing) * 1.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-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[inset\]\:pl-8[data-inset]{padding-left:calc(var(--spacing) * 8)}.data-\[side\=bottom\]\:slide-in-from-top-2[data-side=bottom]{--tw-enter-translate-y:calc(2*var(--spacing)*-1)}.data-\[side\=left\]\:slide-in-from-right-2[data-side=left]{--tw-enter-translate-x:calc(2*var(--spacing))}.data-\[side\=right\]\:slide-in-from-left-2[data-side=right]{--tw-enter-translate-x:calc(2*var(--spacing)*-1)}.data-\[side\=top\]\:slide-in-from-bottom-2[data-side=top]{--tw-enter-translate-y:calc(2*var(--spacing))}.data-\[state\=active\]\:bg-background[data-state=active]{background-color:var(--background)}.data-\[state\=active\]\:shadow-sm[data-state=active]{--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)}.group-data-\[variant\=line\]\/tabs-list\:data-\[state\=active\]\:bg-transparent:is(:where(.group\/tabs-list)[data-variant=line] *)[data-state=active]{background-color:#0000}.group-data-\[variant\=line\]\/tabs-list\:data-\[state\=active\]\:text-foreground:is(:where(.group\/tabs-list)[data-variant=line] *)[data-state=active]{color:var(--foreground)}.group-data-\[variant\=line\]\/tabs-list\:data-\[state\=active\]\:shadow-none:is(:where(.group\/tabs-list)[data-variant=line] *)[data-state=active]{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.group-data-\[variant\=line\]\/tabs-list\:data-\[state\=active\]\:after\:opacity-100:is(:where(.group\/tabs-list)[data-variant=line] *)[data-state=active]:after{content:var(--tw-content);opacity:1}.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)}.data-\[state\=closed\]\:animate-out[data-state=closed]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-\[state\=closed\]\:duration-300[data-state=closed]{--tw-duration:.3s;transition-duration:.3s}.data-\[state\=closed\]\:fade-out-0[data-state=closed]{--tw-exit-opacity:0}.data-\[state\=closed\]\:zoom-out-95[data-state=closed]{--tw-exit-scale:.95}.data-\[state\=closed\]\:slide-out-to-bottom[data-state=closed]{--tw-exit-translate-y:100%}.data-\[state\=closed\]\:slide-out-to-left[data-state=closed]{--tw-exit-translate-x:-100%}.data-\[state\=closed\]\:slide-out-to-right[data-state=closed]{--tw-exit-translate-x:100%}.data-\[state\=closed\]\:slide-out-to-top[data-state=closed]{--tw-exit-translate-y:-100%}.data-\[state\=open\]\:animate-in[data-state=open]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none)}.data-\[state\=open\]\:bg-accent[data-state=open]{background-color:var(--accent)}.data-\[state\=open\]\:bg-secondary[data-state=open]{background-color:var(--secondary)}.data-\[state\=open\]\:text-muted-foreground[data-state=open]{color:var(--muted-foreground)}.data-\[state\=open\]\:duration-500[data-state=open]{--tw-duration:.5s;transition-duration:.5s}.data-\[state\=open\]\:fade-in-0[data-state=open]{--tw-enter-opacity:0}.data-\[state\=open\]\:zoom-in-95[data-state=open]{--tw-enter-scale:.95}.data-\[state\=open\]\:slide-in-from-bottom[data-state=open]{--tw-enter-translate-y:100%}.data-\[state\=open\]\:slide-in-from-left[data-state=open]{--tw-enter-translate-x:-100%}.data-\[state\=open\]\:slide-in-from-right[data-state=open]{--tw-enter-translate-x:100%}.data-\[state\=open\]\:slide-in-from-top[data-state=open]{--tw-enter-translate-y:-100%}.data-\[state\=selected\]\:bg-muted[data-state=selected]{background-color:var(--muted)}.data-\[variant\=destructive\]\:text-destructive[data-variant=destructive]{color:var(--destructive)}.data-\[variant\=destructive\]\:focus\:bg-destructive\/10[data-variant=destructive]:focus{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.data-\[variant\=destructive\]\:focus\:bg-destructive\/10[data-variant=destructive]:focus{background-color:color-mix(in oklab, var(--destructive) 10%, transparent)}}.data-\[variant\=destructive\]\:focus\:text-destructive[data-variant=destructive]:focus{color:var(--destructive)}@media not all and (width>=1100px){.max-\[1100px\]\: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)}}@media (width>=900px){.min-\[900px\]\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (width>=1100px){.min-\[1100px\]\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (width>=40rem){.sm\:max-w-lg{max-width:var(--container-lg)}.sm\:max-w-sm{max-width:var(--container-sm)}.sm\:flex-row{flex-direction:row}.sm\:justify-end{justify-content:flex-end}.sm\:rounded-lg{border-radius:var(--radius)}.sm\:text-left{text-align:left}}@media (width>=48rem){.md\:w-full{width:100%}.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}@media (width>=64rem){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (width>=80rem){.xl\:inline{display:inline}}@container not (width>=48rem){.\@max-3xl\:hidden{display:none}}@media (prefers-color-scheme:dark){.dark\:border-input{border-color:var(--input)}.dark\:bg-destructive\/60{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:bg-destructive\/60{background-color:color-mix(in oklab, var(--destructive) 60%, transparent)}}.dark\:bg-input\/30{background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\:bg-input\/30{background-color:color-mix(in oklab, var(--input) 30%, transparent)}}.dark\:text-muted-foreground{color:var(--muted-foreground)}@media (hover:hover){.dark\:hover\:bg-accent\/50:hover{background-color:var(--accent)}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-accent\/50:hover{background-color:color-mix(in oklab, var(--accent) 50%, transparent)}}.dark\:hover\:bg-input\/50:hover{background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-input\/50:hover{background-color:color-mix(in oklab, var(--input) 50%, transparent)}}}.dark\:focus-visible\:ring-destructive\/40:focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:focus-visible\:ring-destructive\/40:focus-visible{--tw-ring-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.dark\:aria-invalid\:ring-destructive\/40[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:aria-invalid\:ring-destructive\/40[aria-invalid=true]{--tw-ring-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.dark\:data-\[state\=active\]\:border-input[data-state=active]{border-color:var(--input)}.dark\:data-\[state\=active\]\:bg-input\/30[data-state=active]{background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\:data-\[state\=active\]\:bg-input\/30[data-state=active]{background-color:color-mix(in oklab, var(--input) 30%, transparent)}}.dark\:data-\[state\=active\]\:text-foreground[data-state=active]{color:var(--foreground)}.dark\:group-data-\[variant\=line\]\/tabs-list\:data-\[state\=active\]\:border-transparent:is(:where(.group\/tabs-list)[data-variant=line] *)[data-state=active]{border-color:#0000}.dark\:group-data-\[variant\=line\]\/tabs-list\:data-\[state\=active\]\:bg-transparent:is(:where(.group\/tabs-list)[data-variant=line] *)[data-state=active]{background-color:#0000}.dark\:data-\[variant\=destructive\]\:focus\:bg-destructive\/20[data-variant=destructive]:focus{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:data-\[variant\=destructive\]\:focus\:bg-destructive\/20[data-variant=destructive]:focus{background-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}}.\[\&_p\]\:leading-relaxed p{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-3 svg:not([class*=size-]){width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4 svg:not([class*=size-]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\:not\(\[class\*\=\'text-\'\]\)\]\:text-muted-foreground svg:not([class*=text-]){color:var(--muted-foreground)}.\[\&_tr\]\:border-b tr{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-style:var(--tw-border-style);border-width:0}.\[\&_tr\:last-child\]\:border-b tr:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:0}.\[\.border-b\]\:pb-4.border-b{padding-bottom:calc(var(--spacing) * 4)}.\[\.border-t\]\:pt-4.border-t{padding-top:calc(var(--spacing) * 4)}:is(.\*\:\[\[role\=checkbox\]\]\:translate-y-0\.5>*)[role=checkbox]{--tw-translate-y:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}:is(.data-\[variant\=destructive\]\:\*\:\[svg\]\:text-destructive\![data-variant=destructive]>*):is(svg){color:var(--destructive)!important}.\[\&\>svg\]\:pointer-events-none>svg{pointer-events:none}.\[\&\>svg\]\:size-3>svg{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.\[\&\>svg\]\:size-3\.5>svg{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.\[\&\>svg\]\:size-4>svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&\>svg\]\:translate-y-0\.5>svg{--tw-translate-y:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}.\[\&\>svg\]\:text-current>svg{color:currentColor}.\[\&\>svg\]\:text-destructive>svg{color:var(--destructive)}.\[\&\>svg\]\:text-warning>svg{color:var(--warning)}.\[\&\>tr\]\:last\:border-b-0>tr:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}@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)}}}@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{--mf-p-white:#fff;--mf-p-grey-50:#fcfcfc;--mf-p-grey-100:#f9f9f9;--mf-p-grey-200:#f0f0f0;--mf-p-grey-300:#e8e8e8;--mf-p-grey-700:#bbb;--mf-p-grey-800:#8d8d8d;--mf-p-grey-1000:#646464;--mf-p-grey-1100:#202020;--mf-p-brand:#d9a100;--mf-p-blue-700:#5eb0ef;--mf-p-blue-900:#0880ea;--mf-p-green-700:#5bb98c;--mf-p-green-900:#299764;--mf-p-orange-700:#ed8a5c;--mf-p-orange-900:#ed5f00;--mf-p-yellow-1000:#915930;--mf-p-red-800:#e5484d;--mf-p-red-1000:#c62a2f}@media (prefers-color-scheme:dark){:root{--mf-p-grey-50:#111;--mf-p-grey-100:#191919;--mf-p-grey-200:#222;--mf-p-grey-300:#2a2a2a;--mf-p-grey-700:#606060;--mf-p-grey-800:#6e6e6e;--mf-p-grey-1000:#b4b4b4;--mf-p-grey-1100:#eee;--mf-p-blue-700:#1276e2;--mf-p-blue-900:#3cabff;--mf-p-green-700:#2c8c5e;--mf-p-green-900:#35b979;--mf-p-orange-700:#c36522;--mf-p-orange-900:#ff802b;--mf-p-yellow-1000:#ffcc4d;--mf-p-red-1000:#ff8589}}:root{--radius:.625rem;--background:var(--mf-p-white);--foreground:var(--mf-p-grey-1100);--card:var(--mf-p-white);--card-foreground:var(--foreground);--popover:var(--mf-p-white);--popover-foreground:var(--foreground);--primary:var(--mf-p-grey-1100);--primary-foreground:var(--mf-p-white);--secondary:var(--mf-p-grey-200);--secondary-foreground:var(--foreground);--muted:var(--mf-p-grey-200);--muted-foreground:var(--mf-p-grey-1000);--accent:var(--mf-p-grey-200);--accent-foreground:var(--foreground);--destructive:var(--mf-p-red-1000);--border:var(--mf-p-grey-300);--input:var(--mf-p-grey-300);--ring:var(--mf-p-grey-800);--sidebar:var(--mf-p-grey-100);--brand:var(--mf-p-brand);--warning:var(--mf-p-yellow-1000);--status-todo:var(--mf-p-grey-800);--status-doing:var(--mf-p-blue-900);--status-waiting:var(--mf-p-orange-900);--status-done:var(--mf-p-green-900);--status-off:var(--mf-p-grey-700);--priority-p0:var(--mf-p-red-800);--priority-p1:var(--mf-p-orange-900);--priority-p2:var(--mf-p-blue-900);--priority-p3:var(--mf-p-grey-800)}@media (prefers-color-scheme:dark){:root{--background:var(--mf-p-grey-50);--card:var(--mf-p-grey-100);--popover:var(--mf-p-grey-100);--primary-foreground:var(--mf-p-grey-50);--status-doing:var(--mf-p-blue-700);--status-waiting:var(--mf-p-orange-700);--status-done:var(--mf-p-green-700)}}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@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-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0));filter:blur(var(--tw-enter-blur,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0));filter:blur(var(--tw-exit-blur,0))}}