@elench/shell 0.1.8 → 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.
package/README.md CHANGED
@@ -1,27 +1,27 @@
1
1
  # @elench/shell
2
2
 
3
- Avocado's desktop shell extracted into a reusable React package.
3
+ Reusable React shell for Elench desktop-style workspaces.
4
4
 
5
5
  The package owns the shell frame, FlexLayout substrate, activity rail, sidebar,
6
6
  workspace tabs, inspector, search bar, status bar, keyboard shortcuts, state
7
- persistence, and Avocado shell styling. Product code consumes only the public
7
+ persistence, and shell styling. Product code consumes only the public
8
8
  API exported from `@elench/shell`.
9
9
 
10
10
  ## Public API
11
11
 
12
12
  ```tsx
13
13
  import {
14
- ShellApp,
15
- defineShellApp,
16
- defineShellSection,
17
- defineShellTab,
14
+ ShellWorkbench,
15
+ defineWorkbenchApp,
16
+ defineWorkbenchTab,
18
17
  } from "@elench/shell";
19
18
  import "@elench/shell/styles.css";
20
19
  ```
21
20
 
22
- Studio/product code defines sections and tabs. The shell adapts those
23
- definitions into the Avocado shell internals; consumers should not import
24
- FlexLayout, shell internals, or package source paths directly.
21
+ Product code defines sections, tabs, resources, commands, and declarative view
22
+ nodes. The shell adapts those definitions into its internal layout substrate;
23
+ consumers should not import FlexLayout, shell internals, package source paths,
24
+ or UI primitives directly.
25
25
 
26
26
  ## Commands
27
27
 
@@ -4,6 +4,6 @@ import { cn } from "../../../lib/utils.js";
4
4
  import { useShellSurface } from "./shell-surface.js";
5
5
  export function SidebarNewButton({ className, noun, type = "button", ...props }) {
6
6
  const { isCompact, isNarrow } = useShellSurface();
7
- return (_jsxs("button", { className: cn("mx-0.5 mt-1 mb-1.5 flex w-[calc(100%-4px)] items-center justify-center gap-1.5 rounded-[7px] bg-bg-elevated px-3 py-[7px] text-[12px] font-medium text-fg-secondary transition-all", "hover:bg-bg-hover hover:text-fg", "active:translate-y-px active:bg-bg-active", "disabled:pointer-events-none disabled:opacity-50", isCompact && "mt-0.5 mb-1 px-2.5 py-1.5", isNarrow && "mx-0 mt-0.5 w-full gap-1 px-2 py-1.5 text-[11.5px]", className), type: type, ...props, children: [_jsx(PlusIcon, { className: cn("size-3.5", isNarrow && "size-3") }), _jsxs("span", { className: "min-w-0 truncate", children: ["New ", noun] })] }));
7
+ return (_jsxs("button", { className: cn("mx-0.5 mt-1 mb-1.5 flex w-[calc(100%-4px)] items-center justify-center gap-1.5 rounded-[7px] border border-border bg-bg-elevated px-3 py-[7px] text-[12px] font-semibold tracking-[0.01em] text-fg-secondary transition-all", "hover:border-border-light hover:bg-bg-hover hover:text-fg", "active:translate-y-px active:bg-bg-active", "disabled:pointer-events-none disabled:opacity-50", isCompact && "mt-0.5 mb-1 px-2.5 py-1.5", isNarrow && "mx-0 mt-0.5 w-full gap-1 px-2 py-1.5 text-[11.5px]", className), type: type, ...props, children: [_jsx(PlusIcon, { className: cn("size-3.5", isNarrow && "size-3") }), _jsxs("span", { className: "min-w-0 truncate", children: ["New ", noun] })] }));
8
8
  }
