@labpane/ui 0.0.0-stage → 1.2.0

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 (76) hide show
  1. package/README.md +130 -2
  2. package/dist/LICENSE +21 -0
  3. package/dist/chunk-NR3PLNO7.js +100 -0
  4. package/dist/chunk-NR3PLNO7.js.map +7 -0
  5. package/dist/index.js +7137 -0
  6. package/dist/index.js.map +7 -0
  7. package/dist/styles.css +2 -0
  8. package/dist/styles.d.ts +1 -0
  9. package/dist/terminal.js +369 -0
  10. package/dist/terminal.js.map +7 -0
  11. package/dist/ui/alert.d.ts +13 -0
  12. package/dist/ui/app-menu.d.ts +19 -0
  13. package/dist/ui/avatar.d.ts +11 -0
  14. package/dist/ui/badge.d.ts +17 -0
  15. package/dist/ui/breadcrumb.d.ts +11 -0
  16. package/dist/ui/browser-layout.d.ts +20 -0
  17. package/dist/ui/button.d.ts +27 -0
  18. package/dist/ui/card.d.ts +15 -0
  19. package/dist/ui/chart-frame.d.ts +4 -0
  20. package/dist/ui/checkbox.d.ts +4 -0
  21. package/dist/ui/classes.d.ts +7 -0
  22. package/dist/ui/command.d.ts +82 -0
  23. package/dist/ui/confirm-dialog.d.ts +28 -0
  24. package/dist/ui/copy-button.d.ts +7 -0
  25. package/dist/ui/dialog.d.ts +18 -0
  26. package/dist/ui/discard-dialog.d.ts +6 -0
  27. package/dist/ui/email-thread.d.ts +35 -0
  28. package/dist/ui/empty.d.ts +14 -0
  29. package/dist/ui/field.d.ts +26 -0
  30. package/dist/ui/file-input.d.ts +6 -0
  31. package/dist/ui/flame-graph-model.d.ts +23 -0
  32. package/dist/ui/flame-graph.d.ts +15 -0
  33. package/dist/ui/form-fields.d.ts +21 -0
  34. package/dist/ui/histogram.d.ts +23 -0
  35. package/dist/ui/index.d.ts +57 -0
  36. package/dist/ui/input-group.d.ts +28 -0
  37. package/dist/ui/input.d.ts +3 -0
  38. package/dist/ui/kbd.d.ts +4 -0
  39. package/dist/ui/label.d.ts +3 -0
  40. package/dist/ui/menu.d.ts +60 -0
  41. package/dist/ui/native-select.d.ts +7 -0
  42. package/dist/ui/nav-tabs.d.ts +7 -0
  43. package/dist/ui/overlay.d.ts +1 -0
  44. package/dist/ui/page.d.ts +22 -0
  45. package/dist/ui/rail.d.ts +16 -0
  46. package/dist/ui/search-input.d.ts +6 -0
  47. package/dist/ui/select.d.ts +13 -0
  48. package/dist/ui/separator.d.ts +6 -0
  49. package/dist/ui/settings.d.ts +14 -0
  50. package/dist/ui/sheet.d.ts +20 -0
  51. package/dist/ui/side-panel.d.ts +23 -0
  52. package/dist/ui/sidebar.d.ts +81 -0
  53. package/dist/ui/skeleton.d.ts +3 -0
  54. package/dist/ui/spinner.d.ts +3 -0
  55. package/dist/ui/stat.d.ts +7 -0
  56. package/dist/ui/steps.d.ts +7 -0
  57. package/dist/ui/switch.d.ts +6 -0
  58. package/dist/ui/tab-state.d.ts +8 -0
  59. package/dist/ui/table-layout.d.ts +19 -0
  60. package/dist/ui/table-model.d.ts +42 -0
  61. package/dist/ui/table-screen.d.ts +9 -0
  62. package/dist/ui/table.d.ts +41 -0
  63. package/dist/ui/tabs.d.ts +13 -0
  64. package/dist/ui/terminal.d.ts +57 -0
  65. package/dist/ui/textarea.d.ts +3 -0
  66. package/dist/ui/theme.d.ts +22 -0
  67. package/dist/ui/time-series-chart.d.ts +19 -0
  68. package/dist/ui/time-series-model.d.ts +90 -0
  69. package/dist/ui/timing-tracks.d.ts +27 -0
  70. package/dist/ui/toggle.d.ts +22 -0
  71. package/dist/ui/tooltip.d.ts +7 -0
  72. package/dist/ui/topbar.d.ts +4 -0
  73. package/dist/ui/use-chart-width.d.ts +5 -0
  74. package/dist/ui/use-mobile.d.ts +1 -0
  75. package/package.json +116 -4
  76. package/styles.css +358 -0
