@rozenite/vite-plugin 1.13.0 → 2.0.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 (56) hide show
  1. package/README.md +12 -0
  2. package/dist/bundle-dts.d.ts.map +1 -1
  3. package/dist/client-plugin.d.ts.map +1 -1
  4. package/dist/dev-config-module.d.ts.map +1 -1
  5. package/dist/dev-host/assets/index-DU3zXL2c.css +1 -0
  6. package/dist/dev-host/assets/index-Xsb6uYhI.js +13 -0
  7. package/dist/dev-host/index.html +3 -3
  8. package/dist/dev-host/manifest.json +2 -2
  9. package/dist/index.cjs +24 -8
  10. package/dist/index.d.ts +9 -1
  11. package/dist/index.d.ts.map +1 -1
  12. package/dist/index.js +24 -8
  13. package/dist/react-native-plugin.d.ts.map +1 -1
  14. package/dist/sdk-plugin.d.ts.map +1 -1
  15. package/dist/server-plugin.d.ts.map +1 -1
  16. package/dist/tsconfig.lib.tsbuildinfo +1 -1
  17. package/package.json +9 -10
  18. package/src/bundle-dts.ts +7 -6
  19. package/src/client-plugin.ts +8 -6
  20. package/src/dev-config-module.ts +4 -1
  21. package/src/dev-host/App.tsx +219 -413
  22. package/src/dev-host/components/DispatchForm.tsx +108 -122
  23. package/src/dev-host/components/FlowList.tsx +81 -101
  24. package/src/dev-host/components/MessageDetailsPane.tsx +56 -83
  25. package/src/dev-host/components/MessageLogPane.tsx +84 -66
  26. package/src/dev-host/components/PanelTabs.tsx +29 -10
  27. package/src/dev-host/config.ts +6 -2
  28. package/src/dev-host/constants.ts +0 -19
  29. package/src/dev-host/flow-runtime.ts +33 -12
  30. package/src/dev-host/index.html +1 -1
  31. package/src/dev-host/main.tsx +1 -10
  32. package/src/dev-host/server.ts +9 -3
  33. package/src/dev-host/styles.css +162 -830
  34. package/src/dev-host/types.ts +5 -10
  35. package/src/dev-host/utils.ts +9 -6
  36. package/src/dev-host/vite.config.mts +2 -0
  37. package/src/index.ts +15 -5
  38. package/src/load-config.ts +4 -4
  39. package/src/package-json.ts +1 -1
  40. package/src/react-native-plugin.ts +3 -0
  41. package/src/sdk-plugin.ts +3 -0
  42. package/src/server-plugin.ts +3 -0
  43. package/src/utils.ts +1 -1
  44. package/dist/dev-host/assets/index-CkxvBMpp.css +0 -1
  45. package/dist/dev-host/assets/index-cNKHRwej.js +0 -11
  46. package/src/dev-host/components/MessagePayloadDetail.tsx +0 -32
  47. package/src/dev-host/components/ResizeHandle.tsx +0 -33
  48. package/src/dev-host/components/icons.tsx +0 -79
  49. package/src/dev-host/components/ui/Button.tsx +0 -91
  50. package/src/dev-host/components/ui/DropdownMenu.tsx +0 -84
  51. package/src/dev-host/components/ui/IconButton.tsx +0 -41
  52. package/src/dev-host/components/ui/Input.tsx +0 -73
  53. package/src/dev-host/components/ui/ScrollArea.tsx +0 -20
  54. package/src/dev-host/components/ui/Tabs.tsx +0 -166
  55. package/src/dev-host/components/ui/Textarea.tsx +0 -79
  56. package/src/dev-host/components/ui/ToggleGroup.tsx +0 -120
@@ -33,7 +33,11 @@ export type MessageEntry = {
33
33
  payload: unknown;
34
34
  };
35
35
 
36
- export type DevHostFlowRunStatus = 'running' | 'succeeded' | 'failed' | 'aborted';
36
+ export type DevHostFlowRunStatus =
37
+ | 'running'
38
+ | 'succeeded'
39
+ | 'failed'
40
+ | 'aborted';
37
41
 
