polymo 0.2.0__tar.gz → 0.3.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- polymo-0.3.0/PKG-INFO +127 -0
- polymo-0.3.0/README.md +103 -0
- {polymo-0.2.0 → polymo-0.3.0}/pyproject.toml +1 -1
- polymo-0.3.0/src/polymo/builder/static/examples/countries.yml +28 -0
- polymo-0.3.0/src/polymo/builder/static/examples/weather.yml +32 -0
- polymo-0.3.0/src/polymo/builder/static/main.css +1 -0
- polymo-0.3.0/src/polymo/builder/static/main.js +116 -0
- {polymo-0.2.0 → polymo-0.3.0}/src/polymo/config.py +156 -4
- {polymo-0.2.0 → polymo-0.3.0}/src/polymo/rest_client.py +136 -3
- polymo-0.2.0/PKG-INFO +0 -101
- polymo-0.2.0/README.md +0 -77
- polymo-0.2.0/src/polymo/builder/static/examples/incremental-state.json +0 -11
- polymo-0.2.0/src/polymo/builder/static/main.css +0 -1
- polymo-0.2.0/src/polymo/builder/static/main.js +0 -117
- {polymo-0.2.0 → polymo-0.3.0}/src/polymo/__init__.py +0 -0
- {polymo-0.2.0 → polymo-0.3.0}/src/polymo/builder/__init__.py +0 -0
- {polymo-0.2.0 → polymo-0.3.0}/src/polymo/builder/app.py +0 -0
- {polymo-0.2.0 → polymo-0.3.0}/src/polymo/builder/static/examples/githubrepos.yml +0 -0
- {polymo-0.2.0 → polymo-0.3.0}/src/polymo/builder/static/examples/jsonplaceholder.yml +0 -0
- {polymo-0.2.0 → polymo-0.3.0}/src/polymo/builder/static/favicon.ico +0 -0
- {polymo-0.2.0 → polymo-0.3.0}/src/polymo/builder/static/index.html +0 -0
- {polymo-0.2.0 → polymo-0.3.0}/src/polymo/builder/static/logo.png +0 -0
- {polymo-0.2.0 → polymo-0.3.0}/src/polymo/builder/static/logo192.png +0 -0
- {polymo-0.2.0 → polymo-0.3.0}/src/polymo/builder/static/mockServiceWorker.js +0 -0
- {polymo-0.2.0 → polymo-0.3.0}/src/polymo/builder/templates/index.html +0 -0
- {polymo-0.2.0 → polymo-0.3.0}/src/polymo/cli.py +0 -0
- {polymo-0.2.0 → polymo-0.3.0}/src/polymo/datasource.py +0 -0
- {polymo-0.2.0 → polymo-0.3.0}/src/polymo/py.typed +0 -0
- {polymo-0.2.0 → polymo-0.3.0}/src/polymo/scripts/__init__.py +0 -0
- {polymo-0.2.0 → polymo-0.3.0}/src/polymo/scripts/smoke.py +0 -0
polymo-0.3.0/PKG-INFO
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
Metadata-Version: 2.3
|
|
2
|
+
Name: polymo
|
|
3
|
+
Version: 0.3.0
|
|
4
|
+
Summary: API ingestion for PySpark
|
|
5
|
+
Author: Daniel Tom
|
|
6
|
+
Author-email: Daniel Tom <d.e.tom89@gmail.com>
|
|
7
|
+
Requires-Dist: fsspec>=2025.9.0
|
|
8
|
+
Requires-Dist: httpx>=0.26
|
|
9
|
+
Requires-Dist: jinja2>=3.1.6
|
|
10
|
+
Requires-Dist: pyyaml>=6.0.1
|
|
11
|
+
Requires-Dist: polymo[builder,smoke] ; extra == 'all'
|
|
12
|
+
Requires-Dist: fastapi>=0.110 ; extra == 'builder'
|
|
13
|
+
Requires-Dist: uvicorn>=0.24 ; extra == 'builder'
|
|
14
|
+
Requires-Dist: jinja2>=3.1.6 ; extra == 'builder'
|
|
15
|
+
Requires-Dist: pyspark>=4 ; extra == 'builder'
|
|
16
|
+
Requires-Dist: pyarrow>=13 ; extra == 'builder'
|
|
17
|
+
Requires-Dist: pyspark>=4 ; extra == 'smoke'
|
|
18
|
+
Requires-Dist: pyarrow>=13 ; extra == 'smoke'
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Provides-Extra: all
|
|
21
|
+
Provides-Extra: builder
|
|
22
|
+
Provides-Extra: smoke
|
|
23
|
+
Description-Content-Type: text/markdown
|
|
24
|
+
|
|
25
|
+
<p align="center">
|
|
26
|
+
<img src="builder-ui/public/logo.png" alt="Polymo" width="220">
|
|
27
|
+
</p>
|
|
28
|
+
|
|
29
|
+
# Welcome to Polymo
|
|
30
|
+
|
|
31
|
+
Polymo is a helper for pyspark that turns everyday web APIs into tables you can analyse. Point it at an API, tell it what you want to grab, and Polymo does the heavy lifting of fetching the data and lining it up neatly.
|
|
32
|
+
|
|
33
|
+
## Why people use Polymo
|
|
34
|
+
- **No custom code required.** Describe your API once in a short, friendly YAML file or through the point-and-click Builder.
|
|
35
|
+
- **See results before you commit.** Preview the real responses, record-by-record, so you can fix issues early.
|
|
36
|
+
- **Works with Spark-based tools.** When you are ready, Polymo serves the data to your analytics stack using the same interface Spark already understands.
|
|
37
|
+
- **Designed for teams.** Save reusable connectors, share them across projects, and keep secrets (like tokens) out of files.
|
|
38
|
+
|
|
39
|
+
## Pick your path
|
|
40
|
+
- **Mostly clicking?** Open the [Builder UI](builder-ui.md) and follow the guided screens. It is the easiest way to create a connector from scratch.
|
|
41
|
+
- **Prefer a checklist?** Read the [Configuration guide](config.md) for a plain-language tour of every field in the YAML file.
|
|
42
|
+
- **Power user?** Jump straight to the [CLI](cli.md) or the [Python helpers](api.md) to automate things.
|
|
43
|
+
|
|
44
|
+
## Before you start
|
|
45
|
+
- Install Polymo with `pip install polymo`. If you want the Builder UI, add the extras: `pip install "polymo[builder]"`.
|
|
46
|
+
- Make sure you have access to the API you care about (base URL, token if needed, and any sample request parameters).
|
|
47
|
+
- Check that PySpark version 4 or newer is available. Polymo uses Spark under the hood to keep data consistent.
|
|
48
|
+
|
|
49
|
+
## Quick tour
|
|
50
|
+
|
|
51
|
+
1. **Launch the Builder (optional but recommended).** Run `polymo builder --port 9000` and open the provided link in your browser.
|
|
52
|
+
2. **Describe your API.** Fill in a base URL like `https://jsonplaceholder.typicode.com`, pick the endpoint `/posts`, and add filters such as `_limit: 20` if you only need a sample.
|
|
53
|
+
3. **Preview the data.** Press the Preview button to see a table of records, the raw API replies, and any error messages.
|
|
54
|
+
4. **Save the connector.** Download the YAML config or write it directly to your project folder. Tokens stay out of the file and are passed in later.
|
|
55
|
+
5. **Use it in Spark.** Load the file with the short code snippet below or copy/paste from the Builder’s tips panel.
|
|
56
|
+
|
|
57
|
+
The Builder keeps a local library of every connector you work on. Use the header’s connector picker to hop between drafts, open the library to rename or export them, and never worry about losing your place.
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from pyspark.sql import SparkSession
|
|
61
|
+
from polymo import ApiReader
|
|
62
|
+
|
|
63
|
+
spark = SparkSession.builder.getOrCreate()
|
|
64
|
+
spark.dataSource.register(ApiReader)
|
|
65
|
+
|
|
66
|
+
df = (
|
|
67
|
+
spark.read.format("polymo")
|
|
68
|
+
.option("config_path", "./config.yml") # YAML you saved from the Builder
|
|
69
|
+
.option("token", "YOUR_TOKEN") # Only if the API needs one
|
|
70
|
+
.load()
|
|
71
|
+
)
|
|
72
|
+
|
|
73
|
+
df.show()
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Incremental syncs in one minute
|
|
77
|
+
- Add `cursor_param` and `cursor_field` under `incremental:` in your YAML to tell Polymo which API field to track.
|
|
78
|
+
- Pass `.option("incremental_state_path", ...)` when reading with Spark. Local paths and remote URLs (S3, GCS, Azure, etc.) work out of the box.
|
|
79
|
+
- On the first run, seed a starting value with `.option("incremental_start_value", "...")`. Future runs reuse the stored cursor automatically.
|
|
80
|
+
- Override the stored entry name with `.option("incremental_state_key", "...")` if you share a state file across connectors.
|
|
81
|
+
- Skip the state path to keep cursors only in memory during the Spark session, or disable that cache with `.option("incremental_memory_state", "false")` if you always want a cold start.
|
|
82
|
+
|
|
83
|
+
### Handling flaky APIs with retries
|
|
84
|
+
- Add an `error_handler` block under `stream:` when you want to customise retries. By default Polymo retries 5× on HTTP `5XX` and `429` responses with exponential backoff.
|
|
85
|
+
- Override the defaults to catch extra status codes or adjust the timing:
|
|
86
|
+
|
|
87
|
+
```yaml
|
|
88
|
+
stream:
|
|
89
|
+
path: /orders
|
|
90
|
+
error_handler:
|
|
91
|
+
max_retries: 6
|
|
92
|
+
retry_statuses:
|
|
93
|
+
- 5XX
|
|
94
|
+
- 429
|
|
95
|
+
- 404
|
|
96
|
+
retry_on_timeout: true
|
|
97
|
+
retry_on_connection_errors: true
|
|
98
|
+
backoff:
|
|
99
|
+
initial_delay_seconds: 1
|
|
100
|
+
max_delay_seconds: 60
|
|
101
|
+
multiplier: 1.8
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
- Omit the block to keep the safe defaults. The Builder UI exposes the same fields if you prefer toggles over YAML edits.
|
|
105
|
+
|
|
106
|
+
## What’s inside this project
|
|
107
|
+
- `src/polymo/` keeps the logic that speaks to APIs and hands data to Spark.
|
|
108
|
+
- `polymo builder` is a small web app (FastAPI + React) that guides you through every step. No need to run npm, the app is bundled with pip and ready to go.
|
|
109
|
+
- `examples/` contains ready-made configs you can copy, tweak, and use for smoke tests.
|
|
110
|
+
|
|
111
|
+
## Run the Builder in Docker
|
|
112
|
+
- Build the dev-friendly image and launch the Builder with hot reload:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
docker compose up --build builder
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
- The service listens on port `8000`; open <http://localhost:8000> once Uvicorn reports it is running.
|
|
119
|
+
- The image already bundles PySpark and OpenJDK 21;
|
|
120
|
+
- Stop with `docker compose down` and restart quickly using the cached image via `docker compose up builder`.
|
|
121
|
+
|
|
122
|
+
Have fun building connectors!
|
|
123
|
+
|
|
124
|
+
## Where to Next
|
|
125
|
+
Read the docs [here](https://dan1elt0m.github.io/polymo/)
|
|
126
|
+
|
|
127
|
+
Contributions and early feedback welcome!
|
polymo-0.3.0/README.md
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="builder-ui/public/logo.png" alt="Polymo" width="220">
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
# Welcome to Polymo
|
|
6
|
+
|
|
7
|
+
Polymo is a helper for pyspark that turns everyday web APIs into tables you can analyse. Point it at an API, tell it what you want to grab, and Polymo does the heavy lifting of fetching the data and lining it up neatly.
|
|
8
|
+
|
|
9
|
+
## Why people use Polymo
|
|
10
|
+
- **No custom code required.** Describe your API once in a short, friendly YAML file or through the point-and-click Builder.
|
|
11
|
+
- **See results before you commit.** Preview the real responses, record-by-record, so you can fix issues early.
|
|
12
|
+
- **Works with Spark-based tools.** When you are ready, Polymo serves the data to your analytics stack using the same interface Spark already understands.
|
|
13
|
+
- **Designed for teams.** Save reusable connectors, share them across projects, and keep secrets (like tokens) out of files.
|
|
14
|
+
|
|
15
|
+
## Pick your path
|
|
16
|
+
- **Mostly clicking?** Open the [Builder UI](builder-ui.md) and follow the guided screens. It is the easiest way to create a connector from scratch.
|
|
17
|
+
- **Prefer a checklist?** Read the [Configuration guide](config.md) for a plain-language tour of every field in the YAML file.
|
|
18
|
+
- **Power user?** Jump straight to the [CLI](cli.md) or the [Python helpers](api.md) to automate things.
|
|
19
|
+
|
|
20
|
+
## Before you start
|
|
21
|
+
- Install Polymo with `pip install polymo`. If you want the Builder UI, add the extras: `pip install "polymo[builder]"`.
|
|
22
|
+
- Make sure you have access to the API you care about (base URL, token if needed, and any sample request parameters).
|
|
23
|
+
- Check that PySpark version 4 or newer is available. Polymo uses Spark under the hood to keep data consistent.
|
|
24
|
+
|
|
25
|
+
## Quick tour
|
|
26
|
+
|
|
27
|
+
1. **Launch the Builder (optional but recommended).** Run `polymo builder --port 9000` and open the provided link in your browser.
|
|
28
|
+
2. **Describe your API.** Fill in a base URL like `https://jsonplaceholder.typicode.com`, pick the endpoint `/posts`, and add filters such as `_limit: 20` if you only need a sample.
|
|
29
|
+
3. **Preview the data.** Press the Preview button to see a table of records, the raw API replies, and any error messages.
|
|
30
|
+
4. **Save the connector.** Download the YAML config or write it directly to your project folder. Tokens stay out of the file and are passed in later.
|
|
31
|
+
5. **Use it in Spark.** Load the file with the short code snippet below or copy/paste from the Builder’s tips panel.
|
|
32
|
+
|
|
33
|
+
The Builder keeps a local library of every connector you work on. Use the header’s connector picker to hop between drafts, open the library to rename or export them, and never worry about losing your place.
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from pyspark.sql import SparkSession
|
|
37
|
+
from polymo import ApiReader
|
|
38
|
+
|
|
39
|
+
spark = SparkSession.builder.getOrCreate()
|
|
40
|
+
spark.dataSource.register(ApiReader)
|
|
41
|
+
|
|
42
|
+
df = (
|
|
43
|
+
spark.read.format("polymo")
|
|
44
|
+
.option("config_path", "./config.yml") # YAML you saved from the Builder
|
|
45
|
+
.option("token", "YOUR_TOKEN") # Only if the API needs one
|
|
46
|
+
.load()
|
|
47
|
+
)
|
|
48
|
+
|
|
49
|
+
df.show()
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Incremental syncs in one minute
|
|
53
|
+
- Add `cursor_param` and `cursor_field` under `incremental:` in your YAML to tell Polymo which API field to track.
|
|
54
|
+
- Pass `.option("incremental_state_path", ...)` when reading with Spark. Local paths and remote URLs (S3, GCS, Azure, etc.) work out of the box.
|
|
55
|
+
- On the first run, seed a starting value with `.option("incremental_start_value", "...")`. Future runs reuse the stored cursor automatically.
|
|
56
|
+
- Override the stored entry name with `.option("incremental_state_key", "...")` if you share a state file across connectors.
|
|
57
|
+
- Skip the state path to keep cursors only in memory during the Spark session, or disable that cache with `.option("incremental_memory_state", "false")` if you always want a cold start.
|
|
58
|
+
|
|
59
|
+
### Handling flaky APIs with retries
|
|
60
|
+
- Add an `error_handler` block under `stream:` when you want to customise retries. By default Polymo retries 5× on HTTP `5XX` and `429` responses with exponential backoff.
|
|
61
|
+
- Override the defaults to catch extra status codes or adjust the timing:
|
|
62
|
+
|
|
63
|
+
```yaml
|
|
64
|
+
stream:
|
|
65
|
+
path: /orders
|
|
66
|
+
error_handler:
|
|
67
|
+
max_retries: 6
|
|
68
|
+
retry_statuses:
|
|
69
|
+
- 5XX
|
|
70
|
+
- 429
|
|
71
|
+
- 404
|
|
72
|
+
retry_on_timeout: true
|
|
73
|
+
retry_on_connection_errors: true
|
|
74
|
+
backoff:
|
|
75
|
+
initial_delay_seconds: 1
|
|
76
|
+
max_delay_seconds: 60
|
|
77
|
+
multiplier: 1.8
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
- Omit the block to keep the safe defaults. The Builder UI exposes the same fields if you prefer toggles over YAML edits.
|
|
81
|
+
|
|
82
|
+
## What’s inside this project
|
|
83
|
+
- `src/polymo/` keeps the logic that speaks to APIs and hands data to Spark.
|
|
84
|
+
- `polymo builder` is a small web app (FastAPI + React) that guides you through every step. No need to run npm, the app is bundled with pip and ready to go.
|
|
85
|
+
- `examples/` contains ready-made configs you can copy, tweak, and use for smoke tests.
|
|
86
|
+
|
|
87
|
+
## Run the Builder in Docker
|
|
88
|
+
- Build the dev-friendly image and launch the Builder with hot reload:
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
docker compose up --build builder
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
- The service listens on port `8000`; open <http://localhost:8000> once Uvicorn reports it is running.
|
|
95
|
+
- The image already bundles PySpark and OpenJDK 21;
|
|
96
|
+
- Stop with `docker compose down` and restart quickly using the cached image via `docker compose up builder`.
|
|
97
|
+
|
|
98
|
+
Have fun building connectors!
|
|
99
|
+
|
|
100
|
+
## Where to Next
|
|
101
|
+
Read the docs [here](https://dan1elt0m.github.io/polymo/)
|
|
102
|
+
|
|
103
|
+
Contributions and early feedback welcome!
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
version: 0.1
|
|
2
|
+
source:
|
|
3
|
+
type: rest
|
|
4
|
+
base_url: https://restcountries.com/v3.1
|
|
5
|
+
stream:
|
|
6
|
+
path: /all
|
|
7
|
+
infer_schema: true
|
|
8
|
+
schema: null
|
|
9
|
+
pagination:
|
|
10
|
+
type: none
|
|
11
|
+
record_selector:
|
|
12
|
+
field_path: []
|
|
13
|
+
record_filter: null
|
|
14
|
+
cast_to_schema_types: false
|
|
15
|
+
params:
|
|
16
|
+
fields: "name,flags"
|
|
17
|
+
headers:
|
|
18
|
+
Accept: "application/json"
|
|
19
|
+
error_handler:
|
|
20
|
+
max_retries: 2
|
|
21
|
+
retry_statuses: ["5XX", "429", "503"]
|
|
22
|
+
backoff:
|
|
23
|
+
initial_delay_seconds: 1.0
|
|
24
|
+
max_delay_seconds: 10.0
|
|
25
|
+
multiplier: 2.0
|
|
26
|
+
retry_on_timeout: true
|
|
27
|
+
retry_on_connection_errors: true
|
|
28
|
+
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
version: 0.1
|
|
2
|
+
source:
|
|
3
|
+
type: rest
|
|
4
|
+
base_url: https://api.openweathermap.org/data/2.5
|
|
5
|
+
stream:
|
|
6
|
+
path: /weather
|
|
7
|
+
infer_schema: true
|
|
8
|
+
schema: null
|
|
9
|
+
pagination:
|
|
10
|
+
type: none
|
|
11
|
+
record_selector:
|
|
12
|
+
field_path: []
|
|
13
|
+
record_filter: null
|
|
14
|
+
cast_to_schema_types: false
|
|
15
|
+
params:
|
|
16
|
+
appid: "{{ options.api_key }}"
|
|
17
|
+
lat: "{{ options.latitude | default('40.7128') }}"
|
|
18
|
+
lon: "{{ options.longitude | default('-74.0060') }}"
|
|
19
|
+
units: "metric"
|
|
20
|
+
exclude: "minutely"
|
|
21
|
+
headers:
|
|
22
|
+
User-Agent: "Polymo Weather Connector/1.0"
|
|
23
|
+
Accept: "application/json"
|
|
24
|
+
error_handler:
|
|
25
|
+
max_retries: 3
|
|
26
|
+
retry_statuses: ["5XX", "429", "503"]
|
|
27
|
+
backoff:
|
|
28
|
+
initial_delay_seconds: 1.0
|
|
29
|
+
max_delay_seconds: 30.0
|
|
30
|
+
multiplier: 2.0
|
|
31
|
+
retry_on_timeout: true
|
|
32
|
+
retry_on_connection_errors: true
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@import"https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap";*,:before,:after{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }::backdrop{--tw-border-spacing-x: 0;--tw-border-spacing-y: 0;--tw-translate-x: 0;--tw-translate-y: 0;--tw-rotate: 0;--tw-skew-x: 0;--tw-skew-y: 0;--tw-scale-x: 1;--tw-scale-y: 1;--tw-pan-x: ;--tw-pan-y: ;--tw-pinch-zoom: ;--tw-scroll-snap-strictness: proximity;--tw-gradient-from-position: ;--tw-gradient-via-position: ;--tw-gradient-to-position: ;--tw-ordinal: ;--tw-slashed-zero: ;--tw-numeric-figure: ;--tw-numeric-spacing: ;--tw-numeric-fraction: ;--tw-ring-inset: ;--tw-ring-offset-width: 0px;--tw-ring-offset-color: #fff;--tw-ring-color: rgb(59 130 246 / .5);--tw-ring-offset-shadow: 0 0 #0000;--tw-ring-shadow: 0 0 #0000;--tw-shadow: 0 0 #0000;--tw-shadow-colored: 0 0 #0000;--tw-blur: ;--tw-brightness: ;--tw-contrast: ;--tw-grayscale: ;--tw-hue-rotate: ;--tw-invert: ;--tw-saturate: ;--tw-sepia: ;--tw-drop-shadow: ;--tw-backdrop-blur: ;--tw-backdrop-brightness: ;--tw-backdrop-contrast: ;--tw-backdrop-grayscale: ;--tw-backdrop-hue-rotate: ;--tw-backdrop-invert: ;--tw-backdrop-opacity: ;--tw-backdrop-saturate: ;--tw-backdrop-sepia: ;--tw-contain-size: ;--tw-contain-layout: ;--tw-contain-paint: ;--tw-contain-style: }*,:before,:after{box-sizing:border-box;border-width:0;border-style:solid;border-color:#e5e7eb}:before,:after{--tw-content: ""}html,:host{line-height:1.5;-webkit-text-size-adjust:100%;-moz-tab-size:4;-o-tab-size:4;tab-size:4;font-family:Inter,system-ui,sans-serif;font-feature-settings:normal;font-variation-settings:normal;-webkit-tap-highlight-color:transparent}body{margin:0;line-height:inherit}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;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:JetBrains Mono,ui-monospace,SFMono-Regular,monospace;font-feature-settings:normal;font-variation-settings:normal;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}button,input,optgroup,select,textarea{font-family:inherit;font-feature-settings:inherit;font-variation-settings:inherit;font-size:100%;font-weight:inherit;line-height:inherit;letter-spacing:inherit;color:inherit;margin:0;padding:0}button,select{text-transform:none}button,input:where([type=button]),input:where([type=reset]),input:where([type=submit]){-webkit-appearance:button;background-color:transparent;background-image:none}:-moz-focusring{outline:auto}:-moz-ui-invalid{box-shadow:none}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}blockquote,dl,dd,h1,h2,h3,h4,h5,h6,hr,figure,p,pre{margin:0}fieldset{margin:0;padding:0}legend{padding:0}ol,ul,menu{list-style:none;margin:0;padding:0}dialog{padding:0}textarea{resize:vertical}input::-moz-placeholder,textarea::-moz-placeholder{opacity:1;color:#9ca3af}input::placeholder,textarea::placeholder{opacity:1;color:#9ca3af}button,[role=button]{cursor:pointer}:disabled{cursor:default}img,svg,video,canvas,audio,iframe,embed,object{display:block;vertical-align:middle}img,video{max-width:100%;height:auto}[hidden]:where(:not([hidden=until-found])){display:none}.\!container{width:100%!important}.container{width:100%}@media (min-width: 640px){.\!container{max-width:640px!important}.container{max-width:640px}}@media (min-width: 768px){.\!container{max-width:768px!important}.container{max-width:768px}}@media (min-width: 1024px){.\!container{max-width:1024px!important}.container{max-width:1024px}}@media (min-width: 1280px){.\!container{max-width:1280px!important}.container{max-width:1280px}}@media (min-width: 1536px){.\!container{max-width:1536px!important}.container{max-width:1536px}}.pointer-events-none{pointer-events:none}.static{position:static}.fixed{position:fixed}.absolute{position:absolute}.relative{position:relative}.sticky{position:sticky}.inset-0{top:0;right:0;bottom:0;left:0}.-right-2{right:-.5rem}.-top-2{top:-.5rem}.left-0{left:0}.left-1\/2{left:50%}.right-0{right:0}.right-3{right:.75rem}.top-0{top:0}.top-1\/2{top:50%}.top-full{top:100%}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.mx-auto{margin-left:auto;margin-right:auto}.mb-4{margin-bottom:1rem}.mb-6{margin-bottom:1.5rem}.mt-0\.5{margin-top:.125rem}.mt-1{margin-top:.25rem}.mt-2{margin-top:.5rem}.mt-4{margin-top:1rem}.mt-auto{margin-top:auto}.inline-block{display:inline-block}.flex{display:flex}.inline-flex{display:inline-flex}.table{display:table}.grid{display:grid}.contents{display:contents}.hidden{display:none}.h-10{height:2.5rem}.h-12{height:3rem}.h-16{height:4rem}.h-2{height:.5rem}.h-3{height:.75rem}.h-3\.5{height:.875rem}.h-4{height:1rem}.h-5{height:1.25rem}.h-6{height:1.5rem}.h-7{height:1.75rem}.h-8{height:2rem}.h-9{height:2.25rem}.h-\[520px\]{height:520px}.h-full{height:100%}.max-h-60{max-height:15rem}.min-h-\[260px\]{min-height:260px}.min-h-\[96px\]{min-height:96px}.min-h-screen{min-height:100vh}.w-10{width:2.5rem}.w-12{width:3rem}.w-16{width:4rem}.w-2{width:.5rem}.w-24{width:6rem}.w-3{width:.75rem}.w-3\.5{width:.875rem}.w-4{width:1rem}.w-48{width:12rem}.w-5{width:1.25rem}.w-6{width:1.5rem}.w-60{width:15rem}.w-7{width:1.75rem}.w-8{width:2rem}.w-9{width:2.25rem}.w-fit{width:-moz-fit-content;width:fit-content}.w-full{width:100%}.w-max{width:-moz-max-content;width:max-content}.min-w-0{min-width:0px}.min-w-full{min-width:100%}.min-w-max{min-width:-moz-max-content;min-width:max-content}.max-w-2xl{max-width:42rem}.max-w-3xl{max-width:48rem}.max-w-4xl{max-width:56rem}.max-w-7xl{max-width:80rem}.max-w-\[140px\]{max-width:140px}.max-w-full{max-width:100%}.max-w-md{max-width:28rem}.flex-1{flex:1 1 0%}.flex-shrink-0,.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.-translate-x-1\/2{--tw-translate-x: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.-translate-y-1\/2{--tw-translate-y: -50%;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.translate-y-2{--tw-translate-y: .5rem;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.rotate-90{--tw-rotate: 90deg;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.transform{transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.cursor-pointer{cursor:pointer}.select-none{-webkit-user-select:none;-moz-user-select:none;user-select:none}.resize-none{resize:none}.appearance-none{-webkit-appearance:none;-moz-appearance:none;appearance:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-start{align-items:flex-start}.items-end{align-items:flex-end}.items-center{align-items:center}.items-stretch{align-items:stretch}.justify-end{justify-content:flex-end}.justify-center{justify-content:center}.justify-between{justify-content:space-between}.gap-0\.5{gap:.125rem}.gap-1{gap:.25rem}.gap-1\.5{gap:.375rem}.gap-12{gap:3rem}.gap-2{gap:.5rem}.gap-3{gap:.75rem}.gap-4{gap:1rem}.gap-5{gap:1.25rem}.gap-6{gap:1.5rem}.space-y-1>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.25rem * var(--tw-space-y-reverse))}.space-y-2>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.5rem * var(--tw-space-y-reverse))}.space-y-3>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(.75rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(.75rem * var(--tw-space-y-reverse))}.space-y-4>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1rem * var(--tw-space-y-reverse))}.space-y-5>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.25rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.25rem * var(--tw-space-y-reverse))}.space-y-6>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(1.5rem * var(--tw-space-y-reverse))}.space-y-8>:not([hidden])~:not([hidden]){--tw-space-y-reverse: 0;margin-top:calc(2rem * calc(1 - var(--tw-space-y-reverse)));margin-bottom:calc(2rem * var(--tw-space-y-reverse))}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.whitespace-pre-wrap{white-space:pre-wrap}.break-words{overflow-wrap:break-word}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:1rem}.rounded-full{border-radius:9999px}.rounded-lg{border-radius:.5rem}.rounded-md{border-radius:.375rem}.rounded-xl{border-radius:.75rem}.border{border-width:1px}.border-b{border-bottom-width:1px}.border-t{border-top-width:1px}.border-dashed{border-style:dashed}.border-border{--tw-border-opacity: 1;border-color:rgb(219 216 224 / var(--tw-border-opacity, 1))}.border-border\/60{border-color:#dbd8e099}.border-border\/70{border-color:#dbd8e0b3}.border-error\/40{border-color:#e5484d66}.border-red-6{--tw-border-opacity: 1;border-color:rgb(253 189 190 / var(--tw-border-opacity, 1))}.border-red-7\/50{border-color:#f4a9aa80}.bg-background{--tw-bg-opacity: 1;background-color:rgb(250 249 251 / var(--tw-bg-opacity, 1))}.bg-background\/60{background-color:#faf9fb99}.bg-background\/70{background-color:#faf9fbb3}.bg-background\/80{background-color:#faf9fbcc}.bg-black\/50{background-color:#00000080}.bg-blue-4\/50{background-color:#d5efff80}.bg-blue-5{--tw-bg-opacity: 1;background-color:rgb(194 229 255 / var(--tw-bg-opacity, 1))}.bg-blue-9{--tw-bg-opacity: 1;background-color:rgb(0 144 255 / var(--tw-bg-opacity, 1))}.bg-current{background-color:currentColor}.bg-error{--tw-bg-opacity: 1;background-color:rgb(229 72 77 / var(--tw-bg-opacity, 1))}.bg-red-3\/20{background-color:#feebec33}.bg-red-3\/50{background-color:#feebec80}.bg-red-3\/60{background-color:#feebec99}.bg-red-9{--tw-bg-opacity: 1;background-color:rgb(229 72 77 / var(--tw-bg-opacity, 1))}.bg-slate-12{--tw-bg-opacity: 1;background-color:rgb(28 32 36 / var(--tw-bg-opacity, 1))}.bg-slate-2{--tw-bg-opacity: 1;background-color:rgb(249 249 251 / var(--tw-bg-opacity, 1))}.bg-surface{--tw-bg-opacity: 1;background-color:rgb(242 239 243 / var(--tw-bg-opacity, 1))}.bg-surface\/60{background-color:#f2eff399}.bg-surface\/70{background-color:#f2eff3b3}.bg-surface\/80{background-color:#f2eff3cc}.bg-surface\/90{background-color:#f2eff3e6}.bg-surface\/95{background-color:#f2eff3f2}.bg-transparent{background-color:transparent}.object-contain{-o-object-fit:contain;object-fit:contain}.p-1{padding:.25rem}.p-4{padding:1rem}.p-5{padding:1.25rem}.p-6{padding:1.5rem}.p-8{padding:2rem}.px-2{padding-left:.5rem;padding-right:.5rem}.px-3{padding-left:.75rem;padding-right:.75rem}.px-4{padding-left:1rem;padding-right:1rem}.px-5{padding-left:1.25rem;padding-right:1.25rem}.px-6{padding-left:1.5rem;padding-right:1.5rem}.py-1{padding-top:.25rem;padding-bottom:.25rem}.py-1\.5{padding-top:.375rem;padding-bottom:.375rem}.py-10{padding-top:2.5rem;padding-bottom:2.5rem}.py-2{padding-top:.5rem;padding-bottom:.5rem}.py-2\.5{padding-top:.625rem;padding-bottom:.625rem}.py-3{padding-top:.75rem;padding-bottom:.75rem}.py-4{padding-top:1rem;padding-bottom:1rem}.py-8{padding-top:2rem;padding-bottom:2rem}.pr-9{padding-right:2.25rem}.pt-1{padding-top:.25rem}.pt-2{padding-top:.5rem}.text-left{text-align:left}.text-center{text-align:center}.align-top{vertical-align:top}.align-bottom{vertical-align:bottom}.font-mono{font-family:JetBrains Mono,ui-monospace,SFMono-Regular,monospace}.text-2xl{font-size:1.5rem;line-height:2rem}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.text-base{font-size:1rem;line-height:1.5rem}.text-lg{font-size:1.125rem;line-height:1.75rem}.text-sm{font-size:.875rem;line-height:1.25rem}.text-xs{font-size:.75rem;line-height:1rem}.font-bold{font-weight:700}.font-medium{font-weight:500}.font-normal{font-weight:400}.font-semibold{font-weight:600}.uppercase{text-transform:uppercase}.leading-5{line-height:1.25rem}.leading-relaxed{line-height:1.625}.leading-snug{line-height:1.375}.leading-tight{line-height:1.25}.tracking-wide{letter-spacing:.025em}.text-background-foreground{--tw-text-opacity: 1;color:rgb(33 31 38 / var(--tw-text-opacity, 1))}.text-blue-11{--tw-text-opacity: 1;color:rgb(13 116 206 / var(--tw-text-opacity, 1))}.text-blue-7{--tw-text-opacity: 1;color:rgb(142 200 246 / var(--tw-text-opacity, 1))}.text-blue-9{--tw-text-opacity: 1;color:rgb(0 144 255 / var(--tw-text-opacity, 1))}.text-error{--tw-text-opacity: 1;color:rgb(229 72 77 / var(--tw-text-opacity, 1))}.text-muted{--tw-text-opacity: 1;color:rgb(188 186 199 / var(--tw-text-opacity, 1))}.text-red-10{--tw-text-opacity: 1;color:rgb(220 62 66 / var(--tw-text-opacity, 1))}.text-red-11{--tw-text-opacity: 1;color:rgb(206 44 49 / var(--tw-text-opacity, 1))}.text-slate-10{--tw-text-opacity: 1;color:rgb(128 131 141 / var(--tw-text-opacity, 1))}.text-slate-11{--tw-text-opacity: 1;color:rgb(96 100 108 / var(--tw-text-opacity, 1))}.text-slate-12{--tw-text-opacity: 1;color:rgb(28 32 36 / var(--tw-text-opacity, 1))}.text-slate-9{--tw-text-opacity: 1;color:rgb(139 141 152 / var(--tw-text-opacity, 1))}.text-white{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.accent-blue-9{accent-color:#0090ff}.opacity-0{opacity:0}.shadow-inner{--tw-shadow: inset 0 2px 4px 0 rgb(0 0 0 / .05);--tw-shadow-colored: inset 0 2px 4px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-lg{--tw-shadow: 0 10px 15px -3px rgb(0 0 0 / .1), 0 4px 6px -4px rgb(0 0 0 / .1);--tw-shadow-colored: 0 10px 15px -3px var(--tw-shadow-color), 0 4px 6px -4px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-sm{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-soft{--tw-shadow: 0 10px 40px -15px rgba(15, 23, 42, .25);--tw-shadow-colored: 0 10px 40px -15px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.shadow-xl{--tw-shadow: 0 20px 25px -5px rgb(0 0 0 / .1), 0 8px 10px -6px rgb(0 0 0 / .1);--tw-shadow-colored: 0 20px 25px -5px var(--tw-shadow-color), 0 8px 10px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.outline-none{outline:2px solid transparent;outline-offset:2px}.ring-1{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.ring-border\/40{--tw-ring-color: rgb(219 216 224 / .4)}.blur{--tw-blur: blur(8px);filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.filter{filter:var(--tw-blur) var(--tw-brightness) var(--tw-contrast) var(--tw-grayscale) var(--tw-hue-rotate) var(--tw-invert) var(--tw-saturate) var(--tw-sepia) var(--tw-drop-shadow)}.backdrop-blur{--tw-backdrop-blur: blur(8px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-blur-sm{--tw-backdrop-blur: blur(4px);-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.backdrop-filter{-webkit-backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia);backdrop-filter:var(--tw-backdrop-blur) var(--tw-backdrop-brightness) var(--tw-backdrop-contrast) var(--tw-backdrop-grayscale) var(--tw-backdrop-hue-rotate) var(--tw-backdrop-invert) var(--tw-backdrop-opacity) var(--tw-backdrop-saturate) var(--tw-backdrop-sepia)}.transition{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-all{transition-property:all;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-colors{transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.transition-transform{transition-property:transform;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.duration-200{transition-duration:.2s}:root{color-scheme:light dark}body{--tw-bg-opacity: 1;background-color:rgb(250 249 251 / var(--tw-bg-opacity, 1));font-family:Inter,system-ui,sans-serif;--tw-text-opacity: 1;color:rgb(33 31 38 / var(--tw-text-opacity, 1));-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.dark body{background-color:#282a36}.theme-fade{animation:theme-fade .24s ease-out}@keyframes theme-fade{0%{opacity:.4;filter:saturate(.6) brightness(.9)}to{opacity:1;filter:none}}.animate-param-enter{animation:param-enter .22s ease-out}@keyframes param-enter{0%{opacity:0;transform:scale(.97) translateY(4px)}to{opacity:1;transform:scale(1) translateY(0)}}.modern-select{width:100%;-webkit-appearance:none;-moz-appearance:none;appearance:none;border-radius:.5rem;border-width:1px;--tw-border-opacity: 1;border-color:rgb(219 216 224 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(250 249 251 / var(--tw-bg-opacity, 1));padding:.5rem 2.25rem .5rem .75rem;font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(28 32 36 / var(--tw-text-opacity, 1));--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);transition-property:color,background-color,border-color,text-decoration-color,fill,stroke,opacity,box-shadow,transform,filter,backdrop-filter;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s}.dark .modern-select{background-color:#282a36;border-color:#44475a;color:#f8f8f2}.modern-select:focus-visible{--tw-border-opacity: 1;border-color:rgb(142 200 246 / var(--tw-border-opacity, 1));outline:2px solid transparent;outline-offset:2px}.modern-select:is(.dark *){--tw-border-opacity: 1;border-color:rgb(68 71 90 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(48 50 65 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(248 248 242 / var(--tw-text-opacity, 1))}.modern-select:focus-visible:is(.dark *){--tw-border-opacity: 1;border-color:rgb(189 147 249 / var(--tw-border-opacity, 1))}.dark input:not([type=checkbox]),.dark textarea,.dark select{--tw-border-opacity: 1;border-color:rgb(68 71 90 / var(--tw-border-opacity, 1));--tw-bg-opacity: 1;background-color:rgb(48 50 65 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(248 248 242 / var(--tw-text-opacity, 1))}.dark input:not([type=checkbox])::-moz-placeholder,.dark textarea::-moz-placeholder,.dark select::-moz-placeholder{--tw-placeholder-opacity: 1;color:rgb(98 114 164 / var(--tw-placeholder-opacity, 1))}.dark input:not([type=checkbox])::placeholder,.dark textarea::placeholder,.dark select::placeholder{--tw-placeholder-opacity: 1;color:rgb(98 114 164 / var(--tw-placeholder-opacity, 1))}.dark ::-moz-placeholder{--tw-text-opacity: 1;color:rgb(98 114 164 / var(--tw-text-opacity, 1))}.dark ::placeholder{--tw-text-opacity: 1;color:rgb(98 114 164 / var(--tw-text-opacity, 1))}.dark .bg-background{background-color:#282a36!important}.dark .bg-surface{background-color:#303241!important}.dark .border-border{border-color:#44475a!important}.dark .text-muted{color:#6272a4!important}.dark .shadow-soft{box-shadow:0 10px 40px -15px #000000a6}.dark .text-slate-12,.dark .text-slate-11,.dark .text-slate-10{color:#f8f8f2!important}.dark .text-slate-9,.dark .text-slate-8{color:#6272a4!important}.dark .group:hover.bg-background\/60{background-color:#484c5e8c!important}.radix-scroll-area-scrollbar{display:flex;touch-action:none;-webkit-user-select:none;-moz-user-select:none;user-select:none;background-color:transparent;padding:.125rem;transition-property:color,background-color,border-color,text-decoration-color,fill,stroke;transition-timing-function:cubic-bezier(.4,0,.2,1);transition-duration:.15s;transition-timing-function:cubic-bezier(0,0,.2,1)}.radix-scroll-area-thumb{flex:1 1 0%;border-radius:9999px;--tw-bg-opacity: 1;background-color:rgb(188 186 199 / var(--tw-bg-opacity, 1))}.radix-scroll-area-thumb:hover{--tw-bg-opacity: 1;background-color:rgb(142 140 153 / var(--tw-bg-opacity, 1))}.radix-scroll-area-thumb:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(68 71 90 / var(--tw-bg-opacity, 1))}.radix-scroll-area-thumb:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(98 114 164 / var(--tw-bg-opacity, 1))}button:focus-visible,input:focus-visible,textarea:focus-visible,select:focus-visible{outline:2px solid transparent;outline-offset:2px;--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000);--tw-ring-opacity: 1;--tw-ring-color: rgb(142 200 246 / var(--tw-ring-opacity, 1));--tw-ring-offset-width: 2px;--tw-ring-offset-color: #f2eff3}button:focus-visible:is(.dark *),input:focus-visible:is(.dark *),textarea:focus-visible:is(.dark *),select:focus-visible:is(.dark *){--tw-ring-opacity: 1;--tw-ring-color: rgb(189 147 249 / var(--tw-ring-opacity, 1));--tw-ring-offset-color: #303241}[data-status=success]{--tw-text-opacity: 1;color:rgb(48 164 108 / var(--tw-text-opacity, 1))}[data-status=warn],[data-status=warning]{--tw-text-opacity: 1;color:rgb(255 197 61 / var(--tw-text-opacity, 1))}[data-status=error]{--tw-text-opacity: 1;color:rgb(229 72 77 / var(--tw-text-opacity, 1))}[data-status=info]{--tw-text-opacity: 1;color:rgb(13 116 206 / var(--tw-text-opacity, 1))}[data-status=info]:is(.dark *){--tw-text-opacity: 1;color:rgb(189 147 249 / var(--tw-text-opacity, 1))}pre{overflow-x:auto;border-radius:.5rem;--tw-bg-opacity: 1;background-color:rgb(249 249 251 / var(--tw-bg-opacity, 1));padding:1rem;font-size:.875rem;line-height:1.25rem;--tw-text-opacity: 1;color:rgb(28 32 36 / var(--tw-text-opacity, 1))}.dark pre{color:#f8f8f2}pre:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(48 50 65 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(248 248 242 / var(--tw-text-opacity, 1))}.dark table thead tr{background-color:#ffffff0a!important}.dark table tbody tr.even\:bg-slate-2\/40{background-color:#ffffff05!important}.dark table tbody tr:hover{background-color:#bd93f91f!important}.prism-container{position:relative;height:100%;font-family:JetBrains Mono,ui-monospace,SFMono-Regular,monospace;font-size:.875rem;line-height:1.25rem}.prism-editor{position:absolute;top:0;right:0;bottom:0;left:0;height:100%;width:100%;resize:none;background-color:transparent;line-height:1.25rem;color:transparent;caret-color:#fff;outline:2px solid transparent;outline-offset:2px}.prism-highlight{pointer-events:none;white-space:pre-wrap;overflow-wrap:break-word;text-align:left;font-family:JetBrains Mono,ui-monospace,SFMono-Regular,monospace;line-height:1.25rem}.dark .prism-highlight{color:#f8f8f2}.prism-highlight .token.comment{color:#6272a4}.prism-highlight .token.key{color:#ff79c6}.prism-highlight .token.punctuation{color:#f8f8f2}.prism-highlight .token.string{color:#f1fa8c}.prism-highlight .token.number{color:#bd93f9}.prism-highlight .token.boolean{color:#ffb86c}.prism-highlight .token.null{color:#f55}.prism-highlight .token.directive{color:#8be9fd}.prism-highlight{position:relative;--ch: .62ch}.prism-highlight .editor-line{position:relative;padding-left:0}.prism-highlight .editor-line:before{content:attr(data-line);position:absolute;left:-.75rem;transform:translate(-100%);width:3rem;text-align:right;padding-right:.75rem;color:#64748b;font-size:.75rem;line-height:1.25rem;font-variant-numeric:tabular-nums;opacity:.65}.dark .prism-highlight .editor-line:before{color:#6272a4;opacity:.55}.prism-highlight .editor-line.error{background:#ff55551a;box-shadow:inset 0 0 0 1px #ff555559}.dark .prism-highlight .editor-line.error{background:#ff55552b;box-shadow:inset 0 0 0 1px #ff555573}.prism-highlight .editor-line .col-marker{position:absolute;top:0;bottom:0;width:2px;background:#f55;left:calc(var(--col) * var(--ch));pointer-events:none;opacity:.4}.dark .prism-highlight .editor-line .col-marker{background:#f55;opacity:.55}.prism-highlight .editor-line .err-char{background:linear-gradient(transparent 70%,#ff55558c 70%);border-radius:2px}.dark .prism-highlight .editor-line .err-char{background:linear-gradient(transparent 65%,#ff5555bf 65%)}.prism-highlight::-webkit-scrollbar{width:10px;height:10px}.prism-highlight::-webkit-scrollbar-track{background:transparent}.prism-highlight::-webkit-scrollbar-thumb{background:#64748b59;border-radius:6px}.dark .prism-highlight::-webkit-scrollbar-thumb{background:#f8f8f233}.prism-highlight::-webkit-scrollbar-thumb:hover{background:#64748b8c}.dark .prism-highlight::-webkit-scrollbar-thumb:hover{background:#f8f8f259}.prism-highlight,.prism-highlight .editor-line,.prism-highlight .line-content{pointer-events:none}.prism-editor{color:transparent;text-shadow:none}.dark .prism-editor{color:transparent}.prism-editor{caret-color:#111}.dark .prism-editor{caret-color:#f8f8f2}[role=tooltip]{animation:fadeIn .12s ease-out}@keyframes fadeIn{0%{opacity:0;transform:translate(-50%,4px)}to{opacity:1;transform:translate(-50%)}}.dark .btn-accent{--tw-bg-opacity: 1;background-color:rgb(189 147 249 / var(--tw-bg-opacity, 1));--tw-text-opacity: 1;color:rgb(248 248 242 / var(--tw-text-opacity, 1))}.dark .btn-accent:hover{--tw-bg-opacity: 1;background-color:rgb(255 121 198 / var(--tw-bg-opacity, 1))}.dark .border-accent{--tw-border-opacity: 1;border-color:rgb(189 147 249 / var(--tw-border-opacity, 1))}.validate-flash-success{animation:validateFlashSuccess 4s ease-in-out forwards}.validate-flash-error{animation:validateFlashError 4s ease-in-out forwards}@keyframes validateFlashSuccess{0%,85%{background:#30a46c;color:#fff}to{background:transparent;color:inherit}}@keyframes validateFlashError{0%,85%{background:#e5484d;color:#fff}to{background:transparent;color:inherit}}.dark button.validate-flash-success,.dark .validate-flash-success{animation:darkValidateFlashSuccess 4s ease-in-out forwards;position:relative}.dark button.validate-flash-error,.dark .validate-flash-error{animation:darkValidateFlashError 4s ease-in-out forwards;position:relative}.dark button.validate-flash-success:after,.dark .validate-flash-success:after,.dark button.validate-flash-error:after,.dark .validate-flash-error:after{content:"";position:absolute;top:0;right:0;bottom:0;left:0;border-radius:inherit;pointer-events:none}.dark button.validate-flash-success:after,.dark .validate-flash-success:after{background:radial-gradient(circle at 30% 30%,#50fa7b59,#50fa7b0d)}.dark button.validate-flash-error:after,.dark .validate-flash-error:after{background:radial-gradient(circle at 30% 30%,#f556,#ff55550f)}@keyframes darkValidateFlashSuccess{0%,85%{background-color:#50fa7b40!important;color:#fff!important;border-color:#50fa7b8c!important;box-shadow:0 0 #50fa7b99,0 0 16px 4px #50fa7b59}to{background-color:transparent!important;color:inherit!important;border-color:var(--border-color,rgba(100,100,120,.4))!important;box-shadow:none}}@keyframes darkValidateFlashError{0%,85%{background-color:#ff555547!important;color:#fff!important;border-color:#ff55558c!important;box-shadow:0 0 #f559,0 0 16px 4px #ff555561}to{background-color:transparent!important;color:inherit!important;border-color:var(--border-color,rgba(100,100,120,.4))!important;box-shadow:none}}.dark .bg-blue-9{transition:background-color .3s ease,box-shadow .4s ease}.dark .bg-blue-9:hover{box-shadow:0 0 #bd93f900,0 0 12px 2px #bd93f959}.even\:bg-slate-2\/40:nth-child(2n){background-color:#f9f9fb66}.hover\:scale-105:hover{--tw-scale-x: 1.05;--tw-scale-y: 1.05;transform:translate(var(--tw-translate-x),var(--tw-translate-y)) rotate(var(--tw-rotate)) skew(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y))}.hover\:border-blue-7:hover{--tw-border-opacity: 1;border-color:rgb(142 200 246 / var(--tw-border-opacity, 1))}.hover\:border-blue-7\/60:hover{border-color:#8ec8f699}.hover\:border-red-7:hover{--tw-border-opacity: 1;border-color:rgb(244 169 170 / var(--tw-border-opacity, 1))}.hover\:bg-blue-10:hover{--tw-bg-opacity: 1;background-color:rgb(5 136 240 / var(--tw-bg-opacity, 1))}.hover\:bg-blue-3\/20:hover{background-color:#e6f4fe33}.hover\:bg-blue-3\/40:hover{background-color:#e6f4fe66}.hover\:bg-blue-3\/50:hover{background-color:#e6f4fe80}.hover\:bg-blue-3\/60:hover{background-color:#e6f4fe99}.hover\:bg-blue-5\/10:hover{background-color:#c2e5ff1a}.hover\:bg-red-10:hover{--tw-bg-opacity: 1;background-color:rgb(220 62 66 / var(--tw-bg-opacity, 1))}.hover\:bg-red-3\/40:hover{background-color:#feebec66}.hover\:bg-red-3\/60:hover{background-color:#feebec99}.hover\:bg-slate-3:hover{--tw-bg-opacity: 1;background-color:rgb(240 240 243 / var(--tw-bg-opacity, 1))}.hover\:text-blue-11:hover{--tw-text-opacity: 1;color:rgb(13 116 206 / var(--tw-text-opacity, 1))}.hover\:text-red-10:hover{--tw-text-opacity: 1;color:rgb(220 62 66 / var(--tw-text-opacity, 1))}.hover\:text-red-9:hover{--tw-text-opacity: 1;color:rgb(229 72 77 / var(--tw-text-opacity, 1))}.hover\:text-slate-12:hover{--tw-text-opacity: 1;color:rgb(28 32 36 / var(--tw-text-opacity, 1))}.hover\:shadow-md:hover{--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.hover\:shadow-sm:hover{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.focus\:border-blue-7:focus{--tw-border-opacity: 1;border-color:rgb(142 200 246 / var(--tw-border-opacity, 1))}.focus\:outline-none:focus{outline:2px solid transparent;outline-offset:2px}.focus\:ring-blue-5:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(194 229 255 / var(--tw-ring-opacity, 1))}.focus\:ring-blue-7:focus{--tw-ring-opacity: 1;--tw-ring-color: rgb(142 200 246 / var(--tw-ring-opacity, 1))}.focus-visible\:border-blue-7:focus-visible{--tw-border-opacity: 1;border-color:rgb(142 200 246 / var(--tw-border-opacity, 1))}.focus-visible\:bg-blue-9:focus-visible{--tw-bg-opacity: 1;background-color:rgb(0 144 255 / var(--tw-bg-opacity, 1))}.focus-visible\:text-white:focus-visible{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.focus-visible\:opacity-100:focus-visible{opacity:1}.focus-visible\:outline-none:focus-visible{outline:2px solid transparent;outline-offset:2px}.focus-visible\:ring-1:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-2:focus-visible{--tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);--tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color);box-shadow:var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow, 0 0 #0000)}.focus-visible\:ring-blue-5:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: rgb(194 229 255 / var(--tw-ring-opacity, 1))}.focus-visible\:ring-blue-7:focus-visible{--tw-ring-opacity: 1;--tw-ring-color: rgb(142 200 246 / var(--tw-ring-opacity, 1))}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.group:hover .group-hover\:border-blue-7\/50{border-color:#8ec8f680}.group:hover .group-hover\:bg-blue-5\/80{background-color:#c2e5ffcc}.group:hover .group-hover\:opacity-100{opacity:1}.data-\[state\=active\]\:border-b-2[data-state=active]{border-bottom-width:2px}.data-\[state\=active\]\:border-blue-9[data-state=active]{--tw-border-opacity: 1;border-color:rgb(0 144 255 / var(--tw-border-opacity, 1))}.data-\[state\=active\]\:bg-blue-9[data-state=active]{--tw-bg-opacity: 1;background-color:rgb(0 144 255 / var(--tw-bg-opacity, 1))}.data-\[state\=checked\]\:bg-blue-4[data-state=checked]{--tw-bg-opacity: 1;background-color:rgb(213 239 255 / var(--tw-bg-opacity, 1))}.data-\[state\=active\]\:text-blue-11[data-state=active]{--tw-text-opacity: 1;color:rgb(13 116 206 / var(--tw-text-opacity, 1))}.data-\[state\=active\]\:text-white[data-state=active]{--tw-text-opacity: 1;color:rgb(255 255 255 / var(--tw-text-opacity, 1))}.data-\[state\=active\]\:shadow-sm[data-state=active]{--tw-shadow: 0 1px 2px 0 rgb(0 0 0 / .05);--tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}@supports (backdrop-filter: var(--tw)){.supports-\[backdrop-filter\]\:bg-slate-2\/75{background-color:#f9f9fbbf}}.dark\:border-\[\#2c313a\]:is(.dark *){--tw-border-opacity: 1;border-color:rgb(44 49 58 / var(--tw-border-opacity, 1))}.dark\:border-drac-border:is(.dark *){--tw-border-opacity: 1;border-color:rgb(68 71 90 / var(--tw-border-opacity, 1))}.dark\:border-drac-border\/50:is(.dark *){border-color:#44475a80}.dark\:border-drac-border\/60:is(.dark *){border-color:#44475a99}.dark\:border-drac-border\/70:is(.dark *){border-color:#44475ab3}.dark\:border-drac-red\/40:is(.dark *){border-color:#f556}.dark\:border-slate-6:is(.dark *){--tw-border-opacity: 1;border-color:rgb(217 217 224 / var(--tw-border-opacity, 1))}.dark\:bg-\[\#1d2026\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(29 32 38 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#1f232b\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(31 35 43 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#1f232b\]\/60:is(.dark *){background-color:#1f232b99}.dark\:bg-\[\#1f232b\]\/80:is(.dark *){background-color:#1f232bcc}.dark\:bg-\[\#202530\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(32 37 48 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#242a33\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(36 42 51 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#262c35\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(38 44 53 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#272d38\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(39 45 56 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#282a36\]\/50:is(.dark *){background-color:#282a3680}.dark\:bg-\[\#282a36\]\/70:is(.dark *){background-color:#282a36b3}.dark\:bg-\[\#2d3541\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(45 53 65 / var(--tw-bg-opacity, 1))}.dark\:bg-\[\#303745\]:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(48 55 69 / var(--tw-bg-opacity, 1))}.dark\:bg-blue-7\/40:is(.dark *){background-color:#8ec8f666}.dark\:bg-blue-9\/20:is(.dark *){background-color:#0090ff33}.dark\:bg-drac-accent:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(189 147 249 / var(--tw-bg-opacity, 1))}.dark\:bg-drac-base:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(40 42 54 / var(--tw-bg-opacity, 1))}.dark\:bg-drac-red\/25:is(.dark *){background-color:#ff555540}.dark\:bg-drac-surface:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(48 50 65 / var(--tw-bg-opacity, 1))}.dark\:bg-drac-surface\/60:is(.dark *){background-color:#30324199}.dark\:bg-drac-surface\/80:is(.dark *){background-color:#303241cc}.dark\:bg-red-9\/15:is(.dark *){background-color:#e5484d26}.dark\:bg-slate-1:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(252 252 253 / var(--tw-bg-opacity, 1))}.dark\:bg-slate-2:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(249 249 251 / var(--tw-bg-opacity, 1))}.dark\:text-blue-9:is(.dark *){--tw-text-opacity: 1;color:rgb(0 144 255 / var(--tw-text-opacity, 1))}.dark\:text-drac-accent:is(.dark *){--tw-text-opacity: 1;color:rgb(189 147 249 / var(--tw-text-opacity, 1))}.dark\:text-drac-foreground:is(.dark *){--tw-text-opacity: 1;color:rgb(248 248 242 / var(--tw-text-opacity, 1))}.dark\:text-drac-foreground\/80:is(.dark *){color:#f8f8f2cc}.dark\:text-drac-foreground\/90:is(.dark *){color:#f8f8f2e6}.dark\:text-drac-muted:is(.dark *){--tw-text-opacity: 1;color:rgb(98 114 164 / var(--tw-text-opacity, 1))}.dark\:text-red-9:is(.dark *){--tw-text-opacity: 1;color:rgb(229 72 77 / var(--tw-text-opacity, 1))}.dark\:text-slate-12:is(.dark *){--tw-text-opacity: 1;color:rgb(28 32 36 / var(--tw-text-opacity, 1))}.dark\:accent-drac-accent:is(.dark *){accent-color:#bd93f9}.dark\:shadow-\[0_8px_24px_-6px_rgba\(0\,0\,0\,0\.7\)\]:is(.dark *){--tw-shadow: 0 8px 24px -6px rgba(0,0,0,.7);--tw-shadow-colored: 0 8px 24px -6px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.dark\:ring-drac-border\/30:is(.dark *){--tw-ring-color: rgb(68 71 90 / .3)}.dark\:hover\:border-drac-accent:hover:is(.dark *){--tw-border-opacity: 1;border-color:rgb(189 147 249 / var(--tw-border-opacity, 1))}.dark\:hover\:border-drac-accent\/60:hover:is(.dark *){border-color:#bd93f999}.dark\:hover\:border-drac-red\/80:hover:is(.dark *){border-color:#f55c}.dark\:hover\:bg-\[\#273242\]:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(39 50 66 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-\[\#283546\]:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(40 53 70 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-\[\#383f4c\]:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(56 63 76 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-\[\#3a3f4b\]:hover:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(58 63 75 / var(--tw-bg-opacity, 1))}.dark\:hover\:bg-blue-9\/10:hover:is(.dark *){background-color:#0090ff1a}.dark\:hover\:bg-blue-9\/20:hover:is(.dark *){background-color:#0090ff33}.dark\:hover\:bg-blue-9\/25:hover:is(.dark *){background-color:#0090ff40}.dark\:hover\:bg-blue-9\/30:hover:is(.dark *){background-color:#0090ff4d}.dark\:hover\:bg-drac-base\/60:hover:is(.dark *){background-color:#282a3699}.dark\:hover\:text-drac-accent:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(189 147 249 / var(--tw-text-opacity, 1))}.dark\:hover\:text-drac-foreground:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(248 248 242 / var(--tw-text-opacity, 1))}.dark\:hover\:text-drac-red:hover:is(.dark *){--tw-text-opacity: 1;color:rgb(255 85 85 / var(--tw-text-opacity, 1))}.dark\:hover\:shadow-\[0_0_8px_rgba\(80\,250\,123\,0\.15\)\]:hover:is(.dark *){--tw-shadow: 0 0 8px rgba(80,250,123,.15);--tw-shadow-colored: 0 0 8px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow)}.dark\:focus\:border-drac-accent:focus:is(.dark *){--tw-border-opacity: 1;border-color:rgb(189 147 249 / var(--tw-border-opacity, 1))}.dark\:focus\:ring-drac-accent:focus:is(.dark *){--tw-ring-opacity: 1;--tw-ring-color: rgb(189 147 249 / var(--tw-ring-opacity, 1))}.dark\:focus\:ring-drac-accent\/40:focus:is(.dark *){--tw-ring-color: rgb(189 147 249 / .4)}.dark\:focus-visible\:border-drac-accent:focus-visible:is(.dark *){--tw-border-opacity: 1;border-color:rgb(189 147 249 / var(--tw-border-opacity, 1))}.dark\:focus-visible\:bg-drac-accent:focus-visible:is(.dark *){--tw-bg-opacity: 1;background-color:rgb(189 147 249 / var(--tw-bg-opacity, 1))}.dark\:focus-visible\:ring-drac-accent:focus-visible:is(.dark *){--tw-ring-opacity: 1;--tw-ring-color: rgb(189 147 249 / var(--tw-ring-opacity, 1))}.dark\:focus-visible\:ring-drac-accent\/40:focus-visible:is(.dark *){--tw-ring-color: rgb(189 147 249 / .4)}.group:hover .dark\:group-hover\:bg-blue-9\/30:is(.dark *){background-color:#0090ff4d}.dark\:data-\[state\=active\]\:border-drac-accent[data-state=active]:is(.dark *){--tw-border-opacity: 1;border-color:rgb(189 147 249 / var(--tw-border-opacity, 1))}.dark\:data-\[state\=active\]\:text-drac-accent[data-state=active]:is(.dark *){--tw-text-opacity: 1;color:rgb(189 147 249 / var(--tw-text-opacity, 1))}@supports (backdrop-filter: var(--tw)){.dark\:supports-\[backdrop-filter\]\:bg-drac-surface\/70:is(.dark *){background-color:#303241b3}}@media (min-width: 768px){.md\:grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}}@media (min-width: 1024px){.lg\:grid-cols-\[minmax\(0\,1fr\)_minmax\(200px\,auto\)\]{grid-template-columns:minmax(0,1fr) minmax(200px,auto)}.lg\:items-end{align-items:flex-end}.lg\:px-6{padding-left:1.5rem;padding-right:1.5rem}}.\[\&_td\]\:whitespace-nowrap td{white-space:nowrap}.\[\&_td\]\:whitespace-pre-wrap td{white-space:pre-wrap}
|