9
9
  //# sourceMappingURL=sidebar-new-button.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sidebar-new-button.js","sourceRoot":"","sources":["../../../../src/components/shell/primitives/sidebar-new-button.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AASlD,MAAM,UAAU,gBAAgB,CAAC,EAC/B,SAAS,EACT,IAAI,EACJ,IAAI,GAAG,QAAQ,EACf,GAAG,KAAK,EACc;IACtB,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,eAAe,EAAE,CAAC;IAElD,OAAO,CACL,kBACE,SAAS,EAAE,EAAE,CACX,oLAAoL,EACpL,iCAAiC,EACjC,2CAA2C,EAC3C,kDAAkD,EAClD,SAAS,IAAI,2BAA2B,EACxC,QAAQ,IAAI,oDAAoD,EAChE,SAAS,CACV,EACD,IAAI,EAAE,IAAI,KACN,KAAK,aAET,KAAC,QAAQ,IAAC,SAAS,EAAE,EAAE,CAAC,UAAU,EAAE,QAAQ,IAAI,QAAQ,CAAC,GAAI,EAC7D,gBAAM,SAAS,EAAC,kBAAkB,qBAAM,IAAI,IAAQ,IAC7C,CACV,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"sidebar-new-button.js","sourceRoot":"","sources":["../../../../src/components/shell/primitives/sidebar-new-button.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxC,OAAO,EAAE,EAAE,EAAE,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AASlD,MAAM,UAAU,gBAAgB,CAAC,EAC/B,SAAS,EACT,IAAI,EACJ,IAAI,GAAG,QAAQ,EACf,GAAG,KAAK,EACc;IACtB,MAAM,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,eAAe,EAAE,CAAC;IAElD,OAAO,CACL,kBACE,SAAS,EAAE,EAAE,CACX,6NAA6N,EAC7N,2DAA2D,EAC3D,2CAA2C,EAC3C,kDAAkD,EAClD,SAAS,IAAI,2BAA2B,EACxC,QAAQ,IAAI,oDAAoD,EAChE,SAAS,CACV,EACD,IAAI,EAAE,IAAI,KACN,KAAK,aAET,KAAC,QAAQ,IAAC,SAAS,EAAE,EAAE,CAAC,UAAU,EAAE,QAAQ,IAAI,QAAQ,CAAC,GAAI,EAC7D,gBAAM,SAAS,EAAC,kBAAkB,qBAAM,IAAI,IAAQ,IAC7C,CACV,CAAC;AACJ,CAAC"}
