@parallelworks/ui 0.1.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.
package/dist/index.js ADDED
@@ -0,0 +1,421 @@
1
+ import { DEFAULT_PRESET, THEME_PRESETS, THEME_TOKENS, applyTheme, contrastRatio, deriveTheme, isDarkColor } from "./theme/index.js";
2
+ import { AlertIcon, InfoIcon, LoaderIcon, TooltipIcon } from "./icons.js";
3
+ import cx from "classnames";
4
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
+ import React, { Fragment as Fragment$1, useCallback, useEffect, useId, useRef, useState } from "react";
6
+ import { Tooltip } from "react-tooltip";
7
+ import { createPortal } from "react-dom";
8
+ //#region src/components/Callout.tsx
9
+ function CalloutIcon({ type }) {
10
+ if (type === "warning" || type === "error") return /* @__PURE__ */ jsx(AlertIcon, { className: "h-6 w-6 mr-4 text-lg" });
11
+ else return /* @__PURE__ */ jsx(InfoIcon, { className: "h-6 w-6 mr-4 text-lg" });
12
+ }
13
+ function Callout({ type, className = "", children }) {
14
+ return /* @__PURE__ */ jsx("div", {
15
+ className: cx(className, type === "warning" && "bg-orange-100 border-orange-500 text-orange-700", type === "error" && "bg-red-100 border-red-500 text-red-700", type === "info" && "bg-blue-100 border-blue-500 text-blue-700", "border-t-4 rounded-b px-4 py-3 shadow-md my-4"),
16
+ role: "alert",
17
+ children: /* @__PURE__ */ jsxs("div", {
18
+ className: "flex",
19
+ children: [/* @__PURE__ */ jsx("div", {
20
+ className: "py-1",
21
+ children: /* @__PURE__ */ jsx(CalloutIcon, { type })
22
+ }), /* @__PURE__ */ jsx("div", { children })]
23
+ })
24
+ });
25
+ }
26
+ //#endregion
27
+ //#region src/components/Tooltip.tsx
28
+ var TOOLTIP_ID = "global-tooltip";
29
+ var linkRegex = /\[([^\]]+)\]\((https?:\/\/[^\s)]+)\)/g;
30
+ function formatLine(line) {
31
+ const nodes = [];
32
+ let last = 0;
33
+ for (const match of line.matchAll(linkRegex)) {
34
+ if (match.index > last) nodes.push(line.slice(last, match.index));
35
+ nodes.push(/* @__PURE__ */ jsx("a", {
36
+ href: match[2],
37
+ target: "_blank",
38
+ rel: "noopener noreferrer",
39
+ className: "underline",
40
+ children: match[1]
41
+ }, match.index));
42
+ last = match.index + match[0].length;
43
+ }
44
+ if (last < line.length) nodes.push(line.slice(last));
45
+ return nodes;
46
+ }
47
+ /** Tooltip text can come from untrusted sources (workflow YAML), so all markup is literal text — only `[text](url)` links and newlines are parsed. */
48
+ function formatTooltipContent(content) {
49
+ if (typeof content !== "string") return content || null;
50
+ if (!content) return null;
51
+ return content.split(/<br\s*\/?>|\n/i).map((line, idx) => /* @__PURE__ */ jsxs(Fragment$1, { children: [idx > 0 && /* @__PURE__ */ jsx("br", {}), formatLine(line)] }, idx));
52
+ }
53
+ function KbdShortcut({ keys }) {
54
+ return /* @__PURE__ */ jsx("span", {
55
+ className: "inline-flex items-center gap-1 align-middle",
56
+ children: keys.split("+").map((part) => part.trim()).filter(Boolean).map((part, idx) => /* @__PURE__ */ jsxs(Fragment$1, { children: [idx > 0 && /* @__PURE__ */ jsx("span", {
57
+ className: "opacity-60 text-[11px]",
58
+ children: "+"
59
+ }), /* @__PURE__ */ jsx("kbd", {
60
+ className: "inline-flex items-center justify-center min-w-[18px] h-[18px] px-1 rounded border border-white/30 bg-white/10 font-sans text-[11px] font-semibold leading-none",
61
+ children: part
62
+ })] }, `${part}-${idx}`))
63
+ });
64
+ }
65
+ /** Singleton rendered at layout root; anchors opt in via data-tooltip-id={TOOLTIP_ID}, data-tooltip-content, and data-tooltip-shortcut. */
66
+ function GlobalTooltip() {
67
+ return /* @__PURE__ */ jsx(Tooltip, {
68
+ id: TOOLTIP_ID,
69
+ className: "max-w-lg break-words config-tips normal-case text-left z-[10000]",
70
+ place: "top",
71
+ render: ({ content, activeAnchor }) => {
72
+ const body = formatTooltipContent(content);
73
+ const shortcut = activeAnchor?.getAttribute("data-tooltip-shortcut");
74
+ if (!shortcut) return body;
75
+ return /* @__PURE__ */ jsxs("span", {
76
+ className: "inline-flex items-center gap-2",
77
+ children: [body, /* @__PURE__ */ jsx(KbdShortcut, { keys: shortcut })]
78
+ });
79
+ }
80
+ });
81
+ }
82
+ function TooltipInfo({ text, className = "", children, place = "top", tabIndex }) {
83
+ return /* @__PURE__ */ jsx("div", {
84
+ "data-tooltip-id": TOOLTIP_ID,
85
+ "data-tooltip-content": text,
86
+ "data-tooltip-place": place,
87
+ className,
88
+ tabIndex,
89
+ children: children || /* @__PURE__ */ jsx(TooltipIcon, { className: "tooltip" })
90
+ });
91
+ }
92
+ //#endregion
93
+ //#region src/components/DescriptionList.tsx
94
+ function DescriptionListItem({ label, children, tooltip, className, ...props }) {
95
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("dt", {
96
+ className: cx("leading-6 col-span-1 font-normal flex gap-1", className),
97
+ children: [/* @__PURE__ */ jsx("span", {
98
+ className: "min-w-0 truncate",
99
+ children: label
100
+ }), tooltip && /* @__PURE__ */ jsx(TooltipInfo, {
101
+ className: "pr-2",
102
+ text: tooltip
103
+ })]
104
+ }), /* @__PURE__ */ jsx("dd", {
105
+ ...props,
106
+ className: "flex leading-6 col-span-4 font-light items-center overflow-auto",
107
+ children
108
+ })] });
109
+ }
110
+ function DescriptionList({ children, title, separators = true, subtitle, className, wrapperClassName, vertical = false }) {
111
+ return /* @__PURE__ */ jsxs("div", {
112
+ className: cx("w-full", wrapperClassName),
113
+ children: [
114
+ title && /* @__PURE__ */ jsx("h2", {
115
+ className: "text-lg font-semibold w-full mb-1",
116
+ children: title
117
+ }),
118
+ subtitle && /* @__PURE__ */ jsx("div", {
119
+ className: "max-w-2xl text-sm/6 w-full",
120
+ children: subtitle
121
+ }),
122
+ /* @__PURE__ */ jsx("dl", {
123
+ className: cx("grid", separators && "*:not-last-of-type:border-b-1", vertical ? "grid-cols-1" : "grid-cols-5 gap-x-4 gap-y-0.5 *:pb-0.5", className),
124
+ children: Array.isArray(children) ? children.map((child, index) => /* @__PURE__ */ jsx(React.Fragment, { children: child }, index)) : children
125
+ })
126
+ ]
127
+ });
128
+ }
129
+ //#endregion
130
+ //#region src/components/EmptyState.tsx
131
+ function EmptyState({ title, description, action, icon: Icon }) {
132
+ return /* @__PURE__ */ jsxs("div", {
133
+ className: "border-solid rounded-2xl border border-(--theme-border) theme-panel flex flex-col items-center justify-center py-12 px-6",
134
+ children: [
135
+ Icon && /* @__PURE__ */ jsx("div", {
136
+ className: "w-10 h-10 rounded-full bg-(--theme-muted-panel-bg) flex items-center justify-center mb-3",
137
+ children: /* @__PURE__ */ jsx(Icon, { className: "w-5 h-5 theme-muted-text" })
138
+ }),
139
+ /* @__PURE__ */ jsx("p", {
140
+ className: "text-sm font-medium mb-1",
141
+ children: title
142
+ }),
143
+ description && /* @__PURE__ */ jsx("p", {
144
+ className: "text-xs theme-muted-text text-center max-w-xs",
145
+ children: description
146
+ }),
147
+ action && /* @__PURE__ */ jsx("div", {
148
+ className: "mt-4",
149
+ children: action
150
+ })
151
+ ]
152
+ });
153
+ }
154
+ //#endregion
155
+ //#region src/components/Loader.tsx
156
+ function Loader({ size = 48, text, textSize = 12, full = true, color = "", loaderStyle = {} }) {
157
+ const loaderColor = color || "text-(--theme-element,#3b82f6)";
158
+ const fontSize = typeof size === "number" ? `${size}px` : size;
159
+ return /* @__PURE__ */ jsxs("div", {
160
+ className: cx(full && "w-full", "flex flex-col flex-wrap justify-center items-center gap-y-1"),
161
+ children: [/* @__PURE__ */ jsx("div", {
162
+ className: cx("w-full flex justify-center items-center", loaderColor),
163
+ style: loaderStyle,
164
+ children: /* @__PURE__ */ jsx(LoaderIcon, {
165
+ className: "animate-spin",
166
+ style: { fontSize }
167
+ })
168
+ }), text && /* @__PURE__ */ jsx("div", {
169
+ className: "text-center italic",
170
+ style: { fontSize: `${textSize}px` },
171
+ children: text
172
+ })]
173
+ });
174
+ }
175
+ //#endregion
176
+ //#region src/components/Modal.tsx
177
+ var FOCUSABLE = "a[href], button:not([disabled]), textarea, input, select, [tabindex]:not([tabindex=\"-1\"])";
178
+ var noop = () => {};
179
+ var actionClasses = {
180
+ destructive: "bg-red-600 text-white hover:bg-red-700",
181
+ warning: "bg-yellow-500 text-white hover:bg-yellow-700",
182
+ info: "bg-(--theme-element,#06354f) text-(--theme-element-text,#ffffff) hover:opacity-90"
183
+ };
184
+ function Modal({ isOpen, close, cancelAction = noop, children, title = "", text = "", actionLabel = "", cancelLabel = "Cancel", action, closeAfterAction = true, type = "destructive", className = "", showButtons = true, disableAction = false, loading = false, padding = true, fitWidth = false, dimScreen = true, ignoreOutsideClickClose = false }) {
185
+ const [pending, setPending] = useState(false);
186
+ const actionFiredRef = useRef(false);
187
+ const panelRef = useRef(null);
188
+ const titleId = useId();
189
+ const inFlight = loading || pending;
190
+ const inFlightRef = useRef(inFlight);
191
+ inFlightRef.current = inFlight;
192
+ useEffect(() => {
193
+ if (isOpen) actionFiredRef.current = false;
194
+ }, [isOpen]);
195
+ useEffect(() => {
196
+ if (!isOpen) return;
197
+ const previouslyFocused = document.activeElement;
198
+ const previousOverflow = document.body.style.overflow;
199
+ document.body.style.overflow = "hidden";
200
+ panelRef.current?.focus();
201
+ return () => {
202
+ document.body.style.overflow = previousOverflow;
203
+ previouslyFocused?.focus?.();
204
+ };
205
+ }, [isOpen]);
206
+ const trapFocus = useCallback((e) => {
207
+ if (e.key !== "Tab" || !panelRef.current) return;
208
+ const focusable = panelRef.current.querySelectorAll(FOCUSABLE);
209
+ if (focusable.length === 0) {
210
+ e.preventDefault();
211
+ return;
212
+ }
213
+ const first = focusable[0];
214
+ const last = focusable[focusable.length - 1];
215
+ if (e.shiftKey && document.activeElement === first) {
216
+ e.preventDefault();
217
+ last.focus();
218
+ } else if (!e.shiftKey && document.activeElement === last) {
219
+ e.preventDefault();
220
+ first.focus();
221
+ }
222
+ }, []);
223
+ const closeRef = useRef(close);
224
+ closeRef.current = close;
225
+ useEffect(() => {
226
+ if (!isOpen) return;
227
+ const onKey = (e) => {
228
+ if (e.key === "Escape" && !inFlightRef.current) closeRef.current();
229
+ };
230
+ window.addEventListener("keydown", onKey);
231
+ return () => window.removeEventListener("keydown", onKey);
232
+ }, [isOpen]);
233
+ const runAction = useCallback(async () => {
234
+ if (actionFiredRef.current) return;
235
+ actionFiredRef.current = true;
236
+ setPending(true);
237
+ try {
238
+ await action?.();
239
+ if (closeAfterAction) closeRef.current();
240
+ else actionFiredRef.current = false;
241
+ } finally {
242
+ setPending(false);
243
+ }
244
+ }, [action, closeAfterAction]);
245
+ if (!isOpen) return null;
246
+ return createPortal(/* @__PURE__ */ jsxs("div", {
247
+ className: "fixed z-250 inset-0 flex w-screen items-center justify-center p-4",
248
+ role: "dialog",
249
+ "aria-modal": "true",
250
+ ...title ? { "aria-labelledby": titleId } : {},
251
+ onKeyDown: trapFocus,
252
+ children: [/* @__PURE__ */ jsx("div", {
253
+ className: cx("fixed inset-0", dimScreen && "bg-gray-500/75"),
254
+ onClick: inFlight || ignoreOutsideClickClose ? void 0 : close
255
+ }), /* @__PURE__ */ jsxs("div", {
256
+ ref: panelRef,
257
+ tabIndex: -1,
258
+ className: cx(className, "relative inline-block align-bottom rounded-lg text-left shadow-xl z-50 sm:my-8 sm:align-middle max-h-full overflow-y-auto", "bg-(--theme-panel-bg,#ffffff) text-(--theme-panel,#000000)", padding && "px-4 pt-5 pb-4 sm:p-6", fitWidth ? "sm:w-min-[32rem]" : "sm:max-w-lg sm:w-full"),
259
+ children: [/* @__PURE__ */ jsxs("div", { children: [title && /* @__PURE__ */ jsx("h3", {
260
+ id: titleId,
261
+ className: "text-center text-xl leading-6 font-semibold",
262
+ children: title
263
+ }), /* @__PURE__ */ jsxs("div", {
264
+ className: cx(title.length !== 0 && "mt-2"),
265
+ children: [text && /* @__PURE__ */ jsx("p", {
266
+ className: "text-sm text-center",
267
+ children: text
268
+ }), children]
269
+ })] }), showButtons && /* @__PURE__ */ jsxs("div", {
270
+ className: "mt-5 sm:mt-6 grid grid-cols-2 gap-3 grid-flow-row-dense",
271
+ children: [/* @__PURE__ */ jsx("button", {
272
+ type: "button",
273
+ className: cx("self-center cursor-pointer px-3 py-1.5 rounded-md text-xs font-medium whitespace-nowrap flex items-center justify-center", "border border-(--theme-border,#d1d5db) hover:bg-(--theme-hover,#f3f4f6)", inFlight && "cursor-wait"),
274
+ onClick: () => {
275
+ cancelAction();
276
+ close();
277
+ },
278
+ disabled: inFlight,
279
+ children: cancelLabel
280
+ }), /* @__PURE__ */ jsx("button", {
281
+ type: "button",
282
+ className: cx("self-center cursor-pointer px-3 py-1.5 rounded-md text-xs font-medium whitespace-nowrap flex items-center justify-center", "disabled:opacity-50 disabled:cursor-not-allowed", actionClasses[type], loading && "cursor-wait"),
283
+ onClick: runAction,
284
+ disabled: disableAction || inFlight,
285
+ children: actionLabel
286
+ })]
287
+ })]
288
+ })]
289
+ }), document.body);
290
+ }
291
+ //#endregion
292
+ //#region src/components/StatusBadge.tsx
293
+ var variantStyles = {
294
+ default: "bg-(--theme-muted-panel-bg) text-(--theme-app) border-(--theme-border)",
295
+ success: "bg-emerald-500/10 text-emerald-500 border-emerald-500/20",
296
+ warning: "bg-amber-500/10 text-amber-500 border-amber-500/20",
297
+ error: "bg-red-500/10 text-red-500 border-red-500/20",
298
+ info: "bg-blue-500/10 text-blue-500 border-blue-500/20",
299
+ muted: "bg-(--theme-muted-panel-bg)/50 text-(--theme-muted-text-color) border-(--theme-border)"
300
+ };
301
+ var pulseColors = {
302
+ default: "bg-(--theme-app)",
303
+ success: "bg-emerald-500",
304
+ warning: "bg-amber-500",
305
+ error: "bg-red-500",
306
+ info: "bg-blue-500",
307
+ muted: "bg-(--theme-muted-text-color)"
308
+ };
309
+ function StatusBadge({ children, variant = "default", pulse = false, size = "sm", className }) {
310
+ return /* @__PURE__ */ jsxs("span", {
311
+ className: cx("inline-flex items-center gap-1.5 rounded-full border font-medium", size === "sm" && "px-2 py-0.5 text-[10px]", size === "md" && "px-2.5 py-1 text-xs", variantStyles[variant], className),
312
+ children: [pulse && /* @__PURE__ */ jsxs("span", {
313
+ className: "relative flex h-2 w-2",
314
+ children: [/* @__PURE__ */ jsx("span", { className: cx("absolute inline-flex h-full w-full animate-ping rounded-full opacity-75", pulseColors[variant]) }), /* @__PURE__ */ jsx("span", { className: cx("relative inline-flex h-2 w-2 rounded-full", pulseColors[variant]) })]
315
+ }), children]
316
+ });
317
+ }
318
+ function StatusDot({ variant = "default", pulse = false, size = 8, className }) {
319
+ return /* @__PURE__ */ jsxs("span", {
320
+ className: cx("relative inline-flex", className),
321
+ style: {
322
+ width: size,
323
+ height: size
324
+ },
325
+ children: [pulse && /* @__PURE__ */ jsx("span", { className: cx("absolute inline-flex h-full w-full animate-ping rounded-full opacity-75", pulseColors[variant]) }), /* @__PURE__ */ jsx("span", {
326
+ className: cx("relative inline-flex rounded-full", pulseColors[variant]),
327
+ style: {
328
+ width: size,
329
+ height: size
330
+ }
331
+ })]
332
+ });
333
+ }
334
+ //#endregion
335
+ //#region src/components/Table.tsx
336
+ function Item({ wrap = false, children, className, colspan = 1, ...tdProps }) {
337
+ const yPadding = className?.includes("py-") ? "" : "py-4";
338
+ const xPadding = className?.includes("px-") ? "" : "px-2";
339
+ return /* @__PURE__ */ jsx("td", {
340
+ ...tdProps,
341
+ colSpan: colspan,
342
+ className: cx(yPadding, xPadding, wrap ? "" : "whitespace-nowrap", className),
343
+ children
344
+ });
345
+ }
346
+ function CompactItem({ wrap = false, children, className, colspan = 1, ...tdProps }) {
347
+ return /* @__PURE__ */ jsx("td", {
348
+ ...tdProps,
349
+ colSpan: colspan,
350
+ className: cx("px-2 text-sm font-medium", !wrap && "whitespace-nowrap", className),
351
+ children
352
+ });
353
+ }
354
+ function Header({ children, className, style, colspan = 1, onClick, caps = true }) {
355
+ return /* @__PURE__ */ jsx("th", {
356
+ scope: "col",
357
+ colSpan: colspan,
358
+ style,
359
+ className: cx(className, className?.includes("py-") ? "" : "py-3", className?.includes("px-") ? "" : "px-3", className?.includes("text-") ? "" : "text-left", "text-xs font-medium", caps ? "uppercase tracking-wider" : "", onClick && "cursor-pointer hover:opacity-80 transition-opacity"),
360
+ onClick,
361
+ children
362
+ });
363
+ }
364
+ var isHeaderChild = (child) => {
365
+ if (!React.isValidElement(child)) return false;
366
+ return child.type === Header || typeof child.type === "function" && child.type.isTableHeader === true;
367
+ };
368
+ var getHeaders = (children) => children.filter(isHeaderChild);
369
+ function Table({ borderless = false, panel = true, className = "", wrapperClassName = "", tbodyClassName = "divide-y", theadClassName = "theme-muted-panel", children, roundedTop = false, rounded = false, roundedBottom = false, isLoading = false, tableProps }) {
370
+ const ChildrenArr = React.Children.toArray(children);
371
+ const Headers = getHeaders(ChildrenArr);
372
+ return /* @__PURE__ */ jsx("div", {
373
+ className: cx("flex flex-col w-full", !wrapperClassName.split(" ").some((cls) => cls.startsWith("overflow-")) && "overflow-hidden", wrapperClassName),
374
+ children: isLoading ? /* @__PURE__ */ jsx("div", {
375
+ className: "flex justify-center items-center h-32",
376
+ children: /* @__PURE__ */ jsx(Loader, {})
377
+ }) : /* @__PURE__ */ jsx("div", {
378
+ className: cx("align-middle inline-block min-w-full overflow-x-auto", panel && "theme-panel", !borderless && "border theme-border", rounded && "rounded-2xl", roundedBottom && "rounded-b-2xl", roundedTop && "rounded-t-2xl"),
379
+ children: /* @__PURE__ */ jsxs("table", {
380
+ className: cx(className, "min-w-full divide-y theme-border"),
381
+ ...tableProps,
382
+ children: [/* @__PURE__ */ jsx("thead", {
383
+ className: theadClassName,
384
+ children: /* @__PURE__ */ jsx("tr", { children: Headers })
385
+ }), /* @__PURE__ */ jsx("tbody", {
386
+ className: tbodyClassName,
387
+ children: ChildrenArr.filter((c) => !isHeaderChild(c))
388
+ })]
389
+ })
390
+ })
391
+ });
392
+ }
393
+ function CompactTable({ wrapperClassName = "", className = "", tbodyClassName = "divide-y", children, roundedTop = false, rounded = false, roundedBottom = false }) {
394
+ const ChildrenArr = React.Children.toArray(children);
395
+ const Headers = getHeaders(ChildrenArr);
396
+ return /* @__PURE__ */ jsx("div", {
397
+ className: cx("flex flex-col w-full", !wrapperClassName.split(" ").some((cls) => cls.startsWith("overflow-")) && "overflow-hidden", wrapperClassName),
398
+ children: /* @__PURE__ */ jsx("div", {
399
+ className: cx("theme-panel inline-block min-w-full align-middle overflow-x-auto", rounded && "rounded-2xl", roundedBottom && "rounded-b-2xl pb-1", roundedTop && "rounded-t-2xl"),
400
+ children: /* @__PURE__ */ jsxs("table", {
401
+ className: cx("min-w-full divide-y theme-border", className),
402
+ children: [/* @__PURE__ */ jsx("thead", {
403
+ className: "theme-muted-panel",
404
+ children: /* @__PURE__ */ jsx("tr", {
405
+ className: "divide-x",
406
+ children: Headers
407
+ })
408
+ }), /* @__PURE__ */ jsx("tbody", {
409
+ className: tbodyClassName,
410
+ children: ChildrenArr.filter((c) => !isHeaderChild(c))
411
+ })]
412
+ })
413
+ })
414
+ });
415
+ }
416
+ Table.Header = Header;
417
+ Table.Item = Item;
418
+ CompactTable.Header = Header;
419
+ CompactTable.Item = CompactItem;
420
+ //#endregion
421
+ export { Callout, CompactTable, DEFAULT_PRESET, DescriptionList, DescriptionListItem, EmptyState, GlobalTooltip, Loader, Modal, StatusBadge, StatusDot, THEME_PRESETS, THEME_TOKENS, TOOLTIP_ID, Table, TooltipInfo, applyTheme, contrastRatio, deriveTheme, formatTooltipContent, isDarkColor };
@@ -0,0 +1,185 @@
1
+ /* The unified theme contract: `theme-*` utilities backed by a closed set of
2
+ * `--theme-*` CSS variables (see src/theme/index.ts for the full token list —
3
+ * every token is derivable from an {accent, background, contrast} seed per
4
+ * surface via deriveTheme()). Hosts override the variables at runtime (e.g.
5
+ * an org theme); the :root block only supplies defaults for standalone use.
6
+ *
7
+ * Sidebar tokens (--theme-bg, --theme-sidebar-*) are part of the contract but
8
+ * intentionally have no :root defaults: hosts supply per-site fallbacks at the
9
+ * use sites, and a global default here would override them. */
10
+
11
+ :root {
12
+ --theme-app-bg: #ffffff;
13
+ --theme-app: #000000;
14
+ --theme-panel-bg: #ffffff;
15
+ --theme-panel: #000000;
16
+ --theme-muted-panel-bg: #f8f9fa;
17
+ --theme-muted-panel-color: #6c757d;
18
+ --theme-muted-text-color: #6c757d;
19
+ --theme-border: #d1d5db;
20
+ --theme-element: #06354f;
21
+ --theme-element-text: #ffffff;
22
+ --theme-hover: #f3f4f6;
23
+ --theme-hover-text: #000000;
24
+ --theme-link: #428bca;
25
+ --theme-input-bg: #f9fafb;
26
+ --theme-input: #3b82f6;
27
+ --theme-input-disabled-bg: #f3f4f6;
28
+ --theme-input-disabled-text: #9ca3af;
29
+ --theme-card-bg: #ffffff;
30
+ --theme-card-border: rgba(0, 0, 0, 0.04);
31
+ --theme-card-hover: #fafafa;
32
+ --theme-accent: #06354f;
33
+ --theme-accent-text: #ffffff;
34
+ --theme-focus-ring: rgba(37, 99, 235, 0.2);
35
+ --theme-hover-overlay: rgba(0, 0, 0, 0.02);
36
+ --theme-success: #16a34a;
37
+ --theme-success-muted: rgba(22, 163, 74, 0.1);
38
+ --theme-error: #dc2626;
39
+ --theme-error-muted: rgba(220, 38, 38, 0.1);
40
+ --theme-warning: #d97706;
41
+ --theme-warning-muted: rgba(217, 119, 6, 0.1);
42
+ --theme-info: #2563eb;
43
+ --theme-info-muted: rgba(37, 99, 235, 0.1);
44
+ --theme-favorite: #e11d48;
45
+ --theme-favorite-muted: rgba(225, 29, 72, 0.1);
46
+ --theme-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.04);
47
+ --theme-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.07), 0 2px 4px -2px rgba(0, 0, 0, 0.05);
48
+ --theme-shadow-lg: 0 10px 15px -3px rgba(0, 0, 0, 0.08), 0 4px 6px -4px rgba(0, 0, 0, 0.04);
49
+ }
50
+
51
+ @utility theme-element {
52
+ background-color: var(--theme-element, #06354f);
53
+ color: var(--theme-element-text, #ffffff);
54
+ }
55
+
56
+ @utility theme-app {
57
+ background-color: var(--theme-app-bg, #ffffff);
58
+ color: var(--theme-app, #000000);
59
+ }
60
+
61
+ @utility theme-panel {
62
+ background-color: var(--theme-panel-bg, #fff);
63
+ color: var(--theme-panel, #000);
64
+ }
65
+
66
+ @utility theme-muted-panel {
67
+ background-color: var(--theme-muted-panel-bg, #f8f9fa);
68
+ color: var(--theme-muted-panel-color, #6c757d);
69
+ }
70
+
71
+ @utility theme-muted-text {
72
+ color: var(--theme-muted-text-color, #6c757d);
73
+ }
74
+
75
+ @utility theme-text {
76
+ color: var(--theme-app, #000000);
77
+ }
78
+
79
+ /* Utility for theme-aware hover states */
80
+ @utility theme-hover {
81
+ transition:
82
+ background-color 0.15s ease-in-out,
83
+ color 0.15s ease-in-out;
84
+ background-color: var(--theme-hover, #f3f4f6);
85
+ color: var(--theme-hover-text, #000000);
86
+ }
87
+
88
+ /* Utility for theme-aware borders */
89
+ .theme-border {
90
+ border-color: var(--theme-border, #d1d5db);
91
+ }
92
+
93
+ .theme-hover-text {
94
+ color: var(--theme-hover-text);
95
+ }
96
+
97
+ /* Utility for theme-aware input styling */
98
+ .theme-input {
99
+ background-color: var(--theme-input-bg, #f9fafb);
100
+ border-color: var(--theme-border, #d1d5db);
101
+ color: var(--theme-app, #374151);
102
+ }
103
+
104
+ .theme-input:focus {
105
+ border-color: var(--theme-element, #3b82f6);
106
+ outline: none;
107
+ box-shadow: 0 0 0 1px var(--theme-element, #3b82f6);
108
+ }
109
+
110
+ .theme-input:disabled,
111
+ .theme-input.disabled {
112
+ cursor: not-allowed;
113
+ background-color: var(--theme-input-disabled-bg, #f3f4f6);
114
+ color: var(--theme-input-disabled-text, #9ca3af);
115
+ }
116
+
117
+ .tooltip {
118
+ color: var(--theme-muted-text-color, #6c757d);
119
+ }
120
+ .tooltip:hover {
121
+ color: var(--theme-app, #000000);
122
+ }
123
+
124
+ .config-tips .multi-line {
125
+ text-align: left !important;
126
+ }
127
+
128
+ /* Theme-aware scrollbars */
129
+ .theme-scrollbar {
130
+ scrollbar-width: thin;
131
+ scrollbar-color: var(--theme-border, #d1d5db) var(--theme-panel-bg, #ffffff);
132
+ }
133
+
134
+ .theme-scrollbar::-webkit-scrollbar {
135
+ width: 8px;
136
+ height: 8px;
137
+ }
138
+
139
+ .theme-scrollbar::-webkit-scrollbar-track {
140
+ background: var(--theme-panel-bg, #ffffff);
141
+ border-radius: 4px;
142
+ }
143
+
144
+ .theme-scrollbar::-webkit-scrollbar-thumb {
145
+ background: var(--theme-border, #d1d5db);
146
+ border-radius: 4px;
147
+ border: 1px solid var(--theme-panel-bg, #ffffff);
148
+ }
149
+
150
+ .theme-scrollbar::-webkit-scrollbar-thumb:hover {
151
+ background: var(--theme-element, #3b82f6);
152
+ }
153
+
154
+ .theme-scrollbar::-webkit-scrollbar-corner {
155
+ background: var(--theme-panel-bg, #ffffff);
156
+ }
157
+
158
+ /* Small theme-aware scrollbars */
159
+ .theme-scrollbar-small {
160
+ scrollbar-width: thin;
161
+ scrollbar-color: var(--theme-border, #d1d5db) var(--theme-panel-bg, #ffffff);
162
+ }
163
+
164
+ .theme-scrollbar-small::-webkit-scrollbar {
165
+ width: 4px;
166
+ height: 4px;
167
+ }
168
+
169
+ .theme-scrollbar-small::-webkit-scrollbar-track {
170
+ background: var(--theme-panel-bg, #ffffff);
171
+ border-radius: 2px;
172
+ }
173
+
174
+ .theme-scrollbar-small::-webkit-scrollbar-thumb {
175
+ background: var(--theme-border, #d1d5db);
176
+ border-radius: 2px;
177
+ }
178
+
179
+ .theme-scrollbar-small::-webkit-scrollbar-thumb:hover {
180
+ background: var(--theme-element, #3b82f6);
181
+ }
182
+
183
+ .theme-scrollbar-small::-webkit-scrollbar-corner {
184
+ background: var(--theme-panel-bg, #ffffff);
185
+ }
@@ -0,0 +1,2 @@
1
+ /*! tailwindcss v4.3.3 | MIT License | https://tailwindcss.com */
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-divide-x-reverse:0;--tw-border-style:solid;--tw-divide-y-reverse:0;--tw-leading:initial;--tw-font-weight:initial;--tw-tracking:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000}}}@layer theme{:root,:host{--font-sans:-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-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-red-100:oklch(93.6% .032 17.717);--color-red-400:oklch(70.4% .191 22.216);--color-red-500:oklch(63.7% .237 25.331);--color-red-600:oklch(57.7% .245 27.325);--color-red-700:oklch(50.5% .213 27.518);--color-orange-100:oklch(95.4% .038 75.164);--color-orange-500:oklch(70.5% .213 47.604);--color-orange-700:oklch(55.3% .195 38.402);--color-amber-500:oklch(76.9% .188 70.08);--color-yellow-500:oklch(79.5% .184 86.047);--color-yellow-700:oklch(55.4% .135 66.442);--color-green-500:oklch(72.3% .219 149.579);--color-emerald-500:oklch(69.6% .17 162.48);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-700:oklch(48.8% .243 264.376);--color-gray-500:oklch(55.1% .027 264.364);--color-white:#fff;--spacing:.25rem;--container-xs:20rem;--container-lg:32rem;--container-2xl:42rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--font-weight-light:300;--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--tracking-wider:.05em;--radius-md:.375rem;--radius-lg:.5rem;--radius-2xl:1rem;--animate-spin:spin 1s linear infinite;--animate-ping:ping 1s cubic-bezier(0, 0, .2, 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;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{.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:0}.z-50{z-index:50}.z-250{z-index:250}.z-\[10000\]{z-index:10000}.col-span-1{grid-column:span 1/span 1}.col-span-4{grid-column:span 4/span 4}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.my-4{margin-block:calc(var(--spacing) * 4)}.mt-2{margin-top:calc(var(--spacing) * 2)}.mt-4{margin-top:calc(var(--spacing) * 4)}.mt-5{margin-top:calc(var(--spacing) * 5)}.mr-4{margin-right:calc(var(--spacing) * 4)}.mb-1{margin-bottom:var(--spacing)}.mb-3{margin-bottom:calc(var(--spacing) * 3)}.flex{display:flex}.grid{display:grid}.hidden{display:none}.inline-block{display:inline-block}.inline-flex{display:inline-flex}.table{display:table}.h-2{height:calc(var(--spacing) * 2)}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.h-10{height:calc(var(--spacing) * 10)}.h-32{height:calc(var(--spacing) * 32)}.h-\[18px\]{height:18px}.h-full{height:100%}.max-h-full{max-height:100%}.w-2{width:calc(var(--spacing) * 2)}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-10{width:calc(var(--spacing) * 10)}.w-full{width:100%}.w-screen{width:100vw}.max-w-2xl{max-width:var(--container-2xl)}.max-w-lg{max-width:var(--container-lg)}.max-w-xs{max-width:var(--container-xs)}.min-w-0{min-width:0}.min-w-\[18px\]{min-width:18px}.min-w-full{min-width:100%}.animate-ping{animation:var(--animate-ping)}.animate-spin{animation:var(--animate-spin)}.cursor-pointer{cursor:pointer}.cursor-wait{cursor:wait}.grid-flow-row-dense{grid-auto-flow:dense}.grid-cols-1{grid-template-columns:repeat(1,minmax(0,1fr))}.grid-cols-2{grid-template-columns:repeat(2,minmax(0,1fr))}.grid-cols-5{grid-template-columns:repeat(5,minmax(0,1fr))}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.justify-center{justify-content:center}.gap-1{gap:var(--spacing)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-2{gap:calc(var(--spacing) * 2)}.gap-3{gap:calc(var(--spacing) * 3)}.gap-x-4{column-gap:calc(var(--spacing) * 4)}.gap-y-0\.5{row-gap:calc(var(--spacing) * .5)}.gap-y-1{row-gap:var(--spacing)}:where(.divide-x>:not(:last-child)){--tw-divide-x-reverse:0;border-inline-style:var(--tw-border-style);border-inline-start-width:calc(1px * var(--tw-divide-x-reverse));border-inline-end-width:calc(1px * calc(1 - var(--tw-divide-x-reverse)))}:where(.divide-y>:not(:last-child)){--tw-divide-y-reverse:0;border-bottom-style:var(--tw-border-style);border-top-style:var(--tw-border-style);border-top-width:calc(1px * var(--tw-divide-y-reverse));border-bottom-width:calc(1px * calc(1 - var(--tw-divide-y-reverse)))}.self-center{align-self:center}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-auto{overflow:auto}.overflow-hidden{overflow:hidden}.overflow-x-auto{overflow-x:auto}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-2xl{border-radius:var(--radius-2xl)}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-t-2xl{border-top-left-radius:var(--radius-2xl);border-top-right-radius:var(--radius-2xl)}.rounded-b{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.rounded-b-2xl{border-bottom-right-radius:var(--radius-2xl);border-bottom-left-radius:var(--radius-2xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t-4{border-top-style:var(--tw-border-style);border-top-width:4px}.border-solid{--tw-border-style:solid;border-style:solid}.border-\(--theme-border\){border-color:var(--theme-border)}.border-\(--theme-border\,\#d1d5db\){border-color:var(--theme-border,#d1d5db)}.border-amber-500\/20{border-color:#f99c0033}@supports (color:color-mix(in lab, red, red)){.border-amber-500\/20{border-color:color-mix(in oklab, var(--color-amber-500) 20%, transparent)}}.border-blue-500{border-color:var(--color-blue-500)}.border-blue-500\/20{border-color:#3080ff33}@supports (color:color-mix(in lab, red, red)){.border-blue-500\/20{border-color:color-mix(in oklab, var(--color-blue-500) 20%, transparent)}}.border-emerald-500\/20{border-color:#00bb7f33}@supports (color:color-mix(in lab, red, red)){.border-emerald-500\/20{border-color:color-mix(in oklab, var(--color-emerald-500) 20%, transparent)}}.border-orange-500{border-color:var(--color-orange-500)}.border-red-500{border-color:var(--color-red-500)}.border-red-500\/20{border-color:#fb2c3633}@supports (color:color-mix(in lab, red, red)){.border-red-500\/20{border-color:color-mix(in oklab, var(--color-red-500) 20%, transparent)}}.border-white\/30{border-color:#ffffff4d}@supports (color:color-mix(in lab, red, red)){.border-white\/30{border-color:color-mix(in oklab, var(--color-white) 30%, transparent)}}.theme-muted-panel{background-color:var(--theme-muted-panel-bg,#f8f9fa);color:var(--theme-muted-panel-color,#6c757d)}.theme-panel{background-color:var(--theme-panel-bg,#fff);color:var(--theme-panel,#000)}.bg-\(--theme-app\){background-color:var(--theme-app)}.bg-\(--theme-element\,\#06354f\){background-color:var(--theme-element,#06354f)}.bg-\(--theme-muted-panel-bg\),.bg-\(--theme-muted-panel-bg\)\/50{background-color:var(--theme-muted-panel-bg)}@supports (color:color-mix(in lab, red, red)){.bg-\(--theme-muted-panel-bg\)\/50{background-color:color-mix(in oklab, var(--theme-muted-panel-bg) 50%, transparent)}}.bg-\(--theme-muted-text-color\){background-color:var(--theme-muted-text-color)}.bg-\(--theme-panel-bg\,\#ffffff\){background-color:var(--theme-panel-bg,#fff)}.bg-amber-500{background-color:var(--color-amber-500)}.bg-amber-500\/10{background-color:#f99c001a}@supports (color:color-mix(in lab, red, red)){.bg-amber-500\/10{background-color:color-mix(in oklab, var(--color-amber-500) 10%, transparent)}}.bg-blue-100{background-color:var(--color-blue-100)}.bg-blue-500{background-color:var(--color-blue-500)}.bg-blue-500\/10{background-color:#3080ff1a}@supports (color:color-mix(in lab, red, red)){.bg-blue-500\/10{background-color:color-mix(in oklab, var(--color-blue-500) 10%, transparent)}}.bg-emerald-500{background-color:var(--color-emerald-500)}.bg-emerald-500\/10{background-color:#00bb7f1a}@supports (color:color-mix(in lab, red, red)){.bg-emerald-500\/10{background-color:color-mix(in oklab, var(--color-emerald-500) 10%, transparent)}}.bg-gray-500\/75{background-color:#6a7282bf}@supports (color:color-mix(in lab, red, red)){.bg-gray-500\/75{background-color:color-mix(in oklab, var(--color-gray-500) 75%, transparent)}}.bg-orange-100{background-color:var(--color-orange-100)}.bg-red-100{background-color:var(--color-red-100)}.bg-red-500{background-color:var(--color-red-500)}.bg-red-500\/10{background-color:#fb2c361a}@supports (color:color-mix(in lab, red, red)){.bg-red-500\/10{background-color:color-mix(in oklab, var(--color-red-500) 10%, transparent)}}.bg-red-600{background-color:var(--color-red-600)}.bg-white\/10{background-color:#ffffff1a}@supports (color:color-mix(in lab, red, red)){.bg-white\/10{background-color:color-mix(in oklab, var(--color-white) 10%, transparent)}}.bg-yellow-500{background-color:var(--color-yellow-500)}.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-3{padding-block:calc(var(--spacing) * 3)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-12{padding-block:calc(var(--spacing) * 12)}.pt-5{padding-top:calc(var(--spacing) * 5)}.pr-2{padding-right:calc(var(--spacing) * 2)}.pb-1{padding-bottom:var(--spacing)}.pb-4{padding-bottom:calc(var(--spacing) * 4)}.text-center{text-align:center}.text-left{text-align:left}.align-bottom{vertical-align:bottom}.align-middle{vertical-align:middle}.font-sans{font-family:var(--font-sans)}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-sm\/6{font-size:var(--text-sm);line-height:calc(var(--spacing) * 6)}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.text-\[11px\]{font-size:11px}.leading-6{--tw-leading:calc(var(--spacing) * 6);line-height:calc(var(--spacing) * 6)}.leading-none{--tw-leading:1;line-height:1}.font-light{--tw-font-weight:var(--font-weight-light);font-weight:var(--font-weight-light)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-wider{--tw-tracking:var(--tracking-wider);letter-spacing:var(--tracking-wider)}.break-words{overflow-wrap:break-word}.whitespace-nowrap{white-space:nowrap}.text-\(--theme-app\){color:var(--theme-app)}.text-\(--theme-element\,\#3b82f6\){color:var(--theme-element,#3b82f6)}.text-\(--theme-element-text\,\#ffffff\){color:var(--theme-element-text,#fff)}.text-\(--theme-muted-text-color\){color:var(--theme-muted-text-color)}.text-\(--theme-panel\,\#000000\){color:var(--theme-panel,#000)}.text-amber-500{color:var(--color-amber-500)}.text-blue-500{color:var(--color-blue-500)}.text-blue-700{color:var(--color-blue-700)}.text-emerald-500{color:var(--color-emerald-500)}.text-green-500{color:var(--color-green-500)}.text-orange-700{color:var(--color-orange-700)}.text-red-400{color:var(--color-red-400)}.text-red-500{color:var(--color-red-500)}.text-red-700{color:var(--color-red-700)}.text-white{color:var(--color-white)}.theme-muted-text{color:var(--theme-muted-text-color,#6c757d)}.normal-case{text-transform:none}.uppercase{text-transform:uppercase}.italic{font-style:italic}.underline{text-decoration-line:underline}.opacity-60{opacity:.6}.opacity-75{opacity:.75}.shadow-md{--tw-shadow:0 4px 6px -1px var(--tw-shadow-color,#0000001a), 0 2px 4px -2px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.shadow-xl{--tw-shadow:0 20px 25px -5px var(--tw-shadow-color,#0000001a), 0 8px 10px -6px 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)}.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))}:is(.\*\:pb-0\.5>*){padding-bottom:calc(var(--spacing) * .5)}:is(.\*\:not-last-of-type\:border-b-1>*):not(:last-of-type){border-bottom-style:var(--tw-border-style);border-bottom-width:1px}@media (hover:hover){.hover\:bg-\(--theme-hover\,\#f3f4f6\):hover{background-color:var(--theme-hover,#f3f4f6)}.hover\:bg-red-700:hover{background-color:var(--color-red-700)}.hover\:bg-yellow-700:hover{background-color:var(--color-yellow-700)}.hover\:opacity-80:hover{opacity:.8}.hover\:opacity-90:hover{opacity:.9}}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}@media (min-width:40rem){.sm\:my-8{margin-block:calc(var(--spacing) * 8)}.sm\:mt-6{margin-top:calc(var(--spacing) * 6)}.sm\:w-full{width:100%}.sm\:max-w-lg{max-width:var(--container-lg)}.sm\:p-6{padding:calc(var(--spacing) * 6)}.sm\:align-middle{vertical-align:middle}}}:root{--theme-app-bg:#fff;--theme-app:#000;--theme-panel-bg:#fff;--theme-panel:#000;--theme-muted-panel-bg:#f8f9fa;--theme-muted-panel-color:#6c757d;--theme-muted-text-color:#6c757d;--theme-border:#d1d5db;--theme-element:#06354f;--theme-element-text:#fff;--theme-hover:#f3f4f6;--theme-hover-text:#000;--theme-link:#428bca;--theme-input-bg:#f9fafb;--theme-input:#3b82f6;--theme-input-disabled-bg:#f3f4f6;--theme-input-disabled-text:#9ca3af;--theme-card-bg:#fff;--theme-card-border:#0000000a;--theme-card-hover:#fafafa;--theme-accent:#06354f;--theme-accent-text:#fff;--theme-focus-ring:#2563eb33;--theme-hover-overlay:#00000005;--theme-success:#16a34a;--theme-success-muted:#16a34a1a;--theme-error:#dc2626;--theme-error-muted:#dc26261a;--theme-warning:#d97706;--theme-warning-muted:#d977061a;--theme-info:#2563eb;--theme-info-muted:#2563eb1a;--theme-favorite:#e11d48;--theme-favorite-muted:#e11d481a;--theme-shadow-sm:0 1px 2px #0000000a;--theme-shadow:0 4px 6px -1px #00000012, 0 2px 4px -2px #0000000d;--theme-shadow-lg:0 10px 15px -3px #00000014, 0 4px 6px -4px #0000000a}.theme-border{border-color:var(--theme-border,#d1d5db)}.theme-hover-text{color:var(--theme-hover-text)}.theme-input{background-color:var(--theme-input-bg,#f9fafb);border-color:var(--theme-border,#d1d5db);color:var(--theme-app,#374151)}.theme-input:focus{border-color:var(--theme-element,#3b82f6);box-shadow:0 0 0 1px var(--theme-element,#3b82f6);outline:none}.theme-input:disabled,.theme-input.disabled{cursor:not-allowed;background-color:var(--theme-input-disabled-bg,#f3f4f6);color:var(--theme-input-disabled-text,#9ca3af)}.tooltip{color:var(--theme-muted-text-color,#6c757d)}.tooltip:hover{color:var(--theme-app,#000)}.config-tips .multi-line{text-align:left!important}.theme-scrollbar{scrollbar-width:thin;scrollbar-color:var(--theme-border,#d1d5db) var(--theme-panel-bg,#fff)}.theme-scrollbar::-webkit-scrollbar{width:8px;height:8px}.theme-scrollbar::-webkit-scrollbar-track{background:var(--theme-panel-bg,#fff);border-radius:4px}.theme-scrollbar::-webkit-scrollbar-thumb{background:var(--theme-border,#d1d5db);border:1px solid var(--theme-panel-bg,#fff);border-radius:4px}.theme-scrollbar::-webkit-scrollbar-thumb:hover{background:var(--theme-element,#3b82f6)}.theme-scrollbar::-webkit-scrollbar-corner{background:var(--theme-panel-bg,#fff)}.theme-scrollbar-small{scrollbar-width:thin;scrollbar-color:var(--theme-border,#d1d5db) var(--theme-panel-bg,#fff)}.theme-scrollbar-small::-webkit-scrollbar{width:4px;height:4px}.theme-scrollbar-small::-webkit-scrollbar-track{background:var(--theme-panel-bg,#fff);border-radius:2px}.theme-scrollbar-small::-webkit-scrollbar-thumb{background:var(--theme-border,#d1d5db);border-radius:2px}.theme-scrollbar-small::-webkit-scrollbar-thumb:hover{background:var(--theme-element,#3b82f6)}.theme-scrollbar-small::-webkit-scrollbar-corner{background:var(--theme-panel-bg,#fff)}@property --tw-divide-x-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-divide-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-tracking{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@keyframes spin{to{transform:rotate(360deg)}}@keyframes ping{75%,to{opacity:0;transform:scale(2)}}