@fapost/jig-ui 0.3.0-next.42 → 0.3.0-next.44

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/http/app.js CHANGED
@@ -67,6 +67,14 @@ function written(c, w) {
67
67
  return refuse(c, 404, w.code, 'This project has no live task with this id.');
68
68
  return refuse(c, 422, w.code, 'Jig refused the change.');
69
69
  }
70
+ /** An upgrade refused before it ran, in the API's form: under way already, none to make, or Jig's code. */
71
+ function upgradeRefused(c, code) {
72
+ if (code === 'running')
73
+ return refuse(c, 409, code, 'An upgrade of this project is under way.');
74
+ if (code === 'not-found')
75
+ return refuse(c, 404, code, 'This project shows no upgrade of Jig to make.');
76
+ return refuse(c, 422, code, 'Jig refused the upgrade.');
77
+ }
70
78
  /**
71
79
  * The API, chained so that its type carries every route's answers: the page derives its types
72
80
  * from `AppType` and never declares them a second time.
@@ -164,6 +172,33 @@ function apiRoutes(source, version) {
164
172
  return refuse(c, 409, w.code, 'The project has a task with this id, maybe a finished one.');
165
173
  }
166
174
  return written(c, w);
175
+ })
176
+ // A dry run: what upgrading the project's Jig would do, changing nothing.
177
+ .post('/api/projects/:id/upgrade/plan', async (c) => {
178
+ const planned = await source.planUpgrade(c.req.param('id'));
179
+ if (planned === undefined)
180
+ return refuse(c, 404, 'not-connected', 'No connected project has this id.');
181
+ if (planned.state === 'planned')
182
+ return c.json({ plan: planned.plan }, 200);
183
+ if (planned.state !== 'refused')
184
+ return c.json({ project: planned }, 200);
185
+ return upgradeRefused(c, planned.code);
186
+ })
187
+ // Answered at once: the upgrade runs on in the server, and the workspace shows it and then what it came to.
188
+ .post('/api/projects/:id/upgrade', async (c) => {
189
+ const started = await source.upgrade(c.req.param('id'));
190
+ if (started === undefined)
191
+ return refuse(c, 404, 'not-connected', 'No connected project has this id.');
192
+ if (started.state === 'started')
193
+ return c.json({ started: true }, 202);
194
+ if (started.state !== 'refused')
195
+ return c.json({ project: started }, 200);
196
+ return upgradeRefused(c, started.code);
197
+ })
198
+ .delete('/api/projects/:id/upgrade', async (c) => {
199
+ if (!(await source.dismissUpgrade(c.req.param('id'))))
200
+ return refuse(c, 404, 'not-connected', 'No connected project has this id.');
201
+ return c.body(null, 204);
167
202
  })
168
203
  .post('/api/projects', validator('json', (body) => ({
169
204
  path: absolute(body?.path),
@@ -177,9 +212,11 @@ function apiRoutes(source, version) {
177
212
  return result.created ? c.json({ project: result.project }, 201) : c.json({ project: result.project }, 200);
178
213
  })
179
214
  .delete('/api/projects/:id', async (c) => {
180
- if (!(await source.disconnect(c.req.param('id')))) {
215
+ const disconnected = await source.disconnect(c.req.param('id'));
216
+ if (disconnected === 'upgrading')
217
+ return refuse(c, 409, 'upgrading', 'The project is being upgraded; disconnect it once that ends.');
218
+ if (!disconnected)
181
219
  return refuse(c, 404, 'not-connected', 'No connected project has this id.');
182
- }
183
220
  return c.body(null, 204);
184
221
  })
185
222
  // A signal, not data: the page re-fetches what it shows (adr-20261014-project-source-port-keeps-hosting-open).
@@ -10,6 +10,9 @@ export const MIN_JIG_VERSION = '0.31.0';
10
10
  export const RESUME_JIG_VERSION = '0.35.0';
11
11
  const SCRIPT = '.ai/scripts/jig';
12
12
  const TIMEOUT_MS = 10_000;
13
+ /** A dry run compares every framework file; a real upgrade at `agent.git: merge` also waits for CI. */
14
+ const PLAN_TIMEOUT_MS = 60_000;
15
+ const UPGRADE_TIMEOUT_MS = 30 * 60_000;
13
16
  /** The directory whose changes may change what Jig reports: the main checkout's `.ai/`. */
14
17
  export const watchDir = (root) => join(root, '.ai');
15
18
  /**
@@ -43,15 +46,15 @@ async function bash(platform) {
43
46
  * by `BASH_SOURCE`) rather than `exec` it: Git bash's `exec` starts a second bash and waits for it, and every run took
44
47
  * half as long again (CI, task `conflict-display`).
45
48
  */
