From d2b1e61c9fbc0116041b9cba23a1bd7491a346c0 Mon Sep 17 00:00:00 2001 From: Lukas Moschitz Date: Wed, 2 Sep 2026 16:39:04 +0200 Subject: [PATCH 01/57] fix(showcase): redirect the legacy premium inspector and guides URLs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two legacy docs URLs have been dead ends since cc8c945893 ("refactor(docs): optimize structure, content and navigability", 2026-02-23). That commit had no redirect config to update — seo-redirects.ts did not exist yet — and nobody back-filled the entries when it was built. `/premium/inspector` 404s. The commit renamed `(root)/premium/inspector.mdx` to `(root)/inspector.mdx` with identical content, so the page still exists; only the URL moved. Points at /inspector now, expanded over the framework slugs the way the observability entries are, since /langgraph-python/inspector and its siblings are served too. `/direct-to-llm/guides/premium/*` loses the page. All four of them — overview, headless-ui, observability, inspector — were deleted in the same commit, and the R16 `/direct-to-llm/:path*` wildcard drops the remainder on the docs home. That reads as a working link while serving the wrong page, which is why it went unnoticed longer than a 404 would have. Each gets an exact entry. Both need entries on the docs host and the shell host: P7 renames `/premium/*` to a docs-host `/intelligence/*` on the way across, so without the shell entry the legacy shell URL would 301 into a docs-host 404. The harness driver is the intentional copy of the shell list and moves with it. Exact sources beat every wildcard — middleware checks exactMap before the wildcard list — so these win over INTEL-rename-wild, which would otherwise rewrite them to a nonexistent /intelligence/inspector. The decommission report fixtures move with the catalogue: 390 to 395 entries defined, 377 to 382 zero-hit candidates, plus the five new ids. Regenerated through the CLI with --events-json so the byte-for-byte cross-check against the core module keeps its meaning. Verified all 24 distinct destinations against staging. 22 return 200. /langroid/inspector and /spring-ai/inspector 404, because those two framework surfaces are not served at all — their bare roots and quickstarts 404 too. The existing observability entries carry the same property, so no reachable URL changes behavior. --- .../src/probes/drivers/seo-redirects.ts | 38 ++++++++++ .../cli-stdout-human.txt | 9 ++- .../redirect-decommission/cli-stdout.txt | 9 ++- .../src/lib/__tests__/seo-redirects.test.ts | 70 +++++++++++++++++++ showcase/shell-docs/src/lib/seo-redirects.ts | 45 ++++++++++++ showcase/shell/src/lib/seo-redirects.ts | 38 ++++++++++ 6 files changed, 205 insertions(+), 4 deletions(-) diff --git a/showcase/harness/src/probes/drivers/seo-redirects.ts b/showcase/harness/src/probes/drivers/seo-redirects.ts index b8b7e6c180..24ff17e43b 100644 --- a/showcase/harness/src/probes/drivers/seo-redirects.ts +++ b/showcase/harness/src/probes/drivers/seo-redirects.ts @@ -378,6 +378,35 @@ const SPECIFIC_FRAMEWORK: RedirectEntry[] = [ source: "/direct-to-llm/guides/mcp", destination: "/built-in-agent/coding-agents", }, + // `/direct-to-llm/guides/premium/*` pages were deleted in cc8c945893 + // ("refactor(docs): optimize structure, content and navigability", + // 2026-02-23) without redirects. The R16 `/direct-to-llm/:path*` wildcard + // strips the prefix and the remainder falls through to the docs home, so + // the page is lost rather than 404'd — quieter and harder to notice. + // Exact entries land each one on its current equivalent in one hop. + { + id: "INTEL-d2l-guides-overview", + source: "/direct-to-llm/guides/premium/overview", + destination: "/intelligence/overview", + }, + { + id: "INTEL-d2l-guides-headless-ui", + source: "/direct-to-llm/guides/premium/headless-ui", + destination: "/intelligence/headless-ui", + }, + { + // The observability page is retired; the overview is its standing + // destination everywhere else (INTEL-observability-*). + id: "INTEL-d2l-guides-observability", + source: "/direct-to-llm/guides/premium/observability", + destination: "/intelligence/overview", + }, + { + // Inspector moved out of the Intelligence folder rather than retiring. + id: "INTEL-d2l-guides-inspector", + source: "/direct-to-llm/guides/premium/inspector", + destination: "/inspector", + }, ]; // --------------------------------------------------------------------------- @@ -707,6 +736,15 @@ const RETIRED_INTELLIGENCE_REDIRECTS: RedirectEntry[] = [ source: "/premium/observability", destination: "/intelligence/overview", }, + // Same reason, different cause: the inspector page moved out of the folder + // in cc8c945893 instead of retiring, and never got a redirect. Without this + // entry P7 renames the legacy shell URL into a docs-host + // `/intelligence/inspector` that does not exist. + { + id: "INTEL-inspector-root", + source: "/premium/inspector", + destination: "/inspector", + }, ]; // --------------------------------------------------------------------------- diff --git a/showcase/harness/test/fixtures/redirect-decommission/cli-stdout-human.txt b/showcase/harness/test/fixtures/redirect-decommission/cli-stdout-human.txt index 525690624c..861d948169 100644 --- a/showcase/harness/test/fixtures/redirect-decommission/cli-stdout-human.txt +++ b/showcase/harness/test/fixtures/redirect-decommission/cli-stdout-human.txt @@ -1,8 +1,8 @@ === SEO Redirect Decommission Report (last 30 days) === -Total redirects defined: 390 +Total redirects defined: 395 Total hits: 12,537 Redirects with hits: 13 -Zero-hit candidates: 377 +Zero-hit candidates: 382 Top 10 most-hit redirects: D1 5,432 hits @@ -97,6 +97,11 @@ Decommission candidates (zero hits): FI-premium /premium → /intelligence/overview FI-reference /reference → /reference/v2 FI-troubleshooting /troubleshooting → /troubleshooting/common-issues + INTEL-d2l-guides-headless-ui /direct-to-llm/guides/premium/headless-ui → /intelligence/headless-ui + INTEL-d2l-guides-inspector /direct-to-llm/guides/premium/inspector → /inspector + INTEL-d2l-guides-observability /direct-to-llm/guides/premium/observability → /intelligence/overview + INTEL-d2l-guides-overview /direct-to-llm/guides/premium/overview → /intelligence/overview + INTEL-inspector-root /premium/inspector → /inspector INTEL-observability-root /premium/observability → /intelligence/overview L10 /coagents/tutorials → /langgraph-python/tutorials L11 /coagents/videos → /langgraph-python/videos diff --git a/showcase/harness/test/fixtures/redirect-decommission/cli-stdout.txt b/showcase/harness/test/fixtures/redirect-decommission/cli-stdout.txt index b009764b70..6b231ae7b3 100644 --- a/showcase/harness/test/fixtures/redirect-decommission/cli-stdout.txt +++ b/showcase/harness/test/fixtures/redirect-decommission/cli-stdout.txt @@ -1,8 +1,8 @@ :bar_chart: *SEO Redirect Decommission Report* (last 30 days) -Total redirects defined: 390 +Total redirects defined: 395 Total hits: 12,537 -:warning: *377 redirect(s) with zero hits — decommission candidates:* +:warning: *382 redirect(s) with zero hits — decommission candidates:* • B1 • B2 • B3 @@ -59,6 +59,11 @@ Total hits: 12,537 • FI-premium • FI-reference • FI-troubleshooting + • INTEL-d2l-guides-headless-ui + • INTEL-d2l-guides-inspector + • INTEL-d2l-guides-observability + • INTEL-d2l-guides-overview + • INTEL-inspector-root • INTEL-observability-root • L10 • L11 diff --git a/showcase/shell-docs/src/lib/__tests__/seo-redirects.test.ts b/showcase/shell-docs/src/lib/__tests__/seo-redirects.test.ts index 5518ea21ef..90bf44727b 100644 --- a/showcase/shell-docs/src/lib/__tests__/seo-redirects.test.ts +++ b/showcase/shell-docs/src/lib/__tests__/seo-redirects.test.ts @@ -113,6 +113,76 @@ describe("seoRedirects", () => { ); }); + it("redirects the moved Intelligence inspector page instead of 404ing", () => { + // cc8c945893 renamed `(root)/premium/inspector.mdx` to + // `(root)/inspector.mdx` and added no redirect, so `/premium/inspector` + // 404'd from 2026-02-23 on. The page still exists, so these forward to it + // rather than falling back to the overview. + expect(seoRedirects).toEqual( + expect.arrayContaining([ + { + id: "INTEL-inspector-root", + source: "/premium/inspector", + destination: "/inspector", + }, + { + id: "INTEL-inspector×langgraph-python", + source: "/langgraph-python/premium/inspector", + destination: "/langgraph-python/inspector", + }, + { + // Built-in Agent is served at the root, so its destination carries + // no framework prefix. + id: "INTEL-inspector×built-in-agent", + source: "/built-in-agent/premium/inspector", + destination: "/inspector", + }, + ]), + ); + }); + + it("redirects the deleted /direct-to-llm/guides/premium pages to their current equivalents", () => { + // Deleted in cc8c945893 without redirects. The R16 + // `/direct-to-llm/:path*` wildcard drops them on the docs home, which + // reads as a working link while serving the wrong page. + expect(seoRedirects).toEqual( + expect.arrayContaining([ + { + id: "INTEL-d2l-guides-overview", + source: "/direct-to-llm/guides/premium/overview", + destination: "/intelligence/overview", + }, + { + id: "INTEL-d2l-guides-headless-ui", + source: "/direct-to-llm/guides/premium/headless-ui", + destination: "/intelligence/headless-ui", + }, + { + id: "INTEL-d2l-guides-observability", + source: "/direct-to-llm/guides/premium/observability", + destination: "/intelligence/overview", + }, + { + id: "INTEL-d2l-guides-inspector", + source: "/direct-to-llm/guides/premium/inspector", + destination: "/inspector", + }, + ]), + ); + }); + + it("matches the new exact sources before the premium rename wildcard", () => { + // The whole point of exact entries here: INTEL-rename-wild would rewrite + // these to `/intelligence/inspector`, which does not exist. + expect(matchesSeoRedirectSource("/premium/inspector")).toBe(true); + expect( + matchesSeoRedirectSource("/langgraph-python/premium/inspector"), + ).toBe(true); + expect( + matchesSeoRedirectSource("/direct-to-llm/guides/premium/headless-ui"), + ).toBe(true); + }); + it("serves the Built-in Agent docs at the root: no redirect may capture a bare BIA page URL", () => { // These bare URLs render BIA-authored pages directly now. A // middleware entry whose source matches one of them would either diff --git a/showcase/shell-docs/src/lib/seo-redirects.ts b/showcase/shell-docs/src/lib/seo-redirects.ts index 09df72d5c8..36066ed364 100644 --- a/showcase/shell-docs/src/lib/seo-redirects.ts +++ b/showcase/shell-docs/src/lib/seo-redirects.ts @@ -465,6 +465,35 @@ const SPECIFIC_FRAMEWORK: RedirectEntry[] = [ source: "/direct-to-llm/guides/mcp", destination: "/build-with-agents", }, + // `/direct-to-llm/guides/premium/*` pages were deleted in cc8c945893 + // ("refactor(docs): optimize structure, content and navigability", + // 2026-02-23) without redirects. The R16 `/direct-to-llm/:path*` wildcard + // strips the prefix and the remainder falls through to the docs home, so + // the page is lost rather than 404'd — quieter and harder to notice. + // Exact entries land each one on its current equivalent in one hop. + { + id: "INTEL-d2l-guides-overview", + source: "/direct-to-llm/guides/premium/overview", + destination: "/intelligence/overview", + }, + { + id: "INTEL-d2l-guides-headless-ui", + source: "/direct-to-llm/guides/premium/headless-ui", + destination: "/intelligence/headless-ui", + }, + { + // The observability page is retired; the overview is its standing + // destination everywhere else (INTEL-observability-*). + id: "INTEL-d2l-guides-observability", + source: "/direct-to-llm/guides/premium/observability", + destination: "/intelligence/overview", + }, + { + // Inspector moved out of the Intelligence folder rather than retiring. + id: "INTEL-d2l-guides-inspector", + source: "/direct-to-llm/guides/premium/inspector", + destination: "/inspector", + }, ]; // --------------------------------------------------------------------------- @@ -1024,6 +1053,22 @@ const RETIRED_INTELLIGENCE_REDIRECTS: RedirectEntry[] = [ "intelligence/overview", ), })), + // The inspector page MOVED out of the Intelligence folder — it was not + // retired. cc8c945893 renamed `(root)/premium/inspector.mdx` to + // `(root)/inspector.mdx` (R100, identical content) and added no redirect, + // so `/premium/inspector` has 404'd ever since. It needs an exact entry for + // the same reason observability does: INTEL-rename-wild would rewrite it to + // a nonexistent `/intelligence/inspector`. + { + id: "INTEL-inspector-root", + source: "/premium/inspector", + destination: "/inspector", + }, + ...PREMIUM_URL_FRAMEWORKS.map((framework) => ({ + id: `INTEL-inspector×${framework}`, + source: `/${framework}/premium/inspector`, + destination: destinationPath(canonicalSlug(framework), "inspector"), + })), ]; // --------------------------------------------------------------------------- diff --git a/showcase/shell/src/lib/seo-redirects.ts b/showcase/shell/src/lib/seo-redirects.ts index 8406e63be2..1cc87d02f9 100644 --- a/showcase/shell/src/lib/seo-redirects.ts +++ b/showcase/shell/src/lib/seo-redirects.ts @@ -414,6 +414,35 @@ const SPECIFIC_FRAMEWORK: RedirectEntry[] = [ source: "/direct-to-llm/guides/mcp", destination: "/built-in-agent/coding-agents", }, + // `/direct-to-llm/guides/premium/*` pages were deleted in cc8c945893 + // ("refactor(docs): optimize structure, content and navigability", + // 2026-02-23) without redirects. The R16 `/direct-to-llm/:path*` wildcard + // strips the prefix and the remainder falls through to the docs home, so + // the page is lost rather than 404'd — quieter and harder to notice. + // Exact entries land each one on its current equivalent in one hop. + { + id: "INTEL-d2l-guides-overview", + source: "/direct-to-llm/guides/premium/overview", + destination: "/intelligence/overview", + }, + { + id: "INTEL-d2l-guides-headless-ui", + source: "/direct-to-llm/guides/premium/headless-ui", + destination: "/intelligence/headless-ui", + }, + { + // The observability page is retired; the overview is its standing + // destination everywhere else (INTEL-observability-*). + id: "INTEL-d2l-guides-observability", + source: "/direct-to-llm/guides/premium/observability", + destination: "/intelligence/overview", + }, + { + // Inspector moved out of the Intelligence folder rather than retiring. + id: "INTEL-d2l-guides-inspector", + source: "/direct-to-llm/guides/premium/inspector", + destination: "/inspector", + }, ]; // --------------------------------------------------------------------------- @@ -709,6 +738,15 @@ const RETIRED_INTELLIGENCE_REDIRECTS: RedirectEntry[] = [ source: "/premium/observability", destination: "/intelligence/overview", }, + // Same reason, different cause: the inspector page moved out of the folder + // in cc8c945893 instead of retiring, and never got a redirect. Without this + // entry P7 renames the legacy shell URL into a docs-host + // `/intelligence/inspector` that does not exist. + { + id: "INTEL-inspector-root", + source: "/premium/inspector", + destination: "/inspector", + }, ]; // --------------------------------------------------------------------------- From 452356b5e8c73fbf356ea6b2ae2b6379d1eb5fe2 Mon Sep 17 00:00:00 2001 From: Tyler Slaton Date: Wed, 2 Sep 2026 15:57:16 -0700 Subject: [PATCH 02/57] feat(web-inspector): unify locked feature pages --- .../dev/threads-state-lab.spec.ts | 67 ++- .../src/__tests__/inspector-metadata.spec.ts | 34 +- .../src/__tests__/inspector-pop-out.spec.ts | 61 +- .../src/__tests__/metadata-telemetry.spec.ts | 50 +- .../__tests__/threads-example-video.spec.ts | 32 +- .../src/__tests__/threads-states.spec.ts | 142 ++--- .../src/__tests__/threads-telemetry.spec.ts | 67 ++- .../src/__tests__/web-inspector.spec.ts | 150 ++--- packages/web-inspector/src/index.ts | 506 +++++++--------- .../web-inspector/src/styles/generated.css | 2 +- .../web-inspector/src/styles/tailwind.css | 552 ++++++++---------- 11 files changed, 792 insertions(+), 871 deletions(-) diff --git a/packages/web-inspector/dev/threads-state-lab.spec.ts b/packages/web-inspector/dev/threads-state-lab.spec.ts index cf8e733d39..bf458724b6 100644 --- a/packages/web-inspector/dev/threads-state-lab.spec.ts +++ b/packages/web-inspector/dev/threads-state-lab.spec.ts @@ -347,8 +347,12 @@ async function requestCounters( /** Returns the expected action label for trusted fixture metadata. */ function expectedActionLabel(scenario: ThreadsStateScenario): string | null { + if (scenario.capability !== "enabled") return null; const kind = scenario.inspectorMetadata?.action?.kind; - if (kind === "manage_plan") { + if ( + scenario.inspectorMetadata?.license?.state === "valid" && + kind === "manage_plan" + ) { const usage = scenario.inspectorMetadata?.usage; if (usage?.limit.kind === "finite") { const warningThreshold = @@ -357,8 +361,6 @@ function expectedActionLabel(scenario: ThreadsStateScenario): string | null { } return "Manage Your Plan"; } - if (kind === "enable_intelligence") return "Enable Intelligence"; - if (kind === "renew") return "Renew"; return null; } @@ -382,9 +384,10 @@ function expectedOverviewCopy( if (scenario.data === "error") return null; if (scenario.runtimeInfo.licenseStatus === "none") { return { - heading: "Enable Intelligence to inspect Threads.", + heading: + "Production-grade chat threads without the complexity. Self hostable.", description: - "Persist conversations and inspect saved thread history from the Inspector.", + "Chat threads that go beyond text with generative UI and multimodal inputs, built to replay missed events and stay in sync across tabs, sessions, and devices.", }; } if (scenario.runtimeInfo.licenseStatus === "expired") { @@ -1589,6 +1592,37 @@ test("drives the real Core, Inspector, stores, surfaces, and ledger for all 37 r `${key}: setup prompt label`, ).toBe("Copy setup prompt"); } + const lockedVideo = collectDeep( + root, + '[data-inspector-feature-video="threads"]', + ); + const lockedEngineerAction = collectDeep( + root, + '[data-inspector-locked-feature-talk="threads"]', + ); + expect(lockedVideo, `${key}: locked video presence`).toHaveLength( + expectsSetup ? 1 : 0, + ); + expect( + lockedEngineerAction, + `${key}: locked engineer CTA presence`, + ).toHaveLength(expectsSetup ? 1 : 0); + if (expectsSetup) { + expect( + lockedVideo[0]?.getAttribute("src"), + `${key}: locked video URL`, + ).toBe( + "https://www.loom.com/embed/79817778d29e490c97225127d2f17b3a?hide_owner=true&hide_share=true&hide_title=true&hideEmbedTopBar=true&hide_speed=true", + ); + expect( + lockedEngineerAction[0]?.textContent?.trim(), + `${key}: locked engineer CTA label`, + ).toBe("Talk to an Engineer"); + } + expect( + collectDeep(root, "cpk-thread-list"), + `${key}: thread list presence`, + ).toHaveLength(expectsSetup ? 0 : 1); const usage = scenario.inspectorMetadata?.usage; const threadCount = collectDeep( @@ -1596,9 +1630,9 @@ test("drives the real Core, Inspector, stores, surfaces, and ledger for all 37 r "[data-inspector-thread-count]", ); expect(threadCount, `${key}: usage presence`).toHaveLength( - usage ? 1 : 0, + usage && !expectsSetup ? 1 : 0, ); - if (usage) { + if (usage && !expectsSetup) { const used = String(usage.used); expect(text, `${key}: used count`).toContain(used); const progress = collectDeep(root, "progress"); @@ -1715,7 +1749,7 @@ test("drives the real Core, Inspector, stores, surfaces, and ledger for all 37 r if (scenario.data === "error") { expect(examples, `${key}: list-error examples`).toHaveLength(0); } else if ( - scenario.capability !== "enabled" || + scenario.capability === "enabled" && scenario.data === "zero" ) { expect(examples, `${key}: local examples`).toHaveLength(3); @@ -1747,7 +1781,7 @@ test("drives the real Core, Inspector, stores, surfaces, and ledger for all 37 r expect(await requestCounters(lab.origin, scenario), key).toEqual( scenario.expectedRequests, ); - } else { + } else if (scenario.capability === "enabled") { expect(examples, `${key}: no local examples`).toHaveLength(0); for (const thread of scenario.threads) { expect( @@ -1829,6 +1863,21 @@ test("drives the real Core, Inspector, stores, surfaces, and ledger for all 37 r }, { timeout: 5_000, interval: 20 }, ); + } else { + expect(examples, `${key}: locked examples`).toHaveLength(0); + expect( + collectDeep(root, "cpk-thread-details"), + `${key}: locked thread details`, + ).toHaveLength(0); + for (const thread of scenario.threads) { + expect( + inspectorText(inspector), + `${key}: hidden locked thread ${thread.id}`, + ).not.toContain(thread.name); + } + expect(await requestCounters(lab.origin, scenario), key).toEqual( + scenario.expectedRequests, + ); } } finally { stopThreadsStateLabClient(core, inspector); diff --git a/packages/web-inspector/src/__tests__/inspector-metadata.spec.ts b/packages/web-inspector/src/__tests__/inspector-metadata.spec.ts index 55a97bfd1c..90cc97ef75 100644 --- a/packages/web-inspector/src/__tests__/inspector-metadata.spec.ts +++ b/packages/web-inspector/src/__tests__/inspector-metadata.spec.ts @@ -295,18 +295,17 @@ test.each([ ); test.each([ - ["valid", "manage_plan", "Finish setting up Rich Threads", undefined], + ["valid", "manage_plan", "Finish setting up Rich Threads"], [ "none", "enable_intelligence", - "Enable Intelligence to inspect Threads.", - "Enable Intelligence", + "Production-grade chat threads without the complexity. Self hostable.", ], - ["expired", "renew", "Renew Intelligence to inspect Threads.", "Renew"], - ["unknown", "manage_plan", "Threads are unavailable.", undefined], + ["expired", "renew", "Renew Intelligence to inspect Threads."], + ["unknown", "manage_plan", "Threads are unavailable."], ] as const)( - "locked Threads use %s license copy and action placement", - async (licenseState, actionKind, heading, actionLabel) => { + "locked Threads use %s license copy and the unified actions", + async (licenseState, actionKind, heading) => { const context = await setup({ metadata: fullMetadata(licenseState, actionKind), runtimeLicense: licenseState, @@ -320,13 +319,15 @@ test.each([ const action = root.querySelector( '[data-inspector-action-placement="locked"]', ); + const talk = root.querySelector( + '[data-inspector-locked-feature-talk="threads"]', + ); expect(root.textContent).toContain(heading); - expect(action?.textContent?.trim()).toBe(actionLabel); - if (actionLabel !== undefined) { - expect(action?.href).toBe( - `https://cloud.copilotkit.ai/actions/${actionKind}`, - ); - } + expect(action).toBeNull(); + expect(talk?.textContent?.trim()).toBe("Talk to an Engineer"); + expect( + root.querySelector('[data-inspector-feature-setup-prompt="threads"]'), + ).not.toBeNull(); } finally { context.teardown(); } @@ -522,12 +523,9 @@ test("metadata usage stays independent from Threads capability and debug navigat Object.prototype.hasOwnProperty.call(usage ?? {}, "expiringSoonCount"), ).toBe(true); expect(root.textContent).toContain( - "Enable Intelligence to inspect Threads.", - ); - expect(lockedAction?.textContent?.trim()).toBe("Enable Intelligence"); - expect(lockedAction?.href).toBe( - "https://cloud.copilotkit.ai/actions/enable_intelligence", + "Production-grade chat threads without the complexity. Self hostable.", ); + expect(lockedAction).toBeNull(); expect( context.requests.filter((url) => url.includes("/threads?")), ).toHaveLength(0); diff --git a/packages/web-inspector/src/__tests__/inspector-pop-out.spec.ts b/packages/web-inspector/src/__tests__/inspector-pop-out.spec.ts index bd47e701de..771d8477c9 100644 --- a/packages/web-inspector/src/__tests__/inspector-pop-out.spec.ts +++ b/packages/web-inspector/src/__tests__/inspector-pop-out.spec.ts @@ -588,7 +588,7 @@ describe("Inspector pop-out", () => { } }, 15_000); - it("renders the threads list in the pop-out document", async () => { + it("renders the locked Threads page in the pop-out document", async () => { const context = await setup(); try { await context.open(); @@ -596,10 +596,17 @@ describe("Inspector pop-out", () => { await context.clickDetach(); await waitFor( - () => context.popDoc.querySelector("cpk-thread-list") !== null, - "the threads list in the pop-out document", + () => + context.popDoc.querySelector( + '[data-inspector-locked-feature="threads"]', + ) !== null, + "the locked Threads page in the pop-out document", ); - expect(context.popDoc.querySelector("cpk-thread-list")).not.toBeNull(); + expect( + context.popDoc.querySelector( + '[data-inspector-locked-feature="threads"]', + )?.textContent, + ).toContain("Rich Threads"); } finally { context.teardown(); } @@ -611,41 +618,41 @@ describe("Inspector pop-out", () => { await context.open(); await context.selectLeaf("threads"); - const inPageThreadList = requireElement( - requireShadow(context.inspector).querySelector("cpk-thread-list"), - "the in-page threads list", + const inPageLockedFeature = requireElement( + requireShadow(context.inspector).querySelector( + '[data-inspector-locked-feature="threads"]', + ), + "the in-page locked Threads page", ); - const portableThreadListStyle = requireElement( - inPageThreadList.shadowRoot?.querySelector("style"), - "the portable threads-list stylesheet", - ); - expect(portableThreadListStyle.textContent).toContain(".cpk-tl"); await context.clickDetach(); await waitFor( - () => context.popDoc.querySelector("cpk-thread-list") !== null, - "the threads list to move into the pop-out", + () => + context.popDoc.querySelector( + '[data-inspector-locked-feature="threads"]', + ) !== null, + "the locked Threads page to move into the pop-out", ); - expect(context.popDoc.querySelector("cpk-thread-list")).toBe( - inPageThreadList, - ); - expect(inPageThreadList.shadowRoot?.querySelector("style")).toBe( - portableThreadListStyle, - ); - expect(portableThreadListStyle.ownerDocument).toBe(context.popDoc); + expect( + context.popDoc.querySelector( + '[data-inspector-locked-feature="threads"]', + ), + ).toBe(inPageLockedFeature); context.firePageHide(); await context.inspector.updateComplete; await waitFor( () => - requireShadow(context.inspector).querySelector("cpk-thread-list") !== - null, - "the threads list to return to the app page", + requireShadow(context.inspector).querySelector( + '[data-inspector-locked-feature="threads"]', + ) !== null, + "the locked Threads page to return to the app page", ); expect( - requireShadow(context.inspector).querySelector("cpk-thread-list"), - ).toBe(inPageThreadList); - expect(portableThreadListStyle.ownerDocument).toBe(document); + requireShadow(context.inspector).querySelector( + '[data-inspector-locked-feature="threads"]', + ), + ).toBe(inPageLockedFeature); } finally { context.teardown(); } diff --git a/packages/web-inspector/src/__tests__/metadata-telemetry.spec.ts b/packages/web-inspector/src/__tests__/metadata-telemetry.spec.ts index c2859a2b91..d452ba9b92 100644 --- a/packages/web-inspector/src/__tests__/metadata-telemetry.spec.ts +++ b/packages/web-inspector/src/__tests__/metadata-telemetry.spec.ts @@ -402,7 +402,7 @@ test("Threads footer action emits one impression per visible transition and one } }); -test("a valid manage action emits one footer impression when Threads endpoints are locked", async () => { +test("locked Threads suppress the footer action and its impression", async () => { const context = await setup({ metadataResponses: [fullMetadata()], threadsAvailable: false, @@ -414,13 +414,12 @@ test("a valid manage action emits one footer impression when Threads endpoints a const root = requireShadowRoot(context.inspector); const footer = root.querySelectorAll("[data-inspector-threads-footer]"); const action = root.querySelectorAll("[data-inspector-threads-footer] a"); - expect(footer).toHaveLength(1); - expect(action).toHaveLength(1); + expect(footer).toHaveLength(0); + expect(action).toHaveLength(0); const actionViews = metadataBodies(context).filter( ({ properties }) => properties.module === "action", ); - expect(actionViews).toHaveLength(1); - expect(actionViews[0]?.properties.action_placement).toBe("threads_footer"); + expect(actionViews).toHaveLength(0); expect( context.telemetryBodies.filter( ({ event }) => event === TELEMETRY_EVENTS.metadataActionClicked, @@ -439,16 +438,6 @@ const metadataActionCases = [ label: "Manage plan", expectedKind: "manage_plan", }, - { - name: "renew", - metadata: fullMetadata({ - licenseState: "expired", - actionKind: "renew", - }), - threadsAvailable: false, - label: "Renew", - expectedKind: "renew", - }, ] satisfies ReadonlyArray<{ name: string; metadata: InspectorMetadataV1; @@ -503,7 +492,7 @@ test.each(metadataActionCases)( }, ); -test("enable Intelligence stays on its existing event without a generic double count", async () => { +test("locked metadata actions yield to the unified engineer CTA", async () => { const context = await setup({ metadataResponses: [ fullMetadata({ licenseState: "none", actionKind: "enable_intelligence" }), @@ -515,13 +504,7 @@ test("enable Intelligence stays on its existing event without a generic double c await context.selectTab("Threads"); expect( metadataBodies(context).map(({ properties }) => properties.module), - ).toEqual(["identity", "plan", "identity", "plan", "action"]); - - expect(metadataBodies(context).at(-1)?.properties).toMatchObject({ - module: "action", - action_kind: "enable_intelligence", - license_bucket: "none", - }); + ).toEqual(["identity", "plan", "identity", "plan"]); const toggleSettings = async (): Promise => { const settings = context.inspector.shadowRoot?.querySelector( @@ -537,7 +520,7 @@ test("enable Intelligence stays on its existing event without a generic double c metadataBodies(context).filter( ({ properties }) => properties.module === "action", ), - ).toHaveLength(2); + ).toHaveLength(0); await context.selectTab("Agent"); await context.selectTab("AG-UI Events"); @@ -546,24 +529,23 @@ test("enable Intelligence stays on its existing event without a generic double c metadataBodies(context).filter( ({ properties }) => properties.module === "action", ), - ).toHaveLength(3); + ).toHaveLength(0); const action = context.inspector.shadowRoot?.querySelector( - '[data-inspector-action-placement="locked"]', + '[data-inspector-locked-feature-talk="threads"]', ); - if (!action) throw new Error("Enable Intelligence action was not rendered"); + if (!action) throw new Error("Talk to an Engineer action was not rendered"); action.dispatchEvent(new Event("click")); action.dispatchEvent(new Event("click")); await Promise.resolve(); - const enableEvents = context.telemetryBodies.filter( - ({ event }) => - event === "oss.inspector.threads_intelligence_signup_clicked", + const talkEvents = context.telemetryBodies.filter( + ({ event }) => event === TELEMETRY_EVENTS.threadsTalkToEngineerClicked, ); - expect(enableEvents).toHaveLength(2); - expect(enableEvents.map(({ event }) => event)).toEqual([ - "oss.inspector.threads_intelligence_signup_clicked", - "oss.inspector.threads_intelligence_signup_clicked", + expect(talkEvents).toHaveLength(2); + expect(talkEvents.map(({ event }) => event)).toEqual([ + TELEMETRY_EVENTS.threadsTalkToEngineerClicked, + TELEMETRY_EVENTS.threadsTalkToEngineerClicked, ]); expect( context.telemetryBodies.filter( diff --git a/packages/web-inspector/src/__tests__/threads-example-video.spec.ts b/packages/web-inspector/src/__tests__/threads-example-video.spec.ts index 42a33d5cab..84c2ddae5c 100644 --- a/packages/web-inspector/src/__tests__/threads-example-video.spec.ts +++ b/packages/web-inspector/src/__tests__/threads-example-video.spec.ts @@ -515,7 +515,7 @@ test("loaded data fades in and resolved guarded playback enters playing", async } }); -test("locked reduced motion defers then loads the same asset without autoplay", async () => { +test("locked Threads use the Rich Threads Loom embed without starting the native demo lifecycle", async () => { const harness = await setupFixture({ mode: "locked", reducedMotion: true, @@ -524,23 +524,23 @@ test("locked reduced motion defers then loads the same asset without autoplay", }); try { const root = harness.inspector.shadowRoot!; - const video = requireVideo(root); - const routesBeforeGate = harness.routes(); + const video = root.querySelector( + '[data-inspector-feature-video="threads"]', + ); - expect(video.hasAttribute("src")).toBe(false); - expect(requireDemoControl(root).textContent?.trim()).toBe("Play demo"); - expectAllExamples(root); - - await harness.fireGate(); - - const control = requireDemoControl(root); - expect(video.getAttribute("src")).toBe(VIDEO_URL); - expect(video.autoplay).toBe(false); - expect(video.hasAttribute("autoplay")).toBe(false); + expect(video?.src).toBe( + "https://www.loom.com/embed/79817778d29e490c97225127d2f17b3a?hide_owner=true&hide_share=true&hide_title=true&hideEmbedTopBar=true&hide_speed=true", + ); + expect(video?.title).toBe("Rich Threads overview"); + expect(root.querySelector(".cpk-threads-overview-video")).toBeNull(); + expect( + root.querySelector(".cpk-threads-overview-video-control"), + ).toBeNull(); + expect(exampleRows(root)).toHaveLength(0); + expect(root.querySelector("cpk-thread-list")).toBeNull(); + expect(root.textContent).toContain("Rich Threads"); expect(harness.play).not.toHaveBeenCalled(); - expect(control.textContent?.trim()).toBe("Play demo"); - expect(control.getAttribute("aria-pressed")).toBe("true"); - expect(harness.routes()).toEqual(routesBeforeGate); + expect(harness.routes()).toEqual(ZERO_ROUTES); } finally { await harness.teardown(); } diff --git a/packages/web-inspector/src/__tests__/threads-states.spec.ts b/packages/web-inspector/src/__tests__/threads-states.spec.ts index c373086fd0..e91f9cde14 100644 --- a/packages/web-inspector/src/__tests__/threads-states.spec.ts +++ b/packages/web-inspector/src/__tests__/threads-states.spec.ts @@ -985,7 +985,7 @@ const lockedCapabilityCases = [ }>; test.each(lockedCapabilityCases)( - "locked Threads reuse the local demo frame for $name without real routes", + "locked Threads render the full-page Rich Threads gate for $name without real routes", async (case_) => { const harness = await setupSettledState({ endpoints: case_.endpoints, @@ -1004,40 +1004,44 @@ test.each(lockedCapabilityCases)( }); try { const root = harness.inspector.shadowRoot!; - const rows = harness.rows(); - - expect(rows.map((row) => row.textContent)).toEqual([ - expect.stringContaining("Realtime thread sync"), - expect.stringContaining("Manage saved conversations"), - expect.stringContaining("Inspect durable run history"), - ]); - expect(harness.threadList().threads.map((thread) => thread.id)).toEqual([ - "example-realtime-sync", - "example-manage-history", - "example-inspect-runs", - ]); - expect(harness.threadList().shadowRoot?.textContent).not.toContain( - "Persisted support thread", - ); + expect(root.querySelector("cpk-thread-list")).toBeNull(); + expect(root.textContent).toContain("Rich Threads"); expect(root.textContent).toContain( - "Enable Intelligence to inspect Threads.", + "Production-grade chat threads without the complexity. Self hostable.", + ); + const video = root.querySelector( + '[data-inspector-feature-video="threads"]', + ); + expect(video?.src).toBe( + "https://www.loom.com/embed/79817778d29e490c97225127d2f17b3a?hide_owner=true&hide_share=true&hide_title=true&hideEmbedTopBar=true&hide_speed=true", + ); + const outline = root.querySelector( + '[data-inspector-feature-outline="threads"]', + ); + expect(outline?.getAttribute("aria-label")).toBe( + "Rich Threads capabilities", + ); + expect(outline?.textContent).toContain( + "The whole conversation comes back", + ); + expect(outline?.textContent).toContain( + "Generated UI stays in the thread", + ); + expect(outline?.textContent).toContain("Return without starting over"); + expect(outline?.textContent).toContain( + "Infrastructure you do not have to rebuild", ); - expect( - root.querySelector(".cpk-threads-overview-video-frame"), - ).not.toBeNull(); expect(root.textContent).not.toContain("Learn how Threads work"); expect(root.textContent).not.toContain( "Explore self-hosted Intelligence", ); const action = root.querySelector( - '[data-inspector-action-placement="locked"]', + '[data-inspector-locked-feature-talk="threads"]', ); - expect(action?.textContent?.trim()).toBe("Enable Intelligence"); - expect(action?.href).toBe("https://cloud.copilotkit.ai/actions/enable"); - expect( - root.querySelector("[data-inspector-threads-footer]"), - ).not.toBeNull(); - expect(root.textContent).toContain("0 / 200 Threads"); + expect(action?.textContent?.trim()).toBe("Talk to an Engineer"); + expect(new URL(action!.href).pathname).toBe("/talk-to-an-engineer"); + expect(root.querySelector("[data-inspector-threads-footer]")).toBeNull(); + expect(root.textContent).not.toContain("0 / 200 Threads"); expect(harness.routes()).toEqual(ZERO_ROUTES); const lockedEvents = telemetryFor( harness.telemetryBodies, @@ -1059,23 +1063,13 @@ test.each(lockedCapabilityCases)( runtime_url_type: "remote", telemetry_disabled: false, }); - expect(exampleEvents).toHaveLength(3); - expect( - exampleEvents.map(({ properties }) => properties.example_kind), - ).toEqual(["realtime_sync", "manage_history", "inspect_runs"]); + expect(exampleEvents).toEqual([]); expect( telemetryFor( harness.telemetryBodies, TELEMETRY_EVENTS.threadsEmptyEnabledViewed, ), ).toEqual([]); - - await exerciseLocalExamples(harness, ZERO_ROUTES, "Locked"); - - await harness.selectRow("Inspect durable run history"); - expect(root.textContent).toContain( - "Enable Intelligence to inspect Threads.", - ); expect(harness.routes()).toEqual(ZERO_ROUTES); } finally { await harness.teardown(); @@ -1091,8 +1085,6 @@ type LockedActionCase = Readonly<{ actionUrl?: string; heading: string; description?: string; - bodyLabel?: string; - footerLabel?: string; }>; const lockedActionCases: ReadonlyArray = [ @@ -1104,7 +1096,6 @@ const lockedActionCases: ReadonlyArray = [ actionUrl: "https://cloud.copilotkit.ai/actions/manage", heading: "Finish setting up Rich Threads", description: "Copy this prompt into your coding agent to finish the setup.", - footerLabel: "Manage Your Plan", }, { name: "none enable action", @@ -1112,8 +1103,10 @@ const lockedActionCases: ReadonlyArray = [ runtimeLicense: "none", actionKind: "enable_intelligence", actionUrl: "https://cloud.copilotkit.ai/actions/enable", - heading: "Enable Intelligence to inspect Threads.", - bodyLabel: "Enable Intelligence", + heading: + "Production-grade chat threads without the complexity. Self hostable.", + description: + "Chat threads that go beyond text with generative UI and multimodal inputs, built to replay missed events and stay in sync across tabs, sessions, and devices.", }, { name: "expired renew action", @@ -1122,7 +1115,6 @@ const lockedActionCases: ReadonlyArray = [ actionKind: "renew", actionUrl: "https://cloud.copilotkit.ai/actions/renew", heading: "Renew Intelligence to inspect Threads.", - bodyLabel: "Renew", }, { name: "expired manage action", @@ -1131,7 +1123,6 @@ const lockedActionCases: ReadonlyArray = [ actionKind: "manage_plan", actionUrl: "https://cloud.copilotkit.ai/actions/manage-expired", heading: "Renew Intelligence to inspect Threads.", - bodyLabel: "Manage Your Plan", }, { name: "unknown action", @@ -1145,7 +1136,8 @@ const lockedActionCases: ReadonlyArray = [ name: "missing action", metadataState: "none", runtimeLicense: "none", - heading: "Enable Intelligence to inspect Threads.", + heading: + "Production-grade chat threads without the complexity. Self hostable.", }, { name: "unsafe matched action", @@ -1153,7 +1145,8 @@ const lockedActionCases: ReadonlyArray = [ runtimeLicense: "none", actionKind: "enable_intelligence", actionUrl: "javascript:alert(1)", - heading: "Enable Intelligence to inspect Threads.", + heading: + "Production-grade chat threads without the complexity. Self hostable.", }, { name: "known metadata Runtime conflict", @@ -1166,7 +1159,7 @@ const lockedActionCases: ReadonlyArray = [ ]; test.each(lockedActionCases)( - "locked action matrix keeps only the trusted $name", + "locked action matrix keeps the unified CTAs for $name", async (case_) => { const harness = await setupSettledState({ endpoints: DISABLED_ENDPOINTS, @@ -1181,11 +1174,11 @@ test.each(lockedActionCases)( }); try { const root = harness.inspector.shadowRoot!; - const bodyAction = root.querySelector( + const metadataBodyAction = root.querySelector( '[data-inspector-action-placement="locked"]', ); - const footerAction = root.querySelector( - '[data-inspector-action-placement="threads-footer"]', + const talkAction = root.querySelector( + '[data-inspector-locked-feature-talk="threads"]', ); const promptAction = root.querySelector( "[data-inspector-threads-setup-prompt]", @@ -1195,27 +1188,32 @@ test.each(lockedActionCases)( if (case_.description) { expect(root.textContent).toContain(case_.description); } - expect(harness.rows()).toHaveLength(3); + expect(root.querySelector("cpk-thread-list")).toBeNull(); + expect(root.textContent).toContain("Rich Threads"); expect(promptAction?.textContent?.trim()).toBe("Copy setup prompt"); - expect(bodyAction?.textContent?.trim()).toBe(case_.bodyLabel); - expect(footerAction?.textContent?.trim()).toBe(case_.footerLabel); - if (case_.bodyLabel) { - expect(bodyAction?.href).toBe(case_.actionUrl); - expect(bodyAction?.target).toBe("_blank"); - expect(bodyAction?.rel.split(/\s+/)).toContain("noopener"); - } else { - expect(bodyAction).toBeNull(); - } + expect(metadataBodyAction).toBeNull(); + expect(talkAction?.textContent?.trim()).toBe("Talk to an Engineer"); + expect(new URL(talkAction!.href).pathname).toBe("/talk-to-an-engineer"); + expect(talkAction?.target).toBe("_blank"); + expect(talkAction?.rel.split(/\s+/)).toContain("noopener"); expect(promptAction?.type).toBe("button"); + expect(promptAction?.classList.contains("inspector-account-cta")).toBe( + true, + ); + expect( + promptAction?.classList.contains("cpk-threads-overview-action-primary"), + ).toBe(false); expect(promptAction?.getAttribute("aria-label")).toBe( "Copy setup prompt for Threads", ); - if (case_.footerLabel) { - expect(footerAction?.href).toBe(case_.actionUrl); - } else { - expect(footerAction).toBeNull(); - } - await exerciseLocalExamples(harness, ZERO_ROUTES, case_.name); + expect( + root.querySelector('.cpk-locked-feature-icon svg[viewBox="0 0 15 15"]'), + ).not.toBeNull(); + expect( + root.querySelector( + '[data-inspector-action-placement="threads-footer"]', + ), + ).toBeNull(); expect(harness.routes()).toEqual(ZERO_ROUTES); } finally { await harness.teardown(); @@ -1363,7 +1361,7 @@ const footerCases = footerBodyStates.flatMap((state) => ); test.each(footerCases)( - "the $module.name footer stays last in the $state body", + "the $state body handles the $module.name footer placement", async ({ state, module }) => { const metadata = inspectorMetadata( "valid", @@ -1377,6 +1375,11 @@ test.each(footerCases)( const footers = root.querySelectorAll( "footer[data-inspector-threads-footer]", ); + if (state === "locked") { + expect(footers).toHaveLength(0); + expect(root.textContent).toContain("Finish setting up Rich Threads"); + return; + } const footer = footers[0]; expect(footers).toHaveLength(1); expect(footer?.parentElement?.lastElementChild).toBe(footer); @@ -1397,9 +1400,6 @@ test.each(footerCases)( expect(action).toBeNull(); } - if (state === "locked") { - expect(root.textContent).toContain("Finish setting up Rich Threads"); - } if (state === "loading") { expect(root.querySelector('[role="status"]')).not.toBeNull(); } diff --git a/packages/web-inspector/src/__tests__/threads-telemetry.spec.ts b/packages/web-inspector/src/__tests__/threads-telemetry.spec.ts index 1faa779b09..7a2410685b 100644 --- a/packages/web-inspector/src/__tests__/threads-telemetry.spec.ts +++ b/packages/web-inspector/src/__tests__/threads-telemetry.spec.ts @@ -846,14 +846,6 @@ const placementCases = [ renderedPlacement: "threads-footer", telemetryPlacement: "threads_footer", }, - { - name: "locked body", - endpoints: LOCKED_ENDPOINTS, - actionKind: "renew", - licenseState: "expired", - renderedPlacement: "locked", - telemetryPlacement: "threads_locked", - }, ] satisfies readonly PlacementCase[]; test.each(placementCases)( @@ -924,6 +916,59 @@ test.each(placementCases)( }, ); +test("the locked feature engineer CTA serializes its coarse placement", async () => { + const lockedCase = { + name: "locked body", + endpoints: LOCKED_ENDPOINTS, + actionKind: "renew", + licenseState: "expired", + renderedPlacement: "locked", + telemetryPlacement: "threads_locked", + } as const; + const harness = await setup({ + endpoints: lockedCase.endpoints, + metadataResponses: [metadataWithAction(lockedCase)], + threadsByAgent: { alpha: [] }, + }); + try { + await harness.open(); + + const root = requireElement( + harness.inspector.shadowRoot, + "Web Inspector shadow root was not rendered", + ); + const action = requireElement( + root.querySelector( + '[data-inspector-locked-feature-talk="threads"]', + ), + "Locked feature engineer action was not rendered", + ); + + action.dispatchEvent(new Event("click")); + await harness.flush(); + + const clicked = harness.telemetryFor( + TELEMETRY_EVENTS.threadsTalkToEngineerClicked, + ); + expect(clicked).toHaveLength(1); + expectExactProperties( + requireElement(clicked[0], "Engineer click was not captured"), + threadCommon({ + intelligence_status: "intelligence_not_enabled", + thread_service_status: "unavailable", + license_status: "expired", + usage_bucket: "within_limit", + expiry_bucket: "positive", + cta: "talk_to_engineer", + cta_surface: "threads_locked", + posthog_distinct_id: expect.any(String), + }), + ); + } finally { + await harness.teardown(); + } +}); + test("all examples and the complete tour serialize only closed kinds and step pairs", async () => { const harness = await setup(); try { @@ -1242,12 +1287,10 @@ test("Settings overlay keeps Learning memories keys for changed metadata", async test("runtime telemetry opt-out stops every rendered Thread telemetry side effect", async () => { const disclosureLog = vi.spyOn(console, "info").mockImplementation(() => {}); const harness = await setup({ - endpoints: LOCKED_ENDPOINTS, + endpoints: ENABLED_ENDPOINTS, initialMenu: "ag-ui-events", telemetryDisabled: true, - threadsByAgent: { - alpha: [realThread("alpha", "opted-out-seeded-row")], - }, + threadsByAgent: { alpha: [] }, }); try { await harness.open(); diff --git a/packages/web-inspector/src/__tests__/web-inspector.spec.ts b/packages/web-inspector/src/__tests__/web-inspector.spec.ts index 701c3e939f..3702c48702 100644 --- a/packages/web-inspector/src/__tests__/web-inspector.spec.ts +++ b/packages/web-inspector/src/__tests__/web-inspector.spec.ts @@ -2245,7 +2245,6 @@ function setupRuntimeDiagnostics() { test.each([ { diagnostic: "ready entitlement", - status: "ready", legacyStatus: "expired", runtimeEntitlements: { status: "ready", @@ -2258,15 +2257,10 @@ test.each([ entitlementSource: "clerk_subscription", }, }, - errorMessage: undefined, - errorCode: undefined, - requestId: undefined, - traceId: undefined, lockedHeading: "Renew Intelligence to inspect Threads.", }, { diagnostic: "expired self-hosted entitlement", - status: "degraded", legacyStatus: "valid", runtimeEntitlements: { status: "degraded", @@ -2278,15 +2272,10 @@ test.each([ traceId: "trace-expired", }, }, - errorMessage: "Self-hosted license has expired.", - errorCode: "RUNTIME_ENTITLEMENTS_SELF_HOSTED_EXPIRED", - requestId: "req-expired", - traceId: "trace-expired", lockedHeading: "Finish setting up Rich Threads", }, { diagnostic: "misconfigured self-hosted entitlement", - status: "misconfigured", legacyStatus: "valid", runtimeEntitlements: { status: "misconfigured", @@ -2296,15 +2285,10 @@ test.each([ retryable: false, }, }, - errorMessage: "Self-hosted license configuration is missing or invalid.", - errorCode: "RUNTIME_ENTITLEMENTS_SELF_HOSTED_MISCONFIGURED", - requestId: undefined, - traceId: undefined, lockedHeading: "Finish setting up Rich Threads", }, { diagnostic: "unavailable managed entitlement", - status: "unavailable", legacyStatus: "valid", runtimeEntitlements: { status: "unavailable", @@ -2314,15 +2298,10 @@ test.each([ retryable: true, }, }, - errorMessage: "Managed entitlement resolution is temporarily unavailable.", - errorCode: "RUNTIME_ENTITLEMENTS_MANAGED_UNAVAILABLE", - requestId: undefined, - traceId: undefined, lockedHeading: "Finish setting up Rich Threads", }, { diagnostic: "SDK fail-soft entitlement lookup", - status: "unavailable", legacyStatus: "valid", runtimeEntitlements: { status: "unavailable", @@ -2332,24 +2311,11 @@ test.each([ retryable: true, }, }, - errorMessage: "Runtime entitlement lookup failed", - errorCode: "runtime_entitlements_unavailable", - requestId: undefined, - traceId: undefined, lockedHeading: "Finish setting up Rich Threads", }, ] as const)( - "renders structured Runtime entitlement diagnostics for $diagnostic", - async ({ - status, - legacyStatus, - runtimeEntitlements, - errorMessage, - errorCode, - requestId, - traceId, - lockedHeading, - }) => { + "keeps the unified locked splash for $diagnostic", + async ({ legacyStatus, runtimeEntitlements, lockedHeading }) => { const fixture = setupRuntimeDiagnostics(); try { @@ -2361,24 +2327,12 @@ test.each([ const diagnostics = inspector.shadowRoot?.querySelectorAll( "[data-runtime-entitlement-status]", ); - const diagnostic = inspector.shadowRoot?.querySelector( - `[data-runtime-entitlement-status="${status}"]`, - ); - - expect(diagnostics).toHaveLength(1); - expect(diagnostic).not.toBeNull(); - if (errorMessage) { - expect(diagnostic?.textContent).toContain(errorMessage); - } - if (errorCode) { - expect(diagnostic?.textContent).toContain(errorCode); - } - if (requestId) { - expect(diagnostic?.textContent).toContain(requestId); - } - if (traceId) { - expect(diagnostic?.textContent).toContain(traceId); - } + expect(diagnostics).toHaveLength(0); + expect( + inspector.shadowRoot?.querySelector( + '[data-inspector-feature-video="threads"]', + ), + ).not.toBeNull(); expect(inspector.shadowRoot?.textContent ?? "").toContain(lockedHeading); expect( fixture.fetchMock.mock.calls.some((call) => @@ -2391,7 +2345,7 @@ test.each([ }, ); -test("falls back to expired legacy license diagnostics when structured entitlements are omitted", async () => { +test("keeps the unified locked splash for an expired legacy license", async () => { const fixture = setupRuntimeDiagnostics(); try { @@ -2402,12 +2356,7 @@ test("falls back to expired legacy license diagnostics when structured entitleme const diagnostics = inspector.shadowRoot?.querySelectorAll( "[data-runtime-entitlement-status]", ); - const degraded = inspector.shadowRoot?.querySelector( - '[data-runtime-entitlement-status="degraded"]', - ); - - expect(diagnostics).toHaveLength(1); - expect(degraded).not.toBeNull(); + expect(diagnostics).toHaveLength(0); expect(inspector.shadowRoot?.textContent ?? "").toContain( "Renew Intelligence to inspect Threads.", ); @@ -2766,11 +2715,13 @@ describe("WebInspectorElement owned thread store headers (#5581)", () => { ).map((anchor) => anchor.textContent?.trim()); expect( ctaLabels.filter((label) => label === "Talk to an Engineer"), - ).toEqual(["Talk to an Engineer"]); + ).toEqual(["Talk to an Engineer", "Talk to an Engineer"]); const engineer = inspector.shadowRoot?.querySelector( - 'a[href^="https://www.copilotkit.ai/talk-to-an-engineer"]', + '[data-inspector-locked-feature-talk="threads"]', ); - expect(engineer?.closest("#cpk-main-scroll")).toBeNull(); + expect(engineer?.closest("#cpk-main-scroll")).not.toBeNull(); + expect(inspector.shadowRoot?.querySelector("cpk-thread-list")).toBeNull(); + expect(text).toContain("Rich Threads"); expect(text).not.toContain("No threads yet"); expect( fetchMock.mock.calls.some((call) => String(call[0]).includes("/threads")), @@ -3502,15 +3453,37 @@ describe("WebInspectorElement memories — view states", () => { const text = el.shadowRoot?.textContent ?? ""; expect(text).toContain("Learning"); expect(text).toContain( - "Learning turns durable information from agent interactions into reusable context. It isn't enabled on this deployment.", + "Learning captures durable information from agent interactions and brings it back when it matters, so your product gets more useful over time.", ); - expect(el.shadowRoot?.querySelector(".cpk-memory-locked")).not.toBeNull(); expect( - el.shadowRoot?.querySelector(".cpk-memory-locked-scrim"), + el.shadowRoot?.querySelector('[data-inspector-locked-feature="memory"]'), ).not.toBeNull(); + const video = el.shadowRoot?.querySelector( + '[data-inspector-feature-video="memory"]', + ); + expect(video?.src).toBe( + "https://www.loom.com/embed/2978fbfe42324e509057ac5fd46b7a70?hide_owner=true&hide_share=true&hide_title=true&hideEmbedTopBar=true&hide_speed=true", + ); + const outline = el.shadowRoot?.querySelector( + '[data-inspector-feature-outline="memory"]', + ); + expect(outline?.getAttribute("aria-label")).toBe("Learning capabilities"); + expect(outline?.textContent).toContain("Memory across sessions"); + expect(outline?.textContent).toContain("Recall by meaning"); + expect(outline?.textContent).toContain("Built-in structure"); + expect(outline?.textContent).toContain("Full visibility"); + const setupPrompt = el.shadowRoot?.querySelector( + '[data-inspector-feature-setup-prompt="memory"]', + ); + expect(setupPrompt?.classList.contains("inspector-account-cta")).toBe(true); expect( - el.shadowRoot?.querySelector(".cpk-memory-locked-action-secondary"), + el.shadowRoot?.querySelector( + '.cpk-locked-feature-icon svg[viewBox="0 0 24 24"]', + ), ).not.toBeNull(); + expect(el.shadowRoot?.textContent).not.toContain( + "Sign up for Intelligence", + ); const memoryList = el.shadowRoot?.querySelector("cpk-memory-list"); expect( memoryList, @@ -3522,7 +3495,9 @@ describe("WebInspectorElement memories — view states", () => { const core = makeCoreWithMemory([], { licenseStatus: "none" }); const el = await mountMemories(core); - expect(el.shadowRoot?.querySelector(".cpk-memory-locked")).not.toBeNull(); + expect( + el.shadowRoot?.querySelector('[data-inspector-locked-feature="memory"]'), + ).not.toBeNull(); expect( el.shadowRoot?.querySelector( '[data-inspector-feature-setup-prompt="memory"]', @@ -3534,24 +3509,25 @@ describe("WebInspectorElement memories — view states", () => { it("does not use Threads onboarding UTM attribution for locked memory CTAs", async () => { const core = makeCoreNoIntelligence(); const el = await mountMemories(core); + const lockedOverview = el.shadowRoot?.querySelector( + '[data-inspector-locked-feature="memory"]', + ); - const talkToEngineer = el.shadowRoot?.querySelector( + const talkToEngineer = lockedOverview?.querySelector( 'a[href^="https://www.copilotkit.ai/talk-to-an-engineer"]', ); - const signup = el.shadowRoot?.querySelector( - 'a[href^="https://intelligence.copilotkit.ai/?ref="]', - ); - expect(talkToEngineer).not.toBeNull(); - expect(signup).not.toBeNull(); + expect( + lockedOverview?.querySelector( + 'a[href^="https://intelligence.copilotkit.ai/?ref="]', + ), + ).toBeNull(); - for (const href of [talkToEngineer!.href, signup!.href]) { - const url = new URL(href); - expect(url.searchParams.get("ref")).toBeTruthy(); - expect(url.searchParams.has("utm_source")).toBe(false); - expect(url.searchParams.has("utm_medium")).toBe(false); - expect(url.searchParams.has("utm_campaign")).toBe(false); - } + const url = new URL(talkToEngineer!.href); + expect(url.searchParams.get("ref")).toBeTruthy(); + expect(url.searchParams.has("utm_source")).toBe(false); + expect(url.searchParams.has("utm_medium")).toBe(false); + expect(url.searchParams.has("utm_campaign")).toBe(false); }); it("renders the locked teaser when memories are unavailable", async () => { @@ -4123,11 +4099,11 @@ describe("WebInspectorElement memories — older-core compat (no getMemoryStore) await el.updateComplete; const text = el.shadowRoot?.textContent ?? ""; - expect(text).toContain("@copilotkit SDK"); - expect(text).toContain("Upgrade"); + expect(text).toContain("Upgrade to enable Learning"); + expect(text).toContain("@copilotkit/core and @copilotkit/react"); // Must NOT show the deployment-not-enabled copy in this case. expect(text).not.toContain( - "Learning turns durable information from agent interactions into reusable context. It isn't enabled on this deployment.", + "Learning captures durable information from agent interactions and brings it back when it matters, so your product gets more useful over time.", ); }); @@ -4139,9 +4115,9 @@ describe("WebInspectorElement memories — older-core compat (no getMemoryStore) const text = el.shadowRoot?.textContent ?? ""; expect(text).toContain( - "Learning turns durable information from agent interactions into reusable context. It isn't enabled on this deployment.", + "Learning captures durable information from agent interactions and brings it back when it matters, so your product gets more useful over time.", ); - expect(text).not.toContain("@copilotkit SDK"); + expect(text).not.toContain("Learning requires a newer version"); }); }); diff --git a/packages/web-inspector/src/index.ts b/packages/web-inspector/src/index.ts index 97d3f9edf6..c3b66febc4 100644 --- a/packages/web-inspector/src/index.ts +++ b/packages/web-inspector/src/index.ts @@ -193,17 +193,6 @@ const WHATS_NEW_VIEW_LABEL = "What's new"; /** Menu key of the What's new leaf — the news signal's destination. */ const WHATS_NEW_MENU_KEY = "whats-new"; -interface RuntimeEntitlementDisplayDiagnostic { - status: "ready" | "degraded" | "misconfigured" | "unavailable"; - error?: { - code: string; - message: string; - retryable: boolean; - requestId?: string; - traceId?: string; - }; -} - type LucideIconName = keyof typeof icons; type MenuItem = { @@ -823,6 +812,67 @@ const THREADS_EXAMPLE_OVERVIEW_VIDEO_URL = "https://cdn.copilotkit.ai/corp-site/videos/copilotkit-generative-ui-agentic-frontend-demo.webm"; const THREADS_EXAMPLE_OVERVIEW_VIDEO_FALLBACK = "The demo video is unavailable. Use the example threads to explore Messages, AG-UI Events, and State."; +const THREADS_LOCKED_VIDEO_URL = + "https://www.loom.com/embed/79817778d29e490c97225127d2f17b3a?hide_owner=true&hide_share=true&hide_title=true&hideEmbedTopBar=true&hide_speed=true"; +const LEARNING_LOCKED_VIDEO_URL = + "https://www.loom.com/embed/2978fbfe42324e509057ac5fd46b7a70?hide_owner=true&hide_share=true&hide_title=true&hideEmbedTopBar=true&hide_speed=true"; +type LockedFeatureOutlineItem = Readonly<{ + icon: LucideIconName; + title: string; + description: string; +}>; +const THREADS_LOCKED_FEATURE_OUTLINE = [ + { + icon: "MessagesSquare", + title: "The whole conversation comes back", + description: + "Rich Threads restores the complete interaction, not just a transcript. Messages, tool calls, shared state, generated interfaces, and supported files return together when a user reopens the thread.", + }, + { + icon: "LayoutGrid", + title: "Generated UI stays in the thread", + description: + "Cards, charts, A2UI surfaces, MCP Apps, and tool renderers remain part of the conversation. The demo above shows a generated spending chart returning after a reload.", + }, + { + icon: "RefreshCw", + title: "Return without starting over", + description: + "Users can move across sessions and devices while thread lists stay synchronized across open tabs. Rich Threads replays missed events and reconnects to work already in progress.", + }, + { + icon: "Server", + title: "Infrastructure you do not have to rebuild", + description: + "CopilotKit handles durable event storage, replay, synchronization, lifecycle APIs, and thread locks on one portable AG-UI history model. Use CopilotKit Cloud or deploy Intelligence in your own Kubernetes environment.", + }, +] as const satisfies ReadonlyArray; +const LEARNING_LOCKED_FEATURE_OUTLINE = [ + { + icon: "History", + title: "Memory across sessions", + description: + "Keep useful facts, preferences, and decisions after the thread closes. Learning gives future conversations the context they need without asking users to repeat themselves.", + }, + { + icon: "Search", + title: "Recall by meaning", + description: + "Surface relevant memories by what they mean, not by an exact phrase. Your agent can bring the right context into a new interaction even when the user asks in a completely different way.", + }, + { + icon: "Layers", + title: "Built-in structure", + description: + "Turn raw interactions into organized topical, episodic, and operational knowledge. Learning separates enduring facts from individual experiences and useful instructions automatically.", + }, + { + icon: "Eye", + title: "Full visibility", + description: + "Inspect exactly what your agent learned and trace each memory back to the threads that shaped it. Review the stored context instead of treating memory like a black box.", + }, +] as const satisfies ReadonlyArray; const THREADS_EXAMPLE_TOUR_STORAGE_KEY = "cpk:inspector:threads-example-tour:v1"; const THREADS_EXAMPLE_AGENT_ID = "threads-feature"; @@ -10501,6 +10551,11 @@ export class WebInspectorElement extends LitElement { height: 100%; object-fit: cover; } + .cpk-threads-overview-video-embed { + width: 100%; + height: 100%; + border: 0; + } /* ── Header controls on the branded account strip ──────────── */ .drag-handle > div[data-inspector-account-strip] button { @@ -16489,23 +16544,15 @@ export class WebInspectorElement extends LitElement { placement: "threads-footer" | "locked"; }> | undefined { - const { threadsFooterAction, lockedAction } = - this.inspectorMetadataProjection; + const { threadsFooterAction } = this.inspectorMetadataProjection; if ( threadsFooterAction && !this.settingsOpen && - this.selectedMenu === "threads" + this.selectedMenu === "threads" && + this.areThreadEndpointsAvailable() ) { return { action: threadsFooterAction, placement: "threads-footer" }; } - if ( - lockedAction && - !this.settingsOpen && - this.selectedMenu === "threads" && - !this.areThreadEndpointsAvailable() - ) { - return { action: lockedAction, placement: "locked" }; - } return undefined; } @@ -16744,14 +16791,12 @@ export class WebInspectorElement extends LitElement { } private shouldRenderExampleThreads( - locked: boolean, displayThreads: ɵThread[], threadsErrorMessage: string | null, threadsLoading: boolean, ): boolean { return ( - locked || - (!threadsErrorMessage && !threadsLoading && displayThreads.length === 0) + !threadsErrorMessage && !threadsLoading && displayThreads.length === 0 ); } @@ -17496,72 +17541,140 @@ export class WebInspectorElement extends LitElement { `; } - private renderThreadsExampleOverview(locked: boolean) { - const lockedCopy = locked ? this.getThreadsLockedCopy() : undefined; - const { lockedAction } = this.inspectorMetadataProjection; + private renderThreadsExampleOverview() { const onboardingAction = this.getThreadsEmptyOnboardingAction(); return html`

- ${ - lockedCopy?.heading ?? - "Threads are persistent, inspectable conversations" - } + Threads are persistent, inspectable conversations

${this.renderThreadsExampleOverviewVideo()}

- ${ - lockedCopy?.description ?? - "Take a tour with the example threads in the sidebar. Then, start chatting in your app to create the first real thread." - } + Take a tour with the example threads in the sidebar. Then, start + chatting in your app to create the first real thread.

- ${ - locked - ? this.renderRuntimeEntitlementDiagnostic( - this.getRuntimeEntitlementDiagnostic(), - ) - : nothing - }
- ${ - locked - ? html` - ${this.renderFeatureSetupPrompt( - "threads", - "cpk-threads-overview-action cpk-threads-overview-action-primary", - )} - ${ - lockedAction - ? this.renderInspectorAction(lockedAction, "locked") - : nothing - } - ` - : html` - - Learn how Threads work - - - ${onboardingAction.label} - - ` - } + + Learn how Threads work + + + ${onboardingAction.label} +
`; } + private renderLockedFeatureOverview({ + serviceId, + featureName, + heading, + description, + videoUrl, + videoTitle, + outlineItems, + }: { + serviceId: HomeFeaturePromptId; + featureName: string; + heading: string; + description: string; + videoUrl: string; + videoTitle: string; + outlineItems: ReadonlyArray; + }) { + return html` +
+
+
+
+
+ + ${featureName} +
+

${heading}

+

${description}

+
+ ${this.renderFeatureSetupPrompt( + serviceId, + "inspector-account-cta cpk-locked-feature-setup-cta", + )} + + Talk to an Engineer + +
+
+
+
+ +
+
+
+
+
+ ${outlineItems.map( + (item) => html` +
+

+ + ${item.title} +

+

${item.description}

+
+ `, + )} +
+
+
+
+ `; + } + private renderThreadsExampleTour() { if ( !this.selectedThreadId || @@ -17634,58 +17747,6 @@ export class WebInspectorElement extends LitElement { `; } - private renderThreadsLockedBackgroundMockup() { - const threadRows = [ - { width: 74, accent: true }, - { width: 92 }, - { width: 68 }, - { width: 84 }, - { width: 58 }, - { width: 76 }, - ]; - - return html` - - `; - } - private getThreadsLockedCopy(): { heading: string; description: string; @@ -17699,9 +17760,10 @@ export class WebInspectorElement extends LitElement { }; case "none": return { - heading: "Enable Intelligence to inspect Threads.", + heading: + "Production-grade chat threads without the complexity. Self hostable.", description: - "Persist conversations and inspect saved thread history from the Inspector.", + "Chat threads that go beyond text with generative UI and multimodal inputs, built to replay missed events and stay in sync across tabs, sessions, and devices.", }; case "expired": return { @@ -17718,104 +17780,6 @@ export class WebInspectorElement extends LitElement { } } - /** - * Prefer the Runtime's structured entitlement diagnostic and derive a - * compatibility diagnostic only when an older Core exposes legacy status. - */ - private getRuntimeEntitlementDiagnostic(): RuntimeEntitlementDisplayDiagnostic | null { - const runtimeEntitlements = this.core?.runtimeEntitlements; - if (runtimeEntitlements) { - return runtimeEntitlements.status === "ready" - ? { status: runtimeEntitlements.status } - : { - status: runtimeEntitlements.status, - error: runtimeEntitlements.error, - }; - } - - switch (this.core?.licenseStatus) { - case "valid": - return { status: "ready" }; - case "expired": - return { - status: "degraded", - error: { - code: "legacy_license_expired", - message: "Legacy Runtime license has expired.", - retryable: false, - }, - }; - case "expiring": - return { - status: "degraded", - error: { - code: "legacy_license_expiring", - message: "Legacy Runtime license is expiring.", - retryable: false, - }, - }; - case "invalid": - return { - status: "misconfigured", - error: { - code: "legacy_license_invalid", - message: "Legacy Runtime license is invalid.", - retryable: false, - }, - }; - case "none": - case "unknown": - return { status: "unavailable" }; - default: - return null; - } - } - - /** Render exact Runtime entitlement correlation details without gating UI. */ - private renderRuntimeEntitlementDiagnostic( - diagnostic: RuntimeEntitlementDisplayDiagnostic | null, - ) { - if (!diagnostic) { - return nothing; - } - - return html` -
-
- Runtime entitlement: ${diagnostic.status} -
- ${ - diagnostic.error - ? html` -
${diagnostic.error.message}
-
Code: ${diagnostic.error.code}
- ${ - diagnostic.error.requestId - ? html`
Request ID: ${diagnostic.error.requestId}
` - : nothing - } - ${ - diagnostic.error.traceId - ? html`
Trace ID: ${diagnostic.error.traceId}
` - : nothing - } - ` - : nothing - } -
- `; - } - /** * Renders the realtime-connection indicator in the memory-store header. * Only `"connected"` shows the live (green-dot) state; `"connecting"` shows a @@ -17873,51 +17837,19 @@ export class WebInspectorElement extends LitElement { // as Home and the launcher so an unavailable feature always lands on its // setup path instead of an enabled-looking empty state. if (!learningEnabled) { - return html` -
- ${this.renderThreadsLockedBackgroundMockup()} - -
- -

Learning

-

- ${ - this._memoryStoreUnsupported - ? "Learning is unavailable in this version of the @copilotkit SDK. Upgrade @copilotkit/core (and @copilotkit/react) to a version that supports long-term memory." - : "Learning turns durable information from agent interactions into reusable context. It isn't enabled on this deployment." - } -

-
- ${this.renderFeatureSetupPrompt( - "memory", - "cpk-memory-locked-action", - )} - - Talk to an Engineer - - - Sign up for Intelligence - -
-
-
- `; + return this.renderLockedFeatureOverview({ + serviceId: "memory", + featureName: "Learning", + heading: this._memoryStoreUnsupported + ? "Upgrade to enable Learning" + : "Turn every interaction into reusable context.", + description: this._memoryStoreUnsupported + ? "Learning requires a newer version of @copilotkit/core and @copilotkit/react. Copy the setup prompt to upgrade and add long-term memory." + : "Learning captures durable information from agent interactions and brings it back when it matters, so your product gets more useful over time.", + videoUrl: LEARNING_LOCKED_VIDEO_URL, + videoTitle: "CopilotKit Learning overview", + outlineItems: LEARNING_LOCKED_FEATURE_OUTLINE, + }); } // 2. Full-screen error — only for a snapshot-LOAD failure (no memories @@ -18189,22 +18121,32 @@ export class WebInspectorElement extends LitElement { private renderThreadsView() { const locked = !this.areThreadEndpointsAvailable(); + if (locked) { + this.trackThreadsViewStateOnce("locked"); + const lockedCopy = this.getThreadsLockedCopy(); + return this.renderLockedFeatureOverview({ + serviceId: "threads", + featureName: "Rich Threads", + heading: lockedCopy.heading, + description: lockedCopy.description, + videoUrl: THREADS_LOCKED_VIDEO_URL, + videoTitle: "Rich Threads overview", + outlineItems: THREADS_LOCKED_FEATURE_OUTLINE, + }); + } + const { displayThreads, threadsErrorMessage, threadsLoading } = this.getActiveThreadsState(); const loadingWithoutRows = - !locked && - threadsLoading && - !threadsErrorMessage && - displayThreads.length === 0; + threadsLoading && !threadsErrorMessage && displayThreads.length === 0; const showingExamples = this.shouldRenderExampleThreads( - locked, displayThreads, threadsErrorMessage, threadsLoading, ); const visibleThreads = - !locked && (threadsErrorMessage || loadingWithoutRows) + threadsErrorMessage || loadingWithoutRows ? [] : showingExamples ? THREADS_EXAMPLE_THREADS @@ -18221,9 +18163,7 @@ export class WebInspectorElement extends LitElement { selectedThread !== null && selectedThread.id === this.selectedLocalExampleThreadId; - if (locked) { - this.trackThreadsViewStateOnce("locked"); - } else if ( + if ( !threadsErrorMessage && (!threadsLoading || displayThreads.length > 0) ) { @@ -18272,7 +18212,7 @@ export class WebInspectorElement extends LitElement { style="flex:1;min-width:0;overflow:hidden;display:flex;position:relative;" > ${ - !locked && threadsErrorMessage + threadsErrorMessage ? html`
:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-\[16px\]{border-radius:16px}.rounded-\[28px\]{border-radius:28px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-amber-200{border-color:var(--color-amber-200)}.border-blue-200{border-color:var(--color-blue-200)}.border-emerald-200{border-color:var(--color-emerald-200)}.border-gray-200{border-color:var(--color-gray-200)}.border-purple-200{border-color:var(--color-purple-200)}.border-rose-200{border-color:var(--color-rose-200)}.border-rose-300{border-color:var(--color-rose-300)}.border-slate-200{border-color:var(--color-slate-200)}.border-violet-200{border-color:var(--color-violet-200)}.bg-\[\#00000014\]{background-color:#00000014}.bg-amber-50{background-color:var(--color-amber-50)}.bg-amber-100{background-color:var(--color-amber-100)}.bg-black{background-color:var(--color-black)}.bg-blue-50{background-color:var(--color-blue-50)}.bg-blue-100{background-color:var(--color-blue-100)}.bg-emerald-50{background-color:var(--color-emerald-50)}.bg-emerald-500{background-color:var(--color-emerald-500)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-50\/50{background-color:#f9fafb80}@supports (color:color-mix(in lab, red, red)){.bg-gray-50\/50{background-color:color-mix(in oklab,var(--color-gray-50)50%,transparent)}}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-200{background-color:var(--color-gray-200)}.bg-gray-300{background-color:var(--color-gray-300)}.bg-gray-400{background-color:var(--color-gray-400)}.bg-gray-500{background-color:var(--color-gray-500)}.bg-gray-800{background-color:var(--color-gray-800)}.bg-gray-900{background-color:var(--color-gray-900)}.bg-green-100{background-color:var(--color-green-100)}.bg-purple-50{background-color:var(--color-purple-50)}.bg-rose-50{background-color:var(--color-rose-50)}.bg-rose-500{background-color:var(--color-rose-500)}.bg-slate-900{background-color:var(--color-slate-900)}.bg-transparent{background-color:#0000}.bg-violet-50{background-color:var(--color-violet-50)}.bg-white{background-color:var(--color-white)}.bg-white\/95{background-color:#fffffff2}@supports (color:color-mix(in lab, red, red)){.bg-white\/95{background-color:color-mix(in oklab,var(--color-white)95%,transparent)}}.p-0\.5{padding:calc(var(--spacing)*.5)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-4{padding-block:calc(var(--spacing)*4)}.py-8{padding-block:calc(var(--spacing)*8)}.py-10{padding-block:calc(var(--spacing)*10)}.pt-1{padding-top:calc(var(--spacing)*1)}.pt-1\.5{padding-top:calc(var(--spacing)*1.5)}.pt-8{padding-top:calc(var(--spacing)*8)}.pb-2{padding-bottom:calc(var(--spacing)*2)}.pb-3{padding-bottom:calc(var(--spacing)*3)}.pb-5{padding-bottom:calc(var(--spacing)*5)}.text-center{text-align:center}.text-left{text-align:left}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.leading-4{--tw-leading:calc(var(--spacing)*4);line-height:calc(var(--spacing)*4)}.leading-5{--tw-leading:calc(var(--spacing)*5);line-height:calc(var(--spacing)*5)}.leading-\[22px\]{--tw-leading:22px;line-height:22px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[rgb\(13\,13\,13\)\]{color:#0d0d0d}.text-amber-600{color:var(--color-amber-600)}.text-amber-800{color:var(--color-amber-800)}.text-amber-900{color:var(--color-amber-900)}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-blue-800{color:var(--color-blue-800)}.text-emerald-700{color:var(--color-emerald-700)}.text-gray-300{color:var(--color-gray-300)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-800{color:var(--color-gray-800)}.text-gray-900{color:var(--color-gray-900)}.text-green-700{color:var(--color-green-700)}.text-green-800{color:var(--color-green-800)}.text-purple-700{color:var(--color-purple-700)}.text-rose-700{color:var(--color-rose-700)}.text-rose-800{color:var(--color-rose-800)}.text-rose-950{color:var(--color-rose-950)}.text-slate-500{color:var(--color-slate-500)}.text-slate-800{color:var(--color-slate-800)}.text-violet-500{color:var(--color-violet-500)}.text-violet-600{color:var(--color-violet-600)}.text-violet-950{color:var(--color-violet-950)}.text-white{color:var(--color-white)}.italic{font-style:italic}.underline{text-decoration-line:underline}.decoration-violet-300{-webkit-text-decoration-color:var(--color-violet-300);-webkit-text-decoration-color:var(--color-violet-300);text-decoration-color:var(--color-violet-300)}.underline-offset-2{text-underline-offset:2px}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-80{opacity:.8}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_4px_4px_0_\#0000000a\,0_0_1px_0_\#0000009e\]{--tw-shadow:0 4px 4px 0 var(--tw-shadow-color,#0000000a),0 0 1px 0 var(--tw-shadow-color,#0000009e);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring,.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-transparent{--tw-ring-color:transparent}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);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-filter{-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-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-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))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}.placeholder\:text-gray-500::placeholder{color:var(--color-gray-500)}.focus-within\:shadow-\[0_6px_18px_0_\#00000014\,0_0_1px_0_\#0000009e\]:focus-within{--tw-shadow:0 6px 18px 0 var(--tw-shadow-color,#00000014),0 0 1px 0 var(--tw-shadow-color,#0000009e);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}@media (hover:hover){.hover\:border-gray-300:hover{border-color:var(--color-gray-300)}.hover\:bg-blue-50\/50:hover{background-color:#eff6ff80}@supports (color:color-mix(in lab, red, red)){.hover\:bg-blue-50\/50:hover{background-color:color-mix(in oklab,var(--color-blue-50)50%,transparent)}}.hover\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-gray-200:hover{background-color:var(--color-gray-200)}.hover\:bg-gray-800:hover{background-color:var(--color-gray-800)}.hover\:bg-rose-100:hover{background-color:var(--color-rose-100)}.hover\:bg-violet-100:hover{background-color:var(--color-violet-100)}.hover\:text-gray-900:hover{color:var(--color-gray-900)}.hover\:text-violet-800:hover{color:var(--color-violet-800)}.hover\:decoration-violet-700:hover{-webkit-text-decoration-color:var(--color-violet-700);-webkit-text-decoration-color:var(--color-violet-700);text-decoration-color:var(--color-violet-700)}.hover\:opacity-70:hover{opacity:.7}}.focus\:border-gray-300:focus{border-color:var(--color-gray-300)}.focus\:border-violet-400:focus{border-color:var(--color-violet-400)}.focus\:bg-gray-50:focus{background-color:var(--color-gray-50)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-gray-200:focus{--tw-ring-color:var(--color-gray-200)}.focus\:ring-violet-100:focus{--tw-ring-color:var(--color-violet-100)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:rounded:focus-visible{border-radius:.25rem}.focus-visible\:rounded-sm:focus-visible{border-radius:var(--radius-sm)}.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-rose-300:focus-visible{--tw-ring-color:var(--color-rose-300)}.focus-visible\:ring-violet-300:focus-visible{--tw-ring-color:var(--color-violet-300)}.focus-visible\:ring-violet-400:focus-visible{--tw-ring-color:var(--color-violet-400)}.focus-visible\:ring-offset-1:focus-visible{--tw-ring-offset-width:1px;--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-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\:outline:focus-visible{outline-style:var(--tw-outline-style);outline-width:1px}.focus-visible\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\:outline-offset-2:focus-visible{outline-offset:2px}.focus-visible\:outline-\[\#BEC2FF\]:focus-visible{outline-color:#bec2ff}.focus-visible\:outline-gray-300:focus-visible{outline-color:var(--color-gray-300)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.active\:opacity-60:active{opacity:.6}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:text-gray-500:disabled{color:var(--color-gray-500)}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}@media (min-width:48rem){.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}.\[\&\>svg\]\:\!h-8>svg{height:calc(var(--spacing)*8)!important}.\[\&\>svg\]\:h-3>svg{height:calc(var(--spacing)*3)}.\[\&\>svg\]\:h-3\.5>svg{height:calc(var(--spacing)*3.5)}.\[\&\>svg\]\:h-\[18px\]>svg{height:18px}.\[\&\>svg\]\:\!w-8>svg{width:calc(var(--spacing)*8)!important}.\[\&\>svg\]\:w-3>svg{width:calc(var(--spacing)*3)}.\[\&\>svg\]\:w-3\.5>svg{width:calc(var(--spacing)*3.5)}.\[\&\>svg\]\:w-\[18px\]>svg{width:18px}.\[\&\>svg\]\:animate-spin>svg{animation:var(--animate-spin)}.sr-only{clip:rect(0,0,0,0);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}}.cpk-json-block{white-space:pre-wrap;word-break:break-all;color:#57575b;margin:0;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:11px;line-height:1.8;overflow:auto}.inspector-account-strip{border-bottom:1px solid #d8d8e8;width:100%;min-width:0;color:#010507!important;background:#f7f6fd!important}.inspector-account-logo{filter:none}.inspector-account-brand{position:relative}.inspector-account-logo-accent{clip-path:inset(0 0 0 80%);pointer-events:none;display:none;position:absolute;inset:0}.inspector-account-cta{isolation:isolate;color:#3f176f;white-space:nowrap;cursor:pointer;background-color:#eee6fe;border:0;border-radius:5px;flex:none;justify-content:center;align-items:center;gap:7px;min-height:32px;padding:7px 10px;font-size:11px;font-weight:700;line-height:1;text-decoration:none;display:inline-flex;position:relative;overflow:hidden}.inspector-account-cta:after{z-index:0;content:"";opacity:0;pointer-events:none;background:linear-gradient(105deg,#0000 0%,#ffffff14 32%,#ffffffad 50%,#ffffff14 68%,#0000 100%);width:68%;animation:3.8s cubic-bezier(.16,1,.3,1) infinite inspector-account-cta-shimmer;position:absolute;inset:0;transform:translate(-180%)skew(-14deg)}.inspector-account-cta>*{z-index:1;position:relative}.inspector-account-cta[data-motion-paused=true]:after{animation-play-state:paused}@keyframes inspector-account-cta-shimmer{0%{opacity:0;transform:translate(-180%)skew(-14deg)}12%{opacity:1}82%{opacity:.8}to{opacity:0;transform:translate(280%)skew(-14deg)}}.inspector-account-cta:hover{color:#32105d;background-color:#e4d8fc}.inspector-account-cta svg{width:14px;height:14px}@media (prefers-reduced-motion:reduce){.inspector-account-cta:after{animation:none}}.inspector-window-layout{position:relative}.inspector-window-layout-menu{z-index:60;color:#010507;background-color:#fff;border:1px solid #d8d8e8;border-radius:5px;width:188px;padding:4px;display:grid;position:absolute;top:calc(100% + 6px);right:0;overflow:hidden;box-shadow:0 10px 24px #1f173924}.inspector-window-layout-menu button{min-height:34px;color:inherit;text-align:left;cursor:pointer;background-color:#0000;border:0;border-radius:4px;align-items:center;gap:9px;padding:7px 9px;font-size:12px;font-weight:600;display:flex}.inspector-window-layout-menu button:hover,.inspector-window-layout-menu button:focus-visible{color:#3f176f;background-color:#eee6fe;outline:none}.inspector-window-layout-menu button span:first-child{flex:none;display:inline-flex}.inspector-agent-placeholder{color:#68686e;border-color:#c8c8d8}.inspector-primary-navigation,.inspector-child-navigation{display:none}.inspector-shell{background-color:#f7f6fd;flex:auto;min-height:0;display:flex}.inspector-sidebar{z-index:20;background-color:#f7f6fd;border-right:1px solid #d8d8e8;flex-direction:column;flex:none;gap:8px;width:224px;min-width:224px;padding:12px 10px;transition:width .22s,min-width .22s,padding .22s;display:flex;position:relative;overflow:visible}.inspector-sidebar[data-icon-rail=true]{align-items:center;width:52px;min-width:52px;padding:8px}.inspector-sidebar-agent-scope{border-bottom:1px solid #d8d8e8;flex:none;min-width:0;padding-bottom:10px}.inspector-sidebar .inspector-agent-selector{width:100%;min-width:0}.inspector-sidebar .inspector-agent-selector>[data-context-dropdown-root=true]>button{background-color:#fff;border-radius:5px;max-width:none;min-height:34px;padding:6px 8px}.inspector-context-dropdown-icon{color:#68686e;display:inline-flex}.inspector-context-dropdown-icon svg,.inspector-context-dropdown-chevron svg{width:14px;height:14px}.inspector-sidebar[data-icon-rail=true] .inspector-sidebar-agent-scope{padding-bottom:8px}.inspector-sidebar[data-icon-rail=true] .inspector-sidebar-agent-scope,.inspector-sidebar[data-icon-rail=true] .inspector-agent-selector,.inspector-sidebar[data-icon-rail=true] .inspector-agent-selector>[data-context-dropdown-root=true],.inspector-sidebar[data-icon-rail=true] .inspector-sidebar-footer{flex:none;justify-content:center;align-items:center;width:36px;min-width:36px;max-width:36px;display:flex}.inspector-sidebar[data-icon-rail=true] .inspector-agent-selector>[data-context-dropdown-root=true]>button,.inspector-sidebar[data-icon-rail=true] .inspector-agent-placeholder{box-sizing:border-box;justify-content:center;align-items:center;gap:0;width:36px;min-width:36px;max-width:36px;height:36px;min-height:36px;padding:0;transition:background-color .18s,border-color .18s,color .18s,box-shadow .18s;display:flex;overflow:visible}.inspector-sidebar[data-icon-rail=true] .inspector-context-dropdown-label,.inspector-sidebar[data-icon-rail=true] .inspector-context-dropdown-chevron,.inspector-sidebar[data-icon-rail=true] .inspector-agent-placeholder span:last-child{display:none}.inspector-sidebar[data-icon-rail=true] .inspector-sidebar-agent-scope [data-context-dropdown-root=true]>div{margin-top:0;top:0;left:calc(100% + 8px)}.inspector-icon-rail-menu{transform-origin:0;opacity:0;visibility:hidden;pointer-events:none;transition:opacity .18s,transform .18s,visibility .18s;transform:translate(-8px)scale(.96)}.inspector-icon-rail-menu[data-open=true]{opacity:1;visibility:visible;pointer-events:auto;transform:translate(0)scale(1)}.inspector-sidebar[data-icon-rail=true] .inspector-sidebar-section+.inspector-sidebar-section{border-top:1px solid #dbdbe5;margin-top:4px;padding-top:10px}.inspector-sidebar-nav{cursor:default;flex-direction:column;flex:auto;gap:14px;min-height:0;display:flex;overflow:hidden auto}.inspector-sidebar-section{flex-direction:column;gap:4px;display:flex}.inspector-sidebar-label{color:#838389;letter-spacing:.02em;text-align:left;text-transform:none;background:0 0;border:0;width:100%;margin:0 0 2px;padding:0 8px;font-size:11px;font-weight:600;display:block}.inspector-sidebar[data-icon-rail=true] .inspector-sidebar-label,.inspector-sidebar[data-icon-rail=true] .inspector-nav-label{display:none}.inspector-sidebar-rail-tooltip{z-index:60;color:#fff;pointer-events:none;white-space:nowrap;background-color:#242331;border-radius:6px;max-width:220px;padding:6px 9px;font-size:11px;font-weight:600;line-height:1.2;position:absolute;left:calc(100% + 8px);transform:translateY(-50%);box-shadow:0 7px 18px #1a172a2e}.inspector-sidebar-control{justify-content:flex-start;width:100%;min-height:36px;display:flex;position:relative}.inspector-sidebar[data-icon-rail=true] .inspector-sidebar-nav{overflow:visible}.inspector-sidebar[data-icon-rail=true] .inspector-sidebar-control,.inspector-sidebar[data-icon-rail=true] .inspector-sidebar-toggle,.inspector-sidebar[data-icon-rail=true] .inspector-nav-control{box-sizing:border-box;justify-content:center;align-items:center;gap:0;width:36px;min-width:36px;height:36px;min-height:36px;padding:0;overflow:visible}.inspector-sidebar[data-icon-rail=true] .inspector-nav-icon,.inspector-sidebar[data-icon-rail=true] .inspector-nav-icon svg,.inspector-sidebar[data-icon-rail=true] .inspector-context-dropdown-icon,.inspector-sidebar[data-icon-rail=true] .inspector-context-dropdown-icon svg{width:18px;height:18px;overflow:visible}.inspector-home-badge{background-color:#fa5f67;border-radius:999px;width:7px;height:7px;position:absolute;top:8px;right:8px}.inspector-sidebar[data-icon-rail=true] .inspector-home-badge{top:6px;right:8px}.inspector-sidebar-toggle{color:#57575b;width:100%;min-height:32px;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:5px;flex:none;justify-content:flex-start;align-items:center;gap:6px;padding:6px 9px;font-size:12px;font-weight:600;display:flex}.inspector-sidebar-toggle:hover{color:#010507;background-color:#f0f0f4}.inspector-sidebar-footer{flex-direction:column;flex:none;gap:6px;padding:2px 0 0;display:flex}.inspector-sidebar-status-list{grid-template-columns:minmax(0,1fr);gap:8px;display:grid}.inspector-sidebar-status-card{color:#2b2b2b;background-color:#fff;border:1px solid #d8d8e8;border-radius:7px;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:8px;min-height:52px;padding:9px 10px;display:grid;position:relative}.inspector-sidebar-status-copy{flex-direction:column;gap:2px;min-width:0;line-height:1.25;display:flex}.inspector-sidebar-status-copy strong{color:#010507;text-overflow:ellipsis;white-space:nowrap;font-size:11px;font-weight:700;overflow:hidden}.inspector-sidebar-status-copy>span{color:#57575b;text-overflow:ellipsis;white-space:nowrap;font-size:10px;overflow:hidden}.inspector-sidebar-status-card[data-state=disconnected] .inspector-sidebar-status-copy>span{color:#68686e}.inspector-sidebar-status-action{color:#3f176f;white-space:nowrap;background-color:#0000;border:0;border-radius:5px;justify-content:center;align-items:center;gap:0;width:28px;height:28px;padding:0;font-size:10px;font-weight:700;text-decoration:none;display:inline-flex}.inspector-sidebar-status-action:hover{color:#6430ab;background-color:#eee7f8;text-decoration:none}.inspector-sidebar-status-action svg{width:12px;height:12px}.inspector-sidebar-status-action-label{display:none}.inspector-sidebar-intelligence-setup{color:#3f176f;cursor:pointer;background-color:#eee7f8;border-color:#bba5df;text-decoration:none;transition:border-color .12s,background-color .12s,box-shadow .3s;animation:3.2s ease-in-out infinite inspector-sidebar-intelligence-setup-glow}@keyframes inspector-sidebar-intelligence-setup-glow{0%,to{box-shadow:0 0 #6430ab00}50%{box-shadow:0 0 16px 2px #6430ab26}}.inspector-sidebar-intelligence-setup:hover{background-color:#e4d9f4;border-color:#8e6fc0}.inspector-sidebar-intelligence-setup .inspector-sidebar-status-copy strong{color:#3f176f}.inspector-sidebar-setup-arrow{background-color:#6430ab1a;border-radius:5px;justify-content:center;align-items:center;width:28px;height:28px;display:inline-flex}.inspector-sidebar-setup-arrow svg{width:13px;height:13px}.inspector-main{background-color:#fff;flex-direction:column;flex:auto;min-width:0;display:flex;position:relative}.cpk-memory-locked{background-color:#fff;justify-content:center;align-items:center;height:100%;padding:32px;display:flex;position:relative;overflow:hidden}.cpk-locked-preview{opacity:.58;pointer-events:none;grid-template-columns:minmax(180px,28%) 1fr;display:grid;position:absolute;inset:0;overflow:hidden}.cpk-locked-preview-sidebar{background-color:#fafafa;border-right:1px solid #dbdbe5;flex-direction:column;gap:12px;padding:28px 24px;display:flex}.cpk-locked-preview-row{background-color:#fff;border-radius:10px;padding:12px;box-shadow:inset 0 0 0 1px #eeeef4}.cpk-locked-preview-row[data-accent=true]{background-color:#eee6fe}.cpk-locked-preview-bar{background-color:#d7d7df;border-radius:999px}.cpk-locked-preview-row-title{width:var(--preview-width);height:8px}.cpk-locked-preview-row[data-accent=true] .cpk-locked-preview-row-title{background-color:#a984f5}.cpk-locked-preview-row-line{background-color:#e3e3eb;width:88%;height:6px;margin-top:10px}.cpk-locked-preview-row-line:last-child{background-color:#e8e8ef;width:62%;margin-top:7px}.cpk-locked-preview-main{background-color:#fff;min-width:0;padding:42px 48px}.cpk-locked-preview-heading{width:180px;height:10px}.cpk-locked-preview-copy{background-color:#e3e3eb;width:min(520px,58%);height:8px;margin-top:28px}.cpk-locked-preview-copy+.cpk-locked-preview-copy{background-color:#e8e8ef;width:min(430px,48%);margin-top:12px}.cpk-locked-preview-cards{grid-template-columns:repeat(2,minmax(0,1fr));gap:16px;max-width:620px;margin-top:30px;display:grid}.cpk-locked-preview-card{background-color:#f5f5f8;border-radius:10px;height:116px;box-shadow:inset 0 0 0 1px #eeeef4}.cpk-locked-preview-footer-line{background-color:#e3e3eb;width:min(680px,74%);height:10px;margin-top:34px}.cpk-locked-preview-footer-line+.cpk-locked-preview-footer-line{background-color:#e8e8ef;width:min(560px,60%);margin-top:14px}.cpk-memory-locked-scrim{pointer-events:none;background:radial-gradient(circle,#ffffffe6 0,#ffffffc7 24%,#ffffff57 48%,#ffffff8f 100%);position:absolute;inset:0}.cpk-memory-locked-content{z-index:1;color:#57575b;text-align:center;max-width:440px;position:relative}.cpk-memory-locked-icon-wrap{justify-content:center;margin:0 auto 18px;display:flex}.cpk-memory-locked-icon{color:#57575b;background-color:#eee6fe;border:1px solid #dfd6fb;border-radius:10px;justify-content:center;align-items:center;width:44px;height:44px;display:flex;box-shadow:0 8px 18px #57575b24}.cpk-memory-locked-title{color:#010507;margin:0 0 8px;font-size:16px;font-weight:600;line-height:1.35}.cpk-memory-locked-copy{color:#57575b;max-width:380px;margin:0 auto 18px;font-size:13px;line-height:1.55}.cpk-memory-locked-actions{flex-wrap:wrap;justify-content:center;gap:8px;display:flex}.cpk-memory-locked-action{color:#fff;cursor:pointer;background-color:#6430ab;border:1px solid #6430ab;border-radius:5px;justify-content:center;align-items:center;gap:6px;min-height:34px;padding:8px 12px;font-size:12px;font-weight:600;text-decoration:none;display:inline-flex}.cpk-memory-locked-action:hover{background-color:#4e238c;border-color:#4e238c}.cpk-memory-locked-action-secondary{color:#57575b;background-color:#fff;border-color:#dbdbe5}.cpk-memory-locked-action-secondary:hover{background-color:#f7f7f9;border-color:#afafb7}.inspector-home{background-color:#fff;min-height:100%;padding:30px 32px 40px;position:relative;overflow:auto}.inspector-home:before{display:none}.inspector-home>*{width:min(100%,960px);margin-left:auto;margin-right:auto}.inspector-settings{color:#010507;background-color:#fff;min-height:100%;padding:34px 32px 48px;container:inspector-settings/inline-size}.inspector-settings-header{width:min(100%,720px);margin-left:auto;margin-right:auto;padding-bottom:30px}.inspector-settings-title{color:#010507;margin:0;font-family:Plus Jakarta Sans,system-ui,sans-serif;font-size:30px;font-weight:600;line-height:1.15}.inspector-settings-subtitle{color:#57575b;max-width:60ch;margin:8px 0 0;font-size:14px;line-height:1.5}.inspector-settings-section{border-top:1px solid #d5d3e4;width:min(100%,720px);margin-left:auto;margin-right:auto;padding:24px 0 26px}.inspector-settings-section-heading{align-items:flex-start;gap:12px;margin-bottom:22px;display:flex}.inspector-settings-section-icon{color:#3f176f;background-color:#eee6fe;border:1px solid #bec2ff;border-radius:8px;flex:none;justify-content:center;align-items:center;width:34px;height:34px;display:inline-flex}.inspector-settings-section-icon svg{width:17px;height:17px}.inspector-settings-section-heading h2,.inspector-settings-status-row h3,.inspector-settings-visibility h3{color:#010507;margin:0;font-family:Plus Jakarta Sans,system-ui,sans-serif;font-weight:600}.inspector-settings-section-heading h2{font-size:17px;line-height:1.3}.inspector-settings-section-heading p{color:#68686e;max-width:54ch;margin:4px 0 0;font-size:12px;line-height:1.5}.inspector-settings-privacy{margin-left:46px}.inspector-settings-status-row{justify-content:space-between;align-items:flex-start;gap:24px;display:flex}.inspector-settings-status-row>div,.inspector-settings-visibility>div{min-width:0}.inspector-settings-status-row h3{font-size:14px;line-height:1.3}.inspector-settings-status-row p{color:#57575b;max-width:56ch;margin:8px 0 0;font-size:12px;line-height:1.55}.inspector-settings-status{color:#087653;text-align:center;white-space:nowrap;background-color:#e5f7f1;border:1px solid #85d3bb;border-radius:999px;flex:none;align-items:center;min-height:24px;padding:3px 8px;font-size:11px;font-weight:700;line-height:1;display:inline-flex}.inspector-settings-privacy[data-state=disabled] .inspector-settings-status{color:#7d4d0a;background-color:#fff5df;border-color:#dfc08f}.inspector-settings-private-content{border-top:1px solid #e4e4ec;margin-top:22px;padding-top:18px}.inspector-settings-private-content strong{color:#010507;font-size:13px;font-weight:700}.inspector-settings-private-content>p{color:#68686e;margin:4px 0 0;font-size:11px;line-height:1.45}.inspector-settings-private-content ul{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px 18px;margin:12px 0 0;display:grid}.inspector-settings-private-content li{color:#3e3d48;align-items:center;gap:7px;min-width:0;font-size:12px;line-height:1.35;display:flex}.inspector-settings-private-content li span{color:#087653;flex:none;display:inline-flex}.inspector-settings-private-content li svg{width:14px;height:14px}.inspector-settings-policy-link{color:#3f176f;text-underline-offset:3px;outline-offset:2px;outline:2px solid #0000;align-items:center;gap:6px;min-height:36px;margin-top:20px;font-size:12px;font-weight:700;text-decoration:underline;text-decoration-thickness:1px;display:inline-flex}.inspector-settings-policy-link:hover{color:#6430ab}.inspector-settings-policy-link:focus-visible{outline-color:#6430ab}.inspector-settings-policy-link svg{width:14px;height:14px}.inspector-settings-visibility{margin-left:46px}.inspector-settings-visibility h3{font-size:14px;line-height:1.3}.inspector-settings-visibility p{color:#57575b;max-width:48ch;margin:8px 0 0;font-size:12px;line-height:1.55}.inspector-settings-dismiss{color:#3f176f;text-align:center;cursor:pointer;background-color:#f5f2ff;border:1px solid #c9c2e6;border-radius:7px;justify-content:center;align-items:center;gap:7px;min-height:40px;margin-top:16px;padding:8px 12px;font-size:12px;font-weight:700;line-height:1.2;display:inline-flex}.inspector-settings-dismiss:hover{background-color:#eee8ff;border-color:#a69aca}.inspector-settings-dismiss:focus-visible{outline-offset:2px;outline:2px solid #6430ab}.inspector-settings-dismiss svg{width:14px;height:14px}@media (max-width:720px){.inspector-settings{padding:28px 24px 40px}.inspector-settings-section-heading p{max-width:42ch}}@media (max-width:480px){.inspector-settings{padding-left:18px;padding-right:18px}}@container inspector-settings (max-width:520px){.inspector-settings-privacy,.inspector-settings-visibility{margin-left:0}.inspector-settings-status-row{flex-direction:column;gap:12px}.inspector-settings-private-content ul{grid-template-columns:1fr}.inspector-settings-dismiss{width:100%}}.inspector-home-card,.inspector-home-story{background-color:#ffffffd1;border:1px solid #deddea;border-radius:5px;padding:18px 18px 16px;position:relative}.inspector-home-eyebrow,.inspector-home-card-label,.inspector-home-meta{color:#57575b;margin:0;font-size:12px;font-weight:600}.inspector-home-title,.inspector-home-section-title,.inspector-home-card-title{color:#010507;margin:8px 0 0;font-family:Plus Jakarta Sans,system-ui,sans-serif;font-size:28px;font-weight:600;line-height:1.15}.inspector-home-section-title{letter-spacing:-.015em;margin:0 0 14px;font-size:17px}.inspector-home-card-title{font-size:16px}.inspector-home-body,.inspector-home-card-copy{color:#57575b;max-width:52ch;margin:10px 0 0;font-size:15px;line-height:1.5}.inspector-home-section{margin-top:24px;position:relative}.inspector-home>.inspector-home-section:first-child{margin-top:0}.inspector-whats-new-preview+.inspector-home-section{margin-top:20px}.inspector-home-section-header{justify-content:space-between;align-items:center;gap:16px;margin-bottom:12px;display:flex}.inspector-home-section-header .inspector-home-section-title{margin-bottom:0}.inspector-home-section-header>span{color:#68686e;font-size:11px;font-weight:600;line-height:1.35}.inspector-system-health-header>span[data-tone=success]{color:#087653}.inspector-system-health-header>span[data-tone=checking]{color:#8a5900}.inspector-system-health-header>span[data-tone=offline],.inspector-system-health-header>span[data-tone=error]{color:#b32d3b}.inspector-system-health-section{background-color:#f7f4fe;border:1px solid #c8c6e6;border-radius:5px;overflow:hidden}.inspector-system-health-section .inspector-system-health-header{background-color:#f7f4fe;border-bottom:1px solid #d5d3e4;align-items:center;min-height:76px;margin:0;padding:18px}.inspector-system-health-heading{min-width:0}.inspector-system-health-heading .inspector-home-section-title{color:#010507;letter-spacing:-.025em;font-size:18px}.inspector-system-health-state,.inspector-intelligence-hud-state{color:#087653;background-color:#e5f7f1;border:1px solid #85d3bb;border-radius:999px;flex:none;align-items:center;gap:6px;min-height:24px;padding:4px 8px;font-size:10px;font-weight:700;line-height:1;display:inline-flex}.inspector-system-health-state>span,.inspector-intelligence-hud-state>span{background-color:currentColor;border-radius:999px;width:6px;height:6px}.inspector-system-health-state[data-tone=checking],.inspector-intelligence-hud-state[data-tone=checking]{background-color:#fff5df;border-color:#dfc08f;color:#7d4d0a!important}.inspector-system-health-state[data-tone=offline],.inspector-system-health-state[data-tone=error],.inspector-intelligence-hud-state[data-tone=offline],.inspector-intelligence-hud-state[data-tone=error]{background-color:#fff0f1;border-color:#e7a7ac;color:#b32d3b!important}.inspector-system-health-state[data-tone=unavailable],.inspector-intelligence-hud-state[data-tone=unavailable]{background-color:#f0f0f4;border-color:#c8c8d2;color:#57575b!important}.inspector-system-health{background-color:#d5d3e4;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;display:grid;overflow:hidden}.inspector-system-health-signal{background-color:#fff;grid-template-columns:minmax(0,1fr);align-items:start;min-width:0;min-height:84px;padding:15px 16px 14px;display:grid}.inspector-system-health-copy{flex-direction:column;min-width:0;display:flex}.inspector-system-health-signal dt{color:#68686e;letter-spacing:.035em;text-transform:uppercase;font-size:10px;font-weight:700;line-height:1.3}.inspector-system-health-signal dd{color:#010507;text-overflow:ellipsis;white-space:nowrap;min-width:0;margin:5px 0 0;font-size:15px;font-weight:700;overflow:hidden}.inspector-system-health-signal small{color:#68686e;text-overflow:ellipsis;white-space:nowrap;min-width:0;margin-top:4px;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:10px;line-height:1.4;overflow:hidden}small.inspector-system-health-detail{letter-spacing:0;font-family:inherit;font-size:11px;font-weight:500;line-height:1.4}.inspector-system-health-url{cursor:help;outline:none;position:relative;overflow:visible!important}.inspector-system-health-url>span{text-overflow:ellipsis;white-space:nowrap;display:block;overflow:hidden}.inspector-system-health-url:after{z-index:30;color:#f3f4f8;content:attr(data-full-value);opacity:0;overflow-wrap:anywhere;pointer-events:none;white-space:normal;background-color:#15171e;border:1px solid #3a3d49;border-radius:4px;width:max-content;max-width:min(360px,70vw);padding:7px 9px;font-size:10px;font-weight:500;line-height:1.45;transition:opacity .12s,transform .12s;position:absolute;bottom:calc(100% + 7px);left:0;transform:translateY(3px);box-shadow:0 8px 20px #0105072e}.inspector-system-health-url:hover:after,.inspector-system-health-url:focus-visible:after{opacity:1;transform:translateY(0)}.inspector-system-health-url:focus-visible>span{outline-offset:2px;border-radius:3px;outline:2px solid #6430ab}.inspector-system-health-signal[data-tone=success] dd{color:#087653}.inspector-system-health-signal[data-tone=active] dd{color:#8a5900}.inspector-system-health-event-link{width:100%;min-width:0;color:inherit;cursor:pointer;font:inherit;text-align:left;background:0 0;border:0;padding:0;display:block}.inspector-system-health-event-link>span{text-overflow:ellipsis;white-space:nowrap;display:block;overflow:hidden}.inspector-system-health-event-link>.inspector-system-health-event-type{color:#57575b;letter-spacing:.025em;background-color:#f1f1f3;border-radius:999px;align-items:center;width:fit-content;max-width:100%;padding:3px 6px;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:10px;font-weight:700;line-height:1.25;display:inline-flex}.inspector-system-health-event-link>small{color:#68686e;align-items:center;gap:6px;margin:5px 0 0;font-family:Plus Jakarta Sans,system-ui,sans-serif;font-size:10px;font-weight:500;line-height:1.25;display:flex}.inspector-system-health-event-meta strong{color:#6430ab;text-underline-offset:3px;font-weight:700;-webkit-text-decoration:underline #0000;text-decoration:underline #0000}.inspector-system-health-signal[data-tone=error] .inspector-system-health-event-type{color:#b32d3b;background-color:#fff0f1}.inspector-system-health-signal[data-tone=success] .inspector-system-health-event-type{color:#087653;background-color:#e3f5ee}.inspector-system-health-signal[data-tone=active] .inspector-system-health-event-type{color:#8a5900;background-color:#fff5df}.inspector-system-health-event-link:hover .inspector-system-health-event-meta strong{text-decoration-color:currentColor}.inspector-system-health-event-link:focus-visible{outline-offset:3px;border-radius:3px;outline:2px solid #6430ab}.inspector-intelligence-hud{background-color:#f7f4fe;border:1px solid #c8c6e6;border-radius:5px;overflow:hidden}.inspector-intelligence-hud-header{justify-content:space-between;align-items:center;gap:24px;padding:18px;display:flex}.inspector-intelligence-hud[data-state=disconnected]{border-color:#bba5df}.inspector-intelligence-hud[data-state=disconnected] .inspector-intelligence-hud-header{align-items:center;min-height:132px;padding:22px}.inspector-intelligence-hud[data-state=disconnected] .inspector-intelligence-hud-header-actions{flex-direction:column;align-items:flex-end;gap:10px}.inspector-intelligence-hud-heading{min-width:0}.inspector-intelligence-hud-header-actions{flex:none;align-items:center;gap:8px;display:flex}.inspector-intelligence-hud-heading .inspector-home-section-title{margin:0;font-size:18px}.inspector-intelligence-hud-description{color:#4f4f55;max-width:64ch;margin:10px 0 0;font-size:12px;line-height:1.55}.inspector-intelligence-hud-action{color:#fff;background-color:#6430ab;border:1px solid #6430ab;border-radius:4px;flex:none;justify-content:center;align-items:center;gap:7px;min-height:34px;padding:8px 11px;font-family:Plus Jakarta Sans,system-ui,sans-serif;font-size:11px;font-weight:700;text-decoration:none;display:inline-flex}.inspector-intelligence-hud-action:hover{background-color:#4e238c;border-color:#4e238c}.inspector-intelligence-hud-action svg{width:13px;height:13px}.inspector-intelligence-hud-connect-action{min-height:38px;padding:10px 14px;font-size:12px}.inspector-intelligence-hud[data-mode=install] .inspector-intelligence-hud-header{background:linear-gradient(100deg,#fbfaff 0%,#f2eeff 52%,#edfaf5 100%);border-bottom:1px solid #d5d3e4;align-items:center;min-height:76px;padding:18px}.inspector-intelligence-hud[data-mode=install] .inspector-intelligence-hud-heading .inspector-home-section-title{color:#010507;letter-spacing:-.025em;align-items:center;gap:8px;font-size:18px;display:inline-flex}.inspector-intelligence-mark{flex:none;width:17px;height:17px;display:block}.inspector-intelligence-hud[data-mode=install] .inspector-intelligence-hud-header-actions{flex-direction:column;align-items:flex-end;gap:6px}.inspector-intelligence-sr-summary{clip-path:inset(50%);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.inspector-intelligence-copy{padding:16px 18px 0;display:grid}.inspector-intelligence-copy-slide{opacity:0;flex-direction:column;grid-area:1/1;gap:4px;transition:opacity .32s cubic-bezier(.22,1,.36,1),transform .38s cubic-bezier(.22,1,.36,1);display:flex}.inspector-intelligence-copy-slide[data-position=after]{transform:translate(14px)}.inspector-intelligence-copy-slide[data-position=before]{transform:translate(-14px)}.inspector-intelligence-copy-slide[data-position=active]{opacity:1;transform:none}.inspector-intelligence-copy-slide>strong{color:#2b2b31;text-wrap:balance;max-width:52ch;font-size:12.5px;font-weight:650;line-height:1.4}.inspector-intelligence-copy-slide>span{color:#4f4f55;max-width:64ch;font-size:11px;line-height:1.55}.inspector-intelligence-install{justify-content:flex-end;align-items:center;gap:12px;display:flex}.inspector-intelligence-install-copy{cursor:pointer;min-height:34px;transition:background-color .14s,border-color .14s}.inspector-intelligence-install-copy svg{width:13px;height:13px}.inspector-intelligence-install[data-copy-state=copied] .inspector-intelligence-install-copy{color:#4e238c;background-color:#fff;border-color:#bba5df}.inspector-intelligence-install-secondary{color:#6430ab;align-items:center;gap:5px;font-size:11px;font-weight:600;text-decoration:none;display:inline-flex}.inspector-intelligence-install-secondary:hover{text-underline-offset:2px;text-decoration:underline}.inspector-intelligence-install-secondary svg{width:12px;height:12px}.inspector-intelligence-install-hint{color:#68686e;white-space:nowrap;margin:0;font-size:11px;font-weight:600;line-height:1.4}.inspector-intelligence-install-hint[data-tone=success]{color:#4e238c;font-weight:600}.inspector-intelligence-install-hint[data-tone=error]{color:#a3341f;font-weight:600}.inspector-intelligence-install-fallback{color:#4f4f55;-webkit-user-select:all;user-select:all;white-space:pre-wrap;word-break:break-word;background-color:#fff;border-bottom:1px solid #d5d3e4;max-height:96px;padding:10px 18px;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:10.5px;line-height:1.65;display:block;overflow:auto}.inspector-intelligence-story{background-color:#fff;container:cpk-intel-story/inline-size}.inspector-intelligence-story-stage{padding:16px 18px;display:grid}.inspector-intelligence-beat{visibility:hidden;opacity:0;grid-area:1/1;align-items:center;transition:opacity .32s cubic-bezier(.22,1,.36,1),transform .38s cubic-bezier(.22,1,.36,1),visibility 0s linear .38s;display:flex}.inspector-intelligence-beat[data-position=after]{transform:translate(14px)}.inspector-intelligence-beat[data-position=before]{transform:translate(-14px)}.inspector-intelligence-beat[data-position=active]{visibility:visible;opacity:1;transition:opacity .32s cubic-bezier(.22,1,.36,1),transform .38s cubic-bezier(.22,1,.36,1),visibility;transform:none}.inspector-intelligence-beat[data-beat-id=threads]{flex-direction:column;justify-content:center;gap:6px}.inspector-intelligence-threads{flex-direction:column;gap:6px;width:100%;display:flex}.inspector-intelligence-thread{opacity:0;background-color:#faf9fe;border:1px solid #e6e3f2;border-radius:4px;align-items:center;gap:9px;padding:8px 10px;transition:opacity .3s,transform .3s;display:flex;transform:translateY(3px)}.inspector-intelligence-thread>i{background-color:#9b8cc4;border-radius:999px;flex:none;width:6px;height:6px}.inspector-intelligence-thread>strong{color:#2b2b31;text-overflow:ellipsis;white-space:nowrap;font-size:11px;font-weight:600;overflow:hidden}.inspector-intelligence-thread>small{color:#68686e;flex:none;margin-left:auto;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:9.5px}.inspector-intelligence-thread[data-failed=true]{background-color:#fdf6f4;border-color:#f0d5cf}.inspector-intelligence-thread[data-failed=true]>i{background-color:#c2410c}.inspector-intelligence-thread[data-failed=true]>strong,.inspector-intelligence-thread[data-failed=true]>small{color:#8f2f1c;font-weight:650}.inspector-intelligence-story[data-beat=threads] .inspector-intelligence-thread{opacity:1;transition-delay:calc(var(--thread-index)*80ms + 90ms);transform:none}.inspector-intelligence-beat[data-beat-id=learning]{grid-template-columns:minmax(0,1.15fr) auto minmax(0,.85fr);align-items:center;gap:12px;display:grid}.inspector-intelligence-beat-col{flex-direction:column;gap:6px;min-width:0;display:flex}.inspector-intelligence-beat-label{color:#68686e;letter-spacing:.06em;text-transform:uppercase;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:9px;font-weight:600}.inspector-intelligence-signal,.inspector-intelligence-rule{color:#4f4f55;opacity:0;background-color:#faf9fe;border:1px solid #e6e3f2;border-radius:4px;align-items:flex-start;gap:6px;padding:6px 8px;font-size:10.5px;line-height:1.4;transition:opacity .3s,transform .3s;display:flex;transform:translateY(3px)}.inspector-intelligence-signal{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.inspector-intelligence-rule{color:#21543f;background-color:#f4fbf8;border-color:#cfe9dd;font-weight:600}.inspector-intelligence-rule>i{color:#1f8a5f;flex:none;align-items:center;display:inline-flex}.inspector-intelligence-rule>i svg{stroke-width:2.4px;width:11px;height:11px}.inspector-intelligence-story[data-beat=learning] .inspector-intelligence-signal,.inspector-intelligence-story[data-beat=learning] .inspector-intelligence-rule{opacity:1;transform:none}.inspector-intelligence-story[data-beat=learning] .inspector-intelligence-signal{transition-delay:calc(var(--signal-index)*80ms + .1s)}.inspector-intelligence-story[data-beat=learning] .inspector-intelligence-rule{transition-delay:calc(var(--rule-index)*80ms + .42s)}.inspector-intelligence-beat-flow{color:#9b8cc4;justify-content:center;align-items:center;display:inline-flex}.inspector-intelligence-beat-flow svg{width:15px;height:15px}.inspector-intelligence-beat[data-beat-id=skill]{justify-content:center}.inspector-intelligence-skill-file{background-color:#fff;border:1px solid #d5d3e4;border-radius:5px;width:min(100%,30rem);overflow:hidden;box-shadow:0 1px 2px #100c280f}.inspector-intelligence-skill-file>header{background-color:#faf9fe;border-bottom:1px solid #ebe9f4;align-items:center;gap:7px;padding:7px 10px;display:flex}.inspector-intelligence-skill-file>header svg{color:#6430ab;width:12px;height:12px}.inspector-intelligence-skill-file>header strong{color:#2b2b31;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:10.5px;font-weight:600}.inspector-intelligence-skill-file>header em{color:#68686e;letter-spacing:.05em;text-transform:uppercase;margin-left:auto;font-size:9px;font-style:normal;font-weight:600}.inspector-intelligence-skill-code{flex-direction:column;padding:8px 0;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:10.5px;line-height:1.75;display:flex}.inspector-intelligence-skill-code>span{color:#4f4f55;gap:10px;padding:0 12px;display:flex}.inspector-intelligence-skill-code>span:before{color:#a9a7bb;content:attr(data-line);text-align:right;min-width:8px}.inspector-intelligence-skill-code>span>b{color:#6430ab;font-weight:600}.inspector-intelligence-skill-code>span[style*=--rule-index]{opacity:0;transition:opacity .26s,transform .26s;transform:translateY(2px)}.inspector-intelligence-story[data-beat=skill] .inspector-intelligence-skill-code>span[style*=--rule-index]{opacity:1;transition-delay:calc(var(--rule-index)*.11s + .26s);transform:none}.inspector-intelligence-beat[data-beat-id=intelligence]{flex-direction:column;justify-content:center;gap:12px}.inspector-intelligence-chain{justify-content:center;align-items:stretch;gap:6px;width:100%;display:flex}.inspector-intelligence-chain-step{opacity:0;background-color:#faf9fe;border:1px solid #e6e3f2;border-radius:5px;flex-direction:column;flex:1 1 0;align-items:flex-start;gap:3px;min-width:0;padding:9px 10px;transition:opacity .28s,transform .28s;display:flex;transform:translateY(4px)}.inspector-intelligence-chain-step>i{color:#6430ab;display:inline-flex}.inspector-intelligence-chain-step>i svg{width:14px;height:14px}.inspector-intelligence-chain-step>strong{color:#2b2b31;font-size:11px;font-weight:700;line-height:1.25}.inspector-intelligence-chain-step>small{color:#68686e;font-size:9.5px;line-height:1.3}.inspector-intelligence-chain-arrow{color:#bba5df;opacity:0;flex:none;align-items:center;transition:opacity .28s;display:inline-flex}.inspector-intelligence-chain-arrow svg{width:13px;height:13px}.inspector-intelligence-story[data-beat=intelligence] .inspector-intelligence-chain-step,.inspector-intelligence-story[data-beat=intelligence] .inspector-intelligence-chain-arrow{opacity:1;transition-delay:calc(var(--step-index)*90ms + 80ms);transform:none}.inspector-intelligence-chain-proof{color:#21543f;opacity:0;background-color:#f4fbf8;border:1px solid #cfe9dd;border-radius:999px;align-self:center;align-items:center;gap:6px;padding:5px 11px;font-size:10.5px;font-weight:600;transition:opacity .3s,transform .3s;display:inline-flex;transform:translateY(3px)}.inspector-intelligence-chain-proof svg{color:#1f8a5f;width:12px;height:12px}.inspector-intelligence-chain-proof code{font-family:Spline Sans Mono,ui-monospace,monospace;font-size:10px;font-weight:600}.inspector-intelligence-story[data-beat=intelligence] .inspector-intelligence-chain-proof{opacity:1;transition-delay:.46s;transform:none}.inspector-intelligence-story-rail{border-top:1px solid #ebe9f4;align-items:center;gap:2px;padding:8px 18px 9px;display:flex}.inspector-intelligence-story-tab{color:#68686e;cursor:pointer;background:0 0;border:0;border-radius:3px;padding:3px 7px 5px;font-family:Plus Jakarta Sans,system-ui,sans-serif;font-size:10.5px;font-weight:600;transition:color .16s;position:relative}.inspector-intelligence-story-tab:after{content:"";transform-origin:0;background-color:#6430ab;border-radius:2px;height:1.5px;transition:transform .28s cubic-bezier(.22,1,.36,1);position:absolute;bottom:1px;left:7px;right:7px;transform:scaleX(0)}.inspector-intelligence-story-tab:hover{color:#2b2b31}.inspector-intelligence-story-tab[data-active=true]{color:#4e238c}.inspector-intelligence-story-tab[data-active=true]:after{transform:scaleX(1)}@container cpk-intel-story (max-width:30rem){.inspector-intelligence-chain-step>small{display:none}.inspector-intelligence-story-rail{flex-wrap:wrap}}@media (prefers-reduced-motion:reduce){.inspector-intelligence-copy-slide,.inspector-intelligence-thread,.inspector-intelligence-beat,.inspector-intelligence-signal,.inspector-intelligence-rule,.inspector-intelligence-chain-step,.inspector-intelligence-chain-arrow,.inspector-intelligence-chain-proof,.inspector-intelligence-skill-code>span[style*=--rule-index],.inspector-intelligence-story-tab:after{transition-duration:0s;transition-delay:0s}}.inspector-intelligence-hud-details{background-color:#d5d3e4;border-top:1px solid #d5d3e4;grid-template-columns:minmax(0,1fr) minmax(0,2fr);gap:1px;display:grid}.inspector-intelligence-hud-details>section{background-color:#fff;min-width:0;padding:15px 18px 17px}.inspector-intelligence-hud-detail-label{color:#68686e;font-size:11px;font-weight:600;display:block}.inspector-intelligence-hud-detail-value{color:#010507;text-overflow:ellipsis;white-space:nowrap;min-width:0;margin:5px 0 0;font-size:14px;font-weight:700;display:block;overflow:hidden}.inspector-intelligence-hud-detail-subvalue{color:#68686e;text-transform:capitalize;margin-top:3px;font-size:10px;font-weight:500;display:block}.inspector-intelligence-hud-plan{grid-template-columns:minmax(0,1fr) minmax(120px,1fr);align-items:start;gap:24px;display:grid}.inspector-intelligence-hud-usage{min-width:0}.inspector-intelligence-hud-plan-action{color:#6430ab;text-underline-offset:3px;background-color:#0000;border:0;border-radius:0;gap:4px;min-height:auto;margin-top:9px;padding:0;font-size:10px;font-weight:700;line-height:1.2;-webkit-text-decoration:underline #0000;text-decoration:underline #0000;text-decoration-thickness:1px}.inspector-intelligence-hud-plan-action:hover{color:#4e238c;background-color:#0000;border-color:#0000;text-decoration-color:currentColor}.inspector-intelligence-hud-plan-action svg{width:11px;height:11px}.inspector-home-usage-bar{background-color:#dbdbe5;border-radius:999px;width:min(160px,100%);height:5px;margin-top:8px;display:block;overflow:hidden}.inspector-home-usage-bar>span{background-color:#bec2ff;height:100%;display:block}.inspector-home-feature-groups{grid-template-columns:repeat(auto-fit,minmax(min(100%,250px),1fr));align-items:start;gap:12px;display:grid}.inspector-home-feature-group{background-color:#fff;border:1px solid #d5d3e4;border-radius:5px;overflow:visible}.inspector-home-feature-group-header{color:#57575b;background-color:#f7f7f9;border-bottom:1px solid #e4e4ec;border-radius:4px 4px 0 0;justify-content:space-between;align-items:center;gap:12px;min-height:40px;padding:9px 12px;display:flex}.inspector-home-feature-group-header strong{font-size:12px;font-weight:700}.inspector-home-feature-group-header>span{background-color:#fff;border-radius:999px;justify-content:center;align-items:center;min-width:22px;min-height:20px;padding:2px 6px;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:10px;font-weight:700;display:inline-flex}.inspector-home-feature-group[data-feature-state-group=active] .inspector-home-feature-group-header{color:#087653;background-color:#e5f7f1;border-color:#b9e3d6}.inspector-home-feature-list{background-color:#fff;flex-direction:column;margin:0;display:flex}.inspector-home-feature{color:#010507;background-color:#fff;grid-template-columns:18px minmax(0,1fr) auto;align-items:center;gap:8px;min-width:0;min-height:52px;padding:9px 12px;font-size:12px;font-weight:600;display:grid;container-type:inline-size}.inspector-home-feature+.inspector-home-feature{border-top:1px solid #ececf1}.inspector-home-feature:last-child{border-radius:0 0 4px 4px}.inspector-home-feature-group-empty{color:#68686e;margin:0;padding:15px 12px;font-size:11px}.inspector-home-feature:hover{background-color:#f7f7f9}.inspector-home-feature-label{min-width:0;color:inherit;cursor:pointer;align-items:center;gap:4px;text-decoration:none;display:inline-flex}.inspector-home-feature-label>span:first-child{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.inspector-home-feature-label-icon{flex:none;display:inline-flex!important;overflow:visible!important}.inspector-home-feature-label-icon svg{width:12px;height:12px}.inspector-home-feature-label:hover{color:#3f176f;text-underline-offset:3px;text-decoration:underline;text-decoration-thickness:1px}.inspector-home-feature-label:focus-visible{outline-offset:2px;border-radius:3px;outline:2px solid #6430ab}.inspector-home-feature-actions{justify-content:flex-end;align-items:center;gap:6px;display:inline-flex}.inspector-home-feature-status{flex:none;justify-content:center;align-items:center;width:18px;height:28px;display:inline-flex}.inspector-home-feature-status>span{background-color:#fff;border:1px solid #9ca0ab;border-radius:999px;width:8px;height:8px}.inspector-home-feature[data-state=on] .inspector-home-feature-status>span{background-color:#087653;border-color:#087653}.inspector-home-feature[data-state=off]{color:#68686e}.inspector-home-feature-action{color:#4f4f55;min-width:28px;height:28px;min-height:28px;font:inherit;white-space:nowrap;cursor:pointer;background-color:#fff;border:1px solid #d5d3e4;border-radius:4px;justify-content:center;align-items:center;gap:5px;padding:0 8px;font-size:10px;font-weight:700;line-height:1;text-decoration:none;display:inline-flex}.inspector-home-feature-action svg{width:14px;height:14px}.inspector-home-feature-action-icon{flex:none;display:inline-flex!important;overflow:visible!important}.inspector-home-feature-action-label{line-height:1}.inspector-home-feature-action.inspector-system-health-url:after{content:none;left:50%;right:auto;transform:translate(-50%,3px)}.inspector-home-feature-action.inspector-system-health-url:hover:after,.inspector-home-feature-action.inspector-system-health-url:focus-visible:after{transform:translate(-50%)}.inspector-home-feature-action:hover{color:#3f176f;background-color:#f7f4fe;border-color:#bba5df}.inspector-home-feature-action:focus-visible{outline-offset:2px;outline:2px solid #6430ab}.inspector-home-feature-action[data-copy-state=copied]{color:#087653;background-color:#e5f7f1;border-color:#b9e3d6}.inspector-home-feature-action[data-copy-state=error]{color:#b32d3b;background-color:#fff0f1;border-color:#e7a7ac}@container (max-width:286px){.inspector-home-feature-action{width:28px;padding:0}.inspector-home-feature-action-label{display:none!important}.inspector-home-feature-action.inspector-system-health-url:after{content:attr(data-full-value)}}.inspector-home-features-empty{color:#57575b;border-top:1px solid #deddea;border-bottom:1px solid #deddea;margin:14px 0 0;padding:16px 0;font-size:12px}.inspector-home-news{gap:12px;display:grid}.inspector-whats-new-preview{color:#010507;background-color:#f7f4fe;border:1px solid #c8c6e6;border-radius:5px;align-items:stretch;width:100%;min-height:64px;display:flex;position:relative;overflow:hidden;container-type:inline-size}.inspector-whats-new-preview:has(.inspector-whats-new-preview-body:hover){background-color:#f1ebfc;border-color:#8f91d7}.inspector-whats-new-preview-body{min-width:0;color:inherit;text-align:left;cursor:pointer;background-color:#0000;border:0;flex:auto;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:12px;padding:12px 14px;display:grid}.inspector-whats-new-preview-copy{flex-direction:column;gap:3px;min-width:0;display:flex}.inspector-whats-new-preview-title{align-items:center;gap:8px;min-width:0;display:flex}.inspector-whats-new-preview-copy strong{text-overflow:ellipsis;white-space:nowrap;font-family:Plus Jakarta Sans,system-ui,sans-serif;font-size:13px;line-height:1.25;overflow:hidden}.inspector-whats-new-preview-copy>span:last-child{color:#4e4c63;text-overflow:ellipsis;white-space:nowrap;font-size:11px;line-height:1.4;overflow:hidden}.inspector-whats-new-preview-action{color:#3f176f;white-space:nowrap;flex:none;align-items:center;gap:6px;font-size:11px;font-weight:700;display:inline-flex}.inspector-whats-new-preview-action svg{width:15px;height:15px}@container (max-width:640px){.inspector-whats-new-preview-body{grid-template-columns:minmax(0,1fr)}.inspector-whats-new-preview-action{display:none}}.inspector-whats-new-preview-dismiss{color:#68686e;cursor:pointer;background-color:#0000;border:0;border-radius:5px;justify-content:center;align-items:center;width:28px;height:28px;display:inline-flex;position:absolute;top:50%;right:12px;transform:translateY(-50%)}.inspector-whats-new-preview-dismiss:hover{color:#3f176f;background-color:#6430ab1a}.inspector-whats-new-preview-dismiss svg{width:14px;height:14px}@media (max-width:720px){.inspector-account-cta{width:32px;padding-inline:0}.inspector-account-cta-label{display:none}.inspector-home{padding:24px 22px 34px}.inspector-intelligence-hud-header{flex-wrap:wrap}.inspector-intelligence-hud-details{grid-template-columns:1fr}.inspector-intelligence-hud-plan{grid-template-columns:repeat(2,minmax(0,1fr))}.inspector-whats-new-preview-action{display:none}}@media (max-width:600px){.inspector-system-health{grid-template-columns:1fr}}@media (max-width:480px){.inspector-home-feature{grid-template-columns:18px minmax(0,1fr);gap:8px}.inspector-home-feature-actions{grid-column:1/-1;justify-content:flex-end}.inspector-system-health-section .inspector-system-health-header{align-items:flex-start}.inspector-intelligence-hud-header{flex-direction:column;align-items:stretch}.inspector-intelligence-hud-header-actions{justify-content:space-between}.inspector-intelligence-hud-header-actions .inspector-intelligence-hud-action,.inspector-intelligence-hud-plan{width:100%}.inspector-intelligence-hud-plan{grid-template-columns:1fr;align-items:stretch}.inspector-intelligence-hud-plan-action{justify-self:start}.inspector-whats-new-header{align-items:center;gap:16px;width:calc(100% - 24px);padding:24px 22px}.inspector-whats-new-document,.inspector-whats-new-empty{padding:20px 22px 36px}.inspector-whats-new-document .announcement-content h1+p{font-size:16px}}.inspector-whats-new-header{background:#f8f7ff;border:1px solid #d8d8e8;border-radius:5px;justify-content:space-between;align-items:center;gap:24px;width:calc(100% - 44px);max-width:calc(70ch - 44px);padding:30px 32px 28px;display:flex;box-shadow:0 12px 28px #26224e0f}.inspector-whats-new-header .inspector-home-title{letter-spacing:-.035em;margin:0;font-size:clamp(27px,3.6vw,36px)}.inspector-whats-new-updated{color:#6c687c;letter-spacing:.01em;white-space:nowrap;flex:none;margin:0;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:11px;font-weight:600}.inspector-whats-new .inspector-home-news{max-width:70ch;margin-top:0}.inspector-whats-new-document,.inspector-whats-new-empty{max-width:70ch;padding:22px 32px 52px}.inspector-whats-new-document .announcement-content{color:#2b2b39;font-size:15px;line-height:1.72}.inspector-whats-new-document .announcement-content h1{color:#15131d;letter-spacing:-.032em;max-width:24ch;margin:0 0 16px;font-size:clamp(26px,3.2vw,34px);line-height:1.1}.inspector-whats-new-document .announcement-content h1+p{color:#504d61;max-width:58ch;margin-top:0;font-size:18px;line-height:1.58}.inspector-whats-new-document .announcement-content>hr:first-child{display:none}.inspector-whats-new-document .announcement-content h2:first-of-type{border-top:0;margin-top:14px;padding-top:0}.inspector-whats-new-document .announcement-content h2{color:#1b1924;letter-spacing:-.024em;border-top:1px solid #dfdeea;margin:44px 0 14px;padding-top:24px;font-size:21px;line-height:1.2}.inspector-whats-new-document .announcement-content p{max-width:70ch;margin:.85rem 0}.inspector-whats-new-document .announcement-content ul,.inspector-whats-new-document .announcement-content ol{max-width:68ch;margin:1.25rem 0 1.5rem;padding-left:1.4rem}.inspector-whats-new-document .announcement-content li+li{margin-top:.7rem}.inspector-whats-new-document .announcement-content a{color:#4e46a5;text-underline-offset:4px;font-weight:600;text-decoration-color:#4e46a56b;text-decoration-thickness:1px;transition:color .16s,text-decoration-color .16s}.inspector-whats-new-document .announcement-content a:hover{color:#312879;text-decoration-color:currentColor}.inspector-whats-new-empty{color:#5e5b70}.inspector-whats-new-empty .inspector-home-card-title{color:#1b1924;margin:0}.inspector-whats-new-empty .inspector-home-card-copy{max-width:48ch;margin:8px 0 0}.inspector-home-story-featured{padding:22px}.inspector-home-story-link{color:inherit;cursor:pointer;text-decoration:none;display:block}.inspector-home-story-link:hover{background-color:#fff;border-color:#8f91d7}.inspector-home-story[data-unread=true]{border-color:#bec2ff;padding-right:64px;box-shadow:0 0 0 1px #6430ab}.inspector-home-story-unread{color:#fff;letter-spacing:.04em;text-transform:uppercase;background-color:#6430ab;border-radius:999px;align-items:center;min-height:18px;padding:0 7px;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:10px;font-weight:700;display:inline-flex}.inspector-nav-label{text-overflow:ellipsis;white-space:nowrap;min-width:0;transition:opacity .18s,width .22s;overflow:hidden}.inspector-nav-control{color:#57575b;min-height:32px;font:inherit;text-align:left;outline-offset:-2px;cursor:pointer;background-color:#0000;border:1px solid #0000;border-radius:5px;outline:2px solid #0000;flex:none;justify-content:flex-start;align-items:center;gap:6px;padding:6px 9px;font-size:12px;font-weight:600;line-height:1.25;display:flex}.inspector-nav-control:hover{color:#010507;background-color:#f0f0f4}.inspector-nav-control-active{color:#3f176f;background-color:#eee6fe;border-color:#bec2ff}.inspector-nav-icon{flex:none;align-items:center;display:inline-flex}.inspector-nav-icon svg{width:15px;height:15px}.inspector-nav-control:focus-visible,.inspector-account-control:focus-visible,[data-inspector-thread-cta]:focus-visible,[data-inspector-sidebar-intelligence-action]:focus-visible,[data-inspector-whats-new-preview]:focus-visible,[data-inspector-whats-new-dismiss]:focus-visible,[data-inspector-home-intelligence-action]:focus-visible,.inspector-home-feature:focus-visible,[data-inspector-action-placement=threads-footer]:focus-visible{outline-offset:2px;outline:2px solid #6430ab!important}.inspector-sidebar .inspector-nav-control:focus-visible,.inspector-sidebar .inspector-sidebar-label:focus-visible,.inspector-sidebar [data-inspector-thread-cta]:focus-visible{outline-offset:-2px!important}.inspector-account-control{color:#57575b;font:inherit;outline-offset:2px;cursor:pointer;background-color:#0000;border:1px solid #0000;outline:2px solid #0000;justify-content:center;align-items:center;padding:0;display:inline-flex}.inspector-account-control:hover,.inspector-account-control-active{color:#3f176f;background-color:#6430ab17}:host ::selection{color:#010507;background-color:#cfd2ff}:host *{scrollbar-color:#aaa9c1 transparent;scrollbar-width:thin}:host ::-webkit-scrollbar{width:8px;height:8px}:host ::-webkit-scrollbar-thumb{background:#aaa9c1 padding-box padding-box;border:2px solid #0000;border-radius:999px}.inspector-account-control-icon{flex:none;justify-content:center;align-items:center;display:inline-flex}.inspector-account-control-icon svg{width:15px;height:15px}[data-inspector-thread-cta],[data-inspector-account-strip] button,[data-inspector-account-strip] a{cursor:pointer}@media (prefers-reduced-motion:reduce){.inspector-sidebar,.inspector-nav-label,.inspector-sidebar[data-icon-rail=true] .inspector-agent-selector>[data-context-dropdown-root=true]>button{transition:none}.inspector-icon-rail-menu{transition:none;animation:none}}.inspector-threads-footer{color:#57575b;background-color:#f7f7f9;border-top:1px solid #dbdbe5;flex:none;gap:10px;padding:12px;font-size:11px;line-height:1.35;display:grid}.inspector-threads-usage{gap:6px;display:grid}[data-inspector-thread-count]{color:#010507;font-weight:600}[data-inspector-thread-expiry]{color:#57575b}.inspector-thread-progress{--inspector-thread-progress-color:#189370;width:100%;height:6px;accent-color:var(--inspector-thread-progress-color);border-radius:999px;overflow:hidden}.inspector-thread-progress[data-inspector-thread-capacity=warning]{--inspector-thread-progress-color:#b45309}.inspector-thread-progress[data-inspector-thread-capacity=critical]{--inspector-thread-progress-color:#be123c}.inspector-thread-progress::-webkit-progress-bar{background-color:#dbdbe5;border-radius:999px}.inspector-thread-progress::-webkit-progress-value{background-color:var(--inspector-thread-progress-color);border-radius:999px}.inspector-thread-progress::-moz-progress-bar{background-color:var(--inspector-thread-progress-color);border-radius:999px}[data-inspector-action-placement=threads-footer]{color:#57575b;outline-offset:2px;cursor:pointer;background-color:#0000;border:1px solid #d5d3e4;border-radius:5px;outline:2px solid #0000;justify-content:center;align-items:center;width:100%;min-height:32px;padding:6px 9px;font-size:11px;font-weight:600;line-height:1.25;text-decoration:none;display:inline-flex}[data-inspector-action-placement=threads-footer][data-inspector-action-intent=upgrade]{color:#fff;background-color:#6430ab;border-color:#6430ab}[data-inspector-action-placement=threads-footer][data-inspector-action-intent=upgrade]:hover{color:#fff;background-color:#3f176f;border-color:#3f176f}[data-inspector-action-placement=threads-footer]:hover{color:#010507;background-color:#f7f4fe;border-color:#c8c6e6}.cpk-threads-overview-video{opacity:0;transition:opacity .22s}.cpk-threads-overview{background-color:#f7f7f9;flex:1;justify-content:center;align-items:center;min-width:0;padding:32px;display:flex}.cpk-threads-overview-content{color:#57575b;width:100%;max-width:440px}.cpk-threads-overview-title{color:#010507;margin:0 0 10px;font-size:20px;font-weight:600;line-height:1.25}.cpk-threads-overview-copy{color:#57575b;margin:0 0 16px;font-size:13px;line-height:1.55}.cpk-threads-overview-actions{flex-wrap:wrap;gap:8px;display:flex}.cpk-threads-overview-action{outline-offset:2px;cursor:pointer;border:1px solid #0000;border-radius:7px;outline:2px solid #0000;justify-content:center;align-items:center;gap:6px;min-height:34px;padding:8px 12px;font-size:12px;font-weight:600;line-height:1.25;text-decoration:none;display:inline-flex}[data-inspector-feature-setup-prompt][data-copy-state=copied]{background-color:#087653;border-color:#087653}[data-inspector-feature-setup-prompt][data-copy-state=error]{background-color:#b32d3b;border-color:#b32d3b}[data-inspector-feature-setup-prompt]:focus-visible{outline-offset:2px;outline:2px solid #6430ab}.cpk-threads-overview-action-primary{color:#fff;background-color:#010507;border-color:#010507}.cpk-threads-overview-action-primary:hover{background-color:#2b2b2b;border-color:#2b2b2b}.cpk-threads-overview-action-secondary{color:#010507;background-color:#fff;border-color:#dbdbe5}.cpk-threads-overview-action-secondary:hover{background-color:#fff;border-color:#afafb7}.cpk-threads-overview-video[data-loaded=true]{opacity:1}.cpk-threads-overview-video-control{color:#3f176f;min-height:32px;font:inherit;outline-offset:2px;cursor:pointer;background-color:#fff;border:1px solid #dbdbe5;border-radius:5px;outline:2px solid #0000;justify-content:center;align-items:center;margin:0 0 14px;padding:6px 10px;font-size:12px;font-weight:600;line-height:1.25;display:inline-flex}.cpk-threads-overview-video-control:hover{color:#010507;background-color:#f7f7f9;border-color:#afafb7}.cpk-threads-overview-video-control:focus-visible{outline-offset:2px;outline:2px solid #6430ab}.cpk-threads-overview-video-fallback{color:#57575b;max-width:440px;margin:-4px 0 14px;font-size:12px;line-height:1.5}.cpk-threads-tour-launch{z-index:2;color:#57575b;outline-offset:2px;cursor:pointer;background-color:#fff;border:1px solid #dbdbe5;border-radius:7px;outline:2px solid #0000;padding:7px 10px;font-size:12px;font-weight:600;position:absolute;bottom:16px;right:16px;box-shadow:0 8px 18px #01050714}.cpk-threads-tour{z-index:3;color:#57575b;background-color:#fff;border:1px solid #dbdbe5;border-radius:10px;width:min(340px,100% - 32px);padding:14px;position:absolute;bottom:16px;right:16px;box-shadow:0 16px 36px #01050724}.cpk-threads-tour-step{color:#087653;text-transform:uppercase;margin-bottom:8px;font-family:Spline Sans Mono,monospace;font-size:10px;font-weight:600}.cpk-threads-tour-title{color:#010507;margin-bottom:6px;font-size:14px;font-weight:600;line-height:1.35}.cpk-threads-tour-copy{color:#57575b;font-size:12px;line-height:1.5}.cpk-threads-tour-actions{justify-content:space-between;gap:8px;margin-top:14px;display:flex}.cpk-threads-tour-nav{gap:8px;display:flex}.cpk-threads-tour-skip,.cpk-threads-tour-button{font:inherit;outline-offset:2px;cursor:pointer;border-radius:7px;outline:2px solid #0000;padding:7px 10px;font-size:12px;font-weight:600}.cpk-threads-overview-action:focus-visible,.cpk-threads-tour-launch:focus-visible,.cpk-threads-tour-skip:focus-visible,.cpk-threads-tour-button:focus-visible{outline-color:#6430ab}.cpk-threads-tour-skip{color:#68686e;background-color:#0000;border:0;padding-inline:0}.cpk-threads-tour-button-secondary{color:#57575b;background-color:#fff;border:1px solid #dbdbe5}.cpk-threads-tour-button-primary{color:#fff;background-color:#010507;border:1px solid #010507}.cpk-threads-tour-button:disabled{cursor:not-allowed;opacity:.45}@media (max-width:720px){.cpk-threads-overview{padding:24px}}@media (prefers-reduced-motion:reduce){.cpk-threads-overview-video{transition:none}}.inspector-window[data-color-scheme=dark]{color-scheme:dark;background-color:var(--cpk-inspector-surface-dark)!important;color:#f3f4f8!important;border-color:#7b7d89!important}.inspector-window[data-color-scheme=dark] .inspector-shell,.inspector-window[data-color-scheme=dark] .inspector-main,.inspector-window[data-color-scheme=dark] #cpk-main-scroll{color:#f3f4f8!important;background-color:#111319!important}.inspector-window[data-color-scheme=dark] .resize-handle,.inspector-window[data-color-scheme=dark] .edge-resize-handle,.inspector-window[data-color-scheme=dark] .dock-resize-handle{background:0 0!important}.inspector-window[data-color-scheme=dark] .drag-handle,.inspector-window[data-color-scheme=dark] .inspector-account-strip{color:#f3f4f8!important;background:#15171e!important;border-color:#3a3d49!important}.inspector-window[data-color-scheme=dark] .inspector-account-logo{filter:brightness(0)invert();clip-path:inset(0 20% 0 0)}.inspector-window[data-color-scheme=dark] .inspector-account-logo-accent{filter:none;display:block}.inspector-window[data-color-scheme=dark] .inspector-agent-placeholder{color:#b8bbc7!important;border-color:#3a3d49!important}.inspector-window[data-color-scheme=dark] .inspector-account-control{color:#b8bbc7!important;border:0!important}.inspector-window[data-color-scheme=dark] .inspector-account-control:hover,.inspector-window[data-color-scheme=dark] .inspector-account-control-active{color:#d8d9ff!important;background-color:#292c38!important}.inspector-window[data-color-scheme=dark] .inspector-account-cta{color:#d8d9ff;background-color:#292b43}.inspector-window[data-color-scheme=dark] .inspector-account-cta:hover{color:#fff;background-color:#353854}.inspector-window[data-color-scheme=dark] .inspector-window-layout-menu{box-shadow:0 12px 28px #00000052;color:#f3f4f8!important;background-color:#111319!important;border-color:#5c6173!important}.inspector-window[data-color-scheme=dark] .inspector-window-layout-menu button,.inspector-window[data-color-scheme=dark] .inspector-window-layout-menu button span{color:#f3f4f8!important}.inspector-window[data-color-scheme=dark] .inspector-window-layout-menu button:hover,.inspector-window[data-color-scheme=dark] .inspector-window-layout-menu button:focus-visible,.inspector-window[data-color-scheme=dark] .inspector-window-layout-menu button:hover span,.inspector-window[data-color-scheme=dark] .inspector-window-layout-menu button:focus-visible span{color:#fff!important;background-color:#3a3f52!important}.inspector-window[data-color-scheme=dark] .inspector-sidebar .inspector-agent-selector>[data-context-dropdown-root=true]>button{color:#f3f4f8!important;background-color:#20232c!important;border-color:#464957!important}.inspector-window[data-color-scheme=dark] .inspector-sidebar .inspector-agent-selector>[data-context-dropdown-root=true]>button:hover{background-color:#292c38!important;border-color:#777aae!important}.inspector-window[data-color-scheme=dark] .inspector-sidebar .inspector-agent-selector>[data-context-dropdown-root=true]>button>span:last-child{color:#aeb1bd!important}.inspector-window[data-color-scheme=dark] .inspector-context-dropdown-icon{color:#f3f4f8!important}.inspector-window[data-color-scheme=dark] .inspector-sidebar[data-icon-rail=true] .inspector-agent-selector>[data-context-dropdown-root=true]>button{color:#fff!important;background-color:#2f3340!important;border-color:#8b90a5!important}.inspector-window[data-color-scheme=dark] .inspector-sidebar[data-icon-rail=true] .inspector-context-dropdown-icon,.inspector-window[data-color-scheme=dark] .inspector-sidebar[data-icon-rail=true] .inspector-agent-placeholder{color:#fff!important}.inspector-window[data-color-scheme=dark] [data-context-dropdown-root=true]>div{color:#f3f4f8!important;box-shadow:none!important;background-color:#191c24!important;border-color:#464957!important}.inspector-window[data-color-scheme=dark] [data-context-dropdown-root=true]>div button:hover,.inspector-window[data-color-scheme=dark] [data-context-dropdown-root=true]>div button:focus{color:#f3f4f8!important;background-color:#343746!important}.inspector-window[data-color-scheme=dark] .inspector-sidebar{color:#f3f4f8;background-color:#15171e;border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-sidebar-label{color:#8f93a1}.inspector-window[data-color-scheme=dark] .inspector-sidebar-rail-tooltip{color:#191c24;background-color:#e9e9f1;box-shadow:0 7px 18px #00000047}.inspector-window[data-color-scheme=dark] .inspector-nav-control,.inspector-window[data-color-scheme=dark] .inspector-sidebar-toggle{color:#b8bbc7}.inspector-window[data-color-scheme=dark] .inspector-nav-control:hover,.inspector-window[data-color-scheme=dark] .inspector-sidebar-toggle:hover{color:#fff;background-color:#22252f}.inspector-window[data-color-scheme=dark] .inspector-nav-control-active{color:#d8d9ff;background-color:#292b43;border-color:#666a9e}.inspector-window[data-color-scheme=dark] .inspector-sidebar-agent-scope{border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-sidebar-status-card{background-color:#191c24;border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-sidebar-status-copy strong{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-sidebar-status-copy>span,.inspector-window[data-color-scheme=dark] .inspector-sidebar-status-card[data-state=disconnected] .inspector-sidebar-status-copy>span{color:#9da1af}.inspector-window[data-color-scheme=dark] .inspector-sidebar-status-action{color:#caccff}.inspector-window[data-color-scheme=dark] .inspector-sidebar-status-action:hover{color:#fff;background-color:#292b43}.inspector-window[data-color-scheme=dark] .inspector-sidebar-intelligence-setup{color:#d8d9ff;background-color:#292b43;border-color:#666a9e}.inspector-window[data-color-scheme=dark] .inspector-sidebar-intelligence-setup:hover{background-color:#343653;border-color:#777aae}.inspector-window[data-color-scheme=dark] .inspector-sidebar-intelligence-setup .inspector-sidebar-status-copy strong{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-sidebar-setup-arrow{background-color:#caccff1f}@media (prefers-reduced-motion:reduce){.inspector-sidebar-intelligence-setup{animation:none}}.inspector-window[data-color-scheme=dark] .inspector-home{background-color:#111319}.inspector-window[data-color-scheme=dark] .inspector-settings{color:#f3f4f8;background-color:#111319}.inspector-window[data-color-scheme=dark] .inspector-settings-header,.inspector-window[data-color-scheme=dark] .inspector-settings-section,.inspector-window[data-color-scheme=dark] .inspector-settings-privacy,.inspector-window[data-color-scheme=dark] .inspector-settings-visibility,.inspector-window[data-color-scheme=dark] .inspector-settings-private-content{border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-settings-title,.inspector-window[data-color-scheme=dark] .inspector-settings-section-heading h2,.inspector-window[data-color-scheme=dark] .inspector-settings-status-row h3,.inspector-window[data-color-scheme=dark] .inspector-settings-visibility h3,.inspector-window[data-color-scheme=dark] .inspector-settings-private-content strong{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-settings-subtitle,.inspector-window[data-color-scheme=dark] .inspector-settings-section-heading p,.inspector-window[data-color-scheme=dark] .inspector-settings-status-row p,.inspector-window[data-color-scheme=dark] .inspector-settings-visibility p,.inspector-window[data-color-scheme=dark] .inspector-settings-private-content>p{color:#aeb1bd}.inspector-window[data-color-scheme=dark] .inspector-settings-section-icon{color:#d8d9ff;background-color:#292b43;border-color:#666a9e}.inspector-window[data-color-scheme=dark] .inspector-settings-private-content li{color:#c9ccd6}.inspector-window[data-color-scheme=dark] .inspector-settings-private-content li span{color:#75d8b9}.inspector-window[data-color-scheme=dark] .inspector-settings-status{color:#8ce1c5;background-color:#173b32;border-color:#347d69}.inspector-window[data-color-scheme=dark] .inspector-settings-privacy[data-state=disabled] .inspector-settings-status{color:#f2cf8f;background-color:#342916;border-color:#866932}.inspector-window[data-color-scheme=dark] .inspector-settings-policy-link{color:#caccff}.inspector-window[data-color-scheme=dark] .inspector-settings-policy-link:hover{color:#fff}.inspector-window[data-color-scheme=dark] .inspector-settings-dismiss{color:#ded7ff;background-color:#272438;border-color:#5d5975}.inspector-window[data-color-scheme=dark] .inspector-settings-dismiss:hover{background-color:#322e47;border-color:#8179a7}.inspector-window[data-color-scheme=dark] .inspector-settings-dismiss:focus-visible{outline-color:#bec2ff}.inspector-window[data-color-scheme=dark] .inspector-home-card,.inspector-window[data-color-scheme=dark] .inspector-home-story,.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud,.inspector-window[data-color-scheme=dark] .inspector-home-feature-list,.inspector-window[data-color-scheme=dark] .inspector-whats-new-preview{color:#f3f4f8;background:#191c24;border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud[data-state=disconnected]{background-color:#1d1e2b;border-color:#666a9e}.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud[data-state=disconnected] .inspector-intelligence-hud-description{color:#c5c7d0}.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud[data-mode=install] .inspector-intelligence-hud-header{background:linear-gradient(100deg,#1d1e2b 0%,#221f31 54%,#1a2523 100%);border-bottom-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud[data-mode=install] .inspector-intelligence-hud-heading .inspector-home-section-title{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-intelligence-install-hint{color:#aeb1bd}.inspector-window[data-color-scheme=dark] .inspector-intelligence-install-hint[data-tone=success]{color:#d5cbff}.inspector-window[data-color-scheme=dark] .inspector-intelligence-install-hint[data-tone=error]{color:#ffb3a1}.inspector-window[data-color-scheme=dark] .inspector-intelligence-install[data-copy-state=copied] .inspector-intelligence-install-copy{color:#d5cbff;background-color:#0000;border-color:#666a9e}.inspector-window[data-color-scheme=dark] .inspector-intelligence-install-secondary{color:#caccff}.inspector-window[data-color-scheme=dark] .inspector-intelligence-install-fallback{color:#c5c7d0;background-color:#15171e;border-bottom-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-intelligence-story{background-color:#15171e}.inspector-window[data-color-scheme=dark] .inspector-intelligence-beat-label,.inspector-window[data-color-scheme=dark] .inspector-intelligence-chain-step>small,.inspector-window[data-color-scheme=dark] .inspector-intelligence-thread>small,.inspector-window[data-color-scheme=dark] .inspector-intelligence-skill-file>header em{color:#8f93a1}.inspector-window[data-color-scheme=dark] .inspector-intelligence-copy-slide>strong{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-intelligence-copy-slide>span{color:#c5c7d0}.inspector-window[data-color-scheme=dark] .inspector-intelligence-thread{background-color:#1c1f2b;border-color:#33364a}.inspector-window[data-color-scheme=dark] .inspector-intelligence-thread>strong{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-intelligence-thread>i{background-color:#666a9e}.inspector-window[data-color-scheme=dark] .inspector-intelligence-thread[data-failed=true]{background-color:#2a1a16;border-color:#5a3129}.inspector-window[data-color-scheme=dark] .inspector-intelligence-thread[data-failed=true]>i{background-color:#f97316}.inspector-window[data-color-scheme=dark] .inspector-intelligence-thread[data-failed=true]>strong,.inspector-window[data-color-scheme=dark] .inspector-intelligence-thread[data-failed=true]>small{color:#ffb3a1}.inspector-window[data-color-scheme=dark] .inspector-intelligence-signal{color:#c5c7d0;background-color:#1c1f2b;border-color:#33364a}.inspector-window[data-color-scheme=dark] .inspector-intelligence-rule,.inspector-window[data-color-scheme=dark] .inspector-intelligence-chain-proof{color:#8fd9b8;background-color:#16241f;border-color:#2f5748}.inspector-window[data-color-scheme=dark] .inspector-intelligence-rule>i,.inspector-window[data-color-scheme=dark] .inspector-intelligence-chain-proof svg{color:#5be4bb}.inspector-window[data-color-scheme=dark] .inspector-intelligence-beat-flow{color:#666a9e}.inspector-window[data-color-scheme=dark] .inspector-intelligence-skill-file{box-shadow:none;background-color:#191c24;border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-intelligence-skill-file>header{background-color:#1c1f2b;border-bottom-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-intelligence-skill-file>header strong{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-intelligence-skill-file>header svg,.inspector-window[data-color-scheme=dark] .inspector-intelligence-skill-code>span>b,.inspector-window[data-color-scheme=dark] .inspector-intelligence-chain-step>i{color:#caccff}.inspector-window[data-color-scheme=dark] .inspector-intelligence-skill-code>span{color:#c5c7d0}.inspector-window[data-color-scheme=dark] .inspector-intelligence-skill-code>span:before{color:#6d7180}.inspector-window[data-color-scheme=dark] .inspector-intelligence-chain-step{background-color:#1c1f2b;border-color:#33364a}.inspector-window[data-color-scheme=dark] .inspector-intelligence-chain-step>strong{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-intelligence-chain-arrow{color:#666a9e}.inspector-window[data-color-scheme=dark] .inspector-intelligence-story-rail{border-top-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-intelligence-story-tab{color:#8f93a1}.inspector-window[data-color-scheme=dark] .inspector-intelligence-story-tab:hover{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-intelligence-story-tab[data-active=true]{color:#d5cbff}.inspector-window[data-color-scheme=dark] .inspector-intelligence-story-tab:after{background-color:#a78bfa}.inspector-window[data-color-scheme=dark] .inspector-system-health,.inspector-window[data-color-scheme=dark] .inspector-system-health-section{border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-system-health-section{background-color:#191c24}.inspector-window[data-color-scheme=dark] .inspector-system-health-section .inspector-system-health-header{background-color:#191c24;border-bottom-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-system-health{background-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-system-health-signal{background-color:#191c24}.inspector-window[data-color-scheme=dark] .inspector-system-health-event-link>small{color:#caccff}.inspector-window[data-color-scheme=dark] .inspector-system-health-header>span[data-tone=success]{color:#8ce1c5}.inspector-window[data-color-scheme=dark] .inspector-system-health-state[data-tone=success],.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-state[data-tone=success]{background-color:#173b32;border-color:#347d69;color:#8ce1c5!important}.inspector-window[data-color-scheme=dark] .inspector-system-health-state[data-tone=checking],.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-state[data-tone=checking]{background-color:#342916;border-color:#866932;color:#f2cf8f!important}.inspector-window[data-color-scheme=dark] .inspector-system-health-state[data-tone=offline],.inspector-window[data-color-scheme=dark] .inspector-system-health-state[data-tone=error],.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-state[data-tone=offline],.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-state[data-tone=error]{background-color:#3b1c22;border-color:#87424a;color:#ff9aa0!important}.inspector-window[data-color-scheme=dark] .inspector-system-health-state[data-tone=unavailable],.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-state[data-tone=unavailable]{background-color:#242731;border-color:#464957;color:#aeb1bd!important}.inspector-window[data-color-scheme=dark] .inspector-system-health-header>span[data-tone=checking]{color:#f2cf8f}.inspector-window[data-color-scheme=dark] .inspector-system-health-header>span[data-tone=offline],.inspector-window[data-color-scheme=dark] .inspector-system-health-header>span[data-tone=error]{color:#ff9aa0}.inspector-window[data-color-scheme=dark] .inspector-home-story-link:hover,.inspector-window[data-color-scheme=dark] .inspector-whats-new-preview:has(.inspector-whats-new-preview-body:hover){background:#242131;border-color:#777aae}.inspector-window[data-color-scheme=dark] .inspector-home-title,.inspector-window[data-color-scheme=dark] .inspector-home-section-title,.inspector-window[data-color-scheme=dark] .inspector-home-card-title,.inspector-window[data-color-scheme=dark] .inspector-system-health-signal dd,.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-details .inspector-intelligence-hud-detail-value,.inspector-window[data-color-scheme=dark] .inspector-home-feature{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-home-eyebrow,.inspector-window[data-color-scheme=dark] .inspector-home-card-label,.inspector-window[data-color-scheme=dark] .inspector-home-meta,.inspector-window[data-color-scheme=dark] .inspector-home-body,.inspector-window[data-color-scheme=dark] .inspector-home-card-copy,.inspector-window[data-color-scheme=dark] .inspector-system-health-signal dt,.inspector-window[data-color-scheme=dark] .inspector-system-health-signal small,.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-heading p,.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-details .inspector-intelligence-hud-detail-label,.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-details .inspector-intelligence-hud-detail-subvalue,.inspector-window[data-color-scheme=dark] .inspector-home-section-header>span,.inspector-window[data-color-scheme=dark] .inspector-whats-new-preview-copy>span:last-child{color:#aeb1bd}.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-details{background-color:#3a3d49;border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-details>section{background-color:#15171e}.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-plan-action{color:#caccff}.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-plan-action:hover{color:#fff;background-color:#0000;border-color:#0000}.inspector-window[data-color-scheme=dark] .inspector-system-health-signal+.inspector-system-health-signal,.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-details>section+section,.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-details,.inspector-window[data-color-scheme=dark] .inspector-home-features-empty{border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-system-health-signal[data-tone=success] dd,.inspector-window[data-color-scheme=dark] .inspector-home-feature small{color:#8ce1c5}.inspector-window[data-color-scheme=dark] .inspector-system-health-signal[data-tone=active] dd{color:#f2cf8f}.inspector-window[data-color-scheme=dark] .inspector-system-health-signal[data-tone=error] .inspector-system-health-event-type{color:#ff9aa0;background-color:#3b1c22}.inspector-window[data-color-scheme=dark] .inspector-system-health-signal[data-tone=success] .inspector-system-health-event-type{color:#8ce1c5;background-color:#173b32}.inspector-window[data-color-scheme=dark] .inspector-system-health-signal[data-tone=active] .inspector-system-health-event-type{color:#f2cf8f;background-color:#342916}.inspector-window[data-color-scheme=dark] .inspector-home-feature-group{background-color:#191c24;border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-home-feature-group-header{color:#c9ccd6;background-color:#20232d;border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-home-feature-group-header>span{color:#c9ccd6;background-color:#191c24}.inspector-window[data-color-scheme=dark] .inspector-home-feature-group[data-feature-state-group=active] .inspector-home-feature-group-header{color:#8ce1c5;background-color:#173b32;border-color:#347d69}.inspector-window[data-color-scheme=dark] .inspector-home-feature{background-color:#191c24}.inspector-window[data-color-scheme=dark] .inspector-home-feature:hover{background-color:#20232d}.inspector-window[data-color-scheme=dark] .inspector-home-feature+.inspector-home-feature{border-color:#2f323d}.inspector-window[data-color-scheme=dark] .inspector-home-feature-group-empty{color:#9da1af}.inspector-window[data-color-scheme=dark] .inspector-home-feature[data-state=off]{color:#aeb1bd}.inspector-window[data-color-scheme=dark] .inspector-home-feature-status>span{background-color:#191c24;border-color:#6f7484}.inspector-window[data-color-scheme=dark] .inspector-home-feature[data-state=on] .inspector-home-feature-status>span{background-color:#8ce1c5;border-color:#8ce1c5}.inspector-window[data-color-scheme=dark] .inspector-home-feature-action{color:#d4d7e0;background-color:#20232d;border-color:#464957}.inspector-window[data-color-scheme=dark] .inspector-home-feature-label:hover{color:#d8d9ff}.inspector-window[data-color-scheme=dark] .inspector-home-feature-action:hover{color:#fff;background-color:#292b43;border-color:#777aae}.inspector-window[data-color-scheme=dark] .inspector-home-feature-action[data-copy-state=copied]{color:#8ce1c5;background-color:#173b32;border-color:#347d69}.inspector-window[data-color-scheme=dark] .inspector-home-feature-action[data-copy-state=error]{color:#ff9aa0;background-color:#3b1c22;border-color:#87424a}.inspector-window[data-color-scheme=dark] .inspector-whats-new-preview-dismiss{color:#aeb1bd}.inspector-window[data-color-scheme=dark] .inspector-whats-new-preview-dismiss:hover{color:#fff;background-color:#302a40}.inspector-window[data-color-scheme=dark] .inspector-home-usage-bar{background-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-thread-progress::-webkit-progress-bar{background-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-whats-new-header{box-shadow:none;background-color:#1d1e2b;border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-whats-new-updated,.inspector-window[data-color-scheme=dark] .inspector-whats-new-empty{color:#aeb1bd}.inspector-window[data-color-scheme=dark] .inspector-whats-new-preview-action{color:#d8d9ff}.inspector-window[data-color-scheme=dark] .inspector-whats-new-preview:hover .inspector-whats-new-preview-action{color:#fff}.inspector-window[data-color-scheme=dark] .inspector-whats-new-document,.inspector-window[data-color-scheme=dark] .inspector-whats-new-empty{border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-whats-new-document .announcement-content{color:#c9ccd6}.inspector-window[data-color-scheme=dark] .inspector-whats-new-empty .inspector-home-card-title{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-whats-new-document .announcement-content h1+p{color:#c9ccd6}.inspector-window[data-color-scheme=dark] .inspector-whats-new-document .announcement-content h2{border-top-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-whats-new-document .announcement-content h1,.inspector-window[data-color-scheme=dark] .inspector-whats-new-document .announcement-content h2,.inspector-window[data-color-scheme=dark] .inspector-whats-new-document .announcement-content h3,.inspector-window[data-color-scheme=dark] .inspector-whats-new-document .announcement-content strong{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-whats-new-document .announcement-content a{color:#caccff}.inspector-window[data-color-scheme=dark] .inspector-threads-footer{color:#aeb1bd;background-color:#15171e;border-color:#343742}.inspector-window[data-color-scheme=dark] [data-inspector-thread-count]{color:#f3f4f8}.inspector-window[data-color-scheme=dark] [data-inspector-thread-expiry]{color:#aeb1bd}.inspector-window[data-color-scheme=dark] [data-inspector-action-placement=threads-footer]{color:#d8d9ff;background-color:#191c24;border-color:#464957}.inspector-window[data-color-scheme=dark] [data-inspector-action-placement=threads-footer]:hover{color:#fff;background-color:#20232d;border-color:#777aae}.inspector-window[data-color-scheme=dark] .cpk-threads-overview{background-color:#111319}.inspector-window[data-color-scheme=dark] .cpk-threads-overview-content,.inspector-window[data-color-scheme=dark] .cpk-threads-overview-copy,.inspector-window[data-color-scheme=dark] .cpk-threads-overview-video-fallback,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-copy{color:#aeb1bd}.inspector-window[data-color-scheme=dark] .cpk-threads-overview-title,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-title{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .cpk-threads-overview-video-frame{background:linear-gradient(135deg,#666a9e3d,#347d6929),#191c24;border-color:#3a3d49;box-shadow:0 8px 20px #00000038}.inspector-window[data-color-scheme=dark] .cpk-threads-overview-video-control,.inspector-window[data-color-scheme=dark] .cpk-threads-overview-action-secondary,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-launch,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-button-secondary{color:#d8d9ff;background-color:#191c24;border-color:#464957}.inspector-window[data-color-scheme=dark] .cpk-threads-overview-video-control:hover,.inspector-window[data-color-scheme=dark] .cpk-threads-overview-action-secondary:hover,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-launch:hover,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-button-secondary:hover{color:#fff;background-color:#242731;border-color:#777aae}.inspector-window[data-color-scheme=dark] .cpk-threads-overview-action-primary,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-button-primary{color:#171823;background-color:#caccff;border-color:#caccff}.inspector-window[data-color-scheme=dark] .cpk-threads-overview-action-primary:hover,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-button-primary:hover{background-color:#d8d9ff;border-color:#d8d9ff}.inspector-window[data-color-scheme=dark] .cpk-threads-tour{color:#aeb1bd;background-color:#191c24;border-color:#464957;box-shadow:0 16px 36px #00000052}.inspector-window[data-color-scheme=dark] .cpk-threads-tour-step{color:#8ce1c5}.inspector-window[data-color-scheme=dark] .cpk-threads-tour-skip{color:#aeb1bd}.inspector-window[data-color-scheme=dark] .cpk-threads-overview-action:focus-visible,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-launch:focus-visible,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-skip:focus-visible,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-button:focus-visible{outline-color:#bec2ff}.inspector-window[data-color-scheme=dark] .cpk-memory-locked{color:#f3f4f8;background-color:#111319}.inspector-window[data-color-scheme=dark] .cpk-locked-preview-sidebar{background-color:#15171e;border-color:#2f323d}.inspector-window[data-color-scheme=dark] .cpk-locked-preview-main{background-color:#111319}.inspector-window[data-color-scheme=dark] .cpk-locked-preview-row{background-color:#191c24;box-shadow:inset 0 0 0 1px #2f323d}.inspector-window[data-color-scheme=dark] .cpk-locked-preview-row[data-accent=true]{background-color:#292b43}.inspector-window[data-color-scheme=dark] .cpk-locked-preview-bar{background-color:#333641}.inspector-window[data-color-scheme=dark] .cpk-locked-preview-row[data-accent=true] .cpk-locked-preview-row-title{background-color:#777aae}.inspector-window[data-color-scheme=dark] .cpk-locked-preview-row-line,.inspector-window[data-color-scheme=dark] .cpk-locked-preview-copy,.inspector-window[data-color-scheme=dark] .cpk-locked-preview-footer-line{background-color:#2f323d}.inspector-window[data-color-scheme=dark] .cpk-locked-preview-row-line:last-child,.inspector-window[data-color-scheme=dark] .cpk-locked-preview-copy+.cpk-locked-preview-copy,.inspector-window[data-color-scheme=dark] .cpk-locked-preview-footer-line+.cpk-locked-preview-footer-line{background-color:#292c36}.inspector-window[data-color-scheme=dark] .cpk-locked-preview-card{background-color:#191c24;box-shadow:inset 0 0 0 1px #2f323d}.inspector-window[data-color-scheme=dark] .cpk-memory-locked-scrim{background:radial-gradient(circle,#111319f0 0,#111319d6 24%,#11131975 48%,#111319ad 100%)}.inspector-window[data-color-scheme=dark] .cpk-memory-locked-content,.inspector-window[data-color-scheme=dark] .cpk-memory-locked-copy{color:#aeb1bd}.inspector-window[data-color-scheme=dark] .cpk-memory-locked-title{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .cpk-memory-locked-icon{color:#d8d9ff;box-shadow:none;background-color:#292b43;border-color:#666a9e}.inspector-window[data-color-scheme=dark] .cpk-memory-locked-action-secondary{color:#d8d9ff;background-color:#191c24;border-color:#464957}.inspector-window[data-color-scheme=dark] .cpk-memory-locked-action-secondary:hover{color:#fff;background-color:#242731;border-color:#777aae}.inspector-window[data-color-scheme=dark] .cpk-agent-overview,.inspector-window[data-color-scheme=dark] .cpk-section-card{background-color:#191c24!important;border-color:#3a3d49!important}.inspector-window[data-color-scheme=dark] .cpk-section-header{background-color:#242731!important;border-color:#3a3d49!important}.inspector-window[data-color-scheme=dark] .cpk-section-header h4{color:#f3f4f8!important}.inspector-window[data-color-scheme=dark] .cpk-agent-icon{color:#d8d9ff!important;background-color:#292b43!important}.inspector-window[data-color-scheme=dark] .cpk-stat-card{background-color:#191c24!important;border-color:#464957!important}.inspector-window[data-color-scheme=dark] button.cpk-stat-card:hover{background-color:#20232d!important}.cpk-agent-messages-head{border-bottom:1px solid #e4e4ec}.cpk-agent-message-row+.cpk-agent-message-row{border-top:1px solid #e4e4ec}.inspector-window[data-color-scheme=dark] .cpk-agent-messages-head,.inspector-window[data-color-scheme=dark] .cpk-agent-message-row+.cpk-agent-message-row,.inspector-window[data-color-scheme=dark] .cpk-agent-view .divide-gray-200>:not([hidden])~:not([hidden]),.inspector-window[data-color-scheme=dark] .cpk-agent-view .divide-y>*{border-color:#3a3d49!important}.inspector-window[data-color-scheme=dark] .cpk-json-block{color:#c9ccd6}.inspector-window[data-color-scheme=dark] [class*=bg-emerald-50],.inspector-window[data-color-scheme=dark] [class*=bg-green-100]{color:#8ce1c5!important;background-color:#173b32!important}.inspector-window[data-color-scheme=dark] [class*=bg-rose-50]{color:#ff9aa0!important;background-color:#3b1c22!important}.inspector-window[data-color-scheme=dark] [data-cpk-event-error] p,.inspector-window[data-color-scheme=dark] [data-playground-error] p{color:inherit!important}.inspector-window[data-color-scheme=dark] [class*=bg-amber-50],.inspector-window[data-color-scheme=dark] [class*=bg-amber-100]{color:#f2cf8f!important;background-color:#342916!important}.inspector-window[data-color-scheme=dark] [class*=bg-blue-50],.inspector-window[data-color-scheme=dark] [class*=bg-blue-100],.inspector-window[data-color-scheme=dark] [class*=bg-sky-50],.inspector-window[data-color-scheme=dark] [class*=bg-violet-50],.inspector-window[data-color-scheme=dark] [class*=bg-purple-50],.inspector-window[data-color-scheme=dark] [class*=bg-fuchsia-50]{color:#d8d9ff!important;background-color:#292b43!important}.inspector-window[data-color-scheme=dark] [class*=bg-white]{background-color:#191c24!important}.inspector-window[data-color-scheme=dark] [class*=bg-gray-50],.inspector-window[data-color-scheme=dark] [class*=bg-slate-50],.inspector-window[data-color-scheme=dark] [class*=bg-gray-100],.inspector-window[data-color-scheme=dark] [class*=bg-slate-100]{background-color:#171a22!important}.inspector-window[data-color-scheme=dark] [class*=text-gray-900],.inspector-window[data-color-scheme=dark] [class*=text-slate-900],.inspector-window[data-color-scheme=dark] [class*=text-gray-800],.inspector-window[data-color-scheme=dark] [class*=text-slate-800],.inspector-window[data-color-scheme=dark] [class*=text-gray-700],.inspector-window[data-color-scheme=dark] [class*=text-slate-700]{color:#f3f4f8!important}.inspector-window[data-color-scheme=dark] [class*=text-gray-600],.inspector-window[data-color-scheme=dark] [class*=text-slate-600],.inspector-window[data-color-scheme=dark] [class*=text-gray-500],.inspector-window[data-color-scheme=dark] [class*=text-slate-500],.inspector-window[data-color-scheme=dark] [class*=text-gray-400],.inspector-window[data-color-scheme=dark] [class*=text-slate-400]{color:#aeb1bd!important}.inspector-window[data-color-scheme=dark] [class*=border-gray-100],.inspector-window[data-color-scheme=dark] [class*=border-slate-100],.inspector-window[data-color-scheme=dark] [class*=border-gray-200],.inspector-window[data-color-scheme=dark] [class*=border-slate-200],.inspector-window[data-color-scheme=dark] [class*=border-gray-300],.inspector-window[data-color-scheme=dark] [class*=border-slate-300]{border-color:#3a3d49!important}.inspector-window[data-color-scheme=dark] input,.inspector-window[data-color-scheme=dark] select,.inspector-window[data-color-scheme=dark] textarea{color:#f3f4f8!important;background-color:#191c24!important;border-color:#464957!important}.inspector-window[data-color-scheme=dark] input::placeholder,.inspector-window[data-color-scheme=dark] textarea::placeholder{color:#858996}.inspector-window[data-color-scheme=dark] .cpk-playground-composer{background-color:#2f3340!important;box-shadow:0 0 0 1px #6d7285!important}.inspector-window[data-color-scheme=dark] .cpk-playground-composer:focus-within{box-shadow:0 0 0 1px #c5c8de!important}.inspector-window[data-color-scheme=dark] .cpk-playground-input{color:#f3f4f8!important;caret-color:#f3f4f8!important;background-color:#0000!important}.inspector-window[data-color-scheme=dark] .cpk-playground-input::placeholder{color:#e4e6ef!important;opacity:1!important}.inspector-window[data-color-scheme=dark] .cpk-playground-send:not(:disabled){color:#111319!important;opacity:1!important;background-color:#f3f4f8!important}.inspector-window[data-color-scheme=dark] .cpk-playground-send:disabled{color:#f3f4f8!important;background-color:#f3f4f833!important}.inspector-window[data-color-scheme=dark] ::selection{color:#fff;background-color:#5b5f92}@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-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";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:"";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:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}} \ No newline at end of file +@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-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-duration:initial;--tw-ease: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-50:oklch(98.7% .022 95.277);--color-amber-100:oklch(96.2% .059 95.617);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-600:oklch(66.6% .179 58.318);--color-amber-800:oklch(47.3% .137 46.201);--color-amber-900:oklch(41.4% .112 45.904);--color-green-100:oklch(96.2% .044 156.743);--color-green-700:oklch(52.7% .154 150.069);--color-green-800:oklch(44.8% .119 151.328);--color-emerald-50:oklch(97.9% .021 166.113);--color-emerald-200:oklch(90.5% .093 164.15);--color-emerald-500:oklch(69.6% .17 162.48);--color-emerald-700:oklch(50.8% .118 165.612);--color-blue-50:oklch(97% .014 254.604);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-200:oklch(88.2% .059 254.128);--color-blue-600:oklch(54.6% .245 262.881);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-800:oklch(42.4% .199 265.638);--color-violet-50:oklch(96.9% .016 293.756);--color-violet-100:oklch(94.3% .029 294.588);--color-violet-200:oklch(89.4% .057 293.283);--color-violet-300:oklch(81.1% .111 293.571);--color-violet-400:oklch(70.2% .183 293.541);--color-violet-500:oklch(60.6% .25 292.717);--color-violet-600:oklch(54.1% .281 293.009);--color-violet-700:oklch(49.1% .27 292.581);--color-violet-800:oklch(43.2% .232 292.759);--color-violet-950:oklch(28.3% .141 291.089);--color-purple-50:oklch(97.7% .014 308.299);--color-purple-200:oklch(90.2% .063 306.703);--color-purple-700:oklch(49.6% .265 301.924);--color-rose-50:oklch(96.9% .015 12.422);--color-rose-100:oklch(94.1% .03 12.58);--color-rose-200:oklch(89.2% .058 10.001);--color-rose-300:oklch(81% .117 11.638);--color-rose-500:oklch(64.5% .246 16.439);--color-rose-700:oklch(51.4% .222 16.935);--color-rose-800:oklch(45.5% .188 13.697);--color-rose-950:oklch(27.1% .105 12.094);--color-slate-200:oklch(92.9% .013 255.508);--color-slate-500:oklch(55.4% .046 257.417);--color-slate-800:oklch(27.9% .041 260.031);--color-slate-900:oklch(20.8% .042 265.755);--color-gray-50:oklch(98.5% .002 247.839);--color-gray-100:oklch(96.7% .003 264.542);--color-gray-200:oklch(92.8% .006 264.531);--color-gray-300:oklch(87.2% .01 258.338);--color-gray-400:oklch(70.7% .022 261.325);--color-gray-500:oklch(55.1% .027 264.364);--color-gray-600:oklch(44.6% .03 256.802);--color-gray-700:oklch(37.3% .034 259.733);--color-gray-800:oklch(27.8% .033 256.848);--color-gray-900:oklch(21% .034 264.665);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-md:28rem;--container-3xl:48rem;--text-xs:.75rem;--text-xs--line-height:calc(1/.75);--text-sm:.875rem;--text-sm--line-height:calc(1.25/.875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75/1.125);--font-weight-medium:500;--font-weight-semibold:600;--leading-snug:1.375;--leading-relaxed:1.625;--radius-sm:.25rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--ease-out:cubic-bezier(0,0,.2,1);--ease-in-out:cubic-bezier(.4,0,.2,1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4,0,.6,1)infinite;--blur-sm:8px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4,0,.2,1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif,system-ui,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}:host{font-family:var(--font-sans);color:var(--color-slate-900);background-color:#0000;display:block}}@layer components;@layer utilities{.\@container{container-type:inline-size}.pointer-events-auto{pointer-events:auto}.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}.top-0{top:calc(var(--spacing)*0)}.right-0{right:calc(var(--spacing)*0)}.bottom-0{bottom:calc(var(--spacing)*0)}.left-0{left:calc(var(--spacing)*0)}.z-10{z-index:10}.z-30{z-index:30}.z-40{z-index:40}.z-50{z-index:50}.mx-3{margin-inline:calc(var(--spacing)*3)}.mx-4{margin-inline:calc(var(--spacing)*4)}.mx-auto{margin-inline:auto}.my-1{margin-block:calc(var(--spacing)*1)}.my-3{margin-block:calc(var(--spacing)*3)}.mt-0\.5{margin-top:calc(var(--spacing)*.5)}.mt-1{margin-top:calc(var(--spacing)*1)}.mt-1\.5{margin-top:calc(var(--spacing)*1.5)}.mt-2{margin-top:calc(var(--spacing)*2)}.mt-3{margin-top:calc(var(--spacing)*3)}.mt-4{margin-top:calc(var(--spacing)*4)}.mt-5{margin-top:calc(var(--spacing)*5)}.mt-6{margin-top:calc(var(--spacing)*6)}.mr-auto{margin-right:auto}.mb-0\.5{margin-bottom:calc(var(--spacing)*.5)}.mb-1{margin-bottom:calc(var(--spacing)*1)}.mb-2{margin-bottom:calc(var(--spacing)*2)}.mb-3{margin-bottom:calc(var(--spacing)*3)}.mb-4{margin-bottom:calc(var(--spacing)*4)}.-ml-1{margin-left:calc(var(--spacing)*-1)}.ml-1{margin-left:calc(var(--spacing)*1)}.ml-auto{margin-left:auto}.box-border{box-sizing:border-box}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1\.5{height:calc(var(--spacing)*1.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-12{height:calc(var(--spacing)*12)}.h-\[28rem\]{height:28rem}.h-full{height:100%}.max-h-32{max-height:calc(var(--spacing)*32)}.min-h-0{min-height:calc(var(--spacing)*0)}.min-h-7{min-height:calc(var(--spacing)*7)}.min-h-\[20rem\]{min-height:20rem}.min-h-\[40px\]{min-height:40px}.min-h-\[420px\]{min-height:420px}.w-1\.5{width:calc(var(--spacing)*1.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-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-40{width:calc(var(--spacing)*40)}.w-auto{width:auto}.w-full{width:100%}.w-px{width:1px}.max-w-3xl{max-width:var(--container-3xl)}.max-w-\[80\%\]{max-width:80%}.max-w-\[200px\]{max-width:200px}.max-w-\[240px\]{max-width:240px}.max-w-full{max-width:100%}.max-w-md{max-width:var(--container-md)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:calc(var(--spacing)*0)}.min-w-\[200px\]{min-width:200px}.flex-1{flex:1}.flex-shrink,.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.table-fixed{table-layout:fixed}.border-collapse{border-collapse:collapse}.translate-x-0\.5{--tw-translate-x:calc(var(--spacing)*.5);translate:var(--tw-translate-x)var(--tw-translate-y)}.translate-x-4{--tw-translate-x:calc(var(--spacing)*4);translate:var(--tw-translate-x)var(--tw-translate-y)}.-translate-y-\[2px\]{--tw-translate-y:calc(2px*-1);translate:var(--tw-translate-x)var(--tw-translate-y)}.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-grab{cursor:grab}.cursor-grabbing{cursor:grabbing}.cursor-not-allowed{cursor:not-allowed}.cursor-nwse-resize{cursor:nwse-resize}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.resize{resize:both}.resize-none{resize:none}.list-none{list-style-type:none}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing)*1)}.gap-1\.5{gap:calc(var(--spacing)*1.5)}.gap-2{gap:calc(var(--spacing)*2)}.gap-3{gap:calc(var(--spacing)*3)}.gap-4{gap:calc(var(--spacing)*4)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*1)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*1)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*2)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*2)*calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing)*3)*var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing)*3)*calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-\[16px\]{border-radius:16px}.rounded-\[28px\]{border-radius:28px}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-amber-200{border-color:var(--color-amber-200)}.border-blue-200{border-color:var(--color-blue-200)}.border-emerald-200{border-color:var(--color-emerald-200)}.border-gray-200{border-color:var(--color-gray-200)}.border-purple-200{border-color:var(--color-purple-200)}.border-rose-200{border-color:var(--color-rose-200)}.border-rose-300{border-color:var(--color-rose-300)}.border-slate-200{border-color:var(--color-slate-200)}.border-violet-200{border-color:var(--color-violet-200)}.bg-\[\#00000014\]{background-color:#00000014}.bg-amber-50{background-color:var(--color-amber-50)}.bg-amber-100{background-color:var(--color-amber-100)}.bg-black{background-color:var(--color-black)}.bg-blue-50{background-color:var(--color-blue-50)}.bg-blue-100{background-color:var(--color-blue-100)}.bg-emerald-50{background-color:var(--color-emerald-50)}.bg-emerald-500{background-color:var(--color-emerald-500)}.bg-gray-50{background-color:var(--color-gray-50)}.bg-gray-50\/50{background-color:#f9fafb80}@supports (color:color-mix(in lab, red, red)){.bg-gray-50\/50{background-color:color-mix(in oklab,var(--color-gray-50)50%,transparent)}}.bg-gray-100{background-color:var(--color-gray-100)}.bg-gray-200{background-color:var(--color-gray-200)}.bg-gray-300{background-color:var(--color-gray-300)}.bg-gray-400{background-color:var(--color-gray-400)}.bg-gray-500{background-color:var(--color-gray-500)}.bg-gray-800{background-color:var(--color-gray-800)}.bg-gray-900{background-color:var(--color-gray-900)}.bg-green-100{background-color:var(--color-green-100)}.bg-purple-50{background-color:var(--color-purple-50)}.bg-rose-50{background-color:var(--color-rose-50)}.bg-rose-500{background-color:var(--color-rose-500)}.bg-slate-900{background-color:var(--color-slate-900)}.bg-transparent{background-color:#0000}.bg-violet-50{background-color:var(--color-violet-50)}.bg-white{background-color:var(--color-white)}.bg-white\/95{background-color:#fffffff2}@supports (color:color-mix(in lab, red, red)){.bg-white\/95{background-color:color-mix(in oklab,var(--color-white)95%,transparent)}}.p-0\.5{padding:calc(var(--spacing)*.5)}.p-3{padding:calc(var(--spacing)*3)}.p-4{padding:calc(var(--spacing)*4)}.px-1{padding-inline:calc(var(--spacing)*1)}.px-1\.5{padding-inline:calc(var(--spacing)*1.5)}.px-2{padding-inline:calc(var(--spacing)*2)}.px-2\.5{padding-inline:calc(var(--spacing)*2.5)}.px-3{padding-inline:calc(var(--spacing)*3)}.px-4{padding-inline:calc(var(--spacing)*4)}.py-0\.5{padding-block:calc(var(--spacing)*.5)}.py-1{padding-block:calc(var(--spacing)*1)}.py-1\.5{padding-block:calc(var(--spacing)*1.5)}.py-2{padding-block:calc(var(--spacing)*2)}.py-2\.5{padding-block:calc(var(--spacing)*2.5)}.py-3{padding-block:calc(var(--spacing)*3)}.py-4{padding-block:calc(var(--spacing)*4)}.py-8{padding-block:calc(var(--spacing)*8)}.py-10{padding-block:calc(var(--spacing)*10)}.pt-1{padding-top:calc(var(--spacing)*1)}.pt-1\.5{padding-top:calc(var(--spacing)*1.5)}.pt-8{padding-top:calc(var(--spacing)*8)}.pb-2{padding-bottom:calc(var(--spacing)*2)}.pb-3{padding-bottom:calc(var(--spacing)*3)}.pb-5{padding-bottom:calc(var(--spacing)*5)}.text-center{text-align:center}.text-left{text-align:left}.align-middle{vertical-align:middle}.font-mono{font-family:var(--font-mono)}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[9px\]{font-size:9px}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-\[13px\]{font-size:13px}.leading-4{--tw-leading:calc(var(--spacing)*4);line-height:calc(var(--spacing)*4)}.leading-5{--tw-leading:calc(var(--spacing)*5);line-height:calc(var(--spacing)*5)}.leading-\[22px\]{--tw-leading:22px;line-height:22px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.leading-snug{--tw-leading:var(--leading-snug);line-height:var(--leading-snug)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.text-\[rgb\(13\,13\,13\)\]{color:#0d0d0d}.text-amber-600{color:var(--color-amber-600)}.text-amber-800{color:var(--color-amber-800)}.text-amber-900{color:var(--color-amber-900)}.text-blue-600{color:var(--color-blue-600)}.text-blue-700{color:var(--color-blue-700)}.text-blue-800{color:var(--color-blue-800)}.text-emerald-700{color:var(--color-emerald-700)}.text-gray-300{color:var(--color-gray-300)}.text-gray-400{color:var(--color-gray-400)}.text-gray-500{color:var(--color-gray-500)}.text-gray-600{color:var(--color-gray-600)}.text-gray-700{color:var(--color-gray-700)}.text-gray-800{color:var(--color-gray-800)}.text-gray-900{color:var(--color-gray-900)}.text-green-700{color:var(--color-green-700)}.text-green-800{color:var(--color-green-800)}.text-purple-700{color:var(--color-purple-700)}.text-rose-700{color:var(--color-rose-700)}.text-rose-800{color:var(--color-rose-800)}.text-rose-950{color:var(--color-rose-950)}.text-slate-500{color:var(--color-slate-500)}.text-slate-800{color:var(--color-slate-800)}.text-violet-500{color:var(--color-violet-500)}.text-violet-600{color:var(--color-violet-600)}.text-violet-950{color:var(--color-violet-950)}.text-white{color:var(--color-white)}.italic{font-style:italic}.underline{text-decoration-line:underline}.decoration-violet-300{-webkit-text-decoration-color:var(--color-violet-300);-webkit-text-decoration-color:var(--color-violet-300);text-decoration-color:var(--color-violet-300)}.underline-offset-2{text-underline-offset:2px}.opacity-0{opacity:0}.opacity-50{opacity:.5}.opacity-80{opacity:.8}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[0_4px_4px_0_\#0000000a\,0_0_1px_0_\#0000009e\]{--tw-shadow:0 4px 4px 0 var(--tw-shadow-color,#0000000a),0 0 1px 0 var(--tw-shadow-color,#0000009e);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a),0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a),0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a),0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.ring,.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-transparent{--tw-ring-color:transparent}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.blur{--tw-blur:blur(8px);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-filter{-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-shadow{transition-property:box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-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))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-out{--tw-ease:var(--ease-out);transition-timing-function:var(--ease-out)}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}@media (hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}.placeholder\:text-gray-500::placeholder{color:var(--color-gray-500)}.focus-within\:shadow-\[0_6px_18px_0_\#00000014\,0_0_1px_0_\#0000009e\]:focus-within{--tw-shadow:0 6px 18px 0 var(--tw-shadow-color,#00000014),0 0 1px 0 var(--tw-shadow-color,#0000009e);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}@media (hover:hover){.hover\:border-gray-300:hover{border-color:var(--color-gray-300)}.hover\:bg-blue-50\/50:hover{background-color:#eff6ff80}@supports (color:color-mix(in lab, red, red)){.hover\:bg-blue-50\/50:hover{background-color:color-mix(in oklab,var(--color-blue-50)50%,transparent)}}.hover\:bg-gray-50:hover{background-color:var(--color-gray-50)}.hover\:bg-gray-100:hover{background-color:var(--color-gray-100)}.hover\:bg-gray-200:hover{background-color:var(--color-gray-200)}.hover\:bg-gray-800:hover{background-color:var(--color-gray-800)}.hover\:bg-rose-100:hover{background-color:var(--color-rose-100)}.hover\:bg-violet-100:hover{background-color:var(--color-violet-100)}.hover\:text-gray-900:hover{color:var(--color-gray-900)}.hover\:text-violet-800:hover{color:var(--color-violet-800)}.hover\:decoration-violet-700:hover{-webkit-text-decoration-color:var(--color-violet-700);-webkit-text-decoration-color:var(--color-violet-700);text-decoration-color:var(--color-violet-700)}.hover\:opacity-70:hover{opacity:.7}}.focus\:border-gray-300:focus{border-color:var(--color-gray-300)}.focus\:border-violet-400:focus{border-color:var(--color-violet-400)}.focus\:bg-gray-50:focus{background-color:var(--color-gray-50)}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset,)0 0 0 calc(2px + var(--tw-ring-offset-width))var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.focus\:ring-gray-200:focus{--tw-ring-color:var(--color-gray-200)}.focus\:ring-violet-100:focus{--tw-ring-color:var(--color-violet-100)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:rounded:focus-visible{border-radius:.25rem}.focus-visible\:rounded-sm:focus-visible{border-radius:var(--radius-sm)}.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-rose-300:focus-visible{--tw-ring-color:var(--color-rose-300)}.focus-visible\:ring-violet-300:focus-visible{--tw-ring-color:var(--color-violet-300)}.focus-visible\:ring-violet-400:focus-visible{--tw-ring-color:var(--color-violet-400)}.focus-visible\:ring-offset-1:focus-visible{--tw-ring-offset-width:1px;--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-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\:outline:focus-visible{outline-style:var(--tw-outline-style);outline-width:1px}.focus-visible\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\:outline-offset-2:focus-visible{outline-offset:2px}.focus-visible\:outline-\[\#BEC2FF\]:focus-visible{outline-color:#bec2ff}.focus-visible\:outline-gray-300:focus-visible{outline-color:var(--color-gray-300)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.active\:opacity-60:active{opacity:.6}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:text-gray-500:disabled{color:var(--color-gray-500)}.disabled\:opacity-50:disabled{opacity:.5}.disabled\:opacity-60:disabled{opacity:.6}@media (min-width:48rem){.md\:grid-cols-4{grid-template-columns:repeat(4,minmax(0,1fr))}}.\[\&\>svg\]\:\!h-8>svg{height:calc(var(--spacing)*8)!important}.\[\&\>svg\]\:h-3>svg{height:calc(var(--spacing)*3)}.\[\&\>svg\]\:h-3\.5>svg{height:calc(var(--spacing)*3.5)}.\[\&\>svg\]\:h-\[18px\]>svg{height:18px}.\[\&\>svg\]\:\!w-8>svg{width:calc(var(--spacing)*8)!important}.\[\&\>svg\]\:w-3>svg{width:calc(var(--spacing)*3)}.\[\&\>svg\]\:w-3\.5>svg{width:calc(var(--spacing)*3.5)}.\[\&\>svg\]\:w-\[18px\]>svg{width:18px}.\[\&\>svg\]\:animate-spin>svg{animation:var(--animate-spin)}.sr-only{clip:rect(0,0,0,0);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}}.cpk-json-block{white-space:pre-wrap;word-break:break-all;color:#57575b;margin:0;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:11px;line-height:1.8;overflow:auto}.inspector-account-strip{border-bottom:1px solid #d8d8e8;width:100%;min-width:0;color:#010507!important;background:#f7f6fd!important}.inspector-account-logo{filter:none}.inspector-account-brand{position:relative}.inspector-account-logo-accent{clip-path:inset(0 0 0 80%);pointer-events:none;display:none;position:absolute;inset:0}.inspector-account-cta{isolation:isolate;color:#3f176f;white-space:nowrap;cursor:pointer;background-color:#eee6fe;border:0;border-radius:5px;flex:none;justify-content:center;align-items:center;gap:7px;min-height:32px;padding:7px 10px;font-size:11px;font-weight:700;line-height:1;text-decoration:none;display:inline-flex;position:relative;overflow:hidden}.inspector-account-cta:after{z-index:0;content:"";opacity:0;pointer-events:none;background:linear-gradient(105deg,#0000 0%,#ffffff14 32%,#ffffffad 50%,#ffffff14 68%,#0000 100%);width:68%;animation:3.8s cubic-bezier(.16,1,.3,1) infinite inspector-account-cta-shimmer;position:absolute;inset:0;transform:translate(-180%)skew(-14deg)}.inspector-account-cta>*{z-index:1;position:relative}.inspector-account-cta[data-motion-paused=true]:after{animation-play-state:paused}@keyframes inspector-account-cta-shimmer{0%{opacity:0;transform:translate(-180%)skew(-14deg)}12%{opacity:1}82%{opacity:.8}to{opacity:0;transform:translate(280%)skew(-14deg)}}.inspector-account-cta:hover{color:#32105d;background-color:#e4d8fc}.inspector-account-cta svg{width:14px;height:14px}@media (prefers-reduced-motion:reduce){.inspector-account-cta:after{animation:none}}.inspector-window-layout{position:relative}.inspector-window-layout-menu{z-index:60;color:#010507;background-color:#fff;border:1px solid #d8d8e8;border-radius:5px;width:188px;padding:4px;display:grid;position:absolute;top:calc(100% + 6px);right:0;overflow:hidden;box-shadow:0 10px 24px #1f173924}.inspector-window-layout-menu button{min-height:34px;color:inherit;text-align:left;cursor:pointer;background-color:#0000;border:0;border-radius:4px;align-items:center;gap:9px;padding:7px 9px;font-size:12px;font-weight:600;display:flex}.inspector-window-layout-menu button:hover,.inspector-window-layout-menu button:focus-visible{color:#3f176f;background-color:#eee6fe;outline:none}.inspector-window-layout-menu button span:first-child{flex:none;display:inline-flex}.inspector-agent-placeholder{color:#68686e;border-color:#c8c8d8}.inspector-primary-navigation,.inspector-child-navigation{display:none}.inspector-shell{background-color:#f7f6fd;flex:auto;min-height:0;display:flex}.inspector-sidebar{z-index:20;background-color:#f7f6fd;border-right:1px solid #d8d8e8;flex-direction:column;flex:none;gap:8px;width:224px;min-width:224px;padding:12px 10px;transition:width .22s,min-width .22s,padding .22s;display:flex;position:relative;overflow:visible}.inspector-sidebar[data-icon-rail=true]{align-items:center;width:52px;min-width:52px;padding:8px}.inspector-sidebar-agent-scope{border-bottom:1px solid #d8d8e8;flex:none;min-width:0;padding-bottom:10px}.inspector-sidebar .inspector-agent-selector{width:100%;min-width:0}.inspector-sidebar .inspector-agent-selector>[data-context-dropdown-root=true]>button{background-color:#fff;border-radius:5px;max-width:none;min-height:34px;padding:6px 8px}.inspector-context-dropdown-icon{color:#68686e;display:inline-flex}.inspector-context-dropdown-icon svg,.inspector-context-dropdown-chevron svg{width:14px;height:14px}.inspector-sidebar[data-icon-rail=true] .inspector-sidebar-agent-scope{padding-bottom:8px}.inspector-sidebar[data-icon-rail=true] .inspector-sidebar-agent-scope,.inspector-sidebar[data-icon-rail=true] .inspector-agent-selector,.inspector-sidebar[data-icon-rail=true] .inspector-agent-selector>[data-context-dropdown-root=true],.inspector-sidebar[data-icon-rail=true] .inspector-sidebar-footer{flex:none;justify-content:center;align-items:center;width:36px;min-width:36px;max-width:36px;display:flex}.inspector-sidebar[data-icon-rail=true] .inspector-agent-selector>[data-context-dropdown-root=true]>button,.inspector-sidebar[data-icon-rail=true] .inspector-agent-placeholder{box-sizing:border-box;justify-content:center;align-items:center;gap:0;width:36px;min-width:36px;max-width:36px;height:36px;min-height:36px;padding:0;transition:background-color .18s,border-color .18s,color .18s,box-shadow .18s;display:flex;overflow:visible}.inspector-sidebar[data-icon-rail=true] .inspector-context-dropdown-label,.inspector-sidebar[data-icon-rail=true] .inspector-context-dropdown-chevron,.inspector-sidebar[data-icon-rail=true] .inspector-agent-placeholder span:last-child{display:none}.inspector-sidebar[data-icon-rail=true] .inspector-sidebar-agent-scope [data-context-dropdown-root=true]>div{margin-top:0;top:0;left:calc(100% + 8px)}.inspector-icon-rail-menu{transform-origin:0;opacity:0;visibility:hidden;pointer-events:none;transition:opacity .18s,transform .18s,visibility .18s;transform:translate(-8px)scale(.96)}.inspector-icon-rail-menu[data-open=true]{opacity:1;visibility:visible;pointer-events:auto;transform:translate(0)scale(1)}.inspector-sidebar[data-icon-rail=true] .inspector-sidebar-section+.inspector-sidebar-section{border-top:1px solid #dbdbe5;margin-top:4px;padding-top:10px}.inspector-sidebar-nav{cursor:default;flex-direction:column;flex:auto;gap:14px;min-height:0;display:flex;overflow:hidden auto}.inspector-sidebar-section{flex-direction:column;gap:4px;display:flex}.inspector-sidebar-label{color:#838389;letter-spacing:.02em;text-align:left;text-transform:none;background:0 0;border:0;width:100%;margin:0 0 2px;padding:0 8px;font-size:11px;font-weight:600;display:block}.inspector-sidebar[data-icon-rail=true] .inspector-sidebar-label,.inspector-sidebar[data-icon-rail=true] .inspector-nav-label{display:none}.inspector-sidebar-rail-tooltip{z-index:60;color:#fff;pointer-events:none;white-space:nowrap;background-color:#242331;border-radius:6px;max-width:220px;padding:6px 9px;font-size:11px;font-weight:600;line-height:1.2;position:absolute;left:calc(100% + 8px);transform:translateY(-50%);box-shadow:0 7px 18px #1a172a2e}.inspector-sidebar-control{justify-content:flex-start;width:100%;min-height:36px;display:flex;position:relative}.inspector-sidebar[data-icon-rail=true] .inspector-sidebar-nav{overflow:visible}.inspector-sidebar[data-icon-rail=true] .inspector-sidebar-control,.inspector-sidebar[data-icon-rail=true] .inspector-sidebar-toggle,.inspector-sidebar[data-icon-rail=true] .inspector-nav-control{box-sizing:border-box;justify-content:center;align-items:center;gap:0;width:36px;min-width:36px;height:36px;min-height:36px;padding:0;overflow:visible}.inspector-sidebar[data-icon-rail=true] .inspector-nav-icon,.inspector-sidebar[data-icon-rail=true] .inspector-nav-icon svg,.inspector-sidebar[data-icon-rail=true] .inspector-context-dropdown-icon,.inspector-sidebar[data-icon-rail=true] .inspector-context-dropdown-icon svg{width:18px;height:18px;overflow:visible}.inspector-home-badge{background-color:#fa5f67;border-radius:999px;width:7px;height:7px;position:absolute;top:8px;right:8px}.inspector-sidebar[data-icon-rail=true] .inspector-home-badge{top:6px;right:8px}.inspector-sidebar-toggle{color:#57575b;width:100%;min-height:32px;font:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:5px;flex:none;justify-content:flex-start;align-items:center;gap:6px;padding:6px 9px;font-size:12px;font-weight:600;display:flex}.inspector-sidebar-toggle:hover{color:#010507;background-color:#f0f0f4}.inspector-sidebar-footer{flex-direction:column;flex:none;gap:6px;padding:2px 0 0;display:flex}.inspector-sidebar-status-list{grid-template-columns:minmax(0,1fr);gap:8px;display:grid}.inspector-sidebar-status-card{color:#2b2b2b;background-color:#fff;border:1px solid #d8d8e8;border-radius:7px;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:8px;min-height:52px;padding:9px 10px;display:grid;position:relative}.inspector-sidebar-status-copy{flex-direction:column;gap:2px;min-width:0;line-height:1.25;display:flex}.inspector-sidebar-status-copy strong{color:#010507;text-overflow:ellipsis;white-space:nowrap;font-size:11px;font-weight:700;overflow:hidden}.inspector-sidebar-status-copy>span{color:#57575b;text-overflow:ellipsis;white-space:nowrap;font-size:10px;overflow:hidden}.inspector-sidebar-status-card[data-state=disconnected] .inspector-sidebar-status-copy>span{color:#68686e}.inspector-sidebar-status-action{color:#3f176f;white-space:nowrap;background-color:#0000;border:0;border-radius:5px;justify-content:center;align-items:center;gap:0;width:28px;height:28px;padding:0;font-size:10px;font-weight:700;text-decoration:none;display:inline-flex}.inspector-sidebar-status-action:hover{color:#6430ab;background-color:#eee7f8;text-decoration:none}.inspector-sidebar-status-action svg{width:12px;height:12px}.inspector-sidebar-status-action-label{display:none}.inspector-sidebar-intelligence-setup{color:#3f176f;cursor:pointer;background-color:#eee7f8;border-color:#bba5df;text-decoration:none;transition:border-color .12s,background-color .12s,box-shadow .3s;animation:3.2s ease-in-out infinite inspector-sidebar-intelligence-setup-glow}@keyframes inspector-sidebar-intelligence-setup-glow{0%,to{box-shadow:0 0 #6430ab00}50%{box-shadow:0 0 16px 2px #6430ab26}}.inspector-sidebar-intelligence-setup:hover{background-color:#e4d9f4;border-color:#8e6fc0}.inspector-sidebar-intelligence-setup .inspector-sidebar-status-copy strong{color:#3f176f}.inspector-sidebar-setup-arrow{background-color:#6430ab1a;border-radius:5px;justify-content:center;align-items:center;width:28px;height:28px;display:inline-flex}.inspector-sidebar-setup-arrow svg{width:13px;height:13px}.inspector-main{background-color:#fff;flex-direction:column;flex:auto;min-width:0;display:flex;position:relative}.inspector-home{background-color:#fff;min-height:100%;padding:30px 32px 40px;position:relative;overflow:auto}.inspector-home:before{display:none}.inspector-home>*{width:min(100%,960px);margin-left:auto;margin-right:auto}.inspector-settings{color:#010507;background-color:#fff;min-height:100%;padding:34px 32px 48px;container:inspector-settings/inline-size}.inspector-settings-header{width:min(100%,720px);margin-left:auto;margin-right:auto;padding-bottom:30px}.inspector-settings-title{color:#010507;margin:0;font-family:Plus Jakarta Sans,system-ui,sans-serif;font-size:30px;font-weight:600;line-height:1.15}.inspector-settings-subtitle{color:#57575b;max-width:60ch;margin:8px 0 0;font-size:14px;line-height:1.5}.inspector-settings-section{border-top:1px solid #d5d3e4;width:min(100%,720px);margin-left:auto;margin-right:auto;padding:24px 0 26px}.inspector-settings-section-heading{align-items:flex-start;gap:12px;margin-bottom:22px;display:flex}.inspector-settings-section-icon{color:#3f176f;background-color:#eee6fe;border:1px solid #bec2ff;border-radius:8px;flex:none;justify-content:center;align-items:center;width:34px;height:34px;display:inline-flex}.inspector-settings-section-icon svg{width:17px;height:17px}.inspector-settings-section-heading h2,.inspector-settings-status-row h3,.inspector-settings-visibility h3{color:#010507;margin:0;font-family:Plus Jakarta Sans,system-ui,sans-serif;font-weight:600}.inspector-settings-section-heading h2{font-size:17px;line-height:1.3}.inspector-settings-section-heading p{color:#68686e;max-width:54ch;margin:4px 0 0;font-size:12px;line-height:1.5}.inspector-settings-privacy{margin-left:46px}.inspector-settings-status-row{justify-content:space-between;align-items:flex-start;gap:24px;display:flex}.inspector-settings-status-row>div,.inspector-settings-visibility>div{min-width:0}.inspector-settings-status-row h3{font-size:14px;line-height:1.3}.inspector-settings-status-row p{color:#57575b;max-width:56ch;margin:8px 0 0;font-size:12px;line-height:1.55}.inspector-settings-status{color:#087653;text-align:center;white-space:nowrap;background-color:#e5f7f1;border:1px solid #85d3bb;border-radius:999px;flex:none;align-items:center;min-height:24px;padding:3px 8px;font-size:11px;font-weight:700;line-height:1;display:inline-flex}.inspector-settings-privacy[data-state=disabled] .inspector-settings-status{color:#7d4d0a;background-color:#fff5df;border-color:#dfc08f}.inspector-settings-private-content{border-top:1px solid #e4e4ec;margin-top:22px;padding-top:18px}.inspector-settings-private-content strong{color:#010507;font-size:13px;font-weight:700}.inspector-settings-private-content>p{color:#68686e;margin:4px 0 0;font-size:11px;line-height:1.45}.inspector-settings-private-content ul{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px 18px;margin:12px 0 0;display:grid}.inspector-settings-private-content li{color:#3e3d48;align-items:center;gap:7px;min-width:0;font-size:12px;line-height:1.35;display:flex}.inspector-settings-private-content li span{color:#087653;flex:none;display:inline-flex}.inspector-settings-private-content li svg{width:14px;height:14px}.inspector-settings-policy-link{color:#3f176f;text-underline-offset:3px;outline-offset:2px;outline:2px solid #0000;align-items:center;gap:6px;min-height:36px;margin-top:20px;font-size:12px;font-weight:700;text-decoration:underline;text-decoration-thickness:1px;display:inline-flex}.inspector-settings-policy-link:hover{color:#6430ab}.inspector-settings-policy-link:focus-visible{outline-color:#6430ab}.inspector-settings-policy-link svg{width:14px;height:14px}.inspector-settings-visibility{margin-left:46px}.inspector-settings-visibility h3{font-size:14px;line-height:1.3}.inspector-settings-visibility p{color:#57575b;max-width:48ch;margin:8px 0 0;font-size:12px;line-height:1.55}.inspector-settings-dismiss{color:#3f176f;text-align:center;cursor:pointer;background-color:#f5f2ff;border:1px solid #c9c2e6;border-radius:7px;justify-content:center;align-items:center;gap:7px;min-height:40px;margin-top:16px;padding:8px 12px;font-size:12px;font-weight:700;line-height:1.2;display:inline-flex}.inspector-settings-dismiss:hover{background-color:#eee8ff;border-color:#a69aca}.inspector-settings-dismiss:focus-visible{outline-offset:2px;outline:2px solid #6430ab}.inspector-settings-dismiss svg{width:14px;height:14px}@media (max-width:720px){.inspector-settings{padding:28px 24px 40px}.inspector-settings-section-heading p{max-width:42ch}}@media (max-width:480px){.inspector-settings{padding-left:18px;padding-right:18px}}@container inspector-settings (max-width:520px){.inspector-settings-privacy,.inspector-settings-visibility{margin-left:0}.inspector-settings-status-row{flex-direction:column;gap:12px}.inspector-settings-private-content ul{grid-template-columns:1fr}.inspector-settings-dismiss{width:100%}}.inspector-home-card,.inspector-home-story{background-color:#ffffffd1;border:1px solid #deddea;border-radius:5px;padding:18px 18px 16px;position:relative}.inspector-home-eyebrow,.inspector-home-card-label,.inspector-home-meta{color:#57575b;margin:0;font-size:12px;font-weight:600}.inspector-home-title,.inspector-home-section-title,.inspector-home-card-title{color:#010507;margin:8px 0 0;font-family:Plus Jakarta Sans,system-ui,sans-serif;font-size:28px;font-weight:600;line-height:1.15}.inspector-home-section-title{letter-spacing:-.015em;margin:0 0 14px;font-size:17px}.inspector-home-card-title{font-size:16px}.inspector-home-body,.inspector-home-card-copy{color:#57575b;max-width:52ch;margin:10px 0 0;font-size:15px;line-height:1.5}.inspector-home-section{margin-top:24px;position:relative}.inspector-home>.inspector-home-section:first-child{margin-top:0}.inspector-whats-new-preview+.inspector-home-section{margin-top:20px}.inspector-home-section-header{justify-content:space-between;align-items:center;gap:16px;margin-bottom:12px;display:flex}.inspector-home-section-header .inspector-home-section-title{margin-bottom:0}.inspector-home-section-header>span{color:#68686e;font-size:11px;font-weight:600;line-height:1.35}.inspector-system-health-header>span[data-tone=success]{color:#087653}.inspector-system-health-header>span[data-tone=checking]{color:#8a5900}.inspector-system-health-header>span[data-tone=offline],.inspector-system-health-header>span[data-tone=error]{color:#b32d3b}.inspector-system-health-section{background-color:#f7f4fe;border:1px solid #c8c6e6;border-radius:5px;overflow:hidden}.inspector-system-health-section .inspector-system-health-header{background-color:#f7f4fe;border-bottom:1px solid #d5d3e4;align-items:center;min-height:76px;margin:0;padding:18px}.inspector-system-health-heading{min-width:0}.inspector-system-health-heading .inspector-home-section-title{color:#010507;letter-spacing:-.025em;font-size:18px}.inspector-system-health-state,.inspector-intelligence-hud-state{color:#087653;background-color:#e5f7f1;border:1px solid #85d3bb;border-radius:999px;flex:none;align-items:center;gap:6px;min-height:24px;padding:4px 8px;font-size:10px;font-weight:700;line-height:1;display:inline-flex}.inspector-system-health-state>span,.inspector-intelligence-hud-state>span{background-color:currentColor;border-radius:999px;width:6px;height:6px}.inspector-system-health-state[data-tone=checking],.inspector-intelligence-hud-state[data-tone=checking]{background-color:#fff5df;border-color:#dfc08f;color:#7d4d0a!important}.inspector-system-health-state[data-tone=offline],.inspector-system-health-state[data-tone=error],.inspector-intelligence-hud-state[data-tone=offline],.inspector-intelligence-hud-state[data-tone=error]{background-color:#fff0f1;border-color:#e7a7ac;color:#b32d3b!important}.inspector-system-health-state[data-tone=unavailable],.inspector-intelligence-hud-state[data-tone=unavailable]{background-color:#f0f0f4;border-color:#c8c8d2;color:#57575b!important}.inspector-system-health{background-color:#d5d3e4;grid-template-columns:repeat(3,minmax(0,1fr));gap:1px;display:grid;overflow:hidden}.inspector-system-health-signal{background-color:#fff;grid-template-columns:minmax(0,1fr);align-items:start;min-width:0;min-height:84px;padding:15px 16px 14px;display:grid}.inspector-system-health-copy{flex-direction:column;min-width:0;display:flex}.inspector-system-health-signal dt{color:#68686e;letter-spacing:.035em;text-transform:uppercase;font-size:10px;font-weight:700;line-height:1.3}.inspector-system-health-signal dd{color:#010507;text-overflow:ellipsis;white-space:nowrap;min-width:0;margin:5px 0 0;font-size:15px;font-weight:700;overflow:hidden}.inspector-system-health-signal small{color:#68686e;text-overflow:ellipsis;white-space:nowrap;min-width:0;margin-top:4px;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:10px;line-height:1.4;overflow:hidden}small.inspector-system-health-detail{letter-spacing:0;font-family:inherit;font-size:11px;font-weight:500;line-height:1.4}.inspector-system-health-url{cursor:help;outline:none;position:relative;overflow:visible!important}.inspector-system-health-url>span{text-overflow:ellipsis;white-space:nowrap;display:block;overflow:hidden}.inspector-system-health-url:after{z-index:30;color:#f3f4f8;content:attr(data-full-value);opacity:0;overflow-wrap:anywhere;pointer-events:none;white-space:normal;background-color:#15171e;border:1px solid #3a3d49;border-radius:4px;width:max-content;max-width:min(360px,70vw);padding:7px 9px;font-size:10px;font-weight:500;line-height:1.45;transition:opacity .12s,transform .12s;position:absolute;bottom:calc(100% + 7px);left:0;transform:translateY(3px);box-shadow:0 8px 20px #0105072e}.inspector-system-health-url:hover:after,.inspector-system-health-url:focus-visible:after{opacity:1;transform:translateY(0)}.inspector-system-health-url:focus-visible>span{outline-offset:2px;border-radius:3px;outline:2px solid #6430ab}.inspector-system-health-signal[data-tone=success] dd{color:#087653}.inspector-system-health-signal[data-tone=active] dd{color:#8a5900}.inspector-system-health-event-link{width:100%;min-width:0;color:inherit;cursor:pointer;font:inherit;text-align:left;background:0 0;border:0;padding:0;display:block}.inspector-system-health-event-link>span{text-overflow:ellipsis;white-space:nowrap;display:block;overflow:hidden}.inspector-system-health-event-link>.inspector-system-health-event-type{color:#57575b;letter-spacing:.025em;background-color:#f1f1f3;border-radius:999px;align-items:center;width:fit-content;max-width:100%;padding:3px 6px;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:10px;font-weight:700;line-height:1.25;display:inline-flex}.inspector-system-health-event-link>small{color:#68686e;align-items:center;gap:6px;margin:5px 0 0;font-family:Plus Jakarta Sans,system-ui,sans-serif;font-size:10px;font-weight:500;line-height:1.25;display:flex}.inspector-system-health-event-meta strong{color:#6430ab;text-underline-offset:3px;font-weight:700;-webkit-text-decoration:underline #0000;text-decoration:underline #0000}.inspector-system-health-signal[data-tone=error] .inspector-system-health-event-type{color:#b32d3b;background-color:#fff0f1}.inspector-system-health-signal[data-tone=success] .inspector-system-health-event-type{color:#087653;background-color:#e3f5ee}.inspector-system-health-signal[data-tone=active] .inspector-system-health-event-type{color:#8a5900;background-color:#fff5df}.inspector-system-health-event-link:hover .inspector-system-health-event-meta strong{text-decoration-color:currentColor}.inspector-system-health-event-link:focus-visible{outline-offset:3px;border-radius:3px;outline:2px solid #6430ab}.inspector-intelligence-hud{background-color:#f7f4fe;border:1px solid #c8c6e6;border-radius:5px;overflow:hidden}.inspector-intelligence-hud-header{justify-content:space-between;align-items:center;gap:24px;padding:18px;display:flex}.inspector-intelligence-hud[data-state=disconnected]{border-color:#bba5df}.inspector-intelligence-hud[data-state=disconnected] .inspector-intelligence-hud-header{align-items:center;min-height:132px;padding:22px}.inspector-intelligence-hud[data-state=disconnected] .inspector-intelligence-hud-header-actions{flex-direction:column;align-items:flex-end;gap:10px}.inspector-intelligence-hud-heading{min-width:0}.inspector-intelligence-hud-header-actions{flex:none;align-items:center;gap:8px;display:flex}.inspector-intelligence-hud-heading .inspector-home-section-title{margin:0;font-size:18px}.inspector-intelligence-hud-description{color:#4f4f55;max-width:64ch;margin:10px 0 0;font-size:12px;line-height:1.55}.inspector-intelligence-hud-action{color:#fff;background-color:#6430ab;border:1px solid #6430ab;border-radius:4px;flex:none;justify-content:center;align-items:center;gap:7px;min-height:34px;padding:8px 11px;font-family:Plus Jakarta Sans,system-ui,sans-serif;font-size:11px;font-weight:700;text-decoration:none;display:inline-flex}.inspector-intelligence-hud-action:hover{background-color:#4e238c;border-color:#4e238c}.inspector-intelligence-hud-action svg{width:13px;height:13px}.inspector-intelligence-hud-connect-action{min-height:38px;padding:10px 14px;font-size:12px}.inspector-intelligence-hud[data-mode=install] .inspector-intelligence-hud-header{background:linear-gradient(100deg,#fbfaff 0%,#f2eeff 52%,#edfaf5 100%);border-bottom:1px solid #d5d3e4;align-items:center;min-height:76px;padding:18px}.inspector-intelligence-hud[data-mode=install] .inspector-intelligence-hud-heading .inspector-home-section-title{color:#010507;letter-spacing:-.025em;align-items:center;gap:8px;font-size:18px;display:inline-flex}.inspector-intelligence-mark{flex:none;width:17px;height:17px;display:block}.inspector-intelligence-hud[data-mode=install] .inspector-intelligence-hud-header-actions{flex-direction:column;align-items:flex-end;gap:6px}.inspector-intelligence-sr-summary{clip-path:inset(50%);white-space:nowrap;border:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.inspector-intelligence-copy{padding:16px 18px 0;display:grid}.inspector-intelligence-copy-slide{opacity:0;flex-direction:column;grid-area:1/1;gap:4px;transition:opacity .32s cubic-bezier(.22,1,.36,1),transform .38s cubic-bezier(.22,1,.36,1);display:flex}.inspector-intelligence-copy-slide[data-position=after]{transform:translate(14px)}.inspector-intelligence-copy-slide[data-position=before]{transform:translate(-14px)}.inspector-intelligence-copy-slide[data-position=active]{opacity:1;transform:none}.inspector-intelligence-copy-slide>strong{color:#2b2b31;text-wrap:balance;max-width:52ch;font-size:12.5px;font-weight:650;line-height:1.4}.inspector-intelligence-copy-slide>span{color:#4f4f55;max-width:64ch;font-size:11px;line-height:1.55}.inspector-intelligence-install{justify-content:flex-end;align-items:center;gap:12px;display:flex}.inspector-intelligence-install-copy{cursor:pointer;min-height:34px;transition:background-color .14s,border-color .14s}.inspector-intelligence-install-copy svg{width:13px;height:13px}.inspector-intelligence-install[data-copy-state=copied] .inspector-intelligence-install-copy{color:#4e238c;background-color:#fff;border-color:#bba5df}.inspector-intelligence-install-secondary{color:#6430ab;align-items:center;gap:5px;font-size:11px;font-weight:600;text-decoration:none;display:inline-flex}.inspector-intelligence-install-secondary:hover{text-underline-offset:2px;text-decoration:underline}.inspector-intelligence-install-secondary svg{width:12px;height:12px}.inspector-intelligence-install-hint{color:#68686e;white-space:nowrap;margin:0;font-size:11px;font-weight:600;line-height:1.4}.inspector-intelligence-install-hint[data-tone=success]{color:#4e238c;font-weight:600}.inspector-intelligence-install-hint[data-tone=error]{color:#a3341f;font-weight:600}.inspector-intelligence-install-fallback{color:#4f4f55;-webkit-user-select:all;user-select:all;white-space:pre-wrap;word-break:break-word;background-color:#fff;border-bottom:1px solid #d5d3e4;max-height:96px;padding:10px 18px;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:10.5px;line-height:1.65;display:block;overflow:auto}.inspector-intelligence-story{background-color:#fff;container:cpk-intel-story/inline-size}.inspector-intelligence-story-stage{padding:16px 18px;display:grid}.inspector-intelligence-beat{visibility:hidden;opacity:0;grid-area:1/1;align-items:center;transition:opacity .32s cubic-bezier(.22,1,.36,1),transform .38s cubic-bezier(.22,1,.36,1),visibility 0s linear .38s;display:flex}.inspector-intelligence-beat[data-position=after]{transform:translate(14px)}.inspector-intelligence-beat[data-position=before]{transform:translate(-14px)}.inspector-intelligence-beat[data-position=active]{visibility:visible;opacity:1;transition:opacity .32s cubic-bezier(.22,1,.36,1),transform .38s cubic-bezier(.22,1,.36,1),visibility;transform:none}.inspector-intelligence-beat[data-beat-id=threads]{flex-direction:column;justify-content:center;gap:6px}.inspector-intelligence-threads{flex-direction:column;gap:6px;width:100%;display:flex}.inspector-intelligence-thread{opacity:0;background-color:#faf9fe;border:1px solid #e6e3f2;border-radius:4px;align-items:center;gap:9px;padding:8px 10px;transition:opacity .3s,transform .3s;display:flex;transform:translateY(3px)}.inspector-intelligence-thread>i{background-color:#9b8cc4;border-radius:999px;flex:none;width:6px;height:6px}.inspector-intelligence-thread>strong{color:#2b2b31;text-overflow:ellipsis;white-space:nowrap;font-size:11px;font-weight:600;overflow:hidden}.inspector-intelligence-thread>small{color:#68686e;flex:none;margin-left:auto;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:9.5px}.inspector-intelligence-thread[data-failed=true]{background-color:#fdf6f4;border-color:#f0d5cf}.inspector-intelligence-thread[data-failed=true]>i{background-color:#c2410c}.inspector-intelligence-thread[data-failed=true]>strong,.inspector-intelligence-thread[data-failed=true]>small{color:#8f2f1c;font-weight:650}.inspector-intelligence-story[data-beat=threads] .inspector-intelligence-thread{opacity:1;transition-delay:calc(var(--thread-index)*80ms + 90ms);transform:none}.inspector-intelligence-beat[data-beat-id=learning]{grid-template-columns:minmax(0,1.15fr) auto minmax(0,.85fr);align-items:center;gap:12px;display:grid}.inspector-intelligence-beat-col{flex-direction:column;gap:6px;min-width:0;display:flex}.inspector-intelligence-beat-label{color:#68686e;letter-spacing:.06em;text-transform:uppercase;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:9px;font-weight:600}.inspector-intelligence-signal,.inspector-intelligence-rule{color:#4f4f55;opacity:0;background-color:#faf9fe;border:1px solid #e6e3f2;border-radius:4px;align-items:flex-start;gap:6px;padding:6px 8px;font-size:10.5px;line-height:1.4;transition:opacity .3s,transform .3s;display:flex;transform:translateY(3px)}.inspector-intelligence-signal{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.inspector-intelligence-rule{color:#21543f;background-color:#f4fbf8;border-color:#cfe9dd;font-weight:600}.inspector-intelligence-rule>i{color:#1f8a5f;flex:none;align-items:center;display:inline-flex}.inspector-intelligence-rule>i svg{stroke-width:2.4px;width:11px;height:11px}.inspector-intelligence-story[data-beat=learning] .inspector-intelligence-signal,.inspector-intelligence-story[data-beat=learning] .inspector-intelligence-rule{opacity:1;transform:none}.inspector-intelligence-story[data-beat=learning] .inspector-intelligence-signal{transition-delay:calc(var(--signal-index)*80ms + .1s)}.inspector-intelligence-story[data-beat=learning] .inspector-intelligence-rule{transition-delay:calc(var(--rule-index)*80ms + .42s)}.inspector-intelligence-beat-flow{color:#9b8cc4;justify-content:center;align-items:center;display:inline-flex}.inspector-intelligence-beat-flow svg{width:15px;height:15px}.inspector-intelligence-beat[data-beat-id=skill]{justify-content:center}.inspector-intelligence-skill-file{background-color:#fff;border:1px solid #d5d3e4;border-radius:5px;width:min(100%,30rem);overflow:hidden;box-shadow:0 1px 2px #100c280f}.inspector-intelligence-skill-file>header{background-color:#faf9fe;border-bottom:1px solid #ebe9f4;align-items:center;gap:7px;padding:7px 10px;display:flex}.inspector-intelligence-skill-file>header svg{color:#6430ab;width:12px;height:12px}.inspector-intelligence-skill-file>header strong{color:#2b2b31;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:10.5px;font-weight:600}.inspector-intelligence-skill-file>header em{color:#68686e;letter-spacing:.05em;text-transform:uppercase;margin-left:auto;font-size:9px;font-style:normal;font-weight:600}.inspector-intelligence-skill-code{flex-direction:column;padding:8px 0;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:10.5px;line-height:1.75;display:flex}.inspector-intelligence-skill-code>span{color:#4f4f55;gap:10px;padding:0 12px;display:flex}.inspector-intelligence-skill-code>span:before{color:#a9a7bb;content:attr(data-line);text-align:right;min-width:8px}.inspector-intelligence-skill-code>span>b{color:#6430ab;font-weight:600}.inspector-intelligence-skill-code>span[style*=--rule-index]{opacity:0;transition:opacity .26s,transform .26s;transform:translateY(2px)}.inspector-intelligence-story[data-beat=skill] .inspector-intelligence-skill-code>span[style*=--rule-index]{opacity:1;transition-delay:calc(var(--rule-index)*.11s + .26s);transform:none}.inspector-intelligence-beat[data-beat-id=intelligence]{flex-direction:column;justify-content:center;gap:12px}.inspector-intelligence-chain{justify-content:center;align-items:stretch;gap:6px;width:100%;display:flex}.inspector-intelligence-chain-step{opacity:0;background-color:#faf9fe;border:1px solid #e6e3f2;border-radius:5px;flex-direction:column;flex:1 1 0;align-items:flex-start;gap:3px;min-width:0;padding:9px 10px;transition:opacity .28s,transform .28s;display:flex;transform:translateY(4px)}.inspector-intelligence-chain-step>i{color:#6430ab;display:inline-flex}.inspector-intelligence-chain-step>i svg{width:14px;height:14px}.inspector-intelligence-chain-step>strong{color:#2b2b31;font-size:11px;font-weight:700;line-height:1.25}.inspector-intelligence-chain-step>small{color:#68686e;font-size:9.5px;line-height:1.3}.inspector-intelligence-chain-arrow{color:#bba5df;opacity:0;flex:none;align-items:center;transition:opacity .28s;display:inline-flex}.inspector-intelligence-chain-arrow svg{width:13px;height:13px}.inspector-intelligence-story[data-beat=intelligence] .inspector-intelligence-chain-step,.inspector-intelligence-story[data-beat=intelligence] .inspector-intelligence-chain-arrow{opacity:1;transition-delay:calc(var(--step-index)*90ms + 80ms);transform:none}.inspector-intelligence-chain-proof{color:#21543f;opacity:0;background-color:#f4fbf8;border:1px solid #cfe9dd;border-radius:999px;align-self:center;align-items:center;gap:6px;padding:5px 11px;font-size:10.5px;font-weight:600;transition:opacity .3s,transform .3s;display:inline-flex;transform:translateY(3px)}.inspector-intelligence-chain-proof svg{color:#1f8a5f;width:12px;height:12px}.inspector-intelligence-chain-proof code{font-family:Spline Sans Mono,ui-monospace,monospace;font-size:10px;font-weight:600}.inspector-intelligence-story[data-beat=intelligence] .inspector-intelligence-chain-proof{opacity:1;transition-delay:.46s;transform:none}.inspector-intelligence-story-rail{border-top:1px solid #ebe9f4;align-items:center;gap:2px;padding:8px 18px 9px;display:flex}.inspector-intelligence-story-tab{color:#68686e;cursor:pointer;background:0 0;border:0;border-radius:3px;padding:3px 7px 5px;font-family:Plus Jakarta Sans,system-ui,sans-serif;font-size:10.5px;font-weight:600;transition:color .16s;position:relative}.inspector-intelligence-story-tab:after{content:"";transform-origin:0;background-color:#6430ab;border-radius:2px;height:1.5px;transition:transform .28s cubic-bezier(.22,1,.36,1);position:absolute;bottom:1px;left:7px;right:7px;transform:scaleX(0)}.inspector-intelligence-story-tab:hover{color:#2b2b31}.inspector-intelligence-story-tab[data-active=true]{color:#4e238c}.inspector-intelligence-story-tab[data-active=true]:after{transform:scaleX(1)}@container cpk-intel-story (max-width:30rem){.inspector-intelligence-chain-step>small{display:none}.inspector-intelligence-story-rail{flex-wrap:wrap}}@media (prefers-reduced-motion:reduce){.inspector-intelligence-copy-slide,.inspector-intelligence-thread,.inspector-intelligence-beat,.inspector-intelligence-signal,.inspector-intelligence-rule,.inspector-intelligence-chain-step,.inspector-intelligence-chain-arrow,.inspector-intelligence-chain-proof,.inspector-intelligence-skill-code>span[style*=--rule-index],.inspector-intelligence-story-tab:after{transition-duration:0s;transition-delay:0s}}.inspector-intelligence-hud-details{background-color:#d5d3e4;border-top:1px solid #d5d3e4;grid-template-columns:minmax(0,1fr) minmax(0,2fr);gap:1px;display:grid}.inspector-intelligence-hud-details>section{background-color:#fff;min-width:0;padding:15px 18px 17px}.inspector-intelligence-hud-detail-label{color:#68686e;font-size:11px;font-weight:600;display:block}.inspector-intelligence-hud-detail-value{color:#010507;text-overflow:ellipsis;white-space:nowrap;min-width:0;margin:5px 0 0;font-size:14px;font-weight:700;display:block;overflow:hidden}.inspector-intelligence-hud-detail-subvalue{color:#68686e;text-transform:capitalize;margin-top:3px;font-size:10px;font-weight:500;display:block}.inspector-intelligence-hud-plan{grid-template-columns:minmax(0,1fr) minmax(120px,1fr);align-items:start;gap:24px;display:grid}.inspector-intelligence-hud-usage{min-width:0}.inspector-intelligence-hud-plan-action{color:#6430ab;text-underline-offset:3px;background-color:#0000;border:0;border-radius:0;gap:4px;min-height:auto;margin-top:9px;padding:0;font-size:10px;font-weight:700;line-height:1.2;-webkit-text-decoration:underline #0000;text-decoration:underline #0000;text-decoration-thickness:1px}.inspector-intelligence-hud-plan-action:hover{color:#4e238c;background-color:#0000;border-color:#0000;text-decoration-color:currentColor}.inspector-intelligence-hud-plan-action svg{width:11px;height:11px}.inspector-home-usage-bar{background-color:#dbdbe5;border-radius:999px;width:min(160px,100%);height:5px;margin-top:8px;display:block;overflow:hidden}.inspector-home-usage-bar>span{background-color:#bec2ff;height:100%;display:block}.inspector-home-feature-groups{grid-template-columns:repeat(auto-fit,minmax(min(100%,250px),1fr));align-items:start;gap:12px;display:grid}.inspector-home-feature-group{background-color:#fff;border:1px solid #d5d3e4;border-radius:5px;overflow:visible}.inspector-home-feature-group-header{color:#57575b;background-color:#f7f7f9;border-bottom:1px solid #e4e4ec;border-radius:4px 4px 0 0;justify-content:space-between;align-items:center;gap:12px;min-height:40px;padding:9px 12px;display:flex}.inspector-home-feature-group-header strong{font-size:12px;font-weight:700}.inspector-home-feature-group-header>span{background-color:#fff;border-radius:999px;justify-content:center;align-items:center;min-width:22px;min-height:20px;padding:2px 6px;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:10px;font-weight:700;display:inline-flex}.inspector-home-feature-group[data-feature-state-group=active] .inspector-home-feature-group-header{color:#087653;background-color:#e5f7f1;border-color:#b9e3d6}.inspector-home-feature-list{background-color:#fff;flex-direction:column;margin:0;display:flex}.inspector-home-feature{color:#010507;background-color:#fff;grid-template-columns:18px minmax(0,1fr) auto;align-items:center;gap:8px;min-width:0;min-height:52px;padding:9px 12px;font-size:12px;font-weight:600;display:grid;container-type:inline-size}.inspector-home-feature+.inspector-home-feature{border-top:1px solid #ececf1}.inspector-home-feature:last-child{border-radius:0 0 4px 4px}.inspector-home-feature-group-empty{color:#68686e;margin:0;padding:15px 12px;font-size:11px}.inspector-home-feature:hover{background-color:#f7f7f9}.inspector-home-feature-label{min-width:0;color:inherit;cursor:pointer;align-items:center;gap:4px;text-decoration:none;display:inline-flex}.inspector-home-feature-label>span:first-child{text-overflow:ellipsis;white-space:nowrap;min-width:0;overflow:hidden}.inspector-home-feature-label-icon{flex:none;display:inline-flex!important;overflow:visible!important}.inspector-home-feature-label-icon svg{width:12px;height:12px}.inspector-home-feature-label:hover{color:#3f176f;text-underline-offset:3px;text-decoration:underline;text-decoration-thickness:1px}.inspector-home-feature-label:focus-visible{outline-offset:2px;border-radius:3px;outline:2px solid #6430ab}.inspector-home-feature-actions{justify-content:flex-end;align-items:center;gap:6px;display:inline-flex}.inspector-home-feature-status{flex:none;justify-content:center;align-items:center;width:18px;height:28px;display:inline-flex}.inspector-home-feature-status>span{background-color:#fff;border:1px solid #9ca0ab;border-radius:999px;width:8px;height:8px}.inspector-home-feature[data-state=on] .inspector-home-feature-status>span{background-color:#087653;border-color:#087653}.inspector-home-feature[data-state=off]{color:#68686e}.inspector-home-feature-action{color:#4f4f55;min-width:28px;height:28px;min-height:28px;font:inherit;white-space:nowrap;cursor:pointer;background-color:#fff;border:1px solid #d5d3e4;border-radius:4px;justify-content:center;align-items:center;gap:5px;padding:0 8px;font-size:10px;font-weight:700;line-height:1;text-decoration:none;display:inline-flex}.inspector-home-feature-action svg{width:14px;height:14px}.inspector-home-feature-action-icon{flex:none;display:inline-flex!important;overflow:visible!important}.inspector-home-feature-action-label{line-height:1}.inspector-home-feature-action.inspector-system-health-url:after{content:none;left:50%;right:auto;transform:translate(-50%,3px)}.inspector-home-feature-action.inspector-system-health-url:hover:after,.inspector-home-feature-action.inspector-system-health-url:focus-visible:after{transform:translate(-50%)}.inspector-home-feature-action:hover{color:#3f176f;background-color:#f7f4fe;border-color:#bba5df}.inspector-home-feature-action:focus-visible{outline-offset:2px;outline:2px solid #6430ab}.inspector-home-feature-action[data-copy-state=copied]{color:#087653;background-color:#e5f7f1;border-color:#b9e3d6}.inspector-home-feature-action[data-copy-state=error]{color:#b32d3b;background-color:#fff0f1;border-color:#e7a7ac}@container (max-width:286px){.inspector-home-feature-action{width:28px;padding:0}.inspector-home-feature-action-label{display:none!important}.inspector-home-feature-action.inspector-system-health-url:after{content:attr(data-full-value)}}.inspector-home-features-empty{color:#57575b;border-top:1px solid #deddea;border-bottom:1px solid #deddea;margin:14px 0 0;padding:16px 0;font-size:12px}.inspector-home-news{gap:12px;display:grid}.inspector-whats-new-preview{color:#010507;background-color:#f7f4fe;border:1px solid #c8c6e6;border-radius:5px;align-items:stretch;width:100%;min-height:64px;display:flex;position:relative;overflow:hidden;container-type:inline-size}.inspector-whats-new-preview:has(.inspector-whats-new-preview-body:hover){background-color:#f1ebfc;border-color:#8f91d7}.inspector-whats-new-preview-body{min-width:0;color:inherit;text-align:left;cursor:pointer;background-color:#0000;border:0;flex:auto;grid-template-columns:minmax(0,1fr) auto;align-items:center;gap:12px;padding:12px 14px;display:grid}.inspector-whats-new-preview-copy{flex-direction:column;gap:3px;min-width:0;display:flex}.inspector-whats-new-preview-title{align-items:center;gap:8px;min-width:0;display:flex}.inspector-whats-new-preview-copy strong{text-overflow:ellipsis;white-space:nowrap;font-family:Plus Jakarta Sans,system-ui,sans-serif;font-size:13px;line-height:1.25;overflow:hidden}.inspector-whats-new-preview-copy>span:last-child{color:#4e4c63;text-overflow:ellipsis;white-space:nowrap;font-size:11px;line-height:1.4;overflow:hidden}.inspector-whats-new-preview-action{color:#3f176f;white-space:nowrap;flex:none;align-items:center;gap:6px;font-size:11px;font-weight:700;display:inline-flex}.inspector-whats-new-preview-action svg{width:15px;height:15px}@container (max-width:640px){.inspector-whats-new-preview-body{grid-template-columns:minmax(0,1fr)}.inspector-whats-new-preview-action{display:none}}.inspector-whats-new-preview-dismiss{color:#68686e;cursor:pointer;background-color:#0000;border:0;border-radius:5px;justify-content:center;align-items:center;width:28px;height:28px;display:inline-flex;position:absolute;top:50%;right:12px;transform:translateY(-50%)}.inspector-whats-new-preview-dismiss:hover{color:#3f176f;background-color:#6430ab1a}.inspector-whats-new-preview-dismiss svg{width:14px;height:14px}@media (max-width:720px){.inspector-account-cta{width:32px;padding-inline:0}.inspector-account-cta-label{display:none}.inspector-home{padding:24px 22px 34px}.inspector-intelligence-hud-header{flex-wrap:wrap}.inspector-intelligence-hud-details{grid-template-columns:1fr}.inspector-intelligence-hud-plan{grid-template-columns:repeat(2,minmax(0,1fr))}.inspector-whats-new-preview-action{display:none}}@media (max-width:600px){.inspector-system-health{grid-template-columns:1fr}}@media (max-width:480px){.inspector-home-feature{grid-template-columns:18px minmax(0,1fr);gap:8px}.inspector-home-feature-actions{grid-column:1/-1;justify-content:flex-end}.inspector-system-health-section .inspector-system-health-header{align-items:flex-start}.inspector-intelligence-hud-header{flex-direction:column;align-items:stretch}.inspector-intelligence-hud-header-actions{justify-content:space-between}.inspector-intelligence-hud-header-actions .inspector-intelligence-hud-action,.inspector-intelligence-hud-plan{width:100%}.inspector-intelligence-hud-plan{grid-template-columns:1fr;align-items:stretch}.inspector-intelligence-hud-plan-action{justify-self:start}.inspector-whats-new-header{align-items:center;gap:16px;width:calc(100% - 24px);padding:24px 22px}.inspector-whats-new-document,.inspector-whats-new-empty{padding:20px 22px 36px}.inspector-whats-new-document .announcement-content h1+p{font-size:16px}}.inspector-whats-new-header{background:#f8f7ff;border:1px solid #d8d8e8;border-radius:5px;justify-content:space-between;align-items:center;gap:24px;width:calc(100% - 44px);max-width:calc(70ch - 44px);padding:30px 32px 28px;display:flex;box-shadow:0 12px 28px #26224e0f}.inspector-whats-new-header .inspector-home-title{letter-spacing:-.035em;margin:0;font-size:clamp(27px,3.6vw,36px)}.inspector-whats-new-updated{color:#6c687c;letter-spacing:.01em;white-space:nowrap;flex:none;margin:0;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:11px;font-weight:600}.inspector-whats-new .inspector-home-news{max-width:70ch;margin-top:0}.inspector-whats-new-document,.inspector-whats-new-empty{max-width:70ch;padding:22px 32px 52px}.inspector-whats-new-document .announcement-content{color:#2b2b39;font-size:15px;line-height:1.72}.inspector-whats-new-document .announcement-content h1{color:#15131d;letter-spacing:-.032em;max-width:24ch;margin:0 0 16px;font-size:clamp(26px,3.2vw,34px);line-height:1.1}.inspector-whats-new-document .announcement-content h1+p{color:#504d61;max-width:58ch;margin-top:0;font-size:18px;line-height:1.58}.inspector-whats-new-document .announcement-content>hr:first-child{display:none}.inspector-whats-new-document .announcement-content h2:first-of-type{border-top:0;margin-top:14px;padding-top:0}.inspector-whats-new-document .announcement-content h2{color:#1b1924;letter-spacing:-.024em;border-top:1px solid #dfdeea;margin:44px 0 14px;padding-top:24px;font-size:21px;line-height:1.2}.inspector-whats-new-document .announcement-content p{max-width:70ch;margin:.85rem 0}.inspector-whats-new-document .announcement-content ul,.inspector-whats-new-document .announcement-content ol{max-width:68ch;margin:1.25rem 0 1.5rem;padding-left:1.4rem}.inspector-whats-new-document .announcement-content li+li{margin-top:.7rem}.inspector-whats-new-document .announcement-content a{color:#4e46a5;text-underline-offset:4px;font-weight:600;text-decoration-color:#4e46a56b;text-decoration-thickness:1px;transition:color .16s,text-decoration-color .16s}.inspector-whats-new-document .announcement-content a:hover{color:#312879;text-decoration-color:currentColor}.inspector-whats-new-empty{color:#5e5b70}.inspector-whats-new-empty .inspector-home-card-title{color:#1b1924;margin:0}.inspector-whats-new-empty .inspector-home-card-copy{max-width:48ch;margin:8px 0 0}.inspector-home-story-featured{padding:22px}.inspector-home-story-link{color:inherit;cursor:pointer;text-decoration:none;display:block}.inspector-home-story-link:hover{background-color:#fff;border-color:#8f91d7}.inspector-home-story[data-unread=true]{border-color:#bec2ff;padding-right:64px;box-shadow:0 0 0 1px #6430ab}.inspector-home-story-unread{color:#fff;letter-spacing:.04em;text-transform:uppercase;background-color:#6430ab;border-radius:999px;align-items:center;min-height:18px;padding:0 7px;font-family:Spline Sans Mono,ui-monospace,monospace;font-size:10px;font-weight:700;display:inline-flex}.inspector-nav-label{text-overflow:ellipsis;white-space:nowrap;min-width:0;transition:opacity .18s,width .22s;overflow:hidden}.inspector-nav-control{color:#57575b;min-height:32px;font:inherit;text-align:left;outline-offset:-2px;cursor:pointer;background-color:#0000;border:1px solid #0000;border-radius:5px;outline:2px solid #0000;flex:none;justify-content:flex-start;align-items:center;gap:6px;padding:6px 9px;font-size:12px;font-weight:600;line-height:1.25;display:flex}.inspector-nav-control:hover{color:#010507;background-color:#f0f0f4}.inspector-nav-control-active{color:#3f176f;background-color:#eee6fe;border-color:#bec2ff}.inspector-nav-icon{flex:none;align-items:center;display:inline-flex}.inspector-nav-icon svg{width:15px;height:15px}.inspector-nav-control:focus-visible,.inspector-account-control:focus-visible,[data-inspector-thread-cta]:focus-visible,[data-inspector-sidebar-intelligence-action]:focus-visible,[data-inspector-whats-new-preview]:focus-visible,[data-inspector-whats-new-dismiss]:focus-visible,[data-inspector-home-intelligence-action]:focus-visible,.inspector-home-feature:focus-visible,[data-inspector-action-placement=threads-footer]:focus-visible{outline-offset:2px;outline:2px solid #6430ab!important}.inspector-sidebar .inspector-nav-control:focus-visible,.inspector-sidebar .inspector-sidebar-label:focus-visible,.inspector-sidebar [data-inspector-thread-cta]:focus-visible{outline-offset:-2px!important}.inspector-account-control{color:#57575b;font:inherit;outline-offset:2px;cursor:pointer;background-color:#0000;border:1px solid #0000;outline:2px solid #0000;justify-content:center;align-items:center;padding:0;display:inline-flex}.inspector-account-control:hover,.inspector-account-control-active{color:#3f176f;background-color:#6430ab17}:host ::selection{color:#010507;background-color:#cfd2ff}:host *{scrollbar-color:#aaa9c1 transparent;scrollbar-width:thin}:host ::-webkit-scrollbar{width:8px;height:8px}:host ::-webkit-scrollbar-thumb{background:#aaa9c1 padding-box padding-box;border:2px solid #0000;border-radius:999px}.inspector-account-control-icon{flex:none;justify-content:center;align-items:center;display:inline-flex}.inspector-account-control-icon svg{width:15px;height:15px}[data-inspector-thread-cta],[data-inspector-account-strip] button,[data-inspector-account-strip] a{cursor:pointer}@media (prefers-reduced-motion:reduce){.inspector-sidebar,.inspector-nav-label,.inspector-sidebar[data-icon-rail=true] .inspector-agent-selector>[data-context-dropdown-root=true]>button{transition:none}.inspector-icon-rail-menu{transition:none;animation:none}}.inspector-threads-footer{color:#57575b;background-color:#f7f7f9;border-top:1px solid #dbdbe5;flex:none;gap:10px;padding:12px;font-size:11px;line-height:1.35;display:grid}.inspector-threads-usage{gap:6px;display:grid}[data-inspector-thread-count]{color:#010507;font-weight:600}[data-inspector-thread-expiry]{color:#57575b}.inspector-thread-progress{--inspector-thread-progress-color:#189370;width:100%;height:6px;accent-color:var(--inspector-thread-progress-color);border-radius:999px;overflow:hidden}.inspector-thread-progress[data-inspector-thread-capacity=warning]{--inspector-thread-progress-color:#b45309}.inspector-thread-progress[data-inspector-thread-capacity=critical]{--inspector-thread-progress-color:#be123c}.inspector-thread-progress::-webkit-progress-bar{background-color:#dbdbe5;border-radius:999px}.inspector-thread-progress::-webkit-progress-value{background-color:var(--inspector-thread-progress-color);border-radius:999px}.inspector-thread-progress::-moz-progress-bar{background-color:var(--inspector-thread-progress-color);border-radius:999px}[data-inspector-action-placement=threads-footer]{color:#57575b;outline-offset:2px;cursor:pointer;background-color:#0000;border:1px solid #d5d3e4;border-radius:5px;outline:2px solid #0000;justify-content:center;align-items:center;width:100%;min-height:32px;padding:6px 9px;font-size:11px;font-weight:600;line-height:1.25;text-decoration:none;display:inline-flex}[data-inspector-action-placement=threads-footer][data-inspector-action-intent=upgrade]{color:#fff;background-color:#6430ab;border-color:#6430ab}[data-inspector-action-placement=threads-footer][data-inspector-action-intent=upgrade]:hover{color:#fff;background-color:#3f176f;border-color:#3f176f}[data-inspector-action-placement=threads-footer]:hover{color:#010507;background-color:#f7f4fe;border-color:#c8c6e6}.cpk-threads-overview-video{opacity:0;transition:opacity .22s}.cpk-threads-overview{background-color:#f7f7f9;flex:1;justify-content:center;align-items:center;min-width:0;padding:32px;display:flex}.cpk-threads-overview-content{color:#57575b;width:100%;max-width:440px}.cpk-locked-feature{box-sizing:border-box;background:#fff;align-items:flex-start;width:100%;min-height:100%;padding:52px 24px 56px;display:flex;position:relative;overflow:auto;container:cpk-locked-feature/inline-size}.cpk-locked-feature-layout{box-sizing:border-box;width:100%;min-width:0;max-width:600px;margin:0 auto}.cpk-locked-feature-hero{box-sizing:border-box;grid-template-columns:minmax(0,1fr);gap:36px;width:100%;min-width:0;margin:0 auto;display:grid}.cpk-locked-feature-copy{color:#57575b;min-width:0}.cpk-locked-feature-name{color:#5558b2;letter-spacing:.08em;text-transform:uppercase;align-items:center;gap:8px;margin-bottom:20px;font-size:11px;font-weight:700;line-height:1.25;display:inline-flex}.cpk-locked-feature-icon{width:15px;height:15px;color:inherit;flex:none;justify-content:center;align-items:center;display:inline-flex}.cpk-locked-feature-icon svg{width:15px;height:15px;display:block}.cpk-locked-feature-title{color:#010507;letter-spacing:-.025em;max-width:680px;margin:0 0 18px;font-size:clamp(25px,2.6vw,34px);font-weight:600;line-height:1.08}.cpk-locked-feature-description{color:#57575b;max-width:680px;margin:0 0 28px;font-size:14px;line-height:1.6}.cpk-locked-feature-media{justify-self:stretch;width:100%;min-width:0}.cpk-threads-overview-video-frame.cpk-locked-feature-video{background:#000;border-color:#e4e4ec;border-radius:12px;width:100%;min-width:0;max-width:none;margin:0;box-shadow:0 14px 32px #2c2b441f}.cpk-locked-feature-outline{box-sizing:border-box;width:100%;max-width:none;margin:40px 0 0}.cpk-locked-feature-outline-list{margin:0;display:block}.cpk-locked-feature-outline-item{min-width:0;padding:0 0 28px;display:block}.cpk-locked-feature-outline-item+.cpk-locked-feature-outline-item{border-top:1px solid #e4e4ec;padding-top:28px}.cpk-locked-feature-outline-item h3,.cpk-locked-feature-outline-item p{margin:0}.cpk-locked-feature-outline-item h3{color:#010507;letter-spacing:-.018em;align-items:center;gap:10px;margin-bottom:10px;font-size:20px;font-weight:600;line-height:1.25;display:flex}.cpk-locked-feature-outline-icon{color:#5558b2;flex:0 0 20px;justify-content:center;align-items:center;width:20px;height:20px;display:inline-flex}.cpk-locked-feature-outline-icon svg{width:18px;height:18px}.cpk-locked-feature-outline-item p{color:#57575b;max-width:68ch;font-size:15px;line-height:1.65}.cpk-threads-overview-title{color:#010507;margin:0 0 10px;font-size:20px;font-weight:600;line-height:1.25}.cpk-threads-overview-copy{color:#57575b;margin:0 0 16px;font-size:13px;line-height:1.55}.cpk-threads-overview-actions{flex-wrap:wrap;align-items:center;gap:10px;display:flex}.cpk-locked-feature .cpk-locked-feature-setup-cta,.cpk-locked-feature .cpk-threads-overview-action{box-sizing:border-box;align-items:center;height:44px;min-height:44px;padding:12px 16px;font-size:13px;font-weight:700;line-height:1}.cpk-threads-overview-action{outline-offset:2px;cursor:pointer;border:1px solid #0000;border-radius:7px;outline:2px solid #0000;justify-content:center;align-items:center;gap:6px;min-height:34px;padding:8px 12px;font-size:12px;font-weight:600;line-height:1.25;text-decoration:none;display:inline-flex}[data-inspector-feature-setup-prompt][data-copy-state=copied]{color:#fff;background-color:#087653;border-color:#087653}[data-inspector-feature-setup-prompt][data-copy-state=error]{color:#fff;background-color:#b32d3b;border-color:#b32d3b}[data-inspector-feature-setup-prompt]:focus-visible{outline-offset:2px;outline:2px solid #6430ab}.cpk-threads-overview-action-primary{color:#fff;background-color:#010507;border-color:#010507}.cpk-threads-overview-action-primary:hover{background-color:#2b2b2b;border-color:#2b2b2b}.cpk-threads-overview-action-secondary{color:#010507;background-color:#fff;border-color:#dbdbe5}.cpk-threads-overview-action-secondary:hover{background-color:#fff;border-color:#afafb7}.cpk-threads-overview-video[data-loaded=true]{opacity:1}.cpk-threads-overview-video-control{color:#3f176f;min-height:32px;font:inherit;outline-offset:2px;cursor:pointer;background-color:#fff;border:1px solid #dbdbe5;border-radius:5px;outline:2px solid #0000;justify-content:center;align-items:center;margin:0 0 14px;padding:6px 10px;font-size:12px;font-weight:600;line-height:1.25;display:inline-flex}.cpk-threads-overview-video-control:hover{color:#010507;background-color:#f7f7f9;border-color:#afafb7}.cpk-threads-overview-video-control:focus-visible{outline-offset:2px;outline:2px solid #6430ab}.cpk-threads-overview-video-fallback{color:#57575b;max-width:440px;margin:-4px 0 14px;font-size:12px;line-height:1.5}.cpk-threads-tour-launch{z-index:2;color:#57575b;outline-offset:2px;cursor:pointer;background-color:#fff;border:1px solid #dbdbe5;border-radius:7px;outline:2px solid #0000;padding:7px 10px;font-size:12px;font-weight:600;position:absolute;bottom:16px;right:16px;box-shadow:0 8px 18px #01050714}.cpk-threads-tour{z-index:3;color:#57575b;background-color:#fff;border:1px solid #dbdbe5;border-radius:10px;width:min(340px,100% - 32px);padding:14px;position:absolute;bottom:16px;right:16px;box-shadow:0 16px 36px #01050724}.cpk-threads-tour-step{color:#087653;text-transform:uppercase;margin-bottom:8px;font-family:Spline Sans Mono,monospace;font-size:10px;font-weight:600}.cpk-threads-tour-title{color:#010507;margin-bottom:6px;font-size:14px;font-weight:600;line-height:1.35}.cpk-threads-tour-copy{color:#57575b;font-size:12px;line-height:1.5}.cpk-threads-tour-actions{justify-content:space-between;gap:8px;margin-top:14px;display:flex}.cpk-threads-tour-nav{gap:8px;display:flex}.cpk-threads-tour-skip,.cpk-threads-tour-button{font:inherit;outline-offset:2px;cursor:pointer;border-radius:7px;outline:2px solid #0000;padding:7px 10px;font-size:12px;font-weight:600}.cpk-threads-overview-action:focus-visible,.cpk-threads-tour-launch:focus-visible,.cpk-threads-tour-skip:focus-visible,.cpk-threads-tour-button:focus-visible{outline-color:#6430ab}.cpk-threads-tour-skip{color:#68686e;background-color:#0000;border:0;padding-inline:0}.cpk-threads-tour-button-secondary{color:#57575b;background-color:#fff;border:1px solid #dbdbe5}.cpk-threads-tour-button-primary{color:#fff;background-color:#010507;border:1px solid #010507}.cpk-threads-tour-button:disabled{cursor:not-allowed;opacity:.45}@container cpk-locked-feature (max-width:440px){.cpk-locked-feature .cpk-threads-overview-actions{flex-direction:column;align-items:stretch}.cpk-locked-feature .cpk-locked-feature-setup-cta,.cpk-locked-feature .cpk-threads-overview-action{width:100%}}@media (max-width:720px){.cpk-threads-overview{padding:24px}}@media (prefers-reduced-motion:reduce){.cpk-threads-overview-video{transition:none}}.inspector-window[data-color-scheme=dark]{color-scheme:dark;background-color:var(--cpk-inspector-surface-dark)!important;color:#f3f4f8!important;border-color:#7b7d89!important}.inspector-window[data-color-scheme=dark] .inspector-shell,.inspector-window[data-color-scheme=dark] .inspector-main,.inspector-window[data-color-scheme=dark] #cpk-main-scroll{color:#f3f4f8!important;background-color:#111319!important}.inspector-window[data-color-scheme=dark] .resize-handle,.inspector-window[data-color-scheme=dark] .edge-resize-handle,.inspector-window[data-color-scheme=dark] .dock-resize-handle{background:0 0!important}.inspector-window[data-color-scheme=dark] .drag-handle,.inspector-window[data-color-scheme=dark] .inspector-account-strip{color:#f3f4f8!important;background:#15171e!important;border-color:#3a3d49!important}.inspector-window[data-color-scheme=dark] .inspector-account-logo{filter:brightness(0)invert();clip-path:inset(0 20% 0 0)}.inspector-window[data-color-scheme=dark] .inspector-account-logo-accent{filter:none;display:block}.inspector-window[data-color-scheme=dark] .inspector-agent-placeholder{color:#b8bbc7!important;border-color:#3a3d49!important}.inspector-window[data-color-scheme=dark] .inspector-account-control{color:#b8bbc7!important;border:0!important}.inspector-window[data-color-scheme=dark] .inspector-account-control:hover,.inspector-window[data-color-scheme=dark] .inspector-account-control-active{color:#d8d9ff!important;background-color:#292c38!important}.inspector-window[data-color-scheme=dark] .inspector-account-cta{color:#d8d9ff;background-color:#292b43}.inspector-window[data-color-scheme=dark] .inspector-account-cta:hover{color:#fff;background-color:#353854}.inspector-window[data-color-scheme=dark] .inspector-window-layout-menu{box-shadow:0 12px 28px #00000052;color:#f3f4f8!important;background-color:#111319!important;border-color:#5c6173!important}.inspector-window[data-color-scheme=dark] .inspector-window-layout-menu button,.inspector-window[data-color-scheme=dark] .inspector-window-layout-menu button span{color:#f3f4f8!important}.inspector-window[data-color-scheme=dark] .inspector-window-layout-menu button:hover,.inspector-window[data-color-scheme=dark] .inspector-window-layout-menu button:focus-visible,.inspector-window[data-color-scheme=dark] .inspector-window-layout-menu button:hover span,.inspector-window[data-color-scheme=dark] .inspector-window-layout-menu button:focus-visible span{color:#fff!important;background-color:#3a3f52!important}.inspector-window[data-color-scheme=dark] .inspector-sidebar .inspector-agent-selector>[data-context-dropdown-root=true]>button{color:#f3f4f8!important;background-color:#20232c!important;border-color:#464957!important}.inspector-window[data-color-scheme=dark] .inspector-sidebar .inspector-agent-selector>[data-context-dropdown-root=true]>button:hover{background-color:#292c38!important;border-color:#777aae!important}.inspector-window[data-color-scheme=dark] .inspector-sidebar .inspector-agent-selector>[data-context-dropdown-root=true]>button>span:last-child{color:#aeb1bd!important}.inspector-window[data-color-scheme=dark] .inspector-context-dropdown-icon{color:#f3f4f8!important}.inspector-window[data-color-scheme=dark] .inspector-sidebar[data-icon-rail=true] .inspector-agent-selector>[data-context-dropdown-root=true]>button{color:#fff!important;background-color:#2f3340!important;border-color:#8b90a5!important}.inspector-window[data-color-scheme=dark] .inspector-sidebar[data-icon-rail=true] .inspector-context-dropdown-icon,.inspector-window[data-color-scheme=dark] .inspector-sidebar[data-icon-rail=true] .inspector-agent-placeholder{color:#fff!important}.inspector-window[data-color-scheme=dark] [data-context-dropdown-root=true]>div{color:#f3f4f8!important;box-shadow:none!important;background-color:#191c24!important;border-color:#464957!important}.inspector-window[data-color-scheme=dark] [data-context-dropdown-root=true]>div button:hover,.inspector-window[data-color-scheme=dark] [data-context-dropdown-root=true]>div button:focus{color:#f3f4f8!important;background-color:#343746!important}.inspector-window[data-color-scheme=dark] .inspector-sidebar{color:#f3f4f8;background-color:#15171e;border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-sidebar-label{color:#8f93a1}.inspector-window[data-color-scheme=dark] .inspector-sidebar-rail-tooltip{color:#191c24;background-color:#e9e9f1;box-shadow:0 7px 18px #00000047}.inspector-window[data-color-scheme=dark] .inspector-nav-control,.inspector-window[data-color-scheme=dark] .inspector-sidebar-toggle{color:#b8bbc7}.inspector-window[data-color-scheme=dark] .inspector-nav-control:hover,.inspector-window[data-color-scheme=dark] .inspector-sidebar-toggle:hover{color:#fff;background-color:#22252f}.inspector-window[data-color-scheme=dark] .inspector-nav-control-active{color:#d8d9ff;background-color:#292b43;border-color:#666a9e}.inspector-window[data-color-scheme=dark] .inspector-sidebar-agent-scope{border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-sidebar-status-card{background-color:#191c24;border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-sidebar-status-copy strong{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-sidebar-status-copy>span,.inspector-window[data-color-scheme=dark] .inspector-sidebar-status-card[data-state=disconnected] .inspector-sidebar-status-copy>span{color:#9da1af}.inspector-window[data-color-scheme=dark] .inspector-sidebar-status-action{color:#caccff}.inspector-window[data-color-scheme=dark] .inspector-sidebar-status-action:hover{color:#fff;background-color:#292b43}.inspector-window[data-color-scheme=dark] .inspector-sidebar-intelligence-setup{color:#d8d9ff;background-color:#292b43;border-color:#666a9e}.inspector-window[data-color-scheme=dark] .inspector-sidebar-intelligence-setup:hover{background-color:#343653;border-color:#777aae}.inspector-window[data-color-scheme=dark] .inspector-sidebar-intelligence-setup .inspector-sidebar-status-copy strong{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-sidebar-setup-arrow{background-color:#caccff1f}@media (prefers-reduced-motion:reduce){.inspector-sidebar-intelligence-setup{animation:none}}.inspector-window[data-color-scheme=dark] .inspector-home{background-color:#111319}.inspector-window[data-color-scheme=dark] .inspector-settings{color:#f3f4f8;background-color:#111319}.inspector-window[data-color-scheme=dark] .inspector-settings-header,.inspector-window[data-color-scheme=dark] .inspector-settings-section,.inspector-window[data-color-scheme=dark] .inspector-settings-privacy,.inspector-window[data-color-scheme=dark] .inspector-settings-visibility,.inspector-window[data-color-scheme=dark] .inspector-settings-private-content{border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-settings-title,.inspector-window[data-color-scheme=dark] .inspector-settings-section-heading h2,.inspector-window[data-color-scheme=dark] .inspector-settings-status-row h3,.inspector-window[data-color-scheme=dark] .inspector-settings-visibility h3,.inspector-window[data-color-scheme=dark] .inspector-settings-private-content strong{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-settings-subtitle,.inspector-window[data-color-scheme=dark] .inspector-settings-section-heading p,.inspector-window[data-color-scheme=dark] .inspector-settings-status-row p,.inspector-window[data-color-scheme=dark] .inspector-settings-visibility p,.inspector-window[data-color-scheme=dark] .inspector-settings-private-content>p{color:#aeb1bd}.inspector-window[data-color-scheme=dark] .inspector-settings-section-icon{color:#d8d9ff;background-color:#292b43;border-color:#666a9e}.inspector-window[data-color-scheme=dark] .inspector-settings-private-content li{color:#c9ccd6}.inspector-window[data-color-scheme=dark] .inspector-settings-private-content li span{color:#75d8b9}.inspector-window[data-color-scheme=dark] .inspector-settings-status{color:#8ce1c5;background-color:#173b32;border-color:#347d69}.inspector-window[data-color-scheme=dark] .inspector-settings-privacy[data-state=disabled] .inspector-settings-status{color:#f2cf8f;background-color:#342916;border-color:#866932}.inspector-window[data-color-scheme=dark] .inspector-settings-policy-link{color:#caccff}.inspector-window[data-color-scheme=dark] .inspector-settings-policy-link:hover{color:#fff}.inspector-window[data-color-scheme=dark] .inspector-settings-dismiss{color:#ded7ff;background-color:#272438;border-color:#5d5975}.inspector-window[data-color-scheme=dark] .inspector-settings-dismiss:hover{background-color:#322e47;border-color:#8179a7}.inspector-window[data-color-scheme=dark] .inspector-settings-dismiss:focus-visible{outline-color:#bec2ff}.inspector-window[data-color-scheme=dark] .inspector-home-card,.inspector-window[data-color-scheme=dark] .inspector-home-story,.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud,.inspector-window[data-color-scheme=dark] .inspector-home-feature-list,.inspector-window[data-color-scheme=dark] .inspector-whats-new-preview{color:#f3f4f8;background:#191c24;border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud[data-state=disconnected]{background-color:#1d1e2b;border-color:#666a9e}.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud[data-state=disconnected] .inspector-intelligence-hud-description{color:#c5c7d0}.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud[data-mode=install] .inspector-intelligence-hud-header{background:linear-gradient(100deg,#1d1e2b 0%,#221f31 54%,#1a2523 100%);border-bottom-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud[data-mode=install] .inspector-intelligence-hud-heading .inspector-home-section-title{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-intelligence-install-hint{color:#aeb1bd}.inspector-window[data-color-scheme=dark] .inspector-intelligence-install-hint[data-tone=success]{color:#d5cbff}.inspector-window[data-color-scheme=dark] .inspector-intelligence-install-hint[data-tone=error]{color:#ffb3a1}.inspector-window[data-color-scheme=dark] .inspector-intelligence-install[data-copy-state=copied] .inspector-intelligence-install-copy{color:#d5cbff;background-color:#0000;border-color:#666a9e}.inspector-window[data-color-scheme=dark] .inspector-intelligence-install-secondary{color:#caccff}.inspector-window[data-color-scheme=dark] .inspector-intelligence-install-fallback{color:#c5c7d0;background-color:#15171e;border-bottom-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-intelligence-story{background-color:#15171e}.inspector-window[data-color-scheme=dark] .inspector-intelligence-beat-label,.inspector-window[data-color-scheme=dark] .inspector-intelligence-chain-step>small,.inspector-window[data-color-scheme=dark] .inspector-intelligence-thread>small,.inspector-window[data-color-scheme=dark] .inspector-intelligence-skill-file>header em{color:#8f93a1}.inspector-window[data-color-scheme=dark] .inspector-intelligence-copy-slide>strong{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-intelligence-copy-slide>span{color:#c5c7d0}.inspector-window[data-color-scheme=dark] .inspector-intelligence-thread{background-color:#1c1f2b;border-color:#33364a}.inspector-window[data-color-scheme=dark] .inspector-intelligence-thread>strong{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-intelligence-thread>i{background-color:#666a9e}.inspector-window[data-color-scheme=dark] .inspector-intelligence-thread[data-failed=true]{background-color:#2a1a16;border-color:#5a3129}.inspector-window[data-color-scheme=dark] .inspector-intelligence-thread[data-failed=true]>i{background-color:#f97316}.inspector-window[data-color-scheme=dark] .inspector-intelligence-thread[data-failed=true]>strong,.inspector-window[data-color-scheme=dark] .inspector-intelligence-thread[data-failed=true]>small{color:#ffb3a1}.inspector-window[data-color-scheme=dark] .inspector-intelligence-signal{color:#c5c7d0;background-color:#1c1f2b;border-color:#33364a}.inspector-window[data-color-scheme=dark] .inspector-intelligence-rule,.inspector-window[data-color-scheme=dark] .inspector-intelligence-chain-proof{color:#8fd9b8;background-color:#16241f;border-color:#2f5748}.inspector-window[data-color-scheme=dark] .inspector-intelligence-rule>i,.inspector-window[data-color-scheme=dark] .inspector-intelligence-chain-proof svg{color:#5be4bb}.inspector-window[data-color-scheme=dark] .inspector-intelligence-beat-flow{color:#666a9e}.inspector-window[data-color-scheme=dark] .inspector-intelligence-skill-file{box-shadow:none;background-color:#191c24;border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-intelligence-skill-file>header{background-color:#1c1f2b;border-bottom-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-intelligence-skill-file>header strong{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-intelligence-skill-file>header svg,.inspector-window[data-color-scheme=dark] .inspector-intelligence-skill-code>span>b,.inspector-window[data-color-scheme=dark] .inspector-intelligence-chain-step>i{color:#caccff}.inspector-window[data-color-scheme=dark] .inspector-intelligence-skill-code>span{color:#c5c7d0}.inspector-window[data-color-scheme=dark] .inspector-intelligence-skill-code>span:before{color:#6d7180}.inspector-window[data-color-scheme=dark] .inspector-intelligence-chain-step{background-color:#1c1f2b;border-color:#33364a}.inspector-window[data-color-scheme=dark] .inspector-intelligence-chain-step>strong{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-intelligence-chain-arrow{color:#666a9e}.inspector-window[data-color-scheme=dark] .inspector-intelligence-story-rail{border-top-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-intelligence-story-tab{color:#8f93a1}.inspector-window[data-color-scheme=dark] .inspector-intelligence-story-tab:hover{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-intelligence-story-tab[data-active=true]{color:#d5cbff}.inspector-window[data-color-scheme=dark] .inspector-intelligence-story-tab:after{background-color:#a78bfa}.inspector-window[data-color-scheme=dark] .inspector-system-health,.inspector-window[data-color-scheme=dark] .inspector-system-health-section{border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-system-health-section{background-color:#191c24}.inspector-window[data-color-scheme=dark] .inspector-system-health-section .inspector-system-health-header{background-color:#191c24;border-bottom-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-system-health{background-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-system-health-signal{background-color:#191c24}.inspector-window[data-color-scheme=dark] .inspector-system-health-event-link>small{color:#caccff}.inspector-window[data-color-scheme=dark] .inspector-system-health-header>span[data-tone=success]{color:#8ce1c5}.inspector-window[data-color-scheme=dark] .inspector-system-health-state[data-tone=success],.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-state[data-tone=success]{background-color:#173b32;border-color:#347d69;color:#8ce1c5!important}.inspector-window[data-color-scheme=dark] .inspector-system-health-state[data-tone=checking],.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-state[data-tone=checking]{background-color:#342916;border-color:#866932;color:#f2cf8f!important}.inspector-window[data-color-scheme=dark] .inspector-system-health-state[data-tone=offline],.inspector-window[data-color-scheme=dark] .inspector-system-health-state[data-tone=error],.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-state[data-tone=offline],.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-state[data-tone=error]{background-color:#3b1c22;border-color:#87424a;color:#ff9aa0!important}.inspector-window[data-color-scheme=dark] .inspector-system-health-state[data-tone=unavailable],.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-state[data-tone=unavailable]{background-color:#242731;border-color:#464957;color:#aeb1bd!important}.inspector-window[data-color-scheme=dark] .inspector-system-health-header>span[data-tone=checking]{color:#f2cf8f}.inspector-window[data-color-scheme=dark] .inspector-system-health-header>span[data-tone=offline],.inspector-window[data-color-scheme=dark] .inspector-system-health-header>span[data-tone=error]{color:#ff9aa0}.inspector-window[data-color-scheme=dark] .inspector-home-story-link:hover,.inspector-window[data-color-scheme=dark] .inspector-whats-new-preview:has(.inspector-whats-new-preview-body:hover){background:#242131;border-color:#777aae}.inspector-window[data-color-scheme=dark] .inspector-home-title,.inspector-window[data-color-scheme=dark] .inspector-home-section-title,.inspector-window[data-color-scheme=dark] .inspector-home-card-title,.inspector-window[data-color-scheme=dark] .inspector-system-health-signal dd,.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-details .inspector-intelligence-hud-detail-value,.inspector-window[data-color-scheme=dark] .inspector-home-feature{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-home-eyebrow,.inspector-window[data-color-scheme=dark] .inspector-home-card-label,.inspector-window[data-color-scheme=dark] .inspector-home-meta,.inspector-window[data-color-scheme=dark] .inspector-home-body,.inspector-window[data-color-scheme=dark] .inspector-home-card-copy,.inspector-window[data-color-scheme=dark] .inspector-system-health-signal dt,.inspector-window[data-color-scheme=dark] .inspector-system-health-signal small,.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-heading p,.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-details .inspector-intelligence-hud-detail-label,.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-details .inspector-intelligence-hud-detail-subvalue,.inspector-window[data-color-scheme=dark] .inspector-home-section-header>span,.inspector-window[data-color-scheme=dark] .inspector-whats-new-preview-copy>span:last-child{color:#aeb1bd}.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-details{background-color:#3a3d49;border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-details>section{background-color:#15171e}.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-plan-action{color:#caccff}.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-plan-action:hover{color:#fff;background-color:#0000;border-color:#0000}.inspector-window[data-color-scheme=dark] .inspector-system-health-signal+.inspector-system-health-signal,.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-details>section+section,.inspector-window[data-color-scheme=dark] .inspector-intelligence-hud-details,.inspector-window[data-color-scheme=dark] .inspector-home-features-empty{border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-system-health-signal[data-tone=success] dd,.inspector-window[data-color-scheme=dark] .inspector-home-feature small{color:#8ce1c5}.inspector-window[data-color-scheme=dark] .inspector-system-health-signal[data-tone=active] dd{color:#f2cf8f}.inspector-window[data-color-scheme=dark] .inspector-system-health-signal[data-tone=error] .inspector-system-health-event-type{color:#ff9aa0;background-color:#3b1c22}.inspector-window[data-color-scheme=dark] .inspector-system-health-signal[data-tone=success] .inspector-system-health-event-type{color:#8ce1c5;background-color:#173b32}.inspector-window[data-color-scheme=dark] .inspector-system-health-signal[data-tone=active] .inspector-system-health-event-type{color:#f2cf8f;background-color:#342916}.inspector-window[data-color-scheme=dark] .inspector-home-feature-group{background-color:#191c24;border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-home-feature-group-header{color:#c9ccd6;background-color:#20232d;border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-home-feature-group-header>span{color:#c9ccd6;background-color:#191c24}.inspector-window[data-color-scheme=dark] .inspector-home-feature-group[data-feature-state-group=active] .inspector-home-feature-group-header{color:#8ce1c5;background-color:#173b32;border-color:#347d69}.inspector-window[data-color-scheme=dark] .inspector-home-feature{background-color:#191c24}.inspector-window[data-color-scheme=dark] .inspector-home-feature:hover{background-color:#20232d}.inspector-window[data-color-scheme=dark] .inspector-home-feature+.inspector-home-feature{border-color:#2f323d}.inspector-window[data-color-scheme=dark] .inspector-home-feature-group-empty{color:#9da1af}.inspector-window[data-color-scheme=dark] .inspector-home-feature[data-state=off]{color:#aeb1bd}.inspector-window[data-color-scheme=dark] .inspector-home-feature-status>span{background-color:#191c24;border-color:#6f7484}.inspector-window[data-color-scheme=dark] .inspector-home-feature[data-state=on] .inspector-home-feature-status>span{background-color:#8ce1c5;border-color:#8ce1c5}.inspector-window[data-color-scheme=dark] .inspector-home-feature-action{color:#d4d7e0;background-color:#20232d;border-color:#464957}.inspector-window[data-color-scheme=dark] .inspector-home-feature-label:hover{color:#d8d9ff}.inspector-window[data-color-scheme=dark] .inspector-home-feature-action:hover{color:#fff;background-color:#292b43;border-color:#777aae}.inspector-window[data-color-scheme=dark] .inspector-home-feature-action[data-copy-state=copied]{color:#8ce1c5;background-color:#173b32;border-color:#347d69}.inspector-window[data-color-scheme=dark] .inspector-home-feature-action[data-copy-state=error]{color:#ff9aa0;background-color:#3b1c22;border-color:#87424a}.inspector-window[data-color-scheme=dark] .inspector-whats-new-preview-dismiss{color:#aeb1bd}.inspector-window[data-color-scheme=dark] .inspector-whats-new-preview-dismiss:hover{color:#fff;background-color:#302a40}.inspector-window[data-color-scheme=dark] .inspector-home-usage-bar{background-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-thread-progress::-webkit-progress-bar{background-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-whats-new-header{box-shadow:none;background-color:#1d1e2b;border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-whats-new-updated,.inspector-window[data-color-scheme=dark] .inspector-whats-new-empty{color:#aeb1bd}.inspector-window[data-color-scheme=dark] .inspector-whats-new-preview-action{color:#d8d9ff}.inspector-window[data-color-scheme=dark] .inspector-whats-new-preview:hover .inspector-whats-new-preview-action{color:#fff}.inspector-window[data-color-scheme=dark] .inspector-whats-new-document,.inspector-window[data-color-scheme=dark] .inspector-whats-new-empty{border-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-whats-new-document .announcement-content{color:#c9ccd6}.inspector-window[data-color-scheme=dark] .inspector-whats-new-empty .inspector-home-card-title{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-whats-new-document .announcement-content h1+p{color:#c9ccd6}.inspector-window[data-color-scheme=dark] .inspector-whats-new-document .announcement-content h2{border-top-color:#3a3d49}.inspector-window[data-color-scheme=dark] .inspector-whats-new-document .announcement-content h1,.inspector-window[data-color-scheme=dark] .inspector-whats-new-document .announcement-content h2,.inspector-window[data-color-scheme=dark] .inspector-whats-new-document .announcement-content h3,.inspector-window[data-color-scheme=dark] .inspector-whats-new-document .announcement-content strong{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .inspector-whats-new-document .announcement-content a{color:#caccff}.inspector-window[data-color-scheme=dark] .inspector-threads-footer{color:#aeb1bd;background-color:#15171e;border-color:#343742}.inspector-window[data-color-scheme=dark] [data-inspector-thread-count]{color:#f3f4f8}.inspector-window[data-color-scheme=dark] [data-inspector-thread-expiry]{color:#aeb1bd}.inspector-window[data-color-scheme=dark] [data-inspector-action-placement=threads-footer]{color:#d8d9ff;background-color:#191c24;border-color:#464957}.inspector-window[data-color-scheme=dark] [data-inspector-action-placement=threads-footer]:hover{color:#fff;background-color:#20232d;border-color:#777aae}.inspector-window[data-color-scheme=dark] .cpk-threads-overview{background-color:#111319}.inspector-window[data-color-scheme=dark] .cpk-locked-feature{background:#111319}.inspector-window[data-color-scheme=dark] .cpk-locked-feature-copy,.inspector-window[data-color-scheme=dark] .cpk-locked-feature-description{color:#aeb1bd}.inspector-window[data-color-scheme=dark] .cpk-locked-feature-name{color:#caccff}.inspector-window[data-color-scheme=dark] .cpk-locked-feature-title{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .cpk-locked-feature-outline{box-shadow:none;background:0 0}.inspector-window[data-color-scheme=dark] .cpk-locked-feature-outline-item h3{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .cpk-locked-feature-outline-icon{color:#caccff}.inspector-window[data-color-scheme=dark] .cpk-locked-feature-outline-item{box-shadow:none;color:#f3f4f8;background:0 0}.inspector-window[data-color-scheme=dark] .cpk-locked-feature-outline-item+.cpk-locked-feature-outline-item{border-top-color:#3a3d49}.inspector-window[data-color-scheme=dark] .cpk-locked-feature-outline-item p,.inspector-window[data-color-scheme=dark] .cpk-threads-overview-content,.inspector-window[data-color-scheme=dark] .cpk-threads-overview-copy,.inspector-window[data-color-scheme=dark] .cpk-threads-overview-video-fallback,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-copy{color:#aeb1bd}.inspector-window[data-color-scheme=dark] .cpk-threads-overview-title,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-title{color:#f3f4f8}.inspector-window[data-color-scheme=dark] .cpk-threads-overview-video-frame{background:linear-gradient(135deg,#666a9e3d,#347d6929),#191c24;border-color:#3a3d49;box-shadow:0 8px 20px #00000038}.inspector-window[data-color-scheme=dark] .cpk-threads-overview-video-control,.inspector-window[data-color-scheme=dark] .cpk-threads-overview-action-secondary,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-launch,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-button-secondary{color:#d8d9ff;background-color:#191c24;border-color:#464957}.inspector-window[data-color-scheme=dark] .cpk-threads-overview-video-control:hover,.inspector-window[data-color-scheme=dark] .cpk-threads-overview-action-secondary:hover,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-launch:hover,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-button-secondary:hover{color:#fff;background-color:#242731;border-color:#777aae}.inspector-window[data-color-scheme=dark] .cpk-threads-overview-action-primary,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-button-primary{color:#171823;background-color:#caccff;border-color:#caccff}.inspector-window[data-color-scheme=dark] .cpk-threads-overview-action-primary:hover,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-button-primary:hover{background-color:#d8d9ff;border-color:#d8d9ff}.inspector-window[data-color-scheme=dark] .cpk-threads-tour{color:#aeb1bd;background-color:#191c24;border-color:#464957;box-shadow:0 16px 36px #00000052}.inspector-window[data-color-scheme=dark] .cpk-threads-tour-step{color:#8ce1c5}.inspector-window[data-color-scheme=dark] .cpk-threads-tour-skip{color:#aeb1bd}.inspector-window[data-color-scheme=dark] .cpk-threads-overview-action:focus-visible,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-launch:focus-visible,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-skip:focus-visible,.inspector-window[data-color-scheme=dark] .cpk-threads-tour-button:focus-visible{outline-color:#bec2ff}.inspector-window[data-color-scheme=dark] .cpk-agent-overview,.inspector-window[data-color-scheme=dark] .cpk-section-card{background-color:#191c24!important;border-color:#3a3d49!important}.inspector-window[data-color-scheme=dark] .cpk-section-header{background-color:#242731!important;border-color:#3a3d49!important}.inspector-window[data-color-scheme=dark] .cpk-section-header h4{color:#f3f4f8!important}.inspector-window[data-color-scheme=dark] .cpk-agent-icon{color:#d8d9ff!important;background-color:#292b43!important}.inspector-window[data-color-scheme=dark] .cpk-stat-card{background-color:#191c24!important;border-color:#464957!important}.inspector-window[data-color-scheme=dark] button.cpk-stat-card:hover{background-color:#20232d!important}.cpk-agent-messages-head{border-bottom:1px solid #e4e4ec}.cpk-agent-message-row+.cpk-agent-message-row{border-top:1px solid #e4e4ec}.inspector-window[data-color-scheme=dark] .cpk-agent-messages-head,.inspector-window[data-color-scheme=dark] .cpk-agent-message-row+.cpk-agent-message-row,.inspector-window[data-color-scheme=dark] .cpk-agent-view .divide-gray-200>:not([hidden])~:not([hidden]),.inspector-window[data-color-scheme=dark] .cpk-agent-view .divide-y>*{border-color:#3a3d49!important}.inspector-window[data-color-scheme=dark] .cpk-json-block{color:#c9ccd6}.inspector-window[data-color-scheme=dark] [class*=bg-emerald-50],.inspector-window[data-color-scheme=dark] [class*=bg-green-100]{color:#8ce1c5!important;background-color:#173b32!important}.inspector-window[data-color-scheme=dark] [class*=bg-rose-50]{color:#ff9aa0!important;background-color:#3b1c22!important}.inspector-window[data-color-scheme=dark] [data-cpk-event-error] p,.inspector-window[data-color-scheme=dark] [data-playground-error] p{color:inherit!important}.inspector-window[data-color-scheme=dark] [class*=bg-amber-50],.inspector-window[data-color-scheme=dark] [class*=bg-amber-100]{color:#f2cf8f!important;background-color:#342916!important}.inspector-window[data-color-scheme=dark] [class*=bg-blue-50],.inspector-window[data-color-scheme=dark] [class*=bg-blue-100],.inspector-window[data-color-scheme=dark] [class*=bg-sky-50],.inspector-window[data-color-scheme=dark] [class*=bg-violet-50],.inspector-window[data-color-scheme=dark] [class*=bg-purple-50],.inspector-window[data-color-scheme=dark] [class*=bg-fuchsia-50]{color:#d8d9ff!important;background-color:#292b43!important}.inspector-window[data-color-scheme=dark] [class*=bg-white]{background-color:#191c24!important}.inspector-window[data-color-scheme=dark] [class*=bg-gray-50],.inspector-window[data-color-scheme=dark] [class*=bg-slate-50],.inspector-window[data-color-scheme=dark] [class*=bg-gray-100],.inspector-window[data-color-scheme=dark] [class*=bg-slate-100]{background-color:#171a22!important}.inspector-window[data-color-scheme=dark] [class*=text-gray-900],.inspector-window[data-color-scheme=dark] [class*=text-slate-900],.inspector-window[data-color-scheme=dark] [class*=text-gray-800],.inspector-window[data-color-scheme=dark] [class*=text-slate-800],.inspector-window[data-color-scheme=dark] [class*=text-gray-700],.inspector-window[data-color-scheme=dark] [class*=text-slate-700]{color:#f3f4f8!important}.inspector-window[data-color-scheme=dark] [class*=text-gray-600],.inspector-window[data-color-scheme=dark] [class*=text-slate-600],.inspector-window[data-color-scheme=dark] [class*=text-gray-500],.inspector-window[data-color-scheme=dark] [class*=text-slate-500],.inspector-window[data-color-scheme=dark] [class*=text-gray-400],.inspector-window[data-color-scheme=dark] [class*=text-slate-400]{color:#aeb1bd!important}.inspector-window[data-color-scheme=dark] [class*=border-gray-100],.inspector-window[data-color-scheme=dark] [class*=border-slate-100],.inspector-window[data-color-scheme=dark] [class*=border-gray-200],.inspector-window[data-color-scheme=dark] [class*=border-slate-200],.inspector-window[data-color-scheme=dark] [class*=border-gray-300],.inspector-window[data-color-scheme=dark] [class*=border-slate-300]{border-color:#3a3d49!important}.inspector-window[data-color-scheme=dark] input,.inspector-window[data-color-scheme=dark] select,.inspector-window[data-color-scheme=dark] textarea{color:#f3f4f8!important;background-color:#191c24!important;border-color:#464957!important}.inspector-window[data-color-scheme=dark] input::placeholder,.inspector-window[data-color-scheme=dark] textarea::placeholder{color:#858996}.inspector-window[data-color-scheme=dark] .cpk-playground-composer{background-color:#2f3340!important;box-shadow:0 0 0 1px #6d7285!important}.inspector-window[data-color-scheme=dark] .cpk-playground-composer:focus-within{box-shadow:0 0 0 1px #c5c8de!important}.inspector-window[data-color-scheme=dark] .cpk-playground-input{color:#f3f4f8!important;caret-color:#f3f4f8!important;background-color:#0000!important}.inspector-window[data-color-scheme=dark] .cpk-playground-input::placeholder{color:#e4e6ef!important;opacity:1!important}.inspector-window[data-color-scheme=dark] .cpk-playground-send:not(:disabled){color:#111319!important;opacity:1!important;background-color:#f3f4f8!important}.inspector-window[data-color-scheme=dark] .cpk-playground-send:disabled{color:#f3f4f8!important;background-color:#f3f4f833!important}.inspector-window[data-color-scheme=dark] ::selection{color:#fff;background-color:#5b5f92}@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-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";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:"";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:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}} \ No newline at end of file diff --git a/packages/web-inspector/src/styles/tailwind.css b/packages/web-inspector/src/styles/tailwind.css index c141babc64..5742672b42 100644 --- a/packages/web-inspector/src/styles/tailwind.css +++ b/packages/web-inspector/src/styles/tailwind.css @@ -624,222 +624,6 @@ background-color: #ffffff; } -.cpk-memory-locked { - position: relative; - display: flex; - height: 100%; - align-items: center; - justify-content: center; - overflow: hidden; - background-color: #ffffff; - padding: 32px; -} - -.cpk-locked-preview { - position: absolute; - inset: 0; - display: grid; - grid-template-columns: minmax(180px, 28%) 1fr; - overflow: hidden; - opacity: 0.58; - pointer-events: none; -} - -.cpk-locked-preview-sidebar { - display: flex; - flex-direction: column; - gap: 12px; - border-right: 1px solid #dbdbe5; - background-color: #fafafa; - padding: 28px 24px; -} - -.cpk-locked-preview-row { - border-radius: 10px; - background-color: #ffffff; - box-shadow: inset 0 0 0 1px #eeeef4; - padding: 12px; -} - -.cpk-locked-preview-row[data-accent="true"] { - background-color: #eee6fe; -} - -.cpk-locked-preview-bar { - border-radius: 999px; - background-color: #d7d7df; -} - -.cpk-locked-preview-row-title { - width: var(--preview-width); - height: 8px; -} - -.cpk-locked-preview-row[data-accent="true"] .cpk-locked-preview-row-title { - background-color: #a984f5; -} - -.cpk-locked-preview-row-line { - width: 88%; - height: 6px; - margin-top: 10px; - background-color: #e3e3eb; -} - -.cpk-locked-preview-row-line:last-child { - width: 62%; - margin-top: 7px; - background-color: #e8e8ef; -} - -.cpk-locked-preview-main { - min-width: 0; - background-color: #ffffff; - padding: 42px 48px; -} - -.cpk-locked-preview-heading { - width: 180px; - height: 10px; -} - -.cpk-locked-preview-copy { - width: min(520px, 58%); - height: 8px; - margin-top: 28px; - background-color: #e3e3eb; -} - -.cpk-locked-preview-copy + .cpk-locked-preview-copy { - width: min(430px, 48%); - margin-top: 12px; - background-color: #e8e8ef; -} - -.cpk-locked-preview-cards { - display: grid; - max-width: 620px; - grid-template-columns: repeat(2, minmax(0, 1fr)); - gap: 16px; - margin-top: 30px; -} - -.cpk-locked-preview-card { - height: 116px; - border-radius: 10px; - background-color: #f5f5f8; - box-shadow: inset 0 0 0 1px #eeeef4; -} - -.cpk-locked-preview-footer-line { - width: min(680px, 74%); - height: 10px; - margin-top: 34px; - background-color: #e3e3eb; -} - -.cpk-locked-preview-footer-line + .cpk-locked-preview-footer-line { - width: min(560px, 60%); - margin-top: 14px; - background-color: #e8e8ef; -} - -.cpk-memory-locked-scrim { - position: absolute; - inset: 0; - background: radial-gradient( - circle at center, - rgba(255, 255, 255, 0.9) 0, - rgba(255, 255, 255, 0.78) 24%, - rgba(255, 255, 255, 0.34) 48%, - rgba(255, 255, 255, 0.56) 100% - ); - pointer-events: none; -} - -.cpk-memory-locked-content { - position: relative; - z-index: 1; - max-width: 440px; - color: #57575b; - text-align: center; -} - -.cpk-memory-locked-icon-wrap { - display: flex; - justify-content: center; - margin: 0 auto 18px; -} - -.cpk-memory-locked-icon { - display: flex; - width: 44px; - height: 44px; - align-items: center; - justify-content: center; - border: 1px solid #dfd6fb; - border-radius: 10px; - background-color: #eee6fe; - color: #57575b; - box-shadow: 0 8px 18px rgba(87, 87, 91, 0.14); -} - -.cpk-memory-locked-title { - margin: 0 0 8px; - color: #010507; - font-size: 16px; - font-weight: 600; - line-height: 1.35; -} - -.cpk-memory-locked-copy { - max-width: 380px; - margin: 0 auto 18px; - color: #57575b; - font-size: 13px; - line-height: 1.55; -} - -.cpk-memory-locked-actions { - display: flex; - flex-wrap: wrap; - justify-content: center; - gap: 8px; -} - -.cpk-memory-locked-action { - display: inline-flex; - min-height: 34px; - align-items: center; - justify-content: center; - gap: 6px; - border: 1px solid #6430ab; - border-radius: 5px; - background-color: #6430ab; - padding: 8px 12px; - color: #ffffff; - font-size: 12px; - font-weight: 600; - text-decoration: none; - cursor: pointer; -} - -.cpk-memory-locked-action:hover { - border-color: #4e238c; - background-color: #4e238c; -} - -.cpk-memory-locked-action-secondary { - border-color: #dbdbe5; - background-color: #ffffff; - color: #57575b; -} - -.cpk-memory-locked-action-secondary:hover { - border-color: #afafb7; - background-color: #f7f7f9; -} - .inspector-home { position: relative; min-height: 100%; @@ -3384,6 +3168,169 @@ small.inspector-system-health-detail { color: #57575b; } +.cpk-locked-feature { + position: relative; + display: flex; + box-sizing: border-box; + width: 100%; + min-height: 100%; + overflow: auto; + align-items: flex-start; + background: #ffffff; + padding: 52px 24px 56px; + container-name: cpk-locked-feature; + container-type: inline-size; +} + +.cpk-locked-feature-layout { + box-sizing: border-box; + width: 100%; + min-width: 0; + max-width: 600px; + margin: 0 auto; +} + +.cpk-locked-feature-hero { + display: grid; + box-sizing: border-box; + width: 100%; + min-width: 0; + margin: 0 auto; + gap: 36px; + grid-template-columns: minmax(0, 1fr); +} + +.cpk-locked-feature-copy { + min-width: 0; + color: #57575b; +} + +.cpk-locked-feature-name { + display: inline-flex; + align-items: center; + margin-bottom: 20px; + gap: 8px; + color: #5558b2; + font-size: 11px; + font-weight: 700; + letter-spacing: 0.08em; + line-height: 1.25; + text-transform: uppercase; +} + +.cpk-locked-feature-icon { + display: inline-flex; + width: 15px; + height: 15px; + flex: none; + align-items: center; + justify-content: center; + color: inherit; +} + +.cpk-locked-feature-icon svg { + display: block; + width: 15px; + height: 15px; +} + +.cpk-locked-feature-title { + max-width: 680px; + margin: 0 0 18px; + color: #010507; + font-size: clamp(25px, 2.6vw, 34px); + font-weight: 600; + letter-spacing: -0.025em; + line-height: 1.08; +} + +.cpk-locked-feature-description { + max-width: 680px; + margin: 0 0 28px; + color: #57575b; + font-size: 14px; + line-height: 1.6; +} + +.cpk-locked-feature-media { + width: 100%; + min-width: 0; + justify-self: stretch; +} + +.cpk-threads-overview-video-frame.cpk-locked-feature-video { + width: 100%; + min-width: 0; + max-width: none; + margin: 0; + border-color: #e4e4ec; + border-radius: 12px; + background: #000000; + box-shadow: 0 14px 32px rgba(44, 43, 68, 0.12); +} + +.cpk-locked-feature-outline { + box-sizing: border-box; + width: 100%; + max-width: none; + margin: 40px 0 0; +} + +.cpk-locked-feature-outline-list { + display: block; + margin: 0; +} + +.cpk-locked-feature-outline-item { + display: block; + min-width: 0; + padding: 0 0 28px; +} + +.cpk-locked-feature-outline-item + .cpk-locked-feature-outline-item { + border-top: 1px solid #e4e4ec; + padding-top: 28px; +} + +.cpk-locked-feature-outline-item h3, +.cpk-locked-feature-outline-item p { + margin: 0; +} + +.cpk-locked-feature-outline-item h3 { + display: flex; + align-items: center; + margin-bottom: 10px; + gap: 10px; + color: #010507; + font-size: 20px; + font-weight: 600; + letter-spacing: -0.018em; + line-height: 1.25; +} + +.cpk-locked-feature-outline-icon { + display: inline-flex; + width: 20px; + height: 20px; + flex: 0 0 20px; + align-items: center; + justify-content: center; + color: #5558b2; +} + +.cpk-locked-feature-outline-icon svg { + width: 18px; + height: 18px; +} + +.cpk-locked-feature-outline-item p { + max-width: 68ch; + color: #57575b; + font-size: 15px; + line-height: 1.65; +} + .cpk-threads-overview-title { margin: 0 0 10px; color: #010507; @@ -3401,8 +3348,21 @@ small.inspector-system-health-detail { .cpk-threads-overview-actions { display: flex; + align-items: center; flex-wrap: wrap; - gap: 8px; + gap: 10px; +} + +.cpk-locked-feature .cpk-locked-feature-setup-cta, +.cpk-locked-feature .cpk-threads-overview-action { + box-sizing: border-box; + height: 44px; + min-height: 44px; + align-items: center; + padding: 12px 16px; + font-size: 13px; + font-weight: 700; + line-height: 1; } .cpk-threads-overview-action { @@ -3426,11 +3386,13 @@ small.inspector-system-health-detail { [data-inspector-feature-setup-prompt][data-copy-state="copied"] { border-color: #087653; background-color: #087653; + color: #ffffff; } [data-inspector-feature-setup-prompt][data-copy-state="error"] { border-color: #b32d3b; background-color: #b32d3b; + color: #ffffff; } [data-inspector-feature-setup-prompt]:focus-visible { @@ -3613,6 +3575,18 @@ small.inspector-system-health-detail { opacity: 0.45; } +@container cpk-locked-feature (max-width: 440px) { + .cpk-locked-feature .cpk-threads-overview-actions { + align-items: stretch; + flex-direction: column; + } + + .cpk-locked-feature .cpk-locked-feature-setup-cta, + .cpk-locked-feature .cpk-threads-overview-action { + width: 100%; + } +} + @media (max-width: 720px) { .cpk-threads-overview { padding: 24px; @@ -4687,6 +4661,54 @@ small.inspector-system-health-detail { background-color: #111319; } +.inspector-window[data-color-scheme="dark"] .cpk-locked-feature { + background: #111319; +} + +.inspector-window[data-color-scheme="dark"] .cpk-locked-feature-copy, +.inspector-window[data-color-scheme="dark"] .cpk-locked-feature-description { + color: #aeb1bd; +} + +.inspector-window[data-color-scheme="dark"] .cpk-locked-feature-name { + color: #caccff; +} + +.inspector-window[data-color-scheme="dark"] .cpk-locked-feature-title { + color: #f3f4f8; +} + +.inspector-window[data-color-scheme="dark"] .cpk-locked-feature-outline { + background: transparent; + box-shadow: none; +} + +.inspector-window[data-color-scheme="dark"] + .cpk-locked-feature-outline-item + h3 { + color: #f3f4f8; +} + +.inspector-window[data-color-scheme="dark"] .cpk-locked-feature-outline-icon { + color: #caccff; +} + +.inspector-window[data-color-scheme="dark"] .cpk-locked-feature-outline-item { + background: transparent; + box-shadow: none; + color: #f3f4f8; +} + +.inspector-window[data-color-scheme="dark"] + .cpk-locked-feature-outline-item + + .cpk-locked-feature-outline-item { + border-top-color: #3a3d49; +} + +.inspector-window[data-color-scheme="dark"] .cpk-locked-feature-outline-item p { + color: #aeb1bd; +} + .inspector-window[data-color-scheme="dark"] .cpk-threads-overview-content, .inspector-window[data-color-scheme="dark"] .cpk-threads-overview-copy, .inspector-window[data-color-scheme="dark"] @@ -4776,102 +4798,6 @@ small.inspector-system-health-detail { outline-color: #bec2ff; } -.inspector-window[data-color-scheme="dark"] .cpk-memory-locked { - background-color: #111319; - color: #f3f4f8; -} - -.inspector-window[data-color-scheme="dark"] .cpk-locked-preview-sidebar { - border-color: #2f323d; - background-color: #15171e; -} - -.inspector-window[data-color-scheme="dark"] .cpk-locked-preview-main { - background-color: #111319; -} - -.inspector-window[data-color-scheme="dark"] .cpk-locked-preview-row { - background-color: #191c24; - box-shadow: inset 0 0 0 1px #2f323d; -} - -.inspector-window[data-color-scheme="dark"] - .cpk-locked-preview-row[data-accent="true"] { - background-color: #292b43; -} - -.inspector-window[data-color-scheme="dark"] .cpk-locked-preview-bar { - background-color: #333641; -} - -.inspector-window[data-color-scheme="dark"] - .cpk-locked-preview-row[data-accent="true"] - .cpk-locked-preview-row-title { - background-color: #777aae; -} - -.inspector-window[data-color-scheme="dark"] .cpk-locked-preview-row-line, -.inspector-window[data-color-scheme="dark"] .cpk-locked-preview-copy, -.inspector-window[data-color-scheme="dark"] .cpk-locked-preview-footer-line { - background-color: #2f323d; -} - -.inspector-window[data-color-scheme="dark"] - .cpk-locked-preview-row-line:last-child, -.inspector-window[data-color-scheme="dark"] - .cpk-locked-preview-copy - + .cpk-locked-preview-copy, -.inspector-window[data-color-scheme="dark"] - .cpk-locked-preview-footer-line - + .cpk-locked-preview-footer-line { - background-color: #292c36; -} - -.inspector-window[data-color-scheme="dark"] .cpk-locked-preview-card { - background-color: #191c24; - box-shadow: inset 0 0 0 1px #2f323d; -} - -.inspector-window[data-color-scheme="dark"] .cpk-memory-locked-scrim { - background: radial-gradient( - circle at center, - rgba(17, 19, 25, 0.94) 0, - rgba(17, 19, 25, 0.84) 24%, - rgba(17, 19, 25, 0.46) 48%, - rgba(17, 19, 25, 0.68) 100% - ); -} - -.inspector-window[data-color-scheme="dark"] .cpk-memory-locked-content, -.inspector-window[data-color-scheme="dark"] .cpk-memory-locked-copy { - color: #aeb1bd; -} - -.inspector-window[data-color-scheme="dark"] .cpk-memory-locked-title { - color: #f3f4f8; -} - -.inspector-window[data-color-scheme="dark"] .cpk-memory-locked-icon { - border-color: #666a9e; - background-color: #292b43; - color: #d8d9ff; - box-shadow: none; -} - -.inspector-window[data-color-scheme="dark"] - .cpk-memory-locked-action-secondary { - border-color: #464957; - background-color: #191c24; - color: #d8d9ff; -} - -.inspector-window[data-color-scheme="dark"] - .cpk-memory-locked-action-secondary:hover { - border-color: #777aae; - background-color: #242731; - color: #ffffff; -} - .inspector-window[data-color-scheme="dark"] .cpk-agent-overview, .inspector-window[data-color-scheme="dark"] .cpk-section-card { border-color: #3a3d49 !important; From 0308e423cf44b470d8711885cadb3590c322a436 Mon Sep 17 00:00:00 2001 From: Benjamin Taylor Date: Thu, 3 Sep 2026 10:39:39 -0500 Subject: [PATCH 03/57] chore(docs): enable Reo enhanced visitor identification Adds enableThirdPartyTracking to the Reo.init call in shell-docs so the docs site matches the marketing site (CopilotKit/website#556). The Reo dashboard toggle was already enabled on 2026-09-03; this completes the activation. Co-Authored-By: Claude Opus 5 (1M context) --- showcase/shell-docs/src/app/layout.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/showcase/shell-docs/src/app/layout.tsx b/showcase/shell-docs/src/app/layout.tsx index c2184ca3b8..8f93db3d61 100644 --- a/showcase/shell-docs/src/app/layout.tsx +++ b/showcase/shell-docs/src/app/layout.tsx @@ -138,7 +138,7 @@ export default function RootLayout({ e = ${JSON.stringify(REO_KEY)}; t = function() { if (window.Reo) { - window.Reo.init({ clientID: e }); + window.Reo.init({ clientID: e, enableThirdPartyTracking: true }); } }; n = document.createElement("script"); From b302b28d8d6bd8f95e6fd16a6b1fbcdbe0cc8ba1 Mon Sep 17 00:00:00 2001 From: Tyler Slaton Date: Thu, 3 Sep 2026 09:49:05 -0700 Subject: [PATCH 04/57] docs(shell-docs): add WebMCP onboarding guide --- .../webmcp-onboarding-prompt.test.tsx | 86 ++++++++++ .../src/components/docs-page-view.tsx | 2 + .../components/webmcp-onboarding-prompt.tsx | 130 +++++++++++++++ .../content/docs/frontends/angular/webmcp.mdx | 82 ++++++++++ .../shell-docs/src/content/docs/meta.json | 1 + .../shell-docs/src/content/docs/webmcp.mdx | 149 ++++++++++++++++++ .../src/lib/__tests__/webmcp-docs.test.ts | 44 ++++++ .../webmcp-onboarding-prompt-markdown.test.ts | 12 ++ .../webmcp-onboarding-prompt.test.ts | 14 ++ showcase/shell-docs/src/lib/llm-text.ts | 13 ++ .../src/lib/webmcp-onboarding-prompt.ts | 21 +++ 11 files changed, 554 insertions(+) create mode 100644 showcase/shell-docs/src/components/__tests__/webmcp-onboarding-prompt.test.tsx create mode 100644 showcase/shell-docs/src/components/webmcp-onboarding-prompt.tsx create mode 100644 showcase/shell-docs/src/content/docs/frontends/angular/webmcp.mdx create mode 100644 showcase/shell-docs/src/content/docs/webmcp.mdx create mode 100644 showcase/shell-docs/src/lib/__tests__/webmcp-docs.test.ts create mode 100644 showcase/shell-docs/src/lib/__tests__/webmcp-onboarding-prompt-markdown.test.ts create mode 100644 showcase/shell-docs/src/lib/__tests__/webmcp-onboarding-prompt.test.ts create mode 100644 showcase/shell-docs/src/lib/webmcp-onboarding-prompt.ts diff --git a/showcase/shell-docs/src/components/__tests__/webmcp-onboarding-prompt.test.tsx b/showcase/shell-docs/src/components/__tests__/webmcp-onboarding-prompt.test.tsx new file mode 100644 index 0000000000..b2f8feb885 --- /dev/null +++ b/showcase/shell-docs/src/components/__tests__/webmcp-onboarding-prompt.test.tsx @@ -0,0 +1,86 @@ +// @vitest-environment jsdom + +import React from "react"; +import { cleanup, fireEvent, render, screen, waitFor } from "@testing-library/react"; +import { afterEach, expect, test, vi } from "vitest"; +import { WebMCPOnboardingPrompt } from "../webmcp-onboarding-prompt"; +import { INTELLIGENCE_ONBOARDING_EVENTS } from "@/lib/intelligence-onboarding-prompt"; + +const analytics = vi.hoisted(() => ({ capture: vi.fn() })); + +vi.mock("next/navigation", () => ({ + usePathname: () => "/webmcp", +})); + +vi.mock("posthog-js/react", () => ({ + usePostHog: () => analytics, +})); + +afterEach(() => { + cleanup(); + vi.clearAllMocks(); +}); + +test("copies a run-bound WebMCP goal into the CLI onboarding path", async () => { + const writeText = vi.fn().mockResolvedValue(undefined); + Object.defineProperty(navigator, "clipboard", { + configurable: true, + value: { writeText }, + }); + + render(); + fireEvent.click(screen.getByRole("button", { name: "Copy setup prompt" })); + + await waitFor(() => expect(writeText).toHaveBeenCalledTimes(1)); + + const prompt = writeText.mock.calls[0]?.[0] as string; + const runId = /onboard start --run ([0-9a-f]{12}) --coding-agent/.exec( + prompt, + )?.[1]; + + expect(runId).toBeTruthy(); + expect(prompt).toContain("The goal of this onboarding run is to get WebMCP working"); + expect(prompt).toContain("A WebMCP call does not require a CopilotKit backend agent"); + expect(prompt).toContain("https://docs.copilotkit.ai/webmcp"); + expect(screen.getByRole("button", { name: "Copied" })).toBeTruthy(); + expect(screen.getByText("Prompt copied")).toBeTruthy(); + expect(analytics.capture).toHaveBeenCalledWith( + INTELLIGENCE_ONBOARDING_EVENTS.promptCopied, + { + from_path: "/webmcp", + onboarding_run_id: runId, + surface: "docs_webmcp_onboarding_prompt", + }, + ); +}); + +test("disables the CTA while the clipboard write is pending", async () => { + let finishCopy: (() => void) | undefined; + const writeText = vi.fn( + () => + new Promise((resolve) => { + finishCopy = resolve; + }), + ); + Object.defineProperty(navigator, "clipboard", { + configurable: true, + value: { writeText }, + }); + + render(); + const button = screen.getByRole("button", { name: "Copy setup prompt" }); + + fireEvent.click(button); + + await waitFor(() => expect(button).toHaveProperty("disabled", true)); + fireEvent.click(button); + expect(writeText).toHaveBeenCalledTimes(1); + + finishCopy?.(); + await waitFor(() => + expect(screen.getByRole("button", { name: "Copied" })).toHaveProperty( + "disabled", + false, + ), + ); +}); diff --git a/showcase/shell-docs/src/components/docs-page-view.tsx b/showcase/shell-docs/src/components/docs-page-view.tsx index bb06a3c455..2ddb156207 100644 --- a/showcase/shell-docs/src/components/docs-page-view.tsx +++ b/showcase/shell-docs/src/components/docs-page-view.tsx @@ -40,6 +40,7 @@ import type { OpsPlatformCTAProps } from "@/components/react/ops-platform-cta"; import { ChannelsStartPrompt } from "@/components/channels-start-prompt"; import type { ChannelsStartPromptProps } from "@/components/channels-start-prompt"; import { RichThreadsSetupPrompt } from "@/components/rich-threads-setup-prompt"; +import { WebMCPOnboardingPrompt } from "@/components/webmcp-onboarding-prompt"; import { IntelligenceOnboardingPrompt } from "@/components/intelligence-onboarding-prompt"; import type { IntelligenceOnboardingPromptProps } from "@/components/intelligence-onboarding-prompt"; import { SignupLink } from "@/components/react/signup-link"; @@ -364,6 +365,7 @@ export async function DocsPageView({ /> ), RichThreadsSetupPrompt, + WebMCPOnboardingPrompt, IntelligenceOnboardingPrompt: IntelligenceOnboardingPromptMdx, OpsPlatformCTA: (props: OpsPlatformCTAProps) => ( diff --git a/showcase/shell-docs/src/components/webmcp-onboarding-prompt.tsx b/showcase/shell-docs/src/components/webmcp-onboarding-prompt.tsx new file mode 100644 index 0000000000..72172697b5 --- /dev/null +++ b/showcase/shell-docs/src/components/webmcp-onboarding-prompt.tsx @@ -0,0 +1,130 @@ +"use client"; + +import React from "react"; +import { Copy, SquareTerminal } from "lucide-react"; +import { usePathname } from "next/navigation"; +import { usePostHog } from "posthog-js/react"; +import { + createOnboardingRunId, + INTELLIGENCE_ONBOARDING_EVENTS, +} from "@/lib/intelligence-onboarding-prompt"; +import { createWebMCPOnboardingPrompt } from "@/lib/webmcp-onboarding-prompt"; + +const COPY_SURFACE = "docs_webmcp_onboarding_prompt"; + +type CopyState = "idle" | "copied" | "error"; + +/** Copyable WebMCP goal that enters the repository-aware CLI onboarding flow. */ +export function WebMCPOnboardingPrompt(): React.JSX.Element { + const titleId = React.useId(); + const pathname = usePathname(); + const posthog = usePostHog(); + const [copyState, setCopyState] = React.useState("idle"); + const [isCopying, setIsCopying] = React.useState(false); + const copyInFlightRef = React.useRef(false); + const resetTimerRef = React.useRef | null>( + null, + ); + const mountedRef = React.useRef(true); + + React.useEffect( + () => () => { + mountedRef.current = false; + if (resetTimerRef.current) clearTimeout(resetTimerRef.current); + }, + [], + ); + + function scheduleReset(delayMs: number): void { + if (resetTimerRef.current) clearTimeout(resetTimerRef.current); + resetTimerRef.current = setTimeout(() => { + if (mountedRef.current) setCopyState("idle"); + resetTimerRef.current = null; + }, delayMs); + } + + async function copyPrompt(): Promise { + if (copyInFlightRef.current) return; + copyInFlightRef.current = true; + setIsCopying(true); + const runId = createOnboardingRunId(); + + try { + await navigator.clipboard.writeText(createWebMCPOnboardingPrompt(runId)); + } catch { + if (mountedRef.current) { + setCopyState("error"); + scheduleReset(2600); + } + return; + } finally { + copyInFlightRef.current = false; + if (mountedRef.current) setIsCopying(false); + } + + if (!mountedRef.current) return; + setCopyState("copied"); + scheduleReset(1800); + + try { + posthog?.capture(INTELLIGENCE_ONBOARDING_EVENTS.promptCopied, { + from_path: pathname, + onboarding_run_id: runId, + surface: COPY_SURFACE, + }); + } catch { + // Analytics must never change the result of a successful clipboard write. + } + } + + return ( +
+
+
+
+ + +
+ + + {copyState === "copied" + ? "Prompt copied" + : copyState === "error" + ? "Prompt copy failed. Try again." + : ""} + +
+ ); +} diff --git a/showcase/shell-docs/src/content/docs/frontends/angular/webmcp.mdx b/showcase/shell-docs/src/content/docs/frontends/angular/webmcp.mdx new file mode 100644 index 0000000000..44376c97ec --- /dev/null +++ b/showcase/shell-docs/src/content/docs/frontends/angular/webmcp.mdx @@ -0,0 +1,82 @@ +--- +title: WebMCP +icon: "lucide/Globe2" +description: Expose Angular application actions as structured tools for compatible browser agents. +--- + +import { WebMCPOnboardingPrompt } from "@/components/webmcp-onboarding-prompt"; + +WebMCP lets your website declare typed JavaScript tools that compatible browser agents can discover and call. CopilotKit can publish the same frontend tool handler to your configured agent and to [`document.modelContext`](https://webmachinelearning.github.io/webmcp/). + + + + + WebMCP is a draft Community Group report. Chrome offers it through an origin + trial beginning in Chrome 149, or through the + `chrome://flags/#enable-webmcp-testing` flag for local development. Check the + [current Chrome setup instructions](https://developer.chrome.com/docs/ai/webmcp) + before testing. + + +## Do I need an agent? + +You do not need a CopilotKit backend agent to handle a WebMCP call. A compatible browser agent calls the frontend tool handler directly on the page, so the handler context has no `agent` in that path. + +If your application already registers the action as a CopilotKit frontend tool, add `webmcp`. Otherwise, wrap the smallest suitable browser-side action in a frontend tool. Keep any existing backend agent, but do not create one only for WebMCP. + +## Add WebMCP manually + +Call `registerFrontendTool` in an injection context and opt the tool into WebMCP: + +```ts title="src/app/order-search.component.ts" +import { Component } from "@angular/core"; +import { registerFrontendTool } from "@copilotkit/angular"; +import { z } from "zod"; + +@Component({ + selector: "app-order-search", + standalone: true, + template: "", +}) +export class OrderSearchComponent { + constructor() { + registerFrontendTool({ + name: "searchOrders", + description: "Search the signed-in user's orders by status", + parameters: z.object({ + status: z.enum(["open", "shipped", "delivered"]), + }), + handler: async ({ status }) => { + const orders = await searchOrders(status); + return JSON.stringify(orders); + }, + webmcp: { + annotations: { + readOnlyHint: true, + }, + }, + }); + } +} +``` + +The tool remains registered while the owning injector is alive. CopilotKit removes it from `document.modelContext` when that injector is destroyed or when the tool becomes unavailable. + +See the [`registerFrontendTool` reference](/reference/angular/functions/registerFrontendTool) for the full API. + +## Secure and test the tool + +- Give the tool and each parameter a specific description. +- Use `readOnlyHint` only for actions that cannot change state. +- Use `untrustedContentHint` when results may contain user-generated or external content. +- Enforce authentication, authorization, input validation, and required user confirmation in the handler or the API it calls. Annotations are hints, not policy. +- Remember that `agentId` does not restrict WebMCP access; WebMCP registrations are page-level. + +Open the application in Chrome 149 or newer with the origin trial or local flag enabled. The page must be origin-isolated, and cross-origin iframes need `allow="tools"`. Use Chrome's [Model Context Tool Inspector](https://developer.chrome.com/docs/ai/webmcp#imitate-agent-chat-with-the-inspector-extension) to inspect the schema, call the tool, and verify the complete user task. + +## Related + +- [Frontend tools and generative UI](guides/frontend-tools-generative-ui) +- [`registerFrontendTool` reference](/reference/angular/functions/registerFrontendTool) +- [WebMCP specification](https://webmachinelearning.github.io/webmcp/) +- [WebMCP tool security](https://developer.chrome.com/docs/ai/webmcp/secure-tools) diff --git a/showcase/shell-docs/src/content/docs/meta.json b/showcase/shell-docs/src/content/docs/meta.json index 91ff7709ee..21ea0aa071 100644 --- a/showcase/shell-docs/src/content/docs/meta.json +++ b/showcase/shell-docs/src/content/docs/meta.json @@ -32,6 +32,7 @@ "...generative-ui", "---Add Agent Powers---", "frontend-tools", + "webmcp", { "title": "Shared State", "pages": [ diff --git a/showcase/shell-docs/src/content/docs/webmcp.mdx b/showcase/shell-docs/src/content/docs/webmcp.mdx new file mode 100644 index 0000000000..83e17a43b4 --- /dev/null +++ b/showcase/shell-docs/src/content/docs/webmcp.mdx @@ -0,0 +1,149 @@ +--- +title: WebMCP +icon: "lucide/Globe2" +description: Expose browser-side actions as structured tools that compatible agents can discover and call. +--- + +import { WebMCPOnboardingPrompt } from "@/components/webmcp-onboarding-prompt"; + +WebMCP lets your website tell compatible browser agents what they can do. Instead of guessing which buttons to click, an agent discovers a named tool with a description, a typed input schema, and a JavaScript handler. + +CopilotKit can publish an existing frontend tool to [`document.modelContext`](https://webmachinelearning.github.io/webmcp/). The same handler then works for your CopilotKit agent and for WebMCP-aware browser agents. + + + + + WebMCP is a draft Community Group report, not a W3C Standard. Chrome offers + it through an origin trial beginning in Chrome 149, or through the + `chrome://flags/#enable-webmcp-testing` flag for local development. CopilotKit + safely does nothing when `document.modelContext` is unavailable. Check the + [current Chrome setup instructions](https://developer.chrome.com/docs/ai/webmcp) + before testing. + + +## Do I need an agent? + +You do not need a CopilotKit backend agent to handle a WebMCP call. A compatible browser agent calls the frontend tool handler directly on the page; in that path, the handler context has no `agent`. + +Choose the smallest path that fits your app: + +| What your app has today | What to do | +| --- | --- | +| A CopilotKit frontend tool for the action | Add `webmcp: true`, or add annotations with `webmcp: { annotations: ... }`. | +| CopilotKit, but no frontend tool for the action | Wrap the smallest suitable browser-side action in a frontend tool, then opt it into WebMCP. | +| A backend agent | Keep it. The tool can remain available to that agent, but WebMCP calls do not pass through it. | +| No backend agent | Use `CopilotKitCore` directly in browser code, or let the setup prompt add the appropriate frontend integration. Do not create an agent only for WebMCP. | + +React Native does not expose `document.modelContext`, so WebMCP registration is a no-op there. CopilotKit currently supports this WebMCP option in its browser integrations for React, Vue, Angular, and direct core usage. + +## How CopilotKit connects WebMCP + +1. Your app registers a CopilotKit frontend tool with `webmcp` enabled. +2. CopilotKit mirrors the tool's name, description, JSON Schema, annotations, and handler onto `document.modelContext`. +3. A compatible browser agent discovers the tool and calls the same JavaScript handler while the page is open. +4. CopilotKit unregisters the WebMCP tool when the frontend tool is removed or becomes unavailable. + +The WebMCP call stays in the browser unless your handler deliberately calls an API. CopilotKit does not route that call through a Runtime or backend agent. + +## Add WebMCP manually + +### Existing React frontend tool + +Add `webmcp` to the tool you already register. This code must run inside your existing `CopilotKitProvider`. + +```tsx title="OrderSearch.tsx" +"use client"; + +import { useFrontendTool } from "@copilotkit/react-core/v2"; +import { z } from "zod"; + +export function OrderSearch() { + useFrontendTool({ + name: "searchOrders", + description: "Search the signed-in user's orders by status", + parameters: z.object({ + status: z.enum(["open", "shipped", "delivered"]), + }), + handler: async ({ status }) => { + const orders = await searchOrders(status); + return JSON.stringify(orders); + }, + webmcp: { + annotations: { + readOnlyHint: true, + }, + }, + }); + + return null; +} +``` + +Use the equivalent option with [`useFrontendTool` for Vue](/reference/vue/hooks/useFrontendTool) or [`registerFrontendTool` for Angular](/reference/angular/functions/registerFrontendTool). The React API is documented in [`useFrontendTool`](/reference/hooks/useFrontendTool). + +### WebMCP only, with no agent + +For browser code that does not use a framework provider, register the frontend tool directly with the core. Keep the core instance alive for as long as the tool should remain available. + +```ts title="webmcp.ts" +import { CopilotKitCore } from "@copilotkit/core"; +import { z } from "zod"; + +export const copilotkit = new CopilotKitCore({ + tools: [ + { + name: "searchOrders", + description: "Search the signed-in user's orders by status", + parameters: z.object({ + status: z.enum(["open", "shipped", "delivered"]), + }), + handler: async ({ status }) => { + const orders = await searchOrders(status); + return JSON.stringify(orders); + }, + webmcp: { + annotations: { + readOnlyHint: true, + }, + }, + }, + ], +}); +``` + +This path does not configure a Runtime or an agent. It only registers browser-side tools through CopilotKit's core lifecycle. + +## Design tools agents can use reliably + +- Give every WebMCP tool a non-empty, specific `description`. CopilotKit skips WebMCP registration when it is missing. +- Keep each tool focused on one action and give every parameter a useful description. +- Use `readOnlyHint: true` only when the handler cannot change state. +- Use `untrustedContentHint: true` when results may contain user-generated or external content. +- Return concise, structured results that tell the caller what happened. +- Set the frontend tool to unavailable when the action cannot currently run; CopilotKit removes it from WebMCP until it is available again. + +Annotations are hints for browser agents, not security controls. Enforce authentication, authorization, validation, rate limits, and required user confirmation inside the handler or the API it calls. See Chrome's [WebMCP tool security guidance](https://developer.chrome.com/docs/ai/webmcp/secure-tools). + + + `agentId` limits which CopilotKit agent receives a frontend tool. WebMCP tools + are page-level, so `agentId` does not restrict browser-agent access. If + multiple opted-in tools share a name across agent IDs, CopilotKit exposes the + first one and logs a warning. + + +## Test the complete path + +1. Open Chrome 149 or newer and enable the WebMCP origin trial or local testing flag. +2. Load the app in an [origin-isolated document](https://developer.chrome.com/docs/ai/webmcp#origin-isolation). The `tools` permissions policy defaults to `self`; cross-origin iframes also need `allow="tools"`. +3. Confirm that `document.modelContext` exists. +4. Use Chrome's [Model Context Tool Inspector](https://developer.chrome.com/docs/ai/webmcp#imitate-agent-chat-with-the-inspector-extension) to confirm the tool name and schema, call it with representative inputs, and inspect its result. +5. Ask the inspector's agent to complete the user task in natural language. Verify that it chooses the right tool and that authentication and confirmation boundaries still hold. + +If the tool does not appear, check the browser setup first, then verify that the tool has a description, `webmcp` is enabled, and the frontend tool is currently available. + +## Related + +- [Frontend tools](/frontend-tools) +- [React `useFrontendTool` reference](/reference/hooks/useFrontendTool) +- [WebMCP specification](https://webmachinelearning.github.io/webmcp/) +- [Chrome WebMCP best practices](https://developer.chrome.com/docs/ai/webmcp/best-practices) diff --git a/showcase/shell-docs/src/lib/__tests__/webmcp-docs.test.ts b/showcase/shell-docs/src/lib/__tests__/webmcp-docs.test.ts new file mode 100644 index 0000000000..332102a484 --- /dev/null +++ b/showcase/shell-docs/src/lib/__tests__/webmcp-docs.test.ts @@ -0,0 +1,44 @@ +import { expect, test } from "vitest"; +import { loadDoc } from "../docs-render"; +import { renderPageToLlmText } from "../llm-text"; + +test("leads the WebMCP guide with repository-aware onboarding", () => { + const source = loadDoc("webmcp")?.source ?? ""; + const prompt = source.indexOf(""); + const manualSetup = source.indexOf("## Add WebMCP manually"); + + expect(prompt).toBeGreaterThan(-1); + expect(manualSetup).toBeGreaterThan(prompt); + expect(source).toContain("You do not need a CopilotKit backend agent"); + expect(source).toContain("React Native does not expose `document.modelContext`"); + expect(source).toContain("Chrome 149"); +}); + +test("expands the WebMCP onboarding CTA for Markdown and LLM readers", () => { + const doc = loadDoc("webmcp"); + if (!doc) throw new Error("WebMCP guide is missing"); + + const output = renderPageToLlmText({ + url: "webmcp", + title: doc.fm.title, + description: doc.fm.description, + filePath: doc.filePath, + loadSlug: "webmcp", + }); + + expect(output).toContain( + "npx --yes copilotkit@latest onboard start --coding-agent ", + ); + expect(output).toContain( + "The goal of this onboarding run is to get WebMCP working", + ); + expect(output).not.toContain(""); +}); + +test("provides an Angular-native WebMCP page for the frontend selector", () => { + const source = loadDoc("frontends/angular/webmcp")?.source ?? ""; + + expect(source).toContain("registerFrontendTool"); + expect(source).toContain("webmcp:"); + expect(source).not.toMatch(/\bReact\b/); +}); diff --git a/showcase/shell-docs/src/lib/__tests__/webmcp-onboarding-prompt-markdown.test.ts b/showcase/shell-docs/src/lib/__tests__/webmcp-onboarding-prompt-markdown.test.ts new file mode 100644 index 0000000000..bf212c4e51 --- /dev/null +++ b/showcase/shell-docs/src/lib/__tests__/webmcp-onboarding-prompt-markdown.test.ts @@ -0,0 +1,12 @@ +import { expect, test } from "vitest"; +import { createWebMCPOnboardingPrompt } from "../webmcp-onboarding-prompt"; + +test("keeps the Markdown prompt usable when no telemetry run id is available", () => { + const prompt = createWebMCPOnboardingPrompt(); + + expect(prompt).toContain( + "npx --yes copilotkit@latest onboard start --coding-agent ", + ); + expect(prompt).not.toContain("--run undefined"); + expect(prompt).not.toContain(""); +}); diff --git a/showcase/shell-docs/src/lib/__tests__/webmcp-onboarding-prompt.test.ts b/showcase/shell-docs/src/lib/__tests__/webmcp-onboarding-prompt.test.ts new file mode 100644 index 0000000000..5d91384763 --- /dev/null +++ b/showcase/shell-docs/src/lib/__tests__/webmcp-onboarding-prompt.test.ts @@ -0,0 +1,14 @@ +import { expect, test } from "vitest"; +import { createWebMCPOnboardingPrompt } from "../webmcp-onboarding-prompt"; + +test("keeps WebMCP as the goal of the CLI onboarding run", () => { + const prompt = createWebMCPOnboardingPrompt("0123456789ab"); + + expect(prompt).toBe(`Identify which coding-agent product you are, using a short slug such as \`codex\` or \`claude-code\`. From the root of the project where you want CopilotKit, run \`npx --yes copilotkit@latest onboard start --run 0123456789ab --coding-agent \`. Follow the Markdown instructions it prints until onboarding is complete. + +The goal of this onboarding run is to get WebMCP working in this project. Use https://docs.copilotkit.ai/webmcp as the official guide. Let the onboarding workflow inspect the repository and determine whether the app already has CopilotKit, a backend agent, CopilotKit frontend tools, or only browser-side actions. Ask only about choices the repository cannot answer. + +A WebMCP call does not require a CopilotKit backend agent. If suitable CopilotKit frontend tools already exist, expose only the appropriate ones through WebMCP. Otherwise, wrap the smallest suitable browser-side action in a supported CopilotKit frontend tool. Do not create or replace a backend agent solely for WebMCP. + +Preserve the existing framework, agent behavior, authentication, authorization, and user-confirmation boundaries. Follow the guide for schemas, annotations, browser requirements, and verification. Finish only after a compatible browser can discover and call the intended tool; if the selected surface cannot provide \`document.modelContext\`, explain that limitation instead of adding a fake integration.`); +}); diff --git a/showcase/shell-docs/src/lib/llm-text.ts b/showcase/shell-docs/src/lib/llm-text.ts index c379491e96..c54754cb3b 100644 --- a/showcase/shell-docs/src/lib/llm-text.ts +++ b/showcase/shell-docs/src/lib/llm-text.ts @@ -75,6 +75,7 @@ import { resolveDocsHref } from "./docs-link-rewrite"; import { resolveBundledSetupConcept } from "./setup-content"; import type { SetupContentBundle } from "./setup-content"; import { RICH_THREADS_SETUP_PROMPT } from "./rich-threads-setup-prompt"; +import { createWebMCPOnboardingPrompt } from "./webmcp-onboarding-prompt"; interface Region { file: string; @@ -766,6 +767,17 @@ function expandRichThreadsSetupPrompts(body: string): string { ); } +/** Expand the interactive WebMCP prompt for raw Markdown consumers. */ +function expandWebMCPOnboardingPrompts(body: string): string { + return body.replace( + //g, + `### Copy this prompt into your coding agent\n\n${fenceFor( + "text", + createWebMCPOnboardingPrompt(), + )}`, + ); +} + /** * Drop `` tags — these mount live iframes in the * browser; in plain markdown they're noise. Leave a short note so the @@ -899,6 +911,7 @@ export function renderPageToLlmText( // Interactive prompt buttons cannot run in raw Markdown or LLM feeds. body = expandRichThreadsSetupPrompts(body); + body = expandWebMCPOnboardingPrompts(body); // 1) Inline `` shared snippets (``, etc.). Uses // the SNIPPET_MAP / SUBPATH_TO_COMPONENT logic — same as the page diff --git a/showcase/shell-docs/src/lib/webmcp-onboarding-prompt.ts b/showcase/shell-docs/src/lib/webmcp-onboarding-prompt.ts new file mode 100644 index 0000000000..7abd57ab1a --- /dev/null +++ b/showcase/shell-docs/src/lib/webmcp-onboarding-prompt.ts @@ -0,0 +1,21 @@ +import { + createIntelligenceOnboardingPrompt, + INTELLIGENCE_ONBOARDING_PROMPT, +} from "./intelligence-onboarding-prompt"; + +export const WEBMCP_DOCS_URL = "https://docs.copilotkit.ai/webmcp"; + +/** Build the WebMCP goal that a docs reader hands to the CLI onboarding flow. */ +export function createWebMCPOnboardingPrompt(runId?: string): string { + const onboardingPrompt = runId + ? createIntelligenceOnboardingPrompt(runId) + : INTELLIGENCE_ONBOARDING_PROMPT.replace(" --run ", ""); + + return `${onboardingPrompt} + +The goal of this onboarding run is to get WebMCP working in this project. Use ${WEBMCP_DOCS_URL} as the official guide. Let the onboarding workflow inspect the repository and determine whether the app already has CopilotKit, a backend agent, CopilotKit frontend tools, or only browser-side actions. Ask only about choices the repository cannot answer. + +A WebMCP call does not require a CopilotKit backend agent. If suitable CopilotKit frontend tools already exist, expose only the appropriate ones through WebMCP. Otherwise, wrap the smallest suitable browser-side action in a supported CopilotKit frontend tool. Do not create or replace a backend agent solely for WebMCP. + +Preserve the existing framework, agent behavior, authentication, authorization, and user-confirmation boundaries. Follow the guide for schemas, annotations, browser requirements, and verification. Finish only after a compatible browser can discover and call the intended tool; if the selected surface cannot provide \`document.modelContext\`, explain that limitation instead of adding a fake integration.`; +} From 7ce4ab260d4a04c757d1d820f437152f48af4916 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Sep 2026 16:51:22 +0000 Subject: [PATCH 05/57] style: auto-fix formatting --- .../__tests__/webmcp-onboarding-prompt.test.tsx | 16 +++++++++++++--- .../src/components/webmcp-onboarding-prompt.tsx | 8 ++++---- .../src/lib/__tests__/webmcp-docs.test.ts | 4 +++- .../__tests__/webmcp-onboarding-prompt.test.ts | 3 ++- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/showcase/shell-docs/src/components/__tests__/webmcp-onboarding-prompt.test.tsx b/showcase/shell-docs/src/components/__tests__/webmcp-onboarding-prompt.test.tsx index b2f8feb885..9086bc3235 100644 --- a/showcase/shell-docs/src/components/__tests__/webmcp-onboarding-prompt.test.tsx +++ b/showcase/shell-docs/src/components/__tests__/webmcp-onboarding-prompt.test.tsx @@ -1,7 +1,13 @@ // @vitest-environment jsdom import React from "react"; -import { cleanup, fireEvent, render, screen, waitFor } from "@testing-library/react"; +import { + cleanup, + fireEvent, + render, + screen, + waitFor, +} from "@testing-library/react"; import { afterEach, expect, test, vi } from "vitest"; import { WebMCPOnboardingPrompt } from "../webmcp-onboarding-prompt"; import { INTELLIGENCE_ONBOARDING_EVENTS } from "@/lib/intelligence-onboarding-prompt"; @@ -39,8 +45,12 @@ test("copies a run-bound WebMCP goal into the CLI onboarding path", async () => )?.[1]; expect(runId).toBeTruthy(); - expect(prompt).toContain("The goal of this onboarding run is to get WebMCP working"); - expect(prompt).toContain("A WebMCP call does not require a CopilotKit backend agent"); + expect(prompt).toContain( + "The goal of this onboarding run is to get WebMCP working", + ); + expect(prompt).toContain( + "A WebMCP call does not require a CopilotKit backend agent", + ); expect(prompt).toContain("https://docs.copilotkit.ai/webmcp"); expect(screen.getByRole("button", { name: "Copied" })).toBeTruthy(); expect(screen.getByText("Prompt copied")).toBeTruthy(); diff --git a/showcase/shell-docs/src/components/webmcp-onboarding-prompt.tsx b/showcase/shell-docs/src/components/webmcp-onboarding-prompt.tsx index 72172697b5..5218f45956 100644 --- a/showcase/shell-docs/src/components/webmcp-onboarding-prompt.tsx +++ b/showcase/shell-docs/src/components/webmcp-onboarding-prompt.tsx @@ -111,10 +111,10 @@ export function WebMCPOnboardingPrompt(): React.JSX.Element { {isCopying ? "Copying…" : copyState === "copied" - ? "Copied" - : copyState === "error" - ? "Copy blocked" - : "Copy setup prompt"} + ? "Copied" + : copyState === "error" + ? "Copy blocked" + : "Copy setup prompt"}
diff --git a/showcase/shell-docs/src/lib/__tests__/webmcp-docs.test.ts b/showcase/shell-docs/src/lib/__tests__/webmcp-docs.test.ts index 332102a484..41ba67aafe 100644 --- a/showcase/shell-docs/src/lib/__tests__/webmcp-docs.test.ts +++ b/showcase/shell-docs/src/lib/__tests__/webmcp-docs.test.ts @@ -10,7 +10,9 @@ test("leads the WebMCP guide with repository-aware onboarding", () => { expect(prompt).toBeGreaterThan(-1); expect(manualSetup).toBeGreaterThan(prompt); expect(source).toContain("You do not need a CopilotKit backend agent"); - expect(source).toContain("React Native does not expose `document.modelContext`"); + expect(source).toContain( + "React Native does not expose `document.modelContext`", + ); expect(source).toContain("Chrome 149"); }); diff --git a/showcase/shell-docs/src/lib/__tests__/webmcp-onboarding-prompt.test.ts b/showcase/shell-docs/src/lib/__tests__/webmcp-onboarding-prompt.test.ts index 5d91384763..e2c1fa3997 100644 --- a/showcase/shell-docs/src/lib/__tests__/webmcp-onboarding-prompt.test.ts +++ b/showcase/shell-docs/src/lib/__tests__/webmcp-onboarding-prompt.test.ts @@ -4,7 +4,8 @@ import { createWebMCPOnboardingPrompt } from "../webmcp-onboarding-prompt"; test("keeps WebMCP as the goal of the CLI onboarding run", () => { const prompt = createWebMCPOnboardingPrompt("0123456789ab"); - expect(prompt).toBe(`Identify which coding-agent product you are, using a short slug such as \`codex\` or \`claude-code\`. From the root of the project where you want CopilotKit, run \`npx --yes copilotkit@latest onboard start --run 0123456789ab --coding-agent \`. Follow the Markdown instructions it prints until onboarding is complete. + expect(prompt) + .toBe(`Identify which coding-agent product you are, using a short slug such as \`codex\` or \`claude-code\`. From the root of the project where you want CopilotKit, run \`npx --yes copilotkit@latest onboard start --run 0123456789ab --coding-agent \`. Follow the Markdown instructions it prints until onboarding is complete. The goal of this onboarding run is to get WebMCP working in this project. Use https://docs.copilotkit.ai/webmcp as the official guide. Let the onboarding workflow inspect the repository and determine whether the app already has CopilotKit, a backend agent, CopilotKit frontend tools, or only browser-side actions. Ask only about choices the repository cannot answer. From 45e1e6ed7e576133c96693fea22826a383854f9a Mon Sep 17 00:00:00 2001 From: Tyler Slaton Date: Thu, 3 Sep 2026 10:05:00 -0700 Subject: [PATCH 06/57] docs(shell-docs): simplify WebMCP setup prompt --- ....test.tsx => webmcp-setup-prompt.test.tsx} | 32 +++++++------------ .../src/components/docs-page-view.tsx | 4 +-- ...ing-prompt.tsx => webmcp-setup-prompt.tsx} | 24 ++++++-------- .../content/docs/frontends/angular/webmcp.mdx | 4 +-- .../shell-docs/src/content/docs/webmcp.mdx | 4 +-- .../src/lib/__tests__/webmcp-docs.test.ts | 17 ++++------ .../webmcp-onboarding-prompt-markdown.test.ts | 12 ------- .../webmcp-onboarding-prompt.test.ts | 15 --------- .../lib/__tests__/webmcp-setup-prompt.test.ts | 9 ++++++ showcase/shell-docs/src/lib/llm-text.ts | 10 +++--- .../src/lib/webmcp-onboarding-prompt.ts | 21 ------------ .../shell-docs/src/lib/webmcp-setup-prompt.ts | 7 ++++ 12 files changed, 56 insertions(+), 103 deletions(-) rename showcase/shell-docs/src/components/__tests__/{webmcp-onboarding-prompt.test.tsx => webmcp-setup-prompt.test.tsx} (68%) rename showcase/shell-docs/src/components/{webmcp-onboarding-prompt.tsx => webmcp-setup-prompt.tsx} (82%) delete mode 100644 showcase/shell-docs/src/lib/__tests__/webmcp-onboarding-prompt-markdown.test.ts delete mode 100644 showcase/shell-docs/src/lib/__tests__/webmcp-onboarding-prompt.test.ts create mode 100644 showcase/shell-docs/src/lib/__tests__/webmcp-setup-prompt.test.ts delete mode 100644 showcase/shell-docs/src/lib/webmcp-onboarding-prompt.ts create mode 100644 showcase/shell-docs/src/lib/webmcp-setup-prompt.ts diff --git a/showcase/shell-docs/src/components/__tests__/webmcp-onboarding-prompt.test.tsx b/showcase/shell-docs/src/components/__tests__/webmcp-setup-prompt.test.tsx similarity index 68% rename from showcase/shell-docs/src/components/__tests__/webmcp-onboarding-prompt.test.tsx rename to showcase/shell-docs/src/components/__tests__/webmcp-setup-prompt.test.tsx index 9086bc3235..2bd4a676a2 100644 --- a/showcase/shell-docs/src/components/__tests__/webmcp-onboarding-prompt.test.tsx +++ b/showcase/shell-docs/src/components/__tests__/webmcp-setup-prompt.test.tsx @@ -9,8 +9,11 @@ import { waitFor, } from "@testing-library/react"; import { afterEach, expect, test, vi } from "vitest"; -import { WebMCPOnboardingPrompt } from "../webmcp-onboarding-prompt"; -import { INTELLIGENCE_ONBOARDING_EVENTS } from "@/lib/intelligence-onboarding-prompt"; +import { WebMCPSetupPrompt } from "../webmcp-setup-prompt"; +import { + WEBMCP_SETUP_EVENTS, + WEBMCP_SETUP_PROMPT, +} from "@/lib/webmcp-setup-prompt"; const analytics = vi.hoisted(() => ({ capture: vi.fn() })); @@ -27,39 +30,28 @@ afterEach(() => { vi.clearAllMocks(); }); -test("copies a run-bound WebMCP goal into the CLI onboarding path", async () => { +test("copies the standalone WebMCP setup prompt", async () => { const writeText = vi.fn().mockResolvedValue(undefined); Object.defineProperty(navigator, "clipboard", { configurable: true, value: { writeText }, }); - render(); + render(); fireEvent.click(screen.getByRole("button", { name: "Copy setup prompt" })); await waitFor(() => expect(writeText).toHaveBeenCalledTimes(1)); const prompt = writeText.mock.calls[0]?.[0] as string; - const runId = /onboard start --run ([0-9a-f]{12}) --coding-agent/.exec( - prompt, - )?.[1]; - - expect(runId).toBeTruthy(); - expect(prompt).toContain( - "The goal of this onboarding run is to get WebMCP working", - ); - expect(prompt).toContain( - "A WebMCP call does not require a CopilotKit backend agent", - ); - expect(prompt).toContain("https://docs.copilotkit.ai/webmcp"); + expect(prompt).toBe(WEBMCP_SETUP_PROMPT); + expect(prompt).not.toContain("onboard start"); expect(screen.getByRole("button", { name: "Copied" })).toBeTruthy(); expect(screen.getByText("Prompt copied")).toBeTruthy(); expect(analytics.capture).toHaveBeenCalledWith( - INTELLIGENCE_ONBOARDING_EVENTS.promptCopied, + WEBMCP_SETUP_EVENTS.promptCopied, { from_path: "/webmcp", - onboarding_run_id: runId, - surface: "docs_webmcp_onboarding_prompt", + surface: "docs_webmcp_setup_prompt", }, ); }); @@ -77,7 +69,7 @@ test("disables the CTA while the clipboard write is pending", async () => { value: { writeText }, }); - render(); + render(); const button = screen.getByRole("button", { name: "Copy setup prompt" }); fireEvent.click(button); diff --git a/showcase/shell-docs/src/components/docs-page-view.tsx b/showcase/shell-docs/src/components/docs-page-view.tsx index 2ddb156207..7ed9b3fa71 100644 --- a/showcase/shell-docs/src/components/docs-page-view.tsx +++ b/showcase/shell-docs/src/components/docs-page-view.tsx @@ -40,7 +40,7 @@ import type { OpsPlatformCTAProps } from "@/components/react/ops-platform-cta"; import { ChannelsStartPrompt } from "@/components/channels-start-prompt"; import type { ChannelsStartPromptProps } from "@/components/channels-start-prompt"; import { RichThreadsSetupPrompt } from "@/components/rich-threads-setup-prompt"; -import { WebMCPOnboardingPrompt } from "@/components/webmcp-onboarding-prompt"; +import { WebMCPSetupPrompt } from "@/components/webmcp-setup-prompt"; import { IntelligenceOnboardingPrompt } from "@/components/intelligence-onboarding-prompt"; import type { IntelligenceOnboardingPromptProps } from "@/components/intelligence-onboarding-prompt"; import { SignupLink } from "@/components/react/signup-link"; @@ -365,7 +365,7 @@ export async function DocsPageView({ /> ), RichThreadsSetupPrompt, - WebMCPOnboardingPrompt, + WebMCPSetupPrompt, IntelligenceOnboardingPrompt: IntelligenceOnboardingPromptMdx, OpsPlatformCTA: (props: OpsPlatformCTAProps) => ( diff --git a/showcase/shell-docs/src/components/webmcp-onboarding-prompt.tsx b/showcase/shell-docs/src/components/webmcp-setup-prompt.tsx similarity index 82% rename from showcase/shell-docs/src/components/webmcp-onboarding-prompt.tsx rename to showcase/shell-docs/src/components/webmcp-setup-prompt.tsx index 5218f45956..782c94dc08 100644 --- a/showcase/shell-docs/src/components/webmcp-onboarding-prompt.tsx +++ b/showcase/shell-docs/src/components/webmcp-setup-prompt.tsx @@ -5,17 +5,16 @@ import { Copy, SquareTerminal } from "lucide-react"; import { usePathname } from "next/navigation"; import { usePostHog } from "posthog-js/react"; import { - createOnboardingRunId, - INTELLIGENCE_ONBOARDING_EVENTS, -} from "@/lib/intelligence-onboarding-prompt"; -import { createWebMCPOnboardingPrompt } from "@/lib/webmcp-onboarding-prompt"; + WEBMCP_SETUP_EVENTS, + WEBMCP_SETUP_PROMPT, +} from "@/lib/webmcp-setup-prompt"; -const COPY_SURFACE = "docs_webmcp_onboarding_prompt"; +const COPY_SURFACE = "docs_webmcp_setup_prompt"; type CopyState = "idle" | "copied" | "error"; -/** Copyable WebMCP goal that enters the repository-aware CLI onboarding flow. */ -export function WebMCPOnboardingPrompt(): React.JSX.Element { +/** Copyable, standalone WebMCP setup prompt. */ +export function WebMCPSetupPrompt(): React.JSX.Element { const titleId = React.useId(); const pathname = usePathname(); const posthog = usePostHog(); @@ -47,10 +46,9 @@ export function WebMCPOnboardingPrompt(): React.JSX.Element { if (copyInFlightRef.current) return; copyInFlightRef.current = true; setIsCopying(true); - const runId = createOnboardingRunId(); try { - await navigator.clipboard.writeText(createWebMCPOnboardingPrompt(runId)); + await navigator.clipboard.writeText(WEBMCP_SETUP_PROMPT); } catch { if (mountedRef.current) { setCopyState("error"); @@ -67,9 +65,8 @@ export function WebMCPOnboardingPrompt(): React.JSX.Element { scheduleReset(1800); try { - posthog?.capture(INTELLIGENCE_ONBOARDING_EVENTS.promptCopied, { + posthog?.capture(WEBMCP_SETUP_EVENTS.promptCopied, { from_path: pathname, - onboarding_run_id: runId, surface: COPY_SURFACE, }); } catch { @@ -94,9 +91,8 @@ export function WebMCPOnboardingPrompt(): React.JSX.Element { Add WebMCP with your coding agent

- It inspects your app first, then reuses an existing CopilotKit - tool or wraps the smallest suitable browser action. WebMCP calls - do not run through a backend agent. + Copies a short prompt that points your coding agent to this guide + and asks it to verify the result.

diff --git a/showcase/shell-docs/src/content/docs/frontends/angular/webmcp.mdx b/showcase/shell-docs/src/content/docs/frontends/angular/webmcp.mdx index 44376c97ec..799f804933 100644 --- a/showcase/shell-docs/src/content/docs/frontends/angular/webmcp.mdx +++ b/showcase/shell-docs/src/content/docs/frontends/angular/webmcp.mdx @@ -4,11 +4,11 @@ icon: "lucide/Globe2" description: Expose Angular application actions as structured tools for compatible browser agents. --- -import { WebMCPOnboardingPrompt } from "@/components/webmcp-onboarding-prompt"; +import { WebMCPSetupPrompt } from "@/components/webmcp-setup-prompt"; WebMCP lets your website declare typed JavaScript tools that compatible browser agents can discover and call. CopilotKit can publish the same frontend tool handler to your configured agent and to [`document.modelContext`](https://webmachinelearning.github.io/webmcp/). - + WebMCP is a draft Community Group report. Chrome offers it through an origin diff --git a/showcase/shell-docs/src/content/docs/webmcp.mdx b/showcase/shell-docs/src/content/docs/webmcp.mdx index 83e17a43b4..1d2391e8b3 100644 --- a/showcase/shell-docs/src/content/docs/webmcp.mdx +++ b/showcase/shell-docs/src/content/docs/webmcp.mdx @@ -4,13 +4,13 @@ icon: "lucide/Globe2" description: Expose browser-side actions as structured tools that compatible agents can discover and call. --- -import { WebMCPOnboardingPrompt } from "@/components/webmcp-onboarding-prompt"; +import { WebMCPSetupPrompt } from "@/components/webmcp-setup-prompt"; WebMCP lets your website tell compatible browser agents what they can do. Instead of guessing which buttons to click, an agent discovers a named tool with a description, a typed input schema, and a JavaScript handler. CopilotKit can publish an existing frontend tool to [`document.modelContext`](https://webmachinelearning.github.io/webmcp/). The same handler then works for your CopilotKit agent and for WebMCP-aware browser agents. - + WebMCP is a draft Community Group report, not a W3C Standard. Chrome offers diff --git a/showcase/shell-docs/src/lib/__tests__/webmcp-docs.test.ts b/showcase/shell-docs/src/lib/__tests__/webmcp-docs.test.ts index 41ba67aafe..9dad995319 100644 --- a/showcase/shell-docs/src/lib/__tests__/webmcp-docs.test.ts +++ b/showcase/shell-docs/src/lib/__tests__/webmcp-docs.test.ts @@ -1,10 +1,11 @@ import { expect, test } from "vitest"; import { loadDoc } from "../docs-render"; import { renderPageToLlmText } from "../llm-text"; +import { WEBMCP_SETUP_PROMPT } from "../webmcp-setup-prompt"; -test("leads the WebMCP guide with repository-aware onboarding", () => { +test("leads the WebMCP guide with the standalone setup prompt", () => { const source = loadDoc("webmcp")?.source ?? ""; - const prompt = source.indexOf(""); + const prompt = source.indexOf(""); const manualSetup = source.indexOf("## Add WebMCP manually"); expect(prompt).toBeGreaterThan(-1); @@ -16,7 +17,7 @@ test("leads the WebMCP guide with repository-aware onboarding", () => { expect(source).toContain("Chrome 149"); }); -test("expands the WebMCP onboarding CTA for Markdown and LLM readers", () => { +test("expands the WebMCP setup CTA for Markdown and LLM readers", () => { const doc = loadDoc("webmcp"); if (!doc) throw new Error("WebMCP guide is missing"); @@ -28,13 +29,9 @@ test("expands the WebMCP onboarding CTA for Markdown and LLM readers", () => { loadSlug: "webmcp", }); - expect(output).toContain( - "npx --yes copilotkit@latest onboard start --coding-agent ", - ); - expect(output).toContain( - "The goal of this onboarding run is to get WebMCP working", - ); - expect(output).not.toContain(""); + expect(output).toContain(WEBMCP_SETUP_PROMPT); + expect(output).not.toContain("onboard start"); + expect(output).not.toContain(""); }); test("provides an Angular-native WebMCP page for the frontend selector", () => { diff --git a/showcase/shell-docs/src/lib/__tests__/webmcp-onboarding-prompt-markdown.test.ts b/showcase/shell-docs/src/lib/__tests__/webmcp-onboarding-prompt-markdown.test.ts deleted file mode 100644 index bf212c4e51..0000000000 --- a/showcase/shell-docs/src/lib/__tests__/webmcp-onboarding-prompt-markdown.test.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { expect, test } from "vitest"; -import { createWebMCPOnboardingPrompt } from "../webmcp-onboarding-prompt"; - -test("keeps the Markdown prompt usable when no telemetry run id is available", () => { - const prompt = createWebMCPOnboardingPrompt(); - - expect(prompt).toContain( - "npx --yes copilotkit@latest onboard start --coding-agent ", - ); - expect(prompt).not.toContain("--run undefined"); - expect(prompt).not.toContain(""); -}); diff --git a/showcase/shell-docs/src/lib/__tests__/webmcp-onboarding-prompt.test.ts b/showcase/shell-docs/src/lib/__tests__/webmcp-onboarding-prompt.test.ts deleted file mode 100644 index e2c1fa3997..0000000000 --- a/showcase/shell-docs/src/lib/__tests__/webmcp-onboarding-prompt.test.ts +++ /dev/null @@ -1,15 +0,0 @@ -import { expect, test } from "vitest"; -import { createWebMCPOnboardingPrompt } from "../webmcp-onboarding-prompt"; - -test("keeps WebMCP as the goal of the CLI onboarding run", () => { - const prompt = createWebMCPOnboardingPrompt("0123456789ab"); - - expect(prompt) - .toBe(`Identify which coding-agent product you are, using a short slug such as \`codex\` or \`claude-code\`. From the root of the project where you want CopilotKit, run \`npx --yes copilotkit@latest onboard start --run 0123456789ab --coding-agent \`. Follow the Markdown instructions it prints until onboarding is complete. - -The goal of this onboarding run is to get WebMCP working in this project. Use https://docs.copilotkit.ai/webmcp as the official guide. Let the onboarding workflow inspect the repository and determine whether the app already has CopilotKit, a backend agent, CopilotKit frontend tools, or only browser-side actions. Ask only about choices the repository cannot answer. - -A WebMCP call does not require a CopilotKit backend agent. If suitable CopilotKit frontend tools already exist, expose only the appropriate ones through WebMCP. Otherwise, wrap the smallest suitable browser-side action in a supported CopilotKit frontend tool. Do not create or replace a backend agent solely for WebMCP. - -Preserve the existing framework, agent behavior, authentication, authorization, and user-confirmation boundaries. Follow the guide for schemas, annotations, browser requirements, and verification. Finish only after a compatible browser can discover and call the intended tool; if the selected surface cannot provide \`document.modelContext\`, explain that limitation instead of adding a fake integration.`); -}); diff --git a/showcase/shell-docs/src/lib/__tests__/webmcp-setup-prompt.test.ts b/showcase/shell-docs/src/lib/__tests__/webmcp-setup-prompt.test.ts new file mode 100644 index 0000000000..838ff1cef6 --- /dev/null +++ b/showcase/shell-docs/src/lib/__tests__/webmcp-setup-prompt.test.ts @@ -0,0 +1,9 @@ +import { expect, test } from "vitest"; +import { WEBMCP_SETUP_PROMPT } from "../webmcp-setup-prompt"; + +test("keeps the standalone WebMCP setup prompt small and outcome-focused", () => { + expect(WEBMCP_SETUP_PROMPT).toBe( + "Set up WebMCP in this project using https://docs.copilotkit.ai/webmcp. Follow the guide and verify that a compatible browser can discover and call the tool.", + ); + expect(WEBMCP_SETUP_PROMPT).not.toContain("onboard"); +}); diff --git a/showcase/shell-docs/src/lib/llm-text.ts b/showcase/shell-docs/src/lib/llm-text.ts index c54754cb3b..6175a89d99 100644 --- a/showcase/shell-docs/src/lib/llm-text.ts +++ b/showcase/shell-docs/src/lib/llm-text.ts @@ -75,7 +75,7 @@ import { resolveDocsHref } from "./docs-link-rewrite"; import { resolveBundledSetupConcept } from "./setup-content"; import type { SetupContentBundle } from "./setup-content"; import { RICH_THREADS_SETUP_PROMPT } from "./rich-threads-setup-prompt"; -import { createWebMCPOnboardingPrompt } from "./webmcp-onboarding-prompt"; +import { WEBMCP_SETUP_PROMPT } from "./webmcp-setup-prompt"; interface Region { file: string; @@ -768,12 +768,12 @@ function expandRichThreadsSetupPrompts(body: string): string { } /** Expand the interactive WebMCP prompt for raw Markdown consumers. */ -function expandWebMCPOnboardingPrompts(body: string): string { +function expandWebMCPSetupPrompts(body: string): string { return body.replace( - //g, + //g, `### Copy this prompt into your coding agent\n\n${fenceFor( "text", - createWebMCPOnboardingPrompt(), + WEBMCP_SETUP_PROMPT, )}`, ); } @@ -911,7 +911,7 @@ export function renderPageToLlmText( // Interactive prompt buttons cannot run in raw Markdown or LLM feeds. body = expandRichThreadsSetupPrompts(body); - body = expandWebMCPOnboardingPrompts(body); + body = expandWebMCPSetupPrompts(body); // 1) Inline `` shared snippets (``, etc.). Uses // the SNIPPET_MAP / SUBPATH_TO_COMPONENT logic — same as the page diff --git a/showcase/shell-docs/src/lib/webmcp-onboarding-prompt.ts b/showcase/shell-docs/src/lib/webmcp-onboarding-prompt.ts deleted file mode 100644 index 7abd57ab1a..0000000000 --- a/showcase/shell-docs/src/lib/webmcp-onboarding-prompt.ts +++ /dev/null @@ -1,21 +0,0 @@ -import { - createIntelligenceOnboardingPrompt, - INTELLIGENCE_ONBOARDING_PROMPT, -} from "./intelligence-onboarding-prompt"; - -export const WEBMCP_DOCS_URL = "https://docs.copilotkit.ai/webmcp"; - -/** Build the WebMCP goal that a docs reader hands to the CLI onboarding flow. */ -export function createWebMCPOnboardingPrompt(runId?: string): string { - const onboardingPrompt = runId - ? createIntelligenceOnboardingPrompt(runId) - : INTELLIGENCE_ONBOARDING_PROMPT.replace(" --run ", ""); - - return `${onboardingPrompt} - -The goal of this onboarding run is to get WebMCP working in this project. Use ${WEBMCP_DOCS_URL} as the official guide. Let the onboarding workflow inspect the repository and determine whether the app already has CopilotKit, a backend agent, CopilotKit frontend tools, or only browser-side actions. Ask only about choices the repository cannot answer. - -A WebMCP call does not require a CopilotKit backend agent. If suitable CopilotKit frontend tools already exist, expose only the appropriate ones through WebMCP. Otherwise, wrap the smallest suitable browser-side action in a supported CopilotKit frontend tool. Do not create or replace a backend agent solely for WebMCP. - -Preserve the existing framework, agent behavior, authentication, authorization, and user-confirmation boundaries. Follow the guide for schemas, annotations, browser requirements, and verification. Finish only after a compatible browser can discover and call the intended tool; if the selected surface cannot provide \`document.modelContext\`, explain that limitation instead of adding a fake integration.`; -} diff --git a/showcase/shell-docs/src/lib/webmcp-setup-prompt.ts b/showcase/shell-docs/src/lib/webmcp-setup-prompt.ts new file mode 100644 index 0000000000..338554c30e --- /dev/null +++ b/showcase/shell-docs/src/lib/webmcp-setup-prompt.ts @@ -0,0 +1,7 @@ +export const WEBMCP_DOCS_URL = "https://docs.copilotkit.ai/webmcp"; + +export const WEBMCP_SETUP_EVENTS = { + promptCopied: "docs.webmcp_setup_prompt_copied", +} as const; + +export const WEBMCP_SETUP_PROMPT = `Set up WebMCP in this project using ${WEBMCP_DOCS_URL}. Follow the guide and verify that a compatible browser can discover and call the tool.`; From 91aeed423cfa2beebc524d6ac5e0d8cfe34223b3 Mon Sep 17 00:00:00 2001 From: Tyler Slaton Date: Thu, 3 Sep 2026 10:09:25 -0700 Subject: [PATCH 07/57] docs(shell-docs): make WebMCP guide universal --- .../__tests__/webmcp-setup-prompt.test.tsx | 88 ------------ .../src/components/docs-page-view.tsx | 2 - .../src/components/webmcp-setup-prompt.tsx | 126 ------------------ .../content/docs/frontends/angular/webmcp.mdx | 82 ------------ .../shell-docs/src/content/docs/webmcp.mdx | 7 +- .../src/lib/__tests__/webmcp-docs.test.ts | 43 ------ .../lib/__tests__/webmcp-setup-prompt.test.ts | 9 -- showcase/shell-docs/src/lib/llm-text.ts | 13 -- .../shell-docs/src/lib/webmcp-setup-prompt.ts | 7 - 9 files changed, 2 insertions(+), 375 deletions(-) delete mode 100644 showcase/shell-docs/src/components/__tests__/webmcp-setup-prompt.test.tsx delete mode 100644 showcase/shell-docs/src/components/webmcp-setup-prompt.tsx delete mode 100644 showcase/shell-docs/src/content/docs/frontends/angular/webmcp.mdx delete mode 100644 showcase/shell-docs/src/lib/__tests__/webmcp-docs.test.ts delete mode 100644 showcase/shell-docs/src/lib/__tests__/webmcp-setup-prompt.test.ts delete mode 100644 showcase/shell-docs/src/lib/webmcp-setup-prompt.ts diff --git a/showcase/shell-docs/src/components/__tests__/webmcp-setup-prompt.test.tsx b/showcase/shell-docs/src/components/__tests__/webmcp-setup-prompt.test.tsx deleted file mode 100644 index 2bd4a676a2..0000000000 --- a/showcase/shell-docs/src/components/__tests__/webmcp-setup-prompt.test.tsx +++ /dev/null @@ -1,88 +0,0 @@ -// @vitest-environment jsdom - -import React from "react"; -import { - cleanup, - fireEvent, - render, - screen, - waitFor, -} from "@testing-library/react"; -import { afterEach, expect, test, vi } from "vitest"; -import { WebMCPSetupPrompt } from "../webmcp-setup-prompt"; -import { - WEBMCP_SETUP_EVENTS, - WEBMCP_SETUP_PROMPT, -} from "@/lib/webmcp-setup-prompt"; - -const analytics = vi.hoisted(() => ({ capture: vi.fn() })); - -vi.mock("next/navigation", () => ({ - usePathname: () => "/webmcp", -})); - -vi.mock("posthog-js/react", () => ({ - usePostHog: () => analytics, -})); - -afterEach(() => { - cleanup(); - vi.clearAllMocks(); -}); - -test("copies the standalone WebMCP setup prompt", async () => { - const writeText = vi.fn().mockResolvedValue(undefined); - Object.defineProperty(navigator, "clipboard", { - configurable: true, - value: { writeText }, - }); - - render(); - fireEvent.click(screen.getByRole("button", { name: "Copy setup prompt" })); - - await waitFor(() => expect(writeText).toHaveBeenCalledTimes(1)); - - const prompt = writeText.mock.calls[0]?.[0] as string; - expect(prompt).toBe(WEBMCP_SETUP_PROMPT); - expect(prompt).not.toContain("onboard start"); - expect(screen.getByRole("button", { name: "Copied" })).toBeTruthy(); - expect(screen.getByText("Prompt copied")).toBeTruthy(); - expect(analytics.capture).toHaveBeenCalledWith( - WEBMCP_SETUP_EVENTS.promptCopied, - { - from_path: "/webmcp", - surface: "docs_webmcp_setup_prompt", - }, - ); -}); - -test("disables the CTA while the clipboard write is pending", async () => { - let finishCopy: (() => void) | undefined; - const writeText = vi.fn( - () => - new Promise((resolve) => { - finishCopy = resolve; - }), - ); - Object.defineProperty(navigator, "clipboard", { - configurable: true, - value: { writeText }, - }); - - render(); - const button = screen.getByRole("button", { name: "Copy setup prompt" }); - - fireEvent.click(button); - - await waitFor(() => expect(button).toHaveProperty("disabled", true)); - fireEvent.click(button); - expect(writeText).toHaveBeenCalledTimes(1); - - finishCopy?.(); - await waitFor(() => - expect(screen.getByRole("button", { name: "Copied" })).toHaveProperty( - "disabled", - false, - ), - ); -}); diff --git a/showcase/shell-docs/src/components/docs-page-view.tsx b/showcase/shell-docs/src/components/docs-page-view.tsx index 7ed9b3fa71..bb06a3c455 100644 --- a/showcase/shell-docs/src/components/docs-page-view.tsx +++ b/showcase/shell-docs/src/components/docs-page-view.tsx @@ -40,7 +40,6 @@ import type { OpsPlatformCTAProps } from "@/components/react/ops-platform-cta"; import { ChannelsStartPrompt } from "@/components/channels-start-prompt"; import type { ChannelsStartPromptProps } from "@/components/channels-start-prompt"; import { RichThreadsSetupPrompt } from "@/components/rich-threads-setup-prompt"; -import { WebMCPSetupPrompt } from "@/components/webmcp-setup-prompt"; import { IntelligenceOnboardingPrompt } from "@/components/intelligence-onboarding-prompt"; import type { IntelligenceOnboardingPromptProps } from "@/components/intelligence-onboarding-prompt"; import { SignupLink } from "@/components/react/signup-link"; @@ -365,7 +364,6 @@ export async function DocsPageView({ /> ), RichThreadsSetupPrompt, - WebMCPSetupPrompt, IntelligenceOnboardingPrompt: IntelligenceOnboardingPromptMdx, OpsPlatformCTA: (props: OpsPlatformCTAProps) => ( diff --git a/showcase/shell-docs/src/components/webmcp-setup-prompt.tsx b/showcase/shell-docs/src/components/webmcp-setup-prompt.tsx deleted file mode 100644 index 782c94dc08..0000000000 --- a/showcase/shell-docs/src/components/webmcp-setup-prompt.tsx +++ /dev/null @@ -1,126 +0,0 @@ -"use client"; - -import React from "react"; -import { Copy, SquareTerminal } from "lucide-react"; -import { usePathname } from "next/navigation"; -import { usePostHog } from "posthog-js/react"; -import { - WEBMCP_SETUP_EVENTS, - WEBMCP_SETUP_PROMPT, -} from "@/lib/webmcp-setup-prompt"; - -const COPY_SURFACE = "docs_webmcp_setup_prompt"; - -type CopyState = "idle" | "copied" | "error"; - -/** Copyable, standalone WebMCP setup prompt. */ -export function WebMCPSetupPrompt(): React.JSX.Element { - const titleId = React.useId(); - const pathname = usePathname(); - const posthog = usePostHog(); - const [copyState, setCopyState] = React.useState("idle"); - const [isCopying, setIsCopying] = React.useState(false); - const copyInFlightRef = React.useRef(false); - const resetTimerRef = React.useRef | null>( - null, - ); - const mountedRef = React.useRef(true); - - React.useEffect( - () => () => { - mountedRef.current = false; - if (resetTimerRef.current) clearTimeout(resetTimerRef.current); - }, - [], - ); - - function scheduleReset(delayMs: number): void { - if (resetTimerRef.current) clearTimeout(resetTimerRef.current); - resetTimerRef.current = setTimeout(() => { - if (mountedRef.current) setCopyState("idle"); - resetTimerRef.current = null; - }, delayMs); - } - - async function copyPrompt(): Promise { - if (copyInFlightRef.current) return; - copyInFlightRef.current = true; - setIsCopying(true); - - try { - await navigator.clipboard.writeText(WEBMCP_SETUP_PROMPT); - } catch { - if (mountedRef.current) { - setCopyState("error"); - scheduleReset(2600); - } - return; - } finally { - copyInFlightRef.current = false; - if (mountedRef.current) setIsCopying(false); - } - - if (!mountedRef.current) return; - setCopyState("copied"); - scheduleReset(1800); - - try { - posthog?.capture(WEBMCP_SETUP_EVENTS.promptCopied, { - from_path: pathname, - surface: COPY_SURFACE, - }); - } catch { - // Analytics must never change the result of a successful clipboard write. - } - } - - return ( -
-
-
-
- - -
- - - {copyState === "copied" - ? "Prompt copied" - : copyState === "error" - ? "Prompt copy failed. Try again." - : ""} - -
- ); -} diff --git a/showcase/shell-docs/src/content/docs/frontends/angular/webmcp.mdx b/showcase/shell-docs/src/content/docs/frontends/angular/webmcp.mdx deleted file mode 100644 index 799f804933..0000000000 --- a/showcase/shell-docs/src/content/docs/frontends/angular/webmcp.mdx +++ /dev/null @@ -1,82 +0,0 @@ ---- -title: WebMCP -icon: "lucide/Globe2" -description: Expose Angular application actions as structured tools for compatible browser agents. ---- - -import { WebMCPSetupPrompt } from "@/components/webmcp-setup-prompt"; - -WebMCP lets your website declare typed JavaScript tools that compatible browser agents can discover and call. CopilotKit can publish the same frontend tool handler to your configured agent and to [`document.modelContext`](https://webmachinelearning.github.io/webmcp/). - - - - - WebMCP is a draft Community Group report. Chrome offers it through an origin - trial beginning in Chrome 149, or through the - `chrome://flags/#enable-webmcp-testing` flag for local development. Check the - [current Chrome setup instructions](https://developer.chrome.com/docs/ai/webmcp) - before testing. - - -## Do I need an agent? - -You do not need a CopilotKit backend agent to handle a WebMCP call. A compatible browser agent calls the frontend tool handler directly on the page, so the handler context has no `agent` in that path. - -If your application already registers the action as a CopilotKit frontend tool, add `webmcp`. Otherwise, wrap the smallest suitable browser-side action in a frontend tool. Keep any existing backend agent, but do not create one only for WebMCP. - -## Add WebMCP manually - -Call `registerFrontendTool` in an injection context and opt the tool into WebMCP: - -```ts title="src/app/order-search.component.ts" -import { Component } from "@angular/core"; -import { registerFrontendTool } from "@copilotkit/angular"; -import { z } from "zod"; - -@Component({ - selector: "app-order-search", - standalone: true, - template: "", -}) -export class OrderSearchComponent { - constructor() { - registerFrontendTool({ - name: "searchOrders", - description: "Search the signed-in user's orders by status", - parameters: z.object({ - status: z.enum(["open", "shipped", "delivered"]), - }), - handler: async ({ status }) => { - const orders = await searchOrders(status); - return JSON.stringify(orders); - }, - webmcp: { - annotations: { - readOnlyHint: true, - }, - }, - }); - } -} -``` - -The tool remains registered while the owning injector is alive. CopilotKit removes it from `document.modelContext` when that injector is destroyed or when the tool becomes unavailable. - -See the [`registerFrontendTool` reference](/reference/angular/functions/registerFrontendTool) for the full API. - -## Secure and test the tool - -- Give the tool and each parameter a specific description. -- Use `readOnlyHint` only for actions that cannot change state. -- Use `untrustedContentHint` when results may contain user-generated or external content. -- Enforce authentication, authorization, input validation, and required user confirmation in the handler or the API it calls. Annotations are hints, not policy. -- Remember that `agentId` does not restrict WebMCP access; WebMCP registrations are page-level. - -Open the application in Chrome 149 or newer with the origin trial or local flag enabled. The page must be origin-isolated, and cross-origin iframes need `allow="tools"`. Use Chrome's [Model Context Tool Inspector](https://developer.chrome.com/docs/ai/webmcp#imitate-agent-chat-with-the-inspector-extension) to inspect the schema, call the tool, and verify the complete user task. - -## Related - -- [Frontend tools and generative UI](guides/frontend-tools-generative-ui) -- [`registerFrontendTool` reference](/reference/angular/functions/registerFrontendTool) -- [WebMCP specification](https://webmachinelearning.github.io/webmcp/) -- [WebMCP tool security](https://developer.chrome.com/docs/ai/webmcp/secure-tools) diff --git a/showcase/shell-docs/src/content/docs/webmcp.mdx b/showcase/shell-docs/src/content/docs/webmcp.mdx index 1d2391e8b3..c06d5b28d0 100644 --- a/showcase/shell-docs/src/content/docs/webmcp.mdx +++ b/showcase/shell-docs/src/content/docs/webmcp.mdx @@ -2,16 +2,13 @@ title: WebMCP icon: "lucide/Globe2" description: Expose browser-side actions as structured tools that compatible agents can discover and call. +frontend: universal --- -import { WebMCPSetupPrompt } from "@/components/webmcp-setup-prompt"; - WebMCP lets your website tell compatible browser agents what they can do. Instead of guessing which buttons to click, an agent discovers a named tool with a description, a typed input schema, and a JavaScript handler. CopilotKit can publish an existing frontend tool to [`document.modelContext`](https://webmachinelearning.github.io/webmcp/). The same handler then works for your CopilotKit agent and for WebMCP-aware browser agents. - - WebMCP is a draft Community Group report, not a W3C Standard. Chrome offers it through an origin trial beginning in Chrome 149, or through the @@ -32,7 +29,7 @@ Choose the smallest path that fits your app: | A CopilotKit frontend tool for the action | Add `webmcp: true`, or add annotations with `webmcp: { annotations: ... }`. | | CopilotKit, but no frontend tool for the action | Wrap the smallest suitable browser-side action in a frontend tool, then opt it into WebMCP. | | A backend agent | Keep it. The tool can remain available to that agent, but WebMCP calls do not pass through it. | -| No backend agent | Use `CopilotKitCore` directly in browser code, or let the setup prompt add the appropriate frontend integration. Do not create an agent only for WebMCP. | +| No backend agent | Use `CopilotKitCore` directly in browser code, or add the appropriate frontend integration. Do not create an agent only for WebMCP. | React Native does not expose `document.modelContext`, so WebMCP registration is a no-op there. CopilotKit currently supports this WebMCP option in its browser integrations for React, Vue, Angular, and direct core usage. diff --git a/showcase/shell-docs/src/lib/__tests__/webmcp-docs.test.ts b/showcase/shell-docs/src/lib/__tests__/webmcp-docs.test.ts deleted file mode 100644 index 9dad995319..0000000000 --- a/showcase/shell-docs/src/lib/__tests__/webmcp-docs.test.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { expect, test } from "vitest"; -import { loadDoc } from "../docs-render"; -import { renderPageToLlmText } from "../llm-text"; -import { WEBMCP_SETUP_PROMPT } from "../webmcp-setup-prompt"; - -test("leads the WebMCP guide with the standalone setup prompt", () => { - const source = loadDoc("webmcp")?.source ?? ""; - const prompt = source.indexOf(""); - const manualSetup = source.indexOf("## Add WebMCP manually"); - - expect(prompt).toBeGreaterThan(-1); - expect(manualSetup).toBeGreaterThan(prompt); - expect(source).toContain("You do not need a CopilotKit backend agent"); - expect(source).toContain( - "React Native does not expose `document.modelContext`", - ); - expect(source).toContain("Chrome 149"); -}); - -test("expands the WebMCP setup CTA for Markdown and LLM readers", () => { - const doc = loadDoc("webmcp"); - if (!doc) throw new Error("WebMCP guide is missing"); - - const output = renderPageToLlmText({ - url: "webmcp", - title: doc.fm.title, - description: doc.fm.description, - filePath: doc.filePath, - loadSlug: "webmcp", - }); - - expect(output).toContain(WEBMCP_SETUP_PROMPT); - expect(output).not.toContain("onboard start"); - expect(output).not.toContain(""); -}); - -test("provides an Angular-native WebMCP page for the frontend selector", () => { - const source = loadDoc("frontends/angular/webmcp")?.source ?? ""; - - expect(source).toContain("registerFrontendTool"); - expect(source).toContain("webmcp:"); - expect(source).not.toMatch(/\bReact\b/); -}); diff --git a/showcase/shell-docs/src/lib/__tests__/webmcp-setup-prompt.test.ts b/showcase/shell-docs/src/lib/__tests__/webmcp-setup-prompt.test.ts deleted file mode 100644 index 838ff1cef6..0000000000 --- a/showcase/shell-docs/src/lib/__tests__/webmcp-setup-prompt.test.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { expect, test } from "vitest"; -import { WEBMCP_SETUP_PROMPT } from "../webmcp-setup-prompt"; - -test("keeps the standalone WebMCP setup prompt small and outcome-focused", () => { - expect(WEBMCP_SETUP_PROMPT).toBe( - "Set up WebMCP in this project using https://docs.copilotkit.ai/webmcp. Follow the guide and verify that a compatible browser can discover and call the tool.", - ); - expect(WEBMCP_SETUP_PROMPT).not.toContain("onboard"); -}); diff --git a/showcase/shell-docs/src/lib/llm-text.ts b/showcase/shell-docs/src/lib/llm-text.ts index 6175a89d99..c379491e96 100644 --- a/showcase/shell-docs/src/lib/llm-text.ts +++ b/showcase/shell-docs/src/lib/llm-text.ts @@ -75,7 +75,6 @@ import { resolveDocsHref } from "./docs-link-rewrite"; import { resolveBundledSetupConcept } from "./setup-content"; import type { SetupContentBundle } from "./setup-content"; import { RICH_THREADS_SETUP_PROMPT } from "./rich-threads-setup-prompt"; -import { WEBMCP_SETUP_PROMPT } from "./webmcp-setup-prompt"; interface Region { file: string; @@ -767,17 +766,6 @@ function expandRichThreadsSetupPrompts(body: string): string { ); } -/** Expand the interactive WebMCP prompt for raw Markdown consumers. */ -function expandWebMCPSetupPrompts(body: string): string { - return body.replace( - //g, - `### Copy this prompt into your coding agent\n\n${fenceFor( - "text", - WEBMCP_SETUP_PROMPT, - )}`, - ); -} - /** * Drop `` tags — these mount live iframes in the * browser; in plain markdown they're noise. Leave a short note so the @@ -911,7 +899,6 @@ export function renderPageToLlmText( // Interactive prompt buttons cannot run in raw Markdown or LLM feeds. body = expandRichThreadsSetupPrompts(body); - body = expandWebMCPSetupPrompts(body); // 1) Inline `` shared snippets (``, etc.). Uses // the SNIPPET_MAP / SUBPATH_TO_COMPONENT logic — same as the page diff --git a/showcase/shell-docs/src/lib/webmcp-setup-prompt.ts b/showcase/shell-docs/src/lib/webmcp-setup-prompt.ts deleted file mode 100644 index 338554c30e..0000000000 --- a/showcase/shell-docs/src/lib/webmcp-setup-prompt.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const WEBMCP_DOCS_URL = "https://docs.copilotkit.ai/webmcp"; - -export const WEBMCP_SETUP_EVENTS = { - promptCopied: "docs.webmcp_setup_prompt_copied", -} as const; - -export const WEBMCP_SETUP_PROMPT = `Set up WebMCP in this project using ${WEBMCP_DOCS_URL}. Follow the guide and verify that a compatible browser can discover and call the tool.`; From 46225f7c96ce55a122178bc9b135bed899ce40b5 Mon Sep 17 00:00:00 2001 From: Tyler Slaton Date: Thu, 3 Sep 2026 10:34:41 -0700 Subject: [PATCH 08/57] docs(shell-docs): add WebMCP prompt CTA --- .../src/components/docs-page-tools.tsx | 25 +++++++++++-------- .../src/components/docs-page-view.tsx | 1 + .../shell-docs/src/content/docs/webmcp.mdx | 16 ++++++++++++ 3 files changed, 32 insertions(+), 10 deletions(-) diff --git a/showcase/shell-docs/src/components/docs-page-tools.tsx b/showcase/shell-docs/src/components/docs-page-tools.tsx index 2d1c215d1f..2e54bf904a 100644 --- a/showcase/shell-docs/src/components/docs-page-tools.tsx +++ b/showcase/shell-docs/src/components/docs-page-tools.tsx @@ -7,11 +7,11 @@ // whole nav tree, so asserting the row's contents through it would mean // standing up most of the docs pipeline. // -// Every page that renders this row gets the onboarding button. `DocsPageView` -// is only reached by docs surfaces, and the button's offer — set CopilotKit up -// in this project — holds on all of them. Earlier revisions gated it on the -// caller naming a framework, which made identical pages behave differently -// depending on the URL the reader arrived through. +// Pages get the onboarding button by default. A page with its own focused +// prompt CTA can hide that one action while keeping the Markdown and LLM +// tools. Earlier revisions gated it on the caller naming a framework, which +// made identical pages behave differently depending on the URL the reader +// arrived through. import React from "react"; import { @@ -41,6 +41,8 @@ export interface DocsPageToolsProps { * framework, so the CLI's graph has to ask for neither selection. */ onboardingFrontend?: { id: string; name: string }; + /** Hide the generic onboarding prompt when the page provides its own CTA. */ + hideOnboardingPrompt?: boolean; } /** @@ -66,15 +68,18 @@ export function DocsPageTools({ githubUrl, onboardingFramework, onboardingFrontend, + hideOnboardingPrompt = false, }: DocsPageToolsProps): React.JSX.Element { const markdownUrl = docsMarkdownUrl(slugHrefPrefix, slugPath); return (
- + {!hideOnboardingPrompt && ( + + )}
diff --git a/showcase/shell-docs/src/components/docs-page-view.tsx b/showcase/shell-docs/src/components/docs-page-view.tsx index bb06a3c455..ab59411f0a 100644 --- a/showcase/shell-docs/src/components/docs-page-view.tsx +++ b/showcase/shell-docs/src/components/docs-page-view.tsx @@ -320,6 +320,7 @@ export async function DocsPageView({ githubUrl={buildGitHubUrl(doc.filePath)} onboardingFramework={onboardingFramework} onboardingFrontend={onboardingFrontend} + hideOnboardingPrompt={slugPath === "webmcp"} /> {/* Thin divider between the page-actions row and the page body diff --git a/showcase/shell-docs/src/content/docs/webmcp.mdx b/showcase/shell-docs/src/content/docs/webmcp.mdx index c06d5b28d0..a7c6057264 100644 --- a/showcase/shell-docs/src/content/docs/webmcp.mdx +++ b/showcase/shell-docs/src/content/docs/webmcp.mdx @@ -5,6 +5,22 @@ description: Expose browser-side actions as structured tools that compatible age frontend: universal --- + + + + +```text +Set up WebMCP in this project using https://docs.copilotkit.ai/webmcp. First inspect the app and extend its existing CopilotKit setup if present; do not add a backend agent solely for WebMCP. If I haven’t specified a tool, ask what I want to expose. If I don’t have one in mind, add a small, read-only demo tool that fits the app. Finish by verifying that a compatible browser can discover and call it. +``` + + + + + WebMCP lets your website tell compatible browser agents what they can do. Instead of guessing which buttons to click, an agent discovers a named tool with a description, a typed input schema, and a JavaScript handler. CopilotKit can publish an existing frontend tool to [`document.modelContext`](https://webmachinelearning.github.io/webmcp/). The same handler then works for your CopilotKit agent and for WebMCP-aware browser agents. From fdd4e33a6c716bfb62c33c39b1913f7d13bed8ff Mon Sep 17 00:00:00 2001 From: Tyler Slaton Date: Thu, 3 Sep 2026 10:45:16 -0700 Subject: [PATCH 09/57] docs(shell-docs): refine WebMCP prompt CTA --- .../src/components/webmcp-setup-prompt.tsx | 73 +++++++++++++++++++ .../shell-docs/src/content/docs/webmcp.mdx | 16 +--- showcase/shell-docs/src/lib/mdx-registry.tsx | 2 + 3 files changed, 79 insertions(+), 12 deletions(-) create mode 100644 showcase/shell-docs/src/components/webmcp-setup-prompt.tsx diff --git a/showcase/shell-docs/src/components/webmcp-setup-prompt.tsx b/showcase/shell-docs/src/components/webmcp-setup-prompt.tsx new file mode 100644 index 0000000000..13e8257cce --- /dev/null +++ b/showcase/shell-docs/src/components/webmcp-setup-prompt.tsx @@ -0,0 +1,73 @@ +"use client"; + +import React from "react"; +import { ChevronRight } from "lucide-react"; + +export const WEBMCP_SETUP_PROMPT = + "Set up WebMCP in this project using https://docs.copilotkit.ai/webmcp. First inspect the app and extend its existing CopilotKit setup if present; do not add a backend agent solely for WebMCP. If I haven’t specified a tool, ask what I want to expose. If I don’t have one in mind, add a small, read-only demo tool that fits the app. Finish by verifying that a compatible browser can discover and call it."; + +type CopyState = "idle" | "copied" | "error"; + +export function WebMCPSetupPrompt(): React.JSX.Element { + const [copyState, setCopyState] = React.useState("idle"); + const resetTimerRef = React.useRef | null>( + null, + ); + + React.useEffect( + () => () => { + if (resetTimerRef.current) clearTimeout(resetTimerRef.current); + }, + [], + ); + + async function copyPrompt(): Promise { + if (resetTimerRef.current) clearTimeout(resetTimerRef.current); + + try { + await navigator.clipboard.writeText(WEBMCP_SETUP_PROMPT); + setCopyState("copied"); + resetTimerRef.current = setTimeout(() => setCopyState("idle"), 1800); + } catch { + setCopyState("error"); + resetTimerRef.current = setTimeout(() => setCopyState("idle"), 2600); + } + } + + return ( +
+
+
+ + + + + {copyState === "copied" + ? "Prompt copied" + : copyState === "error" + ? "Prompt copy failed. Try again." + : ""} + +
+ ); +} diff --git a/showcase/shell-docs/src/content/docs/webmcp.mdx b/showcase/shell-docs/src/content/docs/webmcp.mdx index a7c6057264..dc8b1c38b7 100644 --- a/showcase/shell-docs/src/content/docs/webmcp.mdx +++ b/showcase/shell-docs/src/content/docs/webmcp.mdx @@ -5,21 +5,13 @@ description: Expose browser-side actions as structured tools that compatible age frontend: universal --- - +import { WebMCPSetupPrompt } from "@/components/webmcp-setup-prompt"; - +## Setup with a coding agent -```text -Set up WebMCP in this project using https://docs.copilotkit.ai/webmcp. First inspect the app and extend its existing CopilotKit setup if present; do not add a backend agent solely for WebMCP. If I haven’t specified a tool, ask what I want to expose. If I don’t have one in mind, add a small, read-only demo tool that fits the app. Finish by verifying that a compatible browser can discover and call it. -``` +Use this pre-built prompt to add WebMCP to your project. Your coding agent will adapt the implementation to your app and verify that a compatible browser can discover and call the tool. - - - + WebMCP lets your website tell compatible browser agents what they can do. Instead of guessing which buttons to click, an agent discovers a named tool with a description, a typed input schema, and a JavaScript handler. diff --git a/showcase/shell-docs/src/lib/mdx-registry.tsx b/showcase/shell-docs/src/lib/mdx-registry.tsx index 0ea906de8c..c0f12af39a 100644 --- a/showcase/shell-docs/src/lib/mdx-registry.tsx +++ b/showcase/shell-docs/src/lib/mdx-registry.tsx @@ -33,6 +33,7 @@ import { DocsLandingNext } from "@/components/docs-landing-next"; import { WhenFrameworkHas } from "@/components/when-framework-has"; import { WhenAngularBackend } from "@/components/when-angular-backend"; import { AgentCoreCommandTabs } from "@/components/agentcore-command-tabs"; +import { WebMCPSetupPrompt } from "@/components/webmcp-setup-prompt"; import { DemoSource } from "@/components/demo-source"; import { AngularFeatureCatalog } from "@/components/angular-feature-catalog"; import { AngularSnippet } from "@/components/angular-snippet"; @@ -270,6 +271,7 @@ export const docsComponents = { SignupLink, DocsTrackedCopy, DocsTrackedLink, + WebMCPSetupPrompt, FeatureIntegrations: ({ feature }: { feature?: string }) => { if (!feature) { warnSilentNull("FeatureIntegrations", "no `feature` prop provided"); From fe33b816f8a08ab3b793c992bae5d00c53b7fd7d Mon Sep 17 00:00:00 2001 From: Tyler Slaton Date: Thu, 3 Sep 2026 10:46:17 -0700 Subject: [PATCH 10/57] docs(shell-docs): reorder WebMCP overview --- showcase/shell-docs/src/content/docs/webmcp.mdx | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/showcase/shell-docs/src/content/docs/webmcp.mdx b/showcase/shell-docs/src/content/docs/webmcp.mdx index dc8b1c38b7..13088ee0da 100644 --- a/showcase/shell-docs/src/content/docs/webmcp.mdx +++ b/showcase/shell-docs/src/content/docs/webmcp.mdx @@ -7,11 +7,7 @@ frontend: universal import { WebMCPSetupPrompt } from "@/components/webmcp-setup-prompt"; -## Setup with a coding agent - -Use this pre-built prompt to add WebMCP to your project. Your coding agent will adapt the implementation to your app and verify that a compatible browser can discover and call the tool. - - +## Overview WebMCP lets your website tell compatible browser agents what they can do. Instead of guessing which buttons to click, an agent discovers a named tool with a description, a typed input schema, and a JavaScript handler. @@ -26,6 +22,12 @@ CopilotKit can publish an existing frontend tool to [`document.modelContext`](ht before testing.
+## Setup with a coding agent + +Use this pre-built prompt to add WebMCP to your project. Your coding agent will adapt the implementation to your app and verify that a compatible browser can discover and call the tool. + + + ## Do I need an agent? You do not need a CopilotKit backend agent to handle a WebMCP call. A compatible browser agent calls the frontend tool handler directly on the page; in that path, the handler context has no `agent`. From af5fbf4065ed94b25cb4700cf1a442992e356d1f Mon Sep 17 00:00:00 2001 From: Tyler Slaton Date: Thu, 3 Sep 2026 10:53:04 -0700 Subject: [PATCH 11/57] docs(shell-docs): polish WebMCP prompt CTA --- .../src/components/webmcp-setup-prompt.tsx | 63 +++++++++++++------ 1 file changed, 44 insertions(+), 19 deletions(-) diff --git a/showcase/shell-docs/src/components/webmcp-setup-prompt.tsx b/showcase/shell-docs/src/components/webmcp-setup-prompt.tsx index 13e8257cce..ef00f93b89 100644 --- a/showcase/shell-docs/src/components/webmcp-setup-prompt.tsx +++ b/showcase/shell-docs/src/components/webmcp-setup-prompt.tsx @@ -9,6 +9,8 @@ export const WEBMCP_SETUP_PROMPT = type CopyState = "idle" | "copied" | "error"; export function WebMCPSetupPrompt(): React.JSX.Element { + const promptId = React.useId(); + const [isExpanded, setIsExpanded] = React.useState(false); const [copyState, setCopyState] = React.useState("idle"); const resetTimerRef = React.useRef | null>( null, @@ -36,30 +38,53 @@ export function WebMCPSetupPrompt(): React.JSX.Element { return (
-
-