@jaato/web-coder-ui 0.1.3 → 0.1.10

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.
Files changed (39) hide show
  1. package/README.md +85 -3
  2. package/bin/jaato-web-coder-ui.d.ts +2 -0
  3. package/dist/assets/barlow-condensed-latin-500-normal-BgYH2mbd.woff2 +0 -0
  4. package/dist/assets/barlow-condensed-latin-500-normal-HIEiP5Ov.woff +0 -0
  5. package/dist/assets/barlow-condensed-latin-600-normal-BFJEwTuo.woff +0 -0
  6. package/dist/assets/barlow-condensed-latin-600-normal-DepVgxBB.woff2 +0 -0
  7. package/dist/assets/barlow-condensed-latin-ext-500-normal-B1RE8WP7.woff +0 -0
  8. package/dist/assets/barlow-condensed-latin-ext-500-normal-yA5ONLQ9.woff2 +0 -0
  9. package/dist/assets/barlow-condensed-latin-ext-600-normal-18ESti3H.woff2 +0 -0
  10. package/dist/assets/barlow-condensed-latin-ext-600-normal-Clv9cIcR.woff +0 -0
  11. package/dist/assets/barlow-condensed-vietnamese-500-normal-CsrJDWc5.woff +0 -0
  12. package/dist/assets/barlow-condensed-vietnamese-500-normal-DjeaNLFD.woff2 +0 -0
  13. package/dist/assets/barlow-condensed-vietnamese-600-normal-A5AYRdjN.woff2 +0 -0
  14. package/dist/assets/barlow-condensed-vietnamese-600-normal-CNlPk46_.woff +0 -0
  15. package/dist/assets/barlow-latin-400-normal-fsAxiSwU.woff +0 -0
  16. package/dist/assets/barlow-latin-400-normal-qiz4-Cze.woff2 +0 -0
  17. package/dist/assets/barlow-latin-500-normal-BPAOfeC8.woff2 +0 -0
  18. package/dist/assets/barlow-latin-500-normal-C1h8hMer.woff +0 -0
  19. package/dist/assets/barlow-latin-600-normal-CNwfPWQD.woff +0 -0
  20. package/dist/assets/barlow-latin-600-normal-DILqtrty.woff2 +0 -0
  21. package/dist/assets/barlow-latin-ext-400-normal-CvBsJvxq.woff +0 -0
  22. package/dist/assets/barlow-latin-ext-400-normal-HxX4XjxC.woff2 +0 -0
  23. package/dist/assets/barlow-latin-ext-500-normal-CJPcKP2Q.woff +0 -0
  24. package/dist/assets/barlow-latin-ext-500-normal-DOaysfXq.woff2 +0 -0
  25. package/dist/assets/barlow-latin-ext-600-normal-B8NK_A3D.woff2 +0 -0
  26. package/dist/assets/barlow-latin-ext-600-normal-DMVRjfRT.woff +0 -0
  27. package/dist/assets/barlow-vietnamese-400-normal-BFeobeCK.woff +0 -0
  28. package/dist/assets/barlow-vietnamese-400-normal-Dpl4UHAZ.woff2 +0 -0
  29. package/dist/assets/barlow-vietnamese-500-normal-GNfB7rCE.woff +0 -0
  30. package/dist/assets/barlow-vietnamese-500-normal-zTViEIzf.woff2 +0 -0
  31. package/dist/assets/barlow-vietnamese-600-normal-CA_GiK2e.woff +0 -0
  32. package/dist/assets/barlow-vietnamese-600-normal-DcjprdFV.woff2 +0 -0
  33. package/dist/assets/index-D6cHhK7P.css +1 -0
  34. package/dist/assets/index-OELmzDkd.js +30 -0
  35. package/dist/build-info.json +3 -3
  36. package/dist/index.html +2 -2
  37. package/package.json +3 -1
  38. package/dist/assets/index-BP-An1YV.css +0 -1
  39. package/dist/assets/index-CtAym22p.js +0 -26
package/README.md CHANGED
@@ -15,10 +15,36 @@ Design notes, stack rationale and the input model live in
15
15
  | UI | React 19 + Vite 7 | largest widget ecosystem for the pieces a client like this needs (virtualised lists, docking, terminals) |
16
16
  | State | Zustand, one event-sourced reducer | the protocol is a stream of typed events; the store folds them, components subscribe to slices |
17
17
  | Protocol | `@jaato/sdk` (workspace `file:` dep, source-aliased) | codegen'd event types stay in lockstep with `events.py`; no hand-written event mirror |