46
- async function jig(root, args, platform) {
49
+ async function jig(root, args, platform, timeout = TIMEOUT_MS) {
47
50
  const argv = [SCRIPT, ...args];
48
51
  const { stdout } = platform === 'win32'
49
52
  ? await run(await bash(platform), ['-c', `. ${argv.map((_, i) => `"$JIG_UI_ARG_${i}"`).join(' ')}`], {
50
53
  cwd: root,
51
- timeout: TIMEOUT_MS,
54
+ timeout,
52
55
  env: { ...process.env, ...Object.fromEntries(argv.map((arg, i) => [`JIG_UI_ARG_${i}`, arg])) },
53
56
  })
54
- : await run(await bash(platform), argv, { cwd: root, timeout: TIMEOUT_MS });
57
+ : await run(await bash(platform), argv, { cwd: root, timeout });
55
58
  return stdout;
56
59
  }
57
60
  /**
@@ -66,14 +69,24 @@ export async function jigVersion(root, platform = process.platform) {
66
69
  throw new Error('jig --version did not print a version');
67
70
  return match[1];
68
71
  }
69
- /** Why a JSON read was refused: Jig's failure code (`failed` for one this Jig UI does not know, or a shape it cannot read). */
72
+ /**
73
+ * Why a JSON read was refused: Jig's failure code (`failed` for one this Jig UI does not know, or a shape it cannot
74
+ * read), and for `upgrade-blocked` every reason Jig gave, without a path.
75
+ */
70
76
  export class JigRefusal extends Error {
71
77
  code;
72
- constructor(code) {
78
+ reasons;
79
+ constructor(code, reasons = []) {
73
80
  super(`jig refused: ${code}`);
74
81
  this.code = code;
82
+ this.reasons = reasons;
75
83
  }
76
84
  }
85
+ /**
86
+ * Jig's text for a person with every absolute path in it cut out: no path reaches the page. Jig 0.35.0 names only
87
+ * paths under the project, relative to it, since it runs in the project's root; this keeps a later one from leaking.
88
+ */
89
+ export const withoutPaths = (text) => text.replace(/(?<=^|[\s(`'"])(?:[A-Za-z]:)?[\\/][^\s)`'"]*/g, '…');
77
90
  const CODES = new Set([
78
91
  'usage',
79
92
  'not-a-repository',
@@ -84,6 +97,7 @@ const CODES = new Set([
84
97
  'not-paused',
85
98
  'wrong-checkout',
86
99
  'stash-conflict',
100
+ 'upgrade-blocked',
87
101
  'failed',
88
102
  ]);
89
103
  /** Jig answered in a shape this Jig UI does not read: a Jig newer than the contract its tests pin. */
@@ -98,10 +112,10 @@ const isObject = (v) => typeof v === 'object' && v !== null && !Array.isArray(v)
98
112
  * JigRefusal, as does output that is no JSON at all (a crash); an envelope of another shape throws
99
113
  * JigShapeError.
100
114
  */
101
- async function readJson(root, args, platform) {
115
+ async function readJson(root, args, platform, timeout) {
102
116
  let stdout;
103
117
  try {
104
- stdout = await jig(root, [...args, '--json'], platform);
118
+ stdout = await jig(root, [...args, '--json'], platform, timeout);
105
119
  }
106
120
  catch (error) {
107
121
  // A refusal is an envelope too, printed before the non-zero exit.
@@ -117,7 +131,12 @@ async function readJson(root, args, platform) {
117
131
  if (!isObject(envelope) || envelope.schema !== 1 || typeof envelope.revision !== 'number')
118
132
  throw new JigShapeError();
119
133
  if (isObject(envelope.error)) {
120
- const code = envelope.error.code;
134
+ const { code, message } = envelope.error;
135
+ if (code === 'upgrade-blocked' && typeof message === 'string') {
136
+ // `upgrade: nothing was changed:` and then a reason a line, as ` - <reason>`.
137
+ const reasons = message.split('\n').flatMap((line) => (line.startsWith(' - ') ? [withoutPaths(line.slice(4))] : []));
138
+ throw new JigRefusal(code, reasons);
139
+ }
121
140
  throw new JigRefusal(typeof code === 'string' && CODES.has(code) ? code : 'failed');
122
141
  }
123
142
  if (!isObject(envelope.data))
@@ -138,7 +157,8 @@ const text = z.string();
138
157
  const maybe = z.string().nullable();
139
158
  const count = z.int().nonnegative();
140
159
  /** Something that needs the person, as `jig status --json` reports it; a kind this Jig UI does not know is shown by its texts. */
141
- const Attention = z.object({
160
+ const Attention = z
161
+ .object({
142
162
  kind: text,
143
163
  subject: z.object({ type: text, id: maybe }),
144
164
  tasks: z.array(text),
@@ -146,7 +166,14 @@ const Attention = z.object({
146
166
  detail: maybe,
147
167
  todo: text,
148
168
  url: maybe,
149
- });
169
+ // The project's Jig and the machine's. The one field left out: only `upgrade-available` carries it
170
+ // (Jig 0.34.0), and that item never without it.
171
+ versions: z
172
+ .object({ from: text, to: text })
173
+ .nullish()
174
+ .transform((v) => v ?? null),
175
+ })
176
+ .refine((a) => a.kind !== 'upgrade-available' || a.versions !== null);
150
177
  const Status = z.object({
151
178
  attention: z.array(Attention),
152
179
  housekeeping: z.object({ stale: z.boolean() }).nullable(),
@@ -355,3 +382,51 @@ export async function resumeTask(root, task, revision, platform = process.platfo
355
382
  export async function fileTask(root, id, goal, platform = process.platform) {
356
383
  await readJson(root, ['task', 'new', id, '--goal', goal], platform);
357
384
  }
385
+ /** What `jig upgrade --json` did, or for `--dry-run` would do (Jig 0.34.0): Jig's texts without a path. */
386
+ const Upgrade = z
387
+ .object({
388
+ mode: text,
389
+ from: maybe,
390
+ to: maybe,
391
+ outcome: text,
392
+ git: z
393
+ .object({
394
+ level: text,
395
+ branch: maybe,
396
+ commit: maybe,
397
+ pushed: z.boolean(),
398
+ pull_request: maybe,
399
+ merged: z.boolean(),
400
+ })
401
+ .nullable(),
402
+ manual_steps: z.array(text),
403
+ would_stop: z.array(text),
404
+ })
405
+ .transform(({ git, manual_steps, would_stop, ...rest }) => ({
406
+ ...rest,
407
+ git: git && {
408
+ level: git.level,
409
+ branch: git.branch,
410
+ commit: git.commit,
411
+ pushed: git.pushed,
412
+ pullRequest: git.pull_request,
413
+ merged: git.merged,
414
+ },
415
+ manualSteps: manual_steps.map(withoutPaths),
416
+ wouldStop: would_stop.map(withoutPaths),
417
+ }));
418
+ /**
419
+ * What upgrading the project's Jig would do (`jig upgrade --dry-run`), changing nothing: the versions, the steps the
420
+ * release asks for by hand and every reason a real run would not start.
421
+ */
422
+ export async function planUpgrade(root, platform = process.platform) {
423
+ return parsed(Upgrade, (await readJson(root, ['upgrade', '--dry-run'], platform, PLAN_TIMEOUT_MS)).data);
424
+ }
425
+ /**
426
+ * Upgrades the project's Jig (`jig upgrade`) in its main checkout, on a branch, as far as its `agent.git` lets Jig take
427
+ * it — at `merge` Jig waits for CI first. Refused as `upgrade-blocked`, with its reasons, before anything is touched;
428
+ * any other refusal, a failed push or pull request after the commit included, is `failed`.
429
+ */
430
+ export async function runUpgrade(root, platform = process.platform) {
431
+ return parsed(Upgrade, (await readJson(root, ['upgrade'], platform, UPGRADE_TIMEOUT_MS)).data);
432
+ }
@@ -1,5 +1,5 @@
1
1
  import { existsSync } from 'node:fs';
2
- import { cancelPause, fileTask, JigRefusal, JigShapeError, jigVersion, MIN_JIG_VERSION, moveInQueue, readQueue, readSpecs, readStatus, readTasks, requestPause, RESUME_JIG_VERSION, resumeTask, setPriority, supports, watchDir, writtenByReads, } from '../jig/client.js';
2
+ import { cancelPause, fileTask, JigRefusal, JigShapeError, jigVersion, MIN_JIG_VERSION, moveInQueue, planUpgrade, readQueue, readSpecs, readStatus, readTasks, requestPause, RESUME_JIG_VERSION, resumeTask, runUpgrade, setPriority, supports, watchDir, writtenByReads, } from '../jig/client.js';
3
3
  import { addProject, readProjects, removeProject } from '../registry/projects.js';
4
4
  import { watchTree } from '../watch/watch.js';
5
5
  import { mainCheckout } from './checkout.js';
@@ -136,6 +136,8 @@ async function readProject(project) {
136
136
  revision,
137
137
  };
138
138
  }
139
+ /** The version Jig's `upgrade-available` item in a read names for this machine; none without the item. */
140
+ const upgradeTo = (read) => read.view.state === 'ready' ? (read.view.attention.find((a) => a.kind === 'upgrade-available')?.versions?.to ?? undefined) : undefined;
139
141
  /** A read that may have caught Jig mid-write: worth one more try before it is believed. */
140
142
  const torn = (read) => read.view.state === 'unreadable' || read.view.state === 'incompatible';
141
143
  /**
@@ -145,6 +147,13 @@ const torn = (read) => read.view.state === 'unreadable' || read.view.state === '
145
147
  */
146
148
  export function localSource(configDir, { rescanMs = 60_000, quietMs, maxWaitMs } = {}) {
147
149
  const entries = new Map();
150
+ /** The last upgrade start or disconnect: they run one at a time, each checking what the one before changed. */
151
+ let changing = Promise.resolve();
152
+ function oneAtATime(change) {
153
+ const done = changing.then(change);
154
+ changing = done.catch(() => undefined);
155
+ return done;
156
+ }
148
157
  const listeners = new Set();
149
158
  let rescan;
150
159
  /** Counts the times following started; a read that finishes after a stop belongs to none. */
@@ -155,7 +164,7 @@ export function localSource(configDir, { rescanMs = 60_000, quietMs, maxWaitMs }
155
164
  const entryOf = (project) => {
156
165
  let entry = entries.get(project.id);
157
166
  if (!entry)
158
- entries.set(project.id, (entry = { project, held: false, dirty: false, news: false }));
167
+ entries.set(project.id, (entry = { project, held: false, dirty: false, news: false, writes: new Set() }));
159
168
  return entry;
160
169
  };
161
170
  /** Keeps what was shown over one torn read; otherwise the read is what the project shows. */
@@ -176,6 +185,9 @@ export function localSource(configDir, { rescanMs = 60_000, quietMs, maxWaitMs }
176
185
  */
177
186
  function refresh(entry, news = false) {
178
187
  entry.news ||= news;
188
+ // Jig replaces its own scripts while it upgrades: a read could run one half placed. The run reads once it ends.
189
+ if (entry.upgrade?.state === 'running' && entry.shown)
190
+ return Promise.resolve();
179
191
  if (entry.reading) {
180
192
  entry.dirty = true;
181
193
  return entry.reading;
@@ -203,6 +215,43 @@ export function localSource(configDir, { rescanMs = 60_000, quietMs, maxWaitMs }
203
215
  for (const listener of listeners)
204
216
  listener(change);
205
217
  }
218
+ /** Tells the listeners that what the project shows beyond Jig's read — its upgrade — changed. */
219
+ function signalUpgrade(entry) {
220
+ if (following() && entries.get(entry.project.id) === entry)
221
+ signal({ id: entry.project.id, revision: entry.shown?.revision ?? null });
222
+ }
223
+ /** The project's last read when an upgrade may start from it: ready and naming a version to upgrade to. */
224
+ async function upgradable(id) {
225
+ const project = (await readProjects(configDir)).find((p) => p.id === id);
226
+ if (!project)
227
+ return undefined;
228
+ const read = await shown(project);
229
+ if (read.view.state !== 'ready')
230
+ return read.view;
231
+ const entry = entryOf(project);
232
+ if (entry.upgrade?.state === 'running')
233
+ return { state: 'refused', code: 'running' };
234
+ const to = upgradeTo(read);
235
+ return to === undefined ? { state: 'refused', code: 'not-found' } : { entry, to };
236
+ }
237
+ /** Runs the upgrade to its end, then keeps what it came to and reads the project again. */
238
+ async function upgrading(entry) {
239
+ // A read or a write under way runs Jig in the same checkout.
240
+ await Promise.allSettled([entry.reading, ...entry.writes]);
241
+ let run;
242
+ try {
243
+ run = { state: 'done', at: '', upgrade: await runUpgrade(entry.project.path) };
244
+ }
245
+ catch (error) {
246
+ run =
247
+ error instanceof JigRefusal
248
+ ? { state: 'refused', at: '', code: error.code, reasons: error.reasons }
249
+ : { state: 'refused', at: '', code: 'failed', reasons: [] };
250
+ }
251
+ entry.upgrade = { ...run, at: new Date().toISOString() };
252
+ await refresh(entry);
253
+ signalUpgrade(entry);
254
+ }
206
255
  /** What the project shows: from the watch while following, read through Jig otherwise. */
207
256
  async function shown(project) {
208
257
  const entry = entryOf(project);
@@ -258,7 +307,9 @@ export function localSource(configDir, { rescanMs = 60_000, quietMs, maxWaitMs }
258
307
  for (const entry of entries.values()) {
259
308
  entry.watch?.close();
260
309
  entry.watch = undefined;
261
- entry.shown = undefined;
310
+ // A project being upgraded keeps its read: it is read again only once the upgrade ends.
311
+ if (entry.upgrade?.state !== 'running')
312
+ entry.shown = undefined;
262
313
  entry.held = false;
263
314
  }
264
315
  }
@@ -276,20 +327,29 @@ export function localSource(configDir, { rescanMs = 60_000, quietMs, maxWaitMs }
276
327
  return tasks;
277
328
  if (!taskIds.every((t) => tasks.tasks.some((live) => live.id === t)))
278
329
  return { state: 'refused', code: 'not-found' };
330
+ const entry = entryOf(project);
331
+ // Jig replaces its own scripts while it upgrades: the write waits for the person to try again.
332
+ if (entry.upgrade?.state === 'running')
333
+ return { state: 'refused', code: 'upgrading' };
279
334
  let written = { state: 'written' };
335
+ const run = write(project.path);
336
+ entry.writes.add(run);
280
337
  try {
281
- await write(project.path);
338
+ await run;
282
339
  }
283
340
  catch (error) {
284
341
  // Only the code goes on: Jig's message may name a path.
285
342
  written = { state: 'refused', code: error instanceof JigRefusal ? error.code : 'failed' };
286
343
  }
287
- await refresh(entryOf(project));
344
+ finally {
345
+ entry.writes.delete(run);
346
+ }
347
+ await refresh(entry);
288
348
  return written;
289
349
  }
290
350
  return {
291
351
  async workspace() {
292
- return Promise.all((await readProjects(configDir)).map(async (p) => (await shown(p)).view));
352
+ return Promise.all((await readProjects(configDir)).map(async (p) => ({ ...(await shown(p)).view, upgrade: entryOf(p).upgrade ?? null })));
293
353
  },
294
354
  async connect(path) {
295
355
  const found = await connectable(path);
@@ -342,16 +402,55 @@ export function localSource(configDir, { rescanMs = 60_000, quietMs, maxWaitMs }
342
402
  // A new id names no live task: Jig itself refuses a taken one.
343
403
  return writing(id, [], (root) => fileTask(root, taskId, goal));
344
404
  },
345
- async disconnect(id) {
346
- if (!(await removeProject(configDir, id)))
405
+ async planUpgrade(id) {
406
+ const found = await upgradable(id);
407
+ if (!found || !('entry' in found))
408
+ return found;
409
+ try {
410
+ return { state: 'planned', plan: await planUpgrade(found.entry.project.path) };
411
+ }
412
+ catch (error) {
413
+ return { state: 'refused', code: error instanceof JigRefusal ? error.code : 'failed' };
414
+ }
415
+ },
416
+ upgrade(id) {
417
+ // Two starts at once make one run; a disconnect sent with a start finds the run, or the start no project.
418
+ return oneAtATime(async () => {
419
+ const found = await upgradable(id);
420
+ if (!found || !('entry' in found))
421
+ return found;
422
+ found.entry.upgrade = { state: 'running', since: new Date().toISOString(), to: found.to };
423
+ signalUpgrade(found.entry);
424
+ void upgrading(found.entry);
425
+ return { state: 'started' };
426
+ });
427
+ },
428
+ async dismissUpgrade(id) {
429
+ const project = (await readProjects(configDir)).find((p) => p.id === id);
430
+ if (!project)
347
431
  return false;
348
- entries.get(id)?.watch?.close();
349
- entries.delete(id);
350
- known?.delete(id); // connected again before the next sweep, it is news again
351
- if (following())
352
- signal({ id, revision: null });
432
+ const entry = entryOf(project);
433
+ if (entry.upgrade && entry.upgrade.state !== 'running') {
434
+ entry.upgrade = undefined;
435
+ signalUpgrade(entry);
436
+ }
353
437
  return true;
354
438
  },
439
+ disconnect(id) {
440
+ return oneAtATime(async () => {
441
+ // The run is the entry's: without it a project connected again would be read, and upgraded, meanwhile.
442
+ if (entries.get(id)?.upgrade?.state === 'running')
443
+ return 'upgrading';
444
+ if (!(await removeProject(configDir, id)))
445
+ return false;
446
+ entries.get(id)?.watch?.close();
447
+ entries.delete(id);
448
+ known?.delete(id); // connected again before the next sweep, it is news again
449
+ if (following())
450
+ signal({ id, revision: null });
451
+ return true;
452
+ });
453
+ },
355
454
  subscribe(listener) {
356
455
  listeners.add(listener);
357
456
  if (!following())
@@ -0,0 +1 @@
1
+ import{$ as e,A as t,B as n,C as r,D as i,E as a,F as o,G as s,H as c,I as l,J as ee,K as u,L as te,M as d,N as f,O as ne,P as p,Q as m,R as re,S as ie,T as h,U as g,V as _,W as v,X as y,Y as b,Z as x,_ as ae,a as S,b as C,c as oe,d as w,et as T,f as se,g as E,h as D,i as ce,j as le,k as ue,l as de,m as fe,n as O,nt as pe,o as me,p as k,q as A,r as j,rt as M,s as he,t as ge,tt as N,u as _e,v as ve,w as P,x as F,y as ye,z as I}from"./index-DhOCL5uI.js";var be=A({__name:`BaseSeparator`,props:{orientation:{type:String,required:!1,default:`horizontal`},decorative:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(t){let r=t,i=[`horizontal`,`vertical`];function a(e){return i.includes(e)}let o=n(()=>a(r.orientation)?r.orientation:`horizontal`),s=n(()=>o.value===`vertical`?r.orientation:void 0),l=n(()=>r.decorative?{role:`none`}:{"aria-orientation":s.value,role:`separator`});return(n,r)=>(y(),c(T(f),b({as:t.as,"as-child":t.asChild,"data-orientation":o.value},l.value),{default:e(()=>[m(n.$slots,`default`)]),_:3},16,[`as`,`as-child`,`data-orientation`]))}}),xe=A({__name:`Separator`,props:{orientation:{type:String,required:!1,default:`horizontal`},decorative:{type:Boolean,required:!1},asChild:{type:Boolean,required:!1},as:{type:null,required:!1}},setup(t){let n=t;return(t,r)=>(y(),c(be,pe(ee(n)),{default:e(()=>[m(t.$slots,`default`)]),_:3},16))}}),Se=A({__name:`CardContent`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(e,n)=>(y(),v(`div`,{"data-slot":`card-content`,class:N(T(p)(`px-4 group-data-[size=sm]/card:px-3`,t.class))},[m(e.$slots,`default`)],2))}}),Ce=A({__name:`CardDescription`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(e,n)=>(y(),v(`div`,{"data-slot":`card-description`,class:N(T(p)(`text-xs/relaxed text-muted-foreground`,t.class))},[m(e.$slots,`default`)],2))}}),we=A({__name:`CardHeader`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(e,n)=>(y(),v(`div`,{"data-slot":`card-header`,class:N(T(p)(`group/card-header @container/card-header grid auto-rows-min items-start gap-1 rounded-none px-4 group-data-[size=sm]/card:px-3 has-data-[slot=card-action]:grid-cols-[1fr_auto] has-data-[slot=card-description]:grid-rows-[auto_auto] [.border-b]:pb-4 group-data-[size=sm]/card:[.border-b]:pb-3`,t.class))},[m(e.$slots,`default`)],2))}}),Te=A({__name:`CardTitle`,props:{class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e;return(e,n)=>(y(),v(`div`,{"data-slot":`card-title`,class:N(T(p)(`cn-font-heading text-sm font-medium group-data-[size=sm]/card:text-sm`,t.class))},[m(e.$slots,`default`)],2))}}),L=A({__name:`Separator`,props:{orientation:{default:`horizontal`},decorative:{type:Boolean,default:!0},asChild:{type:Boolean},as:{},class:{type:[Boolean,null,String,Object,Array]}},setup(e){let t=e,n=ue(t,`class`);return(e,r)=>(y(),c(T(xe),b({"data-slot":`separator`},T(n),{class:T(p)(`shrink-0 bg-border data-[orientation=horizontal]:h-px data-[orientation=horizontal]:w-full data-[orientation=vertical]:w-px data-[orientation=vertical]:self-stretch`,t.class)}),null,16,[`class`]))}}),Ee=[`aria-label`],De={class:`flex items-baseline gap-3 border-b bg-muted/50 px-4 py-2`},Oe={class:`font-semibold tracking-wider uppercase`},ke={key:0,class:`text-muted-foreground`},Ae={class:`grid grid-cols-1 divide-y lg:grid-cols-2 lg:divide-x lg:divide-y-0`},R=A({__name:`CanvasSection`,props:{title:{},note:{}},setup(e){return(t,n)=>(y(),v(`section`,{"aria-label":e.title,class:`border-b`},[_(`h2`,De,[_(`span`,Oe,M(e.title),1),e.note?(y(),v(`span`,ke,M(e.note),1)):g(``,!0)]),_(`div`,Ae,[(y(),v(I,null,x([`light`,`dark`],e=>_(`div`,{key:e,class:N([e,`flex flex-col gap-4 bg-background p-4 text-foreground`])},[m(t.$slots,`default`)],2)),64))])],8,Ee))}}),z=(e,t)=>({id:e,class:`T2`,status:`active`,goal:null,paused:!1,pauseRequest:null,pauseRequestable:!0,resumable:!1,resumesTo:null,started:!0,gate:null,autopilot:null,pullRequest:null,priority:null,queue:null,...t}),B=(e,t)=>({url:`https://github.com/fapost-lab/jig-ui/pull/18`,state:e,ci:t,fetchedAt:`2026-10-18T09:40:00Z`}),V=[z(`design-system`,{class:`T3`,gate:`waiting`,priority:0,queue:{level:null,position:100},goal:`shadcn-vue on Tailwind v4 with light and dark themes; #/canvas with every component in every variant; the three screens rebuilt on it.`}),z(`registry-schema`,{gate:`changed`,priority:3,queue:{level:null,position:200},goal:`Version the registry file so a newer Jig UI can read an older one.`}),z(`pause-request`,{class:`T3`,autopilot:`stopped`,goal:`A drop on the paused column writes a sticky request through Jig; the card shows it with its age and a cancel.`}),z(`specs-and-epics`,{autopilot:`on`,queue:{level:null,position:300},goal:`Show each spec with its phases, progress and epic branch beside the board, from Jig's spec list.`}),z(`task-details`,{status:`ready`,pullRequest:B(`open`,`green`),goal:`Open a task's details from its card.`}),z(`refusal-fixture`,{class:`T0`,status:`ready`,pullRequest:B(`open`,`red`),goal:`Replace the refusal text in task-list-states.json with one Jig prints.`}),z(`docs-board`,{class:`T1`,status:`ready`,pullRequest:B(`open`,`pending`),goal:`Describe the five columns on the projects page of the docs.`}),z(`live-updates`,{status:`ready`,pullRequest:B(`merged`,`none`),goal:`Follow connected projects without a reload.`}),z(`no-pr-yet`,{class:`T1`,status:`ready`,goal:`Ready, nothing pushed.`}),z(`jig-init-hook`,{class:`T3`,paused:!0,pauseRequestable:!1,goal:`Register a project in an installed Jig UI from jig init.`}),z(`file-backlog-task`,{class:null,started:!1,goal:`File a minimal backlog task from the page through jig task new.`}),z(`a-task-with-a-rather-long-identifier-that-wraps`,{goal:null}),z(`conflict-display`,{pauseRequest:{requestedAt:`2026-10-22T09:00:00Z`},pauseRequestable:!1,goal:`Show what changed when a write was based on a stale read.`}),z(`resume-from-page`,{class:`T3`,paused:!0,pauseRequestable:!1,resumable:!0,resumesTo:`in-progress`,goal:`A drop out of Paused, or the card menu, resumes the task through jig task resume.`})],H=[{id:`needs-you`,title:`Needs you`,cards:V.slice(0,3)},{id:`in-progress`,title:`In progress`,cards:[V[3],V[12],V[11]]},{id:`ready`,title:`Ready`,cards:V.slice(4,9)},{id:`backlog`,title:`Backlog`,cards:[V[10]]},{id:`paused`,title:`Paused`,cards:[V[9],V[13]]}],U=H.map(e=>({...e,cards:[]})),je=[{id:`file-backlog-task`,status:`consolidated`,goal:`File a minimal backlog task from the page.`,updatedAt:`2026-10-25`,pullRequest:{url:`https://github.com/fapost-lab/jig-ui/pull/40`,state:`merged`}},{id:`pr-template`,status:`abandoned`,goal:`A pull request template.`,updatedAt:`2026-10-17`,pullRequest:null},{id:`old-spike`,status:`abandoned`,goal:null,updatedAt:`2026-10-12`,pullRequest:null}],Me=[{id:`needs-you`,title:`Needs you`,count:3},{id:`in-progress`,title:`In progress`,count:1},{id:`ready`,title:`Ready`,count:5},{id:`backlog`,title:`Backlog`,count:1},{id:`paused`,title:`Paused`,count:1},{id:`unknown`,title:`A column this page does not know`,count:0}],W=[{kind:`gate`,subject:{type:`task`,id:`design-system`},tasks:[`design-system`],title:`Design waits at its gate`,detail:null,todo:`Review the design and approve it: jig task gate design-system approved`,url:null,versions:null},{kind:`pull-request-ci-failed`,subject:{type:`task`,id:`refusal-fixture`},tasks:[`refusal-fixture`],title:`CI failed`,detail:`pull request #19`,todo:`Look at the failing check.`,url:`https://github.com/fapost-lab/jig-ui/pull/19`,versions:null},{kind:`housekeeping`,subject:{type:`project`,id:null},tasks:[],title:`Housekeeping never ran`,detail:null,todo:`Run jig housekeeping.`,url:`https://example.com/docs`,versions:null}],G=[{id:`approve-gate`,command:`jig task gate design-system approved`},{id:`answer-stop`,command:`jig task autopilot pause-request resume --answer <text>`},{id:`pause`,command:`jig task pause design-system`},{id:`request-pause`,command:`jig queue request task:design-system pause`},{id:`something-new`,command:`jig task something-new design-system`}],K={state:`ready`,issue:null,baseBranch:`main`,createdAt:`2026-10-17`,updatedAt:`2026-10-18`,knowledgeConsolidated:!1,worktree:null,gateBy:null,run:null,housekeepingFlags:[],attention:[]},q=[{...K,...V[2],gate:`approved`,gateBy:`human`,branch:`task/pause-request`,worktree:{uncommitted:4},issue:`#42`,pullRequest:B(`open`,`red`),run:{mode:`attended`,stage:`implement`,stageAt:`2026-10-18T09:00:00Z`,stopReason:`Which column takes a paused task that already has an open pull request?`,stopAt:`2026-10-18T09:12:00Z`,phase:null},housekeepingFlags:[`needs-consolidation`],attention:[W[0]],actions:G,column:{id:`needs-you`,title:`Needs you`}},{...K,...V[10],branch:null,actions:[{id:`start`,command:`jig task start file-backlog-task`}],column:{id:`backlog`,title:`Backlog`}}],J=(e,t={})=>({id:e,state:`ready`,jigVersion:`0.29.0`,counts:{active:11,paused:1,ready:3},attention:[],housekeepingStale:!1,upgrade:null,...t}),Y=[J(`jig-ui`,{attention:W,housekeepingStale:!0}),J(`nextjs-store`,{counts:{active:0,paused:0,ready:0}}),J(`legacy-shop`,{jigVersion:`0.34.0`,counts:{active:2,paused:0,ready:0},attention:[{kind:`upgrade-available`,subject:{type:`project`,id:null},tasks:[],title:`Jig in this project is older than on this machine`,detail:`this project runs 0.34.0; this machine has 0.35.0`,todo:`jig upgrade`,url:null,versions:{from:`0.34.0`,to:`0.35.0`}}]}),{id:`old-jig`,state:`unsupported`,jigVersion:`0.26.0`,minimum:`0.29.0`,upgrade:null},{id:`new-jig`,state:`incompatible`,jigVersion:`1.0.0`,upgrade:null},{id:`busy`,state:`unreadable`,code:`locked`,upgrade:null},{id:`moved`,state:`unavailable`,reason:`missing`,upgrade:null}],X={mode:`copy`,from:`0.34.0`,to:`0.35.0`,outcome:`planned`,git:null,manualSteps:[],wouldStop:[]},Ne=[{state:`reading`},{state:`planned`,plan:X},{state:`planned`,plan:{...X,manualSteps:[`Restart your agent sessions: the skills changed.`]}},{state:`planned`,plan:{...X,wouldStop:["the working tree has uncommitted changes; commit them, stash them (`git stash`), or finish the task they belong to, then run `jig upgrade` again"]}},{state:`refused`,message:`Jig refused the upgrade.`}],Z={level:`pr`,branch:`jig/upgrade-0.35.0`,commit:`279390b`,pushed:!0,pullRequest:`https://github.com/fapost-lab/jig-ui/pull/49`,merged:!1},Q=e=>({state:`done`,at:`2026-10-27T08:00:00Z`,upgrade:{...X,outcome:`upgraded`,git:Z,...e}}),Pe=[{state:`running`,since:new Date(Date.now()-12e4).toISOString(),to:`0.35.0`},Q({git:{...Z,merged:!0}}),Q({manualSteps:[`Restart your agent sessions: the skills changed.`]}),Q({outcome:`staged`,git:{...Z,level:`none`,commit:null,pushed:!1,pullRequest:null}}),Q({outcome:`nothing-to-do`,git:null}),{state:`refused`,at:`2026-10-27T08:00:00Z`,code:`upgrade-blocked`,reasons:[`task up-x is started and its branch task/up-x is checked out here (record .ai/runtime/working/up-x); the upgrade would take this checkout off it`]},{state:`refused`,at:`2026-10-27T08:00:00Z`,code:`failed`,reasons:[]}],$=[{text:"`design-system` — design system and canvas",checked:!0,task:`design-system`,fog:!1},{text:"`specs-and-epics` — specs and epics (after: project board — `jig spec list`)",checked:!1,task:`specs-and-epics`,fog:!1},{text:"`old-task` — a task no longer live",checked:!1,task:`old-task`,fog:!1},{text:`invoices from orders, no task filed yet`,checked:!1,task:null,fog:!1},{text:"fog: registration by `jig init`",checked:!1,task:null,fog:!0}],Fe=[{id:`jig-ui`,title:`Jig UI — a local control center for Jig projects`,missingFiles:[],release:null,epic:null,progress:{done:2,total:6,filed:2,fog:1},phases:[{phase:0,title:`Package and release`,done:1,total:1,filed:0,fog:0,items:[{...$[0],text:`package and release`,task:null}]},{phase:1,title:`Read-only UI`,done:1,total:5,filed:2,fog:1,items:$}]},{id:`billing`,title:`Billing in one place`,missingFiles:[],release:`minor`,epic:{branch:`epic/billing`,state:`open`,checkedOut:!1,missing:!1,fetched:!0},progress:{done:0,total:1,filed:0,fog:0},phases:[{phase:null,title:null,done:0,total:1,filed:0,fog:0,items:[$[3]]}]},{id:`lost-epic`,title:`An epic whose branch is gone`,missingFiles:[],release:`major`,epic:{branch:`epic/lost`,state:`open`,checkedOut:!0,missing:!0,fetched:!1},progress:null,phases:[]},{id:`half-written`,title:null,missingFiles:[`spec.md`,`roadmap.md`],release:null,epic:null,progress:null,phases:[]}],Ie={class:`flex gap-4`},Le={class:`w-24 text-muted-foreground`},Re={class:`flex items-center gap-2`},ze={class:`flex flex-wrap gap-2`},Be={class:`flex max-w-sm flex-col gap-2`},Ve={class:`flex h-5 items-center gap-2`},He={class:`flex gap-2`},Ue={class:`flex flex-wrap items-center gap-6`},We={class:`flex items-center gap-1`},Ge={class:`grid grid-cols-2 gap-2 xl:grid-cols-3`},Ke={class:`flex h-[28rem] flex-col`},qe={class:`flex h-40 flex-col`},Je={class:`flex h-[28rem] flex-col`},Ye={class:`flex h-64 flex-col`},Xe={class:`flex h-64 flex-col`},Ze=A({__name:`CanvasView`,setup(n){let ee=[`default`,`secondary`,`outline`,`ghost`,`destructive`,`link`],f=[`xs`,`sm`,`default`,`lg`],p=[`icon-xs`,`icon-sm`,`icon`,`icon-lg`],m=[`default`,`secondary`,`outline`,`ghost`,`destructive`,`link`],g=[`attention`,`good`,`bad`,`quiet`];return(n,b)=>(y(),v(`div`,null,[b[14]||=_(`div`,{class:`border-b px-4 py-3`},[_(`h1`,{class:`font-semibold tracking-wider uppercase`},`Canvas`),_(`p`,{class:`text-muted-foreground`},`Every component of the page in every variant and state; the left panel light, the right dark.`)],-1),u(R,{title:`Tones`,note:`lib/tones.ts — the only colours with a meaning`},{default:e(()=>[(y(),v(I,null,x(g,e=>_(`p`,{key:e,class:N(T(te)[e])},M(e)+` as a rule`,3)),64)),_(`p`,Ie,[(y(),v(I,null,x(g,e=>_(`span`,{key:e,class:N(T(re)[e])},M(e),3)),64))])]),_:1}),b[15]||=_(`h2`,{class:`border-b px-4 py-2 font-bold tracking-widest uppercase`},`components/ui`,-1),u(R,{title:`Button`,note:`variant × size; icon sizes; disabled`},{default:e(()=>[(y(),v(I,null,x(ee,t=>_(`div`,{key:t,class:`flex flex-wrap items-center gap-2`},[_(`span`,Le,M(t),1),(y(),v(I,null,x(f,n=>u(T(d),{key:n,variant:t,size:n},{default:e(()=>[s(M(n),1)]),_:2},1032,[`variant`,`size`])),64)),u(T(d),{variant:t,disabled:``},{default:e(()=>[...b[0]||=[s(`disabled`,-1)]]),_:1},8,[`variant`])])),64)),_(`div`,Re,[b[2]||=_(`span`,{class:`w-24 text-muted-foreground`},`icon`,-1),(y(),v(I,null,x(p,t=>u(T(d),{key:t,variant:`outline`,size:t,"aria-label":t},{default:e(()=>[u(T(o))]),_:1},8,[`size`,`aria-label`])),64)),u(T(d),{variant:`outline`,size:`sm`},{default:e(()=>[u(T(o),{"data-icon":`inline-start`}),b[1]||=s(`with icon`,-1)]),_:1})])]),_:1}),u(R,{title:`Badge`},{default:e(()=>[_(`div`,ze,[(y(),v(I,null,x(m,t=>u(T(ne),{key:t,variant:t},{default:e(()=>[s(M(t),1)]),_:2},1032,[`variant`])),64))])]),_:1}),u(R,{title:`Card`},{default:e(()=>[u(T(i),{class:`max-w-sm`},{default:e(()=>[u(T(we),null,{default:e(()=>[u(T(Te),null,{default:e(()=>[...b[3]||=[s(`Card title`,-1)]]),_:1}),u(T(Ce),null,{default:e(()=>[...b[4]||=[s(`Card description, muted.`,-1)]]),_:1})]),_:1}),u(T(Se),null,{default:e(()=>[...b[5]||=[s(`Card content.`,-1)]]),_:1})]),_:1})]),_:1}),u(R,{title:`Input and Label`,note:`empty, filled, invalid, disabled`},{default:e(()=>[_(`div`,Be,[u(T(se),null,{default:e(()=>[...b[6]||=[s(`Project path`,-1)]]),_:1}),u(T(k),{placeholder:`/path/to/project`}),u(T(k),{"model-value":`/Users/me/project`}),u(T(k),{"model-value":`/not/a/project`,"aria-invalid":`true`}),u(T(k),{"model-value":`disabled`,disabled:``})])]),_:1}),u(R,{title:`Separator`},{default:e(()=>[u(T(L)),_(`div`,Ve,[b[7]||=s(`left`,-1),u(T(L),{orientation:`vertical`}),b[8]||=s(`right`,-1)])]),_:1}),u(R,{title:`ToggleGroup`,note:`the Board / List switch`},{default:e(()=>[u(T(me),{type:`single`,variant:`outline`,size:`sm`,"model-value":`board`,"aria-label":`View`},{default:e(()=>[u(T(S),{value:`board`},{default:e(()=>[...b[9]||=[s(`Board`,-1)]]),_:1}),u(T(S),{value:`list`},{default:e(()=>[...b[10]||=[s(`List`,-1)]]),_:1})]),_:1})]),_:1}),u(R,{title:`Toggle`,note:`the board's finished tasks: off, on`},{default:e(()=>[_(`div`,He,[u(T(he),{variant:`outline`,size:`sm`,"model-value":!1},{default:e(()=>[...b[11]||=[s(`3 finished tasks`,-1)]]),_:1}),u(T(he),{variant:`outline`,size:`sm`,"model-value":!0},{default:e(()=>[...b[12]||=[s(`3 finished tasks`,-1)]]),_:1})])]),_:1}),u(R,{title:`Collapsible`,note:`open and folded`},{default:e(()=>[(y(),v(I,null,x([!0,!1],t=>u(T(ye),{key:String(t),"default-open":t},{default:e(()=>[u(T(ae),{class:`w-full border-b bg-muted/50 px-3 py-1.5 text-left`},{default:e(()=>[s(`Trigger (`+M(t?`open`:`folded`)+`)`,1)]),_:2},1024),u(T(ve),{class:`px-3 py-2`},{default:e(()=>[...b[13]||=[s(`Content`,-1)]]),_:1})]),_:2},1032,[`default-open`])),64))]),_:1}),b[16]||=_(`h2`,{class:`border-b px-4 py-2 font-bold tracking-widest uppercase`},`components`,-1),u(R,{title:`ProjectTabs`,note:`on the workspace; on a project; empty`},{default:e(()=>[u(l,{projects:T(Y),version:`0.1.0`},{default:e(()=>[u(le)]),_:1},8,[`projects`]),u(l,{projects:T(Y),current:`jig-ui`,version:`0.1.0`},null,8,[`projects`]),u(l,{projects:[]})]),_:1}),u(R,{title:`ThemeToggle`,note:`switches the whole page; the icon is the theme it switches to`},{default:e(()=>[_(`div`,null,[u(le)])]),_:1}),u(R,{title:`ProjectCard`,note:`ready with attention and stale housekeeping; nothing needs you; its Jig older than the machine's, Upgrade… offered; each state it cannot be read in`},{default:e(()=>[(y(!0),v(I,null,x(T(Y),e=>(y(),c(ge,{key:e.id,project:e},null,8,[`project`]))),128))]),_:1}),u(R,{title:`UpgradePanel`,note:`on a card: reading the dry run; the plan, with steps by hand; a stop; a refusal; under way; merged, with steps by hand, staged, nothing to do; not started; failed`},{default:e(()=>[(y(!0),v(I,null,x(T(Ne),(e,t)=>(y(),c(O,{key:`plan-${t}`,project:`legacy-shop`,run:null,plan:e},null,8,[`plan`]))),128)),(y(!0),v(I,null,x(T(Pe),(e,t)=>(y(),c(O,{key:`run-${t}`,project:`legacy-shop`,run:e,plan:void 0},null,8,[`run`]))),128))]),_:1}),u(R,{title:`NewTaskForm`,note:`empty, on its way, the id taken`},{default:e(()=>[u(w,{busy:!1}),u(w,{busy:!0,task:`fix-login`,goal:`Log in with the token after a restart.`}),u(w,{busy:!1,task:`queue-reorder`,goal:`Order the work.`,refusal:`The project has a task called queue-reorder already, maybe a finished one. Choose another id.`,taken:``})]),_:1}),u(R,{title:`ConnectForm`,note:`idle, busy, refused`},{default:e(()=>[u(j,{busy:!1}),u(j,{busy:!0,"model-value":`/Users/me/project`}),u(j,{busy:!1,"model-value":`/Users/me/project/.claude/worktrees/x`,refusal:`That is a worktree. Connect the main checkout instead.`})]),_:1}),u(R,{title:`AttentionItem`,note:`no link; a pull request; another link`},{default:e(()=>[(y(!0),v(I,null,x(T(W),(e,t)=>(y(),c(ce,{key:t,item:e},null,8,[`item`]))),128))]),_:1}),u(R,{title:`ColumnHeader`,note:`each column, and one this page does not know`},{default:e(()=>[(y(!0),v(I,null,x(T(Me),e=>(y(),c(t,{id:e.id,key:e.id,title:e.title,count:e.count},null,8,[`id`,`title`,`count`]))),128))]),_:1}),u(R,{title:`QueueMenu`,note:`press to open: To top, Up, Down, To bottom, Priority, the pause — first queued, in the middle, not queued, last, paused under a Jig that cannot resume it (no pause to ask, Resume off), paused and resumable, a pause asked, while its change is on its way`},{default:e(()=>[_(`div`,Ue,[(y(!0),v(I,null,x([T(V)[0],T(V)[1],T(V)[3],T(V)[11],T(V)[9],T(V)[13],T(V)[12]],e=>(y(),v(`span`,{key:e.id,class:`flex items-center gap-1`},[s(M(e.id),1),u(a,{task:e,cards:T(V)},null,8,[`task`,`cards`])]))),128)),_(`span`,We,[s(M(T(V)[1].id),1),u(a,{task:T(V)[1],cards:T(V),disabled:``},null,8,[`task`,`cards`])])])]),_:1}),u(R,{title:`TaskCard`,note:`every note a card carries, a priority among them; with its queue menu; while its change is on its way; changed since a refused change; open with details, while reading, unreadable`},{default:e(()=>[_(`div`,Ge,[(y(!0),v(I,null,x(T(V),e=>(y(),c(F,{key:e.id,project:`jig-ui`,task:e,open:!1},null,8,[`task`]))),128)),u(F,{project:`jig-ui`,task:T(V)[1],open:!1,cards:T(V)},null,8,[`task`,`cards`]),u(F,{project:`jig-ui`,task:T(V)[0],open:!1,cards:T(V),busy:``},null,8,[`task`,`cards`]),u(F,{project:`jig-ui`,task:T(V)[3],open:!1,cards:T(V),changed:``},null,8,[`task`,`cards`]),u(F,{project:`jig-ui`,task:T(V)[2],open:!0,details:T(q)[0]},null,8,[`task`,`details`]),u(F,{project:`jig-ui`,task:T(V)[0],open:!0},null,8,[`task`]),u(F,{project:`jig-ui`,task:T(V)[1],open:!0,details:`unavailable`},null,8,[`task`])])]),_:1}),u(R,{title:`TaskRow`,note:`each note and priority; selected; with its queue menu; while its change is on its way; changed since a refused change`},{default:e(()=>[_(`div`,null,[(y(!0),v(I,null,x(T(V),(e,t)=>(y(),c(E,{key:e.id,task:e,selected:t===2},null,8,[`task`,`selected`]))),128)),u(E,{task:T(V)[1],selected:!1,cards:T(V)},null,8,[`task`,`cards`]),u(E,{task:T(V)[0],selected:!1,cards:T(V),busy:``},null,8,[`task`,`cards`]),u(E,{task:T(V)[3],selected:!1,cards:T(V),changed:``},null,8,[`task`,`cards`])])]),_:1}),u(R,{title:`BoardColumns`,note:`cards in every column, one open with its details, two changed since a refused change; no live task`},{default:e(()=>[_(`div`,Ke,[u(C,{project:`jig-ui`,columns:T(H),selected:T(V)[2].id,details:T(q)[0],pending:T(V)[0].id,changed:[T(V)[1].id,T(V)[3].id]},null,8,[`columns`,`selected`,`details`,`pending`,`changed`])]),_(`div`,qe,[u(C,{project:`jig-ui`,columns:T(U)},null,8,[`columns`])])]),_:1}),u(R,{title:`BoardList`,note:`a row picked with its details; nothing picked; no live task`},{default:e(()=>[_(`div`,Je,[u(D,{project:`jig-ui`,columns:T(H),selected:T(V)[2].id,details:T(q)[0]},null,8,[`columns`,`selected`,`details`])]),_(`div`,Ye,[u(D,{project:`jig-ui`,columns:T(H)},null,8,[`columns`])]),_(`div`,Xe,[u(D,{project:`jig-ui`,columns:T(U)},null,8,[`columns`])])]),_:1}),u(R,{title:`FinishedList`,note:`closed with its pull request merged; abandoned; one without a goal`},{default:e(()=>[u(fe,{tasks:T(je),class:`border`},null,8,[`tasks`])]),_:1}),u(R,{title:`TaskFacts`,note:`everything a task can carry; a task not started`},{default:e(()=>[(y(!0),v(I,null,x(T(q),e=>(y(),c(r,{key:e.id,details:e,class:`border-b pb-3`},null,8,[`details`]))),128))]),_:1}),u(R,{title:`TaskBrief`,note:`facts, actions and the link to the full page`},{default:e(()=>[u(ie,{project:`jig-ui`,task:T(q)[1].id,details:T(q)[1]},null,8,[`task`,`details`])]),_:1}),u(R,{title:`ActionList`,note:`Jig's offers, one unknown id; none`},{default:e(()=>[u(P,{actions:T(G)},null,8,[`actions`]),u(P,{actions:[]})]),_:1}),u(R,{title:`CopyCommand`,note:`short; long enough to be cut`},{default:e(()=>[u(h,{command:`jig task pause design-system`}),u(h,{command:`jig task autopilot a-task-with-a-rather-long-identifier-that-wraps resume --answer 'a long answer to the question'`,class:`max-w-xs`})]),_:1}),u(R,{title:`ProgressBar`,note:`none, part, all, an empty roadmap`},{default:e(()=>[(y(),v(I,null,x([[0,4],[3,9],[5,5],[0,0]],([e,t])=>u(_e,{key:`${e}/${t}`,done:e,total:t},null,8,[`done`,`total`])),64))]),_:1}),u(R,{title:`SpecItemRow`,note:`done with a live task; open with dependencies; a task no longer live; no task; fog`},{default:e(()=>[_(`ul`,null,[(y(!0),v(I,null,x(T($),(e,t)=>(y(),c(de,{key:t,item:e,project:`jig-ui`,live:t<2},null,8,[`item`,`live`]))),128))])]),_:1}),u(R,{title:`SpecCard`,note:`no epic, a finished phase folded; an open epic as of the last fetch; a lost epic branch; missing files`},{default:e(()=>[(y(!0),v(I,null,x(T(Fe),e=>(y(),c(oe,{key:e.id,spec:e,project:`jig-ui`,live:[`design-system`,`specs-and-epics`]},null,8,[`spec`]))),128))]),_:1})]))}});export{Ze as default};
@@ -0,0 +1,2 @@
1
+ /*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-divide-x-reverse:0;--tw-border-style:solid;--tw-divide-y-reverse:0;--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-duration:initial;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--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-sans:-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-mono:"JetBrains Mono Variable", ui-monospace, monospace;--color-red-600:oklch(57.7% .245 27.325);--color-amber-300:oklch(87.9% .169 91.605);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-700:oklch(55.5% .163 48.998);--color-emerald-300:oklch(84.5% .143 164.978);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-700:oklch(50.8% .118 165.612);--color-sky-500:oklch(68.5% .169 237.323);--color-slate-400:oklch(70.4% .04 256.788);--color-zinc-400:oklch(70.5% .015 286.067);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--container-3xl:48rem;--container-4xl:56rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-wider:.05em;--tracking-widest:.1em;--leading-relaxed:1.625;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:"JetBrains Mono Variable", ui-monospace, 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}*{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:JetBrains Mono Variable,ui-monospace,monospace;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--foreground)}}@layer components;@layer utilities{.\@container\/card-header{container:card-header/inline-size}.\@container{container-type:inline-size}.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}.relative{position:relative}.sticky{position:sticky}.inset-x-0{inset-inline:0}.-top-1\.5{top:calc(var(--spacing) * -1.5)}.top-0{top:0}.right-2{right:calc(var(--spacing) * 2)}.-bottom-1\.5{bottom:calc(var(--spacing) * -1.5)}.bottom-0{bottom:0}.z-10{z-index:10}.z-50{z-index:50}.col-start-2{grid-column-start:2}.row-span-2{grid-row:span 2/span 2}.row-start-1{grid-row-start:1}.-mx-1{margin-inline:calc(var(--spacing) * -1)}.mx-auto{margin-inline:auto}.mt-1{margin-top:var(--spacing)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mb-1{margin-bottom:var(--spacing)}.ml-auto{margin-left:auto}.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-flex{display:inline-flex}.size-3{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.h-0\.5{height:calc(var(--spacing) * .5)}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-3{height:calc(var(--spacing) * 3)}.h-5{height:calc(var(--spacing) * 5)}.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-40{height:calc(var(--spacing) * 40)}.h-64{height:calc(var(--spacing) * 64)}.h-\[28rem\]{height:28rem}.h-full{height:100%}.h-px{height:1px}.h-screen{height:100vh}.max-h-\(--reka-dropdown-menu-content-available-height\){max-height:var(--reka-dropdown-menu-content-available-height)}.max-h-48{max-height:calc(var(--spacing) * 48)}.min-h-0{min-height:0}.w-\(--reka-dropdown-menu-trigger-width\){width:var(--reka-dropdown-menu-trigger-width)}.w-1{width:var(--spacing)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-20{width:calc(var(--spacing) * 20)}.w-24{width:calc(var(--spacing) * 24)}.w-40{width:calc(var(--spacing) * 40)}.w-44{width:calc(var(--spacing) * 44)}.w-56{width:calc(var(--spacing) * 56)}.w-96{width:calc(var(--spacing) * 96)}.w-fit{width:fit-content}.w-full{width:100%}.max-w-\(--reka-dropdown-menu-content-available-width\){max-width:var(--reka-dropdown-menu-content-available-width)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-sm{max-width:var(--container-sm)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:0}.min-w-7{min-width:calc(var(--spacing) * 7)}.min-w-8{min-width:calc(var(--spacing) * 8)}.min-w-9{min-width:calc(var(--spacing) * 9)}.min-w-32{min-width:calc(var(--spacing) * 32)}.min-w-64{min-width:calc(var(--spacing) * 64)}.min-w-\[96px\]{min-width:96px}.flex-1{flex:1}.shrink-0{flex-shrink:0}.origin-\(--reka-dropdown-menu-content-transform-origin\){transform-origin:var(--reka-dropdown-menu-content-transform-origin)}.cursor-default{cursor:default}.list-disc{list-style-type:disc}.auto-rows-min{grid-auto-rows:min-content}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-\[repeat\(5\,minmax\(14rem\,1fr\)\)\]{grid-template-columns:repeat(5,minmax(14rem,1fr))}.flex-col{flex-direction:column}.flex-row{flex-direction:row}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-center{justify-content:center}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-\[--spacing\(var\(--gap\)\)\]{gap:calc(var(--spacing) * var(--gap))}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-y-1{row-gap:var(--spacing)}:where(.divide-x>:not(:last-child)){--tw-divide-x-reverse:0;border-inline-style:var(--tw-border-style);border-inline-start-width:calc(1px * var(--tw-divide-x-reverse));border-inline-end-width:calc(1px * calc(1 - var(--tw-divide-x-reverse)))}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}.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-none{border-radius:0}.border{border-style:var(--tw-border-style);border-width:1px}.border-y{border-block-style:var(--tw-border-style);border-block-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-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-amber-500{border-color:var(--color-amber-500)}.border-border{border-color:var(--border)}.border-destructive{border-color:var(--destructive)}.border-emerald-500{border-color:var(--color-emerald-500)}.border-input{border-color:var(--input)}.border-transparent{border-color:#0000}.bg-amber-500{background-color:var(--color-amber-500)}.bg-background{background-color:var(--background)}.bg-border{background-color:var(--border)}.bg-card{background-color:var(--card)}.bg-destructive\/10{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.bg-destructive\/10{background-color:color-mix(in oklab, var(--destructive) 10%, transparent)}}.bg-emerald-500{background-color:var(--color-emerald-500)}.bg-foreground{background-color:var(--foreground)}.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{background-color:var(--primary)}.bg-red-600{background-color:var(--color-red-600)}.bg-secondary{background-color:var(--secondary)}.bg-sky-500{background-color:var(--color-sky-500)}.bg-slate-400{background-color:var(--color-slate-400)}.bg-transparent{background-color:#0000}.bg-zinc-400{background-color:var(--color-zinc-400)}.bg-clip-padding{background-clip:padding-box}.p-2{padding:calc(var(--spacing) * 2)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.px-0\.5{padding-inline:calc(var(--spacing) * .5)}.px-1{padding-inline:var(--spacing)}.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)}.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-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.pt-2{padding-top:calc(var(--spacing) * 2)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pr-8{padding-right:calc(var(--spacing) * 8)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pl-2{padding-left:calc(var(--spacing) * 2)}.pl-5{padding-left:calc(var(--spacing) * 5)}.text-center{text-align:center}.text-left{text-align:left}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-xs\/relaxed{font-size:var(--text-xs);line-height:var(--leading-relaxed)}.leading-none{--tw-leading:1;line-height:1}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.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-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.tracking-widest{--tw-tracking:var(--tracking-widest);letter-spacing:var(--tracking-widest)}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.text-amber-700{color:var(--color-amber-700)}.text-background{color:var(--background)}.text-black{color:var(--color-black)}.text-card-foreground{color:var(--card-foreground)}.text-destructive{color:var(--destructive)}.text-emerald-700{color:var(--color-emerald-700)}.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-secondary-foreground{color:var(--secondary-foreground)}.text-white{color:var(--color-white)}.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,)}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.underline-offset-4{text-underline-offset:4px}.opacity-60{opacity:.6}.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)}.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-foreground,.ring-foreground\/10{--tw-ring-color:var(--foreground)}@supports (color:color-mix(in lab, red, red)){.ring-foreground\/10{--tw-ring-color:color-mix(in oklab, var(--foreground) 10%, transparent)}}.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}.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))}.duration-100{--tw-duration:.1s;transition-duration:.1s}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.paused{animation-play-state:paused}.running{animation-play-state:running}.group-focus\/dropdown-menu-item\:text-accent-foreground:is(:where(.group\/dropdown-menu-item):focus *){color:var(--accent-foreground)}.group-data-\[disabled\=true\]\:pointer-events-none:is(:where(.group)[data-disabled=true] *){pointer-events:none}.group-data-\[disabled\=true\]\:opacity-50:is(:where(.group)[data-disabled=true] *){opacity:.5}.group-data-\[size\=sm\]\/card\:p-3:is(:where(.group\/card)[data-size=sm] *){padding:calc(var(--spacing) * 3)}.group-data-\[size\=sm\]\/card\:px-3:is(:where(.group\/card)[data-size=sm] *){padding-inline:calc(var(--spacing) * 3)}.group-data-\[size\=sm\]\/card\:text-sm:is(:where(.group\/card)[data-size=sm] *){font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.group-data-\[spacing\=0\]\/toggle-group\:rounded-none:is(:where(.group\/toggle-group)[data-spacing="0"] *){border-radius:0}.group-data-\[spacing\=0\]\/toggle-group\:px-2:is(:where(.group\/toggle-group)[data-spacing="0"] *){padding-inline:calc(var(--spacing) * 2)}.peer-disabled\:cursor-not-allowed:is(:where(.peer):disabled~*){cursor:not-allowed}.peer-disabled\:opacity-50:is(:where(.peer):disabled~*){opacity:.5}.file\:inline-flex::file-selector-button{display:inline-flex}.file\:h-6::file-selector-button{height:calc(var(--spacing) * 6)}.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-xs::file-selector-button{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--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)}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}@media (hover:hover){.hover\:bg-destructive\/20:hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-destructive\/20:hover{background-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.hover\:bg-muted:hover,.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-secondary\/80:hover{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab, var(--secondary) 80%, transparent)}}.hover\:text-foreground:hover{color:var(--foreground)}.hover\:text-muted-foreground:hover{color:var(--muted-foreground)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:z-10:focus{z-index:10}.focus\:bg-accent:focus{background-color:var(--accent)}.focus\:text-accent-foreground:focus,:is(.focus\:\*\*\:text-accent-foreground:focus *),:is(.not-data-\[variant\=destructive\]\:focus\:\*\*\:text-accent-foreground:not([data-variant=destructive]):focus *){color:var(--accent-foreground)}.focus-visible\:z-10:focus-visible{z-index:10}.focus-visible\:border-destructive\/40:focus-visible{border-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:border-destructive\/40:focus-visible{border-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.focus-visible\:border-ring:focus-visible{border-color:var(--ring)}.focus-visible\:ring-1:focus-visible{--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)}.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)}}.active\:not-aria-\[haspopup\]\:translate-y-px:active:not([aria-haspopup]){--tw-translate-y:1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:bg-input\/50:disabled{background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.disabled\:bg-input\/50:disabled{background-color:color-mix(in oklab, var(--input) 50%, transparent)}}.disabled\:opacity-50:disabled{opacity:.5}.has-data-\[icon\=inline-end\]\:pr-1\.5:has([data-icon=inline-end]){padding-right:calc(var(--spacing) * 1.5)}.has-data-\[icon\=inline-end\]\:pr-2:has([data-icon=inline-end]){padding-right:calc(var(--spacing) * 2)}.group-data-\[spacing\=0\]\/toggle-group\:has-data-\[icon\=inline-end\]\:pr-1\.5:is(:where(.group\/toggle-group)[data-spacing="0"] *):has([data-icon=inline-end]){padding-right:calc(var(--spacing) * 1.5)}.has-data-\[icon\=inline-start\]\:pl-1\.5:has([data-icon=inline-start]){padding-left:calc(var(--spacing) * 1.5)}.has-data-\[icon\=inline-start\]\:pl-2:has([data-icon=inline-start]){padding-left:calc(var(--spacing) * 2)}.group-data-\[spacing\=0\]\/toggle-group\:has-data-\[icon\=inline-start\]\:pl-1\.5:is(:where(.group\/toggle-group)[data-spacing="0"] *):has([data-icon=inline-start]){padding-left:calc(var(--spacing) * 1.5)}.has-data-\[slot\=card-action\]\:grid-cols-\[1fr_auto\]:has([data-slot=card-action]){grid-template-columns:1fr auto}.has-data-\[slot\=card-description\]\:grid-rows-\[auto_auto\]:has([data-slot=card-description]){grid-template-rows:auto auto}.has-data-\[slot\=card-footer\]\:pb-0:has([data-slot=card-footer]){padding-bottom:0}.has-\[\>img\:first-child\]\:pt-0:has(>img:first-child){padding-top:0}.aria-expanded\:bg-muted[aria-expanded=true]{background-color:var(--muted)}.aria-expanded\:bg-secondary[aria-expanded=true]{background-color:var(--secondary)}.aria-expanded\:text-foreground[aria-expanded=true]{color:var(--foreground)}.aria-expanded\:text-secondary-foreground[aria-expanded=true]{color:var(--secondary-foreground)}.aria-invalid\:border-destructive[aria-invalid=true]{border-color:var(--destructive)}.aria-invalid\:ring-1[aria-invalid=true]{--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)}.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)}}.aria-pressed\:bg-muted[aria-pressed=true]{background-color:var(--muted)}.data-closed\:animate-out[data-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-closed\:fade-out-0[data-closed]{--tw-exit-opacity:0}.data-closed\:zoom-out-95[data-closed]{--tw-exit-scale:.95}.data-disabled\:pointer-events-none[data-disabled]{pointer-events:none}.data-disabled\:opacity-50[data-disabled]{opacity:.5}.data-inset\:pl-7[data-inset]{padding-left:calc(var(--spacing) * 7)}.data-open\:animate-in[data-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-open\:bg-accent[data-open]{background-color:var(--accent)}.data-open\:text-accent-foreground[data-open]{color:var(--accent-foreground)}.data-open\:fade-in-0[data-open]{--tw-enter-opacity:0}.data-open\:zoom-in-95[data-open]{--tw-enter-scale:.95}.data-vertical\:flex-col[data-vertical]{flex-direction:column}.data-vertical\:items-stretch[data-vertical]{align-items:stretch}.data-\[orientation\=horizontal\]\:h-px[data-orientation=horizontal]{height:1px}.data-\[orientation\=horizontal\]\:w-full[data-orientation=horizontal]{width:100%}.data-\[orientation\=vertical\]\:w-px[data-orientation=vertical]{width:1px}.data-\[orientation\=vertical\]\:self-stretch[data-orientation=vertical]{align-self:stretch}.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-\[size\=sm\]\:gap-2[data-size=sm]{gap:calc(var(--spacing) * 2)}.data-\[size\=sm\]\:rounded-none[data-size=sm]{border-radius:0}.data-\[size\=sm\]\:py-3[data-size=sm]{padding-block:calc(var(--spacing) * 3)}.data-\[size\=sm\]\:has-data-\[slot\=card-footer\]\:pb-0[data-size=sm]:has([data-slot=card-footer]){padding-bottom:0}.group-data-horizontal\/toggle-group\:data-\[spacing\=0\]\:first\:rounded-none:is(:where(.group\/toggle-group)[data-horizontal] *)[data-spacing="0"]:first-child,.group-data-vertical\/toggle-group\:data-\[spacing\=0\]\:first\:rounded-none:is(:where(.group\/toggle-group)[data-vertical] *)[data-spacing="0"]:first-child,.group-data-horizontal\/toggle-group\:data-\[spacing\=0\]\:last\:rounded-none:is(:where(.group\/toggle-group)[data-horizontal] *)[data-spacing="0"]:last-child,.group-data-vertical\/toggle-group\:data-\[spacing\=0\]\:last\:rounded-none:is(:where(.group\/toggle-group)[data-vertical] *)[data-spacing="0"]:last-child{border-radius:0}.data-\[state\=closed\]\:overflow-hidden[data-state=closed]{overflow:hidden}.data-\[state\=on\]\:bg-muted[data-state=on]{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)}.group-data-horizontal\/toggle-group\:data-\[spacing\=0\]\:data-\[variant\=outline\]\:border-l-0:is(:where(.group\/toggle-group)[data-horizontal] *)[data-spacing="0"][data-variant=outline]{border-left-style:var(--tw-border-style);border-left-width:0}.group-data-vertical\/toggle-group\:data-\[spacing\=0\]\:data-\[variant\=outline\]\:border-t-0:is(:where(.group\/toggle-group)[data-vertical] *)[data-spacing="0"][data-variant=outline]{border-top-style:var(--tw-border-style);border-top-width:0}.group-data-horizontal\/toggle-group\:data-\[spacing\=0\]\:data-\[variant\=outline\]\:first\:border-l:is(:where(.group\/toggle-group)[data-horizontal] *)[data-spacing="0"][data-variant=outline]:first-child{border-left-style:var(--tw-border-style);border-left-width:1px}.group-data-vertical\/toggle-group\:data-\[spacing\=0\]\:data-\[variant\=outline\]\:first\:border-t:is(:where(.group\/toggle-group)[data-vertical] *)[data-spacing="0"][data-variant=outline]:first-child{border-top-style:var(--tw-border-style);border-top-width:1px}@media (width>=48rem){.md\:text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}}@media (width>=64rem){.lg\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}:where(.lg\:divide-x>:not(:last-child)){--tw-divide-x-reverse:0;border-inline-style:var(--tw-border-style);border-inline-start-width:calc(1px * var(--tw-divide-x-reverse));border-inline-end-width:calc(1px * calc(1 - var(--tw-divide-x-reverse)))}:where(.lg\:divide-y-0>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(0px * var(--tw-divide-y-reverse));border-bottom-width:calc(0px * calc(1 - var(--tw-divide-y-reverse)))}}@media (width>=80rem){.xl\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@container (width>=24rem){.\@sm\:mb-0{margin-bottom:0}.\@sm\:grid-cols-\[max-content_1fr\]{grid-template-columns:max-content 1fr}.\@sm\:gap-x-4{column-gap:calc(var(--spacing) * 4)}.\@sm\:gap-y-1{row-gap:var(--spacing)}}.dark\:border-input:is(.dark *):not(.light *){border-color:var(--input)}.dark\:bg-destructive\/20:is(.dark *):not(.light *){background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:bg-destructive\/20:is(.dark *):not(.light *){background-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.dark\:bg-input\/30:is(.dark *):not(.light *){background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\:bg-input\/30:is(.dark *):not(.light *){background-color:color-mix(in oklab, var(--input) 30%, transparent)}}.dark\:text-amber-300:is(.dark *):not(.light *){color:var(--color-amber-300)}.dark\:text-emerald-300:is(.dark *):not(.light *){color:var(--color-emerald-300)}@media (hover:hover){.dark\:hover\:bg-destructive\/30:is(.dark *):not(.light *):hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-destructive\/30:is(.dark *):not(.light *):hover{background-color:color-mix(in oklab, var(--destructive) 30%, transparent)}}.dark\:hover\:bg-input\/50:is(.dark *):not(.light *):hover{background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-input\/50:is(.dark *):not(.light *):hover{background-color:color-mix(in oklab, var(--input) 50%, transparent)}}.dark\:hover\:bg-muted\/50:is(.dark *):not(.light *):hover{background-color:var(--muted)}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-muted\/50:is(.dark *):not(.light *):hover{background-color:color-mix(in oklab, var(--muted) 50%, transparent)}}}.dark\:focus-visible\:ring-destructive\/40:is(.dark *):not(.light *):focus-visible{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:focus-visible\:ring-destructive\/40:is(.dark *):not(.light *):focus-visible{--tw-ring-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.dark\:disabled\:bg-input\/80:is(.dark *):not(.light *):disabled{background-color:var(--input)}@supports (color:color-mix(in lab, red, red)){.dark\:disabled\:bg-input\/80:is(.dark *):not(.light *):disabled{background-color:color-mix(in oklab, var(--input) 80%, transparent)}}.dark\:aria-invalid\:border-destructive\/50:is(.dark *):not(.light *)[aria-invalid=true]{border-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:aria-invalid\:border-destructive\/50:is(.dark *):not(.light *)[aria-invalid=true]{border-color:color-mix(in oklab, var(--destructive) 50%, transparent)}}.dark\:aria-invalid\:ring-destructive\/40:is(.dark *):not(.light *)[aria-invalid=true]{--tw-ring-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:aria-invalid\:ring-destructive\/40:is(.dark *):not(.light *)[aria-invalid=true]{--tw-ring-color:color-mix(in oklab, var(--destructive) 40%, transparent)}}.dark\:data-\[variant\=destructive\]\:focus\:bg-destructive\/20:is(.dark *):not(.light *)[data-variant=destructive]:focus{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.dark\:data-\[variant\=destructive\]\:focus\:bg-destructive\/20:is(.dark *):not(.light *)[data-variant=destructive]:focus{background-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.\[\&_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-3\.5 svg:not([class*=size-]){width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.\[\&_svg\:not\(\[class\*\=size-\]\)\]\:size-4 svg:not([class*=size-]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\.border-b\]\:pb-4.border-b{padding-bottom:calc(var(--spacing) * 4)}.group-data-\[size\=sm\]\/card\:\[\.border-b\]\:pb-3:is(:where(.group\/card)[data-size=sm] *).border-b{padding-bottom:calc(var(--spacing) * 3)}@media (hover:hover){.\[a\]\:hover\:bg-destructive\/20:is(a):hover{background-color:var(--destructive)}@supports (color:color-mix(in lab, red, red)){.\[a\]\:hover\:bg-destructive\/20:is(a):hover{background-color:color-mix(in oklab, var(--destructive) 20%, transparent)}}.\[a\]\:hover\:bg-muted:is(a):hover{background-color:var(--muted)}.\[a\]\:hover\:bg-primary\/80:is(a):hover{background-color:var(--primary)}@supports (color:color-mix(in lab, red, red)){.\[a\]\:hover\:bg-primary\/80:is(a):hover{background-color:color-mix(in oklab, var(--primary) 80%, transparent)}}.\[a\]\:hover\:bg-secondary\/80:is(a):hover{background-color:var(--secondary)}@supports (color:color-mix(in lab, red, red)){.\[a\]\:hover\:bg-secondary\/80:is(a):hover{background-color:color-mix(in oklab, var(--secondary) 80%, transparent)}}.\[a\]\:hover\:text-muted-foreground:is(a):hover{color:var(--muted-foreground)}}:is(.\*\:\[img\:first-child\]\:rounded-none>*):is(img:first-child),:is(.\*\:\[img\:last-child\]\:rounded-none>*):is(img:last-child){border-radius:0}:is(.data-\[variant\=destructive\]\:\*\:\[svg\]\:text-destructive[data-variant=destructive]>*):is(svg){color:var(--destructive)}.\[\&\>svg\]\:pointer-events-none>svg{pointer-events:none}.\[\&\>svg\]\:size-3\!>svg{width:calc(var(--spacing) * 3)!important;height:calc(var(--spacing) * 3)!important}}@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}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(data:font/woff2;base64,d09GMgABAAAAAAfsABQAAAAAEAwAAAeCAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGhwbHhwoP0hWQVJbBmA/U1RBVIFiJyYAdC9qEQgKhGSEAAsgADCGCAE2AiQDOgQgBYlMB4EUDAcbLQ4onoexrSC/2ZyLAa8p8VHB8/x3Vue+V0hVJalMJg2nx/TCrQXxBeqLjQG7FyM1WEa/X1tEXN7cFz9EJEMmMUz3RihWSSKeQCbcIou0izz/C8v+fq3VfajEa9gDD11CImXS7qL/RJFVzC1qiB6KmKeD6TZdQ6IRGv78dL6uSVVCfgni5mzu7kcgQBgAEAQTQRCoL++STTYybkJxNfQxAAIAGu8OdEB9teW2jh4BpgDqFjAeSEByW3zFP0CBBgNMsMCGEDjgggdhiEAUAeIIED7ABTDUEnkIE9Q9ahFgKttcVhApo4ACB4qobHaccgDfEjFO6aaWUhjMLt2SyIvHKoDqoA4CSUwEIYQCEjhAO9R1G6keDeDZGjNo+AhxOjCEGTr1WeIF3kYBiLAOKvkJSMiKX0VdAyQt3SDJClCkxJCHkCzfqyVTriJZLcolS32JZHUekq2TYNkYtCtjYHMQXSxGjXDz2t/yLWXzDzxz+o3zFwDEaN23F+13pyMdQAEaSKAR9vcGq4A4MTSKCElGW+M7UcY7xqkggITb28ZJhlqc9q2twYKTt0NjixBgYvO9BIihEBLYuOFXQzfIQ7dXGUEEEgFDooBfAzqiQbpJrhiWSuKJCRFKYbHCyJKI2G5GiZbNAvgAu5pc3vwx4G+g3aDkhklABiSz0BICXrYghtYhx/cdJ+44rY2oZ0aMNRFz3VZjb6W33F3gzltqtOCV8tTHSpOeXuItfvr5lCdfzFpqtEitvqdcdGGFd28ZqqC0tPbeChGXgrIlnhSWu/eUso4uKWFLugyDzQJhflY4659+WjQ++6x72WUMv9G8mw6QJl7BVxX5fe/kpUsOvnZwee9uQ0cGXYd0o89XB2748sDSnt8d2VphdOTTgceDVvOds0v9P/s7HPq15aGun/6Vllb56f1dl0t1LejqrNkpdRZsG8TOnM5vkBG5oiVyVGnS8LHps5cfNWJs6qKPfaNSxiQNBUm3cKNWROr0GSur7Za31k1vieq7LH11VF+jXdRIasRKflc7jkobm1Z9te1IyZA0pDkhLR98+H37Zf1c/8at+dB7x+7GfVyTfJMPiYztsnl59Y5l4j+0n1RXlpHnF3Tq7HecmNF/CJodEMAikruxiyJaGLvHOdAfoA+oDvpjBm2b91cHGRZMU9n25xEU0A8fgEEAdKI3Q1iDtc034sug5YVMkE2jsE+BIkwSoQ3gxXMqz9tELp48bd0cFKOKS7xYjEuXBnZP5ia7DyiO/X/YI+PQSbt2uSdqAkWL9nQbV1XB94/+uPfdZz8dnXYFBYrcTl2SIR/ybxJNJPz/Gupb0JaZeens2ekC7EKr8t+Ls/P5VJPYJdHKyqfg2nqU6bhlidzcddQV/7MmecTzJ5VPcKXkNKSEogHjYFx6QZ7rQ+FSe8njaiNuOnXS8H2ScQ619c2mC3VTtauL0rRbXd/CkSOP37FY9Zkjz8+GibYUMOEWF+RdrFS8Ecv1SHOpPUPZGEIpjPvFyU5cXKjd6OXqorTqy9GwRd++HVufPGnVsW+aO3vggKZ18jR9sXaTC1PWTEsVUaK0FkNySbTQDqlm2PfDjZcu4aalnSLKjnOoYQ0nUlqqXcGpPu/4VgV/xU2pAqW4BW3qzhQ8/hFKhV2qE3+BKAtDqBXjfgnVdH4y0wg5tbVNRenNdTWOrenWLcupQdmsbq5b+18piTe/xRdp1xbILxNPJGInm2z6hoB21Lal0i+ePTtd7B45+3XhFJ329evskXm7qurUVREotqSluSo/L29d3qDhI4YOQqWhI4YNvBNfsMHeXKemXrxQfKeuPOGRVayA3JtkJKEgbPp+dXUDluddutRYLFoXGXWX6N3WFaGLbQtRSitVYNacTNSdy7AaG/HSaUEANcBoGXNdcZvZsOqQ1icBDv21/gzAoYPHH/WDW0qNR3QTYKEAEHig6o13NXbND06CQPlRtYjGNnSktRc09k1mAMDvAlDKfQjgy6fssInlfzmNAjKkDxoxHOBLdVRAIVt9j4qo+hA1w9T1aNBNTUOTTNUHLbqokE+UAfJXCIGw/IxCSL5GRUJeR40rL/UxTm4Q08H6MbCs70ObuNyIIXrINHQYInF06UUlevTjbQzTh5upiDMzMMogUtEnjPs/Y7jAHCJeB0GBHh04tC6FiB6ZFB1oArUSIoFoqhzCeAN6lHwm0T4C3VVPWvjpSMXReuWesMEcoqrmgtNBGd2noWeV0hNAz9rFeShNJxHGsPa3HXeKTk8b55hahySYHaYKKFFLpCfN8rsoaJn01CR04Gkc+5k7KVTCmClX8Q10HCrUEkVlSX+XO33oQR9609tJ516H497WSobWs5Up6TLaS10/dessIskgJSLiDlWvHVUywpkQ7hdPZqGyiEF0uVQerVcPamT1A3eKXdyI1vG9OoflrSXihZ1qqGE3nhmAgiIbRCQgPLEPtOM3UQwTLYaYYomNlpA44opnjV6jkD6id80OOrzf6BzmMD6eEa1zKyeYG1fzfEf16V6jw9XYOaar1/b2kP/IYX8oR2mcFvv2GtBV3JXgd437AQAA)format("woff2-variations");unicode-range:U+460-52F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-cyrillic-wght-normal-D73BlboJ.woff2)format("woff2-variations");unicode-range:U+301,U+400-45F,U+490-491,U+4B0-4B1,U+2116}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-greek-wght-normal-Bw9x6K1M.woff2)format("woff2-variations");unicode-range:U+370-377,U+37A-37F,U+384-38A,U+38C,U+38E-3A1,U+3A3-3FF}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-vietnamese-wght-normal-Bt-aOZkq.woff2)format("woff2-variations");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-latin-ext-wght-normal-DBQx-q_a.woff2)format("woff2-variations");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:JetBrains Mono Variable;font-style:normal;font-display:swap;font-weight:100 800;src:url(/assets/jetbrains-mono-latin-wght-normal-B9CIFXIH.woff2)format("woff2-variations");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}:root,.light{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light;--radius:.625rem;--background:oklch(100% 0 0);--foreground:oklch(14.5% 0 0);--card:oklch(100% 0 0);--card-foreground:oklch(14.5% 0 0);--popover:oklch(100% 0 0);--popover-foreground:oklch(14.5% 0 0);--primary:oklch(20.5% 0 0);--primary-foreground:oklch(98.5% 0 0);--secondary:oklch(97% 0 0);--secondary-foreground:oklch(20.5% 0 0);--muted:oklch(97% 0 0);--muted-foreground:oklch(55.6% 0 0);--accent:oklch(97% 0 0);--accent-foreground:oklch(20.5% 0 0);--destructive:oklch(57.7% .245 27.325);--border:oklch(92.2% 0 0);--input:oklch(92.2% 0 0);--ring:oklch(70.8% 0 0);--chart-1:oklch(64.6% .222 41.116);--chart-2:oklch(60% .118 184.704);--chart-3:oklch(39.8% .07 227.392);--chart-4:oklch(82.8% .189 84.429);--chart-5:oklch(76.9% .188 70.08);--sidebar:oklch(98.5% 0 0);--sidebar-foreground:oklch(14.5% 0 0);--sidebar-primary:oklch(20.5% 0 0);--sidebar-primary-foreground:oklch(98.5% 0 0);--sidebar-accent:oklch(97% 0 0);--sidebar-accent-foreground:oklch(20.5% 0 0);--sidebar-border:oklch(92.2% 0 0);--sidebar-ring:oklch(70.8% 0 0)}.dark{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark;--background:oklch(14.5% 0 0);--foreground:oklch(98.5% 0 0);--card:oklch(20.5% 0 0);--card-foreground:oklch(98.5% 0 0);--popover:oklch(20.5% 0 0);--popover-foreground:oklch(98.5% 0 0);--primary:oklch(92.2% 0 0);--primary-foreground:oklch(20.5% 0 0);--secondary:oklch(26.9% 0 0);--secondary-foreground:oklch(98.5% 0 0);--muted:oklch(26.9% 0 0);--muted-foreground:oklch(70.8% 0 0);--accent:oklch(26.9% 0 0);--accent-foreground:oklch(98.5% 0 0);--destructive:oklch(70.4% .191 22.216);--border:oklch(100% 0 0/.1);--input:oklch(100% 0 0/.15);--ring:oklch(55.6% 0 0);--chart-1:oklch(48.8% .243 264.376);--chart-2:oklch(69.6% .17 162.48);--chart-3:oklch(76.9% .188 70.08);--chart-4:oklch(62.7% .265 303.9);--chart-5:oklch(64.5% .246 16.439);--sidebar:oklch(20.5% 0 0);--sidebar-foreground:oklch(98.5% 0 0);--sidebar-primary:oklch(48.8% .243 264.376);--sidebar-primary-foreground:oklch(98.5% 0 0);--sidebar-accent:oklch(26.9% 0 0);--sidebar-accent-foreground:oklch(98.5% 0 0);--sidebar-border:oklch(100% 0 0/.1);--sidebar-ring:oklch(55.6% 0 0)}@property --tw-divide-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@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-duration{syntax:"*";inherits:false}@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}@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))}}