@askdb/studio 0.2.0-beta.4 → 0.2.0-beta.41

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 (49) hide show
  1. package/README.md +33 -29
  2. package/bin/askdb-studio.js +3 -1
  3. package/dist/bin.d.ts +1 -1
  4. package/dist/bin.d.ts.map +1 -1
  5. package/dist/bin.js +24 -3
  6. package/dist/bin.js.map +1 -1
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/cli.js +72 -15
  9. package/dist/cli.js.map +1 -1
  10. package/dist/client/assets/index-Bl9jqOjj.css +2 -0
  11. package/dist/client/assets/index-CGC5sKu1.js +100 -0
  12. package/dist/client/index.html +2 -2
  13. package/dist/execute-registry.d.ts +89 -0
  14. package/dist/execute-registry.d.ts.map +1 -0
  15. package/dist/execute-registry.js +445 -0
  16. package/dist/execute-registry.js.map +1 -0
  17. package/dist/index.d.ts +1 -0
  18. package/dist/index.d.ts.map +1 -1
  19. package/dist/index.js +1 -0
  20. package/dist/index.js.map +1 -1
  21. package/dist/introspection.d.ts +35 -0
  22. package/dist/introspection.d.ts.map +1 -0
  23. package/dist/introspection.js +106 -0
  24. package/dist/introspection.js.map +1 -0
  25. package/dist/package-manager.d.ts +44 -0
  26. package/dist/package-manager.d.ts.map +1 -0
  27. package/dist/package-manager.js +86 -0
  28. package/dist/package-manager.js.map +1 -0
  29. package/dist/prisma-install.d.ts +7 -0
  30. package/dist/prisma-install.d.ts.map +1 -0
  31. package/dist/prisma-install.js +7 -0
  32. package/dist/prisma-install.js.map +1 -0
  33. package/dist/request-guard.d.ts +44 -0
  34. package/dist/request-guard.d.ts.map +1 -0
  35. package/dist/request-guard.js +170 -0
  36. package/dist/request-guard.js.map +1 -0
  37. package/dist/server.d.ts +22 -4
  38. package/dist/server.d.ts.map +1 -1
  39. package/dist/server.js +1123 -148
  40. package/dist/server.js.map +1 -1
  41. package/dist/setup.d.ts +77 -0
  42. package/dist/setup.d.ts.map +1 -0
  43. package/dist/setup.js +511 -0
  44. package/dist/setup.js.map +1 -0
  45. package/dist/shared/api.d.ts +176 -3
  46. package/dist/shared/api.d.ts.map +1 -1
  47. package/package.json +81 -30
  48. package/dist/client/assets/index-Bsn2S5X2.css +0 -2
  49. package/dist/client/assets/index-C_RfRKkd.js +0 -8
package/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # @askdb/studio
2
2
 
3
- Local React browser UI for editing AskDB Schema v2 enrichment, checking RAG
4
- retrieval, and generating sample NL-to-SQL output.
3
+ Local React browser UI for editing AskDB Schema v2 enrichment, checking RAG retrieval, and generating sample NL-to-SQL output.
5
4
 
6
5
  ```sh
7
6
  askdb-studio --schema ./my-app.schema
@@ -9,21 +8,32 @@ askdb-studio --schema ./my-app.schema
9
8
  askdb studio --schema ./my-app.schema
10
9
  ```
11
10
 
12
- Studio serves a local web app at `http://127.0.0.1:5556` by default. The
13
- published package contains a Node local server plus a Vite-built React client.
14
- It can:
11
+ Studio serves a local web app at `http://127.0.0.1:5556` by default. The published package contains a Node local server plus a Vite-built React client. It can:
15
12
 
16
13
  - browse all physical tables and columns in `schema.json`
17
14
  - edit table descriptions, aliases, primary entities, tags, common query language, example questions, and column metadata
18
15
  - write the describable layer back to `tables/*.md`
19
- - request AI enrichment suggestions when `OPENAI_API_KEY` is configured
16
+ - request AI enrichment suggestions when the `ai` block in `askdb.config.*` has an API key
20
17
  - build and query the configured RAG index (`memory`, file-backed, or `pgvector`)
21
18
  - generate sample Postgres SQL for natural-language questions against the currently saved enrichment
19
+ - define and manage multi-tenancy policy (tenant roots, hierarchy, scoped/polymorphic/global tables) via the Tenancy view
20
+ - draft tenant policy with AI assistance
21
+ - test NL→SQL with tenant scope controls and SQL output modes (`sql-only` vs `sql-params`)
22
22
 
23
- Studio uses `@askdb/enrich` for the shared non-UI Schema v2 authoring logic:
24
- workspace loading, editable drafts, markdown/frontmatter preservation, save
25
- helpers, and suggestion context. It should not depend on `@askdb/tui`, which is
26
- the separate terminal authoring surface.
23
+ Schema browsing, enrichment, and SQL generation do not require a database driver. The optional Playground execute path runs generated SQL against a live database. Studio supports Postgres, MySQL, SQLite, and SQL Server. Each dialect requires its own optional peer driver package — install only the one you need:
24
+
25
+ | Dialect | Package |
26
+ |---|---|
27
+ | Postgres | `pnpm add pg` |
28
+ | MySQL | `pnpm add mysql2` |
29
+ | SQLite | `pnpm add better-sqlite3` |
30
+ | SQL Server | `pnpm add mssql` |
31
+
32
+ Execute is off by default. Enable it with `studio.execute.enabled: true` plus an execute connection (`studio.execute.databaseUrl`, or `file` for SQLite), ideally a read-only database role. Studio only reuses the introspection connection when `studio.execute.useIntrospectionConnection` is `true`. Each query is validated as a single read-only SELECT and runs in a read-only (SQL Server: always-rolled-back) transaction with a timeout (`studio.execute.timeoutMs`, default 30 s) and a row cap (`studio.execute.maxRows`, default 500).
33
+
34
+ The execute provider is resolved from `studio.execute.provider` in `askdb.config.ts`, falling back to the active introspection provider, then defaulting to Postgres for backward compatibility. The Playground displays the configured provider, connection status, and driver readiness near the Execute button. When running locally, Studio can install the missing driver for you.
35
+
36
+ Studio uses `@askdb/enrich` for the shared non-UI Schema v2 authoring logic: workspace loading, editable drafts, markdown/frontmatter preservation, save helpers, and suggestion context.
27
37
 
28
38
  ## Development
29
39
 
@@ -33,30 +43,24 @@ pnpm --filter @askdb/studio test
33
43
  pnpm --filter @askdb/studio start -- --schema ../../fixtures/schemas/orders-users.schema
34
44
  ```
35
45
 
36
- The client source lives in `src/web/` and builds to `dist/client/`. The server
37
- source lives in `src/` and serves the compiled client assets from that directory.
46
+ The client source lives in `src/web/` and builds to `dist/client/`. The server source lives in `src/` and serves the compiled client assets from that directory.
38
47
 
39
- The React client is styled with Tailwind CSS and shadcn-style primitives. The
40
- requested shadcn preset is recorded in `components.json`:
48
+ The React client is styled with Tailwind CSS and shadcn-style primitives. The requested shadcn preset is recorded in `components.json`:
41
49
 
42
50
  ```sh
43
51
  pnpm dlx shadcn@latest init --preset b1D0eCA4