38
42
  export type DevHostFlowRunState = {
39
43
  id: string;
@@ -50,12 +54,3 @@ export type PluginMessage = {
50
54
  type: string;
51
55
  payload: unknown;
52
56
  };
53
-
54
- export type ResizeHandleId = 'devtools-height' | 'command-width' | 'details-width';
55
-
56
- export type ResizeSession = {
57
- handleId: ResizeHandleId;
58
- pointerId: number;
59
- element: HTMLElement;
60
- onMove: (event: PointerEvent) => void;
61
- };
@@ -1,5 +1,10 @@
1
1
  import { DEV_HOST_STATE_ELEMENT_ID } from './constants.js';
2
- import type { DevHostPanelEntry, DevHostState, MessageEntry, PluginMessage } from './types.js';
2
+ import type {
3
+ DevHostPanelEntry,
4
+ DevHostState,
5
+ MessageEntry,
6
+ PluginMessage,
7
+ } from './types.js';
3
8
 
4
9
  export const cn = (...parts: Array<string | false | null | undefined>) => {
5
10
  return parts.filter(Boolean).join(' ');
@@ -21,10 +26,6 @@ export const formatPayloadPreview = (payload: unknown) => {
21
26
  }
22
27
  };
23
28
 
24
- export const isJsonTreeData = (value: unknown): value is Record<string, unknown> | unknown[] => {
25
- return Array.isArray(value) || (typeof value === 'object' && value !== null);
26
- };
27
-
28
29
  export const formatMessageDate = (date: string) => {
29
30
  return new Date(date).toLocaleString();
30
31
  };
@@ -59,7 +60,9 @@ export const isPluginMessage = (value: unknown): value is PluginMessage => {
59
60
  };
60
61
 
61
62
  export const getInitialPanel = (panels: DevHostPanelEntry[]) => {
62
- const requestedPanel = new URLSearchParams(window.location.search).get('panel');
63
+ const requestedPanel = new URLSearchParams(window.location.search).get(
64
+ 'panel',
65
+ );
63
66
 
64
67
  if (requestedPanel) {
65
68
  const matchedPanel = panels.find((panel) => panel.label === requestedPanel);
@@ -1,5 +1,6 @@
1
1
  import path from 'node:path';
2
2
  import { fileURLToPath } from 'node:url';
3
+ import tailwindcss from '@tailwindcss/vite';
3
4
  import { defineConfig } from 'vite';
4
5
 
5
6
  const HOST_APP_ROOT = fileURLToPath(new URL('./', import.meta.url));
@@ -9,6 +10,7 @@ export default defineConfig({
9
10
  root: HOST_APP_ROOT,
10
11
  base: './',
11
12
  publicDir: false,
13
+ plugins: [tailwindcss()],
12
14
  build: {
13
15
  outDir: path.join(PACKAGE_ROOT, 'dist', 'dev-host'),
14
16
  emptyOutDir: true,
package/src/index.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { PluginOption } from 'vite';
2
+ import tailwindcss from '@tailwindcss/vite';
2
3
  import react from '@vitejs/plugin-react';
3
4
  import reactNativeWeb from 'vite-plugin-react-native-web';
4
5
  import path from 'node:path';
@@ -57,10 +58,7 @@ const getDtsPlugin = (
57
58
  };
58
59
  }
59
60
 
60
- if (
61
- target === 'sdk' &&
62
- filePath === rawSdkEntryPath
63
- ) {
61
+ if (target === 'sdk' && filePath === rawSdkEntryPath) {
64
62
  return {
65
63
  // vite-plugin-dts emits the SDK root declaration at dist/sdk.d.ts.
66
64
  // Move it under dist/sdk/ before API Extractor rolls it up into the
@@ -87,7 +85,18 @@ const getDtsPlugin = (
87
85
  });
88
86
  };
89
87
 
90
- export const rozenitePlugin = (): PluginOption[] => {
88
+ export type RozenitePluginOptions = {
89
+ /**
90
+ * Configure Tailwind CSS v4 for client panels.
91
+ *
92
+ * @default true
93
+ */
94
+ tailwind?: boolean;
95
+ };
96
+
97
+ export const rozenitePlugin = ({
98
+ tailwind = true,
99
+ }: RozenitePluginOptions = {}): PluginOption[] => {
91
100
  const isServer = process.env.VITE_ROZENITE_TARGET === 'server';
92
101
  const isReactNative = process.env.VITE_ROZENITE_TARGET === 'react-native';
93
102
  const isSdk = process.env.VITE_ROZENITE_TARGET === 'sdk';
@@ -106,6 +115,7 @@ export const rozenitePlugin = (): PluginOption[] => {
106
115
  }
107
116
 
108
117
  return [
118
+ ...(tailwind ? [tailwindcss()] : []),
109
119
  react(),
110
120
  // @ts-expect-error: TypeScript gets confused by the dual export
111
121
  reactNativeWeb(),
@@ -67,7 +67,7 @@ export type RozeniteConfig = {
67
67
  };
68
68
 
69
69
  export const loadConfig = async (
70
- configPath: string
70
+ configPath: string,
71
71
  ): Promise<RozeniteConfig> => {
72
72
  const absoluteConfigPath = path.resolve(process.cwd(), configPath);
73
73
 
@@ -78,7 +78,7 @@ export const loadConfig = async (
78
78
  try {
79
79
  const configContent = await fs.promises.readFile(
80
80
  absoluteConfigPath,
81
- 'utf-8'
81
+ 'utf-8',
82
82
  );
83
83
 
84
84
  const result = await transformWithEsbuild(
@@ -88,7 +88,7 @@ export const loadConfig = async (
88
88
  loader: 'ts',
89
89
  format: 'cjs',
90
90
  target: 'esnext',
91
- }
91
+ },
92
92
  );
93
93
 
94
94
  const moduleExports: { default?: unknown } = {};
@@ -109,7 +109,7 @@ export const loadConfig = async (
109
109
  } catch (error) {
110
110
  if (error instanceof Error) {
111
111
  throw new Error(
112
- `Failed to load configuration from ${configPath}: ${error.message}`
112
+ `Failed to load configuration from ${configPath}: ${error.message}`,
113
113
  );
114
114
  }
115
115
  throw new Error(`Failed to load configuration from ${configPath}`);
@@ -8,7 +8,7 @@ export type PackageJSON = {
8
8
  };
9
9
 
10
10
  export const getPackageJSON = async (
11
- projectRoot: string
11
+ projectRoot: string,
12
12
  ): Promise<PackageJSON> => {
13
13
  const packageJSONPath = path.join(projectRoot, 'package.json');
14
14
  const packageJSON = await fs.readFile(packageJSONPath, 'utf8');
@@ -8,6 +8,9 @@ export const rozeniteReactNativePlugin = (): Plugin => {
8
8
  const projectRoot = config.root ?? process.cwd();
9
9
 
10
10
  config.build ??= {};
11
+ if (process.env.ROZENITE_BUILD === '1') {
12
+ config.build.emptyOutDir = false;
13
+ }
11
14
  config.build.rollupOptions ??= {};
12
15
 
13
16
  config.build.lib = {
package/src/sdk-plugin.ts CHANGED
@@ -8,6 +8,9 @@ export const rozeniteSdkPlugin = (): Plugin => {
8
8
  const projectRoot = config.root ?? process.cwd();
9
9
 
10
10
  config.build ??= {};
11
+ if (process.env.ROZENITE_BUILD === '1') {
12
+ config.build.emptyOutDir = false;
13
+ }
11
14
  config.build.lib = {
12
15
  entry: path.resolve(projectRoot, 'sdk.ts'),
13
16
  formats: ['es' as const, 'cjs' as const],
@@ -10,6 +10,9 @@ export const rozeniteServerPlugin = (): Plugin => {
10
10
  const projectRoot = config.root ?? process.cwd();
11
11
 
12
12
  config.build ??= {};
13
+ if (process.env.ROZENITE_BUILD === '1') {
14
+ config.build.emptyOutDir = false;
15
+ }
13
16
  config.build.lib = {
14
17
  entry: path.resolve(projectRoot, 'metro.ts'),
15
18
  formats: ['es' as const, 'cjs' as const],
package/src/utils.ts CHANGED
@@ -3,7 +3,7 @@ import path from 'node:path';
3
3
 
4
4
  export const resolveFileWithExtensions = (
5
5
  directory: string,
6
- baseName: string
6
+ baseName: string,
7
7
  ): string | null => {
8
8
  const extensions = ['.tsx', '.ts', '.jsx', '.js'];
9
9
 
@@ -1 +0,0 @@
1
- :root{color-scheme:dark;font-family:Switzer Variable,Inter,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,sans-serif;background:#000;color:#fff}*{box-sizing:border-box}html,body,#root{height:100%;margin:0}body{overflow:hidden;background:#000}button,input,textarea,select{font:inherit}.rz-shell{display:flex;height:100dvh;flex-direction:column;overflow:hidden;background:#000}.rz-topbar{display:flex;align-items:center;justify-content:space-between;gap:16px;min-height:52px;padding:10px 14px;border-bottom:1px solid rgba(255,255,255,.08);overflow:hidden;background:#0a0a0a}.rz-topbar-brand{display:inline-flex;align-items:center;flex:0 0 auto}.rz-topbar-brand svg{display:block;width:auto;height:20px}.rz-topbar-panel-picker{display:flex;align-items:center;min-width:0;justify-content:flex-end}.rz-workspace{flex:1;min-height:0;display:grid;grid-template-rows:minmax(0,1fr) 12px minmax(180px,var(--rz-devtools-height, 288px));overflow:hidden}.rz-card{min-height:0;overflow:hidden;border-top:1px solid rgba(255,255,255,.08)}.rz-card:first-child{border-top:0}.rz-iframe{display:block;width:100%;height:100%;border:0;background:#fff}.rz-iframe[data-resizing=true]{pointer-events:none}.rz-devtools{display:grid;min-height:0;grid-template-columns:minmax(0,1fr) var(--rz-command-splitter-width, 6px) minmax(260px,var(--rz-command-width, 320px))}.rz-devtools-mobile{display:flex;min-height:0;height:100%;width:100%;overflow:hidden}.rz-log-workspace{display:grid;min-height:0;position:relative;grid-template-columns:minmax(0,1fr) var(--rz-details-splitter-width, 0px) var(--rz-details-width, 0px)}.rz-resize-handle{position:relative;cursor:row-resize;background:#0a0a0a;-webkit-user-select:none;user-select:none;touch-action:none}.rz-resize-handle:before{content:"";position:absolute;top:50%;left:50%;width:72px;height:2px;border-radius:999px;background:#fff3;transform:translate(-50%,-50%)}.rz-resize-handle:after{content:"";position:absolute;inset:0;border-top:1px solid rgba(255,255,255,.08);border-bottom:1px solid rgba(255,255,255,.08)}.rz-resize-handle[data-dragging=true]:before,.rz-resize-handle:hover:before{background:#fff}.rz-column-resize-handle{position:relative;width:6px;min-width:6px;cursor:col-resize;background:#0a0a0a;-webkit-user-select:none;user-select:none;touch-action:none}.rz-column-resize-handle:before{content:"";position:absolute;top:50%;left:50%;width:2px;height:72px;border-radius:999px;background:#fff3;transform:translate(-50%,-50%)}.rz-column-resize-handle:after{content:"";position:absolute;inset:0;border-left:1px solid rgba(255,255,255,.08);border-right:1px solid rgba(255,255,255,.08)}.rz-column-resize-handle[data-dragging=true]:before,.rz-column-resize-handle:hover:before{background:#fff}.rz-column-resize-handle[data-dragging=true]:after,.rz-column-resize-handle:hover:after{border-left-color:#ffffff14;border-right-color:#ffffff14}.rz-pane{display:flex;flex-direction:column;min-height:0;overflow:hidden}.rz-pane+.rz-pane{border-left:1px solid rgba(255,255,255,.08)}.rz-pane[data-hidden=true],.rz-column-resize-handle[data-hidden=true]{display:none}.rz-devtools-mobile-tabs{display:grid;grid-template-rows:auto minmax(0,1fr);gap:8px;min-height:0;height:100%;width:100%;padding-top:8px}.rz-devtools-mobile-toggle{display:flex;align-items:flex-start;padding:0 8px}.rz-devtools-mobile-panel{display:flex;min-height:0;width:100%;overflow:hidden}.rz-devtools-mobile-panel>.rz-pane{flex:1;width:100%}.rz-tabs-root{width:100%;min-width:0}.rz-tabs-list{display:inline-flex;min-height:26px;max-width:100%;align-items:center;gap:2px;overflow:auto hidden;border:1px solid rgba(255,255,255,.08);border-radius:4px;background:#ffffff0a;padding:2px;scrollbar-width:none}.rz-tabs-list::-webkit-scrollbar{display:none}.rz-tabs-trigger{display:inline-flex;align-items:center;justify-content:center;white-space:nowrap;border:0;border-radius:2px;background:transparent;min-height:22px;padding:3px 9px;color:#fff9;font-size:12px;font-weight:500;line-height:1.2;letter-spacing:0;transition:background-color .12s ease,color .12s ease}.rz-tabs-trigger:hover{color:#fff}.rz-tabs-trigger[data-state=active]{background:#fff;color:#000}.rz-tabs-trigger:focus-visible,.rz-input:focus-visible,.rz-textarea:focus-visible,.rz-sidebar-close:focus-visible{outline:2px solid rgba(130,50,255,.95);outline-offset:-2px}.rz-scroll-area{position:relative;height:100%;width:100%;overflow:hidden}.rz-scroll-viewport{height:100%;width:100%;overflow-y:auto;overflow-x:hidden;scrollbar-width:thin;scrollbar-color:rgba(255,255,255,.18) transparent}.rz-scroll-viewport::-webkit-scrollbar{width:12px}.rz-scroll-viewport::-webkit-scrollbar-track{background:transparent}.rz-scroll-viewport::-webkit-scrollbar-thumb{border:3px solid transparent;border-radius:999px;background:#ffffff2e;background-clip:padding-box}.rz-message-list{min-width:100%;font-family:Geist Mono,ui-monospace,SFMono-Regular,Menlo,monospace}.rz-log-pane{display:grid;grid-template-rows:auto minmax(0,1fr);min-height:0;background:#050505}.rz-message-list-header,.rz-message-row{display:grid;grid-template-columns:40px 168px minmax(120px,180px) minmax(0,1fr);gap:0;align-items:center}.rz-message-list-header{position:sticky;top:0;z-index:1;background:#0a0a0a;color:#fff6;font-size:11px;line-height:16px;letter-spacing:.06em;text-transform:uppercase;border-bottom:1px solid rgba(255,255,255,.08)}.rz-message-header-cell,.rz-message-cell{min-width:0;padding:8px 12px}.rz-message-header-cell:first-child,.rz-message-cell:first-child{text-align:center}.rz-message-header-cell+.rz-message-header-cell,.rz-message-cell+.rz-message-cell{border-left:1px solid rgba(255,255,255,.04)}.rz-message-row{width:100%;border:0;background:transparent;color:inherit;text-align:left;padding:0;border-bottom:1px solid rgba(255,255,255,.06);cursor:pointer;transition:background-color .12s ease,box-shadow .12s ease}.rz-message-row:last-child{border-bottom:0}.rz-message-row:hover{background:#ffffff09}.rz-message-row[data-selected=true]{background:#3b82f624;box-shadow:inset 2px 0 #4da3ff}.rz-message-direction{display:flex;align-items:center;justify-content:center;color:#ffffffb3;font-size:12px;line-height:18px}.rz-message-arrow{display:inline-flex;width:16px;justify-content:center;font-size:14px;font-weight:700}.rz-message-dir-in .rz-message-arrow{color:#22c55e}.rz-message-dir-out .rz-message-arrow{color:#f59e0b}.rz-message-type{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffffeb;font-size:12px;font-weight:500;line-height:18px}.rz-message-date{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffff85;font-size:12px;line-height:18px}.rz-message-preview{margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:#ffffff85;font-size:12px;line-height:18px}.rz-sidebar{display:grid;grid-template-rows:auto minmax(0,1fr);min-height:0;background:#050505;flex-grow:1}.rz-message-detail{display:flex;flex-direction:column;gap:16px;padding:16px;min-height:100%}.rz-sidebar-header{display:flex;align-items:center;justify-content:space-between;gap:12px;min-height:53px;padding:12px 16px;border-bottom:1px solid rgba(255,255,255,.08);background:#ffffff05}.rz-sidebar-scroll{min-height:0}.rz-sidebar-scroll>.rz-scroll-viewport>*{min-height:100%}.rz-sidebar-title{color:#ffffffe0;font-size:12px;font-weight:600;line-height:18px;letter-spacing:.04em;text-transform:uppercase;font-family:Geist Mono,ui-monospace,SFMono-Regular,Menlo,monospace}.rz-header-actions{display:flex;align-items:center;gap:8px}.rz-sidebar-close{display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;border:0;border-radius:4px;background:transparent;color:#ffffff8f;cursor:pointer}.rz-sidebar-close:hover{background:#ffffff0f;color:#fff}.rz-sidebar-close:disabled{cursor:default;opacity:.4}.rz-sidebar-close:disabled:hover{background:transparent;color:#ffffff8f}.rz-sidebar-action-primary{background:#fff;color:#000}.rz-sidebar-action-primary:hover{background:#ffffffe0;color:#000}.rz-sidebar-action-primary:disabled:hover{background:#fff;color:#000}.rz-detail-section{display:grid;align-content:start;gap:8px;min-width:0}.rz-detail-value{min-width:0;border:1px solid rgba(255,255,255,.08);border-radius:4px;background:#ffffff08;padding:10px 12px;color:#ffffffe6;font-size:13px;line-height:1.5;letter-spacing:-.02em}.rz-detail-mono{font-family:Geist Mono,ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:1.5}.rz-detail-payload{display:flex;border:1px solid rgba(255,255,255,.08);border-radius:4px;background:#ffffff08;padding:12px}.rz-detail-pre{margin:0;white-space:pre-wrap;word-break:break-word}.rz-detail-json-tree{font-family:Geist Mono,ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:1.5}.rz-detail-json-tree ul,.rz-detail-json-tree li,.rz-detail-json-tree label,.rz-detail-json-tree span{font-size:inherit}.rz-command-form{display:flex;flex-direction:column;gap:12px;padding:16px;min-height:100%}.rz-action-tabs{min-height:100%}.rz-action-tabs-header{display:flex;align-items:center;justify-content:space-between;gap:12px}.rz-action-tab-panel{min-height:0}.rz-action-form{display:flex;flex-direction:column;gap:12px;min-height:100%}.rz-field{display:grid;gap:6px}.rz-template-list{display:flex;flex-wrap:wrap;gap:8px}.rz-preset-menu{position:relative}.rz-preset-icon-button{display:flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:1px solid rgba(255,255,255,.08);border-radius:6px;background:#ffffff0a;color:#ffffffe0;cursor:pointer;flex-shrink:0}.rz-preset-icon-button:hover{background:#ffffff14;color:#fff}.rz-baseui-preset-menu{min-width:220px;max-width:min(320px,calc(100vw - 24px))}.rz-template-button{border:1px solid rgba(255,255,255,.08);border-radius:999px;background:#ffffff0a;color:#ffffffdb;padding:6px 10px;font-size:12px;line-height:1.4;cursor:pointer}.rz-template-button:hover{background:#ffffff1a;color:#fff}.rz-template-button:focus-visible{outline:2px solid rgba(130,50,255,.95);outline-offset:1px}.rz-template-button:disabled{cursor:default;opacity:.4}.rz-template-button[data-active=true]{background:#8232ff2e;border-color:#8232ff80;color:#fff}.rz-flow-panel{display:grid;gap:16px}.rz-flow-list{display:grid;gap:8px}.rz-flow-list-button{display:flex;align-items:center;justify-content:space-between;gap:12px;width:100%;border:1px solid rgba(255,255,255,.08);border-radius:8px;background:#ffffff08;color:#ffffffe0;padding:10px 12px;text-align:left;cursor:pointer}.rz-flow-list-button:hover{background:#ffffff0f;color:#fff}.rz-flow-list-button:focus-visible{outline:2px solid rgba(130,50,255,.95);outline-offset:1px}.rz-flow-list-button:disabled{cursor:default;opacity:.4}.rz-flow-list-button[data-active=true]{background:#8232ff24;border-color:#8232ff73}.rz-flow-list-name{display:inline-flex;align-items:center;gap:6px;font-size:13px;line-height:1.4}.rz-flow-list-badge,.rz-flow-state-badge{display:inline-flex;align-items:center;justify-content:center;min-height:18px;padding:0 6px;border-radius:999px;background:#8232ff29;color:#c9a9ff;font-size:10px;line-height:1;font-family:Geist Mono,ui-monospace,SFMono-Regular,Menlo,monospace;text-transform:uppercase}.rz-flow-list-action{color:#ffffff8f;font-size:11px;line-height:1.4;font-family:Geist Mono,ui-monospace,SFMono-Regular,Menlo,monospace;text-transform:uppercase}.rz-flow-empty-state{border:1px dashed rgba(255,255,255,.12);border-radius:8px;padding:12px;color:#fff9;font-size:13px;line-height:1.5}.rz-flow-runs{display:grid;gap:12px}.rz-flow-state{display:grid;gap:8px;padding:12px;border:1px solid rgba(255,255,255,.08);border-radius:8px;background:#ffffff08}.rz-flow-state[data-status=running]{border-color:#8232ff73}.rz-flow-state[data-status=failed]{border-color:#ff787866}.rz-flow-state-header{display:flex;align-items:center;justify-content:space-between;gap:8px}.rz-flow-state-title{display:inline-flex;align-items:center;gap:6px;color:#ffffffe6;font-size:13px;line-height:1.4}.rz-flow-state-status{color:#fff9;font-size:12px;line-height:1.4;font-family:Geist Mono,ui-monospace,SFMono-Regular,Menlo,monospace;text-transform:uppercase}.rz-flow-state-error,.rz-flow-state-result{margin:0;border-radius:4px;background:#ffffff0a;padding:10px 12px;color:#ffffffd6;font-size:12px;line-height:1.5;white-space:pre-wrap;word-break:break-word}.rz-flow-state-error{color:#ffb4b4}.rz-flow-stop-button{flex-shrink:0}.rz-label{color:#fff9;font-size:12px;line-height:20px;letter-spacing:-.04em;font-family:Geist Mono,ui-monospace,SFMono-Regular,Menlo,monospace}.rz-input,.rz-textarea{width:100%;border:1px solid rgba(255,255,255,.08);border-radius:4px;background:#ffffff0a;color:#fff;padding:10px 12px;font-size:14px;line-height:1.5;letter-spacing:-.02em}.rz-textarea{min-height:112px;resize:none}.rz-button-row{display:flex;justify-content:flex-end;gap:8px;margin-top:auto}.rz-empty-state{display:flex;height:100%;align-items:center;justify-content:center;color:#ffffffb3;padding:24px;text-align:center;font-size:16px;line-height:1.5;letter-spacing:-.02em}@media(max-width:960px){.rz-topbar{padding-left:8px;padding-right:8px}.rz-topbar-brand svg{height:18px}.rz-topbar-panel-picker{overflow:hidden}.rz-workspace{grid-template-rows:minmax(0,1fr) 12px minmax(180px,var(--rz-devtools-height, 272px))}.rz-devtools-mobile-tabs{padding-top:8px}.rz-column-resize-handle{width:100%;min-width:0;min-height:6px;cursor:row-resize}.rz-column-resize-handle:before{width:72px;height:2px}.rz-column-resize-handle:after{border-left:0;border-right:0;border-top:1px solid rgba(255,255,255,.08);border-bottom:1px solid rgba(255,255,255,.08)}.rz-column-resize-handle[data-dragging=true]:after,.rz-column-resize-handle:hover:after{border-top-color:#ffffff14;border-bottom-color:#ffffff14}.rz-action-tabs-header{flex-wrap:wrap;align-items:flex-start}}@media(max-width:640px){.rz-message-list-header,.rz-message-row{grid-template-columns:36px 136px minmax(92px,136px) minmax(0,1fr)}.rz-message-header-cell,.rz-message-cell{padding:8px 10px}}