@agent-plan/pi-adapter 0.2.19-next.18 → 0.2.19-next.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,iCAAiC,CAAC;AAixBtF,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CA0wG9D"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAoB,MAAM,iCAAiC,CAAC;AAkxBtF,MAAM,CAAC,OAAO,UAAU,eAAe,CAAC,EAAE,EAAE,YAAY,GAAG,IAAI,CAuzG9D"}
package/dist/index.js CHANGED
@@ -9,7 +9,7 @@
9
9
  * - inject context into prompts
10
10
  */
11
11
  import { Type } from "typebox";
12
- import { ExportService, PlanStore, setWriteBusyHook, setWriteNotifyHook, migrateToUuids, migrateToGlobalSequence, withFeatureLock, needsMotivation, findPhaseByRef, findTaskByRef, buildRecap, addChecklistItem, removeChecklistItem, toggleChecklistItem } from "@agent-plan/core";
12
+ import { ExportService, PlanStore, setWriteBusyHook, setWriteNotifyHook, migrateToUuids, migrateToGlobalSequence, withFeatureLock, needsMotivation, findPhaseByRef, findTaskByRef, buildRecap, addChecklistItem, removeChecklistItem, toggleChecklistItem, buildPhaseContextBlock } from "@agent-plan/core";
13
13
  import { createChecklistItemId, createFeatureId, createPhaseId, createShortId, createTaskId, clampSlug, normalizeSlug, formatPhaseRef, formatFeatureRef, featureNumberOfPhase, validateResolvedTarget } from "@agent-plan/core/naming";
14
14
  import { join, dirname } from "node:path";
15
15
  import { homedir } from "node:os";
@@ -385,8 +385,8 @@ async function buildHandoffMarkdown(st, reason, overrides) {
385
385
  ".planner/features/",
386
386
  currentPhase ? `.planner/phases/${currentPhase.id}.json` : "",
387
387
  latestPhaseUpdate && latestPhaseUpdate.id !== currentPhase?.id ? `.planner/phases/${latestPhaseUpdate.id}.json` : "",
388
- ".planner/resume.json",
389
- ".planner/generated/PLAN.md",
388
+ ".planner/.local/resume.json",
389
+ ".planner/.local/generated/PLAN.md",
390
390
  ].filter(Boolean);
391
391
  const recentActivityLines = recentActivity.length > 0
392
392
  ? recentActivity.map((entry) => `- ${entry.at} [${entry.type}] ${entry.ref}: ${entry.summary}`)