44
52
  ```
45
53
 
46
- Environment variables:
54
+ Configuration, in `askdb.config.*` (bind any value to an environment variable of your choosing with `env("NAME")`; Studio loads `.env` first):
47
55
 
48
- | Variable | Purpose |
56
+ | Config key | Purpose |
49
57
  | --- | --- |
50
- | `OPENAI_API_KEY` | Enables AI suggestions and sample NL-to-SQL generation. |
51
- | `OPENAI_BASE_URL` | Optional OpenAI-compatible base URL. |
52
- | `ASKDB_STUDIO_MODEL` | Studio-specific model override. Falls back to `ASKDB_MODEL`, `OPENAI_MODEL`, then `gpt-4o-mini`. |
53
- | `ASKDB_STUDIO_HOST` | Bind host. Defaults to `127.0.0.1`. |
54
- | `ASKDB_STUDIO_PORT` | Bind port. Defaults to `5556`. |
55
- | `ASKDB_MOCK_SQL` | Deterministic generated SQL for tests or offline demos. |
56
- | `ASKDB_RAG_EMBEDDER` | Set to `mock`, `openai`, or `ai-sdk` for Studio RAG indexing. Defaults to the mock lexical embedder unless an AI key is configured. |
57
- | `ASKDB_RAG_EMBEDDER_MODEL` | Embedding model override for Studio RAG. |
58
- | `ASKDB_RAG_EMBEDDER_DIMENSIONS` | Optional embedding dimension override. |
59
-
60
- Studio uses the active `rag.store` branch from `askdb.config.*`. For `pgvector`,
61
- make sure the configured table/extension already exist and `ASKDB_PGVECTOR_URL`
62
- resolves correctly.
58
+ | `ai.provider`, `ai.providerConfig.<provider>.apiKey` | Enables AI suggestions and sample NL-to-SQL generation. |
59
+ | `ai.providerConfig.<provider>.baseUrl` | Optional base URL, e.g. an OpenAI-compatible endpoint. |
60
+ | `studio.listen.host` | Bind host. Defaults to `127.0.0.1`. `--host` overrides it. |
61
+ | `studio.listen.port` | Bind port. Defaults to `5556`. `--port` overrides it. |
62
+ | `dev.mockSql` | Deterministic generated SQL for tests or offline demos. |
63
+
64
+ Security: every `/api/*` request must carry the per-launch session token that Studio injects into the page it serves (`x-askdb-studio-token` header), come with an allowed `Host` (`localhost`, `127.0.0.1`, `[::1]`, or the bound host), and, for writes, be same-origin JSON. Programmatic callers of `createStudioServer()` can read the token from `server.sessionToken`. Binding to a non-loopback host exposes query execution and schema writes to anyone on that network who can load the page. Only do that on a trusted network. See [Studio → Security model](https://askdb.tools/studio/#security-model).
65
+
66
+ Studio uses the active `rag.store` branch from `askdb.config.*`, and embeds with `rag.embedder`: `mock`, a local lexical embedder that needs no key, or `ai`, the `ai.embedding` model, built from that section's connection only (see the [configuration reference](https://askdb.tools/reference/config/#aiembedding)). For `pgvector`, make sure `rag.storeConfig.pgvector.databaseUrl` resolves; there's no need to create the table. The first index build creates it, and the `vector` extension, at the width the embedding model returns (or `ai.embedding.dimensions`). A table that already exists at another width is refused, with a message saying how to resolve it. If Studio's database role can't create extensions, create `vector` first.
@@ -1,2 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import "../dist/bin.js";
2
+ import { runStudioBin } from "../dist/bin.js";
3
+
4
+ process.exit(await runStudioBin());
package/dist/bin.d.ts CHANGED
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env node
2
- export {};
2
+ export declare function runStudioBin(argv?: readonly string[]): Promise<number>;
3
3
  //# sourceMappingURL=bin.d.ts.map
package/dist/bin.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":""}
1
+ {"version":3,"file":"bin.d.ts","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AAKA,wBAAsB,YAAY,CAAC,IAAI,GAAE,SAAS,MAAM,EAA0B,GAAG,OAAO,CAAC,MAAM,CAAC,CAmBnG"}
package/dist/bin.js CHANGED
@@ -1,6 +1,27 @@
1
1
  #!/usr/bin/env node
2
- import { bootstrapAskDbEnv } from "@askdb/config";
2
+ import { bootstrapAskDbEnv, discoverAskDbConfigPath } from "@askdb/config";
3
+ import { pathToFileURL } from "node:url";
3
4
  import { runStudioCli } from "./cli.js";
4
- bootstrapAskDbEnv({ cwd: process.cwd() });
5
- process.exit(await runStudioCli(process.argv.slice(2)));
5
+ export async function runStudioBin(argv = process.argv.slice(2)) {
6
+ const cwd = process.cwd();
7
+ const configPath = discoverAskDbConfigPath(cwd);
8
+ // No config yet: Studio starts in setup mode and the browser wizard walks the user through
9
+ // creating one. runStudioCli re-probes.
10
+ if (configPath) {
11
+ try {
12
+ bootstrapAskDbEnv({ cwd });
13
+ }
14
+ catch (error) {
15
+ // A config that exists but fails to load (a syntax error, or dependencies not installed
16
+ // yet) still lets Studio start so setup can continue, but the user must hear why their
17
+ // settings are ignored. Setup never overwrites an existing config file.
18
+ const message = error instanceof Error ? error.message : String(error);
19
+ process.stderr.write(`askdb-studio: warning: ${configPath} could not be loaded, so Studio is ignoring it: ${message}\n`);
20
+ }
21
+ }
22
+ return runStudioCli(argv);
23
+ }
24
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
25
+ process.exit(await runStudioBin());
26
+ }
6
27
  //# sourceMappingURL=bin.js.map
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,iBAAiB,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;AAE1C,OAAO,CAAC,IAAI,CAAC,MAAM,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC"}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAExC,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAA0B,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAChF,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,EAAE,CAAC;IAC1B,MAAM,UAAU,GAAG,uBAAuB,CAAC,GAAG,CAAC,CAAC;IAChD,2FAA2F;IAC3F,wCAAwC;IACxC,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,CAAC;YACH,iBAAiB,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC;QAC7B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,wFAAwF;YACxF,uFAAuF;YACvF,wEAAwE;YACxE,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YACvE,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,0BAA0B,UAAU,mDAAmD,OAAO,IAAI,CACnG,CAAC;QACJ,CAAC;IACH,CAAC;IACD,OAAO,YAAY,CAAC,IAAI,CAAC,CAAC;AAC5B,CAAC;AAED,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,MAAM,CAAC,IAAI,CAAC,GAAG,KAAK,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;IAC/E,OAAO,CAAC,IAAI,CAAC,MAAM,YAAY,EAAE,CAAC,CAAC;AACrC,CAAC"}
package/dist/cli.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAaA,wBAAsB,YAAY,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAoD3E"}
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAqBA,wBAAsB,YAAY,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,CAkE3E"}
package/dist/cli.js CHANGED
@@ -1,6 +1,8 @@
1
- import { DEFAULT_INTROSPECT_OUTPUT_DIR, getAskDbRuntimeConfig } from "@askdb/config";
2
- import { readFileSync } from "node:fs";
1
+ import { DEFAULT_INTROSPECT_OUTPUT_DIR, discoverAskDbConfigPath, getAskDbRuntimeConfig, } from "@askdb/config";
2
+ import { existsSync, readFileSync } from "node:fs";
3
3
  import { networkInterfaces } from "node:os";
4
+ import { resolve } from "node:path";
5
+ import { isLoopbackHost } from "./request-guard.js";
4
6
  import { createStudioServer } from "./server.js";
5
7
  export async function runStudioCli(argv) {
6
8
  let opts;
@@ -20,18 +22,25 @@ export async function runStudioCli(argv) {
20
22
  printHelp(process.stdout);
21
23
  return 0;
22
24
  }
25
+ const setupReason = resolveSetupReason(opts);
23
26
  let server;
24
27
  try {
25
28
  server = createStudioServer({
26
29
  schema: opts.schema,
27
30
  host: opts.host,
28
31
  port: opts.port,
32
+ setupReason,
29
33
  });
30
34
  }
31
35
  catch (error) {
32
36
  process.stderr.write(`askdb-studio: ${formatError(error)}\n`);
33
37
  return 1;
34
38
  }
39
+ if (setupReason) {
40
+ process.stdout.write(setupReason === "no-config"
41
+ ? "No askdb.config.* found — Studio will open with the guided setup wizard.\n"
42
+ : "No schema artifact found — Studio will open with the guided setup wizard.\n");
43
+ }
35
44
  await new Promise((resolve, reject) => {
36
45
  server.once("error", reject);
37
46
  server.listen(opts.port, opts.host, resolve);
@@ -44,6 +53,9 @@ export async function runStudioCli(argv) {
44
53
  return 1;
45
54
  const shownHost = opts.host === "0.0.0.0" ? firstPrivateAddress() ?? "127.0.0.1" : opts.host;
46
55
  process.stdout.write(`AskDB Studio is running at http://${shownHost}:${address.port}\n`);
56
+ if (!isLoopbackHost(opts.host)) {
57
+ process.stderr.write(formatNetworkExposureWarning(opts.host));
58
+ }
47
59
  process.stdout.write("Press Ctrl+C to stop.\n");
48
60
  return await new Promise((resolve) => {
49
61
  const stop = () => {
@@ -54,23 +66,32 @@ export async function runStudioCli(argv) {
54
66
  });
55
67
  }
56
68
  function parseOptions(argv) {
57
- const rt = getAskDbRuntimeConfig();
58
- const listen = rt.structured.studio?.listen;
59
- const portFromEnv = rt.ai.aiEnv.ASKDB_STUDIO_PORT;
60
- const parsedPort = listen?.port ??
61
- (portFromEnv !== undefined && portFromEnv.trim() !== "" ? Number(portFromEnv) : NaN);
62
- const introspectOut = rt.flat["ASKDB_INTROSPECT_OUT"] ?? DEFAULT_INTROSPECT_OUTPUT_DIR;
69
+ // Without a config the runtime snapshot is uninitialized — fall back to
70
+ // package defaults so Studio can still start (in setup mode).
71
+ const rt = (() => {
72
+ try {
73
+ return getAskDbRuntimeConfig();
74
+ }
75
+ catch {
76
+ return undefined;
77
+ }
78
+ })();
79
+ const listen = rt?.structured.studio?.listen;
80
+ const introspectOut = rt?.flat["ASKDB_INTROSPECT_OUT"] ?? DEFAULT_INTROSPECT_OUTPUT_DIR;
63
81
  const opts = {
64
82
  schema: introspectOut,
65
- host: listen?.host ?? rt.ai.aiEnv.ASKDB_STUDIO_HOST ?? "127.0.0.1",
66
- port: Number.isFinite(parsedPort) && parsedPort > 0 && parsedPort <= 65535 ? parsedPort : 5556,
83
+ schemaFromFlag: false,
84
+ host: listen?.host ?? "127.0.0.1",
85
+ port: 5556,
67
86
  };
87
+ let portFromFlag = false;
68
88
  for (let i = 0; i < argv.length; i += 1) {
69
89
  const arg = argv[i];
70
90
  switch (arg) {
71
91
  case "--schema":
72
92
  case "-s":
73
93
  opts.schema = readValue(argv, ++i, arg);
94
+ opts.schemaFromFlag = true;
74
95
  break;
75
96
  case "--host":
76
97
  opts.host = readValue(argv, ++i, arg);
@@ -82,6 +103,7 @@ function parseOptions(argv) {
82
103
  throw new Error(`Invalid --port: ${raw}`);
83
104
  }
84
105
  opts.port = port;
106
+ portFromFlag = true;
85
107
  break;
86
108
  }
87
109
  case "--help":
@@ -96,8 +118,30 @@ function parseOptions(argv) {
96
118
  throw new Error(`Unknown option: ${arg}`);
97
119
  }
98
120
  }
121
+ // A bad configured port must fail, not quietly bind 5556. `NaN` (`Number(env("X"))` with X
122
+ // unset) counts as unset, as it does in @askdb/config; a numeric string works like a number.
123
+ const configPort = listen?.port;
124
+ if (!portFromFlag && !opts.help && !opts.version && configPort !== undefined && !Number.isNaN(configPort)) {
125
+ const port = Number(configPort);
126
+ if (!Number.isInteger(port) || port <= 0 || port > 65535) {
127
+ throw new Error(`Invalid studio.listen.port in askdb.config: ${String(configPort)} (expected an integer from 1 to 65535).`);
128
+ }
129
+ opts.port = port;
130
+ }
99
131
  return opts;
100
132
  }
133
+ /**
134
+ * Decide whether to start in setup mode. An explicitly passed `--schema` that
135
+ * doesn't exist stays a hard error (the user pointed at a specific artifact);
136
+ * a missing config or a missing *default* artifact opens the wizard instead.
137
+ */
138
+ function resolveSetupReason(opts) {
139
+ if (!discoverAskDbConfigPath(process.cwd()))
140
+ return "no-config";
141
+ if (!opts.schemaFromFlag && !existsSync(resolve(opts.schema)))
142
+ return "no-artifact";
143
+ return null;
144
+ }
101
145
  function readValue(argv, index, flag) {
102
146
  const value = argv[index];
103
147
  if (!value || value.startsWith("--")) {
@@ -114,17 +158,30 @@ function printHelp(stream) {
114
158
  "",
115
159
  "Options:",
116
160
  " -s, --schema <dir> Schema v2 directory (default: introspection.outputDir from",
117
- " askdb.config, or ASKDB_INTROSPECT_OUT env, or ./askdb/)",
118
- " --port <number> Port to listen on (default: 5556 or ASKDB_STUDIO_PORT)",
119
- " --host <host> Host to bind (default: 127.0.0.1 or ASKDB_STUDIO_HOST)",
161
+ " askdb.config, or ./askdb/)",
162
+ " --port <number> Port to listen on (default: studio.listen.port from askdb.config, or 5556)",
163
+ " --host <host> Host to bind (default: studio.listen.host from askdb.config, or 127.0.0.1)",
120
164
  " -V, --version Print package version",
121
165
  " -h, --help Print this help",
122
166
  "",
123
- "AI enrichment and sample NL-to-SQL use OPENAI_API_KEY. Override the model",
124
- "with ASKDB_STUDIO_MODEL, ASKDB_MODEL, or OPENAI_MODEL.",
167
+ "AI enrichment and sample NL-to-SQL use the ai block in askdb.config: ai.provider,",
168
+ "the key in ai.providerConfig.<provider>.apiKey, and the model in ai.language.model.",
169
+ "Bind any value to an environment variable with env(\"NAME\").",
125
170
  "",
126
171
  ].join("\n"));
127
172
  }
