diff --git a/AGENTS.md b/AGENTS.md index 861733d6..7e5d74ea 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -59,10 +59,11 @@ ORM entities are in `src/gateway/models/entities.py` (User, APIKey, Budget, Usag - Docker local build/run: `docker compose up --build` - CI Docker smoke check is implemented in `scripts/docker_liveness_check.sh`. ## Web Dashboard (`web/`) -- The standalone admin dashboard is a React + HeroUI v3 SPA in `web/` (Vite, Tailwind v4, TanStack Query). It browses the model catalogue, sets model pricing, manages aliases, and toggles runtime settings; it calls the management API (`/v1/models`, `/v1/pricing`, `/v1/aliases`, `/v1/settings`) with the master key, entered on a sign-in screen and kept only in the browser tab's session storage. +- The standalone admin dashboard is a React + HeroUI v3 SPA in `web/` (Vite, Tailwind v4, TanStack Query). It browses the model catalogue, sets model pricing, manages aliases, adds/edits provider API keys, and toggles runtime settings; it calls the management API (`/v1/models`, `/v1/pricing`, `/v1/aliases`, `/v1/provider-credentials`, `/v1/settings`) with the master key, entered on a sign-in screen and kept only in the browser tab's session storage. +- Runtime provider management: the Providers page (`web/src/pages/ProvidersPage.tsx`) manages the `provider_credentials` table via `/v1/provider-credentials` (CRUD + `POST /{instance}/test`). Backend: `services/provider_store_service.py` overlays stored providers onto `config.providers` (per-config baseline on `config._provider_baseline`, refreshed by a TTL refresher wired in the lifespan like the alias refresher, standalone-only); `services/secret_box.py` encrypts keys with `OTARI_SECRET_KEY` (Fernet); `services/master_key_service.py` generates + prints a master key on first run when none is set (hash in `runtime_settings`). Keys are write-only over the API (responses expose only `last4`). - Build: `npm --prefix web ci && npm --prefix web run build`. Output goes to `src/gateway/static/dashboard/` (set in `web/vite.config.ts`), which is committed so the wheel and Docker image ship the dashboard with no Node build stage. Rebuild and commit after any change under `web/src`. - Checks: `npm --prefix web run typecheck`, `npm --prefix web test`. CI runs these and fails if the committed bundle is stale (`.github/workflows/otari-dashboard.yml`). -- Serving: standalone mode serves `index.html` at `/` and hashed assets under `/assets` (`src/gateway/main.py`, `src/gateway/dashboard.py`); the get-started tutorial moved to `/welcome`. Hybrid mode has no local management API, so `/` keeps serving the tutorial. Navigation is client-side section switching, so no server catch-all route is needed. +- Serving: standalone mode serves `index.html` at `/` and hashed assets under `/assets` (`src/gateway/main.py`, `src/gateway/dashboard.py`); the get-started tutorial moved to `/welcome`. Hybrid mode has no local management API, so `/` keeps serving the tutorial. Client-side routing uses react-router's `HashRouter` (routes live under `/#/providers`, `/#/models`, `/#/aliases`, `/#/settings`), so hash routes need no server catch-all and the API/asset paths are never shadowed. ## Lint / Typecheck Commands - Ruff is configured for linting (rules: `E`, `F`, `I`; line length: 120) in `pyproject.toml`. - Run lint checks with `make lint` (or `uv run ruff check src tests scripts`). diff --git a/README.md b/README.md index 2c9dce16..f774c12b 100644 --- a/README.md +++ b/README.md @@ -131,7 +131,7 @@ Prefer a typed client? Use one of the [Otari SDKs](#the-otari-ecosystem) for Pyt The Quickstart touches three different keys. Keeping them straight saves the most common first-run error: - **Provider key** (`OPENAI_API_KEY`): your real OpenAI secret. It goes in as an environment variable and stays inside Otari. Your apps never see it. -- **Master key** (`OTARI_MASTER_KEY`): manages Otari. Use it to create and revoke API keys, not to make requests. +- **Master key** (`OTARI_MASTER_KEY`): manages Otari. Use it to create and revoke API keys, not to make requests. Leave it unset and Otari generates one on first run and prints it to the logs. - **API key** (`gw-...`): what clients send to Otari in the `Authorization` header. The bootstrap key is one of these. To mint a named key yourself instead of using the bootstrap key, call the management endpoint with your master key: @@ -145,6 +145,33 @@ curl -X POST http://localhost:8000/v1/keys \ The returned `gw-` key is shown in full only once. +### Set it up in the browser instead + +Prefer not to pre-set anything on the command line? Launch Otari bare and finish in the dashboard. + +```bash +docker run --rm -p 8000:8000 mzdotai/otari:latest otari serve +``` + +With no master key set, Otari generates one and prints it to the logs once on startup: + +```text +Otari first-run: no master key was set, so one was generated. +Save it now (it is shown only once). Sign in to the dashboard at http://localhost:8000/ +Your master key: +otari-mk-... +``` + +Open `http://localhost:8000/`, sign in with that key, then open **Providers** and add your OpenAI key. Storing a provider key requires `OTARI_SECRET_KEY`, a Fernet key that encrypts credentials at rest; generate one with `otari gen-secret-key` and set it before launch: + +```bash +docker run --rm -p 8000:8000 \ + -e OTARI_SECRET_KEY="$(docker run --rm mzdotai/otari:latest otari gen-secret-key)" \ + mzdotai/otari:latest otari serve +``` + +Back it up somewhere safe: losing `OTARI_SECRET_KEY` makes every stored provider key undecryptable. Providers you set in `config.yml` keep working and appear in the dashboard marked `config` (read-only there); keys you add in the UI are marked `stored`, and a stored key of the same name takes precedence. + ## Run the full stack The Quickstart runs the gateway alone on SQLite. To get a durable database plus the built-in tools and guardrails, run the full stack with Docker Compose. @@ -191,10 +218,15 @@ For hot reload against a local `.env`, use `make dev`. ### Admin dashboard In standalone mode the gateway serves a web admin dashboard at the root URL -(`http://localhost:8000`). Sign in with your master key (`OTARI_MASTER_KEY`) to -browse the model catalogue, set model pricing, manage aliases, and toggle -runtime settings (model discovery and default pricing). The get-started -tutorial page moved to `/welcome`. The dashboard is a React + +(`http://localhost:8000`). Sign in with your master key (`OTARI_MASTER_KEY`, or +the one printed to the logs on first run) to add provider API keys, browse the +model catalogue, set model pricing, manage aliases, and toggle runtime settings +(model discovery and default pricing). Provider keys added in the **Providers** +page are encrypted at rest (requires `OTARI_SECRET_KEY`; see +[Set it up in the browser instead](#set-it-up-in-the-browser-instead)) and merge +over `config.yml` providers, so you can start with an empty config and add +credentials after launch. The get-started tutorial page moved to `/welcome`. The +dashboard is a React + HeroUI app that lives in `web/`; its built bundle is committed under `src/gateway/static/dashboard`, so the published package and Docker image serve it with no extra build step. See [`web/README.md`](web/README.md) to work on it. diff --git a/alembic/versions/b4d6f8a0c2e4_add_provider_credentials.py b/alembic/versions/b4d6f8a0c2e4_add_provider_credentials.py new file mode 100644 index 00000000..0377fccd --- /dev/null +++ b/alembic/versions/b4d6f8a0c2e4_add_provider_credentials.py @@ -0,0 +1,39 @@ +"""Add provider_credentials table. + +Revision ID: b4d6f8a0c2e4 +Revises: a2c4e6f8b0d1 +Create Date: 2026-07-17 00:00:00.000000 + +""" + +from collections.abc import Sequence + +import sqlalchemy as sa +from alembic import op + +# revision identifiers, used by Alembic. +revision: str = "b4d6f8a0c2e4" +down_revision: str | Sequence[str] | None = "a2c4e6f8b0d1" +branch_labels: str | Sequence[str] | None = None +depends_on: str | Sequence[str] | None = None + + +def upgrade() -> None: + """Upgrade schema.""" + op.create_table( + "provider_credentials", + sa.Column("instance", sa.String(), nullable=False), + sa.Column("provider_type", sa.String(), nullable=True), + sa.Column("api_base", sa.String(), nullable=True), + sa.Column("encrypted_api_key", sa.String(), nullable=True), + sa.Column("last4", sa.String(), nullable=True), + sa.Column("client_args", sa.JSON(), nullable=False), + sa.Column("created_at", sa.DateTime(timezone=True), nullable=False), + sa.Column("updated_at", sa.DateTime(timezone=True), nullable=False), + sa.PrimaryKeyConstraint("instance"), + ) + + +def downgrade() -> None: + """Downgrade schema.""" + op.drop_table("provider_credentials") diff --git a/docs/configuration.md b/docs/configuration.md index 2766bb20..401f90f4 100644 --- a/docs/configuration.md +++ b/docs/configuration.md @@ -146,7 +146,8 @@ Note the `require_pricing` interaction: it defaults to `true` (fail-closed), so | Variable | Description | |----------|-------------| -| `OTARI_MASTER_KEY` | Master key for management endpoints | +| `OTARI_MASTER_KEY` | Master key for management endpoints. When unset in standalone mode, one is generated on first run and printed to the logs (see [Runtime provider management](#runtime-provider-management)). | +| `OTARI_SECRET_KEY` | Fernet key that encrypts provider credentials added through the dashboard. Required to store a provider key in the UI. Generate one with `otari gen-secret-key`. | | `OTARI_DATABASE_URL` | Database connection URL | | `OTARI_HOST` | Server bind host | | `OTARI_PORT` | Server bind port | @@ -185,6 +186,32 @@ These credentials are used for standalone deployments. When connected to otari.a | `MISTRAL_API_KEY` | Mistral | | `GEMINI_API_KEY` | Google Gemini | +### Runtime provider management + +Instead of setting providers at launch, you can add them from the admin dashboard +after startup (standalone mode only). This lets you launch Otari with almost +nothing set and finish configuration in the browser. + +- **First-run master key.** If `OTARI_MASTER_KEY` is unset, Otari generates a + master key on first startup, stores only its hash, and prints the plaintext + once to the logs (look for `Your master key:`). Use it to sign in. An + operator-set `OTARI_MASTER_KEY` always takes precedence and is never generated + over. +- **Encryption at rest.** Provider keys added in the dashboard are stored + encrypted with `OTARI_SECRET_KEY` (a Fernet key). Set it before adding a key; + generate one with `otari gen-secret-key`. Keep it safe and separate from the + database: losing it makes every stored provider key undecryptable, and a + database dump alone cannot decrypt them. Rotate by prepending a new key + (comma- or whitespace-separated); both old and new are tried on decrypt. +- **Precedence.** Dashboard-stored providers merge over `config.yml` providers. + A stored provider with the same instance name as a config one takes precedence + (the shadowing is logged at startup). In the dashboard, config providers are + marked `config` and are read-only; stored providers are marked `stored` and can + be edited, tested, and deleted. +- **Scope.** Providers that authenticate with an API key (OpenAI, Anthropic, + Mistral, Gemini, and OpenAI-compatible backends) are supported. Providers that + use ADC/IAM (Vertex AI, Bedrock) remain config-file only. + ### otari.ai variables These are only relevant when running connected to [otari.ai](https://otari.ai). See [Modes](modes.md) for details. diff --git a/docs/public/openapi.json b/docs/public/openapi.json index 2d7353f5..9551d8de 100644 --- a/docs/public/openapi.json +++ b/docs/public/openapi.json @@ -989,6 +989,69 @@ "title": "CreateKeyResponse", "type": "object" }, + "CreateStoredProviderRequest": { + "description": "Create a stored provider. ``api_key`` is write-only and requires OTARI_SECRET_KEY.", + "properties": { + "api_base": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Api Base" + }, + "api_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Provider API key. Stored encrypted; never returned.", + "title": "Api Key" + }, + "client_args": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Client Args" + }, + "instance": { + "description": "Routing key, e.g. 'openai' or a named instance like 'home_lab'.", + "minLength": 1, + "title": "Instance", + "type": "string" + }, + "provider_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "any-llm implementation when the instance name is not itself one.", + "title": "Provider Type" + } + }, + "required": [ + "instance" + ], + "title": "CreateStoredProviderRequest", + "type": "object" + }, "CreateUserRequest": { "description": "Request model for creating a new user.", "properties": { @@ -1444,6 +1507,57 @@ "title": "KeyInfo", "type": "object" }, + "KnownProviderSchema": { + "description": "A provider the add-provider picker can offer, with autofill hints.", + "properties": { + "default_api_base": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Built-in endpoint; blank means the SDK's default.", + "title": "Default Api Base" + }, + "env_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Env var the SDK reads this provider's key from.", + "title": "Env Key" + }, + "id": { + "description": "any-llm provider id, used as the default instance name.", + "title": "Id", + "type": "string" + }, + "name": { + "description": "Human-friendly display name.", + "title": "Name", + "type": "string" + }, + "requires_api_key": { + "description": "False for keyless local backends (Ollama, llama.cpp).", + "title": "Requires Api Key", + "type": "boolean" + } + }, + "required": [ + "id", + "name", + "requires_api_key" + ], + "title": "KnownProviderSchema", + "type": "object" + }, "McpServerConfig": { "description": "Inline MCP server configuration accepted on the chat completions request.\n\nStreamable HTTP transport. The `url` must be reachable from the gateway process.\n\nURL safety (SSRF guard against private/link-local/reserved IP ranges, plus\nrejecting plain ``http://`` when ``authorization_token`` is set) is\nenforced by :func:`gateway.services.url_safety.validate_mcp_url`, called\nfrom the async request pipeline (``prepare_gateway_tools``) rather than\nhere at parse time: the safety check does a DNS lookup, which must be\nawaited so it can't block the event loop, and Pydantic validators run\nsynchronously during request-body parsing.", "properties": { @@ -2903,6 +3017,179 @@ "title": "SetPricingRequest", "type": "object" }, + "StoredProviderResponse": { + "description": "A runtime-stored provider. The API key is never returned, only ``last4``.", + "properties": { + "api_base": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Api Base" + }, + "client_args": { + "additionalProperties": true, + "title": "Client Args", + "type": "object" + }, + "created_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Created At" + }, + "decryptable": { + "default": true, + "title": "Decryptable", + "type": "boolean" + }, + "instance": { + "title": "Instance", + "type": "string" + }, + "last4": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Last4" + }, + "provider_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider Type" + }, + "updated_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Updated At" + } + }, + "required": [ + "instance" + ], + "title": "StoredProviderResponse", + "type": "object" + }, + "TestProviderRequest": { + "description": "Credentials to test before saving (from the add-provider form).", + "properties": { + "api_base": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Api Base" + }, + "api_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Api Key" + }, + "client_args": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Client Args" + }, + "instance": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Provider/instance name; the impl when no provider_type.", + "title": "Instance" + }, + "provider_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider Type" + } + }, + "title": "TestProviderRequest", + "type": "object" + }, + "TestProviderResponse": { + "description": "Result of a live provider connection test.", + "properties": { + "error": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Error" + }, + "model_count": { + "title": "Model Count", + "type": "integer" + }, + "ok": { + "title": "Ok", + "type": "boolean" + } + }, + "required": [ + "ok", + "model_count" + ], + "title": "TestProviderResponse", + "type": "object" + }, "UpdateBudgetRequest": { "description": "Request model for updating a budget.", "properties": { @@ -3013,7 +3300,72 @@ "title": "Model Discovery" } }, - "title": "UpdateSettingsRequest", + "title": "UpdateSettingsRequest", + "type": "object" + }, + "UpdateStoredProviderRequest": { + "description": "Update a stored provider. Omitted fields are unchanged; ``api_key`` rotates in place.", + "properties": { + "api_base": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Api Base" + }, + "api_key": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "New API key. Omit to keep the existing one. Never returned.", + "title": "Api Key" + }, + "client_args": { + "anyOf": [ + { + "additionalProperties": true, + "type": "object" + }, + { + "type": "null" + } + ], + "title": "Client Args" + }, + "expected_updated_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "description": "Optimistic concurrency: if set, the update 412s unless it matches the stored updated_at.", + "title": "Expected Updated At" + }, + "provider_type": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Provider Type" + } + }, + "title": "UpdateStoredProviderRequest", "type": "object" }, "UpdateUserRequest": { @@ -5711,6 +6063,274 @@ ] } }, + "/v1/provider-credentials": { + "get": { + "description": "List runtime-stored providers. Keys are never returned, only ``last4``.", + "operationId": "list_stored_providers_v1_provider_credentials_get", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/StoredProviderResponse" + }, + "title": "Response List Stored Providers V1 Provider Credentials Get", + "type": "array" + } + } + }, + "description": "Successful Response" + } + }, + "security": [ + { + "ApiKeyAuth": [] + } + ], + "summary": "List Stored Providers", + "tags": [ + "providers" + ] + }, + "post": { + "description": "Add a provider at runtime. Storing a key requires OTARI_SECRET_KEY.", + "operationId": "create_stored_provider_v1_provider_credentials_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateStoredProviderRequest" + } + } + }, + "required": true + }, + "responses": { + "201": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StoredProviderResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "security": [ + { + "ApiKeyAuth": [] + } + ], + "summary": "Create Stored Provider", + "tags": [ + "providers" + ] + } + }, + "/v1/provider-credentials/test": { + "post": { + "description": "Test provider credentials without storing them (for the add/edit form).\n\nResolves the implementation from ``provider_type`` (honoring the\n``*-compatible`` aliases) or the ``instance`` name, then lists the provider's\nmodels with the supplied credentials. Nothing is persisted and the key is\nnever echoed.", + "operationId": "test_provider_connection_v1_provider_credentials_test_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TestProviderRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TestProviderResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "security": [ + { + "ApiKeyAuth": [] + } + ], + "summary": "Test Provider Connection", + "tags": [ + "providers" + ] + } + }, + "/v1/provider-credentials/{instance}": { + "delete": { + "description": "Delete a stored provider. A config.yml provider cannot be deleted here.", + "operationId": "delete_stored_provider_v1_provider_credentials__instance__delete", + "parameters": [ + { + "in": "path", + "name": "instance", + "required": true, + "schema": { + "title": "Instance", + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "security": [ + { + "ApiKeyAuth": [] + } + ], + "summary": "Delete Stored Provider", + "tags": [ + "providers" + ] + }, + "patch": { + "description": "Update a stored provider. Omitted fields are left as-is; an explicit ``null`` clears them.\n\n``api_key`` follows the same rule: omit it to keep the stored key, send a new\none to rotate, or send ``null`` to clear it. The row is locked ``FOR UPDATE``\nso the ``expected_updated_at`` check and the write it guards are atomic.", + "operationId": "update_stored_provider_v1_provider_credentials__instance__patch", + "parameters": [ + { + "in": "path", + "name": "instance", + "required": true, + "schema": { + "title": "Instance", + "type": "string" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateStoredProviderRequest" + } + } + }, + "required": true + }, + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/StoredProviderResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "security": [ + { + "ApiKeyAuth": [] + } + ], + "summary": "Update Stored Provider", + "tags": [ + "providers" + ] + } + }, + "/v1/provider-credentials/{instance}/test": { + "post": { + "description": "Verify a stored provider's key by listing its models, without exposing the key.", + "operationId": "test_stored_provider_v1_provider_credentials__instance__test_post", + "parameters": [ + { + "in": "path", + "name": "instance", + "required": true, + "schema": { + "title": "Instance", + "type": "string" + } + } + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TestProviderResponse" + } + } + }, + "description": "Successful Response" + }, + "422": { + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + }, + "description": "Validation Error" + } + }, + "security": [ + { + "ApiKeyAuth": [] + } + ], + "summary": "Test Stored Provider", + "tags": [ + "providers" + ] + } + }, "/v1/providers": { "get": { "description": "List static metadata for every configured provider.\n\nOperator-facing: reports each provider's capabilities, documentation and\npricing links, and display name from the bundled any-llm and genai-prices\ndatasets. No provider is contacted, so this is cheap and always available.\nMaster-key gated because it describes the gateway's own configuration.", @@ -5738,6 +6358,37 @@ ] } }, + "/v1/providers/catalog": { + "get": { + "description": "List every known provider for the add-provider picker.\n\nNetwork-free and config-independent: the full any-llm provider set with each\none's display name, credential env var, default endpoint, and whether it\nneeds a key. Master-key gated because it is operator-facing dashboard data.", + "operationId": "provider_catalog_v1_providers_catalog_get", + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "items": { + "$ref": "#/components/schemas/KnownProviderSchema" + }, + "title": "Response Provider Catalog V1 Providers Catalog Get", + "type": "array" + } + } + }, + "description": "Successful Response" + } + }, + "security": [ + { + "ApiKeyAuth": [] + } + ], + "summary": "Provider Catalog", + "tags": [ + "providers" + ] + } + }, "/v1/rerank": { "post": { "description": "Rerank documents by relevance to a query.\n\nAuthentication modes:\n- Master key + user field: Use specified user (must exist)\n- API key + user field: Use specified user (must exist)\n- API key without user field: Use virtual user created with API key", diff --git a/docs/public/otari.postman_collection.json b/docs/public/otari.postman_collection.json index ce17a28d..f58d2360 100644 --- a/docs/public/otari.postman_collection.json +++ b/docs/public/otari.postman_collection.json @@ -1386,6 +1386,182 @@ }, { "item": [ + { + "name": "List Stored Providers", + "request": { + "description": "List runtime-stored providers. Keys are never returned, only ``last4``.", + "header": [], + "method": "GET", + "url": { + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v1", + "provider-credentials" + ], + "raw": "{{baseUrl}}/v1/provider-credentials" + } + } + }, + { + "name": "Create Stored Provider", + "request": { + "body": { + "mode": "raw", + "options": { + "raw": { + "language": "json" + } + }, + "raw": "{\n \"instance\": \"string\"\n}" + }, + "description": "Add a provider at runtime. Storing a key requires OTARI_SECRET_KEY.", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "method": "POST", + "url": { + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v1", + "provider-credentials" + ], + "raw": "{{baseUrl}}/v1/provider-credentials" + } + } + }, + { + "name": "Test Provider Connection", + "request": { + "body": { + "mode": "raw", + "options": { + "raw": { + "language": "json" + } + }, + "raw": "{\n \"api_base\": \"string\",\n \"api_key\": \"string\",\n \"client_args\": {},\n \"instance\": \"string\",\n \"provider_type\": \"string\"\n}" + }, + "description": "Test provider credentials without storing them (for the add/edit form).\n\nResolves the implementation from ``provider_type`` (honoring the\n``*-compatible`` aliases) or the ``instance`` name, then lists the provider's\nmodels with the supplied credentials. Nothing is persisted and the key is\nnever echoed.", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "method": "POST", + "url": { + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v1", + "provider-credentials", + "test" + ], + "raw": "{{baseUrl}}/v1/provider-credentials/test" + } + } + }, + { + "name": "Update Stored Provider", + "request": { + "body": { + "mode": "raw", + "options": { + "raw": { + "language": "json" + } + }, + "raw": "{\n \"api_base\": \"string\",\n \"api_key\": \"string\",\n \"client_args\": {},\n \"expected_updated_at\": \"string\",\n \"provider_type\": \"string\"\n}" + }, + "description": "Update a stored provider. Omitted fields are left as-is; an explicit ``null`` clears them.\n\n``api_key`` follows the same rule: omit it to keep the stored key, send a new\none to rotate, or send ``null`` to clear it. The row is locked ``FOR UPDATE``\nso the ``expected_updated_at`` check and the write it guards are atomic.", + "header": [ + { + "key": "Content-Type", + "value": "application/json" + } + ], + "method": "PATCH", + "url": { + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v1", + "provider-credentials", + ":instance" + ], + "raw": "{{baseUrl}}/v1/provider-credentials/:instance", + "variable": [ + { + "description": "path parameter", + "key": "instance", + "value": "" + } + ] + } + } + }, + { + "name": "Delete Stored Provider", + "request": { + "description": "Delete a stored provider. A config.yml provider cannot be deleted here.", + "header": [], + "method": "DELETE", + "url": { + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v1", + "provider-credentials", + ":instance" + ], + "raw": "{{baseUrl}}/v1/provider-credentials/:instance", + "variable": [ + { + "description": "path parameter", + "key": "instance", + "value": "" + } + ] + } + } + }, + { + "name": "Test Stored Provider", + "request": { + "description": "Verify a stored provider's key by listing its models, without exposing the key.", + "header": [], + "method": "POST", + "url": { + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v1", + "provider-credentials", + ":instance", + "test" + ], + "raw": "{{baseUrl}}/v1/provider-credentials/:instance/test", + "variable": [ + { + "description": "path parameter", + "key": "instance", + "value": "" + } + ] + } + } + }, { "name": "List Providers", "request": { @@ -1403,6 +1579,25 @@ "raw": "{{baseUrl}}/v1/providers" } } + }, + { + "name": "Provider Catalog", + "request": { + "description": "List every known provider for the add-provider picker.\n\nNetwork-free and config-independent: the full any-llm provider set with each\none's display name, credential env var, default endpoint, and whether it\nneeds a key. Master-key gated because it is operator-facing dashboard data.", + "header": [], + "method": "GET", + "url": { + "host": [ + "{{baseUrl}}" + ], + "path": [ + "v1", + "providers", + "catalog" + ], + "raw": "{{baseUrl}}/v1/providers/catalog" + } + } } ], "name": "providers" diff --git a/pyproject.toml b/pyproject.toml index bf54f7f8..73938a64 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,7 @@ dependencies = [ "aiosqlite>=0.19.0", "asyncpg>=0.29.0", "click>=8.1.0", + "cryptography>=44.0.0", "fastapi>=0.115.0", "genai-prices>=0.0.66", "markitdown[docx,pptx,xlsx,pdf]>=0.1.0", diff --git a/src/gateway/api/deps.py b/src/gateway/api/deps.py index 47775ab9..425e2586 100644 --- a/src/gateway/api/deps.py +++ b/src/gateway/api/deps.py @@ -16,6 +16,7 @@ from gateway.models.entities import APIKey from gateway.services.file_store import FileStore from gateway.services.log_writer import LogWriter +from gateway.services.master_key_service import hash_master_key # Legacy module-level fallback. Config now lives on ``app.state.config`` (set in # ``create_app``); ``get_config`` reads from the request's app state and only @@ -176,8 +177,13 @@ async def _bump_last_used_at(api_key_id: str, now: datetime) -> None: def _is_valid_master_key(token: str, config: GatewayConfig) -> bool: - """Check if token matches the master key.""" - return config.master_key is not None and secrets.compare_digest(token, config.master_key) + """Check if token matches the master key (operator-set plaintext or generated hash).""" + if config.master_key is not None and secrets.compare_digest(token, config.master_key): + return True + stored_hash = config._master_key_hash + if stored_hash is not None: + return secrets.compare_digest(hash_master_key(token), stored_hash) + return False async def verify_api_key( @@ -217,7 +223,7 @@ async def verify_master_key( HTTPException: If master key is not configured or invalid """ - if not config.master_key: + if config.master_key is None and config._master_key_hash is None: raise HTTPException( status_code=status.HTTP_503_SERVICE_UNAVAILABLE, detail="Master key not configured. Set OTARI_MASTER_KEY environment variable.", diff --git a/src/gateway/api/routes/_passthrough.py b/src/gateway/api/routes/_passthrough.py index 31542617..7227d882 100644 --- a/src/gateway/api/routes/_passthrough.py +++ b/src/gateway/api/routes/_passthrough.py @@ -39,7 +39,11 @@ reserve_budget, ) from gateway.services.log_writer import LogWriter -from gateway.services.pricing_service import find_model_pricing, pricing_required_but_missing +from gateway.services.pricing_service import ( + find_model_pricing, + no_pricing_error_detail, + pricing_required_but_missing, +) from gateway.services.provider_kwargs import ResolvedProvider, resolve_provider_selector ResultT = TypeVar("ResultT") @@ -182,7 +186,7 @@ async def run_passthrough( await refund_reservation(db, reservation) raise HTTPException( status_code=status.HTTP_402_PAYMENT_REQUIRED, - detail=f"No pricing configured for model '{model}'", + detail=no_pricing_error_detail(model), ) try: diff --git a/src/gateway/api/routes/_pipeline.py b/src/gateway/api/routes/_pipeline.py index 2f158f60..32fa1e60 100644 --- a/src/gateway/api/routes/_pipeline.py +++ b/src/gateway/api/routes/_pipeline.py @@ -105,7 +105,11 @@ MaxToolIterationsExceeded, ToolBackend, ) -from gateway.services.pricing_service import find_model_pricing, pricing_required_but_missing +from gateway.services.pricing_service import ( + find_model_pricing, + no_pricing_error_detail, + pricing_required_but_missing, +) from gateway.services.provider_kwargs import ResolvedProvider, resolve_provider_selector from gateway.services.sandbox_backend import SandboxBackend, SandboxNotReachableError from gateway.services.url_safety import UnsafeURLError, validate_mcp_url @@ -579,7 +583,7 @@ async def resolve_request_context( await refund_reservation(db, reservation) raise adapter.error( 402, - f"No pricing configured for model '{model}'", + no_pricing_error_detail(model), ErrorKind.INVALID_REQUEST, ) diff --git a/src/gateway/api/routes/providers.py b/src/gateway/api/routes/providers.py index 1d77e8be..52ba5b3a 100644 --- a/src/gateway/api/routes/providers.py +++ b/src/gateway/api/routes/providers.py @@ -1,13 +1,49 @@ -"""Static provider metadata for the operator dashboard.""" +"""Provider metadata and runtime provider-credential management for the dashboard. -from typing import Annotated +The ``/v1/providers`` endpoint reports static, network-free metadata for every +configured provider. The ``/v1/provider-credentials`` endpoints manage the +``provider_credentials`` table: providers an operator adds at runtime through the +dashboard, encrypted at rest and merged over config.yml providers. All routes are +master-key gated and standalone-mode only (the router is not mounted in hybrid). +""" -from fastapi import APIRouter, Depends +from typing import Annotated, Any + +from any_llm import LLMProvider +from fastapi import APIRouter, Depends, HTTPException, status from pydantic import BaseModel, Field +from sqlalchemy.exc import IntegrityError, SQLAlchemyError +from sqlalchemy.ext.asyncio import AsyncSession -from gateway.api.deps import get_config, verify_master_key -from gateway.core.config import GatewayConfig -from gateway.services.provider_metadata_service import ProviderInfo, list_provider_info +from gateway.api.deps import get_config, get_db, verify_master_key +from gateway.core.config import PROVIDER_TYPE_ALIASES, GatewayConfig +from gateway.log_config import logger +from gateway.models.entities import ProviderCredential +from gateway.services.model_discovery_service import ( + discover_provider_models, + get_model_cache, + test_provider_credentials, +) +from gateway.services.provider_metadata_service import ( + KnownProvider, + ProviderInfo, + list_known_providers, + list_provider_info, +) +from gateway.services.provider_store_service import ( + UNSET, + delete_credential, + get_credential, + get_credential_for_update, + list_credentials, + refresh_provider_cache, + save_credential, +) +from gateway.services.secret_box import ( + SecretBoxUnavailableError, + SecretDecryptionError, + decrypt_secret, +) router = APIRouter(prefix="/v1", tags=["providers"]) @@ -85,3 +121,327 @@ async def list_providers( Master-key gated because it describes the gateway's own configuration. """ return ProvidersResponse(providers=[_to_schema(info) for info in list_provider_info(config)]) + + +class KnownProviderSchema(BaseModel): + """A provider the add-provider picker can offer, with autofill hints.""" + + id: str = Field(description="any-llm provider id, used as the default instance name.") + name: str = Field(description="Human-friendly display name.") + env_key: str | None = Field(default=None, description="Env var the SDK reads this provider's key from.") + default_api_base: str | None = Field(default=None, description="Built-in endpoint; blank means the SDK's default.") + requires_api_key: bool = Field(description="False for keyless local backends (Ollama, llama.cpp).") + + +def _to_known_schema(provider: KnownProvider) -> KnownProviderSchema: + return KnownProviderSchema( + id=provider.id, + name=provider.name, + env_key=provider.env_key, + default_api_base=provider.default_api_base, + requires_api_key=provider.requires_api_key, + ) + + +@router.get("/providers/catalog", dependencies=[Depends(verify_master_key)]) +async def provider_catalog() -> list[KnownProviderSchema]: + """List every known provider for the add-provider picker. + + Network-free and config-independent: the full any-llm provider set with each + one's display name, credential env var, default endpoint, and whether it + needs a key. Master-key gated because it is operator-facing dashboard data. + """ + return [_to_known_schema(provider) for provider in list_known_providers()] + + +# --------------------------------------------------------------------------- # +# Runtime provider-credential management (/v1/provider-credentials) +# --------------------------------------------------------------------------- # + + +class StoredProviderResponse(BaseModel): + """A runtime-stored provider. The API key is never returned, only ``last4``.""" + + instance: str + provider_type: str | None = None + api_base: str | None = None + last4: str | None = None + client_args: dict[str, Any] = Field(default_factory=dict) + created_at: str | None = None + updated_at: str | None = None + # False when the stored key cannot be decrypted with the current + # OTARI_SECRET_KEY (e.g. the key was rotated or lost). Such a provider is + # skipped at runtime, so the dashboard flags it for the operator to fix. + decryptable: bool = True + + @classmethod + def from_model(cls, row: ProviderCredential, *, decryptable: bool = True) -> "StoredProviderResponse": + return cls(**row.to_public_dict(), decryptable=decryptable) + + +def _is_decryptable(row: ProviderCredential) -> bool: + """Whether the row's stored key can be read with the current OTARI_SECRET_KEY.""" + if not row.encrypted_api_key: + return True + try: + decrypt_secret(row.encrypted_api_key) + except (SecretBoxUnavailableError, SecretDecryptionError): + return False + return True + + +class CreateStoredProviderRequest(BaseModel): + """Create a stored provider. ``api_key`` is write-only and requires OTARI_SECRET_KEY.""" + + instance: str = Field(min_length=1, description="Routing key, e.g. 'openai' or a named instance like 'home_lab'.") + provider_type: str | None = Field( + default=None, + description="any-llm implementation when the instance name is not itself one.", + ) + api_base: str | None = None + api_key: str | None = Field(default=None, description="Provider API key. Stored encrypted; never returned.") + client_args: dict[str, Any] | None = None + + +class UpdateStoredProviderRequest(BaseModel): + """Update a stored provider. Omitted fields are unchanged; ``api_key`` rotates in place.""" + + provider_type: str | None = None + api_base: str | None = None + api_key: str | None = Field(default=None, description="New API key. Omit to keep the existing one. Never returned.") + client_args: dict[str, Any] | None = None + expected_updated_at: str | None = Field( + default=None, + description="Optimistic concurrency: if set, the update 412s unless it matches the stored updated_at.", + ) + + +class TestProviderResponse(BaseModel): + """Result of a live provider connection test.""" + + ok: bool + model_count: int + error: str | None = None + + +class TestProviderRequest(BaseModel): + """Credentials to test before saving (from the add-provider form).""" + + instance: str | None = Field(default=None, description="Provider/instance name; the impl when no provider_type.") + provider_type: str | None = None + api_base: str | None = None + api_key: str | None = None + client_args: dict[str, Any] | None = None + + +def _validate_instance(instance: str, provider_type: str | None) -> None: + """Reject an unroutable instance name or an unknown provider_type, as a 400.""" + if not instance.strip(): + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="Provider instance name must not be blank.", + ) + if ":" in instance or "/" in instance: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="Provider instance name must not contain ':' or '/'.", + ) + if provider_type: + impl = PROVIDER_TYPE_ALIASES.get(provider_type, provider_type) + try: + LLMProvider(impl) + except ValueError as exc: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail=f"provider_type '{provider_type}' is not a known provider implementation.", + ) from exc + + +async def _commit(db: AsyncSession, *, conflict_detail: str | None = None) -> None: + try: + await db.commit() + except IntegrityError: + # A concurrent create can slip past the pre-check and collide on the + # primary key here; surface that as the intended 409, not a 500. + await db.rollback() + if conflict_detail is not None: + raise HTTPException(status_code=status.HTTP_409_CONFLICT, detail=conflict_detail) from None + raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail="Database error") from None + except SQLAlchemyError: + await db.rollback() + raise HTTPException( + status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, + detail="Database error", + ) from None + + +async def _apply_write(db: AsyncSession, config: GatewayConfig, instance: str) -> None: + """Make a committed credential change take effect on this worker. + + Clears the model-discovery cache for the instance (a stale listing would + otherwise survive a key change) and re-merges the overlay. The write is + already committed, so a refresh failure is logged, not surfaced as a 500; + other workers converge within the TTL. + """ + get_model_cache().clear(instance) + try: + await refresh_provider_cache(db, config) + except SQLAlchemyError: + logger.warning("Provider overlay refresh failed after writing '%s'; converges within TTL", instance) + + +@router.post("/provider-credentials/test", dependencies=[Depends(verify_master_key)]) +async def test_provider_connection(request: TestProviderRequest) -> TestProviderResponse: + """Test provider credentials without storing them (for the add/edit form). + + Resolves the implementation from ``provider_type`` (honoring the + ``*-compatible`` aliases) or the ``instance`` name, then lists the provider's + models with the supplied credentials. Nothing is persisted and the key is + never echoed. + """ + impl = ( + PROVIDER_TYPE_ALIASES.get(request.provider_type, request.provider_type) + if request.provider_type + else (request.instance or "") + ) + if not impl: + raise HTTPException( + status_code=status.HTTP_400_BAD_REQUEST, + detail="Provide a provider or a provider type to test.", + ) + result = await test_provider_credentials( + impl, + api_key=request.api_key, + api_base=request.api_base, + client_args=request.client_args, + ) + return TestProviderResponse(ok=result.error is None, model_count=len(result.models), error=result.error) + + +@router.get("/provider-credentials", dependencies=[Depends(verify_master_key)]) +async def list_stored_providers( + db: Annotated[AsyncSession, Depends(get_db)], +) -> list[StoredProviderResponse]: + """List runtime-stored providers. Keys are never returned, only ``last4``.""" + return [ + StoredProviderResponse.from_model(row, decryptable=_is_decryptable(row)) for row in await list_credentials(db) + ] + + +@router.post("/provider-credentials", status_code=status.HTTP_201_CREATED, dependencies=[Depends(verify_master_key)]) +async def create_stored_provider( + request: CreateStoredProviderRequest, + db: Annotated[AsyncSession, Depends(get_db)], + config: Annotated[GatewayConfig, Depends(get_config)], +) -> StoredProviderResponse: + """Add a provider at runtime. Storing a key requires OTARI_SECRET_KEY.""" + _validate_instance(request.instance, request.provider_type) + if await get_credential(db, request.instance) is not None: + raise HTTPException( + status_code=status.HTTP_409_CONFLICT, + detail=f"A stored provider '{request.instance}' already exists; use PATCH to update it.", + ) + try: + row = await save_credential( + db, + instance=request.instance, + provider_type=request.provider_type, + api_base=request.api_base, + api_key=request.api_key, + client_args=request.client_args, + ) + except SecretBoxUnavailableError as exc: + raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from None + + await _commit( + db, + conflict_detail=f"A stored provider '{request.instance}' already exists; use PATCH to update it.", + ) + if request.instance in (config._provider_baseline or {}): + logger.warning( + "Stored provider '%s' shadows the config.yml provider of the same name; the stored credential now wins.", + request.instance, + ) + await _apply_write(db, config, request.instance) + await db.refresh(row) + return StoredProviderResponse.from_model(row) + + +@router.patch("/provider-credentials/{instance}", dependencies=[Depends(verify_master_key)]) +async def update_stored_provider( + instance: str, + request: UpdateStoredProviderRequest, + db: Annotated[AsyncSession, Depends(get_db)], + config: Annotated[GatewayConfig, Depends(get_config)], +) -> StoredProviderResponse: + """Update a stored provider. Omitted fields are left as-is; an explicit ``null`` clears them. + + ``api_key`` follows the same rule: omit it to keep the stored key, send a new + one to rotate, or send ``null`` to clear it. The row is locked ``FOR UPDATE`` + so the ``expected_updated_at`` check and the write it guards are atomic. + """ + existing = await get_credential_for_update(db, instance) + if existing is None: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"No stored provider '{instance}'.") + if request.expected_updated_at is not None: + current = existing.updated_at.isoformat() if existing.updated_at else None + if current != request.expected_updated_at: + raise HTTPException( + status_code=status.HTTP_412_PRECONDITION_FAILED, + detail="This provider was modified since you loaded it; reload and retry.", + ) + _validate_instance(instance, request.provider_type) + # Distinguish "field omitted" (keep) from "field set to null" (clear). + sent = request.model_fields_set + try: + row = await save_credential( + db, + instance=instance, + provider_type=request.provider_type if "provider_type" in sent else UNSET, + api_base=request.api_base if "api_base" in sent else UNSET, + api_key=request.api_key if "api_key" in sent else UNSET, + client_args=request.client_args if "client_args" in sent else UNSET, + ) + except SecretBoxUnavailableError as exc: + raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=str(exc)) from None + + await _commit(db) + await _apply_write(db, config, instance) + await db.refresh(row) + return StoredProviderResponse.from_model(row) + + +@router.delete( + "/provider-credentials/{instance}", + status_code=status.HTTP_204_NO_CONTENT, + dependencies=[Depends(verify_master_key)], +) +async def delete_stored_provider( + instance: str, + db: Annotated[AsyncSession, Depends(get_db)], + config: Annotated[GatewayConfig, Depends(get_config)], +) -> None: + """Delete a stored provider. A config.yml provider cannot be deleted here.""" + if not await delete_credential(db, instance): + detail = f"No stored provider '{instance}'." + if instance in (config._provider_baseline or {}): + detail = f"Provider '{instance}' is defined in config.yml and cannot be deleted through the API." + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=detail) + await _commit(db) + await _apply_write(db, config, instance) + + +@router.post("/provider-credentials/{instance}/test", dependencies=[Depends(verify_master_key)]) +async def test_stored_provider( + instance: str, + db: Annotated[AsyncSession, Depends(get_db)], + config: Annotated[GatewayConfig, Depends(get_config)], +) -> TestProviderResponse: + """Verify a stored provider's key by listing its models, without exposing the key.""" + if await get_credential(db, instance) is None: + raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail=f"No stored provider '{instance}'.") + # Make sure the just-stored credential is merged, then force a live check + # rather than trusting a cached listing from before a key change. + await _apply_write(db, config, instance) + result = await discover_provider_models(config, instance) + return TestProviderResponse(ok=result.error is None, model_count=len(result.models), error=result.error) diff --git a/src/gateway/cli.py b/src/gateway/cli.py index ea74c8f7..b4230240 100644 --- a/src/gateway/cli.py +++ b/src/gateway/cli.py @@ -125,11 +125,11 @@ def serve( ) logger.info("Hybrid mode active. Base URL: %s", platform_base_url) - if not gateway_config.master_key: - logger.warning( - "No master key configured. Key management endpoints will be unavailable.", + if not gateway_config.master_key and not gateway_config.is_hybrid_mode: + logger.info( + "No master key configured; one will be generated and printed at startup. " + "Set OTARI_MASTER_KEY (or --master-key) to choose your own instead.", ) - logger.warning("Set OTARI_MASTER_KEY environment variable or use --master-key flag.") logger.info("Starting Otari on %s:%s", gateway_config.host, gateway_config.port) if gateway_config.is_hybrid_mode: @@ -213,6 +213,19 @@ def migrate(config: str | None, database_url: str | None, revision: str) -> None sys.exit(1) +@cli.command(name="gen-secret-key") +def gen_secret_key() -> None: + """Print a fresh OTARI_SECRET_KEY for encrypting stored provider credentials. + + Set the printed value as OTARI_SECRET_KEY before adding provider keys in the + dashboard. Keep it safe: losing it makes every stored provider key + undecryptable. + """ + from gateway.services.secret_box import generate_secret_key + + click.echo(generate_secret_key()) + + def main() -> None: """Entry point for the CLI.""" cli() diff --git a/src/gateway/core/config.py b/src/gateway/core/config.py index e6befa3e..0b1f355d 100644 --- a/src/gateway/core/config.py +++ b/src/gateway/core/config.py @@ -22,6 +22,8 @@ PROVIDER_TYPE_ALIASES = { "openai-compatible": "openai", "openai_compatible": "openai", + "anthropic-compatible": "anthropic", + "anthropic_compatible": "anthropic", } LEGACY_API_KEY_HEADERS = ("AnyLLM-Key", "X-AnyLLM-Key") # Back-compat aliases; prefer API_KEY_HEADER. DEFAULT_PLATFORM_BASE_URL = "https://api.otari.ai/api/v1" @@ -439,6 +441,20 @@ class GatewayConfig(BaseSettings): _platform_token: str | None = PrivateAttr(default=None) _platform_token_resolved: bool = PrivateAttr(default=False) + # The config-file providers as loaded, before any dashboard-stored providers + # are overlaid onto ``providers`` at runtime. Captured once by + # ``provider_store_service`` so every refresh rebuilds the merged view from a + # stable base (and a deleted stored row restores the config entry). Kept on + # the config, not a module global, so it is per-config and cannot leak + # between processes or tests. + _provider_baseline: dict[str, dict[str, Any]] | None = PrivateAttr(default=None) + + # SHA-256 hash of a master key generated on first run (see + # ``master_key_service``). Set at startup when no ``master_key`` is + # configured, so ``verify_master_key`` can authenticate the generated key + # without the plaintext ever living in config. + _master_key_hash: str | None = PrivateAttr(default=None) + def _resolve_platform_token(self) -> str | None: if not self._platform_token_resolved: self._platform_token = _get_platform_token_from_env() diff --git a/src/gateway/main.py b/src/gateway/main.py index 5616407a..bed8ea1d 100644 --- a/src/gateway/main.py +++ b/src/gateway/main.py @@ -21,11 +21,17 @@ from gateway.services.bootstrap_service import bootstrap_first_api_key from gateway.services.file_store import build_file_store from gateway.services.log_writer import LogWriter, NoopLogWriter, create_log_writer +from gateway.services.master_key_service import ensure_master_key from gateway.services.pricing_init_service import ( initialize_pricing_from_config, warn_if_require_pricing_without_pricing, ) from gateway.services.pricing_service import configure_default_pricing +from gateway.services.provider_store_service import ( + load_providers_at_startup, + reset_provider_cache, + run_provider_refresher, +) from gateway.services.runtime_settings_service import apply_overrides_from_db from gateway.version import __version__ @@ -87,6 +93,7 @@ async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: configure_default_pricing(config.default_pricing) log_writer: LogWriter alias_refresher: asyncio.Task[None] | None = None + provider_refresher: asyncio.Task[None] | None = None if config.is_hybrid_mode: log_writer = NoopLogWriter() else: @@ -95,6 +102,14 @@ async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: # Persisted dashboard overrides win over config/env; apply them # before pricing init so default-pricing behavior is consistent. await apply_overrides_from_db(config, session) + # Generate + persist a master key on first run when none is set, + # so the dashboard is reachable without hand-editing config, and + # the management API is never left unauthenticated. + await ensure_master_key(config, session) + # Overlay dashboard-stored providers before pricing init, so a + # provider added at runtime is visible to everything that reads + # config.providers (pricing seeding, discovery, dispatch). + await load_providers_at_startup(session, config) await bootstrap_first_api_key(config, session) await initialize_pricing_from_config(config, session) await warn_if_require_pricing_without_pricing(config, session) @@ -105,6 +120,10 @@ async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: # to reload it. A write refreshes its own worker; this is what makes # every other worker and replica catch up. alias_refresher = asyncio.create_task(run_alias_refresher()) + # Provider credentials are the same shape: resolution reads + # config.providers synchronously, so the overlay is reloaded on a TTL + # to converge sibling workers and replicas after a dashboard write. + provider_refresher = asyncio.create_task(run_provider_refresher(config)) await log_writer.start() app.state.log_writer = log_writer @@ -117,6 +136,11 @@ async def lifespan(app: FastAPI) -> AsyncGenerator[None, None]: with suppress(asyncio.CancelledError): await alias_refresher reset_alias_cache() + if provider_refresher is not None: + provider_refresher.cancel() + with suppress(asyncio.CancelledError): + await provider_refresher + reset_provider_cache() await log_writer.stop() return lifespan diff --git a/src/gateway/models/entities.py b/src/gateway/models/entities.py index 29e0ba07..7ba26cb1 100644 --- a/src/gateway/models/entities.py +++ b/src/gateway/models/entities.py @@ -183,6 +183,45 @@ class RuntimeSetting(Base): ) +class ProviderCredential(Base): + """A provider instance configured at runtime through the dashboard. + + The database counterpart of a ``providers:`` entry in config.yml: it is + merged over the config-file providers at runtime (see + ``provider_store_service``), with the stored row winning on an instance-name + collision. The API key is held encrypted (``secret_box``); ``last4`` is kept + in clear only so the UI can show which key is set without ever decrypting. + Standalone mode only, never used in the hybrid platform path. + """ + + __tablename__ = "provider_credentials" + + instance: Mapped[str] = mapped_column(primary_key=True) + provider_type: Mapped[str | None] = mapped_column() + api_base: Mapped[str | None] = mapped_column() + encrypted_api_key: Mapped[str | None] = mapped_column() + last4: Mapped[str | None] = mapped_column() + client_args: Mapped[dict[str, Any]] = mapped_column("client_args", JSON, default=dict) + created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), default=lambda: datetime.now(UTC)) + updated_at: Mapped[datetime] = mapped_column( + DateTime(timezone=True), + default=lambda: datetime.now(UTC), + onupdate=lambda: datetime.now(UTC), + ) + + def to_public_dict(self) -> dict[str, Any]: + """Serialize for the API. Never includes the secret, only ``last4``.""" + return { + "instance": self.instance, + "provider_type": self.provider_type, + "api_base": self.api_base, + "last4": self.last4, + "client_args": self.client_args or {}, + "created_at": self.created_at.isoformat() if self.created_at else None, + "updated_at": self.updated_at.isoformat() if self.updated_at else None, + } + + class ModelPricing(Base): """Model pricing configuration.""" diff --git a/src/gateway/services/master_key_service.py b/src/gateway/services/master_key_service.py new file mode 100644 index 00000000..3ac0ea68 --- /dev/null +++ b/src/gateway/services/master_key_service.py @@ -0,0 +1,97 @@ +"""First-run master-key bootstrap. + +When no master key is configured (no ``OTARI_MASTER_KEY`` / config value), the +gateway generates one on first launch, stores only its SHA-256 hash, and prints +the plaintext once so the operator can sign in to the dashboard. This makes +"launch with almost nothing" real without leaving the management API +unauthenticated: the generated key gates every management route exactly like an +operator-set one, and there is no unauthenticated setup route to race. + +An operator-provided key always wins and is never generated over. The hash is +kept in the ``runtime_settings`` key/value table (the flag logic ignores keys it +does not know), so no new table is needed. The plaintext is never stored or +logged after the one-time banner. +""" + +import hashlib +import secrets + +from sqlalchemy.exc import SQLAlchemyError +from sqlalchemy.ext.asyncio import AsyncSession + +from gateway.core.config import GatewayConfig +from gateway.log_config import log_secret, logger +from gateway.models.entities import RuntimeSetting + +# Stored in runtime_settings; ignored by runtime_settings_service (not a SETTABLE_KEY). +MASTER_KEY_HASH_KEY = "master_key_hash" +_MASTER_KEY_PREFIX = "otari-mk-" + + +def generate_master_key() -> str: + """Return a fresh, high-entropy master key with a recognizable prefix.""" + return f"{_MASTER_KEY_PREFIX}{secrets.token_urlsafe(32)}" + + +def hash_master_key(token: str) -> str: + """SHA-256 hex of a master key. + + Deliberately not ``auth.hash_key``, which validates the ``gw-`` API-key + format; a master key has its own shape. + """ + return hashlib.sha256(token.encode()).hexdigest() + + +async def _load_hash(session: AsyncSession) -> str | None: + row = await session.get(RuntimeSetting, MASTER_KEY_HASH_KEY) + return row.value if row else None + + +async def ensure_master_key(config: GatewayConfig, session: AsyncSession) -> None: + """Make sure a master key exists, generating and printing one on first run. + + - Operator-set key (``config.master_key``): used as-is, nothing generated. + - Previously generated key: its hash is loaded so the stored key keeps working + across restarts (idempotent, no second banner). + - Neither: generate one, persist its hash, print it once, and enable the + hash-compare auth path. + + A persistence failure is logged, not raised: the gateway still serves + inference; only the management API stays locked until a key is available. + """ + if config.master_key: + return + try: + existing = await _load_hash(session) + if existing: + config._master_key_hash = existing + return + token = generate_master_key() + hashed = hash_master_key(token) + session.add(RuntimeSetting(key=MASTER_KEY_HASH_KEY, value=hashed)) + await session.commit() + config._master_key_hash = hashed + _print_banner(config, token) + except SQLAlchemyError: + await session.rollback() + # With several workers/replicas on a shared DB, all of them see no hash + # on first run and race to INSERT; the losers land here on the duplicate + # primary key. Adopt the winner's hash instead of returning with the + # management API locked at 503 (and never print a second, dead banner). + existing = await _load_hash(session) + if existing: + config._master_key_hash = existing + return + logger.warning("Could not persist a generated master key; the management API stays locked until one is set.") + + +def _print_banner(config: GatewayConfig, token: str) -> None: + host = "localhost" if config.host in ("0.0.0.0", "::", "") else config.host + url = f"http://{host}:{config.port}/" + bar = "=" * 64 + logger.warning(bar) + logger.warning("Otari first-run: no master key was set, so one was generated.") + logger.warning("Save it now (it is shown only once). Sign in to the dashboard at %s", url) + log_secret("Your master key:", token) + logger.warning("To choose your own instead, set OTARI_MASTER_KEY and restart.") + logger.warning(bar) diff --git a/src/gateway/services/model_discovery_service.py b/src/gateway/services/model_discovery_service.py index f2226bb4..9dc7e5f0 100644 --- a/src/gateway/services/model_discovery_service.py +++ b/src/gateway/services/model_discovery_service.py @@ -183,13 +183,58 @@ async def discover_provider_models(config: GatewayConfig, instance: str) -> Prov try: _, models = await _discover_for_provider(instance, config) except Exception as exc: - logger.info("Model discovery failed for instance '%s': %s", instance, exc) + # Log the class only, never str(exc): some providers echo a partial key + # or endpoint in the message. The capped text still reaches the + # master-key caller in the response, where it is a useful diagnostic. + logger.info("Model discovery failed for instance '%s' (%s)", instance, type(exc).__name__) return ProviderDiscovery(provider=instance, models=[], error=_short_error(exc)) cache.set(instance, models) return ProviderDiscovery(provider=instance, models=models) +async def test_provider_credentials( + impl_name: str, + *, + api_key: str | None = None, + api_base: str | None = None, + client_args: dict[str, object] | None = None, +) -> ProviderDiscovery: + """List models for ad-hoc credentials without storing them. + + Backs the dashboard's "test connection" before a provider is saved. Reports + failure rather than raising, and never echoes the api key (only sanitized, + capped provider errors, which may include the api_base but never the key). + """ + if not _supports_list_models(impl_name): + return ProviderDiscovery( + provider=impl_name, + models=[], + error=f"Provider '{impl_name}' cannot list models, so a connection cannot be verified this way.", + ) + try: + provider_enum = LLMProvider(impl_name) + except ValueError: + return ProviderDiscovery( + provider=impl_name, + models=[], + error=f"'{impl_name}' is not a known provider implementation.", + ) + try: + models = await alist_models( + provider=provider_enum, + api_key=api_key, + api_base=api_base, + client_args=client_args, + ) + except Exception as exc: + # Class only in the log (see discover_provider_models); the capped + # message still goes back to the master-key caller who owns the key. + logger.info("Provider connection test failed for '%s' (%s)", impl_name, type(exc).__name__) + return ProviderDiscovery(provider=impl_name, models=[], error=_short_error(exc)) + return ProviderDiscovery(provider=impl_name, models=list(models)) + + async def discover_models_with_status(config: GatewayConfig) -> list[ProviderDiscovery]: """Discover every configured instance's models concurrently, keeping errors. diff --git a/src/gateway/services/pricing_service.py b/src/gateway/services/pricing_service.py index 29eb4e16..46bcd3dd 100644 --- a/src/gateway/services/pricing_service.py +++ b/src/gateway/services/pricing_service.py @@ -303,3 +303,18 @@ def pricing_required_but_missing(pricing: ModelPricing | None, *, require_pricin (the request is served and logged without cost). """ return pricing is None and require_pricing + + +def no_pricing_error_detail(model: str) -> str: + """The 402 body for an unpriced model: what went wrong, why, and how to fix it. + + A new operator adding a provider in the dashboard hits this on their first + request; the cause and both fixes live only in a startup log they never see, + so spell them out in the response. + """ + return ( + f"No pricing is configured for model '{model}', and require_pricing is on, so it cannot be billed. " + "Fix it either way: add pricing (POST /v1/pricing, or the pricing section of config.yml), " + 'or enable the default-pricing fallback (PATCH /v1/settings {"default_pricing": true}) ' + "to meter with public list prices." + ) diff --git a/src/gateway/services/provider_kwargs.py b/src/gateway/services/provider_kwargs.py index 19aeaca0..8c7c570a 100644 --- a/src/gateway/services/provider_kwargs.py +++ b/src/gateway/services/provider_kwargs.py @@ -13,6 +13,7 @@ from typing import Any from any_llm import AnyLLM, LLMProvider +from any_llm.exceptions import AnyLLMError from gateway.auth.vertex_auth import setup_vertex_environment from gateway.core.config import GatewayConfig @@ -171,6 +172,10 @@ def normalize_pricing_key(config: GatewayConfig, raw_key: str) -> str: return f"{split[0]}:{split[1]}" try: provider, model = AnyLLM.split_model_provider(raw_key) - except ValueError: + # AnyLLMError (UnsupportedProviderError) fires when the prefix is an instance + # name that is no longer configured, e.g. a pricing row left behind after its + # stored provider was removed or could not be decrypted. Return it unchanged + # rather than 500 the whole listing. + except (ValueError, AnyLLMError): return raw_key return f"{provider.value}:{model}" diff --git a/src/gateway/services/provider_metadata_service.py b/src/gateway/services/provider_metadata_service.py index 93e70509..614effb1 100644 --- a/src/gateway/services/provider_metadata_service.py +++ b/src/gateway/services/provider_metadata_service.py @@ -17,7 +17,7 @@ from dataclasses import dataclass, field -from any_llm import AnyLLM +from any_llm import AnyLLM, LLMProvider from gateway.core.config import GatewayConfig from gateway.log_config import logger @@ -141,3 +141,48 @@ def list_provider_info(config: GatewayConfig) -> list[ProviderInfo]: (provider_info(config, instance) for instance in config.providers), key=lambda info: info.instance, ) + + +@dataclass +class KnownProvider: + """One any-llm provider the add-provider picker can offer.""" + + id: str + name: str + env_key: str | None = None + default_api_base: str | None = None + requires_api_key: bool = True + + +def list_known_providers() -> list[KnownProvider]: + """Every any-llm provider offered in the add-provider picker, by display name. + + Network-free: display name, credential env var, and default endpoint come + from the bundled any-llm and genai-prices datasets. A provider whose class + cannot be imported (a missing optional dependency) is skipped rather than + failing the whole listing. + """ + result: list[KnownProvider] = [] + for provider in LLMProvider: + pid = provider.value + try: + cls = AnyLLM.get_provider_class(pid) + meta = cls.get_provider_metadata() + except Exception as exc: + logger.debug("skipping provider %r in catalog: %s", pid, exc) + continue + gp = _genai_provider(pid) + name = _clean(getattr(gp, "name", None)) or _clean(getattr(meta, "name", None)) or pid + raw_env = _clean(getattr(meta, "env_key", None)) + # any-llm uses the literal string "None" for keyless backends (Ollama, llama.cpp). + env_key = None if raw_env in (None, "None") else raw_env + result.append( + KnownProvider( + id=pid, + name=name, + env_key=env_key, + default_api_base=_clean(getattr(cls, "API_BASE", None)), + requires_api_key=env_key is not None, + ) + ) + return sorted(result, key=lambda provider: provider.name.lower()) diff --git a/src/gateway/services/provider_store_service.py b/src/gateway/services/provider_store_service.py new file mode 100644 index 00000000..d0e75a26 --- /dev/null +++ b/src/gateway/services/provider_store_service.py @@ -0,0 +1,263 @@ +"""Runtime provider credentials: dashboard-configured providers, merged over config. + +A provider instance can come from two places. ``config.yml`` providers are +immutable at runtime and validated at startup; ``provider_credentials`` rows are +written through the dashboard. Both mean the same thing to a request, so the +dispatch path must see them merged. + +Resolution has to stay synchronous. ``get_provider_kwargs`` and +``resolve_provider_selector`` read ``config.providers`` directly and are called +from the streaming hot path, which has no database session. So stored providers +are overlaid onto ``config.providers`` in memory: loaded at startup, refreshed +on a TTL (like the alias cache), and re-applied immediately on the worker that +served a write. A stored row wins over a config-file entry of the same instance +name, and that shadowing is logged at startup so it is never silent. + +The API key is held encrypted; it is decrypted here only to build the in-memory +overlay. A row whose key cannot be decrypted (no or wrong ``OTARI_SECRET_KEY``) +is skipped with a warning rather than crashing the gateway. Standalone mode +only: the caller must not load or refresh this in the hybrid platform path. +""" + +import asyncio +import time +from typing import Any, Final + +from sqlalchemy import select +from sqlalchemy.ext.asyncio import AsyncSession + +from gateway.core.config import GatewayConfig +from gateway.core.database import create_session +from gateway.log_config import logger +from gateway.models.entities import ProviderCredential +from gateway.services.secret_box import ( + SecretBoxUnavailableError, + SecretDecryptionError, + decrypt_secret, + encrypt_secret, +) + +# How long a worker may serve a stale provider overlay before refreshing. A newly +# added or edited provider takes at most this long to reach every replica; +# providers already serving traffic are unaffected. +PROVIDER_CACHE_TTL_SECONDS = 30.0 + + +class _Unset: + """Sentinel type: 'this field was not provided', distinct from an explicit None.""" + + +# A field left at UNSET keeps its stored value; passing None clears it. This lets +# a PATCH distinguish "leave the api_base alone" from "remove the api_base". +UNSET: Final = _Unset() + +# instance -> decrypted overlay entry (the same shape as a config.providers value) +_cache: dict[str, dict[str, Any]] = {} +_cached_at: float | None = None +# The config-file baseline lives on the config object (config._provider_baseline), +# captured once, so it is per-config and survives a cache reset without being +# re-derived from an already-merged providers map. + + +def _last4(api_key: str | None) -> str | None: + if not api_key: + return None + return api_key[-4:] + + +def _row_to_entry(row: ProviderCredential) -> dict[str, Any]: + """Build a config.providers-shaped overlay entry from a stored row. + + Raises ``SecretBoxUnavailableError`` / ``SecretDecryptionError`` when the row + has a key that cannot be decrypted; the caller decides whether to skip it. + """ + entry: dict[str, Any] = {} + if row.provider_type: + entry["provider_type"] = row.provider_type + if row.api_base: + entry["api_base"] = row.api_base + if row.client_args: + entry["client_args"] = dict(row.client_args) + if row.encrypted_api_key: + entry["api_key"] = decrypt_secret(row.encrypted_api_key) + return entry + + +def cached_providers() -> dict[str, dict[str, Any]]: + """The stored provider overlay this worker last loaded (decrypted).""" + return {name: dict(entry) for name, entry in _cache.items()} + + +def cache_is_stale(ttl: float = PROVIDER_CACHE_TTL_SECONDS) -> bool: + """Whether the cache has never been loaded or has outlived ``ttl``.""" + return _cached_at is None or (time.monotonic() - _cached_at) >= ttl + + +def reset_provider_cache() -> None: + """Drop the overlay cache so the next load starts clean (startup, tests). + + The config-file baseline lives on the config object, so it is not touched + here; a fresh config starts with an empty baseline of its own. + """ + global _cached_at # noqa: PLW0603 + + _cache.clear() + _cached_at = None + + +def apply_to_config(config: GatewayConfig) -> set[str]: + """Rebuild ``config.providers`` as config-file providers overlaid by the cache. + + Captures the config-file providers as the per-config baseline on first call + (before any overlay), so repeated applies stay idempotent and a removed + stored row restores the config entry even after a cache reset. Returns the + set of instance names where a stored row shadows a config one. + """ + if config._provider_baseline is None: + config._provider_baseline = {name: dict(entry) for name, entry in config.providers.items()} + baseline = config._provider_baseline + config.providers = {**baseline, **_cache} + return set(baseline) & set(_cache) + + +async def refresh_provider_cache(db: AsyncSession, config: GatewayConfig) -> set[str]: + """Reload the overlay from the database, apply it, and return shadowed names.""" + global _cached_at # noqa: PLW0603 + + rows = (await db.execute(select(ProviderCredential))).scalars().all() + overlay: dict[str, dict[str, Any]] = {} + for row in rows: + try: + overlay[row.instance] = _row_to_entry(row) + except (SecretBoxUnavailableError, SecretDecryptionError): + logger.warning( + "Skipping stored provider '%s': its API key could not be decrypted " + "(check OTARI_SECRET_KEY).", + row.instance, + ) + _cache.clear() + _cache.update(overlay) + _cached_at = time.monotonic() + return apply_to_config(config) + + +async def load_providers_at_startup(db: AsyncSession, config: GatewayConfig) -> None: + """Prime the overlay so the first request does not race the first refresh. + + A failure here is logged rather than raised: stored providers are an addition + to the config ones, and a gateway that serves every config-file provider is + better than one that refuses to start because a credential load failed. + """ + reset_provider_cache() + try: + shadowed = await refresh_provider_cache(db, config) + except Exception: + logger.exception("Failed to load stored providers; continuing with config providers only") + return + if _cache: + logger.info("Loaded %d stored provider(s)", len(_cache)) + for instance in sorted(shadowed): + logger.warning( + "Stored provider '%s' shadows the config.yml provider of the same name; " + "the dashboard credential is in effect.", + instance, + ) + + +async def run_provider_refresher(config: GatewayConfig, interval: float = PROVIDER_CACHE_TTL_SECONDS) -> None: + """Reload the provider overlay forever so other writers' changes arrive. + + A write refreshes the worker that served it; this covers sibling workers and + other replicas, which converge within ``interval``. Every error is swallowed + and retried on the next tick so a database blip cannot kill the refresher and + freeze the overlay. Cancelled at shutdown. + """ + while True: + await asyncio.sleep(interval) + try: + async with create_session() as db: + await refresh_provider_cache(db, config) + except asyncio.CancelledError: + raise + except Exception: + logger.warning("Stored provider refresh failed; retrying in %ss", interval, exc_info=True) + + +# --------------------------------------------------------------------------- # +# CRUD +# --------------------------------------------------------------------------- # + + +async def list_credentials(db: AsyncSession) -> list[ProviderCredential]: + """Every stored provider credential, ordered by instance name.""" + rows = (await db.execute(select(ProviderCredential).order_by(ProviderCredential.instance))).scalars().all() + return list(rows) + + +async def get_credential(db: AsyncSession, instance: str) -> ProviderCredential | None: + """The stored credential for ``instance``, or ``None``.""" + return await db.get(ProviderCredential, instance) + + +async def get_credential_for_update(db: AsyncSession, instance: str) -> ProviderCredential | None: + """Like :func:`get_credential`, but locks the row ``FOR UPDATE``. + + Used by the PATCH path so a version check and the write it guards run under + the same row lock: on PostgreSQL a concurrent PATCH waits and then sees the + new ``updated_at`` (so it 412s instead of clobbering). SQLite serialises + writers anyway, so the lock is a no-op there without changing correctness. + """ + stmt = select(ProviderCredential).where(ProviderCredential.instance == instance).with_for_update() + return (await db.execute(stmt)).scalar_one_or_none() + + +async def save_credential( + db: AsyncSession, + *, + instance: str, + provider_type: str | None | _Unset = UNSET, + api_base: str | None | _Unset = UNSET, + api_key: str | None | _Unset = UNSET, + client_args: dict[str, Any] | None | _Unset = UNSET, +) -> ProviderCredential: + """Create or update a stored credential (staged; caller commits). + + Each field is tri-state: left at ``UNSET`` it keeps the stored value; passed + ``None`` it is cleared; passed a value it is set. That lets a PATCH remove an + ``api_base`` or rotate a key without disturbing the rest. ``api_key`` is + encrypted before storage and requires ``OTARI_SECRET_KEY`` (raises + ``SecretBoxUnavailableError``); passing it ``None`` clears the stored key + (keyless local backends). ``client_args`` is normalised to ``{}`` when + cleared, since the column is non-null. The plaintext key is never logged. + """ + existing = await db.get(ProviderCredential, instance) + if existing is None: + row = ProviderCredential(instance=instance, client_args={}) + db.add(row) + else: + row = existing + + if not isinstance(provider_type, _Unset): + row.provider_type = provider_type + if not isinstance(api_base, _Unset): + row.api_base = api_base + if not isinstance(client_args, _Unset): + row.client_args = client_args or {} + if not isinstance(api_key, _Unset): + if api_key: + row.encrypted_api_key = encrypt_secret(api_key) + row.last4 = _last4(api_key) + else: + row.encrypted_api_key = None + row.last4 = None + + return row + + +async def delete_credential(db: AsyncSession, instance: str) -> bool: + """Delete a stored credential (staged; caller commits). Returns whether it existed.""" + row = await db.get(ProviderCredential, instance) + if row is None: + return False + await db.delete(row) + return True diff --git a/src/gateway/services/secret_box.py b/src/gateway/services/secret_box.py new file mode 100644 index 00000000..4b5cd201 --- /dev/null +++ b/src/gateway/services/secret_box.py @@ -0,0 +1,95 @@ +"""Encryption at rest for provider credentials configured through the dashboard. + +Provider API keys entered in the web UI are persisted encrypted with a Fernet +key supplied out of band as ``OTARI_SECRET_KEY``. The key lives outside the +database on purpose: a stolen database dump is useless without it. We never +auto-generate the key, never persist it next to the ciphertext, and never derive +it from the master key (which the gateway may rotate) because any of those would +make encryption-at-rest theatre against database theft. + +``OTARI_SECRET_KEY`` may hold one or more Fernet keys separated by whitespace or +commas. The first is used to encrypt; all are tried on decrypt (``MultiFernet``), +so a key can be rotated by prepending a new one and re-encrypting stored rows +over time. Generate one with :func:`generate_secret_key`. +""" + +import re + +from cryptography.fernet import Fernet, InvalidToken, MultiFernet + +from gateway.core.env import otari_env + +SECRET_KEY_ENV = "SECRET_KEY" + + +class SecretBoxUnavailableError(RuntimeError): + """Raised when ``OTARI_SECRET_KEY`` is unset or not a valid Fernet key. + + Surfaced to the API as a "set OTARI_SECRET_KEY to store credentials" error; + it must never contain key material. + """ + + +class SecretDecryptionError(ValueError): + """Raised when a stored ciphertext cannot be decrypted with the current key. + + Wraps Fernet's ``InvalidToken`` with a message that never echoes the + ciphertext, so a wrong or rotated-away key degrades one credential instead of + leaking data or crashing the caller. + """ + + +def generate_secret_key() -> str: + """Return a fresh url-safe Fernet key suitable for ``OTARI_SECRET_KEY``.""" + return Fernet.generate_key().decode() + + +def _load_keys() -> list[str]: + raw = otari_env(SECRET_KEY_ENV) + if not raw: + return [] + return [key for key in re.split(r"[\s,]+", raw.strip()) if key] + + +def secret_box_configured() -> bool: + """Whether at least one ``OTARI_SECRET_KEY`` value is set (not validated).""" + return bool(_load_keys()) + + +def get_secret_box() -> MultiFernet: + """Build the ``MultiFernet`` from ``OTARI_SECRET_KEY``. + + Raises ``SecretBoxUnavailableError`` when the variable is unset or holds a + value that is not a valid Fernet key. + """ + keys = _load_keys() + if not keys: + raise SecretBoxUnavailableError( + "OTARI_SECRET_KEY is not set; it is required to store provider credentials." + ) + try: + fernets = [Fernet(key.encode()) for key in keys] + except (ValueError, TypeError): + # Do not include the offending value: it is key material. + raise SecretBoxUnavailableError("OTARI_SECRET_KEY is not a valid Fernet key.") from None + return MultiFernet(fernets) + + +def encrypt_secret(plaintext: str) -> str: + """Encrypt ``plaintext`` with the primary key; return url-safe ciphertext.""" + return get_secret_box().encrypt(plaintext.encode()).decode() + + +def decrypt_secret(ciphertext: str) -> str: + """Decrypt a stored ciphertext, trying every configured key. + + Raises ``SecretBoxUnavailableError`` when no key is configured and + ``SecretDecryptionError`` when none of the configured keys can decrypt it. + Neither error carries the ciphertext. + """ + try: + return get_secret_box().decrypt(ciphertext.encode()).decode() + except InvalidToken: + raise SecretDecryptionError( + "A stored provider credential could not be decrypted with the configured OTARI_SECRET_KEY." + ) from None diff --git a/src/gateway/static/dashboard/assets/index-8efccAl2.css b/src/gateway/static/dashboard/assets/index-8efccAl2.css new file mode 100644 index 00000000..2b89abb6 --- /dev/null +++ b/src/gateway/static/dashboard/assets/index-8efccAl2.css @@ -0,0 +1 @@ +/*! tailwindcss v4.3.1 | MIT License | https://tailwindcss.com */@layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-divide-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-animation-delay:0s;--tw-animation-direction:normal;--tw-animation-duration:initial;--tw-animation-fill-mode:none;--tw-animation-iteration-count:1;--tw-enter-blur:0;--tw-enter-opacity:1;--tw-enter-rotate:0;--tw-enter-scale:1;--tw-enter-translate-x:0;--tw-enter-translate-y:0;--tw-exit-blur:0;--tw-exit-opacity:1;--tw-exit-rotate:0;--tw-exit-scale:1;--tw-exit-translate-x:0;--tw-exit-translate-y:0;--tw-content:"";--tw-ease:initial;--tw-scale-x:1;--tw-scale-y:1;--tw-scale-z:1;--tw-border-spacing-x:0;--tw-border-spacing-y:0;--tw-gradient-position:initial;--tw-gradient-from:#0000;--tw-gradient-via:#0000;--tw-gradient-to:#0000;--tw-gradient-stops:initial;--tw-gradient-via-stops:initial;--tw-gradient-from-position:0%;--tw-gradient-via-position:50%;--tw-gradient-to-position:100%;--tw-space-y-reverse:0;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial;--tw-space-x-reverse:0}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-50:oklch(97.1% .013 17.38);--color-red-200:oklch(88.5% .062 18.334);--color-red-700:oklch(50.5% .213 27.518);--color-amber-50:oklch(98.7% .022 95.277);--color-amber-200:oklch(92.4% .12 95.746);--color-amber-700:oklch(55.5% .163 48.998);--color-amber-800:oklch(47.3% .137 46.201);--color-green-700:oklch(52.7% .154 150.069);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-sm:24rem;--container-md:28rem;--container-lg:32rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height: 1.5 ;--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--text-3xl:1.875rem;--text-3xl--line-height: 1.2 ;--text-4xl:2.25rem;--text-4xl--line-height:calc(2.5 / 2.25);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--tracking-tight:-.025em;--tracking-wide:.025em;--leading-relaxed:1.625;--radius-xl:calc(var(--radius) * 1.5);--radius-2xl:calc(var(--radius) * 2);--radius-3xl:calc(var(--radius) * 3);--ease-out:cubic-bezier(0, 0, .2, 1);--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--blur-md:12px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono);--shadow-surface:var(--surface-shadow);--shadow-overlay:var(--overlay-shadow);--border-width-field:var(--field-border-width,var(--border-width));--ease-smooth:ease;--ease-out-quad:cubic-bezier(.25, .46, .45, .94);--ease-out-quart:cubic-bezier(.165, .84, .44, 1);--ease-out-fluid:cubic-bezier(.32, .72, 0, 1);--ease-linear:linear}@layer theme.base{:root,.light,.default,[data-theme=light],[data-theme=default]{color-scheme:light;--white:oklch(100% 0 0);--black:oklch(0% 0 0);--snow:oklch(99.11% 0 0);--eclipse:oklch(21.03% .0059 285.89);--spacing:.25rem;--border-width:1px;--field-border-width:0px;--disabled-opacity:.5;--ring-offset-width:2px;--cursor-interactive:pointer;--cursor-disabled:not-allowed;--radius:.5rem;--field-radius:calc(var(--radius) * 1.5);--background:oklch(97.02% 0 0);--foreground:var(--eclipse);--surface:var(--white);--surface-foreground:var(--foreground);--surface-secondary:oklch(95.24% .0013 286.37);--surface-secondary-foreground:var(--foreground);--surface-tertiary:oklch(93.73% .0013 286.37);--surface-tertiary-foreground:var(--foreground);--overlay:var(--white);--overlay-foreground:var(--foreground);--muted:oklch(55.17% .0138 285.94);--scrollbar:var(--scrollbar-thumb);--scrollbar-thumb:var(--foreground)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--scrollbar-thumb:color-mix(in oklch, var(--foreground) 15%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--scrollbar-track:transparent;--scrollbar-gutter:auto;--scrollbar-width:thin;--scrollbar-color:var(--scrollbar-thumb) var(--scrollbar-track);--default:oklch(94% .001 286.375);--default-foreground:var(--eclipse);--accent:oklch(62.04% .195 253.83);--accent-foreground:var(--snow);--field-background:var(--white);--field-foreground:oklch(21.03% .0059 285.89);--field-placeholder:var(--muted);--field-border:transparent;--success:oklch(73.29% .1935 150.81);--success-foreground:var(--eclipse);--warning:oklch(78.19% .1585 72.33);--warning-foreground:var(--eclipse);--danger:oklch(65.32% .2328 25.74);--danger-foreground:var(--snow);--segment:var(--white);--segment-foreground:var(--eclipse);--border:oklch(90% .004 286.32);--separator:oklch(92% .004 286.32);--focus:var(--accent);--link:var(--foreground);--backdrop:#00000080;--surface-hover:var(--surface)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--surface-hover:color-mix(in oklab, var(--surface) 92%, var(--surface-foreground) 8%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--background-secondary:var(--background)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--background-secondary:color-mix(in oklab, var(--background) 96%, var(--foreground) 4%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--background-tertiary:var(--background)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--background-tertiary:color-mix(in oklab, var(--background) 92%, var(--foreground) 8%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--background-inverse:var(--foreground);--default-hover:var(--default)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--default-hover:color-mix(in oklab, var(--default) 96%, var(--default-foreground) 4%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-hover:var(--accent)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-hover:color-mix(in oklab, var(--accent) 90%, var(--accent-foreground) 10%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--success-hover:var(--success)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--success-hover:color-mix(in oklab, var(--success) 90%, var(--success-foreground) 10%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-hover:var(--warning)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-hover:color-mix(in oklab, var(--warning) 90%, var(--warning-foreground) 10%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-hover:var(--danger)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-hover:color-mix(in oklab, var(--danger) 90%, var(--danger-foreground) 10%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--field-hover:var(--field-background,var(--default))}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--field-hover:color-mix(in oklab, var(--field-background,var(--default)) 90%, var(--field-foreground,var(--foreground)) 2%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--field-focus:var(--field-background,var(--default));--field-border-hover:var(--field-border,var(--border))}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--field-border-hover:color-mix(in oklab, var(--field-border,var(--border)) 88%, var(--field-foreground,var(--foreground)) 10%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--field-border-focus:var(--field-border,var(--border))}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--field-border-focus:color-mix(in oklab, var(--field-border,var(--border)) 74%, var(--field-foreground,var(--foreground)) 22%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--default-soft:var(--default)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--default-soft:color-mix(in oklab, var(--default) 50%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--default-soft-foreground:var(--default-foreground);--default-soft-hover:var(--default)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--default-soft-hover:color-mix(in oklab, var(--default) 60%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-soft:var(--accent)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-soft:color-mix(in oklab, var(--accent) 15%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-soft-foreground:var(--accent)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-soft-foreground:color-mix(in oklab, var(--accent) 70%, var(--foreground) 30%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-soft-hover:var(--accent)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--accent-soft-hover:color-mix(in oklab, var(--accent) 20%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-soft:var(--danger)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-soft:color-mix(in oklab, var(--danger) 15%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-soft-foreground:var(--danger)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-soft-foreground:color-mix(in oklab, var(--danger) 70%, var(--foreground) 40%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-soft-hover:var(--danger)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--danger-soft-hover:color-mix(in oklab, var(--danger) 20%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-soft:var(--warning)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-soft:color-mix(in oklab, var(--warning) 15%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-soft-foreground:var(--warning)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-soft-foreground:color-mix(in oklab, var(--warning) 80%, var(--foreground) 70%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-soft-hover:var(--warning)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--warning-soft-hover:color-mix(in oklab, var(--warning) 20%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--success-soft:var(--success)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--success-soft:color-mix(in oklab, var(--success) 15%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--success-soft-foreground:var(--success)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--success-soft-foreground:color-mix(in oklab, var(--success) 80%, var(--foreground) 60%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--success-soft-hover:var(--success)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--success-soft-hover:color-mix(in oklab, var(--success) 20%, transparent)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--separator-secondary:var(--surface)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--separator-secondary:color-mix(in oklab, var(--surface) 85%, var(--surface-foreground) 15%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--separator-tertiary:var(--surface)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--separator-tertiary:color-mix(in oklab, var(--surface) 81%, var(--surface-foreground) 19%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--border-secondary:var(--surface)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--border-secondary:color-mix(in oklab, var(--surface) 78%, var(--surface-foreground) 22%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--border-tertiary:var(--surface)}@supports (color:color-mix(in lab,red,red)){:root,.light,.default,[data-theme=light],[data-theme=default]{--border-tertiary:color-mix(in oklab, var(--surface) 66%, var(--surface-foreground) 34%)}}:root,.light,.default,[data-theme=light],[data-theme=default]{--surface-shadow:0 2px 4px 0 #0000000a, 0 1px 2px 0 #0000000f, 0 0 1px 0 #0000000f;--overlay-shadow:0 2px 8px 0 #0000000f, 0 -6px 12px 0 #00000008, 0 14px 28px 0 #00000014;--field-shadow:0 2px 4px 0 #0000000a, 0 1px 2px 0 #0000000f, 0 0 1px 0 #0000000f;--skeleton-animation:shimmer;--tooltip-delay:1.5s;--tooltip-close-delay:.5s}.dark,[data-theme=dark]{color-scheme:dark;--background:oklch(12% .005 285.823);--foreground:var(--snow);--surface:oklch(21.03% .0059 285.89);--surface-foreground:var(--foreground);--surface-secondary:oklch(25.7% .0037 286.14);--surface-tertiary:oklch(27.21% .0024 247.91);--overlay:oklch(21.03% .0059 285.89);--overlay-foreground:var(--foreground);--muted:oklch(70.5% .015 286.067);--scrollbar:var(--scrollbar-thumb);--scrollbar-thumb:var(--foreground)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--scrollbar-thumb:color-mix(in oklch, var(--foreground) 15%, transparent)}}.dark,[data-theme=dark]{--scrollbar-track:transparent;--scrollbar-gutter:auto;--scrollbar-width:thin;--scrollbar-color:var(--scrollbar-thumb) var(--scrollbar-track);--default:oklch(27.4% .006 286.033);--default-foreground:var(--snow);--field-background:oklch(21.03% .0059 285.89);--field-foreground:var(--foreground);--warning:oklch(82.03% .1388 76.34);--warning-foreground:var(--eclipse);--danger:oklch(59.4% .1967 24.63);--danger-foreground:var(--snow);--segment:oklch(39.64% .01 285.93);--segment-foreground:var(--foreground);--border:oklch(28% .006 286.033);--separator:oklch(25% .006 286.033);--focus:var(--accent);--link:var(--foreground);--backdrop:#0009;--surface-shadow:0 0 0 0 transparent inset;--overlay-shadow:0 0 1px 0 #ffffff4d inset;--field-shadow:0 0 0 0 transparent inset;--surface-hover:var(--surface)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--surface-hover:color-mix(in oklab, var(--surface) 92%, var(--surface-foreground) 8%)}}.dark,[data-theme=dark]{--background-secondary:var(--background)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--background-secondary:color-mix(in oklab, var(--background) 96%, var(--foreground) 4%)}}.dark,[data-theme=dark]{--background-tertiary:var(--background)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--background-tertiary:color-mix(in oklab, var(--background) 92%, var(--foreground) 8%)}}.dark,[data-theme=dark]{--background-inverse:var(--foreground);--default-hover:var(--default)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--default-hover:color-mix(in oklab, var(--default) 96%, var(--default-foreground) 4%)}}.dark,[data-theme=dark]{--accent-hover:var(--accent)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--accent-hover:color-mix(in oklab, var(--accent) 90%, var(--accent-foreground) 10%)}}.dark,[data-theme=dark]{--success-hover:var(--success)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--success-hover:color-mix(in oklab, var(--success) 90%, var(--success-foreground) 10%)}}.dark,[data-theme=dark]{--warning-hover:var(--warning)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--warning-hover:color-mix(in oklab, var(--warning) 90%, var(--warning-foreground) 10%)}}.dark,[data-theme=dark]{--danger-hover:var(--danger)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--danger-hover:color-mix(in oklab, var(--danger) 90%, var(--danger-foreground) 10%)}}.dark,[data-theme=dark]{--field-hover:var(--field-background,var(--default))}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--field-hover:color-mix(in oklab, var(--field-background,var(--default)) 90%, var(--field-foreground,var(--foreground)) 2%)}}.dark,[data-theme=dark]{--field-focus:var(--field-background,var(--default));--field-border-hover:var(--field-border,var(--border))}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--field-border-hover:color-mix(in oklab, var(--field-border,var(--border)) 88%, var(--field-foreground,var(--foreground)) 10%)}}.dark,[data-theme=dark]{--field-border-focus:var(--field-border,var(--border))}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--field-border-focus:color-mix(in oklab, var(--field-border,var(--border)) 74%, var(--field-foreground,var(--foreground)) 22%)}}.dark,[data-theme=dark]{--default-soft:var(--default)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--default-soft:color-mix(in oklab, var(--default) 50%, transparent)}}.dark,[data-theme=dark]{--default-soft-foreground:var(--default-foreground);--default-soft-hover:var(--default)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--default-soft-hover:color-mix(in oklab, var(--default) 60%, transparent)}}.dark,[data-theme=dark]{--accent-soft:var(--accent)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--accent-soft:color-mix(in oklab, var(--accent) 12%, transparent)}}.dark,[data-theme=dark]{--accent-soft-foreground:var(--accent)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--accent-soft-foreground:color-mix(in oklab, var(--accent) 80%, var(--foreground) 30%)}}.dark,[data-theme=dark]{--accent-soft-hover:var(--accent)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--accent-soft-hover:color-mix(in oklab, var(--accent) 16%, transparent)}}.dark,[data-theme=dark]{--danger-soft:var(--danger)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--danger-soft:color-mix(in oklab, var(--danger) 15%, transparent)}}.dark,[data-theme=dark]{--danger-soft-foreground:var(--danger)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--danger-soft-foreground:color-mix(in oklab, var(--danger) 80%, var(--foreground) 30%)}}.dark,[data-theme=dark]{--danger-soft-hover:var(--danger)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--danger-soft-hover:color-mix(in oklab, var(--danger) 20%, transparent)}}.dark,[data-theme=dark]{--warning-soft:var(--warning)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--warning-soft:color-mix(in oklab, var(--warning) 12%, transparent)}}.dark,[data-theme=dark]{--warning-soft-foreground:var(--warning)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--warning-soft-foreground:color-mix(in oklab, var(--warning) 80%, var(--foreground) 30%)}}.dark,[data-theme=dark]{--warning-soft-hover:var(--warning)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--warning-soft-hover:color-mix(in oklab, var(--warning) 16%, transparent)}}.dark,[data-theme=dark]{--success-soft:var(--success)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--success-soft:color-mix(in oklab, var(--success) 12%, transparent)}}.dark,[data-theme=dark]{--success-soft-foreground:var(--success)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--success-soft-foreground:color-mix(in oklab, var(--success) 80%, var(--foreground) 30%)}}.dark,[data-theme=dark]{--success-soft-hover:var(--success)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--success-soft-hover:color-mix(in oklab, var(--success) 16%, transparent)}}.dark,[data-theme=dark]{--separator-secondary:var(--surface)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--separator-secondary:color-mix(in oklab, var(--surface) 85%, var(--surface-foreground) 15%)}}.dark,[data-theme=dark]{--separator-tertiary:var(--surface)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--separator-tertiary:color-mix(in oklab, var(--surface) 81%, var(--surface-foreground) 19%)}}.dark,[data-theme=dark]{--border-secondary:var(--surface)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--border-secondary:color-mix(in oklab, var(--surface) 78%, var(--surface-foreground) 22%)}}.dark,[data-theme=dark]{--border-tertiary:var(--surface)}@supports (color:color-mix(in lab,red,red)){.dark,[data-theme=dark]{--border-tertiary:color-mix(in oklab, var(--surface) 66%, var(--surface-foreground) 34%)}}[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--accent-soft-foreground:var(--accent)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--accent-soft-foreground:color-mix(in oklab, var(--accent) 92%, var(--foreground) 8%)}}[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--danger-soft-foreground:var(--danger)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--danger-soft-foreground:color-mix(in oklab, var(--danger) 92%, var(--foreground) 8%)}}[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--warning-soft-foreground:var(--warning)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--warning-soft-foreground:color-mix(in oklab, var(--warning) 92%, var(--foreground) 8%)}}[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--success-soft-foreground:var(--success)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true]:not(.dark):not([data-theme=dark]){--success-soft-foreground:color-mix(in oklab, var(--success) 92%, var(--foreground) 8%)}}[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--accent-soft-foreground:var(--accent)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--accent-soft-foreground:color-mix(in oklab, var(--accent) 92%, var(--foreground) 8%)}}[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--danger-soft-foreground:var(--danger)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--danger-soft-foreground:color-mix(in oklab, var(--danger) 92%, var(--foreground) 8%)}}[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--warning-soft-foreground:var(--warning)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--warning-soft-foreground:color-mix(in oklab, var(--warning) 92%, var(--foreground) 8%)}}[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--success-soft-foreground:var(--success)}@supports (color:color-mix(in lab,red,red)){[data-vibrant-palette=true].dark,[data-vibrant-palette=true][data-theme=dark]{--success-soft-foreground:color-mix(in oklab, var(--success) 92%, var(--foreground) 8%)}}}@layer components;}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;-moz-tab-size:4;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){-webkit-appearance:button;-moz-appearance:button;appearance:button}::file-selector-button{-webkit-appearance:button;-moz-appearance:button;appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}*,:after,:before,::backdrop{border-color:var(--border,currentColor)}::file-selector-button{border-color:var(--border,currentColor)}:root{view-transition-name:none}::view-transition{pointer-events:none}[data-scrollbar=thin]{--scrollbar-width:thin;--scrollbar-color:var(--scrollbar-thumb) var(--scrollbar-track);--scrollbar-gutter:auto}[data-scrollbar=default]{--scrollbar-width:auto;--scrollbar-color:auto;--scrollbar-gutter:auto}[data-scrollbar=none]{--scrollbar-width:none;--scrollbar-color:auto;--scrollbar-gutter:auto}}@layer components{.close-button{isolation:isolate;height:calc(var(--spacing) * 6);width:calc(var(--spacing) * 6);transform-origin:50%;border-radius:calc(var(--radius) * 1.5);padding:var(--spacing);-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);transition:transform .25s var(--ease-out-quart),color .15s var(--ease-out),background-color .1s var(--ease-out),box-shadow .15s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);flex-shrink:0;justify-content:center;align-items:center;display:inline-flex;position:relative}.close-button:is([data-reduce-motion=true],[data-reduce-motion=true] *),.close-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.close-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.close-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.close-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.close-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.close-button:focus-visible:not(:focus),.close-button[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.close-button:disabled,.close-button[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.close-button[data-pending=true]{pointer-events:none}.close-button svg{pointer-events:none;width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);margin-inline:calc(var(--spacing) * -.5);margin-block:calc(var(--spacing) * .5);flex-shrink:0;align-self:center}.close-button--default{background-color:var(--default);color:var(--muted)}@media(hover:hover){.close-button--default:hover,.close-button--default[data-hovered=true]{background-color:var(--default-hover)}}.close-button--default:active,.close-button--default[data-pressed=true]{transform:scale(.93)}.description{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));text-wrap:wrap;overflow-wrap:break-word;color:var(--muted)}.error-message{height:auto;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));overflow-wrap:break-word;color:var(--danger);transition:opacity .15s var(--ease-out),height .35s var(--ease-smooth)}.error-message:is([data-reduce-motion=true],[data-reduce-motion=true] *),.error-message:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.error-message:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.error-message:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.error-message:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.error-message:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.field-error{height:0;padding-inline:var(--spacing);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));overflow-wrap:break-word;color:var(--danger);opacity:0}.field-error[data-visible]{opacity:1;height:auto}.field-error{transition:opacity .15s var(--ease-out),height .35s var(--ease-smooth)}.field-error:is([data-reduce-motion=true],[data-reduce-motion=true] *),.field-error:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.field-error:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.field-error:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.field-error:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.field-error:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.checkbox>.field-error,.checkbox>[data-slot=field-error],.switch>.field-error,.switch>[data-slot=field-error],.radio>.field-error,.radio>[data-slot=field-error]{height:auto;min-height:0;color:var(--muted);opacity:1;margin:0;padding:0;transition:none}.label{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground)}:is(.label--required,[data-required=true]:not([role=group]):not([role=radiogroup]):not([role=checkboxgroup])>.label,[data-required=true]:not([data-slot=radio]):not([data-slot=checkbox])>.label):after{margin-left:calc(var(--spacing) * .5);color:var(--danger);--tw-content:"*";content:var(--tw-content)}.label--disabled,[data-disabled=true] .label{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.label--invalid,[data-invalid=true] .label,[aria-invalid=true] .label{color:var(--danger)}.accordion{contain:layout style;width:100%}.accordion__body{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.accordion__body-inner{padding-inline:calc(var(--spacing) * 4);padding-top:0;padding-bottom:calc(var(--spacing) * 4);color:var(--muted)}.accordion__indicator{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);color:var(--muted);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.25s;flex-shrink:0;margin-left:auto;transition-duration:.25s}.accordion__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.accordion__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.accordion__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.accordion__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.accordion__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.accordion__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.accordion__indicator[data-expanded=true]{rotate:-180deg}.accordion__item{--tw-border-style:none;border-style:none;position:relative}.accordion__item:after{content:"";border-radius:calc(var(--radius) * .25);background-color:var(--separator);width:100%;height:1px;position:absolute;bottom:0;left:0}.accordion__item:last-child:after{content:none}.accordion__item[data-hide-separator=true]:after{display:none}.accordion__trigger{cursor:var(--cursor-interactive);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 4);text-align:left;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);-webkit-tap-highlight-color:transparent;transition:opacity .15s var(--ease-out),box-shadow .15s var(--ease-out);flex:1;justify-content:space-between;align-items:center;display:flex}.accordion__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.accordion__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.accordion__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.accordion__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.accordion__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.accordion__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.accordion__trigger:hover:not([aria-expanded=true]),.accordion__trigger[data-hovered=true]:not([aria-expanded=true]){background-color:var(--foreground)}@supports (color:color-mix(in lab,red,red)){.accordion__trigger:hover:not([aria-expanded=true]),.accordion__trigger[data-hovered=true]:not([aria-expanded=true]){background-color:color-mix(in oklab,var(--foreground) 3%,transparent 90%)}}}.accordion__trigger:focus-visible:not(:focus),.accordion__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.accordion__trigger:disabled,.accordion__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.accordion__panel{opacity:0;height:var(--disclosure-panel-height);transition:height .2s var(--ease-out-quad),opacity .2s var(--ease-out);overflow:clip}.accordion__panel:is([data-reduce-motion=true],[data-reduce-motion=true] *),.accordion__panel:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.accordion__panel:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.accordion__panel:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.accordion__panel:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.accordion__panel:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.accordion__panel[data-expanded=true]{will-change:height,opacity;opacity:1}.accordion--surface{background-color:var(--surface);border-radius:min(32px,var(--radius-3xl))}@media(hover:hover){.accordion--surface .accordion__trigger:hover:not([aria-expanded=true]),.accordion--surface .accordion__trigger[data-hovered=true]:not([aria-expanded=true]){background-color:var(--default)}}.accordion--surface .accordion__item:after{background-color:var(--surface-foreground)}@supports (color:color-mix(in lab,red,red)){.accordion--surface .accordion__item:after{background-color:color-mix(in oklab,var(--surface-foreground) 6%,transparent)}}.accordion--surface .accordion__item:after{width:94%;left:3%}.accordion--surface .accordion__item:first-child [data-slot=accordion-trigger]{border-top-left-radius:min(32px,var(--radius-3xl));border-top-right-radius:min(32px,var(--radius-3xl))}.accordion--surface .accordion__item:last-child:not(:has([data-slot=accordion-trigger][aria-expanded=true])) [data-slot=accordion-trigger]{border-bottom-left-radius:min(32px,var(--radius-3xl));border-bottom-right-radius:min(32px,var(--radius-3xl))}.breadcrumbs{align-items:center;display:flex}.breadcrumbs .breadcrumbs__link{padding-inline:calc(var(--spacing) * .5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--muted);opacity:1;text-decoration-line:none;position:relative}.breadcrumbs .breadcrumbs__link:hover,.breadcrumbs .breadcrumbs__link[data-hovered=true]{text-decoration-line:underline}.breadcrumbs .breadcrumbs__link[data-current=true]{color:var(--link);opacity:1}.breadcrumbs .breadcrumbs__item{justify-content:center;align-items:center;gap:calc(var(--spacing) * .5);padding-inline:calc(var(--spacing) * .5);flex-shrink:0;display:flex}.breadcrumbs .breadcrumbs__separator{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3);color:var(--muted)}.breadcrumbs .breadcrumbs__separator:where(:dir(rtl),[dir=rtl],[dir=rtl] *){rotate:180deg}.disclosure-group{contain:layout style;width:100%}.disclosure{position:relative}.accordion__heading{display:flex}.disclosure__trigger{cursor:var(--cursor-interactive);-webkit-tap-highlight-color:transparent;display:inline-block}.disclosure__trigger:focus-visible:not(:focus),.disclosure__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.disclosure__trigger:disabled,.disclosure__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.disclosure__indicator{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);color:inherit;transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.25s;flex-shrink:0;margin-left:auto;transition-duration:.25s}.disclosure__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.disclosure__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.disclosure__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.disclosure__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.disclosure__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.disclosure__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.disclosure__indicator[data-expanded=true]{rotate:-180deg}.disclosure__content{opacity:0;height:var(--disclosure-panel-height);transition:height .2s var(--ease-out-quad),opacity .2s var(--ease-out);overflow:clip}.disclosure__content:is([data-reduce-motion=true],[data-reduce-motion=true] *),.disclosure__content:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.disclosure__content:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.disclosure__content:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.disclosure__content:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.disclosure__content:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.disclosure__content[data-expanded=true]{will-change:height,opacity;opacity:1}.disclosure__body{padding:calc(var(--spacing) * 2)}.link{border-radius:calc(var(--radius) * 1.5);--tw-font-weight:var(--font-weight-medium);width:fit-content;height:fit-content;font-weight:var(--font-weight-medium);color:var(--link);text-decoration-line:none;-webkit-text-decoration-color:var(--separator-tertiary);text-decoration-color:var(--separator-tertiary);text-underline-offset:4px;-webkit-tap-highlight-color:transparent;transition:color .1s var(--ease-smooth),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out),opacity .1s var(--ease-out);align-items:center;text-decoration-thickness:1.5px;display:inline-flex;position:relative}.link:is([data-reduce-motion=true],[data-reduce-motion=true] *),.link:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.link:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.link:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.link:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.link:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.link{cursor:var(--cursor-interactive)}@media(hover:hover){.link:hover,.link[data-hovered=true]{text-decoration-line:underline;-webkit-text-decoration-color:var(--muted);text-decoration-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.link:hover,.link[data-hovered=true]{-webkit-text-decoration-color:color-mix(in oklab,var(--muted) 50%,transparent);text-decoration-color:color-mix(in oklab,var(--muted) 50%,transparent)}}:is(.link:hover,.link[data-hovered=true]) .link__icon{opacity:1}}.link:active,.link[data-pressed=true]{text-decoration-line:underline;-webkit-text-decoration-color:var(--muted);text-decoration-color:var(--muted)}:is(.link:active,.link[data-pressed=true]) .link__icon{opacity:1}.link:focus-visible:not(:focus),.link[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}:is(.link:focus-visible:not(:focus),.link[data-focus-visible=true]) .link__icon{opacity:1}.link[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.link .link__icon{pointer-events:none;color:currentColor;opacity:.6;width:.75em;height:.75em;transition:opacity .15s var(--ease-out);flex-shrink:0;justify-content:center;align-items:center;display:inline-flex}.link .link__icon:is([data-reduce-motion=true],[data-reduce-motion=true] *),.link .link__icon:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.link .link__icon:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.link .link__icon:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.link .link__icon:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.link .link__icon:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.link .link__icon svg{transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.link .link__icon[data-default-icon=true]{margin-left:var(--spacing);padding-bottom:calc(var(--spacing) * 1.5)}.link.button{gap:0;text-decoration-line:none}.pagination{justify-content:space-between;align-items:center;gap:calc(var(--spacing) * 4);flex-direction:column;width:100%;display:flex}@media(min-width:40rem){.pagination{flex-direction:row}}.pagination__summary{align-items:center;gap:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--muted);align-self:flex-start;display:flex}@media(min-width:40rem){.pagination__summary{align-self:center}}.pagination__content{align-items:center;gap:var(--spacing);align-self:flex-start;display:flex}@media(min-width:40rem){.pagination__content{align-self:center}}.pagination__item{display:inline-flex}.pagination__link{isolation:isolate;width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9);transform-origin:50%;border-radius:calc(var(--radius) * 3);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);white-space:nowrap;--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;outline-style:none;justify-content:center;align-items:center;display:inline-flex;position:relative}@media(min-width:48rem){.pagination__link{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}}.pagination__link{cursor:var(--cursor-interactive);transition:transform .25s var(--ease-smooth),background-color .1s var(--ease-out),box-shadow .1s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.pagination__link:is([data-reduce-motion=true],[data-reduce-motion=true] *),.pagination__link:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.pagination__link:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.pagination__link:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.pagination__link:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.pagination__link:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.pagination__link{--pagination-link-bg:transparent;--pagination-link-bg-hover:var(--default-hover);--pagination-link-bg-pressed:var(--default-hover);--pagination-link-fg:var(--default-foreground);background-color:var(--pagination-link-bg);color:var(--pagination-link-fg)}.pagination__link:focus-visible,.pagination__link[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.pagination__link:disabled,.pagination__link[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}@media(hover:hover){.pagination__link:hover,.pagination__link[data-hovered=true]{background-color:var(--pagination-link-bg-hover)}}.pagination__link:active,.pagination__link[data-pressed=true]{background-color:var(--pagination-link-bg-pressed);transform:scale(.97)}.pagination__link[data-active=true]{--pagination-link-bg:var(--default);--pagination-link-bg-hover:var(--default-hover);--pagination-link-bg-pressed:var(--default-hover)}.pagination__ellipsis{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--muted);-webkit-user-select:none;user-select:none;justify-content:center;align-items:center;display:inline-flex}@media(min-width:48rem){.pagination__ellipsis{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}}.pagination__link--nav{gap:calc(var(--spacing) * 1.5);width:auto;padding-inline:calc(var(--spacing) * 2.5)}.pagination--sm .pagination__link{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}@media(min-width:48rem){.pagination--sm .pagination__link{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}}.pagination--sm .pagination__link:active,.pagination--sm .pagination__link[data-pressed=true]{transform:scale(.98)}.pagination--sm .pagination__link--nav{width:auto;padding-inline:calc(var(--spacing) * 2)}.pagination--sm .pagination__ellipsis{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}@media(min-width:48rem){.pagination--sm .pagination__ellipsis{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}}.pagination--sm .pagination__summary{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.pagination--lg .pagination__link{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}@media(min-width:48rem){.pagination--lg .pagination__link{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}}.pagination--lg .pagination__link:active,.pagination--lg .pagination__link[data-pressed=true]{transform:scale(.96)}.pagination--lg .pagination__link--nav{width:auto;padding-inline:calc(var(--spacing) * 3)}.pagination--lg .pagination__ellipsis{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}@media(min-width:48rem){.pagination--lg .pagination__ellipsis{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}}.pagination--lg .pagination__summary{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.tabs{gap:calc(var(--spacing) * 2);display:flex}.tabs[data-orientation=horizontal]{flex-direction:column}.tabs[data-orientation=vertical]{flex-direction:row}.tabs__list-container{position:relative}.tabs__list{background-color:var(--default);padding:var(--spacing);border-radius:calc(var(--radius) * 2.5);display:inline-flex}.tabs__list[data-orientation=horizontal]{flex-direction:row;width:100%}.tabs__list[data-orientation=vertical]{gap:var(--spacing);flex-direction:column}.tabs__list[data-orientation=vertical] .tabs__tab{min-width:calc(var(--spacing) * 20)}.tabs__tab{z-index:1;cursor:var(--cursor-interactive);height:calc(var(--spacing) * 8);border-radius:calc(var(--radius) * 3);width:100%;padding-inline:calc(var(--spacing) * 4);text-align:center;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--muted);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;transition:color .15s var(--ease-smooth),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out),opacity .15s var(--ease-smooth);outline-style:none;justify-content:center;align-items:center;display:flex;position:relative}.tabs__tab:is([data-reduce-motion=true],[data-reduce-motion=true] *),.tabs__tab:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.tabs__tab:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.tabs__tab:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.tabs__tab:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.tabs__tab:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.tabs__tab[data-selected=true]{color:var(--segment-foreground)}.tabs__tab[data-selected=true] .tabs__separator,.tabs__tab[data-selected=true]+.tabs__tab .tabs__separator{opacity:0}.tabs__tab:disabled,.tabs__tab[data-disabled=true],.tabs__tab[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}@media(hover:hover){.tabs__tab:not([data-selected=true]):not([data-disabled=true]):hover,.tabs__tab[data-hovered=true]:not([data-selected=true]):not([data-disabled=true]){opacity:.7}}.tabs__tab:focus-visible:not(:focus),.tabs__tab[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.tabs__separator{border-radius:calc(var(--radius) * .5);background-color:var(--muted)}@supports (color:color-mix(in lab,red,red)){.tabs__separator{background-color:color-mix(in oklab,var(--muted) 25%,transparent)}}.tabs__separator{pointer-events:none;transition:opacity .15s var(--ease-smooth);position:absolute}.tabs__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.tabs__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.tabs__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.tabs__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.tabs__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.tabs__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.tabs__list[data-orientation=horizontal] .tabs__separator{width:1px;height:50%;top:25%;left:0}.tabs__list[data-orientation=vertical] .tabs__separator{width:90%;height:1px;top:0;left:5%}.tabs__panel{width:100%;padding:calc(var(--spacing) * 2);--tw-outline-style:none;outline-style:none}.tabs__panel[data-exiting=true]{width:100%;position:absolute;top:0;left:0}.tabs__panel[data-orientation=horizontal]{margin-top:calc(var(--spacing) * 4)}.tabs__panel[data-orientation=vertical]{margin-left:calc(var(--spacing) * 4)}.tabs__indicator{box-shadow:var(--shadow-surface);z-index:-1;border-radius:var(--radius-3xl);background-color:var(--segment);width:100%;height:100%;transition-property:translate,width,height;transition-duration:.25s;transition-timing-function:var(--ease-out-fluid);position:absolute;top:0;left:0}.tabs__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.tabs__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.tabs__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.tabs__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.tabs__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.tabs__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.tabs--secondary>.tabs__list-container>.tabs__list{background-color:#0000;border-radius:0;padding:0}.tabs--secondary>.tabs__list-container>.tabs__list[data-orientation=horizontal]{scrollbar-color:auto;scrollbar-gutter:auto;-ms-overflow-style:none;scrollbar-width:none;border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--border);max-width:100%;overflow:auto clip}.tabs--secondary>.tabs__list-container>.tabs__list[data-orientation=vertical]{border-left-style:var(--tw-border-style);border-left-width:1px;border-color:var(--border)}.tabs--secondary>.tabs__list-container .tabs__tab{border-radius:0}.tabs--secondary>.tabs__list-container .tabs__tab[data-selected=true]{color:var(--foreground)}.tabs--secondary>.tabs__list-container .tabs__separator{display:none}.tabs--secondary>.tabs__list-container .tabs__indicator{background-color:var(--accent);box-shadow:none;border-radius:0}.tabs--secondary[data-orientation=horizontal]>.tabs__list-container .tabs__indicator{height:2px;top:auto;bottom:0}.tabs--secondary[data-orientation=vertical]>.tabs__list-container .tabs__indicator{width:2px;height:100%;top:0;left:0}.button{isolation:isolate;height:calc(var(--spacing) * 10);transform-origin:50%;justify-content:center;align-items:center;gap:calc(var(--spacing) * 2);border-radius:calc(var(--radius) * 3);width:fit-content;padding-inline:calc(var(--spacing) * 4);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);white-space:nowrap;--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;outline-style:none;display:inline-flex;position:relative}@media(min-width:48rem){.button{height:calc(var(--spacing) * 9)}}.button{transition:transform .25s var(--ease-smooth),background-color .1s var(--ease-out),box-shadow .1s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.button:is([data-reduce-motion=true],[data-reduce-motion=true] *),.button:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.button:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.button{cursor:var(--cursor-interactive);--button-bg:transparent;--button-bg-hover:var(--button-bg);--button-bg-pressed:var(--button-bg-hover);--button-fg:currentColor;background-color:var(--button-bg);color:var(--button-fg)}.button:focus-visible:not(:focus),.button[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.button:disabled,.button[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.button[data-pending=true]{pointer-events:none}.button:active,.button[data-pressed=true]{background-color:var(--button-bg-pressed);transform:scale(.97)}@media(hover:hover){.button:hover,.button[data-hovered=true]{background-color:var(--button-bg-hover)}}.button svg:not([data-slot=spinner] svg,[data-slot=link-icon] svg){pointer-events:none;margin-inline:calc(var(--spacing) * -.5);margin-block:calc(var(--spacing) * .5);width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5);flex-shrink:0;align-self:center}@media(min-width:40rem){.button svg:not([data-slot=spinner] svg,[data-slot=link-icon] svg){margin-block:var(--spacing);width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}}.button--sm{height:calc(var(--spacing) * 9);padding-inline:calc(var(--spacing) * 3)}@media(min-width:48rem){.button--sm{height:calc(var(--spacing) * 8)}}.button--sm svg:not([data-slot=spinner] svg,[data-slot=link-icon] svg){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.button--sm:active,.button--sm[data-pressed=true]{transform:scale(.98)}.button--lg{height:calc(var(--spacing) * 11);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}@media(min-width:48rem){.button--lg{height:calc(var(--spacing) * 10)}}.button--lg:active,.button--lg[data-pressed=true]{transform:scale(.96)}.button--primary{--button-bg:var(--accent);--button-bg-hover:var(--accent-hover);--button-bg-pressed:var(--accent-hover);--button-fg:var(--accent-foreground)}.button--secondary{--button-bg:var(--default);--button-bg-hover:var(--default-hover);--button-bg-pressed:var(--default-hover);--button-fg:var(--accent-soft-foreground)}.button--tertiary{--button-bg:var(--default);--button-bg-hover:var(--default-hover);--button-bg-pressed:var(--default-hover)}.button--ghost,.button--outline{--button-bg:transparent;--button-bg-hover:var(--default);--button-bg-pressed:var(--default);--button-fg:var(--default-foreground)}.button--outline{border-style:var(--tw-border-style);border-width:1px;border-color:var(--border);--button-bg-hover:var(--default)}@supports (color:color-mix(in lab,red,red)){.button--outline{--button-bg-hover:color-mix(in srgb, var(--default) 60%, transparent)}}.button--danger{--button-bg:var(--danger);--button-bg-hover:var(--danger-hover);--button-bg-pressed:var(--danger-hover);--button-fg:var(--danger-foreground)}.button--danger-soft{--button-bg:var(--danger-soft);--button-bg-hover:var(--danger-soft-hover);--button-bg-pressed:var(--danger-soft-hover);--button-fg:var(--danger-soft-foreground)}.button--icon-only{width:calc(var(--spacing) * 10);padding:0}@media(min-width:48rem){.button--icon-only{width:calc(var(--spacing) * 9)}}.button--icon-only.button--sm{width:calc(var(--spacing) * 9)}@media(min-width:48rem){.button--icon-only.button--sm{width:calc(var(--spacing) * 8)}}.button--icon-only.button--lg{width:calc(var(--spacing) * 11)}@media(min-width:48rem){.button--icon-only.button--lg{width:calc(var(--spacing) * 10)}}.button--full-width{width:100%}.button-group{justify-content:center;align-items:center;gap:0;height:auto;display:inline-flex}.button-group--horizontal{flex-direction:row}.button-group--vertical{flex-direction:column}.button-group .button{border-radius:0}.button-group--horizontal .button:first-child{border-start-start-radius:calc(var(--radius) * 3);border-end-start-radius:calc(var(--radius) * 3)}.button-group--horizontal .button:last-child{border-start-end-radius:calc(var(--radius) * 3);border-end-end-radius:calc(var(--radius) * 3)}.button-group--horizontal .button:first-child:last-child{border-radius:calc(var(--radius) * 3)}.button-group--vertical .button:first-child{border-top-left-radius:calc(var(--radius) * 3);border-top-right-radius:calc(var(--radius) * 3)}.button-group--vertical .button:last-child{border-bottom-right-radius:calc(var(--radius) * 3);border-bottom-left-radius:calc(var(--radius) * 3)}.button-group--vertical .button:first-child:last-child{border-radius:calc(var(--radius) * 3)}.button-group .button:active,.button-group .button[data-pressed=true]{transform:none}.button-group .button:focus-visible:not(:focus),.button-group .button[data-focus-visible=true]{--tw-ring-offset-width:0px;--tw-ring-inset:inset}.button-group__separator{border-radius:calc(var(--radius) * .5);opacity:.15;pointer-events:none;transition:opacity .15s var(--ease-smooth);background-color:currentColor;position:absolute}.button-group__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.button-group__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.button-group__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.button-group__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.button-group__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.button-group__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.button-group--horizontal .button-group__separator{width:1px;height:50%;top:25%;left:-1px}.button-group--vertical .button-group__separator{width:50%;height:1px;top:-1px;left:25%}.button-group--horizontal .button--outline:first-child{border-inline-end-style:var(--tw-border-style);border-inline-end-width:0}.button-group--horizontal .button--outline:last-child{border-inline-start-style:var(--tw-border-style);border-inline-start-width:0}.button-group--horizontal .button--outline:not(:first-child):not(:last-child){border-inline-style:var(--tw-border-style);border-inline-width:0}.button-group--vertical .button--outline:first-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}.button-group--vertical .button--outline:last-child{border-top-style:var(--tw-border-style);border-top-width:0}.button-group--vertical .button--outline:not(:first-child):not(:last-child){border-block-style:var(--tw-border-style);border-block-width:0}.button-group--full-width{width:100%}.toggle-button{isolation:isolate;height:calc(var(--spacing) * 10);transform-origin:50%;justify-content:center;align-items:center;gap:calc(var(--spacing) * 2);border-radius:calc(var(--radius) * 3);width:fit-content;padding-inline:calc(var(--spacing) * 4);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);white-space:nowrap;--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;outline-style:none;display:inline-flex;position:relative}@media(min-width:48rem){.toggle-button{height:calc(var(--spacing) * 9)}}.toggle-button{transition:transform .25s var(--ease-smooth),background-color .1s var(--ease-out),box-shadow .1s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.toggle-button:is([data-reduce-motion=true],[data-reduce-motion=true] *),.toggle-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.toggle-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.toggle-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.toggle-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.toggle-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.toggle-button{cursor:var(--cursor-interactive);--toggle-button-bg:var(--default);--toggle-button-bg-hover:var(--default-hover);--toggle-button-bg-pressed:var(--default-hover);--toggle-button-fg:currentColor;--toggle-button-bg-selected:var(--accent-soft);--toggle-button-bg-selected-hover:var(--accent-soft-hover);--toggle-button-bg-selected-pressed:var(--accent-soft-hover);--toggle-button-fg-selected:var(--accent-soft-foreground);background-color:var(--toggle-button-bg);color:var(--toggle-button-fg)}.toggle-button:focus-visible:not(:focus),.toggle-button[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.toggle-button:disabled,.toggle-button[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}@media(hover:hover){.toggle-button:hover,.toggle-button[data-hovered=true]{background-color:var(--toggle-button-bg-hover)}}.toggle-button:active,.toggle-button[data-pressed=true]{background-color:var(--toggle-button-bg-pressed);transform:scale(.97)}.toggle-button[data-selected=true]{background-color:var(--toggle-button-bg-selected);color:var(--toggle-button-fg-selected)}@media(hover:hover){.toggle-button[data-selected=true]:hover,.toggle-button[data-selected=true][data-hovered=true]{background-color:var(--toggle-button-bg-selected-hover)}}.toggle-button[data-selected=true]:active,.toggle-button[data-selected=true][data-pressed=true]{background-color:var(--toggle-button-bg-selected-pressed)}.toggle-button svg{pointer-events:none;margin-inline:calc(var(--spacing) * -.5);margin-block:calc(var(--spacing) * .5);width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5);flex-shrink:0;align-self:center}@media(min-width:40rem){.toggle-button svg{margin-block:var(--spacing);width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}}.toggle-button--sm{height:calc(var(--spacing) * 9);padding-inline:calc(var(--spacing) * 3)}@media(min-width:48rem){.toggle-button--sm{height:calc(var(--spacing) * 8)}}.toggle-button--sm svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.toggle-button--sm:active,.toggle-button--sm[data-pressed=true]{transform:scale(.98)}.toggle-button--lg{height:calc(var(--spacing) * 11);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}@media(min-width:48rem){.toggle-button--lg{height:calc(var(--spacing) * 10)}}.toggle-button--lg:active,.toggle-button--lg[data-pressed=true]{transform:scale(.96)}.toggle-button--default{--toggle-button-bg:var(--default);--toggle-button-bg-hover:var(--default-hover);--toggle-button-bg-pressed:var(--default-hover)}.toggle-button--ghost{--toggle-button-bg:transparent;--toggle-button-bg-hover:var(--default);--toggle-button-bg-pressed:var(--default);--toggle-button-fg:var(--default-foreground)}.toggle-button--icon-only{width:calc(var(--spacing) * 10);padding:0}@media(min-width:48rem){.toggle-button--icon-only{width:calc(var(--spacing) * 9)}}.toggle-button--icon-only.toggle-button--sm{width:calc(var(--spacing) * 9)}@media(min-width:48rem){.toggle-button--icon-only.toggle-button--sm{width:calc(var(--spacing) * 8)}}.toggle-button--icon-only.toggle-button--lg{width:calc(var(--spacing) * 11)}@media(min-width:48rem){.toggle-button--icon-only.toggle-button--lg{width:calc(var(--spacing) * 10)}}.toggle-button-group{justify-content:center;align-items:center;gap:0;width:fit-content;height:auto;display:inline-flex}.toggle-button-group--horizontal{flex-direction:row}.toggle-button-group--vertical{flex-direction:column}.toggle-button-group--full-width{width:100%}.toggle-button-group .toggle-button{border-radius:0}.toggle-button-group--horizontal .toggle-button:first-child{border-start-start-radius:calc(var(--radius) * 3);border-end-start-radius:calc(var(--radius) * 3)}.toggle-button-group--horizontal .toggle-button:last-child{border-start-end-radius:calc(var(--radius) * 3);border-end-end-radius:calc(var(--radius) * 3)}.toggle-button-group--horizontal .toggle-button:first-child:last-child{border-radius:calc(var(--radius) * 3)}.toggle-button-group--vertical .toggle-button:first-child{border-top-left-radius:calc(var(--radius) * 3);border-top-right-radius:calc(var(--radius) * 3)}.toggle-button-group--vertical .toggle-button:last-child{border-bottom-right-radius:calc(var(--radius) * 3);border-bottom-left-radius:calc(var(--radius) * 3)}.toggle-button-group--vertical .toggle-button:first-child:last-child{border-radius:calc(var(--radius) * 3)}.toggle-button-group .toggle-button:active,.toggle-button-group .toggle-button[data-pressed=true]{transform:none}.toggle-button-group .toggle-button:focus-visible:not(:focus),.toggle-button-group .toggle-button[data-focus-visible=true]{--tw-ring-offset-width:0px;--tw-ring-inset:inset}.toggle-button-group--full-width .toggle-button{flex:1}.toggle-button-group__separator{border-radius:calc(var(--radius) * .5);opacity:.15;pointer-events:none;transition:opacity .15s var(--ease-smooth);background-color:currentColor;position:absolute}.toggle-button-group__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.toggle-button-group__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.toggle-button-group__separator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.toggle-button-group__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.toggle-button-group__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.toggle-button-group__separator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.toggle-button-group--horizontal .toggle-button-group__separator{width:1px;height:50%;top:25%;left:-1px}.toggle-button-group--vertical .toggle-button-group__separator{width:50%;height:1px;top:-1px;left:25%}.toggle-button-group--detached{gap:var(--spacing)}.toggle-button-group--detached .toggle-button{border-radius:calc(var(--radius) * 3)}.toggle-button-group--detached .toggle-button-group__separator{display:none}.toolbar{align-items:center;gap:calc(var(--spacing) * 2);grid-auto-flow:column;width:fit-content;display:grid}.toolbar .separator--vertical{align-self:center;height:50%}.toolbar .separator--horizontal{justify-content:center;justify-self:center;width:50%}.toolbar--vertical{grid-auto-flow:row;justify-content:flex-start;align-items:flex-start}.toolbar--vertical .button-group{justify-content:flex-start}.toolbar--attached{border-radius:calc(var(--radius) * 3);background-color:var(--surface);padding:var(--spacing);--tw-shadow:var(--overlay-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.dropdown{gap:var(--spacing);flex-direction:column;display:flex}.dropdown__trigger{--tw-outline-style:none;transition:transform .25s var(--ease-out-quart),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);outline-style:none;display:inline-block}.dropdown__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.dropdown__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.dropdown__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.dropdown__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.dropdown__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.dropdown__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.dropdown__trigger{cursor:var(--cursor-interactive)}.dropdown__trigger:focus-visible:not(:focus),.dropdown__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.dropdown__trigger:disabled,.dropdown__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.dropdown__trigger[data-pending=true]{pointer-events:none}.dropdown__trigger:active,.dropdown__trigger[data-pressed=true]{transform:scale(.97)}.dropdown__popover{max-width:48svw;transform-origin:var(--trigger-anchor-point);scroll-padding-block:var(--spacing);scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);overscroll-behavior:contain;background-color:var(--overlay);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));padding:0;overflow-y:auto}@media(min-width:48rem){.dropdown__popover{min-width:calc(var(--spacing) * 55)}}.dropdown__popover{border-radius:min(32px,var(--radius-3xl));box-shadow:var(--shadow-overlay)}.dropdown__popover:focus-visible:not(:focus),.dropdown__popover[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.dropdown__popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.9;transition-duration:.15s;transition-timing-function:ease}.dropdown__popover[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.dropdown__popover[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.dropdown__popover[data-entering=true][data-placement=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.dropdown__popover[data-entering=true][data-placement=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.dropdown__popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.dropdown__popover[data-exiting=true],.dropdown__popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.dropdown__popover [data-slot=popover-overlay-arrow]{fill:var(--overlay)}.dropdown__popover[data-placement=bottom] [data-slot=popover-overlay-arrow]{rotate:180deg}.dropdown__popover[data-placement=left] [data-slot=popover-overlay-arrow]{rotate:-90deg}.dropdown__popover[data-placement=right] [data-slot=popover-overlay-arrow]{rotate:90deg}.dropdown__popover [data-slot=dropdown-menu]{padding:calc(var(--spacing) * 1.5);--tw-outline-style:none;outline-style:none}.dropdown__popover [data-slot=menu-item]{padding-inline:calc(var(--spacing) * 2.5)}.dropdown__menu{gap:calc(var(--spacing) * .5);width:100%;padding:var(--spacing);flex-direction:column;display:flex;position:relative;overflow:clip}.dropdown__menu [data-slot=separator]{width:94%;margin-left:3%}.list-box-item{min-height:calc(var(--spacing) * 9);justify-content:flex-start;align-items:center;gap:calc(var(--spacing) * 3);border-radius:calc(var(--radius) * 2);width:100%;padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 1.5);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;transition:transform .25s var(--ease-out-quart),box-shadow .15s var(--ease-out);outline-style:none;display:flex;position:relative}.list-box-item:is([data-reduce-motion=true],[data-reduce-motion=true] *),.list-box-item:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.list-box-item:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.list-box-item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.list-box-item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.list-box-item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.list-box-item{cursor:var(--cursor-interactive)}.list-box-item [data-slot=label]{pointer-events:none;-webkit-user-select:none;user-select:none;width:fit-content}.list-box-item [data-slot=description]{pointer-events:none;text-wrap:wrap;-webkit-user-select:none;user-select:none}.list-box-item:has(.list-box-item__indicator){padding-inline-end:calc(var(--spacing) * 7)}.list-box-item:focus-visible:not(:focus),.list-box-item[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.list-box-item:active,.list-box-item[data-pressed=true]{transform:scale(.98)}@media(hover:hover){.list-box-item:hover,.list-box-item[data-hovered=true]{background-color:var(--default)}}.list-box-item[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.list-box-item__indicator{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);color:var(--default-foreground);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.25s;inset-inline-end:calc(var(--spacing) * 2);flex-shrink:0;justify-content:center;align-items:center;transition-duration:.25s;display:flex;position:absolute;top:50%}.list-box-item__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.list-box-item__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.list-box-item__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.list-box-item__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.list-box-item__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.list-box-item__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.list-box-item__indicator [data-slot=list-box-item-indicator--checkmark]{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5);transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.3s;transition-duration:.3s}.list-box-item__indicator [data-slot=list-box-item-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *),.list-box-item__indicator [data-slot=list-box-item-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.list-box-item__indicator [data-slot=list-box-item-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.list-box-item__indicator [data-slot=list-box-item-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.list-box-item__indicator [data-slot=list-box-item-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.list-box-item__indicator [data-slot=list-box-item-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.list-box-item__indicator .list-box-item[aria-selected=true] [data-slot=list-box-item-indicator--checkmark],.list-box-item__indicator .list-box-item[data-selected=true] [data-slot=list-box-item-indicator--checkmark]{transition:stroke-dashoffset .25s linear}:is(.list-box-item__indicator .list-box-item[aria-selected=true] [data-slot=list-box-item-indicator--checkmark],.list-box-item__indicator .list-box-item[data-selected=true] [data-slot=list-box-item-indicator--checkmark]):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.list-box-item__indicator .list-box-item[aria-selected=true] [data-slot=list-box-item-indicator--checkmark],.list-box-item__indicator .list-box-item[data-selected=true] [data-slot=list-box-item-indicator--checkmark]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.list-box-item__indicator .list-box-item[aria-selected=true] [data-slot=list-box-item-indicator--checkmark],.list-box-item__indicator .list-box-item[data-selected=true] [data-slot=list-box-item-indicator--checkmark]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){:is(.list-box-item__indicator .list-box-item[aria-selected=true] [data-slot=list-box-item-indicator--checkmark],.list-box-item__indicator .list-box-item[data-selected=true] [data-slot=list-box-item-indicator--checkmark]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.list-box-item__indicator .list-box-item[aria-selected=true] [data-slot=list-box-item-indicator--checkmark],.list-box-item__indicator .list-box-item[data-selected=true] [data-slot=list-box-item-indicator--checkmark]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.list-box-item__indicator .list-box-item[aria-selected=true] [data-slot=list-box-item-indicator--checkmark],.list-box-item__indicator .list-box-item[data-selected=true] [data-slot=list-box-item-indicator--checkmark]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.list-box-item--danger .list-box-item__indicator,.list-box-item--danger [data-slot=label]{color:var(--danger)}.list-box-section{flex-direction:column;align-items:flex-start;gap:0;display:flex}.list-box{width:100%;padding:var(--spacing);position:relative;overflow:clip}.list-box>*+*{margin-top:var(--spacing)}.list-box [data-slot=separator][data-orientation=horizontal]{width:94%;margin-left:3%}.menu-item{min-height:calc(var(--spacing) * 9);justify-content:flex-start;align-items:center;gap:calc(var(--spacing) * 3);border-radius:calc(var(--radius) * 2);width:100%;padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 1.5);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;transition:transform .25s var(--ease-out-quart),box-shadow .15s var(--ease-out);outline-style:none;display:flex;position:relative}.menu-item:is([data-reduce-motion=true],[data-reduce-motion=true] *),.menu-item:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.menu-item:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.menu-item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.menu-item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.menu-item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.menu-item{cursor:var(--cursor-interactive)}.menu-item [data-slot=label]{pointer-events:none;-webkit-user-select:none;user-select:none;width:fit-content}.menu-item [data-slot=description]{pointer-events:none;text-wrap:wrap;-webkit-user-select:none;user-select:none}.menu-item [data-slot=submenu-indicator] svg{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}.menu-item:has(.menu-item__indicator){padding-inline-start:calc(var(--spacing) * 7)}.menu-item[data-has-submenu=true]:has(.menu-item__indicator){padding-inline-start:calc(var(--spacing) * 2);padding-inline-end:calc(var(--spacing) * 7)}.menu-item:focus-visible:not(:focus),.menu-item[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.menu-item:active,.menu-item[data-pressed=true]{transform:scale(.98)}@media(hover:hover){.menu-item:hover,.menu-item[data-hovered=true]{background-color:var(--default)}}:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--checkmark]{transition:stroke-dashoffset .1s linear}:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}:is(.menu-item[aria-checked=true],.menu-item[aria-selected=true],.menu-item[data-selected=true]) [data-slot=menu-item-indicator--dot]{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y);opacity:1}.menu-item[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.menu-item__indicator{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);--tw-translate-y: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);color:var(--muted);transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.25s;inset-inline-start:calc(var(--spacing) * 2);flex-shrink:0;justify-content:center;align-items:center;transition-duration:.25s;display:flex;position:absolute;top:50%}.menu-item__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.menu-item__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.menu-item__indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.menu-item__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.menu-item__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.menu-item__indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.menu-item[data-has-submenu=true] .menu-item__indicator{inset-inline-start:auto;inset-inline-end:calc(var(--spacing) * 2)}.menu-item__indicator [data-slot=menu-item-indicator--checkmark]{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--checkmark]){transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.3s;transition-duration:.3s}.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--checkmark]):is([data-reduce-motion=true],[data-reduce-motion=true] *),.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--checkmark]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--checkmark]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--checkmark]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--checkmark]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--checkmark]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.menu-item__indicator [data-slot=menu-item-indicator--dot]{width:calc(var(--spacing) * 2);height:calc(var(--spacing) * 2)}.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--dot]){transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.25s;transition-duration:.25s}.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--dot]):is([data-reduce-motion=true],[data-reduce-motion=true] *),.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--dot]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--dot]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--dot]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--dot]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.menu-item[data-selection-mode=multiple] :is(.menu-item__indicator [data-slot=menu-item-indicator--dot]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.menu-item__indicator [data-slot=menu-item-indicator--dot]{--tw-scale-x:70%;--tw-scale-y:70%;--tw-scale-z:70%;scale:var(--tw-scale-x) var(--tw-scale-y);opacity:0}.menu-item__indicator--submenu{color:var(--muted)}.menu-item__indicator--submenu svg{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.menu-item--danger .menu-item__indicator,.menu-item--danger [data-slot=label]{color:var(--danger)}.menu-section{flex-direction:column;align-items:flex-start;gap:0;display:flex}.menu{gap:var(--spacing);width:100%;padding:var(--spacing);flex-direction:column;display:flex;position:relative;overflow:clip}.menu [data-slot=separator]{width:94%;margin-left:3%}.tag-group{gap:var(--spacing);flex-direction:column;display:flex;position:relative}.tag-group__list{gap:calc(var(--spacing) * 1.5);flex-wrap:wrap;display:flex;position:relative}.tag-group [slot=description],.tag-group [data-slot=description],.tag-group [slot=errorMessage],.tag-group [data-slot=error-message]{padding:var(--spacing)}.tag{--optical-offset:.031em;align-items:center;gap:var(--spacing);border-radius:calc(var(--radius) * 1.5);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:color .1s var(--ease-smooth),scale .1s var(--ease-smooth),opacity .1s var(--ease-smooth),background-color .1s var(--ease-smooth),box-shadow .1s var(--ease-out);transform-origin:50%;transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);display:inline-flex;position:relative}.tag:is([data-reduce-motion=true],[data-reduce-motion=true] *),.tag:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.tag:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.tag:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.tag:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.tag:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.tag{cursor:var(--cursor-interactive)}.tag svg{pointer-events:none;width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3);color:currentColor;flex-shrink:0;align-self:center}.tag:is([data-disabled=true],[aria-disabled=true]){opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.tag:is(:focus-visible,[data-focus-visible]){--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.tag:is([data-selected=true],[aria-selected=true]){background-color:var(--accent-soft);color:var(--accent-soft-foreground)}@media(hover:hover){.tag:is([data-selected=true],[aria-selected=true]):is(:hover,[data-hovered=true]){background-color:var(--accent-soft-hover)}}.tag--sm{padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * .5);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.tag--md{padding-inline:calc(var(--spacing) * 2);padding-block:var(--spacing);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.tag--lg{border-radius:calc(var(--radius) * 2);padding-inline:calc(var(--spacing) * 2.5);padding-block:calc(var(--spacing) * 1.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.tag--default{background-color:var(--default);color:var(--default-foreground)}@media(hover:hover){.tag--default:is(:hover,[data-hovered=true]):not([data-selected=true]):not([data-disabled=true]){background-color:var(--default-hover)}}.tag--surface{background-color:var(--surface);color:var(--surface-foreground)}@media(hover:hover){.tag--surface:is(:hover,[data-hovered=true]):not([data-selected=true]):not([data-disabled=true]){background-color:var(--surface-hover)}}.tag__remove-button{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3);color:inherit}.tag__remove-button svg{width:inherit;height:inherit;color:currentColor;flex-shrink:0;align-self:center}.color-area{width:100%;max-width:calc(var(--spacing) * 56);border-radius:calc(var(--radius) * 2);-webkit-tap-highlight-color:transparent;aspect-ratio:1;background:var(--color-area-background);flex-shrink:0;position:relative;box-shadow:inset 0 0 0 1px #0000001a}.color-area[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.color-area--show-dots:after{content:"";pointer-events:none;border-radius:inherit;background-image:radial-gradient(circle,#fff3 1px,#0000 1px);background-size:8px 8px;position:absolute;top:0;right:0;bottom:0;left:0}.color-area__thumb{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * 1.5);will-change:width,height;background-color:var(--color-area-thumb-color);transition:width .15s var(--ease-out),height .15s var(--ease-out);border:3px solid #fff;box-shadow:0 0 0 1px #0000001a,inset 0 0 0 1px #0000001a}.color-area__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *),.color-area__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.color-area__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.color-area__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.color-area__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.color-area__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.color-area__thumb[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.color-area__thumb[data-dragging=true]{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.color-area__thumb[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.color-picker{display:inline-flex}.color-picker__trigger{align-items:center;gap:calc(var(--spacing) * 3);border-radius:calc(var(--radius) * .5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);transition:background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);display:inline-flex}.color-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.color-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.color-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.color-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.color-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.color-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.color-picker__trigger [data-slot=label]{cursor:var(--cursor-interactive)}.color-picker__trigger:focus-visible:not(:focus),.color-picker__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.color-picker__trigger:disabled,.color-picker__trigger[data-disabled=true],.color-picker__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.color-picker__popover{min-width:calc(var(--spacing) * 62);transform-origin:var(--trigger-anchor-point);scrollbar-color:auto;scrollbar-gutter:auto;-ms-overflow-style:none;scrollbar-width:none;overscroll-behavior:contain;background-color:var(--overlay);padding-inline:calc(var(--spacing) * 2);padding-top:calc(var(--spacing) * 2);padding-bottom:calc(var(--spacing) * 3);box-shadow:var(--shadow-overlay);border-radius:min(32px,calc(var(--radius) * 2.5));gap:calc(var(--spacing) * 3);flex-direction:column;display:flex;overflow:hidden auto}.color-picker__popover:focus-visible:not(:focus),.color-picker__popover[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.color-picker__popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.95;transition-duration:.15s;transition-timing-function:ease}.color-picker__popover[data-entering=true][data-placement^=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.color-picker__popover[data-entering=true][data-placement^=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.color-picker__popover[data-entering=true][data-placement^=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.color-picker__popover[data-entering=true][data-placement^=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.color-picker__popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.color-picker__popover[data-exiting=true],.color-picker__popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.color-slider{gap:var(--spacing);grid-template:"label output""track track"/1fr auto;width:100%;display:grid}.color-slider:not(:has([data-slot=label])):not(:has(.color-slider__output)){grid-template:"track"/1fr;gap:0}.color-slider:has([data-slot=label]):not(:has(.color-slider__output)){grid-template-columns:1fr;grid-template-areas:"label""track"}.color-slider:not(:has([data-slot=label])):has(.color-slider__output){grid-template-columns:1fr;grid-template-areas:"output""track"}.color-slider:not(:has([data-slot=label])):has(.color-slider__output) .color-slider__output{justify-self:end}.color-slider [data-slot=label]{width:fit-content;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);grid-area:label}.color-slider .color-slider__output{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);grid-area:output}.color-slider .color-slider__track{border-radius:calc(var(--radius) * 2);grid-area:track;position:relative}.color-slider .color-slider__track:before,.color-slider .color-slider__track:after{content:"";z-index:0;pointer-events:none;position:absolute}.color-slider .color-slider__thumb{cursor:grab;border-radius:calc(var(--radius) * 2);-webkit-tap-highlight-color:transparent;border-style:var(--tw-border-style);border-width:3px;border-color:var(--color-white);--tw-shadow:var(--overlay-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);z-index:1;transition:transform .25s var(--ease-out),box-shadow .15s var(--ease-out);justify-content:center;align-items:center;display:flex;position:absolute}.color-slider .color-slider__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *),.color-slider .color-slider__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.color-slider .color-slider__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.color-slider .color-slider__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.color-slider .color-slider__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.color-slider .color-slider__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.color-slider .color-slider__thumb[data-dragging=true]{cursor:grabbing}.color-slider .color-slider__thumb[data-focus-visible=true]{z-index:10;--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.color-slider .color-slider__thumb[data-disabled=true]{cursor:default;background-color:var(--default)}.color-slider:disabled,.color-slider[data-disabled=true],.color-slider[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:is(.color-slider:disabled,.color-slider[data-disabled=true],.color-slider[aria-disabled=true]) [data-slot=label]{opacity:1}.color-slider[data-orientation=horizontal]{flex-direction:column}.color-slider[data-orientation=horizontal] .color-slider__track{height:calc(var(--spacing) * 5);border-radius:0;justify-self:center;width:calc(100% - 1.25rem);box-shadow:inset 0 1px #0000001a,inset 0 -1px #0000001a}.color-slider[data-orientation=horizontal] .color-slider__track:before,.color-slider[data-orientation=horizontal] .color-slider__track:after{width:.625rem;height:100%;top:0}.color-slider[data-orientation=horizontal] .color-slider__track:before{border-top-left-radius:calc(var(--radius) * 2);border-bottom-left-radius:calc(var(--radius) * 2);background:linear-gradient(var(--track-start-color,transparent)),repeating-conic-gradient(#efefef,#efefef 25%,#f7f7f7 0%,#f7f7f7 50%) 50% / 16px 16px;left:-.625rem;box-shadow:inset 1px 0 #0000001a,inset 0 1px #0000001a,inset 0 -1px #0000001a}.color-slider[data-orientation=horizontal] .color-slider__track:after{border-top-right-radius:calc(var(--radius) * 2);border-bottom-right-radius:calc(var(--radius) * 2);background-color:var(--track-end-color,transparent);right:-.625rem;box-shadow:inset -1px 0 #0000001a,inset 0 1px #0000001a,inset 0 -1px #0000001a}.color-slider[data-orientation=horizontal] .color-slider__thumb{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);top:50%}.color-slider[data-orientation=vertical]{gap:calc(var(--spacing) * 2);flex-direction:row;grid-template:"output""track"1fr"label"/1fr;place-items:center;height:100%}.color-slider[data-orientation=vertical]:not(:has([data-slot=label])):not(:has(.color-slider__output)){grid-template-rows:1fr;grid-template-areas:"track";gap:0}.color-slider[data-orientation=vertical]:has([data-slot=label]):not(:has(.color-slider__output)){grid-template-rows:1fr auto;grid-template-areas:"track""label"}.color-slider[data-orientation=vertical]:not(:has([data-slot=label])):has(.color-slider__output){grid-template-rows:auto 1fr;grid-template-areas:"output""track"}.color-slider[data-orientation=vertical] .color-slider__output,.color-slider[data-orientation=vertical] [data-slot=label]{text-align:center}.color-slider[data-orientation=vertical] .color-slider__track{width:calc(var(--spacing) * 5);border-radius:0;justify-self:center;height:calc(100% - 1.25rem);box-shadow:inset 1px 0 #0000001a,inset -1px 0 #0000001a}.color-slider[data-orientation=vertical] .color-slider__track:before,.color-slider[data-orientation=vertical] .color-slider__track:after{width:100%;height:.625rem;left:0}.color-slider[data-orientation=vertical] .color-slider__track:before{background:linear-gradient(var(--track-start-color,transparent)),repeating-conic-gradient(#efefef,#efefef 25%,#f7f7f7 0%,#f7f7f7 50%) 50% / 16px 16px;border-bottom-right-radius:999px;border-bottom-left-radius:999px;bottom:-.625rem;box-shadow:inset 1px 0 #0000001a,inset -1px 0 #0000001a,inset 0 -1px #0000001a}.color-slider[data-orientation=vertical] .color-slider__track:after{background-color:var(--track-end-color,transparent);border-top-left-radius:999px;border-top-right-radius:999px;top:-.625rem;box-shadow:inset 1px 0 #0000001a,inset -1px 0 #0000001a,inset 0 1px #0000001a}.color-slider[data-orientation=vertical] .color-slider__thumb{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);left:50%}.color-swatch{box-sizing:border-box;width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8);background:linear-gradient(var(--color-swatch-current),var(--color-swatch-current)),repeating-conic-gradient(#efefef,#efefef 25%,#f7f7f7 0%,#f7f7f7 50%) 50% / 16px 16px;flex-shrink:0;position:relative;box-shadow:inset 0 0 0 1px #0000001a}.color-swatch--circle{border-radius:calc(var(--radius) * 2)}.color-swatch--square{border-radius:calc(var(--radius) * .75)}.color-swatch--xs{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.color-swatch--xs.color-swatch--circle{border-radius:calc(var(--radius) * 1)}.color-swatch--sm{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.color-swatch--sm.color-swatch--circle{border-radius:calc(var(--radius) * 1.5)}.color-swatch--lg{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.color-swatch--lg.color-swatch--circle{border-radius:calc(var(--radius) * 3)}.color-swatch--xl{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.color-swatch--xl.color-swatch--circle{border-radius:calc(var(--radius) * 3)}.color-swatch-picker{align-items:center;gap:calc(var(--spacing) * 2);flex-wrap:wrap;display:flex}.color-swatch-picker__item{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8);border-radius:calc(var(--radius) * 2);border-style:var(--tw-border-style);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);transition:border-color .1s var(--ease-out),box-shadow .1s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);border-width:2px;border-color:#0000;outline-style:none;justify-content:center;align-items:center;display:flex;position:relative}.color-swatch-picker__item:is([data-reduce-motion=true],[data-reduce-motion=true] *),.color-swatch-picker__item:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.color-swatch-picker__item:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.color-swatch-picker__item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.color-swatch-picker__item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.color-swatch-picker__item:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.color-swatch-picker__item:focus-visible,.color-swatch-picker__item[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.color-swatch-picker__item[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.color-swatch-picker__item[data-selected=true]{border-color:var(--color-swatch-current);box-shadow:var(--field-shadow)}.color-swatch-picker__item[data-selected=true] .color-swatch-picker__swatch{transform:scale(.77)}.color-swatch-picker__swatch{border-radius:inherit;width:100%;height:100%;transition:transform .1s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);display:block}.color-swatch-picker__swatch:is([data-reduce-motion=true],[data-reduce-motion=true] *),.color-swatch-picker__swatch:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.color-swatch-picker__swatch:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.color-swatch-picker__swatch:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.color-swatch-picker__swatch:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.color-swatch-picker__swatch:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.color-swatch-picker__swatch:hover{transform:scale(1.1)}}.color-swatch-picker__indicator{pointer-events:none;z-index:10;justify-content:center;align-items:center;display:flex;position:absolute;top:0;right:0;bottom:0;left:0}.color-swatch-picker__indicator>*{width:33.3333%;height:33.3333%;color:var(--color-white);transition:transform .15s var(--ease-out);transform:scale(0)translateZ(0)}.color-swatch-picker__indicator>:is([data-reduce-motion=true],[data-reduce-motion=true] *),.color-swatch-picker__indicator>:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.color-swatch-picker__indicator>:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.color-swatch-picker__indicator>:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.color-swatch-picker__indicator>:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.color-swatch-picker__indicator>:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.color-swatch-picker__indicator[data-light-color=true] .color-swatch-picker__indicator>*{color:var(--color-black)}.color-swatch-picker__item[data-selected=true] .color-swatch-picker__indicator>*{transform:scale(1)translateZ(0)}.color-swatch-picker--stack{flex-direction:column}.color-swatch-picker--xs .color-swatch-picker__item{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * 1);border-style:var(--tw-border-style);border-width:1px}.color-swatch-picker--sm .color-swatch-picker__item{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6);border-radius:calc(var(--radius) * 1.5);border-style:var(--tw-border-style);border-width:2px}.color-swatch-picker--lg .color-swatch-picker__item{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9);border-radius:calc(var(--radius) * 3);border-style:var(--tw-border-style);border-width:3px}.color-swatch-picker--xl .color-swatch-picker__item{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10);border-radius:calc(var(--radius) * 3);border-style:var(--tw-border-style);border-width:3px}.color-swatch-picker--square .color-swatch-picker__item{border-radius:calc(var(--radius) * 1.5)}.color-swatch-picker--square .color-swatch-picker__item .color-swatch-picker__swatch,.color-swatch-picker--square .color-swatch-picker__item[data-selected=true] .color-swatch-picker__swatch{border-radius:calc(var(--radius) * 1)}.color-swatch-picker--square.color-swatch-picker--xs .color-swatch-picker__item,.color-swatch-picker--square.color-swatch-picker--xs .color-swatch-picker__item .color-swatch-picker__swatch,.color-swatch-picker--square.color-swatch-picker--xs .color-swatch-picker__item[data-selected=true] .color-swatch-picker__swatch{border-radius:calc(var(--radius) * .75)}.color-swatch-picker--square.color-swatch-picker--sm .color-swatch-picker__item,.color-swatch-picker--square.color-swatch-picker--sm .color-swatch-picker__item .color-swatch-picker__swatch{border-radius:calc(var(--radius) * 1)}.color-swatch-picker--square.color-swatch-picker--sm .color-swatch-picker__item[data-selected=true] .color-swatch-picker__swatch{border-radius:calc(var(--radius) * .75)}.color-swatch-picker--square.color-swatch-picker--lg .color-swatch-picker__item{border-radius:calc(var(--radius) * 1.5)}.color-swatch-picker--square.color-swatch-picker--lg .color-swatch-picker__item .color-swatch-picker__swatch,.color-swatch-picker--square.color-swatch-picker--lg .color-swatch-picker__item[data-selected=true] .color-swatch-picker__swatch{border-radius:calc(var(--radius) * 1)}.color-swatch-picker--square.color-swatch-picker--xl .color-swatch-picker__item{border-radius:calc(var(--radius) * 1.5)}.color-swatch-picker--square.color-swatch-picker--xl .color-swatch-picker__item .color-swatch-picker__swatch,.color-swatch-picker--square.color-swatch-picker--xl .color-swatch-picker__item[data-selected=true] .color-swatch-picker__swatch{border-radius:calc(var(--radius) * 1)}.color-input-group{height:calc(var(--spacing) * 9);border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border);transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);outline-style:none;align-items:center;display:inline-flex;overflow:hidden}.color-input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *),.color-input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.color-input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.color-input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.color-input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.color-input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.color-input-group:hover:not(:focus-within),.color-input-group[data-hovered=true]:not([data-focus-within=true]){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.color-input-group[data-focus-within=true],.color-input-group:focus-within{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;outline-style:none}.color-input-group[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.color-input-group[data-invalid=true]:focus,.color-input-group[data-invalid=true]:focus-visible,.color-input-group[data-invalid=true][data-focused=true],.color-input-group[data-invalid=true][data-focus-visible=true],.color-input-group[data-invalid=true]:focus-within,.color-input-group[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.color-input-group[data-invalid=true]{background-color:var(--field-focus);border-color:var(--color-field-border-invalid)}.color-input-group[data-disabled=true],.color-input-group[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.color-input-group__input{cursor:text;border-style:var(--tw-border-style);height:100%;padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;background-color:#0000;border-width:0;border-radius:0;outline-style:none;flex:1;align-items:center;display:flex}@media(min-width:40rem){.color-input-group__input{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.color-input-group__input::placeholder{color:var(--field-placeholder,var(--muted))}.color-input-group:has([data-slot=color-input-group-prefix]) .color-input-group__input{padding-left:calc(var(--spacing) * 2);border-top-left-radius:0;border-bottom-left-radius:0}.color-input-group:has([data-slot=color-input-group-suffix]) .color-input-group__input{padding-right:calc(var(--spacing) * 2);border-top-right-radius:0;border-bottom-right-radius:0}.color-input-group__input:focus,.color-input-group__input:focus-visible{--tw-outline-style:none;outline-style:none}.color-input-group__prefix{color:var(--field-placeholder,var(--muted));margin-right:0;margin-left:calc(var(--spacing) * 3);flex-shrink:0;align-items:center;display:flex}.color-input-group__suffix{color:var(--field-placeholder,var(--muted));margin-right:calc(var(--spacing) * 3);flex-shrink:0;align-items:center;display:flex}.color-input-group--secondary{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--color-input-group-bg);--color-input-group-bg:var(--default);--color-input-group-bg-hover:var(--default-hover);--color-input-group-bg-focus:var(--default)}@media(hover:hover){.color-input-group--secondary:hover:not(:focus-within),.color-input-group--secondary[data-hovered=true]:not([data-focus-within=true]){background-color:var(--color-input-group-bg-hover)}}.color-input-group--secondary:focus-within,.color-input-group--secondary[data-focus-within=true]{background-color:var(--color-input-group-bg-focus)}.color-input-group--secondary[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.color-input-group--secondary[data-invalid=true]:focus,.color-input-group--secondary[data-invalid=true]:focus-visible,.color-input-group--secondary[data-invalid=true][data-focused=true],.color-input-group--secondary[data-invalid=true][data-focus-visible=true],.color-input-group--secondary[data-invalid=true]:focus-within,.color-input-group--secondary[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.color-input-group--secondary[data-invalid=true]{border-color:var(--color-field-border-invalid);background-color:var(--color-input-group-bg-focus)}.color-input-group--secondary [data-slot=color-input-group-input]{background-color:#0000}.color-input-group--full-width{width:100%}.color-field{gap:var(--spacing);flex-direction:column;display:flex}:is(.color-field[data-invalid=true],.color-field[aria-invalid=true]) [data-slot=description]{display:none}.color-field [data-slot=label]{width:fit-content}.color-field--full-width{width:100%}.slider{gap:var(--spacing);grid-template-columns:1fr auto;grid-template-areas:"label output""track track";width:100%;display:grid}.slider [data-slot=label]{width:fit-content;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);grid-area:label}.slider .slider__output{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);grid-area:output}.slider .slider__track{border-radius:calc(var(--radius) * 1.5);background-color:var(--default);grid-area:track;position:relative}.slider .slider__fill{pointer-events:none;background-color:var(--accent);position:absolute}.slider .slider__thumb{cursor:grab;border-radius:calc(var(--radius) * 1.5);background-color:var(--accent);-webkit-tap-highlight-color:transparent;transition:background-color .25s var(--ease-smooth),transform .25s var(--ease-out),box-shadow .15s var(--ease-out);justify-content:center;align-items:center;display:flex;position:absolute}.slider .slider__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *),.slider .slider__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.slider .slider__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.slider .slider__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.slider .slider__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.slider .slider__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.slider .slider__thumb:after{z-index:10;border-radius:calc(var(--radius) * 1);background-color:var(--accent-foreground);color:var(--color-black);--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);content:"";transform-origin:50%;transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));position:relative}@media(prefers-reduced-motion:reduce){.slider .slider__thumb:after:not(:is()){transition-property:none}}.slider .slider__thumb[data-dragging=true]{cursor:grabbing}.slider .slider__thumb[data-dragging=true]:after{scale:.9}@media(prefers-reduced-motion:reduce){.slider .slider__thumb[data-dragging=true]:after:not(:is()){--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y)}}.slider .slider__thumb[data-focus-visible=true]{z-index:10;--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.slider .slider__thumb[data-disabled=true]{cursor:default}.slider:disabled,.slider[data-disabled=true],.slider[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:is(.slider:disabled,.slider[data-disabled=true],.slider[aria-disabled=true]) [data-slot=label]{opacity:1}.slider[data-orientation=horizontal]{flex-direction:column}.slider[data-orientation=horizontal] .slider__track{height:calc(var(--spacing) * 5);border-inline-style:var(--tw-border-style);border-inline-width:.75rem;border-inline-color:#0000;width:100%}.slider[data-orientation=horizontal] .slider__track[data-fill-start=true]{border-inline-start-color:var(--accent)}.slider[data-orientation=horizontal] .slider__track[data-fill-end=true]{border-inline-end-color:var(--accent)}.slider[data-orientation=horizontal] .slider__fill,.slider[data-orientation=horizontal] .slider__thumb{height:100%}.slider[data-orientation=horizontal] .slider__thumb{width:1.75rem;top:50%}.slider[data-orientation=horizontal] .slider__thumb:after{width:1.5rem;height:1rem}.slider[data-orientation=vertical]{gap:calc(var(--spacing) * 2);flex-direction:row;grid-template:"output""track"1fr"label"/1fr;height:100%}.slider[data-orientation=vertical] .slider__output,.slider[data-orientation=vertical] [data-slot=label]{text-align:center}.slider[data-orientation=vertical] .slider__track{height:100%;width:calc(var(--spacing) * 5);border-block-style:var(--tw-border-style);border-block-width:.75rem;border-block-color:#0000;justify-self:center}.slider[data-orientation=vertical] .slider__track[data-fill-start=true]{border-bottom-color:var(--accent)}.slider[data-orientation=vertical] .slider__track[data-fill-end=true]{border-top-color:var(--accent)}.slider[data-orientation=vertical] .slider__fill,.slider[data-orientation=vertical] .slider__thumb{width:100%}.slider[data-orientation=vertical] .slider__thumb{height:1.75rem;left:50%}.slider[data-orientation=vertical] .slider__thumb:after{width:1rem;height:1.5rem}.switch{align-items:flex-start;gap:var(--spacing);-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);--switch-control-bg:var(--default);--switch-control-bg-hover:var(--switch-control-bg);flex-direction:column;display:flex}@supports (color:color-mix(in lab,red,red)){.switch{--switch-control-bg-hover:color-mix(in oklab, var(--switch-control-bg), transparent 20%)}}.switch{--switch-control-bg-pressed:var(--switch-control-bg-hover);--switch-control-bg-checked:var(--accent);--switch-control-bg-checked-hover:var(--accent-hover)}.switch[data-disabled=true],.switch[data-disabled=true] [data-slot=description],.switch[data-disabled=true] [data-slot=field-error]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.switch[data-disabled=true] .switch__thumb{background-color:var(--default-foreground)}@supports (color:color-mix(in lab,red,red)){.switch[data-disabled=true] .switch__thumb{background-color:color-mix(in oklab,var(--default-foreground) 20%,transparent)}}.switch>[data-slot=description]{width:100%;min-width:0;padding-inline-start:3.25rem}.switch>[data-slot=field-error]{width:100%;min-width:0;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--muted);padding-inline-start:3.25rem}.switch.switch--sm>[data-slot=description],.switch.switch--sm>[data-slot=field-error]{padding-inline-start:2.75rem}.switch.switch--lg>[data-slot=description],.switch.switch--lg>[data-slot=field-error]{padding-inline-start:3.75rem}:is(.switch:disabled[aria-checked=true],.switch:disabled[data-selected=true],.switch[data-disabled=true][aria-checked=true],.switch[data-disabled=true][data-selected=true],.switch[aria-disabled=true][aria-checked=true],.switch[aria-disabled=true][data-selected=true]) .switch__thumb{opacity:.4}.switch__control{border-radius:calc(var(--radius) * 1.5);background-color:var(--switch-control-bg);width:2.5rem;height:1.25rem;transition:background-color .25s var(--ease-smooth),box-shadow .15s var(--ease-out);flex-shrink:0;align-items:center;display:flex;position:relative;overflow:hidden}.switch__control:is([data-reduce-motion=true],[data-reduce-motion=true] *),.switch__control:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.switch__control:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.switch__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.switch__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.switch__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.switch:focus-visible .switch__control,.switch:has([data-slot=switch-content][data-focus-visible=true]) .switch__control,.switch [data-slot=switch-content][data-focus-visible=true] .switch__control{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.switch:hover .switch__control,.switch:has([data-slot=switch-content][data-hovered=true]) .switch__control,.switch [data-slot=switch-content][data-hovered=true] .switch__control{background-color:var(--switch-control-bg-hover)}.switch:active .switch__control,.switch:has([data-slot=switch-content][data-pressed=true]) .switch__control,.switch [data-slot=switch-content][data-pressed=true] .switch__control{background-color:var(--switch-control-bg-pressed)}:is(.switch:active .switch__control,.switch:has([data-slot=switch-content][data-pressed=true]) .switch__control,.switch [data-slot=switch-content][data-pressed=true] .switch__control):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.switch:active .switch__control,.switch:has([data-slot=switch-content][data-pressed=true]) .switch__control,.switch [data-slot=switch-content][data-pressed=true] .switch__control):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.switch:active .switch__control,.switch:has([data-slot=switch-content][data-pressed=true]) .switch__control,.switch [data-slot=switch-content][data-pressed=true] .switch__control):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transform:none}@media(prefers-reduced-motion:reduce){:is(.switch:active .switch__control,.switch:has([data-slot=switch-content][data-pressed=true]) .switch__control,.switch [data-slot=switch-content][data-pressed=true] .switch__control):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.switch:active .switch__control,.switch:has([data-slot=switch-content][data-pressed=true]) .switch__control,.switch [data-slot=switch-content][data-pressed=true] .switch__control):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.switch:active .switch__control,.switch:has([data-slot=switch-content][data-pressed=true]) .switch__control,.switch [data-slot=switch-content][data-pressed=true] .switch__control):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transform:none}}.switch[aria-checked=true] .switch__control,.switch[data-selected=true] .switch__control{background-color:var(--switch-control-bg-checked)}.switch[aria-checked=true]:hover .switch__control,.switch[data-selected=true]:hover .switch__control,.switch[aria-checked=true][data-hovered=true] .switch__control,.switch[data-selected=true][data-hovered=true] .switch__control,.switch:has([data-slot=switch-content][data-hovered=true])[data-selected=true] .switch__control,.switch[aria-checked=true]:active .switch__control,.switch[data-selected=true]:active .switch__control,.switch[aria-checked=true][data-pressed=true] .switch__control,.switch[data-selected=true][data-pressed=true] .switch__control,.switch:has([data-slot=switch-content][data-pressed=true])[data-selected=true] .switch__control{background-color:var(--switch-control-bg-checked-hover)}.switch__content{cursor:inherit;align-items:center;gap:calc(var(--spacing) * 3);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground);--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;outline-style:none;display:inline-flex}.switch--sm .switch__control{border-radius:calc(var(--radius) * 1);width:2rem;height:1rem}.switch--lg .switch__control{width:3rem;height:1.5rem}.switch__thumb{transform-origin:50%;border-radius:calc(var(--radius) * 1);background-color:var(--color-white);color:var(--color-black);--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);width:1.375rem;height:1rem;transition:margin .3s var(--ease-out-fluid),background-color .2s var(--ease-out);margin-inline-start:calc(var(--spacing) * .5);display:flex}.switch__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *),.switch__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.switch__thumb:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.switch__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.switch__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.switch__thumb:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.switch[aria-checked=true] .switch__thumb,.switch[data-selected=true] .switch__thumb{background-color:var(--accent-foreground);color:var(--accent);margin-inline-start:calc(100% - 1.5rem);box-shadow:0 0 5px #00000005,0 2px 10px #0000000f,0 0 1px #0000004d}.switch--sm .switch__thumb{border-radius:calc(var(--radius) * .75);width:1.03125rem;height:.75rem}.switch[aria-checked=true] :is(.switch--sm .switch__thumb),.switch[data-selected=true] :is(.switch--sm .switch__thumb){margin-inline-start:calc(100% - 1.15625rem)}.switch--lg .switch__thumb{border-radius:calc(var(--radius) * 1.5);width:1.71875rem;height:1.25rem}.switch[aria-checked=true] :is(.switch--lg .switch__thumb),.switch[data-selected=true] :is(.switch--lg .switch__thumb){margin-inline-start:calc(100% - 1.84375rem)}.switch__thumb>*{justify-content:center;align-items:center;width:100%;height:100%;display:flex}.switch__label{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground)}.switch [data-slot=label]{-webkit-user-select:none;user-select:none}.switch__content [data-slot=label]{cursor:var(--cursor-interactive)}.switch [data-slot=description]{cursor:default;-webkit-user-select:none;user-select:none}.switch-group{gap:calc(var(--spacing) * 6);flex-direction:column;display:flex}.switch-group__items{gap:calc(var(--spacing) * 4);display:flex}.switch-group--horizontal .switch-group__items{flex-direction:row}.switch-group--vertical .switch-group__items{flex-direction:column}.badge{justify-content:center;align-items:center;gap:calc(var(--spacing) * .5);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);min-height:calc(var(--spacing) * 7);min-width:calc(var(--spacing) * 7);border-radius:calc(var(--radius) * 3);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-leading:1.34;--badge-bg:var(--default);--badge-fg:var(--default-foreground);--badge-border:var(--background);background-color:var(--badge-bg);color:var(--badge-fg);border:1px solid var(--badge-border);flex-shrink:0;line-height:1.34;display:inline-flex}.badge__label{padding-inline:calc(var(--spacing) * .5)}.badge-anchor{flex-shrink:0;display:inline-flex;position:relative}.badge--lg{min-height:calc(var(--spacing) * 8);min-width:calc(var(--spacing) * 8);border-radius:calc(var(--radius) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:1.43;line-height:1.43}.badge--sm{min-height:calc(var(--spacing) * 4);min-width:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * 1.5);--tw-leading:1.34;font-size:10px;line-height:1.34}.badge--accent{--badge-fg:var(--accent-soft-foreground)}.badge--default{--badge-fg:var(--default-foreground)}.badge--success{--badge-fg:var(--success-soft-foreground)}.badge--warning{--badge-fg:var(--warning-soft-foreground)}.badge--danger{--badge-fg:var(--danger-soft-foreground)}.badge--top-right{position:absolute;top:0;right:0;transform:translate(25%,-25%)}.badge--top-left{position:absolute;top:0;left:0;transform:translate(-25%,-25%)}.badge--bottom-right{position:absolute;bottom:0;right:0;transform:translate(25%,25%)}.badge--bottom-left{position:absolute;bottom:0;left:0;transform:translate(-25%,25%)}.badge--primary.badge--accent{--badge-bg:var(--accent);--badge-fg:var(--accent-foreground)}.badge--primary.badge--default{--badge-bg:var(--default);--badge-fg:var(--default-foreground)}.badge--primary.badge--success{--badge-bg:var(--success);--badge-fg:var(--success-foreground)}.badge--primary.badge--warning{--badge-bg:var(--warning);--badge-fg:var(--warning-foreground)}.badge--primary.badge--danger{--badge-bg:var(--danger);--badge-fg:var(--danger-foreground)}.badge--soft.badge--accent{--badge-bg:var(--accent-soft);--badge-fg:var(--accent-soft-foreground)}.badge--soft.badge--default{--badge-bg:var(--default-soft);--badge-fg:var(--default-soft-foreground)}.badge--soft.badge--success{--badge-bg:var(--success-soft);--badge-fg:var(--success-soft-foreground)}.badge--soft.badge--warning{--badge-bg:var(--warning-soft);--badge-fg:var(--warning-soft-foreground)}.badge--soft.badge--danger{--badge-bg:var(--danger-soft);--badge-fg:var(--danger-soft-foreground)}.chip{align-items:center;gap:calc(var(--spacing) * .5);border-radius:calc(var(--radius) * 2);padding-inline:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * .5);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--chip-bg:var(--default);--chip-fg:currentColor;background-color:var(--chip-bg);color:var(--chip-fg);flex-shrink:0;display:inline-flex}.chip__label{padding-inline:calc(var(--spacing) * .5)}.chip--accent{--chip-fg:var(--accent-soft-foreground)}.chip--danger{--chip-fg:var(--danger-soft-foreground)}.chip--default{--chip-fg:var(--default-foreground)}.chip--success{--chip-fg:var(--success-soft-foreground)}.chip--warning{--chip-fg:var(--warning-soft-foreground)}.chip--tertiary{--chip-bg:transparent}.chip--sm{padding-inline:var(--spacing);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));padding-block:0}.chip--md{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.chip--lg{padding-inline:calc(var(--spacing) * 3);padding-block:var(--spacing);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.chip--primary.chip--accent{--chip-bg:var(--accent);--chip-fg:var(--accent-foreground)}.chip--primary.chip--success{--chip-bg:var(--success);--chip-fg:var(--success-foreground)}.chip--primary.chip--warning{--chip-bg:var(--warning);--chip-fg:var(--warning-foreground)}.chip--primary.chip--danger{--chip-bg:var(--danger);--chip-fg:var(--danger-foreground)}.chip--accent.chip--soft{--chip-bg:var(--accent-soft);--chip-fg:var(--accent-soft-foreground)}.chip--success.chip--soft{--chip-bg:var(--success-soft);--chip-fg:var(--success-soft-foreground)}.chip--warning.chip--soft{--chip-bg:var(--warning-soft);--chip-fg:var(--warning-soft-foreground)}.chip--danger.chip--soft{--chip-bg:var(--danger-soft);--chip-fg:var(--danger-soft-foreground)}.chip--default.chip--soft{--chip-bg:var(--default-soft);--chip-fg:var(--default-soft-foreground)}.table-root{grid-template-columns:minmax(0,1fr);width:100%;display:grid;position:relative;overflow:clip}.table__scroll-container{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);scrollbar-gutter:auto;overflow-x:auto}.table-root--primary{background-color:var(--surface-secondary);padding-inline:var(--spacing);padding-bottom:var(--spacing);border-radius:min(32px,calc(var(--radius) * 2.5))}.table-root--secondary .table__header{border-bottom-style:var(--tw-border-style);background-color:#0000;border-bottom-width:0}.table-root--secondary .table__column{background-color:var(--surface-secondary)}.table-root--secondary :is(th.table__column:first-child,[role=row]>[role=presentation]:first-of-type>.table__column){border-start-start-radius:min(32px,var(--radius-2xl));border-end-start-radius:min(32px,var(--radius-2xl))}.table-root--secondary :is(th.table__column:last-child,[role=row]>[role=presentation]:last-of-type>.table__column){border-start-end-radius:min(32px,var(--radius-2xl));border-end-end-radius:min(32px,var(--radius-2xl))}.table-root--secondary .table__body{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.table-root--secondary .table__body tr:first-child td:first-child,.table-root--secondary .table__body tr:first-child td:last-child,.table-root--secondary .table__body tr:last-child td:first-child,.table-root--secondary .table__body tr:last-child td:last-child{border-radius:0}.table-root--secondary .table__body:not(tbody){border-radius:0;overflow:visible}.table-root--secondary .table__row .table__cell{border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--separator-tertiary)}@supports (color:color-mix(in lab,red,red)){.table-root--secondary .table__row .table__cell{border-color:color-mix(in oklab,var(--separator-tertiary) 50%,transparent)}}.table-root--secondary .table__row .table__cell{background-color:#0000}@media(hover:hover){.table-root--secondary .table__row:hover .table__cell,.table-root--secondary .table__row[data-hovered=true] .table__cell{background-color:var(--default)}@supports (color:color-mix(in lab,red,red)){.table-root--secondary .table__row:hover .table__cell,.table-root--secondary .table__row[data-hovered=true] .table__cell{background-color:color-mix(in oklab,var(--default) 50%,transparent)}}}.table__content{border-collapse:separate;--tw-border-spacing-x:0;--tw-border-spacing-y:0;width:100%;border-spacing:var(--tw-border-spacing-x) var(--tw-border-spacing-y);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.table-root--primary .table__content{overflow:clip}.table__header{border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--separator)}@supports (color:color-mix(in lab,red,red)){.table__header{border-color:color-mix(in oklab,var(--separator) 50%,transparent)}}.table__header{background-color:var(--surface-secondary)}.table__column{padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2.5);text-align:left;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--muted);position:relative}.table__column:after{content:"";pointer-events:none;height:calc(var(--spacing) * 4);--tw-translate-y: -50% ;width:1px;translate:var(--tw-translate-x) var(--tw-translate-y);border-radius:calc(var(--radius) * .5);background-color:var(--separator);inset-inline-end:calc(var(--spacing) * 0);position:absolute;top:50%}.table__column:last-child:not(:only-child):after{content:none}.table__column[data-allows-sorting=true]{cursor:var(--cursor-interactive)}@media(hover:hover){.table__column[data-allows-sorting=true]:hover,.table__column[data-allows-sorting=true][data-hovered=true]{color:var(--foreground)}}.table__column:focus-visible,.table__column[data-focus-visible=true]{border-radius:calc(var(--radius) * 1);--tw-outline-style:none;box-shadow:inset 0 0 0 2px var(--focus);outline-style:none}[role=row]>[role=presentation]:last-of-type:not(:only-of-type)>.table__column:after{content:none}.table__sortable-column-header{justify-content:space-between;align-items:center;display:flex}.table__sortable-column-indicator{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3);transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.1s;--tw-ease:var(--ease-out);transition-duration:.1s;transition-timing-function:var(--ease-out)}.table__sortable-column-indicator[data-direction=descending]{rotate:180deg}.table__body tr:first-child td:first-child{border-start-start-radius:min(32px,var(--radius-2xl))}.table__body tr:first-child td:last-child{border-start-end-radius:min(32px,var(--radius-2xl))}.table__body tr:last-child td:first-child{border-end-start-radius:min(32px,var(--radius-2xl))}.table__body tr:last-child td:last-child{border-end-end-radius:min(32px,var(--radius-2xl))}.table__body:not(tbody){border-radius:min(32px,var(--radius-2xl));height:100%;position:relative;overflow:clip}.table__row{border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--separator);height:100%;position:relative}@supports (color:color-mix(in lab,red,red)){.table__row{border-color:color-mix(in oklab,var(--separator) 50%,transparent)}}.table__row:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}@media(hover:hover){.table__row:hover .table__cell,.table__row[data-hovered=true] .table__cell{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.table__row:hover .table__cell,.table__row[data-hovered=true] .table__cell{background-color:color-mix(in oklab,var(--surface) 40%,transparent)}}}.table__row[data-selected=true] .table__cell{background-color:var(--surface)}@supports (color:color-mix(in lab,red,red)){.table__row[data-selected=true] .table__cell{background-color:color-mix(in oklab,var(--surface) 10%,transparent)}}.table__row[aria-disabled=true],.table__row[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.table__row:focus-visible,.table__row[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.table__row[data-dragging=true]{opacity:.5}.table__row[data-drop-target=true] .table__cell{background-color:var(--accent-soft)}.table__cell{background-color:var(--surface);height:100%;padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);vertical-align:middle;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--foreground);border-bottom-style:var(--tw-border-style);border-bottom-width:1px;border-color:var(--separator-tertiary)}@supports (color:color-mix(in lab,red,red)){.table__cell{border-color:color-mix(in oklab,var(--separator-tertiary) 50%,transparent)}}.table__cell:focus-visible,.table__cell[data-focus-visible=true]{border-radius:calc(var(--radius) * 1);--tw-outline-style:none;box-shadow:inset 0 0 0 2px var(--focus);outline-style:none}.table__row:is(:focus-visible,[data-focus-visible=true]) :is(.table__cell,.table__column){--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.table__row:is(:focus-visible,[data-focus-visible=true])>:is(.table__cell,.table__column):only-child,.table__row:is(:focus-visible,[data-focus-visible=true])>:only-child :is(.table__cell,.table__column){border-radius:calc(var(--radius) * 1);--tw-shadow:inset 0 0 0 2px var(--tw-shadow-color,var(--focus));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;outline-style:none}.table__row:is(:focus-visible,[data-focus-visible=true])>:is(.table__cell,.table__column):first-child:not(:only-child),.table__row:is(:focus-visible,[data-focus-visible=true])>:first-child:not(:only-child) :is(.table__cell,.table__column){border-top-left-radius:calc(var(--radius) * 1);border-bottom-left-radius:calc(var(--radius) * 1);--tw-shadow:inset 2px 0 0 0 var(--tw-shadow-color,var(--focus)), inset 0 2px 0 0 var(--tw-shadow-color,var(--focus)), inset 0 -2px 0 0 var(--tw-shadow-color,var(--focus));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;outline-style:none}.table__row:is(:focus-visible,[data-focus-visible=true])>:is(.table__cell,.table__column):last-child:not(:only-child),.table__row:is(:focus-visible,[data-focus-visible=true])>:last-child:not(:only-child) :is(.table__cell,.table__column){border-top-right-radius:calc(var(--radius) * 1);border-bottom-right-radius:calc(var(--radius) * 1);--tw-shadow:inset -2px 0 0 0 var(--tw-shadow-color,var(--focus)), inset 0 2px 0 0 var(--tw-shadow-color,var(--focus)), inset 0 -2px 0 0 var(--tw-shadow-color,var(--focus));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;outline-style:none}.table__row:is(:focus-visible,[data-focus-visible=true])>:is(.table__cell,.table__column):not(:first-child):not(:last-child):not(:only-child),.table__row:is(:focus-visible,[data-focus-visible=true])>:not(:first-child):not(:last-child):not(:only-child) :is(.table__cell,.table__column){--tw-shadow:inset 0 2px 0 0 var(--tw-shadow-color,var(--focus)), inset 0 -2px 0 0 var(--tw-shadow-color,var(--focus));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;outline-style:none}.table__cell[data-tree-column]{padding-inline-start:calc(1rem * var(--table-row-level,1))}.table__footer{padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 2.5);align-items:center;display:flex}.table__resizable-container{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);scrollbar-gutter:auto;position:relative;overflow:auto}.table__column-resizer{height:calc(var(--spacing) * 4);--tw-translate-y: -50% ;border-radius:calc(var(--radius) * .5);background-color:var(--separator);box-sizing:content-box;--tw-translate-x: 50% ;width:1px;translate:var(--tw-translate-x) var(--tw-translate-y);cursor:col-resize;touch-action:none;padding-inline:calc(var(--spacing) * 2);--tw-border-style:none;--tw-outline-style:none;inset-inline-end:calc(var(--spacing) * 0);background-clip:content-box;border-style:none;outline-style:none;position:absolute;top:50%}.table__column-resizer[data-hovered=true],.table__column-resizer:hover,.table__column-resizer[data-resizing=true]{height:100%;width:calc(var(--spacing) * .5);background-color:var(--accent)}.table__column-resizer[data-focus-visible=true],.table__column-resizer:focus-visible{height:100%;width:calc(var(--spacing) * .5);background-color:var(--focus)}.table__column:has(.table__column-resizer):after{content:none}.table__load-more td,.table__load-more [role=rowheader]{padding-block:calc(var(--spacing) * 3);text-align:center}:is(.table__load-more td,.table__load-more [role=rowheader])>*{margin-inline:auto}.table__load-more-content{justify-content:center;align-items:center;gap:calc(var(--spacing) * 2);padding-block:calc(var(--spacing) * 2);display:flex}.alert{justify-content:flex-start;align-items:flex-start;gap:calc(var(--spacing) * 4);background-color:var(--surface);width:100%;padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);--tw-shadow:var(--surface-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-radius:min(32px,var(--radius-3xl));flex-direction:row;display:flex}.alert__content{flex-direction:column;flex-grow:1;align-items:flex-start;height:100%;display:flex}.alert__indicator{padding:var(--spacing);-webkit-user-select:none;user-select:none;justify-content:center;align-items:center;display:flex}.alert__indicator [data-slot=alert-default-icon]{box-sizing:content-box;width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.alert__title{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.alert__description{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--muted)}.alert--default .alert__indicator,.alert--default .alert__title{color:var(--foreground)}.alert--accent .alert__indicator,.alert--accent .alert__title{color:var(--accent-soft-foreground)}.alert--success .alert__indicator,.alert--success .alert__title{color:var(--success-soft-foreground)}.alert--warning .alert__indicator,.alert--warning .alert__title{color:var(--warning-soft-foreground)}.alert--danger .alert__indicator,.alert--danger .alert__title{color:var(--danger-soft-foreground)}.empty-state{padding:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--muted)}.skeleton{pointer-events:none;border-radius:calc(var(--radius) * .5);background-color:var(--surface-tertiary);position:relative;overflow:hidden}@supports (color:color-mix(in lab,red,red)){.skeleton{background-color:color-mix(in oklab,var(--surface-tertiary) 70%,transparent)}}.skeleton--shimmer:after{--tw-translate-x:-100%;translate:var(--tw-translate-x) var(--tw-translate-y);--tw-gradient-position:to right;animation:2s linear infinite skeleton;position:absolute;top:0;right:0;bottom:0;left:0}@supports (background-image:linear-gradient(in lab,red,red)){.skeleton--shimmer:after{--tw-gradient-position:to right in oklab}}.skeleton--shimmer:after{background-image:linear-gradient(var(--tw-gradient-stops));--tw-gradient-from:transparent;--tw-gradient-via:var(--surface-tertiary);--tw-gradient-via-stops:var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-via) var(--tw-gradient-via-position), var(--tw-gradient-to) var(--tw-gradient-to-position);--tw-gradient-stops:var(--tw-gradient-via-stops,var(--tw-gradient-position), var(--tw-gradient-from) var(--tw-gradient-from-position), var(--tw-gradient-to) var(--tw-gradient-to-position));--tw-gradient-to:transparent;--tw-content:"";content:var(--tw-content)}.skeleton--shimmer:has(.skeleton):after{content:none}.skeleton--shimmer:has(.skeleton):before{--tw-translate-x:-100%;translate:var(--tw-translate-x) var(--tw-translate-y);--tw-content:"";content:var(--tw-content);z-index:10;pointer-events:none;mix-blend-mode:overlay;background:linear-gradient(90deg,#0000,#ffffff80,#0000);animation:2s linear infinite skeleton;position:absolute;top:0;right:0;bottom:0;left:0}.skeleton--shimmer:has(.skeleton) .skeleton:after{content:none}.skeleton--pulse{animation:var(--animate-pulse)}.meter{gap:var(--spacing);--meter-fill:var(--accent);grid-template-columns:1fr auto;grid-template-areas:"label output""track track";width:100%;display:grid}.meter [data-slot=label]{width:fit-content;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);grid-area:label}.meter .meter__output{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);grid-area:output}.meter .meter__track{border-radius:calc(var(--radius) * .5);background-color:var(--default);height:calc(var(--spacing) * 2);grid-area:track;position:relative;overflow:hidden}.meter .meter__fill{border-radius:calc(var(--radius) * .5);background-color:var(--meter-fill);height:100%;transition:width .3s var(--ease-out);position:absolute;top:0;left:0}.meter .meter__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *),.meter .meter__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.meter .meter__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.meter .meter__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.meter .meter__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.meter .meter__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.meter:disabled,.meter[data-disabled=true],.meter[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:is(.meter:disabled,.meter[data-disabled=true],.meter[aria-disabled=true]) [data-slot=label]{opacity:1}.meter--sm .meter__track{height:var(--spacing);border-radius:calc(var(--radius) * .25)}.meter--sm .meter__fill{border-radius:calc(var(--radius) * .25)}.meter--lg .meter__track{height:calc(var(--spacing) * 3);border-radius:calc(var(--radius) * .75)}.meter--lg .meter__fill{border-radius:calc(var(--radius) * .75)}.meter--default{--meter-fill:var(--default-foreground)}.meter--accent{--meter-fill:var(--accent)}.meter--success{--meter-fill:var(--success)}.meter--warning{--meter-fill:var(--warning)}.meter--danger{--meter-fill:var(--danger)}.progress-bar{gap:var(--spacing);--progress-bar-fill:var(--accent);grid-template-columns:1fr auto;grid-template-areas:"label output""track track";width:100%;display:grid}.progress-bar [data-slot=label]{width:fit-content;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);grid-area:label}.progress-bar .progress-bar__output{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);grid-area:output}.progress-bar .progress-bar__track{border-radius:calc(var(--radius) * .5);background-color:var(--default);height:calc(var(--spacing) * 2);grid-area:track;position:relative;overflow:hidden}.progress-bar .progress-bar__fill{border-radius:calc(var(--radius) * .5);background-color:var(--progress-bar-fill);height:100%;transition:width .3s var(--ease-out);position:absolute;top:0;left:0}.progress-bar .progress-bar__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *),.progress-bar .progress-bar__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.progress-bar .progress-bar__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.progress-bar .progress-bar__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.progress-bar .progress-bar__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.progress-bar .progress-bar__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.progress-bar:not([aria-valuenow]) .progress-bar__fill{width:40%;animation:1.5s cubic-bezier(.65,0,.35,1) infinite progress-bar-indeterminate}.progress-bar:not([aria-valuenow]) .progress-bar__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *),.progress-bar:not([aria-valuenow]) .progress-bar__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.progress-bar:not([aria-valuenow]) .progress-bar__fill:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){.progress-bar:not([aria-valuenow]) .progress-bar__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.progress-bar:not([aria-valuenow]) .progress-bar__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.progress-bar:not([aria-valuenow]) .progress-bar__fill:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.progress-bar:disabled,.progress-bar[data-disabled=true],.progress-bar[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:is(.progress-bar:disabled,.progress-bar[data-disabled=true],.progress-bar[aria-disabled=true]) [data-slot=label]{opacity:1}@keyframes progress-bar-indeterminate{0%{transform:translate(-100%)}to{transform:translate(350%)}}.progress-bar--sm .progress-bar__track{height:var(--spacing);border-radius:calc(var(--radius) * .25)}.progress-bar--sm .progress-bar__fill{border-radius:calc(var(--radius) * .25)}.progress-bar--lg .progress-bar__track{height:calc(var(--spacing) * 3);border-radius:calc(var(--radius) * .75)}.progress-bar--lg .progress-bar__fill{border-radius:calc(var(--radius) * .75)}.progress-bar--default{--progress-bar-fill:var(--default-foreground)}.progress-bar--accent{--progress-bar-fill:var(--accent)}.progress-bar--success{--progress-bar-fill:var(--success)}.progress-bar--warning{--progress-bar-fill:var(--warning)}.progress-bar--danger{--progress-bar-fill:var(--danger)}.progress-circle{--progress-circle-stroke:var(--accent);--progress-circle-track-stroke:var(--default);justify-content:center;align-items:center;display:inline-flex}.progress-circle .progress-circle__track{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.progress-circle .progress-circle__track-circle{stroke:var(--progress-circle-track-stroke)}.progress-circle .progress-circle__fill-circle{stroke:var(--progress-circle-stroke);transition:stroke-dashoffset .3s var(--ease-out)}.progress-circle .progress-circle__fill-circle:is([data-reduce-motion=true],[data-reduce-motion=true] *),.progress-circle .progress-circle__fill-circle:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.progress-circle .progress-circle__fill-circle:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.progress-circle .progress-circle__fill-circle:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.progress-circle .progress-circle__fill-circle:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.progress-circle .progress-circle__fill-circle:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.progress-circle:not([aria-valuenow]) .progress-circle__track{animation:1s linear infinite progress-circle-spin}.progress-circle:not([aria-valuenow]) .progress-circle__track:is([data-reduce-motion=true],[data-reduce-motion=true] *),.progress-circle:not([aria-valuenow]) .progress-circle__track:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.progress-circle:not([aria-valuenow]) .progress-circle__track:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){.progress-circle:not([aria-valuenow]) .progress-circle__track:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.progress-circle:not([aria-valuenow]) .progress-circle__track:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.progress-circle:not([aria-valuenow]) .progress-circle__track:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.progress-circle:disabled,.progress-circle[data-disabled=true],.progress-circle[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}@keyframes progress-circle-spin{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.progress-circle--sm .progress-circle__track{width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.progress-circle--lg .progress-circle__track{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.progress-circle--default{--progress-circle-stroke:var(--default-foreground)}.progress-circle--accent{--progress-circle-stroke:var(--accent)}.progress-circle--success{--progress-circle-stroke:var(--success)}.progress-circle--warning{--progress-circle-stroke:var(--warning)}.progress-circle--danger{--progress-circle-stroke:var(--danger)}.spinner{pointer-events:none;width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6);flex-shrink:0;animation:.75s linear infinite spin;display:inline-flex}.spinner:is([data-reduce-motion=true],[data-reduce-motion=true] *),.spinner:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.spinner:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){.spinner:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.spinner:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.spinner:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.spinner--sm{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.spinner--lg{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.spinner--xl{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.spinner--current{color:inherit}.spinner--accent{color:var(--accent)}.spinner--danger{color:var(--danger)}.spinner--success{color:var(--success)}.spinner--warning{color:var(--warning)}.toast-region{pointer-events:none;z-index:50;--tw-outline-style:none;outline-style:none;width:calc(100vw - 2rem);position:fixed}@media(min-width:40rem){.toast-region{width:auto;min-width:var(--toast-width)}}.toast-region{display:block}.toast-region--bottom{bottom:calc(var(--spacing) * 4);--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);left:50%}.toast-region--bottom-start{bottom:calc(var(--spacing) * 4);left:calc(var(--spacing) * 4)}.toast-region--bottom-end{right:calc(var(--spacing) * 4);bottom:calc(var(--spacing) * 4)}.toast-region--top{top:calc(var(--spacing) * 4);--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y);left:50%}.toast-region--top-start{top:calc(var(--spacing) * 4);left:calc(var(--spacing) * 4)}.toast-region--top-end{top:calc(var(--spacing) * 4);right:calc(var(--spacing) * 4)}.toast-region:focus-visible{outline-style:var(--tw-outline-style);outline-offset:2px;outline-width:2px;outline-color:var(--focus)}.toast{pointer-events:auto;justify-content:flex-start;align-items:flex-start;gap:calc(var(--spacing) * 1.5);background-color:var(--surface);padding-inline:calc(var(--spacing) * 4);padding-block:calc(var(--spacing) * 3);--tw-shadow:var(--overlay-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-radius:min(32px,var(--radius-3xl));flex-direction:row;display:flex;position:absolute;left:0;right:0}.toast--bottom,.toast--bottom-start,.toast--bottom-end{bottom:0}.toast--top,.toast--top-start,.toast--top-end{top:0}.toast:not([data-frontmost=true]){pointer-events:none;height:var(--front-height);overflow:hidden}.toast:not([data-frontmost=true]) .toast__close-button{pointer-events:none;opacity:0;outline:none}.toast[data-hidden=true]{pointer-events:none;opacity:0;display:flex}.toast:focus-visible{outline-style:var(--tw-outline-style);outline-offset:2px;outline-width:2px;outline-color:var(--focus)}.toast--bottom,.toast--bottom-start,.toast--bottom-end{view-transition-class:toast-bottom}.toast--top,.toast--top-start,.toast--top-end{view-transition-class:toast-top}.toast__content{flex-direction:column;flex-grow:1;align-self:center;align-items:flex-start;height:100%;display:flex}.toast__indicator{padding:var(--spacing);color:var(--overlay-foreground);-webkit-user-select:none;user-select:none;flex-shrink:0;justify-content:center;align-items:center;display:flex}.toast__indicator [data-slot=toast-default-icon]{box-sizing:content-box;width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.toast__indicator [data-slot=spinner],.toast__indicator [data-slot=spinner-icon]{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.toast__title{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--overlay-foreground)}.toast__description{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--muted)}.toast__close-button{pointer-events:none;top:calc(var(--spacing) * -1);right:calc(var(--spacing) * -1);width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5);border-color:var(--border);background-color:var(--default);opacity:0;position:absolute}@media(min-width:40rem){.toast__close-button{border-style:var(--tw-border-style);background-color:var(--overlay);border-width:1px}}.toast__close-button{transition:opacity .15s var(--ease-smooth)}.toast__close-button:is([data-reduce-motion=true],[data-reduce-motion=true] *),.toast__close-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.toast__close-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.toast__close-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.toast__close-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.toast__close-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.toast__close-button [data-slot=close-button-icon]{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}@media(min-width:40rem){.toast__close-button [data-slot=close-button-icon]{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}}@media(hover:hover){.toast__close-button:hover,.toast__close-button[data-hovered=true]{background-color:var(--default)}}.toast[data-frontmost=true]:hover .toast__close-button{pointer-events:auto;opacity:1}.toast__action{margin-top:calc(var(--spacing) * 2)}@media(min-width:40rem){.toast__action{margin-top:0}}.toast--accent .toast__title{color:var(--accent-soft-foreground)}.toast--success .toast__title,.toast--success .toast__indicator{color:var(--success-soft-foreground)}.toast--warning .toast__title,.toast--warning .toast__indicator{color:var(--warning-soft-foreground)}.toast--danger .toast__title,.toast--danger .toast__indicator{color:var(--danger-soft-foreground)}::view-transition-old(*){will-change:translate,opacity}::view-transition-new(*){will-change:translate,opacity}::view-transition-new(.toast-bottom):only-child{animation:.35s toast-slide-bottom-in}::view-transition-old(.toast-bottom):only-child{animation:.35s forwards toast-slide-bottom-out}::view-transition-new(.toast-top):only-child{animation:.35s toast-slide-top-in}::view-transition-old(.toast-top):only-child{animation:.35s forwards toast-slide-top-out}@keyframes toast-slide-bottom-in{0%{opacity:0;translate:0 100%}}@keyframes toast-slide-bottom-out{to{opacity:0;translate:0 100%}}@keyframes toast-slide-top-in{0%{opacity:0;translate:0 -100%}}@keyframes toast-slide-top-out{to{opacity:0;translate:0 -100%}}.checkbox-group{flex-direction:column;display:flex}.checkbox-group [data-slot=checkbox]{margin-top:calc(var(--spacing) * 4)}.checkbox{align-items:flex-start;gap:var(--spacing);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);outline-style:none;flex-direction:column;display:flex}.checkbox>[data-slot=description],.checkbox>[data-slot=field-error]{cursor:default;width:100%;min-width:0;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));text-wrap:wrap;overflow-wrap:break-word;color:var(--muted);-webkit-user-select:none;user-select:none;padding-inline-start:calc(var(--spacing) * 7)}.checkbox [data-slot=label]{-webkit-user-select:none;user-select:none}.checkbox .checkbox__content [data-slot=label]{cursor:var(--cursor-interactive)}.checkbox[data-disabled=true],.checkbox[data-disabled=true] [data-slot=description],.checkbox[data-disabled=true] [data-slot=field-error]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:is(.checkbox[data-selected=true],.checkbox[data-indeterminate=true]) .checkbox__indicator{border-color:var(--accent-foreground)}.checkbox [data-slot=checkbox-default-indicator--checkmark]{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5);stroke-width:2.5px;color:var(--accent-foreground);transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.2s;transition-duration:.2s}.checkbox [data-slot=checkbox-default-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *),.checkbox [data-slot=checkbox-default-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.checkbox [data-slot=checkbox-default-indicator--checkmark]:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.checkbox [data-slot=checkbox-default-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.checkbox [data-slot=checkbox-default-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.checkbox [data-slot=checkbox-default-indicator--checkmark]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.checkbox[data-selected=true] [data-slot=checkbox-default-indicator--checkmark]{transition:stroke-dashoffset .15s linear 15ms}.checkbox[data-invalid=true][data-selected=true] [data-slot=checkbox-default-indicator--checkmark],.checkbox[data-invalid=true][aria-checked=true] [data-slot=checkbox-default-indicator--checkmark],.checkbox[aria-invalid=true][data-selected=true] [data-slot=checkbox-default-indicator--checkmark],.checkbox[aria-invalid=true][aria-checked=true] [data-slot=checkbox-default-indicator--checkmark]{color:var(--danger-foreground)}.checkbox[data-indeterminate=true] [data-slot=checkbox-default-indicator--indeterminate]{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.checkbox[data-indeterminate=true][data-invalid=true] [data-slot=checkbox-default-indicator--indeterminate],.checkbox[data-indeterminate=true][aria-invalid=true] [data-slot=checkbox-default-indicator--indeterminate]{color:var(--danger-foreground)}.checkbox__control{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * .75);border-style:var(--tw-border-style);border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border,var(--border));background-color:var(--field-background,var(--default));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;transition:background-color .2s var(--ease-out),border-color .2s var(--ease-out),transform .1s var(--ease-out);outline-style:none;flex-shrink:0;justify-content:center;align-items:center;display:inline-flex;position:relative;overflow:hidden}.checkbox__control:is([data-reduce-motion=true],[data-reduce-motion=true] *),.checkbox__control:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.checkbox__control:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.checkbox__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.checkbox__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.checkbox__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.checkbox__control{cursor:var(--cursor-interactive)}.checkbox__control:before{pointer-events:none;z-index:0;transform-origin:50%;--tw-scale-x:70%;--tw-scale-y:70%;--tw-scale-z:70%;scale:var(--tw-scale-x) var(--tw-scale-y);border-radius:calc(var(--radius) * .75);background-color:var(--accent);opacity:0;--tw-content:"";content:var(--tw-content);transition:scale .1s var(--ease-linear),opacity .2s var(--ease-linear),background-color .2s var(--ease-out);position:absolute;top:0;right:0;bottom:0;left:0}@media(prefers-reduced-motion:reduce){.checkbox__control:before:not(:is()){transition-property:none}}.checkbox:focus-visible .checkbox__control,.checkbox:has([data-slot=checkbox-content][data-focus-visible=true]) .checkbox__control,.checkbox [data-slot=checkbox-content][data-focus-visible=true] .checkbox__control{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.checkbox:hover .checkbox__control,.checkbox:has([data-slot=checkbox-content][data-hovered=true]) .checkbox__control,.checkbox [data-slot=checkbox-content][data-hovered=true] .checkbox__control{border-color:var(--field-border-hover)}:is(.checkbox:hover .checkbox__control,.checkbox:has([data-slot=checkbox-content][data-hovered=true]) .checkbox__control,.checkbox [data-slot=checkbox-content][data-hovered=true] .checkbox__control):before{background-color:var(--accent-hover)}.checkbox[aria-checked=true] .checkbox__control,.checkbox[data-selected=true] .checkbox__control{color:var(--accent-foreground);border-color:#0000}:is(.checkbox[aria-checked=true] .checkbox__control,.checkbox[data-selected=true] .checkbox__control):before{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y);opacity:1}.checkbox[data-indeterminate=true] .checkbox__control{background-color:var(--accent);color:var(--accent-foreground)}.checkbox:active[data-indeterminate=true] .checkbox__control,.checkbox[data-pressed=true][data-indeterminate=true] .checkbox__control,.checkbox:has([data-slot=checkbox-content][data-pressed=true])[data-indeterminate=true] .checkbox__control{background-color:var(--accent-hover)}.checkbox[data-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control,.checkbox[aria-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}:is(.checkbox[data-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control,.checkbox[aria-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control):focus,:is(.checkbox[data-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control,.checkbox[aria-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control):focus-visible,:is(.checkbox[data-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control,.checkbox[aria-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control)[data-focused=true],:is(.checkbox[data-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control,.checkbox[aria-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control)[data-focus-visible=true],:is(.checkbox[data-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control,.checkbox[aria-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control):focus-within,:is(.checkbox[data-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control,.checkbox[aria-invalid=true]:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control)[data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.checkbox[data-invalid=true][aria-checked=true] .checkbox__control,.checkbox[data-invalid=true][data-selected=true] .checkbox__control,.checkbox[aria-invalid=true][aria-checked=true] .checkbox__control,.checkbox[aria-invalid=true][data-selected=true] .checkbox__control{background-color:var(--danger);color:var(--danger-foreground);border-color:#0000}:is(.checkbox[data-invalid=true][aria-checked=true] .checkbox__control,.checkbox[data-invalid=true][data-selected=true] .checkbox__control,.checkbox[aria-invalid=true][aria-checked=true] .checkbox__control,.checkbox[aria-invalid=true][data-selected=true] .checkbox__control):before{--tw-scale-x:100%;--tw-scale-y:100%;--tw-scale-z:100%;scale:var(--tw-scale-x) var(--tw-scale-y);background-color:var(--danger);opacity:1}.checkbox[data-indeterminate=true][aria-invalid=true] .checkbox__control,.checkbox[data-indeterminate=true][data-invalid=true] .checkbox__control{background-color:var(--danger);color:var(--danger-foreground)}.checkbox__indicator{z-index:10;width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3);justify-content:center;align-items:center;display:flex;position:relative}.checkbox__indicator svg{width:100%;height:100%;transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.checkbox--disabled{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.checkbox--secondary .checkbox__control{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--checkbox-control-bg);--checkbox-control-bg:var(--default)}.checkbox:hover :is(.checkbox--secondary .checkbox__control),.checkbox:has([data-slot=checkbox-content][data-hovered=true]) :is(.checkbox--secondary .checkbox__control),.checkbox [data-slot=checkbox-content][data-hovered=true] :is(.checkbox--secondary .checkbox__control){border-color:var(--field-border-hover)}.checkbox__content{cursor:inherit;align-items:center;gap:calc(var(--spacing) * 3);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground);--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;outline-style:none;display:inline-flex}.checkbox--secondary:not([aria-checked=true]):not([data-selected=true]):not([data-indeterminate=true]) .checkbox__control{background-color:var(--checkbox-control-bg)}:is(.checkbox--secondary[aria-checked=true] .checkbox__control,.checkbox--secondary[data-selected=true] .checkbox__control):before,.checkbox--secondary[data-indeterminate=true] .checkbox__control,.checkbox--secondary[data-indeterminate=true] .checkbox__control:before{background-color:var(--accent)}.fieldset{gap:calc(var(--spacing) * 6);flex-direction:column;flex:1 1 0;display:flex}.fieldset__legend{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground)}.fieldset__field_group{width:100%}:where(.fieldset__field_group>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}.fieldset__actions{align-items:center;gap:calc(var(--spacing) * 2);padding-top:var(--spacing);display:flex}.input-otp{align-items:center;gap:calc(var(--spacing) * 2);display:flex;position:relative}.input-otp[data-disabled=true]{cursor:not-allowed;opacity:.5}.input-otp__group{align-items:center;gap:calc(var(--spacing) * 2);display:flex}.input-otp__slot{height:calc(var(--spacing) * 10);width:calc(var(--spacing) * 9.5);border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-radius:var(--field-radius,calc(var(--radius) * 1.5));font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-outline-style:none;border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border);transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);outline-style:none;flex:1;justify-content:center;align-items:center;display:flex;position:relative}.input-otp__slot:is([data-reduce-motion=true],[data-reduce-motion=true] *),.input-otp__slot:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.input-otp__slot:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.input-otp__slot:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.input-otp__slot:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.input-otp__slot:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.input-otp__slot:hover,.input-otp__slot[data-hovered=true]{background-color:var(--field-hover);border-color:var(--field-border-hover)}}.input-otp__slot[data-active=true]{z-index:10;background-color:var(--field-focus);--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;outline-style:none}.input-otp__slot[data-filled=true]{background-color:var(--field-focus)}.input-otp__slot[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.input-otp__slot[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.input-otp__slot[data-invalid=true]:focus,.input-otp__slot[data-invalid=true]:focus-visible,.input-otp__slot[data-invalid=true][data-focused=true],.input-otp__slot[data-invalid=true][data-focus-visible=true],.input-otp__slot[data-invalid=true]:focus-within,.input-otp__slot[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.input-otp__slot[data-invalid=true]{background-color:var(--field-focus)}.input-otp__slot-value{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height));--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6);--tw-tracking:-.27px;letter-spacing:-.27px;animation:slot-value-in .25s var(--ease-smooth) both;transform-origin:bottom}.input-otp__slot-value:is([data-reduce-motion=true],[data-reduce-motion=true] *),.input-otp__slot-value:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.input-otp__slot-value:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){.input-otp__slot-value:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.input-otp__slot-value:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.input-otp__slot-value:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.input-otp__caret{height:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * .5);background-color:var(--field-placeholder,var(--muted));width:2px;animation:1.2s ease-out infinite caret-blink;position:absolute}.input-otp__separator{border-radius:calc(var(--radius) * .5);background-color:var(--separator);flex-shrink:0;width:6px;height:2px}.input-otp--secondary .input-otp__slot{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--input-otp-slot-bg);--input-otp-slot-bg:var(--default);--input-otp-slot-bg-hover:var(--default-hover);--input-otp-slot-bg-focus:var(--default)}@media(hover:hover){.input-otp--secondary .input-otp__slot:hover,.input-otp--secondary .input-otp__slot[data-hovered=true]{background-color:var(--input-otp-slot-bg-hover)}}.input-otp--secondary .input-otp__slot[data-active=true],.input-otp--secondary .input-otp__slot[data-filled=true]{background-color:var(--input-otp-slot-bg-focus)}@keyframes slot-value-in{0%{opacity:0;transform:translateY(8px)scale(.8)}to{opacity:1;transform:translateY(0)scale(1)}}.input{border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-width:1px;outline-style:none}.input::placeholder{color:var(--field-placeholder,var(--muted))}@media(min-width:40rem){.input{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.input{border-width:var(--border-width-field);border-color:var(--field-border);transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out)}.input:is([data-reduce-motion=true],[data-reduce-motion=true] *),.input:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.input:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.input:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.input:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.input:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.input:hover:not(:focus):not(:focus-visible),.input[data-hovered=true]:not([data-focused=true]):not([data-focus-visible=true]){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.input:focus,.input[data-focused=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;border-color:var(--field-border-focus);background-color:var(--field-focus);outline-style:none}.input[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.input[data-invalid=true]:focus,.input[data-invalid=true]:focus-visible,.input[data-invalid=true][data-focused=true],.input[data-invalid=true][data-focus-visible=true],.input[data-invalid=true]:focus-within,.input[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.input[data-invalid=true]{background-color:var(--field-focus)}.input:disabled,.input[data-disabled=true],.input[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.input--secondary{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--input-bg);--input-bg:var(--default);--input-bg-hover:var(--default-hover);--input-bg-focus:var(--default)}@media(hover:hover){.input--secondary:hover:not(:focus):not(:focus-visible),.input--secondary[data-hovered=true]:not([data-focus-visible=true]):not([data-focused=true]){background-color:var(--input-bg-hover)}}.input--secondary:focus,.input--secondary[data-focused=true]{background-color:var(--input-bg-focus)}.input--secondary[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.input--secondary[data-invalid=true]:focus,.input--secondary[data-invalid=true]:focus-visible,.input--secondary[data-invalid=true][data-focused=true],.input--secondary[data-invalid=true][data-focus-visible=true],.input--secondary[data-invalid=true]:focus-within,.input--secondary[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.input--secondary[data-invalid=true]{background-color:var(--input-bg-focus)}.input--full-width{width:100%}.input-group{min-height:calc(var(--spacing) * 9);border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border);outline-style:none;align-items:center;display:inline-flex}.input-group:has([data-slot=input-group-textarea]){align-items:flex-start;height:auto}.input-group{transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out)}.input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *),.input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.input-group:hover:not(:focus-within),.input-group[data-hovered=true]:not([data-focus-within=true]){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.input-group:has([data-slot=input-group-input]:focus),.input-group:has([data-slot=input-group-textarea]:focus){--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;border-color:var(--field-border-focus);background-color:var(--field-focus);outline-style:none}.input-group[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.input-group[data-invalid=true]:focus,.input-group[data-invalid=true]:focus-visible,.input-group[data-invalid=true][data-focused=true],.input-group[data-invalid=true][data-focus-visible=true],.input-group[data-invalid=true]:focus-within,.input-group[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.input-group[data-invalid=true]{background-color:var(--field-focus);border-color:var(--color-field-border-invalid)}.input-group[data-disabled=true],.input-group[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:-webkit-any(.input-group:has([data-slot=input-group-input]:-webkit-autofill),.input-group:has([data-slot=input-group-input]:autofill)){background-color:var(--field-focus);border-color:var(--field-border-focus)}:is(.input-group:has([data-slot=input-group-input]:autofill)){background-color:var(--field-focus);border-color:var(--field-border-focus)}.input-group__input{border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;background-color:#0000;border-width:0;border-radius:0;outline-style:none;flex:1}.input-group__input::placeholder{color:var(--field-placeholder,var(--muted))}@media(min-width:40rem){.input-group__input{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.input-group:has([data-slot=input-group-prefix]) .input-group__input{border-top-left-radius:0;border-bottom-left-radius:0;padding-left:0}.input-group:has([data-slot=input-group-suffix]) .input-group__input{border-top-right-radius:0;border-bottom-right-radius:0;padding-right:0}.input-group__input:focus,.input-group__input:focus-visible{--tw-outline-style:none;outline-style:none}.input-group__input:-webkit-autofill{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.input-group__input:-webkit-autofill:hover{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.input-group__input:-webkit-autofill:focus{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.input-group__input:-webkit-autofill:active{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.input-group__input:autofill{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.input-group__input[data-slot=input-group-textarea]{resize:vertical;min-height:38px}.input-group__prefix{border-top-left-radius:var(--field-radius,calc(var(--radius) * 1.5));border-bottom-left-radius:var(--field-radius,calc(var(--radius) * 1.5));height:100%;padding-inline:calc(var(--spacing) * 3);color:var(--field-placeholder,var(--muted));border-width:var(--border-width-field);border-color:var(--field-border);border-style:solid;border-right-color:var(--field-border);background-color:#0000;border-top:none;border-bottom:none;border-left:none;border-top-right-radius:0;border-bottom-right-radius:0;justify-content:center;align-items:center;display:flex}.input-group:has([data-slot=input-group-textarea]) .input-group__prefix{align-items:flex-start;padding-top:.5rem}.input-group__prefix{transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth)}.input-group__prefix:is([data-reduce-motion=true],[data-reduce-motion=true] *),.input-group__prefix:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.input-group__prefix:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.input-group__prefix:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.input-group__prefix:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.input-group__prefix:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.input-group__suffix{border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:var(--field-radius,calc(var(--radius) * 1.5));border-bottom-right-radius:var(--field-radius,calc(var(--radius) * 1.5));height:100%;padding-inline:calc(var(--spacing) * 3);color:var(--field-placeholder,var(--muted));border-width:var(--border-width-field);border-color:var(--field-border);border-style:solid;border-left-color:var(--field-border);background-color:#0000;border-top:none;border-bottom:none;border-right:none;justify-content:center;align-items:center;display:flex}.input-group:has([data-slot=input-group-textarea]) .input-group__suffix{align-items:flex-start;padding-top:.5rem}.input-group__suffix{transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth)}.input-group__suffix:is([data-reduce-motion=true],[data-reduce-motion=true] *),.input-group__suffix:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.input-group__suffix:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.input-group__suffix:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.input-group__suffix:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.input-group__suffix:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.input-group--secondary{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--input-group-bg);--input-group-bg:var(--default);--input-group-bg-hover:var(--default-hover);--input-group-bg-focus:var(--default)}@media(hover:hover){.input-group--secondary:hover:not(:focus-within),.input-group--secondary[data-hovered=true]:not([data-focus-within=true]){background-color:var(--input-group-bg-hover)}}.input-group--secondary:has([data-slot=input-group-input]:focus),.input-group--secondary:has([data-slot=input-group-textarea]:focus){background-color:var(--input-group-bg-focus)}.input-group--secondary[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.input-group--secondary[data-invalid=true]:focus,.input-group--secondary[data-invalid=true]:focus-visible,.input-group--secondary[data-invalid=true][data-focused=true],.input-group--secondary[data-invalid=true][data-focus-visible=true],.input-group--secondary[data-invalid=true]:focus-within,.input-group--secondary[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.input-group--secondary[data-invalid=true]{border-color:var(--color-field-border-invalid);background-color:var(--input-group-bg-focus)}.input-group--secondary [data-slot=input-group-input],.input-group--secondary [data-slot=input-group-textarea]{background-color:#0000}.input-group--full-width{width:100%}.number-field{gap:var(--spacing);flex-direction:column;display:flex}:is(.number-field[data-invalid=true],.number-field[aria-invalid=true]) [data-slot=description]{display:none}.number-field [data-slot=label]{width:fit-content}.number-field__group{height:calc(var(--spacing) * 9);border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border);transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);outline-style:none;grid-template-columns:40px 1fr 40px;align-items:center;display:grid;overflow:hidden}.number-field__group:is([data-reduce-motion=true],[data-reduce-motion=true] *),.number-field__group:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.number-field__group:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.number-field__group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.number-field__group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.number-field__group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.number-field__group:hover:not(:focus-within),.number-field__group[data-hovered=true]:not([data-focus-within=true]){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.number-field__group[data-focus-within=true],.number-field__group:focus-within{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;border-color:var(--field-border-focus);background-color:var(--field-focus);outline-style:none}.number-field__group[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.number-field__group[data-invalid=true]:focus,.number-field__group[data-invalid=true]:focus-visible,.number-field__group[data-invalid=true][data-focused=true],.number-field__group[data-invalid=true][data-focus-visible=true],.number-field__group[data-invalid=true]:focus-within,.number-field__group[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.number-field__group[data-invalid=true]{background-color:var(--field-focus);border-color:var(--color-field-border-invalid)}.number-field__group[data-disabled=true],.number-field__group[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:-webkit-any(.number-field__group:has([data-slot=number-field-input]:-webkit-autofill),.number-field__group:has([data-slot=number-field-input]:autofill)){background-color:var(--field-focus);border-color:var(--field-border-focus)}:is(.number-field__group:has([data-slot=number-field-input]:autofill)){background-color:var(--field-focus);border-color:var(--field-border-focus)}.number-field__input{border-style:var(--tw-border-style);min-width:0;padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,);--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;background-color:#0000;border-width:0;border-radius:0;outline-style:none}@media(min-width:40rem){.number-field__input{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.number-field__group:has([slot=decrement]) .number-field__input{border-top-left-radius:0;border-bottom-left-radius:0}.number-field__group:has([slot=increment]) .number-field__input{border-top-right-radius:0;border-bottom-right-radius:0}.number-field__input:focus,.number-field__input:focus-visible{--tw-outline-style:none;outline-style:none}.number-field__input:-webkit-autofill{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.number-field__input:-webkit-autofill:hover{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.number-field__input:-webkit-autofill:focus{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.number-field__input:-webkit-autofill:active{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.number-field__input:autofill{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.number-field__increment-button,.number-field__decrement-button{height:100%;width:calc(var(--spacing) * 10);color:var(--field-foreground,var(--foreground));--tw-outline-style:none;border-width:var(--border-width-field);border-color:var(--field-border);transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth);background-color:#0000;border-style:solid;border-radius:0;outline-style:none;justify-content:center;align-items:center;display:flex}:is(.number-field__increment-button,.number-field__decrement-button):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.number-field__increment-button,.number-field__decrement-button):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.number-field__increment-button,.number-field__decrement-button):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){:is(.number-field__increment-button,.number-field__decrement-button):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.number-field__increment-button,.number-field__decrement-button):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.number-field__increment-button,.number-field__decrement-button):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.number-field__increment-button,.number-field__decrement-button{cursor:var(--cursor-interactive)}:is(.number-field__increment-button,.number-field__decrement-button):active,:is(.number-field__increment-button,.number-field__decrement-button)[data-pressed=true]{background-color:var(--field-foreground,var(--foreground))}@supports (color:color-mix(in lab,red,red)){:is(.number-field__increment-button,.number-field__decrement-button):active,:is(.number-field__increment-button,.number-field__decrement-button)[data-pressed=true]{background-color:color-mix(in oklab,var(--field-foreground,var(--foreground)) 10%,transparent)}}:is(.number-field__increment-button,.number-field__decrement-button):active,:is(.number-field__increment-button,.number-field__decrement-button)[data-pressed=true]{transform:scale(.97)}:is(.number-field__increment-button,.number-field__decrement-button):disabled,:is(.number-field__increment-button,.number-field__decrement-button)[data-disabled=true],:is(.number-field__increment-button,.number-field__decrement-button)[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:is(.number-field__increment-button,.number-field__decrement-button) [data-slot=number-field-increment-button-icon],:is(.number-field__increment-button,.number-field__decrement-button) [data-slot=number-field-decrement-button-icon]{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.number-field__increment-button{border-top-left-radius:0;border-bottom-left-radius:0;border-top-right-radius:var(--field-radius,calc(var(--radius) * 1.5));border-bottom-right-radius:var(--field-radius,calc(var(--radius) * 1.5));border-left-style:var(--tw-border-style);border-left-width:1px;border-color:var(--field-placeholder,var(--muted))}@supports (color:color-mix(in lab,red,red)){.number-field__increment-button{border-color:color-mix(in oklab,var(--field-placeholder,var(--muted)) 15%,transparent)}}.number-field__decrement-button{border-top-left-radius:var(--field-radius,calc(var(--radius) * 1.5));border-bottom-left-radius:var(--field-radius,calc(var(--radius) * 1.5));border-right-style:var(--tw-border-style);border-right-width:1px;border-color:var(--field-placeholder,var(--muted));border-top-right-radius:0;border-bottom-right-radius:0}@supports (color:color-mix(in lab,red,red)){.number-field__decrement-button{border-color:color-mix(in oklab,var(--field-placeholder,var(--muted)) 15%,transparent)}}.number-field--secondary .number-field__group{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--number-field-group-bg);--number-field-group-bg:var(--default);--number-field-group-bg-hover:var(--default-hover);--number-field-group-bg-focus:var(--default)}@media(hover:hover){.number-field--secondary .number-field__group:hover:not(:focus-within),.number-field--secondary .number-field__group[data-hovered=true]:not([data-focus-within=true]){background-color:var(--number-field-group-bg-hover)}}.number-field--secondary .number-field__group:focus-within,.number-field--secondary .number-field__group[data-focus-within=true]{background-color:var(--number-field-group-bg-focus)}.number-field--secondary .number-field__group[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.number-field--secondary .number-field__group[data-invalid=true]:focus,.number-field--secondary .number-field__group[data-invalid=true]:focus-visible,.number-field--secondary .number-field__group[data-invalid=true][data-focused=true],.number-field--secondary .number-field__group[data-invalid=true][data-focus-visible=true],.number-field--secondary .number-field__group[data-invalid=true]:focus-within,.number-field--secondary .number-field__group[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.number-field--secondary .number-field__group[data-invalid=true]{border-color:var(--color-field-border-invalid);background-color:var(--number-field-group-bg-focus)}.number-field--secondary .number-field__group [data-slot=number-field-input]{background-color:#0000}.number-field--full-width,.number-field__group--full-width{width:100%}.radio-group{flex-direction:column;display:flex}.radio-group[data-orientation=vertical] [data-slot=radio]{margin-top:calc(var(--spacing) * 4)}.radio-group[data-orientation=horizontal]{gap:calc(var(--spacing) * 4);flex-flow:wrap}.radio-group--secondary .radio__control{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--radio-control-bg);--radio-control-bg:var(--default);--radio-control-bg-hover:var(--default-hover)}.radio:has([data-slot=radio-content][data-hovered=true]) :is(.radio-group--secondary .radio__control),.radio [data-slot=radio-content][data-hovered=true] :is(.radio-group--secondary .radio__control){border-color:var(--field-border-hover)}.radio:not([data-selected]):not(:has(input:checked)) :is(.radio-group--secondary .radio__control) .radio__indicator:empty:before{background-color:var(--radio-control-bg)}.radio:has([data-slot=radio-content][data-hovered=true]):not([data-selected]):not(:has(input:checked)) :is(.radio-group--secondary .radio__control) .radio__indicator:empty:before{background-color:var(--radio-control-bg-hover)}.radio{align-items:flex-start;gap:var(--spacing);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);outline-style:none;flex-direction:column;display:flex}.radio [data-slot=label]{-webkit-user-select:none;user-select:none}.radio .radio__content [data-slot=label]{cursor:var(--cursor-interactive)}.radio>[data-slot=description],.radio>[data-slot=field-error]{cursor:default;width:100%;min-width:0;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));text-wrap:wrap;overflow-wrap:break-word;color:var(--muted);-webkit-user-select:none;user-select:none;padding-inline-start:calc(var(--spacing) * 7)}.radio:disabled,.radio[data-disabled=true],.radio[aria-disabled=true],:is(.radio:disabled,.radio[data-disabled=true],.radio[aria-disabled=true]) [data-slot=description],:is(.radio:disabled,.radio[data-disabled=true],.radio[aria-disabled=true]) [data-slot=field-error]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.radio__content{cursor:inherit;align-items:center;gap:calc(var(--spacing) * 3);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground);--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;outline-style:none;display:inline-flex}.radio__control{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * 1);border-style:var(--tw-border-style);border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border,var(--border));background-color:var(--field-background,var(--default));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;transition:background-color .2s var(--ease-out),border-color .2s var(--ease-out),transform .1s var(--ease-out);outline-style:none;flex-shrink:0;justify-content:center;align-items:center;display:inline-flex;position:relative}.radio__control:is([data-reduce-motion=true],[data-reduce-motion=true] *),.radio__control:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.radio__control:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.radio__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.radio__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.radio__control:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.radio__control{cursor:var(--cursor-interactive)}.radio:has([data-slot=radio-content][data-focus-visible=true]) .radio__control,.radio [data-slot=radio-content][data-focus-visible=true] .radio__control{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.radio:has([data-slot=radio-content][data-hovered=true]) .radio__control,.radio [data-slot=radio-content][data-hovered=true] .radio__control{border-color:var(--field-border-hover)}.radio:has([data-slot=radio-content][data-hovered=true]):not([data-selected]):not(:has(input:checked)) .radio__control .radio__indicator:empty:before{background-color:var(--field-hover)}.radio:has([data-slot=radio-content][data-pressed=true]) .radio__control,.radio [data-slot=radio-content][data-pressed=true] .radio__control{--tw-scale-x:95%;--tw-scale-y:95%;--tw-scale-z:95%;scale:var(--tw-scale-x) var(--tw-scale-y)}.radio[data-selected] .radio__control,.radio:has([data-slot=radio-content][aria-checked=true]) .radio__control,.radio:has(input:checked) .radio__control{background-color:var(--accent);border-color:#0000}.radio[data-selected]:has([data-slot=radio-content][data-pressed=true]) .radio__control,.radio:has([data-slot=radio-content][data-pressed=true][aria-checked=true]) .radio__control,.radio:has(input:checked):has([data-slot=radio-content][data-pressed=true]) .radio__control{background-color:var(--accent-hover)}.radio[data-invalid=true] .radio__control,.radio[aria-invalid=true] .radio__control{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}:is(.radio[data-invalid=true] .radio__control,.radio[aria-invalid=true] .radio__control):focus,:is(.radio[data-invalid=true] .radio__control,.radio[aria-invalid=true] .radio__control):focus-visible,:is(.radio[data-invalid=true] .radio__control,.radio[aria-invalid=true] .radio__control)[data-focused=true],:is(.radio[data-invalid=true] .radio__control,.radio[aria-invalid=true] .radio__control)[data-focus-visible=true],:is(.radio[data-invalid=true] .radio__control,.radio[aria-invalid=true] .radio__control):focus-within,:is(.radio[data-invalid=true] .radio__control,.radio[aria-invalid=true] .radio__control)[data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.radio[data-invalid=true][data-selected] .radio__control,.radio[aria-invalid=true][data-selected] .radio__control,.radio[data-invalid=true]:has(input:checked) .radio__control,.radio[aria-invalid=true]:has(input:checked) .radio__control{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}:is(.radio[data-invalid=true][data-selected] .radio__control,.radio[aria-invalid=true][data-selected] .radio__control,.radio[data-invalid=true]:has(input:checked) .radio__control,.radio[aria-invalid=true]:has(input:checked) .radio__control):focus,:is(.radio[data-invalid=true][data-selected] .radio__control,.radio[aria-invalid=true][data-selected] .radio__control,.radio[data-invalid=true]:has(input:checked) .radio__control,.radio[aria-invalid=true]:has(input:checked) .radio__control):focus-visible,:is(.radio[data-invalid=true][data-selected] .radio__control,.radio[aria-invalid=true][data-selected] .radio__control,.radio[data-invalid=true]:has(input:checked) .radio__control,.radio[aria-invalid=true]:has(input:checked) .radio__control)[data-focused=true],:is(.radio[data-invalid=true][data-selected] .radio__control,.radio[aria-invalid=true][data-selected] .radio__control,.radio[data-invalid=true]:has(input:checked) .radio__control,.radio[aria-invalid=true]:has(input:checked) .radio__control)[data-focus-visible=true],:is(.radio[data-invalid=true][data-selected] .radio__control,.radio[aria-invalid=true][data-selected] .radio__control,.radio[data-invalid=true]:has(input:checked) .radio__control,.radio[aria-invalid=true]:has(input:checked) .radio__control):focus-within,:is(.radio[data-invalid=true][data-selected] .radio__control,.radio[aria-invalid=true][data-selected] .radio__control,.radio[data-invalid=true]:has(input:checked) .radio__control,.radio[aria-invalid=true]:has(input:checked) .radio__control)[data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.radio__indicator{pointer-events:none;justify-content:center;align-items:center;display:flex;position:absolute;top:0;right:0;bottom:0;left:0}.radio__indicator:empty:before{content:"";border-radius:calc(var(--radius) * 1);background-color:var(--field-background,var(--default));width:100%;height:100%;transition:scale .2s var(--ease-out),background-color .2s var(--ease-out);scale:1}@media(prefers-reduced-motion:reduce){.radio__indicator:empty:before:not(:is()){transition-property:none}}.radio[data-selected] .radio__indicator:empty:before,.radio:has([data-slot=radio-content][aria-checked=true]) .radio__indicator:empty:before,.radio:has(input:checked) .radio__indicator:empty:before{background-color:var(--accent-foreground);scale:.4286}.radio[data-selected]:has([data-slot=radio-content][data-pressed=true]) .radio__indicator:empty:before,.radio:has([data-slot=radio-content][data-pressed=true][aria-checked=true]) .radio__indicator:empty:before,.radio:has(input:checked):has([data-slot=radio-content][data-pressed=true]) .radio__indicator:empty:before{scale:.5714}.radio--disabled{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.textfield{gap:var(--spacing);flex-direction:column;display:flex}:is(.textfield[data-invalid=true],.textfield[aria-invalid=true]) [data-slot=description]{display:none}.textfield--full-width,.textfield--full-width [data-slot=input],.textfield--full-width [data-slot=textarea]{width:100%}.search-field{gap:var(--spacing);flex-direction:column;display:flex}:is(.search-field[data-invalid=true],.search-field[aria-invalid=true]) [data-slot=description]{display:none}.search-field [data-slot=label]{width:fit-content}.search-field[data-empty=true] [data-slot=search-field-clear-button]{pointer-events:none;opacity:0}.search-field__group{height:calc(var(--spacing) * 9);border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border);transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);outline-style:none;align-items:center;display:inline-flex;position:relative;overflow:hidden}.search-field__group:is([data-reduce-motion=true],[data-reduce-motion=true] *),.search-field__group:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.search-field__group:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.search-field__group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.search-field__group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.search-field__group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.search-field__group:hover:not(:focus-within),.search-field__group[data-hovered=true]:not([data-focus-within=true]){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.search-field__group[data-focus-within=true],.search-field__group:focus-within{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;outline-style:none}.search-field__group[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.search-field__group[data-invalid=true]:focus,.search-field__group[data-invalid=true]:focus-visible,.search-field__group[data-invalid=true][data-focused=true],.search-field__group[data-invalid=true][data-focus-visible=true],.search-field__group[data-invalid=true]:focus-within,.search-field__group[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.search-field__group[data-invalid=true]{background-color:var(--field-focus);border-color:var(--color-field-border-invalid)}.search-field__group[data-disabled=true],.search-field__group[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}:-webkit-any(.search-field__group:has([data-slot=search-field-input]:-webkit-autofill),.search-field__group:has([data-slot=search-field-input]:autofill)){background-color:var(--field-focus);border-color:var(--field-border-focus)}:is(.search-field__group:has([data-slot=search-field-input]:autofill)){background-color:var(--field-focus);border-color:var(--field-border-focus)}.search-field__input{border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;background-color:#0000;border-width:0;border-radius:0;outline-style:none;flex:1}@media(min-width:40rem){.search-field__input{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.search-field__input::-webkit-search-cancel-button{-webkit-appearance:none;-moz-appearance:none;appearance:none}.search-field__input::-webkit-search-decoration{-webkit-appearance:none;-moz-appearance:none;appearance:none}.search-field__group:has([data-slot=search-field-search-icon]) .search-field__input{padding-left:calc(var(--spacing) * 2);border-top-left-radius:0;border-bottom-left-radius:0}.search-field__group:has([slot=clear]) .search-field__input{padding-right:calc(var(--spacing) * 2);border-top-right-radius:0;border-bottom-right-radius:0}.search-field__input:focus,.search-field__input:focus-visible{--tw-outline-style:none;outline-style:none}.search-field__input:-webkit-autofill{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.search-field__input:-webkit-autofill:hover{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.search-field__input:-webkit-autofill:focus{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.search-field__input:-webkit-autofill:active{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.search-field__input:autofill{-webkit-text-fill-color:var(--field-foreground);caret-color:var(--field-foreground);transition:background-color 9999s ease-in-out;box-shadow:inset 0 0 0 1000px #0000}.search-field__search-icon{pointer-events:none;color:var(--field-placeholder,var(--muted));margin-right:0;margin-left:calc(var(--spacing) * 3);width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);flex-shrink:0}.search-field__clear-button{margin-right:calc(var(--spacing) * 2);width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5);flex-shrink:0}.search-field__clear-button [data-slot=close-button-icon]{width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.search-field--secondary .search-field__group{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--search-field-group-bg);--search-field-group-bg:var(--default);--search-field-group-bg-hover:var(--default-hover);--search-field-group-bg-focus:var(--default)}@media(hover:hover){.search-field--secondary .search-field__group:hover:not(:focus-within),.search-field--secondary .search-field__group[data-hovered=true]:not([data-focus-within=true]){background-color:var(--search-field-group-bg-hover)}}.search-field--secondary .search-field__group:focus-within,.search-field--secondary .search-field__group[data-focus-within=true]{background-color:var(--search-field-group-bg-focus)}.search-field--secondary .search-field__group[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.search-field--secondary .search-field__group[data-invalid=true]:focus,.search-field--secondary .search-field__group[data-invalid=true]:focus-visible,.search-field--secondary .search-field__group[data-invalid=true][data-focused=true],.search-field--secondary .search-field__group[data-invalid=true][data-focus-visible=true],.search-field--secondary .search-field__group[data-invalid=true]:focus-within,.search-field--secondary .search-field__group[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.search-field--secondary .search-field__group[data-invalid=true]{border-color:var(--color-field-border-invalid);background-color:var(--search-field-group-bg-focus)}.search-field--secondary .search-field__group [data-slot=search-field-input]{background-color:#0000}.search-field--full-width,.search-field__group--full-width{width:100%}.textarea{border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-width:1px;outline-style:none}.textarea::placeholder{color:var(--field-placeholder,var(--muted))}@media(min-width:40rem){.textarea{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.textarea{border-width:var(--border-width-field);border-color:var(--field-border);min-height:38px;transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out)}.textarea:is([data-reduce-motion=true],[data-reduce-motion=true] *),.textarea:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.textarea:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.textarea:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.textarea:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.textarea:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.textarea:hover:not(:focus):not(:focus-visible),.textarea[data-hovered=true]:not([data-focused=true]):not([data-focus-visible=true]){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.textarea:focus,.textarea[data-focused=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;border-color:var(--field-border-focus);background-color:var(--field-focus);outline-style:none}.textarea[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.textarea[data-invalid=true]:focus,.textarea[data-invalid=true]:focus-visible,.textarea[data-invalid=true][data-focused=true],.textarea[data-invalid=true][data-focus-visible=true],.textarea[data-invalid=true]:focus-within,.textarea[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.textarea[data-invalid=true]{background-color:var(--field-focus)}.textarea:disabled,.textarea[data-disabled=true],.textarea[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.textarea--secondary{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--textarea-bg);--textarea-bg:var(--default);--textarea-bg-hover:var(--default-hover);--textarea-bg-focus:var(--default)}@media(hover:hover){.textarea--secondary:hover:not(:focus):not(:focus-visible),.textarea--secondary[data-hovered=true]:not([data-focused=true]):not([data-focus-visible=true]){background-color:var(--textarea-bg-hover)}}.textarea--secondary:focus,.textarea--secondary[data-focused=true]{background-color:var(--textarea-bg-focus)}.textarea--secondary[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.textarea--secondary[data-invalid=true]:focus,.textarea--secondary[data-invalid=true]:focus-visible,.textarea--secondary[data-invalid=true][data-focused=true],.textarea--secondary[data-invalid=true][data-focus-visible=true],.textarea--secondary[data-invalid=true]:focus-within,.textarea--secondary[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.textarea--secondary[data-invalid=true]{background-color:var(--textarea-bg-focus)}.textarea--full-width{width:100%}.calendar{width:calc(var(--spacing) * 63);max-width:calc(var(--spacing) * 63);container-type:inline-size}.calendar--week-view .calendar__cell,.calendar--day-view .calendar__cell{aspect-ratio:1;place-self:center;width:100%;height:auto}.calendar--day-view .calendar__grid{flex-direction:column;display:flex}.calendar--day-view .calendar__grid-header{grid-template-columns:repeat(7,1fr);width:100%;display:grid}.calendar--day-view .calendar__grid-header>tr{display:contents}.calendar--day-view .calendar__grid-body{margin-top:var(--spacing);grid-template-columns:repeat(7,1fr);width:100%;display:grid}.calendar--day-view .calendar__grid-body>tr{display:contents}.calendar--day-view .calendar__grid-body>tr:first-child>td{margin-top:0}.calendar__header{padding-inline:calc(var(--spacing) * .5);padding-bottom:calc(var(--spacing) * 4);justify-content:space-between;align-items:center;display:flex}.calendar__header:has(.calendar-year-picker__trigger[data-open=true]) .calendar__nav-button{pointer-events:none;opacity:0}.calendar__heading{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);flex:1}.calendar__nav-button{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6);border-radius:calc(var(--radius) * 2);color:var(--accent-soft-foreground);will-change:scale;transition:transform .25s var(--ease-out),background-color .1s var(--ease-out),box-shadow .1s var(--ease-out),opacity .15s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);justify-content:center;align-items:center;display:flex}.calendar__nav-button:is([data-reduce-motion=true],[data-reduce-motion=true] *),.calendar__nav-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.calendar__nav-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.calendar__nav-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.calendar__nav-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.calendar__nav-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar__nav-button{cursor:var(--cursor-interactive)}@media(hover:hover){.calendar__nav-button:hover,.calendar__nav-button[data-hovered=true]{background-color:var(--default);color:var(--accent-soft-foreground)}}.calendar__nav-button:active,.calendar__nav-button[data-pressed=true]{transform:scale(.95)}.calendar__nav-button:focus-visible,.calendar__nav-button[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.calendar__nav-button:disabled,.calendar__nav-button[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.calendar__nav-button-icon{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.calendar__grid{grid-template-columns:repeat(7,1fr);width:100%;display:grid}.calendar__grid[aria-readonly=true] .calendar__cell{pointer-events:none}.calendar__grid-header,.calendar__grid-header>tr,.calendar__grid-body,.calendar__grid-body>tr{display:contents}.calendar__grid-body>tr:first-child>td{margin-top:var(--spacing)}.calendar__grid-row{display:contents}.calendar__header-cell{padding-bottom:calc(var(--spacing) * 2);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--muted);justify-content:center;align-items:center;display:flex}.calendar__cell{aspect-ratio:1;border-radius:calc(var(--radius) * 3);text-align:center;width:100%;height:100%;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-outline-style:none;-webkit-tap-highlight-color:transparent;will-change:scale;transition:transform .25s var(--ease-out),box-shadow .1s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);outline-style:none;justify-content:center;align-items:center;display:flex;position:relative}.calendar__cell:is([data-reduce-motion=true],[data-reduce-motion=true] *),.calendar__cell:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.calendar__cell:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.calendar__cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.calendar__cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.calendar__cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar__cell{cursor:var(--cursor-interactive)}.calendar__cell:focus-visible:not(:focus),.calendar__cell[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.calendar__cell[data-today=true]{background-color:var(--accent-soft);color:var(--accent-soft-foreground)}@media(hover:hover){.calendar__cell[data-today=true]:hover:not([data-selected=true]),.calendar__cell[data-today=true][data-hovered=true]:not([data-selected=true]){background-color:var(--accent-soft-hover)}}.calendar__cell[data-selected=true]{background-color:var(--accent);color:var(--accent-foreground)}.calendar__cell:active,.calendar__cell[data-pressed=true]{background-color:var(--default);transform:scale(.95)}:is(.calendar__cell:active,.calendar__cell[data-pressed=true])[data-selected=true]{background-color:var(--accent-hover)}@media(hover:hover){.calendar__cell:hover:not([data-selected=true]),.calendar__cell[data-hovered=true]:not([data-selected=true]){background-color:var(--default)}}.calendar__cell[data-outside-month=true]{color:var(--muted);opacity:.5}.calendar__cell[data-selected=true][data-outside-month=true]{background-color:var(--default)}.calendar__cell[data-unavailable=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.calendar__cell:disabled:not([data-outside-month=true]),.calendar__cell[data-disabled=true]:not([data-outside-month=true]){opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none;text-decoration:line-through}.calendar__cell-indicator{bottom:var(--spacing);--tw-translate-x: -50% ;width:3px;height:3px;translate:var(--tw-translate-x) var(--tw-translate-y);border-radius:calc(var(--radius) * .25);background-color:var(--muted);position:absolute;left:50%}[data-selected=true]>.calendar__cell-indicator{background-color:var(--accent-foreground)}.range-calendar{width:calc(var(--spacing) * 63);max-width:calc(var(--spacing) * 63);container-type:inline-size}.range-calendar--week-view .range-calendar__cell,.range-calendar--day-view .range-calendar__cell{aspect-ratio:1;place-self:center;width:100%;height:auto}.range-calendar--day-view .range-calendar__grid{flex-direction:column;display:flex}.range-calendar--day-view .range-calendar__grid-header{grid-template-columns:repeat(7,1fr);width:100%;display:grid}.range-calendar--day-view .range-calendar__grid-header>tr{display:contents}.range-calendar--day-view .range-calendar__grid-body{margin-top:var(--spacing);grid-template-columns:repeat(7,1fr);width:100%;display:grid}.range-calendar--day-view .range-calendar__grid-body>tr{display:contents}.range-calendar--day-view .range-calendar__grid-body>tr:first-child>td{margin-top:0}.range-calendar__header{padding-inline:calc(var(--spacing) * .5);padding-bottom:calc(var(--spacing) * 4);justify-content:space-between;align-items:center;display:flex}.range-calendar__header:has(.calendar-year-picker__trigger[data-open=true]) .range-calendar__nav-button{pointer-events:none;opacity:0}.range-calendar__heading{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);flex:1}.range-calendar__nav-button{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6);border-radius:calc(var(--radius) * 1.5);color:var(--accent-soft-foreground);will-change:scale;transition:transform .25s var(--ease-out),background-color .1s var(--ease-out),box-shadow .1s var(--ease-out),opacity .15s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);justify-content:center;align-items:center;display:flex}.range-calendar__nav-button:is([data-reduce-motion=true],[data-reduce-motion=true] *),.range-calendar__nav-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.range-calendar__nav-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.range-calendar__nav-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.range-calendar__nav-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.range-calendar__nav-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.range-calendar__nav-button{cursor:var(--cursor-interactive)}@media(hover:hover){.range-calendar__nav-button:hover,.range-calendar__nav-button[data-hovered=true]{background-color:var(--default);color:var(--accent-soft-foreground)}}.range-calendar__nav-button:active,.range-calendar__nav-button[data-pressed=true]{transform:scale(.95)}.range-calendar__nav-button:focus-visible,.range-calendar__nav-button[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.range-calendar__nav-button:disabled,.range-calendar__nav-button[data-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.range-calendar__nav-button-icon{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.range-calendar__grid{grid-template-columns:repeat(7,1fr);width:100%;display:grid}.range-calendar__grid[aria-readonly=true] .range-calendar__cell{pointer-events:none}.range-calendar__grid-header,.range-calendar__grid-header>tr,.range-calendar__grid-body,.range-calendar__grid-body>tr{display:contents}.range-calendar__grid-body>tr:first-child>td{margin-top:var(--spacing)}.range-calendar__grid-row{display:contents}.range-calendar__header-cell{padding-bottom:calc(var(--spacing) * 2);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--muted);justify-content:center;align-items:center;display:flex}.range-calendar__cell{z-index:1;border-radius:calc(var(--radius) * 3);--tw-outline-style:none;cursor:var(--cursor-interactive);will-change:background-color,border-color;transition:box-shadow .1s var(--ease-out),border-color .1s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);outline-style:none;margin-block:2px;margin-inline:0;padding:0;position:relative}.range-calendar__cell:is([data-reduce-motion=true],[data-reduce-motion=true] *),.range-calendar__cell:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.range-calendar__cell:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.range-calendar__cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.range-calendar__cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.range-calendar__cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.range-calendar__cell .range-calendar__cell-button{aspect-ratio:1;border-radius:calc(var(--radius) * 3);width:100%;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground);-webkit-tap-highlight-color:transparent;will-change:scale;transition:scale .2s var(--ease-out);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);justify-content:center;align-items:center;display:flex}.range-calendar__cell .range-calendar__cell-button:is([data-reduce-motion=true],[data-reduce-motion=true] *),.range-calendar__cell .range-calendar__cell-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.range-calendar__cell .range-calendar__cell-button:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.range-calendar__cell .range-calendar__cell-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.range-calendar__cell .range-calendar__cell-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.range-calendar__cell .range-calendar__cell-button:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.range-calendar__cell:focus-visible:not(:focus),.range-calendar__cell[data-focus-visible=true]{z-index:2}:is(.range-calendar__cell:focus-visible:not(:focus),.range-calendar__cell[data-focus-visible=true]) .range-calendar__cell-button{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.range-calendar__cell[data-today=true] .range-calendar__cell-button{background-color:var(--accent-soft);color:var(--accent-soft-foreground)}@media(hover:hover){:is(.range-calendar__cell[data-today=true]:hover:not([data-selected=true]),.range-calendar__cell[data-today=true][data-hovered=true]:not([data-selected=true])) .range-calendar__cell-button{background-color:var(--accent-soft-hover)}}.range-calendar__cell[data-selected=true]:not([data-outside-month=true]){background-color:var(--accent-soft);border-radius:0}.range-calendar__cell[data-selected=true]:is(td:first-child>*,[aria-disabled]+td>*){border-start-start-radius:calc(var(--radius) * 1);border-end-start-radius:calc(var(--radius) * 1)}.range-calendar__cell[data-selected=true]:is(td:first-child>*,[aria-disabled]+td>*)[data-selection-start=true]{border-start-start-radius:calc(var(--radius) * 3);border-end-start-radius:calc(var(--radius) * 3)}.range-calendar__cell[data-selected=true]:is(td:last-child>*,td:has(+[aria-disabled])>*){border-start-end-radius:calc(var(--radius) * 1);border-end-end-radius:calc(var(--radius) * 1)}.range-calendar__cell[data-selected=true]:is(td:last-child>*,td:has(+[aria-disabled])>*)[data-selection-end=true]{border-start-end-radius:calc(var(--radius) * 3);border-end-end-radius:calc(var(--radius) * 3)}.range-calendar__cell[data-selection-start=true]:not([data-outside-month=true]),.range-calendar__cell[data-selection-end=true]:not([data-outside-month=true]){z-index:2}:is(.range-calendar__cell[data-selection-start=true]:not([data-outside-month=true]),.range-calendar__cell[data-selection-end=true]:not([data-outside-month=true])) .range-calendar__cell-button{background-color:var(--accent);color:var(--accent-foreground)}.range-calendar__cell[data-selection-start=true]:not([data-outside-month=true]){border-top-left-radius:calc(var(--radius) * 3);border-bottom-left-radius:calc(var(--radius) * 3)}.range-calendar__cell[data-selection-end=true]:not([data-outside-month=true]){border-top-right-radius:calc(var(--radius) * 3);border-bottom-right-radius:calc(var(--radius) * 3)}:is(.range-calendar__cell:active,.range-calendar__cell[data-pressed=true]) .range-calendar__cell-button{scale:.9}:is(:is(.range-calendar__cell:active,.range-calendar__cell[data-pressed=true])[data-selection-start=true],:is(.range-calendar__cell:active,.range-calendar__cell[data-pressed=true])[data-selection-end=true]) .range-calendar__cell-button{background-color:var(--accent-hover)}@media(hover:hover){:is(.range-calendar__cell:hover:not([data-selected=true]),.range-calendar__cell[data-hovered=true]:not([data-selected=true])) .range-calendar__cell-button{background-color:var(--default)}}.range-calendar__cell[data-outside-month=true]{color:var(--muted);opacity:.5}.range-calendar__cell[data-selected=true][data-outside-month=true]:not([data-selection-start=true],[data-selection-end=true]){background-color:var(--default)}@supports (color:color-mix(in lab,red,red)){.range-calendar__cell[data-selected=true][data-outside-month=true]:not([data-selection-start=true],[data-selection-end=true]){background-color:color-mix(in oklab,var(--default) 20%,transparent)}}.range-calendar__cell[data-unavailable=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.range-calendar__cell:disabled:not([data-outside-month=true]),.range-calendar__cell[data-disabled=true]:not([data-outside-month=true]){opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none;text-decoration:line-through}.range-calendar__grid-body td:has(>.range-calendar__cell[data-outside-month=true])+td>.range-calendar__cell[data-selected=true]{border-start-start-radius:calc(var(--radius) * 1);border-end-start-radius:calc(var(--radius) * 1)}.range-calendar__grid-body td:has(>.range-calendar__cell[data-outside-month=true])+td>.range-calendar__cell[data-selected=true][data-outside-month=true],.range-calendar__grid-body td:has(>.range-calendar__cell[data-outside-month=true])+td>.range-calendar__cell[data-selected=true][data-selection-start=true]{border-start-start-radius:calc(var(--radius) * 3);border-end-start-radius:calc(var(--radius) * 3)}.range-calendar__grid-body td:has(>.range-calendar__cell[data-selected=true]):has(+td>.range-calendar__cell[data-outside-month=true])>.range-calendar__cell[data-selected=true]{border-start-end-radius:calc(var(--radius) * 1);border-end-end-radius:calc(var(--radius) * 1)}.range-calendar__grid-body td:has(>.range-calendar__cell[data-selected=true]):has(+td>.range-calendar__cell[data-outside-month=true])>.range-calendar__cell[data-selected=true][data-outside-month=true],.range-calendar__grid-body td:has(>.range-calendar__cell[data-selected=true]):has(+td>.range-calendar__cell[data-outside-month=true])>.range-calendar__cell[data-selected=true][data-selection-end=true]{border-start-end-radius:calc(var(--radius) * 3);border-end-end-radius:calc(var(--radius) * 3)}.range-calendar__cell-indicator{bottom:var(--spacing);--tw-translate-x: -50% ;width:3px;height:3px;translate:var(--tw-translate-x) var(--tw-translate-y);border-radius:calc(var(--radius) * .25);background-color:var(--muted);position:absolute;left:50%}[data-selected=true]>.range-calendar__cell-indicator{background-color:var(--accent-foreground)}.calendar:has(.calendar-year-picker__year-grid),.range-calendar:has(.calendar-year-picker__year-grid){position:relative}.calendar:has(.calendar-year-picker__year-grid)>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid)>[data-slot=range-calendar-grid]{will-change:opacity;transition:opacity .15s var(--ease-out),visibility 0s linear}:is(.calendar:has(.calendar-year-picker__year-grid)>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid)>[data-slot=range-calendar-grid]):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.calendar:has(.calendar-year-picker__year-grid)>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid)>[data-slot=range-calendar-grid]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.calendar:has(.calendar-year-picker__year-grid)>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid)>[data-slot=range-calendar-grid]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){:is(.calendar:has(.calendar-year-picker__year-grid)>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid)>[data-slot=range-calendar-grid]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.calendar:has(.calendar-year-picker__year-grid)>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid)>[data-slot=range-calendar-grid]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.calendar:has(.calendar-year-picker__year-grid)>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid)>[data-slot=range-calendar-grid]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=range-calendar-grid]{pointer-events:none;opacity:0;visibility:hidden;transition:opacity .15s var(--ease-out),visibility 0s linear .15s}:is(.calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=range-calendar-grid]):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=range-calendar-grid]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=range-calendar-grid]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){:is(.calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=range-calendar-grid]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=range-calendar-grid]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=calendar-grid],.range-calendar:has(.calendar-year-picker__year-grid[data-open=true])>[data-slot=range-calendar-grid]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar-year-picker__trigger{justify-content:flex-start;align-items:center;gap:var(--spacing);border-radius:calc(var(--radius) * 1);--tw-outline-style:none;cursor:var(--cursor-interactive);touch-action:manipulation;outline-style:none;flex:1;display:flex}.calendar-year-picker__trigger:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.calendar-year-picker__trigger-heading{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);transition:color .15s var(--ease-out)}.calendar-year-picker__trigger-heading:is([data-reduce-motion=true],[data-reduce-motion=true] *),.calendar-year-picker__trigger-heading:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.calendar-year-picker__trigger-heading:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.calendar-year-picker__trigger-heading:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.calendar-year-picker__trigger-heading:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.calendar-year-picker__trigger-heading:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar-year-picker__trigger-indicator{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));color:var(--accent-soft-foreground);transition:transform .15s var(--ease-out)}.calendar-year-picker__trigger-indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *),.calendar-year-picker__trigger-indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.calendar-year-picker__trigger-indicator:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.calendar-year-picker__trigger-indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.calendar-year-picker__trigger-indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.calendar-year-picker__trigger-indicator:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar-year-picker__trigger[data-open=true] .calendar-year-picker__trigger-indicator{transform:rotate(90deg)}.calendar-year-picker__trigger[data-open=true] .calendar-year-picker__trigger-heading{color:var(--accent-soft-foreground)}.calendar-year-picker__year-grid{pointer-events:none;scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);align-content:flex-start;gap:var(--spacing);padding:var(--spacing);opacity:0;will-change:opacity;grid-template-columns:repeat(3,1fr);display:grid;position:absolute;left:0;right:0;overflow-y:auto}.calendar-year-picker__year-grid[data-open=true]{pointer-events:auto;opacity:1;transition:opacity .2s var(--ease-out) 50ms}.calendar-year-picker__year-grid[data-open=true]:is([data-reduce-motion=true],[data-reduce-motion=true] *),.calendar-year-picker__year-grid[data-open=true]:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.calendar-year-picker__year-grid[data-open=true]:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.calendar-year-picker__year-grid[data-open=true]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.calendar-year-picker__year-grid[data-open=true]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.calendar-year-picker__year-grid[data-open=true]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar-year-picker__year-cell{height:calc(var(--spacing) * 8);border-radius:calc(var(--radius) * 3);padding-inline:calc(var(--spacing) * 2.5);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;touch-action:manipulation;transition:color .1s var(--ease-smooth),scale .1s var(--ease-smooth),opacity .1s var(--ease-smooth),background-color .1s var(--ease-smooth),box-shadow .1s var(--ease-out);transform-origin:50%;transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);outline-style:none;justify-content:center;align-items:center;display:inline-flex;position:relative}.calendar-year-picker__year-cell:is([data-reduce-motion=true],[data-reduce-motion=true] *),.calendar-year-picker__year-cell:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.calendar-year-picker__year-cell:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.calendar-year-picker__year-cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.calendar-year-picker__year-cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.calendar-year-picker__year-cell:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.calendar-year-picker__year-cell{cursor:var(--cursor-interactive)}@media(hover:hover)and (pointer:fine){.calendar-year-picker__year-cell:is(:hover,[data-hovered=true]):not([data-selected=true]){background-color:var(--default);color:var(--default-foreground)}}.calendar-year-picker__year-cell[data-selected=true],.calendar-year-picker__year-cell[aria-selected=true]{background-color:var(--accent);color:var(--accent-foreground)}@media(hover:hover)and (pointer:fine){:is(.calendar-year-picker__year-cell[data-selected=true],.calendar-year-picker__year-cell[aria-selected=true]):is(:hover,[data-hovered=true]){background-color:var(--accent-hover)}}.calendar-year-picker__year-cell:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.date-field{gap:var(--spacing);flex-direction:column;display:flex}:is(.date-field[data-invalid=true],.date-field[aria-invalid=true]) [data-slot=description]{display:none}.date-field [data-slot=label]{width:fit-content}.date-field--full-width{width:100%}.time-field{gap:var(--spacing);flex-direction:column;display:flex}:is(.time-field[data-invalid=true],.time-field[aria-invalid=true]) [data-slot=description]{display:none}.time-field [data-slot=label]{width:fit-content}.time-field--full-width{width:100%}.date-input-group{height:calc(var(--spacing) * 9);border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-width:1px;border-width:var(--border-width-field);border-color:var(--field-border);transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);outline-style:none;align-items:center;display:inline-flex;overflow:hidden}.date-input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *),.date-input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.date-input-group:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.date-input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.date-input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.date-input-group:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}@media(hover:hover){.date-input-group:hover:not(:focus-within),.date-input-group[data-hovered=true]:not([data-focus-within=true]){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.date-input-group[data-focus-within=true]:not(:has([data-slot=date-picker-trigger]:focus,[data-slot=date-picker-trigger][data-focused=true],[data-slot=date-range-picker-trigger]:focus,[data-slot=date-range-picker-trigger][data-focused=true])),.date-input-group:focus-within:not(:has([data-slot=date-picker-trigger]:focus,[data-slot=date-picker-trigger][data-focused=true],[data-slot=date-range-picker-trigger]:focus,[data-slot=date-range-picker-trigger][data-focused=true])){--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;outline-style:none}.date-input-group[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.date-input-group[data-invalid=true]:focus,.date-input-group[data-invalid=true]:focus-visible,.date-input-group[data-invalid=true][data-focused=true],.date-input-group[data-invalid=true][data-focus-visible=true],.date-input-group[data-invalid=true]:focus-within,.date-input-group[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.date-input-group[data-invalid=true]{background-color:var(--field-focus);border-color:var(--color-field-border-invalid)}.date-input-group[data-disabled=true],.date-input-group[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.date-input-group__input{cursor:text;border-style:var(--tw-border-style);padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;background-color:#0000;border-width:0;border-radius:0;outline-style:none;flex:1;align-items:center;gap:1px;display:flex}@media(min-width:40rem){.date-input-group__input{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.date-input-group:has([data-slot=date-input-group-prefix]) .date-input-group__input{padding-left:calc(var(--spacing) * 2);border-top-left-radius:0;border-bottom-left-radius:0}.date-input-group:has([data-slot=date-input-group-suffix]) .date-input-group__input{padding-right:calc(var(--spacing) * 2);border-top-right-radius:0;border-bottom-right-radius:0}.date-input-group:has(.date-range-picker__range-separator) .date-input-group__input[slot=start]{flex:none;padding-right:0}.date-input-group:has(.date-range-picker__range-separator) .date-input-group__input[slot=end]{padding-left:0}.date-input-group__input:focus,.date-input-group__input:focus-visible{--tw-outline-style:none;outline-style:none}.date-input-group__input-container{scrollbar-color:auto;scrollbar-gutter:auto;-ms-overflow-style:none;scrollbar-width:none;flex:1;align-items:center;width:fit-content;display:flex;overflow:auto clip}.date-input-group__segment{border-radius:calc(var(--radius) * .75);padding-inline:calc(var(--spacing) * .5);text-align:end;text-wrap:nowrap;--tw-outline-style:none;outline-style:none;display:inline-block}.date-input-group__segment[data-type=literal]{color:var(--muted);padding:0}.date-input-group__segment[data-placeholder=true]{color:var(--field-placeholder,var(--muted))}.date-input-group__segment:focus,.date-input-group__segment[data-focused=true]{background-color:var(--accent-soft);color:var(--accent-soft-foreground)}.date-input-group__segment[data-disabled=true]{opacity:.5}.date-input-group__segment[data-invalid=true]{color:var(--danger)}.date-input-group__segment[data-invalid=true]:focus,.date-input-group__segment[data-invalid=true][data-focused=true]{background-color:var(--danger-soft);color:var(--danger-soft-foreground)}.date-input-group__prefix{pointer-events:none;color:var(--field-placeholder,var(--muted));margin-right:0;margin-left:calc(var(--spacing) * 3);flex-shrink:0;align-items:center;display:flex}.date-input-group__suffix{pointer-events:none;color:var(--field-placeholder,var(--muted));margin-right:calc(var(--spacing) * 3);flex-shrink:0;align-items:center;display:flex}.date-input-group--secondary{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--date-input-group-bg);--date-input-group-bg:var(--default);--date-input-group-bg-hover:var(--default-hover);--date-input-group-bg-focus:var(--default)}@media(hover:hover){.date-input-group--secondary:hover:not(:focus-within),.date-input-group--secondary[data-hovered=true]:not([data-focus-within=true]){background-color:var(--date-input-group-bg-hover)}}.date-input-group--secondary:focus-within,.date-input-group--secondary[data-focus-within=true]{background-color:var(--date-input-group-bg-focus)}.date-input-group--secondary[data-invalid=true]{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}.date-input-group--secondary[data-invalid=true]:focus,.date-input-group--secondary[data-invalid=true]:focus-visible,.date-input-group--secondary[data-invalid=true][data-focused=true],.date-input-group--secondary[data-invalid=true][data-focus-visible=true],.date-input-group--secondary[data-invalid=true]:focus-within,.date-input-group--secondary[data-invalid=true][data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.date-input-group--secondary[data-invalid=true]{border-color:var(--color-field-border-invalid);background-color:var(--date-input-group-bg-focus)}.date-input-group--secondary [data-slot=date-input-group-input]{background-color:#0000}.date-input-group--full-width{width:100%}.date-picker{gap:var(--spacing);flex-direction:column;display:inline-flex}.date-picker .date-input-group__suffix,.date-picker .date-input-group__prefix{pointer-events:auto}.date-picker__trigger{border-radius:var(--field-radius,calc(var(--radius) * 1.5));width:100%;padding:var(--spacing);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);transition:box-shadow .15s var(--ease-out);align-items:center;display:inline-flex}.date-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.date-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.date-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.date-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.date-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.date-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.date-picker__trigger:focus-visible:not(:focus),.date-picker__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.date-picker__trigger:disabled,.date-picker__trigger[data-disabled=true],.date-picker__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.date-picker__trigger-indicator{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);color:var(--field-placeholder,var(--muted));justify-content:center;align-items:center;display:inline-flex}.date-picker__popover{min-width:var(--trigger-width);transform-origin:var(--trigger-anchor-point);scrollbar-color:auto;scrollbar-gutter:auto;-ms-overflow-style:none;scrollbar-width:none;overscroll-behavior:contain;background-color:var(--overlay);padding:calc(var(--spacing) * 3);overflow-y:auto}.date-picker__popover:is([data-reduce-motion=true],[data-reduce-motion=true] *),.date-picker__popover:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.date-picker__popover:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.date-picker__popover:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.date-picker__popover:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.date-picker__popover:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.date-picker__popover{box-shadow:var(--shadow-overlay);border-radius:min(32px,calc(var(--radius) * 2.5))}.date-picker__popover:focus-visible:not(:focus),.date-picker__popover[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.date-picker__popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.95;transition-duration:.15s;transition-timing-function:ease}.date-picker__popover[data-entering=true][data-placement^=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.date-picker__popover[data-entering=true][data-placement^=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.date-picker__popover[data-entering=true][data-placement^=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.date-picker__popover[data-entering=true][data-placement^=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.date-picker__popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.date-picker__popover[data-exiting=true],.date-picker__popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.date-range-picker{gap:var(--spacing);flex-direction:column;display:inline-flex}.date-range-picker .date-input-group__suffix,.date-range-picker .date-input-group__prefix{pointer-events:auto}.date-range-picker__trigger{border-radius:var(--field-radius,calc(var(--radius) * 1.5));width:100%;padding:var(--spacing);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));-webkit-tap-highlight-color:transparent;cursor:var(--cursor-interactive);transition:box-shadow .15s var(--ease-out);align-items:center;display:inline-flex}.date-range-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.date-range-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.date-range-picker__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.date-range-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.date-range-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.date-range-picker__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.date-range-picker__trigger:focus-visible:not(:focus),.date-range-picker__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.date-range-picker__trigger:disabled,.date-range-picker__trigger[data-disabled=true],.date-range-picker__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.date-range-picker__trigger-indicator{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);color:var(--field-placeholder,var(--muted));justify-content:center;align-items:center;display:inline-flex}.date-range-picker__range-separator{padding-inline:var(--spacing);color:var(--field-placeholder,var(--muted));-webkit-user-select:none;user-select:none}.date-range-picker__popover{min-width:var(--trigger-width);transform-origin:var(--trigger-anchor-point);scrollbar-color:auto;scrollbar-gutter:auto;-ms-overflow-style:none;scrollbar-width:none;overscroll-behavior:contain;background-color:var(--overlay);padding:calc(var(--spacing) * 3);overflow-y:auto}.date-range-picker__popover:is([data-reduce-motion=true],[data-reduce-motion=true] *),.date-range-picker__popover:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.date-range-picker__popover:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.date-range-picker__popover:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.date-range-picker__popover:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.date-range-picker__popover:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.date-range-picker__popover{box-shadow:var(--shadow-overlay);border-radius:min(32px,calc(var(--radius) * 2.5))}.date-range-picker__popover:focus-visible:not(:focus),.date-range-picker__popover[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.date-range-picker__popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.95;transition-duration:.15s;transition-timing-function:ease}.date-range-picker__popover[data-entering=true][data-placement^=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.date-range-picker__popover[data-entering=true][data-placement^=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.date-range-picker__popover[data-entering=true][data-placement^=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.date-range-picker__popover[data-entering=true][data-placement^=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.date-range-picker__popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.date-range-picker__popover[data-exiting=true],.date-range-picker__popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.card{gap:calc(var(--spacing) * 3);padding:calc(var(--spacing) * 4);--tw-shadow:var(--surface-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-radius:min(32px,var(--radius-3xl));flex-direction:column;display:flex;position:relative;overflow:visible}.card__header{flex-direction:column;display:flex}.card__title{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6);--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground)}.card__description{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5);color:var(--muted)}.card__content{gap:var(--spacing);flex-direction:column;flex:1;display:flex}.card__footer{flex-direction:row;align-items:center;display:flex}.card--transparent{--tw-border-style:none;--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:#0000;border-style:none}.card--default{background-color:var(--surface)}.card--secondary{background-color:var(--surface-secondary)}.card--tertiary{background-color:var(--surface-tertiary)}.header{width:100%;padding-inline:calc(var(--spacing) * 2);padding-top:calc(var(--spacing) * 1.5);padding-bottom:var(--spacing);text-align:left;font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--muted)}.separator{border-radius:calc(var(--radius) * .5);border-top-style:var(--tw-border-style);border-top-width:0;border-bottom-style:var(--tw-border-style);background-color:var(--separator);border-bottom-width:0;flex-shrink:0;width:100%;height:1px}.separator--horizontal{width:100%;height:1px}.separator--vertical{height:auto;min-height:calc(var(--spacing) * 2);align-self:stretch;width:1px}.separator--default{background-color:var(--separator)}.separator--secondary{background-color:var(--separator-secondary)}.separator--tertiary{background-color:var(--separator-tertiary)}.separator__container{align-items:center;gap:calc(var(--spacing) * 3);display:flex}.separator__container--horizontal{flex-direction:row;width:100%}.separator__container--vertical{flex-direction:column;justify-content:center;height:100%}.separator__line{flex-grow:1;flex-shrink:0}.separator__content{text-align:center;white-space:nowrap;color:var(--muted);justify-content:center;align-items:center;display:inline-flex}.separator__content--horizontal,.separator__content--vertical{text-align:center}.surface{color:var(--foreground);position:relative}.surface--transparent{background-color:#0000}.surface--default{background-color:var(--surface);color:var(--surface-foreground)}.surface--secondary{background-color:var(--surface-secondary);color:var(--surface-secondary-foreground)}.surface--tertiary{background-color:var(--surface-tertiary);color:var(--surface-tertiary-foreground)}.avatar{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10);border-radius:calc(var(--radius) * 3);background-color:var(--default);flex-shrink:0;justify-content:center;align-items:center;display:flex;position:relative;overflow:hidden}.avatar__fallback{background-color:var(--default);width:100%;height:100%;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);justify-content:center;align-items:center;display:flex}.avatar__image{aspect-ratio:1;width:100%;height:100%;transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.25s;transition-duration:.25s;position:absolute;top:0;right:0;bottom:0;left:0}.avatar__image:is([data-reduce-motion=true],[data-reduce-motion=true] *),.avatar__image:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.avatar__image:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.avatar__image:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.avatar__image:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.avatar__image:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.avatar--sm{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8);border-radius:calc(var(--radius) * 2)}.avatar--lg{width:calc(var(--spacing) * 12);height:calc(var(--spacing) * 12);border-radius:calc(var(--radius) * 3)}.avatar--lg .avatar__fallback{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.avatar__fallback--accent{color:var(--accent-soft-foreground)}.avatar__fallback--default{color:var(--default-soft-foreground)}.avatar__fallback--success{color:var(--success-soft-foreground)}.avatar__fallback--warning{color:var(--warning-soft-foreground)}.avatar__fallback--danger{color:var(--danger-soft-foreground)}.avatar--soft{background-color:#0000}.avatar--soft .avatar__fallback--accent{background-color:var(--accent-soft);color:var(--accent-soft-foreground)}.avatar--soft .avatar__fallback--success{background-color:var(--success-soft);color:var(--success-soft-foreground)}.avatar--soft .avatar__fallback--warning{background-color:var(--warning-soft);color:var(--warning-soft-foreground)}.avatar--soft .avatar__fallback--default{background-color:var(--default-soft);color:var(--default-soft-foreground)}.avatar--soft .avatar__fallback--danger{background-color:var(--danger-soft);color:var(--danger-soft-foreground)}.alert-dialog__trigger{cursor:var(--cursor-interactive);transition:transform .25s var(--ease-out-quart),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);display:inline-block}.alert-dialog__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.alert-dialog__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.alert-dialog__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.alert-dialog__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.alert-dialog__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.alert-dialog__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.alert-dialog__trigger:focus-visible:not(:focus),.alert-dialog__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.alert-dialog__trigger:disabled,.alert-dialog__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.alert-dialog__trigger:active,.alert-dialog__trigger[data-pressed=true]{transform:scale(.97)}.alert-dialog__backdrop{z-index:50;height:var(--visual-viewport-height);flex-direction:row;justify-content:center;align-items:center;width:100%;display:flex;position:fixed;top:0;right:0;bottom:0;left:0}.alert-dialog__backdrop[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:var(--ease-out);transition-duration:.15s;transition-timing-function:var(--ease-out);--tw-enter-opacity:0}.alert-dialog__backdrop[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:var(--ease-out);transition-duration:.1s;transition-timing-function:var(--ease-out);--tw-exit-opacity:0}.alert-dialog__backdrop[data-exiting=true],.alert-dialog__backdrop[data-entering=true]{will-change:opacity}:is(.alert-dialog__backdrop[data-exiting=true],.alert-dialog__backdrop[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.alert-dialog__backdrop[data-exiting=true],.alert-dialog__backdrop[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.alert-dialog__backdrop[data-exiting=true],.alert-dialog__backdrop[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){:is(.alert-dialog__backdrop[data-exiting=true],.alert-dialog__backdrop[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.alert-dialog__backdrop[data-exiting=true],.alert-dialog__backdrop[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.alert-dialog__backdrop[data-exiting=true],.alert-dialog__backdrop[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.alert-dialog__backdrop--transparent{background-color:#0000}.alert-dialog__backdrop--opaque{background-color:var(--backdrop)}.alert-dialog__backdrop--blur{background-color:var(--backdrop);--tw-backdrop-blur:blur(var(--blur-md));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.alert-dialog__container{height:var(--visual-viewport-height);width:100%;min-width:0;padding:calc(var(--spacing) * 4);flex-direction:column;flex:1;align-items:center;display:flex}@media(min-width:40rem){.alert-dialog__container{width:fit-content;padding:calc(var(--spacing) * 10)}}.alert-dialog__container{pointer-events:none}.alert-dialog__container[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.25s;--tw-ease:cubic-bezier(.25, .46, .45, .94);--tw-enter-opacity:0;--tw-enter-scale: 105% ;transition-duration:.25s;transition-timing-function:cubic-bezier(.25,.46,.45,.94)}.alert-dialog__container[data-entering=true][data-placement=auto]{--tw-enter-translate-y:calc(1*var(--spacing))}@media(min-width:40rem){.alert-dialog__container[data-entering=true][data-placement=auto]{--tw-enter-translate-y: 0% }}.alert-dialog__container[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.alert-dialog__container[data-entering=true][data-placement=center]{--tw-enter-translate-y: -0% }.alert-dialog__container[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing))}.alert-dialog__container[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:cubic-bezier(.25, .46, .45, .94);--tw-exit-opacity:0;--tw-exit-scale:.95;transition-duration:.1s;transition-timing-function:cubic-bezier(.25,.46,.45,.94)}.alert-dialog__container[data-exiting=true],.alert-dialog__container[data-entering=true]{will-change:opacity,transform}:is(.alert-dialog__container[data-exiting=true],.alert-dialog__container[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.alert-dialog__container[data-exiting=true],.alert-dialog__container[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.alert-dialog__container[data-exiting=true],.alert-dialog__container[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){:is(.alert-dialog__container[data-exiting=true],.alert-dialog__container[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.alert-dialog__container[data-exiting=true],.alert-dialog__container[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.alert-dialog__container[data-exiting=true],.alert-dialog__container[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.alert-dialog__dialog{background-color:var(--overlay);--tw-shadow:var(--overlay-shadow);width:100%;min-height:0;max-height:100%;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-radius:min(32px,var(--radius-3xl));padding:calc(var(--spacing) * 6);pointer-events:auto;outline-style:none;flex-direction:column;display:flex;position:relative;overflow:clip}.alert-dialog__dialog[data-placement=auto]{margin-top:auto}@media(min-width:40rem){.alert-dialog__dialog[data-placement=auto]{margin-block:auto}}.alert-dialog__dialog[data-placement=center]{margin-block:auto}.alert-dialog__dialog[data-placement=bottom]{margin-top:auto}.alert-dialog__dialog[data-placement=top]{margin-top:0}.alert-dialog__dialog--xs{max-width:var(--container-xs)}.alert-dialog__dialog--sm{max-width:var(--container-sm)}.alert-dialog__dialog--md{max-width:var(--container-md)}.alert-dialog__dialog--lg{max-width:var(--container-lg)}.alert-dialog__dialog--cover{width:100%;height:100%;min-height:100%}.alert-dialog__header{gap:calc(var(--spacing) * 3);flex-direction:column;margin-bottom:0;display:flex}.alert-dialog__header>.modal__icon{margin-bottom:0}.alert-dialog__heading{vertical-align:middle;font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground)}.alert-dialog__icon{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10);border-radius:calc(var(--radius) * 3);-webkit-user-select:none;user-select:none;flex-shrink:0;justify-content:center;align-items:center;display:flex}.alert-dialog__icon [data-slot=alert-dialog-default-icon]{box-sizing:content-box;width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5)}.alert-dialog__icon--default{background-color:var(--default);color:var(--foreground)}.alert-dialog__icon--accent{background-color:var(--accent-soft);color:var(--accent-soft-foreground)}.alert-dialog__icon--success{background-color:var(--success-soft);color:var(--success-soft-foreground)}.alert-dialog__icon--warning{background-color:var(--warning-soft);color:var(--warning-soft-foreground)}.alert-dialog__icon--danger{background-color:var(--danger-soft);color:var(--danger-soft-foreground)}.alert-dialog__body{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);min-height:0;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:1.43;color:var(--muted);overscroll-behavior:contain;-webkit-overflow-scrolling:touch;margin:-3px;flex:1;margin-block:0;padding:3px;line-height:1.43;overflow-y:auto}.alert-dialog__footer{justify-content:flex-end;align-items:center;gap:calc(var(--spacing) * 2);flex-direction:row;margin-top:0;display:flex}.alert-dialog__close-trigger{top:calc(var(--spacing) * 4);right:calc(var(--spacing) * 4);position:absolute}.alert-dialog__header+.alert-dialog__body{margin-top:calc(var(--spacing) * 2)}.alert-dialog__header+.alert-dialog__footer,.alert-dialog__body+.alert-dialog__footer{margin-top:calc(var(--spacing) * 5)}.drawer__trigger{cursor:var(--cursor-interactive);transition:transform .25s var(--ease-out-quart),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);display:inline-block}.drawer__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.drawer__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.drawer__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.drawer__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.drawer__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.drawer__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.drawer__trigger:focus-visible:not(:focus),.drawer__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.drawer__trigger:disabled,.drawer__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.drawer__trigger:active,.drawer__trigger[data-pressed=true]{transform:scale(.97)}.drawer__backdrop{z-index:50;height:var(--visual-viewport-height);opacity:1;width:100%;transition:opacity .25s cubic-bezier(.32,.72,0,1);position:fixed;top:0;right:0;bottom:0;left:0}.drawer__backdrop[data-entering=true]{opacity:0}.drawer__backdrop[data-exiting=true]{opacity:0;transition-duration:.2s;transition-timing-function:cubic-bezier(.32,.72,0,1)}.drawer__backdrop[data-exiting=true],.drawer__backdrop[data-entering=true]{will-change:opacity}@media(prefers-reduced-motion:reduce){.drawer__backdrop{transition:none}}.drawer__backdrop--transparent{background-color:#0000}.drawer__backdrop--opaque{background-color:var(--backdrop)}.drawer__backdrop--blur{background-color:var(--backdrop);--tw-backdrop-blur:blur(var(--blur-md));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.drawer__content{pointer-events:none;z-index:50;height:var(--visual-viewport-height);width:100%;min-width:0;display:flex;position:fixed;top:0;right:0;bottom:0;left:0}.drawer__content--bottom{align-items:flex-end}.drawer__content--top{align-items:flex-start}.drawer__content--left{justify-content:flex-start}.drawer__content--right{justify-content:flex-end}.drawer__dialog{background-color:var(--overlay);--tw-shadow:var(--overlay-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;padding:calc(var(--spacing) * 6);pointer-events:auto;--drawer-enter-duration:.25s;--drawer-exit-duration:.2s;--drawer-enter-ease:cubic-bezier(.32, .72, 0, 1);--drawer-exit-ease:cubic-bezier(.32, .72, 0, 1);will-change:translate;transition:translate var(--drawer-enter-duration) var(--drawer-enter-ease);outline-style:none;flex-direction:column;display:flex;position:relative}@media(prefers-reduced-motion:reduce){.drawer__dialog{transition:none}}.drawer__dialog[data-placement=bottom]{border-top-left-radius:min(32px,var(--radius-2xl));border-top-right-radius:min(32px,var(--radius-2xl));width:100%;max-height:85vh}.drawer__dialog[data-placement=top]{border-bottom-left-radius:min(32px,var(--radius-2xl));border-bottom-right-radius:min(32px,var(--radius-2xl));width:100%;max-height:85vh}.drawer__dialog[data-placement=left]{height:100%;width:calc(var(--spacing) * 80);border-radius:0;max-width:85vw}@media(min-width:40rem){.drawer__dialog[data-placement=left]{width:calc(var(--spacing) * 96)}}.drawer__dialog[data-placement=right]{height:100%;width:calc(var(--spacing) * 80);border-radius:0;max-width:85vw}@media(min-width:40rem){.drawer__dialog[data-placement=right]{width:calc(var(--spacing) * 96)}}[data-exiting=true] .drawer__dialog{transition-duration:var(--drawer-exit-duration);transition-timing-function:var(--drawer-exit-ease)}.drawer__content--left .drawer__dialog,.drawer__content--right .drawer__dialog,.drawer__content--top .drawer__dialog,.drawer__content--bottom .drawer__dialog{translate:0}.drawer__content--left[data-entering=true] .drawer__dialog,.drawer__content--left[data-exiting=true] .drawer__dialog{translate:-100%}.drawer__content--right[data-entering=true] .drawer__dialog,.drawer__content--right[data-exiting=true] .drawer__dialog{translate:100%}.drawer__content--top[data-entering=true] .drawer__dialog,.drawer__content--top[data-exiting=true] .drawer__dialog{translate:0 -100%}.drawer__content--bottom[data-entering=true] .drawer__dialog,.drawer__content--bottom[data-exiting=true] .drawer__dialog{translate:0 100%}.drawer__dialog--top{padding-bottom:calc(var(--spacing) * 2)}.drawer__dialog--top .drawer__handle{padding-bottom:0}.drawer__header{gap:calc(var(--spacing) * 3);flex-direction:column;margin-bottom:0;display:flex}.drawer__heading{vertical-align:middle;font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground)}.drawer__body{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);min-height:0;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:1.43;color:var(--muted);overscroll-behavior:contain;-webkit-overflow-scrolling:touch;margin:-3px;flex:1;margin-block:0;padding:3px;line-height:1.43;overflow-y:auto}.drawer__footer{justify-content:flex-end;align-items:center;gap:calc(var(--spacing) * 2);flex-direction:row;margin-top:0;display:flex}.drawer__handle{padding-bottom:calc(var(--spacing) * 2);justify-content:center;align-items:center;display:flex}.drawer__handle>[data-slot=drawer-handle-bar]{height:var(--spacing);width:calc(var(--spacing) * 9);border-radius:calc(var(--radius) * .25);background-color:var(--separator)}.drawer__close-trigger{top:calc(var(--spacing) * 4);right:calc(var(--spacing) * 4);position:absolute}.drawer__header+.drawer__body{margin-top:calc(var(--spacing) * 2)}.drawer__header+.drawer__footer,.drawer__body+.drawer__footer{margin-top:calc(var(--spacing) * 5)}.drawer__handle+.drawer__header,.drawer__handle+.drawer__body{margin-top:0}.modal__trigger{cursor:var(--cursor-interactive);transition:transform .25s var(--ease-out-quart),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);display:inline-block}.modal__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.modal__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.modal__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.modal__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.modal__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.modal__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.modal__trigger:focus-visible:not(:focus),.modal__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.modal__trigger:disabled,.modal__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.modal__trigger:active,.modal__trigger[data-pressed=true]{transform:scale(.97)}.modal__backdrop{z-index:50;height:var(--visual-viewport-height);flex-direction:row;justify-content:center;align-items:center;width:100%;display:flex;position:fixed;top:0;right:0;bottom:0;left:0}.modal__backdrop[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:var(--ease-out);transition-duration:.15s;transition-timing-function:var(--ease-out);--tw-enter-opacity:0}.modal__backdrop[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:var(--ease-out);transition-duration:.1s;transition-timing-function:var(--ease-out);--tw-exit-opacity:0}.modal__backdrop[data-exiting=true],.modal__backdrop[data-entering=true]{will-change:opacity}:is(.modal__backdrop[data-exiting=true],.modal__backdrop[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.modal__backdrop[data-exiting=true],.modal__backdrop[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.modal__backdrop[data-exiting=true],.modal__backdrop[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){:is(.modal__backdrop[data-exiting=true],.modal__backdrop[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.modal__backdrop[data-exiting=true],.modal__backdrop[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.modal__backdrop[data-exiting=true],.modal__backdrop[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.modal__backdrop--transparent{background-color:#0000}.modal__backdrop--opaque{background-color:var(--backdrop)}.modal__backdrop--blur{background-color:var(--backdrop);--tw-backdrop-blur:blur(var(--blur-md));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.modal__container{height:var(--visual-viewport-height);width:100%;min-width:0;padding:calc(var(--spacing) * 4);flex-direction:column;flex:1;align-items:center;display:flex}@media(min-width:40rem){.modal__container{width:fit-content;padding:calc(var(--spacing) * 10)}}.modal__container{pointer-events:none}.modal__container[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.25s;--tw-ease:cubic-bezier(.25, .46, .45, .94);--tw-enter-opacity:0;--tw-enter-scale: 105% ;transition-duration:.25s;transition-timing-function:cubic-bezier(.25,.46,.45,.94)}.modal__container[data-entering=true][data-placement=auto]{--tw-enter-translate-y:calc(1*var(--spacing))}@media(min-width:40rem){.modal__container[data-entering=true][data-placement=auto]{--tw-enter-translate-y: 0% }}.modal__container[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.modal__container[data-entering=true][data-placement=center]{--tw-enter-translate-y: -0% }.modal__container[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing))}.modal__container[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:cubic-bezier(.25, .46, .45, .94);--tw-exit-opacity:0;--tw-exit-scale:.95;transition-duration:.1s;transition-timing-function:cubic-bezier(.25,.46,.45,.94)}.modal__container[data-exiting=true],.modal__container[data-entering=true]{will-change:opacity,transform}:is(.modal__container[data-exiting=true],.modal__container[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *),:is(.modal__container[data-exiting=true],.modal__container[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,:is(.modal__container[data-exiting=true],.modal__container[data-entering=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{animation:none}@media(prefers-reduced-motion:reduce){:is(.modal__container[data-exiting=true],.modal__container[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),:is(.modal__container[data-exiting=true],.modal__container[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,:is(.modal__container[data-exiting=true],.modal__container[data-entering=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{animation:none}}.modal__container--scroll-outside{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);pointer-events:auto;-webkit-overflow-scrolling:touch;overflow-y:auto}.modal__container--full{padding:0}@media(min-width:40rem){.modal__container--full{padding:0}}.modal__container--full[data-entering=true]{--tw-enter-translate-y: 0% ;--tw-enter-scale:1}@media(min-width:40rem){.modal__container--full[data-entering=true]{--tw-enter-translate-y: 0% }}.modal__container--full[data-exiting=true]{--tw-exit-scale:1}.modal__dialog{background-color:var(--overlay);--tw-shadow:var(--overlay-shadow);width:100%;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;border-radius:min(32px,var(--radius-3xl));padding:calc(var(--spacing) * 6);pointer-events:auto;outline-style:none;flex-direction:column;display:flex;position:relative}.modal__dialog[data-placement=auto]{margin-top:auto}@media(min-width:40rem){.modal__dialog[data-placement=auto]{margin-block:auto}}.modal__dialog[data-placement=center]{margin-block:auto}.modal__dialog[data-placement=bottom]{margin-top:auto}.modal__dialog[data-placement=top]{margin-top:0}.modal__dialog--scroll-inside{min-height:0;max-height:100%;overflow:clip}.modal__dialog--scroll-outside{flex-shrink:0;height:auto;min-height:0}.modal__dialog--xs{max-width:var(--container-xs)}.modal__dialog--sm{max-width:var(--container-sm)}.modal__dialog--md{max-width:var(--container-md)}.modal__dialog--lg{max-width:var(--container-lg)}.modal__dialog--cover{width:100%;height:100%;min-height:100%}.modal__dialog--full{--tw-shadow:0 0 #0000;width:100%;height:100%;min-height:100%;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);border-radius:0}.modal__header{gap:calc(var(--spacing) * 3);flex-direction:column;margin-bottom:0;display:flex}.modal__header>.modal__icon{margin-bottom:0}.modal__heading{vertical-align:middle;font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--foreground)}.modal__icon{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10);border-radius:calc(var(--radius) * 3);-webkit-user-select:none;user-select:none;flex-shrink:0;justify-content:center;align-items:center;display:flex}.modal__body{min-height:0;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:1.43;color:var(--muted);margin:-3px;flex:1;margin-block:0;padding:3px;line-height:1.43;overflow:visible}.modal__body--scroll-inside{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);overscroll-behavior:contain;-webkit-overflow-scrolling:touch;overflow-y:auto}.modal__body--scroll-outside{overflow-y:visible}.modal__footer{justify-content:flex-end;align-items:center;gap:calc(var(--spacing) * 2);flex-direction:row;margin-top:0;display:flex}.modal__close-trigger{top:calc(var(--spacing) * 4);right:calc(var(--spacing) * 4);position:absolute}.modal__header+.modal__body{margin-top:calc(var(--spacing) * 2)}.modal__header+.modal__footer,.modal__body+.modal__footer{margin-top:calc(var(--spacing) * 5)}.popover{transform-origin:var(--trigger-anchor-point);background-color:var(--overlay);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));border-radius:min(32px,var(--radius-3xl));box-shadow:var(--shadow-overlay);padding:0}.popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.9;transition-duration:.15s;transition-timing-function:ease}.popover[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.popover[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.popover[data-entering=true][data-placement=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.popover[data-entering=true][data-placement=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.popover[data-exiting=true],.popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.popover [data-slot=popover-overlay-arrow]{fill:var(--overlay)}.popover[data-placement=bottom] [data-slot=popover-overlay-arrow]{rotate:180deg}.popover[data-placement=left] [data-slot=popover-overlay-arrow]{rotate:-90deg}.popover[data-placement=right] [data-slot=popover-overlay-arrow]{rotate:90deg}.popover__dialog{padding:calc(var(--spacing) * 4);--tw-outline-style:none;outline-style:none}.popover__heading{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.popover__trigger{transition:color .15s var(--ease-smooth),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);display:inline-block}.popover__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.popover__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.popover__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.popover__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.popover__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.popover__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.popover__trigger{cursor:var(--cursor-interactive)}.popover__trigger:focus-visible:not(:focus),.popover__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.popover__trigger:disabled,.popover__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.tooltip{max-width:var(--container-xs);transform-origin:var(--trigger-anchor-point);background-color:var(--overlay);padding:calc(var(--spacing) * 2);font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));word-break:break-all;border-radius:min(32px,var(--radius-xl));box-shadow:var(--shadow-overlay)}.tooltip[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.9;transition-duration:.15s;transition-timing-function:ease}.tooltip[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.tooltip[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.tooltip[data-entering=true][data-placement=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.tooltip[data-entering=true][data-placement=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.tooltip[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.tooltip[data-exiting=true],.tooltip[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.tooltip [data-slot=overlay-arrow]{stroke:var(--border)}@supports (color:color-mix(in lab,red,red)){.tooltip [data-slot=overlay-arrow]{stroke:color-mix(in oklab,var(--border) 40%,transparent)}}.tooltip [data-slot=overlay-arrow]{fill:var(--overlay)}.tooltip[data-placement=bottom] [data-slot=overlay-arrow]{rotate:180deg}.tooltip[data-placement=left] [data-slot=overlay-arrow]{rotate:-90deg}.tooltip[data-placement=right] [data-slot=overlay-arrow]{rotate:90deg}.tooltip__trigger{transition:color .15s var(--ease-smooth),background-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);display:inline-block}.tooltip__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.tooltip__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.tooltip__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.tooltip__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.tooltip__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.tooltip__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.tooltip__trigger:focus-visible:not(:focus),.tooltip__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;outline-style:none}.combo-box{gap:var(--spacing);flex-direction:column;display:flex}:is(.combo-box[data-invalid=true],.combo-box[aria-invalid=true]) [data-slot=description]{display:none}.combo-box [data-slot=label]{width:fit-content}.combo-box [data-slot=input]{flex:1;min-width:0}.combo-box [data-slot=input]:has(+.combo-box__trigger){padding-inline-end:calc(var(--spacing) * 7)}.combo-box [data-slot=input]:focus,.combo-box [data-slot=input][data-focus]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-outline-style:none;--tw-ring-offset-width:0px;border-color:var(--field-border-focus);background-color:var(--field-focus);outline-style:none}.combo-box [data-slot=input]:disabled,.combo-box [data-slot=input][data-disabled],.combo-box [data-slot=input][aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.combo-box__input-group{isolation:isolate;align-items:center;display:inline-flex;position:relative}.combo-box__trigger{--tw-translate-y: -50% ;height:100%;translate:var(--tw-translate-x) var(--tw-translate-y);cursor:pointer;color:var(--field-placeholder,var(--muted));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.15s;-webkit-tap-highlight-color:transparent;--tw-border-style:none;--tw-outline-style:none;inset-inline-end:calc(var(--spacing) * 0);background-color:#0000;border-style:none;outline-style:none;flex-shrink:0;justify-content:center;align-items:center;padding-inline-end:calc(var(--spacing) * 2);transition-duration:.15s;display:flex;position:absolute;top:50%}@media(hover:hover){.combo-box__trigger:hover,.combo-box__trigger[data-hovered=true]{color:var(--field-foreground,var(--foreground))}}.combo-box__trigger:focus-visible:not(:focus),.combo-box__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;border-radius:.25rem;outline-style:none}.combo-box__trigger[data-pressed=true]{opacity:.7}.combo-box__trigger:disabled,.combo-box__trigger[data-disabled],.combo-box__trigger[aria-disabled=true]{cursor:not-allowed;opacity:.5}.combo-box__trigger [data-slot=combo-box-trigger-default-icon]{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4);transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.15s;transition-duration:.15s}.combo-box__trigger [data-slot=combo-box-trigger-default-icon]:is([data-reduce-motion=true],[data-reduce-motion=true] *),.combo-box__trigger [data-slot=combo-box-trigger-default-icon]:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.combo-box__trigger [data-slot=combo-box-trigger-default-icon]:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.combo-box__trigger [data-slot=combo-box-trigger-default-icon]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.combo-box__trigger [data-slot=combo-box-trigger-default-icon]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.combo-box__trigger [data-slot=combo-box-trigger-default-icon]:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.combo-box__trigger[data-open=true] [data-slot=combo-box-trigger-default-icon]{rotate:180deg}.combo-box__popover{min-width:var(--trigger-width);transform-origin:var(--trigger-anchor-point);scroll-padding-block:var(--spacing);scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);overscroll-behavior:contain;background-color:var(--overlay);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));border-radius:min(32px,var(--radius-3xl));box-shadow:var(--shadow-overlay);padding:0;overflow-y:auto}.combo-box__popover:focus-visible:not(:focus),.combo-box__popover[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.combo-box__popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.95;transition-duration:.15s;transition-timing-function:ease}.combo-box__popover[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.combo-box__popover[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.combo-box__popover[data-entering=true][data-placement=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.combo-box__popover[data-entering=true][data-placement=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.combo-box__popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.combo-box__popover[data-exiting=true],.combo-box__popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.combo-box__popover [data-slot=popover-overlay-arrow]{fill:var(--overlay)}.combo-box__popover[data-placement=bottom] [data-slot=popover-overlay-arrow]{rotate:180deg}.combo-box__popover[data-placement=left] [data-slot=popover-overlay-arrow]{rotate:-90deg}.combo-box__popover[data-placement=right] [data-slot=popover-overlay-arrow]{rotate:90deg}.combo-box__popover [data-slot=list-box]{padding:calc(var(--spacing) * 1.5);--tw-outline-style:none;outline-style:none}.combo-box__popover [data-slot=list-box-item]{padding-inline:calc(var(--spacing) * 2.5)}.combo-box__popover [data-slot=list-box-item] [data-slot=list-box-item-indicator--checkmark]{transition-property:none}.combo-box--full-width,.combo-box__input-group--full-width{width:100%}.select{gap:var(--spacing);flex-direction:column;display:flex}:is(.select[data-invalid=true],.select[aria-invalid=true]) [data-slot=description]{display:none}.select [data-slot=label]{width:fit-content}.select__trigger{isolation:isolate;min-height:calc(var(--spacing) * 9);border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);border-width:1px;outline-style:none;display:inline-flex;position:relative}.select__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.select__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.select__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.select__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.select__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.select__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.select__trigger{cursor:var(--cursor-interactive);border-width:var(--border-width-field);border-color:var(--field-border)}.select__trigger:has(.select__indicator){padding-inline-end:calc(var(--spacing) * 7)}@media(hover:hover){.select__trigger:hover,.select__trigger[data-hovered=true]{background-color:var(--field-hover);border-color:var(--field-border-hover)}}.select__trigger:focus-visible:not(:focus),.select__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;border-color:var(--field-border-focus);background-color:var(--field-focus);outline-style:none}.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}:is(.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger):focus,:is(.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger):focus-visible,:is(.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger)[data-focused=true],:is(.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger)[data-focus-visible=true],:is(.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger):focus-within,:is(.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger)[data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.select[data-invalid=true] .select__trigger,.select[aria-invalid=true] .select__trigger{background-color:var(--field-focus)}.select__trigger:disabled,.select__trigger[data-disabled=true],.select__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.select--secondary .select__trigger{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--select-trigger-bg);--select-trigger-bg:var(--default);--select-trigger-bg-hover:var(--default-hover);--select-trigger-bg-focus:var(--default)}@media(hover:hover){.select--secondary .select__trigger:hover,.select--secondary .select__trigger[data-hovered=true]{background-color:var(--select-trigger-bg-hover)}}.select--secondary .select__trigger:focus-visible:not(:focus),.select--secondary .select__trigger[data-focus-visible=true],.select[data-invalid=true] :is(.select--secondary .select__trigger),.select[aria-invalid=true] :is(.select--secondary .select__trigger){background-color:var(--select-trigger-bg-focus)}.select__value{text-align:start;font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));overflow-wrap:break-word;color:currentColor;flex:1}@media(min-width:40rem){.select__value{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.select__value[data-placeholder=true]{color:var(--field-placeholder,var(--muted))}.select__value [data-slot=list-box-item-indicator]{display:none}.select__indicator{color:var(--field-placeholder,var(--muted));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.15s;flex-shrink:0;justify-content:center;align-items:center;margin-block:auto;transition-duration:.15s;display:flex;position:absolute;inset-block:0;inset-inline-end:calc(var(--spacing) * 2)}.select__indicator[data-open=true]{rotate:180deg}.select__indicator[data-slot=select-default-indicator]{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.select__popover{min-width:var(--trigger-width);transform-origin:var(--trigger-anchor-point);scroll-padding-block:var(--spacing);scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);overscroll-behavior:contain;background-color:var(--overlay);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));border-radius:min(32px,var(--radius-3xl));box-shadow:var(--shadow-overlay);padding:0;overflow-y:auto}.select__popover:focus-visible:not(:focus),.select__popover[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.select__popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.15s;--tw-ease:ease;--tw-enter-opacity:0;--tw-enter-scale:.95;transition-duration:.15s;transition-timing-function:ease}.select__popover[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.select__popover[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.select__popover[data-entering=true][data-placement=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.select__popover[data-entering=true][data-placement=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.select__popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:ease;--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:ease}.select__popover[data-exiting=true],.select__popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.select__popover [data-slot=popover-overlay-arrow]{fill:var(--overlay)}.select__popover[data-placement=bottom] [data-slot=popover-overlay-arrow]{rotate:180deg}.select__popover[data-placement=left] [data-slot=popover-overlay-arrow]{rotate:-90deg}.select__popover[data-placement=right] [data-slot=popover-overlay-arrow]{rotate:90deg}.select__popover [data-slot=list-box]{padding:calc(var(--spacing) * 1.5);--tw-outline-style:none;outline-style:none}.select__popover [data-slot=list-box-item]{padding-inline:calc(var(--spacing) * 2.5)}.select__popover [data-slot=list-box]:not([aria-multiselectable=true]) [data-slot=list-box-item-indicator],.select__popover [data-slot=list-box]:not([aria-multiselectable=true]) [data-slot=list-box-item-indicator] [data-slot=list-box-item-indicator--checkmark]{transition-property:none}.select--full-width,.select__trigger--full-width{width:100%}.autocomplete{gap:var(--spacing);flex-direction:column;display:flex}.autocomplete__trigger{isolation:isolate;min-height:calc(var(--spacing) * 9);border-radius:var(--field-radius,calc(var(--radius) * 1.5));border-style:var(--tw-border-style);background-color:var(--field-background,var(--default));padding-inline:calc(var(--spacing) * 3);padding-block:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--field-foreground,var(--foreground));--tw-shadow:var(--field-shadow);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-outline-style:none;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;transition:background-color .15s var(--ease-smooth),border-color .15s var(--ease-smooth),box-shadow .15s var(--ease-out);border-width:1px;outline-style:none;display:inline-flex;position:relative}.autocomplete__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *),.autocomplete__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.autocomplete__trigger:is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.autocomplete__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.autocomplete__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.autocomplete__trigger:not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.autocomplete__trigger{cursor:var(--cursor-interactive);border-width:var(--border-width-field);border-color:var(--field-border)}.autocomplete__trigger:has(.autocomplete__indicator){padding-inline-end:calc(var(--spacing) * 7)}@media(hover:hover){.autocomplete__trigger:hover:not(:has(.autocomplete__clear-button:hover)),.autocomplete__trigger[data-hovered=true]:not(:has(.autocomplete__clear-button:hover)){background-color:var(--field-hover);border-color:var(--field-border-hover)}}.autocomplete__trigger:focus-visible:not(:focus),.autocomplete__trigger[data-focus-visible=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--focus);--tw-ring-offset-width:var(--ring-offset-width);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-color:var(--background);--tw-outline-style:none;border-color:var(--field-border-focus);background-color:var(--field-focus);outline-style:none}.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger{outline-style:var(--tw-outline-style);outline-width:1px;outline-color:var(--danger);--tw-outline-style:solid;--tw-ring-offset-width:3px;outline-style:solid}:is(.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger):focus,:is(.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger):focus-visible,:is(.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger)[data-focused=true],:is(.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger)[data-focus-visible=true],:is(.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger):focus-within,:is(.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger)[data-focus-within=true]{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);--tw-ring-color:var(--danger);--tw-ring-offset-shadow:var(--tw-ring-inset,) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-offset-width:0px}.autocomplete[data-invalid=true] .autocomplete__trigger,.autocomplete[aria-invalid=true] .autocomplete__trigger{background-color:var(--field-focus)}.autocomplete__trigger:disabled,.autocomplete__trigger[data-disabled=true],.autocomplete__trigger[aria-disabled=true]{opacity:var(--disabled-opacity);cursor:var(--cursor-disabled);pointer-events:none}.autocomplete--secondary .autocomplete__trigger{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow);background-color:var(--autocomplete-trigger-bg);--autocomplete-trigger-bg:var(--default);--autocomplete-trigger-bg-hover:var(--default-hover);--autocomplete-trigger-bg-focus:var(--default)}@media(hover:hover){.autocomplete--secondary .autocomplete__trigger:hover:not(:has(.autocomplete__clear-button:hover)),.autocomplete--secondary .autocomplete__trigger[data-hovered=true]:not(:has(.autocomplete__clear-button:hover)){background-color:var(--autocomplete-trigger-bg-hover)}}.autocomplete--secondary .autocomplete__trigger:focus-visible:not(:focus),.autocomplete--secondary .autocomplete__trigger[data-focus-visible=true],.autocomplete[data-invalid=true] :is(.autocomplete--secondary .autocomplete__trigger),.autocomplete[aria-invalid=true] :is(.autocomplete--secondary .autocomplete__trigger){background-color:var(--autocomplete-trigger-bg-focus)}.autocomplete__value{text-align:start;font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));overflow-wrap:break-word;color:currentColor;flex:1}@media(min-width:40rem){.autocomplete__value{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.autocomplete__value[data-placeholder=true]{color:var(--field-placeholder,var(--muted))}.autocomplete__value [data-slot=list-box-item-indicator]{display:none}.autocomplete__indicator{color:var(--field-placeholder,var(--muted));transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));--tw-duration:.15s;cursor:var(--cursor-interactive);flex-shrink:0;justify-content:center;align-items:center;margin-block:auto;transition-duration:.15s;display:flex;position:absolute;inset-block:0;inset-inline-end:calc(var(--spacing) * 2)}.autocomplete__indicator[data-open=true]{rotate:180deg}.autocomplete__indicator[data-slot=autocomplete-default-indicator]{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.autocomplete__popover{width:var(--trigger-width);max-width:var(--trigger-width);transform-origin:var(--trigger-anchor-point);scroll-padding-block:var(--spacing);overscroll-behavior:contain;background-color:var(--overlay);padding:0;padding-top:calc(var(--spacing) * 2);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));border-radius:min(32px,var(--radius-3xl));box-shadow:var(--shadow-overlay);overflow:hidden}.autocomplete__popover:focus-visible:not(:focus),.autocomplete__popover[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.autocomplete__popover[data-entering=true]{animation:enter var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.25s;--tw-ease:cubic-bezier(.32, .72, 0, 1);--tw-enter-opacity:0;--tw-enter-scale:.95;transition-duration:.25s;transition-timing-function:cubic-bezier(.32,.72,0,1)}.autocomplete__popover[data-entering=true][data-placement=top]{--tw-enter-translate-y:calc(1*var(--spacing))}.autocomplete__popover[data-entering=true][data-placement=bottom]{--tw-enter-translate-y:calc(1*var(--spacing)*-1)}.autocomplete__popover[data-entering=true][data-placement=left]{--tw-enter-translate-x:calc(1*var(--spacing))}.autocomplete__popover[data-entering=true][data-placement=right]{--tw-enter-translate-x:calc(1*var(--spacing)*-1)}.autocomplete__popover[data-exiting=true]{animation:exit var(--tw-animation-duration,var(--tw-duration,.15s))var(--tw-ease,ease)var(--tw-animation-delay,0s)var(--tw-animation-iteration-count,1)var(--tw-animation-direction,normal)var(--tw-animation-fill-mode,none);--tw-duration:.1s;--tw-ease:cubic-bezier(.25, .46, .45, .94);--tw-exit-scale:.95;--tw-exit-opacity:0;transition-duration:.1s;transition-timing-function:cubic-bezier(.25,.46,.45,.94)}.autocomplete__popover[data-exiting=true],.autocomplete__popover[data-entering=true]{transition-property:opacity,transform;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration));will-change:opacity,transform}.autocomplete__popover [data-slot=popover-overlay-arrow]{fill:var(--overlay)}.autocomplete__popover[data-placement=bottom] [data-slot=popover-overlay-arrow]{rotate:180deg}.autocomplete__popover[data-placement=left] [data-slot=popover-overlay-arrow]{rotate:-90deg}.autocomplete__popover[data-placement=right] [data-slot=popover-overlay-arrow]{rotate:90deg}.autocomplete__popover [data-slot=list-box]{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);max-height:320px;padding:calc(var(--spacing) * 1.5);--tw-outline-style:none;outline-style:none;overflow-y:auto}.autocomplete__popover [data-slot=list-box-item]{padding-inline:calc(var(--spacing) * 2.5)}.autocomplete__popover [data-slot=list-box]:not([aria-multiselectable=true]) [data-slot=list-box-item-indicator],.autocomplete__popover [data-slot=list-box]:not([aria-multiselectable=true]) [data-slot=list-box-item-indicator] [data-slot=list-box-item-indicator--checkmark]{transition-property:none}.autocomplete__popover [data-slot=search-field]{padding-inline:calc(var(--spacing) * 3);padding-block:var(--spacing);--tw-outline-style:none;outline-style:none}.autocomplete__popover [data-slot=empty-state]{text-align:center;font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--overlay-foreground)}@supports (color:color-mix(in lab,red,red)){.autocomplete__popover [data-slot=empty-state]{color:color-mix(in oklab,var(--overlay-foreground) 60%,transparent)}}.autocomplete__popover-dialog,.autocomplete__popover-dialog:focus,.autocomplete__popover-dialog:focus-visible,.autocomplete__popover-dialog[data-focus-visible=true]{--tw-outline-style:none;outline-style:none}.autocomplete--full-width,.autocomplete__trigger--full-width{width:100%}.autocomplete__clear-button{isolation:isolate;height:calc(var(--spacing) * 6);width:calc(var(--spacing) * 6);transform-origin:50%;border-radius:calc(var(--radius) * 1.5);padding:var(--spacing);color:var(--muted);-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;width:calc(var(--spacing) * 5);height:calc(var(--spacing) * 5);cursor:var(--cursor-interactive);transform:translateZ(0) var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,);background-color:#0000;flex-shrink:0;justify-content:center;align-self:center;align-items:center;margin-inline-end:0;display:inline-flex;position:relative}.autocomplete__clear-button:not([data-empty=true]){transition:opacity .15s var(--ease-smooth)}.autocomplete__clear-button:not([data-empty=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *),.autocomplete__clear-button:not([data-empty=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):before,.autocomplete__clear-button:not([data-empty=true]):is([data-reduce-motion=true],[data-reduce-motion=true] *):after{transition-property:none}@media(prefers-reduced-motion:reduce){.autocomplete__clear-button:not([data-empty=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)),.autocomplete__clear-button:not([data-empty=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):before,.autocomplete__clear-button:not([data-empty=true]):not(:is([data-reduce-motion=true],[data-reduce-motion=true] *)):after{transition-property:none}}.autocomplete__clear-button[data-empty=true]{pointer-events:none;opacity:0}.autocomplete__clear-button [data-slot=autocomplete-clear-button-icon]{width:calc(var(--spacing) * 3.5);height:calc(var(--spacing) * 3.5)}@media(hover:hover){.autocomplete__clear-button:hover,.autocomplete__clear-button[data-hovered=true]{background-color:var(--default-hover)}}.autocomplete__clear-button:active,.autocomplete__clear-button[data-pressed=true]{transform:scale(.93)}.kbd{height:calc(var(--spacing) * 6);align-items:center;display:inline-flex}:where(.kbd>:not(:last-child)){--tw-space-x-reverse:0;margin-inline-start:calc(calc(var(--spacing) * .5) * var(--tw-space-x-reverse));margin-inline-end:calc(calc(var(--spacing) * .5) * calc(1 - var(--tw-space-x-reverse)))}.kbd{border-radius:calc(var(--radius) * 1);background-color:var(--default);padding-inline:calc(var(--spacing) * 2);text-align:center;font-family:var(--font-sans);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);white-space:nowrap;color:var(--muted)}:where(.kbd:where(:dir(rtl),[dir=rtl],[dir=rtl] *)>:not(:last-child)){--tw-space-x-reverse:1}.kbd{word-spacing:-.25rem}.kbd__abbr{justify-content:center;align-items:center;width:100%;height:100%;text-decoration:none;display:flex}.kbd__content{justify-content:center;align-items:center;display:flex}.kbd--light{background-color:#0000}.typography,.typography-prose{color:var(--foreground)}.typography-prose h1{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography-prose h2{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography-prose h3{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography-prose h4{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography-prose h5{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography-prose h6{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography-prose p{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-leading:calc(var(--spacing) * 7);line-height:calc(var(--spacing) * 7)}.typography-prose code{border-radius:calc(var(--radius) * .75);background-color:var(--default);padding-inline:calc(var(--spacing) * 1.5);padding-block:calc(var(--spacing) * .5);font-family:var(--font-mono);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--foreground)}.typography-prose a{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium);color:var(--link);text-underline-offset:4px;text-decoration-line:underline}.typography-prose blockquote{margin-top:calc(var(--spacing) * 4);border-left-style:var(--tw-border-style);border-left-width:4px;border-color:var(--border);padding-left:calc(var(--spacing) * 4);color:var(--muted);font-style:italic}.typography-prose ul{margin-block:calc(var(--spacing) * 4);list-style-type:disc}:where(.typography-prose ul>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}.typography-prose ul{padding-left:calc(var(--spacing) * 6)}.typography-prose ol{margin-block:calc(var(--spacing) * 4);list-style-type:decimal}:where(.typography-prose ol>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}.typography-prose ol{padding-left:calc(var(--spacing) * 6)}.typography-prose li{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-leading:calc(var(--spacing) * 7);line-height:calc(var(--spacing) * 7)}.typography-prose hr{margin-block:calc(var(--spacing) * 8);border-color:var(--separator)}.typography-prose pre{margin-block:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * 1.5);background-color:var(--default);padding:calc(var(--spacing) * 4);font-family:var(--font-mono);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed);overflow-x:auto}.typography-prose strong{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);color:var(--foreground)}.typography-prose em{font-style:italic}.typography-prose img{margin-block:calc(var(--spacing) * 4);border-radius:calc(var(--radius) * 1.5)}.typography--h1{font-size:var(--text-4xl);line-height:var(--tw-leading,var(--text-4xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography--h2{font-size:var(--text-3xl);line-height:var(--tw-leading,var(--text-3xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography--h3{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography--h4{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography--h5{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography--h6{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold);--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.typography--body{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height));--tw-leading:calc(var(--spacing) * 7);line-height:calc(var(--spacing) * 7)}.typography--body-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6)}.typography--body-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height));--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.typography--code{border-radius:calc(var(--radius) * .75);background-color:var(--default);padding-inline:calc(var(--spacing) * 1.5);padding-block:calc(var(--spacing) * .5);font-family:var(--font-mono);font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height));color:var(--foreground)}.typography--align-start{text-align:left}.typography--align-start:where(:dir(rtl),[dir=rtl],[dir=rtl] *){text-align:right}.typography--align-center{text-align:center}.typography--align-end{text-align:right}.typography--align-end:where(:dir(rtl),[dir=rtl],[dir=rtl] *){text-align:left}.typography--align-justify{text-align:justify}.typography--color-default{color:var(--foreground)}.typography--color-muted{color:var(--muted)}.typography--truncate{text-overflow:ellipsis;white-space:nowrap;display:block;overflow:hidden}.typography--weight-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.typography--weight-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.typography--weight-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.typography--weight-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.scroll-shadow{--scroll-shadow-size:40px;--scroll-shadow-scrollbar-size:10px;position:relative}.scroll-shadow--vertical{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);overflow-y:auto}.scroll-shadow--horizontal{scrollbar-width:var(--scrollbar-width);scrollbar-color:var(--scrollbar-color);scrollbar-gutter:var(--scrollbar-gutter);overflow-x:auto}.scroll-shadow--fade.scroll-shadow--vertical:where([data-top-scroll=true],[data-bottom-scroll=true],[data-top-bottom-scroll=true]){mask-image:linear-gradient(var(--scroll-linear-gradient)),linear-gradient(#000,#000);mask-position:0 0,100% 0;mask-repeat:no-repeat;mask-size:calc(100% - var(--scroll-shadow-scrollbar-size)) 100%,var(--scroll-shadow-scrollbar-size) 100%;-webkit-mask-image:linear-gradient(var(--scroll-linear-gradient)),linear-gradient(#000,#000);-webkit-mask-position:0 0,100% 0;-webkit-mask-repeat:no-repeat;-webkit-mask-size:calc(100% - var(--scroll-shadow-scrollbar-size)) 100%,var(--scroll-shadow-scrollbar-size) 100%}.scroll-shadow--fade.scroll-shadow--vertical[data-top-scroll=true]{--scroll-linear-gradient:0deg, #000 calc(100% - var(--scroll-shadow-size)), transparent}.scroll-shadow--fade.scroll-shadow--vertical[data-bottom-scroll=true]{--scroll-linear-gradient:180deg, #000 calc(100% - var(--scroll-shadow-size)), transparent}.scroll-shadow--fade.scroll-shadow--vertical[data-top-bottom-scroll=true]{--scroll-linear-gradient:#000, #000, transparent 0, #000 var(--scroll-shadow-size), #000 calc(100% - var(--scroll-shadow-size)), transparent}.scroll-shadow--fade.scroll-shadow--horizontal:where([data-left-scroll=true],[data-right-scroll=true],[data-left-right-scroll=true]){mask-image:linear-gradient(var(--scroll-linear-gradient)),linear-gradient(#000,#000);mask-position:0 0,0 100%;mask-repeat:no-repeat;mask-size:100% calc(100% - var(--scroll-shadow-scrollbar-size)),100% var(--scroll-shadow-scrollbar-size);-webkit-mask-image:linear-gradient(var(--scroll-linear-gradient)),linear-gradient(#000,#000);-webkit-mask-position:0 0,0 100%;-webkit-mask-repeat:no-repeat;-webkit-mask-size:100% calc(100% - var(--scroll-shadow-scrollbar-size)),100% var(--scroll-shadow-scrollbar-size)}.scroll-shadow--fade.scroll-shadow--horizontal[data-left-scroll=true]{--scroll-linear-gradient:270deg, #000 calc(100% - var(--scroll-shadow-size)), transparent}.scroll-shadow--fade.scroll-shadow--horizontal[data-right-scroll=true]{--scroll-linear-gradient:90deg, #000 calc(100% - var(--scroll-shadow-size)), transparent}.scroll-shadow--fade.scroll-shadow--horizontal[data-left-right-scroll=true]{--scroll-linear-gradient:to right, #000, #000, transparent 0, #000 var(--scroll-shadow-size), #000 calc(100% - var(--scroll-shadow-size)), transparent}.scroll-shadow--hide-scrollbar{scrollbar-color:auto;scrollbar-gutter:auto;-ms-overflow-style:none;scrollbar-width:none;--scroll-shadow-scrollbar-size:0px}}@layer utilities{.pointer-events-none{pointer-events:none}.collapse{visibility:collapse}.visible{visibility:visible}.absolute{position:absolute}.relative{position:relative}.top-0{top:0}.top-4{top:calc(var(--spacing) * 4)}.top-full{top:100%}.-right-3{right:calc(var(--spacing) * -3)}.right-0{right:0}.z-10{z-index:10}.z-20{z-index:20}.z-30{z-index:30}.container{width:100%}@media(min-width:40rem){.container{max-width:40rem}}@media(min-width:48rem){.container{max-width:48rem}}@media(min-width:64rem){.container{max-width:64rem}}@media(min-width:80rem){.container{max-width:80rem}}@media(min-width:96rem){.container{max-width:96rem}}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mx-3{margin-inline:calc(var(--spacing) * 3)}.mx-auto{margin-inline:auto}.mt-1{margin-top:var(--spacing)}.mt-1\.5{margin-top:calc(var(--spacing) * 1.5)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-auto{margin-top:auto}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.block{display:block}.flex{display:flex}.grid{display:grid}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-12{height:calc(var(--spacing) * 12)}.h-full{height:100%}.max-h-72{max-height:calc(var(--spacing) * 72)}.min-h-0{min-height:0}.min-h-full{min-height:100%}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-7{width:calc(var(--spacing) * 7)}.w-11{width:calc(var(--spacing) * 11)}.w-12{width:calc(var(--spacing) * 12)}.w-28{width:calc(var(--spacing) * 28)}.w-72{width:calc(var(--spacing) * 72)}.w-fit{width:fit-content}.w-full{width:100%}.max-w-\[1800px\]{max-width:1800px}.max-w-md{max-width:var(--container-md)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:0}.min-w-\[180px\]{min-width:180px}.flex-1{flex:1}.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.translate-x-0\.5{--tw-translate-x:calc(var(--spacing) * .5);translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-5{--tw-translate-x:calc(var(--spacing) * 5);translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-180{rotate:180deg}.transform{transform:var(--tw-rotate-x,) var(--tw-rotate-y,) var(--tw-rotate-z,) var(--tw-skew-x,) var(--tw-skew-y,)}.cursor-col-resize{cursor:col-resize}.cursor-pointer{cursor:pointer}.touch-none{touch-action:none}.flex-col{flex-direction:column}.flex-row-reverse{flex-direction:row-reverse}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-2\.5{gap:calc(var(--spacing) * 2.5)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-4{gap:calc(var(--spacing) * 4)}.gap-5{gap:calc(var(--spacing) * 5)}.gap-6{gap:calc(var(--spacing) * 6)}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-y-2{row-gap:calc(var(--spacing) * 2)}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}:where(.divide-\[var\(--otari-line\)\]>:not(:last-child)){border-color:var(--otari-line)}.self-start{align-self:flex-start}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:calc(var(--radius) * 1)}.rounded-md{border-radius:calc(var(--radius) * .75)}.rounded-xl{border-radius:calc(var(--radius) * 1.5)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-\[\#c2843a\]{border-color:#c2843a}.border-\[var\(--otari-brand\)\]{border-color:var(--otari-brand)}.border-\[var\(--otari-line\)\]{border-color:var(--otari-line)}.border-amber-200{border-color:var(--color-amber-200)}.border-red-200{border-color:var(--color-red-200)}.bg-\[var\(--otari-bg\)\]{background-color:var(--otari-bg)}.bg-\[var\(--otari-brand\)\]{background-color:var(--otari-brand)}.bg-\[var\(--otari-brand-tint\)\]{background-color:var(--otari-brand-tint)}.bg-\[var\(--otari-line\)\]{background-color:var(--otari-line)}.bg-\[var\(--otari-surface\)\]{background-color:var(--otari-surface)}.bg-amber-50{background-color:var(--color-amber-50)}.bg-red-50{background-color:var(--color-red-50)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.p-1{padding:var(--spacing)}.p-3{padding:calc(var(--spacing) * 3)}.p-5{padding:calc(var(--spacing) * 5)}.p-6{padding:calc(var(--spacing) * 6)}.p-7{padding:calc(var(--spacing) * 7)}.px-0{padding-inline:0}.px-1{padding-inline:var(--spacing)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-6{padding-block:calc(var(--spacing) * 6)}.py-10{padding-block:calc(var(--spacing) * 10)}.pt-1{padding-top:var(--spacing)}.pt-4{padding-top:calc(var(--spacing) * 4)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-middle{vertical-align:middle}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.leading-none{--tw-leading:1;line-height:1}.leading-relaxed{--tw-leading:var(--leading-relaxed);line-height:var(--leading-relaxed)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wide{--tw-tracking:var(--tracking-wide);letter-spacing:var(--tracking-wide)}.break-words{overflow-wrap:break-word}.break-all{word-break:break-all}.whitespace-normal{white-space:normal}.whitespace-nowrap{white-space:nowrap}.text-\[\#b45309\]{color:#b45309}.text-\[var\(--otari-brand\)\]{color:var(--otari-brand)}.text-\[var\(--otari-brand-dark\)\]{color:var(--otari-brand-dark)}.text-\[var\(--otari-ink\)\]{color:var(--otari-ink)}.text-\[var\(--otari-muted\)\]{color:var(--otari-muted)}.text-amber-700{color:var(--color-amber-700)}.text-amber-800{color:var(--color-amber-800)}.text-green-700{color:var(--color-green-700)}.text-red-700{color:var(--color-red-700)}.normal-case{text-transform:none}.uppercase{text-transform:uppercase}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal,) var(--tw-slashed-zero,) var(--tw-numeric-figure,) var(--tw-numeric-spacing,) var(--tw-numeric-fraction,)}.underline{text-decoration-line:underline}.underline-offset-2{text-underline-offset:2px}.opacity-0{opacity:0}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-150{--tw-duration:.15s;transition-duration:.15s}.select-none{-webkit-user-select:none;user-select:none}.running{animation-play-state:running}.group-focus-within\:opacity-100:is(:where(.group):focus-within *){opacity:1}@media(hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}.last\:border-b-0:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}@media(hover:hover){.hover\:border-\[var\(--otari-brand\)\]:hover{border-color:var(--otari-brand)}.hover\:bg-\[var\(--otari-bg\)\]:hover{background-color:var(--otari-bg)}.hover\:bg-\[var\(--otari-brand\)\]:hover{background-color:var(--otari-brand)}.hover\:text-\[var\(--otari-brand\)\]:hover{color:var(--otari-brand)}.hover\:text-\[var\(--otari-brand-dark\)\]:hover{color:var(--otari-brand-dark)}.hover\:text-\[var\(--otari-ink\)\]:hover{color:var(--otari-ink)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:border-\[var\(--otari-brand\)\]:focus{border-color:var(--otari-brand)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:bg-\[var\(--otari-brand\)\]:focus-visible{background-color:var(--otari-brand)}.focus-visible\:outline-2:focus-visible{outline-style:var(--tw-outline-style);outline-width:2px}.focus-visible\:-outline-offset-2:focus-visible{outline-offset:-2px}.focus-visible\:outline-\[var\(--otari-brand\)\]:focus-visible{outline-color:var(--otari-brand)}.disabled\:opacity-50:disabled{opacity:.5}@media(min-width:40rem){.sm\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.sm\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media(min-width:64rem){.lg\:sticky{position:sticky}.lg\:top-4{top:calc(var(--spacing) * 4)}.lg\:grid-cols-\[minmax\(0\,1fr\)_360px\]{grid-template-columns:minmax(0,1fr) 360px}.lg\:items-start{align-items:flex-start}}}@property --tw-animation-delay{syntax:"*";inherits:false;initial-value:0s}@property --tw-animation-direction{syntax:"*";inherits:false;initial-value:normal}@property --tw-animation-duration{syntax:"*";inherits:false}@property --tw-animation-fill-mode{syntax:"*";inherits:false;initial-value:none}@property --tw-animation-iteration-count{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-enter-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-enter-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-blur{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-opacity{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-rotate{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-scale{syntax:"*";inherits:false;initial-value:1}@property --tw-exit-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-exit-translate-y{syntax:"*";inherits:false;initial-value:0}:root{--otari-brand:#4e8295;--otari-brand-dark:#3c6678;--otari-brand-tint:#eaf1f3;--otari-ink:#14242c;--otari-muted:#5b6b73;--otari-line:#dbe5e8;--otari-surface:#fff;--otari-bg:#f6f9fa}html,body,#root{height:100%}body{background-color:var(--otari-bg);color:var(--otari-ink);margin:0;font-family:ui-sans-serif,system-ui,-apple-system,Segoe UI,Roboto,sans-serif}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@property --tw-ease{syntax:"*";inherits:false}@property --tw-scale-x{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-y{syntax:"*";inherits:false;initial-value:1}@property --tw-scale-z{syntax:"*";inherits:false;initial-value:1}@property --tw-border-spacing-x{syntax:"";inherits:false;initial-value:0}@property --tw-border-spacing-y{syntax:"";inherits:false;initial-value:0}@property --tw-gradient-position{syntax:"*";inherits:false}@property --tw-gradient-from{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-via{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-to{syntax:"";inherits:false;initial-value:#0000}@property --tw-gradient-stops{syntax:"*";inherits:false}@property --tw-gradient-via-stops{syntax:"*";inherits:false}@property --tw-gradient-from-position{syntax:"";inherits:false;initial-value:0%}@property --tw-gradient-via-position{syntax:"";inherits:false;initial-value:50%}@property --tw-gradient-to-position{syntax:"";inherits:false;initial-value:100%}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}@property --tw-space-x-reverse{syntax:"*";inherits:false;initial-value:0}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse{50%{opacity:.5}}@keyframes enter{0%{opacity:var(--tw-enter-opacity,1);transform:translate3d(var(--tw-enter-translate-x,0),var(--tw-enter-translate-y,0),0)scale3d(var(--tw-enter-scale,1),var(--tw-enter-scale,1),var(--tw-enter-scale,1))rotate(var(--tw-enter-rotate,0));filter:blur(var(--tw-enter-blur,0))}}@keyframes exit{to{opacity:var(--tw-exit-opacity,1);transform:translate3d(var(--tw-exit-translate-x,0),var(--tw-exit-translate-y,0),0)scale3d(var(--tw-exit-scale,1),var(--tw-exit-scale,1),var(--tw-exit-scale,1))rotate(var(--tw-exit-rotate,0));filter:blur(var(--tw-exit-blur,0))}}@keyframes caret-blink{0%,70%,to{opacity:1}20%,50%{opacity:0}}@keyframes skeleton{to{transform:translate(200%)}} diff --git a/src/gateway/static/dashboard/assets/index-BLYI-Riq.js b/src/gateway/static/dashboard/assets/index-BLYI-Riq.js new file mode 100644 index 00000000..3fb97bb1 --- /dev/null +++ b/src/gateway/static/dashboard/assets/index-BLYI-Riq.js @@ -0,0 +1,79 @@ +var tE=Object.defineProperty;var Ug=n=>{throw TypeError(n)};var nE=(n,t,i)=>t in n?tE(n,t,{enumerable:!0,configurable:!0,writable:!0,value:i}):n[t]=i;var Hg=(n,t,i)=>nE(n,typeof t!="symbol"?t+"":t,i),bh=(n,t,i)=>t.has(n)||Ug("Cannot "+i);var j=(n,t,i)=>(bh(n,t,"read from private field"),i?i.call(n):t.get(n)),ge=(n,t,i)=>t.has(n)?Ug("Cannot add the same private member more than once"):t instanceof WeakSet?t.add(n):t.set(n,i),oe=(n,t,i,r)=>(bh(n,t,"write to private field"),r?r.call(n,i):t.set(n,i),i),De=(n,t,i)=>(bh(n,t,"access private method"),i);var Io=(n,t,i,r)=>({set _(s){oe(n,t,s,i)},get _(){return j(n,t,r)}});(function(){const t=document.createElement("link").relList;if(t&&t.supports&&t.supports("modulepreload"))return;for(const s of document.querySelectorAll('link[rel="modulepreload"]'))r(s);new MutationObserver(s=>{for(const o of s)if(o.type==="childList")for(const f of o.addedNodes)f.tagName==="LINK"&&f.rel==="modulepreload"&&r(f)}).observe(document,{childList:!0,subtree:!0});function i(s){const o={};return s.integrity&&(o.integrity=s.integrity),s.referrerPolicy&&(o.referrerPolicy=s.referrerPolicy),s.crossOrigin==="use-credentials"?o.credentials="include":s.crossOrigin==="anonymous"?o.credentials="omit":o.credentials="same-origin",o}function r(s){if(s.ep)return;s.ep=!0;const o=i(s);fetch(s.href,o)}})();function Jx(n){return n&&n.__esModule&&Object.prototype.hasOwnProperty.call(n,"default")?n.default:n}var yh={exports:{}},Bu={};/** + * @license React + * react-jsx-runtime.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Vg;function lE(){if(Vg)return Bu;Vg=1;var n=Symbol.for("react.transitional.element"),t=Symbol.for("react.fragment");function i(r,s,o){var f=null;if(o!==void 0&&(f=""+o),s.key!==void 0&&(f=""+s.key),"key"in s){o={};for(var h in s)h!=="key"&&(o[h]=s[h])}else o=s;return s=o.ref,{$$typeof:n,type:r,key:f,ref:s!==void 0?s:null,props:o}}return Bu.Fragment=t,Bu.jsx=i,Bu.jsxs=i,Bu}var qg;function iE(){return qg||(qg=1,yh.exports=lE()),yh.exports}var y=iE(),vh={exports:{}},Te={};/** + * @license React + * react.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Ig;function aE(){if(Ig)return Te;Ig=1;var n=Symbol.for("react.transitional.element"),t=Symbol.for("react.portal"),i=Symbol.for("react.fragment"),r=Symbol.for("react.strict_mode"),s=Symbol.for("react.profiler"),o=Symbol.for("react.consumer"),f=Symbol.for("react.context"),h=Symbol.for("react.forward_ref"),m=Symbol.for("react.suspense"),p=Symbol.for("react.memo"),g=Symbol.for("react.lazy"),v=Symbol.for("react.activity"),$=Symbol.iterator;function S(A){return A===null||typeof A!="object"?null:(A=$&&A[$]||A["@@iterator"],typeof A=="function"?A:null)}var E={isMounted:function(){return!1},enqueueForceUpdate:function(){},enqueueReplaceState:function(){},enqueueSetState:function(){}},w=Object.assign,T={};function M(A,H,W){this.props=A,this.context=H,this.refs=T,this.updater=W||E}M.prototype.isReactComponent={},M.prototype.setState=function(A,H){if(typeof A!="object"&&typeof A!="function"&&A!=null)throw Error("takes an object of state variables to update or a function which returns an object of state variables.");this.updater.enqueueSetState(this,A,H,"setState")},M.prototype.forceUpdate=function(A){this.updater.enqueueForceUpdate(this,A,"forceUpdate")};function R(){}R.prototype=M.prototype;function P(A,H,W){this.props=A,this.context=H,this.refs=T,this.updater=W||E}var L=P.prototype=new R;L.constructor=P,w(L,M.prototype),L.isPureReactComponent=!0;var U=Array.isArray;function Y(){}var Z={H:null,A:null,T:null,S:null},B=Object.prototype.hasOwnProperty;function ie(A,H,W){var ae=W.ref;return{$$typeof:n,type:A,key:H,ref:ae!==void 0?ae:null,props:W}}function te(A,H){return ie(A.type,H,A.props)}function ue(A){return typeof A=="object"&&A!==null&&A.$$typeof===n}function fe(A){var H={"=":"=0",":":"=2"};return"$"+A.replace(/[=:]/g,function(W){return H[W]})}var de=/\/+/g;function D(A,H){return typeof A=="object"&&A!==null&&A.key!=null?fe(""+A.key):H.toString(36)}function F(A){switch(A.status){case"fulfilled":return A.value;case"rejected":throw A.reason;default:switch(typeof A.status=="string"?A.then(Y,Y):(A.status="pending",A.then(function(H){A.status==="pending"&&(A.status="fulfilled",A.value=H)},function(H){A.status==="pending"&&(A.status="rejected",A.reason=H)})),A.status){case"fulfilled":return A.value;case"rejected":throw A.reason}}throw A}function N(A,H,W,ae,se){var he=typeof A;(he==="undefined"||he==="boolean")&&(A=null);var ce=!1;if(A===null)ce=!0;else switch(he){case"bigint":case"string":case"number":ce=!0;break;case"object":switch(A.$$typeof){case n:case t:ce=!0;break;case g:return ce=A._init,N(ce(A._payload),H,W,ae,se)}}if(ce)return se=se(A),ce=ae===""?"."+D(A,0):ae,U(se)?(W="",ce!=null&&(W=ce.replace(de,"$&/")+"/"),N(se,H,W,"",function(re){return re})):se!=null&&(ue(se)&&(se=te(se,W+(se.key==null||A&&A.key===se.key?"":(""+se.key).replace(de,"$&/")+"/")+ce)),H.push(se)),1;ce=0;var Oe=ae===""?".":ae+":";if(U(A))for(var Re=0;Re>>1,V=N[Q];if(0>>1;Qs(W,z))aes(se,W)?(N[Q]=se,N[ae]=z,Q=ae):(N[Q]=W,N[H]=z,Q=H);else if(aes(se,z))N[Q]=se,N[ae]=z,Q=ae;else break e}}return _}function s(N,_){var z=N.sortIndex-_.sortIndex;return z!==0?z:N.id-_.id}if(n.unstable_now=void 0,typeof performance=="object"&&typeof performance.now=="function"){var o=performance;n.unstable_now=function(){return o.now()}}else{var f=Date,h=f.now();n.unstable_now=function(){return f.now()-h}}var m=[],p=[],g=1,v=null,$=3,S=!1,E=!1,w=!1,T=!1,M=typeof setTimeout=="function"?setTimeout:null,R=typeof clearTimeout=="function"?clearTimeout:null,P=typeof setImmediate<"u"?setImmediate:null;function L(N){for(var _=i(p);_!==null;){if(_.callback===null)r(p);else if(_.startTime<=N)r(p),_.sortIndex=_.expirationTime,t(m,_);else break;_=i(p)}}function U(N){if(w=!1,L(N),!E)if(i(m)!==null)E=!0,Y||(Y=!0,fe());else{var _=i(p);_!==null&&F(U,_.startTime-N)}}var Y=!1,Z=-1,B=5,ie=-1;function te(){return T?!0:!(n.unstable_now()-ieN&&te());){var Q=v.callback;if(typeof Q=="function"){v.callback=null,$=v.priorityLevel;var V=Q(v.expirationTime<=N);if(N=n.unstable_now(),typeof V=="function"){v.callback=V,L(N),_=!0;break t}v===i(m)&&r(m),L(N)}else r(m);v=i(m)}if(v!==null)_=!0;else{var A=i(p);A!==null&&F(U,A.startTime-N),_=!1}}break e}finally{v=null,$=z,S=!1}_=void 0}}finally{_?fe():Y=!1}}}var fe;if(typeof P=="function")fe=function(){P(ue)};else if(typeof MessageChannel<"u"){var de=new MessageChannel,D=de.port2;de.port1.onmessage=ue,fe=function(){D.postMessage(null)}}else fe=function(){M(ue,0)};function F(N,_){Z=M(function(){N(n.unstable_now())},_)}n.unstable_IdlePriority=5,n.unstable_ImmediatePriority=1,n.unstable_LowPriority=4,n.unstable_NormalPriority=3,n.unstable_Profiling=null,n.unstable_UserBlockingPriority=2,n.unstable_cancelCallback=function(N){N.callback=null},n.unstable_forceFrameRate=function(N){0>N||125Q?(N.sortIndex=z,t(p,N),i(m)===null&&N===i(p)&&(w?(R(Z),Z=-1):w=!0,F(U,z-Q))):(N.sortIndex=V,t(m,N),E||S||(E=!0,Y||(Y=!0,fe()))),N},n.unstable_shouldYield=te,n.unstable_wrapCallback=function(N){var _=$;return function(){var z=$;$=_;try{return N.apply(this,arguments)}finally{$=z}}}})(Sh)),Sh}var Yg;function uE(){return Yg||(Yg=1,xh.exports=rE()),xh.exports}var $h={exports:{}},Ft={};/** + * @license React + * react-dom.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Xg;function sE(){if(Xg)return Ft;Xg=1;var n=Oc();function t(m){var p="https://react.dev/errors/"+m;if(1"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(t){console.error(t)}}return n(),$h.exports=sE(),$h.exports}/** + * @license React + * react-dom-client.production.js + * + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */var Jg;function oE(){if(Jg)return Fu;Jg=1;var n=uE(),t=Oc(),i=Wx();function r(e){var l="https://react.dev/errors/"+e;if(1V||(e.current=Q[V],Q[V]=null,V--)}function W(e,l){V++,Q[V]=e.current,e.current=l}var ae=A(null),se=A(null),he=A(null),ce=A(null);function Oe(e,l){switch(W(he,l),W(se,e),W(ae,null),l.nodeType){case 9:case 11:e=(e=l.documentElement)&&(e=e.namespaceURI)?fg(e):0;break;default:if(e=l.tagName,l=l.namespaceURI)l=fg(l),e=dg(l,e);else switch(e){case"svg":e=1;break;case"math":e=2;break;default:e=0}}H(ae),W(ae,e)}function Re(){H(ae),H(se),H(he)}function re(e){e.memoizedState!==null&&W(ce,e);var l=ae.current,a=dg(l,e.type);l!==a&&(W(se,e),W(ae,a))}function ye(e){se.current===e&&(H(ae),H(se)),ce.current===e&&(H(ce),ku._currentValue=z)}var Be,wt;function Gt(e){if(Be===void 0)try{throw Error()}catch(a){var l=a.stack.trim().match(/\n( *(at )?)/);Be=l&&l[1]||"",wt=-1)":-1c||O[u]!==I[c]){var ee=` +`+O[u].replace(" at new "," at ");return e.displayName&&ee.includes("")&&(ee=ee.replace("",e.displayName)),ee}while(1<=u&&0<=c);break}}}finally{fn=!1,Error.prepareStackTrace=a}return(a=e?e.displayName||e.name:"")?Gt(a):""}function Ir(e,l){switch(e.tag){case 26:case 27:case 5:return Gt(e.type);case 16:return Gt("Lazy");case 13:return e.child!==l&&l!==null?Gt("Suspense Fallback"):Gt("Suspense");case 19:return Gt("SuspenseList");case 0:case 15:return el(e.type,!1);case 11:return el(e.type.render,!1);case 1:return el(e.type,!0);case 31:return Gt("Activity");default:return""}}function Da(e){try{var l="",a=null;do l+=Ir(e,a),a=e,e=e.return;while(e);return l}catch(u){return` +Error generating stack: `+u.message+` +`+u.stack}}var Xl=Object.prototype.hasOwnProperty,xe=n.unstable_scheduleCallback,Ue=n.unstable_cancelCallback,ot=n.unstable_shouldYield,Bn=n.unstable_requestPaint,At=n.unstable_now,Ds=n.unstable_getCurrentPriorityLevel,Gr=n.unstable_ImmediatePriority,Qr=n.unstable_UserBlockingPriority,Ki=n.unstable_NormalPriority,we=n.unstable_LowPriority,ct=n.unstable_IdlePriority,_e=n.log,bt=n.unstable_setDisableYieldValue,Nt=null,Qe=null;function at(e){if(typeof _e=="function"&&bt(e),Qe&&typeof Qe.setStrictMode=="function")try{Qe.setStrictMode(Nt,e)}catch{}}var Ee=Math.clz32?Math.clz32:Yt,Qt=Math.log,Zl=Math.LN2;function Yt(e){return e>>>=0,e===0?32:31-(Qt(e)/Zl|0)|0}var tl=256,Rs=262144,Ns=4194304;function Bi(e){var l=e&42;if(l!==0)return l;switch(e&-e){case 1:return 1;case 2:return 2;case 4:return 4;case 8:return 8;case 16:return 16;case 32:return 32;case 64:return 64;case 128:return 128;case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:return e&261888;case 262144:case 524288:case 1048576:case 2097152:return e&3932160;case 4194304:case 8388608:case 16777216:case 33554432:return e&62914560;case 67108864:return 67108864;case 134217728:return 134217728;case 268435456:return 268435456;case 536870912:return 536870912;case 1073741824:return 0;default:return e}}function Os(e,l,a){var u=e.pendingLanes;if(u===0)return 0;var c=0,d=e.suspendedLanes,x=e.pingedLanes;e=e.warmLanes;var C=u&134217727;return C!==0?(u=C&~d,u!==0?c=Bi(u):(x&=C,x!==0?c=Bi(x):a||(a=C&~e,a!==0&&(c=Bi(a))))):(C=u&~d,C!==0?c=Bi(C):x!==0?c=Bi(x):a||(a=u&~e,a!==0&&(c=Bi(a)))),c===0?0:l!==0&&l!==c&&(l&d)===0&&(d=c&-c,a=l&-l,d>=a||d===32&&(a&4194048)!==0)?l:c}function Yr(e,l){return(e.pendingLanes&~(e.suspendedLanes&~e.pingedLanes)&l)===0}function US(e,l){switch(e){case 1:case 2:case 4:case 8:case 64:return l+250;case 16:case 32:case 128:case 256:case 512:case 1024:case 2048:case 4096:case 8192:case 16384:case 32768:case 65536:case 131072:case 262144:case 524288:case 1048576:case 2097152:return l+5e3;case 4194304:case 8388608:case 16777216:case 33554432:return-1;case 67108864:case 134217728:case 268435456:case 536870912:case 1073741824:return-1;default:return-1}}function Ip(){var e=Ns;return Ns<<=1,(Ns&62914560)===0&&(Ns=4194304),e}function lf(e){for(var l=[],a=0;31>a;a++)l.push(e);return l}function Xr(e,l){e.pendingLanes|=l,l!==268435456&&(e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0)}function HS(e,l,a,u,c,d){var x=e.pendingLanes;e.pendingLanes=a,e.suspendedLanes=0,e.pingedLanes=0,e.warmLanes=0,e.expiredLanes&=a,e.entangledLanes&=a,e.errorRecoveryDisabledLanes&=a,e.shellSuspendCounter=0;var C=e.entanglements,O=e.expirationTimes,I=e.hiddenUpdates;for(a=x&~a;0"u")return null;try{return e.activeElement||e.body}catch{return e.body}}var YS=/[\n"\\]/g;function An(e){return e.replace(YS,function(l){return"\\"+l.charCodeAt(0).toString(16)+" "})}function cf(e,l,a,u,c,d,x,C){e.name="",x!=null&&typeof x!="function"&&typeof x!="symbol"&&typeof x!="boolean"?e.type=x:e.removeAttribute("type"),l!=null?x==="number"?(l===0&&e.value===""||e.value!=l)&&(e.value=""+wn(l)):e.value!==""+wn(l)&&(e.value=""+wn(l)):x!=="submit"&&x!=="reset"||e.removeAttribute("value"),l!=null?ff(e,x,wn(l)):a!=null?ff(e,x,wn(a)):u!=null&&e.removeAttribute("value"),c==null&&d!=null&&(e.defaultChecked=!!d),c!=null&&(e.checked=c&&typeof c!="function"&&typeof c!="symbol"),C!=null&&typeof C!="function"&&typeof C!="symbol"&&typeof C!="boolean"?e.name=""+wn(C):e.removeAttribute("name")}function ab(e,l,a,u,c,d,x,C){if(d!=null&&typeof d!="function"&&typeof d!="symbol"&&typeof d!="boolean"&&(e.type=d),l!=null||a!=null){if(!(d!=="submit"&&d!=="reset"||l!=null)){of(e);return}a=a!=null?""+wn(a):"",l=l!=null?""+wn(l):a,C||l===e.value||(e.value=l),e.defaultValue=l}u=u??c,u=typeof u!="function"&&typeof u!="symbol"&&!!u,e.checked=C?e.checked:!!u,e.defaultChecked=!!u,x!=null&&typeof x!="function"&&typeof x!="symbol"&&typeof x!="boolean"&&(e.name=x),of(e)}function ff(e,l,a){l==="number"&&_s(e.ownerDocument)===e||e.defaultValue===""+a||(e.defaultValue=""+a)}function _a(e,l,a,u){if(e=e.options,l){l={};for(var c=0;c"u"||typeof window.document>"u"||typeof window.document.createElement>"u"),bf=!1;if(gl)try{var eu={};Object.defineProperty(eu,"passive",{get:function(){bf=!0}}),window.addEventListener("test",eu,eu),window.removeEventListener("test",eu,eu)}catch{bf=!1}var Wl=null,yf=null,Ps=null;function db(){if(Ps)return Ps;var e,l=yf,a=l.length,u,c="value"in Wl?Wl.value:Wl.textContent,d=c.length;for(e=0;e=lu),vb=" ",gb=!1;function xb(e,l){switch(e){case"keyup":return C$.indexOf(l.keyCode)!==-1;case"keydown":return l.keyCode!==229;case"keypress":case"mousedown":case"focusout":return!0;default:return!1}}function Sb(e){return e=e.detail,typeof e=="object"&&"data"in e?e.data:null}var Ka=!1;function T$(e,l){switch(e){case"compositionend":return Sb(l);case"keypress":return l.which!==32?null:(gb=!0,vb);case"textInput":return e=l.data,e===vb&&gb?null:e;default:return null}}function w$(e,l){if(Ka)return e==="compositionend"||!$f&&xb(e,l)?(e=db(),Ps=yf=Wl=null,Ka=!1,e):null;switch(e){case"paste":return null;case"keypress":if(!(l.ctrlKey||l.altKey||l.metaKey)||l.ctrlKey&&l.altKey){if(l.char&&1=l)return{node:a,offset:l-e};e=u}e:{for(;a;){if(a.nextSibling){a=a.nextSibling;break e}a=a.parentNode}a=void 0}a=Db(a)}}function Nb(e,l){return e&&l?e===l?!0:e&&e.nodeType===3?!1:l&&l.nodeType===3?Nb(e,l.parentNode):"contains"in e?e.contains(l):e.compareDocumentPosition?!!(e.compareDocumentPosition(l)&16):!1:!1}function Ob(e){e=e!=null&&e.ownerDocument!=null&&e.ownerDocument.defaultView!=null?e.ownerDocument.defaultView:window;for(var l=_s(e.document);l instanceof e.HTMLIFrameElement;){try{var a=typeof l.contentWindow.location.href=="string"}catch{a=!1}if(a)e=l.contentWindow;else break;l=_s(e.document)}return l}function Tf(e){var l=e&&e.nodeName&&e.nodeName.toLowerCase();return l&&(l==="input"&&(e.type==="text"||e.type==="search"||e.type==="tel"||e.type==="url"||e.type==="password")||l==="textarea"||e.contentEditable==="true")}var L$=gl&&"documentMode"in document&&11>=document.documentMode,Ba=null,wf=null,uu=null,Af=!1;function jb(e,l,a){var u=a.window===a?a.document:a.nodeType===9?a:a.ownerDocument;Af||Ba==null||Ba!==_s(u)||(u=Ba,"selectionStart"in u&&Tf(u)?u={start:u.selectionStart,end:u.selectionEnd}:(u=(u.ownerDocument&&u.ownerDocument.defaultView||window).getSelection(),u={anchorNode:u.anchorNode,anchorOffset:u.anchorOffset,focusNode:u.focusNode,focusOffset:u.focusOffset}),uu&&ru(uu,u)||(uu=u,u=No(wf,"onSelect"),0>=x,c-=x,nl=1<<32-Ee(l)+c|a<Me?(Pe=ve,ve=null):Pe=ve.sibling;var qe=G(K,ve,q[Me],ne);if(qe===null){ve===null&&(ve=Pe);break}e&&ve&&qe.alternate===null&&l(K,ve),k=d(qe,k,Me),Ve===null?Se=qe:Ve.sibling=qe,Ve=qe,ve=Pe}if(Me===q.length)return a(K,ve),ze&&Sl(K,Me),Se;if(ve===null){for(;MeMe?(Pe=ve,ve=null):Pe=ve.sibling;var Si=G(K,ve,qe.value,ne);if(Si===null){ve===null&&(ve=Pe);break}e&&ve&&Si.alternate===null&&l(K,ve),k=d(Si,k,Me),Ve===null?Se=Si:Ve.sibling=Si,Ve=Si,ve=Pe}if(qe.done)return a(K,ve),ze&&Sl(K,Me),Se;if(ve===null){for(;!qe.done;Me++,qe=q.next())qe=le(K,qe.value,ne),qe!==null&&(k=d(qe,k,Me),Ve===null?Se=qe:Ve.sibling=qe,Ve=qe);return ze&&Sl(K,Me),Se}for(ve=u(ve);!qe.done;Me++,qe=q.next())qe=X(ve,K,Me,qe.value,ne),qe!==null&&(e&&qe.alternate!==null&&ve.delete(qe.key===null?Me:qe.key),k=d(qe,k,Me),Ve===null?Se=qe:Ve.sibling=qe,Ve=qe);return e&&ve.forEach(function(eE){return l(K,eE)}),ze&&Sl(K,Me),Se}function nt(K,k,q,ne){if(typeof q=="object"&&q!==null&&q.type===w&&q.key===null&&(q=q.props.children),typeof q=="object"&&q!==null){switch(q.$$typeof){case S:e:{for(var Se=q.key;k!==null;){if(k.key===Se){if(Se=q.type,Se===w){if(k.tag===7){a(K,k.sibling),ne=c(k,q.props.children),ne.return=K,K=ne;break e}}else if(k.elementType===Se||typeof Se=="object"&&Se!==null&&Se.$$typeof===B&&Zi(Se)===k.type){a(K,k.sibling),ne=c(k,q.props),hu(ne,q),ne.return=K,K=ne;break e}a(K,k);break}else l(K,k);k=k.sibling}q.type===w?(ne=Ii(q.props.children,K.mode,ne,q.key),ne.return=K,K=ne):(ne=Gs(q.type,q.key,q.props,null,K.mode,ne),hu(ne,q),ne.return=K,K=ne)}return x(K);case E:e:{for(Se=q.key;k!==null;){if(k.key===Se)if(k.tag===4&&k.stateNode.containerInfo===q.containerInfo&&k.stateNode.implementation===q.implementation){a(K,k.sibling),ne=c(k,q.children||[]),ne.return=K,K=ne;break e}else{a(K,k);break}else l(K,k);k=k.sibling}ne=Lf(q,K.mode,ne),ne.return=K,K=ne}return x(K);case B:return q=Zi(q),nt(K,k,q,ne)}if(F(q))return me(K,k,q,ne);if(fe(q)){if(Se=fe(q),typeof Se!="function")throw Error(r(150));return q=Se.call(q),Ce(K,k,q,ne)}if(typeof q.then=="function")return nt(K,k,eo(q),ne);if(q.$$typeof===P)return nt(K,k,Xs(K,q),ne);to(K,q)}return typeof q=="string"&&q!==""||typeof q=="number"||typeof q=="bigint"?(q=""+q,k!==null&&k.tag===6?(a(K,k.sibling),ne=c(k,q),ne.return=K,K=ne):(a(K,k),ne=jf(q,K.mode,ne),ne.return=K,K=ne),x(K)):a(K,k)}return function(K,k,q,ne){try{du=0;var Se=nt(K,k,q,ne);return Za=null,Se}catch(ve){if(ve===Xa||ve===Js)throw ve;var Ve=hn(29,ve,null,K.mode);return Ve.lanes=ne,Ve.return=K,Ve}finally{}}}var Wi=ny(!0),ly=ny(!1),ii=!1;function If(e){e.updateQueue={baseState:e.memoizedState,firstBaseUpdate:null,lastBaseUpdate:null,shared:{pending:null,lanes:0,hiddenCallbacks:null},callbacks:null}}function Gf(e,l){e=e.updateQueue,l.updateQueue===e&&(l.updateQueue={baseState:e.baseState,firstBaseUpdate:e.firstBaseUpdate,lastBaseUpdate:e.lastBaseUpdate,shared:e.shared,callbacks:null})}function ai(e){return{lane:e,tag:0,payload:null,callback:null,next:null}}function ri(e,l,a){var u=e.updateQueue;if(u===null)return null;if(u=u.shared,(Ye&2)!==0){var c=u.pending;return c===null?l.next=l:(l.next=c.next,c.next=l),u.pending=l,l=Is(e),Bb(e,null,a),l}return qs(e,u,l,a),Is(e)}function mu(e,l,a){if(l=l.updateQueue,l!==null&&(l=l.shared,(a&4194048)!==0)){var u=l.lanes;u&=e.pendingLanes,a|=u,l.lanes=a,Qp(e,a)}}function Qf(e,l){var a=e.updateQueue,u=e.alternate;if(u!==null&&(u=u.updateQueue,a===u)){var c=null,d=null;if(a=a.firstBaseUpdate,a!==null){do{var x={lane:a.lane,tag:a.tag,payload:a.payload,callback:null,next:null};d===null?c=d=x:d=d.next=x,a=a.next}while(a!==null);d===null?c=d=l:d=d.next=l}else c=d=l;a={baseState:u.baseState,firstBaseUpdate:c,lastBaseUpdate:d,shared:u.shared,callbacks:u.callbacks},e.updateQueue=a;return}e=a.lastBaseUpdate,e===null?a.firstBaseUpdate=l:e.next=l,a.lastBaseUpdate=l}var Yf=!1;function pu(){if(Yf){var e=Ya;if(e!==null)throw e}}function bu(e,l,a,u){Yf=!1;var c=e.updateQueue;ii=!1;var d=c.firstBaseUpdate,x=c.lastBaseUpdate,C=c.shared.pending;if(C!==null){c.shared.pending=null;var O=C,I=O.next;O.next=null,x===null?d=I:x.next=I,x=O;var ee=e.alternate;ee!==null&&(ee=ee.updateQueue,C=ee.lastBaseUpdate,C!==x&&(C===null?ee.firstBaseUpdate=I:C.next=I,ee.lastBaseUpdate=O))}if(d!==null){var le=c.baseState;x=0,ee=I=O=null,C=d;do{var G=C.lane&-536870913,X=G!==C.lane;if(X?(ke&G)===G:(u&G)===G){G!==0&&G===Qa&&(Yf=!0),ee!==null&&(ee=ee.next={lane:0,tag:C.tag,payload:C.payload,callback:null,next:null});e:{var me=e,Ce=C;G=l;var nt=a;switch(Ce.tag){case 1:if(me=Ce.payload,typeof me=="function"){le=me.call(nt,le,G);break e}le=me;break e;case 3:me.flags=me.flags&-65537|128;case 0:if(me=Ce.payload,G=typeof me=="function"?me.call(nt,le,G):me,G==null)break e;le=v({},le,G);break e;case 2:ii=!0}}G=C.callback,G!==null&&(e.flags|=64,X&&(e.flags|=8192),X=c.callbacks,X===null?c.callbacks=[G]:X.push(G))}else X={lane:G,tag:C.tag,payload:C.payload,callback:C.callback,next:null},ee===null?(I=ee=X,O=le):ee=ee.next=X,x|=G;if(C=C.next,C===null){if(C=c.shared.pending,C===null)break;X=C,C=X.next,X.next=null,c.lastBaseUpdate=X,c.shared.pending=null}}while(!0);ee===null&&(O=le),c.baseState=O,c.firstBaseUpdate=I,c.lastBaseUpdate=ee,d===null&&(c.shared.lanes=0),fi|=x,e.lanes=x,e.memoizedState=le}}function iy(e,l){if(typeof e!="function")throw Error(r(191,e));e.call(l)}function ay(e,l){var a=e.callbacks;if(a!==null)for(e.callbacks=null,e=0;ed?d:8;var x=N.T,C={};N.T=C,md(e,!1,l,a);try{var O=c(),I=N.S;if(I!==null&&I(C,O),O!==null&&typeof O=="object"&&typeof O.then=="function"){var ee=H$(O,u);gu(e,l,ee,vn(e))}else gu(e,l,u,vn(e))}catch(le){gu(e,l,{then:function(){},status:"rejected",reason:le},vn())}finally{_.p=d,x!==null&&C.types!==null&&(x.types=C.types),N.T=x}}function Y$(){}function dd(e,l,a,u){if(e.tag!==5)throw Error(r(476));var c=Py(e).queue;ky(e,c,l,z,a===null?Y$:function(){return zy(e),a(u)})}function Py(e){var l=e.memoizedState;if(l!==null)return l;l={memoizedState:z,baseState:z,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Tl,lastRenderedState:z},next:null};var a={};return l.next={memoizedState:a,baseState:a,baseQueue:null,queue:{pending:null,lanes:0,dispatch:null,lastRenderedReducer:Tl,lastRenderedState:a},next:null},e.memoizedState=l,e=e.alternate,e!==null&&(e.memoizedState=l),l}function zy(e){var l=Py(e);l.next===null&&(l=e.alternate.memoizedState),gu(e,l.next.queue,{},vn())}function hd(){return zt(ku)}function Ky(){return vt().memoizedState}function By(){return vt().memoizedState}function X$(e){for(var l=e.return;l!==null;){switch(l.tag){case 24:case 3:var a=vn();e=ai(a);var u=ri(l,e,a);u!==null&&(nn(u,l,a),mu(u,l,a)),l={cache:Uf()},e.payload=l;return}l=l.return}}function Z$(e,l,a){var u=vn();a={lane:u,revertLane:0,gesture:null,action:a,hasEagerState:!1,eagerState:null,next:null},fo(e)?Uy(l,a):(a=Nf(e,l,a,u),a!==null&&(nn(a,e,u),Hy(a,l,u)))}function Fy(e,l,a){var u=vn();gu(e,l,a,u)}function gu(e,l,a,u){var c={lane:u,revertLane:0,gesture:null,action:a,hasEagerState:!1,eagerState:null,next:null};if(fo(e))Uy(l,c);else{var d=e.alternate;if(e.lanes===0&&(d===null||d.lanes===0)&&(d=l.lastRenderedReducer,d!==null))try{var x=l.lastRenderedState,C=d(x,a);if(c.hasEagerState=!0,c.eagerState=C,dn(C,x))return qs(e,l,c,0),lt===null&&Vs(),!1}catch{}finally{}if(a=Nf(e,l,c,u),a!==null)return nn(a,e,u),Hy(a,l,u),!0}return!1}function md(e,l,a,u){if(u={lane:2,revertLane:Id(),gesture:null,action:u,hasEagerState:!1,eagerState:null,next:null},fo(e)){if(l)throw Error(r(479))}else l=Nf(e,a,u,2),l!==null&&nn(l,e,2)}function fo(e){var l=e.alternate;return e===Ae||l!==null&&l===Ae}function Uy(e,l){Wa=io=!0;var a=e.pending;a===null?l.next=l:(l.next=a.next,a.next=l),e.pending=l}function Hy(e,l,a){if((a&4194048)!==0){var u=l.lanes;u&=e.pendingLanes,a|=u,l.lanes=a,Qp(e,a)}}var xu={readContext:zt,use:uo,useCallback:ht,useContext:ht,useEffect:ht,useImperativeHandle:ht,useLayoutEffect:ht,useInsertionEffect:ht,useMemo:ht,useReducer:ht,useRef:ht,useState:ht,useDebugValue:ht,useDeferredValue:ht,useTransition:ht,useSyncExternalStore:ht,useId:ht,useHostTransitionStatus:ht,useFormState:ht,useActionState:ht,useOptimistic:ht,useMemoCache:ht,useCacheRefresh:ht};xu.useEffectEvent=ht;var Vy={readContext:zt,use:uo,useCallback:function(e,l){return Ht().memoizedState=[e,l===void 0?null:l],e},useContext:zt,useEffect:Ay,useImperativeHandle:function(e,l,a){a=a!=null?a.concat([e]):null,oo(4194308,4,Ny.bind(null,l,e),a)},useLayoutEffect:function(e,l){return oo(4194308,4,e,l)},useInsertionEffect:function(e,l){oo(4,2,e,l)},useMemo:function(e,l){var a=Ht();l=l===void 0?null:l;var u=e();if(ea){at(!0);try{e()}finally{at(!1)}}return a.memoizedState=[u,l],u},useReducer:function(e,l,a){var u=Ht();if(a!==void 0){var c=a(l);if(ea){at(!0);try{a(l)}finally{at(!1)}}}else c=l;return u.memoizedState=u.baseState=c,e={pending:null,lanes:0,dispatch:null,lastRenderedReducer:e,lastRenderedState:c},u.queue=e,e=e.dispatch=Z$.bind(null,Ae,e),[u.memoizedState,e]},useRef:function(e){var l=Ht();return e={current:e},l.memoizedState=e},useState:function(e){e=ud(e);var l=e.queue,a=Fy.bind(null,Ae,l);return l.dispatch=a,[e.memoizedState,a]},useDebugValue:cd,useDeferredValue:function(e,l){var a=Ht();return fd(a,e,l)},useTransition:function(){var e=ud(!1);return e=ky.bind(null,Ae,e.queue,!0,!1),Ht().memoizedState=e,[!1,e]},useSyncExternalStore:function(e,l,a){var u=Ae,c=Ht();if(ze){if(a===void 0)throw Error(r(407));a=a()}else{if(a=l(),lt===null)throw Error(r(349));(ke&127)!==0||fy(u,l,a)}c.memoizedState=a;var d={value:a,getSnapshot:l};return c.queue=d,Ay(hy.bind(null,u,d,e),[e]),u.flags|=2048,tr(9,{destroy:void 0},dy.bind(null,u,d,a,l),null),a},useId:function(){var e=Ht(),l=lt.identifierPrefix;if(ze){var a=ll,u=nl;a=(u&~(1<<32-Ee(u)-1)).toString(32)+a,l="_"+l+"R_"+a,a=ao++,0<\/script>",d=d.removeChild(d.firstChild);break;case"select":d=typeof u.is=="string"?x.createElement("select",{is:u.is}):x.createElement("select"),u.multiple?d.multiple=!0:u.size&&(d.size=u.size);break;default:d=typeof u.is=="string"?x.createElement(c,{is:u.is}):x.createElement(c)}}d[kt]=l,d[Xt]=u;e:for(x=l.child;x!==null;){if(x.tag===5||x.tag===6)d.appendChild(x.stateNode);else if(x.tag!==4&&x.tag!==27&&x.child!==null){x.child.return=x,x=x.child;continue}if(x===l)break e;for(;x.sibling===null;){if(x.return===null||x.return===l)break e;x=x.return}x.sibling.return=x.return,x=x.sibling}l.stateNode=d;e:switch(Bt(d,c,u),c){case"button":case"input":case"select":case"textarea":u=!!u.autoFocus;break e;case"img":u=!0;break e;default:u=!1}u&&Al(l)}}return ut(l),Md(l,l.type,e===null?null:e.memoizedProps,l.pendingProps,a),null;case 6:if(e&&l.stateNode!=null)e.memoizedProps!==u&&Al(l);else{if(typeof u!="string"&&l.stateNode===null)throw Error(r(166));if(e=he.current,Ia(l)){if(e=l.stateNode,a=l.memoizedProps,u=null,c=Pt,c!==null)switch(c.tag){case 27:case 5:u=c.memoizedProps}e[kt]=l,e=!!(e.nodeValue===a||u!==null&&u.suppressHydrationWarning===!0||og(e.nodeValue,a)),e||ni(l,!0)}else e=Oo(e).createTextNode(u),e[kt]=l,l.stateNode=e}return ut(l),null;case 31:if(a=l.memoizedState,e===null||e.memoizedState!==null){if(u=Ia(l),a!==null){if(e===null){if(!u)throw Error(r(318));if(e=l.memoizedState,e=e!==null?e.dehydrated:null,!e)throw Error(r(557));e[kt]=l}else Gi(),(l.flags&128)===0&&(l.memoizedState=null),l.flags|=4;ut(l),e=!1}else a=zf(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=a),e=!0;if(!e)return l.flags&256?(pn(l),l):(pn(l),null);if((l.flags&128)!==0)throw Error(r(558))}return ut(l),null;case 13:if(u=l.memoizedState,e===null||e.memoizedState!==null&&e.memoizedState.dehydrated!==null){if(c=Ia(l),u!==null&&u.dehydrated!==null){if(e===null){if(!c)throw Error(r(318));if(c=l.memoizedState,c=c!==null?c.dehydrated:null,!c)throw Error(r(317));c[kt]=l}else Gi(),(l.flags&128)===0&&(l.memoizedState=null),l.flags|=4;ut(l),c=!1}else c=zf(),e!==null&&e.memoizedState!==null&&(e.memoizedState.hydrationErrors=c),c=!0;if(!c)return l.flags&256?(pn(l),l):(pn(l),null)}return pn(l),(l.flags&128)!==0?(l.lanes=a,l):(a=u!==null,e=e!==null&&e.memoizedState!==null,a&&(u=l.child,c=null,u.alternate!==null&&u.alternate.memoizedState!==null&&u.alternate.memoizedState.cachePool!==null&&(c=u.alternate.memoizedState.cachePool.pool),d=null,u.memoizedState!==null&&u.memoizedState.cachePool!==null&&(d=u.memoizedState.cachePool.pool),d!==c&&(u.flags|=2048)),a!==e&&a&&(l.child.flags|=8192),yo(l,l.updateQueue),ut(l),null);case 4:return Re(),e===null&&Xd(l.stateNode.containerInfo),ut(l),null;case 10:return Cl(l.type),ut(l),null;case 19:if(H(yt),u=l.memoizedState,u===null)return ut(l),null;if(c=(l.flags&128)!==0,d=u.rendering,d===null)if(c)$u(u,!1);else{if(mt!==0||e!==null&&(e.flags&128)!==0)for(e=l.child;e!==null;){if(d=lo(e),d!==null){for(l.flags|=128,$u(u,!1),e=d.updateQueue,l.updateQueue=e,yo(l,e),l.subtreeFlags=0,e=a,a=l.child;a!==null;)Fb(a,e),a=a.sibling;return W(yt,yt.current&1|2),ze&&Sl(l,u.treeForkCount),l.child}e=e.sibling}u.tail!==null&&At()>$o&&(l.flags|=128,c=!0,$u(u,!1),l.lanes=4194304)}else{if(!c)if(e=lo(d),e!==null){if(l.flags|=128,c=!0,e=e.updateQueue,l.updateQueue=e,yo(l,e),$u(u,!0),u.tail===null&&u.tailMode==="hidden"&&!d.alternate&&!ze)return ut(l),null}else 2*At()-u.renderingStartTime>$o&&a!==536870912&&(l.flags|=128,c=!0,$u(u,!1),l.lanes=4194304);u.isBackwards?(d.sibling=l.child,l.child=d):(e=u.last,e!==null?e.sibling=d:l.child=d,u.last=d)}return u.tail!==null?(e=u.tail,u.rendering=e,u.tail=e.sibling,u.renderingStartTime=At(),e.sibling=null,a=yt.current,W(yt,c?a&1|2:a&1),ze&&Sl(l,u.treeForkCount),e):(ut(l),null);case 22:case 23:return pn(l),Zf(),u=l.memoizedState!==null,e!==null?e.memoizedState!==null!==u&&(l.flags|=8192):u&&(l.flags|=8192),u?(a&536870912)!==0&&(l.flags&128)===0&&(ut(l),l.subtreeFlags&6&&(l.flags|=8192)):ut(l),a=l.updateQueue,a!==null&&yo(l,a.retryQueue),a=null,e!==null&&e.memoizedState!==null&&e.memoizedState.cachePool!==null&&(a=e.memoizedState.cachePool.pool),u=null,l.memoizedState!==null&&l.memoizedState.cachePool!==null&&(u=l.memoizedState.cachePool.pool),u!==a&&(l.flags|=2048),e!==null&&H(Xi),null;case 24:return a=null,e!==null&&(a=e.memoizedState.cache),l.memoizedState.cache!==a&&(l.flags|=2048),Cl(xt),ut(l),null;case 25:return null;case 30:return null}throw Error(r(156,l.tag))}function nC(e,l){switch(kf(l),l.tag){case 1:return e=l.flags,e&65536?(l.flags=e&-65537|128,l):null;case 3:return Cl(xt),Re(),e=l.flags,(e&65536)!==0&&(e&128)===0?(l.flags=e&-65537|128,l):null;case 26:case 27:case 5:return ye(l),null;case 31:if(l.memoizedState!==null){if(pn(l),l.alternate===null)throw Error(r(340));Gi()}return e=l.flags,e&65536?(l.flags=e&-65537|128,l):null;case 13:if(pn(l),e=l.memoizedState,e!==null&&e.dehydrated!==null){if(l.alternate===null)throw Error(r(340));Gi()}return e=l.flags,e&65536?(l.flags=e&-65537|128,l):null;case 19:return H(yt),null;case 4:return Re(),null;case 10:return Cl(l.type),null;case 22:case 23:return pn(l),Zf(),e!==null&&H(Xi),e=l.flags,e&65536?(l.flags=e&-65537|128,l):null;case 24:return Cl(xt),null;case 25:return null;default:return null}}function mv(e,l){switch(kf(l),l.tag){case 3:Cl(xt),Re();break;case 26:case 27:case 5:ye(l);break;case 4:Re();break;case 31:l.memoizedState!==null&&pn(l);break;case 13:pn(l);break;case 19:H(yt);break;case 10:Cl(l.type);break;case 22:case 23:pn(l),Zf(),e!==null&&H(Xi);break;case 24:Cl(xt)}}function Cu(e,l){try{var a=l.updateQueue,u=a!==null?a.lastEffect:null;if(u!==null){var c=u.next;a=c;do{if((a.tag&e)===e){u=void 0;var d=a.create,x=a.inst;u=d(),x.destroy=u}a=a.next}while(a!==c)}}catch(C){We(l,l.return,C)}}function oi(e,l,a){try{var u=l.updateQueue,c=u!==null?u.lastEffect:null;if(c!==null){var d=c.next;u=d;do{if((u.tag&e)===e){var x=u.inst,C=x.destroy;if(C!==void 0){x.destroy=void 0,c=l;var O=a,I=C;try{I()}catch(ee){We(c,O,ee)}}}u=u.next}while(u!==d)}}catch(ee){We(l,l.return,ee)}}function pv(e){var l=e.updateQueue;if(l!==null){var a=e.stateNode;try{ay(l,a)}catch(u){We(e,e.return,u)}}}function bv(e,l,a){a.props=ta(e.type,e.memoizedProps),a.state=e.memoizedState;try{a.componentWillUnmount()}catch(u){We(e,l,u)}}function Eu(e,l){try{var a=e.ref;if(a!==null){switch(e.tag){case 26:case 27:case 5:var u=e.stateNode;break;case 30:u=e.stateNode;break;default:u=e.stateNode}typeof a=="function"?e.refCleanup=a(u):a.current=u}}catch(c){We(e,l,c)}}function il(e,l){var a=e.ref,u=e.refCleanup;if(a!==null)if(typeof u=="function")try{u()}catch(c){We(e,l,c)}finally{e.refCleanup=null,e=e.alternate,e!=null&&(e.refCleanup=null)}else if(typeof a=="function")try{a(null)}catch(c){We(e,l,c)}else a.current=null}function yv(e){var l=e.type,a=e.memoizedProps,u=e.stateNode;try{e:switch(l){case"button":case"input":case"select":case"textarea":a.autoFocus&&u.focus();break e;case"img":a.src?u.src=a.src:a.srcSet&&(u.srcset=a.srcSet)}}catch(c){We(e,e.return,c)}}function Dd(e,l,a){try{var u=e.stateNode;EC(u,e.type,a,l),u[Xt]=l}catch(c){We(e,e.return,c)}}function vv(e){return e.tag===5||e.tag===3||e.tag===26||e.tag===27&&bi(e.type)||e.tag===4}function Rd(e){e:for(;;){for(;e.sibling===null;){if(e.return===null||vv(e.return))return null;e=e.return}for(e.sibling.return=e.return,e=e.sibling;e.tag!==5&&e.tag!==6&&e.tag!==18;){if(e.tag===27&&bi(e.type)||e.flags&2||e.child===null||e.tag===4)continue e;e.child.return=e,e=e.child}if(!(e.flags&2))return e.stateNode}}function Nd(e,l,a){var u=e.tag;if(u===5||u===6)e=e.stateNode,l?(a.nodeType===9?a.body:a.nodeName==="HTML"?a.ownerDocument.body:a).insertBefore(e,l):(l=a.nodeType===9?a.body:a.nodeName==="HTML"?a.ownerDocument.body:a,l.appendChild(e),a=a._reactRootContainer,a!=null||l.onclick!==null||(l.onclick=vl));else if(u!==4&&(u===27&&bi(e.type)&&(a=e.stateNode,l=null),e=e.child,e!==null))for(Nd(e,l,a),e=e.sibling;e!==null;)Nd(e,l,a),e=e.sibling}function vo(e,l,a){var u=e.tag;if(u===5||u===6)e=e.stateNode,l?a.insertBefore(e,l):a.appendChild(e);else if(u!==4&&(u===27&&bi(e.type)&&(a=e.stateNode),e=e.child,e!==null))for(vo(e,l,a),e=e.sibling;e!==null;)vo(e,l,a),e=e.sibling}function gv(e){var l=e.stateNode,a=e.memoizedProps;try{for(var u=e.type,c=l.attributes;c.length;)l.removeAttributeNode(c[0]);Bt(l,u,a),l[kt]=e,l[Xt]=a}catch(d){We(e,e.return,d)}}var Ml=!1,Ct=!1,Od=!1,xv=typeof WeakSet=="function"?WeakSet:Set,jt=null;function lC(e,l){if(e=e.containerInfo,Wd=Ko,e=Ob(e),Tf(e)){if("selectionStart"in e)var a={start:e.selectionStart,end:e.selectionEnd};else e:{a=(a=e.ownerDocument)&&a.defaultView||window;var u=a.getSelection&&a.getSelection();if(u&&u.rangeCount!==0){a=u.anchorNode;var c=u.anchorOffset,d=u.focusNode;u=u.focusOffset;try{a.nodeType,d.nodeType}catch{a=null;break e}var x=0,C=-1,O=-1,I=0,ee=0,le=e,G=null;t:for(;;){for(var X;le!==a||c!==0&&le.nodeType!==3||(C=x+c),le!==d||u!==0&&le.nodeType!==3||(O=x+u),le.nodeType===3&&(x+=le.nodeValue.length),(X=le.firstChild)!==null;)G=le,le=X;for(;;){if(le===e)break t;if(G===a&&++I===c&&(C=x),G===d&&++ee===u&&(O=x),(X=le.nextSibling)!==null)break;le=G,G=le.parentNode}le=X}a=C===-1||O===-1?null:{start:C,end:O}}else a=null}a=a||{start:0,end:0}}else a=null;for(eh={focusedElem:e,selectionRange:a},Ko=!1,jt=l;jt!==null;)if(l=jt,e=l.child,(l.subtreeFlags&1028)!==0&&e!==null)e.return=l,jt=e;else for(;jt!==null;){switch(l=jt,d=l.alternate,e=l.flags,l.tag){case 0:if((e&4)!==0&&(e=l.updateQueue,e=e!==null?e.events:null,e!==null))for(a=0;a title"))),Bt(d,u,a),d[kt]=e,Ot(d),u=d;break e;case"link":var x=wg("link","href",c).get(u+(a.href||""));if(x){for(var C=0;Cnt&&(x=nt,nt=Ce,Ce=x);var K=Rb(C,Ce),k=Rb(C,nt);if(K&&k&&(X.rangeCount!==1||X.anchorNode!==K.node||X.anchorOffset!==K.offset||X.focusNode!==k.node||X.focusOffset!==k.offset)){var q=le.createRange();q.setStart(K.node,K.offset),X.removeAllRanges(),Ce>nt?(X.addRange(q),X.extend(k.node,k.offset)):(q.setEnd(k.node,k.offset),X.addRange(q))}}}}for(le=[],X=C;X=X.parentNode;)X.nodeType===1&&le.push({element:X,left:X.scrollLeft,top:X.scrollTop});for(typeof C.focus=="function"&&C.focus(),C=0;Ca?32:a,N.T=null,a=Kd,Kd=null;var d=hi,x=jl;if(Mt=0,rr=hi=null,jl=0,(Ye&6)!==0)throw Error(r(331));var C=Ye;if(Ye|=4,Nv(d.current),Mv(d,d.current,x,a),Ye=C,Ru(0,!1),Qe&&typeof Qe.onPostCommitFiberRoot=="function")try{Qe.onPostCommitFiberRoot(Nt,d)}catch{}return!0}finally{_.p=c,N.T=u,Yv(e,l)}}function Zv(e,l,a){l=Dn(a,l),l=vd(e.stateNode,l,2),e=ri(e,l,2),e!==null&&(Xr(e,2),al(e))}function We(e,l,a){if(e.tag===3)Zv(e,e,a);else for(;l!==null;){if(l.tag===3){Zv(l,e,a);break}else if(l.tag===1){var u=l.stateNode;if(typeof l.type.getDerivedStateFromError=="function"||typeof u.componentDidCatch=="function"&&(di===null||!di.has(u))){e=Dn(a,e),a=Jy(2),u=ri(l,a,2),u!==null&&(Wy(a,u,l,e),Xr(u,2),al(u));break}}l=l.return}}function Hd(e,l,a){var u=e.pingCache;if(u===null){u=e.pingCache=new rC;var c=new Set;u.set(l,c)}else c=u.get(l),c===void 0&&(c=new Set,u.set(l,c));c.has(a)||(_d=!0,c.add(a),e=fC.bind(null,e,l,a),l.then(e,e))}function fC(e,l,a){var u=e.pingCache;u!==null&&u.delete(l),e.pingedLanes|=e.suspendedLanes&a,e.warmLanes&=~a,lt===e&&(ke&a)===a&&(mt===4||mt===3&&(ke&62914560)===ke&&300>At()-So?(Ye&2)===0&&ur(e,0):kd|=a,ar===ke&&(ar=0)),al(e)}function Jv(e,l){l===0&&(l=Ip()),e=qi(e,l),e!==null&&(Xr(e,l),al(e))}function dC(e){var l=e.memoizedState,a=0;l!==null&&(a=l.retryLane),Jv(e,a)}function hC(e,l){var a=0;switch(e.tag){case 31:case 13:var u=e.stateNode,c=e.memoizedState;c!==null&&(a=c.retryLane);break;case 19:u=e.stateNode;break;case 22:u=e.stateNode._retryCache;break;default:throw Error(r(314))}u!==null&&u.delete(l),Jv(e,a)}function mC(e,l){return xe(e,l)}var Mo=null,or=null,Vd=!1,Do=!1,qd=!1,pi=0;function al(e){e!==or&&e.next===null&&(or===null?Mo=or=e:or=or.next=e),Do=!0,Vd||(Vd=!0,bC())}function Ru(e,l){if(!qd&&Do){qd=!0;do for(var a=!1,u=Mo;u!==null;){if(e!==0){var c=u.pendingLanes;if(c===0)var d=0;else{var x=u.suspendedLanes,C=u.pingedLanes;d=(1<<31-Ee(42|e)+1)-1,d&=c&~(x&~C),d=d&201326741?d&201326741|1:d?d|2:0}d!==0&&(a=!0,ng(u,d))}else d=ke,d=Os(u,u===lt?d:0,u.cancelPendingCommit!==null||u.timeoutHandle!==-1),(d&3)===0||Yr(u,d)||(a=!0,ng(u,d));u=u.next}while(a);qd=!1}}function pC(){Wv()}function Wv(){Do=Vd=!1;var e=0;pi!==0&&wC()&&(e=pi);for(var l=At(),a=null,u=Mo;u!==null;){var c=u.next,d=eg(u,l);d===0?(u.next=null,a===null?Mo=c:a.next=c,c===null&&(or=a)):(a=u,(e!==0||(d&3)!==0)&&(Do=!0)),u=c}Mt!==0&&Mt!==5||Ru(e),pi!==0&&(pi=0)}function eg(e,l){for(var a=e.suspendedLanes,u=e.pingedLanes,c=e.expirationTimes,d=e.pendingLanes&-62914561;0C)break;var ee=O.transferSize,le=O.initiatorType;ee&&cg(le)&&(O=O.responseEnd,x+=ee*(O"u"?null:document;function $g(e,l,a){var u=cr;if(u&&typeof l=="string"&&l){var c=An(l);c='link[rel="'+e+'"][href="'+c+'"]',typeof a=="string"&&(c+='[crossorigin="'+a+'"]'),Sg.has(c)||(Sg.add(c),e={rel:e,crossOrigin:a,href:l},u.querySelector(c)===null&&(l=u.createElement("link"),Bt(l,"link",e),Ot(l),u.head.appendChild(l)))}}function _C(e){Ll.D(e),$g("dns-prefetch",e,null)}function kC(e,l){Ll.C(e,l),$g("preconnect",e,l)}function PC(e,l,a){Ll.L(e,l,a);var u=cr;if(u&&e&&l){var c='link[rel="preload"][as="'+An(l)+'"]';l==="image"&&a&&a.imageSrcSet?(c+='[imagesrcset="'+An(a.imageSrcSet)+'"]',typeof a.imageSizes=="string"&&(c+='[imagesizes="'+An(a.imageSizes)+'"]')):c+='[href="'+An(e)+'"]';var d=c;switch(l){case"style":d=fr(e);break;case"script":d=dr(e)}_n.has(d)||(e=v({rel:"preload",href:l==="image"&&a&&a.imageSrcSet?void 0:e,as:l},a),_n.set(d,e),u.querySelector(c)!==null||l==="style"&&u.querySelector(Lu(d))||l==="script"&&u.querySelector(_u(d))||(l=u.createElement("link"),Bt(l,"link",e),Ot(l),u.head.appendChild(l)))}}function zC(e,l){Ll.m(e,l);var a=cr;if(a&&e){var u=l&&typeof l.as=="string"?l.as:"script",c='link[rel="modulepreload"][as="'+An(u)+'"][href="'+An(e)+'"]',d=c;switch(u){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":d=dr(e)}if(!_n.has(d)&&(e=v({rel:"modulepreload",href:e},l),_n.set(d,e),a.querySelector(c)===null)){switch(u){case"audioworklet":case"paintworklet":case"serviceworker":case"sharedworker":case"worker":case"script":if(a.querySelector(_u(d)))return}u=a.createElement("link"),Bt(u,"link",e),Ot(u),a.head.appendChild(u)}}}function KC(e,l,a){Ll.S(e,l,a);var u=cr;if(u&&e){var c=ja(u).hoistableStyles,d=fr(e);l=l||"default";var x=c.get(d);if(!x){var C={loading:0,preload:null};if(x=u.querySelector(Lu(d)))C.loading=5;else{e=v({rel:"stylesheet",href:e,"data-precedence":l},a),(a=_n.get(d))&&uh(e,a);var O=x=u.createElement("link");Ot(O),Bt(O,"link",e),O._p=new Promise(function(I,ee){O.onload=I,O.onerror=ee}),O.addEventListener("load",function(){C.loading|=1}),O.addEventListener("error",function(){C.loading|=2}),C.loading|=4,Lo(x,l,u)}x={type:"stylesheet",instance:x,count:1,state:C},c.set(d,x)}}}function BC(e,l){Ll.X(e,l);var a=cr;if(a&&e){var u=ja(a).hoistableScripts,c=dr(e),d=u.get(c);d||(d=a.querySelector(_u(c)),d||(e=v({src:e,async:!0},l),(l=_n.get(c))&&sh(e,l),d=a.createElement("script"),Ot(d),Bt(d,"link",e),a.head.appendChild(d)),d={type:"script",instance:d,count:1,state:null},u.set(c,d))}}function FC(e,l){Ll.M(e,l);var a=cr;if(a&&e){var u=ja(a).hoistableScripts,c=dr(e),d=u.get(c);d||(d=a.querySelector(_u(c)),d||(e=v({src:e,async:!0,type:"module"},l),(l=_n.get(c))&&sh(e,l),d=a.createElement("script"),Ot(d),Bt(d,"link",e),a.head.appendChild(d)),d={type:"script",instance:d,count:1,state:null},u.set(c,d))}}function Cg(e,l,a,u){var c=(c=he.current)?jo(c):null;if(!c)throw Error(r(446));switch(e){case"meta":case"title":return null;case"style":return typeof a.precedence=="string"&&typeof a.href=="string"?(l=fr(a.href),a=ja(c).hoistableStyles,u=a.get(l),u||(u={type:"style",instance:null,count:0,state:null},a.set(l,u)),u):{type:"void",instance:null,count:0,state:null};case"link":if(a.rel==="stylesheet"&&typeof a.href=="string"&&typeof a.precedence=="string"){e=fr(a.href);var d=ja(c).hoistableStyles,x=d.get(e);if(x||(c=c.ownerDocument||c,x={type:"stylesheet",instance:null,count:0,state:{loading:0,preload:null}},d.set(e,x),(d=c.querySelector(Lu(e)))&&!d._p&&(x.instance=d,x.state.loading=5),_n.has(e)||(a={rel:"preload",as:"style",href:a.href,crossOrigin:a.crossOrigin,integrity:a.integrity,media:a.media,hrefLang:a.hrefLang,referrerPolicy:a.referrerPolicy},_n.set(e,a),d||UC(c,e,a,x.state))),l&&u===null)throw Error(r(528,""));return x}if(l&&u!==null)throw Error(r(529,""));return null;case"script":return l=a.async,a=a.src,typeof a=="string"&&l&&typeof l!="function"&&typeof l!="symbol"?(l=dr(a),a=ja(c).hoistableScripts,u=a.get(l),u||(u={type:"script",instance:null,count:0,state:null},a.set(l,u)),u):{type:"void",instance:null,count:0,state:null};default:throw Error(r(444,e))}}function fr(e){return'href="'+An(e)+'"'}function Lu(e){return'link[rel="stylesheet"]['+e+"]"}function Eg(e){return v({},e,{"data-precedence":e.precedence,precedence:null})}function UC(e,l,a,u){e.querySelector('link[rel="preload"][as="style"]['+l+"]")?u.loading=1:(l=e.createElement("link"),u.preload=l,l.addEventListener("load",function(){return u.loading|=1}),l.addEventListener("error",function(){return u.loading|=2}),Bt(l,"link",a),Ot(l),e.head.appendChild(l))}function dr(e){return'[src="'+An(e)+'"]'}function _u(e){return"script[async]"+e}function Tg(e,l,a){if(l.count++,l.instance===null)switch(l.type){case"style":var u=e.querySelector('style[data-href~="'+An(a.href)+'"]');if(u)return l.instance=u,Ot(u),u;var c=v({},a,{"data-href":a.href,"data-precedence":a.precedence,href:null,precedence:null});return u=(e.ownerDocument||e).createElement("style"),Ot(u),Bt(u,"style",c),Lo(u,a.precedence,e),l.instance=u;case"stylesheet":c=fr(a.href);var d=e.querySelector(Lu(c));if(d)return l.state.loading|=4,l.instance=d,Ot(d),d;u=Eg(a),(c=_n.get(c))&&uh(u,c),d=(e.ownerDocument||e).createElement("link"),Ot(d);var x=d;return x._p=new Promise(function(C,O){x.onload=C,x.onerror=O}),Bt(d,"link",u),l.state.loading|=4,Lo(d,a.precedence,e),l.instance=d;case"script":return d=dr(a.src),(c=e.querySelector(_u(d)))?(l.instance=c,Ot(c),c):(u=a,(c=_n.get(d))&&(u=v({},a),sh(u,c)),e=e.ownerDocument||e,c=e.createElement("script"),Ot(c),Bt(c,"link",u),e.head.appendChild(c),l.instance=c);case"void":return null;default:throw Error(r(443,l.type))}else l.type==="stylesheet"&&(l.state.loading&4)===0&&(u=l.instance,l.state.loading|=4,Lo(u,a.precedence,e));return l.instance}function Lo(e,l,a){for(var u=a.querySelectorAll('link[rel="stylesheet"][data-precedence],style[data-precedence]'),c=u.length?u[u.length-1]:null,d=c,x=0;x title"):null)}function HC(e,l,a){if(a===1||l.itemProp!=null)return!1;switch(e){case"meta":case"title":return!0;case"style":if(typeof l.precedence!="string"||typeof l.href!="string"||l.href==="")break;return!0;case"link":if(typeof l.rel!="string"||typeof l.href!="string"||l.href===""||l.onLoad||l.onError)break;switch(l.rel){case"stylesheet":return e=l.disabled,typeof l.precedence=="string"&&e==null;default:return!0}case"script":if(l.async&&typeof l.async!="function"&&typeof l.async!="symbol"&&!l.onLoad&&!l.onError&&l.src&&typeof l.src=="string")return!0}return!1}function Mg(e){return!(e.type==="stylesheet"&&(e.state.loading&3)===0)}function VC(e,l,a,u){if(a.type==="stylesheet"&&(typeof u.media!="string"||matchMedia(u.media).matches!==!1)&&(a.state.loading&4)===0){if(a.instance===null){var c=fr(u.href),d=l.querySelector(Lu(c));if(d){l=d._p,l!==null&&typeof l=="object"&&typeof l.then=="function"&&(e.count++,e=ko.bind(e),l.then(e,e)),a.state.loading|=4,a.instance=d,Ot(d);return}d=l.ownerDocument||l,u=Eg(u),(c=_n.get(c))&&uh(u,c),d=d.createElement("link"),Ot(d);var x=d;x._p=new Promise(function(C,O){x.onload=C,x.onerror=O}),Bt(d,"link",u),a.instance=d}e.stylesheets===null&&(e.stylesheets=new Map),e.stylesheets.set(a,l),(l=a.state.preload)&&(a.state.loading&3)===0&&(e.count++,a=ko.bind(e),l.addEventListener("load",a),l.addEventListener("error",a))}}var oh=0;function qC(e,l){return e.stylesheets&&e.count===0&&zo(e,e.stylesheets),0oh?50:800)+l);return e.unsuspend=a,function(){e.unsuspend=null,clearTimeout(u),clearTimeout(c)}}:null}function ko(){if(this.count--,this.count===0&&(this.imgCount===0||!this.waitingForImages)){if(this.stylesheets)zo(this,this.stylesheets);else if(this.unsuspend){var e=this.unsuspend;this.unsuspend=null,e()}}}var Po=null;function zo(e,l){e.stylesheets=null,e.unsuspend!==null&&(e.count++,Po=new Map,l.forEach(IC,e),Po=null,ko.call(e))}function IC(e,l){if(!(l.state.loading&4)){var a=Po.get(e);if(a)var u=a.get(null);else{a=new Map,Po.set(e,a);for(var c=e.querySelectorAll("link[data-precedence],style[data-precedence]"),d=0;d"u"||typeof __REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE!="function"))try{__REACT_DEVTOOLS_GLOBAL_HOOK__.checkDCE(n)}catch(t){console.error(t)}}return n(),gh.exports=oE(),gh.exports}var fE=cE();/** + * react-router v7.18.1 + * + * Copyright (c) Remix Software Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE.md file in the root directory of this source tree. + * + * @license MIT + */var qm=/^(?:[a-z][a-z0-9+.-]*:|[\\/]{2})/i,e1=/^[\\/]{2}/;function dE(n,t){return t+n.replace(/\\/g,"/")}var e0="popstate";function t0(n){return typeof n=="object"&&n!=null&&"pathname"in n&&"search"in n&&"hash"in n&&"state"in n&&"key"in n}function hE(n={}){function t(s,o){let{pathname:f="/",search:h="",hash:m=""}=Ta(s.location.hash.substring(1));return!f.startsWith("/")&&!f.startsWith(".")&&(f="/"+f),Xh("",{pathname:f,search:h,hash:m},o.state&&o.state.usr||null,o.state&&o.state.key||"default")}function i(s,o){let f=s.document.querySelector("base"),h="";if(f&&f.getAttribute("href")){let m=s.location.href,p=m.indexOf("#");h=p===-1?m:m.slice(0,p)}return h+"#"+(typeof o=="string"?o:ls(o))}function r(s,o){$n(s.pathname.charAt(0)==="/",`relative pathnames are not supported in hash history.push(${JSON.stringify(o)})`)}return pE(t,i,r,n)}function dt(n,t){if(n===!1||n===null||typeof n>"u")throw new Error(t)}function $n(n,t){if(!n){typeof console<"u"&&console.warn(t);try{throw new Error(t)}catch{}}}function mE(){return Math.random().toString(36).substring(2,10)}function n0(n,t){return{usr:n.state,key:n.key,idx:t,masked:n.mask?{pathname:n.pathname,search:n.search,hash:n.hash}:void 0}}function Xh(n,t,i=null,r,s){return{pathname:typeof n=="string"?n:n.pathname,search:"",hash:"",...typeof t=="string"?Ta(t):t,state:i,key:t&&t.key||r||mE(),mask:s}}function ls({pathname:n="/",search:t="",hash:i=""}){return t&&t!=="?"&&(n+=t.charAt(0)==="?"?t:"?"+t),i&&i!=="#"&&(n+=i.charAt(0)==="#"?i:"#"+i),n}function Ta(n){let t={};if(n){let i=n.indexOf("#");i>=0&&(t.hash=n.substring(i),n=n.substring(0,i));let r=n.indexOf("?");r>=0&&(t.search=n.substring(r),n=n.substring(0,r)),n&&(t.pathname=n)}return t}function pE(n,t,i,r={}){let{window:s=document.defaultView,v5Compat:o=!1}=r,f=s.history,h="POP",m=null,p=g();p==null&&(p=0,f.replaceState({...f.state,idx:p},""));function g(){return(f.state||{idx:null}).idx}function v(){h="POP";let T=g(),M=T==null?null:T-p;p=T,m&&m({action:h,location:w.location,delta:M})}function $(T,M){h="PUSH";let R=t0(T)?T:Xh(w.location,T,M);i&&i(R,T),p=g()+1;let P=n0(R,p),L=w.createHref(R.mask||R);try{f.pushState(P,"",L)}catch(U){if(U instanceof DOMException&&U.name==="DataCloneError")throw U;s.location.assign(L)}o&&m&&m({action:h,location:w.location,delta:1})}function S(T,M){h="REPLACE";let R=t0(T)?T:Xh(w.location,T,M);i&&i(R,T),p=g();let P=n0(R,p),L=w.createHref(R.mask||R);f.replaceState(P,"",L),o&&m&&m({action:h,location:w.location,delta:0})}function E(T){return bE(s,T)}let w={get action(){return h},get location(){return n(s,f)},listen(T){if(m)throw new Error("A history only accepts one active listener");return s.addEventListener(e0,v),m=T,()=>{s.removeEventListener(e0,v),m=null}},createHref(T){return t(s,T)},createURL:E,encodeLocation(T){let M=E(T);return{pathname:M.pathname,search:M.search,hash:M.hash}},push:$,replace:S,go(T){return f.go(T)}};return w}function bE(n,t,i=!1){let r="http://localhost";n&&(r=n.location.origin!=="null"?n.location.origin:n.location.href),dt(r,"No window.location.(origin|href) available to create URL");let s=typeof t=="string"?t:ls(t);return s=s.replace(/ $/,"%20"),!i&&e1.test(s)&&(s=r+s),new URL(s,r)}function t1(n,t,i="/"){return yE(n,t,i,!1)}function yE(n,t,i,r,s){let o=typeof t=="string"?Ta(t):t,f=Il(o.pathname||"/",i);if(f==null)return null;let h=vE(n),m=null,p=DE(f);for(let g=0;m==null&&g{let g={relativePath:p===void 0?f.path||"":p,caseSensitive:f.caseSensitive===!0,childrenIndex:h,route:f};if(g.relativePath.startsWith("/")){if(!g.relativePath.startsWith(r)&&m)return;dt(g.relativePath.startsWith(r),`Absolute route path "${g.relativePath}" nested under path "${r}" is not valid. An absolute child route path must start with the combined path of all its parent routes.`),g.relativePath=g.relativePath.slice(r.length)}let v=In([r,g.relativePath]),$=i.concat(g);f.children&&f.children.length>0&&(dt(f.index!==!0,`Index routes must not have child routes. Please remove all child routes from route path "${v}".`),n1(f.children,t,$,v,m)),!(f.path==null&&!f.index)&&t.push({path:v,score:wE(v,f.index),routesMeta:$.map((S,E)=>{let[w,T]=a1(S.relativePath,S.caseSensitive,E===$.length-1);return{...S,matcher:w,compiledParams:T}})})};return n.forEach((f,h)=>{var m;if(f.path===""||!((m=f.path)!=null&&m.includes("?")))o(f,h);else for(let p of l1(f.path))o(f,h,!0,p)}),t}function l1(n){let t=n.split("/");if(t.length===0)return[];let[i,...r]=t,s=i.endsWith("?"),o=i.replace(/\?$/,"");if(r.length===0)return s?[o,""]:[o];let f=l1(r.join("/")),h=[];return h.push(...f.map(m=>m===""?o:[o,m].join("/"))),s&&h.push(...f),h.map(m=>n.startsWith("/")&&m===""?"/":m)}function gE(n){n.sort((t,i)=>t.score!==i.score?i.score-t.score:AE(t.routesMeta.map(r=>r.childrenIndex),i.routesMeta.map(r=>r.childrenIndex)))}var xE=/^:[\w-]+$/,SE=3,$E=2,CE=1,EE=10,TE=-2,l0=n=>n==="*";function wE(n,t){let i=n.split("/"),r=i.length;return i.some(l0)&&(r+=TE),t&&(r+=$E),i.filter(s=>!l0(s)).reduce((s,o)=>s+(xE.test(o)?SE:o===""?CE:EE),r)}function AE(n,t){return n.length===t.length&&n.slice(0,-1).every((r,s)=>r===t[s])?n[n.length-1]-t[t.length-1]:0}function ME(n,t,i=!1){let{routesMeta:r}=n,s={},o="/",f=[];for(let h=0;h{if(g==="*"){let E=h[$]||"";f=o.slice(0,o.length-E.length).replace(/(.)\/+$/,"$1")}const S=h[$];return v&&!S?p[g]=void 0:p[g]=(S||"").replace(/%2F/g,"/"),p},{}),pathname:o,pathnameBase:f,pattern:n}}function a1(n,t=!1,i=!0){$n(n==="*"||!n.endsWith("*")||n.endsWith("/*"),`Route path "${n}" will be treated as if it were "${n.replace(/\*$/,"/*")}" because the \`*\` character must always follow a \`/\` in the pattern. To get rid of this warning, please change the route path to "${n.replace(/\*$/,"/*")}".`);let r=[],s="^"+n.replace(/\/*\*?$/,"").replace(/^\/*/,"/").replace(/[\\.*+^${}|()[\]]/g,"\\$&").replace(/\/:([\w-]+)(\?)?/g,(f,h,m,p,g)=>{if(r.push({paramName:h,isOptional:m!=null}),m){let v=g.charAt(p+f.length);return v&&v!=="/"?"/([^\\/]*)":"(?:/([^\\/]*))?"}return"/([^\\/]+)"}).replace(/\/([\w-]+)\?(\/|$)/g,"(/$1)?$2");return n.endsWith("*")?(r.push({paramName:"*"}),s+=n==="*"||n==="/*"?"(.*)$":"(?:\\/(.+)|\\/*)$"):i?s+="\\/*$":n!==""&&n!=="/"&&(s+="(?:(?=\\/|$))"),[new RegExp(s,t?void 0:"i"),r]}function DE(n){try{return n.split("/").map(t=>decodeURIComponent(t).replace(/\//g,"%2F")).join("/")}catch(t){return $n(!1,`The URL path "${n}" could not be decoded because it is a malformed URL segment. This is probably due to a bad percent encoding (${t}).`),n}}function Il(n,t){if(t==="/")return n;if(!n.toLowerCase().startsWith(t.toLowerCase()))return null;let i=t.endsWith("/")?t.length-1:t.length,r=n.charAt(i);return r&&r!=="/"?null:n.slice(i)||"/"}function RE(n,t="/"){let{pathname:i,search:r="",hash:s=""}=typeof n=="string"?Ta(n):n,o;return i?(i=r1(i),i.startsWith("/")?o=i0(i.substring(1),"/"):o=i0(i,t)):o=t,{pathname:o,search:jE(r),hash:LE(s)}}function i0(n,t){let i=bc(t).split("/");return n.split("/").forEach(s=>{s===".."?i.length>1&&i.pop():s!=="."&&i.push(s)}),i.length>1?i.join("/"):"/"}function Ch(n,t,i,r){return`Cannot include a '${n}' character in a manually specified \`to.${t}\` field [${JSON.stringify(r)}]. Please separate it out to the \`to.${i}\` field. Alternatively you may provide the full path as a string in and the router will parse it for you.`}function NE(n){return n.filter((t,i)=>i===0||t.route.path&&t.route.path.length>0)}function Im(n){let t=NE(n);return t.map((i,r)=>r===t.length-1?i.pathname:i.pathnameBase)}function jc(n,t,i,r=!1){let s;typeof n=="string"?s=Ta(n):(s={...n},dt(!s.pathname||!s.pathname.includes("?"),Ch("?","pathname","search",s)),dt(!s.pathname||!s.pathname.includes("#"),Ch("#","pathname","hash",s)),dt(!s.search||!s.search.includes("#"),Ch("#","search","hash",s)));let o=n===""||s.pathname==="",f=o?"/":s.pathname,h;if(f==null)h=i;else{let v=t.length-1;if(!r&&f.startsWith("..")){let $=f.split("/");for(;$[0]==="..";)$.shift(),v-=1;s.pathname=$.join("/")}h=v>=0?t[v]:"/"}let m=RE(s,h),p=f&&f!=="/"&&f.endsWith("/"),g=(o||f===".")&&i.endsWith("/");return!m.pathname.endsWith("/")&&(p||g)&&(m.pathname+="/"),m}var r1=n=>n.replace(/[\\/]{2,}/g,"/"),In=n=>r1(n.join("/")),bc=n=>n.replace(/\/+$/,""),OE=n=>bc(n).replace(/^\/*/,"/"),jE=n=>!n||n==="?"?"":n.startsWith("?")?n:"?"+n,LE=n=>!n||n==="#"?"":n.startsWith("#")?n:"#"+n,_E=class{constructor(n,t,i,r=!1){this.status=n,this.statusText=t||"",this.internal=r,i instanceof Error?(this.data=i.toString(),this.error=i):this.data=i}};function kE(n){return n!=null&&typeof n.status=="number"&&typeof n.statusText=="string"&&typeof n.internal=="boolean"&&"data"in n}function PE(n){let t=n.map(i=>i.route.path).filter(Boolean);return In(t)||"/"}var u1=typeof window<"u"&&typeof window.document<"u"&&typeof window.document.createElement<"u";function s1(n,t){let i=n;if(typeof i!="string"||!qm.test(i))return{absoluteURL:void 0,isExternal:!1,to:i};let r=i,s=!1;if(u1)try{let o=new URL(window.location.href),f=e1.test(i)?new URL(dE(i,o.protocol)):new URL(i),h=Il(f.pathname,t);f.origin===o.origin&&h!=null?i=h+f.search+f.hash:s=!0}catch{$n(!1,` contains an invalid URL which will probably break when clicked - please update to a valid URL path.`)}return{absoluteURL:r,isExternal:s,to:i}}Object.getOwnPropertyNames(Object.prototype).sort().join("\0");var o1=["POST","PUT","PATCH","DELETE"];new Set(o1);var zE=["GET",...o1];new Set(zE);var KE=["about:","blob:","chrome:","chrome-untrusted:","content:","data:","devtools:","file:","filesystem:","javascript:"];function BE(n){try{return KE.includes(new URL(n).protocol)}catch{return!1}}var zr=b.createContext(null);zr.displayName="DataRouter";var Lc=b.createContext(null);Lc.displayName="DataRouterState";var c1=b.createContext(!1);function FE(){return b.useContext(c1)}var f1=b.createContext({isTransitioning:!1});f1.displayName="ViewTransition";var UE=b.createContext(new Map);UE.displayName="Fetchers";var HE=b.createContext(null);HE.displayName="Await";var En=b.createContext(null);En.displayName="Navigation";var ys=b.createContext(null);ys.displayName="Location";var Yn=b.createContext({outlet:null,matches:[],isDataRoute:!1});Yn.displayName="Route";var Gm=b.createContext(null);Gm.displayName="RouteError";var d1="REACT_ROUTER_ERROR",VE="REDIRECT",qE="ROUTE_ERROR_RESPONSE";function IE(n){if(n.startsWith(`${d1}:${VE}:{`))try{let t=JSON.parse(n.slice(28));if(typeof t=="object"&&t&&typeof t.status=="number"&&typeof t.statusText=="string"&&typeof t.location=="string"&&typeof t.reloadDocument=="boolean"&&typeof t.replace=="boolean")return t}catch{}}function GE(n){if(n.startsWith(`${d1}:${qE}:{`))try{let t=JSON.parse(n.slice(40));if(typeof t=="object"&&t&&typeof t.status=="number"&&typeof t.statusText=="string")return new _E(t.status,t.statusText,t.data)}catch{}}function QE(n,{relative:t}={}){dt(Kr(),"useHref() may be used only in the context of a component.");let{basename:i,navigator:r}=b.useContext(En),{hash:s,pathname:o,search:f}=vs(n,{relative:t}),h=o;return i!=="/"&&(h=o==="/"?i:In([i,o])),r.createHref({pathname:h,search:f,hash:s})}function Kr(){return b.useContext(ys)!=null}function Xn(){return dt(Kr(),"useLocation() may be used only in the context of a component."),b.useContext(ys).location}var h1="You should call navigate() in a React.useEffect(), not when your component is first rendered.";function m1(n){b.useContext(En).static||b.useLayoutEffect(n)}function _c(){let{isDataRoute:n}=b.useContext(Yn);return n?o5():YE()}function YE(){dt(Kr(),"useNavigate() may be used only in the context of a component.");let n=b.useContext(zr),{basename:t,navigator:i}=b.useContext(En),{matches:r}=b.useContext(Yn),{pathname:s}=Xn(),o=JSON.stringify(Im(r)),f=b.useRef(!1);return m1(()=>{f.current=!0}),b.useCallback((m,p={})=>{if($n(f.current,h1),!f.current)return;if(typeof m=="number"){i.go(m);return}let g=jc(m,JSON.parse(o),s,p.relative==="path");n==null&&t!=="/"&&(g.pathname=g.pathname==="/"?t:In([t,g.pathname])),(p.replace?i.replace:i.push)(g,p.state,p)},[t,i,o,s,n])}var XE=b.createContext(null);function ZE(n){let t=b.useContext(Yn).outlet;return b.useMemo(()=>t&&b.createElement(XE.Provider,{value:n},t),[t,n])}function vs(n,{relative:t}={}){let{matches:i}=b.useContext(Yn),{pathname:r}=Xn(),s=JSON.stringify(Im(i));return b.useMemo(()=>jc(n,JSON.parse(s),r,t==="path"),[n,s,r,t])}function JE(n,t){return p1(n,t)}function p1(n,t,i){var T;dt(Kr(),"useRoutes() may be used only in the context of a component.");let{navigator:r}=b.useContext(En),{matches:s}=b.useContext(Yn),o=s[s.length-1],f=o?o.params:{},h=o?o.pathname:"/",m=o?o.pathnameBase:"/",p=o&&o.route;{let M=p&&p.path||"";y1(h,!p||M.endsWith("*")||M.endsWith("*?"),`You rendered descendant (or called \`useRoutes()\`) at "${h}" (under ) but the parent route path has no trailing "*". This means if you navigate deeper, the parent won't match anymore and therefore the child routes will never render. + +Please change the parent to .`)}let g=Xn(),v;if(t){let M=typeof t=="string"?Ta(t):t;dt(m==="/"||((T=M.pathname)==null?void 0:T.startsWith(m)),`When overriding the location using \`\` or \`useRoutes(routes, location)\`, the location pathname must begin with the portion of the URL pathname that was matched by all parent routes. The current pathname base is "${m}" but pathname "${M.pathname}" was given in the \`location\` prop.`),v=M}else v=g;let $=v.pathname||"/",S=$;if(m!=="/"){let M=m.replace(/^\//,"").split("/");S="/"+$.replace(/^\//,"").split("/").slice(M.length).join("/")}let E=i&&i.state.matches.length?i.state.matches.map(M=>Object.assign(M,{route:i.manifest[M.route.id]||M.route})):t1(n,{pathname:S});$n(p||E!=null,`No routes matched location "${v.pathname}${v.search}${v.hash}" `),$n(E==null||E[E.length-1].route.element!==void 0||E[E.length-1].route.Component!==void 0||E[E.length-1].route.lazy!==void 0,`Matched leaf route at location "${v.pathname}${v.search}${v.hash}" does not have an element or Component. This means it will render an with a null value by default resulting in an "empty" page.`);let w=l5(E&&E.map(M=>Object.assign({},M,{params:Object.assign({},f,M.params),pathname:In([m,r.encodeLocation?r.encodeLocation(M.pathname.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:M.pathname]),pathnameBase:M.pathnameBase==="/"?m:In([m,r.encodeLocation?r.encodeLocation(M.pathnameBase.replace(/%/g,"%25").replace(/\?/g,"%3F").replace(/#/g,"%23")).pathname:M.pathnameBase])})),s,i);return t&&w?b.createElement(ys.Provider,{value:{location:{pathname:"/",search:"",hash:"",state:null,key:"default",mask:void 0,...v},navigationType:"POP"}},w):w}function WE(){let n=s5(),t=kE(n)?`${n.status} ${n.statusText}`:n instanceof Error?n.message:JSON.stringify(n),i=n instanceof Error?n.stack:null,r="rgba(200,200,200, 0.5)",s={padding:"0.5rem",backgroundColor:r},o={padding:"2px 4px",backgroundColor:r},f=null;return console.error("Error handled by React Router default ErrorBoundary:",n),f=b.createElement(b.Fragment,null,b.createElement("p",null,"💿 Hey developer 👋"),b.createElement("p",null,"You can provide a way better UX than this when your app throws errors by providing your own ",b.createElement("code",{style:o},"ErrorBoundary")," or"," ",b.createElement("code",{style:o},"errorElement")," prop on your route.")),b.createElement(b.Fragment,null,b.createElement("h2",null,"Unexpected Application Error!"),b.createElement("h3",{style:{fontStyle:"italic"}},t),i?b.createElement("pre",{style:s},i):null,f)}var e5=b.createElement(WE,null),b1=class extends b.Component{constructor(n){super(n),this.state={location:n.location,revalidation:n.revalidation,error:n.error}}static getDerivedStateFromError(n){return{error:n}}static getDerivedStateFromProps(n,t){return t.location!==n.location||t.revalidation!=="idle"&&n.revalidation==="idle"?{error:n.error,location:n.location,revalidation:n.revalidation}:{error:n.error!==void 0?n.error:t.error,location:t.location,revalidation:n.revalidation||t.revalidation}}componentDidCatch(n,t){this.props.onError?this.props.onError(n,t):console.error("React Router caught the following error during render",n)}render(){let n=this.state.error;if(this.context&&typeof n=="object"&&n&&"digest"in n&&typeof n.digest=="string"){const i=GE(n.digest);i&&(n=i)}let t=n!==void 0?b.createElement(Yn.Provider,{value:this.props.routeContext},b.createElement(Gm.Provider,{value:n,children:this.props.component})):this.props.children;return this.context?b.createElement(t5,{error:n},t):t}};b1.contextType=c1;var Eh=new WeakMap;function t5({children:n,error:t}){let{basename:i}=b.useContext(En);if(typeof t=="object"&&t&&"digest"in t&&typeof t.digest=="string"){let r=IE(t.digest);if(r){let s=Eh.get(t);if(s)throw s;let o=s1(r.location,i),f=o.absoluteURL||o.to;if(BE(f))throw new Error("Invalid redirect location");if(u1&&!Eh.get(t))if(o.isExternal||r.reloadDocument)window.location.href=f;else{const h=Promise.resolve().then(()=>window.__reactRouterDataRouter.navigate(o.to,{replace:r.replace}));throw Eh.set(t,h),h}return b.createElement("meta",{httpEquiv:"refresh",content:`0;url=${f}`})}}return n}function n5({routeContext:n,match:t,children:i}){let r=b.useContext(zr);return r&&r.static&&r.staticContext&&(t.route.errorElement||t.route.ErrorBoundary)&&(r.staticContext._deepestRenderedBoundaryId=t.route.id),b.createElement(Yn.Provider,{value:n},i)}function l5(n,t=[],i){let r=i==null?void 0:i.state;if(n==null){if(!r)return null;if(r.errors)n=r.matches;else if(t.length===0&&!r.initialized&&r.matches.length>0)n=r.matches;else return null}let s=n,o=r==null?void 0:r.errors;if(o!=null){let g=s.findIndex(v=>v.route.id&&(o==null?void 0:o[v.route.id])!==void 0);dt(g>=0,`Could not find a matching route for errors on route IDs: ${Object.keys(o).join(",")}`),s=s.slice(0,Math.min(s.length,g+1))}let f=!1,h=-1;if(i&&r){f=r.renderFallback;for(let g=0;g=0?s=s.slice(0,h+1):s=[s[0]];break}}}}let m=i==null?void 0:i.onError,p=r&&m?(g,v)=>{var $,S;m(g,{location:r.location,params:((S=($=r.matches)==null?void 0:$[0])==null?void 0:S.params)??{},pattern:PE(r.matches),errorInfo:v})}:void 0;return s.reduceRight((g,v,$)=>{let S,E=!1,w=null,T=null;r&&(S=o&&v.route.id?o[v.route.id]:void 0,w=v.route.errorElement||e5,f&&(h<0&&$===0?(y1("route-fallback",!1,"No `HydrateFallback` element provided to render during initial hydration"),E=!0,T=null):h===$&&(E=!0,T=v.route.hydrateFallbackElement||null)));let M=t.concat(s.slice(0,$+1)),R=()=>{let P;return S?P=w:E?P=T:v.route.Component?P=b.createElement(v.route.Component,null):v.route.element?P=v.route.element:P=g,b.createElement(n5,{match:v,routeContext:{outlet:g,matches:M,isDataRoute:r!=null},children:P})};return r&&(v.route.ErrorBoundary||v.route.errorElement||$===0)?b.createElement(b1,{location:r.location,revalidation:r.revalidation,component:w,error:S,children:R(),routeContext:{outlet:null,matches:M,isDataRoute:!0},onError:p}):R()},null)}function Qm(n){return`${n} must be used within a data router. See https://reactrouter.com/en/main/routers/picking-a-router.`}function i5(n){let t=b.useContext(zr);return dt(t,Qm(n)),t}function a5(n){let t=b.useContext(Lc);return dt(t,Qm(n)),t}function r5(n){let t=b.useContext(Yn);return dt(t,Qm(n)),t}function Ym(n){let t=r5(n),i=t.matches[t.matches.length-1];return dt(i.route.id,`${n} can only be used on routes that contain a unique "id"`),i.route.id}function u5(){return Ym("useRouteId")}function s5(){var r;let n=b.useContext(Gm),t=a5("useRouteError"),i=Ym("useRouteError");return n!==void 0?n:(r=t.errors)==null?void 0:r[i]}function o5(){let{router:n}=i5("useNavigate"),t=Ym("useNavigate"),i=b.useRef(!1);return m1(()=>{i.current=!0}),b.useCallback(async(s,o={})=>{$n(i.current,h1),i.current&&(typeof s=="number"?await n.navigate(s):await n.navigate(s,{fromRouteId:t,...o}))},[n,t])}var a0={};function y1(n,t,i){!t&&!a0[n]&&(a0[n]=!0,$n(!1,i))}b.memo(c5);function c5({routes:n,manifest:t,future:i,state:r,isStatic:s,onError:o}){return p1(n,void 0,{manifest:t,state:r,isStatic:s,onError:o})}function Zh({to:n,replace:t,state:i,relative:r}){dt(Kr()," may be used only in the context of a component.");let{static:s}=b.useContext(En);$n(!s," must not be used on the initial render in a . This is a no-op, but you should modify your code so the is only ever rendered in response to some user interaction or state change.");let{matches:o}=b.useContext(Yn),{pathname:f}=Xn(),h=_c(),m=jc(n,Im(o),f,r==="path"),p=JSON.stringify(m);return b.useEffect(()=>{h(JSON.parse(p),{replace:t,state:i,relative:r})},[h,p,r,t,i]),null}function f5(n){return ZE(n.context)}function Ci(n){dt(!1,"A is only ever to be used as the child of element, never rendered directly. Please wrap your in a .")}function d5({basename:n="/",children:t=null,location:i,navigationType:r="POP",navigator:s,static:o=!1,useTransitions:f}){dt(!Kr(),"You cannot render a inside another . You should never have more than one in your app.");let h=n.replace(/^\/*/,"/"),m=b.useMemo(()=>({basename:h,navigator:s,static:o,useTransitions:f,future:{}}),[h,s,o,f]);typeof i=="string"&&(i=Ta(i));let{pathname:p="/",search:g="",hash:v="",state:$=null,key:S="default",mask:E}=i,w=b.useMemo(()=>{let T=Il(p,h);return T==null?null:{location:{pathname:T,search:g,hash:v,state:$,key:S,mask:E},navigationType:r}},[h,p,g,v,$,S,r,E]);return $n(w!=null,` is not able to match the URL "${p}${g}${v}" because it does not start with the basename, so the won't render anything.`),w==null?null:b.createElement(En.Provider,{value:m},b.createElement(ys.Provider,{children:t,value:w}))}function h5({children:n,location:t}){return JE(Jh(n),t)}function Jh(n,t=[]){let i=[];return b.Children.forEach(n,(r,s)=>{if(!b.isValidElement(r))return;let o=[...t,s];if(r.type===b.Fragment){i.push.apply(i,Jh(r.props.children,o));return}dt(r.type===Ci,`[${typeof r.type=="string"?r.type:r.type.name}] is not a component. All component children of must be a or `),dt(!r.props.index||!r.props.children,"An index route cannot have child routes.");let f={id:r.props.id||o.join("-"),caseSensitive:r.props.caseSensitive,element:r.props.element,Component:r.props.Component,index:r.props.index,path:r.props.path,middleware:r.props.middleware,loader:r.props.loader,action:r.props.action,hydrateFallbackElement:r.props.hydrateFallbackElement,HydrateFallback:r.props.HydrateFallback,errorElement:r.props.errorElement,ErrorBoundary:r.props.ErrorBoundary,hasErrorBoundary:r.props.hasErrorBoundary===!0||r.props.ErrorBoundary!=null||r.props.errorElement!=null,shouldRevalidate:r.props.shouldRevalidate,handle:r.props.handle,lazy:r.props.lazy};r.props.children&&(f.children=Jh(r.props.children,o)),i.push(f)}),i}var ac="get",rc="application/x-www-form-urlencoded";function kc(n){return typeof HTMLElement<"u"&&n instanceof HTMLElement}function m5(n){return kc(n)&&n.tagName.toLowerCase()==="button"}function p5(n){return kc(n)&&n.tagName.toLowerCase()==="form"}function b5(n){return kc(n)&&n.tagName.toLowerCase()==="input"}function y5(n){return!!(n.metaKey||n.altKey||n.ctrlKey||n.shiftKey)}function v5(n,t){return n.button===0&&(!t||t==="_self")&&!y5(n)}function Wh(n=""){return new URLSearchParams(typeof n=="string"||Array.isArray(n)||n instanceof URLSearchParams?n:Object.keys(n).reduce((t,i)=>{let r=n[i];return t.concat(Array.isArray(r)?r.map(s=>[i,s]):[[i,r]])},[]))}function g5(n,t){let i=Wh(n);return t&&t.forEach((r,s)=>{i.has(s)||t.getAll(s).forEach(o=>{i.append(s,o)})}),i}var Go=null;function x5(){if(Go===null)try{new FormData(document.createElement("form"),0),Go=!1}catch{Go=!0}return Go}var S5=new Set(["application/x-www-form-urlencoded","multipart/form-data","text/plain"]);function Th(n){return n!=null&&!S5.has(n)?($n(!1,`"${n}" is not a valid \`encType\` for \`
\`/\`\` and will default to "${rc}"`),null):n}function $5(n,t){let i,r,s,o,f;if(p5(n)){let h=n.getAttribute("action");r=h?Il(h,t):null,i=n.getAttribute("method")||ac,s=Th(n.getAttribute("enctype"))||rc,o=new FormData(n)}else if(m5(n)||b5(n)&&(n.type==="submit"||n.type==="image")){let h=n.form;if(h==null)throw new Error('Cannot submit a - ))} - -
+ + + +
+
- {collapsed ? null : ( -
+ {NAV.map((item) => ( + + clsx( + "flex items-center rounded-lg py-2 text-sm font-medium transition-colors", + collapsed ? "justify-center px-0" : "gap-3 px-3", + isActive + ? "bg-[var(--otari-brand-tint)] text-[var(--otari-brand-dark)]" + : "text-[var(--otari-muted)] hover:bg-[var(--otari-bg)] hover:text-[var(--otari-ink)]", + ) + } + > + {item.icon} + {collapsed ? null : item.label} + + ))} + + {/* Subtle pointer to the hosted product; muted until hovered. */} + - )} - -
-
- - {children} -
-
+ > + + + + {collapsed ? null : ( + + otari.ai + + )} +
+ {collapsed ? null : ( +
+ )} + +
+
+ +
+
+
); } diff --git a/web/src/components/Login.tsx b/web/src/components/Login.tsx index 22c536de..6b21365b 100644 --- a/web/src/components/Login.tsx +++ b/web/src/components/Login.tsx @@ -66,8 +66,18 @@ export function Login() { className="flex flex-col gap-1" > - + +
+ + First run? Where to find your key + +

+ If you did not set OTARI_MASTER_KEY, Otari generated one and printed it to the server logs + on startup. Look for the line Your master key: (for example, run{" "} + docker logs <container>) and paste it above. +

+
+ +
+ + + ); +} + +export function AliasesPage() { + const aliases = useAliases(); + const deleteAlias = useDeleteAlias(); + // A "Make an alias" link from the Models page arrives as ?target=provider:model, + // opening the form with the target prefilled. + const [searchParams] = useSearchParams(); + const initialTarget = searchParams.get("target") ?? ""; + const [adding, setAdding] = useState(initialTarget !== ""); + + const rows = [...(aliases.data ?? [])].sort((a, b) => a.name.localeCompare(b.name)); + + return ( +
+ setAdding(true)}> + New alias + + ) + } + /> + + + + {adding ? setAdding(false)} /> : null} + + + + + + + + + + + + {aliases.isLoading ? ( + + ) : rows.length === 0 ? ( + No aliases yet. Create one to give a model a friendly name. + ) : ( + rows.map((alias) => ( + + + + + + + )) + )} + +
AliasTargetSourceActions
{alias.name}{alias.target} + + {alias.source} + + + {alias.source === "stored" ? ( + + deleteAlias.mutate(alias.name)} + > + Delete + + {deleteAlias.error ? ( + {errorMessage(deleteAlias.error)} + ) : null} + + ) : ( + set in config.yml + )} +
+
+ ); +} diff --git a/web/src/pages/ModelsPage.test.tsx b/web/src/pages/ModelsPage.test.tsx index 3b712689..b178fc70 100644 --- a/web/src/pages/ModelsPage.test.tsx +++ b/web/src/pages/ModelsPage.test.tsx @@ -1,5 +1,6 @@ import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; import { render, screen, within } from "@testing-library/react"; +import { MemoryRouter } from "react-router-dom"; import userEvent from "@testing-library/user-event"; import type { ReactElement } from "react"; import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; @@ -196,13 +197,13 @@ function panel(): HTMLElement { return screen.getByRole("complementary"); } -function aliasRow(): HTMLElement { - return within(table()).getByText("fast-model").closest("tr") as HTMLElement; -} - function renderWithClient(ui: ReactElement) { const client = new QueryClient({ defaultOptions: { queries: { retry: false } } }); - return render({ui}); + return render( + + {ui} + , + ); } function notFound(): Response { @@ -266,12 +267,8 @@ function mockApi( }); } -async function goToTab(user: ReturnType, name: string) { - await user.click(screen.getByRole("tab", { name: new RegExp(`^${name}`) })); -} - -async function openAdd(user: ReturnType) { - await user.click(screen.getByRole("button", { name: "Add" })); +async function openPriceForm(user: ReturnType) { + await user.click(screen.getByRole("button", { name: /Price a model not listed here/i })); } // Selects a model row and returns the detail panel scoped for assertions. @@ -300,19 +297,6 @@ describe("ModelsPage", () => { window.localStorage.clear(); }); - // -- tab structure ------------------------------------------------------- - - it("opens on the Models tab and keeps aliases separate, each with a count", async () => { - mockApi(); - - renderWithClient(); - await screen.findByText("openai:gpt-4o"); - - expect(screen.getByRole("tab", { name: /All models 3/ })).toBeInTheDocument(); - expect(screen.getByRole("tab", { name: /Aliases 1/ })).toBeInTheDocument(); - expect(within(table()).queryByText("fast-model")).not.toBeInTheDocument(); - }); - it("shows no usage columns anywhere", async () => { mockApi(); @@ -326,7 +310,7 @@ describe("ModelsPage", () => { // -- model list ---------------------------------------------------------- - it("lists models with their context window and feature chips", async () => { + it("lists models with their context window", async () => { mockApi(); renderWithClient(); @@ -334,9 +318,6 @@ describe("ModelsPage", () => { expect(within(tableRow("openai:gpt-4o")).getByText("128K")).toBeInTheDocument(); expect(within(tableRow("anthropic:claude-sonnet-4")).getByText("200K")).toBeInTheDocument(); - // Feature chips come from models.dev metadata (image input -> Vision, tools). - expect(within(tableRow("openai:gpt-4o")).getByText("Vision")).toBeInTheDocument(); - expect(within(tableRow("openai:gpt-4o")).getByText("Tools")).toBeInTheDocument(); }); it("surfaces the default-pricing note as a tooltip on the pricing column, not a banner", async () => { @@ -493,21 +474,19 @@ describe("ModelsPage", () => { expect(miniIndex).toBeLessThan(claudeIndex); }); - it("defaults to newest models first with a compact release date", async () => { + it("defaults to sorting by model name, ascending", async () => { mockApi(); renderWithClient(); - // Wait for models.dev metadata (release dates) to land; "2025-05-14" -> "May 2025". - await screen.findByText("May 2025"); - expect(within(tableRow("openai:gpt-4o")).getByText("May 2024")).toBeInTheDocument(); + await screen.findByText("openai:gpt-4o"); - // No header click needed: the default sort is newest-first. + // No header click needed: default is model A→Z, so anthropic sorts before openai. const order = modelOrder(); const claude = order.findIndex((text) => text.includes("claude-sonnet-4")); - const mini = order.findIndex((text) => text.includes("gpt-4o-mini")); const base = order.findIndex((text) => text.includes("openai:gpt-4o") && !text.includes("mini")); - expect(claude).toBeLessThan(mini); - expect(mini).toBeLessThan(base); + const mini = order.findIndex((text) => text.includes("gpt-4o-mini")); + expect(claude).toBeLessThan(base); + expect(base).toBeLessThan(mini); }); it("remembers the chosen sort across a remount", async () => { @@ -515,20 +494,20 @@ describe("ModelsPage", () => { const user = userEvent.setup(); const { unmount } = renderWithClient(); - await screen.findByText("May 2025"); + await screen.findByText("openai:gpt-4o"); - // Flip the Released column to oldest-first and confirm it is persisted. - await user.click(screen.getByRole("button", { name: /Released/ })); + // Flip the Model column to Z→A and confirm it is persisted. + await user.click(screen.getByRole("button", { name: /^Model/ })); expect(JSON.parse(window.localStorage.getItem("otari.dashboard.modelsSort") ?? "{}")).toEqual({ - col: "released", - dir: "asc", + col: "model", + dir: "desc", }); unmount(); - // A fresh mount restores oldest-first rather than the newest-first default. + // A fresh mount restores Z→A rather than the A→Z default. renderWithClient(); - await screen.findByText("May 2025"); + await screen.findByText("openai:gpt-4o"); const order = modelOrder(); const base = order.findIndex((text) => text.includes("openai:gpt-4o") && !text.includes("mini")); const claude = order.findIndex((text) => text.includes("claude-sonnet-4")); @@ -614,66 +593,7 @@ describe("ModelsPage", () => { expect(screen.queryByRole("button", { name: /backfill/i })).not.toBeInTheDocument(); }); - it("opens the Add form in alias mode with the target prefilled from the panel", async () => { - mockApi({ - post: (url) => (url.includes("/v1/aliases") ? jsonResponse(ALIASES[0]) : jsonResponse(PRICED)), - }); - const fetchSpy = vi.spyOn(globalThis, "fetch"); - const user = userEvent.setup(); - - renderWithClient(); - await screen.findByText("openai:gpt-4o"); - - const detail = await selectModel(user, "openai:gpt-4o"); - await user.click(within(detail).getByRole("button", { name: /Alias to this model/ })); - - await user.type(screen.getByRole("textbox", { name: /alias name/i }), "smart"); - await user.click(screen.getByRole("button", { name: /create alias/i })); - - const aliasPost = fetchSpy.mock.calls.find( - ([url, init]) => String(url).includes("/v1/aliases") && (init?.method ?? "") === "POST", - ); - expect(JSON.parse(String(aliasPost?.[1]?.body))).toEqual({ name: "smart", target: "openai:gpt-4o" }); - }); - - // -- Aliases tab --------------------------------------------------------- - - it("shows an alias with its target and resolved price, and no way to price it", async () => { - mockApi(); - const user = userEvent.setup(); - - renderWithClient(); - await goToTab(user, "Aliases"); - await screen.findByText("fast-model"); - - expect(within(aliasRow()).getByText("openai:gpt-4o-mini")).toBeInTheDocument(); - expect(within(aliasRow()).getByText("$0.15")).toBeInTheDocument(); - expect(within(aliasRow()).getByText("set in config.yml")).toBeInTheDocument(); - expect(within(aliasRow()).queryByRole("button", { name: /price|delete/i })).not.toBeInTheDocument(); - }); - - it("deletes a stored alias but not one from config.yml", async () => { - mockApi({ - aliases: [ - { name: "fast-model", target: "openai:gpt-4o-mini", source: "stored", created_at: null, updated_at: null }, - ], - }); - const fetchSpy = vi.spyOn(globalThis, "fetch"); - const user = userEvent.setup(); - - renderWithClient(); - await goToTab(user, "Aliases"); - await screen.findByText("fast-model"); - - expect(screen.queryByText("set in config.yml")).not.toBeInTheDocument(); - await user.click(within(aliasRow()).getByRole("button", { name: "Delete" })); - await user.click(within(aliasRow()).getByRole("button", { name: "Delete" })); - - const call = fetchSpy.mock.calls.find(([, init]) => (init?.method ?? "") === "DELETE"); - expect(String(call?.[0])).toContain("/v1/aliases/fast-model"); - }); - - // -- Add form: picker + alias creation ----------------------------------- + // -- Price an unlisted model: the picker ----------------------------------- it("offers discovered models in the picker and puts the full selector in the field", async () => { mockApi(); @@ -681,7 +601,7 @@ describe("ModelsPage", () => { renderWithClient(); await screen.findByText("openai:gpt-4o"); - await openAdd(user); + await openPriceForm(user); const picker = screen.getByRole("combobox", { name: /model/i }); await user.type(picker, "4o-mini"); @@ -697,7 +617,7 @@ describe("ModelsPage", () => { renderWithClient(); await screen.findByText("openai:gpt-4o"); - await openAdd(user); + await openPriceForm(user); const picker = screen.getByRole("combobox", { name: /model/i }); await user.type(picker, "bedrock:claude-3-sonnet"); @@ -717,18 +637,4 @@ describe("ModelsPage", () => { output_price_per_million: 2, }); }); - - it("refuses an alias name that could be mistaken for a model key", async () => { - mockApi(); - const user = userEvent.setup(); - - renderWithClient(); - await goToTab(user, "Aliases"); - await openAdd(user); - - await user.type(screen.getByRole("textbox", { name: /alias name/i }), "openai:fast"); - - expect(screen.getByText(/cannot contain/)).toBeInTheDocument(); - expect(screen.getByRole("button", { name: /create alias/i })).toBeDisabled(); - }); }); diff --git a/web/src/pages/ModelsPage.tsx b/web/src/pages/ModelsPage.tsx index 8150817a..5622ea7f 100644 --- a/web/src/pages/ModelsPage.tsx +++ b/web/src/pages/ModelsPage.tsx @@ -1,10 +1,8 @@ import { Button, Card, Chip } from "@heroui/react"; -import { type ReactNode, useEffect, useMemo, useState } from "react"; +import { Fragment, type ReactNode, useEffect, useId, useMemo, useState } from "react"; +import { useNavigate } from "react-router-dom"; import { - useAliases, - useCreateAlias, - useDeleteAlias, useDeletePricing, useDiscoverableModels, useModelMetadata, @@ -15,7 +13,6 @@ import { useSettings, } from "@/api/hooks"; import type { ModelMetadata, ProviderCapabilities, ProviderInfo } from "@/api/types"; -import { Field } from "@/components/Field"; import { ModelComboBox } from "@/components/ModelComboBox"; import { LoadingRow, Table, TableMessage, Td, Th, THead, Tr } from "@/components/Table"; import { ConfirmButton, ErrorBanner, errorMessage, InfoBanner, PageHeader } from "@/components/ui"; @@ -108,8 +105,6 @@ interface ModelRow { key: string; model: string; provider: string; - aliasSource?: "config" | "stored"; - aliasPriceSource?: PriceSource; isDiscovered?: boolean; contextWindow: number | null; releaseDate?: string | null; @@ -164,91 +159,6 @@ function SourceChip({ source }: { source: PriceSource }) { return not priced; } -// A compact row of the model's headline capabilities, for the table's Features -// column: vision from the input modalities, plus tool calling and reasoning. -function FeatureChips({ metadata }: { metadata: ModelMetadata | undefined }) { - const chips: string[] = []; - if (metadata) { - if (metadata.input_modalities.includes("image")) { - chips.push("Vision"); - } - if (metadata.tool_call) { - chips.push("Tools"); - } - if (metadata.reasoning) { - chips.push("Reasoning"); - } - } - if (chips.length === 0) { - return ; - } - return ( -
- {chips.map((chip) => ( - - {chip} - - ))} -
- ); -} - -// Creates a stored alias. Pricing, budgets, and usage all key on the target, so -// an alias is never priced here. `initialTarget` prefills the target when the -// detail panel opens this to alias a specific model. -function AddAliasForm({ onClose, initialTarget = "" }: { onClose: () => void; initialTarget?: string }) { - const createAlias = useCreateAlias(); - const [name, setName] = useState(""); - const [target, setTarget] = useState(initialTarget); - - const nameHasDelimiter = /[:/]/.test(name); - const canSubmit = name.trim() !== "" && target.trim() !== "" && !nameHasDelimiter; - - const submit = () => { - if (!canSubmit) { - return; - } - createAlias.mutate({ name: name.trim(), target: target.trim() }, { onSuccess: onClose }); - }; - - return ( -
- -
- - An alias name cannot contain “:” or “/”, which would make it look like a provider:model key. - - ) : ( - "What callers send as `model`." - ) - } - /> - -
-
- -
-
- ); -} - // Prices a model the picker lists, or one it cannot see (an unconfigured // provider, a brand-new release), which is why the key stays free text. function PriceModelForm({ onClose }: { onClose: () => void }) { @@ -303,59 +213,6 @@ function PriceModelForm({ onClose }: { onClose: () => void }) { ); } -type AddTab = "model" | "alias"; - -function AddForm({ - onClose, - initialMode = "model", - initialTarget = "", -}: { - onClose: () => void; - initialMode?: AddTab; - initialTarget?: string; -}) { - const [tab, setTab] = useState(initialMode); - - return ( - - -
-
- {( - [ - ["model", "Price a model"], - ["alias", "Add an alias"], - ] as const - ).map(([id, label]) => ( - - ))} -
- -
- {tab === "model" ? ( - - ) : ( - - )} -
-
- ); -} - // A small info affordance: an "i" bubble that reveals a tooltip on hover or // keyboard focus. Hand-rolled to match the dashboard's other bare primitives // (HeroUI v3 ships no tooltip we use here). @@ -368,12 +225,15 @@ function InfoTooltip({ tone?: "info" | "warning"; children: ReactNode; }) { + // Unique per instance: several tooltips render at once, so a shared id would + // make aria-describedby resolve to the wrong (or ambiguous) tooltip. + const tipId = useId(); return ( {row.source === "configured" ? ( - deletePricing.mutate(row.key)} - > - Clear - + <> + deletePricing.mutate(row.key)} + > + Reset + + + Removes the custom price. The model reverts to the default rate (genai-prices) when default pricing is on, + otherwise it is metered at no cost. + + ) : null} {deletePricing.error ? {errorMessage(deletePricing.error)} : null} @@ -607,7 +473,7 @@ function ModelDetailPanel({ providerInfo, providerModelCount, providerDiscoveryError, - onAliasTo, + onMakeAlias, }: { row: ModelRow | null; metadata: ModelMetadata | undefined; @@ -615,7 +481,7 @@ function ModelDetailPanel({ providerInfo: ProviderInfo | undefined; providerModelCount: number; providerDiscoveryError: string | null; - onAliasTo: (key: string) => void; + onMakeAlias: (key: string) => void; }) { if (!row) { return ( @@ -656,8 +522,8 @@ function ModelDetailPanel({ {row.isDiscovered ? null : not discovered} - @@ -712,53 +578,24 @@ function ModelDetailPanel({ )} - + {/* Skip the provider pane for a custom / self-hosted instance (its name is + not a stock provider): the bundled capabilities and doc links describe + the underlying implementation, not the operator's endpoint. */} + {providerInfo && providerInfo.provider_type === row.provider ? ( + + ) : null} ); } -const TAB_ITEMS = [ - { id: "models", label: "All models" }, - { id: "aliases", label: "Aliases" }, -] as const; - -type Tab = (typeof TAB_ITEMS)[number]["id"]; - const PAGE_SIZE = 25; -function TabBar({ tab, counts, onSelect }: { tab: Tab; counts: Record; onSelect: (tab: Tab) => void }) { - return ( -
- {TAB_ITEMS.map((item) => { - const active = item.id === tab; - return ( - - ); - })} -
- ); -} - function SearchInput({ value, onChange, placeholder }: { value: string; onChange: (value: string) => void; placeholder: string }) { return ( void }) { + const setPricing = useSetPricing(); + const deletePricing = useDeletePricing(); + const [input, setInput] = useState(row.inputPrice == null ? "" : String(row.inputPrice)); + const [output, setOutput] = useState(row.outputPrice == null ? "" : String(row.outputPrice)); + + const save = () => { + if (!isValidPrice(input) || !isValidPrice(output)) return; + setPricing.mutate( + { model_key: row.key, input_price_per_million: Number(input), output_price_per_million: Number(output) }, + { onSuccess: onClose }, + ); + }; + + return ( +
+ {row.key} + + + + + {row.source === "configured" ? ( + + deletePricing.mutate(row.key, { onSuccess: onClose })} + > + Reset + + + Removes the custom price. The model reverts to the default rate (genai-prices) when default pricing is on, + otherwise it is metered at no cost. + + + ) : null} + {setPricing.error || deletePricing.error ? ( + {errorMessage(setPricing.error ?? deletePricing.error)} + ) : null} +
+ ); +} + function ModelTable({ rows, - metadataByKey, isLoading, empty, sort, onSort, selectedKey, onSelect, + pricingKey, + onSetPricingKey, }: { rows: ModelRow[]; - metadataByKey: Record; isLoading: boolean; empty: ReactNode; sort: { col: SortCol; dir: SortDir }; onSort: (col: SortCol) => void; selectedKey: string | null; onSelect: (key: string) => void; + pricingKey: string | null; + onSetPricingKey: (key: string | null) => void; }) { return ( @@ -908,8 +807,6 @@ function ModelTable({ - - } /> + {isLoading ? ( - + ) : rows.length > 0 ? ( rows.map((row) => ( - onSelect(row.key)} selected={row.key === selectedKey}> - - - - - - - - + + onSelect(row.key)} selected={row.key === selectedKey}> + + + + + + + + {pricingKey === row.key ? ( + + + + ) : null} + )) ) : ( - {empty} - )} - -
Provider Features Price
{row.model}{row.provider}{formatContext(row.contextWindow)}{formatReleaseDate(row.releaseDate)} - - {row.inputPrice == null ? "—" : formatCost(row.inputPrice)}{row.outputPrice == null ? "—" : formatCost(row.outputPrice)}
{row.model}{row.provider} + {formatContext(row.contextWindow)} + + {row.inputPrice == null ? "—" : formatCost(row.inputPrice)} + + {row.outputPrice == null ? "—" : formatCost(row.outputPrice)} + + +
+ onSetPricingKey(null)} /> +
- ); -} - -interface AliasEntry { - name: string; - target: string; - source: "config" | "stored"; - row?: ModelRow; -} - -function AliasTableRow({ entry }: { entry: AliasEntry }) { - const deleteAlias = useDeleteAlias(); - const row = entry.row; - return ( - - {entry.name} - {entry.target} - - {row?.aliasPriceSource ? ( - - ) : ( - - )} - - {row?.inputPrice != null ? formatCost(row.inputPrice) : "—"} - {row?.outputPrice != null ? formatCost(row.outputPrice) : "—"} - - {entry.source === "stored" ? ( - - deleteAlias.mutate(entry.name)} - > - Delete - - {deleteAlias.error ? {errorMessage(deleteAlias.error)} : null} - - ) : ( - set in config.yml - )} - - - ); -} - -function AliasTable({ entries, isLoading }: { entries: AliasEntry[]; isLoading: boolean }) { - return ( - - - - - - - - - - - - - {isLoading ? ( - - ) : entries.length > 0 ? ( - entries.map((entry) => ) - ) : ( - No aliases yet. Use “Add” to create one. + {empty} )}
AliasTargetResolves toInput $ / 1MOutput $ / 1MActions
@@ -1028,19 +880,17 @@ function DiscoveredErrors({ providers }: { providers: { provider: string; error: } export function ModelsPage() { + const navigate = useNavigate(); const models = useModels(); const pricing = usePricing(); - const aliases = useAliases(); const discoverable = useDiscoverableModels(); const providers = useProviders(); const metadata = useModelMetadata(); - const [tab, setTab] = useState("models"); const [search, setSearch] = useState(""); const [page, setPage] = useState(0); - const [showForm, setShowForm] = useState(false); - const [addMode, setAddMode] = useState("model"); - const [addTarget, setAddTarget] = useState(""); + const [showPriceForm, setShowPriceForm] = useState(false); + const [pricingKey, setPricingKey] = useState(null); const [selectedKey, setSelectedKey] = useState(null); const [sort, setSort] = useState(readStoredSort); @@ -1068,11 +918,6 @@ export function ModelsPage() { [discoverable.data], ); - const selectTab = (next: Tab) => { - setTab(next); - setSearch(""); - setPage(0); - }; const changeSearch = (value: string) => { setSearch(value); setPage(0); @@ -1089,20 +934,9 @@ export function ModelsPage() { ); setPage(0); }; - const openAliasTo = (key: string) => { - setAddMode("alias"); - setAddTarget(key); - setShowForm(true); - }; - const openAdd = () => { - setAddMode(tab === "aliases" ? "alias" : "model"); - setAddTarget(""); - setShowForm((open) => !open); - }; const rows = useMemo(() => { const configured = new Map(currentPricing(pricing.data ?? []).map((row) => [row.model_key, row])); - const aliasSourceByName = new Map((aliases.data ?? []).map((alias) => [alias.name, alias.source])); const result: ModelRow[] = []; const seen = new Set(); @@ -1111,14 +945,11 @@ export function ModelsPage() { return; } seen.add(key); - const isAlias = catalogRow?.source === "alias"; - const priced = isAlias ? undefined : configured.get(key); + const priced = configured.get(key); result.push({ key, model, provider, - aliasSource: isAlias ? aliasSourceByName.get(key) : undefined, - aliasPriceSource: catalogRow?.aliasPriceSource, isDiscovered: discoverableKeys.has(key), contextWindow: catalogRow?.contextWindow ?? null, inputPrice: priced ? priced.input_price_per_million : (catalogRow?.inputPrice ?? null), @@ -1128,18 +959,20 @@ export function ModelsPage() { }; for (const model of models.data?.data ?? []) { - const isAlias = model.owned_by === ALIAS_OWNED_BY; + // Aliases are managed on their own page, not part of the model catalogue. + if (model.owned_by === ALIAS_OWNED_BY) { + continue; + } const priceStatus: PriceSource = model.pricing_source === "default" ? "default" : model.pricing ? "configured" : "none"; add(model.id, model.id, model.owned_by || providerFromModelKey(model.id), { key: model.id, model: model.id, provider: model.owned_by, - aliasPriceSource: isAlias ? priceStatus : undefined, contextWindow: model.context_window, inputPrice: model.pricing?.input_price_per_million ?? null, outputPrice: model.pricing?.output_price_per_million ?? null, - source: isAlias ? "alias" : priceStatus, + source: priceStatus, }); } for (const key of configured.keys()) { @@ -1147,16 +980,14 @@ export function ModelsPage() { } return result; - }, [models.data, pricing.data, aliases.data, discoverableKeys]); + }, [models.data, pricing.data, discoverableKeys]); const rowsByKey = useMemo(() => new Map(rows.map((row) => [row.key, row])), [rows]); - // The unified model list, with the context window filled from models.dev when - // the catalog did not supply one. Aliases are their own tab. + // The model list, with the context window filled from models.dev when the + // catalog did not supply one. Aliases live on their own page. const modelRows = useMemo(() => { - const out = rows - .filter((row) => row.source !== "alias") - .map((row) => ({ + const out = rows.map((row) => ({ ...row, contextWindow: row.contextWindow ?? (metadataByKey[row.key]?.context_window ?? null), releaseDate: metadataByKey[row.key]?.release_date ?? null, @@ -1186,19 +1017,6 @@ export function ModelsPage() { const discoveredErrors = (discoverable.data?.providers ?? []).filter((provider) => !provider.ok); - const aliasEntries = useMemo( - () => - (aliases.data ?? []) - .map((alias) => ({ - name: alias.name, - target: alias.target, - source: alias.source, - row: rowsByKey.get(alias.name), - })) - .sort((a, b) => a.name.localeCompare(b.name)), - [aliases.data, rowsByKey], - ); - const providerOptions = useMemo(() => { const names = Array.from(new Set(modelRows.map((row) => row.provider))).sort((a, b) => a.localeCompare(b)); return [{ value: "all", label: "All providers" }, ...names.map((name) => ({ value: name, label: name }))]; @@ -1308,21 +1126,11 @@ export function ModelsPage() { sort, ]); - const filteredAliases = aliasEntries.filter( - (entry) => !query || entry.name.toLowerCase().includes(query) || entry.target.toLowerCase().includes(query), - ); - - const counts: Record = { - models: modelRows.length, - aliases: aliasEntries.length, - }; - - const total = tab === "aliases" ? filteredAliases.length : filteredModels.length; + const total = filteredModels.length; const pageCount = Math.max(1, Math.ceil(total / PAGE_SIZE)); const clampedPage = Math.min(page, pageCount - 1); const start = clampedPage * PAGE_SIZE; const pageModels = filteredModels.slice(start, start + PAGE_SIZE); - const pageAliases = filteredAliases.slice(start, start + PAGE_SIZE); const modelsLoading = models.isLoading || pricing.isLoading || discoverable.isLoading; const hasActiveFilters = @@ -1336,7 +1144,7 @@ export function ModelsPage() { releaseFilter !== "all"; const emptyModels = hasActiveFilters ? "No models match your filters." - : "No models yet. Check provider credentials in config.yml, or use “Add” to price one."; + : "No models yet. Add a provider on the Providers page, or price a model below."; // The row selected in the table, resolved against the filtered list (falling // back to any known row) to fill the detail panel. @@ -1355,47 +1163,14 @@ export function ModelsPage() {
- {showForm ? "Hide form" : "Add"} - - } + description="Every model your providers can serve. Set a price on any model so budgets and usage tracking work." /> - {showForm ? ( - // Remount when the requested mode/target changes so "Alias to this model" - // re-seeds the form's tab and target even while the form is already open - // (AddForm copies these props into state only on mount). - setShowForm(false)} - initialMode={addMode} - initialTarget={addTarget} - /> - ) : null} - - - - {tab === "aliases" ? ( -
- - - -
- ) : ( -
+
@@ -1460,16 +1235,40 @@ export function ModelsPage() { - +
+ + +
+ + {showPriceForm ? ( + + +
+
Price a model not listed here
+ +
+ setShowPriceForm(false)} /> +
+
+ ) : null}
- )}
); } diff --git a/web/src/pages/ProvidersPage.test.tsx b/web/src/pages/ProvidersPage.test.tsx new file mode 100644 index 00000000..82dfd95f --- /dev/null +++ b/web/src/pages/ProvidersPage.test.tsx @@ -0,0 +1,283 @@ +import { QueryClient, QueryClientProvider } from "@tanstack/react-query"; +import { render, screen, within } from "@testing-library/react"; +import userEvent from "@testing-library/user-event"; +import type { ReactElement } from "react"; +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; + +import { setMasterKey } from "@/api/client"; +import type { GatewaySettings, KnownProvider, ProviderInfo, StoredProvider, TestProviderResult } from "@/api/types"; +import { ProvidersPage } from "@/pages/ProvidersPage"; + +const CAPS = { + streaming: false, + reasoning: false, + vision: false, + pdf: false, + embeddings: false, + image_generation: false, + audio: false, + rerank: false, + responses_api: false, + moderation: false, + list_models: false, +}; + +function providerInfo(instance: string, envKey: string | null = null): ProviderInfo { + return { + instance, + provider_type: instance, + name: instance, + doc_url: null, + description: null, + env_key: envKey, + pricing_urls: [], + capabilities: CAPS, + }; +} + +function storedProvider(instance: string, last4: string | null, decryptable = true): StoredProvider { + return { + instance, + provider_type: null, + api_base: null, + last4, + client_args: {}, + created_at: null, + updated_at: "2026-01-01T00:00:00+00:00", + decryptable, + }; +} + +const SETTINGS: GatewaySettings = { + mode: "standalone", + version: "1.0.0", + model_discovery: true, + default_pricing: true, + require_pricing: false, +}; + +function jsonResponse(body: unknown, status = 200): Response { + return new Response(JSON.stringify(body), { status, headers: { "Content-Type": "application/json" } }); +} + +interface MockOpts { + meta?: ProviderInfo[]; + stored?: StoredProvider[]; + settings?: GatewaySettings; + testResult?: TestProviderResult; + catalog?: KnownProvider[]; +} + +function mockApi(opts: MockOpts = {}) { + let storedList = [...(opts.stored ?? [])]; + let settings = { ...(opts.settings ?? SETTINGS) }; + const meta = opts.meta ?? []; + const testResult = opts.testResult ?? { ok: true, model_count: 3, error: null }; + const catalog = opts.catalog ?? []; + + return vi.spyOn(globalThis, "fetch").mockImplementation(async (input, init) => { + const url = String(input); + const method = (init?.method ?? "GET").toUpperCase(); + + if (url.includes("/v1/provider-credentials")) { + if (url.endsWith("/test") && method === "POST") { + return jsonResponse(testResult); + } + if (method === "POST") { + const body = JSON.parse(String(init?.body)) as { instance: string; api_key?: string | null }; + const row = storedProvider(body.instance, body.api_key ? body.api_key.slice(-4) : null); + storedList = [...storedList, row]; + return jsonResponse(row, 201); + } + if (method === "DELETE") { + const instance = decodeURIComponent(url.split("/").pop() ?? ""); + storedList = storedList.filter((p) => p.instance !== instance); + return new Response(null, { status: 204 }); + } + return jsonResponse(storedList); + } + if (url.includes("/v1/providers/catalog")) { + return jsonResponse(catalog); + } + if (url.includes("/v1/providers")) { + return jsonResponse({ providers: meta }); + } + if (url.includes("/v1/settings")) { + if (method === "PATCH") { + settings = { ...settings, ...JSON.parse(String(init?.body)) }; + } + return jsonResponse(settings); + } + return jsonResponse([]); + }); +} + +function renderPage(ui: ReactElement) { + const client = new QueryClient({ defaultOptions: { queries: { retry: false } } }); + return render({ui}); +} + +describe("ProvidersPage", () => { + beforeEach(() => setMasterKey("test-master-key")); + afterEach(() => { + vi.restoreAllMocks(); + setMasterKey(null); + }); + + it("lists config and stored providers with provenance and redacted keys", async () => { + mockApi({ + meta: [providerInfo("openai", "OPENAI_API_KEY"), providerInfo("anthropic")], + stored: [storedProvider("anthropic", "4242")], + }); + + renderPage(); + + // Key off cells unique to each row (the instance name appears in two columns). + const storedRow = (await screen.findByText("••••4242")).closest("tr")!; + expect(within(storedRow).getByText("stored")).toBeInTheDocument(); + + const configRow = screen.getByText("OPENAI_API_KEY").closest("tr")!; + expect(within(configRow).getByText("config")).toBeInTheDocument(); + // The plaintext key is never shown, only the last 4. + expect(document.body.textContent).not.toContain("sk-"); + }); + + it("adds a custom provider and posts a write-only key, never rendering it", async () => { + const fetchMock = mockApi({ meta: [], stored: [] }); + const user = userEvent.setup(); + renderPage(); + + await screen.findByText(/No providers yet/); + await user.click(screen.getByRole("button", { name: "Add provider" })); + await user.click(screen.getByRole("button", { name: "Custom endpoint" })); + await user.type(screen.getByLabelText("Name"), "my-llm"); + await user.type(screen.getByLabelText("API base"), "http://box:8000/v1"); + await user.type(screen.getByLabelText("API key (optional)"), "sk-live-9999"); + await user.click(screen.getByRole("button", { name: "Add provider" })); + + const post = fetchMock.mock.calls.find( + ([u, init]) => String(u).endsWith("/v1/provider-credentials") && (init?.method ?? "") === "POST", + ); + expect(post).toBeDefined(); + expect(JSON.parse(String(post?.[1]?.body))).toMatchObject({ + instance: "my-llm", + provider_type: "openai-compatible", + api_base: "http://box:8000/v1", + api_key: "sk-live-9999", + }); + + // After the round trip the row shows the redacted key, never the plaintext. + expect(await screen.findByText("••••9999")).toBeInTheDocument(); + expect(document.body.textContent).not.toContain("sk-live-9999"); + }); + + it("offers the known-provider picker with an Advanced disclosure", async () => { + mockApi({ + stored: [storedProvider("anthropic", "0000")], + catalog: [ + { + id: "openai", + name: "OpenAI", + env_key: "OPENAI_API_KEY", + default_api_base: "https://api.openai.com/v1", + requires_api_key: true, + }, + ], + }); + const user = userEvent.setup(); + renderPage(); + + await screen.findByText("••••0000"); + await user.click(screen.getByRole("button", { name: "Add provider" })); + + // Known provider is the default tab: a provider picker plus a collapsed Advanced section. + expect(screen.getByPlaceholderText("Search providers…")).toBeInTheDocument(); + expect(screen.getByText("Advanced (API base, rename)")).toBeInTheDocument(); + expect(screen.queryByLabelText("API base")).not.toBeInTheDocument(); + }); + + it("keeps Add disabled for a key-requiring provider until a key is entered", async () => { + mockApi({ + stored: [storedProvider("anthropic", "0000")], + catalog: [ + { + id: "openai", + name: "OpenAI", + env_key: "OPENAI_API_KEY", + default_api_base: "https://api.openai.com/v1", + requires_api_key: true, + }, + ], + }); + const user = userEvent.setup(); + renderPage(); + + await screen.findByText("••••0000"); + await user.click(screen.getByRole("button", { name: "Add provider" })); + + await user.type(screen.getByPlaceholderText("Search providers…"), "OpenAI"); + await user.click(await screen.findByRole("option", { name: /OpenAI/ })); + // Close the combobox popover, which otherwise aria-hides the submit button. + await user.keyboard("{Escape}"); + + const submit = screen.getByRole("button", { name: "Add provider" }); + expect(submit).toBeDisabled(); + + await user.type(screen.getByLabelText("API key"), "sk-live-xxxx"); + expect(submit).toBeEnabled(); + }); + + it("shows the welcome onboarding when no provider is configured", async () => { + mockApi({ meta: [], stored: [] }); + renderPage(); + + expect(await screen.findByText("Welcome to Otari")).toBeInTheDocument(); + expect(screen.getByRole("button", { name: "Add your first provider" })).toBeInTheDocument(); + }); + + it("hides the onboarding once a provider exists", async () => { + mockApi({ stored: [storedProvider("openai", "1234")] }); + renderPage(); + + await screen.findByText("••••1234"); + expect(screen.queryByText("Welcome to Otari")).not.toBeInTheDocument(); + }); + + it("flags a stored provider whose key can't be decrypted", async () => { + mockApi({ stored: [storedProvider("home-lab", "0000", false)] }); + renderPage(); + + expect(await screen.findByText(/key unreadable/)).toBeInTheDocument(); + // Test is disabled for an unreadable key; Edit/Delete remain to recover it. + expect(screen.getByRole("button", { name: "Test" })).toBeDisabled(); + expect(screen.getByRole("button", { name: "Edit" })).toBeEnabled(); + }); + + it("reports a successful connection test", async () => { + mockApi({ stored: [storedProvider("openai", "1234")], testResult: { ok: true, model_count: 5, error: null } }); + const user = userEvent.setup(); + renderPage(); + + await screen.findByText("••••1234"); + await user.click(screen.getByRole("button", { name: "Test" })); + + expect(await screen.findByText(/Connected\. 5 models available\./)).toBeInTheDocument(); + }); + + it("offers to enable default pricing when require_pricing would reject requests", async () => { + const fetchMock = mockApi({ + stored: [storedProvider("openai", "1234")], + settings: { ...SETTINGS, require_pricing: true, default_pricing: false }, + }); + const user = userEvent.setup(); + renderPage(); + + const enable = await screen.findByRole("button", { name: "Enable default pricing" }); + await user.click(enable); + + const patch = fetchMock.mock.calls.find( + ([u, init]) => String(u).includes("/v1/settings") && (init?.method ?? "") === "PATCH", + ); + expect(JSON.parse(String(patch?.[1]?.body))).toEqual({ default_pricing: true }); + }); +}); diff --git a/web/src/pages/ProvidersPage.tsx b/web/src/pages/ProvidersPage.tsx new file mode 100644 index 00000000..62107bcd --- /dev/null +++ b/web/src/pages/ProvidersPage.tsx @@ -0,0 +1,827 @@ +import { Button, Card, Chip, ComboBox, Description, Input, Label, ListBox, ListBoxItem, Spinner, TextField } from "@heroui/react"; +import { type CSSProperties, type ReactNode, useMemo, useState } from "react"; + +import { + useCreateStoredProvider, + useDeleteStoredProvider, + useProviderCatalog, + useProviders, + useSettings, + useStoredProviders, + useTestProviderCredentials, + useTestStoredProvider, + useUpdateSettings, + useUpdateStoredProvider, +} from "@/api/hooks"; +import type { + CreateStoredProviderRequest, + ProviderInfo, + StoredProvider, + TestProviderResult, + UpdateStoredProviderRequest, +} from "@/api/types"; +import { Field } from "@/components/Field"; +import { LoadingRow, Table, TableMessage, Td, Th, THead, Tr } from "@/components/Table"; +import { ConfirmButton, ErrorBanner, errorMessage, InfoBanner, PageHeader } from "@/components/ui"; + +// WebkitTextSecurity masks the value like a password field without being one. +// It is non-standard, so it is absent from React's CSSProperties type. +const SECRET_MASK_STYLE = { WebkitTextSecurity: "disc" } as CSSProperties; + +// A masked, never-prefilled secret input. Editing a key is "replace, not +// reveal": the current key is only ever shown as its last 4 digits elsewhere, +// and a new value is typed into an empty field. +function SecretField({ + value, + onChange, + label, + placeholder, + description, +}: { + value: string; + onChange: (next: string) => void; + label: string; + placeholder?: string; + description?: string; +}) { + return ( + + + {/* Deliberately NOT type="password": Chrome flags password fields on non-HTTPS + origins ("this form is not secure, login entered here may be compromised") + and attaches its password manager + username heuristics to sibling fields + (the provider picker). A text input masked with -webkit-text-security hides + the key without any of that. */} + + {description ? {description} : null} + + ); +} + +// A searchable provider picker over the known-provider catalog. Selection sets +// an id (provider id, or a provider_type) while the input shows the display +// name. `extra` prepends synthetic options like "OpenAI-compatible". +function ProviderComboBox({ + label, + value, + onChange, + description, + placeholder, + extra = [], + includeCatalog = true, +}: { + label: string; + value: string; + onChange: (id: string) => void; + description?: ReactNode; + placeholder?: string; + extra?: { id: string; name: string }[]; + // When false, offer only `extra` (e.g. the two API dialects), not the full + // provider catalog. + includeCatalog?: boolean; +}) { + const catalog = useProviderCatalog(); + const options = useMemo( + () => (includeCatalog ? [...extra, ...(catalog.data ?? []).map((p) => ({ id: p.id, name: p.name }))] : extra), + [catalog.data, extra, includeCatalog], + ); + + // Seed the input with the selected option's display name. The field owns its + // text after mount (updated on typing and on selection); syncing it back from + // `value` on every render would wipe out what the user is typing, since the + // options array is recreated each render. + const [text, setText] = useState(() => options.find((o) => o.id === value)?.name ?? ""); + + // When the input merely shows the current selection, treat the query as empty + // so opening the dropdown reveals every option, not just the selected one. + const selectedName = options.find((o) => o.id === value)?.name ?? ""; + const query = text.trim() === selectedName.trim() ? "" : text.trim().toLowerCase(); + const visible = options + .filter((o) => !query || o.name.toLowerCase().includes(query) || o.id.toLowerCase().includes(query)) + .slice(0, 50); + + return ( + { + if (key != null) { + onChange(String(key)); + setText(options.find((o) => o.id === String(key))?.name ?? ""); + } else { + // Selection cleared: clear the parent value too, so the submitted + // data cannot keep a stale provider after the field is emptied. + onChange(""); + setText(""); + } + }} + className="flex flex-col gap-1" + > + + + {/* Not a credential field: keep browser password managers from offering to fill it. + Select the text on focus so typing replaces the current selection instead of + appending to it (otherwise "OpenAI-compatible" + typing filters to nothing). */} + event.currentTarget.select()} + /> + + + + + {(option: { id: string; name: string }) => ( + + {option.name} + + )} + + + {description ? {description} : null} + + ); +} + +// A "Test connection" button + inline result, testing the form's credentials +// before they are saved. `getPayload` returns null when the minimum fields for a +// test are not filled in yet, which disables the button. +function ConnectionTest({ getPayload }: { getPayload: () => CreateStoredProviderRequest | null }) { + const test = useTestProviderCredentials(); + const payload = getPayload(); + + return ( +
+ + {test.isPending ? null : test.error ? ( + {errorMessage(test.error)} + ) : test.data ? ( + test.data.ok ? ( + + Connected. {test.data.model_count} model{test.data.model_count === 1 ? "" : "s"} available. + + ) : ( + + {test.data.error ?? "Connection failed."} + + ) + ) : null} +
+ ); +} + +// Add a hosted provider whose endpoint is built into the SDK: pick it, paste a +// key. Name and api_base are only exposed under Advanced. +function KnownProviderForm({ onClose }: { onClose: () => void }) { + const catalog = useProviderCatalog(); + const create = useCreateStoredProvider(); + const [providerId, setProviderId] = useState(""); + const [apiKey, setApiKey] = useState(""); + const [showAdvanced, setShowAdvanced] = useState(false); + const [apiBase, setApiBase] = useState(""); + const [name, setName] = useState(""); + + const selected = catalog.data?.find((p) => p.id === providerId); + const needsKey = selected?.requires_api_key ?? true; + const renamed = name.trim() !== "" && name.trim() !== providerId; + const nameHasDelimiter = /[:/]/.test(name); + // Require the key when the chosen provider says it needs one; keyless local + // backends (Ollama, llama.cpp) can submit without it. + const canSubmit = + providerId !== "" && !nameHasDelimiter && (!needsKey || apiKey.trim() !== "") && !create.isPending; + + const submit = () => { + if (!canSubmit) return; + create.mutate( + { + instance: renamed ? name.trim() : providerId, + // A renamed instance is no longer named after its provider, so record the + // provider it is so routing still resolves. + provider_type: renamed ? providerId : null, + api_base: apiBase.trim() || null, + api_key: apiKey.trim() || null, + }, + { onSuccess: onClose }, + ); + }; + + return ( +
+ + { + setProviderId(id); + setName(""); + // Prefill the (editable) API base with the provider's built-in default + // so Advanced shows what will be used; empty when the SDK has no explicit one. + setApiBase(catalog.data?.find((p) => p.id === id)?.default_api_base ?? ""); + }} + description="Its endpoint is built in." + /> + + + {showAdvanced ? ( +
+ + A name cannot contain “:” or “/”. + ) : ( + "Rename to run two instances of the same provider." + ) + } + /> +
+ ) : null} +
+ + + providerId === "" + ? null + : { + instance: renamed ? name.trim() : providerId, + provider_type: renamed ? providerId : null, + api_base: apiBase.trim() || null, + api_key: apiKey.trim() || null, + } + } + /> +
+
+ ); +} + +// Add a self-hosted or OpenAI-compatible endpoint: name it anything, say what +// API it speaks, and give the base URL (and a key if it needs one). +function CustomProviderForm({ onClose }: { onClose: () => void }) { + const create = useCreateStoredProvider(); + const [name, setName] = useState(""); + const [providerType, setProviderType] = useState("openai-compatible"); + const [apiBase, setApiBase] = useState(""); + const [apiKey, setApiKey] = useState(""); + + const nameHasDelimiter = /[:/]/.test(name); + const canSubmit = name.trim() !== "" && !nameHasDelimiter && apiBase.trim() !== "" && !create.isPending; + + const submit = () => { + if (!canSubmit) return; + create.mutate( + { + instance: name.trim(), + provider_type: providerType || "openai-compatible", + api_base: apiBase.trim(), + api_key: apiKey.trim() || null, + }, + { onSuccess: onClose }, + ); + }; + + return ( +
+ +
+ A name cannot contain “:” or “/”. + ) : ( + "Call it whatever you want." + ) + } + /> + +
+ + +
+ + + name.trim() === "" || apiBase.trim() === "" + ? null + : { + instance: name.trim(), + provider_type: providerType || "openai-compatible", + api_base: apiBase.trim(), + api_key: apiKey.trim() || null, + } + } + /> +
+
+ ); +} + +type ProviderTab = "known" | "custom"; + +function AddProviderForm({ onClose }: { onClose: () => void }) { + const [tab, setTab] = useState("known"); + + return ( + + +
+
+ {( + [ + ["known", "Known provider"], + ["custom", "Custom endpoint"], + ] as const + ).map(([id, label]) => ( + + ))} +
+ +
+ {tab === "known" ? : } +
+
+ ); +} + +function EditProviderForm({ provider, onClose }: { provider: StoredProvider; onClose: () => void }) { + const update = useUpdateStoredProvider(); + const [providerType, setProviderType] = useState(provider.provider_type ?? ""); + const [apiBase, setApiBase] = useState(provider.api_base ?? ""); + const [replacingKey, setReplacingKey] = useState(false); + const [apiKey, setApiKey] = useState(""); + + const submit = () => { + if (update.isPending) return; + const body: UpdateStoredProviderRequest = { + provider_type: providerType.trim() || null, + api_base: apiBase.trim() || null, + // Guard against clobbering a concurrent edit; a 412 tells the operator to reload. + expected_updated_at: provider.updated_at, + }; + if (replacingKey && apiKey.trim()) { + body.api_key = apiKey.trim(); + } + update.mutate({ instance: provider.instance, body }, { onSuccess: onClose }); + }; + + return ( + + +
+ Edit {provider.instance} +
+ +
+ + +
+
+ {replacingKey ? ( + <> + + + + ) : ( +
+ + API key: {provider.last4 ? `••••${provider.last4}` : "none set"} + + +
+ )} +
+
+ + +
+
+
+ ); +} + +interface ProviderRow { + instance: string; + source: "config" | "stored"; + stored: StoredProvider | undefined; + meta: ProviderInfo | undefined; +} + +function buildRows(meta: ProviderInfo[] | undefined, stored: StoredProvider[] | undefined): ProviderRow[] { + const storedByInstance = new Map((stored ?? []).map((p) => [p.instance, p])); + const metaByInstance = new Map((meta ?? []).map((p) => [p.instance, p])); + const instances = new Set([...storedByInstance.keys(), ...metaByInstance.keys()]); + return [...instances] + .sort() + .map((instance) => { + const s = storedByInstance.get(instance); + return { instance, source: s ? "stored" : "config", stored: s, meta: metaByInstance.get(instance) } as const; + }); +} + +type TestState = { status: "pending" } | ({ status: "done" } & TestProviderResult); + +function TestOutcome({ state }: { state: TestState | undefined }) { + if (!state) return null; + if (state.status === "pending") { + return ( + + Testing… + + ); + } + if (state.ok) { + return ( + + Connected. {state.model_count} model{state.model_count === 1 ? "" : "s"} available. + + ); + } + return ( + + {state.error ?? "Connection failed."} + + ); +} + +function Step({ n, title, children }: { n: number; title: string; children: ReactNode }) { + return ( +
  • + + {n} + +
    +
    {title}
    +
    {children}
    +
    +
  • + ); +} + +// Shown on first run (no provider configured yet). It disappears the moment a +// provider exists, so it is a nudge to the first key, not a permanent banner. +function OnboardingPanel({ + onAddProvider, + needsPricing, + onEnablePricing, + enabling, +}: { + onAddProvider: () => void; + needsPricing: boolean; + onEnablePricing: () => void; + enabling: boolean; +}) { + return ( + + +
    +

    Welcome to Otari

    +

    + You are signed in. Add a provider to start serving models: three quick steps. +

    +
    +
      + + Enter a provider name (like openai) and its API key. Keys are encrypted at rest. + + + Use Test on the provider row to confirm the key works and see how many models it serves. + + + Point your app at /v1 on this gateway with the API key printed in the server logs + (gw-…). See the{" "} + + quickstart + + . + +
    + {needsPricing ? ( +

    + Tip: require_pricing is on, so requests are rejected until pricing is set.{" "} + {" "} + to meter new models with public rates. +

    + ) : null} +
    + +
    +
    +
    + ); +} + +export function ProvidersPage() { + const meta = useProviders(); + const stored = useStoredProviders(); + const settings = useSettings(); + const deleteProvider = useDeleteStoredProvider(); + const testProvider = useTestStoredProvider(); + const updateSettings = useUpdateSettings(); + + const [addOpen, setAddOpen] = useState(false); + const [editing, setEditing] = useState(null); + const [tests, setTests] = useState>({}); + + const rows = buildRows(meta.data?.providers, stored.data); + const loading = meta.isLoading || stored.isLoading; + const editingProvider = stored.data?.find((p) => p.instance === editing) ?? null; + const needsPricing = settings.data?.require_pricing === true && settings.data.default_pricing === false; + const showOnboarding = !loading && rows.length === 0; + + const runTest = (instance: string) => { + setTests((prev) => ({ ...prev, [instance]: { status: "pending" } })); + testProvider.mutate(instance, { + onSuccess: (result) => setTests((prev) => ({ ...prev, [instance]: { status: "done", ...result } })), + onError: (error) => + setTests((prev) => ({ + ...prev, + [instance]: { status: "done", ok: false, model_count: 0, error: errorMessage(error) }, + })), + }); + }; + + return ( +
    +
    + ); +}