@@ -412,7 +412,7 @@ async function buildHandoffMarkdown(st, reason, overrides) {
412
412
  ? ["", `## Current Task Statuses (phase ${currentPhase.id})`, ...currentPhaseTaskLines]
413
413
  : [];
414
414
  return [
415
- "# Handoff",
415
+ `# ${overrides?.title?.trim() || `Handoff — ${reason}`}`,
416
416
  "",
417
417
  `Created at: ${createdAt}`,
418
418
  `Updated at: ${updatedAt}`,
@@ -449,7 +449,7 @@ async function buildHandoffMarkdown(st, reason, overrides) {
449
449
  ...recentActivityLines,
450
450
  "",
451
451
  "## Reminder",
452
- "- This handoff is KEPT until a task in this phase starts (then auto-archived to .planner/handoff-archive/) or the phase completes. No need to clear it manually.",
452
+ "- This handoff is KEPT until a task in this phase starts (then auto-archived to .planner/.local/handoff-archive/) or the phase completes. No need to clear it manually.",
453
453
  ].join("\n");
454
454
  }
455
455
  async function writeProjectHandoff(st, reason, overrides) {
@@ -2106,7 +2106,7 @@ export default function planPiExtension(pi) {
2106
2106
  // Other phases' handoffs are left untouched (informational, non-blocking).
2107
2107
  if ((phase.handoff ?? "") !== "") {
2108
2108
  await st.clearPhaseHandoff(phase.id, "task-started").catch(() => { });
2109
- ctx.ui.notify("📦 Archived handoff for this phase (task started) — recover via /planner handoff list + .planner/handoff-archive/.", "info");
2109
+ ctx.ui.notify("📦 Archived handoff for this phase (task started) — recover via /planner handoff list + .planner/.local/handoff-archive/.", "info");
2110
2110
  }
2111
2111
  const _otherHandoffs = (await st.listHandoffs()).filter((h) => h.phaseId !== phase.id);
2112
2112
  if (_otherHandoffs.length > 0) {
@@ -2311,7 +2311,9 @@ export default function planPiExtension(pi) {
2311
2311
  return;
2312
2312
  }
2313
2313
  const handoffs = await st.listHandoffs();
2314
- await capturedPi.sendUserMessage("Prepare the canonical session handoff now and write it on the current in-progress phase using the `handoff_write` tool (entity-scoped, stored on phase.handoff — .planner/HANDOFF.md is deprecated).\n\n" +
2314
+ await capturedPi.sendUserMessage("Prepare the canonical session handoff now and write it on the phase the user explicitly identifies as the one just worked on in this session, using the `handoff_write` tool (entity-scoped, stored on phase.handoff — .planner/HANDOFF.md is deprecated).\n\n" +
2315
+ "Pass a meaningful `title` summarizing the work (e.g. 'P049 — featureId validation: tests + adapter wiring') — it becomes the H1 / first line in handoff lists. Generic titles like 'Handoff' or 'Canonical handoff' are REJECTED.\n\n" +
2316
+ "WARNING: Do not default to 'current in-progress phase' or a stale resume pointer. If the user just completed P058, write the handoff on P058 (or its continuation P061), not on P031 just because P031 is marked in-progress or has an existing handoff.\n\n" +
2315
2317
  "The handoff MUST be a structured markdown document containing at minimum:\n" +
2316
2318
  "- `Created at:` and `Updated at:` lines (ISO timestamps)\n" +
2317
2319
  "- `Reason:` why this handoff is being written\n" +
@@ -2785,7 +2787,7 @@ export default function planPiExtension(pi) {
2785
2787
  pi.registerTool({
2786
2788
  name: "plan_render",
2787
2789
  label: "Plan Render",
2788
- description: "Regenerate all generated markdown views in .planner/generated/. Call after any data change to keep docs in sync.",
2790
+ description: "Regenerate all generated markdown views in .planner/.local/generated/. Call after any data change to keep docs in sync.",
2789
2791
  parameters: Type.Object({}),
2790
2792
  async execute(_id, _params, _signal, _onUpdate, ctx) {
2791
2793
  const st = await requirePlan(ctx);
@@ -2871,9 +2873,10 @@ export default function planPiExtension(pi) {
2871
2873
  pi.registerTool({
2872
2874
  name: "plan_write_handoff",
2873
2875
  label: "Plan Write Handoff",
2874
- description: "DEPRECATED — writes to the entity-scoped phase.handoff (not .planner/HANDOFF.md). Prefer handoff_write. Write or refresh the canonical phase handoff. Capture full design context, not just operational resume steps: pass extraSections with locked decisions, architecture (with file:line refs), mode/state flows, plugin/API contracts, data mappings, files touched, and known gaps so a resuming agent doesn't re-discover decisions already made.",
2876
+ description: "DEPRECATED — writes to the entity-scoped phase.handoff (not .planner/HANDOFF.md). Prefer handoff_write. Write or refresh the canonical phase handoff. Capture full design context, not just operational resume steps: pass extraSections with locked decisions, architecture (with file:line refs), mode/state flows, plugin/API contracts, data mappings, files touched, and known gaps so a resuming agent doesn't re-discover decisions already made. IMPORTANT: write the handoff on the phase the user explicitly identifies as the one just worked on in this session; do not default to a stale 'current phase' pointer or an existing handoff on a different phase.",
2875
2877
  parameters: Type.Object({
2876
2878
  reason: Type.Optional(Type.String({ description: "Why the handoff is being written" })),
2879
+ title: Type.Optional(Type.String({ description: "Meaningful handoff title summarizing the work (becomes the H1 / first line in lists). Example: 'P049 — featureId validation: tests + adapter wiring'." })),
2877
2880
  whatWasBeingDone: Type.Optional(Type.String({ description: "Optional override for the current work summary" })),
2878
2881
  howToResume: Type.Optional(Type.String({ description: "Optional override for resume instructions" })),
2879
2882
  extraSections: Type.Optional(Type.Array(Type.Object({
@@ -2886,6 +2889,7 @@ export default function planPiExtension(pi) {
2886
2889
  if (!st)
2887
2890
  return { content: [{ type: "text", text: "No .planner/ found." }], details: {} };
2888
2891
  const markdown = await buildHandoffMarkdown(st, params.reason?.trim() || "manual tool handoff", {
2892
+ ...(params.title?.trim() ? { title: params.title.trim() } : {}),
2889
2893
  ...(params.whatWasBeingDone?.trim() ? { whatWasBeingDone: params.whatWasBeingDone.trim() } : {}),
2890
2894
  ...(params.howToResume?.trim() ? { howToResume: params.howToResume.trim() } : {}),
2891
2895
  ...(params.extraSections && params.extraSections.length > 0
@@ -2922,6 +2926,9 @@ export default function planPiExtension(pi) {
2922
2926
  // Resolve a phase for entity-scoped handoff tools. ref = P00x | P00x(F00x) |
2923
2927
  // UUID | title; omitted -> current in-progress phase (phase.status, or the
2924
2928
  // phase containing an in-progress task). Returns the phase + its composite ref.
2929
+ // NOTE: callers must NOT treat the resolved phase as a directive; it is a
2930
+ // fallback pointer that may be stale if the agent worked on a different
2931
+ // workstream in this session.
2925
2932
  async function resolvePhaseForHandoff(st, ref) {
2926
2933
  const phases = await st.loadAllPhases();
2927
2934
  const features = (await st.loadFeatures()).features;
@@ -2981,9 +2988,10 @@ export default function planPiExtension(pi) {
2981
2988
  pi.registerTool({
2982
2989
  name: "handoff_write",
2983
2990
  label: "Handoff Write",
2984
- description: "Write/refresh the entity-scoped handoff on a phase. Pass content (or markdown_content). phaseRef optional (default: current in-progress phase). Captures design context for a resuming agent on that phase.",
2991
+ description: "Write/refresh the entity-scoped handoff on a phase. Pass content (or markdown_content) AND a meaningful `title` summarizing the work (e.g. 'P049 — featureId validation: tests + adapter wiring'). The title becomes the H1 and the first line shown in handoff lists; generic titles like 'Handoff' or 'Canonical handoff' are REJECTED. phaseRef optional (default: current in-progress phase). IMPORTANT: defaulting to 'current in-progress phase' is a fallback only; write the handoff on the phase the user explicitly identifies as the one just worked on in this session, and do not update an existing handoff on a different phase unless the user confirms.",
2985
2992
  parameters: Type.Object({
2986
2993
  phaseRef: Type.Optional(Type.String({ description: "Phase ref. Default: current in-progress phase." })),
2994
+ title: Type.Optional(Type.String({ description: "Meaningful handoff title summarizing the work (becomes the H1 / first line in lists). REQUIRED if your markdown's first heading is generic. Example: 'P049 — featureId validation: tests + adapter wiring'." })),
2987
2995
  content: Type.Optional(Type.String({ description: "Handoff text (plain)." })),
2988
2996
  markdown_content: Type.Optional(Type.String({ description: "Handoff text (markdown). Preferred over content." })),
2989
2997
  }),
@@ -2991,9 +2999,32 @@ export default function planPiExtension(pi) {
2991
2999
  const st = await requirePlan(ctx);
2992
3000
  if (!st)
2993
3001
  return { content: [{ type: "text", text: "No .planner/ found." }], details: {} };
2994
- const body = (params.markdown_content ?? params.content ?? "").trim();
3002
+ let body = (params.markdown_content ?? params.content ?? "").trim();
2995
3003
  if (!body)
2996
3004
  return { content: [{ type: "text", text: "❌ Provide the handoff text (content or markdown_content)." }], details: { error: "empty text" } };
3005
+ const title = params.title?.trim();
3006
+ // Derive the current first non-empty line (H1) of the supplied body.
3007
+ const firstLine = body.split(/\r?\n/).find((l) => l.trim().length > 0) ?? "";
3008
+ const firstHeadingText = firstLine.replace(/^#+\s*/, "").trim();
3009
+ const isGeneric = !firstHeadingText || /^(handoff|canonical handoff|session handoff)$/i.test(firstHeadingText);
3010
+ if (!title && isGeneric) {
3011
+ return {
3012
+ content: [{ type: "text", text: "❌ Generic handoff title. Provide a meaningful `title` (or start your markdown with a descriptive H1) summarizing the work — e.g. 'P049 — featureId validation: tests + adapter wiring'. Generic titles like 'Handoff' or 'Canonical handoff' are not accepted." }],
3013
+ details: { error: "generic title", firstHeadingText },
3014
+ };
3015
+ }
3016
+ // Normalize: if a title is provided, replace or prepend the H1 so the first line is the title.
3017
+ if (title) {
3018
+ const lines = body.split(/\r?\n/);
3019
+ const firstIdx = lines.findIndex((l) => l.trim().length > 0);
3020
+ if (firstIdx !== -1 && /^#+\s/.test(lines[firstIdx] ?? "")) {
3021
+ lines[firstIdx] = `# ${title}`;
3022
+ body = lines.join("\n");
3023
+ }
3024
+ else {
3025
+ body = `# ${title}\n\n${body}`;
3026
+ }
3027
+ }
2997
3028
  const r = await resolvePhaseForHandoff(st, params.phaseRef);
2998
3029
  if (!r.ok)
2999
3030
  return { content: [{ type: "text", text: `❌ ${r.error}` }], details: { error: r.error } };
@@ -3014,7 +3045,7 @@ export default function planPiExtension(pi) {
3014
3045
  if (!r.ok)
3015
3046
  return { content: [{ type: "text", text: `❌ ${r.error}` }], details: { error: r.error } };
3016
3047
  await st.clearPhaseHandoff(r.phase.id, "manual");
3017
- return { content: [{ type: "text", text: `✅ Cleared handoff on ${r.compositeRef} (handoffUpdatedAt preserved as audit; archived to .planner/handoff-archive/).` }], details: { phaseRef: r.compositeRef, phaseId: r.phase.id } };
3048
+ return { content: [{ type: "text", text: `✅ Cleared handoff on ${r.compositeRef} (handoffUpdatedAt preserved as audit; archived to .planner/.local/handoff-archive/).` }], details: { phaseRef: r.compositeRef, phaseId: r.phase.id } };
3018
3049
  },
3019
3050
  });
3020
3051
  pi.registerTool({
@@ -3639,6 +3670,7 @@ export default function planPiExtension(pi) {
3639
3670
  label: "Task Create",
3640
3671
  description: "Add a task to a phase with a RICH description. REQUIRED: description must include code references (file:line), what already exists vs what needs to be built, specific structs/traits/systems to modify, concrete implementation steps, and edge cases to handle. The description is the execution context for agents; one-liners cause misalignment. Status defaults to planned.",
3641
3672
  parameters: Type.Object({
3673
+ featureId: Type.String({ description: "Feature ID the phase belongs to (required)" }),
3642
3674
  phaseId: Type.String({ description: "Phase ID the task belongs to" }),
3643
3675
  title: Type.String({ description: "Task title" }),
3644
3676
  description: Type.String({ description: "REQUIRED — execution context: code references (file:line), current state vs desired state, structs/traits to modify, concrete implementation steps, edge cases. Not a one-liner. Prefix with 'design-only' for pre-implementation design tasks.", minLength: 50 }),
@@ -3650,11 +3682,25 @@ export default function planPiExtension(pi) {
3650
3682
  const st = await requirePlan(ctx);
3651
3683
  if (!st)
3652
3684
  return { content: [{ type: "text", text: "No .planner/ found." }], details: {} };
3653
- // Resolve the phase ref (accepts F00x/P00x, bare P00x, shortId, UUID, title).
3685
+ if (!params.featureId?.trim())
3686
+ return { content: [{ type: "text", text: "featureId is required: a task must belong to a feature." }], details: {} };
3654
3687
  const features = (await st.loadFeatures()).features;
3688
+ const resolvedFeature = resolveFeatureRefStrict(features, params.featureId.trim());
3689
+ if (!resolvedFeature.ok)
3690
+ return { content: [{ type: "text", text: resolvedFeature.error }], details: {} };
3691
+ const featureValidation = await validateResolvedTarget("feature", resolvedFeature.feature.id, () => st.loadFeatures().then((doc) => doc.features.find((f) => f.id === resolvedFeature.feature.id)).catch(() => undefined));
3692
+ if (!featureValidation.ok)
3693
+ return { content: [{ type: "text", text: featureValidation.error }], details: {} };
3694
+ const feature = resolvedFeature.feature;
3695
+ const existingFeature = features.find((f) => f.id === feature.id);
3696
+ if (!existingFeature)
3697
+ return { content: [{ type: "text", text: `Resolved feature ${feature.id} no longer exists. Refusing to create task.` }], details: {} };
3698
+ // Resolve the phase ref (accepts F00x/P00x, bare P00x, shortId, UUID, title).
3655
3699
  const resolvedPhase = findPhaseByRef(await st.loadAllPhases(), features, params.phaseId.trim());
3656
3700
  if (!resolvedPhase)
3657
3701
  return { content: [{ type: "text", text: `Phase not found: ${params.phaseId}` }], details: {} };
3702
+ if (resolvedPhase.featureId !== feature.id)
3703
+ return { content: [{ type: "text", text: `Phase ${formatPhaseRef(resolvedPhase.number, featureNumberOfPhase(resolvedPhase, features))} does not belong to feature ${formatFeatureRef(feature.number)}. Refusing to create task.` }], details: {} };
3658
3704
  const phaseId = resolvedPhase.id;
3659
3705
  const phaseValidation = await validateResolvedTarget("phase", phaseId, () => st.loadPhase(phaseId).catch(() => undefined));
3660
3706
  if (!phaseValidation.ok)
@@ -3695,7 +3741,8 @@ export default function planPiExtension(pi) {
3695
3741
  return phase;
3696
3742
  });
3697
3743
  await st.writeGenerated();
3698
- return { content: [{ type: "text", text: `Task created: ${taskId}` }], details: task };
3744
+ const taskRef = `${formatPhaseRef(resolvedPhase.number, feature.number)}/T${String(task.number).padStart(3, "0")}`;
3745
+ return { content: [{ type: "text", text: `Task created: ${taskRef} — ${task.title}${task.shortId ? ` · ${task.shortId}` : ""}` }], details: task };
3699
3746
  },
3700
3747
  });
3701
3748
  pi.registerTool({
@@ -3848,7 +3895,9 @@ export default function planPiExtension(pi) {
3848
3895
  await st.writeGenerated();
3849
3896
  if (!startedTask)
3850
3897
  return { content: [{ type: "text", text: `Task not found: ${params.taskId}` }], details: {} };
3851
- return { content: [{ type: "text", text: `✅ Task started: ${startedTask.id} — ${startedTask.title} (in-progress)` }], details: startedTask };
3898
+ const parentFeature = found.phase.featureId ? features.find((f) => f.id === found.phase.featureId) : undefined;
3899
+ const phaseContext = buildPhaseContextBlock(found.phase, parentFeature);
3900
+ return { content: [{ type: "text", text: `✅ Task started: ${startedTask.id} — ${startedTask.title} (in-progress)${phaseContext}` }], details: startedTask };
3852
3901
  },
3853
3902
  });
3854
3903
  pi.registerTool({
@@ -4289,16 +4338,18 @@ export default function planPiExtension(pi) {
4289
4338
  openQuestions.length ? "Open questions:" : "",
4290
4339
  ...openQuestions.map((question) => `- ${question}`),
4291
4340
  "",
4292
- "Resume focus:",
4293
- currentFeatureRef ? ` current feature: ${currentFeatureRef} — ${currentFeature?.name}` : " current feature: (none)",
4294
- currentPhaseRef ? ` current phase: ${currentPhaseRef} — ${currentPhase?.title}` : " current phase: (none)",
4295
- currentTaskRef ? ` current task: ${currentTaskRef} — ${currentTask?.title}` : " current task: (none)",
4341
+ "Resume focus (stale/fallback pointer — may not match the phase you actually worked on in this session):",
4342
+ currentFeatureRef ? ` current feature pointer: ${currentFeatureRef} — ${currentFeature?.name}` : " current feature pointer: (none)",
4343
+ currentPhaseRef ? ` current phase pointer: ${currentPhaseRef} — ${currentPhase?.title}` : " current phase pointer: (none)",
4344
+ currentTaskRef ? ` current task pointer: ${currentTaskRef} — ${currentTask?.title}` : " current task pointer: (none)",
4296
4345
  inProgressTaskLines.length ? ` in-progress tasks: ${inProgressTaskLines.join("; ")}` : " in-progress tasks: (none)",
4297
4346
  resume.blockers.length ? ` blockers: ${resume.blockers.join("; ")}` : " blockers: (none)",
4298
4347
  handoffs.length === 0 && resume.nextSteps.length
4299
4348
  ? ` next step: ${resume.nextSteps[0]}${resume.nextStepsUpdatedAt ? ` (updated ${resume.nextStepsUpdatedAt})` : ""}`
4300
4349
  : "",
4301
4350
  "",
4351
+ "CRITICAL: The 'Resume focus' pointers above are persisted across sessions. They are NOT necessarily the phase you worked on right now. When asked to write a handoff, use the phase the user explicitly identifies as the one just completed in this session, not a stale pointer.",
4352
+ "",
4302
4353
  "Phase overview:",
4303
4354
  ` counts: ${phaseCountsSummary}`,
4304
4355
  currentPhaseRef ? ` current: ${currentPhaseRef} — ${currentPhase?.title} (${currentPhase?.status})` : " current: (none)",
@@ -4308,9 +4359,9 @@ export default function planPiExtension(pi) {
4308
4359
  recentActivity.length ? "Recent activity:" : "",
4309
4360
  ...recentActivity.map((entry) => `- ${entry.at} [${entry.type}] ${entry.ref}: ${entry.summary}`),
4310
4361
  "",
4311
- handoffs.length > 0 ? `Pending phase handoffs (${handoffs.length}):` : "",
4362
+ handoffs.length > 0 ? "Pending phase handoffs (entity-scoped; may be on a stale phase — validate before treating as current focus):" : "",
4312
4363
  ...handoffs.map((handoff, index) => ` [${index + 1}] ${handoff.compositeRef} — ${handoff.updatedAt} — "${handoff.firstLine}"`),
4313
- handoffs.length > 0 ? "Use handoff show <ref>; if no task is active, treat the handoff target as a candidate to validate, not the current focus." : "",
4364
+ handoffs.length > 0 ? "Use handoff show <ref> for context. A pending handoff is a candidate to validate; do not default to it as the current focus unless it matches the phase you actually worked on in this session." : "",
4314
4365
  "",
4315
4366
  `Language: content=${project.contentLanguage || "(not set)"}; chat=${project.chatLanguage || "(not set)"}`,
4316
4367
  "Planner discuss mode is Agent Plan only: ignore GSD workflows unless the user explicitly asks for GSD.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-plan/pi-adapter",
3
- "version": "0.2.19-next.18",
3
+ "version": "0.2.19-next.19",
4
4
  "private": false,
5
5
  "description": "Pi agent extension for Agent Plan — structured project planning in .planner/",
6
6
  "keywords": [
@@ -28,8 +28,8 @@
28
28
  "dependencies": {
29
29
  "typebox": "^1.1.24",
30
30
  "zod": "^3.24.0",
31
- "@agent-plan/server": "0.2.19-next.18",
32
- "@agent-plan/core": "0.2.19-next.18"
31
+ "@agent-plan/core": "0.2.19-next.19",
32
+ "@agent-plan/server": "0.2.19-next.19"
33
33
  },
34
34
  "devDependencies": {
35
35
  "@earendil-works/pi-coding-agent": "^0.74.0",
@@ -0,0 +1 @@
1
+ @import"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800;900&family=JetBrains+Mono:wght@400;500;600;700&display=swap";/*! tailwindcss v4.3.1 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-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-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-700:oklch(55.5% .163 48.998);--color-emerald-400:oklch(76.5% .177 163.223);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-600:oklch(59.6% .145 163.225);--color-sky-400:oklch(74.6% .16 232.661);--color-sky-500:oklch(68.5% .169 237.323);--color-sky-700:oklch(50% .134 242.749);--color-rose-400:oklch(71.2% .194 13.428);--color-rose-500:oklch(64.5% .246 16.439);--color-rose-600:oklch(58.6% .253 17.585);--color-rose-700:oklch(51.4% .222 16.935);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-md:28rem;--container-2xl:42rem;--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);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--font-weight-black:900;--tracking-tight:-.025em;--tracking-wide:.025em;--tracking-wider:.05em;--leading-snug:1.375;--radius-md:.375rem;--radius-lg:.5rem;--radius-2xl:1rem;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--blur-sm:8px;--blur-xl:24px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--color-status-draft:#94a3b8;--color-status-discovery:#6366f1;--color-status-planned:#0ea5e9;--color-status-in-progress:#f59e0b;--color-status-done:#22c55e;--color-status-blocked:#ef4444;--color-status-canceled:#94a3b8;--color-status-waiting:#64748b;--color-status-deferred:#8b5cf6;--color-status-rejected:#f43f5e;--color-status-started:#6366f1;--color-status-closed:#0d9488}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.top-0{top:0}.top-1\/2{top:50%}.top-full{top:100%}.right-0{right:0}.right-2\.5{right:calc(var(--spacing) * 2.5)}.right-3{right:calc(var(--spacing) * 3)}.bottom-0{bottom:0}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.z-50{z-index:50}.z-\[200\]{z-index:200}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mt-0{margin-top:0}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.mt-1{margin-top:var(--spacing)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-6{margin-top:calc(var(--spacing) * 6)}.mb-1{margin-bottom:var(--spacing)}.mb-6{margin-bottom:calc(var(--spacing) * 6)}.mb-8{margin-bottom:calc(var(--spacing) * 8)}.ml-1{margin-left:var(--spacing)}.ml-1\.5{margin-left:calc(var(--spacing) * 1.5)}.ml-2{margin-left:calc(var(--spacing) * 2)}.ml-4{margin-left:calc(var(--spacing) * 4)}.line-clamp-2{-webkit-line-clamp:2;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-2{height:calc(var(--spacing) * 2)}.h-2\.5{height:calc(var(--spacing) * 2.5)}.h-3{height:calc(var(--spacing) * 3)}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-11{height:calc(var(--spacing) * 11)}.max-h-\[32dvh\]{max-height:32dvh}.max-h-\[35vh\]{max-height:35vh}.max-h-\[calc\(100vh-2rem\)\]{max-height:calc(100vh - 2rem)}.min-h-0{min-height:0}.min-h-8{min-height:calc(var(--spacing) * 8)}.min-h-9{min-height:calc(var(--spacing) * 9)}.min-h-full{min-height:100%}.min-h-screen{min-height:100vh}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-2{width:calc(var(--spacing) * 2)}.w-2\.5{width:calc(var(--spacing) * 2.5)}.w-3{width:calc(var(--spacing) * 3)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-8{width:calc(var(--spacing) * 8)}.w-9{width:calc(var(--spacing) * 9)}.w-10{width:calc(var(--spacing) * 10)}.w-11{width:calc(var(--spacing) * 11)}.w-\[1px\]{width:1px}.w-full{width:100%}.max-w-2xl{max-width:var(--container-2xl)}.max-w-3xl{max-width:var(--container-3xl)}.max-w-4xl{max-width:var(--container-4xl)}.max-w-full{max-width:100%}.max-w-md{max-width:var(--container-md)}.max-w-none{max-width:none}.min-w-0{min-width:0}.min-w-44{min-width:calc(var(--spacing) * 44)}.min-w-\[7\.5rem\]{min-width:7.5rem}.flex-1{flex:1}.shrink-0{flex-shrink:0}.-translate-y-1\/2{--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-0{rotate:0deg}.rotate-90{rotate:90deg}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.animate-pulse{animation:var(--animate-pulse)}.cursor-not-allowed{cursor:not-allowed}.cursor-pointer{cursor:pointer}.resize{resize:both}.scroll-mt-20{scroll-margin-top:calc(var(--spacing) * 20)}.list-decimal{list-style-type:decimal}.list-disc{list-style-type:disc}.list-none{list-style-type:none}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.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-between{justify-content:space-between}.justify-center{justify-content:center}.justify-end{justify-content:flex-end}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-8{gap:calc(var(--spacing) * 8)}.gap-x-3{column-gap:calc(var(--spacing) * 3)}.gap-y-1{row-gap:var(--spacing)}.self-end{align-self:flex-end}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-visible{overflow:visible}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-\[8px\]{border-radius:8px}.rounded-\[10px\]{border-radius:10px}.rounded-\[12px\]{border-radius:12px}.rounded-\[14px\]{border-radius:14px}.rounded-\[16px\]{border-radius:16px}.rounded-\[18px\]{border-radius:18px}.rounded-\[24px\]{border-radius:24px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{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-dashed{--tw-border-style:dashed;border-style:dashed}.border-\[color\:color-mix\(in_srgb\,var\(--color-status-done\)_0\%\,transparent\)\]{border-color:#0000}@supports (color:color-mix(in lab,red,red)){.border-\[color\:color-mix\(in_srgb\,var\(--color-status-done\)_0\%\,transparent\)\]{border-color:color-mix(in srgb,var(--color-status-done) 0%,transparent)}}.border-\[var\(--accent\)\]{border-color:var(--accent)}.border-\[var\(--border\)\]{border-color:var(--border)}.border-\[var\(--border-strong\)\]{border-color:var(--border-strong)}.border-\[var\(--danger-soft\)\]{border-color:var(--danger-soft)}.border-amber-500\/30{border-color:#f99c004d}@supports (color:color-mix(in lab,red,red)){.border-amber-500\/30{border-color:color-mix(in oklab,var(--color-amber-500) 30%,transparent)}}.border-emerald-500\/30{border-color:#00bb7f4d}@supports (color:color-mix(in lab,red,red)){.border-emerald-500\/30{border-color:color-mix(in oklab,var(--color-emerald-500) 30%,transparent)}}.border-rose-500\/30{border-color:#ff23574d}@supports (color:color-mix(in lab,red,red)){.border-rose-500\/30{border-color:color-mix(in oklab,var(--color-rose-500) 30%,transparent)}}.border-sky-500\/30{border-color:#00a5ef4d}@supports (color:color-mix(in lab,red,red)){.border-sky-500\/30{border-color:color-mix(in oklab,var(--color-sky-500) 30%,transparent)}}.border-transparent{border-color:#0000}.bg-\[color\:color-mix\(in_srgb\,var\(--accent\)_8\%\,transparent\)\]{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.bg-\[color\:color-mix\(in_srgb\,var\(--accent\)_8\%\,transparent\)\]{background-color:color-mix(in srgb,var(--accent) 8%,transparent)}}.bg-\[color\:color-mix\(in_srgb\,var\(--accent\)_10\%\,transparent\)\]{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.bg-\[color\:color-mix\(in_srgb\,var\(--accent\)_10\%\,transparent\)\]{background-color:color-mix(in srgb,var(--accent) 10%,transparent)}}.bg-\[color\:color-mix\(in_srgb\,var\(--accent\)_12\%\,transparent\)\]{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.bg-\[color\:color-mix\(in_srgb\,var\(--accent\)_12\%\,transparent\)\]{background-color:color-mix(in srgb,var(--accent) 12%,transparent)}}.bg-\[color\:color-mix\(in_srgb\,var\(--accent\)_16\%\,transparent\)\]{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.bg-\[color\:color-mix\(in_srgb\,var\(--accent\)_16\%\,transparent\)\]{background-color:color-mix(in srgb,var(--accent) 16%,transparent)}}.bg-\[color\:color-mix\(in_srgb\,var\(--accent\)_18\%\,transparent\)\]{background-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.bg-\[color\:color-mix\(in_srgb\,var\(--accent\)_18\%\,transparent\)\]{background-color:color-mix(in srgb,var(--accent) 18%,transparent)}}.bg-\[var\(--accent\)\]{background-color:var(--accent)}.bg-\[var\(--accent-soft\)\]{background-color:var(--accent-soft)}.bg-\[var\(--border\)\]{background-color:var(--border)}.bg-\[var\(--danger-soft\)\],.bg-\[var\(--danger-soft\)\]\/50{background-color:var(--danger-soft)}@supports (color:color-mix(in lab,red,red)){.bg-\[var\(--danger-soft\)\]\/50{background-color:color-mix(in oklab,var(--danger-soft) 50%,transparent)}}.bg-\[var\(--surface\)\]{background-color:var(--surface)}.bg-\[var\(--surface-card\)\]{background-color:var(--surface-card)}.bg-\[var\(--surface-elevated\)\],.bg-\[var\(--surface-elevated\)\]\/95{background-color:var(--surface-elevated)}@supports (color:color-mix(in lab,red,red)){.bg-\[var\(--surface-elevated\)\]\/95{background-color:color-mix(in oklab,var(--surface-elevated) 95%,transparent)}}.bg-amber-500{background-color:var(--color-amber-500)}.bg-amber-500\/10{background-color:#f99c001a}@supports (color:color-mix(in lab,red,red)){.bg-amber-500\/10{background-color:color-mix(in oklab,var(--color-amber-500) 10%,transparent)}}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab,red,red)){.bg-black\/50{background-color:color-mix(in oklab,var(--color-black) 50%,transparent)}}.bg-current{background-color:currentColor}.bg-emerald-500{background-color:var(--color-emerald-500)}.bg-emerald-500\/10{background-color:#00bb7f1a}@supports (color:color-mix(in lab,red,red)){.bg-emerald-500\/10{background-color:color-mix(in oklab,var(--color-emerald-500) 10%,transparent)}}.bg-rose-500{background-color:var(--color-rose-500)}.bg-rose-500\/10{background-color:#ff23571a}@supports (color:color-mix(in lab,red,red)){.bg-rose-500\/10{background-color:color-mix(in oklab,var(--color-rose-500) 10%,transparent)}}.bg-sky-500{background-color:var(--color-sky-500)}.bg-sky-500\/10{background-color:#00a5ef1a}@supports (color:color-mix(in lab,red,red)){.bg-sky-500\/10{background-color:color-mix(in oklab,var(--color-sky-500) 10%,transparent)}}.bg-transparent{background-color:#0000}.p-0{padding:0}.p-1{padding:var(--spacing)}.p-3{padding:calc(var(--spacing) * 3)}.p-4{padding:calc(var(--spacing) * 4)}.p-6{padding:calc(var(--spacing) * 6)}.px-0{padding-inline:0}.px-1{padding-inline:var(--spacing)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-8{padding-inline:calc(var(--spacing) * 8)}.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)}.py-5{padding-block:calc(var(--spacing) * 5)}.py-8{padding-block:calc(var(--spacing) * 8)}.py-12{padding-block:calc(var(--spacing) * 12)}.pt-0\.5{padding-top:calc(var(--spacing) * .5)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pr-1{padding-right:var(--spacing)}.pr-6{padding-right:calc(var(--spacing) * 6)}.pr-8{padding-right:calc(var(--spacing) * 8)}.pb-1{padding-bottom:var(--spacing)}.pl-1{padding-left:var(--spacing)}.pl-3{padding-left:calc(var(--spacing) * 3)}.pl-4{padding-left:calc(var(--spacing) * 4)}.pl-5{padding-left:calc(var(--spacing) * 5)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[0\.95em\]{font-size:.95em}.text-\[10\.5px\]{font-size:10.5px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-6{--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6)}.leading-none{--tw-leading:1;line-height:1}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-black{--tw-font-weight:var(--font-weight-black);font-weight:var(--font-weight-black)}.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-\[0\.12em\]{--tw-tracking:.12em;letter-spacing:.12em}.tracking-\[0\.16em\]{--tw-tracking:.16em;letter-spacing:.16em}.tracking-\[0\.18em\]{--tw-tracking:.18em;letter-spacing:.18em}.tracking-\[0\.22em\]{--tw-tracking:.22em;letter-spacing:.22em}.tracking-\[0\.24em\]{--tw-tracking:.24em;letter-spacing:.24em}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.\[overflow-wrap\:anywhere\]{overflow-wrap:anywhere}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[var\(--accent\)\]{color:var(--accent)}.text-\[var\(--color-status-blocked\)\]{color:var(--color-status-blocked)}.text-\[var\(--text\)\]{color:var(--text)}.text-\[var\(--text-muted\)\]{color:var(--text-muted)}.text-\[var\(--text-subtle\)\]{color:var(--text-subtle)}.text-amber-600{color:var(--color-amber-600)}.text-amber-700{color:var(--color-amber-700)}.text-emerald-500{color:var(--color-emerald-500)}.text-emerald-600{color:var(--color-emerald-600)}.text-rose-600{color:var(--color-rose-600)}.text-rose-700{color:var(--color-rose-700)}.text-sky-700{color:var(--color-sky-700)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.italic{font-style:italic}.line-through{text-decoration-line:line-through}.underline-offset-2{text-underline-offset:2px}.underline-offset-4{text-underline-offset:4px}.accent-\[var\(--accent\)\]{accent-color:var(--accent)}.opacity-60{opacity:.6}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px 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-\[color\:color-mix\(in_srgb\,var\(--accent\)_55\%\,transparent\)\]{--tw-ring-color:var(--accent)}@supports (color:color-mix(in lab,red,red)){.ring-\[color\:color-mix\(in_srgb\,var\(--accent\)_55\%\,transparent\)\]{--tw-ring-color:color-mix(in srgb,var(--accent) 55%,transparent)}}.grayscale{--tw-grayscale:grayscale(100%);filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.backdrop-blur-xl{--tw-backdrop-blur:blur(var(--blur-xl));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.backdrop-saturate-150{--tw-backdrop-saturate:saturate(150%);-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.group-open\:rotate-180:is(:where(.group):is([open],:popover-open,:open) *){rotate:180deg}@media(hover:hover){.group-hover\:border-\[var\(--accent\)\]:is(:where(.group):hover *){border-color:var(--accent)}.group-hover\:text-\[var\(--accent\)\]:is(:where(.group):hover *){color:var(--accent)}.hover\:border-\[var\(--accent\)\]:hover{border-color:var(--accent)}.hover\:bg-\[color-mix\(in_srgb\,var\(--danger-soft\)_88\%\,black_12\%\)\]:hover{background-color:var(--danger-soft)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-\[color-mix\(in_srgb\,var\(--danger-soft\)_88\%\,black_12\%\)\]:hover{background-color:color-mix(in srgb,var(--danger-soft) 88%,black 12%)}}.hover\:bg-\[var\(--accent\)\]:hover{background-color:var(--accent)}.hover\:bg-\[var\(--accent-hover\)\]:hover{background-color:var(--accent-hover)}.hover\:bg-\[var\(--accent-soft\)\]:hover{background-color:var(--accent-soft)}.hover\:bg-\[var\(--surface-card\)\]:hover{background-color:var(--surface-card)}.hover\:bg-\[var\(--surface-elevated\)\]:hover,.hover\:bg-\[var\(--surface-elevated\)\]\/65:hover{background-color:var(--surface-elevated)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-\[var\(--surface-elevated\)\]\/65:hover{background-color:color-mix(in oklab,var(--surface-elevated) 65%,transparent)}}.hover\:bg-\[var\(--surface-hover\)\]\/60:hover{background-color:var(--surface-hover)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-\[var\(--surface-hover\)\]\/60:hover{background-color:color-mix(in oklab,var(--surface-hover) 60%,transparent)}}.hover\:bg-\[var\(--surface-strong\)\]:hover{background-color:var(--surface-strong)}.hover\:text-\[var\(--accent\)\]:hover{color:var(--accent)}.hover\:text-\[var\(--text\)\]:hover{color:var(--text)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-90:hover{opacity:.9}}.focus-visible\:bg-\[var\(--surface-hover\)\]\/60:focus-visible{background-color:var(--surface-hover)}@supports (color:color-mix(in lab,red,red)){.focus-visible\:bg-\[var\(--surface-hover\)\]\/60:focus-visible{background-color:color-mix(in oklab,var(--surface-hover) 60%,transparent)}}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus-visible\:ring-\[var\(--accent\)\]:focus-visible{--tw-ring-color:var(--accent)}.focus-visible\:ring-offset-2:focus-visible{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus-visible\:ring-offset-\[var\(--surface\)\]:focus-visible{--tw-ring-offset-color:var(--surface)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:cursor-wait:disabled{cursor:wait}.disabled\:opacity-60:disabled{opacity:.6}@media(prefers-reduced-motion:reduce){.motion-reduce\:transition-none{transition-property:none}}@media(min-width:40rem){.sm\:ml-4{margin-left:calc(var(--spacing) * 4)}.sm\:flex{display:flex}.sm\:hidden{display:none}.sm\:inline{display:inline}.sm\:inline-block{display:inline-block}.sm\:h-11{height:calc(var(--spacing) * 11)}.sm\:min-h-9{min-height:calc(var(--spacing) * 9)}.sm\:min-h-11{min-height:calc(var(--spacing) * 11)}.sm\:w-11{width:calc(var(--spacing) * 11)}.sm\:w-auto{width:auto}.sm\:flex-1{flex:1}.sm\:shrink-0{flex-shrink:0}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.sm\:flex-row{flex-direction:row}.sm\:items-end{align-items:flex-end}.sm\:items-start{align-items:flex-start}.sm\:justify-between{justify-content:space-between}.sm\:gap-2{gap:calc(var(--spacing) * 2)}.sm\:gap-3{gap:calc(var(--spacing) * 3)}.sm\:gap-4{gap:calc(var(--spacing) * 4)}.sm\:truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.sm\:rounded-\[14px\]{border-radius:14px}.sm\:rounded-\[18px\]{border-radius:18px}.sm\:p-4{padding:calc(var(--spacing) * 4)}.sm\:px-3{padding-inline:calc(var(--spacing) * 3)}.sm\:px-4{padding-inline:calc(var(--spacing) * 4)}.sm\:py-2{padding-block:calc(var(--spacing) * 2)}.sm\:py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.sm\:py-3{padding-block:calc(var(--spacing) * 3)}.sm\:pl-4{padding-left:calc(var(--spacing) * 4)}.sm\:text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}}@media(min-width:48rem){.md\:col-span-4{grid-column:span 4/span 4}.md\:max-h-\[calc\(100vh-3rem\)\]{max-height:calc(100vh - 3rem)}.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-\[minmax\(0\,1fr\)_200px_auto_auto\]{grid-template-columns:minmax(0,1fr) 200px auto auto}.md\:flex-row{flex-direction:row}.md\:items-center{align-items:center}.md\:items-end{align-items:flex-end}.md\:items-start{align-items:flex-start}.md\:justify-between{justify-content:space-between}.md\:justify-end{justify-content:flex-end}.md\:gap-6{gap:calc(var(--spacing) * 6)}.md\:p-6{padding:calc(var(--spacing) * 6)}.md\:p-8{padding:calc(var(--spacing) * 8)}.md\:text-3xl{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height))}}@media(min-width:64rem){.lg\:block{display:block}.lg\:contents{display:contents}.lg\:hidden{display:none}.lg\:w-auto{width:auto}.lg\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.lg\:grid-cols-6{grid-template-columns:repeat(6,minmax(0,1fr))}.lg\:grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,150px\)_124px_44px_44px\]{grid-template-columns:minmax(0,1fr) minmax(0,150px) 124px 44px 44px}.lg\:grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,168px\)_124px_44px_44px\]{grid-template-columns:minmax(0,1fr) minmax(0,168px) 124px 44px 44px}.lg\:items-center{align-items:center}}@media(min-width:80rem){.xl\:block{display:block}.xl\:contents{display:contents}.xl\:hidden{display:none}.xl\:w-auto{width:auto}.xl\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}.xl\:grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.xl\:grid-cols-\[minmax\(0\,1fr\)_minmax\(0\,132px\)_minmax\(0\,152px\)_124px_44px_44px\]{grid-template-columns:minmax(0,1fr) minmax(0,132px) minmax(0,152px) 124px 44px 44px}.xl\:items-center{align-items:center}}@media(prefers-color-scheme:dark){.dark\:text-amber-400{color:var(--color-amber-400)}.dark\:text-emerald-400{color:var(--color-emerald-400)}.dark\:text-rose-400{color:var(--color-rose-400)}.dark\:text-sky-400{color:var(--color-sky-400)}}.\[\&\:\:-webkit-details-marker\]\:hidden::-webkit-details-marker{display:none}}:root{--font-sans:"Inter", ui-sans-serif, system-ui, sans-serif;--font-mono:"JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;--radius-panel:24px;--radius-card:20px;--radius-input:14px;--container-width:1180px;--surface-blur:18px;--bg-base:#f8fafc;--bg-gradient-a:#3b82f62e;--bg-gradient-b:#8b5cf629;--surface:#ffffffc2;--surface-strong:#ffffffe6;--surface-elevated:#fffffffa;--border:#94a3b838;--border-strong:#94a3b857;--text:#0f172a;--text-muted:#475569;--text-subtle:#64748b;--accent:#6366f1;--accent-soft:#6366f124;--accent-hover:#4f46e5;--danger-soft:#ef44441f;--color-entity-feature:#8b5cf6;--color-entity-phase:#06b6d4;--color-entity-task:#10b981;--shadow-panel:0 20px 60px -24px #0f172a38;--shadow-card:0 12px 30px -18px #0f172a2e;color-scheme:light}[data-theme=dark]{--bg-base:#08111f;--bg-gradient-a:#3b82f61f;--bg-gradient-b:#8b5cf624;--surface:#0f172abd;--surface-strong:#0f172ae0;--surface-elevated:#0f172af5;--border:#94a3b824;--border-strong:#94a3b847;--text:#f8fafc;--text-muted:#94a3b8;--text-subtle:#64748b;--accent:#818cf8;--accent-soft:#818cf829;--accent-hover:#6366f1;--danger-soft:#ef44442e;--color-entity-feature:#a78bfa;--color-entity-phase:#22d3ee;--color-entity-task:#34d399;--shadow-panel:0 20px 60px -24px #0009;--shadow-card:0 12px 30px -18px #0000006b;color-scheme:dark}*,:before,:after{box-sizing:border-box}html,body,#root{min-height:100%}body{font-family:var(--font-sans);color:var(--text);background-color:var(--bg-base);background-image:radial-gradient(50% 55% at 0% 0%,var(--bg-gradient-a) 0%,transparent 70%),radial-gradient(42% 48% at 100% 0%,var(--bg-gradient-b) 0%,transparent 64%);-webkit-font-smoothing:antialiased;background-attachment:fixed;margin:0;line-height:1.5}button,input,select,textarea{font:inherit}a{color:inherit;text-decoration:none}.page-shell{min-height:100vh}.page-container{width:min(100% - 3rem,var(--container-width));margin-inline:auto}.grid>*,.formatted-text{min-width:0}.formatted-text p,.formatted-text li,.formatted-text blockquote,.formatted-text a,.formatted-text code{overflow-wrap:anywhere}.surface-panel{background:var(--surface);border:1px solid var(--border);border-radius:var(--radius-panel);-webkit-backdrop-filter:blur(var(--surface-blur)) saturate(140%);box-shadow:var(--shadow-panel)}.surface-card{background:var(--surface-strong);border-radius:var(--radius-card);-webkit-backdrop-filter:blur(14px)saturate(130%);box-shadow:var(--shadow-card)}.field-control{border-radius:var(--radius-input);border:1px solid var(--border-strong);background:var(--surface-elevated);width:100%;min-height:48px;color:var(--text);outline:none;padding:.75rem .95rem}.field-control:focus{border-color:var(--accent);box-shadow:0 0 0 3px var(--accent-soft)}.field-textarea{resize:vertical;min-height:120px}.status-chip{border:1px solid var(--border-strong);letter-spacing:.02em;text-transform:capitalize;border-radius:999px;align-items:center;gap:.35rem;padding:.25rem .65rem;font-size:.72rem;font-weight:700;display:inline-flex}.status-draft{background:#94a3b824}@supports (color:color-mix(in lab,red,red)){.status-draft{background:color-mix(in srgb,var(--color-status-draft) 14%,transparent)}}.status-draft{color:var(--color-status-draft)}.status-discovery{background:#6366f124}@supports (color:color-mix(in lab,red,red)){.status-discovery{background:color-mix(in srgb,var(--color-status-discovery) 14%,transparent)}}.status-discovery{color:var(--color-status-discovery)}.status-planned{background:#0ea5e924}@supports (color:color-mix(in lab,red,red)){.status-planned{background:color-mix(in srgb,var(--color-status-planned) 14%,transparent)}}.status-planned{color:var(--color-status-planned)}.status-in-progress{background:#f59e0b29}@supports (color:color-mix(in lab,red,red)){.status-in-progress{background:color-mix(in srgb,var(--color-status-in-progress) 16%,transparent)}}.status-in-progress{color:var(--color-status-in-progress)}.status-done{background:#22c55e29}@supports (color:color-mix(in lab,red,red)){.status-done{background:color-mix(in srgb,var(--color-status-done) 16%,transparent)}}.status-done{color:var(--color-status-done)}.status-blocked{background:#ef444426}@supports (color:color-mix(in lab,red,red)){.status-blocked{background:color-mix(in srgb,var(--color-status-blocked) 15%,transparent)}}.status-blocked{color:var(--color-status-blocked)}.status-canceled{background:#94a3b81f}@supports (color:color-mix(in lab,red,red)){.status-canceled{background:color-mix(in srgb,var(--color-status-canceled) 12%,transparent)}}.status-canceled{color:var(--color-status-canceled)}.status-rejected{background:#f43f5e1f}@supports (color:color-mix(in lab,red,red)){.status-rejected{background:color-mix(in srgb,var(--color-status-rejected) 12%,transparent)}}.status-rejected{color:var(--color-status-rejected)}.status-deferred{background:#8b5cf61f}@supports (color:color-mix(in lab,red,red)){.status-deferred{background:color-mix(in srgb,var(--color-status-deferred) 12%,transparent)}}.status-deferred{color:var(--color-status-deferred)}.status-waiting{background:#64748b1f}@supports (color:color-mix(in lab,red,red)){.status-waiting{background:color-mix(in srgb,var(--color-status-waiting) 12%,transparent)}}.status-waiting{color:var(--color-status-waiting)}.status-started{background:#6366f11a}@supports (color:color-mix(in lab,red,red)){.status-started{background:color-mix(in srgb,var(--color-status-started) 10%,transparent)}}.status-started{color:var(--color-status-started)}.status-closed{background:#0d94881f}@supports (color:color-mix(in lab,red,red)){.status-closed{background:color-mix(in srgb,var(--color-status-closed) 12%,transparent)}}.status-closed{color:var(--color-status-closed)}.status-pattern-dashed{border-style:dashed;border-color:#6366f1b3}@supports (color:color-mix(in lab,red,red)){.status-pattern-dashed{border-color:color-mix(in srgb,var(--color-status-started) 70%,transparent)}}.status-pattern-dashed-planned{border-style:dashed;border-color:#0ea5e9a6}@supports (color:color-mix(in lab,red,red)){.status-pattern-dashed-planned{border-color:color-mix(in srgb,var(--color-status-planned) 65%,transparent)}}.status-pattern-dashed-started{border-style:dashed;border-color:#6366f1b3}@supports (color:color-mix(in lab,red,red)){.status-pattern-dashed-started{border-color:color-mix(in srgb,var(--color-status-started) 70%,transparent)}}.status-pattern-dashed-waiting{border-style:dashed;border-color:#64748bb3}@supports (color:color-mix(in lab,red,red)){.status-pattern-dashed-waiting{border-color:color-mix(in srgb,var(--color-status-waiting) 70%,transparent)}}.status-pattern-dashed-deferred{border-style:dashed;border-color:#8b5cf6b3}@supports (color:color-mix(in lab,red,red)){.status-pattern-dashed-deferred{border-color:color-mix(in srgb,var(--color-status-deferred) 70%,transparent)}}@keyframes ap-status-pulse{0%,to{box-shadow:0 0 color-mix(in srgb,var(--color-status-in-progress) 40%,transparent)}50%{box-shadow:0 0 0 3px color-mix(in srgb,var(--color-status-in-progress) 12%,transparent)}}.status-pattern-pulse{animation:2s ease-in-out infinite ap-status-pulse}.status-pattern-stripe{background-image:repeating-linear-gradient(135deg,#0000 0,#0000 10px,#0d948814 10px,#0d948814 20px)}@supports (color:color-mix(in lab,red,red)){.status-pattern-stripe{background-image:repeating-linear-gradient(135deg,transparent 0 10px,color-mix(in srgb,var(--color-status-closed) 8%,transparent) 10px 20px)}}.status-pattern-hatch{background-image:repeating-linear-gradient(45deg,#0000 0,#0000 8px,#94a3b814 8px,#94a3b814 16px)}@supports (color:color-mix(in lab,red,red)){.status-pattern-hatch{background-image:repeating-linear-gradient(45deg,transparent 0 8px,color-mix(in srgb,var(--color-status-canceled) 8%,transparent) 8px 16px)}}.status-pattern-crosshatch{background-image:repeating-linear-gradient(45deg,#0000 0,#0000 4px,#f43f5e14 4px,#f43f5e14 8px),repeating-linear-gradient(-45deg,#0000 0,#0000 4px,#f43f5e14 4px,#f43f5e14 8px)}@supports (color:color-mix(in lab,red,red)){.status-pattern-crosshatch{background-image:repeating-linear-gradient(45deg,transparent 0 4px,color-mix(in srgb,var(--color-status-rejected) 8%,transparent) 4px 8px),repeating-linear-gradient(-45deg,transparent 0 4px,color-mix(in srgb,var(--color-status-rejected) 8%,transparent) 4px 8px)}}@media(prefers-reduced-motion:reduce){.status-pattern-pulse{animation:none}}.plan-description{background:var(--surface-elevated);border-left:3px solid var(--accent)}@supports (color:color-mix(in lab,red,red)){.plan-description{border-left:3px solid color-mix(in srgb,var(--accent) 55%,transparent)}}.plan-description{border-radius:var(--radius-card);color:var(--text);padding:.85rem 1rem}.plan-description p{margin:0}.entity-badge{border:1px solid var(--border-strong);letter-spacing:.03em;text-transform:uppercase;border-radius:999px;align-items:center;gap:.4rem;padding:.3rem .7rem;font-size:.72rem;font-weight:800;display:inline-flex}.entity-badge--feature{color:var(--color-entity-feature);background:var(--color-entity-feature)}@supports (color:color-mix(in lab,red,red)){.entity-badge--feature{background:color-mix(in srgb,var(--color-entity-feature) 14%,transparent)}}.entity-badge--phase{color:var(--color-entity-phase);background:var(--color-entity-phase)}@supports (color:color-mix(in lab,red,red)){.entity-badge--phase{background:color-mix(in srgb,var(--color-entity-phase) 14%,transparent)}}.entity-badge--task{color:var(--color-entity-task);background:var(--color-entity-task)}@supports (color:color-mix(in lab,red,red)){.entity-badge--task{background:color-mix(in srgb,var(--color-entity-task) 14%,transparent)}}.entity-badge--requirement{color:var(--accent);background:var(--accent)}@supports (color:color-mix(in lab,red,red)){.entity-badge--requirement{background:color-mix(in srgb,var(--accent) 14%,transparent)}}.entity-link--feature{color:var(--color-entity-feature)}.entity-link--phase{color:var(--color-entity-phase)}.entity-link--task{color:var(--color-entity-task)}.entity-path-badge{border:1px solid var(--border-strong);background:var(--surface-elevated);font-variant-numeric:tabular-nums;border-radius:7px;align-items:stretch;line-height:1;display:inline-flex;overflow:hidden}.entity-path-seg{letter-spacing:.02em;align-items:center;padding:.24rem .5rem;font-size:.72rem;font-weight:800;display:inline-flex}.entity-path-seg--feature{color:var(--color-entity-feature);background:var(--color-entity-feature)}@supports (color:color-mix(in lab,red,red)){.entity-path-seg--feature{background:color-mix(in srgb,var(--color-entity-feature) 14%,transparent)}}.entity-path-seg--phase{color:var(--color-entity-phase);background:var(--color-entity-phase)}@supports (color:color-mix(in lab,red,red)){.entity-path-seg--phase{background:color-mix(in srgb,var(--color-entity-phase) 14%,transparent)}}.entity-path-seg--task{color:var(--color-entity-task);background:var(--color-entity-task)}@supports (color:color-mix(in lab,red,red)){.entity-path-seg--task{background:color-mix(in srgb,var(--color-entity-task) 14%,transparent)}}.entity-path-seg--link{cursor:pointer;text-decoration:none;transition:filter .15s,transform 50ms}.entity-path-seg--link:hover{filter:brightness(1.15)}.entity-path-seg--link:active{transform:translateY(1px)}.entity-path-seg--link:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}.entity-path-sep{color:var(--text-subtle);align-items:center;padding-inline:.2rem;font-size:.72rem;font-weight:700;display:inline-flex}.copyable-id{-webkit-appearance:none;-moz-appearance:none;appearance:none;cursor:pointer;font:inherit;color:inherit;background:0 0;border:none;border-radius:8px;padding:0}.copyable-id:focus-visible{outline:2px solid var(--accent);outline-offset:2px}.copyable-id__icon{opacity:.4;align-items:center;transition:opacity .15s;display:inline-flex}.copyable-id:hover .copyable-id__icon,.copyable-id:focus-visible .copyable-id__icon{opacity:1}.handoff-badge{border:1px solid var(--border);background:var(--surface-card);color:var(--text-muted);border-radius:9999px;align-items:center;gap:.25rem;padding:.125rem .5rem;font-size:.6875rem;line-height:1.1;text-decoration:none;transition:background .15s,color .15s,border-color .15s;display:inline-flex}.handoff-badge:hover{background:var(--surface-elevated);color:var(--text);border-color:var(--accent)}.handoff-badge svg{flex:none}.handoff-badge__label{white-space:nowrap;font-weight:500}@media(max-width:640px){:root{font-size:106.25%}}.btn-primary{background:var(--accent);color:#fff}.btn-primary:hover{background:var(--accent-hover)}button:disabled,select:disabled,input:disabled,textarea:disabled{cursor:not-allowed;opacity:.6}::-webkit-scrollbar{width:8px}::-webkit-scrollbar-thumb{background:var(--border-strong);border-radius:999px}@keyframes ap-progress-glow{0%,to{box-shadow:0 0 color-mix(in srgb,var(--color-status-in-progress) 0%,transparent)}50%{box-shadow:0 0 18px -2px color-mix(in srgb,var(--color-status-in-progress) 28%,transparent)}}.ap-in-progress{background:#f59e0b12;animation:2.6s ease-in-out infinite ap-progress-glow}@supports (color:color-mix(in lab,red,red)){.ap-in-progress{background:color-mix(in srgb,var(--color-status-in-progress) 7%,transparent)}}@keyframes ap-dot-ping{0%{opacity:.85;transform:scale(1)}75%,to{opacity:0;transform:scale(2.6)}}.status-item{border-radius:10px;position:relative;overflow:hidden}.ap-progress-dot{flex:none;width:9px;height:9px;margin-inline:6px;display:inline-block;position:relative;overflow:visible}.ap-progress-dot:before{content:"";background:var(--color-status-in-progress);border-radius:999px;position:absolute;top:0;right:0;bottom:0;left:0;box-shadow:0 0 8px #f59e0bb3}@supports (color:color-mix(in lab,red,red)){.ap-progress-dot:before{box-shadow:0 0 8px color-mix(in srgb,var(--color-status-in-progress) 70%,transparent)}}.ap-progress-dot:after{content:"";background:var(--color-status-in-progress);transform-origin:50%;border-radius:999px;animation:1.9s cubic-bezier(0,0,.2,1) infinite ap-dot-ping;position:absolute;top:0;right:0;bottom:0;left:0}@media(prefers-reduced-motion:reduce){.ap-in-progress{animation:none}.ap-progress-dot:after{opacity:0;animation:none}}.short-id-badge{font-family:var(--font-mono,ui-monospace, monospace);letter-spacing:.04em;color:var(--text-muted);background:var(--accent);border-radius:6px;align-items:center;padding:3px 6px;font-size:10.5px;font-weight:700;line-height:1;display:inline-flex}@supports (color:color-mix(in lab,red,red)){.short-id-badge{background:color-mix(in srgb,var(--accent) 8%,transparent)}}.short-id-badge{border:1px solid var(--accent)}@supports (color:color-mix(in lab,red,red)){.short-id-badge{border:1px solid color-mix(in srgb,var(--accent) 24%,transparent)}}.short-id-badge{font-variant-numeric:tabular-nums}.drag-handle{width:28px;height:28px;color:var(--text-subtle);cursor:grab;touch-action:none;opacity:.6;background:0 0;border:1px solid #0000;border-radius:6px;flex:none;justify-content:center;align-items:center;transition:opacity .12s,background .12s,color .12s,border-color .12s;display:inline-flex}.drag-handle:hover,.drag-handle:focus-visible{opacity:1;background:var(--surface-elevated);color:var(--text);border-color:var(--border)}.drag-handle:active{cursor:grabbing}.ap-sortable--dragging{opacity:.55;outline:2px solid var(--accent)}@supports (color:color-mix(in lab,red,red)){.ap-sortable--dragging{outline:2px solid color-mix(in srgb,var(--accent) 55%,transparent)}}.ap-sortable--dragging{outline-offset:2px;border-radius:12px}.ap-drag-overlay{border:1px solid var(--accent);box-shadow:0 12px 32px -8px #0006}@supports (color:color-mix(in lab,red,red)){.ap-drag-overlay{border:1px solid color-mix(in srgb,var(--accent) 45%,transparent)}}.ap-drag-overlay{cursor:grabbing;background:var(--surface-elevated);border-radius:12px}.search-bar .ei-placeholder{padding:0 12px}.ap-search-sticky{z-index:20;background:var(--surface-elevated);-webkit-backdrop-filter:saturate(180%)blur(10px);border-bottom:1px solid var(--border);margin-bottom:.75rem;padding-bottom:.5rem;position:sticky;top:0}.status-card-stepper{flex-wrap:wrap;align-items:center;gap:.15rem;min-width:0;display:flex}.status-card{border:1px solid var(--border-strong);background:var(--surface);opacity:.75;border-radius:.5rem;align-items:center;gap:.3rem;min-width:0;padding:.3rem .5rem;display:inline-flex}.status-card.status-card-current{opacity:1;border-width:2px;box-shadow:0 0 0 1px}@supports (color:color-mix(in lab,red,red)){.status-card.status-card-current{box-shadow:0 0 0 1px color-mix(in srgb,currentColor 35%,transparent)}}.status-card-icon{flex-shrink:0;width:.9rem;height:.9rem}.status-card-label{text-transform:capitalize;white-space:nowrap;font-size:.7rem;font-weight:700}.status-card-time{opacity:.8;white-space:nowrap;font-size:.62rem;font-weight:500}.status-card-time-initial{opacity:.6;font-style:italic}.status-card.status-draft,.status-card.status-discovery,.status-card.status-planned,.status-card.status-in-progress,.status-card.status-done,.status-card.status-blocked,.status-card.status-canceled,.status-card.status-rejected,.status-card.status-deferred,.status-card.status-waiting{background:var(--surface)}@supports (color:color-mix(in lab,red,red)){.status-card.status-draft,.status-card.status-discovery,.status-card.status-planned,.status-card.status-in-progress,.status-card.status-done,.status-card.status-blocked,.status-card.status-canceled,.status-card.status-rejected,.status-card.status-deferred,.status-card.status-waiting{background:color-mix(in srgb,var(--surface) 60%,transparent)}}.status-card.status-draft,.status-card.status-discovery,.status-card.status-planned,.status-card.status-in-progress,.status-card.status-done,.status-card.status-blocked,.status-card.status-canceled,.status-card.status-rejected,.status-card.status-deferred,.status-card.status-waiting{border-color:currentColor}@supports (color:color-mix(in lab,red,red)){.status-card.status-draft,.status-card.status-discovery,.status-card.status-planned,.status-card.status-in-progress,.status-card.status-done,.status-card.status-blocked,.status-card.status-canceled,.status-card.status-rejected,.status-card.status-deferred,.status-card.status-waiting{border-color:color-mix(in srgb,currentColor 40%,var(--border-strong))}}.status-card.status-in-progress{background:#f59e0b24}@supports (color:color-mix(in lab,red,red)){.status-card.status-in-progress{background:color-mix(in srgb,var(--color-status-in-progress) 14%,transparent)}}.status-card.status-in-progress{color:var(--color-status-in-progress)}.status-card.status-done{background:#22c55e29}@supports (color:color-mix(in lab,red,red)){.status-card.status-done{background:color-mix(in srgb,var(--color-status-done) 16%,transparent)}}.status-card.status-done{color:var(--color-status-done)}.status-card.status-blocked{background:#ef444429}@supports (color:color-mix(in lab,red,red)){.status-card.status-blocked{background:color-mix(in srgb,var(--color-status-blocked) 16%,transparent)}}.status-card.status-blocked{color:var(--color-status-blocked)}.status-card.status-planned{background:#0ea5e924}@supports (color:color-mix(in lab,red,red)){.status-card.status-planned{background:color-mix(in srgb,var(--color-status-planned) 14%,transparent)}}.status-card.status-planned{color:var(--color-status-planned)}.status-card.status-draft{background:#94a3b824}@supports (color:color-mix(in lab,red,red)){.status-card.status-draft{background:color-mix(in srgb,var(--color-status-draft) 14%,transparent)}}.status-card.status-draft{color:var(--color-status-draft)}.status-card.status-discovery{background:#6366f124}@supports (color:color-mix(in lab,red,red)){.status-card.status-discovery{background:color-mix(in srgb,var(--color-status-discovery) 14%,transparent)}}.status-card.status-discovery{color:var(--color-status-discovery)}.status-card.status-canceled{background:#94a3b824}@supports (color:color-mix(in lab,red,red)){.status-card.status-canceled{background:color-mix(in srgb,var(--color-status-canceled) 14%,transparent)}}.status-card.status-canceled{color:var(--color-status-canceled)}.status-card.status-rejected{background:#f43f5e24}@supports (color:color-mix(in lab,red,red)){.status-card.status-rejected{background:color-mix(in srgb,var(--color-status-rejected) 14%,transparent)}}.status-card.status-rejected{color:var(--color-status-rejected)}.status-card.status-deferred{background:#8b5cf624}@supports (color:color-mix(in lab,red,red)){.status-card.status-deferred{background:color-mix(in srgb,var(--color-status-deferred) 14%,transparent)}}.status-card.status-deferred{color:var(--color-status-deferred)}.status-card.status-waiting{background:#64748b24}@supports (color:color-mix(in lab,red,red)){.status-card.status-waiting{background:color-mix(in srgb,var(--color-status-waiting) 14%,transparent)}}.status-card.status-waiting{color:var(--color-status-waiting)}.status-card.status-card-future{opacity:.55;border-style:dashed!important;border-color:var(--border-strong)!important;color:var(--text-subtle)!important;background:0 0!important}.status-card.status-card-future .status-card-icon{opacity:.6}.status-stepper{align-items:flex-start;gap:0;padding:.9rem 1rem .7rem;display:flex;overflow-x:auto}.status-step{flex-direction:column;flex:1 1 0;align-items:center;gap:.45rem;min-width:5.5rem;display:flex;position:relative}.status-step-label{text-align:center;white-space:nowrap;letter-spacing:.01em;font-size:.68rem;font-weight:700;line-height:1.25}.status-step-date{font-variant-numeric:tabular-nums;color:var(--text-subtle);text-align:center;white-space:nowrap;margin-top:.1rem;font-size:.58rem;line-height:1.2}.status-step--current .status-step-date{color:var(--text-muted)}.status-node{z-index:1;border-radius:9999px;flex-shrink:0;place-items:center;width:2rem;height:2rem;transition:background .2s,box-shadow .2s,border-color .2s;display:grid;position:relative}.status-node-icon{width:1rem;height:1rem}.status-step--completed .status-node{border:2px solid var(--step-color);background:0 0}@supports (color:color-mix(in lab,red,red)){.status-step--completed .status-node{border:2px solid color-mix(in srgb,var(--step-color) 45%,transparent)}}.status-step--completed .status-node{color:var(--step-color)}@supports (color:color-mix(in lab,red,red)){.status-step--completed .status-node{color:color-mix(in srgb,var(--step-color) 70%,var(--text))}}.status-step--completed .status-step-label{color:var(--step-color)}@supports (color:color-mix(in lab,red,red)){.status-step--completed .status-step-label{color:color-mix(in srgb,var(--step-color) 70%,var(--text))}}.status-step--current .status-node{border:2px solid var(--step-color);color:var(--step-color);box-shadow:0 0 0 4px var(--step-color);background:0 0}@supports (color:color-mix(in lab,red,red)){.status-step--current .status-node{box-shadow:0 0 0 4px color-mix(in srgb,var(--step-color) 16%,transparent)}}.status-step--current .status-step-label{color:var(--text);font-weight:800}.status-step--pending .status-node{background:var(--surface);border:2px dashed var(--border-strong);color:var(--step-color)}@supports (color:color-mix(in lab,red,red)){.status-step--pending .status-node{color:color-mix(in srgb,var(--step-color) 45%,var(--text-subtle))}}.status-step--pending .status-step-label{color:var(--text-subtle)}.status-connector{z-index:0;width:calc(100% - 2rem);height:2px;position:absolute;top:1rem;left:calc(1rem - 50%);transform:translateY(-1px)}.status-connector--traveled{background:var(--step-color)}@supports (color:color-mix(in lab,red,red)){.status-connector--traveled{background:color-mix(in srgb,var(--step-color) 50%,transparent)}}.status-connector--pending{background:repeating-linear-gradient(90deg,var(--border-strong) 0 5px,transparent 5px 10px)}@media(max-width:640px){.status-step{min-width:4.2rem}.status-step-label{font-size:.62rem}.status-node{width:1.7rem;height:1.7rem}.status-node-icon{width:.85rem;height:.85rem}.status-connector{width:calc(100% - 1.7rem);top:.85rem;left:calc(.85rem - 50%)}}.checklist-num{background:var(--text-subtle);border-radius:.3rem;justify-content:center;align-items:center;min-width:1.6rem;padding:.05rem .3rem;display:inline-flex}@supports (color:color-mix(in lab,red,red)){.checklist-num{background:color-mix(in srgb,var(--text-subtle) 12%,transparent)}}.checklist-num{color:var(--text-subtle);font-variant-numeric:tabular-nums;letter-spacing:.02em;text-transform:uppercase;margin-right:.15rem;font-size:.62rem;font-weight:800}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-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-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@keyframes pulse{50%{opacity:.5}}