package/dist/index.d.ts CHANGED
@@ -1,3 +1,6 @@
1
- export { ShellApp, ShellEmptyState, ShellField, ShellMetric, ShellPage, ShellSidebar, ShellSidebarItem, ShellSidebarNewButton, ShellSidebarSection, defineShellApp, defineShellSection, defineShellTab, useShellController, } from "./public-api.js";
2
- export type { DefineShellSectionInput, ShellActionMeta, ShellAppDefinition, ShellAppProps, ShellController, ShellRenderContext, ShellSectionDefinition, ShellSidebarContext, ShellTab, ShellTabTarget, ShellTabTone, } from "./public-api.js";
1
+ export { ShellErrorBoundaryView, ShellWorkbench, defineWorkbenchApp, defineWorkbenchTab, } from "./workbench.js";
2
+ export type { ShellTabTarget, ShellTabTone } from "./lib/shell/types.js";
3
+ export type { ShellCommandDefinition, ShellCommandHelpers, ShellCommandState, ShellInspectorField, ShellMetricDefinition, ShellResourceDefinition, ShellResourceState, ShellRowDefinition, ShellRowStatus, ShellSidebarItemDefinition, ShellSidebarNewDefinition, ShellSidebarSectionDefinition, ShellTabInput, ShellTransport, ShellViewContext, ShellViewNode, ShellWorkbenchAppDefinition, ShellWorkbenchSectionDefinition, ShellWorkbenchTab, } from "./workbench.js";
4
+ export { createShellApiClient, ShellApiError } from "./lib/shell/api.js";
5
+ export type { ShellApiClientOptions, ShellApiRequestInit, ShellApiResponseType, } from "./lib/shell/api.js";
3
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,eAAe,EACf,UAAU,EACV,WAAW,EACX,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,uBAAuB,EACvB,eAAe,EACf,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,kBAAkB,EAClB,sBAAsB,EACtB,mBAAmB,EACnB,QAAQ,EACR,cAAc,EACd,YAAY,GACb,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzE,YAAY,EACV,sBAAsB,EACtB,mBAAmB,EACnB,iBAAiB,EACjB,mBAAmB,EACnB,qBAAqB,EACrB,uBAAuB,EACvB,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,EACd,0BAA0B,EAC1B,yBAAyB,EACzB,6BAA6B,EAC7B,aAAa,EACb,cAAc,EACd,gBAAgB,EAChB,aAAa,EACb,2BAA2B,EAC3B,+BAA+B,EAC/B,iBAAiB,GAClB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACzE,YAAY,EACV,qBAAqB,EACrB,mBAAmB,EACnB,oBAAoB,GACrB,MAAM,oBAAoB,CAAC"}
package/dist/index.js CHANGED
@@ -1,2 +1,3 @@
1
- export { ShellApp, ShellEmptyState, ShellField, ShellMetric, ShellPage, ShellSidebar, ShellSidebarItem, ShellSidebarNewButton, ShellSidebarSection, defineShellApp, defineShellSection, defineShellTab, useShellController, } from "./public-api.js";
1
+ export { ShellErrorBoundaryView, ShellWorkbench, defineWorkbenchApp, defineWorkbenchTab, } from "./workbench.js";
2
+ export { createShellApiClient, ShellApiError } from "./lib/shell/api.js";
2
3
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,eAAe,EACf,UAAU,EACV,WAAW,EACX,SAAS,EACT,YAAY,EACZ,gBAAgB,EAChB,qBAAqB,EACrB,mBAAmB,EACnB,cAAc,EACd,kBAAkB,EAClB,cAAc,EACd,kBAAkB,GACnB,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,sBAAsB,EACtB,cAAc,EACd,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,gBAAgB,CAAC;AAuBxB,OAAO,EAAE,oBAAoB,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC"}
@@ -0,0 +1,17 @@
1
+ export declare class ShellApiError extends Error {
2
+ status: number;
3
+ body?: unknown | undefined;
4
+ constructor(status: number, message: string, body?: unknown | undefined);
5
+ }
6
+ export type ShellApiResponseType = "json" | "text" | "blob" | "arrayBuffer" | "void";
7
+ export type ShellApiRequestInit = RequestInit & {
8
+ json?: unknown;
9
+ responseType?: ShellApiResponseType;
10
+ };
11
+ export type ShellApiClientOptions = {
12
+ baseUrl?: string;
13
+ getToken?: () => string | null | Promise<string | null>;
14
+ getTraceId?: () => string;
15
+ };
16
+ export declare function createShellApiClient({ baseUrl, getToken, getTraceId, }?: ShellApiClientOptions): <T>(path: string, init?: ShellApiRequestInit) => Promise<T>;
17
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../../src/lib/shell/api.ts"],"names":[],"mappings":"AAIA,qBAAa,aAAc,SAAQ,KAAK;IAE7B,MAAM,EAAE,MAAM;IAEd,IAAI,CAAC,EAAE,OAAO;gBAFd,MAAM,EAAE,MAAM,EACrB,OAAO,EAAE,MAAM,EACR,IAAI,CAAC,EAAE,OAAO,YAAA;CAIxB;AAED,MAAM,MAAM,oBAAoB,GAC5B,MAAM,GACN,MAAM,GACN,MAAM,GACN,aAAa,GACb,MAAM,CAAC;AAEX,MAAM,MAAM,mBAAmB,GAAG,WAAW,GAAG;IAC9C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,YAAY,CAAC,EAAE,oBAAoB,CAAC;CACrC,CAAC;AAEF,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,MAAM,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;IACxD,UAAU,CAAC,EAAE,MAAM,MAAM,CAAC;CAC3B,CAAC;AAoDF,wBAAgB,oBAAoB,CAAC,EACnC,OAAY,EACZ,QAAQ,EACR,UAA4B,GAC7B,GAAE,qBAA0B,IACS,CAAC,EACnC,MAAM,MAAM,EACZ,OAAO,mBAAmB,KACzB,OAAO,CAAC,CAAC,CAAC,CAkDd"}
@@ -0,0 +1,93 @@
1
+ import { logger, sessionId } from "../infra/logger.js";
2
+ const apiLog = logger.named("api");
3
+ export class ShellApiError extends Error {
4
+ constructor(status, message, body) {
5
+ super(message);
6
+ this.status = status;
7
+ this.body = body;
8
+ }
9
+ }
10
+ function resolveUrl(baseUrl, path) {
11
+ if (/^https?:\/\//.test(path))
12
+ return path;
13
+ const normalizedBase = baseUrl.endsWith("/") ? baseUrl.slice(0, -1) : baseUrl;
14
+ const normalizedPath = path.startsWith("/") ? path : `/${path}`;
15
+ return `${normalizedBase}${normalizedPath}`;
16
+ }
17
+ function headersFrom(initHeaders) {
18
+ return new Headers(initHeaders);
19
+ }
20
+ async function parseResponse(response, responseType, method) {
21
+ if (response.status === 204 || response.status === 205 || method === "HEAD") {
22
+ return undefined;
23
+ }
24
+ const resolvedType = responseType ??
25
+ (response.headers.get("content-type")?.includes("application/json")
26
+ ? "json"
27
+ : "text");
28
+ switch (resolvedType) {
29
+ case "void":
30
+ return undefined;
31
+ case "text":
32
+ return (await response.text());
33
+ case "blob":
34
+ return (await response.blob());
35
+ case "arrayBuffer":
36
+ return (await response.arrayBuffer());
37
+ case "json":
38
+ default:
39
+ return (await response.json());
40
+ }
41
+ }
42
+ async function parseErrorBody(response) {
43
+ const contentType = response.headers.get("content-type") ?? "";
44
+ if (contentType.includes("application/json")) {
45
+ return response.json().catch(() => null);
46
+ }
47
+ const text = await response.text().catch(() => "");
48
+ return text || null;
49
+ }
50
+ export function createShellApiClient({ baseUrl = "", getToken, getTraceId = () => sessionId, } = {}) {
51
+ return async function shellApiFetch(path, init) {
52
+ const body = init?.json !== undefined
53
+ ? JSON.stringify(init.json)
54
+ : (init?.body ?? null);
55
+ const method = init?.method ?? "GET";
56
+ const headers = headersFrom(init?.headers);
57
+ const token = getToken ? await getToken() : null;
58
+ headers.set("X-Session-ID", getTraceId());
59
+ if (token && !headers.has("Authorization")) {
60
+ headers.set("Authorization", `Bearer ${token}`);
61
+ }
62
+ if (init?.json !== undefined &&
63
+ body !== null &&
64
+ body !== undefined &&
65
+ !headers.has("Content-Type")) {
66
+ headers.set("Content-Type", "application/json");
67
+ }
68
+ const start = performance.now();
69
+ const url = resolveUrl(baseUrl, path);
70
+ const response = await fetch(url, { ...init, body, headers });
71
+ const durationMs = Math.round(performance.now() - start);
72
+ apiLog
73
+ .event("api.request")
74
+ .setMany({
75
+ method,
76
+ path,
77
+ status: response.status,
78
+ duration_ms: durationMs,
79
+ })
80
+ .setLevel(response.status >= 500 ? "error" : "info")
81
+ .send();
82
+ if (!response.ok) {
83
+ const errorBody = await parseErrorBody(response);
84
+ const message = typeof errorBody === "string"
85
+ ? errorBody
86
+ : (errorBody?.error ??
87
+ response.statusText);
88
+ throw new ShellApiError(response.status, message, errorBody);
89
+ }
90
+ return parseResponse(response, init?.responseType, method);
91
+ };
92
+ }
93
+ //# sourceMappingURL=api.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../../src/lib/shell/api.ts"],"names":[],"mappings":"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"}
package/dist/styles.css CHANGED
@@ -1,6 +1,6 @@
1
1
  @import "flexlayout-react/style/light.css";
2
2
 
3
- /* ═══════ FlexLayout Avocado Theme ═══════ */
3
+ /* ═══════ FlexLayout Shell Theme ═══════ */
4
4
 
5
5
  .flexlayout__layout {
6
6
  --color-text: var(--fg);
@@ -345,3 +345,408 @@
345
345
  background: var(--fg-tertiary);
346
346
  border-radius: 4px;
347
347
  }
348
+
349
+ @custom-variant dark (&:where(.dark, .dark *, .theme-carbon, .theme-carbon *, .theme-dark, .theme-dark *, .theme-night-owl, .theme-night-owl *));
350
+
351
+ /* ── Theme foundation ─────────────────────────────────────────────── */
352
+ :root {
353
+ --font-geist-sans: "Geist Variable";
354
+ --font-geist-mono: "Geist Mono Variable";
355
+ --transition: 150ms ease;
356
+ --radius: 0.5rem;
357
+
358
+ /* Canonical semantic tokens default to Studio carbon. */
359
+ --background: #0a1120;
360
+ --foreground: #e5edf7;
361
+ --card: #162236;
362
+ --card-foreground: #e5edf7;
363
+ --popover: #162236;
364
+ --popover-foreground: #e5edf7;
365
+ --primary: #3b82f6;
366
+ --primary-foreground: #f8fbff;
367
+ --secondary: #0f172a;
368
+ --secondary-foreground: #e5edf7;
369
+ --muted: #0f172a;
370
+ --muted-foreground: #73839b;
371
+ --accent: #1e3050;
372
+ --accent-foreground: #e5edf7;
373
+ --destructive: #ef4444;
374
+ --destructive-foreground: #fef2f2;
375
+ --border: #1e2d44;
376
+ --input: #1e2d44;
377
+ --ring: #3b82f6;
378
+
379
+ /* Product-specific tokens that do not map cleanly to generic semantics. */
380
+ --fg-80: rgba(229, 237, 247, 0.8);
381
+ --fg-secondary: #a8b5c7;
382
+ --fg-tertiary: #73839b;
383
+ --fg-inverse: #0a1120;
384
+ --border-light: #2a3f5f;
385
+ --primary-hover: #2563eb;
386
+ --primary-rgb: 59, 130, 246;
387
+
388
+ --status-ok: rgb(34, 197, 94);
389
+ --status-ok-bg: rgba(34, 197, 94, 0.1);
390
+ --status-ok-border: rgba(34, 197, 94, 0.28);
391
+ --status-err: rgb(239, 68, 68);
392
+ --status-err-bg: rgba(239, 68, 68, 0.1);
393
+ --status-err-border: rgba(239, 68, 68, 0.28);
394
+ --status-warn: rgb(245, 158, 11);
395
+ --status-warn-bg: rgba(245, 158, 11, 0.1);
396
+ --status-warn-border: rgba(245, 158, 11, 0.28);
397
+ --status-info: rgb(56, 189, 248);
398
+ --status-info-bg: rgba(56, 189, 248, 0.1);
399
+ --status-info-border: rgba(56, 189, 248, 0.28);
400
+ --status-debug: #7a8499;
401
+ --status-debug-bg: rgba(122, 132, 153, 0.1);
402
+ --status-muted: var(--fg-tertiary);
403
+ --status-auto: rgb(59, 130, 246);
404
+ --status-auto-bg: rgba(59, 130, 246, 0.12);
405
+ --status-auto-border: rgba(59, 130, 246, 0.28);
406
+
407
+ --chart-1: #93c5fd;
408
+ --chart-2: #60a5fa;
409
+ --chart-3: #38bdf8;
410
+ --chart-4: #22c55e;
411
+ --chart-5: #f59e0b;
412
+
413
+ /* Shell aliases derived from semantic tokens. */
414
+ --bg-primary: var(--background);
415
+ --bg-secondary: var(--secondary);
416
+ --bg-card: var(--card);
417
+ --bg-muted: var(--muted);
418
+ --bg-hover: var(--accent);
419
+ --bg-base: var(--background);
420
+ --bg-surface: var(--secondary);
421
+ --bg-elevated: #1b2a42;
422
+ --bg-active: #1a2d4a;
423
+ --fg: var(--foreground);
424
+ --fg-muted: var(--fg-tertiary);
425
+ --primary-muted: rgba(var(--primary-rgb), 0.12);
426
+ --shell-gap: 6px;
427
+ --shell-radius: 8px;
428
+ --border-subtle: #172338;
429
+ --border-strong: var(--border-light);
430
+ --ok: var(--status-ok);
431
+ --warn: var(--status-warn);
432
+ --error: var(--status-err);
433
+ --info: var(--status-info);
434
+ --ok-glow: rgba(34, 197, 94, 0.3);
435
+ --warn-glow: rgba(245, 158, 11, 0.3);
436
+ --error-glow: rgba(239, 68, 68, 0.3);
437
+ --info-glow: rgba(56, 189, 248, 0.3);
438
+ --error-bg: rgba(239, 68, 68, 0.1);
439
+
440
+ /* Brand gradients */
441
+ --gradient-brand: linear-gradient(135deg, #22c55e 0%, #3b82f6 100%);
442
+ --gradient-cta: linear-gradient(
443
+ 135deg,
444
+ #3b82f6 0%,
445
+ #2563eb 50%,
446
+ #1d4ed8 100%
447
+ );
448
+
449
+ --sidebar: var(--secondary);
450
+ --sidebar-foreground: var(--foreground);
451
+ --sidebar-primary: var(--primary);
452
+ --sidebar-primary-foreground: var(--primary-foreground);
453
+ --sidebar-accent: var(--accent);
454
+ --sidebar-accent-foreground: var(--accent-foreground);
455
+ --sidebar-border: var(--border);
456
+ --sidebar-ring: var(--ring);
457
+ }
458
+
459
+ .theme-carbon {
460
+ }
461
+
462
+ .theme-light {
463
+ --gradient-brand: linear-gradient(135deg, #16a34a 0%, #2563eb 100%);
464
+ --gradient-cta: linear-gradient(
465
+ 135deg,
466
+ #2563eb 0%,
467
+ #1d4ed8 50%,
468
+ #1e40af 100%
469
+ );
470
+
471
+ --background: #f8fafc;
472
+ --foreground: #0f172a;
473
+ --card: #ffffff;
474
+ --card-foreground: #0f172a;
475
+ --popover: #ffffff;
476
+ --popover-foreground: #0f172a;
477
+ --primary: #2563eb;
478
+ --primary-foreground: #eff6ff;
479
+ --secondary: #f1f5f9;
480
+ --secondary-foreground: #0f172a;
481
+ --muted: #f8fafc;
482
+ --muted-foreground: #64748b;
483
+ --accent: #e2e8f0;
484
+ --accent-foreground: #0f172a;
485
+ --destructive: #dc2626;
486
+ --destructive-foreground: #fef2f2;
487
+ --border: #dbe4f0;
488
+ --input: #dbe4f0;
489
+ --ring: #2563eb;
490
+
491
+ --fg-80: rgba(15, 23, 42, 0.8);
492
+ --fg-secondary: #475569;
493
+ --fg-tertiary: #64748b;
494
+ --fg-inverse: #ffffff;
495
+ --border-light: #cbd5e1;
496
+ --primary-hover: #1d4ed8;
497
+ --primary-rgb: 37, 99, 235;
498
+
499
+ --chart-1: #2563eb;
500
+ --chart-2: #0f766e;
501
+ --chart-3: #ea580c;
502
+ --chart-4: #7c3aed;
503
+ --chart-5: #dc2626;
504
+ }
505
+
506
+ .theme-dark {
507
+ --background: #111827;
508
+ --foreground: #e2e8f0;
509
+ --card: #1b273a;
510
+ --card-foreground: #e2e8f0;
511
+ --popover: #1b273a;
512
+ --popover-foreground: #e2e8f0;
513
+ --primary: #3b82f6;
514
+ --primary-foreground: #eff6ff;
515
+ --secondary: #182235;
516
+ --secondary-foreground: #e2e8f0;
517
+ --muted: #152033;
518
+ --muted-foreground: #64748b;
519
+ --accent: #21314a;
520
+ --accent-foreground: #e2e8f0;
521
+ --destructive: #ef4444;
522
+ --destructive-foreground: #fef2f2;
523
+ --border: #283548;
524
+ --input: #283548;
525
+ --ring: #3b82f6;
526
+
527
+ --fg-80: rgba(226, 232, 240, 0.8);
528
+ --fg-secondary: #94a3b8;
529
+ --fg-tertiary: #64748b;
530
+ --fg-inverse: #111827;
531
+ --border-light: #334155;
532
+ --primary-hover: #60a5fa;
533
+ --primary-rgb: 59, 130, 246;
534
+
535
+ --chart-1: #60a5fa;
536
+ --chart-2: #34d399;
537
+ --chart-3: #f59e0b;
538
+ --chart-4: #f472b6;
539
+ --chart-5: #a78bfa;
540
+ }
541
+
542
+ .theme-night-owl {
543
+ --gradient-brand: linear-gradient(135deg, #7fdbca 0%, #82aaff 100%);
544
+ --gradient-cta: linear-gradient(
545
+ 135deg,
546
+ #82aaff 0%,
547
+ #6b93e8 50%,
548
+ #5a82d8 100%
549
+ );
550
+
551
+ --background: #011627;
552
+ --foreground: #d6deeb;
553
+ --card: #022e4c;
554
+ --card-foreground: #d6deeb;
555
+ --popover: #022e4c;
556
+ --popover-foreground: #d6deeb;
557
+ --primary: #82aaff;
558
+ --primary-foreground: #011627;
559
+ --secondary: #01243d;
560
+ --secondary-foreground: #d6deeb;
561
+ --muted: #01243d;
562
+ --muted-foreground: #637777;
563
+ --accent: #033558;
564
+ --accent-foreground: #d6deeb;
565
+ --destructive: #ff6363;
566
+ --destructive-foreground: #1a2330;
567
+ --border: #1d3b53;
568
+ --input: #1d3b53;
569
+ --ring: #82aaff;
570
+
571
+ --fg-80: rgba(214, 222, 235, 0.8);
572
+ --fg-secondary: #7fdbca;
573
+ --fg-tertiary: #637777;
574
+ --fg-inverse: #011627;
575
+ --border-light: #234e6d;
576
+ --primary-hover: #a3c1ff;
577
+ --primary-rgb: 130, 170, 255;
578
+
579
+ --chart-1: #82aaff;
580
+ --chart-2: #7fdbca;
581
+ --chart-3: #ecc48d;
582
+ --chart-4: #c792ea;
583
+ --chart-5: #f78c6c;
584
+ }
585
+
586
+ /* ── Tailwind v4 theme bridge ────────────────────────────────────── */
587
+ @theme inline {
588
+ --font-sans: var(--font-geist-sans);
589
+ --font-heading: var(--font-geist-sans);
590
+ --font-mono: var(--font-geist-mono);
591
+
592
+ --color-background: var(--background);
593
+ --color-foreground: var(--foreground);
594
+ --color-card: var(--card);
595
+ --color-card-foreground: var(--card-foreground);
596
+ --color-popover: var(--popover);
597
+ --color-popover-foreground: var(--popover-foreground);
598
+ --color-primary: var(--primary);
599
+ --color-primary-foreground: var(--primary-foreground);
600
+ --color-secondary: var(--secondary);
601
+ --color-secondary-foreground: var(--secondary-foreground);
602
+ --color-muted: var(--muted);
603
+ --color-muted-foreground: var(--muted-foreground);
604
+ --color-accent: var(--accent);
605
+ --color-accent-foreground: var(--accent-foreground);
606
+ --color-destructive: var(--destructive);
607
+ --color-input: var(--input);
608
+ --color-border: var(--border);
609
+ --color-ring: var(--ring);
610
+
611
+ --color-bg-primary: var(--bg-primary);
612
+ --color-bg-secondary: var(--bg-secondary);
613
+ --color-bg-base: var(--bg-base);
614
+ --color-bg-surface: var(--bg-surface);
615
+ --color-bg-card: var(--bg-card);
616
+ --color-bg-muted: var(--bg-muted);
617
+ --color-bg-hover: var(--bg-hover);
618
+ --color-bg-elevated: var(--bg-elevated);
619
+ --color-bg-active: var(--bg-active);
620
+ --color-fg: var(--fg);
621
+ --color-fg-secondary: var(--fg-secondary);
622
+ --color-fg-tertiary: var(--fg-tertiary);
623
+ --color-fg-inverse: var(--fg-inverse);
624
+ --color-primary-hover: var(--primary-hover);
625
+ --color-border-light: var(--border-light);
626
+ --color-border-subtle: var(--border-subtle);
627
+ --color-border-strong: var(--border-strong);
628
+
629
+ --color-status-ok: var(--status-ok);
630
+ --color-status-ok-bg: var(--status-ok-bg);
631
+ --color-status-err: var(--status-err);
632
+ --color-status-err-bg: var(--status-err-bg);
633
+ --color-status-warn: var(--status-warn);
634
+ --color-status-warn-bg: var(--status-warn-bg);
635
+ --color-status-info: var(--status-info);
636
+ --color-status-info-bg: var(--status-info-bg);
637
+
638
+ --color-chart-1: var(--chart-1);
639
+ --color-chart-2: var(--chart-2);
640
+ --color-chart-3: var(--chart-3);
641
+ --color-chart-4: var(--chart-4);
642
+ --color-chart-5: var(--chart-5);
643
+
644
+ --color-sidebar: var(--sidebar);
645
+ --color-sidebar-foreground: var(--sidebar-foreground);
646
+ --color-sidebar-primary: var(--sidebar-primary);
647
+ --color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
648
+ --color-sidebar-accent: var(--sidebar-accent);
649
+ --color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
650
+ --color-sidebar-border: var(--sidebar-border);
651
+ --color-sidebar-ring: var(--sidebar-ring);
652
+
653
+ --radius-sm: calc(var(--radius) * 0.6);
654
+ --radius-md: calc(var(--radius) * 0.8);
655
+ --radius-lg: var(--radius);
656
+ --radius-xl: calc(var(--radius) * 1.4);
657
+ --radius-2xl: calc(var(--radius) * 1.8);
658
+ --radius-3xl: calc(var(--radius) * 2.2);
659
+ --radius-4xl: calc(var(--radius) * 2.6);
660
+ }
661
+
662
+ /* ── Reset & base ───────────────────────────────────────────────── */
663
+ * {
664
+ box-sizing: border-box;
665
+ }
666
+
667
+ html {
668
+ height: 100%;
669
+ }
670
+
671
+ body {
672
+ min-height: 100%;
673
+ background: var(--background);
674
+ color: var(--foreground);
675
+ font-family: var(--font-geist-sans), sans-serif;
676
+ -webkit-font-smoothing: antialiased;
677
+ -moz-osx-font-smoothing: grayscale;
678
+ overflow: hidden;
679
+ }
680
+
681
+ .shell-viewport-y-gap {
682
+ padding-block: var(--shell-gap);
683
+ }
684
+
685
+ .shell-main-gap {
686
+ padding: var(--shell-gap);
687
+ }
688
+
689
+ .shell-main-gap-no-left {
690
+ padding: var(--shell-gap);
691
+ padding-left: 0;
692
+ }
693
+
694
+ .shell-surface-radius {
695
+ border-radius: var(--shell-radius);
696
+ }
697
+
698
+ ::selection {
699
+ background: rgba(var(--primary-rgb), 0.28);
700
+ }
701
+
702
+ a {
703
+ color: inherit;
704
+ text-decoration: none;
705
+ }
706
+
707
+ :focus-visible {
708
+ outline: 2px solid var(--ring);
709
+ outline-offset: -2px;
710
+ }
711
+
712
+ ::-webkit-scrollbar {
713
+ width: 6px;
714
+ height: 6px;
715
+ }
716
+
717
+ ::-webkit-scrollbar-track {
718
+ background: transparent;
719
+ }
720
+
721
+ ::-webkit-scrollbar-thumb {
722
+ background: var(--border-strong);
723
+ border-radius: 999px;
724
+ }
725
+
726
+ ::-webkit-scrollbar-thumb:hover {
727
+ background: var(--fg-tertiary);
728
+ }
729
+
730
+ /* ── Keyframes ─────────────────────────────────────────────────── */
731
+ @keyframes shimmer {
732
+ 0% {
733
+ background-position: -200% 0;
734
+ }
735
+ 100% {
736
+ background-position: 200% 0;
737
+ }
738
+ }
739
+
740
+ @layer base {
741
+ * {
742
+ @apply border-border outline-ring/50;
743
+ }
744
+
745
+ body {
746
+ @apply bg-background text-foreground;
747
+ }
748
+
749
+ html {
750
+ @apply font-sans;
751
+ }
752
+ }