From 2bc452fa848373c6e11d55d1fbdb59ee0b785feb Mon Sep 17 00:00:00 2001 From: Sparkle <2705263765@qq.com> Date: Thu, 3 Sep 2026 16:11:33 +0800 Subject: [PATCH 01/12] docs(web): define React migration MVP Record the frozen PR #352 behavior baseline, Pi-native ownership boundaries, selected frontend stack, static delivery contract, and validation matrix for the local migration experiment. --- docs/design/OPENPI_WEB_REACT_MVP.md | 122 ++++++++++++++++++++++++++++ docs/design/README.md | 1 + 2 files changed, 123 insertions(+) create mode 100644 docs/design/OPENPI_WEB_REACT_MVP.md diff --git a/docs/design/OPENPI_WEB_REACT_MVP.md b/docs/design/OPENPI_WEB_REACT_MVP.md new file mode 100644 index 00000000..fba66e14 --- /dev/null +++ b/docs/design/OPENPI_WEB_REACT_MVP.md @@ -0,0 +1,122 @@ +# OpenPI Web React migration MVP + +- Status: draft +- Created: 2026-09-03 +- Verified through: not yet validated +- Source boundary: OpenPI `72fbba5`, PR #352 head `1b340f2` +- Related issue: none; local validation branch only +- Related PR: [#352](https://github.com/openpi-dev/openpi/pull/352) is the frozen behavior and visual reference, not a dependency merged into this branch + +## Purpose + +Validate that the OpenPI Web browser projection can move from one imperative `app.js` file to React without changing Pi ownership, the Web protocol, or the visible behavior restored by PR #352. The result must work both through the Vite development server with HMR and as built static assets served by `WebHost`. + +This is a framework migration, not a redesign. The browser remains a projection of the Web-owned Pi runtime and must not become a second Session, model, capability, or configuration source of truth. + +## Chosen stack + +- React 19 and TypeScript +- Vite 8 +- Zustand vanilla store with React bindings +- Fetch, authenticated SSE, and `eventsource-parser` +- Existing TypeBox protocol contracts +- Tailwind CSS 4 as the primary CSS system +- Astryx Core and the neutral theme for selected accessible interaction primitives +- Lucide React icons +- `react-markdown`, `remark-gfm`, and `rehype-sanitize` +- i18next and react-i18next +- Vitest, React Testing Library, Playwright, and axe-core + +Astryx owns generic Dialog, Menu, Tooltip, and Select behavior where its API preserves the reference interaction. Tailwind owns layout and visual matching. OpenPI-specific transcript evidence, activity projections, and the animated logo remain local React components. Astryx does not own runtime state or persistence. + +## Runtime boundary + +`PiWebRuntime`, `PiWebAdapter`, the protocol types, command endpoints, authentication token, cursor semantics, and lifecycle remain authoritative and unchanged. The migration adds three browser-side modules: + +1. A typed HTTP client sends the existing bounded commands and distinguishes accepted receipts from terminal runtime evidence. +2. An authenticated Fetch-based SSE client parses records, resumes from the last cursor, and requests a snapshot after invalidation or replay gaps. +3. A Zustand vanilla store reduces snapshots and events into browser projection state. React reads selectors and dispatches commands; it does not infer completion from labels or CSS. + +Only browser-local UI state may persist in `sessionStorage`: the process token and collapsed workspace groups. Theme, language, Sessions, models, and runtime capabilities are not independently persisted by this UI. + +## Component boundaries + +- `AppShell`: desktop grid, narrow-screen drawer, and global connection state. +- `SessionRail`: search, collapse, workspace groups, Session selection, and row actions. +- `WorkspacePicker`: initial workspace selection and native directory chooser command. +- `TranscriptViewport`: ordered persisted/live projections, follow-scroll policy, and turn anchors. +- `MessageBlock`: user and assistant text, copy action, latest-user edit-and-resend flow. +- `ThinkingEvidence`: live and settled thinking duration. +- `ToolEvidence`: call/result pairing, summaries, status, output disclosure, and empty output. +- `CapabilityEvidence`: Subagent and Workflow call/result cards. +- `ToolGroup`: collapses runs of four or more ordinary tool rows. +- `TurnRail`: jumps between user turns without owning transcript state. +- `ActivityBar`: bounded Subagent and Workflow status chips from canonical capability projections. +- `Composer`: active-Session checks, model selection, prompt admission, queued/running states, and auto-resizing input. +- `OpenPiLogo`: PR #352's 16-cell assembly, impact, line-clear, settling animation, click replay, and reduced-motion behavior. + +Components receive typed projected values and callbacks. Protocol messages are normalized before rendering; components do not parse Session files or call Pi APIs directly. + +## Behavior baseline + +The complete baseline is PR #352 exact head `1b340f2`: + +- engineering-grid backdrop, frosted desktop rail, opaque narrow-screen drawer, paper transcript lane, and favicon; +- workspace import, rename, remove, collapse, search, and per-workspace Session creation; +- Session select, rename, archive, active/readonly behavior, and switching feedback; +- model picker and Pi-native model selection; +- prompt admission tokens, queued/running/retrying states, duplicate terminal receipt handling, and edit-and-resend; +- snapshot plus cursor SSE recovery, stale response protection, reconnect status, and invalidation refresh; +- safe GFM Markdown, external links, image-as-link rendering, code, tables, and task lists; +- thinking timers, ordinary tool summaries and evidence, result pairing, error/running states, and four-step grouping; +- Subagent and Workflow cards, custom results, bounded capability chips, omitted counts, message copy/time actions, turn navigation, and follow-scroll behavior; +- responsive sidebar and composer at 390 by 844, keyboard operation, visible focus, and reduced motion; +- animated landing logo with click replay. + +The removed browser-local theme/language settings are deliberately excluded. Language follows browser locale as in the final PR head until canonical package configuration is implemented separately. + +## Build and static delivery + +Vite uses `web/ui` as its source root and writes deterministic, auditable assets to `web/dist`. CSS splitting is disabled for the MVP so `WebHost` can retain a fixed static allowlist. No source map or arbitrary filesystem path is served. + +- `bun run dev:web` starts the source backend plus Vite HMR. +- `bun run build:web` creates production assets. +- `node ./bin/openpi.js web [workspace]` serves those assets without Vite. +- `npm pack` must contain the built browser assets and run without remote CDN dependencies. + +## Error and recovery behavior + +- Missing or rejected auth yields an explicit disconnected/error surface without leaking the token. +- HTTP command errors preserve the current snapshot and show action-scoped feedback. +- A stale Session activation or prompt receipt cannot overwrite a newer selection or prompt state. +- SSE reconnect uses the last accepted cursor. A replay gap, invalid event, or `state_invalidated` event triggers a bounded snapshot refresh. +- Non-active Sessions remain read-only. UI optimism never proves model completion. +- Markdown input is sanitized, raw HTML is rendered as text, unsafe URL schemes are rejected, and images remain outbound links rather than embedded remote loads. +- Reduced-motion users receive the final logo state and nonanimated navigation. + +## Validation + +Automated validation must include: + +- pure reducer tests for snapshot/event ordering, prompt settlement, activation races, reconnect, and invalidation; +- component tests for Session/workspace actions, composer gates, Markdown safety, tool pairing/grouping, copy/edit, turn navigation, activity chips, and Logo replay; +- existing Host/runtime/protocol tests updated to assert the built static asset contract; +- Playwright desktop and 390 by 844 flows against a real local WebHost, including keyboard navigation and axe checks; +- `bun run check`, `bun run test`, `bun run build:web`, and an `npm pack` content/startup smoke. + +Manual acceptance must prove the checkout revision and single OpenPI source before exercising a real provider Session. It then covers landing animation, workspace and Session lifecycle, model selection, normal and queued prompts, streaming, tool evidence, Subagent/Workflow projections, reconnect, refresh recovery, narrow-screen navigation, and production static delivery. + +## Success criteria + +- Every visible and interactive behavior in the frozen PR #352 baseline is present or has an explicit failing test. +- No command, protocol, runtime ownership, persistence, permission, or lifecycle behavior is widened. +- Development HMR and production static delivery both work from the same React source. +- The production page makes no remote asset request and does not require Vite. +- The result passes repository gates and the real-browser acceptance matrix. + +## Non-goals + +- Merging or publishing the migration. +- Adding settings, trust approval, file attachments, interrupt control, transcript search, or other open Web issues. +- Changing Pi Session storage, provider selection semantics, capability schemas, or command endpoints. +- Keeping a second legacy UI route. diff --git a/docs/design/README.md b/docs/design/README.md index 0283a682..945ef370 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -13,5 +13,6 @@ These records predate [`Decision 0001`](../decisions/0001-documentation-and-evid - [`WORKFLOW_INVOCATION_GRAPH.md`](WORKFLOW_INVOCATION_GRAPH.md) — durable invocation facts, same-run handoff refs, reusable operators, and derived graph semantics - [`CHILD_TOOL_ACTIVITY.md`](CHILD_TOOL_ACTIVITY.md) — shared compact and Pi-native expanded evidence projection for Direct Subagent and Workflow child transcripts - [`OPENPI_WEB_ARCHITECTURE.md`](OPENPI_WEB_ARCHITECTURE.md) — draft architecture, protocol boundaries, delivery phases, and visual direction for the local Web workbench +- [`OPENPI_WEB_REACT_MVP.md`](OPENPI_WEB_REACT_MVP.md) — draft local validation design for a behavior-compatible React, Astryx, and Tailwind browser migration 开发与热更新流程见 [`docs/development/OPENPI_WEB_DEVELOPMENT.md`](../development/OPENPI_WEB_DEVELOPMENT.md)。 From 036dd9c8faeb33e1fb277c76ce5693c04296531d Mon Sep 17 00:00:00 2001 From: Sparkle <2705263765@qq.com> Date: Thu, 3 Sep 2026 22:08:46 +0800 Subject: [PATCH 02/12] docs(web): define development port conflict handling Document default port fallback, strict explicit ports, fast startup diagnostics, and TUI error projection for the local React validation branch. --- docs/design/OPENPI_WEB_DEV_PORT_CONFLICTS.md | 85 ++++++++++++++++++++ docs/design/README.md | 1 + 2 files changed, 86 insertions(+) create mode 100644 docs/design/OPENPI_WEB_DEV_PORT_CONFLICTS.md diff --git a/docs/design/OPENPI_WEB_DEV_PORT_CONFLICTS.md b/docs/design/OPENPI_WEB_DEV_PORT_CONFLICTS.md new file mode 100644 index 00000000..73fa8d9f --- /dev/null +++ b/docs/design/OPENPI_WEB_DEV_PORT_CONFLICTS.md @@ -0,0 +1,85 @@ +# OpenPI Web development port-conflict handling + +- Status: draft +- Created: 2026-09-03 +- Last reviewed: 2026-09-03 +- Source boundary: OpenPI `72fbba5` plus the local `codex/web-react-mvp` development launcher +- Related issue: none; local validation branch only +- Related PR: none +- Supersedes: none + +## Context + +`bun run dev:web` starts two loopback listeners: a WebHost backend and a Vite UI. The current launcher fixes them to ports `57107` and `5173`, waits up to 15 seconds for the backend, and starts Vite with `strictPort: true`. + +Two failures currently look similar even though they require different operator actions: + +- an unrelated process owns a preferred port, so another loopback port is safe; +- another OpenPI WebHost owns the shared Web Session directory, so starting a second runtime is unsafe regardless of port. + +A backend started through Node watch can also fail while the watch supervisor remains alive. In that case the launcher waits for the full readiness timeout and reports a secondary timeout after the real startup error. + +The TUI `/web` command inherits child output while the TUI is suspended, but after the terminal is restored its notification reports only the exit code. The actionable child error can therefore disappear from the operator-facing result. + +## Chosen behavior + +### Default ports + +When `OPENPI_WEB_UI_PORT` or `OPENPI_WEB_BACKEND_PORT` is absent, its documented value is a preferred port rather than a required port. The launcher checks loopback availability starting at `5173` for the UI and `57107` for the backend and selects the first available port among at most 100 consecutive candidates, without exceeding `65535`. + +If either preferred port is skipped, startup output names the occupied preferred port and the selected replacement. The selected backend origin and UI origin are the only values passed to the readiness probe, Vite proxy, WebHost `--port`, `OPENPI_WEB_ALLOWED_ORIGIN`, and browser URL. + +Port discovery is a development convenience, not an ownership boundary. The eventual listener bind remains authoritative. If another process wins the port after discovery, startup fails explicitly rather than claiming success. + +### Explicit ports + +When an operator sets either port environment variable, that port is an exact request. The launcher validates it as an integer from 1 through 65535 and fails immediately if it cannot be bound. It does not silently select a different port. + +The error names the occupied port and the matching environment variable. This preserves deterministic CI, scripts, bookmarks, and debugging commands. + +### Existing OpenPI WebHost + +The single WebHost lease remains unchanged. A live `/web`, `openpi web`, `dev:web`, or `dev:web:backend` process cannot be bypassed by selecting another port because all of them own the same Web Session and metadata directory. + +During development startup, the launcher observes up to the latest 8 KiB of backend startup stderr while continuing to forward it to the terminal. A lease conflict or other terminal startup failure ends the launcher promptly and preserves the original error in the final diagnostic instead of waiting for a readiness timeout. It does not reuse the existing Host, persist or recover its token, or terminate it automatically. + +### TUI diagnostics + +`/web` continues to run the packaged CLI in the foreground with the terminal suspended. It forwards normal child output and retains only the latest 8 KiB, terminal-sanitized tail of stderr. If the child exits unsuccessfully, the restored TUI notification includes the actionable final error when available; otherwise it retains the existing exit-code or signal fallback. + +This diagnostic projection is display evidence only. It does not change child lifecycle, Session state, or the canonical process exit result. + +## Implementation boundaries + +- Keep port selection and startup-output handling in small development-script helpers with injected listener/process seams for deterministic tests. +- Do not weaken or duplicate `acquireWebHostLease`. +- Do not add a daemon, registry, persisted development token, or attach-to-existing-Host behavior. +- Do not make the standalone production CLI silently avoid an explicitly requested `--port`. +- Preserve normal `SIGINT` and `SIGTERM` cleanup for Vite, the watch supervisor, WebHost, and its lease. +- Bound both the number of candidate ports and captured stderr bytes. + +## Alternatives considered + +1. Let Vite alone choose another port. Rejected because the backend, proxy, allowed origin, readiness endpoint, and displayed URL would not share one resolved configuration. +2. Bind both services to port `0` and return their assigned ports over a new IPC protocol. This removes the small discovery-to-bind race but requires a larger CLI/watch protocol refactor than the development problem justifies. +3. Fail on every conflict and require manual environment variables. This is deterministic but makes ordinary local development unnecessarily brittle when common frontend ports are occupied. +4. Reuse an existing WebHost. Rejected because the process token is intentionally ephemeral and not persisted, and a second UI cannot infer compatible source, protocol, or runtime ownership from a port alone. + +## Validation + +Automated checks must cover: + +- default UI and backend ports remain unchanged when available; +- occupied default ports select the next available candidates and update every downstream origin; +- explicitly configured occupied ports fail immediately without fallback; +- invalid and out-of-range port values fail before spawning children; +- a backend lease/startup failure rejects immediately with the original cause rather than the readiness timeout; +- a bind race fails explicitly and cleans up any process or listener already started; +- `/web` reports a bounded sanitized child error and preserves signal/code fallbacks; +- successful shutdown still releases both ports and the WebHost lease. + +Repository validation remains `bun run check` and `bun run test`. Manual validation starts an unrelated listener on each preferred port, confirms automatic fallback, then starts an existing OpenPI WebHost and confirms the second launcher fails promptly without selecting a second runtime. + +## Evidence boundary + +Verified facts in the source boundary are the fixed current ports, Vite strict-port configuration, 15-second readiness timeout, Node watch supervision, and the single WebHost lease. The behavior above is approved local design, not shipped behavior or an accepted project Decision. Exact output wording and helper names may change during implementation while preserving the stated operator-visible outcomes. diff --git a/docs/design/README.md b/docs/design/README.md index 945ef370..9b011567 100644 --- a/docs/design/README.md +++ b/docs/design/README.md @@ -14,5 +14,6 @@ These records predate [`Decision 0001`](../decisions/0001-documentation-and-evid - [`CHILD_TOOL_ACTIVITY.md`](CHILD_TOOL_ACTIVITY.md) — shared compact and Pi-native expanded evidence projection for Direct Subagent and Workflow child transcripts - [`OPENPI_WEB_ARCHITECTURE.md`](OPENPI_WEB_ARCHITECTURE.md) — draft architecture, protocol boundaries, delivery phases, and visual direction for the local Web workbench - [`OPENPI_WEB_REACT_MVP.md`](OPENPI_WEB_REACT_MVP.md) — draft local validation design for a behavior-compatible React, Astryx, and Tailwind browser migration +- [`OPENPI_WEB_DEV_PORT_CONFLICTS.md`](OPENPI_WEB_DEV_PORT_CONFLICTS.md) — draft local design for development-port fallback, strict explicit ports, startup diagnostics, and TUI `/web` error projection 开发与热更新流程见 [`docs/development/OPENPI_WEB_DEVELOPMENT.md`](../development/OPENPI_WEB_DEVELOPMENT.md)。 From 645e4b68a567c3c551883d84bba5dc9e52fb678c Mon Sep 17 00:00:00 2001 From: Sparkle <2705263765@qq.com> Date: Fri, 4 Sep 2026 17:48:39 +0800 Subject: [PATCH 03/12] feat(web): migrate workbench UI to React - replace the imperative browser UI with typed React and Zustand projections - add Vite HMR, production asset builds, and bounded port conflict handling - cover the Web store, packaged host, responsive browser flows, and artifact drift in CI --- .github/workflows/ci.yml | 88 +- biome.json | 3 + bun.lock | 469 +++++- docs/design/OPENPI_WEB_REACT_MVP.md | 26 +- docs/development/OPENPI_WEB_DEVELOPMENT.md | 30 +- extensions/web/index.ts | 74 +- package.json | 29 +- scripts/dev-web-support.ts | 170 ++ scripts/dev-web.mjs | 127 +- tests/extensions/web/index.test.ts | 28 +- tests/web/app-render.spec.ts | 171 ++ tests/web/app-render.test.ts | 995 ------------ tests/web/cli.test.ts | 14 +- tests/web/dev-web-support.test.ts | 126 ++ tests/web/openpi-web.e2e.ts | 171 ++ tests/web/playwright.config.ts | 50 + tests/web/web-host.test.ts | 145 +- tests/web/web-store.spec.ts | 778 +++++++++ tsconfig.json | 8 +- web/dist/app.js | 87 + web/dist/favicon.svg | 9 + web/dist/index.html | 15 + web/dist/styles.css | 3 + web/host/static-assets.ts | 4 - web/host/web-host.ts | 15 +- web/ui/app.js | 1398 ----------------- web/ui/index.html | 131 +- web/ui/public/favicon.svg | 9 + web/ui/src/app/App.tsx | 130 ++ web/ui/src/app/providers.tsx | 15 + web/ui/src/components/Markdown.tsx | 52 + web/ui/src/components/OpenPiLogo.tsx | 41 + web/ui/src/features/activity/ActivityBar.tsx | 109 ++ web/ui/src/features/composer/Composer.tsx | 199 +++ .../src/features/sessions/SessionSidebar.tsx | 418 +++++ web/ui/src/features/transcript/Transcript.tsx | 856 ++++++++++ web/ui/src/i18n.ts | 151 ++ web/ui/src/lib/format.ts | 57 + web/ui/src/main.tsx | 16 + web/ui/src/protocol/client.ts | 141 ++ web/ui/src/protocol/event-stream.ts | 55 + web/ui/src/store/web-store.ts | 780 +++++++++ web/ui/src/styles.css | 403 +++++ web/ui/styles.css | 598 ------- web/ui/tsconfig.json | 12 + web/ui/vite-env.d.ts | 1 + web/vite.config.mjs | 22 +- 47 files changed, 5890 insertions(+), 3339 deletions(-) create mode 100644 scripts/dev-web-support.ts create mode 100644 tests/web/app-render.spec.ts delete mode 100644 tests/web/app-render.test.ts create mode 100644 tests/web/dev-web-support.test.ts create mode 100644 tests/web/openpi-web.e2e.ts create mode 100644 tests/web/playwright.config.ts create mode 100644 tests/web/web-store.spec.ts create mode 100644 web/dist/app.js create mode 100644 web/dist/favicon.svg create mode 100644 web/dist/index.html create mode 100644 web/dist/styles.css delete mode 100644 web/host/static-assets.ts delete mode 100644 web/ui/app.js create mode 100644 web/ui/public/favicon.svg create mode 100644 web/ui/src/app/App.tsx create mode 100644 web/ui/src/app/providers.tsx create mode 100644 web/ui/src/components/Markdown.tsx create mode 100644 web/ui/src/components/OpenPiLogo.tsx create mode 100644 web/ui/src/features/activity/ActivityBar.tsx create mode 100644 web/ui/src/features/composer/Composer.tsx create mode 100644 web/ui/src/features/sessions/SessionSidebar.tsx create mode 100644 web/ui/src/features/transcript/Transcript.tsx create mode 100644 web/ui/src/i18n.ts create mode 100644 web/ui/src/lib/format.ts create mode 100644 web/ui/src/main.tsx create mode 100644 web/ui/src/protocol/client.ts create mode 100644 web/ui/src/protocol/event-stream.ts create mode 100644 web/ui/src/store/web-store.ts create mode 100644 web/ui/src/styles.css delete mode 100644 web/ui/styles.css create mode 100644 web/ui/tsconfig.json create mode 100644 web/ui/vite-env.d.ts diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 718cf5b4..44df5ac5 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -32,6 +32,14 @@ jobs: - name: Install dependencies run: bun install --frozen-lockfile - run: bun run check + - name: Verify committed Web build + run: | + changes="$(git status --porcelain=v1 --untracked-files=all -- web/dist)" + if [[ -n "$changes" ]]; then + printf '%s\n' "$changes" + echo "web/dist is missing or stale; run bun run build:web and commit the result" + exit 1 + fi - run: bun run test - name: Smoke-test Pi package discovery run: | @@ -89,12 +97,88 @@ jobs: done origin="$(sed -n 's/^OpenPI Web Workbench is running at //p' "$root/host.log" | tail -n 1)" test -n "$origin" - curl --fail --silent --show-error --output "$root/marked.js" "$origin/marked.js" - grep -q 'marked v18' "$root/marked.js" + curl --fail --silent --show-error --output "$root/index.html" "$origin/" + grep -q '
' "$root/index.html" + grep -Eq ' + + + +
+ + diff --git a/web/dist/styles.css b/web/dist/styles.css new file mode 100644 index 00000000..14ea910e --- /dev/null +++ b/web/dist/styles.css @@ -0,0 +1,3 @@ +/*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */ +@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-border-style:solid;--tw-outline-style:solid;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}@layer reset{:where(*){box-sizing:border-box;border:0 solid}:where(html){-webkit-text-size-adjust:100%;tab-size:4;--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark;line-height:1.5}@media (prefers-color-scheme:dark){:where(html){--lightningcss-light: ;--lightningcss-dark:initial}}:where(body){line-height:inherit;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;margin:0}:where(h1,h2,h3,h4,h5,h6){font-size:inherit;font-weight:inherit}:where(h1,h2,h3,h4,h5,h6,p,blockquote,figure,pre,dl,dd){margin:0}:where(a){color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}:where(b,strong){font-weight:bolder}:where(code,kbd,samp,pre){font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}:where(small){font-size:80%}:where(sub,sup){vertical-align:baseline;font-size:75%;line-height:0;position:relative}:where(sub){bottom:-.25em}:where(sup){top:-.5em}:where(ol,ul,menu){margin:0;padding:0;list-style:none}:where(img,svg,video,canvas,audio,iframe,embed,object){vertical-align:middle;display:block}:where(img,video){max-width:100%;height:auto}:where([data-astryx-aspect-ratio-override=cover],[data-astryx-aspect-ratio-override=contain])>:where(*){width:100%;height:100%}:where([data-astryx-aspect-ratio-override=cover])>:where(img,video){object-fit:cover}:where([data-astryx-aspect-ratio-override=contain])>:where(img,video){object-fit:contain}:where(button,input,optgroup,select,textarea){font:inherit;color:inherit;margin:0;padding:0}:where(button,[type=button],[type=reset],[type=submit]){appearance:button;background-color:#0000;background-image:none}:where(button,[role=button]){cursor:pointer}:where(:disabled,[aria-disabled=true]){cursor:default}:where(textarea){resize:vertical}:where(){opacity:1;color:var(--color-text-secondary,#9ca3af);-webkit-appearance:none}:where(fieldset){margin:0;padding:0}:where(legend){padding:0}:where(table){text-indent:0;border-color:inherit;border-collapse:collapse}:where(hr){height:0;color:inherit;border-top-width:1px}:where(summary){display:list-item}:where(dialog){outline:none;padding:0}:where([hidden]){display:none}:where(html){-webkit-tap-highlight-color:transparent}:where(html[data-theme=light]){--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}:where(html[data-theme=dark]){--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}:where(html:not([data-theme])){--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark}@media (prefers-color-scheme:dark){:where(html:not([data-theme])){--lightningcss-light: ;--lightningcss-dark:initial}}:where([data-astryx-media=dark]){--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}:where([data-astryx-media=light]){--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}@scope([data-astryx-theme=neutral]) to ([data-astryx-theme]){:where(h1,h2,h3,h4,h5,h6){font-family:var(--font-family-heading);color:var(--color-text-primary)}:where(h1){font-size:var(--font-size-2xl);font-weight:var(--font-weight-semibold);line-height:1.3333}:where(h2){font-size:var(--font-size-xl);font-weight:var(--font-weight-semibold);line-height:1.4}:where(h3){font-size:var(--font-size-lg);font-weight:var(--font-weight-bold);line-height:1.4118}:where(h4){font-size:var(--font-size-base);font-weight:var(--font-weight-bold);line-height:1.4286}:where(h5){font-size:var(--font-size-sm);font-weight:var(--font-weight-semibold);line-height:1.6667}:where(h6){font-size:var(--font-size-xs);font-weight:var(--font-weight-semibold);line-height:1.6}:where(p){font-family:var(--font-family-body);font-size:var(--font-size-base);font-weight:var(--font-weight-normal);color:var(--color-text-primary);line-height:1.4286}:where(small){font-size:var(--font-size-sm);font-weight:var(--font-weight-normal);color:var(--color-text-secondary);line-height:1.6667}:where(code,pre){font-family:var(--font-family-code);font-size:var(--font-size-base);line-height:1.4286}:where(hr){border:none;border-top:1px solid var(--color-border)}}}@layer theme{:root,:host{--container-xl:36rem;--font-weight-normal:var(--font-weight-normal);--font-weight-medium:var(--font-weight-medium);--font-weight-semibold:var(--font-weight-semibold);--font-weight-bold:var(--font-weight-bold);--default-font-family:var(--font-family-body);--default-mono-font-family:var(--font-family-code);--color-accent:var(--color-text-accent);--color-overlay:var(--color-overlay);--color-accent-muted:var(--color-accent-muted);--color-on-accent:var(--color-on-accent);--color-neutral:var(--color-neutral);--color-overlay-hover:var(--color-overlay-hover);--color-overlay-pressed:var(--color-overlay-pressed);--color-tint-hover:var(--color-tint-hover);--color-success:var(--color-success);--color-success-muted:var(--color-success-muted);--color-on-success:var(--color-on-success);--color-error:var(--color-error);--color-error-muted:var(--color-error-muted);--color-on-error:var(--color-on-error);--color-warning:var(--color-warning);--color-warning-muted:var(--color-warning-muted);--color-on-warning:var(--color-on-warning);--color-border:var(--color-border);--color-on-dark:var(--color-on-dark);--color-on-light:var(--color-on-light);--color-skeleton:var(--color-skeleton);--color-track:var(--color-track);--color-shadow:var(--color-shadow);--radius-none:var(--radius-none);--radius-full:var(--radius-full)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer astryx-base{@property --x---_avatar-group-overlap{syntax:"*";inherits:false}@property --x---_codeblock-gutter-width{syntax:"*";inherits:false}@property --x---_hover-delay{syntax:"*";inherits:false}@property --x---_tab-indicator-bottom{syntax:"*";inherits:false}@property --x---container-max-height{syntax:"*";inherits:false}@property --x---layout-content-width{syntax:"*";inherits:false}@property --x-126w13d{syntax:"*";inherits:false}@property --x-4drmnv{syntax:"*";inherits:false}@property --x-animationDelay{syntax:"*";inherits:false}@property --x-aspectRatio{syntax:"*";inherits:false}@property --x-backgroundColor{syntax:"*";inherits:false}@property --x-borderWidth{syntax:"*";inherits:false}@property --x-bottom{syntax:"*";inherits:false}@property --x-counterReset{syntax:"*";inherits:false}@property --x-fontSize{syntax:"*";inherits:false}@property --x-gap{syntax:"*";inherits:false}@property --x-gridAutoRows{syntax:"*";inherits:false}@property --x-gridTemplateColumns{syntax:"*";inherits:false}@property --x-height{syntax:"*";inherits:false}@property --x-inlineSize{syntax:"*";inherits:false}@property --x-insetInlineEnd{syntax:"*";inherits:false}@property --x-insetInlineStart{syntax:"*";inherits:false}@property --x-marginBlock{syntax:"*";inherits:false}@property --x-marginBlockEnd{syntax:"*";inherits:false}@property --x-marginBlockStart{syntax:"*";inherits:false}@property --x-marginInline{syntax:"*";inherits:false}@property --x-marginInlineEnd{syntax:"*";inherits:false}@property --x-marginInlineStart{syntax:"*";inherits:false}@property --x-maxHeight{syntax:"*";inherits:false}@property --x-maxWidth{syntax:"*";inherits:false}@property --x-minHeight{syntax:"*";inherits:false}@property --x-minWidth{syntax:"*";inherits:false}@property --x-paddingBlock{syntax:"*";inherits:false}@property --x-paddingInline{syntax:"*";inherits:false}@property --x-paddingInlineEnd{syntax:"*";inherits:false}@property --x-paddingInlineStart{syntax:"*";inherits:false}@property --x-qthpiu{syntax:"*";inherits:false}@property --x-sj6hyi{syntax:"*";inherits:false}@property --x-top{syntax:"*";inherits:false}@property --x-transform{syntax:"*";inherits:false}@property --x-WebkitLineClamp{syntax:"*";inherits:false}@property --x-width{syntax:"*";inherits:false}@property --x-1dd27dc{syntax:"*";inherits:true}@property --x-owu7oy{syntax:"*";inherits:true}@keyframes x188b6p3-B{0%{color:inherit}to{color:#0000}}@keyframes xuvekqa-B{0%{opacity:.3}50%{opacity:1}to{opacity:.3}}@keyframes x1tut0r7-B{0%{opacity:.3;transform:rotateX(52deg)scale(.86)}50%{opacity:1;transform:rotateX(0)scale(1)}to{opacity:.3;transform:rotateX(-52deg)scale(.86)}}@keyframes x13kz0yu-B{0%,to{opacity:1}50%{opacity:.5}}@keyframes x18re5ia-B{0%{opacity:0}to{opacity:1}}@keyframes xgnty7z-B{0%{opacity:.25}to{opacity:1}}@keyframes xtut5q7-B{0%{opacity:1}50%{opacity:.5}to{opacity:1}}@keyframes x1k48ry3-B{0%{opacity:0;transform:scale(.95)}to{opacity:1;transform:scale(1)}}@keyframes x11lauxq-B{0%{opacity:0;transform:translate(var(--dialog-dir-x,0px),var(--dialog-dir-y,16px)) scale(.95)}to{opacity:1;transform:translate(0)scale(1)}}@keyframes xu7jd1z-B{0%{opacity:0;transform:translateX(var(--spacing-2)) scale(.95)}to{opacity:1;transform:translate(0)scale(1)}}@keyframes xwmkjkf-B{0%{opacity:0;transform:translateX(calc(-1 * var(--spacing-2))) scale(.95)}to{opacity:1;transform:translate(0)scale(1)}}@keyframes x1ahk7ht-B{0%{opacity:0;transform:translateY(var(--spacing-2)) scale(.95)}to{opacity:1;transform:translateY(0)scale(1)}}@keyframes xv1hr86-B{0%{opacity:0;transform:translateY(calc(-1 * var(--spacing-2))) scale(.95)}to{opacity:1;transform:translateY(0)scale(1)}}@keyframes x1b6yrix-B{0%{opacity:0;transform:translateY(var(--spacing-2))}to{opacity:1;transform:translateY(0)}}@keyframes xiylxmw-B{0%{opacity:0;transform:translateY(calc(-1 * var(--spacing-2)))}to{opacity:1;transform:translateY(0)}}@keyframes xqng64z-B{0%{transform:rotate(0)}to{transform:rotate(360deg)}}@keyframes x1c2q33o-B{0%{transform:translate(100%)}to{transform:translate(-250%)}}@keyframes xr3m334-B{0%{transform:translate(-100%)}to{transform:translate(250%)}}@keyframes x1xhkexc-B{0%{opacity:0;width:0;margin-inline-end:0}to{opacity:1;width:14px;margin-inline-end:var(--spacing-1)}}:root,.xafi2nm{--border-width:1px}:root,.xj0fimd{--color-accent:var(--lightningcss-light,#0064e0)var(--lightningcss-dark,#2694fe);--color-accent-muted:var(--lightningcss-light,#0082fb33)var(--lightningcss-dark,#0082fb3f);--color-on-accent:#fff;--color-neutral:var(--lightningcss-light,#0536591a)var(--lightningcss-dark,#dfe2e533);--color-background-surface:var(--lightningcss-light,#fff)var(--lightningcss-dark,#1f1f22);--color-background-body:var(--lightningcss-light,#f1f4f7)var(--lightningcss-dark,#111112);--color-overlay:var(--lightningcss-light,#01122866)var(--lightningcss-dark,#11111299);--color-overlay-hover:var(--lightningcss-light,#0536590c)var(--lightningcss-dark,#ffffff0c);--color-overlay-pressed:var(--lightningcss-light,#05365919)var(--lightningcss-dark,#ffffff19);--color-background-muted:var(--lightningcss-light,#0536590c)var(--lightningcss-dark,#1111127f);--color-text-primary:var(--lightningcss-light,#0a1317)var(--lightningcss-dark,#dfe2e5);--color-text-secondary:var(--lightningcss-light,#4e606f)var(--lightningcss-dark,#aaafb5);--color-text-disabled:var(--lightningcss-light,#a4b0bc)var(--lightningcss-dark,#6f747c);--color-text-accent:var(--lightningcss-light,#0064e0)var(--lightningcss-dark,#3e9efb);--color-on-dark:#fff;--color-on-light:#000;--color-icon-accent:var(--lightningcss-light,#0064e0)var(--lightningcss-dark,#2694fe);--color-icon-primary:var(--lightningcss-light,#0a1317)var(--lightningcss-dark,#dfe2e5);--color-icon-secondary:var(--lightningcss-light,#4e606f)var(--lightningcss-dark,#aaafb5);--color-icon-disabled:var(--lightningcss-light,#a4b0bc)var(--lightningcss-dark,#6f747c);--color-background-card:var(--lightningcss-light,#fff)var(--lightningcss-dark,#1f1f22);--color-background-popover:var(--lightningcss-light,#fff)var(--lightningcss-dark,#28292c);--color-background-inverted:var(--lightningcss-light,#0a1317)var(--lightningcss-dark,#fff);--color-background-error-inverted:var(--lightningcss-light,#aa071e)var(--lightningcss-dark,#e3193b);--color-success:#0d8626;--color-success-muted:var(--lightningcss-light,#0b991f33)var(--lightningcss-dark,#0b991f3f);--color-on-success:#fff;--color-error:var(--lightningcss-light,#e3193b)var(--lightningcss-dark,#f5394f);--color-error-muted:var(--lightningcss-light,#e3193b33)var(--lightningcss-dark,#f5394f3f);--color-on-error:#fff;--color-warning:var(--lightningcss-light,#e9af08)var(--lightningcss-dark,#f2c00b);--color-warning-muted:var(--lightningcss-light,#e2a40033)var(--lightningcss-dark,#e2a4003f);--color-on-warning:#0a1317;--color-border:var(--lightningcss-light,#05365919)var(--lightningcss-dark,#f2f4f619);--color-border-emphasized:var(--lightningcss-light,#ccd3db)var(--lightningcss-dark,#494d53);--color-skeleton:var(--lightningcss-light,#ccd3db)var(--lightningcss-dark,#5a5e66);--color-track:var(--lightningcss-light,#ccd3db)var(--lightningcss-dark,#5a5e66);--color-shadow:var(--lightningcss-light,#0536591a)var(--lightningcss-dark,#0000004d);--color-tint-hover:var(--lightningcss-light,#000)var(--lightningcss-dark,#fff);--color-background-blue:#0171e333;--color-border-blue:var(--lightningcss-light,#0064e0)var(--lightningcss-dark,#2694fe);--color-icon-blue:var(--lightningcss-light,#0064e0)var(--lightningcss-dark,#2694fe);--color-text-blue:var(--lightningcss-light,#042f97)var(--lightningcss-dark,#afd7ff);--color-background-cyan:#03a7d733;--color-border-cyan:var(--lightningcss-light,#089dd0)var(--lightningcss-dark,#0171a4);--color-icon-cyan:var(--lightningcss-light,#00acc1)var(--lightningcss-dark,#26c6da);--color-text-cyan:var(--lightningcss-light,#014975)var(--lightningcss-dark,#a1eef9);--color-background-gray:var(--lightningcss-light,#0a131733)var(--lightningcss-dark,#666a724c);--color-border-gray:var(--lightningcss-light,#647685)var(--lightningcss-dark,#748695);--color-icon-gray:var(--lightningcss-light,#4e606f)var(--lightningcss-dark,#aaafb5);--color-text-gray:var(--lightningcss-light,#0a1317)var(--lightningcss-dark,#e7eaed);--color-background-green:#24bb5e33;--color-border-green:var(--lightningcss-light,#0d8626)var(--lightningcss-dark,#0b991f);--color-icon-green:var(--lightningcss-light,#0d8626)var(--lightningcss-dark,#26a756);--color-text-green:var(--lightningcss-light,#09441f)var(--lightningcss-dark,#a5f690);--color-background-orange:#f2790233;--color-border-orange:var(--lightningcss-light,#eb6e00)var(--lightningcss-dark,#b34a01);--color-icon-orange:var(--lightningcss-light,#e9690b)var(--lightningcss-dark,#fb8c00);--color-text-orange:var(--lightningcss-light,#6b2203)var(--lightningcss-dark,#fdb876);--color-background-pink:#e638b333;--color-border-pink:var(--lightningcss-light,#f351c0)var(--lightningcss-dark,#c02294);--color-icon-pink:var(--lightningcss-light,#c2185b)var(--lightningcss-dark,#ec407a);--color-text-pink:var(--lightningcss-light,#650053)var(--lightningcss-dark,#feade3);--color-background-purple:#7952ff33;--color-border-purple:var(--lightningcss-light,#9081ff)var(--lightningcss-dark,#7340fe);--color-icon-purple:var(--lightningcss-light,#5b08d8)var(--lightningcss-dark,#7952ff);--color-text-purple:var(--lightningcss-light,#3e0697)var(--lightningcss-dark,#b3b0fe);--color-background-red:#e3193b33;--color-border-red:var(--lightningcss-light,#e3193b)var(--lightningcss-dark,#f5394f);--color-icon-red:var(--lightningcss-light,#d31130)var(--lightningcss-dark,#e3193b);--color-text-red:var(--lightningcss-light,#7b0210)var(--lightningcss-dark,#ffb2b8);--color-background-teal:#0db7af33;--color-border-teal:var(--lightningcss-light,#08a3a3)var(--lightningcss-dark,#08767d);--color-icon-teal:var(--lightningcss-light,#009688)var(--lightningcss-dark,#26a69a);--color-text-teal:var(--lightningcss-light,#083943)var(--lightningcss-dark,#40dccd);--color-background-yellow:#e2a40033;--color-border-yellow:var(--lightningcss-light,#c58600)var(--lightningcss-dark,#b47700);--color-icon-yellow:var(--lightningcss-light,#fbc02d)var(--lightningcss-dark,#ffee58);--color-text-yellow:var(--lightningcss-light,#753f07)var(--lightningcss-dark,#fbce03)}:root,.x14lkjui{--duration-fast-min:.13s;--duration-fast:.175s;--duration-fast-max:.23s;--duration-medium-min:.31s;--duration-medium:.41s;--duration-medium-max:.55s;--duration-slow-min:.73s;--duration-slow:.975s;--duration-slow-max:1.3s}:root,.xf09i69{--ease-standard:cubic-bezier(.24, 1, .4, 1)}:root,.xzxs3qz{--focus-outline-width:2px;--focus-outline-style:solid;--focus-outline-color:var(--color-accent);--focus-outline-offset:3px}:root,.x5tdzeq{--font-family-body:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;--font-family-code:"SF Mono", Monaco, Consolas, monospace;--font-family-heading:-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif}:root,.x1q1ms06{--font-size-4xs:.375rem;--font-size-3xs:.4375rem;--font-size-2xs:.5rem;--font-size-xs:.625rem;--font-size-sm:.75rem;--font-size-base:.875rem;--font-size-lg:1.0625rem;--font-size-xl:1.25rem;--font-size-2xl:1.5rem;--font-size-3xl:1.8125rem;--font-size-4xl:2.1875rem;--font-size-5xl:2.625rem}:root,.x1ccmotb{--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700}:root,.xrw1vgx{--radius-none:0px;--radius-inner:4px;--radius-element:8px;--radius-container:12px;--radius-page:28px;--radius-chat:28px;--radius-full:9999px}:root,.xua8qm3{--shadow-low:0px 1px 1px var(--lightningcss-light,#0000001a)var(--lightningcss-dark,#0003), 0px 2px 8px var(--lightningcss-light,#0000001a)var(--lightningcss-dark,#0003);--shadow-med:0px 1px 2px var(--lightningcss-light,#0000001a)var(--lightningcss-dark,#0003), 0px 2px 12px var(--lightningcss-light,#0000001a)var(--lightningcss-dark,#0003);--shadow-high:0px 2px 2px var(--lightningcss-light,#0000001a)var(--lightningcss-dark,#0003), 0px 8px 24px var(--lightningcss-light,#0000001a)var(--lightningcss-dark,#0000004d);--shadow-inset-hover:inset 0px 0px 0px 2px var(--lightningcss-light,#05365926)var(--lightningcss-dark,#dfe2e533);--shadow-inset-selected:inset 0px 0px 0px 2px #0171e380;--shadow-inset-success:inset 0px 0px 0px 2px #26a7564d;--shadow-inset-warning:inset 0px 0px 0px 2px #e2a4004d;--shadow-inset-error:inset 0px 0px 0px 2px #e3193b4d}:root,.xkgjyic{--size-element-sm:28px;--size-element-md:32px;--size-element-lg:36px}:root,.x1kvdh9l{--spacing-0:0px;--spacing-0-5:2px;--spacing-1:4px;--spacing-1-5:6px;--spacing-2:8px;--spacing-3:12px;--spacing-4:16px;--spacing-5:20px;--spacing-6:24px;--spacing-7:28px;--spacing-8:32px;--spacing-9:36px;--spacing-10:40px;--spacing-11:44px;--spacing-12:48px}:root,.x1etlgq0{--text-heading-1-size:var(--font-size-2xl);--text-heading-1-weight:var(--font-weight-semibold);--text-heading-1-leading:1.3333;--text-heading-2-size:var(--font-size-xl);--text-heading-2-weight:var(--font-weight-semibold);--text-heading-2-leading:1.4;--text-heading-3-size:var(--font-size-lg);--text-heading-3-weight:var(--font-weight-semibold);--text-heading-3-leading:1.4118;--text-heading-4-size:var(--font-size-base);--text-heading-4-weight:var(--font-weight-semibold);--text-heading-4-leading:1.4286;--text-heading-5-size:var(--font-size-sm);--text-heading-5-weight:var(--font-weight-semibold);--text-heading-5-leading:1.6667;--text-heading-6-size:var(--font-size-xs);--text-heading-6-weight:var(--font-weight-semibold);--text-heading-6-leading:1.6;--text-body-size:var(--font-size-base);--text-body-weight:var(--font-weight-normal);--text-body-leading:1.4286;--text-large-size:var(--font-size-lg);--text-large-weight:var(--font-weight-semibold);--text-large-leading:1.4118;--text-label-size:var(--font-size-base);--text-label-weight:var(--font-weight-medium);--text-label-leading:1.4286;--text-code-size:var(--font-size-base);--text-code-weight:var(--font-weight-normal);--text-code-leading:1.4286;--text-supporting-size:var(--font-size-sm);--text-supporting-weight:var(--font-weight-normal);--text-supporting-leading:1.6667;--text-display-1-size:var(--font-size-5xl);--text-display-1-weight:var(--font-weight-normal);--text-display-1-leading:1.2381;--text-display-2-size:var(--font-size-4xl);--text-display-2-weight:var(--font-weight-normal);--text-display-2-leading:1.2571;--text-display-3-size:var(--font-size-3xl);--text-display-3-weight:var(--font-weight-normal);--text-display-3-leading:1.2414}.xlz5hwt{--_avatar-group-overlap:var(--x---_avatar-group-overlap)}.xdarwi0{--_avatar-radius:var(--radius-element)}.xeincmr{--_avatar-radius:var(--radius-full)}.x877142{--_avatar-radius:var(--radius-none)}.xh8ntw8{--_button-radius:calc(var(--radius-element) - var(--spacing-1))}.xcw7vlg{--_button-radius:max(var(--radius-element),calc(var(--_chat-composer-radius) - var(--_chat-composer-padding)))}.x1rjw8qi{--_button-radius:var(--radius-full)}.xw28qpl{--_card-elevation:0 0 transparent}.xnpe7fx{--_card-elevation:var(--shadow-high)}.x1nn8khe{--_card-elevation:var(--shadow-low)}.x1ovzxg0{--_card-elevation:var(--shadow-med)}.x2kkz0m{--_card-radius:var(--radius-container)}.xr9ms2c{--_card-ring:inset 0 0 0 2px var(--color-accent)}.xgwwt2v{--_card-ring:inset 0 0 0 2px var(--color-border-blue)}.xcdi0x3{--_card-ring:inset 0 0 0 2px var(--color-border-cyan)}.x1m1zkwp{--_card-ring:inset 0 0 0 2px var(--color-border-gray)}.x1485227{--_card-ring:inset 0 0 0 2px var(--color-border-green)}.x1cclxpp{--_card-ring:inset 0 0 0 2px var(--color-border-orange)}.xzs6dn4{--_card-ring:inset 0 0 0 2px var(--color-border-pink)}.x9zgi83{--_card-ring:inset 0 0 0 2px var(--color-border-purple)}.xo8718j{--_card-ring:inset 0 0 0 2px var(--color-border-red)}.xp4e5fy{--_card-ring:inset 0 0 0 2px var(--color-border-teal)}.x1glw7ee{--_card-ring:inset 0 0 0 2px var(--color-border-yellow)}.x3zsw4j{--_card-ring:inset 0 0 0 2px var(--selectable-card-ring-color)}.x18zce08{--_chat-composer-padding:var(--spacing-2)}.xk0ittl{--_chat-composer-padding:var(--spacing-3)}.xx161y6{--_chat-composer-radius:var(--radius-chat)}.xtk08jq{--_codeblock-gutter-width:var(--x---_codeblock-gutter-width)}.x9pmotm{--_conceal-opacity:0}.x1kgmhs9{--_conceal-opacity:1}.xvuvksw{--_dialog-radius:var(--radius-container)}.xgory14{--_dropdown-menu-padding:var(--spacing-1)}.x1fcsqxe{--_dropdown-menu-radius:var(--radius-container)}.x13l1x9d{--_fade-delay:0s}.x1832zxr{--_field-radius:var(--radius-element)}.xgzxwq1{--_focus-outline-offset:0}.x17wzz1v{--_focus-outline:none}.xhg274n{--_hover-delay:0s}.x8xu23y{--_hover-delay:var(--x---_hover-delay)}.xqwz7mz{--_hovercard-radius:var(--radius-container)}.xqxtgf4{--_input-clear-hit-content:none}.xtoycft{--_input-clear-hit-inset:0px}.xqlix59{--_item-description-color:var(--color-error)}.xufyqxy{--_item-label-color:var(--color-error)}.xiki222{--_popover-radius:var(--radius-container)}.xdjmrzf{--_reveal-delay-reduced:0s,0s}.x1dejzja{--_reveal-delay:0s,0s}.x1xiarpw{--_reveal-delay:0s,var(--duration-fast)}.xct0gwe{--_reveal-opacity:0}.x5setjs{--_reveal-opacity:1}.xp0pj8v{--_reveal-position:absolute}.x1r6s5ct{--_reveal-position:static}.x1f17rg1{--_section-padding-propagated:initial}.x2ccaqq{--_section-padding-propagated:var(--spacing-0-5)}.x7mo41q{--_section-padding-propagated:var(--spacing-0)}.xxa843v{--_section-padding-propagated:var(--spacing-1-5)}.x1j3iakl{--_section-padding-propagated:var(--spacing-1)}.x4h2jfd{--_section-padding-propagated:var(--spacing-10)}.xezgk69{--_section-padding-propagated:var(--spacing-2)}.x1wtz8uf{--_section-padding-propagated:var(--spacing-3)}.x5wdj8h{--_section-padding-propagated:var(--spacing-4)}.xgjndll{--_section-padding-propagated:var(--spacing-5)}.x15i4jqh{--_section-padding-propagated:var(--spacing-6)}.xmb9lpv{--_section-padding-propagated:var(--spacing-8)}.x18jk3ff{--_segmented-control-padding:var(--spacing-0-5)}.x9icjy1{--_segmented-control-radius:var(--radius-element)}.x69vvuq{--_spinner-box-size:calc(var(--_spinner-ring-diameter) + var(--_spinner-ring-stroke) * 2)}.x2lq4xu{--_spinner-ring-diameter:var(--spinner-diameter)}.x10qssua{--_spinner-ring-stroke:var(--spinner-stroke-width)}.xficto1{--_tab-indicator-bottom:calc(-1 * (var(--spacing-1) + var(--border-width)))}.xbrl7fg{--_tab-indicator-bottom:var(--x---_tab-indicator-bottom)}.x78b515{--_tab-strip-bleed:0px}.x1kdpo6e{--_textarea-inline-padding:var(--spacing-2)}.x1ur4yav{--_thumbnail-hit-inset:0px}.x87gnkx{--_toast-slide-y:calc(-1 * var(--spacing-2))}.x1heqljd{--_toast-slide-y:var(--spacing-2)}.x16bblx1{--button-focus-offset:var(--focus-outline-offset)}.x1v15ycx{--button-icon-only-aspect:1 / 1}.x1mtvhk1{--color-syntax-background:transparent}.x18nyedi{--container-max-height:var(--x---container-max-height)}.xax9j7h{--container-padding-block-end:0px}.x1omyuck{--container-padding-block-end:var(--astryx-card-padding-block-end,var(--astryx-card-padding,var(--spacing-4)))}.x1gvthzm{--container-padding-block-end:var(--astryx-dialog-padding-block-end,var(--astryx-dialog-padding,var(--spacing-4)))}.xek4msv{--container-padding-block-end:var(--astryx-section-padding-block-end,var(--_section-padding-propagated,var(--astryx-section-padding,var(--spacing-4))))}.xi9ns85{--container-padding-block-end:var(--layout-padding-inner-y,var(--spacing-4))}.x1xjq73n{--container-padding-block-end:var(--layout-padding-outer-y,var(--spacing-4))}.x1cao3zv{--container-padding-block-end:var(--spacing-0-5)}.xkunwnr{--container-padding-block-end:var(--spacing-0)}.xv53x8y{--container-padding-block-end:var(--spacing-1-5)}.x57a7ii{--container-padding-block-end:var(--spacing-1)}.x15vxphk{--container-padding-block-end:var(--spacing-10)}.x4bg2x9{--container-padding-block-end:var(--spacing-11)}.x186mjxr{--container-padding-block-end:var(--spacing-12)}.x1lsgcmx{--container-padding-block-end:var(--spacing-2)}.x1q3ppug{--container-padding-block-end:var(--spacing-3)}.x4hfsld{--container-padding-block-end:var(--spacing-4)}.xbib2ws{--container-padding-block-end:var(--spacing-5)}.x1q8d17g{--container-padding-block-end:var(--spacing-6)}.x1yqogew{--container-padding-block-end:var(--spacing-7)}.x8lgq76{--container-padding-block-end:var(--spacing-8)}.x1f7f9rt{--container-padding-block-end:var(--spacing-9)}.x1047aw6{--container-padding-block-start:0px}.x1rqz8me{--container-padding-block-start:var(--astryx-card-padding-block-start,var(--astryx-card-padding,var(--spacing-4)))}.x1g2kccc{--container-padding-block-start:var(--astryx-dialog-padding-block-start,var(--astryx-dialog-padding,var(--spacing-4)))}.xnw7zt4{--container-padding-block-start:var(--astryx-section-padding-block-start,var(--_section-padding-propagated,var(--astryx-section-padding,var(--spacing-4))))}.xjmgx01{--container-padding-block-start:var(--layout-padding-inner-y,var(--spacing-4))}.xzz8v79{--container-padding-block-start:var(--layout-padding-outer-y,var(--spacing-4))}.xvdf9ev{--container-padding-block-start:var(--spacing-0-5)}.x1i3qcxz{--container-padding-block-start:var(--spacing-0)}.x1kbx601{--container-padding-block-start:var(--spacing-1-5)}.xnsckjb{--container-padding-block-start:var(--spacing-1)}.x17h9kl7{--container-padding-block-start:var(--spacing-10)}.x1rdjxae{--container-padding-block-start:var(--spacing-11)}.xecwdl6{--container-padding-block-start:var(--spacing-12)}.xa8b4fq{--container-padding-block-start:var(--spacing-2)}.x11k4f5r{--container-padding-block-start:var(--spacing-3)}.xm01sq8{--container-padding-block-start:var(--spacing-4)}.xp8wdkl{--container-padding-block-start:var(--spacing-5)}.x1hmud4d{--container-padding-block-start:var(--spacing-6)}.x1c00sag{--container-padding-block-start:var(--spacing-7)}.xfv60at{--container-padding-block-start:var(--spacing-8)}.x14fzdu7{--container-padding-block-start:var(--spacing-9)}.xjsfl84{--container-padding-inline-end:0px}.x1ihxwbr{--container-padding-inline-end:var(--astryx-card-padding-inline-end,var(--astryx-card-padding-inline,var(--astryx-card-padding,var(--spacing-4))))}.x11h1f2o{--container-padding-inline-end:var(--astryx-dialog-padding-inline-end,var(--astryx-dialog-padding-inline,var(--astryx-dialog-padding,var(--spacing-4))))}.xu1wldr{--container-padding-inline-end:var(--astryx-section-padding-inline-end,var(--astryx-section-padding-inline,var(--_section-padding-propagated,var(--astryx-section-padding,var(--spacing-4)))))}.xikqloz{--container-padding-inline-end:var(--layout-padding-inner-x,var(--spacing-4))}.xqpvj4r{--container-padding-inline-end:var(--layout-padding-outer-x,var(--spacing-4))}.x1wz3t3y{--container-padding-inline-end:var(--spacing-0-5)}.x91ghl5{--container-padding-inline-end:var(--spacing-0)}.xntetml{--container-padding-inline-end:var(--spacing-1-5)}.x2oyxnl{--container-padding-inline-end:var(--spacing-1)}.xx5lg5w{--container-padding-inline-end:var(--spacing-10)}.x1nmgbqg{--container-padding-inline-end:var(--spacing-11)}.x1wsfsk2{--container-padding-inline-end:var(--spacing-12)}.xcas3b9{--container-padding-inline-end:var(--spacing-2)}.xu0ipoa{--container-padding-inline-end:var(--spacing-3)}.xs0pscg{--container-padding-inline-end:var(--spacing-4)}.xgkj7vj{--container-padding-inline-end:var(--spacing-5)}.x94cj42{--container-padding-inline-end:var(--spacing-6)}.x11tj35w{--container-padding-inline-end:var(--spacing-7)}.x1b9k1pi{--container-padding-inline-end:var(--spacing-8)}.x19w02kr{--container-padding-inline-end:var(--spacing-9)}.xrhngw9{--container-padding-inline-start:0px}.xjmlhfd{--container-padding-inline-start:var(--astryx-card-padding-inline-start,var(--astryx-card-padding-inline,var(--astryx-card-padding,var(--spacing-4))))}.x1tewnwq{--container-padding-inline-start:var(--astryx-dialog-padding-inline-start,var(--astryx-dialog-padding-inline,var(--astryx-dialog-padding,var(--spacing-4))))}.x19lemt0{--container-padding-inline-start:var(--astryx-section-padding-inline-start,var(--astryx-section-padding-inline,var(--_section-padding-propagated,var(--astryx-section-padding,var(--spacing-4)))))}.x408pgh{--container-padding-inline-start:var(--layout-padding-inner-x,var(--spacing-4))}.xdvaxxn{--container-padding-inline-start:var(--layout-padding-outer-x,var(--spacing-4))}.x14ws0sr{--container-padding-inline-start:var(--spacing-0-5)}.x1gu2k80{--container-padding-inline-start:var(--spacing-0)}.x176g23i{--container-padding-inline-start:var(--spacing-1-5)}.x1cvlban{--container-padding-inline-start:var(--spacing-1)}.xserb3f{--container-padding-inline-start:var(--spacing-10)}.xziclwo{--container-padding-inline-start:var(--spacing-11)}.x1iiwihq{--container-padding-inline-start:var(--spacing-12)}.x1xlrr2o{--container-padding-inline-start:var(--spacing-2)}.xfdwxua{--container-padding-inline-start:var(--spacing-3)}.x1dlhslv{--container-padding-inline-start:var(--spacing-4)}.x1s81nki{--container-padding-inline-start:var(--spacing-5)}.x1ep0dkj{--container-padding-inline-start:var(--spacing-6)}.x157xojc{--container-padding-inline-start:var(--spacing-7)}.xw1diwv{--container-padding-inline-start:var(--spacing-8)}.xraca2a{--container-padding-inline-start:var(--spacing-9)}.x1qfzo5y{--indicator-color:transparent}.x4906uf{--layout-content-width:var(--x---layout-content-width)}.x1qfll2g{--layout-padding-inner-x:initial}.x4poyjn{--layout-padding-inner-x:var(--astryx-card-padding-inline-start,var(--astryx-card-padding-inline,var(--astryx-card-padding,var(--spacing-4))))}.x2so38{--layout-padding-inner-x:var(--astryx-dialog-padding-inline-start,var(--astryx-dialog-padding-inline,var(--astryx-dialog-padding,var(--spacing-4))))}.x1v3gmnx{--layout-padding-inner-x:var(--astryx-section-padding-inline-start,var(--astryx-section-padding-inline,var(--_section-padding-propagated,var(--astryx-section-padding,var(--spacing-4)))))}.xlriy2h{--layout-padding-inner-x:var(--spacing-0-5)}.xj1bl4l{--layout-padding-inner-x:var(--spacing-0)}.xd38f90{--layout-padding-inner-x:var(--spacing-1-5)}.x6uuyak{--layout-padding-inner-x:var(--spacing-1)}.x1vf4qco{--layout-padding-inner-x:var(--spacing-10)}.xsmamsf{--layout-padding-inner-x:var(--spacing-11)}.x2xk2xj{--layout-padding-inner-x:var(--spacing-12)}.xxqksqd{--layout-padding-inner-x:var(--spacing-2)}.x1fyui2f{--layout-padding-inner-x:var(--spacing-3)}.x1i2ajwi{--layout-padding-inner-x:var(--spacing-4)}.x1tac27u{--layout-padding-inner-x:var(--spacing-5)}.x1ntgf3t{--layout-padding-inner-x:var(--spacing-6)}.xhjd9tl{--layout-padding-inner-x:var(--spacing-7)}.xn7c84u{--layout-padding-inner-x:var(--spacing-8)}.xeqkbsz{--layout-padding-inner-x:var(--spacing-9)}.xyvxpqs{--layout-padding-inner-y:initial}.x1u1kw4e{--layout-padding-inner-y:var(--astryx-card-padding-block-start,var(--astryx-card-padding,var(--spacing-4)))}.xinu7xd{--layout-padding-inner-y:var(--astryx-dialog-padding-block-start,var(--astryx-dialog-padding,var(--spacing-4)))}.x15yx5hm{--layout-padding-inner-y:var(--astryx-section-padding-block-start,var(--_section-padding-propagated,var(--astryx-section-padding,var(--spacing-4))))}.x180h0y5{--layout-padding-inner-y:var(--spacing-0-5)}.xwuefyo{--layout-padding-inner-y:var(--spacing-0)}.x1g8jpzm{--layout-padding-inner-y:var(--spacing-1-5)}.xmpug6m{--layout-padding-inner-y:var(--spacing-1)}.x18gbwmk{--layout-padding-inner-y:var(--spacing-10)}.x14zymzj{--layout-padding-inner-y:var(--spacing-11)}.xzfpkx9{--layout-padding-inner-y:var(--spacing-12)}.x1lksgje{--layout-padding-inner-y:var(--spacing-2)}.x4j7gld{--layout-padding-inner-y:var(--spacing-3)}.x1s3ehtl{--layout-padding-inner-y:var(--spacing-4)}.x1rj5eim{--layout-padding-inner-y:var(--spacing-5)}.x1ftgg6u{--layout-padding-inner-y:var(--spacing-6)}.x1ho74vh{--layout-padding-inner-y:var(--spacing-7)}.xm2cs6f{--layout-padding-inner-y:var(--spacing-8)}.x1vsq92b{--layout-padding-inner-y:var(--spacing-9)}.x1wbjvqu{--layout-padding-outer-x:0px}.xdt8ak2{--layout-padding-outer-x:initial}.x14rzhog{--layout-padding-outer-x:var(--astryx-card-padding-inline-start,var(--astryx-card-padding-inline,var(--astryx-card-padding,var(--spacing-4))))}.x1hsjncj{--layout-padding-outer-x:var(--astryx-dialog-padding-inline-start,var(--astryx-dialog-padding-inline,var(--astryx-dialog-padding,var(--spacing-4))))}.x15i0zw9{--layout-padding-outer-x:var(--astryx-section-padding-inline-start,var(--astryx-section-padding-inline,var(--_section-padding-propagated,var(--astryx-section-padding,var(--spacing-4)))))}.xihiwg7{--layout-padding-outer-x:var(--spacing-0-5)}.xswhm3q{--layout-padding-outer-x:var(--spacing-0)}.x1u93lgd{--layout-padding-outer-x:var(--spacing-1-5)}.xc96xmq{--layout-padding-outer-x:var(--spacing-1)}.x1jdf5a4{--layout-padding-outer-x:var(--spacing-10)}.x1hct0t0{--layout-padding-outer-x:var(--spacing-11)}.x11cyqoe{--layout-padding-outer-x:var(--spacing-12)}.x15dxnc0{--layout-padding-outer-x:var(--spacing-2)}.xadgj3j{--layout-padding-outer-x:var(--spacing-3)}.x1v56qcf{--layout-padding-outer-x:var(--spacing-4)}.x1nzs0gl{--layout-padding-outer-x:var(--spacing-5)}.x1c3n52a{--layout-padding-outer-x:var(--spacing-6)}.x1gfiokx{--layout-padding-outer-x:var(--spacing-7)}.x1t3kfz{--layout-padding-outer-x:var(--spacing-8)}.xzr4qsh{--layout-padding-outer-x:var(--spacing-9)}.xzxxx64{--layout-padding-outer-y:0px}.x1rs4lu4{--layout-padding-outer-y:initial}.xjej9fs{--layout-padding-outer-y:var(--astryx-card-padding-block-start,var(--astryx-card-padding,var(--spacing-4)))}.x1pui4bz{--layout-padding-outer-y:var(--astryx-dialog-padding-block-start,var(--astryx-dialog-padding,var(--spacing-4)))}.x1vw4zgg{--layout-padding-outer-y:var(--astryx-section-padding-block-start,var(--_section-padding-propagated,var(--astryx-section-padding,var(--spacing-4))))}.x1vj96e0{--layout-padding-outer-y:var(--spacing-0-5)}.x1mzf5mb{--layout-padding-outer-y:var(--spacing-0)}.xd3dqby{--layout-padding-outer-y:var(--spacing-1-5)}.x1gpfxoh{--layout-padding-outer-y:var(--spacing-1)}.x26l4wa{--layout-padding-outer-y:var(--spacing-10)}.x10zktp0{--layout-padding-outer-y:var(--spacing-11)}.x1yz3n6a{--layout-padding-outer-y:var(--spacing-12)}.x10pz7y9{--layout-padding-outer-y:var(--spacing-2)}.x1p6yq3h{--layout-padding-outer-y:var(--spacing-3)}.xx738ci{--layout-padding-outer-y:var(--spacing-4)}.x6yxws5{--layout-padding-outer-y:var(--spacing-5)}.x180vrwl{--layout-padding-outer-y:var(--spacing-6)}.x1q6rme1{--layout-padding-outer-y:var(--spacing-7)}.xid7e43{--layout-padding-outer-y:var(--spacing-8)}.x1t5kicu{--layout-padding-outer-y:var(--spacing-9)}.xnpej1e{--radius-element:var(--radius-full)}.x11rj6l1{--selectable-card-ring-color:var(--color-accent)}.xkce8z9{--separator-display:flex}.x1uzk0gl{--spinner-color:currentColor}.xt1b8mc{--spinner-color:var(--color-accent)}.x13u6jys{--spinner-color:var(--color-on-dark)}.x1jevo6s{--spinner-color:var(--color-text-secondary)}.x11wm0hx{--spinner-diameter:10px}.x15pu9g6{--spinner-diameter:14px}.x1w424tr{--spinner-diameter:18px}.x1orj1z9{--spinner-diameter:28px}.xls98ul{--spinner-stroke-width:2px}.xr0wkrm{--spinner-stroke-width:3px}.x7y2bof{--spinner-stroke-width:4px}.xbfzqbu{--spinner-track-color:currentColor}.x1ufpcf6{--spinner-track-color:var(--color-on-dark)}.xspt9s2{--spinner-track-color:var(--color-track)}.xpa4xmd{--tree-list-indent:var(--spacing-4)}.x1xbi2jf{--tree-list-row-gap:var(--spacing-0-5)}.x1wfyzv7:focus-within{--_fade-delay:0s}.xqchwus:focus-visible{--_focus-outline-offset:var(--focus-outline-offset)}.xqih627:focus-visible{--_focus-outline:var(--focus-outline-width) var(--focus-outline-style) var(--focus-outline-color)}.x1z42dm:focus-within{--_reveal-delay-reduced:0s,0s}.x1mjsb9v:focus-within{--_reveal-delay:0s,0s}.xi33vf3:focus-within{--_reveal-opacity:1}.xoa21yc:focus-within{--_reveal-position:static}.x11woleg:focus-visible,.x1my2cv6.x1my2cv6:hover:where(:not(:disabled,[aria-disabled=true])){--indicator-color:var(--color-accent)}.x158n88w:has(:focus-visible){--_tab-strip-bleed:calc(var(--focus-outline-width) + var(--focus-outline-offset))}.x1ibt0lz:first-child{--separator-display:none}.x1rht92:nth-child(2n){--table-row-overlay:var(--color-background-muted)}@media (any-pointer:coarse){.x1hl81f0.x1hl81f0{--_fade-delay:0s}}@media (pointer:coarse){.xp8r40j.xp8r40j{--_input-clear-hit-content:""}.x181bpwf.x181bpwf{--_input-clear-hit-inset:-2px}}@media (any-pointer:coarse){.xm1aeao.xm1aeao{--_reveal-delay-reduced:0s,0s}.x1pn63d7.x1pn63d7{--_reveal-delay:0s,0s}.xi7d7de.xi7d7de{--_reveal-opacity:1}.xarvkxi.xarvkxi{--_reveal-position:static}}@media (pointer:coarse){.x1h9khjt.x1h9khjt{--_thumbnail-hit-inset:-2px}}@media (hover:hover){.x1316hva.x1316hva.x1316hva:hover:where(:not(:disabled,[aria-disabled=true])){--_conceal-opacity:0}.xuzfaso.xuzfaso.xuzfaso:hover:where(:not(:disabled,[aria-disabled=true])){--_conceal-opacity:1}.xq03417.xq03417.xq03417:hover:where(:not(:disabled,[aria-disabled=true])){--_fade-delay:0s}.x14nxqze.x14nxqze.x14nxqze:hover:where(:not(:disabled,[aria-disabled=true])){--_fade-delay:var(--_hover-delay,0s)}.xap96qf.xap96qf.xap96qf:hover:where(:not(:disabled,[aria-disabled=true])){--_reveal-delay-reduced:0s,0s}.xvd8mm8.xvd8mm8.xvd8mm8:hover:where(:not(:disabled,[aria-disabled=true])){--_reveal-delay-reduced:var(--_hover-delay,0s),var(--_hover-delay,0s)}.x1t6fdr0.x1t6fdr0.x1t6fdr0:hover:where(:not(:disabled,[aria-disabled=true])){--_reveal-delay:0s,0s}.x1tx49wl.x1tx49wl.x1tx49wl:hover:where(:not(:disabled,[aria-disabled=true])){--_reveal-delay:0s,var(--duration-fast)}.xi1ebb6.xi1ebb6.xi1ebb6:hover:where(:not(:disabled,[aria-disabled=true])){--_reveal-delay:var(--_hover-delay,0s),var(--_hover-delay,0s)}.xfqgg65.xfqgg65.xfqgg65:hover:where(:not(:disabled,[aria-disabled=true])){--_reveal-opacity:0}.x2xrgwu.x2xrgwu.x2xrgwu:hover:where(:not(:disabled,[aria-disabled=true])){--_reveal-opacity:1}.x17ock8y.x17ock8y.x17ock8y:hover:where(:not(:disabled,[aria-disabled=true])){--_reveal-position:absolute}.x1or4zte.x1or4zte.x1or4zte:hover:where(:not(:disabled,[aria-disabled=true])){--_reveal-position:static}.xc01ov8.xc01ov8.xc01ov8:hover:where(:not(:disabled,[aria-disabled=true])){--table-row-overlay:var(--color-overlay-hover)}}.xln7xf2:not(#\#){font:inherit}.x15r89dc:not(#\#){grid-area:1/1}.x10a8y8t:not(#\#){inset:0}.x1anvkwx:not(#\#){inset:auto}.xh3736h:not(#\#){inset:unset}.xkdpibf:not(#\#){margin:-1px}.x1ghz6dp:not(#\#){margin:0}.xkib98w:not(#\#){margin:8px}.x1bpp3o7:not(#\#){margin:auto}.x1n5sqmh:not(#\#){margin:calc(-1 * (var(--spacing-2) - var(--spacing-1) + 1px))}.x1717udv:not(#\#){padding:0}.x1tamke2:not(#\#){padding:16px}.x1i3ajwb:not(#\#){padding:2px}.xfawy5m:not(#\#){padding:4px}.x1b50gpf:not(#\#){padding:calc(var(--_chat-composer-padding) - var(--border-width))}.x18oj4ui:not(#\#){padding:var(--_chat-composer-padding)}.xpoxszi:not(#\#){padding:var(--_segmented-control-padding)}.xtozwh:not(#\#){padding:var(--spacing-1) var(--spacing-2)}.x9epnlk:not(#\#){padding:var(--spacing-1)}.x15nmkw0:not(#\#){padding:var(--spacing-2) 0}.xlsj2fj:not(#\#){padding:var(--spacing-2)}.x1b2ylru:not(#\#){padding:var(--spacing-3)}.x1shk3sm:not(#\#){padding:var(--spacing-4)}.x1y5lnwp:focus:not(#\#){margin:0}.xg8s4dl:not(#\#):not(#\#){animation-range:cover}.x9r1u3d:not(#\#):not(#\#){border-color:#0000}.xad5do:not(#\#):not(#\#){border-color:var(--color-accent)}.x1touxvs:not(#\#):not(#\#){border-color:var(--color-background-surface)}.xlee4gx:not(#\#):not(#\#){border-color:var(--color-border-blue)}.xb1xfl:not(#\#):not(#\#){border-color:var(--color-border-cyan)}.xvy26l8:not(#\#):not(#\#){border-color:var(--color-border-emphasized)}.x1w9ec3u:not(#\#):not(#\#){border-color:var(--color-border-gray)}.xy90a9n:not(#\#):not(#\#){border-color:var(--color-border-green)}.xloqurj:not(#\#):not(#\#){border-color:var(--color-border-orange)}.x1czkbn8:not(#\#):not(#\#){border-color:var(--color-border-pink)}.xq98wne:not(#\#):not(#\#){border-color:var(--color-border-purple)}.xjqgoec:not(#\#):not(#\#){border-color:var(--color-border-red)}.x1r9gxr1:not(#\#):not(#\#){border-color:var(--color-border-teal)}.x1kpnwn1:not(#\#):not(#\#){border-color:var(--color-border-yellow)}.x14i3s5s:not(#\#):not(#\#){border-color:var(--color-border)}.x1ofxpqo:not(#\#):not(#\#){border-color:var(--color-error)}.x16m2moy:not(#\#):not(#\#){border-color:var(--color-success)}.xqcx1ss:not(#\#):not(#\#){border-color:var(--color-text-primary)}.x8wg1ba:not(#\#):not(#\#){border-color:var(--color-warning)}.x2u8bby:not(#\#):not(#\#){border-radius:0}.x1nj7uno:not(#\#):not(#\#){border-radius:1px}.x16rqkct:not(#\#):not(#\#){border-radius:50%}.xur7f20:not(#\#):not(#\#){border-radius:8px}.x1pjcqnp:not(#\#):not(#\#){border-radius:inherit}.x1ws5lxm:not(#\#):not(#\#){border-radius:max(0px,calc(var(--_dropdown-menu-radius,var(--spacing-2)) - var(--_dropdown-menu-padding,var(--spacing-1))))}.xc910v0:not(#\#):not(#\#){border-radius:max(0px,calc(var(--_segmented-control-radius) - var(--_segmented-control-padding)))}.xbc78cj:not(#\#):not(#\#){border-radius:var(--_avatar-radius)}.x1vf2byn:not(#\#):not(#\#){border-radius:var(--_banner-radius,var(--radius-container))}.x1jxw6zd:not(#\#):not(#\#){border-radius:var(--_button-radius,var(--radius-element))}.xy0xnkn:not(#\#):not(#\#){border-radius:var(--_button-radius,var(--radius-full))}.x153u1i6:not(#\#):not(#\#){border-radius:var(--_card-radius)}.x1xunbrq:not(#\#):not(#\#){border-radius:var(--_chat-composer-radius)}.xuacgfc:not(#\#):not(#\#){border-radius:var(--_dialog-radius)}.x1n97fys:not(#\#):not(#\#){border-radius:var(--_dropdown-menu-radius)}.xvdfih8:not(#\#):not(#\#){border-radius:var(--_field-radius)}.x7a53xk:not(#\#):not(#\#){border-radius:var(--_hovercard-radius)}.x11m9jtl:not(#\#):not(#\#){border-radius:var(--_popover-radius)}.x1hapoqb:not(#\#):not(#\#){border-radius:var(--_segmented-control-radius)}.xashgol:not(#\#):not(#\#){border-radius:var(--radius-chat)}.x1hviunn:not(#\#):not(#\#){border-radius:var(--radius-container)}.xh6dtrn:not(#\#):not(#\#){border-radius:var(--radius-element)}.xjspbzw:not(#\#):not(#\#){border-radius:var(--radius-full)}.xx3sua9:not(#\#):not(#\#){border-radius:var(--radius-inner)}.xwksslw:not(#\#):not(#\#){border-radius:var(--radius-none)}.xbsl7fq:not(#\#):not(#\#){border-style:dashed}.xng3xce:not(#\#):not(#\#){border-style:none}.x1y0btm7:not(#\#):not(#\#){border-style:solid}.xc342km:not(#\#):not(#\#){border-width:0}.xmkeg23:not(#\#):not(#\#){border-width:1px}.xdh2fpr:not(#\#):not(#\#){border-width:2px}.x1litavf:not(#\#):not(#\#){border-width:var(--border-width)}.x1mw0n95:not(#\#):not(#\#){border-width:var(--x-borderWidth)}.x1somy94:not(#\#):not(#\#){flex:0 0 0}.x3psx0u:not(#\#):not(#\#){flex:none}.x1cqoux5:not(#\#):not(#\#){flex:1 1 0}.x845mor:not(#\#):not(#\#){flex:1}.xfoc8du:not(#\#):not(#\#){flex:40px}.x12lumcd:not(#\#):not(#\#){flex:auto}.x98rzlu:not(#\#):not(#\#){flex:1}.xxhr3t:not(#\#):not(#\#){gap:0}.x1jnr06f:not(#\#):not(#\#){gap:4px}.x167g77z:not(#\#):not(#\#){gap:8px}.x14kbac9:not(#\#):not(#\#){gap:inherit}.x1lsbc85:not(#\#):not(#\#){gap:var(--spacing-0-5)}.xsn7fz1:not(#\#):not(#\#){gap:var(--spacing-0)}.x1s4dlld:not(#\#):not(#\#){gap:var(--spacing-1-5)}.xzye2dw:not(#\#):not(#\#){gap:var(--spacing-1)}.x3hoi3v:not(#\#):not(#\#){gap:var(--spacing-10)}.xpec5dj:not(#\#):not(#\#){gap:var(--spacing-2) var(--spacing-4)}.x1txdalj:not(#\#):not(#\#){gap:var(--spacing-2)}.xlaq8a2:not(#\#):not(#\#){gap:var(--spacing-3) var(--spacing-4)}.xjcht0a:not(#\#):not(#\#){gap:var(--spacing-3)}.x18g69wz:not(#\#):not(#\#){gap:var(--spacing-4)}.x9mgr7n:not(#\#):not(#\#){gap:var(--spacing-5)}.x1qh66ti:not(#\#):not(#\#){gap:var(--spacing-6)}.x4t41sb:not(#\#):not(#\#){gap:var(--spacing-8)}.x1pidvrl:not(#\#):not(#\#){gap:var(--x-gap)}.xgkxs2y:not(#\#):not(#\#){grid-column:1}.x1ms6mhf:not(#\#):not(#\#){grid-row:1}.x10no89f:not(#\#):not(#\#){inset-block:0}.x17y0mx6:not(#\#):not(#\#){inset-inline:0}.xe8uvvx:not(#\#):not(#\#){list-style:none}.x81ka23:not(#\#):not(#\#){margin-block:calc(-1 * (var(--spacing-3) - var(--spacing-2)))}.xhzvc8f:not(#\#):not(#\#){margin-block:calc(-1 * var(--spacing-2))}.xqixskq:not(#\#):not(#\#){margin-block:calc(var(--size-element-md) / 2 - var(--spacing-2) - var(--text-heading-2-size) * var(--text-heading-2-leading) / 2)}.xsq74q5:not(#\#):not(#\#){margin-block:var(--spacing-1)}.x1g06x3t:not(#\#):not(#\#){margin-block:var(--spacing-2)}.x1oqu0vw:not(#\#):not(#\#){margin-block:var(--x-marginBlock)}.xvueqy4:not(#\#):not(#\#){margin-inline:auto}.xi5l473:not(#\#):not(#\#){margin-inline:calc(-1 * (var(--_tab-strip-bleed)))}.xtedp8i:not(#\#):not(#\#){margin-inline:calc(-1 * var(--spacing-1))}.x1ho7dyk:not(#\#):not(#\#){margin-inline:calc(-1 * var(--spacing-2))}.x1ng9b9t:not(#\#):not(#\#){margin-inline:calc(-1 * var(--spacing-4))}.xhrcg97:not(#\#):not(#\#){margin-inline:var(--spacing-1)}.xvlecxo:not(#\#):not(#\#){margin-inline:var(--x-marginInline)}.x1a2a7pz:not(#\#):not(#\#){outline:none}.xaw4jrz:not(#\#):not(#\#){outline:var(--_focus-outline,none)}.xysyzu8:not(#\#):not(#\#){overflow:auto}.x7giv3:not(#\#):not(#\#){overflow:clip}.xb3r6kr:not(#\#):not(#\#){overflow:hidden}.x1rea2x4:not(#\#):not(#\#){overflow:visible}.xish69e:not(#\#):not(#\#){overscroll-behavior:contain}.x8du1vd:not(#\#):not(#\#){overscroll-behavior:none}.xt970qd:not(#\#):not(#\#){padding-block:0}.x1vn5h1t:not(#\#):not(#\#){padding-block:calc((var(--size-element-lg) - var(--spacing-5) - 2 * var(--border-width)) / 2)}.x1ioay2v:not(#\#):not(#\#){padding-block:calc((var(--size-element-md) - var(--spacing-5) - 2 * var(--border-width)) / 2)}.x1ecmfrv:not(#\#):not(#\#){padding-block:calc((var(--size-element-sm) - var(--spacing-5) - 2 * var(--border-width)) / 2)}.x1x7cmac:not(#\#):not(#\#){padding-block:calc(var(--spacing-1) - 1px)}.xwo4yc8:not(#\#):not(#\#){padding-block:calc(var(--tree-list-row-gap,0px) / 2)}.x13f7esw:not(#\#):not(#\#){padding-block:var(--spacing-0-5)}.x1hp7d8q:not(#\#):not(#\#){padding-block:var(--spacing-0)}.x1vofgu7:not(#\#):not(#\#){padding-block:var(--spacing-1-5)}.xu0wf1k:not(#\#):not(#\#){padding-block:var(--spacing-1)}.xce4md1:not(#\#):not(#\#){padding-block:var(--spacing-2)}.x8o8v82:not(#\#):not(#\#){padding-block:var(--spacing-3)}.x1na6nto:not(#\#):not(#\#){padding-block:var(--spacing-4)}.xq6koh6:not(#\#):not(#\#){padding-block:var(--spacing-6)}.xmfvnks:not(#\#):not(#\#){padding-block:var(--spacing-8)}.x1giekp1:not(#\#):not(#\#){padding-block:var(--x-paddingBlock)}.x1uameg1:not(#\#):not(#\#){padding-block:118px}.xnjsko4:not(#\#):not(#\#){padding-inline:0}.xx2oswg:not(#\#):not(#\#){padding-inline:calc(var(--spacing-1) - 1px)}.x2hg6jq:not(#\#):not(#\#){padding-inline:calc(var(--spacing-1) + var(--border-width))}.x1kpkw9v:not(#\#):not(#\#){padding-inline:var(--_tab-strip-bleed)}.x1w6f3ag:not(#\#):not(#\#){padding-inline:var(--_textarea-inline-padding)}.xkjnx3w:not(#\#):not(#\#){padding-inline:var(--spacing-0-5)}.x17a0aqu:not(#\#):not(#\#){padding-inline:var(--spacing-0)}.x4ezzuc:not(#\#):not(#\#){padding-inline:var(--spacing-1-5)}.x7a5moj:not(#\#):not(#\#){padding-inline:var(--spacing-1)}.xixulwi:not(#\#):not(#\#){padding-inline:var(--spacing-10)}.xf314gf:not(#\#):not(#\#){padding-inline:var(--spacing-2)}.xrrkdod:not(#\#):not(#\#){padding-inline:var(--spacing-3)}.x1pzlopt:not(#\#):not(#\#){padding-inline:var(--spacing-4)}.xzz68wx:not(#\#):not(#\#){padding-inline:var(--spacing-5)}.xm7rs69:not(#\#):not(#\#){padding-inline:var(--spacing-6)}.x6xnjw4:not(#\#):not(#\#){padding-inline:var(--spacing-8)}.x30g6up:not(#\#):not(#\#){padding-inline:var(--x-paddingInline)}.x1ku5rj1:not(#\#):not(#\#){place-items:center}.x1xif8ns:not(#\#):not(#\#){scroll-padding-inline:calc(var(--_tab-strip-bleed) + var(--spacing-8))}.xdf8p4l:not(#\#):not(#\#){scroll-padding-inline:var(--spacing-0-5)}.x9lgdif:not(#\#):not(#\#){scroll-padding-inline:var(--spacing-0)}.x1w8vatw:not(#\#):not(#\#){scroll-padding-inline:var(--spacing-1-5)}.x1u2972t:not(#\#):not(#\#){scroll-padding-inline:var(--spacing-1)}.xw959t8:not(#\#):not(#\#){scroll-padding-inline:var(--spacing-10)}.x1mfb6cv:not(#\#):not(#\#){scroll-padding-inline:var(--spacing-2)}.xpnzzb2:not(#\#):not(#\#){scroll-padding-inline:var(--spacing-3)}.x3m3szd:not(#\#):not(#\#){scroll-padding-inline:var(--spacing-4)}.x1vx7sv0:not(#\#):not(#\#){scroll-padding-inline:var(--spacing-5)}.x1mvw9yj:not(#\#):not(#\#){scroll-padding-inline:var(--spacing-6)}.x1xn2tv3:not(#\#):not(#\#){scroll-padding-inline:var(--spacing-8)}.xhfbhpw:not(#\#):not(#\#){scroll-snap-type:x mandatory}.x168l2et:not(#\#):not(#\#){scroll-snap-type:y mandatory}.xmqliwb:not(#\#):not(#\#){text-decoration:line-through}.x1hl2dhg:not(#\#):not(#\#){text-decoration:none}.x1bvjpef:not(#\#):not(#\#){text-decoration:underline}.xrg7dcy:not(#\#):not(#\#){transition:box-shadow var(--duration-fast) var(--ease-standard),border-color var(--duration-fast) var(--ease-standard)}.xb0j27v:not(#\#):not(#\#){transition:grid-template-rows var(--duration-medium) var(--ease-standard)}.xq2gx43:not(#\#):not(#\#){transition:none}.x1ey1afo:not(#\#):not(#\#){transition:opacity var(--duration-fast)}.x1ob6yzd:not(#\#):not(#\#){transition:transform var(--duration-fast) var(--ease-standard)}.x6q1khz:focus-within:not(#\#):not(#\#){border-color:var(--color-accent)}.xk2sxw7:focus-within:not(#\#):not(#\#){border-color:var(--color-error)}.xyq33ac:focus-within:not(#\#):not(#\#){border-color:var(--color-success)}.xa1yw2k:focus-within:not(#\#):not(#\#){border-color:var(--color-warning)}.xafswnp.xafswnp:where(.x1iwu4tg:has(:focus-visible) *):not(#\#):not(#\#){outline:var(--focus-outline-width) var(--focus-outline-style) var(--focus-outline-color)}.x1dordxg:focus-within:not(#\#):not(#\#){overflow:visible}.x16s19ga:has(:focus-visible):not(#\#):not(#\#){outline:var(--focus-outline-width) var(--focus-outline-style) var(--focus-outline-color)}.x64lkcz:focus:not(#\#):not(#\#){border-color:var(--color-error)}.x1lglk5v:focus:not(#\#):not(#\#){border-color:var(--color-success)}.x12sck4v:focus:not(#\#):not(#\#){border-color:var(--color-warning)}.x1uvtmcs:focus:not(#\#):not(#\#){outline:none}.xomzh7y:focus:not(#\#):not(#\#){overflow:visible}.xh2mrf5:focus:not(#\#):not(#\#){padding-block:var(--spacing-2)}.x1cf3d6k:focus:not(#\#):not(#\#){padding-inline:var(--spacing-4)}@media (forced-colors:active){.x1w1tqly.x1w1tqly:not(#\#):not(#\#){border-color:canvastext}.xmnqt3w.xmnqt3w:not(#\#):not(#\#){border-color:graytext}.xx61lck.xx61lck:not(#\#):not(#\#){border-style:solid}.x13rsnn2.x13rsnn2:not(#\#):not(#\#){border-width:1px}}@media (width<=480px){.x1a1jff.x1a1jff:not(#\#):not(#\#){gap:var(--spacing-4)}}@media (prefers-reduced-motion:reduce){.x9kvfbb.x9kvfbb:not(#\#):not(#\#){transition:none}}@media (hover:hover){.x1ozl1p1.x1ozl1p1.x1ozl1p1:where(.x1odsvnm:hover *):not(#\#):not(#\#){border-color:var(--color-accent)}@supports (color:color-mix(in lab, red, red)){.x1ozl1p1.x1ozl1p1.x1ozl1p1:where(.x1odsvnm:hover *):not(#\#):not(#\#){border-color:color-mix(in srgb,var(--color-accent),var(--color-tint-hover) 15%)}}.xilc7fp.xilc7fp.xilc7fp:where(.x1odsvnm:hover *):not(#\#):not(#\#){border-color:var(--color-border-emphasized)}@supports (color:color-mix(in lab, red, red)){.xilc7fp.xilc7fp.xilc7fp:where(.x1odsvnm:hover *):not(#\#):not(#\#){border-color:color-mix(in srgb,var(--color-border-emphasized),var(--color-tint-hover) 20%)}}.x61roa7.x61roa7.x61roa7:where(.x1odsvnm:hover *):not(#\#):not(#\#){border-color:var(--color-border)}.x1xwh4np.x1xwh4np.x1xwh4np:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#){border-color:var(--color-border-emphasized)}.x13nosk6.x13nosk6.x13nosk6:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#){text-decoration:underline}}.x1lugfcp:not(#\#):not(#\#):not(#\#){-webkit-appearance:none}.x67t5t6:not(#\#):not(#\#):not(#\#){-webkit-backdrop-filter:blur(12px)}.x1ua5tub:not(#\#):not(#\#):not(#\#){-webkit-box-orient:vertical}.x1yhjpo9:not(#\#):not(#\#):not(#\#){-webkit-line-clamp:var(--x-WebkitLineClamp)}.xiy8rlo:not(#\#):not(#\#):not(#\#){-webkit-mask-image:linear-gradient(#0000,#000 24px)}.x1bv1mxo:not(#\#):not(#\#):not(#\#){-webkit-mask-image:linear-gradient(#0000,#000 36px)}.xo9xo30:not(#\#):not(#\#):not(#\#){-webkit-mask-image:linear-gradient(#0000,#000 48px)}.xt2iwb0:not(#\#):not(#\#):not(#\#){-webkit-mask-image:linear-gradient(#0000,#0000)}.x5lxg6s:not(#\#):not(#\#):not(#\#){-webkit-overflow-scrolling:touch}.x1i10hfl:not(#\#):not(#\#):not(#\#){-webkit-tap-highlight-color:transparent}.xg7jpbn:not(#\#):not(#\#):not(#\#){-webkit-text-fill-color:transparent}.xpdipgo:not(#\#):not(#\#):not(#\#){-webkit-touch-callout:none}.x8gbvx8:not(#\#):not(#\#):not(#\#){align-content:flex-start}.x1pha0wt:not(#\#):not(#\#):not(#\#){align-items:baseline}.x6s0dn4:not(#\#):not(#\#):not(#\#){align-items:center}.xpqajaz:not(#\#):not(#\#):not(#\#){align-items:end}.xuk3077:not(#\#):not(#\#):not(#\#){align-items:flex-end}.x1cy8zhl:not(#\#):not(#\#):not(#\#){align-items:flex-start}.x7a106z:not(#\#):not(#\#):not(#\#){align-items:start}.x1qjc9v5:not(#\#):not(#\#):not(#\#){align-items:stretch}.xoi2r2e:not(#\#):not(#\#):not(#\#){align-self:baseline}.xamitd3:not(#\#):not(#\#):not(#\#){align-self:center}.xpvyfi4:not(#\#):not(#\#):not(#\#){align-self:flex-end}.xqcrz7y:not(#\#):not(#\#):not(#\#){align-self:flex-start}.x1y8v6su:not(#\#):not(#\#):not(#\#){align-self:start}.xkh2ocl:not(#\#):not(#\#):not(#\#){align-self:stretch}.x7dpabl:not(#\#):not(#\#):not(#\#){anchor-name:--outline-active}.x17yabm6:not(#\#):not(#\#):not(#\#){animation-delay:var(--duration-medium-min)}.xvo38ju:not(#\#):not(#\#):not(#\#){animation-delay:var(--x-animationDelay)}.xpz12be:not(#\#):not(#\#):not(#\#){animation-direction:alternate}.xmg6eyc:not(#\#):not(#\#):not(#\#){animation-duration:1.5s}.xjlvqhv:not(#\#):not(#\#):not(#\#){animation-duration:1ms}.x1c74tu6:not(#\#):not(#\#):not(#\#){animation-duration:2s}.xwms9i0:not(#\#):not(#\#):not(#\#){animation-duration:auto}.x9uej1z:not(#\#):not(#\#):not(#\#){animation-duration:var(--duration-fast-max)}.xb2rp9n:not(#\#):not(#\#):not(#\#){animation-duration:var(--duration-fast)}.xqgcaz:not(#\#):not(#\#):not(#\#){animation-duration:var(--duration-medium-max)}.x12wqnr7:not(#\#):not(#\#):not(#\#){animation-duration:var(--duration-medium)}.x14qxm4i:not(#\#):not(#\#):not(#\#){animation-duration:var(--duration-slow-min)}.xskzprw:not(#\#):not(#\#):not(#\#){animation-fill-mode:backwards}.x1u6ievf:not(#\#):not(#\#):not(#\#){animation-fill-mode:both}.x10e4vud:not(#\#):not(#\#):not(#\#){animation-fill-mode:forwards}.xa4qsjk:not(#\#):not(#\#):not(#\#){animation-iteration-count:infinite}.x1ewfqum:not(#\#):not(#\#):not(#\#){animation-name:x11lauxq-B}.xcx56e2:not(#\#):not(#\#):not(#\#){animation-name:x13kz0yu-B}.x1ffowhz:not(#\#):not(#\#):not(#\#){animation-name:x188b6p3-B}.xqcmdr3:not(#\#):not(#\#):not(#\#){animation-name:x18re5ia-B}.x3psbcj:not(#\#):not(#\#):not(#\#){animation-name:x1ahk7ht-B}.x1dvww92:not(#\#):not(#\#):not(#\#){animation-name:x1b6yrix-B}.x97zbip:not(#\#):not(#\#):not(#\#){animation-name:x1k48ry3-B}.x1gbn2au:not(#\#):not(#\#):not(#\#){animation-name:x1xhkexc-B}.xeuoslp:not(#\#):not(#\#):not(#\#){animation-name:xgnty7z-B}.x1srr2gu:not(#\#):not(#\#):not(#\#){animation-name:xiylxmw-B}.x1ka1v4i:not(#\#):not(#\#):not(#\#){animation-name:xqng64z-B}.xozk8ic:not(#\#):not(#\#):not(#\#){animation-name:xr3m334-B}.x1mta51n:not(#\#):not(#\#):not(#\#){animation-name:xtut5q7-B}.xck01x9:not(#\#):not(#\#):not(#\#){animation-name:xu7jd1z-B}.xl1vlw0:not(#\#):not(#\#):not(#\#){animation-name:xv1hr86-B}.x1i331go:not(#\#):not(#\#):not(#\#){animation-name:xwmkjkf-B}.x190lv1:not(#\#):not(#\#):not(#\#){animation-timeline:view(y)}.x4hg4is:not(#\#):not(#\#):not(#\#){animation-timing-function:ease-in-out}.x1esw782:not(#\#):not(#\#):not(#\#){animation-timing-function:linear}.x193epu2:not(#\#):not(#\#):not(#\#){animation-timing-function:steps(10,end)}.x128ha8g:not(#\#):not(#\#):not(#\#){animation-timing-function:var(--ease-standard)}.xjyslct:not(#\#):not(#\#):not(#\#){appearance:none}.x1plog1:not(#\#):not(#\#):not(#\#){aspect-ratio:1}.xioom0i:not(#\#):not(#\#):not(#\#){aspect-ratio:var(--button-icon-only-aspect)}.x10y9f9r:not(#\#):not(#\#):not(#\#){aspect-ratio:var(--x-aspectRatio)}.xvn2z4z:not(#\#):not(#\#):not(#\#){-webkit-backdrop-filter:blur(12px);backdrop-filter:blur(12px)}.xlp1x4z:not(#\#):not(#\#):not(#\#){backface-visibility:hidden}.xx83zyx:not(#\#):not(#\#):not(#\#){background-clip:padding-box}.x1rkw3yq:not(#\#):not(#\#):not(#\#){background-color:#fff9}.xtwfq29:not(#\#):not(#\#):not(#\#){background-color:currentColor}.xgcd1z6:not(#\#):not(#\#):not(#\#){background-color:inherit}.xcpsgoo:not(#\#):not(#\#):not(#\#){background-color:#00000080}.xjbqb8w:not(#\#):not(#\#):not(#\#){background-color:#0000}.xgcxg3y:not(#\#):not(#\#):not(#\#){background-color:var(--color-accent-muted)}.x1ewilqj:not(#\#):not(#\#):not(#\#){background-color:var(--color-accent)}.x1o0wnni:not(#\#):not(#\#):not(#\#){background-color:var(--color-background-blue)}.x1eiddq6:not(#\#):not(#\#):not(#\#){background-color:var(--color-background-body)}.x1de1mus:not(#\#):not(#\#):not(#\#){background-color:var(--color-background-card)}.x1rgj867:not(#\#):not(#\#):not(#\#){background-color:var(--color-background-cyan)}.x1l5t2a3:not(#\#):not(#\#):not(#\#){background-color:var(--color-background-error-inverted)}.xspzpui:not(#\#):not(#\#):not(#\#){background-color:var(--color-background-gray)}.x1sqjeoo:not(#\#):not(#\#):not(#\#){background-color:var(--color-background-green)}.xenstv7:not(#\#):not(#\#):not(#\#){background-color:var(--color-background-inverted)}.xwmxj5m:not(#\#):not(#\#):not(#\#){background-color:var(--color-background-muted)}.x1e9xt6e:not(#\#):not(#\#):not(#\#){background-color:var(--color-background-orange)}.xnpoty2:not(#\#):not(#\#):not(#\#){background-color:var(--color-background-pink)}.x1prclbq:not(#\#):not(#\#):not(#\#){background-color:var(--color-background-popover)}.x16i6n6f:not(#\#):not(#\#):not(#\#){background-color:var(--color-background-purple)}.x1cibrc5:not(#\#):not(#\#):not(#\#){background-color:var(--color-background-red)}.x10xzikg:not(#\#):not(#\#):not(#\#){background-color:var(--color-background-surface)}.x1jtji5o:not(#\#):not(#\#):not(#\#){background-color:var(--color-background-teal)}.x1bo7t0x:not(#\#):not(#\#):not(#\#){background-color:var(--color-background-yellow)}.x7njt3n:not(#\#):not(#\#):not(#\#){background-color:var(--color-border-emphasized)}.x1m4xfpy:not(#\#):not(#\#):not(#\#){background-color:var(--color-border)}.x1pritpl:not(#\#):not(#\#):not(#\#){background-color:var(--color-error-muted)}.x1pjz0fi:not(#\#):not(#\#):not(#\#){background-color:var(--color-error)}.xowkcby:not(#\#):not(#\#):not(#\#){background-color:var(--color-icon-primary)}.x1q5y3ey:not(#\#):not(#\#):not(#\#){background-color:var(--color-icon-secondary)}.x17x4s8c:not(#\#):not(#\#):not(#\#){background-color:var(--color-neutral)}.x1azo05:not(#\#):not(#\#):not(#\#){background-color:var(--color-on-accent)}.xfba6wv:not(#\#):not(#\#):not(#\#){background-color:var(--color-on-error)}.x9mohwv:not(#\#):not(#\#):not(#\#){background-color:var(--color-on-success)}.xmgwp2l:not(#\#):not(#\#):not(#\#){background-color:var(--color-on-warning)}.x1lmrjuc:not(#\#):not(#\#):not(#\#){background-color:var(--color-overlay-hover)}.xi89dp7:not(#\#):not(#\#):not(#\#){background-color:var(--color-overlay-pressed)}.x1u4601x:not(#\#):not(#\#):not(#\#){background-color:var(--color-overlay)}.xprdx6m:not(#\#):not(#\#):not(#\#){background-color:var(--color-skeleton)}.xu13z74:not(#\#):not(#\#):not(#\#){background-color:var(--color-success-muted)}.xdsz4j9:not(#\#):not(#\#):not(#\#){background-color:var(--color-success)}.xzyc27v:not(#\#):not(#\#):not(#\#){background-color:var(--color-syntax-background)}.x16fr6go:not(#\#):not(#\#):not(#\#){background-color:var(--color-text-disabled)}.x19aspcf:not(#\#):not(#\#):not(#\#){background-color:var(--color-text-primary)}.xdomwnj:not(#\#):not(#\#):not(#\#){background-color:var(--color-text-secondary)}.xdsb6cv:not(#\#):not(#\#):not(#\#){background-color:var(--color-track)}.x24i8r5:not(#\#):not(#\#):not(#\#){background-color:var(--color-warning-muted)}.x1q8g9m5:not(#\#):not(#\#):not(#\#){background-color:var(--color-warning)}.x1fd97le:not(#\#):not(#\#):not(#\#){background-color:var(--table-sticky-background,var(--color-background-card))}.xl8spv7:not(#\#):not(#\#):not(#\#){background-color:var(--x-backgroundColor)}.xafqdz2:not(#\#):not(#\#):not(#\#){background-image:linear-gradient(to bottom,var(--color-background-surface) 60%,transparent)}.x1vrk509:not(#\#):not(#\#):not(#\#){background-image:linear-gradient(var(--color-background-muted),var(--color-background-muted))}.x14bno8m:not(#\#):not(#\#):not(#\#){background-image:linear-gradient(var(--color-neutral),var(--color-neutral))}.x18o3ruo:not(#\#):not(#\#):not(#\#){background-image:none}.x1mwwwfo:not(#\#):not(#\#):not(#\#){border-collapse:collapse}.x16uus16:not(#\#):not(#\#):not(#\#){border-end-end-radius:0}.x1eprgri:not(#\#):not(#\#):not(#\#){border-end-end-radius:var(--_banner-radius,var(--radius-container))}.x6k0y1c:not(#\#):not(#\#):not(#\#){border-end-end-radius:var(--_chat-composer-radius)}.xoao14b:not(#\#):not(#\#):not(#\#){border-end-end-radius:var(--_field-radius)}.x14i3lts:not(#\#):not(#\#):not(#\#){border-end-end-radius:var(--radius-element)}.x1dgc8on:not(#\#):not(#\#):not(#\#){border-end-end-radius:var(--radius-full)}.x1whkvtz:not(#\#):not(#\#):not(#\#){border-end-end-radius:var(--radius-inner)}.xbiv7yw:not(#\#):not(#\#):not(#\#){border-end-start-radius:0}.x1k5g1gk:not(#\#):not(#\#):not(#\#){border-end-start-radius:var(--_banner-radius,var(--radius-container))}.xkvxy4d:not(#\#):not(#\#):not(#\#){border-end-start-radius:var(--_chat-composer-radius)}.xquck67:not(#\#):not(#\#):not(#\#){border-end-start-radius:var(--radius-element)}.x1wc3881:not(#\#):not(#\#):not(#\#){border-end-start-radius:var(--radius-full)}.xrfs2vl:not(#\#):not(#\#):not(#\#){border-end-start-radius:var(--radius-inner)}.xl0t3rv:not(#\#):not(#\#):not(#\#){border-inline-end-color:var(--color-border-emphasized)}.x1gejf6u:not(#\#):not(#\#):not(#\#){border-inline-end-color:var(--color-border)}.x18b5jzi:not(#\#):not(#\#):not(#\#){border-inline-end-style:solid}.x1lun4ml:not(#\#):not(#\#):not(#\#){border-inline-end-width:1px}.xw8tdv1:not(#\#):not(#\#):not(#\#){border-inline-end-width:var(--border-width)}.x14ydlgx:not(#\#):not(#\#):not(#\#){border-inline-start-color:var(--color-border-emphasized)}.x1j92z86:not(#\#):not(#\#):not(#\#){border-inline-start-color:var(--color-border)}.xrvmtm5:not(#\#):not(#\#):not(#\#){border-inline-start-color:var(--color-on-accent)}.x1t7ytsu:not(#\#):not(#\#):not(#\#){border-inline-start-style:solid}.xpilrb4:not(#\#):not(#\#):not(#\#){border-inline-start-width:1px}.xgbv0en:not(#\#):not(#\#):not(#\#){border-inline-start-width:var(--border-width)}.xtpqe59:not(#\#):not(#\#):not(#\#){border-inline-start-width:var(--spacing-0-5)}.x1gukg7c:not(#\#):not(#\#):not(#\#){border-spacing:0}.x1ga7v0g:not(#\#):not(#\#):not(#\#){border-start-end-radius:0}.x13nour3:not(#\#):not(#\#):not(#\#){border-start-end-radius:var(--_banner-radius,var(--radius-container))}.xzc3kxz:not(#\#):not(#\#):not(#\#){border-start-end-radius:var(--_chat-composer-radius)}.x1g2gkjz:not(#\#):not(#\#):not(#\#){border-start-end-radius:var(--_field-radius)}.xg0tfu:not(#\#):not(#\#):not(#\#){border-start-end-radius:var(--radius-chat)}.x7hs6f1:not(#\#):not(#\#):not(#\#){border-start-end-radius:var(--radius-container)}.x8agd5o:not(#\#):not(#\#):not(#\#){border-start-end-radius:var(--radius-full)}.x126per9:not(#\#):not(#\#):not(#\#){border-start-end-radius:var(--radius-inner)}.x15mokao:not(#\#):not(#\#):not(#\#){border-start-start-radius:0}.xwxb7qi:not(#\#):not(#\#):not(#\#){border-start-start-radius:var(--_banner-radius,var(--radius-container))}.xy7p8pm:not(#\#):not(#\#):not(#\#){border-start-start-radius:var(--_chat-composer-radius)}.x1n70msy:not(#\#):not(#\#):not(#\#){border-start-start-radius:var(--radius-chat)}.x81l70g:not(#\#):not(#\#):not(#\#){border-start-start-radius:var(--radius-container)}.x19415el:not(#\#):not(#\#):not(#\#){border-start-start-radius:var(--radius-full)}.x3qb8m:not(#\#):not(#\#):not(#\#){border-start-start-radius:var(--radius-inner)}.x183tx6i:not(#\#):not(#\#):not(#\#){border-start-start-radius:var(--radius-page)}.x1lp15jv:not(#\#):not(#\#):not(#\#){box-shadow:inset 0 0 0 1px var(--color-border-emphasized)}.x1er153n:not(#\#):not(#\#):not(#\#){box-shadow:inset 0 0 0 1px var(--color-border)}.x1iobdd1:not(#\#):not(#\#):not(#\#){box-shadow:inset 0 0 0 1px var(--color-text-primary)}.x1gnnqk1:not(#\#):not(#\#):not(#\#){box-shadow:none}.x1p8z4y0:not(#\#):not(#\#):not(#\#){box-shadow:var(--_card-ring,0 0 transparent),var(--_card-elevation,0 0 transparent)}.x1kcpxr7:not(#\#):not(#\#):not(#\#){box-shadow:var(--shadow-high)}.x1i5ehqx:not(#\#):not(#\#):not(#\#){box-shadow:var(--shadow-low)}.x14hfi27:not(#\#):not(#\#):not(#\#){box-shadow:var(--shadow-med)}.x9f619:not(#\#):not(#\#):not(#\#){box-sizing:border-box}.x1afcbsf:not(#\#):not(#\#):not(#\#){box-sizing:content-box}.xbuiw85:not(#\#):not(#\#):not(#\#){caret-color:#0000}.xxugrtn:not(#\#):not(#\#):not(#\#){caret-color:var(--color-accent)}.x1hyvwdk:not(#\#):not(#\#):not(#\#){clip-path:inset(50%)}.xzpqnlu:not(#\#):not(#\#):not(#\#){clip:rect(0,0,0,0)}.xntwwlm:not(#\#):not(#\#):not(#\#){--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}.x108lcm5:not(#\#):not(#\#):not(#\#){--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark}@media (prefers-color-scheme:dark){.x108lcm5:not(#\#):not(#\#):not(#\#){--lightningcss-light: ;--lightningcss-dark:initial}}.x19aimcq:not(#\#):not(#\#):not(#\#){--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}.xj8ax7g:not(#\#):not(#\#):not(#\#){color:red}.x1heor9g:not(#\#):not(#\#):not(#\#){color:inherit}.x19co3pv:not(#\#):not(#\#):not(#\#){color:#0000}.x1gb3s7i:not(#\#):not(#\#):not(#\#){color:var(--_item-description-color,var(--color-text-secondary))}.x5tbw38:not(#\#):not(#\#):not(#\#){color:var(--_item-label-color,var(--color-text-primary))}.xqwr325:not(#\#):not(#\#):not(#\#){color:var(--color-accent)}.xrkvqaz:not(#\#):not(#\#):not(#\#){color:var(--color-background-surface)}.xjt36v0:not(#\#):not(#\#):not(#\#){color:var(--color-error)}.x1fns2mt:not(#\#):not(#\#):not(#\#){color:var(--color-icon-blue)}.x157w0xa:not(#\#):not(#\#):not(#\#){color:var(--color-icon-cyan)}.xqa6c3m:not(#\#):not(#\#):not(#\#){color:var(--color-icon-disabled)}.x1eyinzz:not(#\#):not(#\#):not(#\#){color:var(--color-icon-gray)}.xmxeech:not(#\#):not(#\#):not(#\#){color:var(--color-icon-green)}.xxu74a4:not(#\#):not(#\#):not(#\#){color:var(--color-icon-orange)}.x1kxxfg5:not(#\#):not(#\#):not(#\#){color:var(--color-icon-pink)}.xtbr613:not(#\#):not(#\#):not(#\#){color:var(--color-icon-primary)}.xzdw94u:not(#\#):not(#\#):not(#\#){color:var(--color-icon-purple)}.xeffzf7:not(#\#):not(#\#):not(#\#){color:var(--color-icon-red)}.xv9yike:not(#\#):not(#\#):not(#\#){color:var(--color-icon-secondary)}.x1f3zxcb:not(#\#):not(#\#):not(#\#){color:var(--color-icon-teal)}.x1g6zdft:not(#\#):not(#\#):not(#\#){color:var(--color-icon-yellow)}.x17wrial:not(#\#):not(#\#):not(#\#){color:var(--color-on-accent)}.x9e3rv5:not(#\#):not(#\#):not(#\#){color:var(--color-on-dark)}.x1m024r3:not(#\#):not(#\#):not(#\#){color:var(--color-on-error)}.xri61p4:not(#\#):not(#\#):not(#\#){color:var(--color-on-success)}.xrebv38:not(#\#):not(#\#):not(#\#){color:var(--color-on-warning)}.xtjic6:not(#\#):not(#\#):not(#\#){color:var(--color-success)}.x1mjzq1q:not(#\#):not(#\#):not(#\#){color:var(--color-syntax-comment)}.xdfisg:not(#\#):not(#\#):not(#\#){color:var(--color-syntax-variable)}.xjse4m1:not(#\#):not(#\#):not(#\#){color:var(--color-text-accent)}.x1vvqiwl:not(#\#):not(#\#):not(#\#){color:var(--color-text-blue)}.x1txnczv:not(#\#):not(#\#):not(#\#){color:var(--color-text-cyan)}.xnbbluu:not(#\#):not(#\#):not(#\#){color:var(--color-text-disabled)}.xru1t7f:not(#\#):not(#\#):not(#\#){color:var(--color-text-gray)}.xltfdvo:not(#\#):not(#\#):not(#\#){color:var(--color-text-green)}.xm47u9q:not(#\#):not(#\#):not(#\#){color:var(--color-text-orange)}.xiuofww:not(#\#):not(#\#):not(#\#){color:var(--color-text-pink)}.x1tgivj0:not(#\#):not(#\#):not(#\#){color:var(--color-text-primary)}.x1m9wyeb:not(#\#):not(#\#):not(#\#){color:var(--color-text-purple)}.x1joocv1:not(#\#):not(#\#):not(#\#){color:var(--color-text-red)}.xv1l7n4:not(#\#):not(#\#):not(#\#){color:var(--color-text-secondary)}.x9x0lbs:not(#\#):not(#\#):not(#\#){color:var(--color-text-teal)}.xdhq94a:not(#\#):not(#\#):not(#\#){color:var(--color-text-yellow)}.xs3pv69:not(#\#):not(#\#):not(#\#){color:var(--color-warning)}.xf5zn4v:not(#\#):not(#\#):not(#\#){column-gap:calc(var(--spacing-3) + var(--border-width) + var(--spacing-4))}.x1kihgfc:not(#\#):not(#\#):not(#\#){column-gap:var(--spacing-0-5)}.x1o57wo1:not(#\#):not(#\#):not(#\#){column-gap:var(--spacing-0)}.x1thn6ci:not(#\#):not(#\#):not(#\#){column-gap:var(--spacing-1-5)}.x1lfs0n9:not(#\#):not(#\#):not(#\#){column-gap:var(--spacing-1)}.x1p37tyl:not(#\#):not(#\#):not(#\#){column-gap:var(--spacing-10)}.xak3so:not(#\#):not(#\#):not(#\#){column-gap:var(--spacing-2)}.xewh9hi:not(#\#):not(#\#):not(#\#){column-gap:var(--spacing-3)}.xty4p9g:not(#\#):not(#\#):not(#\#){column-gap:var(--spacing-4)}.x1eqhezk:not(#\#):not(#\#):not(#\#){column-gap:var(--spacing-5)}.x3qlgwd:not(#\#):not(#\#):not(#\#){column-gap:var(--spacing-6)}.xicv188:not(#\#):not(#\#):not(#\#){column-gap:var(--spacing-8)}.xawy1a7:not(#\#):not(#\#):not(#\#){contain:layout style}.x12h1iku:not(#\#):not(#\#):not(#\#){container-type:inline-size}.xb5mbof:not(#\#):not(#\#):not(#\#){content-visibility:auto}.xfrknyr:not(#\#):not(#\#):not(#\#){counter-increment:astryx-list}.xif0320:not(#\#):not(#\#):not(#\#){counter-reset:astryx-list}.x1khind5:not(#\#):not(#\#):not(#\#){counter-reset:var(--x-counterReset)}.xicojor:not(#\#):not(#\#):not(#\#){cursor:col-resize}.xt0e3qv:not(#\#):not(#\#):not(#\#){cursor:default}.x7eptgl:not(#\#):not(#\#):not(#\#){cursor:ew-resize}.x1jm3nie:not(#\#):not(#\#):not(#\#){cursor:grab}.xi9pz9s:not(#\#):not(#\#):not(#\#){cursor:grabbing}.xmper1u:not(#\#):not(#\#):not(#\#){cursor:inherit}.x1ypdohk:not(#\#):not(#\#):not(#\#){cursor:pointer}.xyozgr7:not(#\#):not(#\#):not(#\#){cursor:row-resize}.x1ed109x:not(#\#):not(#\#):not(#\#){cursor:text}.x1huxd7x:not(#\#):not(#\#):not(#\#){cursor:zoom-in}.x104kibb:not(#\#):not(#\#):not(#\#){display:-webkit-box}.x1lliihq:not(#\#):not(#\#):not(#\#){display:block}.xjp7ctv:not(#\#):not(#\#):not(#\#){display:contents}.x78zum5:not(#\#):not(#\#):not(#\#){display:flex}.xrvj5dj:not(#\#):not(#\#):not(#\#){display:grid}.x1rg5ohu:not(#\#):not(#\#):not(#\#){display:inline-block}.x3nfvp2:not(#\#):not(#\#):not(#\#){display:inline-flex}.xwz0xwf:not(#\#):not(#\#):not(#\#){display:inline-grid}.xt0psk2:not(#\#):not(#\#):not(#\#){display:inline}.x1s85apg:not(#\#):not(#\#):not(#\#){display:none}.x11ke7fs:not(#\#):not(#\#):not(#\#){display:var(--separator-display)}.xbh8q5q:not(#\#):not(#\#):not(#\#){fill:none}.x1r8uery:not(#\#):not(#\#):not(#\#){flex-basis:0}.xrjwirl:not(#\#):not(#\#):not(#\#){flex-basis:196px}.xjpgo6f:not(#\#):not(#\#):not(#\#){flex-basis:200px}.xchdapg:not(#\#):not(#\#):not(#\#){flex-basis:300px}.xgualba:not(#\#):not(#\#):not(#\#){flex-basis:8rem}.xdl72j9:not(#\#):not(#\#):not(#\#){flex-basis:auto}.x3ieub6:not(#\#):not(#\#):not(#\#){flex-direction:column-reverse}.xdt5ytf:not(#\#):not(#\#):not(#\#){flex-direction:column}.x15zctf7:not(#\#):not(#\#):not(#\#){flex-direction:row-reverse}.x1q0g3np:not(#\#):not(#\#):not(#\#){flex-direction:row}.x1c4vz4f:not(#\#):not(#\#):not(#\#){flex-grow:0}.x1iyjqo2:not(#\#):not(#\#):not(#\#){flex-grow:1}.xgyuaek:not(#\#):not(#\#):not(#\#){flex-grow:2}.x2lah0s:not(#\#):not(#\#):not(#\#){flex-shrink:0}.xs83m0k:not(#\#):not(#\#):not(#\#){flex-shrink:1}.x1g3ib7:not(#\#):not(#\#):not(#\#){flex-shrink:10}.xozqiw3:not(#\#):not(#\#):not(#\#){flex-wrap:nowrap}.x8hhl5t:not(#\#):not(#\#):not(#\#){flex-wrap:wrap-reverse}.x1a02dak:not(#\#):not(#\#):not(#\#){flex-wrap:wrap}.xjb2p0i:not(#\#):not(#\#):not(#\#){font-family:inherit}.x9ynric:not(#\#):not(#\#):not(#\#){font-family:var(--font-family-body)}.x9m5x89:not(#\#):not(#\#):not(#\#){font-family:var(--font-family-code)}.x1g81bgm:not(#\#):not(#\#):not(#\#){font-family:var(--font-family-heading)}.xboafo0:not(#\#):not(#\#):not(#\#){font-size:.75rem}.x1603h9y:not(#\#):not(#\#):not(#\#){font-size:1.25rem}.xngnso2:not(#\#):not(#\#):not(#\#){font-size:1.5rem}.x1k6wstc:not(#\#):not(#\#):not(#\#){font-size:10px}.xfifm61:not(#\#):not(#\#):not(#\#){font-size:12px}.xif65rj:not(#\#):not(#\#):not(#\#){font-size:14px}.x1j61zf2:not(#\#):not(#\#):not(#\#){font-size:16px}.x1jchvi3:not(#\#):not(#\#):not(#\#){font-size:1rem}.xwsyq91:not(#\#):not(#\#):not(#\#){font-size:20px}.x1qlqyl8:not(#\#):not(#\#):not(#\#){font-size:inherit}.xhs0kqb:not(#\#):not(#\#):not(#\#){font-size:var(--font-size-2xl)}.x16a80zy:not(#\#):not(#\#):not(#\#){font-size:var(--font-size-2xs)}.x10srzze:not(#\#):not(#\#):not(#\#){font-size:var(--font-size-3xl)}.x10p7juq:not(#\#):not(#\#):not(#\#){font-size:var(--font-size-3xs)}.xqcvi3d:not(#\#):not(#\#):not(#\#){font-size:var(--font-size-4xl)}.xxc45ev:not(#\#):not(#\#):not(#\#){font-size:var(--font-size-4xs)}.x1j29vfg:not(#\#):not(#\#):not(#\#){font-size:var(--font-size-base)}.xc7cgfe:not(#\#):not(#\#):not(#\#){font-size:var(--font-size-lg)}.x1eqnyfr:not(#\#):not(#\#):not(#\#){font-size:var(--font-size-sm)}.x1wqms48:not(#\#):not(#\#):not(#\#){font-size:var(--font-size-xl)}.x51wmvv:not(#\#):not(#\#):not(#\#){font-size:var(--font-size-xs)}.xho7bvi:not(#\#):not(#\#):not(#\#){font-size:var(--spacing-4)}.xjm74w1:not(#\#):not(#\#):not(#\#){font-size:var(--text-body-size)}.xp03k98:not(#\#):not(#\#):not(#\#){font-size:var(--text-code-size)}.xsub3ws:not(#\#):not(#\#):not(#\#){font-size:var(--text-display-1-size)}.x1yego12:not(#\#):not(#\#):not(#\#){font-size:var(--text-display-2-size)}.xlgnzhf:not(#\#):not(#\#):not(#\#){font-size:var(--text-display-3-size)}.xcg7oai:not(#\#):not(#\#):not(#\#){font-size:var(--text-heading-1-size)}.x1xvnhcw:not(#\#):not(#\#):not(#\#){font-size:var(--text-heading-2-size)}.xii13ha:not(#\#):not(#\#):not(#\#){font-size:var(--text-heading-3-size)}.x8tkxat:not(#\#):not(#\#):not(#\#){font-size:var(--text-heading-4-size)}.xsgqta0:not(#\#):not(#\#):not(#\#){font-size:var(--text-heading-5-size)}.xw5ohdf:not(#\#):not(#\#):not(#\#){font-size:var(--text-heading-6-size)}.xcr08ib:not(#\#):not(#\#):not(#\#){font-size:var(--text-label-size)}.x18juvz8:not(#\#):not(#\#):not(#\#){font-size:var(--text-large-size)}.x141an7d:not(#\#):not(#\#):not(#\#){font-size:var(--text-supporting-size)}.xdmh292:not(#\#):not(#\#):not(#\#){font-size:var(--x-fontSize)}.x1j61x8r:not(#\#):not(#\#):not(#\#){font-style:normal}.xss6m8b:not(#\#):not(#\#):not(#\#){font-variant-numeric:tabular-nums}.xk50ysn:not(#\#):not(#\#):not(#\#){font-weight:500}.x1s688f:not(#\#):not(#\#):not(#\#){font-weight:600}.x1pd3egz:not(#\#):not(#\#):not(#\#){font-weight:inherit}.x1lvx875:not(#\#):not(#\#):not(#\#){font-weight:var(--font-weight-bold)}.x1e4wzip:not(#\#):not(#\#):not(#\#){font-weight:var(--font-weight-medium)}.x1sodnla:not(#\#):not(#\#):not(#\#){font-weight:var(--font-weight-normal)}.x2mo6ok:not(#\#):not(#\#):not(#\#){font-weight:var(--font-weight-semibold)}.xxovm9e:not(#\#):not(#\#):not(#\#){font-weight:var(--text-body-weight)}.xx3eeay:not(#\#):not(#\#):not(#\#){font-weight:var(--text-code-weight)}.x1txul5o:not(#\#):not(#\#):not(#\#){font-weight:var(--text-display-1-weight)}.x1y36c3f:not(#\#):not(#\#):not(#\#){font-weight:var(--text-display-2-weight)}.x1on40hk:not(#\#):not(#\#):not(#\#){font-weight:var(--text-display-3-weight)}.x1v68xuy:not(#\#):not(#\#):not(#\#){font-weight:var(--text-heading-1-weight)}.x12yy4cs:not(#\#):not(#\#):not(#\#){font-weight:var(--text-heading-2-weight)}.x1jcxfy8:not(#\#):not(#\#):not(#\#){font-weight:var(--text-heading-3-weight)}.x2hcmsi:not(#\#):not(#\#):not(#\#){font-weight:var(--text-heading-4-weight)}.xno150v:not(#\#):not(#\#):not(#\#){font-weight:var(--text-heading-5-weight)}.x1pw4frv:not(#\#):not(#\#):not(#\#){font-weight:var(--text-heading-6-weight)}.xmhvcl5:not(#\#):not(#\#):not(#\#){font-weight:var(--text-label-weight)}.x149oux8:not(#\#):not(#\#):not(#\#){font-weight:var(--text-large-weight)}.xv8on6e:not(#\#):not(#\#):not(#\#){font-weight:var(--text-supporting-weight)}.x1kzknox:not(#\#):not(#\#):not(#\#){forced-color-adjust:none}.xu6a5m6:not(#\#):not(#\#):not(#\#){grid-auto-columns:1fr}.x1mt1orb:not(#\#):not(#\#):not(#\#){grid-auto-flow:column}.xhij9v2:not(#\#):not(#\#):not(#\#){grid-auto-rows:var(--x-gridAutoRows)}.xcrlgei:not(#\#):not(#\#):not(#\#){grid-column-start:1}.x1agbcgv:not(#\#):not(#\#):not(#\#){grid-row-start:1}.x134kloy:not(#\#):not(#\#):not(#\#){grid-template-columns:1fr auto 1fr}.x52fmzj:not(#\#):not(#\#):not(#\#){grid-template-columns:1fr auto}.x1y6fwsi:not(#\#):not(#\#):not(#\#){grid-template-columns:1fr}.x1g3yg12:not(#\#):not(#\#):not(#\#){grid-template-columns:auto 1fr auto}.x1pmbctz:not(#\#):not(#\#):not(#\#){grid-template-columns:auto 1fr}.x1wthsqz:not(#\#):not(#\#):not(#\#){grid-template-columns:auto repeat(7,1fr)}.x1mzazjb:not(#\#):not(#\#):not(#\#){grid-template-columns:repeat(7,1fr)}.x189bvgu:not(#\#):not(#\#):not(#\#){grid-template-columns:repeat(auto-fill,minmax(280px,1fr))}.x1xx4m37:not(#\#):not(#\#):not(#\#){grid-template-columns:var(--_codeblock-gutter-width) 1fr}.xqketvx:not(#\#):not(#\#):not(#\#){grid-template-columns:var(--x-gridTemplateColumns)}.xihq33y:not(#\#):not(#\#):not(#\#){grid-template-rows:0fr}.x1tu4anv:not(#\#):not(#\#):not(#\#){grid-template-rows:1fr}.xy8nx85:not(#\#):not(#\#):not(#\#){grid-template-rows:repeat(6,1fr)}.xtijo5x:not(#\#):not(#\#):not(#\#){inset-inline-end:0}.xz03a8w:not(#\#):not(#\#):not(#\#){inset-inline-end:2px}.x1oinnt5:not(#\#):not(#\#):not(#\#){inset-inline-end:calc((var(--size-element-md) - 20px) / 2 - 1px)}.x8qlsd8:not(#\#):not(#\#):not(#\#){inset-inline-end:calc((var(--size-element-sm) - 20px) / 2 - 1px)}.x13oyzgk:not(#\#):not(#\#):not(#\#){inset-inline-end:var(--_textarea-inline-padding)}.xy3asu9:not(#\#):not(#\#):not(#\#){inset-inline-end:var(--spacing-1)}.x72tfeb:not(#\#):not(#\#):not(#\#){inset-inline-end:var(--spacing-2)}.x1mcfs9z:not(#\#):not(#\#):not(#\#){inset-inline-end:var(--spacing-3)}.xqxgn94:not(#\#):not(#\#):not(#\#){inset-inline-end:var(--x-insetInlineEnd)}.x1o0tod:not(#\#):not(#\#):not(#\#){inset-inline-start:0}.x9p6ekw:not(#\#):not(#\#):not(#\#){inset-inline-start:14px}.xaoy8p5:not(#\#):not(#\#):not(#\#){inset-inline-start:2px}.xbudbmw:not(#\#):not(#\#):not(#\#){inset-inline-start:50%}.x1kiyvbf:not(#\#):not(#\#):not(#\#){inset-inline-start:var(--_textarea-inline-padding)}.x1ybfrjj:not(#\#):not(#\#):not(#\#){inset-inline-start:var(--spacing-3)}.x1lxsm33:not(#\#):not(#\#):not(#\#){inset-inline-start:var(--x-insetInlineStart)}.xc8icb0:not(#\#):not(#\#):not(#\#){isolation:isolate}.xl56j7k:not(#\#):not(#\#):not(#\#){justify-content:center}.x13a6bvl:not(#\#):not(#\#):not(#\#){justify-content:flex-end}.x1nhvcw1:not(#\#):not(#\#):not(#\#){justify-content:flex-start}.x1l1ennw:not(#\#):not(#\#):not(#\#){justify-content:space-around}.x1qughib:not(#\#):not(#\#):not(#\#){justify-content:space-between}.xaw8158:not(#\#):not(#\#):not(#\#){justify-content:space-evenly}.x1o2pa38:not(#\#):not(#\#):not(#\#){justify-items:center}.x4xo5sw:not(#\#):not(#\#):not(#\#){justify-items:end}.x619ttb:not(#\#):not(#\#):not(#\#){justify-items:start}.xl4xnwh:not(#\#):not(#\#):not(#\#){justify-items:stretch}.x7v7x1q:not(#\#):not(#\#):not(#\#){justify-self:center}.x1lqcxt8:not(#\#):not(#\#):not(#\#){justify-self:start}.x14ju556:not(#\#):not(#\#):not(#\#){line-height:0}.xo5v014:not(#\#):not(#\#):not(#\#){line-height:1}.x19v9tvf:not(#\#):not(#\#):not(#\#){line-height:22px}.x15bjb6t:not(#\#):not(#\#):not(#\#){line-height:inherit}.x1ojctns:not(#\#):not(#\#):not(#\#){line-height:var(--spacing-4)}.x7acx1w:not(#\#):not(#\#):not(#\#){line-height:var(--spacing-5)}.xw6l6zx:not(#\#):not(#\#):not(#\#){line-height:var(--text-body-leading)}.x17iicif:not(#\#):not(#\#):not(#\#){line-height:var(--text-code-leading)}.x112ttwr:not(#\#):not(#\#):not(#\#){line-height:var(--text-display-1-leading)}.xh0iwvy:not(#\#):not(#\#):not(#\#){line-height:var(--text-display-2-leading)}.x1ujwuaq:not(#\#):not(#\#):not(#\#){line-height:var(--text-display-3-leading)}.xfmsba7:not(#\#):not(#\#):not(#\#){line-height:var(--text-heading-1-leading)}.x1cpk1wn:not(#\#):not(#\#):not(#\#){line-height:var(--text-heading-2-leading)}.xwjzt0u:not(#\#):not(#\#):not(#\#){line-height:var(--text-heading-3-leading)}.xqerer:not(#\#):not(#\#):not(#\#){line-height:var(--text-heading-4-leading)}.xo3gurs:not(#\#):not(#\#):not(#\#){line-height:var(--text-heading-5-leading)}.xeixjfn:not(#\#):not(#\#):not(#\#){line-height:var(--text-heading-6-leading)}.x1kq96og:not(#\#):not(#\#):not(#\#){line-height:var(--text-label-leading)}.xf74fhv:not(#\#):not(#\#):not(#\#){line-height:var(--text-large-leading)}.x1ltkj2j:not(#\#):not(#\#):not(#\#){line-height:var(--text-supporting-leading)}.x3ct3a4:not(#\#):not(#\#):not(#\#){list-style-type:none}.x14z9mp:not(#\#):not(#\#):not(#\#){margin-inline-end:0}.x1fcf3bl:not(#\#):not(#\#):not(#\#){margin-inline-end:calc(-1 * var(--container-padding-inline-end,0px))}.x1kpg4um:not(#\#):not(#\#):not(#\#){margin-inline-end:calc(-1 * var(--layout-padding-inner-x,var(--spacing-4)))}.xkd40ry:not(#\#):not(#\#):not(#\#){margin-inline-end:calc(-1 * var(--spacing-1))}.x3kzqx6:not(#\#):not(#\#):not(#\#){margin-inline-end:calc(-1 * var(--spacing-2))}.xmequkd:not(#\#):not(#\#):not(#\#){margin-inline-end:calc(var(--spacing-1) * -1)}.xnur1sd:not(#\#):not(#\#):not(#\#){margin-inline-end:var(--spacing-1)}.x1c9tiao:not(#\#):not(#\#):not(#\#){margin-inline-end:var(--x-marginInlineEnd)}.x1qfufaz:not(#\#):not(#\#):not(#\#){margin-inline-start:-8px}.x1lziwak:not(#\#):not(#\#):not(#\#){margin-inline-start:0}.xvc5jky:not(#\#):not(#\#):not(#\#){margin-inline-start:auto}.xd10s4z:not(#\#):not(#\#):not(#\#){margin-inline-start:calc(-1 * var(--border-width))}.xojxgvx:not(#\#):not(#\#):not(#\#){margin-inline-start:calc(-1 * var(--container-padding-inline-start,0px))}.x1wim8z0:not(#\#):not(#\#):not(#\#){margin-inline-start:calc(-1 * var(--layout-padding-inner-x,var(--spacing-4)))}.x1s1akpx:not(#\#):not(#\#):not(#\#){margin-inline-start:calc(-1 * var(--spacing-2))}.x1xrm450:not(#\#):not(#\#):not(#\#){margin-inline-start:calc(var(--spacing-2) - var(--spacing-1) + 1px)}.x12vn87o:not(#\#):not(#\#):not(#\#){margin-inline-start:var(--_tree-indent,0px)}.xladpz9:not(#\#):not(#\#):not(#\#){margin-inline-start:var(--spacing-0-5)}.x11g1kdw:not(#\#):not(#\#):not(#\#){margin-inline-start:var(--spacing-1)}.x1l10yog:not(#\#):not(#\#):not(#\#){margin-inline-start:var(--spacing-6)}.x4lel18:not(#\#):not(#\#):not(#\#){margin-inline-start:var(--x-marginInlineStart)}.xkm2don:not(#\#):not(#\#):not(#\#){-webkit-mask-image:linear-gradient(#0000,#000 24px);mask-image:linear-gradient(#0000,#000 24px)}.xw26lqc:not(#\#):not(#\#):not(#\#){-webkit-mask-image:linear-gradient(#0000,#000 36px);mask-image:linear-gradient(#0000,#000 36px)}.xr5yg4x:not(#\#):not(#\#):not(#\#){-webkit-mask-image:linear-gradient(#0000,#000 48px);mask-image:linear-gradient(#0000,#000 48px)}.xtdd0ob:not(#\#):not(#\#):not(#\#){-webkit-mask-image:linear-gradient(to left,transparent 0%,#0000004d 2px,black var(--spacing-1));-webkit-mask-image:linear-gradient(to left,transparent 0%,#0000004d 2px,black var(--spacing-1));-webkit-mask-image:linear-gradient(to left,transparent 0%,#0000004d 2px,black var(--spacing-1));mask-image:linear-gradient(to left,transparent 0%,#0000004d 2px,black var(--spacing-1))}.xoj6v2h:not(#\#):not(#\#):not(#\#){-webkit-mask-image:linear-gradient(to left,transparent var(--_tab-strip-bleed),black calc(var(--_tab-strip-bleed) + var(--spacing-8)));-webkit-mask-image:linear-gradient(to left,transparent var(--_tab-strip-bleed),black calc(var(--_tab-strip-bleed) + var(--spacing-8)));-webkit-mask-image:linear-gradient(to left,transparent var(--_tab-strip-bleed),black calc(var(--_tab-strip-bleed) + var(--spacing-8)));mask-image:linear-gradient(to left,transparent var(--_tab-strip-bleed),black calc(var(--_tab-strip-bleed) + var(--spacing-8)))}.x1b5cd1y:not(#\#):not(#\#):not(#\#){-webkit-mask-image:linear-gradient(to right,transparent 0%,#0000004d 2px,black var(--spacing-1),black calc(100% - var(--spacing-1)),#0000004d calc(100% - 2px),transparent 100%);-webkit-mask-image:linear-gradient(to right,transparent 0%,#0000004d 2px,black var(--spacing-1),black calc(100% - var(--spacing-1)),#0000004d calc(100% - 2px),transparent 100%);-webkit-mask-image:linear-gradient(to right,transparent 0%,#0000004d 2px,black var(--spacing-1),black calc(100% - var(--spacing-1)),#0000004d calc(100% - 2px),transparent 100%);mask-image:linear-gradient(to right,transparent 0%,#0000004d 2px,black var(--spacing-1),black calc(100% - var(--spacing-1)),#0000004d calc(100% - 2px),transparent 100%)}.x1ujl4f5:not(#\#):not(#\#):not(#\#){-webkit-mask-image:linear-gradient(to right,transparent 0%,#0000004d 2px,black var(--spacing-1));-webkit-mask-image:linear-gradient(to right,transparent 0%,#0000004d 2px,black var(--spacing-1));-webkit-mask-image:linear-gradient(to right,transparent 0%,#0000004d 2px,black var(--spacing-1));mask-image:linear-gradient(to right,transparent 0%,#0000004d 2px,black var(--spacing-1))}.xq05pg6:not(#\#):not(#\#):not(#\#){-webkit-mask-image:linear-gradient(to right,transparent var(--_tab-strip-bleed),black calc(var(--_tab-strip-bleed) + var(--spacing-8)),black calc(100% - calc(var(--_tab-strip-bleed) + var(--spacing-8))),transparent calc(100% - var(--_tab-strip-bleed)));-webkit-mask-image:linear-gradient(to right,transparent var(--_tab-strip-bleed),black calc(var(--_tab-strip-bleed) + var(--spacing-8)),black calc(100% - calc(var(--_tab-strip-bleed) + var(--spacing-8))),transparent calc(100% - var(--_tab-strip-bleed)));-webkit-mask-image:linear-gradient(to right,transparent var(--_tab-strip-bleed),black calc(var(--_tab-strip-bleed) + var(--spacing-8)),black calc(100% - calc(var(--_tab-strip-bleed) + var(--spacing-8))),transparent calc(100% - var(--_tab-strip-bleed)));mask-image:linear-gradient(to right,transparent var(--_tab-strip-bleed),black calc(var(--_tab-strip-bleed) + var(--spacing-8)),black calc(100% - calc(var(--_tab-strip-bleed) + var(--spacing-8))),transparent calc(100% - var(--_tab-strip-bleed)))}.x1hua2o0:not(#\#):not(#\#):not(#\#){-webkit-mask-image:linear-gradient(to right,transparent var(--_tab-strip-bleed),black calc(var(--_tab-strip-bleed) + var(--spacing-8)));-webkit-mask-image:linear-gradient(to right,transparent var(--_tab-strip-bleed),black calc(var(--_tab-strip-bleed) + var(--spacing-8)));-webkit-mask-image:linear-gradient(to right,transparent var(--_tab-strip-bleed),black calc(var(--_tab-strip-bleed) + var(--spacing-8)));mask-image:linear-gradient(to right,transparent var(--_tab-strip-bleed),black calc(var(--_tab-strip-bleed) + var(--spacing-8)))}.x1cb67k9:not(#\#):not(#\#):not(#\#){-webkit-mask-image:linear-gradient(#0000,#0000);mask-image:linear-gradient(#0000,#0000)}.xw4ya9i:not(#\#):not(#\#):not(#\#){-webkit-mask-image:none;mask-image:none}.x19kjcj4:not(#\#):not(#\#):not(#\#){object-fit:contain}.xl1xv1r:not(#\#):not(#\#):not(#\#){object-fit:cover}.x1xyvc85:not(#\#):not(#\#):not(#\#){opacity:.15}.xvpkmg4:not(#\#):not(#\#):not(#\#){opacity:.25}.xuzhngd:not(#\#):not(#\#):not(#\#){opacity:.3}.x3onkmb:not(#\#):not(#\#):not(#\#){opacity:.35}.xbyyjgo:not(#\#):not(#\#):not(#\#){opacity:.5}.x197sbye:not(#\#):not(#\#):not(#\#){opacity:.6}.xg01cxk:not(#\#):not(#\#):not(#\#){opacity:0}.x1hc1fzr:not(#\#):not(#\#):not(#\#){opacity:1}.x1wnsjo:not(#\#):not(#\#):not(#\#){opacity:var(--_conceal-opacity,1)}.xgsobzw:not(#\#):not(#\#):not(#\#){opacity:var(--_reveal-opacity,1)}.x1i7u4iq:not(#\#):not(#\#):not(#\#){opacity:var(--_toast-swipe-opacity,1)}.x1clqncf:not(#\#):not(#\#):not(#\#){order:-1}.x1g77sc7:not(#\#):not(#\#):not(#\#){order:0}.x1wfwxd8:not(#\#):not(#\#):not(#\#){outline-offset:0}.x1kvmbwa:not(#\#):not(#\#):not(#\#){outline-offset:var(--_focus-outline-offset,0)}.x1t137rt:not(#\#):not(#\#):not(#\#){outline-style:none}.x1k57tk5:not(#\#):not(#\#):not(#\#){outline-width:0}.x9y5y3v:not(#\#):not(#\#):not(#\#){overflow-clip-margin:1px}.xj0a0fe:not(#\#):not(#\#):not(#\#){overflow-wrap:anywhere}.x1mzt3pk:not(#\#):not(#\#):not(#\#){overflow-wrap:break-word}.x1h4wwuj:not(#\#):not(#\#):not(#\#){overflow-wrap:normal}.xyri2b:not(#\#):not(#\#):not(#\#){padding-inline-end:0}.x1g2apga:not(#\#):not(#\#):not(#\#){padding-inline-end:calc(var(--_textarea-inline-padding) + var(--spacing-12))}.xp2dy4z:not(#\#):not(#\#):not(#\#){padding-inline-end:calc(var(--_textarea-inline-padding) + var(--spacing-6))}.x12frdag:not(#\#):not(#\#):not(#\#){padding-inline-end:calc(var(--container-padding-inline-end) - var(--border-width))}.x1g0rcpp:not(#\#):not(#\#):not(#\#){padding-inline-end:max(var(--spacing-4),env(safe-area-inset-right,0px))}.x1by8st6:not(#\#):not(#\#):not(#\#){padding-inline-end:var(--astryx-dialog-padding-inline-end,var(--astryx-dialog-padding-inline,var(--astryx-dialog-padding,max(var(--spacing-4),env(safe-area-inset-right,0px)))))}.x17sfb9:not(#\#):not(#\#):not(#\#){padding-inline-end:var(--astryx-number-input-padding-inline-end,var(--astryx-number-input-padding-inline,var(--astryx-number-input-padding,var(--spacing-2))))}.x64h4k7:not(#\#):not(#\#):not(#\#){padding-inline-end:var(--container-padding-inline-end)}.x1peupej:not(#\#):not(#\#):not(#\#){padding-inline-end:var(--layout-padding-inner-x,var(--spacing-4))}.xpc6k2p:not(#\#):not(#\#):not(#\#){padding-inline-end:var(--layout-padding-outer-x,var(--spacing-4))}.x1le3yxw:not(#\#):not(#\#):not(#\#){padding-inline-end:var(--spacing-0-5)}.x1s0aq8i:not(#\#):not(#\#):not(#\#){padding-inline-end:var(--spacing-0)}.x17hk9do:not(#\#):not(#\#):not(#\#){padding-inline-end:var(--spacing-1-5)}.x1nryj5t:not(#\#):not(#\#):not(#\#){padding-inline-end:var(--spacing-1)}.x160ivqr:not(#\#):not(#\#):not(#\#){padding-inline-end:var(--spacing-10)}.x1djylfy:not(#\#):not(#\#):not(#\#){padding-inline-end:var(--spacing-2)}.x1t818jl:not(#\#):not(#\#):not(#\#){padding-inline-end:var(--spacing-3)}.xnjyzlh:not(#\#):not(#\#):not(#\#){padding-inline-end:var(--spacing-4)}.xdbrk9v:not(#\#):not(#\#):not(#\#){padding-inline-end:var(--spacing-5)}.x1we12cn:not(#\#):not(#\#):not(#\#){padding-inline-end:var(--spacing-6)}.x1q91b2g:not(#\#):not(#\#):not(#\#){padding-inline-end:var(--spacing-8)}.x120eax6:not(#\#):not(#\#):not(#\#){padding-inline-end:var(--x-paddingInlineEnd)}.x1c1uobl:not(#\#):not(#\#):not(#\#){padding-inline-start:0}.x1f43n9v:not(#\#):not(#\#):not(#\#){padding-inline-start:calc(16px + var(--spacing-1-5))}.x1b6te9z:not(#\#):not(#\#):not(#\#){padding-inline-start:calc(var(--_textarea-inline-padding) + var(--spacing-6))}.xs19ii7:not(#\#):not(#\#):not(#\#){padding-inline-start:calc(var(--container-padding-inline-start) - var(--border-width))}.x2a0j69:not(#\#):not(#\#):not(#\#){padding-inline-start:calc(var(--spacing-2) - var(--spacing-1) + 1px)}.xf4btlh:not(#\#):not(#\#):not(#\#){padding-inline-start:max(var(--spacing-4),env(safe-area-inset-left,0px))}.xqmdmw:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--astryx-dialog-padding-inline-start,var(--astryx-dialog-padding-inline,var(--astryx-dialog-padding,max(var(--spacing-4),env(safe-area-inset-left,0px)))))}.x1jni19p:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--astryx-number-input-padding-inline-start,var(--astryx-number-input-padding-inline,var(--astryx-number-input-padding,var(--spacing-2))))}.x1c35znw:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--container-padding-inline-start)}.xwjyata:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--layout-padding-inner-x,var(--spacing-4))}.x139j0dd:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--layout-padding-outer-x,var(--spacing-4))}.x138rykx:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--spacing-0-5)}.x18gyask:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--spacing-0)}.xfti1ec:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--spacing-1-5)}.x1vsv5vr:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--spacing-1)}.xqp078j:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--spacing-10)}.xc8afjc:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--spacing-11)}.x19b7t93:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--spacing-12)}.x12gdq22:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--spacing-2)}.x126nfab:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--spacing-3)}.x1rey3nv:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--spacing-4)}.x1blguxw:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--spacing-5)}.x31w388:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--spacing-6)}.xchaq28:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--spacing-7)}.x1j3hnjz:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--spacing-8)}.xnvo3vl:not(#\#):not(#\#):not(#\#){padding-inline-start:var(--x-paddingInlineStart)}.x201tam:not(#\#):not(#\#):not(#\#){perspective:520px}.x67bb7w:not(#\#):not(#\#):not(#\#){pointer-events:auto}.x47corl:not(#\#):not(#\#):not(#\#){pointer-events:none}.x1tsffl5:not(#\#):not(#\#):not(#\#){position-anchor:--outline-active}.x10l6tqk:not(#\#):not(#\#):not(#\#){position:absolute}.xixxii4:not(#\#):not(#\#):not(#\#){position:fixed}.x1n2onr6:not(#\#):not(#\#):not(#\#){position:relative}.x1uhb9sk:not(#\#):not(#\#):not(#\#){position:static}.x7wzq59:not(#\#):not(#\#):not(#\#){position:sticky}.x1mf7ja4:not(#\#):not(#\#):not(#\#){position:var(--_reveal-position,static)}.xio8zfp:not(#\#):not(#\#):not(#\#){r:calc(var(--_spinner-ring-diameter) / 2)}.xtt52l0:not(#\#):not(#\#):not(#\#){resize:none}.x288g5:not(#\#):not(#\#):not(#\#){resize:vertical}.xajebq8:not(#\#):not(#\#):not(#\#){row-gap:calc(var(--spacing-1) - 1px)}.x1tw44j4:not(#\#):not(#\#):not(#\#){row-gap:var(--spacing-0-5)}.x6yxi7o:not(#\#):not(#\#):not(#\#){row-gap:var(--spacing-0)}.xhq53yo:not(#\#):not(#\#):not(#\#){row-gap:var(--spacing-1-5)}.x1ngg2t4:not(#\#):not(#\#):not(#\#){row-gap:var(--spacing-1)}.x1xpicb7:not(#\#):not(#\#):not(#\#){row-gap:var(--spacing-10)}.x1x7z4sm:not(#\#):not(#\#):not(#\#){row-gap:var(--spacing-2)}.x4olc9o:not(#\#):not(#\#):not(#\#){row-gap:var(--spacing-3)}.xtx9w7w:not(#\#):not(#\#):not(#\#){row-gap:var(--spacing-4)}.x1iu6piu:not(#\#):not(#\#):not(#\#){row-gap:var(--spacing-5)}.xczp1bk:not(#\#):not(#\#):not(#\#){row-gap:var(--spacing-6)}.xgx0vcf:not(#\#):not(#\#):not(#\#){row-gap:var(--spacing-8)}.xkcv6ua:not(#\#):not(#\#):not(#\#){scroll-behavior:smooth}.xrw9175:not(#\#):not(#\#):not(#\#){scroll-padding-block-end:48px}.x1hdbdi8:not(#\#):not(#\#):not(#\#){scroll-snap-align:center}.x1bhewko:not(#\#):not(#\#):not(#\#){scroll-snap-align:start}.x1rohswg:not(#\#):not(#\#):not(#\#){scrollbar-width:none}.x1vy8frr:not(#\#):not(#\#):not(#\#){stroke-dasharray:calc(var(--_spinner-ring-diameter) * 1.1781) calc(var(--_spinner-ring-diameter) * 1.9635)}.x1owpc8m:not(#\#):not(#\#):not(#\#){stroke-linecap:round}.x7bo2k:not(#\#):not(#\#):not(#\#){stroke-opacity:.3}.x1smxkh6:not(#\#):not(#\#):not(#\#){stroke-opacity:.302}.x1g350g8:not(#\#):not(#\#):not(#\#){stroke-opacity:1}.xgw3ha0:not(#\#):not(#\#):not(#\#){stroke-width:var(--_spinner-ring-stroke)}.xtve3lm:not(#\#):not(#\#):not(#\#){stroke:var(--spinner-color)}.xalkhop:not(#\#):not(#\#):not(#\#){stroke:var(--spinner-track-color)}.xeq4nuv:not(#\#):not(#\#):not(#\#){tab-size:2}.x1drmoe9:not(#\#):not(#\#):not(#\#){table-layout:auto}.x140o2bo:not(#\#):not(#\#):not(#\#){table-layout:fixed}.x2b8uid:not(#\#):not(#\#):not(#\#){text-align:center}.xp4054r:not(#\#):not(#\#):not(#\#){text-align:end}.x16tdsg8:not(#\#):not(#\#):not(#\#){text-align:inherit}.x1yc453h:not(#\#):not(#\#):not(#\#){text-align:start}.x1b2iylo:not(#\#):not(#\#):not(#\#){text-box-edge:cap alphabetic}.xwgcxoh:not(#\#):not(#\#):not(#\#){text-box-trim:trim-both}.xycaml9:not(#\#):not(#\#):not(#\#){-webkit-text-decoration-color:var(--color-border-emphasized);-webkit-text-decoration-color:var(--color-border-emphasized);-webkit-text-decoration-color:var(--color-border-emphasized);text-decoration-color:var(--color-border-emphasized)}.xujl8zx:not(#\#):not(#\#):not(#\#){text-decoration-line:underline}.xev0dqp:not(#\#):not(#\#):not(#\#){text-decoration-style:dashed}.xlyipyv:not(#\#):not(#\#):not(#\#){text-overflow:ellipsis}.xtvhhri:not(#\#):not(#\#):not(#\#){text-transform:uppercase}.xrys4gj:not(#\#):not(#\#):not(#\#){text-underline-offset:2px}.x11b3rvo:not(#\#):not(#\#):not(#\#){text-underline-offset:var(--spacing-0-5)}.x1w2vvpw:not(#\#):not(#\#):not(#\#){text-wrap:balance}.xebhuq6:not(#\#):not(#\#):not(#\#){text-wrap:nowrap}.x1fzhlzt:not(#\#):not(#\#):not(#\#){text-wrap:pretty}.xk4td0m:not(#\#):not(#\#):not(#\#){text-wrap:wrap}.x5ve5x3:not(#\#):not(#\#):not(#\#){touch-action:none}.x1bblx7b:not(#\#):not(#\#):not(#\#){touch-action:pan-x}.xx69xxh:not(#\#):not(#\#):not(#\#){touch-action:pan-y}.x1g0ag68:not(#\#):not(#\#):not(#\#){transform-origin:50%}.x1oyok0e:not(#\#):not(#\#):not(#\#){transform-style:preserve-3d}.x1c071of:not(#\#):not(#\#):not(#\#){transform:none}.x7p49u4:not(#\#):not(#\#):not(#\#){transform:rotate(0)}.x19jd1h0:not(#\#):not(#\#):not(#\#){transform:rotate(180deg)}.x1iffjtl:not(#\#):not(#\#):not(#\#){transform:rotate(90deg)}.x3oybdh:not(#\#):not(#\#):not(#\#){transform:scale(1)}.x11lhmoz:not(#\#):not(#\#):not(#\#){transform:translate(-50%,-50%)}.x1m9mm8y:not(#\#):not(#\#):not(#\#){transform:translate(-50%,50%)}.xv8yid9:not(#\#):not(#\#):not(#\#){transform:translate(25%,25%)}.x4v1no5:not(#\#):not(#\#):not(#\#){transform:translate(50%,50%)}.x5i6ehr:not(#\#):not(#\#):not(#\#){transform:translate(-100%)}.xuuh30:not(#\#):not(#\#):not(#\#){transform:translate(-50%)}.xbryuvx:not(#\#):not(#\#):not(#\#){transform:translate(0)}.xumwmo6:not(#\#):not(#\#):not(#\#){transform:translate(100%)}.xv5t66b:not(#\#):not(#\#):not(#\#){transform:translate(12px)}.x15481yp:not(#\#):not(#\#):not(#\#){transform:translate(14px)}.xitnhlw:not(#\#):not(#\#):not(#\#){transform:translate(50%)}.x105ttfm:not(#\#):not(#\#):not(#\#){transform:translateY(-100%)}.x19xzu86:not(#\#):not(#\#):not(#\#){transform:translateY(-3px)scale(.985)}.x1bvilyr:not(#\#):not(#\#):not(#\#){transform:translateY(-4px)}.x1cb1t30:not(#\#):not(#\#):not(#\#){transform:translateY(-50%)}.xp0htlv:not(#\#):not(#\#):not(#\#){transform:translateY(-6px)scale(.97)}.xnn1q72:not(#\#):not(#\#):not(#\#){transform:translateY(0)}.x1weeur4:not(#\#):not(#\#):not(#\#){transform:translateY(100%)}.x131p8rn:not(#\#):not(#\#):not(#\#){transform:translateY(50%)}.x149p1fo:not(#\#):not(#\#):not(#\#){transform:translateY(var(--_toast-swipe-exit-y,var(--_toast-swipe-y,var(--_toast-slide-y,var(--spacing-2))))) scale(var(--_toast-swipe-scale,1))}.x1qk3xlt:not(#\#):not(#\#):not(#\#){transform:translateY(var(--_toast-swipe-y,0px)) scale(var(--_toast-swipe-scale,1))}.x11wx31z:not(#\#):not(#\#):not(#\#){transform:var(--x-qthpiu)}.xsqj5wx:not(#\#):not(#\#):not(#\#){transform:var(--x-transform)}.xd00j3c:not(#\#):not(#\#):not(#\#){transition-behavior:allow-discrete}.x5h36tt:not(#\#):not(#\#):not(#\#){transition-delay:.15s}.x1ahifba:not(#\#):not(#\#):not(#\#){transition-delay:0s}.x4avkj2:not(#\#):not(#\#):not(#\#){transition-delay:var(--_fade-delay,0s)}.x1rq8cwj:not(#\#):not(#\#):not(#\#){transition-delay:var(--_reveal-delay,0s,0s)}.x10b1n17:not(#\#):not(#\#):not(#\#){transition-delay:var(--duration-fast)}.x11bq7d0:not(#\#):not(#\#):not(#\#){transition-duration:60ms}.xx6bhzk:not(#\#):not(#\#):not(#\#){transition-duration:.15s}.x13dflua:not(#\#):not(#\#):not(#\#){transition-duration:.2s}.xjd9b36:not(#\#):not(#\#):not(#\#){transition-duration:1ms}.x2rcmwa:not(#\#):not(#\#):not(#\#){transition-duration:var(--duration-fast-max)}.xkvfbh3:not(#\#):not(#\#):not(#\#){transition-duration:var(--duration-fast-min)}.x1tw3moq:not(#\#):not(#\#):not(#\#){transition-duration:var(--duration-fast),0s}.xuedmi6:not(#\#):not(#\#):not(#\#){transition-duration:var(--duration-fast)}.xgneliz:not(#\#):not(#\#):not(#\#){transition-duration:var(--duration-medium-min)}.x80gvsz:not(#\#):not(#\#):not(#\#){transition-duration:var(--duration-medium)}.x1eaenvl:not(#\#):not(#\#):not(#\#){transition-property:background-color,border-color,color}.xts7igz:not(#\#):not(#\#):not(#\#){transition-property:background-color,border-color}.x106061f:not(#\#):not(#\#):not(#\#){transition-property:background-color,box-shadow}.xzo0q3i:not(#\#):not(#\#):not(#\#){transition-property:background-color,color,border-color}.xs2xxs2:not(#\#):not(#\#):not(#\#){transition-property:background-color,color}.x1e8aii2:not(#\#):not(#\#):not(#\#){transition-property:background-color,opacity}.x15406qy:not(#\#):not(#\#):not(#\#){transition-property:background-color}.xrafxwg:not(#\#):not(#\#):not(#\#){transition-property:background-image,background-color,color,opacity,transform}.x12qzo2w:not(#\#):not(#\#):not(#\#){transition-property:background-image}.x1tv3a4w:not(#\#):not(#\#):not(#\#){transition-property:border-color,box-shadow,background-color}.x12zzom9:not(#\#):not(#\#):not(#\#){transition-property:border-color,box-shadow}.xshfolx:not(#\#):not(#\#):not(#\#){transition-property:border-color}.x16mfhj0:not(#\#):not(#\#):not(#\#){transition-property:box-shadow,border-color}.xkdsq27:not(#\#):not(#\#):not(#\#){transition-property:box-shadow}.x1vix5yk:not(#\#):not(#\#):not(#\#){transition-property:color,background-color,box-shadow}.x1gbuem2:not(#\#):not(#\#):not(#\#){transition-property:color,background-color}.x1jbe559:not(#\#):not(#\#):not(#\#){transition-property:color,font-weight}.x1mpt4pi:not(#\#):not(#\#):not(#\#){transition-property:color,-webkit-text-decoration,text-decoration}.xt3l3uh:not(#\#):not(#\#):not(#\#){transition-property:color}.xrgi2yo:not(#\#):not(#\#):not(#\#){transition-property:display}.xjshnde:not(#\#):not(#\#):not(#\#){transition-property:grid-template-rows,padding}.x1qn9uv2:not(#\#):not(#\#):not(#\#){transition-property:grid-template-rows}.x157bb6t:not(#\#):not(#\#):not(#\#){transition-property:-webkit-mask-image,mask-image}.x13b0p5u:not(#\#):not(#\#):not(#\#){transition-property:none}.x1wbls7o:not(#\#):not(#\#):not(#\#){transition-property:opacity,background-color,transform}.xnpjden:not(#\#):not(#\#):not(#\#){transition-property:opacity,background-color}.xsm4mo9:not(#\#):not(#\#):not(#\#){transition-property:opacity,display,overlay}.x1n1p2mu:not(#\#):not(#\#):not(#\#){transition-property:opacity,position}.x1apppo2:not(#\#):not(#\#):not(#\#){transition-property:opacity,transform,max-width}.x4bbghf:not(#\#):not(#\#):not(#\#){transition-property:opacity,transform,overlay,display}.x6o7n8i:not(#\#):not(#\#):not(#\#){transition-property:opacity,transform}.xxup5nn:not(#\#):not(#\#):not(#\#){transition-property:opacity,visibility,transform}.x1jl3cmp:not(#\#):not(#\#):not(#\#){transition-property:opacity,visibility}.x19991ni:not(#\#):not(#\#):not(#\#){transition-property:opacity}.x1xuz8iz:not(#\#):not(#\#):not(#\#){transition-property:top,height}.x18dpk69:not(#\#):not(#\#):not(#\#){transition-property:transform,background-color}.x12pfavo:not(#\#):not(#\#):not(#\#){transition-property:transform,color}.xwcsmn1:not(#\#):not(#\#):not(#\#){transition-property:transform,opacity}.xh3q6i0:not(#\#):not(#\#):not(#\#){transition-property:transform,width,height}.x11xpdln:not(#\#):not(#\#):not(#\#){transition-property:transform}.x74b7sa:not(#\#):not(#\#):not(#\#){transition-property:visibility}.xxrbq2n:not(#\#):not(#\#):not(#\#){transition-property:width}.xv2sgk5:not(#\#):not(#\#):not(#\#){transition-timing-function:cubic-bezier(.3,0,.6,.6)}.x9lcvmn:not(#\#):not(#\#):not(#\#){transition-timing-function:ease-out}.xcj1dhv:not(#\#):not(#\#):not(#\#){transition-timing-function:linear}.xlr8y92:not(#\#):not(#\#):not(#\#){transition-timing-function:var(--ease-standard)}.x3sa99s:not(#\#):not(#\#):not(#\#){translate:0 -50%}.x87ps6o:not(#\#):not(#\#):not(#\#){-webkit-user-select:none;user-select:none}.x11njtxf:not(#\#):not(#\#):not(#\#){vertical-align:baseline}.x3ajldb:not(#\#):not(#\#):not(#\#){vertical-align:bottom}.xxymvpz:not(#\#):not(#\#):not(#\#){vertical-align:middle}.x1v0h343:not(#\#):not(#\#):not(#\#){vertical-align:super}.x16dsc37:not(#\#):not(#\#):not(#\#){vertical-align:top}.xlshs6z:not(#\#):not(#\#):not(#\#){visibility:hidden}.xnpuxes:not(#\#):not(#\#):not(#\#){visibility:visible}.xeaf4i8:not(#\#):not(#\#):not(#\#){white-space:normal}.xuxw1ft:not(#\#):not(#\#):not(#\#){white-space:nowrap}.x126k92a:not(#\#):not(#\#):not(#\#){white-space:pre-wrap}.x1sdyfia:not(#\#):not(#\#):not(#\#){white-space:pre}.x1q1rmc8:not(#\#):not(#\#):not(#\#){will-change:transform,opacity}.x1so62im:not(#\#):not(#\#):not(#\#){will-change:transform}.x1yn0g08:not(#\#):not(#\#):not(#\#){word-break:break-all}.x13faqbe:not(#\#):not(#\#):not(#\#){word-break:break-word}.x1lldw8n:not(#\#):not(#\#):not(#\#){word-break:normal}.x1ja2u2z:not(#\#):not(#\#):not(#\#){z-index:0}.x1vjfegm:not(#\#):not(#\#):not(#\#){z-index:1}.xfo81ep:not(#\#):not(#\#):not(#\#){z-index:1000}.xhtitgo:not(#\#):not(#\#):not(#\#){z-index:2}.xzkaem6:not(#\#):not(#\#):not(#\#){z-index:3}.x6cuj84:not(#\#):not(#\#):not(#\#){z-index:500}.x1q2oy4v:not(#\#):not(#\#):not(#\#){z-index:9999}.x1v2claj.x1v2claj:where(.x84s7jz:focus-within *):not(#\#):not(#\#):not(#\#){opacity:1}.x3730vf.x3730vf:where(.x84s7jz:focus-within *):not(#\#):not(#\#):not(#\#){pointer-events:auto}.xuqivmr.xuqivmr:where(.x84s7jz:focus-within *):not(#\#):not(#\#):not(#\#){transform:translateY(0)}.x7v6acp.x7v6acp:where(.x84s7jz:focus-within *):not(#\#):not(#\#):not(#\#){visibility:visible}.x5um2zc.x5um2zc:where(.x1twag4g:first-child *):not(#\#):not(#\#):not(#\#),.x1se5z8o.x1se5z8o:where(.x1twag4g:last-child *):not(#\#):not(#\#):not(#\#){visibility:hidden}@supports (animation-timeline:view()){.x1iu2jvn.x1iu2jvn:not(#\#):not(#\#):not(#\#){animation-name:x1tut0r7-B}}.xfd3fxj:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){animation-name:x1c2q33o-B}.x1vxsm5i:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){animation-name:xu7jd1z-B}.x18lne9g:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){animation-name:xwmkjkf-B}.x1spg45b.x1spg45b:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){background-color:var(--color-accent)}.x1rmb4wm:not(:has(~:not([popover]):not(template))):not(#\#):not(#\#):not(#\#){border-end-end-radius:var(--radius-element)}.xturttb:not(:has(~:not([popover]):not(template))):not(#\#):not(#\#):not(#\#){border-end-start-radius:var(--radius-element)}.x1tzxhge:not(:has(~:not([popover]):not(template))):not(#\#):not(#\#):not(#\#){border-start-end-radius:var(--radius-element)}.xuihb5h:focus-within:not(#\#):not(#\#):not(#\#){box-shadow:inset 0 0 0 2px var(--color-accent-muted)}.x15ysqaf:focus-within:not(#\#):not(#\#):not(#\#){box-shadow:none}.xyavpck:focus-within:not(#\#):not(#\#):not(#\#){box-shadow:var(--shadow-med)}.x10wafsz:focus-within:not(#\#):not(#\#):not(#\#){clip-path:none}.xy5bzlh.xy5bzlh:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){color:var(--color-icon-primary)}.x9o1np9.x9o1np9:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){color:var(--color-text-primary)}.x16khyan:is(:disabled,[aria-disabled=true]):not(#\#):not(#\#):not(#\#){cursor:default}.x1y40yee:popover-open:not(#\#):not(#\#):not(#\#){display:flex}.x1sik18w:not(:first-child):not(#\#):not(#\#):not(#\#){margin-inline-start:var(--_avatar-group-overlap)}.x1nwey30:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){-webkit-mask-image:linear-gradient(to left,transparent var(--_tab-strip-bleed),black calc(var(--_tab-strip-bleed) + var(--spacing-8)));-webkit-mask-image:linear-gradient(to left,transparent var(--_tab-strip-bleed),black calc(var(--_tab-strip-bleed) + var(--spacing-8)));-webkit-mask-image:linear-gradient(to left,transparent var(--_tab-strip-bleed),black calc(var(--_tab-strip-bleed) + var(--spacing-8)));mask-image:linear-gradient(to left,transparent var(--_tab-strip-bleed),black calc(var(--_tab-strip-bleed) + var(--spacing-8)))}.x1rxa4r8:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){-webkit-mask-image:linear-gradient(to right,transparent var(--_tab-strip-bleed),black calc(var(--_tab-strip-bleed) + var(--spacing-8)));-webkit-mask-image:linear-gradient(to right,transparent var(--_tab-strip-bleed),black calc(var(--_tab-strip-bleed) + var(--spacing-8)));-webkit-mask-image:linear-gradient(to right,transparent var(--_tab-strip-bleed),black calc(var(--_tab-strip-bleed) + var(--spacing-8)));mask-image:linear-gradient(to right,transparent var(--_tab-strip-bleed),black calc(var(--_tab-strip-bleed) + var(--spacing-8)))}.x1euntei:focus-within:not(#\#):not(#\#):not(#\#),.x25t5g8:focus-visible:not(#\#):not(#\#):not(#\#),.xof6bs:is(th:hover *):not(#\#):not(#\#):not(#\#){opacity:1}.xofkqq2:popover-open:not(#\#):not(#\#):not(#\#){opacity:1}.x1e0x2sz:focus-visible:not(#\#):not(#\#):not(#\#){outline-color:var(--color-error)}.xx47ajj:focus-visible:not(#\#):not(#\#):not(#\#){outline-color:var(--focus-outline-color)}.x7s97pk:focus-visible:not(#\#):not(#\#):not(#\#){outline-offset:2px}.x13aywxo:focus-visible:not(#\#):not(#\#):not(#\#){outline-offset:var(--button-focus-offset)}.x1vwwbsn:focus-visible:not(#\#):not(#\#):not(#\#),.xwz5zln.xwz5zln:where(.x1iwu4tg:has(:focus-visible) *):not(#\#):not(#\#):not(#\#){outline-offset:var(--focus-outline-offset)}.x1jhp3zv:focus-visible:not(#\#):not(#\#):not(#\#){outline-style:var(--focus-outline-style)}.x1vidyx5:focus-visible:not(#\#):not(#\#):not(#\#){outline-width:var(--focus-outline-width)}.x1n6uwha:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){padding-inline-end:max(var(--spacing-4),env(safe-area-inset-left,0px))}.xtjjor6:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){padding-inline-end:var(--astryx-dialog-padding-inline-end,var(--astryx-dialog-padding-inline,var(--astryx-dialog-padding,max(var(--spacing-4),env(safe-area-inset-left,0px)))))}.x19efkpl:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){padding-inline-start:max(var(--spacing-4),env(safe-area-inset-right,0px))}.x1i7f2ot:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){padding-inline-start:var(--astryx-dialog-padding-inline-start,var(--astryx-dialog-padding-inline,var(--astryx-dialog-padding,max(var(--spacing-4),env(safe-area-inset-right,0px)))))}.xbt4iw:focus-within:not(#\#):not(#\#):not(#\#){pointer-events:auto}.xo74pv5:focus-within:not(#\#):not(#\#):not(#\#){position:static}.x1mqgsch[data-astryx-scrolling]:not(#\#):not(#\#):not(#\#){scrollbar-width:none}.xaafvuh:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){transform:scaleX(-1)rotate(0)}.x1nxqau:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){transform:scaleX(-1)rotate(90deg)}.xgtlewx:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){transform:scaleX(-1)}.x10fxb7p:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){transform:translate(-25%,25%)}.xqgnvz5:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){transform:translate(-50%,50%)}.xoffwj3:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){transform:translate(50%,-50%)}.x1df3fe5:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){transform:translate(-100%)}.xi9aj42:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){transform:translate(-12px)}.x12xz5k6:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){transform:translate(-14px)}.x36dvrd:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){transform:translate(-50%)}.xttggg:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){transform:translate(100%)}.x1nyx83j:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){transform:translate(50%)}.x9cjr8z:popover-open:not(#\#):not(#\#):not(#\#){transform:translateY(0)}.x75qhwu:is([dir=rtl] *):not(#\#):not(#\#):not(#\#){transform:var(--x-sj6hyi)}.x1rm9qnc:focus-within:not(#\#):not(#\#):not(#\#){z-index:1}.x1btxeh5:has(input:focus-visible):not(#\#):not(#\#):not(#\#){box-shadow:inset 0 0 0 2px var(--color-accent)}.x92e2el:has(>[data-astryx-edge-comp]:last-child):not(#\#):not(#\#):not(#\#){margin-inline-end:var(--x-4drmnv)}.x1kftj4p:has(>[data-astryx-edge-comp]:first-child):not(#\#):not(#\#):not(#\#){margin-inline-start:var(--x-126w13d)}:is(.x1uy843r:has(:focus-visible):not(#\#):not(#\#):not(#\#),.xobxmqy:has(>:first-child:focus-visible):not(#\#):not(#\#):not(#\#)){outline-color:var(--focus-outline-color)}:is(.x1jumodi:has(:focus-visible):not(#\#):not(#\#):not(#\#),.x2vr5qc:has(>:first-child:focus-visible):not(#\#):not(#\#):not(#\#)){outline-offset:var(--focus-outline-offset)}:is(.xciu248:has(:focus-visible):not(#\#):not(#\#):not(#\#),.xfd04fr:has(>:first-child:focus-visible):not(#\#):not(#\#):not(#\#)){outline-style:var(--focus-outline-style)}:is(.x11j6mr8:has(:focus-visible):not(#\#):not(#\#):not(#\#),.xmmisi4:has(>:first-child:focus-visible):not(#\#):not(#\#):not(#\#)){outline-width:var(--focus-outline-width)}.xmnmr5y:has(.astryx-nav-icon):not(#\#):not(#\#):not(#\#){padding-inline-start:0}.x1xrp5p4:first-child:not(#\#):not(#\#):not(#\#){border-end-start-radius:var(--radius-element)}.xyf0ibl:first-child:not(#\#):not(#\#):not(#\#){border-inline-start-style:none}.x1pjv70x:first-child:not(#\#):not(#\#):not(#\#){border-inline-start-width:0}.x2qxyot:first-child:not(#\#):not(#\#):not(#\#){border-start-end-radius:var(--radius-element)}.x8eehn2:first-child:not(#\#):not(#\#):not(#\#){border-start-start-radius:var(--radius-element)}.x1pwwqoy:first-child:not(#\#):not(#\#):not(#\#){margin-inline-start:0}.x5uh4xs:first-child:not(#\#):not(#\#):not(#\#){padding-inline-start:max(var(--container-padding-inline-start,var(--spacing-2)),var(--spacing-2))}.x9bi00s:first-child:not(#\#):not(#\#):not(#\#){padding-inline-start:max(var(--container-padding-inline-start,var(--spacing-3)),var(--spacing-2))}.x18c6q21:first-child:not(#\#):not(#\#):not(#\#){padding-inline-start:max(var(--container-padding-inline-start,var(--spacing-4)),var(--spacing-2))}.x747jw7:last-child:not(#\#):not(#\#):not(#\#){border-end-end-radius:var(--radius-element)}.x1qlsc9e:last-child:not(#\#):not(#\#):not(#\#){border-inline-end-width:0}.x11xp8u1:last-child:not(#\#):not(#\#):not(#\#){border-start-end-radius:var(--radius-element)}.xbg7gas:last-child:not(#\#):not(#\#):not(#\#){padding-inline-end:max(var(--container-padding-inline-end,var(--spacing-2)),var(--spacing-2))}.xpilulx:last-child:not(#\#):not(#\#):not(#\#){padding-inline-end:max(var(--container-padding-inline-end,var(--spacing-3)),var(--spacing-2))}.x1wzlfcn:last-child:not(#\#):not(#\#):not(#\#){padding-inline-end:max(var(--container-padding-inline-end,var(--spacing-4)),var(--spacing-2))}.x1dnou9g:nth-child(2n):not(#\#):not(#\#):not(#\#){background-color:var(--color-background-muted)}.x1c52tdz:focus:not(#\#):not(#\#):not(#\#){background-color:var(--color-overlay-hover)}.x1rsz1da:focus:not(#\#):not(#\#):not(#\#){clip-path:none}.xodanix:focus:not(#\#):not(#\#):not(#\#){inset-inline-start:var(--spacing-2)}.x1xrnuwo:focus:not(#\#):not(#\#):not(#\#){position:fixed}.x1hbpcn8:focus:not(#\#):not(#\#):not(#\#){white-space:normal}.xjtnuge:active:not(#\#):not(#\#):not(#\#){background-color:var(--color-neutral)}.xuqm82a:active:not(#\#):not(#\#):not(#\#){background-image:none}.x1pdlv7q:active:not(#\#):not(#\#):not(#\#){transform:none}.xk4oym4:active:not(#\#):not(#\#):not(#\#){transform:scale(.98)}@media (prefers-reduced-motion:reduce){.x14q22ui.x14q22ui:not(#\#):not(#\#):not(#\#){animation-delay:0s}.xnh0sag.xnh0sag:not(#\#):not(#\#):not(#\#){animation-duration:3s}.x1aquc0h.x1aquc0h:not(#\#):not(#\#):not(#\#){animation-name:none}}@media (forced-colors:active){.x9yvj25.x9yvj25:not(#\#):not(#\#):not(#\#){background-color:canvas}.xwvh9j7.xwvh9j7:not(#\#):not(#\#):not(#\#){background-color:canvastext}}@media (prefers-contrast:more) and (not (forced-colors:active)){.x1j0df82.x1j0df82:not(#\#):not(#\#):not(#\#){background-color:var(--color-skeleton)}@supports (color:color-mix(in lab, red, red)){.x1j0df82.x1j0df82:not(#\#):not(#\#):not(#\#){background-color:color-mix(in srgb,var(--color-skeleton),var(--color-text-primary) 30%)}}}@media (forced-colors:active){.x1o55y2u.x1o55y2u:not(#\#):not(#\#):not(#\#){background-color:graytext}.x1jzqe4.x1jzqe4:not(#\#):not(#\#):not(#\#){background-color:highlight}.x1sir5s4.x1sir5s4:not(#\#):not(#\#):not(#\#){background-color:highlighttext}}@media (hover:hover){.x150ydqw.x150ydqw:not(#\#):not(#\#):not(#\#){background-color:#0000}}@media (forced-colors:active){.xs5hli.xs5hli:not(#\#):not(#\#):not(#\#){color:canvastext}.x1k5gbb1.x1k5gbb1:not(#\#):not(#\#):not(#\#){color:highlighttext}}@media (hover:hover){.x2dt3px.x2dt3px:not(#\#):not(#\#):not(#\#){cursor:zoom-in}.xqwu39o.xqwu39o:not(#\#):not(#\#):not(#\#){display:flex}}@media (width<=480px){.xedohl4.xedohl4:not(#\#):not(#\#):not(#\#){display:flex}}@media (pointer:coarse){.xhj50sb.xhj50sb:not(#\#):not(#\#):not(#\#){display:none}}@media (width<=480px){.x1rpgqan.x1rpgqan:not(#\#):not(#\#):not(#\#){flex-direction:column}}@media (pointer:coarse){.x6pjikd.x6pjikd:not(#\#):not(#\#):not(#\#){font-size:max(1rem,var(--text-body-size))}.xdk3u5w.xdk3u5w:not(#\#):not(#\#):not(#\#){font-size:max(1rem,var(--text-label-size))}.x1hsn8va.x1hsn8va:not(#\#):not(#\#):not(#\#){inset-inline-start:50%}.x1jymrmb.x1jymrmb:not(#\#):not(#\#):not(#\#){margin-inline-start:auto}}@media (forced-colors:active){.x1tbh5bv.x1tbh5bv:not(#\#):not(#\#):not(#\#){opacity:1}}@media (pointer:coarse){.xozvky.xozvky:not(#\#):not(#\#):not(#\#){order:1}}@media (prefers-reduced-motion:reduce){.xg83hb1.xg83hb1:not(#\#):not(#\#):not(#\#){scroll-behavior:auto}}@media (pointer:coarse){.x8i4i9p.x8i4i9p:not(#\#):not(#\#):not(#\#){transform:translate(-50%,-50%)}}@media (prefers-reduced-motion:reduce){.xwgk2z2.xwgk2z2:not(#\#):not(#\#):not(#\#){transition-delay:var(--_reveal-delay-reduced,0s,0s)}.xsagj69.xsagj69:not(#\#):not(#\#):not(#\#){transition-duration:.01ms}.xzg1mie.xzg1mie:not(#\#):not(#\#):not(#\#){transition-duration:10ms}.xsr0bmt.xsr0bmt:not(#\#):not(#\#):not(#\#){transition-duration:0s,0s}.x12w9bfk.x12w9bfk:not(#\#):not(#\#):not(#\#){transition-duration:0s}.x4wkmsb.x4wkmsb:not(#\#):not(#\#):not(#\#){transition-property:none}}.x1anq1lc.x1anq1lc:active:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){background-color:var(--color-overlay-pressed)}.xzmimnh.xzmimnh:active:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){background-image:linear-gradient(var(--color-overlay-pressed),var(--color-overlay-pressed)),linear-gradient(var(--color-neutral),var(--color-neutral))}.x7uyq82.x7uyq82:active:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){background-image:linear-gradient(var(--color-overlay-pressed),var(--color-overlay-pressed))}@media (hover:hover) and (forced-colors:none){.xcgwt1n.xcgwt1n.xcgwt1n:where(.x1iwu4tg:hover *):not(#\#):not(#\#):not(#\#){background-color:var(--color-accent)}@supports (color:color-mix(in lab, red, red)){.xcgwt1n.xcgwt1n.xcgwt1n:where(.x1iwu4tg:hover *):not(#\#):not(#\#):not(#\#){background-color:color-mix(in srgb,var(--color-accent),var(--color-tint-hover) 15%)}}}@media (hover:hover){.x17srpfb.x17srpfb.x17srpfb:where(.x1odsvnm:hover *):not(#\#):not(#\#):not(#\#){background-color:var(--color-accent)}@supports (color:color-mix(in lab, red, red)){.x17srpfb.x17srpfb.x17srpfb:where(.x1odsvnm:hover *):not(#\#):not(#\#):not(#\#){background-color:color-mix(in srgb,var(--color-accent),var(--color-tint-hover) 15%)}}}@media (hover:hover) and (forced-colors:none){.x1a8ae7b.x1a8ae7b.x1a8ae7b:where(.x1iwu4tg:hover *):not(#\#):not(#\#):not(#\#){background-color:var(--color-background-gray)}@supports (color:color-mix(in lab, red, red)){.x1a8ae7b.x1a8ae7b.x1a8ae7b:where(.x1iwu4tg:hover *):not(#\#):not(#\#):not(#\#){background-color:color-mix(in srgb,var(--color-background-gray),var(--color-tint-hover) 5%)}}}@media (hover:hover){.xeultfy.xeultfy.xeultfy:where(.x1odsvnm:hover *):not(#\#):not(#\#):not(#\#){background-color:var(--color-background-surface)}@supports (color:color-mix(in lab, red, red)){.xeultfy.xeultfy.xeultfy:where(.x1odsvnm:hover *):not(#\#):not(#\#):not(#\#){background-color:color-mix(in srgb,var(--color-background-surface),var(--color-tint-hover) 5%)}}.xqxnq6d.xqxnq6d.xqxnq6d:where(.x1odsvnm:hover *):not(#\#):not(#\#):not(#\#){background-color:var(--color-background-muted)}.x1pe4z86.x1pe4z86.x1pe4z86:where(.x-default-marker:hover *):not(#\#):not(#\#):not(#\#){background-color:var(--color-icon-primary)}.x1a1zr74.x1a1zr74.x1a1zr74:where(.x1u3b27q:hover *):not(#\#):not(#\#):not(#\#){background-color:var(--color-overlay-hover)}.x1t9gxa6.x1t9gxa6.x1t9gxa6:where(.x-default-marker:hover *):not(#\#):not(#\#):not(#\#){color:var(--color-text-primary)}.xcwhr9z.xcwhr9z.xcwhr9z:where(.x84s7jz:hover *):not(#\#):not(#\#):not(#\#){opacity:1}.x8ydxbz.x8ydxbz.x8ydxbz:where(.x84s7jz:hover *):not(#\#):not(#\#):not(#\#){pointer-events:auto}.x17hxqr7.x17hxqr7.x17hxqr7:where(.x84s7jz:hover *):not(#\#):not(#\#):not(#\#){transform:translateY(0)}.xneequu.xneequu.xneequu:where(.x84s7jz:hover *):not(#\#):not(#\#):not(#\#){visibility:visible}}@supports (animation-timeline:view()){@media (prefers-reduced-motion:reduce){.xk3h8ob.xk3h8ob.xk3h8ob:not(#\#):not(#\#):not(#\#){animation-name:xuvekqa-B}}}@media (hover:hover){.xvxo0qp.xvxo0qp.xvxo0qp:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){background-color:var(--color-accent)}@supports (color:color-mix(in lab, red, red)){.xvxo0qp.xvxo0qp.xvxo0qp:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){background-color:color-mix(in srgb,var(--color-accent),var(--color-tint-hover) 15%)}}.x1pfkqlk.x1pfkqlk.x1pfkqlk:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){background-color:#0000}.xcu6dpe.xcu6dpe.xcu6dpe:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){background-color:var(--color-neutral)}.x1912f9e.x1912f9e.x1912f9e:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#):after,.xoevpu5.xoevpu5.xoevpu5:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){background-color:var(--color-overlay-hover)}.xmvprkv.xmvprkv.xmvprkv:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){background-image:linear-gradient(var(--color-overlay-hover),var(--color-overlay-hover))}.x1bm8j9m.x1bm8j9m.x1bm8j9m:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){background-image:none}.x1telqz2.x1telqz2.x1telqz2:hover:not(:focus-within):where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){box-shadow:inset 0 0 0 2px var(--color-accent)}@supports (color:color-mix(in lab, red, red)){.x1telqz2.x1telqz2.x1telqz2:hover:not(:focus-within):where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){box-shadow:inset 0 0 0 2px color-mix(in srgb,var(--color-accent) 20%,transparent)}}.x1v5wwkd.x1v5wwkd.x1v5wwkd:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){box-shadow:inset 0 0 0 2px var(--color-accent)}@supports (color:color-mix(in lab, red, red)){.x1v5wwkd.x1v5wwkd.x1v5wwkd:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){box-shadow:inset 0 0 0 2px color-mix(in srgb,var(--color-accent) 20%,transparent)}}.x1xqjsvb.x1xqjsvb.x1xqjsvb:hover:not(:focus-within):where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){box-shadow:inset 0 0 0 2px var(--color-border-emphasized)}@supports (color:color-mix(in lab, red, red)){.x1xqjsvb.x1xqjsvb.x1xqjsvb:hover:not(:focus-within):where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){box-shadow:inset 0 0 0 2px color-mix(in srgb,var(--color-border-emphasized) 30%,transparent)}}.x1s17dad.x1s17dad.x1s17dad:hover:not(:focus-within):where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){box-shadow:none}.x1bgmis8.x1bgmis8.x1bgmis8:hover:not(:focus-within):where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){box-shadow:var(--shadow-inset-error)}.x8wp45d.x8wp45d.x8wp45d:hover:not(:focus-within):where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){box-shadow:var(--shadow-inset-success)}.x9156jc.x9156jc.x9156jc:hover:not(:focus-within):where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){box-shadow:var(--shadow-inset-warning)}.x1ymidup.x1ymidup.x1ymidup:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){box-shadow:var(--shadow-med)}.x1rfoswn.x1rfoswn.x1rfoswn:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){color:var(--color-text-accent)}@supports (color:color-mix(in lab, red, red)){.x1rfoswn.x1rfoswn.x1rfoswn:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){color:color-mix(in srgb,var(--color-text-accent),var(--color-tint-hover) 15%)}}.xcunlro.xcunlro.xcunlro:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){color:var(--color-text-primary)}@supports (color:color-mix(in lab, red, red)){.xcunlro.xcunlro.xcunlro:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){color:color-mix(in srgb,var(--color-text-primary),var(--color-tint-hover) 15%)}}.x7jm8ul.x7jm8ul.x7jm8ul:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){color:var(--color-text-secondary)}@supports (color:color-mix(in lab, red, red)){.x7jm8ul.x7jm8ul.x7jm8ul:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){color:color-mix(in srgb,var(--color-text-secondary),var(--color-tint-hover) 15%)}}.xo5jvnm.xo5jvnm.xo5jvnm:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){color:var(--color-text-primary)}}@container (width<=399px){.x1alyx8p.x1alyx8p:not(#\#):not(#\#):not(#\#){flex-wrap:wrap}}@media (forced-colors:active){.x1vo6n7o.x1vo6n7o:active:not(#\#):not(#\#):not(#\#){background-color:highlight}}@media (hover:hover){.x1otsd3y.x1otsd3y.x1otsd3y:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){background-image:linear-gradient(var(--color-overlay-hover),var(--color-overlay-hover)),linear-gradient(var(--color-neutral),var(--color-neutral))}.xprvw0a.xprvw0a.xprvw0a:active:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){background-color:var(--color-overlay-pressed)}.xo3fi6e.xo3fi6e.xo3fi6e:active:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){background-image:linear-gradient(var(--color-overlay-pressed),var(--color-overlay-pressed)),linear-gradient(var(--color-neutral),var(--color-neutral))}.xetgvay.xetgvay.xetgvay:active:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){background-image:linear-gradient(var(--color-overlay-pressed),var(--color-overlay-pressed))}@media (forced-colors:active){.x1d42zcn.x1d42zcn.x1d42zcn.x1d42zcn:hover:where(:not(:disabled,[aria-disabled=true])):not(#\#):not(#\#):not(#\#){background-color:highlight}}}.xib2hle:not(#\#):not(#\#):not(#\#):not(#\#){border-bottom-color:var(--color-border-emphasized)}.xw8gpjh:not(#\#):not(#\#):not(#\#):not(#\#){border-bottom-color:var(--color-border)}.x1q0q8m5:not(#\#):not(#\#):not(#\#):not(#\#){border-bottom-style:solid}.xso031l:not(#\#):not(#\#):not(#\#):not(#\#){border-bottom-width:1px}.xlxy82:not(#\#):not(#\#):not(#\#):not(#\#){border-bottom-width:2px}.x92x3c3:not(#\#):not(#\#):not(#\#):not(#\#){border-bottom-width:var(--border-width)}.x1mly77v:not(#\#):not(#\#):not(#\#):not(#\#){border-top-color:var(--color-border-emphasized)}.x1pc3f07:not(#\#):not(#\#):not(#\#):not(#\#){border-top-color:var(--color-border)}.x11npmm7:not(#\#):not(#\#):not(#\#):not(#\#){border-top-color:var(--color-on-accent)}.x13fuv20:not(#\#):not(#\#):not(#\#):not(#\#){border-top-style:solid}.x178xt8z:not(#\#):not(#\#):not(#\#):not(#\#){border-top-width:1px}.x11xkdxz:not(#\#):not(#\#):not(#\#):not(#\#){border-top-width:var(--border-width)}.x1ey2m1c:not(#\#):not(#\#):not(#\#):not(#\#){bottom:0}.x1c7jfne:not(#\#):not(#\#):not(#\#):not(#\#){bottom:2px}.xyi47jn:not(#\#):not(#\#):not(#\#):not(#\#){bottom:var(--_tab-indicator-bottom,-1px)}.x112dmjn:not(#\#):not(#\#):not(#\#):not(#\#){bottom:var(--spacing-1)}.x1nqzi6q:not(#\#):not(#\#):not(#\#):not(#\#){bottom:var(--x-bottom)}.xvle69y:not(#\#):not(#\#):not(#\#):not(#\#){height:.75rem}.xqtp20y:not(#\#):not(#\#):not(#\#):not(#\#){height:0}.xmll18r:not(#\#):not(#\#):not(#\#):not(#\#){height:1.25rem}.xam5rvr:not(#\#):not(#\#):not(#\#):not(#\#){height:1.5rem}.x5yr21d:not(#\#):not(#\#):not(#\#):not(#\#){height:100%}.xtdtrs8:not(#\#):not(#\#):not(#\#):not(#\#){height:100dvh}.xpyat2d:not(#\#):not(#\#):not(#\#):not(#\#){height:100px}.x1dr59a3:not(#\#):not(#\#):not(#\#):not(#\#){height:100vh}.x170jfvy:not(#\#):not(#\#):not(#\#):not(#\#){height:10px}.x1wkxgih:not(#\#):not(#\#):not(#\#):not(#\#){height:120px}.x1kpxq89:not(#\#):not(#\#):not(#\#):not(#\#){height:12px}.xhjk10j:not(#\#):not(#\#):not(#\#):not(#\#){height:140px}.x1v9usgg:not(#\#):not(#\#):not(#\#):not(#\#){height:14px}.x1ymw6g:not(#\#):not(#\#):not(#\#):not(#\#){height:160px}.xlup9mm:not(#\#):not(#\#):not(#\#):not(#\#){height:16px}.xmix8c7:not(#\#):not(#\#):not(#\#):not(#\#){height:18px}.xlzyvqe:not(#\#):not(#\#):not(#\#):not(#\#){height:1em}.xjm9jq1:not(#\#):not(#\#):not(#\#):not(#\#){height:1px}.x1l36t39:not(#\#):not(#\#):not(#\#):not(#\#){height:1rem}.x1qx5ct2:not(#\#):not(#\#):not(#\#):not(#\#){height:20px}.xxk0z11:not(#\#):not(#\#):not(#\#):not(#\#){height:24px}.x1fgtraw:not(#\#):not(#\#):not(#\#):not(#\#){height:28px}.x36qwtl:not(#\#):not(#\#):not(#\#):not(#\#){height:2px}.x10w6t97:not(#\#):not(#\#):not(#\#):not(#\#){height:32px}.xuoj239:not(#\#):not(#\#):not(#\#):not(#\#){height:3px}.x1vqgdyp:not(#\#):not(#\#):not(#\#):not(#\#){height:40px}.xsdox4t:not(#\#):not(#\#):not(#\#):not(#\#){height:48px}.xqu0tyb:not(#\#):not(#\#):not(#\#):not(#\#){height:4px}.xols6we:not(#\#):not(#\#):not(#\#):not(#\#){height:6px}.xwzfr38:not(#\#):not(#\#):not(#\#):not(#\#){height:80px}.xdk7pt:not(#\#):not(#\#):not(#\#):not(#\#){height:8px}.x1qjb5ga:not(#\#):not(#\#):not(#\#):not(#\#){height:anchor-size(--outline-active height,0px)}.xt7dq6l:not(#\#):not(#\#):not(#\#):not(#\#){height:auto}.xuk38ov:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(100% - var(--tree-list-row-gap,0px) / 2)}.xs02d24:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(100% + 1px)}.x12qplqi:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(100% + var(--container-padding-block-start,0px) + var(--container-padding-block-end,0px))}.xpa73km:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(100dvh - var(--_app-shell-header-height,0px))}.x1oglpa6:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(max(1rem,var(--text-body-size)) * var(--text-body-leading));height:1lh}.x1tpcejd:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(var(--_sheet-budget) + 48px)}.x1uiybsj:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(var(--size-element-lg) - 4px)}.x102lyln:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(var(--size-element-lg) - 8px)}.x184gfjb:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(var(--size-element-md) - 4px)}.xrmxcn7:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(var(--size-element-md) - 8px)}.x1u5rhrp:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(var(--size-element-md) + var(--spacing-1))}.xzj98nu:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(var(--size-element-sm) - 4px)}.xzydfjl:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(var(--size-element-sm) - 8px)}.x1q370uo:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(var(--text-body-size) * var(--text-body-leading))}.x14o5nre:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(var(--text-supporting-size) * var(--text-supporting-leading))}.xw1wawg:not(#\#):not(#\#):not(#\#):not(#\#){height:36px}.xg7h5cd:not(#\#):not(#\#):not(#\#):not(#\#){height:fit-content}.xhovv34:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--_progressbar-mark-height,8px)}.xsyqizj:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--border-width)}.x5kfih4:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--resize-handle-hit-area,16px)}.xssyfek:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--size-element-lg)}.x1ueg155:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--size-element-md)}.x6k0iem:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--size-element-sm)}.x1b2l0oc:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--spacing-0-5)}.xcenk2v:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--spacing-1-5)}.x11c6zpc:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--spacing-1)}.x1k15mir:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--spacing-12)}.xoqw5ej:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--spacing-2)}.x9gl9lo:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--spacing-3)}.x6b6gus:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--spacing-4)}.x1grt7ep:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--spacing-5)}.xvpftlf:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--spacing-6)}.x18to7ep:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--spacing-8)}.x1w0ack5:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--table-resize-height,100%)}.x1seg80s:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--text-large-size)}.x15rwvks:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--text-supporting-size)}.x16ye13r:not(#\#):not(#\#):not(#\#):not(#\#){height:var(--x-height)}.xm8gem:not(#\#):not(#\#):not(#\#):not(#\#){height:264px}.x6hpsvf:not(#\#):not(#\#):not(#\#):not(#\#){height:28px}.x1nrll8i:not(#\#):not(#\#):not(#\#):not(#\#){left:50%}.x1jyxor1:not(#\#):not(#\#):not(#\#):not(#\#){margin-bottom:-1px}.x1if0o47:not(#\#):not(#\#):not(#\#):not(#\#){margin-bottom:-48px}.xat24cr:not(#\#):not(#\#):not(#\#):not(#\#){margin-bottom:0}.xlgak1e:not(#\#):not(#\#):not(#\#):not(#\#){margin-bottom:calc(-1 * (max(var(--_tab-strip-bleed),calc(-1 * var(--_tab-indicator-bottom,-1px)))))}.x1z0f2p2:not(#\#):not(#\#):not(#\#):not(#\#){margin-bottom:calc(-1 * var(--_chat-composer-radius))}.x13i4uq0:not(#\#):not(#\#):not(#\#):not(#\#){margin-bottom:calc(-1 * var(--astryx-number-input-padding-block-end,var(--astryx-number-input-padding,var(--spacing-1))))}.x6h7pi7:not(#\#):not(#\#):not(#\#):not(#\#){margin-bottom:calc(-1 * var(--container-padding-block-end,0px))}.x1cdrix3:not(#\#):not(#\#):not(#\#):not(#\#){margin-bottom:calc(-1 * var(--radius-chat))}.xdrfirk:not(#\#):not(#\#):not(#\#):not(#\#){margin-bottom:calc(-1 * var(--spacing-1-5))}.xlstkdb:not(#\#):not(#\#):not(#\#):not(#\#){margin-bottom:var(--spacing-0-5)}.x14cgwvg:not(#\#):not(#\#):not(#\#):not(#\#){margin-bottom:var(--spacing-1)}.x1p37lm5:not(#\#):not(#\#):not(#\#):not(#\#){margin-bottom:var(--spacing-2)}.xep27e5:not(#\#):not(#\#):not(#\#):not(#\#){margin-bottom:var(--spacing-3)}.xwh1t77:not(#\#):not(#\#):not(#\#):not(#\#){margin-bottom:var(--spacing-4)}.x4d5cxa:not(#\#):not(#\#):not(#\#):not(#\#){margin-bottom:var(--spacing-6)}.xlm3tn6:not(#\#):not(#\#):not(#\#):not(#\#){margin-bottom:var(--x-marginBlockEnd)}.xdj266r:not(#\#):not(#\#):not(#\#):not(#\#){margin-top:0}.xr1yuqi:not(#\#):not(#\#):not(#\#):not(#\#){margin-top:auto}.xmqyaqf:not(#\#):not(#\#):not(#\#):not(#\#){margin-top:calc(-1 * (var(--_tab-strip-bleed)))}.xvyqdj1:not(#\#):not(#\#):not(#\#):not(#\#){margin-top:calc(-1 * anchor-size(height) - 8px)}.xckg3cf:not(#\#):not(#\#):not(#\#):not(#\#){margin-top:calc(-1 * var(--_chat-composer-radius))}.x5j3pgv:not(#\#):not(#\#):not(#\#):not(#\#){margin-top:calc(-1 * var(--astryx-number-input-padding-block-start,var(--astryx-number-input-padding,var(--spacing-1))))}.x1sa9bsh:not(#\#):not(#\#):not(#\#):not(#\#){margin-top:calc(-1 * var(--container-padding-block-start,0px))}.x1c40v9y:not(#\#):not(#\#):not(#\#):not(#\#){margin-top:calc(-1 * var(--spacing-1-5))}.x1ajqlyv:not(#\#):not(#\#):not(#\#):not(#\#){margin-top:calc(-1 * var(--spacing-2))}.x1233pnv:not(#\#):not(#\#):not(#\#):not(#\#){margin-top:calc((1em * var(--text-body-leading) - 6px) / 2)}.xjc2qm6:not(#\#):not(#\#):not(#\#):not(#\#){margin-top:var(--spacing-0-5)}.xcsaf9d:not(#\#):not(#\#):not(#\#):not(#\#){margin-top:var(--spacing-1)}.xtbrsbv:not(#\#):not(#\#):not(#\#):not(#\#){margin-top:var(--spacing-2)}.xj6sv8s:not(#\#):not(#\#):not(#\#):not(#\#){margin-top:var(--spacing-3)}.x1s1qpeq:not(#\#):not(#\#):not(#\#):not(#\#){margin-top:var(--spacing-4)}.x13rv44w:not(#\#):not(#\#):not(#\#):not(#\#){margin-top:var(--spacing-6)}.x1vhfslr:not(#\#):not(#\#):not(#\#):not(#\#){margin-top:var(--x-marginBlockStart)}.xmz0i5r:not(#\#):not(#\#):not(#\#):not(#\#){max-height:100%}.x1wj9ous:not(#\#):not(#\#):not(#\#):not(#\#){max-height:100dvh}.x18s7i0i:not(#\#):not(#\#):not(#\#):not(#\#){max-height:176px}.x1xiyphd:not(#\#):not(#\#):not(#\#):not(#\#){max-height:240px}.xuyqlj2:not(#\#):not(#\#):not(#\#):not(#\#){max-height:300px}.xbhvqqn:not(#\#):not(#\#):not(#\#):not(#\#){max-height:calc(100% - var(--spacing-3))}.x14bu9tk:not(#\#):not(#\#):not(#\#):not(#\#){max-height:calc(92dvh + 48px)}.xpnbb6b:not(#\#):not(#\#):not(#\#):not(#\#){max-height:min(480px,100vh - 32px)}.x7ab17h:not(#\#):not(#\#):not(#\#):not(#\#){max-height:none}.xenllk4:not(#\#):not(#\#):not(#\#):not(#\#){max-height:var(--container-max-height,none)}.x1jols5v:not(#\#):not(#\#):not(#\#):not(#\#){max-height:var(--x-maxHeight)}.x1m189uc:not(#\#):not(#\#):not(#\#):not(#\#){max-width:0}.x193iq5w:not(#\#):not(#\#):not(#\#):not(#\#){max-width:100%}.xlbgzzq:not(#\#):not(#\#):not(#\#):not(#\#){max-width:100dvw}.x55n99s:not(#\#):not(#\#):not(#\#):not(#\#){max-width:15em}.x1ncir08:not(#\#):not(#\#):not(#\#):not(#\#){max-width:200px}.xw5ewwj:not(#\#):not(#\#):not(#\#):not(#\#){max-width:300px}.x1x67gh:not(#\#):not(#\#):not(#\#):not(#\#){max-width:32px}.xxc7z9f:not(#\#):not(#\#):not(#\#):not(#\#){max-width:360px}.x1j9u4d2:not(#\#):not(#\#):not(#\#):not(#\#){max-width:400px}.x17fpy1y:not(#\#):not(#\#):not(#\#):not(#\#){max-width:480px}.xrlsmeg:not(#\#):not(#\#):not(#\#):not(#\#){max-width:600px}.x11gisft:not(#\#):not(#\#):not(#\#):not(#\#){max-width:640px}.x1ap80js:not(#\#):not(#\#):not(#\#):not(#\#){max-width:800px}.xq8v1hd:not(#\#):not(#\#):not(#\#):not(#\#){max-width:90%}.xl6temz:not(#\#):not(#\#):not(#\#):not(#\#){max-width:max(80%,280px)}.x1m1aaou:not(#\#):not(#\#):not(#\#):not(#\#){max-width:min(960px,calc(100dvw - var(--spacing-4)))}.x1x1rfll:not(#\#):not(#\#):not(#\#):not(#\#){max-width:none}.xjl2t3p:not(#\#):not(#\#):not(#\#):not(#\#){max-width:var(--layout-content-width,none)}.xf68679:not(#\#):not(#\#):not(#\#):not(#\#){max-width:var(--x-maxWidth)}.x2lwn1j:not(#\#):not(#\#):not(#\#):not(#\#){min-height:0}.x1us19tq:not(#\#):not(#\#):not(#\#):not(#\#){min-height:100%}.x1ov3xa9:not(#\#):not(#\#):not(#\#):not(#\#){min-height:100dvh}.xz65tgg:not(#\#):not(#\#):not(#\#):not(#\#){min-height:200px}.xisnujt:not(#\#):not(#\#):not(#\#):not(#\#){min-height:20px}.xe0957l:not(#\#):not(#\#):not(#\#):not(#\#){min-height:22px}.xjwf9q1:not(#\#):not(#\#):not(#\#):not(#\#){min-height:24px}.xe0p6wg:not(#\#):not(#\#):not(#\#):not(#\#){min-height:28px}.x21xpn4:not(#\#):not(#\#):not(#\#):not(#\#){min-height:32px}.x1xf4nls:not(#\#):not(#\#):not(#\#):not(#\#){min-height:var(--size-element-lg)}.x1uogy3y:not(#\#):not(#\#):not(#\#):not(#\#){min-height:var(--size-element-md)}.x1gdqauq:not(#\#):not(#\#):not(#\#):not(#\#){min-height:var(--size-element-sm)}.x175cymr:not(#\#):not(#\#):not(#\#):not(#\#){min-height:var(--spacing-2)}.ximsjs8:not(#\#):not(#\#):not(#\#):not(#\#){min-height:var(--spacing-7)}.xkoleio:not(#\#):not(#\#):not(#\#):not(#\#){min-height:var(--spacing-8)}.x82snj4:not(#\#):not(#\#):not(#\#):not(#\#){min-height:var(--x-minHeight)}.x1dg37ty:not(#\#):not(#\#):not(#\#):not(#\#){min-height:44px}.xeuugli:not(#\#):not(#\#):not(#\#):not(#\#){min-width:0}.x1i9suas:not(#\#):not(#\#):not(#\#):not(#\#){min-width:120px}.x1d77m7x:not(#\#):not(#\#):not(#\#):not(#\#){min-width:140px}.x5w4yej:not(#\#):not(#\#):not(#\#):not(#\#){min-width:160px}.xfb3i0g:not(#\#):not(#\#):not(#\#):not(#\#){min-width:180px}.xgomdpo:not(#\#):not(#\#):not(#\#):not(#\#){min-width:1rem}.x1jzhcrs:not(#\#):not(#\#):not(#\#):not(#\#){min-width:200px}.xt4ypqs:not(#\#):not(#\#):not(#\#):not(#\#){min-width:20px}.x12rczxh:not(#\#):not(#\#):not(#\#):not(#\#){min-width:220px}.xlm99nl:not(#\#):not(#\#):not(#\#):not(#\#){min-width:240px}.x1u2d2a2:not(#\#):not(#\#):not(#\#):not(#\#){min-width:280px}.x1fns5xo:not(#\#):not(#\#):not(#\#):not(#\#){min-width:40px}.x900493:not(#\#):not(#\#):not(#\#):not(#\#){min-width:48px}.x13n9wmd:not(#\#):not(#\#):not(#\#):not(#\#){min-width:4ch}.xfvyar9:not(#\#):not(#\#):not(#\#):not(#\#){min-width:60px}.xrzjruh:not(#\#):not(#\#):not(#\#):not(#\#){min-width:anchor-size(width)}.x8wyhu6:not(#\#):not(#\#):not(#\#):not(#\#){min-width:calc(anchor-size(width) + 16px)}.x1pshirs:not(#\#):not(#\#):not(#\#):not(#\#){min-width:fit-content}.x15mybvi:not(#\#):not(#\#):not(#\#):not(#\#){min-width:min(400px,calc(100% - var(--spacing-4)))}.x17ydmr0:not(#\#):not(#\#):not(#\#):not(#\#){min-width:var(--size-element-md)}.x1nkkqge:not(#\#):not(#\#):not(#\#):not(#\#){min-width:var(--size-element-sm)}.x18ki04u:not(#\#):not(#\#):not(#\#):not(#\#){min-width:var(--spacing-2)}.x16asifk:not(#\#):not(#\#):not(#\#):not(#\#){min-width:var(--spacing-5)}.xy8csz5:not(#\#):not(#\#):not(#\#):not(#\#){min-width:var(--spacing-7)}.xkj4a21:not(#\#):not(#\#):not(#\#):not(#\#){min-width:var(--x-minWidth)}.x1tutbut:not(#\#):not(#\#):not(#\#):not(#\#){min-width:44px}.xw2csxc:not(#\#):not(#\#):not(#\#):not(#\#){overflow-x:auto}.x6ikm8r:not(#\#):not(#\#):not(#\#):not(#\#){overflow-x:hidden}.x1odjw0f:not(#\#):not(#\#):not(#\#):not(#\#){overflow-y:auto}.x10wlt62:not(#\#):not(#\#):not(#\#):not(#\#){overflow-y:hidden}.x7p5m3t:not(#\#):not(#\#):not(#\#):not(#\#){overscroll-behavior-x:contain}.x18d9i69:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:0}.x1j85h84:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:1px}.x1wkw6tp:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:calc(env(safe-area-inset-bottom,0px) + 48px)}.x9jihrk:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:calc(var(--_chat-composer-padding) + var(--_chat-composer-radius))}.xbv1mwh:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:calc(var(--container-padding-block-end) - var(--border-width))}.xxbfulo:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:calc(var(--spacing-3) + var(--radius-chat))}.xwhchk8:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:max(var(--_tab-strip-bleed),calc(-1 * var(--_tab-indicator-bottom,-1px)))}.xew4nw4:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:max(var(--spacing-4),env(safe-area-inset-bottom,0px))}.xvpcij2:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:var(--_chat-composer-padding)}.x1rgxemn:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:var(--astryx-dialog-padding-block-end,var(--astryx-dialog-padding,max(var(--spacing-4),env(safe-area-inset-bottom,0px))))}.x3jnfsm:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:var(--astryx-number-input-padding-block-end,var(--astryx-number-input-padding,var(--spacing-1)))}.xc1wllq:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:var(--container-padding-block-end)}.xg476vw:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:var(--layout-padding-inner-y,var(--spacing-4))}.xon7vh3:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:var(--layout-padding-outer-y,var(--spacing-4))}.xij103a:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:var(--spacing-0-5)}.x1l20ajd:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:var(--spacing-0)}.x1opdxmq:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:var(--spacing-1-5)}.xy143xn:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:var(--spacing-1)}.x2izi54:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:var(--spacing-10)}.x1wesfrj:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:var(--spacing-2)}.xvmdzux:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:var(--spacing-3)}.x1awphl8:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:var(--spacing-4)}.x1hk98q:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:var(--spacing-5)}.xjpqqx5:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:var(--spacing-6)}.xekm6fs:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:var(--spacing-7)}.x2oz4g1:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:var(--spacing-8)}.xexx8yu:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:0}.x1htvmrp:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:calc(var(--_chat-composer-padding) + var(--_chat-composer-radius))}.x1enrzb7:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:calc(var(--border-width) + var(--spacing-1))}.x1nex4ik:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:calc(var(--container-padding-block-start) - var(--border-width))}.x1ak3mig:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:calc(var(--spacing-1-5) + var(--spacing-2))}.x1vjezoa:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:max(var(--spacing-4),env(safe-area-inset-top,0px))}.x2gtn7z:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:var(--_chat-composer-padding)}.xlr2r7p:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:var(--_tab-strip-bleed)}.x15ld1ci:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:var(--astryx-dialog-padding-block-start,var(--astryx-dialog-padding,max(var(--spacing-4),env(safe-area-inset-top,0px))))}.x4kswst:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:var(--astryx-number-input-padding-block-start,var(--astryx-number-input-padding,var(--spacing-1)))}.x14m0hsi:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:var(--container-padding-block-start)}.xqty4a:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:var(--layout-padding-inner-y,var(--spacing-4))}.x81pis9:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:var(--layout-padding-outer-y,var(--spacing-4))}.xbx876j:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:var(--spacing-0-5)}.x1ydh6w3:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:var(--spacing-0)}.x1kwdpsa:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:var(--spacing-1-5)}.xfsso4q:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:var(--spacing-1)}.xk6660b:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:var(--spacing-10)}.x1xye8es:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:var(--spacing-2)}.x1vlblms:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:var(--spacing-3)}.x1oa1p4a:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:var(--spacing-4)}.xx7rijo:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:var(--spacing-5)}.x1adxfkp:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:var(--spacing-6)}.xoxd1wu:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:var(--spacing-8)}.x13vifvy:not(#\#):not(#\#):not(#\#):not(#\#){top:0}.xuivejd:not(#\#):not(#\#):not(#\#):not(#\#){top:14px}.xs7f9wi:not(#\#):not(#\#):not(#\#):not(#\#){top:2px}.xwa60dl:not(#\#):not(#\#):not(#\#):not(#\#){top:50%}.x1ltwjim:not(#\#):not(#\#):not(#\#):not(#\#){top:anchor(--outline-active top,0px)}.x1nzz77m:not(#\#):not(#\#):not(#\#):not(#\#){top:calc((var(--size-element-md) - 20px) / 2 - 1px)}.xeqxqpg:not(#\#):not(#\#):not(#\#):not(#\#){top:calc((var(--size-element-sm) - 20px) / 2 - 1px)}.x7rbydg:not(#\#):not(#\#):not(#\#):not(#\#){top:calc(50% - 14px)}.x1oysc8t:not(#\#):not(#\#):not(#\#):not(#\#){top:calc(var(--size-element-lg) / 2 - 1px)}.xkmsrut:not(#\#):not(#\#):not(#\#):not(#\#){top:calc(var(--size-element-md) / 2 - 1px)}.x1968x6z:not(#\#):not(#\#):not(#\#):not(#\#){top:calc(var(--size-element-sm) / 2 - 1px)}.xht72ud:not(#\#):not(#\#):not(#\#):not(#\#){top:var(--_app-shell-header-height,0px)}.x8d4r5l:not(#\#):not(#\#):not(#\#):not(#\#){top:var(--spacing-1)}.xctzyg:not(#\#):not(#\#):not(#\#):not(#\#){top:var(--spacing-2)}.xyx6v2t:not(#\#):not(#\#):not(#\#):not(#\#){top:var(--spacing-3)}.xjbys53:not(#\#):not(#\#):not(#\#):not(#\#){top:var(--x-top)}.x1jw3ynk:not(#\#):not(#\#):not(#\#):not(#\#){width:.75rem}.xnalus7:not(#\#):not(#\#):not(#\#):not(#\#){width:0}.xwqq7k2:not(#\#):not(#\#):not(#\#):not(#\#){width:1.25rem}.xp8d6y2:not(#\#):not(#\#):not(#\#):not(#\#){width:1.5rem}.xh8yej3:not(#\#):not(#\#):not(#\#):not(#\#){width:100%}.x1o6l61p:not(#\#):not(#\#):not(#\#):not(#\#){width:100dvw}.xn9wirt:not(#\#):not(#\#):not(#\#):not(#\#){width:100vw}.x1fsd2vl:not(#\#):not(#\#):not(#\#):not(#\#){width:10px}.xsmyaan:not(#\#):not(#\#):not(#\#):not(#\#){width:12px}.x6jxa94:not(#\#):not(#\#):not(#\#):not(#\#){width:14px}.x1kky2od:not(#\#):not(#\#):not(#\#):not(#\#){width:16px}.xzjbwwf:not(#\#):not(#\#):not(#\#):not(#\#){width:180px}.x1xp8n7a:not(#\#):not(#\#):not(#\#):not(#\#){width:18px}.x15vhz18:not(#\#):not(#\#):not(#\#):not(#\#){width:1em}.x1i1rx1s:not(#\#):not(#\#):not(#\#):not(#\#){width:1px}.xcdlrvm:not(#\#):not(#\#):not(#\#):not(#\#){width:1rem}.x1oysuqx:not(#\#):not(#\#):not(#\#):not(#\#){width:200px}.xw4jnvo:not(#\#):not(#\#):not(#\#):not(#\#){width:20px}.xafpxmx:not(#\#):not(#\#):not(#\#):not(#\#){width:240px}.xvy4d1p:not(#\#):not(#\#):not(#\#):not(#\#){width:24px}.x1hfn5x7:not(#\#):not(#\#):not(#\#):not(#\#){width:260px}.xfo62xy:not(#\#):not(#\#):not(#\#):not(#\#){width:2px}.x1td3qas:not(#\#):not(#\#):not(#\#):not(#\#){width:32px}.x1g8rjiy:not(#\#):not(#\#):not(#\#):not(#\#){width:3px}.xz84dc7:not(#\#):not(#\#):not(#\#):not(#\#){width:40%}.x1l2rt3b:not(#\#):not(#\#):not(#\#):not(#\#){width:400px}.x100vrsf:not(#\#):not(#\#):not(#\#):not(#\#){width:40px}.x51ohtg:not(#\#):not(#\#):not(#\#):not(#\#){width:4px}.x1fu8urw:not(#\#):not(#\#):not(#\#):not(#\#){width:64px}.x1v4s8kt:not(#\#):not(#\#):not(#\#):not(#\#){width:6px}.x1xc55vz:not(#\#):not(#\#):not(#\#):not(#\#){width:8px}.x1xgy17j:not(#\#):not(#\#):not(#\#):not(#\#){width:anchor-size(width)}.x14atkfc:not(#\#):not(#\#):not(#\#):not(#\#){width:auto}.xx6qvi6:not(#\#):not(#\#):not(#\#):not(#\#){width:calc(100% + var(--container-padding-inline-start,0px) + var(--container-padding-inline-end,0px))}.x1y2t9nm:not(#\#):not(#\#):not(#\#):not(#\#){width:36px}.xeq5yr9:not(#\#):not(#\#):not(#\#):not(#\#){width:fit-content}.x63cpjl:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--_progressbar-mark-width,2px)}.xjk4fl7:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--border-width)}.xkhob8h:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--resize-handle-hit-area,16px)}.x1m747yf:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--size-element-lg)}.x805d0l:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--size-element-md)}.x1fvqzum:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--size-element-sm)}.x1wu31ai:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--spacing-1-5)}.xx9zwd3:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--spacing-1)}.xhgvbfk:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--spacing-12)}.x1f0dxl5:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--spacing-2)}.x1ad1g3v:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--spacing-3)}.x12xnipv:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--spacing-4)}.xfyiiit:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--spacing-5)}.x1mtvzj0:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--spacing-6)}.xgc8j7m:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--spacing-8)}.xta46cu:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--text-large-size)}.x5livx5:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--text-supporting-size)}.x1uyokj7:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--x-inlineSize)}.x5lhr3w:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--x-width)}.x1wp2rvj.x1wp2rvj:where(.x139im0d:last-child *):not(#\#):not(#\#):not(#\#):not(#\#){border-bottom-width:0}.x132qfvm:focus-within:not(#\#):not(#\#):not(#\#):not(#\#){height:auto}.xsg11nj.xsg11nj:where(.x-default-marker:has(>.astryx-layout-footer:not([data-divider])) *):not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:0}.x1ioh5az.x1ioh5az:where(.x-default-marker:has(>.astryx-layout-header:not([data-divider])) *):not(#\#):not(#\#):not(#\#):not(#\#){padding-top:0}.x1kw28su:focus-within:not(#\#):not(#\#):not(#\#):not(#\#){padding-top:var(--spacing-1)}.x10okhzq:focus-within:not(#\#):not(#\#):not(#\#):not(#\#){width:auto}.x5du68j:has(~* [data-chat-name]):not(#\#):not(#\#):not(#\#):not(#\#){margin-top:var(--spacing-5)}.x1d9v4yf:first-child:not(#\#):not(#\#):not(#\#):not(#\#){border-top-style:none}.x1g31smg:first-child:not(#\#):not(#\#):not(#\#):not(#\#){border-top-width:0}.xkibk3:first-child:not(#\#):not(#\#):not(#\#):not(#\#){margin-top:calc(-1 * var(--container-padding-block-start,0px))}.x1vjq31q:first-child:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:0}.xlayyun:last-child:not(#\#):not(#\#):not(#\#):not(#\#){margin-bottom:calc(-1 * var(--container-padding-block-end,0px))}.xup0pd7:last-child:not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:0}.x15cytp8:focus:not(#\#):not(#\#):not(#\#):not(#\#){height:auto}.x1rw3289:focus:not(#\#):not(#\#):not(#\#):not(#\#){top:var(--spacing-2)}.x1jqxupm:focus:not(#\#):not(#\#):not(#\#):not(#\#){width:auto}@media (pointer:coarse){.x80b3aj.x80b3aj:not(#\#):not(#\#):not(#\#):not(#\#){min-height:24px}.x17aqpur.x17aqpur:not(#\#):not(#\#):not(#\#):not(#\#),.xygd9yz.xygd9yz:not(#\#):not(#\#):not(#\#):not(#\#){min-height:44px}.xkagaj0.xkagaj0:not(#\#):not(#\#):not(#\#):not(#\#){min-width:24px}.x1xrq5m.x1xrq5m:not(#\#):not(#\#):not(#\#):not(#\#),.xngvp7v.xngvp7v:not(#\#):not(#\#):not(#\#):not(#\#){min-width:44px}.xijlfn0.xijlfn0:not(#\#):not(#\#):not(#\#):not(#\#){top:50%}}@starting-style{.x1sopeo2.x1sopeo2:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){grid-template-rows:0fr}}.x1xsm0q9:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{inset:-14px}.xarstr8:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after,.xxx281p:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{inset:0}.xht581f:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{inset:var(--_input-clear-hit-inset)}.xeu5z55:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{inset:var(--_thumbnail-hit-inset)}@starting-style{.x4itv7f.x4itv7f:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){opacity:0}.x6mt36l.x6mt36l:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){transform:translate(-100%)}.x1yqmsfc.x1yqmsfc:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){transform:translate(100%)}.xub2912.xub2912:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){transform:translateY(-100%)}.x12p7p72.x12p7p72:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){transform:translateY(-4px)}.xhbqy3z.xhbqy3z:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){transform:translateY(100%)}.x6s140c.x6s140c:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){transform:translateY(var(--_toast-slide-y,var(--spacing-2)))}.x1lymnkk.x1lymnkk:is([dir=rtl] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){transform:translate(-100%)}.x14gflnl.x14gflnl:is([dir=rtl] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){transform:translate(100%)}}.x1k48kgn:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after,.xxyica1:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{border-radius:inherit}.x17gn2l9:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{grid-column:1}.xd54j2p:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{inset-block:0}.xpsyfx0:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::-webkit-date-and-time-value{margin-block:0}.x1qqcexc:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::-webkit-date-and-time-value{margin-inline:0}.x1x4c3m6:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::-webkit-date-and-time-value{padding-block:0}.xtbxizx:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::-webkit-datetime-edit{padding-block:0}@starting-style{.x5rzir7.x5rzir7:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:0}}.xkqr7wz:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::-webkit-date-and-time-value{padding-inline:0}.xslb4at:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::-webkit-datetime-edit{padding-inline:0}.xvtkv6q:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{transition:background-color .15s,width .15s}.x17s1k9h:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{transition:opacity .15s}.x19ds33d:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{align-self:start}.x1abwkk1:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::backdrop{-webkit-backdrop-filter:blur(2px);backdrop-filter:blur(2px)}.xyhc2n1:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{background-color:#0000}.x1tzqye7:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{background-color:var(--color-accent)}.xnixb3f:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::backdrop{background-color:var(--color-overlay)}.x1i3206j:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{background-color:var(--indicator-color,transparent)}.x1uvfo0n:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{background-color:var(--table-row-overlay,transparent)}.xccdyz0:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{background-image:linear-gradient(to left,var(--color-shadow),transparent)}.x1ppu1g5:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{background-image:linear-gradient(to right,var(--color-shadow),transparent)}.xnnzo76:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{border-inline-start-color:var(--color-border)}.xvsnedh:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{border-inline-start-style:solid}.x1p96cux:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{border-inline-start-width:var(--border-width)}.xtkarl4:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{color:var(--color-syntax-punctuation)}.xnf3u0:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::placeholder{color:var(--color-text-disabled)}.xeyghm5:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::placeholder{color:var(--color-text-secondary)}.x1cpjm7i:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before,.x1s928wv:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{content:""}.x46gnpd:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{content:attr(data-line)}.xc2ndz5:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{content:counter(astryx-list) "."}.xh3pasq:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{content:var(--_input-clear-hit-content)}.xhkezso:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{display:block}.xolhmmf:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::-webkit-calendar-picker-indicator{display:none}.x3nzp0f:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{font-family:var(--font-family-code)}.xekda60:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{inset-inline-end:-2px}.x1unh1gc:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{inset-inline-end:0}.xvw6utc:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{inset-inline-start:-2px}.x1iygr5g:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{inset-inline-start:0}.x1km86hw:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{inset-inline-start:calc(var(--spacing-4) + var(--_codeblock-gutter-width) + var(--spacing-3))}.x15bqym3:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::-webkit-datetime-edit{line-height:inherit}.x1f74mqm:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::-webkit-date-and-time-value{line-height:inherit}.xph5o2a:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::backdrop{opacity:0}.xb3n6bw:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::backdrop{opacity:1}.xni466t:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::backdrop{opacity:var(--_sheet-scrim-opacity,1)}.x1c2idit:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{opacity:var(--table-sticky-shadow-end,0)}.x1sggmfs:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{opacity:var(--table-sticky-shadow-start,0)}.x2q1x1w:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after,.xkk1bqk:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{pointer-events:none}.x1hmns74:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before,.x1j6awrg:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{position:absolute}.x1wnbjh8:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{text-align:end}.x9rmy9g:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::-webkit-date-and-time-value{text-align:start}.x1fgylwi:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{transform-origin:top}.xgu12d:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{transform-origin:0}.x1e8txe:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{transform:scaleX(0)}.xp1ps4y:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{transform:scaleX(1)}.xb5f74o:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{transform:scaleY(0)}.xd30wvy:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{transform:scaleY(1)}.xvs0bi2:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{transform:translate(-100%)}.x1qyefdi:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{transform:translate(100%)}.x142juwg:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::backdrop{transition-behavior:allow-discrete}.xizoc3:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{transition-delay:var(--x-owu7oy)}.x1y1nw7a:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before,.x97pup0:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{transition-duration:var(--duration-fast)}.xft5bk6:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::backdrop,.xuhr57t:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{transition-duration:var(--duration-medium)}.x196sc62:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{transition-duration:var(--x-1dd27dc)}.x1ywzrc5:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after,.xxcwgru:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{transition-property:background-color}.xc0dz0a:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::backdrop{transition-property:opacity,display}.x167zut7:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::backdrop{transition-property:opacity}.x1hu8v7x:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{transition-property:transform}.x1cz9k3x:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::backdrop,.xyt8op7:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{transition-timing-function:linear}.x15h3t91:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::backdrop,.x1dlmc9c:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after,.xa5v58t:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{transition-timing-function:var(--ease-standard)}.x1rbqspl:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{-webkit-user-select:none;user-select:none}.xy5mcqj:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{z-index:-1}.xk7vujl:is([dir=rtl] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{background-image:linear-gradient(to left,var(--color-shadow),transparent)}.xlptwl5:is([dir=rtl] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{background-image:linear-gradient(to right,var(--color-shadow),transparent)}.xdq8fwl:is([dir=rtl] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{transform-origin:100%}.x1c108yo:is([dir=rtl] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{transform:translate(-100%)}.x12ayhd5:is([dir=rtl] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{transform:translate(100%)}.x1k7wiig:active:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{background-color:var(--color-overlay-pressed)}@media (prefers-reduced-motion:reduce){.xhhm9v0.xhhm9v0:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{transition-delay:0s}.x1viac0w.x1viac0w:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::backdrop{transition-duration:10ms}.x13sdc92.x13sdc92:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{transition-duration:0s}}.xe80sof:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{bottom:-2px}.x1xrz1ek:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{bottom:0}.xu6fald:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{height:var(--_sheet-keyboard-inset,0px)}.xec4aax:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::-webkit-date-and-time-value{min-height:0}.x51xajf:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):before{top:-2px}.x1m1drc7:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{top:0}.xkj6t0a:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{width:0}.xzkji8o:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{width:6px}.xi8c0p9:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):after{width:var(--indicator-width,1px)}@starting-style{.xxiuuzi.xxiuuzi:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::backdrop{opacity:0}}:root{--color-data-categorical-blue:#0171e3;--color-data-categorical-orange:#eb6e00;--color-data-categorical-purple:#6b1efd;--color-data-categorical-green:#0b991f;--color-data-categorical-pink:#f351c0;--color-data-categorical-cyan:#0171a4;--color-data-categorical-red:#f5394f;--color-data-categorical-teal:#08a3a3;--color-data-categorical-brown:#965e03;--color-data-categorical-indigo:#6f8aff;--color-data-neutral:var(--lightningcss-light,#8494a3)var(--lightningcss-dark,#8c939b);--color-data-blue-5:#02165e;--color-data-blue-4:#004cbc;--color-data-blue-3:#2694fe;--color-data-blue-2:#78beff;--color-data-blue-1:#dbecff;--color-data-shamrock-5:#0b603d;--color-data-shamrock-4:#138546;--color-data-shamrock-3:#24bb5e;--color-data-shamrock-2:#8ef7aa;--color-data-shamrock-1:#d6fee4;--color-data-orange-5:#a13f04;--color-data-orange-4:#d66100;--color-data-orange-3:#fd9537;--color-data-orange-2:#fdb876;--color-data-orange-1:#ffe6cf;--color-data-pink-5:#8e1073;--color-data-pink-4:#d123a1;--color-data-pink-3:#f989d3;--color-data-pink-2:#feade3;--color-data-pink-1:#fce3f4;--color-data-purple-5:#3e0697;--color-data-purple-4:#6b1efd;--color-data-purple-3:#9081ff;--color-data-purple-2:#b3b0fe;--color-data-purple-1:#e8e8fb;--color-data-red-5:#9d0519;--color-data-red-4:#d31130;--color-data-red-3:#fb7d87;--color-data-red-2:#ffb2b8;--color-data-red-1:#fee4e6;--color-data-teal-5:#08767d;--color-data-teal-4:#0c9293;--color-data-teal-3:#0db7af;--color-data-teal-2:#6ce6d8;--color-data-teal-1:#d7fcf8;--color-data-yellow-5:#8a5001;--color-data-yellow-4:#d69804;--color-data-yellow-3:#fbce03;--color-data-yellow-2:#fcec85;--color-data-yellow-1:#fdf6ba;--color-data-gray-5:var(--lightningcss-light,#25363f)var(--lightningcss-dark,#333338);--color-data-gray-4:var(--lightningcss-light,#5d6c7b)var(--lightningcss-dark,#666a72);--color-data-gray-3:var(--lightningcss-light,#afb9c4)var(--lightningcss-dark,#b2b8be);--color-data-gray-2:var(--lightningcss-light,#ccd3db)var(--lightningcss-dark,#d0d3d6);--color-data-gray-1:var(--lightningcss-light,#f1f4f7)var(--lightningcss-dark,#f2f4f6)}}@layer astryx-theme{:root{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light dark}@media (prefers-color-scheme:dark){:root{--lightningcss-light: ;--lightningcss-dark:initial}}html[data-theme=light]{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light}html[data-theme=dark]{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark}@scope([data-astryx-theme=neutral]) to ([data-astryx-theme]){:scope{--font-size-4xs:.375rem;--font-size-3xs:.4375rem;--font-size-2xs:.5rem;--font-size-xs:.625rem;--font-size-sm:.75rem;--font-size-base:.875rem;--font-size-lg:1.0625rem;--font-size-xl:1.25rem;--font-size-2xl:1.5rem;--font-size-3xl:1.8125rem;--font-size-4xl:2.1875rem;--font-size-5xl:2.625rem;--text-heading-1-size:var(--font-size-2xl);--text-heading-1-weight:var(--font-weight-semibold);--text-heading-1-leading:1.3333;--text-heading-2-size:var(--font-size-xl);--text-heading-2-weight:var(--font-weight-semibold);--text-heading-2-leading:1.4;--text-heading-3-size:var(--font-size-lg);--text-heading-3-weight:var(--font-weight-bold);--text-heading-3-leading:1.4118;--text-heading-4-size:var(--font-size-base);--text-heading-4-weight:var(--font-weight-bold);--text-heading-4-leading:1.4286;--text-heading-5-size:var(--font-size-sm);--text-heading-5-weight:var(--font-weight-semibold);--text-heading-5-leading:1.6667;--text-heading-6-size:var(--font-size-xs);--text-heading-6-weight:var(--font-weight-semibold);--text-heading-6-leading:1.6;--text-body-size:var(--font-size-base);--text-body-weight:var(--font-weight-normal);--text-body-leading:1.4286;--text-large-size:var(--font-size-lg);--text-large-weight:var(--font-weight-semibold);--text-large-leading:1.4118;--text-label-size:var(--font-size-base);--text-label-weight:var(--font-weight-medium);--text-label-leading:1.4286;--text-code-size:var(--font-size-base);--text-code-weight:var(--font-weight-normal);--text-code-leading:1.4286;--text-supporting-size:var(--font-size-sm);--text-supporting-weight:var(--font-weight-normal);--text-supporting-leading:1.6667;--text-display-1-size:var(--font-size-5xl);--text-display-1-weight:var(--font-weight-normal);--text-display-1-leading:1.2381;--text-display-2-size:var(--font-size-4xl);--text-display-2-weight:var(--font-weight-normal);--text-display-2-leading:1.2571;--text-display-3-size:var(--font-size-3xl);--text-display-3-weight:var(--font-weight-normal);--text-display-3-leading:1.3793;--duration-fast-min:95ms;--duration-fast:.125s;--duration-fast-max:.165s;--duration-medium-min:.225s;--duration-medium:.3s;--duration-medium-max:.4s;--duration-slow-min:.525s;--duration-slow:.7s;--duration-slow-max:.935s;--font-family-body:Figtree, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;--font-family-heading:Figtree, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;--font-family-code:ui-monospace, "SF Mono", Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-syntax-keyword:var(--lightningcss-light,#700084)var(--lightningcss-dark,#efa8ff);--color-syntax-string:var(--lightningcss-light,#005600)var(--lightningcss-dark,#a6d2a2);--color-syntax-comment:var(--lightningcss-light,#737373)var(--lightningcss-dark,#a3a3a3);--color-syntax-number:var(--lightningcss-light,#6e3500)var(--lightningcss-dark,#ffb37f);--color-syntax-function:var(--lightningcss-light,#00458c)var(--lightningcss-dark,#a0caff);--color-syntax-type:var(--lightningcss-light,#700084)var(--lightningcss-dark,#efa8ff);--color-syntax-variable:var(--lightningcss-light,#171717)var(--lightningcss-dark,#e5e5e5);--color-syntax-operator:var(--lightningcss-light,#737373)var(--lightningcss-dark,#a3a3a3);--color-syntax-constant:var(--lightningcss-light,#6e3500)var(--lightningcss-dark,#ffb37f);--color-syntax-tag:var(--lightningcss-light,#89001a)var(--lightningcss-dark,#ffaeaa);--color-syntax-attribute:var(--lightningcss-light,#584400)var(--lightningcss-dark,#eec12f);--color-syntax-property:var(--lightningcss-light,#005348)var(--lightningcss-dark,#83dac9);--color-syntax-punctuation:var(--lightningcss-light,#6e6e6e)var(--lightningcss-dark,#a0a0a0);--color-syntax-background:var(--lightningcss-light,#fafafa)var(--lightningcss-dark,#0a0a0a);--color-background-surface:var(--lightningcss-light,#fff)var(--lightningcss-dark,#262626);--color-background-body:var(--lightningcss-light,#f1f1f1)var(--lightningcss-dark,#1b1b1b);--color-background-card:var(--lightningcss-light,#fff)var(--lightningcss-dark,#1b1b1b);--color-background-popover:var(--lightningcss-light,#fff)var(--lightningcss-dark,#1b1b1b);--color-background-muted:var(--lightningcss-light,#f1f1f1)var(--lightningcss-dark,#1b1b1b);--color-accent:var(--lightningcss-light,#262626)var(--lightningcss-dark,#ebebeb);--color-accent-muted:var(--lightningcss-light,#f1f1f1)var(--lightningcss-dark,#262626);--color-neutral:var(--lightningcss-light,#0000000f)var(--lightningcss-dark,#ffffff1a);--color-overlay:var(--lightningcss-light,#00000080)var(--lightningcss-dark,#000c);--color-overlay-hover:var(--lightningcss-light,#0000000d)var(--lightningcss-dark,#ffffff0d);--color-overlay-pressed:var(--lightningcss-light,#0000001a)var(--lightningcss-dark,#ffffff1a);--color-text-primary:var(--lightningcss-light,#171717)var(--lightningcss-dark,#fafafa);--color-text-secondary:var(--lightningcss-light,#525252)var(--lightningcss-dark,#a3a3a3);--color-text-disabled:var(--lightningcss-light,#a3a3a3)var(--lightningcss-dark,#525252);--color-text-accent:var(--lightningcss-light,#262626)var(--lightningcss-dark,#ebebeb);--color-on-dark:#fff;--color-on-light:#171717;--color-on-accent:var(--lightningcss-light,#fff)var(--lightningcss-dark,#171717);--color-on-success:var(--lightningcss-light,#fff)var(--lightningcss-dark,#171717);--color-on-error:var(--lightningcss-light,#fff)var(--lightningcss-dark,#171717);--color-on-warning:#171717;--color-icon-accent:var(--lightningcss-light,#262626)var(--lightningcss-dark,#ebebeb);--color-icon-primary:var(--lightningcss-light,#171717)var(--lightningcss-dark,#fafafa);--color-icon-secondary:var(--lightningcss-light,#737373)var(--lightningcss-dark,#a3a3a3);--color-icon-disabled:var(--lightningcss-light,#a3a3a3)var(--lightningcss-dark,#525252);--color-success:var(--lightningcss-light,#007004)var(--lightningcss-dark,#9fe59b);--color-error:var(--lightningcss-light,#a50c25)var(--lightningcss-dark,#ffc6c1);--color-warning:var(--lightningcss-light,#745b00)var(--lightningcss-dark,#fdcf4f);--color-success-muted:var(--lightningcss-light,#c5e5c0)var(--lightningcss-dark,#84c9803d);--color-error-muted:var(--lightningcss-light,#facecb)var(--lightningcss-dark,#ff9e973d);--color-warning-muted:var(--lightningcss-light,#f8da9d)var(--lightningcss-dark,#deb4333d);--color-border:var(--lightningcss-light,#00000014)var(--lightningcss-dark,#ffffff1a);--color-border-emphasized:var(--lightningcss-light,#d4d4d4)var(--lightningcss-dark,#525252);--color-skeleton:var(--lightningcss-light,#ebebeb)var(--lightningcss-dark,#525252);--color-shadow:var(--lightningcss-light,#0000001a)var(--lightningcss-dark,#0000004d);--color-tint-hover:var(--lightningcss-light,#000)var(--lightningcss-dark,#fff);--color-background-red:var(--lightningcss-light,#facecb)var(--lightningcss-dark,#ff9e973d);--color-border-red:var(--lightningcss-light,#e6bab8)var(--lightningcss-dark,#ff6f6c);--color-icon-red:var(--lightningcss-light,#89001a)var(--lightningcss-dark,#ff9e97);--color-text-red:var(--lightningcss-light,#89001a)var(--lightningcss-dark,#ffc6c1);--color-background-orange:var(--lightningcss-light,#fad0b5)var(--lightningcss-dark,#ffa2583d);--color-border-orange:var(--lightningcss-light,#e6bda2)var(--lightningcss-dark,#e2883e);--color-icon-orange:var(--lightningcss-light,#6e3500)var(--lightningcss-dark,#ffa258);--color-text-orange:var(--lightningcss-light,#6e3500)var(--lightningcss-dark,#ffc9a2);--color-background-yellow:var(--lightningcss-light,#f8da9d)var(--lightningcss-dark,#deb4333d);--color-border-yellow:var(--lightningcss-light,#e4c279)var(--lightningcss-dark,#c0990e);--color-icon-yellow:var(--lightningcss-light,#584400)var(--lightningcss-dark,#deb433);--color-text-yellow:var(--lightningcss-light,#584400)var(--lightningcss-dark,#fdcf4f);--color-background-green:var(--lightningcss-light,#c5e5c0)var(--lightningcss-dark,#84c9803d);--color-border-green:var(--lightningcss-light,#b2d1ac)var(--lightningcss-dark,#69ad67);--color-icon-green:var(--lightningcss-light,#0c5700)var(--lightningcss-dark,#84c980);--color-text-green:var(--lightningcss-light,#0c5700)var(--lightningcss-dark,#9fe59b);--color-background-teal:var(--lightningcss-light,#a5e3d6)var(--lightningcss-dark,#7ec6b83d);--color-border-teal:var(--lightningcss-light,#94d6c8)var(--lightningcss-dark,#63ab9d);--color-icon-teal:var(--lightningcss-light,#005348)var(--lightningcss-dark,#7ec6b8);--color-text-teal:var(--lightningcss-light,#005348)var(--lightningcss-dark,#99e2d3);--color-background-cyan:var(--lightningcss-light,#a3e0ef)var(--lightningcss-dark,#83c2d43d);--color-border-cyan:var(--lightningcss-light,#91d3e3)var(--lightningcss-dark,#67a7b8);--color-icon-cyan:var(--lightningcss-light,#00505f)var(--lightningcss-dark,#83c2d4);--color-text-cyan:var(--lightningcss-light,#00505f)var(--lightningcss-dark,#9edef0);--color-background-blue:var(--lightningcss-light,#c4ddfb)var(--lightningcss-dark,#9eb7ff3d);--color-border-blue:var(--lightningcss-light,#b1c9e7)var(--lightningcss-dark,#6d9cfe);--color-icon-blue:var(--lightningcss-light,#00458c)var(--lightningcss-dark,#9eb7ff);--color-text-blue:var(--lightningcss-light,#00458c)var(--lightningcss-dark,#c7d3ff);--color-background-purple:var(--lightningcss-light,#eccef3)var(--lightningcss-dark,#f297ff3d);--color-border-purple:var(--lightningcss-light,#d8bbdf)var(--lightningcss-dark,#dd74f0);--color-icon-purple:var(--lightningcss-light,#700084)var(--lightningcss-dark,#f297ff);--color-text-purple:var(--lightningcss-light,#700084)var(--lightningcss-dark,#fac1ff);--color-background-pink:var(--lightningcss-light,#fccadc)var(--lightningcss-dark,#ff99c33d);--color-border-pink:var(--lightningcss-light,#e7b7c8)var(--lightningcss-dark,#f273aa);--color-icon-pink:var(--lightningcss-light,#83004b)var(--lightningcss-dark,#ff99c3);--color-text-pink:var(--lightningcss-light,#83004b)var(--lightningcss-dark,#ffc3da);--color-background-gray:var(--lightningcss-light,#e5e5e5)var(--lightningcss-dark,var(--color-neutral));--color-border-gray:var(--lightningcss-light,#d4d4d4)var(--lightningcss-dark,#262626);--color-icon-gray:var(--lightningcss-light,#525252)var(--lightningcss-dark,#a3a3a3);--color-text-gray:var(--lightningcss-light,#262626)var(--lightningcss-dark,#e5e5e5);--radius-none:0px;--radius-inner:.375rem;--radius-element:.625rem;--radius-container:.75rem;--radius-page:1.75rem;--radius-full:9999px;--shadow-low:0 2px 4px var(--lightningcss-light,oklch(0% 0 0/.05))var(--lightningcss-dark,oklch(0% 0 0/.25)), 0 4px 8px var(--lightningcss-light,oklch(0% 0 0/.1))var(--lightningcss-dark,oklch(0% 0 0/.4)), inset 0 0 0 1px var(--lightningcss-light,#0000)var(--lightningcss-dark,oklch(100% 0 0/.08));--shadow-med:0 2px 4px var(--lightningcss-light,oklch(0% 0 0/.05))var(--lightningcss-dark,oklch(0% 0 0/.35)), 0 4px 12px var(--lightningcss-light,oklch(0% 0 0/.1))var(--lightningcss-dark,oklch(0% 0 0/.5)), inset 0 0 0 1px var(--lightningcss-light,#0000)var(--lightningcss-dark,oklch(100% 0 0/.12));--shadow-high:0 4px 6px var(--lightningcss-light,oklch(0% 0 0/.1))var(--lightningcss-dark,oklch(0% 0 0/.5)), 0 12px 24px var(--lightningcss-light,oklch(0% 0 0/.15))var(--lightningcss-dark,oklch(0% 0 0/.7)), inset 0 0 0 1px var(--lightningcss-light,#0000)var(--lightningcss-dark,oklch(100% 0 0/.15));--shadow-inset-hover:inset 0px 0px 0px 2px #0074e24d;--shadow-inset-selected:inset 0px 0px 0px 2px #0074e280;--shadow-inset-success:inset 0px 0px 0px 2px #1981004d;--shadow-inset-warning:inset 0px 0px 0px 2px #ffce2f4d;--shadow-inset-error:inset 0px 0px 0px 2px #e33f4a4d}.astryx-heading.level-1{font-family:var(--font-family-heading);font-size:var(--text-heading-1-size);font-weight:var(--text-heading-1-weight);line-height:var(--text-heading-1-leading)}.astryx-heading.level-2{font-family:var(--font-family-heading);font-size:var(--text-heading-2-size);font-weight:var(--text-heading-2-weight);line-height:var(--text-heading-2-leading)}.astryx-heading.level-3{font-family:var(--font-family-heading);font-size:var(--text-heading-3-size);font-weight:var(--text-heading-3-weight);line-height:var(--text-heading-3-leading)}.astryx-heading.level-4{font-family:var(--font-family-heading);font-size:var(--text-heading-4-size);font-weight:var(--text-heading-4-weight);line-height:var(--text-heading-4-leading)}.astryx-heading.level-5{font-family:var(--font-family-heading);font-size:var(--text-heading-5-size);font-weight:var(--text-heading-5-weight);line-height:var(--text-heading-5-leading)}.astryx-heading.level-6{font-family:var(--font-family-heading);font-size:var(--text-heading-6-size);font-weight:var(--text-heading-6-weight);line-height:var(--text-heading-6-leading)}.astryx-heading.display-1{font-family:var(--font-family-heading);font-size:var(--text-display-1-size);line-height:var(--text-display-1-leading)}.astryx-heading.display-2{font-family:var(--font-family-heading);font-size:var(--text-display-2-size);line-height:var(--text-display-2-leading)}.astryx-heading.display-3{font-family:var(--font-family-heading);font-size:var(--text-display-3-size);line-height:var(--text-display-3-leading)}.astryx-text.body{font-family:var(--font-family-body);font-size:var(--text-body-size);line-height:var(--text-body-leading)}.astryx-text.large{font-family:var(--font-family-body);font-size:var(--text-large-size);line-height:var(--text-large-leading)}.astryx-text.label{font-family:var(--font-family-body);font-size:var(--text-label-size);line-height:var(--text-label-leading)}.astryx-text.code{font-family:var(--font-family-code);font-size:var(--text-code-size);line-height:var(--text-code-leading)}.astryx-text.supporting{font-family:var(--font-family-body);font-size:var(--text-supporting-size);line-height:var(--text-supporting-leading)}.astryx-text.display-1{font-family:var(--font-family-heading);font-size:var(--text-display-1-size);line-height:var(--text-display-1-leading)}.astryx-text.display-2{font-family:var(--font-family-heading);font-size:var(--text-display-2-size);line-height:var(--text-display-2-leading)}.astryx-text.display-3{font-family:var(--font-family-heading);font-size:var(--text-display-3-size);line-height:var(--text-display-3-leading)}.astryx-button.destructive{background-color:var(--color-error-muted);color:var(--color-error)}.astryx-badge.info{color:var(--lightningcss-light,#fff)var(--lightningcss-dark,#171717);background-color:var(--lightningcss-light,#0074e2)var(--lightningcss-dark,#6d9cfe)}.astryx-badge.neutral{background-color:var(--color-background-gray);color:var(--color-text-gray)}.astryx-badge.success{color:var(--lightningcss-light,#fff)var(--lightningcss-dark,#171717);background-color:var(--lightningcss-light,#198100)var(--lightningcss-dark,#64af4c)}.astryx-badge.warning{color:#171717;background-color:#ffce2f}.astryx-badge.error{color:var(--lightningcss-light,#fff)var(--lightningcss-dark,#171717);background-color:var(--lightningcss-light,#c9303a)var(--lightningcss-dark,#ff705d)}.astryx-badge.red{background-color:var(--color-background-red);color:var(--color-text-red)}.astryx-badge.orange{background-color:var(--color-background-orange);color:var(--color-text-orange)}.astryx-badge.yellow{background-color:var(--color-background-yellow);color:var(--color-text-yellow)}.astryx-badge.green{background-color:var(--color-background-green);color:var(--color-text-green)}.astryx-badge.teal{background-color:var(--color-background-teal);color:var(--color-text-teal)}.astryx-badge.cyan{background-color:var(--color-background-cyan);color:var(--color-text-cyan)}.astryx-badge.blue{background-color:var(--color-background-blue);color:var(--color-text-blue)}.astryx-badge.purple{background-color:var(--color-background-purple);color:var(--color-text-purple)}.astryx-badge.pink{background-color:var(--color-background-pink);color:var(--color-text-pink)}.astryx-badge.gray{background-color:var(--color-background-gray);color:var(--color-text-gray)}.astryx-statusdot.success{background-color:var(--lightningcss-light,#198100)var(--lightningcss-dark,#64af4c)}.astryx-statusdot.warning{background-color:#ffce2f}.astryx-statusdot.error{background-color:var(--lightningcss-light,#c9303a)var(--lightningcss-dark,#ff705d)}.astryx-statusdot.accent{background-color:var(--lightningcss-light,#0074e2)var(--lightningcss-dark,#6d9cfe)}.astryx-banner.info{--color-accent-muted:var(--color-background-blue);--color-text-primary:var(--color-text-blue);--color-text-secondary:var(--color-text-blue);--color-accent:var(--color-text-blue)}.astryx-banner.success{--color-text-primary:var(--color-text-green);--color-text-secondary:var(--color-text-green);--color-success:var(--color-text-green)}.astryx-banner.warning{--color-text-primary:var(--color-text-yellow);--color-text-secondary:var(--color-text-yellow);--color-warning:var(--color-text-yellow)}.astryx-banner.error{--color-text-primary:var(--color-text-red);--color-text-secondary:var(--color-text-red);--color-error:var(--color-text-red)}.astryx-switch{--color-background-gray:var(--color-border-emphasized)}.astryx-progressbar{--color-background-muted:var(--color-border-emphasized)}.astryx-progressbar.accent{--color-accent:#0074e2}.astryx-progressbar.success{--color-success:#198100}.astryx-progressbar.warning{--color-warning:#ffce2f}.astryx-progressbar.error{--color-error:#c9303a}.astryx-card{--astryx-card-padding:var(--spacing-3)}.astryx-section{--astryx-section-padding:var(--spacing-3)}.astryx-text.primary,.astryx-heading.primary{color:var(--color-text-primary)}.astryx-text.secondary,.astryx-heading.secondary{color:var(--color-text-secondary)}.astryx-text.disabled,.astryx-heading.disabled{color:var(--color-text-disabled)}.astryx-text.placeholder,.astryx-heading.placeholder{color:var(--color-text-secondary)}.astryx-text.accent,.astryx-heading.accent{color:var(--color-text-accent)}.astryx-text.size-4xs{font-size:var(--font-size-4xs)}.astryx-text.size-3xs{font-size:var(--font-size-3xs)}.astryx-text.size-2xs{font-size:var(--font-size-2xs)}.astryx-text.xsm{font-size:var(--font-size-xs)}.astryx-text.sm{font-size:var(--font-size-sm)}.astryx-text.base{font-size:var(--font-size-base)}.astryx-text.lg{font-size:var(--font-size-lg)}.astryx-text.xl{font-size:var(--font-size-xl)}.astryx-text.size-2xl{font-size:var(--font-size-2xl)}.astryx-text.size-3xl{font-size:var(--font-size-3xl)}.astryx-text.size-4xl{font-size:var(--font-size-4xl)}}@scope([data-astryx-theme=neutral]) to ([data-astryx-theme]){[data-astryx-media=dark]{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark;--color-text-primary:var(--color-on-dark);--color-icon-primary:var(--color-on-dark);--color-accent:var(--color-on-dark)}[data-astryx-media=light]{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light;--color-text-primary:var(--color-on-light);--color-icon-primary:var(--color-on-light);--color-accent:var(--color-on-light)}}}@layer components;@layer utilities{.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}.block{display:block}.hidden{display:none}.resize{resize:both}}:root{--lightningcss-light:initial;--lightningcss-dark: ;color-scheme:light;--page:oklch(99.8% .003 87);--sidebar:oklch(97.8% .021 91);--sidebar-hover:oklch(93.5% .043 91/.65);--sidebar-active:oklch(92.8% .025 91/.82);--border:oklch(91.6% .009 248);--border-strong:oklch(86.8% .014 248);--text:oklch(26.2% .018 249);--muted:oklch(52.5% .019 249);--subtle:oklch(65.2% .016 249);--accent:oklch(51.6% .151 253);--focus:oklch(61.8% .14 251);--healthy:oklch(53.6% .12 158);--error:oklch(49.7% .187 28);--warning:oklch(56.4% .126 74);--grid-minor:oklch(27% .024 250/.03);--grid-major:oklch(27% .024 250/.07);--grid-cross:oklch(27% .024 250/.11)}*{box-sizing:border-box}html,body,#root{width:100%;height:100%;overflow:hidden}body{background-color:var(--sidebar);background-image:linear-gradient(to bottom, oklch(65% .04 85/.06), transparent 40%, transparent 72%, oklch(97.8% .021 91/.5)), linear-gradient(var(--grid-minor) 0 1px, transparent 1px 4px), linear-gradient(to right, var(--grid-minor) 0 1px, transparent 1px 4px), linear-gradient(var(--grid-major) 0 1px, transparent 1px 20px), linear-gradient(to right, var(--grid-major) 0 1px, transparent 1px 20px), radial-gradient(circle at center, transparent 2px, var(--sidebar) 2px 100%), linear-gradient(var(--grid-cross) 0 1px, transparent 1px 20px), linear-gradient(to right, var(--grid-cross) 0 1px, transparent 1px 20px);color:var(--text);-webkit-font-smoothing:antialiased;text-rendering:optimizelegibility;background-position:0 0,0 0,0 0,0 0,0 0,-10px -10px,0 0,0 0;background-size:100% 100%,4px 4px,4px 4px,20px 20px,20px 20px,20px 20px,20px 20px,20px 20px;margin:0;font:14px/1.5 ui-sans-serif,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif}::selection{background:oklch(51.6% .151 253/.18)}button,input,textarea{font:inherit;letter-spacing:0}input,textarea{caret-color:var(--accent)}button{color:inherit}button:focus-visible,input:focus-visible,textarea:focus-visible,summary:focus-visible{outline:2px solid var(--focus);outline-offset:2px}svg{fill:none;stroke:currentColor;stroke-width:1.8px;width:1em;height:1em;display:block}.app-shell{grid-template-columns:280px minmax(0,1fr);width:100%;height:100dvh;transition:grid-template-columns .18s;display:grid}.app-shell.sidebar-collapsed{grid-template-columns:56px minmax(0,1fr)}.session-sidebar{z-index:20;-webkit-backdrop-filter:blur(30px)saturate(1.8)brightness(1.04);backdrop-filter:blur(30px)saturate(1.8)brightness(1.04);background-color:oklch(97.8% .021 91/.3);background-image:linear-gradient(oklch(99.8% .003 87/.42),oklch(99.8% .003 87/.08) 36%,#0000);border-right:1px solid oklch(86.8% .014 248/.5);flex-direction:column;min-height:0;padding:8px 10px;display:flex;position:relative;overflow:hidden;box-shadow:inset 0 1px oklch(99.8% .003 87/.6),inset -1px 0 oklch(99.8% .003 87/.3)}.session-sidebar:before{content:"";pointer-events:none;z-index:calc(10 * -1);filter:blur(1.6px);background-image:linear-gradient(oklch(27% .024 250/.07) 0 1px,#0000 1px 4px),linear-gradient(90deg,oklch(27% .024 250/.07) 0 1px,#0000 1px 4px),linear-gradient(oklch(27% .024 250/.09) 0 1px,#0000 1px 20px),linear-gradient(90deg,oklch(27% .024 250/.09) 0 1px,#0000 1px 20px);background-size:4px 4px,4px 4px,20px 20px,20px 20px;position:absolute;inset:0}.sidebar-brand{height:calc(var(--spacing-1) * 11);justify-content:space-between;align-items:center;padding:0 4px 0 6px;display:flex}.brand-lockup{color:var(--text);align-items:center;font-weight:700;line-height:1;display:inline-flex}.brand-lockup.compact{font-size:18px}.compact .pixel-mark{width:21px;height:21px;margin-left:2px;display:inline-block;position:relative}.compact .pixel-mark i{background:currentColor;width:6px;height:6px;display:block;position:absolute}.compact .pixel-mark i:first-child{top:0;left:0}.compact .pixel-mark i:nth-child(2){top:0;left:5px}.compact .pixel-mark i:nth-child(3){top:0;left:10px}.compact .pixel-mark i:nth-child(4){top:5px;left:0}.compact .pixel-mark i:nth-child(5){top:5px;left:10px}.compact .pixel-mark i:nth-child(6){top:10px;left:0}.compact .pixel-mark i:nth-child(7){top:10px;left:5px}.compact .pixel-mark i:nth-child(8){top:10px;left:15px}.compact .pixel-mark i:nth-child(9){top:15px;left:0}.compact .pixel-mark i:nth-child(10){top:15px;left:15px}.collapse-button,.icon-button,.workspace-action,.sidebar-expand{border-style:var(--tw-border-style);color:var(--muted);background-color:#0000;border-width:0;border-radius:6px;flex-shrink:0;place-items:center;transition:background-color .14s,color .14s;display:grid}.collapse-button{width:30px;height:30px}.collapse-button svg,.icon-button svg{width:18px;height:18px}.collapse-button:hover,.icon-button:hover,.workspace-action:hover{background:var(--sidebar-hover);color:var(--text)}.new-session-button{justify-content:center;align-items:center;gap:calc(var(--spacing-1) * 2);border:1px solid var(--border-strong);background:var(--page);border-radius:19px;flex-shrink:0;width:calc(100% - 4px);height:38px;margin:8px 2px 10px;font-weight:550;display:flex}.new-session-button:hover{background:oklch(99% .004 248);border-color:oklch(78% .018 248)}.new-session-button svg{width:17px;height:17px}.workspace-heading{min-height:calc(var(--spacing-1) * 8);justify-content:space-between;align-items:center;padding:0 4px 0 8px;display:flex}.workspace-heading-label{color:var(--muted);letter-spacing:.04em;text-transform:uppercase;font-size:11px;font-weight:650}.workspace-actions{gap:calc(var(--spacing-1) * .5);display:flex}.icon-button{width:28px;height:28px}.session-search{align-items:center;gap:calc(var(--spacing-1) * 1.5);flex:1;min-width:0;display:none}.session-search>svg{width:14px;height:14px;color:var(--subtle)}.session-search input{border-style:var(--tw-border-style);outline-style:var(--tw-outline-style);min-width:0;height:28px;color:var(--text);background-color:#0000;border-width:0;outline-width:0;flex:1;font-size:12px}.session-search button{width:calc(var(--spacing-1) * 6);height:calc(var(--spacing-1) * 6);border-style:var(--tw-border-style);color:var(--subtle);background-color:#0000;border-width:0;place-items:center;display:grid}.session-search button svg{width:14px;height:14px}.workspace-heading.is-searching .session-search{display:flex}.workspace-heading.is-searching .workspace-heading-label,.workspace-heading.is-searching .workspace-actions{display:none}.workspace-tree{min-height:0;padding-block:var(--spacing-1);scrollbar-width:thin;scrollbar-color:oklch(58% .02 250/.45) transparent;flex:1;overflow-y:auto}.workspace-group{margin-bottom:3px}.workspace-button{min-width:0;height:34px;color:var(--muted);cursor:pointer;border-radius:6px;align-items:center;display:flex}.workspace-button:hover{background:var(--sidebar-hover);color:var(--text)}.workspace-label{border-style:var(--tw-border-style);text-align:left;background-color:#0000;border-width:0;flex:1;align-items:center;min-width:0;height:100%;display:flex}.workspace-toggle{height:100%;width:calc(var(--spacing-1) * 7);border-style:var(--tw-border-style);background-color:#0000;border-width:0;flex-shrink:0;place-items:center;display:grid}.workspace-chevron{font-size:15px;transition:transform .14s;display:block;transform:rotate(0)}.workspace-group.collapsed .workspace-chevron{transform:rotate(-90deg)}.workspace-button strong{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-size:12.5px;font-weight:600;overflow:hidden}.workspace-row-actions{align-items:center;display:flex}.workspace-action{width:27px;height:27px}.workspace-action svg{width:14px;height:14px}.menu-action-button{width:27px!important;min-width:27px!important;height:27px!important;color:var(--muted)!important;padding:0!important}.menu-action-button svg{width:14px;height:14px}.workspace-sessions{display:grid}.workspace-group.collapsed .workspace-sessions{display:none}.session-row{align-items:center;min-width:0;display:flex;position:relative}.session{align-items:center;gap:calc(var(--spacing-1) * 2);border-style:var(--tw-border-style);text-align:left;min-width:0;height:34px;color:var(--muted);background-color:#0000;border-width:0;border-radius:6px;flex:1;padding:0 8px 0 29px;display:flex}.session:hover{background:var(--sidebar-hover);color:var(--text)}.session.active{background:var(--sidebar-active);color:var(--text)}.session-title{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-size:12.5px;overflow:hidden}.session-time{color:var(--subtle);flex:none;font-size:10.5px}.session-row>.astryx-menu-trigger{right:var(--spacing-1);opacity:0;pointer-events:none;position:absolute}.session-row:hover>.astryx-menu-trigger,.session-row:focus-within>.astryx-menu-trigger{opacity:1;pointer-events:auto}.session-row:hover .session-time,.session-row:focus-within .session-time{visibility:hidden}.empty{min-height:32px;color:var(--subtle);padding:7px 10px 7px 29px;font-size:12px}.sidebar-expand{top:calc(var(--spacing-1) * 2);left:calc(var(--spacing-1) * 2);z-index:30;width:40px;height:40px;position:fixed}.sidebar-expand svg{width:19px;height:19px}.sidebar-collapsed .session-sidebar{align-items:center;padding:8px}.sidebar-collapsed .sidebar-brand{justify-content:center;width:40px;padding:0}.sidebar-collapsed .sidebar-brand,.sidebar-collapsed .workspace-heading,.sidebar-collapsed .workspace-tree{visibility:hidden}.sidebar-collapsed .new-session-button{background:0 0;border-color:#0000;width:36px;height:36px;margin:54px 0 12px;padding:0}.sidebar-collapsed .new-session-button span{display:none}.sidebar-collapsed .new-session-button:hover{background:var(--sidebar-hover)}.conversation-shell{grid-template-rows:minmax(0,1fr) auto;min-width:0;min-height:0;display:grid;position:relative;container:conversation-shell/inline-size}.conversation-shell:not(.landing){background-image:linear-gradient(90deg,#0000,oklch(97.8% .021 91/.88) 90px calc(100% - 90px),#0000);background-position:50%;background-repeat:no-repeat;background-size:min(1020px,100%) 100%}.conversation-shell.landing{grid-template-rows:minmax(0,1fr)}.landing .conversation,.landing .composer-dock{grid-area:1/1}.conversation{scroll-behavior:smooth;scrollbar-width:thin;scrollbar-color:oklch(58% .02 250/.45) transparent;min-height:0;overflow-y:auto}.landing-conversation{pointer-events:none;place-items:center;display:grid}.landing-welcome{text-align:center;padding:0 24px;transform:translateY(-110px)}.landing-brand{border-style:var(--tw-border-style);pointer-events:auto;background-color:#0000;border-width:0;justify-content:center;align-items:center;display:flex}.landing-brand .brand-lockup{align-items:flex-end;font-size:44px;animation:2.1s cubic-bezier(.22,1,.36,1) both brand-lockup}.landing-brand .brand-word{opacity:0;animation:2.1s cubic-bezier(.22,1,.36,1) both brand-word-slide;display:inline-block}.landing-brand .pixel-mark{width:66px;height:55px;margin-left:4px;animation:2.1s cubic-bezier(.22,1,.36,1) both pixel-nudge;display:inline-block;position:relative}.landing-brand .pixel-mark i{background-color:var(--piece,currentColor);border-radius:2px;width:11px;height:11px;animation:.35s cubic-bezier(.22,1,.36,1) both pixel-drop,2.1s both piece-to-ink;display:block;position:absolute}.landing-brand .pixel-mark i:after{content:"";border-radius:2px;animation:2.1s both piece-texture-fade;position:absolute;inset:0;box-shadow:inset 0 2px oklch(99% 0 0/.3),inset 0 -2px oklch(0% 0 0/.16),inset 2px 0 oklch(99% 0 0/.12),inset -2px 0 oklch(0% 0 0/.08)}.landing-brand .pixel-mark i:first-child{top:0;left:11px}.landing-brand .pixel-mark i:nth-child(2){top:0;left:22px}.landing-brand .pixel-mark i:nth-child(3){top:0;left:33px}.landing-brand .pixel-mark i:nth-child(4){top:11px;left:33px}.landing-brand .pixel-mark i:nth-child(5){top:11px;left:11px}.landing-brand .pixel-mark i:nth-child(6){top:22px;left:11px}.landing-brand .pixel-mark i:nth-child(7){top:22px;left:22px}.landing-brand .pixel-mark i:nth-child(8){top:33px;left:11px}.landing-brand .pixel-mark i:nth-child(9){top:22px;left:44px}.landing-brand .pixel-mark i:nth-child(10){top:33px;left:44px}.landing-brand .pixel-mark i:nth-child(11){top:44px;left:44px}.landing-brand .pixel-mark i:nth-child(12){top:44px;left:55px}.landing-brand .pixel-mark i:nth-child(13){top:44px;left:0}.landing-brand .pixel-mark i:nth-child(14){top:44px;left:11px}.landing-brand .pixel-mark i:nth-child(15){top:44px;left:22px}.landing-brand .pixel-mark i:nth-child(16){top:44px;left:33px}.landing-brand .pixel-mark i:nth-child(5),.landing-brand .pixel-mark i:nth-child(6),.landing-brand .pixel-mark i:nth-child(7),.landing-brand .pixel-mark i:nth-child(8){--piece:oklch(55% .105 37);animation-delay:.25s,0s}.landing-brand .pixel-mark i:first-child,.landing-brand .pixel-mark i:nth-child(2),.landing-brand .pixel-mark i:nth-child(3),.landing-brand .pixel-mark i:nth-child(4){--piece:oklch(52% .083 252);animation-delay:.5s,0s}.landing-brand .pixel-mark i:nth-child(9),.landing-brand .pixel-mark i:nth-child(10),.landing-brand .pixel-mark i:nth-child(11),.landing-brand .pixel-mark i:nth-child(12){--piece:oklch(66% .08 111);animation-delay:.75s,0s}.landing-brand .pixel-mark i:nth-child(13),.landing-brand .pixel-mark i:nth-child(14),.landing-brand .pixel-mark i:nth-child(15),.landing-brand .pixel-mark i:nth-child(16){--piece:oklch(69% .116 78)}.landing-brand .pixel-mark i:nth-child(11),.landing-brand .pixel-mark i:nth-child(12),.landing-brand .pixel-mark i:nth-child(13),.landing-brand .pixel-mark i:nth-child(14),.landing-brand .pixel-mark i:nth-child(15),.landing-brand .pixel-mark i:nth-child(16){opacity:0;animation:2.1s both pixel-doomed}.landing-brand .pixel-mark i:nth-child(11),.landing-brand .pixel-mark i:nth-child(12){animation-name:pixel-doomed-late}.landing-brand .pixel-mark i:nth-child(13){--dx:-12px;--rot:-22deg}.landing-brand .pixel-mark i:nth-child(14){--dx:-8px;--rot:-12deg}.landing-brand .pixel-mark i:nth-child(15){--dx:-3px;--rot:-5deg}.landing-brand .pixel-mark i:nth-child(16){--dx:3px;--rot:6deg}.landing-brand .pixel-mark i:nth-child(11){--dx:8px;--rot:14deg}.landing-brand .pixel-mark i:nth-child(12){--dx:13px;--rot:24deg}@keyframes pixel-drop{0%{opacity:0;transform:translateY(-40px)}to{opacity:1;transform:none}}@keyframes piece-to-ink{0%,72%{background-color:var(--piece,currentColor)}86%,to{background-color:currentColor}}@keyframes piece-texture-fade{0%,72%{opacity:1}86%,to{opacity:0}}@keyframes pixel-doomed{0%{opacity:0;transform:translateY(-40px)}13%,60%{opacity:1;transform:none}74%{opacity:.9;transform:translate(var(--dx), 14px) rotate(var(--rot)) scale(.85)}to{opacity:0;transform:translate(calc(var(--dx) * 2.5), 44px) rotate(calc(var(--rot) * 1.5)) scale(.5)}}@keyframes pixel-doomed-late{0%,33%{opacity:0;transform:translateY(-40px)}44%,60%{opacity:1;transform:none}74%{opacity:.9;transform:translate(var(--dx), 14px) rotate(var(--rot)) scale(.85)}to{opacity:0;transform:translate(calc(var(--dx) * 2.5), 44px) rotate(calc(var(--rot) * 1.5)) scale(.5)}}@keyframes brand-word-slide{0%,55%{opacity:0;transform:translate(-64px)}62%{opacity:1;transform:translate(2px)}70%,to{opacity:1;transform:none}}@keyframes brand-lockup{0%,56%{transform:translate(-52px)}64%{transform:translate(-38px)}90%,to{transform:none}}@keyframes pixel-nudge{0%,60%{transform:none}65%{transform:translateY(13px)}71%{transform:translateY(11px)}82%,to{transform:translate(-11px,11px)}}.message-row{width:min(820px,100% - 48px);margin-inline:auto;padding:18px 0 26px;position:relative}.message-row.user{justify-content:flex-end;padding-top:26px;display:flex}.message-row.assistant{width:min(840px,100% - 48px);padding:6px 0}.message-row.detail-only{padding:6px 0}.message-content{min-width:0;max-width:min(78%,620px)}.message-row.assistant .message-content{width:100%;max-width:none}.message-body{color:oklch(28% .018 249);overflow-wrap:anywhere;white-space:pre-wrap;font-size:14px;line-height:1.7}.message-row.user .message-body{background:var(--sidebar-active);border-radius:18px;padding:9px 15px;box-shadow:inset 0 0 0 1px oklch(72% .06 85/.2)}.markdown{color:oklch(28% .018 249);overflow-wrap:anywhere;font-size:14px;line-height:1.7}.markdown>:first-child{margin-top:0}.markdown>:last-child{margin-bottom:0}.markdown p{margin:0 0 12px}.markdown h1,.markdown h2,.markdown h3,.markdown h4{color:var(--text);margin:18px 0 8px;font-weight:650;line-height:1.3}.markdown h1{font-size:1.45em}.markdown h2{font-size:1.3em}.markdown h3{font-size:1.15em}.markdown ul,.markdown ol{margin:0 0 12px;padding-left:24px}.markdown li+li{margin-top:4px}.markdown blockquote{border:1px solid var(--border-strong);color:var(--muted);background:oklch(97% .006 249);border-radius:6px;margin:0 0 12px;padding:8px 14px}.markdown hr{border:0;border-top:1px solid var(--border);margin:18px 0}.markdown a{color:var(--accent);text-underline-offset:2px;-webkit-text-decoration:underline oklch(51.6% .151 253/.35);text-decoration:underline oklch(51.6% .151 253/.35)}.markdown code{color:oklch(35% .02 249);background:oklch(95.5% .008 249);border:1px solid oklch(86.8% .014 248/.55);border-radius:5px;padding:2px 5px;font:.9em ui-monospace,SFMono-Regular,Menlo,monospace}.markdown pre{border:1px solid var(--border);background:oklch(96.8% .006 249/.9);border-radius:8px;margin:0 0 14px;padding:12px 14px;overflow-x:auto}.markdown pre code{color:var(--text);white-space:pre;background:0 0;border:0;padding:0;font-size:12px}.markdown table{border-collapse:collapse;width:100%;margin:0 0 14px;font-size:.95em}.markdown th,.markdown td{border:1px solid var(--border);text-align:left;vertical-align:top;padding:7px 9px}.markdown th{background:oklch(96% .007 249);font-weight:650}.markdown input[type=checkbox]{accent-color:var(--accent);margin-right:7px}.message-details{width:min(820px,100% - 4px);color:var(--muted);margin:4px auto}.message-details summary{min-height:calc(var(--spacing-1) * 9);align-items:center;gap:calc(var(--spacing-1) * 2);cursor:pointer;border-radius:7px;padding:5px 8px;font-size:12.5px;list-style:none;display:flex}.message-details summary::-webkit-details-marker{display:none}.tool-group summary::-webkit-details-marker{display:none}.message-details summary:hover{color:var(--text);background:oklch(95% .008 249/.72)}.details-mark{border-bottom:1.5px solid;border-right:1.5px solid;flex:none;width:8px;height:8px;transition:transform .14s;transform:rotate(-45deg)}.message-details[open] .details-mark,.tool-group[open]>summary .details-mark{transform:rotate(45deg)}.details-body{color:oklch(42% .018 249);white-space:pre-wrap;overflow-wrap:anywhere;margin:2px 8px 9px 38px;font-size:12px;line-height:1.6}.tool-icon{background:oklch(55% .02 249/.1);border-radius:6px;flex-shrink:0;place-items:center;width:22px;height:22px;display:grid}.tool-icon svg{width:13px;height:13px}.details-title{align-items:baseline;gap:calc(var(--spacing-1) * 2);flex:1;min-width:0;display:flex}.tool-name{color:var(--text);flex-shrink:0;font-size:12.5px;font-weight:600}.tool-summary{text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--muted);font:11.5px ui-monospace,SFMono-Regular,Menlo,monospace;overflow:hidden}.tool-evidence{border:1px solid var(--border);background:oklch(97% .006 249/.75);border-radius:6px;max-height:440px;padding:9px 10px;overflow:auto}.status-mark{flex-shrink:0;width:14px;height:14px}.status-mark.done{color:var(--healthy)}.status-mark.error{color:var(--error)}.status-mark.warn{color:var(--warning)}.status-mark.running{justify-content:center;align-items:center;display:flex}.status-mark.running i,.activity-chip-dot,.conversation-running-dot{background:var(--accent);border-radius:50%;width:7px;height:7px;animation:1.5s ease-out infinite conversation-pulse}.tool-line.error .tool-icon{color:var(--error);background:oklch(50% .18 28/.09)}.tool-line-empty{min-height:calc(var(--spacing-1) * 8);align-items:center;gap:calc(var(--spacing-1) * 2);color:var(--muted);padding:3px 8px;display:flex}.tool-group{border:1px solid var(--border);width:min(820px,100% - 48px);color:var(--muted);background:oklch(99% .004 249/.5);border-radius:8px;margin:6px auto;overflow:hidden}.tool-group>summary{min-height:calc(var(--spacing-1) * 9);align-items:center;gap:calc(var(--spacing-1) * 2);cursor:pointer;padding:5px 10px;font-size:12.5px;list-style:none;display:flex}.tool-group>summary:hover{background:oklch(95% .008 249/.72)}.tool-group-icons{align-items:center;gap:var(--spacing-1);display:flex}.tool-group-icons svg{width:13px;height:13px}.tool-group-body{border-top:1px solid var(--border);padding:4px 10px}.tool-group-body .message-row{width:100%;padding:0}.activity-card{border:1px solid var(--border);background:oklch(99% .004 249/.6);border-radius:8px;overflow:hidden}.activity-card summary{min-height:44px;padding:7px 10px}.activity-card .details-mark{order:3}.activity-icon{border-radius:7px;flex-shrink:0;place-items:center;width:28px;height:28px;display:grid}.activity-icon svg{width:16px;height:16px}.activity-card.subagent .activity-icon{color:var(--accent);background:oklch(52% .15 253/.1)}.activity-card.workflow .activity-icon{color:oklch(55% .09 310);background:oklch(55% .09 310/.12)}.activity-main{flex-direction:column;flex:1;gap:1px;min-width:0;display:flex}.activity-title,.activity-meta{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.activity-title{color:var(--text);font-weight:550}.activity-meta{color:var(--subtle);font-size:11px}.activity-card .details-body{margin-left:48px}.activity-bar{gap:calc(var(--spacing-1) * 1.5);flex-wrap:wrap;width:100%;max-width:840px;margin-inline:auto;padding:0 15px 2px;display:flex}.activity-chip{align-items:center;gap:calc(var(--spacing-1) * 1.5);border:1px solid var(--border);min-width:0;max-width:320px;color:var(--muted);background:oklch(99% .004 249/.78);border-radius:999px;padding:3px 10px;font-size:11.5px;display:flex}.activity-chip>svg{width:12px;height:12px}.activity-chip-text{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.activity-chip.more{color:var(--subtle)}.activity-chip.done>svg{color:var(--healthy)}.activity-chip.error>svg{color:var(--error)}.conversation-running{align-items:center;gap:calc(var(--spacing-1) * 2);width:min(840px,100% - 48px);color:var(--muted);margin-inline:auto;margin-bottom:18px;font-size:12px;display:flex}@keyframes conversation-pulse{70%{box-shadow:0 0 0 6px oklch(52% .15 253/0)}to{box-shadow:0 0 oklch(52% .15 253/0)}}.switching{align-items:center;display:flex}.message-actions{margin-top:var(--spacing-1);height:calc(var(--spacing-1) * 6);justify-content:flex-end;align-items:center;gap:var(--spacing-1);color:var(--subtle);opacity:0;font-size:10.5px;transition:opacity .12s;display:flex}.message-row:hover>.message-actions,.message-row:focus-within>.message-actions{opacity:1}.message-actions button{width:calc(var(--spacing-1) * 6);height:calc(var(--spacing-1) * 6);border-style:var(--tw-border-style);background-color:#0000;border-width:0;border-radius:5px;place-items:center;display:grid}.message-actions button:hover{color:var(--text);background:oklch(95% .008 249)}.message-actions svg{width:13px;height:13px}.message-editor{width:min(100%,620px);margin-left:auto}.message-editor textarea{resize:vertical;border:1px solid var(--border-strong);background:var(--page);border-radius:14px;outline:0;width:100%;min-height:52px;max-height:220px;padding:10px 14px}.message-edit-actions{margin-top:calc(var(--spacing-1) * 2);justify-content:flex-end;gap:calc(var(--spacing-1) * 2);display:flex}.message-edit-actions button{border:1px solid var(--border-strong);background:var(--page);border-radius:15px;height:30px;padding:0 14px;font-size:12.5px}.message-edit-actions .confirm{border-color:var(--text);background:var(--text);color:var(--page)}.turn-rail{z-index:10;gap:calc(var(--spacing-1) * .5);border:1px solid #0000;border-radius:8px;flex-direction:column;width:16px;max-height:70%;padding:4px 2px;transition:width .16s,background-color .16s,border-color .16s;display:flex;position:absolute;top:50%;right:24px;overflow-y:auto;transform:translateY(-50%)}.turn-rail:hover,.turn-rail:focus-within{border-color:var(--border);-webkit-backdrop-filter:blur(8px);backdrop-filter:blur(8px);background:oklch(99% .004 249/.92);width:240px;padding:6px;box-shadow:0 12px 28px oklch(26% .02 249/.14)}.turn-tick{align-items:center;gap:calc(var(--spacing-1) * 2);border-style:var(--tw-border-style);background-color:#0000;border-width:0;border-radius:6px;width:100%;padding:3px 4px;display:flex}.turn-tick:hover{background:oklch(95% .008 249)}.turn-tick-mark{background:var(--subtle);border-radius:1px;flex:none;width:8px;height:2px}.turn-tick-label{text-align:left;text-overflow:ellipsis;white-space:nowrap;min-width:0;color:var(--muted);font-size:12px;display:none;overflow:hidden}.turn-rail:hover .turn-tick-label,.turn-rail:focus-within .turn-tick-label{display:block}@container conversation-shell (width<=960px){.turn-rail{display:none}}.composer-dock{align-items:center;gap:calc(var(--spacing-1) * 2);flex-direction:column;padding:12px 24px 22px;display:flex}.landing .composer-dock{z-index:10;inset-inline:0;align-items:stretch;width:100%;padding:0 24px;position:absolute;top:calc(50% - 81px)}.workspace-picker-row{align-items:center;width:100%;min-width:0;max-width:840px;margin-inline:auto;padding-left:15px;display:flex;position:relative}.workspace-picker{max-width:260px!important;height:36px!important;color:var(--text)!important;box-shadow:none!important;background:0 0!important;border-radius:18px!important}.workspace-picker:hover,.workspace-picker[aria-expanded=true]{background:var(--sidebar-active)!important}.workspace-picker svg{width:15px;height:15px}.composer{border:1px solid var(--border-strong);background:var(--page);border-radius:18px;flex-direction:column;width:100%;max-width:840px;min-height:118px;margin-inline:auto;padding:13px 13px 10px;transition:border-color .16s,box-shadow .16s;display:flex;position:relative;box-shadow:0 8px 26px oklch(42% .06 251/.1)}.dormant-overlay{z-index:10;border-style:var(--tw-border-style);background-color:#0000;border-width:0;border-radius:18px;position:absolute;inset:0}.composer:focus-within{border-color:oklch(84% .04 87);box-shadow:0 0 0 2px oklch(84% .04 87/.28),0 8px 26px oklch(40% .04 87/.1)}.composer.dormant{box-shadow:none;cursor:pointer;border-style:dashed}.composer.dormant:hover{border-color:oklch(66% .018 249)}.composer textarea{border-style:var(--tw-border-style);outline-style:var(--tw-outline-style);resize:none;width:100%;min-width:0;min-height:52px;max-height:220px;color:var(--text);background-color:#0000;border-width:0;outline-width:0;flex:none;padding:0 2px;font-size:14px;line-height:1.55}.composer textarea::placeholder{color:var(--subtle)}.composer-toolbar{margin-top:calc(var(--spacing-1) * 2);justify-content:flex-end;align-items:center;gap:calc(var(--spacing-1) * 2);min-width:0;display:flex}.model-picker-wrap{min-width:0;max-width:48%}.model-picker{min-width:150px!important;max-width:100%!important;height:34px!important;color:var(--muted)!important;box-shadow:none!important;background:0 0!important;padding:0 9px 0 10px!important}.model-picker:hover,.model-picker[aria-expanded=true]{color:var(--text)!important;background:oklch(97% .006 249)!important}.model-picker svg{width:14px;height:14px}.send-button{border-style:var(--tw-border-style);background:var(--sidebar);border-width:0;border-radius:50%;flex-shrink:0;place-items:center;width:34px;height:34px;transition:background-color .14s,transform .1s;display:grid}.send-button:hover:not(:disabled){background:var(--sidebar-hover)}.send-button:active:not(:disabled){transform:scale(.92)}.send-button:disabled{color:var(--subtle);opacity:.65}.send-button svg{width:17px;height:17px}.composer-hint{display:none}.notice{bottom:calc(var(--spacing-1) * 4);z-index:40;max-width:var(--container-xl);--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y);align-items:center;gap:calc(var(--spacing-1) * 3);background:var(--page);color:var(--error);border:1px solid oklch(70% .11 28);border-radius:6px;padding:9px 10px 9px 14px;font-size:12px;display:flex;position:absolute;left:50%;box-shadow:0 12px 32px oklch(26% .02 249/.18)}.notice button{width:calc(var(--spacing-1) * 6);height:calc(var(--spacing-1) * 6);border-style:var(--tw-border-style);background-color:#0000;border-width:0;place-items:center;display:grid}.notice svg{width:14px;height:14px}.mobile-header{display:none}.connection-state{align-items:center;gap:calc(var(--spacing-1) * 1.5);color:var(--healthy);font-size:11px}.connection-state:before{content:"";background:currentColor;border-radius:50%;width:6px;height:6px}.connection-state.reconnecting{color:var(--warning)}.connection-state.unavailable{color:var(--error)}.sidebar-scrim{display:none}.openpi-dialog{gap:calc(var(--spacing-1) * 4);color:var(--text);padding:20px;display:grid}.openpi-dialog strong{font-size:15px;font-weight:650}.openpi-dialog p{color:var(--muted);margin:0;font-size:13px;line-height:1.65}.openpi-dialog input{border:1px solid var(--border-strong);background:var(--page);border-radius:5px;width:100%;height:38px;padding:0 10px}.dialog-actions{justify-content:flex-end;gap:calc(var(--spacing-1) * 2);display:flex}.dialog-actions button{border:1px solid var(--border-strong);background:var(--page);border-radius:5px;height:34px;padding:0 13px}.dialog-actions .primary{border-color:var(--text);background:var(--text);color:var(--page)}.dialog-actions .danger{color:var(--error);border-color:oklch(80% .08 28)}@media (width<=760px){.app-shell,.app-shell.sidebar-collapsed{grid-template-columns:1fr}.session-sidebar{border-right:1px solid var(--border);background:var(--sidebar);-webkit-backdrop-filter:none;backdrop-filter:none;width:min(86vw,300px);transition:transform .18s;position:fixed;inset:0 auto 0 0;transform:translate(-100%)}.session-sidebar:before{display:none}.sidebar-open .session-sidebar{transform:translate(0)}.sidebar-collapsed .session-sidebar{align-items:stretch;padding:8px 10px}.sidebar-collapsed .sidebar-brand,.sidebar-collapsed .workspace-heading,.sidebar-collapsed .workspace-tree{visibility:visible}.sidebar-collapsed .new-session-button{border-color:var(--border-strong);background:var(--page);width:calc(100% - 4px);height:38px;margin:8px 2px 10px}.sidebar-collapsed .new-session-button span{display:initial}.sidebar-expand{display:none}.sidebar-scrim{z-index:10;border-style:var(--tw-border-style);background:oklch(20% .02 249/.28);border-width:0;position:fixed;inset:0}.sidebar-open .sidebar-scrim{display:block}.mobile-header{pointer-events:none;z-index:10;display:block;position:absolute;inset:0}.mobile-header>button{pointer-events:auto;top:calc(var(--spacing-1) * 3);left:calc(var(--spacing-1) * 3);border-style:var(--tw-border-style);background:oklch(99% .004 249/.88);border-width:0;border-radius:6px;place-items:center;width:34px;height:34px;display:grid;position:fixed}.mobile-header>button svg{width:19px;height:19px}.mobile-header .connection-state{top:calc(var(--spacing-1) * 4);right:calc(var(--spacing-1) * 3);font-size:0;display:flex;position:absolute}.message-row{width:calc(100% - 28px)}.message-row.assistant,.conversation-running{width:calc(100% - 24px)}.turn-rail{display:none}.composer-dock{padding:10px 12px 12px}.landing .composer-dock{padding:0 12px;top:calc(50% - 74px)}.landing-welcome{transform:translateY(-96px)}.composer{min-height:104px}.notice{width:calc(100% - 24px);bottom:12px}}@media (any-pointer:coarse){.session-row>.astryx-menu-trigger{opacity:1;pointer-events:auto}.session-row .session-time{visibility:hidden}.message-actions{opacity:1}}@media (prefers-reduced-motion:reduce){.app-shell,.session-sidebar,.workspace-chevron,.message-actions,.turn-rail,.details-mark{transition:none}.conversation{scroll-behavior:auto}.landing-brand .brand-lockup,.landing-brand .brand-word,.landing-brand .pixel-mark,.landing-brand .pixel-mark i,.landing-brand .pixel-mark i:after{animation:none}.landing-brand .brand-word{opacity:1}.landing-brand .pixel-mark i{background-color:currentColor}.landing-brand .pixel-mark i:after{opacity:0}.status-mark.running i,.activity-chip-dot,.conversation-running-dot{animation:none}}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@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} +/*$vite$:1*/ \ No newline at end of file diff --git a/web/host/static-assets.ts b/web/host/static-assets.ts deleted file mode 100644 index 6d9947e4..00000000 --- a/web/host/static-assets.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const MARKED_BROWSER_URL = new URL( - "./lib/marked.umd.js", - import.meta.resolve("marked/package.json"), -); diff --git a/web/host/web-host.ts b/web/host/web-host.ts index 6203e647..9256b002 100644 --- a/web/host/web-host.ts +++ b/web/host/web-host.ts @@ -25,10 +25,9 @@ import { type WebRuntimeController, } from "../runtime/types.ts"; import { elapsed, traceWeb } from "../trace.ts"; -import { MARKED_BROWSER_URL } from "./static-assets.ts"; const HOST = "127.0.0.1"; -const UI_ROOT = new URL("../ui/", import.meta.url); +const UI_ROOT = new URL("../dist/", import.meta.url); const MAX_COMMAND_BYTES = 16 * 1024; const MAX_SSE_CLIENTS = 8; const MAX_SSE_BUFFER_BYTES = 256 * 1024; @@ -314,22 +313,20 @@ export class WebHost { if ( url.pathname === "/styles.css" || url.pathname === "/app.js" || - url.pathname === "/marked.js" + url.pathname === "/favicon.svg" ) { if (request.method !== "GET") return this.json(response, 405, { error: "static assets accept GET only", }); const file = url.pathname.slice(1); - const body = await readFile( - file === "marked.js" - ? MARKED_BROWSER_URL - : new URL(file, UI_ROOT), - ); + const body = await readFile(new URL(file, UI_ROOT)); response.writeHead(200, { "Content-Type": file.endsWith(".css") ? "text/css; charset=utf-8" - : "text/javascript; charset=utf-8", + : file.endsWith(".svg") + ? "image/svg+xml; charset=utf-8" + : "text/javascript; charset=utf-8", "Cache-Control": "no-store", }); response.end(body); diff --git a/web/ui/app.js b/web/ui/app.js deleted file mode 100644 index bcff449d..00000000 --- a/web/ui/app.js +++ /dev/null @@ -1,1398 +0,0 @@ -const collapsedWorkspacesStorageKey = "openpi.collapsed-workspaces"; -function readCollapsedWorkspaces() { - try { - const value = JSON.parse(sessionStorage.getItem(collapsedWorkspacesStorageKey) || "[]"); - return new Set(Array.isArray(value) ? value.filter((path) => typeof path === "string") : []); - } catch { - return new Set(); - } -} - -function persistCollapsedWorkspaces(collapsed) { - try { sessionStorage.setItem(collapsedWorkspacesStorageKey, JSON.stringify([...collapsed])); } catch {} -} - -const state = { - snapshot: null, - cursor: null, - selectedPath: null, - collapsed: readCollapsedWorkspaces(), - liveMessages: [], - liveRunning: false, - promptAdmissionPending: false, - promptAdmissionToken: null, - promptAdmissionSequence: 0, - terminalPromptIds: new Set(), - sessionEpoch: 0, - sessionSwitching: false, - sessionActivation: null, - completedActivationIds: new Set(), - snapshotGeneration: 0, - livePhase: "idle", - liveRetry: null, - query: "", - selectedWorkspace: null, - language: navigator.language?.toLowerCase().startsWith("zh") ? "zh" : "en", -}; - -const translations = { - en: { - newSession: "New session", - untitledSession: "New session", - workspaces: "Workspaces", - addWorkspace: "Add workspace", - selectWorkspace: "Select workspace", - describeTask: "Describe a task", - chooseWorkspaceHint: "Choose a workspace and describe the work", - promptStart: "Choose a workspace to begin.", - promptTask: "Describe what you want to build.", - promptMessage: "Send a message to the active Web session", - promptReadonly: "A non-active session cannot receive prompts", - searchConversations: "Search conversations", - closeSearch: "Close search", - searchPlaceholder: "Search conversations...", - noSessions: "No sessions", - noMatching: "No matching conversations", - noConversations: "No conversations yet", - addWorkspaceMenu: "Add workspace...", - renameConversation: "Rename conversation", - archiveConversation: "Archive conversation", - deleteWorkspace: "Delete workspace", - cancel: "Cancel", - workspaceDeleteConfirm: "The folder and conversation records will be kept. Its conversations will move to Ungrouped.", - ungrouped: "Ungrouped", - conversationName: "Conversation name", - conversationOptions: "Conversation options", - queuedHint: "The message will be queued after the current turn.", - enterHint: "Enter to send, Shift+Enter for a new line.", - activeOnlyHint: "Only the active Web session accepts messages.", - acceptedHint: "Message accepted by OpenPI Web.", - modelRunning: "Working...", - modelPreparing: "Preparing task...", - modelRetrying: "Retrying model request...", - switchingSession: "Switching session...", - }, - zh: { - newSession: "新建会话", - untitledSession: "新会话", - workspaces: "工作区", - addWorkspace: "添加工作区", - selectWorkspace: "选择工作区", - describeTask: "描述任务", - chooseWorkspaceHint: "选择工作区并描述任务", - promptStart: "选择一个工作区开始", - promptTask: "描述你想要构建的任务", - promptMessage: "向当前 Web 会话发送消息", - promptReadonly: "非当前会话不能接收消息", - searchConversations: "搜索会话", - closeSearch: "关闭搜索", - searchPlaceholder: "搜索会话...", - noSessions: "暂无会话", - noMatching: "没有匹配的会话", - noConversations: "暂无对话", - addWorkspaceMenu: "添加工作区...", - renameConversation: "重命名会话", - archiveConversation: "归档会话", - deleteWorkspace: "删除工作区", - cancel: "取消", - workspaceDeleteConfirm: "文件夹与会话记录会保留,其中的会话会被放到“未分组”;再次打开此目录时将是一个干净的工作区。", - ungrouped: "未分组", - conversationName: "会话名称", - conversationOptions: "会话选项", - queuedHint: "当前回合结束后将发送消息。", - enterHint: "按 Enter 发送,Shift+Enter 换行。", - activeOnlyHint: "只有当前 Web 会话可以接收消息。", - acceptedHint: "OpenPI Web 已接收消息。", - modelRunning: "正在运行...", - modelPreparing: "正在准备任务...", - modelRetrying: "模型请求重试中...", - switchingSession: "正在切换会话...", - }, -}; -const t = (key) => translations[state.language][key] || translations.en[key] || key; -function applyLanguage() { - document.documentElement.lang = state.language === "zh" ? "zh-CN" : "en"; - document.querySelectorAll("[data-i18n]").forEach((element) => { element.textContent = t(element.dataset.i18n); }); - document.querySelectorAll("[data-i18n-placeholder]").forEach((element) => { element.placeholder = t(element.dataset.i18nPlaceholder); }); - document.querySelectorAll("[data-i18n-aria]").forEach((element) => { element.setAttribute("aria-label", t(element.dataset.i18nAria)); }); - document.querySelectorAll("[data-i18n-title]").forEach((element) => { element.title = t(element.dataset.i18nTitle); }); - const search = $("search"); - if (search) search.placeholder = t("searchPlaceholder"); - renderWorkspacePicker(); - if (state.snapshot) { - renderWorkspaces(); - renderConversation(); - } -} - -const $ = (id) => document.getElementById(id); -const tokenStorageKey = "openpi.web.token"; -const fragmentToken = new URLSearchParams(location.hash.slice(1)).get("token"); -let token = fragmentToken; -if (fragmentToken) { - try { sessionStorage.setItem(tokenStorageKey, fragmentToken); } catch {} - history.replaceState(null, "", `${location.pathname}${location.search}`); -} else { - try { token = sessionStorage.getItem(tokenStorageKey); } catch {} -} -const headers = (json = false) => ({ - Authorization: `Bearer ${token}`, - ...(json ? { "Content-Type": "application/json" } : {}), -}); -const escapeHtml = (value) => - String(value ?? "").replace( - /[&<>"']/g, - (char) => - ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" })[ - char - ], - ); - -const markdownRenderer = (() => { - const markdown = globalThis.marked; - if (!markdown?.Renderer) return null; - const renderer = new markdown.Renderer(); - renderer.html = ({ text }) => escapeHtml(text); - renderer.link = ({ href, title, tokens }) => { - const safeHref = safeMarkdownUrl(href); - const label = renderer.parser.parseInline(tokens); - if (!safeHref) return label; - const titleAttribute = title ? ` title="${escapeHtml(title)}"` : ""; - return `${label}`; - }; - renderer.image = ({ href, title, text, tokens }) => { - const safeHref = safeMarkdownUrl(href); - const alt = tokens ? renderer.parser.parseInline(tokens, renderer.parser.textRenderer) : text; - if (!safeHref) return escapeHtml(alt); - const titleAttribute = title ? ` title="${escapeHtml(title)}"` : ""; - const label = escapeHtml(alt || "image"); - return `[image: ${label}]`; - }; - return renderer; -})(); - -function safeMarkdownUrl(value) { - try { - const url = new URL(String(value ?? ""), document.baseURI); - const allowedProtocols = ["http:", "https:", "mailto:", "tel:"]; - return allowedProtocols.includes(url.protocol) ? url.href : null; - } catch { - return null; - } -} - -function renderMarkdown(value) { - const content = String(value ?? ""); - if (!markdownRenderer || !globalThis.marked?.parse) return escapeHtml(content); - try { - return globalThis.marked.parse(content, { - renderer: markdownRenderer, - gfm: true, - breaks: true, - }); - } catch { - return escapeHtml(content); - } -} - -async function api(path, options = {}) { - const response = await fetch(path, { - ...options, - headers: { ...headers(Boolean(options.body)), ...options.headers }, - }); - const body = await response.json().catch(() => ({})); - if (!response.ok) throw new Error(body.error || `Request failed (${response.status})`); - return body; -} - -function sessionTitle(session) { - return session.name?.trim() || session.firstMessage?.trim() || t("untitledSession"); -} - -function compactSummary(value, limit = 96) { - const text = String(value ?? "").replace(/\s+/gu, " ").trim(); - return text.length > limit ? `${text.slice(0, limit - 1)}…` : text; -} - -function relativeTime(value) { - const elapsed = Date.now() - new Date(value).getTime(); - if (elapsed < 60_000) return "now"; - if (elapsed < 3_600_000) return `${Math.floor(elapsed / 60_000)}m`; - if (elapsed < 86_400_000) return `${Math.floor(elapsed / 3_600_000)}h`; - return new Date(value).toLocaleDateString(undefined, { month: "short", day: "numeric" }); -} - -function visibleSessions(workspacePath) { - const query = state.query.toLowerCase(); - return state.snapshot.sessions.filter( - (session) => - session.cwd === workspacePath && - !session.ungrouped && - !session.archived && - (!query || - [sessionTitle(session), session.cwd] - .join(" ") - .toLowerCase() - .includes(query)), - ); -} - -function visibleUngroupedSessions() { - const query = state.query.toLowerCase(); - return state.snapshot.sessions.filter( - (session) => - session.ungrouped && - !session.archived && - (!query || - [sessionTitle(session), session.cwd] - .join(" ") - .toLowerCase() - .includes(query)), - ); -} - -const ICONS = { - folder: '', - chevronDown: '', - plus: '', - more: '', -}; - -function icon(name, className = "icon") { - return ``; -} - -function renderWorkspaces() { - if (!state.snapshot) return; - const groups = state.snapshot.workspaces - .map((workspace) => { - const sessions = visibleSessions(workspace.path); - if (state.query && sessions.length === 0) return ""; - const collapsed = state.collapsed.has(workspace.path); - return `
-
- - ${escapeHtml(workspace.name)} - - - - -
-
- ${ - sessions.length - ? sessions - .map( - (session) => `
- - -
`, - ) - .join("") - : `
${escapeHtml(t("noConversations"))}
` - } -
-
`; - }) - .join(""); - const ungrouped = visibleUngroupedSessions(); - const ungroupedGroup = ungrouped.length - ? `
-
- - ${escapeHtml(t("ungrouped"))} -
-
${ungrouped.map((session) => `
- - -
`).join("")}
-
` - : ""; - $("workspaces").innerHTML = groups + ungroupedGroup || `
${escapeHtml(state.query ? t("noMatching") : t("noSessions"))}
`; - - document.querySelectorAll(".workspace-toggle").forEach((button) => { - button.onclick = (event) => { - event.stopPropagation(); - toggleWorkspace(button.closest(".workspace-group").dataset.workspace); - }; - }); - document.querySelectorAll(".workspace-button").forEach((button) => { - button.onclick = () => toggleWorkspace(button.closest(".workspace-group").dataset.workspace); - }); - document.querySelectorAll(".workspace-action").forEach((button) => { - button.onclick = (event) => { - event.stopPropagation(); - const path = button.closest(".workspace-group").dataset.workspace; - if (button.dataset.workspaceAction === "new") void createSession(path); - else openWorkspaceMenu(path, button); - }; - }); - document.querySelectorAll(".session").forEach((button) => { - button.onclick = () => void selectSession(button.dataset.session); - }); - document.querySelectorAll(".session-action").forEach((button) => { - button.onclick = (event) => { - event.stopPropagation(); - openSessionMenu(button.dataset.sessionPath, button); - }; - }); -} - -function messageMarkup(entry) { - const message = entry.message; - if (!message) return ""; - if (message.role === "user") { - return `
-
${escapeHtml(message.content)}
-
`; - } - if (message.role === "assistant") { - const parts = Array.isArray(message.parts) ? message.parts : []; - const detailItems = parts - .filter((part) => part.type === "thinking" || part.type === "toolCall") - .map((part) => { - const title = part.type === "thinking" ? "Thinking" : `${part.name} · tool call`; - const body = part.type === "thinking" ? part.text : part.arguments; - return `
- ${escapeHtml(title)} -
${escapeHtml(body)}
-
`; - }); - const detailRows = detailItems - .map( - (detail) => `
-
${detail}
-
`, - ) - .join(""); - const content = typeof message.content === "string" ? message.content.trim() : ""; - const contentRow = content - ? `
-
${renderMarkdown(content)}
-
` - : ""; - return detailRows + contentRow; - } - if (message.role === "toolResult") { - const toolName = message.toolName || "tool"; - const summary = compactSummary(message.content || "completed"); - return `
-
- ${escapeHtml(toolName)} · ${escapeHtml(summary)} -
${escapeHtml(message.content || "completed")}
-
-
`; - } - return ""; -} - -function landingMarkup() { - return `
-
Open
-
`; -} - -function runtimeActivityMarkup(capabilities) { - const labels = { - subagents: "Subagent", - workflows: "Workflow", - "background-terminals": "Terminal", - }; - const rows = Object.entries(capabilities || {}).flatMap(([kind, projection]) => { - const items = Array.isArray(projection?.items) ? projection.items : []; - const projected = items.map((item) => { - const title = item.title || item.name || item.id || item.runId || labels[kind] || kind; - const status = typeof item.status === "string" ? item.status : "unknown"; - return `
  • ${escapeHtml(labels[kind] || kind)}${escapeHtml(title)}${escapeHtml(status)}
  • `; - }); - if (Number.isSafeInteger(projection?.omitted) && projection.omitted > 0) { - projected.push(`
  • ${escapeHtml(labels[kind] || kind)}+${projection.omitted} omitted
  • `); - } - return projected; - }); - return rows.length > 0 - ? `` - : ""; -} - -function renderConversation() { - const snapshot = state.snapshot; - const selected = snapshot?.selectedSession; - const shell = document.querySelector(".conversation-shell"); - if (!shell) { - updateComposer(); - return; - } - const summary = snapshot?.sessions.find((session) => session.path === state.selectedPath); - if (state.sessionSwitching) { - shell.classList.remove("landing"); - $("session-header").innerHTML = `${escapeHtml(summary ? sessionTitle(summary) : t("newSession"))}${escapeHtml(t("switchingSession"))}`; - $("conversation").innerHTML = `
    ${escapeHtml(t("switchingSession"))}
    `; - updateComposer(); - return; - } - const persistedEntries = selected?.entries || []; - const persistedMessageKeys = new Set( - persistedEntries.map((entry) => `${entry.message?.role || ""}:${entry.message?.content || ""}`), - ); - const liveEntries = selected - ? state.liveMessages - .filter(({ message }) => !persistedMessageKeys.has(`${message.role || ""}:${message.content || ""}`)) - .map(({ message }) => messageMarkup({ type: "message", message })) - : []; - const messages = selected - ? [...persistedEntries.map(messageMarkup).filter(Boolean), ...liveEntries].join("") - : ""; - const landing = !selected || !summary || !messages; - shell.classList.toggle("landing", landing); - - if (landing) { - $("conversation").innerHTML = landingMarkup(); - $("session-header").innerHTML = `${escapeHtml(t("newSession"))}${escapeHtml(t("chooseWorkspaceHint"))}`; - updateComposer(); - return; - } - - $("session-header").innerHTML = `${escapeHtml(sessionTitle(summary))}${escapeHtml(selected.cwd)}`; - const isCurrentSession = selected.id === snapshot.currentSessionId; - const isRunning = isCurrentSession && (snapshot.runtime.status === "running" || state.liveRunning); - const runningLabel = state.liveRetry - ? `${t("modelRetrying")} (${state.liveRetry.attempt}/${state.liveRetry.maxAttempts})` - : state.livePhase === "preparing" ? t("modelPreparing") : t("modelRunning"); - const activity = isCurrentSession - ? runtimeActivityMarkup(snapshot.runtime.capabilities) - : ""; - $("conversation").innerHTML = `${messages}${activity}${isRunning ? `
    ${escapeHtml(runningLabel)}
    ` : ""}`; - $("conversation").scrollTop = $("conversation").scrollHeight; - updateComposer(); -} - -function updateComposer() { - const selected = state.snapshot?.selectedSession; - const active = selected?.id === state.snapshot?.currentSessionId; - const newSessionDraft = - Boolean(state.selectedWorkspace) && - !selected && - !state.snapshot?.currentSessionId; - const canCompose = active || newSessionDraft; - $("prompt-input").disabled = - state.sessionSwitching || (!canCompose && Boolean(state.selectedWorkspace)); - $("send-prompt").disabled = - state.sessionSwitching || - !canCompose || - !state.selectedWorkspace || - state.promptAdmissionPending; - const modelPicker = $("model-picker"); - const modelPickerValue = $("model-picker-value"); - const modelMenu = $("model-menu"); - const models = state.snapshot?.models || []; - if (modelPicker && models.length > 0) { - const current = models.find((model) => model.current) || models[0]; - if (modelPickerValue) modelPickerValue.textContent = current.label; - if (modelMenu) { - modelMenu.innerHTML = models - .map((model) => ``) - .join(""); - modelMenu.querySelectorAll("[data-model]").forEach((option) => { - option.onclick = () => { - modelMenu.hidden = true; - modelPicker.setAttribute("aria-expanded", "false"); - void selectModel(option.dataset.model); - }; - }); - } - modelPicker.disabled = - state.sessionSwitching || - !active || - !state.selectedWorkspace || - state.liveRunning; - } else if (modelPicker) { - if (modelPickerValue) modelPickerValue.textContent = "No models available"; - if (modelMenu) modelMenu.innerHTML = ""; - modelPicker.disabled = true; - } - const shell = document.querySelector(".conversation-shell"); - const landing = !shell || shell.classList.contains("landing"); - $("prompt-input").placeholder = !state.selectedWorkspace - ? t("promptStart") - : landing - ? t("promptTask") - : active - ? t("promptMessage") - : t("promptReadonly"); - $("composer-hint").textContent = canCompose - ? state.snapshot.runtime.status === "running" || state.liveRunning - ? t("queuedHint") - : t("enterHint") - : t("activeOnlyHint"); -} - -async function selectModel(value) { - const [provider, ...idParts] = value.split("/"); - const modelId = idParts.join("/"); - if (!provider || !modelId) return; - const epoch = state.sessionEpoch; - const sessionId = state.snapshot?.selectedSession?.id; - if (!sessionId || state.sessionSwitching) return; - const picker = $("model-picker"); - if (picker) picker.disabled = true; - try { - await api("/api/model", { - method: "POST", - body: JSON.stringify({ provider, modelId, sessionId }), - }); - if ( - epoch !== state.sessionEpoch || - sessionId !== state.snapshot?.selectedSession?.id - ) return; - await refreshSnapshot({ epoch }); - } catch (error) { - if ( - epoch !== state.sessionEpoch || - sessionId !== state.snapshot?.selectedSession?.id - ) return; - showNotice(error.message); - await refreshSnapshot({ epoch }); - } -} - -async function refreshSnapshot({ - resetCursor = false, - epoch = state.sessionEpoch, - canonicalRetry = false, -} = {}) { - const generation = ++state.snapshotGeneration; - try { - const requestedPath = state.selectedPath; - const suffix = requestedPath - ? `?path=${encodeURIComponent(requestedPath)}` - : ""; - const snapshot = await api(`/api/snapshot${suffix}`); - if ( - epoch !== state.sessionEpoch || - generation !== state.snapshotGeneration - ) return false; - const hasCurrentSession = typeof snapshot.currentSessionId === "string"; - const current = hasCurrentSession - ? snapshot.sessions.find( - (session) => session.id === snapshot.currentSessionId, - ) - : undefined; - const selectedIsCurrent = hasCurrentSession - ? snapshot.selectedSession?.id === snapshot.currentSessionId - : snapshot.selectedSession === undefined; - const requestedExists = - !requestedPath || - snapshot.sessions.some((session) => session.path === requestedPath); - const requestedMatches = - !requestedPath || snapshot.selectedSession?.path === requestedPath; - if (!requestedExists || !requestedMatches || !selectedIsCurrent) { - state.selectedPath = null; - if (!canonicalRetry) { - return refreshSnapshot({ - resetCursor, - epoch, - canonicalRetry: true, - }); - } - return false; - } - state.snapshot = snapshot; - if ( - state.snapshot.runtime.status !== "running" && - !state.promptAdmissionPending - ) { - state.liveRunning = false; - state.livePhase = "idle"; - state.liveRetry = null; - } - if (resetCursor) resetLiveState(); - state.cursor = resetCursor || state.cursor === null - ? state.snapshot.cursor - : Math.max(state.cursor, state.snapshot.cursor); - const availableWorkspaces = state.snapshot.workspaces; - const selectedSessionWorkspace = state.snapshot.selectedSession?.cwd; - const activeWorkspace = availableWorkspaces.find((workspace) => workspace.current)?.path; - const retainedWorkspace = availableWorkspaces.some( - (workspace) => workspace.path === state.selectedWorkspace, - ) - ? state.selectedWorkspace - : undefined; - const readyWorkspace = availableWorkspaces.some((workspace) => workspace.path === selectedSessionWorkspace) - ? selectedSessionWorkspace - : activeWorkspace ?? retainedWorkspace; - setWorkspaceReady(readyWorkspace); - state.selectedPath = current?.path || snapshot.selectedSession?.path || null; - renderWorkspaces(); - renderConversation(); - return true; - } catch (error) { - if ( - epoch !== state.sessionEpoch || - generation !== state.snapshotGeneration - ) return false; - $("connection-state").textContent = "Unavailable"; - $("connection-state").classList.add("reconnecting"); - $("composer-hint").textContent = error.message; - $("composer-hint").classList.add("error"); - return false; - } -} - -let sessionSelectionTail = Promise.resolve(); -async function selectSession(path) { - if (!path) return; - const epoch = ++state.sessionEpoch; - state.sessionSwitching = true; - state.selectedPath = path; - state.promptAdmissionPending = false; - state.promptAdmissionToken = null; - resetLiveState(); - document.body.classList.remove("sidebar-open"); - renderWorkspaces(); - renderConversation(); - const selection = sessionSelectionTail.then(async () => { - if (epoch !== state.sessionEpoch) return; - state.sessionActivation = { epoch, kind: "select", expectedPath: path }; - try { - await api("/api/sessions/select", { - method: "POST", - body: JSON.stringify({ path }), - }); - if (epoch !== state.sessionEpoch) return; - if (!(await refreshSnapshot({ epoch }))) state.selectedPath = null; - } catch (error) { - if (epoch !== state.sessionEpoch) return; - // Re-read Pi's canonical current session instead of rolling back to a - // possibly optimistic path from an older queued selection. - state.selectedPath = null; - showNotice(error.message); - await refreshSnapshot({ epoch }); - } finally { - if (state.sessionActivation?.epoch === epoch) state.sessionActivation = null; - if (epoch === state.sessionEpoch) { - state.sessionSwitching = false; - renderWorkspaces(); - renderConversation(); - } - } - }); - sessionSelectionTail = selection.catch(() => undefined); - await selection; -} - -let refreshTimer = null; -let refreshInFlight = false; -let refreshPending = false; - -function scheduleSnapshotRefresh(delay = 160) { - if (refreshInFlight) { - refreshPending = true; - return; - } - if (refreshTimer !== null) return; - refreshTimer = window.setTimeout(async () => { - refreshTimer = null; - refreshInFlight = true; - try { - await refreshSnapshot(); - } finally { - refreshInFlight = false; - if (refreshPending) { - refreshPending = false; - scheduleSnapshotRefresh(); - } - } - }, delay); -} - -async function sendPrompt() { - if (!state.selectedWorkspace) { - await chooseWorkspace(); - } - const content = $("prompt-input").value.trim(); - if ( - !content || - !state.selectedWorkspace || - state.sessionSwitching || - state.promptAdmissionPending - ) return; - if (!state.snapshot?.selectedSession?.id) { - await createSession(state.selectedWorkspace); - } - const sessionId = state.snapshot?.selectedSession?.id; - if (!sessionId || state.sessionSwitching || state.promptAdmissionPending) return; - const epoch = state.sessionEpoch; - const admissionToken = ++state.promptAdmissionSequence; - const optimisticKey = `optimistic-${Date.now()}`; - state.liveMessages = [ - ...state.liveMessages, - { key: optimisticKey, message: { role: "user", content } }, - ].slice(-8); - state.promptAdmissionPending = true; - state.promptAdmissionToken = admissionToken; - renderConversation(); - $("composer-hint").classList.remove("error"); - try { - const receipt = await api("/api/prompt", { - method: "POST", - body: JSON.stringify({ sessionId, content }), - }); - if (epoch !== state.sessionEpoch || state.promptAdmissionToken !== admissionToken) return; - const alreadySettled = state.terminalPromptIds.has(receipt.id); - state.liveRunning = !alreadySettled; - state.livePhase = alreadySettled ? "idle" : "preparing"; - $("prompt-input").value = ""; - resizePrompt(); - $("composer-hint").textContent = t("acceptedHint"); - scheduleSnapshotRefresh(120); - } catch (error) { - if (epoch !== state.sessionEpoch || state.promptAdmissionToken !== admissionToken) return; - state.liveRunning = false; - state.livePhase = "idle"; - state.liveRetry = null; - state.liveMessages = state.liveMessages.filter( - (entry) => entry.key !== optimisticKey, - ); - $("composer-hint").textContent = error.message; - $("composer-hint").classList.add("error"); - } finally { - if (epoch === state.sessionEpoch && state.promptAdmissionToken === admissionToken) { - state.promptAdmissionPending = false; - state.promptAdmissionToken = null; - renderConversation(); - } - } -} - -function resizePrompt() { - const input = $("prompt-input"); - const maxHeight = 220; - input.style.height = "auto"; - input.style.height = `${Math.min(input.scrollHeight, maxHeight)}px`; - input.style.overflowY = input.scrollHeight > maxHeight ? "auto" : "hidden"; -} - -function workspaceName(path) { - return path.split(/[\\/]/).filter(Boolean).pop() || path; -} - -function setWorkspaceReady(path) { - state.selectedWorkspace = path || null; - const composer = $("composer"); - const input = $("prompt-input"); - composer?.classList.toggle("dormant", !state.selectedWorkspace); - if (input) input.readOnly = !state.selectedWorkspace; - $("selected-workspace").textContent = state.selectedWorkspace - ? workspaceName(state.selectedWorkspace) - : t("selectWorkspace"); - renderWorkspacePicker(); -} - -function renderWorkspacePicker() { - const menu = $("workspace-picker-menu"); - const picker = $("select-workspace"); - if (!menu || !picker) return; - const workspaces = state.snapshot?.workspaces || []; - if (workspaces.length === 0) { - menu.hidden = true; - picker.setAttribute("aria-expanded", "false"); - $("selected-workspace").textContent = t("selectWorkspace"); - return; - } - menu.innerHTML = `${workspaces.map((workspace) => ``).join("")}`; - picker.setAttribute("aria-expanded", String(!menu.hidden)); - menu.querySelectorAll("[data-workspace-path]").forEach((button) => { - button.onclick = () => { - const path = button.dataset.workspacePath; - menu.hidden = true; - picker.setAttribute("aria-expanded", "false"); - if (!path) return; - setWorkspaceReady(path); - void refreshSnapshot(); - }; - }); - menu.querySelector("[data-workspace-add]")?.addEventListener("click", () => { - menu.hidden = true; - picker.setAttribute("aria-expanded", "false"); - void chooseWorkspace(); - }); -} - -function toggleWorkspace(path) { - if (state.collapsed.has(path)) state.collapsed.delete(path); - else state.collapsed.add(path); - persistCollapsedWorkspaces(state.collapsed); - renderWorkspaces(); -} - -function closeSearch({ restoreFocus = true } = {}) { - const search = $("search"); - const heading = search?.closest(".workspace-heading"); - if (!search || !heading) return; - heading.classList.remove("is-searching"); - search.value = ""; - state.query = ""; - renderWorkspaces(); - if (restoreFocus) $("search-toggle")?.focus(); -} - -async function createSession(workspacePath) { - if (!workspacePath) return; - const epoch = ++state.sessionEpoch; - const commandId = globalThis.crypto?.randomUUID?.() || - `web-create-${Date.now()}-${epoch}`; - state.sessionSwitching = true; - state.selectedPath = null; - state.promptAdmissionPending = false; - state.promptAdmissionToken = null; - resetLiveState(); - document.body.classList.remove("sidebar-open"); - renderWorkspaces(); - renderConversation(); - const creation = sessionSelectionTail.then(async () => { - if (epoch !== state.sessionEpoch) return; - state.sessionActivation = { - epoch, - kind: "create", - commandId, - expectedPath: null, - observedPath: null, - }; - try { - const result = await api("/api/sessions", { - method: "POST", - body: JSON.stringify({ workspacePath, commandId }), - }); - if (epoch !== state.sessionEpoch) return; - state.selectedPath = null; - await refreshSnapshot({ epoch }); - if (!result.cancelled && epoch === state.sessionEpoch) { - $("prompt-input")?.focus(); - } - } catch (error) { - if (epoch !== state.sessionEpoch) return; - state.selectedPath = null; - showNotice(error.message); - await refreshSnapshot({ epoch }); - } finally { - rememberCompletedActivation(commandId); - if (state.sessionActivation?.epoch === epoch) state.sessionActivation = null; - if (epoch === state.sessionEpoch) { - state.sessionSwitching = false; - renderWorkspaces(); - renderConversation(); - } - } - }); - sessionSelectionTail = creation.catch(() => undefined); - await creation; -} - -function showNotice(message) { - $("composer-hint").textContent = message; - $("composer-hint").classList.add("error"); -} - -function openWorkspaceMenu(path, anchor) { - const menu = $("workspace-menu"); - menu.dataset.workspace = path; - const rect = anchor.getBoundingClientRect(); - menu.style.left = `${Math.max(8, rect.right - 178)}px`; - menu.style.top = `${rect.bottom + 4}px`; - menu.show(); -} - -function openSessionMenu(path, anchor) { - const menu = $("session-menu"); - if (!menu || !path) return; - menu.dataset.session = path; - const rect = anchor.getBoundingClientRect(); - menu.style.left = `${Math.max(8, rect.right - 178)}px`; - menu.style.top = `${rect.bottom + 4}px`; - menu.show(); -} - -function openWorkspaceRename(path) { - const workspace = state.snapshot.workspaces.find((item) => item.path === path); - const dialog = $("workspace-rename-dialog"); - $("workspace-name-input").value = workspace?.name || workspaceName(path); - dialog.dataset.workspace = path; - $("workspace-menu").close(); - dialog.showModal(); - $("workspace-name-input").focus(); - $("workspace-name-input").select(); -} - -async function removeWorkspace(path) { - $("workspace-menu").close(); - try { - await api(`/api/workspaces?path=${encodeURIComponent(path)}`, { method: "DELETE" }); - if (state.selectedWorkspace === path) setWorkspaceReady(null); - state.selectedPath = null; - await refreshSnapshot(); - } catch (error) { - showNotice(error.message); - } -} - -function requestRemoveWorkspace(path) { - const workspace = state.snapshot?.workspaces.find((item) => item.path === path); - if (!workspace) return; - $("workspace-menu").close(); - const dialog = $("workspace-delete-dialog"); - const message = $("workspace-delete-message"); - if (!dialog || !message) return; - dialog.dataset.workspace = path; - message.textContent = `${workspace.name}:${t("workspaceDeleteConfirm")}`; - dialog.showModal(); -} - -function openSessionRename(path) { - const session = state.snapshot?.sessions.find((item) => item.path === path); - const dialog = $("session-rename-dialog"); - if (!dialog) return; - $("session-name-input").value = sessionTitle(session || {}); - dialog.dataset.session = path; - $("session-menu")?.close(); - dialog.showModal(); - $("session-name-input").focus(); - $("session-name-input").select(); -} - -async function archiveSession(path) { - if (!path) return; - $("session-menu")?.close(); - try { - await api(`/api/sessions/archive?path=${encodeURIComponent(path)}`, { method: "POST" }); - await refreshSnapshot(); - } catch (error) { - showNotice(error.message); - } -} - -async function chooseWorkspace() { - try { - const result = await api("/api/workspaces/select", { method: "POST" }); - if (result.cancelled || !result.path) return; - setWorkspaceReady(result.path); - await refreshSnapshot(); - } catch (error) { - const selectedWorkspace = $("selected-workspace"); - if (selectedWorkspace) selectedWorkspace.textContent = error.message; - } -} - -function applyRuntimeEvent(event) { - const eventSessionId = event.detail?.sessionId; - const sessionTransition = - event.type === "session_start" || - event.type === "session_switched" || - event.type === "session_created"; - if (state.sessionSwitching && !sessionTransition) { - scheduleSnapshotRefresh(); - return; - } - if ( - typeof eventSessionId === "string" && - eventSessionId !== state.snapshot?.currentSessionId && - event.type !== "session_start" && - event.type !== "session_switched" && - event.type !== "session_created" - ) { - scheduleSnapshotRefresh(); - return; - } - if (sessionTransition) { - const activation = state.sessionActivation; - const eventCommandId = event.detail?.commandId; - if ( - typeof eventCommandId === "string" && - state.completedActivationIds.has(eventCommandId) - ) { - scheduleSnapshotRefresh(); - return; - } - const eventPath = event.detail?.sessionPath; - const knownExistingPath = state.snapshot?.sessions.some( - (session) => session.path === eventPath, - ); - let belongsToActivation = false; - if (activation?.kind === "select") { - belongsToActivation = activation.expectedPath === eventPath; - } else if ( - activation?.kind === "create" && - activation.commandId === eventCommandId && - event.type === "session_switched" && - typeof eventPath === "string" && - !knownExistingPath - ) { - activation.observedPath = eventPath; - belongsToActivation = true; - } else if ( - activation?.kind === "create" && - activation.commandId === eventCommandId && - event.type === "session_created" && - typeof activation.observedPath === "string" - ) { - belongsToActivation = true; - } - if (belongsToActivation && activation.epoch !== state.sessionEpoch) return; - if (!belongsToActivation) { - state.sessionEpoch += 1; - state.promptAdmissionPending = false; - state.promptAdmissionToken = null; - state.sessionSwitching = true; - state.selectedPath = typeof eventPath === "string" ? eventPath : null; - const epoch = state.sessionEpoch; - void refreshSnapshot({ epoch }).then((refreshed) => { - if (epoch !== state.sessionEpoch) return; - if (!refreshed) state.selectedPath = null; - state.sessionSwitching = false; - renderWorkspaces(); - renderConversation(); - }); - } - resetLiveState(); - renderWorkspaces(); - renderConversation(); - scheduleSnapshotRefresh(); - } else if (event.type === "prompt_accepted") { - const alreadySettled = state.terminalPromptIds.has(event.detail?.commandId); - state.liveRunning = !alreadySettled; - state.livePhase = alreadySettled ? "idle" : "preparing"; - state.liveRetry = null; - renderConversation(); - } else if (event.type === "agent_start") { - state.liveRunning = true; - state.livePhase = "running"; - state.liveRetry = null; - renderConversation(); - } else if (event.type === "agent_settled" || event.type === "prompt_settled") { - if (event.type === "prompt_settled") rememberTerminalPrompt(event.detail?.commandId); - state.liveRunning = false; - state.livePhase = "idle"; - state.liveRetry = null; - renderConversation(); - } else if (event.detail?.message) { - if (event.detail.message.role === "user") { - state.liveMessages = state.liveMessages.filter( - (entry) => - !entry.key.startsWith("optimistic-") || - entry.message.content !== event.detail.message.content, - ); - } - const key = event.detail.messageKey || `${event.detail.message.role || "message"}-${event.sequence}`; - const index = state.liveMessages.findIndex((entry) => entry.key === key); - const live = { key, message: event.detail.message }; - if (index >= 0) state.liveMessages[index] = live; - else state.liveMessages = [...state.liveMessages, live].slice(-8); - renderConversation(); - } - if ( - [ - "agent_start", - "agent_settled", - "prompt_settled", - "message_end", - "tool_execution_end", - "session_start", - "session_switched", - "session_progress", - "prompt_failed", - "model_select", - "workspace_imported", - "workspace_removed", - "workspace_renamed", - "session_renamed", - "session_archived", - "session_created", - "prompt_accepted", - "runtime_changed", - ].includes(event.type) - ) { - scheduleSnapshotRefresh(); - } - if (event.type === "prompt_failed") { - rememberTerminalPrompt(event.detail?.commandId); - state.liveRunning = false; - state.livePhase = "idle"; - state.liveRetry = null; - state.liveMessages = state.liveMessages.filter( - (entry) => !entry.key.startsWith("optimistic-"), - ); - showNotice(event.detail?.error || "Prompt failed"); - renderConversation(); - } - if (event.type === "auto_retry_start") { - state.liveRunning = true; - state.livePhase = "running"; - state.liveRetry = { - attempt: event.detail?.attempt || 0, - maxAttempts: event.detail?.maxAttempts || 0, - }; - renderConversation(); - } -} - -function rememberTerminalPrompt(commandId) { - if (typeof commandId !== "string") return; - state.terminalPromptIds.add(commandId); - while (state.terminalPromptIds.size > 32) { - state.terminalPromptIds.delete(state.terminalPromptIds.values().next().value); - } -} - -function rememberCompletedActivation(commandId) { - state.completedActivationIds.add(commandId); - while (state.completedActivationIds.size > 32) { - state.completedActivationIds.delete( - state.completedActivationIds.values().next().value, - ); - } -} - -let eventLoopStarted = false; -function resetLiveState() { - state.liveMessages = []; - state.liveRunning = false; - state.livePhase = "idle"; - state.liveRetry = null; -} - -async function connectEvents() { - if (eventLoopStarted) return; - eventLoopStarted = true; - let reconnectDelay = 500; - while (true) { - let reader = null; - let recoveryAttempted = false; - try { - if (state.cursor === null) { - recoveryAttempted = true; - const ready = await refreshSnapshot({ resetCursor: true }); - if (!ready) throw new Error("snapshot unavailable"); - recoveryAttempted = false; - } - const response = await fetch(`/events?cursor=${state.cursor}`, { - headers: headers(), - }); - if (response.status === 409) { - recoveryAttempted = true; - const ready = await refreshSnapshot({ resetCursor: true }); - if (!ready) throw new Error("snapshot resync failed"); - continue; - } - if (!response.ok || !response.body) throw new Error("event connection failed"); - $("connection-state").textContent = "Connected"; - $("connection-state").classList.remove("reconnecting"); - reconnectDelay = 500; - reader = response.body.getReader(); - const decoder = new TextDecoder(); - let buffer = ""; - while (true) { - const { done, value } = await reader.read(); - if (done) throw new Error("event connection closed"); - buffer += decoder.decode(value, { stream: true }); - const records = buffer.split("\n\n"); - buffer = records.pop() || ""; - for (const record of records) { - const line = record.split("\n").find((item) => item.startsWith("data: ")); - if (!line) continue; - const event = JSON.parse(line.slice(6)); - if (!Number.isSafeInteger(event.sequence)) throw new Error("invalid event cursor"); - if (event.sequence <= state.cursor) continue; - if (event.sequence !== state.cursor + 1) throw new Error("event cursor gap"); - state.cursor = event.sequence; - if (event.type === "state_invalidated") throw new Error("state invalidated"); - applyRuntimeEvent(event); - } - } - } catch { - await reader?.cancel().catch(() => undefined); - reader = null; - $("connection-state").textContent = "Reconnecting"; - $("connection-state").classList.add("reconnecting"); - const recovered = recoveryAttempted - ? false - : await refreshSnapshot({ resetCursor: true }); - if (!recovered) resetLiveState(); - await new Promise((resolve) => setTimeout(resolve, reconnectDelay)); - reconnectDelay = Math.min(reconnectDelay * 2, 5_000); - } finally { - await reader?.cancel().catch(() => undefined); - } - } -} - -const collapseButton = $("collapse-sidebar"); -const collapsedStorageKey = "openpi.sidebar-collapsed"; -const setSidebarCollapsed = (collapsed) => { - document.body.classList.toggle("sidebar-collapsed", collapsed); - collapseButton?.setAttribute("aria-label", collapsed ? "Expand sidebar" : "Collapse sidebar"); - collapseButton?.setAttribute("title", collapsed ? "Expand sidebar" : "Collapse sidebar"); - try { sessionStorage.setItem(collapsedStorageKey, String(collapsed)); } catch {} -}; -try { setSidebarCollapsed(sessionStorage.getItem(collapsedStorageKey) === "true"); } catch {} -collapseButton?.addEventListener("click", () => { - if (window.matchMedia("(max-width: 760px)").matches) { - document.body.classList.remove("sidebar-open"); - return; - } - setSidebarCollapsed(!document.body.classList.contains("sidebar-collapsed")); -}); - -$("search-toggle")?.addEventListener("click", () => { - const search = $("search"); - const heading = search?.closest(".workspace-heading"); - if (!search || !heading) return; - if (heading.classList.contains("is-searching")) { - closeSearch(); - return; - } - heading.classList.add("is-searching"); - search.focus(); -}); -$("search")?.addEventListener("input", (event) => { - state.query = event.target.value.trim(); - renderWorkspaces(); -}); -$("search")?.addEventListener("keydown", (event) => { - if (event.key !== "Escape") return; - event.preventDefault(); - closeSearch(); -}); -$("search-clear")?.addEventListener("click", () => { - closeSearch(); -}); -$("workspace-menu")?.addEventListener("click", (event) => { - const action = event.target.closest("[data-action]")?.dataset.action; - const path = $("workspace-menu").dataset.workspace; - if (!action || !path) return; - if (action === "rename") openWorkspaceRename(path); - else requestRemoveWorkspace(path); -}); -$("session-menu")?.addEventListener("click", (event) => { - const action = event.target.closest("[data-action]")?.dataset.action; - const path = $("session-menu").dataset.session; - if (!action || !path) return; - if (action === "rename") openSessionRename(path); - else if (action === "archive") void archiveSession(path); -}); -$("workspace-rename-form")?.addEventListener("submit", async (event) => { - if (event.submitter?.value !== "save") return; - event.preventDefault(); - const dialog = $("workspace-rename-dialog"); - const path = dialog.dataset.workspace; - const name = $("workspace-name-input").value.trim(); - if (!path || !name) return; - try { - await api("/api/workspaces", { - method: "PATCH", - body: JSON.stringify({ path, name }), - }); - dialog.close(); - await refreshSnapshot(); - } catch (error) { - showNotice(error.message); - } -}); -$("workspace-delete-form")?.addEventListener("submit", async (event) => { - if (event.submitter?.value !== "delete") return; - const dialog = $("workspace-delete-dialog"); - const path = dialog?.dataset.workspace; - if (path) await removeWorkspace(path); -}); -$("session-rename-form")?.addEventListener("submit", async (event) => { - if (event.submitter?.value !== "save") return; - event.preventDefault(); - const dialog = $("session-rename-dialog"); - const path = dialog.dataset.session; - const name = $("session-name-input").value.trim(); - if (!path || !name) return; - try { - await api("/api/sessions", { - method: "PATCH", - body: JSON.stringify({ path, name }), - }); - dialog.close(); - await refreshSnapshot(); - } catch (error) { - showNotice(error.message); - } -}); -document.addEventListener("pointerdown", (event) => { - const menu = $("workspace-menu"); - if (menu?.open && !menu.contains(event.target) && !event.target.closest('[data-workspace-action="more"]')) menu.close(); - const sessionMenu = $("session-menu"); - if (sessionMenu?.open && !sessionMenu.contains(event.target) && !event.target.closest('[data-session-action="menu"]')) sessionMenu.close(); - const heading = document.querySelector(".workspace-heading"); - if (heading?.classList.contains("is-searching") && !heading.contains(event.target)) { - closeSearch({ restoreFocus: false }); - } - const picker = document.querySelector(".workspace-picker-row"); - if (picker && !picker.contains(event.target)) { - $("workspace-picker-menu").hidden = true; - $("select-workspace")?.setAttribute("aria-expanded", "false"); - } - const modelPicker = document.querySelector(".model-picker-wrap"); - if (modelPicker && !modelPicker.contains(event.target)) { - $("model-menu").hidden = true; - $("model-picker")?.setAttribute("aria-expanded", "false"); - } -}); -document.querySelector(".new-session-button")?.addEventListener("click", async () => { - if (!state.selectedWorkspace) await chooseWorkspace(); - if (state.selectedWorkspace) await createSession(state.selectedWorkspace); -}); -$("import-workspace")?.addEventListener("click", chooseWorkspace); -$("select-workspace")?.addEventListener("click", () => { - const menu = $("workspace-picker-menu"); - const picker = $("select-workspace"); - if (!menu || !picker) return; - if ((state.snapshot?.workspaces || []).length === 0) { - void chooseWorkspace(); - return; - } - menu.hidden = !menu.hidden; - picker.setAttribute("aria-expanded", String(!menu.hidden)); - if (!menu.hidden) renderWorkspacePicker(); -}); -$("model-picker")?.addEventListener("click", () => { - const picker = $("model-picker"); - const menu = $("model-menu"); - if (!picker || !menu || picker.disabled) return; - menu.hidden = !menu.hidden; - picker.setAttribute("aria-expanded", String(!menu.hidden)); -}); -$("mobile-sidebar")?.addEventListener("click", () => document.body.classList.toggle("sidebar-open")); -document.querySelector(".sidebar-scrim")?.addEventListener("click", () => document.body.classList.remove("sidebar-open")); -$("composer")?.addEventListener("pointerdown", (event) => { - if (state.selectedWorkspace) return; - event.preventDefault(); - void chooseWorkspace(); -}, true); -$("composer")?.addEventListener("submit", (event) => { - event.preventDefault(); - if (state.selectedWorkspace) void sendPrompt(); - else void chooseWorkspace(); -}); -$("prompt-input")?.addEventListener("input", resizePrompt); -$("prompt-input")?.addEventListener("keydown", (event) => { - if (event.isComposing || event.keyCode === 229) return; - if (event.key === "Enter" && !event.shiftKey) { - event.preventDefault(); - if (state.selectedWorkspace) void sendPrompt(); - else void chooseWorkspace(); - } -}); - -applyLanguage(); -void connectEvents(); diff --git a/web/ui/index.html b/web/ui/index.html index 7aa60047..c2b1debf 100644 --- a/web/ui/index.html +++ b/web/ui/index.html @@ -5,135 +5,10 @@ OpenPI - - - + -
    - - -
    -
    - -
    - New session - Choose a workspace and describe the work -
    - Connecting -
    - -
    -
    -
    - Open -
    -
    -
    - -
    -
    - - -
    -
    - -
    -
    - - -
    - -
    -
    -
    -
    -
    - -
    - 删除工作区 -

    -
    - - -
    -
    -
    -
    - +
    + diff --git a/web/ui/public/favicon.svg b/web/ui/public/favicon.svg new file mode 100644 index 00000000..887996c8 --- /dev/null +++ b/web/ui/public/favicon.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/web/ui/src/app/App.tsx b/web/ui/src/app/App.tsx new file mode 100644 index 00000000..3947c7ab --- /dev/null +++ b/web/ui/src/app/App.tsx @@ -0,0 +1,130 @@ +import { Menu, PanelLeftOpen, X } from "lucide-react"; +import { useCallback, useEffect } from "react"; +import { useTranslation } from "react-i18next"; +import { useStore } from "zustand"; +import { OpenPiLogo } from "../components/OpenPiLogo.tsx"; +import { Composer } from "../features/composer/Composer.tsx"; +import { SessionSidebar } from "../features/sessions/SessionSidebar.tsx"; +import { Transcript } from "../features/transcript/Transcript.tsx"; +import { webStore } from "../store/web-store.ts"; + +export function App() { + const state = useStore(webStore); + const { t } = useTranslation(); + const { actions } = state; + + useEffect(() => { + actions.start(); + return actions.stop; + }, [actions]); + + const selected = state.snapshot?.selectedSession; + const hasMessages = + selected?.entries.some( + (entry) => entry.type === "message" && entry.message, + ) || state.liveMessages.length > 0; + const landing = !selected || !hasMessages; + const resend = useCallback( + (content: string) => actions.sendPrompt(content), + [actions], + ); + + return ( +
    + + {state.sidebarCollapsed && ( + + )} +
    +
    + + + {t(state.connection)} + +
    + {state.sessionSwitching ? ( +
    +
    + + {t("switchingSession")} +
    +
    + ) : landing ? ( +
    +
    +

    OpenPI

    + +
    +
    + ) : state.snapshot ? ( + + ) : null} + + {state.notice && ( +
    + {state.notice} + +
    + )} +
    +
    + ); +} diff --git a/web/ui/src/app/providers.tsx b/web/ui/src/app/providers.tsx new file mode 100644 index 00000000..75e95138 --- /dev/null +++ b/web/ui/src/app/providers.tsx @@ -0,0 +1,15 @@ +import { Theme } from "@astryxdesign/core/theme"; +import { neutralTheme } from "@astryxdesign/theme-neutral/built"; +import type { PropsWithChildren } from "react"; +import { I18nextProvider } from "react-i18next"; +import { i18n } from "../i18n.ts"; + +export function Providers({ children }: PropsWithChildren) { + return ( + + + {children} + + + ); +} diff --git a/web/ui/src/components/Markdown.tsx b/web/ui/src/components/Markdown.tsx new file mode 100644 index 00000000..d22bfed9 --- /dev/null +++ b/web/ui/src/components/Markdown.tsx @@ -0,0 +1,52 @@ +import ReactMarkdown from "react-markdown"; +import rehypeSanitize from "rehype-sanitize"; +import remarkGfm from "remark-gfm"; + +function safeUrl(value: string) { + if (!value.trim()) return ""; + try { + const url = new URL(value, document.baseURI); + return ["http:", "https:", "mailto:", "tel:"].includes(url.protocol) + ? url.href + : ""; + } catch { + return ""; + } +} + +export function Markdown({ children }: { children: string }) { + return ( +
    + + {label} + + ) : ( + label + ); + }, + img({ src, alt, title }) { + const safeHref = safeUrl(src ?? ""); + const label = alt || "image"; + return safeHref ? ( + + [image: {label}] + + ) : ( + {label} + ); + }, + }} + > + {children} + +
    + ); +} diff --git a/web/ui/src/components/OpenPiLogo.tsx b/web/ui/src/components/OpenPiLogo.tsx new file mode 100644 index 00000000..7e33a8b6 --- /dev/null +++ b/web/ui/src/components/OpenPiLogo.tsx @@ -0,0 +1,41 @@ +import { useState } from "react"; + +interface OpenPiLogoProps { + animated?: boolean; + compact?: boolean; +} + +const cellIds = Array.from({ length: 16 }, (_, index) => `cell-${index + 1}`); + +export function OpenPiLogo({ + animated = false, + compact = false, +}: OpenPiLogoProps) { + const [replay, setReplay] = useState(0); + const count = compact ? 10 : 16; + const logo = ( + + Open + + {cellIds.slice(0, count).map((cellId) => ( + + ))} + + + ); + + if (!animated) return logo; + return ( + + ); +} diff --git a/web/ui/src/features/activity/ActivityBar.tsx b/web/ui/src/features/activity/ActivityBar.tsx new file mode 100644 index 00000000..ab6c65cf --- /dev/null +++ b/web/ui/src/features/activity/ActivityBar.tsx @@ -0,0 +1,109 @@ +import { Check, X } from "lucide-react"; +import { useEffect, useState } from "react"; +import type { WebSnapshot } from "../../../../protocol/types.ts"; +import { formatElapsedMs } from "../../lib/format.ts"; + +type Status = "running" | "done" | "error" | "warn" | "unknown"; + +function canonicalStatus(value: string): Status { + if (value === "running") return "running"; + if (value === "done" || value === "completed") return "done"; + if (["error", "failed", "aborted", "killed", "timed_out"].includes(value)) + return "error"; + if (value === "uncertain") return "warn"; + return "unknown"; +} + +function Chip({ + kind, + label, + status, +}: { + kind: string; + label: string; + status: Status; +}) { + return ( + + {status === "running" ? ( + + ) : status === "done" ? ( + + ) : status === "error" ? ( + + ) : ( + ? + )} + {label} + + ); +} + +export function ActivityBar({ snapshot }: { snapshot: WebSnapshot | null }) { + const [, tick] = useState(0); + const capabilities = snapshot?.runtime.capabilities; + const running = [ + ...(capabilities?.subagents?.items ?? []), + ...(capabilities?.workflows?.items ?? []), + ].some((item) => item.status === "running"); + useEffect(() => { + if (!running) return; + const interval = window.setInterval( + () => tick((value) => value + 1), + 1_000, + ); + return () => window.clearInterval(interval); + }, [running]); + + const chips: Array<{ + key: string; + kind: string; + label: string; + status: Status; + }> = []; + for (const workflow of capabilities?.workflows?.items ?? []) { + const settled = workflow.agents.total - workflow.agents.running; + const progress = workflow.agents.total + ? ` · ${settled}/${workflow.agents.total} agents` + : ""; + const phase = + workflow.status === "running" && workflow.currentPhase + ? ` · ${workflow.currentPhase}` + : ""; + const elapsed = formatElapsedMs(workflow.startedAt, workflow.finishedAt); + chips.push({ + key: `workflow-${workflow.runId}`, + kind: "workflow", + label: `${workflow.name || workflow.runId}${phase}${progress}${elapsed ? ` · ${elapsed}` : ""}`, + status: canonicalStatus(workflow.status), + }); + } + for (const subagent of capabilities?.subagents?.items ?? []) { + const elapsed = formatElapsedMs(subagent.createdAt, subagent.settledAt); + chips.push({ + key: `subagent-${subagent.id}`, + kind: "subagent", + label: `${subagent.title || subagent.id}${elapsed ? ` · ${elapsed}` : ""}`, + status: canonicalStatus(subagent.status), + }); + } + chips.sort( + (left, right) => + Number(right.status === "running") - Number(left.status === "running"), + ); + const visible = chips.slice(0, 5); + const omitted = + chips.length - + visible.length + + (capabilities?.subagents?.omitted ?? 0) + + (capabilities?.workflows?.omitted ?? 0); + if (!visible.length && !omitted) return null; + return ( +
    + {visible.map(({ key, ...chip }) => ( + + ))} + {omitted > 0 && +{omitted}} +
    + ); +} diff --git a/web/ui/src/features/composer/Composer.tsx b/web/ui/src/features/composer/Composer.tsx new file mode 100644 index 00000000..fb67325a --- /dev/null +++ b/web/ui/src/features/composer/Composer.tsx @@ -0,0 +1,199 @@ +import { DropdownMenu } from "@astryxdesign/core/DropdownMenu"; +import { Tooltip } from "@astryxdesign/core/Tooltip"; +import { Check, ChevronDown, Folder, Plus, Send } from "lucide-react"; +import { type FormEvent, useRef, useState } from "react"; +import { useTranslation } from "react-i18next"; +import type { WebSnapshot } from "../../../../protocol/types.ts"; +import { workspaceName } from "../../lib/format.ts"; +import type { WebStoreActions } from "../../store/web-store.ts"; +import { ActivityBar } from "../activity/ActivityBar.tsx"; + +interface ComposerProps { + snapshot: WebSnapshot | null; + selectedWorkspace: string | null; + sessionSwitching: boolean; + promptAdmissionPending: boolean; + liveRunning: boolean; + landing: boolean; + actions: WebStoreActions; +} + +export function Composer(props: ComposerProps) { + const { t } = useTranslation(); + const [prompt, setPrompt] = useState(""); + const textarea = useRef(null); + const selected = props.snapshot?.selectedSession; + const active = Boolean( + selected?.id && selected.id === props.snapshot?.currentSessionId, + ); + const draftSession = Boolean( + props.selectedWorkspace && !selected && !props.snapshot?.currentSessionId, + ); + const canCompose = active || draftSession; + const running = + props.snapshot?.runtime.status === "running" || props.liveRunning; + const disabled = + props.sessionSwitching || (!canCompose && Boolean(props.selectedWorkspace)); + + const resize = (element: HTMLTextAreaElement) => { + element.style.height = "auto"; + element.style.height = `${Math.min(element.scrollHeight, 220)}px`; + element.style.overflowY = element.scrollHeight > 220 ? "auto" : "hidden"; + }; + + const send = async (event?: FormEvent) => { + event?.preventDefault(); + if (!props.selectedWorkspace) { + await props.actions.chooseWorkspace(); + return; + } + if (await props.actions.sendPrompt(prompt)) setPrompt(""); + }; + + const workspaceItems = [ + ...(props.snapshot?.workspaces ?? []).map((workspace) => ({ + id: workspace.path, + label: workspace.name, + icon: , + endContent: + workspace.path === props.selectedWorkspace ? : undefined, + onClick: () => props.actions.setWorkspace(workspace.path), + })), + { type: "divider" as const }, + { + id: "add", + label: t("addWorkspaceMenu"), + icon: , + onClick: () => void props.actions.chooseWorkspace(), + }, + ]; + const currentModel = + props.snapshot?.models.find((model) => model.current) ?? + props.snapshot?.models[0]; + const modelItems = (props.snapshot?.models ?? []).map((model) => ({ + id: `${model.provider}/${model.id}`, + label: model.label, + endContent: model.current ? : undefined, + onClick: () => + void props.actions.selectModel(`${model.provider}/${model.id}`), + })); + const placeholder = !props.selectedWorkspace + ? t("promptStart") + : props.landing + ? t("promptTask") + : active + ? t("promptMessage") + : t("promptReadonly"); + const hint = canCompose + ? running + ? t("queuedHint") + : t("enterHint") + : t("activeOnlyHint"); + + return ( +
    + + {props.landing && ( +
    + , + size: "md", + variant: "ghost", + className: "workspace-picker", + }} + items={workspaceItems} + menuWidth={240} + placement="above" + alignment="start" + hasChevron + /> +
    + )} +
    void send(event)} + > + {!props.selectedWorkspace && ( +