18
- | Styling | Tailwind v4 + CSS variables | the eleven base colours of the TUI's `themes/*.json` become CSS custom properties, so both clients share one palette definition |
18
+ | Styling | Tailwind v4 + CSS variables | the eleven base colours of the TUI's `themes/*.json` become CSS custom properties, so both clients share one palette definition; the redesign's plates, chrome type and interface accent are one layer on top of them (see [Look](#look)) |
19
19
  | Rendering | own `<j-*>` + markdown parsers, no `innerHTML` | the server emits neutral markup (`<j-code>`, `<j-table>`, Pygments token classes); the client only maps classes to theme colours |
20
20
  | Tests | Vitest (protocol, store) + Playwright (UI against a scripted mock daemon) | |
21
21
 
22
+ ## Look
23
+
24
+ The client is drawn on a blueprint (Claude Design, *Jaato Web UI
25
+ Redesign*, proposal 01c): square, hairline-bordered **plates** with
26
+ registration marks at their corners, **Barlow Condensed** for what the
27
+ interface says (kickers, buttons, tab names) and monospace reserved for
28
+ what the daemon said (ids, paths, models, arguments), and one **steel**
29
+ interface accent carrying the chrome while the theme's own colours shrink
30
+ to state glyphs. The light face (`theme light`, the default) is the
31
+ design's paper ground; `theme dark` and the other four TUI themes draw the
32
+ same structure on their own ground, because the structure is written in
33
+ terms of the theme variables plus a derived `--c-steel`
34
+ (`src/theme/themes.ts`). Fonts are self-hosted from `@fontsource`, so a
35
+ deployment behind a corporate proxy needs no font CDN.
36
+
37
+ The five screens the design draws: the connect plate (what jaato is on the
38
+ left, the one thing to do on the right, daemon settings behind a
39
+ disclosure, the build stamp at the foot); workspaces as a table;
40
+ new-session with resume and start side by side; the session with its
41
+ identity in a 46px header (brand, agent tabs, workspace / model / context),
42
+ tool calls as rows, user turns numbered in the gutter, one persistent rail
43
+ whose Plan / Budget / Files sections open and close (same toggles as
44
+ before: `Ctrl+P` / `Ctrl+B` / `Alt+W` and the status bar), and a 26px
45
+ status bar; and the permission request as a full-width warning plate with
46
+ the diff at full measure and one solid action.
47
+
22
48
  ## Commands are words, not `/verbs`
23
49
 
24
50
  jaato commands are typed as bare words: `model gpt-4o`, `tools enable cli`,
@@ -31,6 +57,26 @@ with a command word. A hint under the box always states what Enter will do.
31
57
  as in the TUI. See `src/protocol/commands.ts` for the routing rules, which
32
58
  are a port of `jaato-tui/client_commands.py`.
33
59
 
60
+ ## Files go into the workspace, not the prompt
61
+
62
+ Drop files on the composer, paste them, or press **Attach**, and they are
63
+ **staged into the session's workspace** on the daemon — the same
64
+ `StageFilesRequest` verb the premium `<jaato-task>` component uses (one
65
+ JSON frame naming the files, one binary frame each, one answer per file;
66
+ `docs/sdk-file-staging.md`). A strip above the box shows each file's state
67
+ (queued / staging / ✓ staged / ✗ with the daemon's reason), the Files
68
+ panel lists them as the daemon's monitor sees them, and the next message
69
+ ends with one line naming the paths so the model knows where they are:
70
+ `@path` then reads them. The strip's **into** field picks a folder for the
71
+ files that follow; a dropped directory keeps its structure.
72
+
73
+ The session picker has the same strip, for a session that should start
74
+ with files in place: with a workspace selected they are staged before
75
+ `session.new`; on a daemon that provisions the workspace as part of
76
+ `session.new` they wait for its `session.info` and are staged then, still
77
+ ahead of the first turn. The daemon caps a file at 10 MB and a request at
78
+ 50 MB; the client applies the same caps before sending.
79
+
34
80
  ## Run it
35
81
 
36
82
  The client is published on npm as `@jaato/web-coder-ui`; the package is the built
@@ -87,6 +133,40 @@ a workspace goes straight to that card whether or not the workspace already
87
133
  names a provider. The daemon's manual provider / model / API-key form is one
88
134
  click away behind `configure` on each row, never a gate.
89
135
 
136
+ Served by `jaato-web-coder-server` with its key store enabled (`config.json`
137
+ names `credentialsUrl`), that form's API-key field is a combobox of the keys
138
+ you stored before for the selected provider — label and a masked hint, never
139
+ the secret — plus "New key…". The newest one is preselected, so a second
140
+ workspace on the same provider is one click; the key is revealed once when
141
+ you save and forwarded to the daemon exactly as a typed one is. A
142
+ `<provider>-auth key …` typed at the prompt is remembered the same way. The
143
+ daemon knows nothing of the store: it is the backend's, keyed by who signed
144
+ in (`src/app/credentials.ts`, `src/components/workspace/CredentialPicker.tsx`).
145
+
146
+ Two ways out, as buttons. The workspace list's header says who is signed in
147
+ and offers the backend's **Sign out** (which also revokes that user's
148
+ daemon tickets); without a backend it offers **Disconnect** instead. The
149
+ status bar's **exit** is the `exit` command, and like the TUI's it asks
150
+ first what should become of the session (`src/app/exitChoice.ts`):
151
+ **Detach** `d` leaves it on the daemon for `session attach` later and
152
+ returns to the connect screen; **End session** `e` deletes it
153
+ (`session.delete`, which never touches the workspace directory) and lands
154
+ on the workspace list where there is one, else the connect screen; with a
155
+ turn in flight **Cancel task and exit** `c` stops it first and detaches;
156
+ **Return** `r` (or Escape) goes back. A typed key answers the plate as it
157
+ does a permission prompt. A page served with `autoConnect` does not
158
+ connect straight back after an exit; the next click does
159
+ (`src/app/exitIntent.ts`).
160
+
161
+ Leaving drops this client's session state, because that is what it
162
+ describes, so coming back opens the picker rather than a detached session's
163
+ transcript. A new session starts on an empty pane, as attaching to one
164
+ always has. And a reconnect re-asserts what the client believes before
165
+ anything else goes out: the daemon keeps the workspace selection and the
166
+ session attachment per connection, so without it the next staged file is
167
+ refused and the next session resolves no `.env` (`reassertAfterReconnect`
168
+ in `src/sdk/connection.ts`).
169
+
90
170
  ### Hosting the bundle yourself
91
171
 
92
172
  `dist/` is static (assets are referenced relatively, so it can sit under any
@@ -194,7 +274,8 @@ src/
194
274
  input/Composer.tsx prompts/ (Permission, Clarification, ReferenceSelection)
195
275
  panels/ (Plan, Budget, Workspace, AgentTabs) layout/StatusBar.tsx
196
276
  screens/ ConnectScreen, WorkspaceScreen, SessionScreen
197
- theme/ themes.ts (imports ../jaato-tui/themes/*.json), theme.css
277
+ theme/ themes.ts (imports ../jaato-tui/themes/*.json, derives the steel accent), theme.css (tokens, plates, chrome type)
278
+ components/layout/Plate.tsx the redesign's unit of surface: a square hairline plate with registration marks
198
279
  mock/daemon.ts scripted daemon speaking the wire protocol, for dev + e2e
199
280
  e2e/ Playwright smoke suite
200
281
  ```
@@ -204,4 +285,5 @@ e2e/ Playwright smoke suite
204
285
  `Enter` send · `Shift+Enter` newline · `Tab` complete / re-arm proposals ·
205
286
  `Esc` dismiss proposal (send verbatim) · `Ctrl+P` plan · `Ctrl+B` budget ·
206
287
  `Alt+W` files · `Ctrl+T` expand/collapse tools · `Ctrl+A` next agent ·
207
- `Ctrl+O` next running tool in the popup · `Ctrl+C` (nothing selected) stop.
288
+ `Ctrl+O` next running tool in the popup · `Ctrl+C` (nothing selected) stop ·
289
+ drop / paste a file on the composer to stage it into the workspace.
@@ -15,6 +15,8 @@ export interface StaticConfig {
15
15
  token?: string;
16
16
  ticketUrl?: string;
17
17
  loginUrl?: string;
18
+ /** Where the sign-in backend keeps the user's provider API keys; absent = no combobox, a plain key field. */
19
+ credentialsUrl?: string;
18
20
  autoConnect?: boolean;
19
21
  }
20
22
 
@@ -0,0 +1 @@
1
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0;--tw-rotate-x:initial;--tw-rotate-y:initial;--tw-rotate-z:initial;--tw-skew-x:initial;--tw-skew-y:initial;--tw-space-y-reverse:0;--tw-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid}}}@layer theme{:root,:host{--font-sans:var(--font-sans);--font-mono:var(--font-mono);--spacing:.25rem;--container-md:28rem;--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 ;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-normal:0em;--radius-md:.375rem;--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);--font-heading:var(--font-heading)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab,red,red)){::placeholder{color:color-mix(in oklab,currentcolor 50%,transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.collapse{visibility:collapse}.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.sticky{position:sticky}.right-5{right:calc(var(--spacing) * 5)}.bottom-3{bottom:calc(var(--spacing) * 3)}.bottom-\[104px\]{bottom:104px}.bottom-full{bottom:100%}.left-0{left:0}.left-1\/2{left:50%}.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}}.m-0{margin:0}.mx-0\.5{margin-inline:calc(var(--spacing) * .5)}.my-1\.5{margin-block:calc(var(--spacing) * 1.5)}.my-2{margin-block:calc(var(--spacing) * 2)}.my-2\.5{margin-block:calc(var(--spacing) * 2.5)}.my-3{margin-block:calc(var(--spacing) * 3)}.mt-0\.5{margin-top:calc(var(--spacing) * .5)}.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-2\.5{margin-top:calc(var(--spacing) * 2.5)}.mt-3{margin-top:calc(var(--spacing) * 3)}.mt-auto{margin-top:auto}.-mr-\[4px\]{margin-right:-4px}.mr-2{margin-right:calc(var(--spacing) * 2)}.mb-1\.5{margin-bottom:calc(var(--spacing) * 1.5)}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-2\.5{margin-bottom:calc(var(--spacing) * 2.5)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.-ml-\[3px\]{margin-left:-3px}.ml-6{margin-left:calc(var(--spacing) * 6)}.ml-auto{margin-left:auto}.block{display:block}.contents{display:contents}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-1\.5{height:calc(var(--spacing) * 1.5)}.h-\[26px\]{height:26px}.h-\[46px\]{height:46px}.h-full{height:100%}.max-h-60{max-height:calc(var(--spacing) * 60)}.max-h-72{max-height:calc(var(--spacing) * 72)}.max-h-80{max-height:calc(var(--spacing) * 80)}.max-h-96{max-height:calc(var(--spacing) * 96)}.max-h-\[40vh\]{max-height:40vh}.max-h-\[45vh\]{max-height:45vh}.max-h-\[60\%\]{max-height:60%}.max-h-\[60vh\]{max-height:60vh}.min-h-0{min-height:0}.min-h-5{min-height:calc(var(--spacing) * 5)}.w-1\.5{width:calc(var(--spacing) * 1.5)}.w-3{width:calc(var(--spacing) * 3)}.w-9{width:calc(var(--spacing) * 9)}.w-40{width:calc(var(--spacing) * 40)}.w-\[7px\]{width:7px}.w-\[22px\]{width:22px}.w-\[52px\]{width:52px}.w-\[84px\]{width:84px}.w-\[120px\]{width:120px}.w-\[min\(34rem\,100\%\)\]{width:min(34rem,100%)}.w-\[min\(560px\,70\%\)\]{width:min(560px,70%)}.w-full{width:100%}.max-w-\[16rem\]{max-width:16rem}.max-w-\[18rem\]{max-width:18rem}.max-w-\[34ch\]{max-width:34ch}.max-w-\[36ch\]{max-width:36ch}.max-w-\[52ch\]{max-width:52ch}.max-w-\[76\%\]{max-width:76%}.max-w-\[860px\]{max-width:860px}.max-w-\[880px\]{max-width:880px}.max-w-md{max-width:var(--container-md)}.min-w-0{min-width:0}.flex-1{flex:1}.shrink{flex-shrink:1}.shrink-0{flex-shrink:0}.border-collapse{border-collapse:collapse}.-translate-x-1\/2{--tw-translate-x: -50% ;translate:var(--tw-translate-x) var(--tw-translate-y)}.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}.resize{resize:both}.resize-none{resize:none}.list-none{list-style-type:none}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-\[max-content_1fr\]{grid-template-columns:max-content 1fr}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-baseline{align-items:baseline}.items-center{align-items:center}.items-end{align-items:flex-end}.items-start{align-items:flex-start}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-0\.5{gap:calc(var(--spacing) * .5)}.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-\[18px\]{gap:18px}:where(.space-y-0\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * .5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * .5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(var(--spacing) * var(--tw-space-y-reverse));margin-block-end:calc(var(--spacing) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-3>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 3) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 3) * calc(1 - var(--tw-space-y-reverse)))}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-y-1{row-gap:var(--spacing)}.gap-y-1\.5{row-gap:calc(var(--spacing) * 1.5)}.self-center{align-self:center}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-0{border-style:var(--tw-border-style);border-width:0}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-l-2{border-left-style:var(--tw-border-style);border-left-width:2px}.border-error,.border-error\/40{border-color:var(--c-error)}@supports (color:color-mix(in lab,red,red)){.border-error\/40{border-color:color-mix(in oklab,var(--c-error) 40%,transparent)}}.border-steel{border-color:var(--c-steel)}.border-transparent{border-color:#0000}.border-warning{border-color:var(--c-warning)}.bg-\[color-mix\(in_srgb\,var\(--c-text\)_16\%\,var\(--c-bg\)\)\]{background-color:var(--c-text)}@supports (color:color-mix(in lab,red,red)){.bg-\[color-mix\(in_srgb\,var\(--c-text\)_16\%\,var\(--c-bg\)\)\]{background-color:color-mix(in srgb,var(--c-text) 16%,var(--c-bg))}}.bg-divider{background-color:var(--c-divider)}.bg-error{background-color:var(--c-error)}.bg-steel,.bg-steel\/8{background-color:var(--c-steel)}@supports (color:color-mix(in lab,red,red)){.bg-steel\/8{background-color:color-mix(in oklab,var(--c-steel) 8%,transparent)}}.bg-success{background-color:var(--c-success)}.bg-surface{background-color:var(--c-surface)}.bg-tint{background-color:var(--c-tint)}.bg-transparent{background-color:#0000}.bg-warning{background-color:var(--c-warning)}.p-0{padding:0}.p-2{padding:calc(var(--spacing) * 2)}.p-2\.5{padding:calc(var(--spacing) * 2.5)}.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\.5{padding-inline:calc(var(--spacing) * .5)}.px-1{padding-inline:var(--spacing)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-2\.5{padding-inline:calc(var(--spacing) * 2.5)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-3\.5{padding-inline:calc(var(--spacing) * 3.5)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-5{padding-inline:calc(var(--spacing) * 5)}.px-\[18px\]{padding-inline:18px}.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-3\.5{padding-block:calc(var(--spacing) * 3.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.pt-0\.5{padding-top:calc(var(--spacing) * .5)}.pt-1{padding-top:var(--spacing)}.pt-2\.5{padding-top:calc(var(--spacing) * 2.5)}.pt-3{padding-top:calc(var(--spacing) * 3)}.pt-4{padding-top:calc(var(--spacing) * 4)}.pr-1{padding-right:var(--spacing)}.pb-1\.5{padding-bottom:calc(var(--spacing) * 1.5)}.pb-2\.5{padding-bottom:calc(var(--spacing) * 2.5)}.pb-3{padding-bottom:calc(var(--spacing) * 3)}.pb-\[3px\]{padding-bottom:3px}.pl-2\.5{padding-left:calc(var(--spacing) * 2.5)}.text-center{text-align:center}.text-left{text-align:left}.text-right{text-align:right}.align-middle{vertical-align:middle}.font-heading{font-family:var(--font-heading)}.font-mono{font-family:var(--font-mono)}.font-sans{font-family:var(--font-sans)}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.text-\[11\.5px\]{font-size:11.5px}.text-\[11px\]{font-size:11px}.text-\[12px\]{font-size:12px}.text-\[13\.5px\]{font-size:13.5px}.text-\[13px\]{font-size:13px}.text-\[15px\]{font-size:15px}.text-\[16px\]{font-size:16px}.text-\[18px\]{font-size:18px}.text-\[20px\]{font-size:20px}.text-\[26px\]{font-size:26px}.text-\[30px\]{font-size:30px}.text-\[34px\]{font-size:34px}.text-\[40px\]{font-size:40px}.leading-5{--tw-leading:calc(var(--spacing) * 5);line-height:calc(var(--spacing) * 5)}.leading-\[1\.8\]{--tw-leading:1.8;line-height:1.8}.leading-\[1\.15\]{--tw-leading:1.15;line-height:1.15}.leading-none{--tw-leading:1;line-height:1}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-\[0\.1em\]{--tw-tracking:.1em;letter-spacing:.1em}.tracking-\[0\.02em\]{--tw-tracking:.02em;letter-spacing:.02em}.tracking-\[0\.08em\]{--tw-tracking:.08em;letter-spacing:.08em}.tracking-\[0\.12em\]{--tw-tracking:.12em;letter-spacing:.12em}.tracking-\[0\.16em\]{--tw-tracking:.16em;letter-spacing:.16em}.tracking-\[0\.18em\]{--tw-tracking:.18em;letter-spacing:.18em}.tracking-normal{--tw-tracking:var(--tracking-normal);letter-spacing:var(--tracking-normal)}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.whitespace-pre{white-space:pre}.whitespace-pre-wrap{white-space:pre-wrap}.text-error,.text-error\/90{color:var(--c-error)}@supports (color:color-mix(in lab,red,red)){.text-error\/90{color:color-mix(in oklab,var(--c-error) 90%,transparent)}}.text-primary{color:var(--c-primary)}.text-steel{color:var(--c-steel)}.text-success,.text-success\/80{color:var(--c-success)}@supports (color:color-mix(in lab,red,red)){.text-success\/80{color:color-mix(in oklab,var(--c-success) 80%,transparent)}}.text-text{color:var(--c-text)}.text-text-muted{color:var(--c-text-muted)}.text-warning{color:var(--c-warning)}.normal-case{text-transform:none}.uppercase{text-transform:uppercase}.italic{font-style:italic}.no-underline{text-decoration-line:none}.underline{text-decoration-line:underline}.opacity-50{opacity:.5}.opacity-60{opacity:.6}.opacity-70{opacity:.7}.shadow-\[inset_0_-2px_0_var\(--c-steel\)\]{--tw-shadow:inset 0 -2px 0 var(--tw-shadow-color,var(--c-steel));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-\[inset_0_-2px_0_var\(--c-warning\)\]{--tw-shadow:inset 0 -2px 0 var(--tw-shadow-color,var(--c-warning));box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-lg{--tw-shadow:0 10px 15px -3px var(--tw-shadow-color,#0000001a), 0 4px 6px -4px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow),var(--tw-inset-ring-shadow),var(--tw-ring-offset-shadow),var(--tw-ring-shadow),var(--tw-shadow)}.outline,.outline-1{outline-style:var(--tw-outline-style);outline-width:1px}.outline-steel{outline-color:var(--c-steel)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.group-open\:rotate-90:is(:where(.group):is([open],:popover-open,:open) *){rotate:90deg}@media(hover:hover){.group-hover\:opacity-100:is(:where(.group):hover *){opacity:1}}.placeholder\:text-text-muted::placeholder{color:var(--c-text-muted)}@media(hover:hover){.hover\:border-steel:hover{border-color:var(--c-steel)}.hover\:bg-steel\/40:hover{background-color:var(--c-steel)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-steel\/40:hover{background-color:color-mix(in oklab,var(--c-steel) 40%,transparent)}}.hover\:bg-tint:hover,.hover\:bg-tint\/60:hover{background-color:var(--c-tint)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-tint\/60:hover{background-color:color-mix(in oklab,var(--c-tint) 60%,transparent)}}.hover\:bg-tint\/70:hover{background-color:var(--c-tint)}@supports (color:color-mix(in lab,red,red)){.hover\:bg-tint\/70:hover{background-color:color-mix(in oklab,var(--c-tint) 70%,transparent)}}.hover\:text-error:hover{color:var(--c-error)}.hover\:text-steel:hover{color:var(--c-steel)}.hover\:text-text:hover{color:var(--c-text)}}.focus\:opacity-100:focus{opacity:1}.focus-visible\:bg-steel\/60:focus-visible{background-color:var(--c-steel)}@supports (color:color-mix(in lab,red,red)){.focus-visible\:bg-steel\/60:focus-visible{background-color:color-mix(in oklab,var(--c-steel) 60%,transparent)}}.active\:bg-steel\/60:active{background-color:var(--c-steel)}@supports (color:color-mix(in lab,red,red)){.active\:bg-steel\/60:active{background-color:color-mix(in oklab,var(--c-steel) 60%,transparent)}}.disabled\:opacity-40:disabled{opacity:.4}@media(min-width:40rem){.sm\:p-10{padding:calc(var(--spacing) * 10)}.sm\:p-12{padding:calc(var(--spacing) * 12)}}@media(min-width:48rem){.md\:block{display:block}.md\:flex{display:flex}.md\:inline{display:inline}.md\:grid-cols-3{grid-template-columns:repeat(3,minmax(0,1fr))}.md\:grid-cols-\[1fr_1px_1fr\]{grid-template-columns:1fr 1px 1fr}.md\:border-t-0{border-top-style:var(--tw-border-style);border-top-width:0}}.\[\&\:\:-webkit-details-marker\]\:hidden::-webkit-details-marker{display:none}}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:400;src:url(./barlow-vietnamese-400-normal-Dpl4UHAZ.woff2)format("woff2"),url(./barlow-vietnamese-400-normal-BFeobeCK.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:400;src:url(./barlow-latin-ext-400-normal-HxX4XjxC.woff2)format("woff2"),url(./barlow-latin-ext-400-normal-CvBsJvxq.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:400;src:url(./barlow-latin-400-normal-qiz4-Cze.woff2)format("woff2"),url(./barlow-latin-400-normal-fsAxiSwU.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:500;src:url(./barlow-vietnamese-500-normal-zTViEIzf.woff2)format("woff2"),url(./barlow-vietnamese-500-normal-GNfB7rCE.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:500;src:url(./barlow-latin-ext-500-normal-DOaysfXq.woff2)format("woff2"),url(./barlow-latin-ext-500-normal-CJPcKP2Q.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:500;src:url(./barlow-latin-500-normal-BPAOfeC8.woff2)format("woff2"),url(./barlow-latin-500-normal-C1h8hMer.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:600;src:url(./barlow-vietnamese-600-normal-DcjprdFV.woff2)format("woff2"),url(./barlow-vietnamese-600-normal-CA_GiK2e.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:600;src:url(./barlow-latin-ext-600-normal-B8NK_A3D.woff2)format("woff2"),url(./barlow-latin-ext-600-normal-DMVRjfRT.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Barlow;font-style:normal;font-display:swap;font-weight:600;src:url(./barlow-latin-600-normal-DILqtrty.woff2)format("woff2"),url(./barlow-latin-600-normal-CNwfPWQD.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:500;src:url(./barlow-condensed-vietnamese-500-normal-DjeaNLFD.woff2)format("woff2"),url(./barlow-condensed-vietnamese-500-normal-CsrJDWc5.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:500;src:url(./barlow-condensed-latin-ext-500-normal-yA5ONLQ9.woff2)format("woff2"),url(./barlow-condensed-latin-ext-500-normal-B1RE8WP7.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:500;src:url(./barlow-condensed-latin-500-normal-BgYH2mbd.woff2)format("woff2"),url(./barlow-condensed-latin-500-normal-HIEiP5Ov.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:600;src:url(./barlow-condensed-vietnamese-600-normal-A5AYRdjN.woff2)format("woff2"),url(./barlow-condensed-vietnamese-600-normal-CNlPk46_.woff)format("woff");unicode-range:U+102-103,U+110-111,U+128-129,U+168-169,U+1A0-1A1,U+1AF-1B0,U+300-301,U+303-304,U+308-309,U+323,U+329,U+1EA0-1EF9,U+20AB}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:600;src:url(./barlow-condensed-latin-ext-600-normal-18ESti3H.woff2)format("woff2"),url(./barlow-condensed-latin-ext-600-normal-Clv9cIcR.woff)format("woff");unicode-range:U+100-2BA,U+2BD-2C5,U+2C7-2CC,U+2CE-2D7,U+2DD-2FF,U+304,U+308,U+329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}@font-face{font-family:Barlow Condensed;font-style:normal;font-display:swap;font-weight:600;src:url(./barlow-condensed-latin-600-normal-DepVgxBB.woff2)format("woff2"),url(./barlow-condensed-latin-600-normal-BFJEwTuo.woff)format("woff");unicode-range:U+??,U+131,U+152-153,U+2BB-2BC,U+2C6,U+2DA,U+2DC,U+304,U+308,U+329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}:root{--c-primary:#07c;--c-secondary:#060;--c-accent:#960;--c-success:#060;--c-warning:#960;--c-error:#c00;--c-muted:#7a7a7d;--c-bg:#f2f2f3;--c-surface:#fff;--c-text:#1d1f20;--c-text-muted:#5d5d60;--c-steel:#5980a6;--c-divider:var(--c-text)}@supports (color:color-mix(in lab,red,red)){:root{--c-divider:color-mix(in srgb, var(--c-text) 16%, transparent)}}:root{--c-tint:var(--c-text)}@supports (color:color-mix(in lab,red,red)){:root{--c-tint:color-mix(in srgb, var(--c-text) 7%, var(--c-bg))}}:root{--font-mono:ui-monospace, "JetBrains Mono", "Fira Code", Menlo, Consolas, monospace;--font-sans:"Barlow", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;--font-heading:"Barlow Condensed", "Barlow", system-ui, sans-serif}html,body,#root{height:100%;margin:0}body{background:var(--c-bg);color:var(--c-text);font-family:var(--font-sans);font-size:14px;line-height:1.5}button,input,select,textarea{border-radius:0;font-family:inherit}.plate{background:var(--c-surface);border:1px solid var(--plate-edge,var(--c-divider));position:relative}.plate-ground{background:var(--c-bg)}.plate-steel{--plate-edge:var(--c-steel)}.plate-warning{--plate-edge:var(--c-warning)}@supports (color:color-mix(in lab,red,red)){.plate-warning{--plate-edge:color-mix(in srgb, var(--c-warning) 55%, transparent)}}.plate-error{--plate-edge:var(--c-error)}@supports (color:color-mix(in lab,red,red)){.plate-error{--plate-edge:color-mix(in srgb, var(--c-error) 55%, transparent)}}.plate>.corner{pointer-events:none;width:11px;height:11px;color:var(--corner-color,var(--c-text));position:absolute}@supports (color:color-mix(in lab,red,red)){.plate>.corner{color:var(--corner-color,color-mix(in srgb, var(--c-text) 55%, transparent))}}.plate>.corner:before,.plate>.corner:after{content:"";background:currentColor;position:absolute}.plate>.corner:before{width:1px;height:100%;top:0;left:5px}.plate>.corner:after{width:100%;height:1px;top:5px;left:0}.plate>.corner.tl{top:-6px;left:-6px}.plate>.corner.tr{top:-6px;right:-6px}.plate>.corner.bl{bottom:-6px;left:-6px}.plate>.corner.br{bottom:-6px;right:-6px}.surface-1{background:var(--c-surface)}.surface-2{background:var(--c-tint)}.hairline{border-color:var(--c-divider)}.tint{background:var(--c-tint)}.kicker{font-family:var(--font-heading);letter-spacing:.14em;text-transform:uppercase;color:var(--c-steel);font-size:11px;font-weight:500}.kicker-muted{color:var(--c-text-muted)}.chrome{font-family:var(--font-heading);letter-spacing:.08em;text-transform:uppercase;font-size:14px;font-weight:600}.chrome-sm{font-size:12px}.display{font-family:var(--font-heading);letter-spacing:-.015em;font-weight:600;line-height:1.1}.btn{font-family:var(--font-heading);letter-spacing:.08em;text-transform:uppercase;white-space:nowrap;color:var(--c-text);border:1px solid var(--c-divider);cursor:pointer;background:0 0;justify-content:center;align-items:center;gap:8px;padding:7px 14px;font-size:14px;font-weight:600;line-height:1.2;display:inline-flex}.btn:hover{background:var(--c-tint)}.btn:disabled{opacity:.45;cursor:not-allowed}.btn-primary{background:var(--c-steel);color:var(--c-bg);border-color:var(--c-steel)}.btn-primary:hover{filter:brightness(.92);background:var(--c-steel)}.btn-steel{color:var(--c-steel);border-color:var(--c-steel)}.btn-quiet{color:var(--c-text-muted)}.btn-quiet:hover{color:var(--c-text)}.btn-danger{color:var(--c-error)}.btn-sm{padding:2px 8px;font-size:12px;font-weight:500}.btn-md{padding:5px 12px;font-size:13px}.btn kbd,.btn .key{font-family:var(--font-mono);letter-spacing:0;text-transform:none;opacity:.7;border:0;padding:0;font-size:11px}.btn-primary kbd,.btn-primary .key{color:inherit}.link{color:var(--c-text-muted);text-underline-offset:3px;text-decoration:underline}.link:hover{color:var(--c-text)}.input{width:100%;min-height:34px;font:inherit;color:var(--c-text);caret-color:var(--c-steel);background:var(--c-surface);border:1px solid var(--c-divider);outline:none;padding:6px 10px;font-size:14px}.input:hover{border-color:var(--c-text)}@supports (color:color-mix(in lab,red,red)){.input:hover{border-color:color-mix(in srgb,var(--c-text) 45%,transparent)}}.input:focus-visible,.input:focus{border-color:var(--c-steel)}.input-mono{font-family:var(--font-mono);font-size:13px}.field-label{color:var(--c-text-muted);margin-bottom:4px;font-size:12px;display:block}:focus-visible{outline:2px solid var(--c-steel);outline-offset:2px}::selection{background:var(--c-steel)}@supports (color:color-mix(in lab,red,red)){::selection{background:color-mix(in srgb,var(--c-steel) 30%,transparent)}}.kv{font-family:var(--font-mono);grid-template-columns:max-content 1fr;gap:3px 14px;font-size:11.5px;display:grid}.kv>:nth-child(odd){color:var(--c-text-muted)}.kv>:nth-child(2n){text-align:right}.bar{background:var(--c-text);height:3px}@supports (color:color-mix(in lab,red,red)){.bar{background:color-mix(in srgb,var(--c-text) 16%,var(--c-bg))}}.bar{overflow:hidden}.bar>span{background:var(--c-steel);height:100%;display:block}.tok-keyword{color:var(--c-steel);font-weight:600}.tok-function{color:var(--c-success)}.tok-class,.tok-builtin{color:var(--c-accent)}.tok-name{color:var(--c-text)}.tok-string{color:var(--c-success)}.tok-number{color:var(--c-warning)}.tok-operator,.tok-punctuation{color:var(--c-text-muted)}.tok-comment{color:var(--c-muted);font-style:italic}.tok-decorator{color:var(--c-accent)}.tok-tag{color:var(--c-steel)}.tok-attribute{color:var(--c-success)}.tok-error{color:var(--c-error);-webkit-text-decoration:underline wavy;text-decoration:underline wavy}.tok-inserted{color:var(--c-success)}.tok-deleted{color:var(--c-error)}.tok-heading{color:var(--c-steel);font-weight:700}.tok-prompt{color:var(--c-muted)}.tok-text{color:var(--c-text)}.diff-add{color:var(--c-success);background:var(--c-success)}@supports (color:color-mix(in lab,red,red)){.diff-add{background:color-mix(in srgb,var(--c-success) 8%,transparent)}}.diff-del{color:var(--c-error);background:var(--c-error)}@supports (color:color-mix(in lab,red,red)){.diff-del{background:color-mix(in srgb,var(--c-error) 8%,transparent)}}.diff-hunk{color:var(--c-steel)}.diff-meta{color:var(--c-muted)}.prose-j{max-width:74ch;font-size:15px;line-height:1.55}.prose-j p{margin:.35rem 0}.prose-j h1,.prose-j h2,.prose-j h3,.prose-j h4{line-height:1.15;font-family:var(--font-heading);letter-spacing:-.01em;margin:.9rem 0 .3rem;font-weight:600}.prose-j h1{font-size:1.6rem}.prose-j h2{font-size:1.35rem}.prose-j h3{font-size:1.15rem}.prose-j h4{text-transform:uppercase;letter-spacing:.06em;font-size:1rem}.prose-j ul,.prose-j ol{margin:.3rem 0 .3rem 1.4rem}.prose-j ul{list-style:outside}.prose-j ol{list-style:decimal}.prose-j li{margin:.1rem 0}.prose-j blockquote{border-left:2px solid var(--c-steel);color:var(--c-text-muted);margin:.4rem 0;padding-left:.75rem}.prose-j hr{border:0;border-top:1px solid var(--c-divider);margin:.75rem 0}.prose-j code.inline{font-family:var(--font-mono);border-bottom:1px solid var(--c-steel);font-size:.87em}@supports (color:color-mix(in lab,red,red)){.prose-j code.inline{border-bottom:1px solid color-mix(in srgb,var(--c-steel) 50%,transparent)}}.prose-j code.inline{padding:0 .1rem}.prose-j a{color:var(--c-steel);text-underline-offset:3px;text-decoration:underline}.code-block{font-family:var(--font-mono);font-size:12.5px;line-height:1.5}.code-block .ln{-webkit-user-select:none;user-select:none;color:var(--c-muted);text-align:right;min-width:2.5rem;padding-right:.9rem;display:inline-block}table.j-table{border-collapse:collapse;margin:.4rem 0;font-size:13px}table.j-table th,table.j-table td{border:1px solid var(--c-divider);text-align:left;vertical-align:top;padding:.2rem .6rem}table.j-table th{font-family:var(--font-heading);letter-spacing:.1em;text-transform:uppercase;color:var(--c-text-muted);background:var(--c-tint);font-size:11px;font-weight:600}*{scrollbar-width:thin;scrollbar-color:var(--c-muted) transparent}@supports (color:color-mix(in lab,red,red)){*{scrollbar-color:color-mix(in srgb,var(--c-muted) 50%,transparent) transparent}}@keyframes pulse-dot{0%,to{opacity:.25}50%{opacity:1}}.pulse{animation:1.2s ease-in-out infinite pulse-dot}kbd{font-family:var(--font-mono);border:1px solid var(--c-divider);color:var(--c-text-muted);border-bottom-width:2px;padding:0 .3rem;font-size:.75rem}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}@property --tw-rotate-x{syntax:"*";inherits:false}@property --tw-rotate-y{syntax:"*";inherits:false}@property --tw-rotate-z{syntax:"*";inherits:false}@property --tw-skew-x{syntax:"*";inherits:false}@property --tw-skew-y{syntax:"*";inherits:false}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}