173
+ function formatNetworkExposureWarning(host) {
174
+ return [
175
+ "",
176
+ `WARNING: Studio is bound to ${host}, which other machines on your network can reach.`,
177
+ "Studio can execute SQL against your configured database and write schema files.",
178
+ "Anyone who can load the Studio page from this address gets its session token and",
179
+ "can use those features (setup, resync, and driver install stay loopback-only).",
180
+ "Only do this on a network you trust; the default 127.0.0.1 keeps Studio local.",
181
+ "",
182
+ "",
183
+ ].join("\n");
184
+ }
128
185
  function firstPrivateAddress() {
129
186
  for (const entries of Object.values(networkInterfaces())) {
130
187
  for (const entry of entries ?? []) {
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,6BAA6B,EAC7B,uBAAuB,EACvB,qBAAqB,GACtB,MAAM,eAAe,CAAC;AACvB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAsB,MAAM,aAAa,CAAC;AAYrE,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAuB;IACxD,IAAI,IAAgB,CAAC;IACrB,IAAI,CAAC;QACH,IAAI,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;IAC5B,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QAClD,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC1B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,kBAAkB,EAAE,IAAI,CAAC,CAAC;QAClD,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAC1B,OAAO,CAAC,CAAC;IACX,CAAC;IAED,MAAM,WAAW,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IAE7C,IAAI,MAAM,CAAC;IACX,IAAI,CAAC;QACH,MAAM,GAAG,kBAAkB,CAAC;YAC1B,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW;SACZ,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9D,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,WAAW,KAAK,WAAW;YACzB,CAAC,CAAC,4EAA4E;YAC9E,CAAC,CAAC,6EAA6E,CAClF,CAAC;IACJ,CAAC;IAED,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QAC1C,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;QAC7B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC/C,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACjB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,WAAW,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC9D,OAAO,SAAS,CAAC;IACnB,CAAC,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,MAAM,CAAC,OAAO,EAAE,CAAC;IACjC,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,CAAC,CAAC;IACtD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,mBAAmB,EAAE,IAAI,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;IAC7F,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,qCAAqC,SAAS,IAAI,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC;IACzF,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,4BAA4B,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAChE,CAAC;IACD,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAChD,OAAO,MAAM,IAAI,OAAO,CAAS,CAAC,OAAO,EAAE,EAAE;QAC3C,MAAM,IAAI,GAAG,GAAG,EAAE;YAChB,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;QACjC,CAAC,CAAC;QACF,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;QAC7B,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,YAAY,CAAC,IAAuB;IAC3C,wEAAwE;IACxE,8DAA8D;IAC9D,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE;QACf,IAAI,CAAC;YACH,OAAO,qBAAqB,EAAE,CAAC;QACjC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,SAAS,CAAC;QACnB,CAAC;IACH,CAAC,CAAC,EAAE,CAAC;IACL,MAAM,MAAM,GAAG,EAAE,EAAE,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC;IAC7C,MAAM,aAAa,GAAG,EAAE,EAAE,IAAI,CAAC,sBAAsB,CAAC,IAAI,6BAA6B,CAAC;IACxF,MAAM,IAAI,GAAe;QACvB,MAAM,EAAE,aAAa;QACrB,cAAc,EAAE,KAAK;QACrB,IAAI,EAAE,MAAM,EAAE,IAAI,IAAI,WAAW;QACjC,IAAI,EAAE,IAAI;KACX,CAAC;IACF,IAAI,YAAY,GAAG,KAAK,CAAC;IAEzB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC;QACrB,QAAQ,GAAG,EAAE,CAAC;YACZ,KAAK,UAAU,CAAC;YAChB,KAAK,IAAI;gBACP,IAAI,CAAC,MAAM,GAAG,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;gBACxC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;gBAC3B,MAAM;YACR,KAAK,QAAQ;gBACX,IAAI,CAAC,IAAI,GAAG,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;gBACtC,MAAM;YACR,KAAK,QAAQ,CAAC,CAAC,CAAC;gBACd,MAAM,GAAG,GAAG,SAAS,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,CAAC;gBACtC,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;gBACzB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;oBACzD,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAC;gBAC5C,CAAC;gBACD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;gBACjB,YAAY,GAAG,IAAI,CAAC;gBACpB,MAAM;YACR,CAAC;YACD,KAAK,QAAQ,CAAC;YACd,KAAK,IAAI;gBACP,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;gBACjB,MAAM;YACR,KAAK,WAAW,CAAC;YACjB,KAAK,IAAI;gBACP,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;gBACpB,MAAM;YACR;gBACE,MAAM,IAAI,KAAK,CAAC,mBAAmB,GAAG,EAAE,CAAC,CAAC;QAC9C,CAAC;IACH,CAAC;IAED,2FAA2F;IAC3F,6FAA6F;IAC7F,MAAM,UAAU,GAAG,MAAM,EAAE,IAAI,CAAC;IAChC,IAAI,CAAC,YAAY,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,UAAU,KAAK,SAAS,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC;QAC1G,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC;QAChC,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAC;YACzD,MAAM,IAAI,KAAK,CACb,+CAA+C,MAAM,CAAC,UAAU,CAAC,yCAAyC,CAC3G,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;GAIG;AACH,SAAS,kBAAkB,CAAC,IAAgB;IAC1C,IAAI,CAAC,uBAAuB,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC;QAAE,OAAO,WAAW,CAAC;IAChE,IAAI,CAAC,IAAI,CAAC,cAAc,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAAE,OAAO,aAAa,CAAC;IACpF,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,SAAS,CAAC,IAAuB,EAAE,KAAa,EAAE,IAAY;IACrE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC;IAC1B,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,oBAAoB,CAAC,CAAC;IAC/C,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,SAAS,CAAC,MAA0B;IAC3C,MAAM,CAAC,KAAK,CACV;QACE,gEAAgE;QAChE,EAAE;QACF,QAAQ;QACR,mEAAmE;QACnE,EAAE;QACF,UAAU;QACV,mFAAmF;QACnF,mDAAmD;QACnD,mGAAmG;QACnG,mGAAmG;QACnG,8CAA8C;QAC9C,wCAAwC;QACxC,EAAE;QACF,mFAAmF;QACnF,qFAAqF;QACrF,+DAA+D;QAC/D,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;AACJ,CAAC;AAED,SAAS,4BAA4B,CAAC,IAAY;IAChD,OAAO;QACL,EAAE;QACF,+BAA+B,IAAI,mDAAmD;QACtF,iFAAiF;QACjF,kFAAkF;QAClF,gFAAgF;QAChF,gFAAgF;QAChF,EAAE;QACF,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AACf,CAAC;AAED,SAAS,mBAAmB;IAC1B,KAAK,MAAM,OAAO,IAAI,MAAM,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,EAAE,CAAC;QACzD,KAAK,MAAM,KAAK,IAAI,OAAO,IAAI,EAAE,EAAE,CAAC;YAClC,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ;gBAAE,OAAO,KAAK,CAAC,OAAO,CAAC;QACvE,CAAC;IACH,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,kBAAkB;IACzB,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,iBAAiB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC5D,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAA0B,CAAC;IAClF,OAAO,OAAO,MAAM,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;AACvE,CAAC;AAED,SAAS,WAAW,CAAC,KAAc;IACjC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC"}
@@ -0,0 +1,2 @@
1
+ /*! tailwindcss v4.3.4 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:block))) 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-border-style:solid;--tw-leading:initial;--tw-font-weight:initial;--tw-ordinal:initial;--tw-slashed-zero:initial;--tw-numeric-figure:initial;--tw-numeric-spacing:initial;--tw-numeric-fraction:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-outline-style:solid;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-duration:initial;--tw-ease:initial;--tw-content:""}}}@layer theme{:root,:host{--font-sans:var(--font-sans);--font-mono:var(--font-mono);--color-amber-400:oklch(82.8% .189 84.429);--color-amber-500:oklch(76.9% .188 70.08);--color-green-500:oklch(72.3% .219 149.579);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-sm:24rem;--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:calc(1.5 / 1);--font-weight-medium:500;--font-weight-semibold:600;--radius-xs:.125rem;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--ease-in-out:cubic-bezier(.4, 0, .2, 1);--animate-spin:spin 1s linear infinite;--animate-pulse:pulse 2s cubic-bezier(.4, 0, .6, 1) infinite;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", "Noto Sans", Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring:where(:not(iframe)){outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.pointer-events-none{pointer-events:none}.visible{visibility:visible}.sr-only{clip-path:inset(50%);white-space:nowrap;border-width:0;width:1px;height:1px;margin:-1px;padding:0;position:absolute;overflow:hidden}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:0}.inset-x-0{inset-inline:0}.inset-y-0{inset-block:0}.top-0{top:0}.top-1\.5{top:calc(var(--spacing) * 1.5)}.top-3\.5{top:calc(var(--spacing) * 3.5)}.top-4{top:calc(var(--spacing) * 4)}.right-0{right:0}.right-1{right:var(--spacing)}.right-3{right:calc(var(--spacing) * 3)}.right-4{right:calc(var(--spacing) * 4)}.bottom-0{bottom:0}.left-0{left:0}.z-10{z-index:10}.z-20{z-index:20}.z-50{z-index:50}.mx-2{margin-inline:calc(var(--spacing) * 2)}.mx-3\.5{margin-inline:calc(var(--spacing) * 3.5)}.mt-auto{margin-top:auto}.mr-2{margin-right:calc(var(--spacing) * 2)}.-ml-1{margin-left:calc(var(--spacing) * -1)}.block{display:block}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline{display:inline}.inline-flex{display:inline-flex}.table{display:table}.aspect-square{aspect-ratio:1}.size-2\.5{width:calc(var(--spacing) * 2.5);height:calc(var(--spacing) * 2.5)}.size-4{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.size-6{width:calc(var(--spacing) * 6);height:calc(var(--spacing) * 6)}.size-7{width:calc(var(--spacing) * 7);height:calc(var(--spacing) * 7)}.size-8{width:calc(var(--spacing) * 8);height:calc(var(--spacing) * 8)}.size-9{width:calc(var(--spacing) * 9);height:calc(var(--spacing) * 9)}.size-10{width:calc(var(--spacing) * 10);height:calc(var(--spacing) * 10)}.\!h-4{height:calc(var(--spacing) * 4)!important}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-7{height:calc(var(--spacing) * 7)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-12{height:calc(var(--spacing) * 12)}.h-auto{height:auto}.h-full{height:100%}.h-svh{height:100svh}.\!min-h-0{min-height:0!important}.min-h-0{min-height:0}.min-h-6{min-height:calc(var(--spacing) * 6)}.min-h-24{min-height:calc(var(--spacing) * 24)}.min-h-32{min-height:calc(var(--spacing) * 32)}.min-h-36{min-height:calc(var(--spacing) * 36)}.min-h-48{min-height:calc(var(--spacing) * 48)}.min-h-svh{min-height:100svh}.w-\(--sidebar-width\){width:var(--sidebar-width)}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-3\/4{width:75%}.w-4{width:calc(var(--spacing) * 4)}.w-5{width:calc(var(--spacing) * 5)}.w-auto{width:auto}.w-fit{width:fit-content}.w-full{width:100%}.max-w-\(--skeleton-width\){max-width:var(--skeleton-width)}.max-w-full{max-width:100%}.min-w-0{min-width:0}.min-w-5{min-width:calc(var(--spacing) * 5)}.flex-1{flex:1}.shrink-0{flex-shrink:0}.origin-\(--radix-tooltip-content-transform-origin\){transform-origin:var(--radix-tooltip-content-transform-origin)}.-translate-x-1\/2{--tw-translate-x:calc(calc(1 / 2 * 100%) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.-translate-x-px{--tw-translate-x:-1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-x-px{--tw-translate-x:1px;translate:var(--tw-translate-x) var(--tw-translate-y)}.translate-y-\[calc\(-50\%_-_2px\)\]{--tw-translate-y:calc(-50% - 2px);translate:var(--tw-translate-x) var(--tw-translate-y)}.rotate-45{rotate:45deg}.transform{transform:var(--tw-rotate-x, ) var(--tw-rotate-y, ) var(--tw-rotate-z, ) var(--tw-skew-x, ) var(--tw-skew-y, )}.animate-pulse{animation:var(--animate-pulse)}.animate-spin{animation:var(--animate-spin)}.flex-col{flex-direction:column}.items-center{align-items:center}.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-4{gap:calc(var(--spacing) * 4)}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.rounded-\[2px\]{border-radius:2px}.rounded-md{border-radius:var(--radius-md)}.rounded-xs{border-radius:var(--radius-xs)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-r{border-right-style:var(--tw-border-style);border-right-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-l{border-left-style:var(--tw-border-style);border-left-width:1px}.border-dashed{--tw-border-style:dashed;border-style:dashed}.border-border,.border-input{border-color:var(--border)}.border-sidebar-border{border-color:var(--sidebar-border)}.bg-background{background-color:var(--bg)}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab, red, red)){.bg-black\/50{background-color:color-mix(in oklab, var(--color-black) 50%, transparent)}}.bg-border{background-color:var(--border)}.bg-destructive{background-color:var(--red-600)}.bg-foreground{background-color:var(--ink-900)}.bg-primary{background-color:var(--red-600)}.bg-secondary{background-color:var(--surface-2)}.bg-sidebar{background-color:var(--sidebar)}.bg-sidebar-border{background-color:var(--sidebar-border)}.bg-transparent{background-color:#0000}.bg-warning{background-color:#fef3cd}.fill-foreground{fill:var(--ink-900)}.p-0{padding:0}.p-2{padding:calc(var(--spacing) * 2)}.p-4{padding:calc(var(--spacing) * 4)}.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-4{padding-inline:calc(var(--spacing) * 4)}.px-6{padding-inline:calc(var(--spacing) * 6)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-6{padding-block:calc(var(--spacing) * 6)}.text-center{text-align:center}.text-left{text-align:left}.font-mono{font-family:var(--font-mono)}.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))}.leading-none{--tw-leading:1;line-height:1}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.text-balance{text-wrap:balance}.break-all{word-break:break-all}.whitespace-nowrap{white-space:nowrap}.text-background{color:var(--bg)}.text-destructive-foreground{color:#fff}.text-foreground{color:var(--ink-900)}.text-green-500{color:var(--color-green-500)}.text-muted-foreground{color:var(--ink-500)}.text-primary{color:var(--red-600)}.text-primary-foreground{color:#fff}.text-secondary-foreground{color:var(--ink-900)}.text-sidebar-foreground,.text-sidebar-foreground\/70{color:var(--sidebar-foreground)}@supports (color:color-mix(in lab, red, red)){.text-sidebar-foreground\/70{color:color-mix(in oklab, var(--sidebar-foreground) 70%, transparent)}}.text-warning-foreground{color:var(--amber-500)}.text-white{color:var(--color-white)}.uppercase{text-transform:uppercase}.italic{font-style:italic}.tabular-nums{--tw-numeric-spacing:tabular-nums;font-variant-numeric:var(--tw-ordinal, ) var(--tw-slashed-zero, ) var(--tw-numeric-figure, ) var(--tw-numeric-spacing, ) var(--tw-numeric-fraction, )}.no-underline{text-decoration-line:none}.underline-offset-4{text-underline-offset:4px}.opacity-70{opacity:.7}.shadow-\[0_0_0_1px_var\(--sidebar-border\)\]{--tw-shadow:0 0 0 1px var(--tw-shadow-color,var(--sidebar-border));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-none{--tw-shadow:0 0 #0000;box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xs{--tw-shadow:0 1px 2px 0 var(--tw-shadow-color,#0000000d);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-sidebar-ring{--tw-ring-color:var(--sidebar-ring)}.ring-offset-background{--tw-ring-offset-color:var(--bg)}.outline-hidden{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.outline-hidden{outline-offset:2px;outline:2px solid #0000}}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.filter{filter:var(--tw-blur, ) var(--tw-brightness, ) var(--tw-contrast, ) var(--tw-grayscale, ) var(--tw-hue-rotate, ) var(--tw-invert, ) var(--tw-saturate, ) var(--tw-sepia, ) var(--tw-drop-shadow, )}.transition{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-\[color\,box-shadow\]{transition-property:color,box-shadow;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[left\,right\,width\]{transition-property:left,right,width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[margin\,opacity\]{transition-property:margin,opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[width\,height\,padding\]{transition-property:width,height,padding;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-\[width\]{transition-property:width;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-all{transition-property:all;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-opacity{transition-property:opacity;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-transform{transition-property:transform,translate,scale,rotate;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.duration-200{--tw-duration:.2s;transition-duration:.2s}.ease-in-out{--tw-ease:var(--ease-in-out);transition-timing-function:var(--ease-in-out)}.ease-linear{--tw-ease:linear;transition-timing-function:linear}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}:is(:where(.group\/menu-item):focus-within .group-focus-within\/menu-item\:opacity-100){opacity:1}@media (hover:hover){:is(:where(.group\/menu-item):hover .group-hover\/menu-item\:opacity-100){opacity:1}}:is(:where(.group\/menu-item):has([data-sidebar=menu-action]) .group-has-data-\[sidebar\=menu-action\]\/menu-item\:pr-8){padding-right:calc(var(--spacing) * 8)}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:-mt-8){margin-top:calc(var(--spacing) * -8)}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:hidden){display:none}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:size-8\!){width:calc(var(--spacing) * 8)!important;height:calc(var(--spacing) * 8)!important}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:w-\(--sidebar-width-icon\)){width:var(--sidebar-width-icon)}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:w-\[calc\(var\(--sidebar-width-icon\)\+\(--spacing\(4\)\)\)\]){width:calc(var(--sidebar-width-icon) + (calc(var(--spacing) * 4)))}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:w-\[calc\(var\(--sidebar-width-icon\)\+\(--spacing\(4\)\)\+2px\)\]){width:calc(var(--sidebar-width-icon) + (calc(var(--spacing) * 4)) + 2px)}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:justify-center){justify-content:center}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:overflow-hidden){overflow:hidden}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:p-0\!){padding:0!important}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:p-2\!){padding:calc(var(--spacing) * 2)!important}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:px-0){padding-inline:0}:is(:where(.group)[data-collapsible=icon] .group-data-\[collapsible\=icon\]\:opacity-0){opacity:0}:is(:where(.group)[data-collapsible=offcanvas] .group-data-\[collapsible\=offcanvas\]\:right-\[calc\(var\(--sidebar-width\)\*-1\)\]){right:calc(var(--sidebar-width) * -1)}:is(:where(.group)[data-collapsible=offcanvas] .group-data-\[collapsible\=offcanvas\]\:left-\[calc\(var\(--sidebar-width\)\*-1\)\]){left:calc(var(--sidebar-width) * -1)}:is(:where(.group)[data-collapsible=offcanvas] .group-data-\[collapsible\=offcanvas\]\:w-0){width:0}:is(:where(.group)[data-collapsible=offcanvas] .group-data-\[collapsible\=offcanvas\]\:translate-x-0){--tw-translate-x:0px;translate:var(--tw-translate-x) var(--tw-translate-y)}:is(:where(.group)[data-side=left] .group-data-\[side\=left\]\:-right-4){right:calc(var(--spacing) * -4)}:is(:where(.group)[data-side=left] .group-data-\[side\=left\]\:border-r){border-right-style:var(--tw-border-style);border-right-width:1px}:is(:where(.group)[data-side=right] .group-data-\[side\=right\]\:left-0){left:0}:is(:where(.group)[data-side=right] .group-data-\[side\=right\]\:rotate-180){rotate:180deg}:is(:where(.group)[data-side=right] .group-data-\[side\=right\]\:border-l){border-left-style:var(--tw-border-style);border-left-width:1px}:is(:where(.group)[data-variant=floating] .group-data-\[variant\=floating\]\:rounded-lg){border-radius:var(--radius-lg)}:is(:where(.group)[data-variant=floating] .group-data-\[variant\=floating\]\:border){border-style:var(--tw-border-style);border-width:1px}:is(:where(.group)[data-variant=floating] .group-data-\[variant\=floating\]\:border-sidebar-border){border-color:var(--sidebar-border)}:is(:where(.group)[data-variant=floating] .group-data-\[variant\=floating\]\:shadow-sm){--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}@media (hover:hover){:is(:where(.peer\/menu-button):hover~.peer-hover\/menu-button\:text-sidebar-accent-foreground){color:var(--sidebar-accent-foreground)}}:is(:where(.peer\/menu-button)[data-active=true]~.peer-data-\[active\=true\]\/menu-button\:text-sidebar-accent-foreground){color:var(--sidebar-accent-foreground)}:is(:where(.peer\/menu-button)[data-size=default]~.peer-data-\[size\=default\]\/menu-button\:top-1\.5){top:calc(var(--spacing) * 1.5)}:is(:where(.peer\/menu-button)[data-size=lg]~.peer-data-\[size\=lg\]\/menu-button\:top-2\.5){top:calc(var(--spacing) * 2.5)}:is(:where(.peer\/menu-button)[data-size=sm]~.peer-data-\[size\=sm\]\/menu-button\:top-1){top:var(--spacing)}.selection\:bg-primary ::selection{background-color:var(--red-600)}.selection\:bg-primary::selection{background-color:var(--red-600)}.selection\:text-primary-foreground ::selection{color:#fff}.selection\:text-primary-foreground::selection{color:#fff}.file\:inline-flex::file-selector-button{display:inline-flex}.file\:h-7::file-selector-button{height:calc(var(--spacing) * 7)}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\:text-foreground::file-selector-button{color:var(--ink-900)}.placeholder\:text-muted-foreground::placeholder{color:var(--ink-500)}.after\:absolute:after{content:var(--tw-content);position:absolute}.after\:-inset-2:after{content:var(--tw-content);inset:calc(var(--spacing) * -2)}.after\:inset-y-0:after{content:var(--tw-content);inset-block:0}.after\:left-1\/2:after{content:var(--tw-content);left:50%}.after\:w-\[2px\]:after{content:var(--tw-content);width:2px}:is(:where(.group)[data-collapsible=offcanvas] .group-data-\[collapsible\=offcanvas\]\:after\:left-full):after{content:var(--tw-content);left:100%}@media (hover:hover){.hover\:bg-destructive\/90:hover{background-color:var(--red-600)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-destructive\/90:hover{background-color:color-mix(in oklab, var(--red-600) 90%, transparent)}}.hover\:bg-primary\/90:hover{background-color:var(--red-600)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab, var(--red-600) 90%, transparent)}}.hover\:bg-secondary\/80:hover{background-color:var(--surface-2)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab, var(--surface-2) 80%, transparent)}}.hover\:bg-sidebar-accent:hover{background-color:var(--sidebar-accent)}.hover\:text-sidebar-accent-foreground:hover{color:var(--sidebar-accent-foreground)}.hover\:underline:hover{text-decoration-line:underline}.hover\:opacity-100:hover{opacity:1}.hover\:shadow-\[0_0_0_1px_var\(--sidebar-accent\)\]:hover{--tw-shadow:0 0 0 1px var(--tw-shadow-color,var(--sidebar-accent));box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}:is(:where(.group)[data-collapsible=offcanvas] .hover\:group-data-\[collapsible\=offcanvas\]\:bg-sidebar:hover){background-color:var(--sidebar)}.hover\:after\:bg-sidebar-border:hover:after{content:var(--tw-content);background-color:var(--sidebar-border)}}.focus\:ring-2:focus{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-ring:focus{--tw-ring-color:var(--red-500)}.focus\:ring-offset-2:focus{--tw-ring-offset-width:2px;--tw-ring-offset-shadow:var(--tw-ring-inset, ) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color)}.focus\:outline-hidden:focus{--tw-outline-style:none;outline-style:none}@media (forced-colors:active){.focus\:outline-hidden:focus{outline-offset:2px;outline:2px solid #0000}}.focus-visible\:border-ring:focus-visible{border-color:var(--red-500)}.focus-visible\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-2:focus-visible{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(2px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-\[1\.5px\]:focus-visible{--tw-ring-shadow:var(--tw-ring-inset, ) 0 0 0 calc(1.5px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-destructive\/20:focus-visible{--tw-ring-color:var(--red-600)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-destructive\/20:focus-visible{--tw-ring-color:color-mix(in oklab, var(--red-600) 20%, transparent)}}.focus-visible\:ring-ring:focus-visible,.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:var(--red-500)}@supports (color:color-mix(in lab, red, red)){.focus-visible\:ring-ring\/50:focus-visible{--tw-ring-color:color-mix(in oklab, var(--red-500) 50%, transparent)}}.active\:bg-sidebar-accent:active{background-color:var(--sidebar-accent)}.active\:text-sidebar-accent-foreground:active{color:var(--sidebar-accent-foreground)}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}:where([data-side=left]) .in-data-\[side\=left\]\:cursor-w-resize{cursor:w-resize}:where([data-side=right]) .in-data-\[side\=right\]\:cursor-e-resize{cursor:e-resize}.has-data-\[variant\=inset\]\:bg-sidebar:has([data-variant=inset]){background-color:var(--sidebar)}.has-\[\>svg\]\:px-1\.5:has(>svg){padding-inline:calc(var(--spacing) * 1.5)}.has-\[\>svg\]\:px-2\.5:has(>svg){padding-inline:calc(var(--spacing) * 2.5)}.has-\[\>svg\]\:px-3:has(>svg){padding-inline:calc(var(--spacing) * 3)}.has-\[\>svg\]\:px-4:has(>svg){padding-inline:calc(var(--spacing) * 4)}.aria-disabled\:pointer-events-none[aria-disabled=true]{pointer-events:none}.aria-disabled\:opacity-50[aria-disabled=true]{opacity:.5}.aria-invalid\:border-destructive[aria-invalid=true]{border-color:var(--red-600)}.aria-invalid\:ring-destructive\/20[aria-invalid=true]{--tw-ring-color:var(--red-600)}@supports (color:color-mix(in lab, red, red)){.aria-invalid\:ring-destructive\/20[aria-invalid=true]{--tw-ring-color:color-mix(in oklab, var(--red-600) 20%, transparent)}}.data-\[active\=true\]\:bg-sidebar-accent[data-active=true]{background-color:var(--sidebar-accent)}.data-\[active\=true\]\:font-medium[data-active=true]{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.data-\[active\=true\]\:text-sidebar-accent-foreground[data-active=true]{color:var(--sidebar-accent-foreground)}.data-\[orientation\=horizontal\]\:h-px[data-orientation=horizontal]{height:1px}.data-\[orientation\=horizontal\]\:w-full[data-orientation=horizontal]{width:100%}.data-\[orientation\=vertical\]\:h-full[data-orientation=vertical]{height:100%}.data-\[orientation\=vertical\]\:w-px[data-orientation=vertical]{width:1px}.data-\[state\=closed\]\:duration-300[data-state=closed]{--tw-duration:.3s;transition-duration:.3s}.data-\[state\=open\]\:bg-secondary[data-state=open]{background-color:var(--surface-2)}.data-\[state\=open\]\:opacity-100[data-state=open]{opacity:1}.data-\[state\=open\]\:duration-500[data-state=open]{--tw-duration:.5s;transition-duration:.5s}@media (hover:hover){.data-\[state\=open\]\:hover\:bg-sidebar-accent[data-state=open]:hover{background-color:var(--sidebar-accent)}.data-\[state\=open\]\:hover\:text-sidebar-accent-foreground[data-state=open]:hover{color:var(--sidebar-accent-foreground)}}@media (width>=40rem){.sm\:flex{display:flex}.sm\:max-w-sm{max-width:var(--container-sm)}}@media (width>=48rem){.md\:block{display:block}.md\:flex{display:flex}.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.md\:opacity-0{opacity:0}:is(:where(.peer)[data-variant=inset]~.md\:peer-data-\[variant\=inset\]\:m-2){margin:calc(var(--spacing) * 2)}:is(:where(.peer)[data-variant=inset]~.md\:peer-data-\[variant\=inset\]\:ml-0){margin-left:0}:is(:where(.peer)[data-variant=inset]~.md\:peer-data-\[variant\=inset\]\:rounded-xl){border-radius:var(--radius-xl)}:is(:where(.peer)[data-variant=inset]~.md\:peer-data-\[variant\=inset\]\:shadow-sm){--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}:is(:where(.peer)[data-state=collapsed]~:is(:where(.peer)[data-variant=inset]~.md\:peer-data-\[variant\=inset\]\:peer-data-\[state\=collapsed\]\:ml-2)){margin-left:calc(var(--spacing) * 2)}.md\:after\:hidden:after{content:var(--tw-content);display:none}}.dark\:border-input:is(.dark *){border-color:var(--border)}.dark\:bg-amber-500\/15:is(.dark *){background-color:#f99c0026}@supports (color:color-mix(in lab, red, red)){.dark\:bg-amber-500\/15:is(.dark *){background-color:color-mix(in oklab, var(--color-amber-500) 15%, transparent)}}.dark\:bg-destructive\/60:is(.dark *){background-color:var(--red-600)}@supports (color:color-mix(in lab, red, red)){.dark\:bg-destructive\/60:is(.dark *){background-color:color-mix(in oklab, var(--red-600) 60%, transparent)}}.dark\:bg-input\/30:is(.dark *){background-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.dark\:bg-input\/30:is(.dark *){background-color:color-mix(in oklab, var(--border) 30%, transparent)}}.dark\:text-amber-400:is(.dark *){color:var(--color-amber-400)}@media (hover:hover){.dark\:hover\:bg-input\/50:is(.dark *):hover{background-color:var(--border)}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-input\/50:is(.dark *):hover{background-color:color-mix(in oklab, var(--border) 50%, transparent)}}}.dark\:focus-visible\:ring-destructive\/40:is(.dark *):focus-visible{--tw-ring-color:var(--red-600)}@supports (color:color-mix(in lab, red, red)){.dark\:focus-visible\:ring-destructive\/40:is(.dark *):focus-visible{--tw-ring-color:color-mix(in oklab, var(--red-600) 40%, transparent)}}.dark\:aria-invalid\:ring-destructive\/40:is(.dark *)[aria-invalid=true]{--tw-ring-color:var(--red-600)}@supports (color:color-mix(in lab, red, red)){.dark\:aria-invalid\:ring-destructive\/40:is(.dark *)[aria-invalid=true]{--tw-ring-color:color-mix(in oklab, var(--red-600) 40%, transparent)}}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-3 svg:not([class*=size-]){width:calc(var(--spacing) * 3);height:calc(var(--spacing) * 3)}.\[\&_svg\:not\(\[class\*\=\'size-\'\]\)\]\:size-4 svg:not([class*=size-]){width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&\>button\]\:hidden>button{display:none}.\[\&\>span\:last-child\]\:truncate>span:last-child{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.\[\&\>svg\]\:size-4>svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&\>svg\]\:shrink-0>svg{flex-shrink:0}.\[\&\>svg\]\:text-sidebar-accent-foreground>svg{color:var(--sidebar-accent-foreground)}[data-side=left][data-collapsible=offcanvas] .\[\[data-side\=left\]\[data-collapsible\=offcanvas\]_\&\]\:-right-2{right:calc(var(--spacing) * -2)}[data-side=left][data-state=collapsed] .\[\[data-side\=left\]\[data-state\=collapsed\]_\&\]\:cursor-e-resize{cursor:e-resize}[data-side=right][data-collapsible=offcanvas] .\[\[data-side\=right\]\[data-collapsible\=offcanvas\]_\&\]\:-left-2{left:calc(var(--spacing) * -2)}[data-side=right][data-state=collapsed] .\[\[data-side\=right\]\[data-state\=collapsed\]_\&\]\:cursor-w-resize{cursor:w-resize}}:root{--red-50:#fbf1f2;--red-100:#f7e2e4;--red-200:#efc5cb;--red-400:#cf5867;--red-500:#b8313f;--red-600:#9f1024;--red-700:#85101f;--red-800:#5f0a16;--bg:#fafaf9;--surface:#fff;--surface-2:#f5f4f1;--surface-3:#efeeea;--border:#e7e5e3;--border-strong:#d6d3cf;--ink-900:#1a1815;--ink-700:#3c3a36;--ink-500:#6b6862;--ink-400:#8a8680;--ink-300:#a8a39c;--green-500:#16a34a;--amber-500:#d97706;--blue-500:#2563eb;--font-sans:"Inter", -apple-system, BlinkMacSystemFont, sans-serif;--font-mono:"JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;--radius-sm:4px;--radius:6px;--radius-lg:10px;--shadow-1:0 1px 0 #14120f0a, 0 1px 2px #14120f0a;--shadow-2:0 4px 14px #14120f0f, 0 1px 2px #14120f0a;--nav-w:200px;--sub-w:400px;--pad-y:11px;--pad-x:14px;--sidebar:var(--surface);--sidebar-foreground:var(--ink-700);--sidebar-primary:var(--red-600);--sidebar-primary-foreground:#fff;--sidebar-accent:var(--surface-2);--sidebar-accent-foreground:var(--ink-900);--sidebar-border:var(--border);--sidebar-ring:var(--red-500)}[data-theme=dark]{--bg:#141210;--surface:#1c1a17;--surface-2:#252320;--surface-3:#2e2b28;--border:#332f2b;--border-strong:#403c37;--ink-900:#f5f3f0;--ink-700:#d4d0ca;--ink-500:#9a958d;--ink-400:#7a756d;--ink-300:#5c5852;--red-50:#2a1014;--red-100:#3a161c;--red-600:#c54353;--red-700:#a02a3a;--green-500:#4ade80;--amber-500:#fbbf24;--blue-500:#60a5fa;--shadow-1:0 1px 0 #0000004d, 0 1px 2px #0003;--shadow-2:0 4px 14px #00000059}*{box-sizing:border-box}html,body,#root{height:100%;overflow:hidden}body{background:var(--bg);color:var(--ink-900);font-family:var(--font-sans);-webkit-font-smoothing:antialiased;text-rendering:optimizelegibility;margin:0;font-size:13px;line-height:1.45}button{font:inherit;color:inherit;cursor:default}input,textarea,select{font:inherit;color:inherit}code,pre,.mono{font-family:var(--font-mono)}.app-shell{background:var(--bg);justify-content:center;align-items:center;height:100vh;display:flex}.topbar{border-bottom:1px solid var(--border);background:var(--surface);color:var(--ink-700);align-items:center;gap:10px;height:38px;padding:0 14px;font-size:12px;display:flex}.app-content{grid-template-columns:var(--sub-w) 1fr;flex:1;min-height:0;display:grid;overflow:hidden}.app-content>.main-pane:only-child{grid-column:1/-1}.topbar .crumbs{flex:1;align-items:center;gap:8px;min-width:0;display:flex}.topbar .crumb{color:var(--ink-500)}.topbar .crumb.cur{color:var(--ink-900);font-weight:500}.topbar .sep{color:var(--ink-300)}.topbar .right{align-items:center;gap:8px;display:flex}.cmd-palette{border:1px solid var(--border);background:var(--surface-2);height:24px;color:var(--ink-400);cursor:default;border-radius:6px;align-items:center;gap:8px;width:240px;padding:0 8px 0 10px;font-size:11.5px;display:flex}.cmd-palette:hover{background:var(--surface);color:var(--ink-700)}.kbd{border:1px solid var(--border);background:var(--surface);height:18px;font:500 10px/1 var(--font-mono);color:var(--ink-500);border-bottom-width:2px;border-radius:4px;align-items:center;gap:3px;padding:0 5px;display:inline-flex}.btn.primary .kbd{color:#ffffffd9;background:#ffffff26;border-color:#ffffff4d}[data-sidebar=menu-button].active{background:var(--sidebar-accent);color:var(--sidebar-accent-foreground);font-weight:600}.sub-rail{border-right:1px solid var(--border);background:var(--surface);flex-direction:column;min-height:0;display:flex}.sub-rail-hd{border-bottom:1px solid var(--border);justify-content:space-between;align-items:center;gap:6px;padding:10px 14px 8px;display:flex}.sub-rail-hd h2{letter-spacing:-.01em;color:var(--ink-900);align-items:center;gap:8px;margin:0;font-size:13px;font-weight:600;display:flex}.sub-rail-search{border:1px solid var(--border);background:var(--surface-2);border-radius:6px;align-items:center;gap:8px;height:28px;padding:0 10px;display:flex}.sub-rail-search input{color:var(--ink-900);background:0 0;border:0;outline:0;flex:1;font-size:12.5px}.sub-rail-search input::placeholder{color:var(--ink-400)}.enrich-filter-bar{border-bottom:1px solid var(--border);flex-wrap:wrap;gap:4px;padding:6px 10px;display:flex}.enrich-filter-chip{border:1px solid var(--border);height:22px;color:var(--ink-400);cursor:pointer;white-space:nowrap;background:0 0;border-radius:11px;align-items:center;gap:4px;padding:0 7px;font-size:10.5px;transition:all .12s;display:flex}.enrich-filter-chip:hover{background:var(--surface-2);color:var(--ink-700)}.enrich-filter-chip.active{color:var(--ink-700);border-color:var(--border-strong);background:var(--surface-2)}.enrich-filter-chip.active.enriched{border-color:var(--green-500);background:var(--green-500)}@supports (color:color-mix(in lab, red, red)){.enrich-filter-chip.active.enriched{background:color-mix(in srgb, var(--green-500) 8%, transparent)}}.enrich-filter-chip.active.partial{border-color:var(--amber-500);background:var(--amber-500)}@supports (color:color-mix(in lab, red, red)){.enrich-filter-chip.active.partial{background:color-mix(in srgb, var(--amber-500) 8%, transparent)}}.enrich-filter-chip.active.none{border-color:var(--ink-300);background:var(--surface-2)}.enrich-filter-chip.active.untracked{color:var(--amber-700);border-color:var(--amber-500);background:var(--amber-500)}@supports (color:color-mix(in lab, red, red)){.enrich-filter-chip.active.untracked{background:color-mix(in srgb, var(--amber-500) 10%, transparent)}}.enrich-filter-chip:not(.active){opacity:.5}.enrich-filter-chip:not(.active):hover{opacity:.8}.enrich-filter-chip .enrich-dot{width:6px;height:6px}.enrich-filter-chip svg{flex:none}.enrich-filter-label{font-weight:500}.enrich-filter-count{font-variant-numeric:tabular-nums;font-weight:600}.sub-rail-list{flex:1;padding:4px 6px;overflow:auto}.sub-rail-list::-webkit-scrollbar{width:8px}.sub-rail-list::-webkit-scrollbar-thumb{background:var(--border-strong);background-clip:content-box;border:2px solid #0000;border-radius:4px}.sub-rail-row{cursor:default;width:100%;color:var(--ink-700);text-align:left;border-radius:6px;align-items:center;gap:8px;padding:5px 10px;text-decoration:none;transition:background .12s;display:flex}.sub-rail-row:hover{background:var(--surface-2);color:var(--ink-900)}.sub-rail-row.active{background:var(--red-50);color:var(--red-700)}.sub-rail-row .row-name{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;font-size:12.5px;font-weight:500;overflow:hidden}.sub-rail-row .row-meta{color:var(--ink-400);text-overflow:ellipsis;white-space:nowrap;font-size:10.5px;overflow:hidden}.sub-rail-row.active .row-meta{color:var(--red-600)}.sub-rail-row.untracked{opacity:.55}.sub-rail-row.untracked:hover{opacity:.8}.sub-rail-row.untracked.active{opacity:1}.sub-section-hd{letter-spacing:.08em;text-transform:uppercase;color:var(--ink-400);align-items:center;gap:6px;padding:10px 12px 4px;font-size:9.5px;font-weight:600;display:flex}.sub-section-hd .count{color:var(--ink-300);letter-spacing:0;font-weight:500}.schema-group{margin-bottom:2px}.schema-group-hd{text-align:left;cursor:pointer;width:100%;color:var(--ink-600);text-transform:uppercase;letter-spacing:.04em;background:0 0;border:none;border-radius:6px;justify-content:flex-start;align-items:center;gap:6px;padding:6px 10px;font-size:11px;font-weight:600;transition:background .12s;display:flex}.schema-group-hd:hover{background:var(--surface-2);color:var(--ink-900)}.schema-chevron{color:var(--ink-400);flex-shrink:0;transition:transform .15s}.schema-icon{color:var(--ink-400);flex-shrink:0}.schema-name{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.schema-count{color:var(--ink-400);letter-spacing:0;text-transform:none;flex-shrink:0;font-size:10px;font-weight:500}.schema-group-bd{padding-left:8px}.table-leaf{padding-left:28px}.main-pane{background:var(--bg);flex-direction:column;min-width:0;min-height:0;display:flex}.main-hd{border-bottom:1px solid var(--border);background:var(--surface);align-items:center;gap:14px;padding:10px 18px;display:flex}.main-hd .main-title{flex-direction:column;flex:1;gap:2px;min-width:0;display:flex}.main-hd h1{letter-spacing:-.02em;color:var(--ink-900);align-items:center;gap:10px;margin:0;font-size:16px;font-weight:600;display:flex}.main-hd .main-sub{color:var(--ink-500);font-size:11px;font-family:var(--font-mono)}.main-hd .main-actions{align-items:center;gap:8px;display:flex}.main-body{flex:1;padding:14px 18px 40px;overflow:auto}.sub-tabs{border-bottom:1px solid var(--border);background:var(--surface);gap:2px;padding:0 18px;display:flex}.sub-tab{height:30px;color:var(--ink-500);background:0 0;border:none;border-bottom:2px solid #0000;align-items:center;gap:6px;margin-bottom:-1px;padding:0 12px;font-size:12px;font-weight:500;text-decoration:none;transition:color .12s;display:flex}.sub-tab:hover{color:var(--ink-900)}.sub-tab.active{color:var(--red-600);border-bottom-color:var(--red-600)}.sub-tab .tab-badge{color:var(--ink-400);font-variant-numeric:tabular-nums;font-size:10.5px}.sub-tab.active .tab-badge{color:var(--red-600)}.btn{border:1px solid var(--border);background:var(--surface);height:28px;color:var(--ink-900);cursor:default;border-radius:6px;justify-content:center;align-items:center;gap:6px;padding:0 11px;font-size:12px;font-weight:500;text-decoration:none;transition:all .12s;display:inline-flex}.btn:hover{background:var(--surface-2);border-color:var(--border-strong)}.btn.primary{background:var(--red-600);color:#fff;border-color:var(--red-600);box-shadow:inset 0 -1.5px #0000002e,0 1px #14120f0a}.btn.primary:hover{background:var(--red-700);border-color:var(--red-700)}.btn.ghost{color:var(--ink-500);background:0 0;border-color:#0000}.btn.ghost:hover{background:var(--surface-2);color:var(--ink-900)}.btn.danger{color:var(--red-600);border-color:var(--red-600)}@supports (color:color-mix(in lab, red, red)){.btn.danger{border-color:color-mix(in oklab, var(--red-600), transparent 70%)}}.btn.danger:hover{background:var(--red-50)}.btn.sm{height:24px;padding:0 8px;font-size:11.5px}.btn.lg{height:32px;padding:0 13px;font-size:12.5px}.btn:disabled{opacity:.5;cursor:not-allowed}.card{background:var(--surface);border:1px solid var(--border);box-shadow:var(--shadow-1);border-radius:10px}.card-hd{border-bottom:1px solid var(--border);justify-content:space-between;align-items:center;padding:9px 14px;display:flex}.card-hd h3{color:var(--ink-900);letter-spacing:-.005em;align-items:center;gap:8px;margin:0;font-size:12.5px;font-weight:600;display:flex}.card-hd .card-meta{color:var(--ink-500);font-size:11px}.card-bd{padding:12px 14px}.card-bd.tight{padding:0}.field{flex-direction:column;gap:6px;display:flex}.field label{color:var(--ink-700);letter-spacing:.005em;justify-content:space-between;align-items:center;gap:8px;font-size:11px;font-weight:600;display:flex}.field .help{color:var(--ink-500);font-size:11px;font-weight:400}.env-var-field{border:1px solid var(--border);background:var(--surface-2);text-align:left;cursor:pointer;border-radius:6px;justify-content:space-between;align-items:center;gap:8px;width:100%;height:36px;padding:0 12px;display:flex}.env-var-field:disabled{cursor:default}.env-var-field .env-var-field-value{font-size:13px}.field input[type=text],.field input[type=number],.field input:not([type]),.field textarea,.field select{border:1px solid var(--border);background:var(--surface);color:var(--ink-900);border-radius:6px;outline:0;width:100%;padding:7px 9px;font-size:12px;transition:border-color .12s,box-shadow .12s}.field textarea{resize:vertical;min-height:64px;font-family:var(--font-sans);line-height:1.5}.field input:focus,.field textarea:focus,.field select:focus{border-color:var(--red-500);box-shadow:0 0 0 1.5px var(--red-100)}.pill{border:1px solid var(--border);background:var(--surface);height:20px;color:var(--ink-700);border-radius:10px;align-items:center;gap:6px;padding:0 8px;font-size:10.5px;display:inline-flex}.pill.ok{color:var(--green-500);border-color:var(--green-500)}@supports (color:color-mix(in lab, red, red)){.pill.ok{border-color:color-mix(in oklab, var(--green-500), transparent 70%)}}.pill.warn{color:var(--amber-500);border-color:var(--amber-500)}@supports (color:color-mix(in lab, red, red)){.pill.warn{border-color:color-mix(in oklab, var(--amber-500), transparent 70%)}}.chip{background:var(--surface-2);border:1px solid var(--border);height:20px;color:var(--ink-700);border-radius:10px;align-items:center;gap:5px;padding:0 8px;font-size:10.5px;font-weight:500;display:inline-flex}.chip.red{background:var(--red-50);border-color:var(--red-100);color:var(--red-700)}.chip.blue{background:var(--blue-500)}@supports (color:color-mix(in lab, red, red)){.chip.blue{background:color-mix(in oklab, var(--blue-500), transparent 92%)}}.chip.blue{border-color:var(--blue-500)}@supports (color:color-mix(in lab, red, red)){.chip.blue{border-color:color-mix(in oklab, var(--blue-500), transparent 80%)}}.chip.blue{color:var(--blue-500)}.chip.green{background:var(--green-500)}@supports (color:color-mix(in lab, red, red)){.chip.green{background:color-mix(in oklab, var(--green-500), transparent 92%)}}.chip.green{border-color:var(--green-500)}@supports (color:color-mix(in lab, red, red)){.chip.green{border-color:color-mix(in oklab, var(--green-500), transparent 80%)}}.chip.green{color:var(--green-500)}.chip.amber{background:var(--amber-500)}@supports (color:color-mix(in lab, red, red)){.chip.amber{background:color-mix(in oklab, var(--amber-500), transparent 92%)}}.chip.amber{border-color:var(--amber-500)}@supports (color:color-mix(in lab, red, red)){.chip.amber{border-color:color-mix(in oklab, var(--amber-500), transparent 80%)}}.chip.amber{color:var(--amber-500)}.stat-card{flex-direction:column;gap:6px;padding:10px 14px;display:flex}.stat-card .stat-label{color:var(--ink-500);text-transform:uppercase;letter-spacing:.06em;font-size:10px;font-weight:600}.stat-card .stat-num{letter-spacing:-.02em;color:var(--ink-900);font-variant-numeric:tabular-nums;font-size:22px;font-weight:600;line-height:1.1}.stat-card .stat-hint{color:var(--ink-500);font-size:11px}.stat-card .stat-delta{color:var(--ink-500);align-items:center;gap:5px;font-size:11px;display:flex}.stat-card .stat-delta.up{color:var(--green-500)}.stat-card .stat-delta.dn{color:var(--red-600)}.enrich-dot{background:var(--ink-300);border-radius:50%;flex:none;width:6px;height:6px;display:inline-block}.enrich-dot.full,.enrich-dot.enriched{background:var(--green-500)}.enrich-dot.partial{background:var(--amber-500)}.enrich-dot.none{background:var(--ink-300)}.toggle-seg{background:var(--surface-2);border:1px solid var(--border);border-radius:7px;gap:2px;margin:0;padding:2px;display:inline-flex}.toggle-seg button{height:24px;color:var(--ink-500);background:0 0;border:0;border-radius:5px;padding:0 12px;font-size:12px;font-weight:500}.toggle-seg button.on,.toggle-seg button.active{background:var(--surface);color:var(--ink-900);box-shadow:var(--shadow-1)}.tbl{border-collapse:separate;border-spacing:0;width:100%;font-size:12px}.tbl th{color:var(--ink-500);text-align:left;text-transform:uppercase;letter-spacing:.05em;background:var(--surface-2);border-bottom:1px solid var(--border);padding:6px 12px;font-size:10.5px;font-weight:600}.tbl td{border-bottom:1px solid var(--border);color:var(--ink-900);vertical-align:top;padding:7px 12px}.tbl tr:last-child td{border-bottom:0}.tbl tr:hover td{background:var(--surface-2)}.code-block{color:#f5f3f0;font:13px/1.6 var(--font-mono);white-space:pre-wrap;background:#15110f;border:1px solid #2a2421;border-radius:8px;margin:0;padding:14px 16px;overflow:auto}.code-block .k{color:#ff9ba6}.code-block .s{color:#a3e1b2}.code-block .n{color:#f4c879}.code-block .c{color:#7a756d;font-style:italic}.suggest-link{color:var(--red-600);cursor:default;background:0 0;border:none;align-items:center;gap:5px;padding:0;font-size:11.5px;font-weight:500;display:inline-flex}.suggest-link:hover{color:var(--red-700)}.bar{background:var(--surface-3);border-radius:3px;height:6px;overflow:hidden}.bar>i{background:var(--red-600);border-radius:3px;height:100%;display:block}.grid-2{grid-template-columns:1fr 1fr;gap:12px;display:grid}.grid-3{grid-template-columns:repeat(3,1fr);gap:10px;display:grid}.grid-4{grid-template-columns:repeat(4,1fr);gap:10px;display:grid}.stack{flex-direction:column;gap:12px;display:flex}.stack.tight{gap:8px}.row-h{align-items:center;gap:10px;display:flex}.spread{justify-content:space-between;align-items:center;gap:12px;display:flex}.muted{color:var(--ink-500)}.tiny{font-size:11px}.policy-edge-card{border:1px solid var(--border);border-radius:var(--radius);justify-content:space-between;align-items:start;gap:8px;padding:12px;font-size:13px;display:flex}.collapsible-btn{cursor:pointer;color:var(--ink-700);background:0 0;border:none;align-items:center;gap:6px;margin-bottom:8px;padding:0;font-size:13px;font-weight:600;display:flex}.check{color:var(--ink-700);align-items:center;gap:6px;font-size:12px;display:inline-flex}.check input{accent-color:var(--red-600);width:14px;height:14px}.status-banner{border-bottom:1px solid var(--border);align-items:center;gap:8px;min-height:32px;padding:6px 18px;font-size:12px;display:flex}.status-banner.neutral,.status-banner.loading{color:var(--ink-500)}.status-banner.success{color:var(--green-500)}.status-banner.error{color:var(--red-600)}.inline-status{overflow-wrap:anywhere;align-items:center;gap:6px;min-height:20px;font-size:12px;display:flex}.inline-status.neutral,.inline-status.loading{color:var(--ink-500)}.inline-status.success{color:var(--green-500)}.inline-status.error{color:var(--red-600)}.dialog-overlay{z-index:40;background:#14120f59;justify-content:center;align-items:center;padding:18px;display:flex;position:fixed;inset:0}.dialog{border:1px solid var(--border);background:var(--surface);width:min(720px,100%);max-height:min(760px,90vh);box-shadow:var(--shadow-2);border-radius:10px;flex-direction:column;display:flex;overflow:hidden}.dialog-hd{border-bottom:1px solid var(--border);justify-content:space-between;align-items:center;gap:10px;padding:14px 16px;display:flex}.dialog-hd h3{color:var(--ink-900);margin:0;font-size:14px;font-weight:600}.dialog-bd{flex-direction:column;flex:1;gap:10px;padding:16px;display:flex;overflow:auto}.candidate{white-space:pre-wrap;overflow-wrap:anywhere;border:1px solid var(--border);background:var(--bg);text-align:left;border-radius:6px;width:100%;padding:12px;font-size:12px}.candidate p{margin:0}.candidate:hover{border-color:var(--red-600)}@supports (color:color-mix(in lab, red, red)){.candidate:hover{border-color:color-mix(in oklab, var(--red-600), transparent 55%)}}.candidate:hover{background:var(--red-50)}.candidate-actions{justify-content:flex-end;margin-top:10px;display:flex}.sql-block{white-space:pre-wrap;overflow-wrap:anywhere;color:#f5f3f0;background:#15110f;border-radius:8px;min-height:120px;margin:0;padding:14px 16px;font-size:12px;line-height:1.5}.plain-block,.warning-block{white-space:pre-wrap;overflow-wrap:anywhere;border:1px solid var(--border);background:var(--surface);border-radius:6px;margin:0;padding:10px;font-size:12px;line-height:1.5}.warning-block{border-color:var(--amber-500)}@supports (color:color-mix(in lab, red, red)){.warning-block{border-color:color-mix(in oklab, var(--amber-500), transparent 75%)}}.warning-block{background:var(--amber-500)}@supports (color:color-mix(in lab, red, red)){.warning-block{background:color-mix(in oklab, var(--amber-500), transparent 92%)}}.warning-block{color:var(--amber-500)}.definition-list{grid-template-columns:110px minmax(0,1fr);gap:8px 12px;font-size:12px;display:grid}.definition-list dt{color:var(--ink-500);font-weight:600}.definition-list dd{overflow-wrap:anywhere;min-width:0}.chunk-card{border:1px solid var(--border);background:var(--surface);border-radius:8px;min-width:0;padding:12px}.chunk-text{border:1px solid var(--border);background:var(--bg);max-height:220px;color:var(--ink-900);white-space:pre-wrap;overflow-wrap:anywhere;border-radius:6px;margin-top:10px;padding:10px;font-size:12px;line-height:1.5;overflow:auto}.chunk-toggle{border:1px solid var(--border);background:var(--bg);border-radius:999px;align-items:center;gap:5px;padding:4px 8px;font-size:12px;display:inline-flex}.chunk-toggle input{width:auto}.column-row{border:1px solid var(--border);background:var(--surface);border-radius:8px;min-width:0;padding:14px}.relationship-row{border:1px solid var(--border);background:var(--surface);border-radius:6px;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);align-items:center;gap:8px;padding:10px;font-size:12px;display:grid}.usage-summary{gap:8px;display:grid}.usage-summary h3{color:var(--ink-500);margin:0;font-size:12px;font-weight:700}.usage-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:8px;display:grid}.usage-grid div{border:1px solid var(--border);background:var(--bg);border-radius:6px;min-width:0;padding:8px}.usage-grid .usage-total{grid-column:1/-1}.usage-grid dt{color:var(--ink-500);font-size:11px;font-weight:600}.usage-grid dd{overflow-wrap:anywhere;margin-top:3px;font-size:15px;font-weight:700}.concept-id-input{border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);align-items:center;height:36px;transition:border-color .12s,box-shadow .12s;display:flex;overflow:hidden}.concept-id-input:focus-within{border-color:var(--red-500);box-shadow:0 0 0 1.5px var(--red-100)}.concept-id-prefix{background:var(--surface-2);border-right:1px solid var(--border);height:100%;color:var(--ink-400);font-family:var(--font-mono);white-space:nowrap;-webkit-user-select:none;user-select:none;align-items:center;padding:0 8px;font-size:12px;font-weight:500;display:flex}.concept-id-slug{min-width:0;height:100%;font-family:var(--font-mono);color:var(--ink-900);background:0 0;border:none;outline:none;flex:1;padding:0 8px;font-size:12px}.concept-id-slug::placeholder{color:var(--ink-400)}.links-input{border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);transition:border-color .12s,box-shadow .12s;position:relative}.links-input:focus-within{border-color:var(--red-500);box-shadow:0 0 0 1.5px var(--red-100)}.links-chips{flex-wrap:wrap;gap:4px;padding:6px 8px 2px;display:flex}.links-chip{height:22px;font-size:11px;font-family:var(--font-mono);white-space:nowrap;border-radius:4px;align-items:center;gap:3px;max-width:220px;padding:0 4px 0 6px;display:inline-flex;overflow:hidden}.links-chip.table{background:var(--blue-500)}@supports (color:color-mix(in lab, red, red)){.links-chip.table{background:color-mix(in srgb, var(--blue-500) 10%, transparent)}}.links-chip.table{color:var(--blue-500);border:1px solid var(--blue-500)}@supports (color:color-mix(in lab, red, red)){.links-chip.table{border:1px solid color-mix(in srgb, var(--blue-500) 25%, transparent)}}.links-chip.column{background:var(--green-500)}@supports (color:color-mix(in lab, red, red)){.links-chip.column{background:color-mix(in srgb, var(--green-500) 10%, transparent)}}.links-chip.column{color:var(--green-500);border:1px solid var(--green-500)}@supports (color:color-mix(in lab, red, red)){.links-chip.column{border:1px solid color-mix(in srgb, var(--green-500) 25%, transparent)}}.links-chip-label{text-overflow:ellipsis;overflow:hidden}.links-chip-remove{width:14px;height:14px;color:inherit;opacity:.6;cursor:pointer;background:0 0;border:none;border-radius:2px;flex-shrink:0;justify-content:center;align-items:center;display:flex}.links-chip-remove:hover{opacity:1;background:#00000014}.links-search{height:32px;color:var(--ink-400);align-items:center;gap:6px;padding:0 8px;display:flex}.links-search-input{min-width:0;color:var(--ink-900);background:0 0;border:none;outline:none;flex:1;font-size:12px}.links-search-input::placeholder{color:var(--ink-400)}.links-dropdown{border:1px solid var(--border);border-radius:var(--radius);background:var(--surface);max-height:240px;box-shadow:var(--shadow-2);z-index:50;margin:0;padding:0;list-style:none;position:absolute;top:100%;left:0;right:0;overflow:auto}.links-dropdown-item{text-align:left;width:100%;color:var(--ink-700);cursor:pointer;background:0 0;border:none;align-items:center;gap:8px;padding:6px 10px;font-size:12px;transition:background 80ms;display:flex}.links-dropdown-item:hover,.links-dropdown-item.highlighted{background:var(--surface-2);color:var(--ink-900)}.links-kind-badge{border-radius:3px;flex-shrink:0;justify-content:center;align-items:center;width:18px;height:18px;font-size:10px;font-weight:700;display:inline-flex}.links-kind-badge.table{background:var(--blue-500)}@supports (color:color-mix(in lab, red, red)){.links-kind-badge.table{background:color-mix(in srgb, var(--blue-500) 12%, transparent)}}.links-kind-badge.table{color:var(--blue-500)}.links-kind-badge.column{background:var(--green-500)}@supports (color:color-mix(in lab, red, red)){.links-kind-badge.column{background:color-mix(in srgb, var(--green-500) 12%, transparent)}}.links-kind-badge.column{color:var(--green-500)}.links-dropdown-label{text-overflow:ellipsis;white-space:nowrap;min-width:0;font-family:var(--font-mono);flex:1;overflow:hidden}.links-dropdown-more{color:var(--ink-400);text-align:center;border-top:1px solid var(--border);padding:6px 10px;font-size:11px}@keyframes spin{to{transform:rotate(360deg)}}.animate-spin{animation:1s linear infinite spin}@keyframes fadeIn{0%{opacity:0;transform:translateY(6px)}to{opacity:1;transform:translateY(0)}}.fade-in{animation:.18s ease-out fadeIn}.toggle-seg button{transition:background .12s,color .12s,box-shadow .12s}.sub-tab{transition:color .12s,border-color .12s}.card{transition:box-shadow .15s}.card:hover{box-shadow:var(--shadow-2)}.pill{transition:background .12s,border-color .12s}:focus-visible,button:focus-visible,a:focus-visible{outline:1.5px solid var(--red-500);outline-offset:1px}input:focus-visible,textarea:focus-visible,select:focus-visible{border-color:var(--red-500);box-shadow:0 0 0 1.5px var(--red-100);outline:none}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:0 0}::-webkit-scrollbar-thumb{background:var(--border-strong);background-clip:content-box;border:2px solid #0000;border-radius:4px}::-webkit-scrollbar-thumb:hover{background-color:var(--ink-300)}@media (width<=1280px){:root{--sub-w:220px}.grid-4,.grid-3{grid-template-columns:repeat(2,1fr)}}@media (width<=960px){:root{--sub-w:0px}.sub-rail{display:none}.app-content,.grid-4,.grid-3,.grid-2{grid-template-columns:1fr}}[data-theme=dark]{--lightningcss-light: ;--lightningcss-dark:initial;color-scheme:dark;--sidebar:var(--surface);--sidebar-foreground:var(--ink-700);--sidebar-primary:var(--red-600);--sidebar-primary-foreground:#fff;--sidebar-accent:var(--surface-2);--sidebar-accent-foreground:var(--ink-900);--sidebar-border:var(--border);--sidebar-ring:var(--red-500);--color-accent:var(--surface-2);--color-accent-foreground:var(--ink-900)}@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-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-ordinal{syntax:"*";inherits:false}@property --tw-slashed-zero{syntax:"*";inherits:false}@property --tw-numeric-figure{syntax:"*";inherits:false}@property --tw-numeric-spacing{syntax:"*";inherits:false}@property --tw-numeric-fraction{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<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}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-duration{syntax:"*";inherits:false}@property --tw-ease{syntax:"*";inherits:false}@property --tw-content{syntax:"*";inherits:false;initial-value:""}@keyframes pulse{50%{opacity:.5}}