@@ -0,0 +1,19 @@
1
+ import * as React from "react";
2
+ import { type ChartOptions, type SeriesPoint } from "./time-series-model.js";
3
+ export { DAY, DEFAULT_OPTIONS, type ChartOptions, type SeriesPoint, } from "./time-series-model.js";
4
+ export type TimeSeriesChartProps = {
5
+ points: SeriesPoint[];
6
+ series: {
7
+ key: string;
8
+ color: string;
9
+ }[];
10
+ start: number;
11
+ options: ChartOptions;
12
+ onOptionsChange: (options: ChartOptions) => void;
13
+ title?: string;
14
+ subtitle?: string;
15
+ unit?: string;
16
+ label: string;
17
+ };
18
+ declare const TimeSeriesChart: React.ForwardRefExoticComponent<TimeSeriesChartProps & React.RefAttributes<HTMLDivElement>>;
19
+ export { TimeSeriesChart };
@@ -0,0 +1,90 @@
1
+ /** Pure chart geometry: no DOM, React, clock or storage. */
2
+ export declare const DAY = 86400000;
3
+ export type Range = [number, number];
4
+ export type SeriesPoint = {
5
+ time: number;
6
+ total: number;
7
+ values: Record<string, number>;
8
+ annotation?: string;
9
+ carried?: boolean;
10
+ };
11
+ export type ChartOptions = {
12
+ logarithmic: boolean;
13
+ logBase: number;
14
+ sma: boolean;
15
+ ema: boolean;
16
+ bollinger: boolean;
17
+ forecast: boolean;
18
+ };
19
+ export declare const DEFAULT_OPTIONS: ChartOptions;
20
+ export declare const FORECAST_DAYS = 90;
21
+ export declare const INDICATOR_PERIOD = 20;
22
+ export declare function nearestPoint(points: SeriesPoint[], time: number): number;
23
+ export declare function clampRange(range: Range, bounds: Range, minimum?: number): Range;
24
+ export declare function zoomRange(range: Range, factor: number, anchor: number, bounds: Range): Range;
25
+ export declare function indicators(points: SeriesPoint[], period?: number): {
26
+ time: number;
27
+ ema: number;
28
+ sma: number | null;
29
+ upper: number | null;
30
+ lower: number | null;
31
+ }[];
32
+ /** Fits the last 90 daily values, then anchors the projection to the latest actual value. */
33
+ export declare function regression(points: SeriesPoint[]): {
34
+ slope: number;
35
+ r2: number;
36
+ points: {
37
+ time: number;
38
+ value: number;
39
+ }[];
40
+ } | null;
41
+ export declare function niceTicks(maximum: number, count?: number): number[];
42
+ export declare function chartModel(points: SeriesPoint[], keys: string[], range: Range, width: number, height: number, options: ChartOptions, lockedDomain?: Range): {
43
+ plot: {
44
+ left: number;
45
+ right: number;
46
+ top: number;
47
+ bottom: number;
48
+ };
49
+ domain: Range;
50
+ x: (time: number) => number;
51
+ y: (value: number) => number;
52
+ timeAt: (pixel: number) => number;
53
+ bands: {
54
+ key: string;
55
+ path: string;
56
+ }[];
57
+ totalPath: string;
58
+ xTicks: {
59
+ value: number;
60
+ pixel: number;
61
+ }[];
62
+ yTicks: {
63
+ value: number;
64
+ pixel: number;
65
+ }[];
66
+ positions: {
67
+ x: number;
68
+ y: number;
69
+ }[];
70
+ computed: {
71
+ time: number;
72
+ ema: number;
73
+ sma: number | null;
74
+ upper: number | null;
75
+ lower: number | null;
76
+ }[];
77
+ smaPath: string;
78
+ emaPath: string;
79
+ upperPath: string;
80
+ lowerPath: string;
81
+ forecast: {
82
+ slope: number;
83
+ r2: number;
84
+ points: {
85
+ time: number;
86
+ value: number;
87
+ }[];
88
+ } | null;
89
+ forecastPath: string;
90
+ };
@@ -0,0 +1,27 @@
1
+ import * as React from "react";
2
+ export type TimingSpan = {
3
+ id: string;
4
+ start: number;
5
+ end: number;
6
+ label: string;
7
+ detail?: string;
8
+ color?: string;
9
+ /** A bound or observation window, not a measured execution interval. */
10
+ uncertain?: boolean;
11
+ };
12
+ export type TimingTrack = {
13
+ id: string;
14
+ label: string;
15
+ spans: TimingSpan[];
16
+ };
17
+ export type TimingTracksProps = {
18
+ tracks: TimingTrack[];
19
+ from: number;
20
+ to: number;
21
+ label?: string;
22
+ unit?: string;
23
+ onSelect?: (span: TimingSpan) => void;
24
+ };
25
+ /** Shared-clock tracks supplied by the caller. Deliberately no clock conversion. */
26
+ declare const TimingTracks: React.ForwardRefExoticComponent<TimingTracksProps & React.RefAttributes<HTMLDivElement>>;
27
+ export { TimingTracks };
@@ -0,0 +1,22 @@
1
+ import * as React from "react";
2
+ import * as TogglePrimitive from "@radix-ui/react-toggle";
3
+ import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
4
+ declare const toggleVariants: {
5
+ default: string;
6
+ outline: string;
7
+ };
8
+ declare const toggleSizes: {
9
+ default: string;
10
+ sm: string;
11
+ lg: string;
12
+ };
13
+ type ToggleStyle = {
14
+ variant?: keyof typeof toggleVariants;
15
+ size?: keyof typeof toggleSizes;
16
+ };
17
+ declare const Toggle: React.ForwardRefExoticComponent<Omit<TogglePrimitive.ToggleProps & React.RefAttributes<HTMLButtonElement>, "ref"> & ToggleStyle & React.RefAttributes<HTMLButtonElement>>;
18
+ declare const ToggleGroup: React.ForwardRefExoticComponent<((Omit<ToggleGroupPrimitive.ToggleGroupMultipleProps & React.RefAttributes<HTMLDivElement>, "ref"> | Omit<ToggleGroupPrimitive.ToggleGroupSingleProps & React.RefAttributes<HTMLDivElement>, "ref">) & ToggleStyle & {
19
+ spacing?: number;
20
+ }) & React.RefAttributes<HTMLDivElement>>;
21
+ declare const ToggleGroupItem: React.ForwardRefExoticComponent<Omit<ToggleGroupPrimitive.ToggleGroupItemProps & React.RefAttributes<HTMLButtonElement>, "ref"> & ToggleStyle & React.RefAttributes<HTMLButtonElement>>;
22
+ export { Toggle, ToggleGroup, ToggleGroupItem };
@@ -0,0 +1,7 @@
1
+ import * as React from "react";
2
+ import * as TooltipPrimitive from "@radix-ui/react-tooltip";
3
+ declare function TooltipProvider({ delayDuration, ...props }: React.ComponentProps<typeof TooltipPrimitive.Provider>): React.JSX.Element;
4
+ declare function Tooltip({ open, defaultOpen, onOpenChange, ...props }: React.ComponentProps<typeof TooltipPrimitive.Root>): React.JSX.Element;
5
+ declare const TooltipTrigger: React.ForwardRefExoticComponent<TooltipPrimitive.TooltipTriggerProps & React.RefAttributes<HTMLButtonElement>>;
6
+ declare const TooltipContent: React.ForwardRefExoticComponent<Omit<TooltipPrimitive.TooltipContentProps & React.RefAttributes<HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
7
+ export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider };
@@ -0,0 +1,4 @@
1
+ import * as React from "react";
2
+ declare const Topbar: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>, "ref"> & React.RefAttributes<HTMLElement>>;
3
+ declare const TopbarActions: React.ForwardRefExoticComponent<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref"> & React.RefAttributes<HTMLDivElement>>;
4
+ export { Topbar, TopbarActions };
@@ -0,0 +1,5 @@
1
+ /** Measures a chart container with a ResizeObserver. Zero widths (hidden tabs, display none) keep the last size. */
2
+ export declare function useChartWidth(): {
3
+ container: import("react").RefObject<HTMLDivElement | null>;
4
+ width: number;
5
+ };
@@ -0,0 +1 @@
1
+ export declare function useIsMobile(): boolean;
package/package.json CHANGED
@@ -1,6 +1,118 @@
1
1
  {
2
2
  "name": "@labpane/ui",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.2.0",
4
+ "description": "Page layouts, forms, dialogs, menus, tables, and an optional terminal for React",
5
+ "license": "MIT",
6
+ "homepage": "https://labpane.com",
7
+ "bugs": "https://github.com/labpane/labpane/issues",
8
+ "keywords": [
9
+ "react",
10
+ "radix",
11
+ "components",
12
+ "ui",
13
+ "tailwind",
14
+ "terminal"
15
+ ],
16
+ "type": "module",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./dist/ui/index.d.ts",
20
+ "default": "./dist/index.js"
21
+ },
22
+ "./styles.css": {
23
+ "types": "./dist/styles.d.ts",
24
+ "default": "./dist/styles.css"
25
+ },
26
+ "./tailwind.css": {
27
+ "types": "./dist/styles.d.ts",
28
+ "style": "./styles.css",
29
+ "default": "./styles.css"
30
+ },
31
+ "./terminal": {
32
+ "types": "./dist/ui/terminal.d.ts",
33
+ "default": "./dist/terminal.js"
34
+ }
35
+ },
36
+ "files": [
37
+ "dist",
38
+ "styles.css"
39
+ ],
40
+ "sideEffects": [
41
+ "**/*.css"
42
+ ],
43
+ "publishConfig": {
44
+ "access": "public"
45
+ },
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "git+https://github.com/labpane/labpane.git",
49
+ "directory": "packages/ui"
50
+ },
51
+ "scripts": {
52
+ "build": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc -p tsconfig.json && esbuild index.ts terminal.tsx --bundle --sourcemap --splitting --chunk-names=[name]-[hash] --format=esm --packages=external --outdir=dist && tailwindcss -i styles.css -o dist/styles.css --minify && node ../unlayer.mjs dist/styles.css && node ../package-assets.mjs",
53
+ "test": "bun test",
54
+ "prepack": "npm run build"
55
+ },
56
+ "dependencies": {
57
+ "clsx": "^2.1.1",
58
+ "cmdk": "^1.1.1",
59
+ "lucide-react": "^1.55.0",
60
+ "tailwind-merge": "^3.6.0"
61
+ },
62
+ "peerDependencies": {
63
+ "@radix-ui/react-alert-dialog": "^1.1.15",
64
+ "@radix-ui/react-avatar": "^1.2.7",
65
+ "@radix-ui/react-checkbox": "^1.3.3",
66
+ "@radix-ui/react-context-menu": "^2.2.16",
67
+ "@radix-ui/react-dialog": "^1.1.15",
68
+ "@radix-ui/react-dropdown-menu": "^2.1.16",
69
+ "@radix-ui/react-popover": "^1.1.15",
70
+ "@radix-ui/react-select": "^2.2.6",
71
+ "@radix-ui/react-slot": "^1.2.3",
72
+ "@radix-ui/react-switch": "^1.3.8",
73
+ "@radix-ui/react-tabs": "^1.1.22",
74
+ "@radix-ui/react-toggle": "^1.1.19",
75
+ "@radix-ui/react-toggle-group": "^1.1.20",
76
+ "@radix-ui/react-tooltip": "^1.3.0",
77
+ "@wterm/dom": "^0.5.4",
78
+ "react": "^18.2.0 || ^19.0.0",
79
+ "react-dom": "^18.2.0 || ^19.0.0"
80
+ },
81
+ "peerDependenciesMeta": {
82
+ "@wterm/dom": {
83
+ "optional": true
84
+ }
85
+ },
86
+ "devDependencies": {
87
+ "@happy-dom/global-registrator": "^20.14.5",
88
+ "@radix-ui/react-alert-dialog": "^1.1.15",
89
+ "@radix-ui/react-avatar": "^1.2.7",
90
+ "@radix-ui/react-checkbox": "^1.3.3",
91
+ "@radix-ui/react-context-menu": "^2.2.16",
92
+ "@radix-ui/react-dialog": "^1.1.15",
93
+ "@radix-ui/react-dropdown-menu": "^2.1.16",
94
+ "@radix-ui/react-popover": "^1.1.15",
95
+ "@radix-ui/react-select": "^2.2.6",
96
+ "@radix-ui/react-slot": "^1.2.3",
97
+ "@radix-ui/react-switch": "^1.3.8",
98
+ "@radix-ui/react-tabs": "^1.1.22",
99
+ "@radix-ui/react-toggle": "^1.1.19",
100
+ "@radix-ui/react-toggle-group": "^1.1.20",
101
+ "@radix-ui/react-tooltip": "^1.3.0",
102
+ "@tailwindcss/cli": "^4.3.3",
103
+ "@testing-library/dom": "^10.4.2",
104
+ "@testing-library/react": "^16.3.3",
105
+ "@testing-library/user-event": "^14.6.7",
106
+ "@types/bun": "^1.4.2",
107
+ "@types/react": "^19.3.0",
108
+ "@types/react-dom": "^19.3.0",
109
+ "@wterm/dom": "^0.5.4",
110
+ "esbuild": "^0.28.2",
111
+ "postcss": "^8.5.6",
112
+ "react": "^19.0.0",
113
+ "react-dom": "^19.0.0",
114
+ "tailwindcss": "^4.3.3",
115
+ "tailwindcss3": "npm:tailwindcss@^3.4.17",
116
+ "typescript": "^7.0.2"
117
+ }
118
+ }
package/styles.css ADDED
@@ -0,0 +1,358 @@
1
+ @layer theme, base, components, utilities;
2
+ @import "tailwindcss/theme.css" layer(theme) prefix(labui);
3
+ @import "tailwindcss/utilities.css" layer(utilities) prefix(labui) source(none);
4
+ @source "./";
5
+ @custom-variant dark (&:is(.dark *));
6
+
7
+ :where(:root) {
8
+ --labui-font-sans:
9
+ system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text",
10
+ "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
11
+ --labui-font-mono:
12
+ ui-monospace, "SFMono-Regular", "SF Mono", "Cascadia Mono", Menlo, Consolas,
13
+ "Liberation Mono", monospace;
14
+ --labui-font-display:
15
+ system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI Variable Display",
16
+ "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
17
+ --labui-radius: 0.75rem;
18
+ --labui-radius-dialog: 1.25rem;
19
+ --labui-control-height: 2.5rem;
20
+ --labui-control-height-sm: 2.25rem;
21
+ --labui-control-px: 0.75rem;
22
+ --labui-row-py: 0.625rem;
23
+ --labui-background: #eeeeee;
24
+ --labui-foreground: #242424;
25
+ --labui-card: #ffffff;
26
+ --labui-card-foreground: #242424;
27
+ --labui-popover: #fcfcfc;
28
+ --labui-popover-foreground: #242424;
29
+ --labui-primary: #05697a;
30
+ --labui-primary-foreground: #ffffff;
31
+ --labui-link: #05697a;
32
+ --labui-secondary: #e6e6e6;
33
+ --labui-secondary-foreground: #626262;
34
+ --labui-muted: #eeeeee;
35
+ --labui-muted-foreground: #626262;
36
+ --labui-accent: #e6e6e6;
37
+ --labui-accent-foreground: #242424;
38
+ --labui-destructive: #b12637;
39
+ --labui-destructive-foreground: #ffffff;
40
+ --labui-destructive-muted: #fff0f1;
41
+ --labui-success: #116d3b;
42
+ --labui-success-foreground: #ffffff;
43
+ --labui-warning: oklch(47.3% 0.137 46.201);
44
+ --labui-warning-foreground: #ffffff;
45
+ --labui-border: #d6d6d6;
46
+ --labui-input: #858585;
47
+ --labui-input-background: #eeeeee;
48
+ --labui-ring: #1d9db4;
49
+ --labui-overlay: color-mix(in srgb, #242424 18%, transparent);
50
+ --labui-info: #1e5aa8;
51
+ --labui-info-foreground: #ffffff;
52
+ --labui-chart-1: #05697a;
53
+ --labui-chart-2: #1d9db4;
54
+ --labui-chart-3: #116d3b;
55
+ --labui-chart-4: #b8741a;
56
+ --labui-chart-5: #7a4ea0;
57
+ --labui-sidebar: #f6f6f6;
58
+ --labui-sidebar-foreground: #242424;
59
+ --labui-sidebar-primary: #05697a;
60
+ --labui-sidebar-primary-foreground: #ffffff;
61
+ --labui-sidebar-accent: #e6e6e6;
62
+ --labui-sidebar-accent-foreground: #242424;
63
+ --labui-sidebar-border: #d6d6d6;
64
+ --labui-sidebar-ring: #1d9db4;
65
+ --labui-card-gap: 1.5rem;
66
+ --labui-card-px: 1.5rem;
67
+ --labui-card-py: 1.5rem;
68
+ --labui-topbar-height: 3rem;
69
+ }
70
+
71
+ :where(.dark) {
72
+ --labui-background: #1c1c1c;
73
+ --labui-foreground: #e8e8e8;
74
+ --labui-card: #242424;
75
+ --labui-card-foreground: #e8e8e8;
76
+ --labui-popover: #2d2d2d;
77
+ --labui-popover-foreground: #f3f3f3;
78
+ --labui-primary: #68bccf;
79
+ --labui-primary-foreground: #1c1c1c;
80
+ --labui-link: #68bccf;
81
+ --labui-secondary: #363636;
82
+ --labui-secondary-foreground: #e8e8e8;
83
+ --labui-muted: #2d2d2d;
84
+ --labui-muted-foreground: #a3a3a3;
85
+ --labui-accent: #363636;
86
+ --labui-accent-foreground: #f3f3f3;
87
+ --labui-destructive: #f0808c;
88
+ --labui-destructive-foreground: #ffffff;
89
+ --labui-destructive-muted: color-mix(in srgb, #f0808c 12%, #242424);
90
+ --labui-success: #3ddc84;
91
+ --labui-success-foreground: #06271a;
92
+ --labui-warning: oklch(87.9% 0.169 91.605);
93
+ --labui-warning-foreground: oklch(27.9% 0.077 45.635);
94
+ --labui-border: #363636;
95
+ --labui-input: #858585;
96
+ --labui-input-background: #242424;
97
+ --labui-ring: #68bccf;
98
+ --labui-overlay: color-mix(in srgb, #000000 50%, transparent);
99
+ --labui-info: #7fb4f0;
100
+ --labui-info-foreground: #0c2340;
101
+ --labui-chart-1: #68bccf;
102
+ --labui-chart-2: #1d9db4;
103
+ --labui-chart-3: #3ddc84;
104
+ --labui-chart-4: #e0a84a;
105
+ --labui-chart-5: #b58ce0;
106
+ --labui-sidebar: #202020;
107
+ --labui-sidebar-foreground: #e8e8e8;
108
+ --labui-sidebar-primary: #68bccf;
109
+ --labui-sidebar-primary-foreground: #1c1c1c;
110
+ --labui-sidebar-accent: #363636;
111
+ --labui-sidebar-accent-foreground: #f3f3f3;
112
+ --labui-sidebar-border: #363636;
113
+ --labui-sidebar-ring: #68bccf;
114
+ }
115
+
116
+ @media (forced-colors: active) {
117
+ :root,
118
+ .dark {
119
+ --labui-background: Canvas !important;
120
+ --labui-card: Canvas !important;
121
+ --labui-border: CanvasText !important;
122
+ --labui-foreground: CanvasText !important;
123
+ }
124
+ }
125
+
126
+ @theme inline {
127
+ --radius-sm: calc(var(--labui-radius) - 4px);
128
+ --radius-md: calc(var(--labui-radius) - 2px);
129
+ --radius-lg: var(--labui-radius);
130
+ --radius-xl: calc(var(--labui-radius) + 4px);
131
+ --color-background: var(--labui-background);
132
+ --color-foreground: var(--labui-foreground);
133
+ --color-card: var(--labui-card);
134
+ --color-card-foreground: var(--labui-card-foreground);
135
+ --color-popover: var(--labui-popover);
136
+ --color-popover-foreground: var(--labui-popover-foreground);
137
+ --color-primary: var(--labui-primary);
138
+ --color-primary-foreground: var(--labui-primary-foreground);
139
+ --color-link: var(--labui-link);
140
+ --color-secondary: var(--labui-secondary);
141
+ --color-secondary-foreground: var(--labui-secondary-foreground);
142
+ --color-muted: var(--labui-muted);
143
+ --color-muted-foreground: var(--labui-muted-foreground);
144
+ --color-accent: var(--labui-accent);
145
+ --color-accent-foreground: var(--labui-accent-foreground);
146
+ --color-destructive: var(--labui-destructive);
147
+ --color-destructive-foreground: var(--labui-destructive-foreground);
148
+ --color-destructive-muted: var(--labui-destructive-muted);
149
+ --color-success: var(--labui-success);
150
+ --color-success-foreground: var(--labui-success-foreground);
151
+ --color-warning: var(--labui-warning);
152
+ --color-warning-foreground: var(--labui-warning-foreground);
153
+ --color-border: var(--labui-border);
154
+ --color-input: var(--labui-input);
155
+ --color-input-background: var(--labui-input-background);
156
+ --color-ring: var(--labui-ring);
157
+ --color-overlay: var(--labui-overlay);
158
+ --color-info: var(--labui-info);
159
+ --color-info-foreground: var(--labui-info-foreground);
160
+ --color-chart-1: var(--labui-chart-1);
161
+ --color-chart-2: var(--labui-chart-2);
162
+ --color-chart-3: var(--labui-chart-3);
163
+ --color-chart-4: var(--labui-chart-4);
164
+ --color-chart-5: var(--labui-chart-5);
165
+ --color-sidebar: var(--labui-sidebar);
166
+ --color-sidebar-foreground: var(--labui-sidebar-foreground);
167
+ --color-sidebar-primary: var(--labui-sidebar-primary);
168
+ --color-sidebar-primary-foreground: var(--labui-sidebar-primary-foreground);
169
+ --color-sidebar-accent: var(--labui-sidebar-accent);
170
+ --color-sidebar-accent-foreground: var(--labui-sidebar-accent-foreground);
171
+ --color-sidebar-border: var(--labui-sidebar-border);
172
+ --color-sidebar-ring: var(--labui-sidebar-ring);
173
+ }
174
+
175
+ @theme {
176
+ --animate-spin: labui-spin 1s linear infinite;
177
+ --animate-pulse: labui-pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
178
+ --animate-pop: labui-pop 160ms ease-out;
179
+ --animate-fade-in: labui-fade-in 150ms ease-out;
180
+ --animate-fade-out: labui-fade-out 150ms ease-in;
181
+ --animate-zoom-in: labui-zoom-in 150ms ease-out;
182
+ --animate-zoom-out: labui-zoom-out 150ms ease-in;
183
+ --animate-slide-in-right: labui-slide-in-right 200ms ease-out;
184
+ --animate-slide-out-right: labui-slide-out-right 200ms ease-in;
185
+ --animate-slide-in-left: labui-slide-in-left 200ms ease-out;
186
+ --animate-slide-out-left: labui-slide-out-left 200ms ease-in;
187
+ --animate-slide-in-top: labui-slide-in-top 200ms ease-out;
188
+ --animate-slide-out-top: labui-slide-out-top 200ms ease-in;
189
+ --animate-slide-in-bottom: labui-slide-in-bottom 200ms ease-out;
190
+ --animate-slide-out-bottom: labui-slide-out-bottom 200ms ease-in;
191
+ @keyframes labui-fade-in {
192
+ from {
193
+ opacity: 0;
194
+ }
195
+ }
196
+ @keyframes labui-fade-out {
197
+ to {
198
+ opacity: 0;
199
+ }
200
+ }
201
+ @keyframes labui-zoom-in {
202
+ from {
203
+ opacity: 0;
204
+ transform: translate(-50%, -50%) scale(0.95);
205
+ }
206
+ }
207
+ @keyframes labui-zoom-out {
208
+ to {
209
+ opacity: 0;
210
+ transform: translate(-50%, -50%) scale(0.95);
211
+ }
212
+ }
213
+ @keyframes labui-slide-in-right {
214
+ from {
215
+ transform: translateX(100%);
216
+ }
217
+ }
218
+ @keyframes labui-slide-out-right {
219
+ to {
220
+ transform: translateX(100%);
221
+ }
222
+ }
223
+ @keyframes labui-slide-in-left {
224
+ from {
225
+ transform: translateX(-100%);
226
+ }
227
+ }
228
+ @keyframes labui-slide-out-left {
229
+ to {
230
+ transform: translateX(-100%);
231
+ }
232
+ }
233
+ @keyframes labui-slide-in-top {
234
+ from {
235
+ transform: translateY(-100%);
236
+ }
237
+ }
238
+ @keyframes labui-slide-out-top {
239
+ to {
240
+ transform: translateY(-100%);
241
+ }
242
+ }
243
+ @keyframes labui-slide-in-bottom {
244
+ from {
245
+ transform: translateY(100%);
246
+ }
247
+ }
248
+ @keyframes labui-slide-out-bottom {
249
+ to {
250
+ transform: translateY(100%);
251
+ }
252
+ }
253
+ @keyframes labui-spin {
254
+ to {
255
+ transform: rotate(360deg);
256
+ }
257
+ }
258
+ @keyframes labui-pulse {
259
+ 50% {
260
+ opacity: 0.5;
261
+ }
262
+ }
263
+ @keyframes labui-pop {
264
+ from {
265
+ opacity: 0;
266
+ transform: scale(0.92);
267
+ }
268
+ to {
269
+ opacity: 1;
270
+ transform: scale(1);
271
+ }
272
+ }
273
+ }
274
+
275
+ @utility range-overlay {
276
+ position: absolute;
277
+ inset: 0;
278
+ width: 100%;
279
+ height: 100%;
280
+ cursor: ns-resize;
281
+ appearance: none;
282
+ opacity: 0;
283
+ writing-mode: vertical-lr;
284
+ direction: rtl;
285
+ &::-webkit-slider-thumb {
286
+ appearance: none;
287
+ width: 100%;
288
+ height: 0;
289
+ }
290
+ &::-moz-range-thumb {
291
+ width: 100%;
292
+ height: 0;
293
+ border: 0;
294
+ }
295
+ @media (forced-colors: active) {
296
+ appearance: auto;
297
+ opacity: 1;
298
+ &::-webkit-slider-thumb {
299
+ appearance: auto;
300
+ width: auto;
301
+ height: auto;
302
+ }
303
+ &::-moz-range-thumb {
304
+ width: 1rem;
305
+ height: 1rem;
306
+ border: 1px solid ButtonText;
307
+ }
308
+ }
309
+ }
310
+
311
+ @theme inline reference {
312
+ --font-sans: var(--labui-font-sans);
313
+ --font-mono: var(--labui-font-mono);
314
+ --font-display: var(--labui-font-display);
315
+ }
316
+
317
+ @layer base {
318
+ :where([class*="labui:"]) {
319
+ box-sizing: border-box;
320
+ margin: 0;
321
+ padding: 0;
322
+ border: 0 solid var(--labui-border);
323
+ outline-color: color-mix(in oklab, var(--labui-ring) 50%, transparent);
324
+ }
325
+ :where(button, input, select, textarea, a)[class*="labui:"] {
326
+ font: inherit;
327
+ font-feature-settings: inherit;
328
+ letter-spacing: inherit;
329
+ color: inherit;
330
+ border-radius: 0;
331
+ background-color: transparent;
332
+ text-decoration: inherit;
333
+ }
334
+ :where(input, textarea)[class*="labui:"]::placeholder {
335
+ opacity: 1;
336
+ color: color-mix(in srgb, currentcolor 50%, transparent);
337
+ }
338
+ :where(table[class*="labui:"]) {
339
+ border-collapse: collapse;
340
+ text-indent: 0;
341
+ }
342
+ :where(h1, h2, h3, h4, h5, h6)[class*="labui:"] {
343
+ font-size: inherit;
344
+ font-weight: inherit;
345
+ }
346
+ :where(svg[class*="labui:"]) {
347
+ display: block;
348
+ vertical-align: middle;
349
+ }
350
+ @media (prefers-reduced-motion: reduce) {
351
+ :where([class*="labui:"]) {
352
+ animation-duration: 0.01ms !important;
353
+ animation-iteration-count: 1 !important;
354
+ transition-duration: 0.01ms !important;
355
+ scroll-behavior: auto !important;
356
+ }
357
+ }
358
+ }