@jini-ai/ui 0.6.12 → 0.6.15-rc.2
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/CHANGELOG.md +28 -0
- package/README.md +14 -0
- package/dist/features/admin-widgets/components/InfoTip.d.ts +3 -2
- package/dist/features/admin-widgets/components/InfoTip.hooks.d.ts +17 -2
- package/dist/features/admin-widgets/components/InfoTip.hooks.js +64 -14
- package/dist/features/admin-widgets/components/InfoTip.js +2 -2
- package/dist/features/admin-widgets/index.d.ts +1 -1
- package/dist/features/admin-widgets/index.js +1 -1
- package/dist/features/execution/react/components/AgentCliEnvFields.js +27 -8
- package/dist/features/execution/react/components/ByokProviderForm.js +16 -19
- package/dist/features/interactive-ui/interactive-ui.css +1 -1
- package/dist/features/interactive-ui/providers/shadcn/button.d.ts +8 -6
- package/dist/features/interactive-ui/providers/shadcn/button.js +5 -6
- package/dist/features/interactive-ui/providers/shadcn/card.d.ts +3 -3
- package/dist/features/interactive-ui/providers/shadcn/card.js +3 -4
- package/dist/features/interactive-ui/providers/shadcn/select.d.ts +3 -5
- package/dist/features/interactive-ui/providers/shadcn/select.js +3 -7
- package/dist/features/interactive-ui/providers/shadcn/table.d.ts +4 -5
- package/dist/features/interactive-ui/providers/shadcn/table.js +4 -9
- package/dist/features/mcp-ui/surfaces/document.d.ts +1 -1
- package/dist/features/mcp-ui/surfaces/document.js +28 -0
- package/dist/features/mcp-ui/surfaces/fields.d.ts +28 -1
- package/dist/features/mcp-ui/surfaces/fields.js +5 -1
- package/dist/features/mcp-ui/surfaces/form.js +86 -16
- package/dist/features/mcp-ui/surfaces/text-input.d.ts +3 -3
- package/dist/features/mcp-ui/surfaces/text-input.js +26 -11
- package/dist/features/media-providers/catalog.d.ts +3 -0
- package/dist/features/media-providers/catalog.js +3 -0
- package/dist/features/media-providers/react/components/MediaProviderCard.js +5 -4
- package/dist/features/media-providers/react/components/media-providers-tab-labels.js +2 -1
- package/dist/features/panel-kit/fetch-query/adapter.react.d.ts +10 -5
- package/dist/features/panel-kit/fetch-query/adapter.react.js +9 -3
- package/dist/features/panel-kit/fetch-query/binding.react.d.ts +4 -0
- package/dist/features/panel-kit/fetch-query/binding.react.js +29 -10
- package/dist/features/panel-kit/fetch-query/index.d.ts +1 -1
- package/dist/features/panel-kit/fetch-query/index.js +1 -1
- package/dist/features/panel-kit/fetch-query/tanstack.d.ts +1 -1
- package/dist/features/panel-kit/fetch-query/tanstack.js +1 -1
- package/dist/features/privacy/react/components/PrivacyTab.d.ts +1 -3
- package/dist/features/privacy/react/components/PrivacyTab.js +5 -8
- package/dist/features/resource-dashboard/react/components/ResourceBoardView.js +3 -2
- package/dist/features/resource-dashboard/react/components/ResourceBoardViewParts.d.ts +0 -2
- package/dist/features/resource-dashboard/react/components/ResourceBoardViewParts.js +0 -6
- package/dist/features/settings/dialog/styles/settings-dialog.css +5 -70
- package/dist/features/source-config-list/react/components/SourceConfigField.js +27 -26
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/react/components/SecretInput.d.ts +47 -0
- package/dist/react/components/SecretInput.hooks.d.ts +26 -0
- package/dist/react/components/SecretInput.hooks.js +25 -0
- package/dist/react/components/SecretInput.js +30 -0
- package/dist/styles/lightbox.css +1 -1
- package/dist/styles/variables.css +1 -1
- package/package.json +9 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,33 @@
|
|
|
1
1
|
# @jini-ai/ui
|
|
2
2
|
|
|
3
|
+
## 0.6.13
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 0728914: Engine guard clean-up (`pnpm guard` 106 -> 0): layer, subpath-isolation and module-state findings fixed by moving
|
|
8
|
+
shared contracts to their owners instead of reaching across domains. Additive public API: `@jini-ai/core/filesystem`
|
|
9
|
+
(guarded-reader contracts), `useFetchQueryScope` from `@jini-ai/ui` fetch-query (per-provider query scope),
|
|
10
|
+
`@jini-ai/chat/react` re-exports of the accepted-input, run-state and agent-plugin chat-state helpers. The Claude
|
|
11
|
+
filesystem probe cache in `@jini-ai/agent-runtime` is instance-owned. No behaviour change intended; host-facing
|
|
12
|
+
breaks are listed in `owner-store-to-server` and `guard-host-ports`.
|
|
13
|
+
- 0a2b903: Share accessible eye toggles across React credential fields, including multiline question answers,
|
|
14
|
+
CLI overrides, provider keys, login, new users, password resets, and source configuration. Preserve
|
|
15
|
+
autofill protection, translated toggle names, agent handles, and secret-answer redaction. Hidden
|
|
16
|
+
source environment blocks keep names visible and stored values masked until explicitly revealed.
|
|
17
|
+
|
|
18
|
+
Chat and user-management require `@jini-ai/ui ^0.5.7` for the new `SecretInput` and `SecretTextarea`
|
|
19
|
+
exports. Release UI 0.5.7 (or adjust those peer floors to the actual release containing these exports)
|
|
20
|
+
with these consumers; older UI versions cannot satisfy their imports. Hosts supply `.jini-secret`,
|
|
21
|
+
`.jini-secret-toggle`, and `.jini-secret--multiline` visual rules.
|
|
22
|
+
|
|
23
|
+
- 01de8c4: Allow the built-in fetch-query provider to accept core clock and scheduler ports while retaining existing timing defaults and provider-scoped cleanup.
|
|
24
|
+
- Updated dependencies [7479159]
|
|
25
|
+
- Updated dependencies [c31264d]
|
|
26
|
+
- Updated dependencies [0728914]
|
|
27
|
+
- Updated dependencies [6ecbdb2]
|
|
28
|
+
- Updated dependencies [63bacc5]
|
|
29
|
+
- @jini-ai/core@0.6.13
|
|
30
|
+
|
|
3
31
|
## 0.6.12
|
|
4
32
|
|
|
5
33
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -478,6 +478,20 @@ Fetch-query caches accept the shared `Clock` from `@jini-ai/core/primitives` thr
|
|
|
478
478
|
by default and idle retention five minutes. Browser HTTP defaults now use injected
|
|
479
479
|
native fetch ports and have no platform imports.
|
|
480
480
|
|
|
481
|
+
The built-in `@jini-ai/ui/fetch-query` provider accepts those same optional ports:
|
|
482
|
+
|
|
483
|
+
```tsx
|
|
484
|
+
<FetchQueryProvider environment={environment} clock={clock} scheduler={scheduler}>
|
|
485
|
+
<Records />
|
|
486
|
+
</FetchQueryProvider>
|
|
487
|
+
```
|
|
488
|
+
|
|
489
|
+
`clock.nowMs()` controls cache timestamps and freshness. The scheduler's
|
|
490
|
+
`schedule({ callback, delayMs })` returns a handle; `cancel({ handle })` releases it.
|
|
491
|
+
Omitted ports retain real-clock/native-timer defaults. Keep the injected objects stable:
|
|
492
|
+
replacing `environment`, `clock` or `scheduler` recreates the cache and disposes the previous
|
|
493
|
+
scope's timers and subscriptions. Timing injection applies only to the built-in provider.
|
|
494
|
+
|
|
481
495
|
The A2UI interpreter uses that same core `Clock` with `nowMs()`; import the clock type
|
|
482
496
|
directly from `@jini-ai/core/primitives`. The obsolete `A2uiClockPort` re-export is removed.
|
|
483
497
|
Create the basic catalog with `createLabCatalog({})` and inject it through
|
|
@@ -10,8 +10,9 @@ import { useInfoTip } from "./InfoTip.hooks.js";
|
|
|
10
10
|
* preference, with the hook's headroom guard choosing below near the viewport's top; near a side
|
|
11
11
|
* edge (or a host panel marked `data-jini-tip-bounds`) it shifts by its real width, never squeezes.
|
|
12
12
|
* Keep state and DOM measurement in the injectable hook so rendering can use fixed fake state.
|
|
13
|
-
* Touch has no hover, so a tap
|
|
14
|
-
*
|
|
13
|
+
* Touch has no hover, so a tap pins the tip open until a second tap, an outside tap, blur, Escape
|
|
14
|
+
* or a 2.5 s timeout; Enter/Space pin it without the timeout. A hover- or mouse-click-opened tip
|
|
15
|
+
* closes when the pointer leaves, and only one tip is open at a time.
|
|
15
16
|
*/
|
|
16
17
|
export interface InfoTipProps {
|
|
17
18
|
/** The explanation the bubble shows; newlines separate lines, and "• " lines show as a hanging list. */
|
|
@@ -3,6 +3,16 @@ import { type KeyboardEvent } from "react";
|
|
|
3
3
|
* measurement, so another async dependency/port layer would provide no rejection seam to test. */
|
|
4
4
|
/** Hosts mark a panel (e.g. an assistant dock) with this attribute to keep tips inside it. */
|
|
5
5
|
export declare const TIP_BOUNDS_ATTRIBUTE = "data-jini-tip-bounds";
|
|
6
|
+
/** How long a tap-opened tip stays up on its own; touch has no pointer-leave to close it. */
|
|
7
|
+
export declare const TAP_TIP_MS = 2500;
|
|
8
|
+
/**
|
|
9
|
+
* Makes `close` the one open tip, closing whichever tip held that slot before. Hosts with their own
|
|
10
|
+
* tip state (e.g. a dock-header tip) can call it too, to join the same one-open rule.
|
|
11
|
+
* @param close Closes the claiming tip; identity must stay stable while it is open.
|
|
12
|
+
* @returns A release that empties the slot only if `close` still holds it.
|
|
13
|
+
* @complexity O(1).
|
|
14
|
+
*/
|
|
15
|
+
export declare function claimOpenTip(close: () => void): () => void;
|
|
6
16
|
export interface InfoTipController {
|
|
7
17
|
open: boolean;
|
|
8
18
|
placement: "above" | "below";
|
|
@@ -21,9 +31,14 @@ export interface InfoTipController {
|
|
|
21
31
|
hide: () => void;
|
|
22
32
|
/** Pointer left the icon: closes only a hover-opened tip, never one the operator tapped open. */
|
|
23
33
|
leave: () => void;
|
|
24
|
-
/** Tap/
|
|
25
|
-
*
|
|
34
|
+
/** Tap/Enter/Space: pins an open tip so it survives the pointer leaving (touch has no hover to
|
|
35
|
+
* keep it up), or closes a pinned one. Hover and mouse clicks never pin. */
|
|
26
36
|
toggle: () => void;
|
|
37
|
+
/** Records the pointer type of the press a following click comes from; optional for injected
|
|
38
|
+
* controllers. */
|
|
39
|
+
pointerDown?: (e: {
|
|
40
|
+
pointerType: string;
|
|
41
|
+
}) => void;
|
|
27
42
|
/** Escape closes in place; Enter/Space toggle like a button; blur covers Tab/Shift+Tab. */
|
|
28
43
|
handleIconKeyDown: (e: KeyboardEvent<HTMLSpanElement>) => void;
|
|
29
44
|
}
|
|
@@ -5,6 +5,27 @@ import { placeInfoTipBubble } from "./InfoTip.rules.js";
|
|
|
5
5
|
* measurement, so another async dependency/port layer would provide no rejection seam to test. */
|
|
6
6
|
/** Hosts mark a panel (e.g. an assistant dock) with this attribute to keep tips inside it. */
|
|
7
7
|
export const TIP_BOUNDS_ATTRIBUTE = "data-jini-tip-bounds";
|
|
8
|
+
/** How long a tap-opened tip stays up on its own; touch has no pointer-leave to close it. */
|
|
9
|
+
export const TAP_TIP_MS = 2500;
|
|
10
|
+
/** The close of the one tip open app-wide. A pinned or focused tip used to stay up beside the one
|
|
11
|
+
* the pointer had just reached (owner, 2026-10-25: two "Soon" tips open at once). */
|
|
12
|
+
let closeOpenTip = null;
|
|
13
|
+
/**
|
|
14
|
+
* Makes `close` the one open tip, closing whichever tip held that slot before. Hosts with their own
|
|
15
|
+
* tip state (e.g. a dock-header tip) can call it too, to join the same one-open rule.
|
|
16
|
+
* @param close Closes the claiming tip; identity must stay stable while it is open.
|
|
17
|
+
* @returns A release that empties the slot only if `close` still holds it.
|
|
18
|
+
* @complexity O(1).
|
|
19
|
+
*/
|
|
20
|
+
export function claimOpenTip(close) {
|
|
21
|
+
if (closeOpenTip && closeOpenTip !== close)
|
|
22
|
+
closeOpenTip();
|
|
23
|
+
closeOpenTip = close;
|
|
24
|
+
return () => {
|
|
25
|
+
if (closeOpenTip === close)
|
|
26
|
+
closeOpenTip = null;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
8
29
|
/** Prefer a host's placement when the measured bubble fits; default preserves automatic flipping.
|
|
9
30
|
* @complexity Time/space: O(1), with one icon and one bubble measurement.
|
|
10
31
|
*/
|
|
@@ -12,9 +33,16 @@ export function useInfoTip(_input = {}, { placement: preferredPlacement } = {})
|
|
|
12
33
|
const [open, setOpen] = useState(false);
|
|
13
34
|
const [placement, setPlacement] = useState("above");
|
|
14
35
|
const [coords, setCoords] = useState({ top: 0, left: 0 });
|
|
36
|
+
// "tap" pins auto-hide; "key" (Enter/Space) pins stay until blur or Escape.
|
|
15
37
|
const [pinned, setPinned] = useState(false);
|
|
16
38
|
const iconRef = useRef(null);
|
|
17
39
|
const bubbleRef = useRef(null);
|
|
40
|
+
const pointerTypeRef = useRef(null);
|
|
41
|
+
// Stable identity for the one-open-tip slot; state setters never change.
|
|
42
|
+
const hide = useRef(() => {
|
|
43
|
+
setOpen(false);
|
|
44
|
+
setPinned(false);
|
|
45
|
+
}).current;
|
|
18
46
|
// Placement math lives in `placeInfoTipBubble`; this only gathers the measurements. Before the
|
|
19
47
|
// portal exists the bubble is unmeasured and the rules assume the worst-case width.
|
|
20
48
|
const place = () => {
|
|
@@ -43,36 +71,58 @@ export function useInfoTip(_input = {}, { placement: preferredPlacement } = {})
|
|
|
43
71
|
if (open)
|
|
44
72
|
place();
|
|
45
73
|
}, [open, preferredPlacement]);
|
|
46
|
-
const hide = () => {
|
|
47
|
-
setOpen(false);
|
|
48
|
-
setPinned(false);
|
|
49
|
-
};
|
|
50
74
|
const leave = () => {
|
|
51
75
|
if (!pinned)
|
|
52
76
|
setOpen(false);
|
|
53
77
|
};
|
|
78
|
+
const pointerDown = (e) => {
|
|
79
|
+
pointerTypeRef.current = e.pointerType;
|
|
80
|
+
};
|
|
54
81
|
const toggle = () => {
|
|
82
|
+
const via = pointerTypeRef.current;
|
|
83
|
+
pointerTypeRef.current = null;
|
|
55
84
|
if (open && pinned) {
|
|
56
85
|
hide();
|
|
57
86
|
return;
|
|
58
87
|
}
|
|
59
88
|
show();
|
|
60
|
-
|
|
89
|
+
// A mouse already has hover to hold the tip up; pinning on a mouse click is what left tips
|
|
90
|
+
// stuck open after the pointer moved on. No pointer press means Enter/Space.
|
|
91
|
+
if (via !== "mouse")
|
|
92
|
+
setPinned(via ? "tap" : "key");
|
|
61
93
|
};
|
|
62
|
-
// A tapped-open tip stays up until the operator taps elsewhere; the bubble itself is
|
|
63
|
-
// pointer-events:none, so "outside the icon" is every other target.
|
|
64
|
-
useDismissOnOutsideOrEscape({ onDismiss: hide }, { enabled: pinned, containerRef: iconRef });
|
|
65
|
-
// The bubble is position:fixed at measured viewport coordinates, so a scroll while it is open
|
|
66
|
-
// would leave it floating over the wrong content. Re-measure instead of closing: a pinned tip
|
|
67
|
-
// the operator is reading should follow its icon.
|
|
68
94
|
useEffect(() => {
|
|
69
95
|
if (!open)
|
|
70
96
|
return;
|
|
97
|
+
return claimOpenTip(hide);
|
|
98
|
+
}, [open]);
|
|
99
|
+
// A tapped-open tip stays up until the operator taps elsewhere or it times out; the bubble
|
|
100
|
+
// itself is pointer-events:none, so "outside the icon" is every other target.
|
|
101
|
+
useDismissOnOutsideOrEscape({ onDismiss: hide }, { enabled: pinned !== false, containerRef: iconRef });
|
|
102
|
+
useEffect(() => {
|
|
103
|
+
if (pinned !== "tap")
|
|
104
|
+
return;
|
|
105
|
+
const timer = setTimeout(hide, TAP_TIP_MS);
|
|
106
|
+
return () => clearTimeout(timer);
|
|
107
|
+
}, [pinned]);
|
|
108
|
+
// The bubble is position:fixed at measured viewport coordinates, so a scroll that moves the icon
|
|
109
|
+
// would leave it floating over the wrong content, and the pointer has usually left the icon
|
|
110
|
+
// without a mouseleave firing yet: close it. A scroll in an unrelated pane (a streaming chat)
|
|
111
|
+
// leaves it be. A resize re-measures instead, so it keeps following its icon.
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (!open)
|
|
114
|
+
return;
|
|
115
|
+
const closeIfMoved = (e) => {
|
|
116
|
+
const icon = iconRef.current;
|
|
117
|
+
if (icon && e.target instanceof Node && !e.target.contains(icon))
|
|
118
|
+
return;
|
|
119
|
+
hide();
|
|
120
|
+
};
|
|
71
121
|
const follow = () => show();
|
|
72
|
-
window.addEventListener("scroll",
|
|
122
|
+
window.addEventListener("scroll", closeIfMoved, true);
|
|
73
123
|
window.addEventListener("resize", follow);
|
|
74
124
|
return () => {
|
|
75
|
-
window.removeEventListener("scroll",
|
|
125
|
+
window.removeEventListener("scroll", closeIfMoved, true);
|
|
76
126
|
window.removeEventListener("resize", follow);
|
|
77
127
|
};
|
|
78
128
|
}, [open]);
|
|
@@ -89,6 +139,6 @@ export function useInfoTip(_input = {}, { placement: preferredPlacement } = {})
|
|
|
89
139
|
toggle();
|
|
90
140
|
}
|
|
91
141
|
}
|
|
92
|
-
return { open, placement, coords, iconRef, bubbleRef, show, hide, leave, toggle, handleIconKeyDown };
|
|
142
|
+
return { open, placement, coords, iconRef, bubbleRef, show, hide, leave, toggle, pointerDown, handleIconKeyDown };
|
|
93
143
|
}
|
|
94
144
|
//# sourceMappingURL=InfoTip.hooks.js.map
|
|
@@ -7,10 +7,10 @@ import { infoTipBubbleStyle, infoTipLines } from "./InfoTip.rules.js";
|
|
|
7
7
|
/** Focus/hover tooltip that portals outside clipping ancestors; Escape dismisses in place. */
|
|
8
8
|
export function InfoTip({ label, triggerLabel, descriptionId, placement: preferredPlacement, useTip = useInfoTip, agentHandle: handle, icon }) {
|
|
9
9
|
const inline = preferredPlacement === "inline";
|
|
10
|
-
const { open, placement, coords, iconRef, bubbleRef, show, hide, leave, toggle, handleIconKeyDown } = useTip({}, { placement: inline ? undefined : preferredPlacement });
|
|
10
|
+
const { open, placement, coords, iconRef, bubbleRef, show, hide, leave, toggle, pointerDown, handleIconKeyDown } = useTip({}, { placement: inline ? undefined : preferredPlacement });
|
|
11
11
|
const autoId = useId();
|
|
12
12
|
const { name, textId, describedBy } = infoTipNaming({ label, autoId }, { triggerLabel, descriptionId });
|
|
13
|
-
return (_jsxs("span", { className: inline ? "info-tip info-tip--inline" : "info-tip", children: [_jsx("span", { ref: iconRef, className: icon ? "info-tip-icon info-tip-icon--custom" : "info-tip-icon", role: "button", tabIndex: 0, "aria-label": name, "aria-expanded": open, ...(describedBy ? { "aria-describedby": describedBy } : {}), onMouseEnter: show, onMouseLeave: leave, onFocus: show, onBlur: hide, onClick: toggle, onKeyDown: handleIconKeyDown, ...(handle ? agentHandle({ handle }, { role: "button", label: name }) : {}), children: icon ?? "ⓘ" }), textId ? _jsx("span", { id: textId, hidden: true, children: label }) : null, open ? _jsx(InfoTipOpenCopy, { label: label, inline: inline, placement: placement, coords: coords, iconRef: iconRef, bubbleRef: bubbleRef }) : null] }));
|
|
13
|
+
return (_jsxs("span", { className: inline ? "info-tip info-tip--inline" : "info-tip", children: [_jsx("span", { ref: iconRef, className: icon ? "info-tip-icon info-tip-icon--custom" : "info-tip-icon", role: "button", tabIndex: 0, "aria-label": name, "aria-expanded": open, ...(describedBy ? { "aria-describedby": describedBy } : {}), onMouseEnter: show, onMouseLeave: leave, onFocus: show, onBlur: hide, onPointerDown: pointerDown, onClick: toggle, onKeyDown: handleIconKeyDown, ...(handle ? agentHandle({ handle }, { role: "button", label: name }) : {}), children: icon ?? "ⓘ" }), textId ? _jsx("span", { id: textId, hidden: true, children: label }) : null, open ? _jsx(InfoTipOpenCopy, { label: label, inline: inline, placement: placement, coords: coords, iconRef: iconRef, bubbleRef: bubbleRef }) : null] }));
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
16
|
* The icon's accessible name and the id of the hidden copy of `label` (if any).
|
|
@@ -6,7 +6,7 @@ export { InfoTip } from './components/InfoTip.js';
|
|
|
6
6
|
export type { InfoTipProps } from './components/InfoTip.js';
|
|
7
7
|
export { useInfoTip } from './components/InfoTip.hooks.js';
|
|
8
8
|
export type { InfoTipController } from './components/InfoTip.hooks.js';
|
|
9
|
-
export { TIP_BOUNDS_ATTRIBUTE } from './components/InfoTip.hooks.js';
|
|
9
|
+
export { TIP_BOUNDS_ATTRIBUTE, TAP_TIP_MS, claimOpenTip } from './components/InfoTip.hooks.js';
|
|
10
10
|
export { placeInfoTipBubble, infoTipBubbleStyle } from './components/InfoTip.rules.js';
|
|
11
11
|
export type { InfoTipPlacement } from './components/InfoTip.rules.js';
|
|
12
12
|
export { SeeMore, resolveSeeMoreView } from './components/SeeMore/SeeMore.js';
|
|
@@ -2,7 +2,7 @@ export { Select, resolveSelectTriggerLabel } from './components/Select/Select.js
|
|
|
2
2
|
export { useSelectDropdown, usePanelPosition } from './components/Select/Select.hooks.js';
|
|
3
3
|
export { InfoTip } from './components/InfoTip.js';
|
|
4
4
|
export { useInfoTip } from './components/InfoTip.hooks.js';
|
|
5
|
-
export { TIP_BOUNDS_ATTRIBUTE } from './components/InfoTip.hooks.js';
|
|
5
|
+
export { TIP_BOUNDS_ATTRIBUTE, TAP_TIP_MS, claimOpenTip } from './components/InfoTip.hooks.js';
|
|
6
6
|
export { placeInfoTipBubble, infoTipBubbleStyle } from './components/InfoTip.rules.js';
|
|
7
7
|
export { SeeMore, resolveSeeMoreView } from './components/SeeMore/SeeMore.js';
|
|
8
8
|
export { useSeeMoreClamp } from './components/SeeMore/SeeMore.hooks.js';
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useId } from 'react';
|
|
2
3
|
import { useT } from '../../../i18n/index.js';
|
|
4
|
+
import { SecretInput } from '../../../../react/components/SecretInput.js';
|
|
3
5
|
import { agentCliEnvValue, cliEnvFieldsForAgent } from '../../rules.js';
|
|
4
6
|
/**
|
|
5
7
|
* Per-agent CLI environment overrides — proxy URLs, custom config
|
|
@@ -17,16 +19,33 @@ import { agentCliEnvValue, cliEnvFieldsForAgent } from '../../rules.js';
|
|
|
17
19
|
*/
|
|
18
20
|
export function AgentCliEnvFields({ agentId, fields, config, onChange }) {
|
|
19
21
|
const t = useT();
|
|
22
|
+
const idBase = useId();
|
|
20
23
|
const relevant = cliEnvFieldsForAgent(fields, agentId);
|
|
21
24
|
if (relevant.length === 0)
|
|
22
25
|
return null;
|
|
23
|
-
return (_jsxs("details", { className: "jini-agent-cli-env", "data-testid": `jini-agent-cli-env-${agentId}`, children: [_jsx("summary", { className: "jini-agent-cli-env-summary", children: t('Advanced: proxy & custom paths') }), _jsxs("div", { className: "jini-agent-cli-env-body", children: [_jsx("p", { className: "jini-field-hint", children: t("Environment variables passed to this CLI when it runs.") }), _jsx("div", { className: "jini-agent-cli-env-grid", children: relevant.map((field) =>
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
26
|
+
return (_jsxs("details", { className: "jini-agent-cli-env", "data-testid": `jini-agent-cli-env-${agentId}`, children: [_jsx("summary", { className: "jini-agent-cli-env-summary", children: t('Advanced: proxy & custom paths') }), _jsxs("div", { className: "jini-agent-cli-env-body", children: [_jsx("p", { className: "jini-field-hint", children: t("Environment variables passed to this CLI when it runs.") }), _jsx("div", { className: "jini-agent-cli-env-grid", children: relevant.map((field) => {
|
|
27
|
+
const id = `${idBase}-${field.envKey}`;
|
|
28
|
+
const input = {
|
|
29
|
+
id,
|
|
30
|
+
className: 'jini-input',
|
|
31
|
+
value: agentCliEnvValue(config, agentId, field.envKey),
|
|
32
|
+
placeholder: field.placeholder,
|
|
33
|
+
spellCheck: false,
|
|
34
|
+
'data-testid': `jini-agent-cli-env-${agentId}-${field.envKey}`,
|
|
35
|
+
onChange: (event) => onChange(agentId, field.envKey, event.target.value),
|
|
36
|
+
};
|
|
37
|
+
/* Per-field, because this input is both kinds at once. A `secret` field is a password
|
|
38
|
+
input, and Chrome deliberately ignores `autoComplete="off"` on credential-shaped
|
|
39
|
+
fields — the same defect fixed on `ByokProviderForm`'s API-key input; see its comment
|
|
40
|
+
for the full reasoning. A NON-secret field (a proxy URL, a config path) keeps `off`:
|
|
41
|
+
`new-password` there would invite Chrome to offer to GENERATE a password for a field
|
|
42
|
+
that holds a file path. */
|
|
43
|
+
return (
|
|
44
|
+
// A `<div>` + `<label htmlFor>`: the secret field's eye toggle must stay out of a
|
|
45
|
+
// wrapping label, or its "Show …" name would join the input's own.
|
|
46
|
+
_jsxs("div", { className: "jini-field", children: [_jsx("label", { className: "jini-field-label", htmlFor: id, children: field.label }), field.secret
|
|
47
|
+
? _jsx(SecretInput, { ...input, label: field.label, autoComplete: "new-password" })
|
|
48
|
+
: _jsx("input", { ...input, type: "text", autoComplete: "off" })] }, `${field.agentId}:${field.envKey}`));
|
|
49
|
+
}) })] })] }));
|
|
31
50
|
}
|
|
32
51
|
//# sourceMappingURL=AgentCliEnvFields.js.map
|
|
@@ -5,6 +5,7 @@ import { useT } from '../../../i18n/index.js';
|
|
|
5
5
|
import { CUSTOM_MODEL_SENTINEL } from '../../constants.js';
|
|
6
6
|
import { apiKeyFormatWarning, parseMaxTokens, presetRequiresApiKey, shouldShowCustomModelInput, showsBaseUrlField, } from '../../rules.js';
|
|
7
7
|
import { SearchableModelSelect } from './SearchableModelSelect.js';
|
|
8
|
+
import { SecretInput } from '../../../../react/components/SecretInput.js';
|
|
8
9
|
import { useByokFieldValidation } from '../hooks/use-byok-field-validation.hooks.js';
|
|
9
10
|
/** `' is-missing'` when `field` is a required field the operator still has to fill. */
|
|
10
11
|
function missingClass(validation, field) {
|
|
@@ -56,31 +57,27 @@ function ByokConnectionFields({ config, patch, preset, agentHandle, validation }
|
|
|
56
57
|
function ByokApiKeyField({ config, patch, preset, agentHandle, validation, presets, revealKey, onToggleReveal, apiKeyFooter, apiKeyPlaceholder, apiKeyActions, }) {
|
|
57
58
|
const t = useT();
|
|
58
59
|
const keyInputId = useId();
|
|
59
|
-
const KeyField = apiKeyActions ? 'div' : 'label';
|
|
60
60
|
/** Deliberately NOT folded into `missing` above: that set drives `is-missing` styling and the
|
|
61
61
|
* Test-connection disable, and a wrong-SHAPED key must never reach either. */
|
|
62
62
|
const keyFormatWarning = apiKeyFormatWarning(config, preset, presets);
|
|
63
|
-
return (_jsxs(_Fragment, { children: [_jsxs(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
63
|
+
return (_jsxs(_Fragment, { children: [_jsxs("div", { className: "jini-field", onBlurCapture: () => validation.markTouched({ field: 'apiKey' }), children: [_jsxs("span", { className: "jini-field-label", children: [_jsx(ByokApiKeyLabel, { keyInputId: keyInputId }), preset?.apiKeyConsoleUrl ? (_jsx("a", { className: "jini-field-link", href: preset.apiKeyConsoleUrl, target: "_blank", rel: "noreferrer noopener", children: t('Get key') })) : null] }), _jsx(SecretInput, { id: keyInputId, label: t('API key'), revealed: revealKey, onRevealedChange: onToggleReveal, className: 'jini-input' + missingClass(validation, 'apiKey'),
|
|
64
|
+
/* `new-password`, NOT `"off"` — Chrome deliberately ignores `off` on credential-shaped
|
|
65
|
+
fields (a long-standing intentional decision, not a bug). `off` here is what let the
|
|
66
|
+
reported autofill through: Chrome filled this field with the admin's own saved
|
|
67
|
+
PASSWORD, the form sent it, and the provider answered with its own "API key not
|
|
68
|
+
valid" — a true message about a string the operator never typed. `new-password` is
|
|
69
|
+
the value Chrome/Safari/Firefox actually honor for "this is not a saved-login
|
|
70
|
+
field", which suppresses both the credential dropdown and the silent fill.
|
|
71
|
+
|
|
72
|
+
Known trade-off, not fixed here: Chrome may now offer to GENERATE a password on
|
|
73
|
+
this field — a suggestion popup, not a silently wrong value. */
|
|
74
|
+
autoComplete: "new-password", spellCheck: false, placeholder: apiKeyPlaceholder, value: config.apiKey, onChange: (event) => patch({ apiKey: event.target.value }), toggleAttrs: agentHandleProps({}, { base: agentHandle, ...({ action: 'reveal-key', role: 'button', label: t('Reveal API key') }) }), ...agentHandleProps({}, { base: agentHandle, ...({ action: 'api-key', role: 'field', label: t('API key') }) }) }), apiKeyActions ? _jsx("span", { className: "jini-byok-key-actions", children: apiKeyActions }) : null, _jsx("span", { className: "jini-field-hint", children: t('Stored only by this host.') }), keyFormatWarning ? (_jsx("span", { className: "jini-field-hint is-error", role: "status", children: t(keyFormatWarning.message, keyFormatWarning.vars) })) : null] }), _jsx(ByokSlot, { className: "jini-byok-key-footer", children: apiKeyFooter })] }));
|
|
75
75
|
}
|
|
76
|
-
/** "API key *".
|
|
77
|
-
*
|
|
76
|
+
/** "API key *". The field is a `<div>` (the eye toggle must stay out of any wrapping label), so
|
|
77
|
+
* the name gets its own `<label>` pointing at the input by id. */
|
|
78
78
|
function ByokApiKeyLabel({ keyInputId }) {
|
|
79
79
|
const t = useT();
|
|
80
|
-
|
|
81
|
-
return (_jsxs("label", { className: "jini-field-label", htmlFor: keyInputId, children: [_jsx("span", { children: t('API key') }), _jsx("span", { className: "jini-field-required", "aria-hidden": "true", children: "*" })] }));
|
|
82
|
-
}
|
|
83
|
-
return (_jsxs(_Fragment, { children: [t('API key'), _jsx("span", { className: "jini-field-required", "aria-hidden": "true", children: "*" })] }));
|
|
80
|
+
return (_jsxs("label", { className: "jini-field-label", htmlFor: keyInputId, children: [_jsx("span", { children: t('API key') }), _jsx("span", { className: "jini-field-required", "aria-hidden": "true", children: "*" })] }));
|
|
84
81
|
}
|
|
85
82
|
/** The Model field (live picker, free-text box, or both) with "Test connection" beside it. */
|
|
86
83
|
function ByokModelRow({ config, patch, preset, agentHandle, validation, modelDiscovery, explicitCustomModel, setExplicitCustomModel, connectionTest, onTestConnection, canTestConnection, }) {
|
|
@@ -1,2 +1,2 @@
|
|
|
1
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-space-y-reverse:0;--tw-border-style:solid;--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;--tw-outline-style:solid;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}:root,[data-admin-theme],[data-color-scheme=light]{color-scheme:light;--jini-bg:var(--jini-theme-light-bg,#fff);--jini-surface:var(--jini-theme-light-surface,#f5f5f5);--jini-text:var(--jini-theme-light-text,#202020);--jini-muted:var(--jini-theme-light-muted,#666);--jini-border:var(--jini-theme-light-border,#d9d9d9);--jini-primary:var(--jini-theme-light-primary,#363636);--jini-primary-ink:var(--jini-theme-light-primary-ink,#fff);--jini-danger:var(--jini-theme-light-danger,#b42318);--jini-success:var(--jini-theme-light-success,#18763b);--jini-warning:var(--jini-theme-light-warning,#845800)}[data-color-scheme=dark]{color-scheme:dark;--jini-bg:var(--jini-theme-dark-bg,#171717);--jini-surface:var(--jini-theme-dark-surface,#242424);--jini-text:var(--jini-theme-dark-text,#f0f0f0);--jini-muted:var(--jini-theme-dark-muted,#b3b3b3);--jini-border:var(--jini-theme-dark-border,#454545);--jini-primary:var(--jini-theme-dark-primary,#e0e0e0);--jini-primary-ink:var(--jini-theme-dark-primary-ink,#202020);--jini-danger:var(--jini-theme-dark-danger,#ff8b80);--jini-success:var(--jini-theme-dark-success,#79d69b);--jini-warning:var(--jini-theme-dark-warning,#ebc36b)}:root,[data-color-scheme=light],[data-theme=light]{--jini-chart-default-1:oklch(55.29% .1129 43.4);--jini-chart-default-2:oklch(50% .11 240);--jini-chart-default-3:oklch(64% .13 88);--jini-chart-default-4:oklch(58% .15 350);--jini-chart-default-5:oklch(50% .11 155);--jini-chart-default-6:oklch(48% .12 295)}[data-color-scheme=dark],[data-theme=dark]{--jini-chart-default-1:oklch(62% .11 44);--jini-chart-default-2:oklch(64% .11 240);--jini-chart-default-3:oklch(66% .13 88);--jini-chart-default-4:oklch(65% .14 350);--jini-chart-default-5:oklch(56% .12 155);--jini-chart-default-6:oklch(64% .12 295)}:root{--jini-font-body:system-ui, sans-serif;--jini-font-heading:system-ui, sans-serif;--jini-font-mono:ui-monospace, monospace;--jini-radius:8px;--jini-density:1}:root,[data-admin-theme],[data-color-scheme]{--jini-bg-panel:var(--jini-surface);--jini-bg-subtle:var(--jini-surface)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-bg-subtle:color-mix(in srgb, var(--jini-surface) 75%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-bg-elevated:var(--jini-surface);--jini-border-soft:var(--jini-border);--jini-border-strong:var(--jini-border)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-border-strong:color-mix(in srgb, var(--jini-border) 75%, var(--jini-text))}}:root,[data-admin-theme],[data-color-scheme]{--jini-backdrop:var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-backdrop:color-mix(in srgb, var(--jini-text) 42%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-text-strong:var(--jini-text);--jini-text-secondary:var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-text-secondary:color-mix(in srgb, var(--jini-text) 80%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-text-muted:var(--jini-muted);--jini-text-faint:var(--jini-muted)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-text-faint:color-mix(in srgb, var(--jini-muted) 75%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-text-disabled:var(--jini-muted)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-text-disabled:color-mix(in srgb, var(--jini-muted) 60%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-accent:var(--jini-primary);--jini-accent-hover:var(--jini-primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-accent-hover:color-mix(in srgb, var(--jini-primary) 88%, var(--jini-text))}}:root,[data-admin-theme],[data-color-scheme]{--jini-accent-strong:var(--jini-primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-accent-strong:color-mix(in srgb, var(--jini-primary) 85%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-accent-ink:var(--jini-primary-ink);--jini-accent-soft:var(--jini-primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-accent-soft:color-mix(in srgb, var(--jini-primary) 10%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-accent-ring:var(--jini-primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-accent-ring:color-mix(in srgb, var(--jini-primary) 22%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-neutral-accent:var(--jini-text);--jini-neutral-accent-hover:var(--jini-muted);--jini-neutral-accent-ink:var(--jini-bg);--jini-neutral-accent-text:var(--jini-text);--jini-neutral-accent-soft:var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-neutral-accent-soft:color-mix(in srgb, var(--jini-text) 7%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-neutral-accent-ring:var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-neutral-accent-ring:color-mix(in srgb, var(--jini-text) 16%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-link:var(--jini-primary);--jini-link-ink:var(--jini-primary-ink);--jini-success-bg:var(--jini-success)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-success-bg:color-mix(in srgb, var(--jini-success) 12%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-success-solid:var(--jini-success);--jini-success-solid-ink:var(--jini-bg);--jini-danger-bg:var(--jini-danger)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-danger-bg:color-mix(in srgb, var(--jini-danger) 12%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-warning-bg:var(--jini-warning)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-warning-bg:color-mix(in srgb, var(--jini-warning) 12%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-font-ui:var(--jini-font-body);--jini-font-display:var(--jini-font-heading);--jini-shadow-xs:0 1px 0 var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-xs:0 1px 0 color-mix(in srgb, var(--jini-text) 4%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-sm:0 1px 3px var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-sm:0 1px 3px color-mix(in srgb, var(--jini-text) 10%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-md:0 6px 24px var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-md:0 6px 24px color-mix(in srgb, var(--jini-text) 15%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-lg:0 24px 60px var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-lg:0 24px 60px color-mix(in srgb, var(--jini-text) 22%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-radius-xs:calc(var(--jini-radius) * .5);--jini-radius-sm:calc(var(--jini-radius) * .75);--jini-radius-md:calc(var(--jini-radius) * 1.25);--jini-radius-lg:calc(var(--jini-radius) * 1.5);--jini-radius-pill:999px;--jini-space-1:calc(.25rem * var(--jini-density));--jini-space-2:calc(.5rem * var(--jini-density));--jini-space-3:calc(.75rem * var(--jini-density));--jini-space-4:calc(1rem * var(--jini-density));--jini-space-5:calc(1.25rem * var(--jini-density));--jini-space-6:calc(1.5rem * var(--jini-density));--jini-space-7:calc(2rem * var(--jini-density));--jini-space-8:calc(2.5rem * var(--jini-density));--jini-font-size-2xs:.6875rem;--jini-font-size-xs:.75rem;--jini-font-size-sm:.8125rem;--jini-font-size-base:.875rem;--jini-font-size-md:.95rem;--jini-font-size-lg:1.05rem;--jini-font-size-xl:1.65rem;--jini-font-weight-normal:400;--jini-font-weight-medium:500;--jini-font-weight-semibold:600;--jini-font-weight-bold:700;--jini-line-tight:1.25;--jini-line-normal:1.5;--jini-line-relaxed:1.7;--jini-duration-fast:.12s;--jini-duration-base:.2s;--jini-duration-slow:.32s;--jini-ease-out:cubic-bezier(.23, 1, .32, 1);--jini-ease-in-out:cubic-bezier(.4, 0, .2, 1);--jini-transition-base:var(--jini-duration-base) var(--jini-ease-out);--jini-z-dropdown:100;--jini-z-sticky:200;--jini-z-overlay:300;--jini-z-modal:400;--jini-z-toast:500;--jini-modal-padding:24px;--jini-sidebar-width:240px;--jini-app-bg:var(--jini-theme-app-bg,var(--jini-default-app-bg));--jini-shell-bg:var(--jini-theme-shell-bg,var(--jini-bg));--jini-panel-bg:var(--jini-theme-panel-bg,var(--jini-default-panel-bg));--jini-panel-border:var(--jini-theme-panel-border,var(--jini-default-panel-border));--jini-panel-shadow:var(--jini-theme-panel-shadow,var(--jini-default-panel-shadow));--jini-panel-backdrop:var(--jini-theme-panel-backdrop);--jini-panel-texture:var(--jini-theme-panel-texture);--jini-rail-bg:var(--jini-theme-rail-bg,var(--jini-panel-bg));--jini-rail-border:var(--jini-theme-rail-border,var(--jini-panel-border));--jini-rail-shadow:var(--jini-theme-rail-shadow,none);--jini-rail-backdrop:var(--jini-theme-rail-backdrop,var(--jini-panel-backdrop,none));--jini-overlay-bg:var(--jini-theme-overlay-bg,var(--jini-default-overlay-bg));--jini-overlay-backdrop:var(--jini-theme-overlay-backdrop);--jini-overlay-shadow:var(--jini-theme-overlay-shadow,var(--jini-default-overlay-shadow));--jini-control-preview-backdrop:var(--jini-theme-control-preview-backdrop,blur(6px));--jini-control-bg:var(--jini-theme-control-bg,var(--jini-default-control-bg));--jini-control-border:var(--jini-theme-control-border,var(--jini-default-control-border));--jini-control-shadow:var(--jini-theme-control-shadow);--jini-control-shadow-hover:var(--jini-theme-control-shadow-hover);--jini-control-shadow-pressed:var(--jini-theme-control-shadow-pressed);--jini-control-shadow-inset:var(--jini-theme-control-shadow-inset);--jini-border-width:var(--jini-theme-border-width);--jini-control-chevron-image:var(--jini-theme-control-chevron-image,url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M3.5 5.5 7 9l3.5-3.5' stroke='%23666C75' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"));--jini-overlay-tooltip-bg:var(--jini-theme-overlay-tooltip-bg,#fff);--jini-overlay-tooltip-text:var(--jini-theme-overlay-tooltip-text,#111);--jini-overlay-tooltip-border:var(--jini-theme-overlay-tooltip-border,#0000001a);--jini-overlay-bg-preview:var(--jini-theme-overlay-bg-preview,oklch(0% 0 0/.55));--jini-overlay-bg-navigation:var(--jini-theme-overlay-bg-navigation,oklch(0% 0 0/.4));--jini-code-string:var(--jini-theme-code-string,#4caf7a);--jini-code-number:var(--jini-theme-code-number,#d1975a);--jini-control-thumb-bg:var(--jini-theme-control-thumb-bg,#fff);--jini-control-solid-ink:var(--jini-theme-control-solid-ink,#fff);--jini-overlay-bg-lightbox:var(--jini-theme-overlay-bg-lightbox,oklch(0% 0 0/.6));--jini-lightbox-bg:var(--jini-theme-lightbox-bg,oklch(23% .005 256));--jini-lightbox-ink:var(--jini-theme-lightbox-ink,oklch(97% 0 0));--jini-lightbox-ink-muted:var(--jini-theme-lightbox-ink-muted,oklch(97% 0 0/.58));--jini-lightbox-media-bg:var(--jini-theme-lightbox-media-bg,oklch(0% 0 0/.25));--jini-lightbox-document-bg:var(--jini-theme-lightbox-document-bg,#fff);--jini-lightbox-button-border:var(--jini-theme-lightbox-button-border,oklch(100% 0 0/.16));--jini-lightbox-button-bg:var(--jini-theme-lightbox-button-bg,oklch(100% 0 0/.07));--jini-lightbox-button-bg-hover:var(--jini-theme-lightbox-button-bg-hover,oklch(100% 0 0/.15));--jini-lightbox-button-border-hover:var(--jini-theme-lightbox-button-border-hover,oklch(100% 0 0/.28));--jini-control-media-bg:var(--jini-theme-control-media-bg,oklch(0% 0 0/.55));--jini-control-media-ink:var(--jini-theme-control-media-ink,oklch(100% 0 0));--jini-control-media-border:var(--jini-theme-control-media-border,oklch(100% 0 0/.35));--jini-control-media-bg-hover:var(--jini-theme-control-media-bg-hover,oklch(0% 0 0/.72));--jini-overlay-bg-source:var(--jini-theme-overlay-bg-source,oklch(0% 0 0/.48));--jini-file-icon-folder:var(--jini-theme-file-icon-folder,oklch(72% .12 75));--jini-file-icon-json:var(--jini-theme-file-icon-json,oklch(72% .13 90));--jini-file-icon-markdown:var(--jini-theme-file-icon-markdown,oklch(62% .12 245));--jini-file-icon-javascript:var(--jini-theme-file-icon-javascript,oklch(76% .15 95));--jini-file-icon-typescript:var(--jini-theme-file-icon-typescript,oklch(60% .13 250));--jini-file-icon-config:var(--jini-theme-file-icon-config,oklch(62% .14 20));--jini-file-icon-html:var(--jini-theme-file-icon-html,oklch(64% .17 40));--jini-file-icon-css:var(--jini-theme-file-icon-css,oklch(62% .13 280));--jini-file-icon-image:var(--jini-theme-file-icon-image,oklch(64% .12 160));--jini-file-icon-shell:var(--jini-theme-file-icon-shell,oklch(64% .12 145));--jini-status-complete-ink-fallback:var(--jini-theme-status-complete-ink-fallback,oklch(99% 0 none));--jini-control-preview-ink:var(--jini-theme-control-preview-ink,#fff);--jini-control-preview-bg:var(--jini-theme-control-preview-bg,#1111116b);--jini-control-preview-bg-hover:var(--jini-theme-control-preview-bg-hover,#111111b8);--jini-control-preview-tip-bg:var(--jini-theme-control-preview-tip-bg,#111111e0);--jini-panel-border-muted:var(--jini-theme-panel-border-muted,#d9d9d9);--jini-control-composer-border-focus:var(--jini-theme-control-composer-border-focus,oklch(70% .012 255));--jini-overlay-bg-chat:var(--jini-theme-overlay-bg-chat,#00000073);--jini-control-hover-neutral-bg:var(--jini-theme-control-hover-neutral-bg,#7f7f7f26);--jini-control-recording-bg:var(--jini-theme-control-recording-bg,#dc2626);--jini-control-recording-ink:var(--jini-theme-control-recording-ink,#fff);--jini-control-recording-bg-hover:var(--jini-theme-control-recording-bg-hover,#b91c1c);--jini-control-shadow-focus:var(--jini-theme-control-shadow-focus,0 0 0 3px var(--jini-accent-ring));--jini-overlay-tooltip-shadow:var(--jini-theme-overlay-tooltip-shadow,0 4px 16px #00000040);--jini-control-shadow-focus-subtle:var(--jini-theme-control-shadow-focus-subtle,0 0 0 2px var(--jini-neutral-accent-soft));--jini-overlay-toast-shadow:var(--jini-theme-overlay-toast-shadow,0 8px 24px #00000038);--jini-status-danger-shadow:var(--jini-theme-status-danger-shadow,inset 3px 0 0 var(--jini-danger));--jini-control-thumb-shadow-strong:var(--jini-theme-control-thumb-shadow-strong,0 1px 2px #1c1b1a47);--jini-panel-shadow-divider:var(--jini-theme-panel-shadow-divider,inset 0 -1px 0 var(--jini-border));--jini-control-shadow-focus-accent:var(--jini-theme-control-shadow-focus-accent,0 0 0 3px var(--jini-accent))}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-control-shadow-focus-accent:var(--jini-theme-control-shadow-focus-accent,0 0 0 3px color-mix(in srgb, var(--jini-accent) 18%, transparent))}}:root,[data-admin-theme],[data-color-scheme]{--jini-overlay-menu-shadow-above:var(--jini-theme-overlay-menu-shadow-above,0 -4px 14px #141c2d17, 0 -1px 4px #141c2d0f);--jini-control-shadow-selected:var(--jini-theme-control-shadow-selected,0 0 0 1px var(--jini-accent));--jini-control-shadow-swatch-selected:var(--jini-theme-control-shadow-swatch-selected,0 0 0 2px var(--jini-bg-panel), 0 0 0 4px var(--jini-accent));--jini-control-shadow-segment:var(--jini-theme-control-shadow-segment,0 1px 2px #00000014);--jini-panel-shadow-sticky:var(--jini-theme-panel-shadow-sticky,0 6px 8px -6px #00000024);--jini-overlay-menu-shadow:var(--jini-theme-overlay-menu-shadow,0 12px 32px #0000001f);--jini-control-shadow-segment-raised:var(--jini-theme-control-shadow-segment-raised,0 1px 2px #0000001f);--jini-control-thumb-shadow:var(--jini-theme-control-thumb-shadow,0 1px 2px #00000040);--jini-panel-shadow-banner:var(--jini-theme-panel-shadow-banner,0 2px 8px #0000001f);--jini-status-warning-shadow:var(--jini-theme-status-warning-shadow,inset 2px 0 0 var(--jini-warning));--jini-panel-shadow-flat:var(--jini-theme-panel-shadow-flat,none)}:root{--jini-chat-font-body:var(--jini-theme-chat-font-body,-apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft YaHei UI", "Noto Sans", Roboto, "Helvetica Neue", Arial, sans-serif);--jini-chat-font-mono:var(--jini-theme-chat-font-mono,ui-monospace, SFMono-Regular, Menlo, monospace);--jini-chat-popover-shadow:var(--jini-theme-chat-popover-shadow,0 18px 46px #0d0c0a26, 0 2px 8px #0d0c0a0f);--jini-chat-bg:var(--jini-theme-chat-bg);--jini-chat-panel:var(--jini-theme-chat-panel);--jini-chat-text:var(--jini-theme-chat-text);--jini-chat-text-strong:var(--jini-theme-chat-text-strong);--jini-chat-muted:var(--jini-theme-chat-muted);--jini-chat-faint:var(--jini-theme-chat-faint);--jini-chat-border:var(--jini-theme-chat-border);--jini-chat-border-strong:var(--jini-theme-chat-border-strong);--jini-chat-border-soft:var(--jini-theme-chat-border-soft);--jini-chat-subtle:var(--jini-theme-chat-subtle);--jini-chat-accent:var(--jini-theme-chat-accent);--jini-chat-accent-soft:var(--jini-theme-chat-accent-soft);--jini-chat-danger:var(--jini-theme-chat-danger);--jini-chat-radius:var(--jini-theme-chat-radius);--jini-chat-radius-lg:var(--jini-theme-chat-radius-lg);--jini-chat-user-bubble:var(--jini-theme-chat-user-bubble);--jini-chat-user-bubble-ink:var(--jini-theme-chat-user-bubble-ink)}@layer theme{:root,:host{--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--radius-sm:.25rem;--radius-md:.375rem;--radius-xl:.75rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer base,components;@layer utilities{.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.right-2{right:calc(var(--spacing) * 2)}.z-50{z-index:50}.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}}.-mx-1{margin-inline:calc(var(--spacing) * -1)}.my-1{margin-block:var(--spacing)}.mt-4{margin-top:calc(var(--spacing) * 4)}.block{display:block}.flex{display:flex}.grid{display:grid}.inline-flex{display:inline-flex}.table{display:table}.table-caption{display:table-caption}.table-cell{display:table-cell}.table-row{display:table-row}.aspect-square{aspect-ratio:1}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.h-px{height:1px}.max-h-\[--radix-select-content-available-height\]{max-height:--radix-select-content-available-height}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-9{width:calc(var(--spacing) * 9)}.w-full{width:100%}.min-w-\[8rem\]{min-width:8rem}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.shrink-0{flex-shrink:0}.caption-bottom{caption-side:bottom}.origin-\[--radix-select-content-transform-origin\]{transform-origin:--radix-select-content-transform-origin}.cursor-default{cursor:default}.flex-col{flex-direction:column}.place-content-center{place-content:center}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-2{gap:calc(var(--spacing) * 2)}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded-full{border-radius:3.40282e38px}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-input{border-color:var(--jini-border)}.border-primary{border-color:var(--jini-primary)}.bg-background{background-color:var(--jini-bg)}.bg-destructive{background-color:var(--jini-danger)}.bg-muted,.bg-muted\/50{background-color:var(--jini-surface)}@supports (color:color-mix(in lab, red, red)){.bg-muted\/50{background-color:color-mix(in oklab, var(--jini-surface) 50%, transparent)}}.bg-primary{background-color:var(--jini-primary)}.bg-secondary{background-color:var(--jini-surface)}.bg-transparent{background-color:#0000}.fill-primary{fill:var(--jini-primary)}.p-1{padding:var(--spacing)}.p-2{padding:calc(var(--spacing) * 2)}.p-6{padding:calc(var(--spacing) * 6)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-8{padding-inline:calc(var(--spacing) * 8)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.pt-0{padding-top:0}.pr-8{padding-right:calc(var(--spacing) * 8)}.pl-2{padding-left:calc(var(--spacing) * 2)}.text-left{text-align:left}.align-middle{vertical-align:middle}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-none{--tw-leading:1;line-height:1}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.whitespace-nowrap{white-space:nowrap}.text-current{color:currentColor}.text-destructive-foreground{color:var(--jini-bg)}.text-foreground{color:var(--jini-text)}.text-input{color:var(--jini-border)}.text-muted-foreground{color:var(--jini-muted)}.text-primary{color:var(--jini-primary)}.text-primary-foreground{color:var(--jini-primary-ink)}.text-secondary-foreground{color:var(--jini-text)}.underline-offset-4{text-underline-offset:4px}.opacity-50{opacity:.5}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.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-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-offset-background{--tw-ring-offset-color:var(--jini-bg)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.peer-disabled\:cursor-not-allowed:is(:where(.peer):disabled~*){cursor:not-allowed}.peer-disabled\:opacity-70:is(:where(.peer):disabled~*){opacity:.7}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\:text-foreground::file-selector-button{color:var(--jini-text)}.placeholder\:text-muted-foreground::placeholder{color:var(--jini-muted)}@media (hover:hover){.hover\:bg-accent:hover{background-color:var(--jini-surface)}.hover\:bg-destructive\/90:hover{background-color:var(--jini-danger)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-destructive\/90:hover{background-color:color-mix(in oklab, var(--jini-danger) 90%, transparent)}}.hover\:bg-muted\/50:hover{background-color:var(--jini-surface)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-muted\/50:hover{background-color:color-mix(in oklab, var(--jini-surface) 50%, transparent)}}.hover\:bg-primary\/90:hover{background-color:var(--jini-primary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab, var(--jini-primary) 90%, transparent)}}.hover\:bg-secondary\/80:hover{background-color:var(--jini-surface)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab, var(--jini-surface) 80%, transparent)}}.hover\:text-accent-foreground:hover{color:var(--jini-text)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:bg-accent:focus{background-color:var(--jini-surface)}.focus\:text-accent-foreground:focus{color:var(--jini-text)}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-ring:focus{--tw-ring-color:var(--jini-primary)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--jini-primary)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.has-aria-expanded\:bg-muted\/50:has([aria-expanded=true]){background-color:var(--jini-surface)}@supports (color:color-mix(in lab, red, red)){.has-aria-expanded\:bg-muted\/50:has([aria-expanded=true]){background-color:color-mix(in oklab, var(--jini-surface) 50%, transparent)}}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[placeholder\]\:text-muted-foreground[data-placeholder]{color:var(--jini-muted)}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y:var(--spacing);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x:calc(var(--spacing) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x:var(--spacing);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y:calc(var(--spacing) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[state\=checked\]\:bg-primary[data-state=checked]{background-color:var(--jini-primary)}.data-\[state\=checked\]\:text-primary-foreground[data-state=checked]{color:var(--jini-primary-ink)}.data-\[state\=selected\]\:bg-muted[data-state=selected]{background-color:var(--jini-surface)}@media (min-width:48rem){.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_tr\]\:border-b tr{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-style:var(--tw-border-style);border-width:0}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:0}.\[\&\>span\]\:line-clamp-1>span{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}.\[\&\>tr\]\:last\:border-b-0>tr:last-child{border-bottom-style:var(--tw-border-style);border-bottom-width:0}}.jini-data-table-frame{border:1px solid var(--jini-border);border-radius:var(--jini-radius);background:var(--jini-bg);min-width:0;max-width:100%;color:var(--jini-text);overflow:hidden}.jini-data-table-scroll,.jini-data-table-frame>[data-slot=table-container]{overscroll-behavior-x:contain;width:100%;max-height:28rem;overflow:auto}.jini-data-table{border-collapse:separate;border-spacing:0;width:100%;font-family:var(--jini-font-body);font-size:var(--jini-font-size-sm);line-height:var(--jini-line-normal);font-variant-numeric:tabular-nums}.jini-data-table th,.jini-data-table td{text-align:left;vertical-align:middle;white-space:nowrap;border-bottom:1px solid var(--jini-border);height:2.5rem;padding:.625rem .875rem}.jini-data-table th{z-index:1;background:var(--jini-surface);color:var(--jini-muted);font-size:var(--jini-font-size-xs);font-weight:var(--jini-font-weight-semibold);position:sticky;top:0}.jini-data-table tbody tr:last-child td{border-bottom:0}.jini-data-table tbody tr:nth-child(2n){background:var(--jini-bg-subtle)}.jini-data-table tbody tr:hover,.jini-data-table tbody tr:focus-visible{background:var(--jini-surface)}.jini-data-table tbody tr[role=button]{cursor:pointer}.jini-data-table [data-numeric=true]{text-align:right}.jini-data-table-sort{width:100%;min-height:1.5rem;color:inherit;font:inherit;text-align:inherit;cursor:pointer;background:0 0;border:0;justify-content:space-between;align-items:center;gap:.625rem;padding:0;display:inline-flex}.jini-data-table [data-numeric=true] .jini-data-table-sort{justify-content:flex-end}.jini-data-table th[aria-sort=ascending],.jini-data-table th[aria-sort=descending],.jini-data-table-sort:hover{color:var(--jini-text)}.jini-data-table td.jini-data-table-empty{height:8rem;color:var(--jini-muted);text-align:center}.jini-data-table-pagination{border-top:1px solid var(--jini-border);color:var(--jini-muted);font-size:var(--jini-font-size-xs);font-variant-numeric:tabular-nums;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:.75rem;padding:.625rem .875rem;display:flex}.jini-data-table-pagination-controls{gap:.5rem;display:flex}.jini-data-table-pagination button{border:1px solid var(--jini-border);border-radius:var(--jini-radius-sm);background:var(--jini-bg);min-height:2rem;color:var(--jini-text);font:inherit;cursor:pointer;padding:.375rem .75rem}.jini-data-table-pagination button:hover:not(:disabled){background:var(--jini-surface)}.jini-data-table-pagination button:disabled{opacity:.5;cursor:default}.jini-data-table-sort:focus-visible,.jini-data-table-pagination button:focus-visible,.jini-data-table tr[role=button]:focus-visible{outline:2px solid var(--jini-primary);outline-offset:-2px}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-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}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}
|
|
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-space-y-reverse:0;--tw-border-style:solid;--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;--tw-outline-style:solid;--tw-translate-x:0;--tw-translate-y:0;--tw-translate-z:0}}}:root,[data-admin-theme],[data-color-scheme=light]{color-scheme:light;--jini-bg:var(--jini-theme-light-bg,#fff);--jini-surface:var(--jini-theme-light-surface,#f5f5f5);--jini-text:var(--jini-theme-light-text,#202020);--jini-muted:var(--jini-theme-light-muted,#666);--jini-border:var(--jini-theme-light-border,#d9d9d9);--jini-primary:var(--jini-theme-light-primary,#363636);--jini-primary-ink:var(--jini-theme-light-primary-ink,#fff);--jini-danger:var(--jini-theme-light-danger,#b42318);--jini-success:var(--jini-theme-light-success,#18763b);--jini-warning:var(--jini-theme-light-warning,#845800)}[data-color-scheme=dark]{color-scheme:dark;--jini-bg:var(--jini-theme-dark-bg,#171717);--jini-surface:var(--jini-theme-dark-surface,#242424);--jini-text:var(--jini-theme-dark-text,#f0f0f0);--jini-muted:var(--jini-theme-dark-muted,#b3b3b3);--jini-border:var(--jini-theme-dark-border,#454545);--jini-primary:var(--jini-theme-dark-primary,#e0e0e0);--jini-primary-ink:var(--jini-theme-dark-primary-ink,#202020);--jini-danger:var(--jini-theme-dark-danger,#ff8b80);--jini-success:var(--jini-theme-dark-success,#79d69b);--jini-warning:var(--jini-theme-dark-warning,#ebc36b)}:root,[data-color-scheme=light],[data-theme=light]{--jini-chart-default-1:oklch(55.29% .1129 43.4);--jini-chart-default-2:oklch(50% .11 240);--jini-chart-default-3:oklch(64% .13 88);--jini-chart-default-4:oklch(58% .15 350);--jini-chart-default-5:oklch(50% .11 155);--jini-chart-default-6:oklch(48% .12 295)}[data-color-scheme=dark],[data-theme=dark]{--jini-chart-default-1:oklch(62% .11 44);--jini-chart-default-2:oklch(64% .11 240);--jini-chart-default-3:oklch(66% .13 88);--jini-chart-default-4:oklch(65% .14 350);--jini-chart-default-5:oklch(56% .12 155);--jini-chart-default-6:oklch(64% .12 295)}:root{--jini-font-body:system-ui, sans-serif;--jini-font-heading:system-ui, sans-serif;--jini-font-mono:ui-monospace, monospace;--jini-radius:8px;--jini-density:1}:root,[data-admin-theme],[data-color-scheme]{--jini-bg-panel:var(--jini-surface);--jini-bg-subtle:var(--jini-surface)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-bg-subtle:color-mix(in srgb, var(--jini-surface) 75%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-bg-elevated:var(--jini-surface);--jini-border-soft:var(--jini-border);--jini-border-strong:var(--jini-border)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-border-strong:color-mix(in srgb, var(--jini-border) 75%, var(--jini-text))}}:root,[data-admin-theme],[data-color-scheme]{--jini-backdrop:var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-backdrop:color-mix(in srgb, var(--jini-text) 42%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-text-strong:var(--jini-text);--jini-text-secondary:var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-text-secondary:color-mix(in srgb, var(--jini-text) 80%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-text-muted:var(--jini-muted);--jini-text-faint:var(--jini-muted)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-text-faint:color-mix(in srgb, var(--jini-muted) 75%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-text-disabled:var(--jini-muted)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-text-disabled:color-mix(in srgb, var(--jini-muted) 60%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-accent:var(--jini-primary);--jini-accent-hover:var(--jini-primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-accent-hover:color-mix(in srgb, var(--jini-primary) 88%, var(--jini-text))}}:root,[data-admin-theme],[data-color-scheme]{--jini-accent-strong:var(--jini-primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-accent-strong:color-mix(in srgb, var(--jini-primary) 85%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-accent-ink:var(--jini-primary-ink);--jini-accent-soft:var(--jini-primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-accent-soft:color-mix(in srgb, var(--jini-primary) 10%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-accent-ring:var(--jini-primary)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-accent-ring:color-mix(in srgb, var(--jini-primary) 22%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-neutral-accent:var(--jini-text);--jini-neutral-accent-hover:var(--jini-muted);--jini-neutral-accent-ink:var(--jini-bg);--jini-neutral-accent-text:var(--jini-text);--jini-neutral-accent-soft:var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-neutral-accent-soft:color-mix(in srgb, var(--jini-text) 7%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-neutral-accent-ring:var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-neutral-accent-ring:color-mix(in srgb, var(--jini-text) 16%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-link:var(--jini-primary);--jini-link-ink:var(--jini-primary-ink);--jini-success-bg:var(--jini-success)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-success-bg:color-mix(in srgb, var(--jini-success) 12%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-success-solid:var(--jini-success);--jini-success-solid-ink:var(--jini-bg);--jini-danger-bg:var(--jini-danger)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-danger-bg:color-mix(in srgb, var(--jini-danger) 12%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-warning-bg:var(--jini-warning)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-warning-bg:color-mix(in srgb, var(--jini-warning) 12%, var(--jini-bg))}}:root,[data-admin-theme],[data-color-scheme]{--jini-font-ui:var(--jini-font-body);--jini-font-display:var(--jini-font-heading);--jini-shadow-xs:0 1px 0 var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-xs:0 1px 0 color-mix(in srgb, var(--jini-text) 4%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-sm:0 1px 3px var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-sm:0 1px 3px color-mix(in srgb, var(--jini-text) 10%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-md:0 6px 24px var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-md:0 6px 24px color-mix(in srgb, var(--jini-text) 15%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-lg:0 24px 60px var(--jini-text)}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-shadow-lg:0 24px 60px color-mix(in srgb, var(--jini-text) 22%, transparent)}}:root,[data-admin-theme],[data-color-scheme]{--jini-radius-xs:calc(var(--jini-radius) * .5);--jini-radius-sm:calc(var(--jini-radius) * .75);--jini-radius-md:calc(var(--jini-radius) * 1.25);--jini-radius-lg:calc(var(--jini-radius) * 1.5);--jini-radius-pill:999px;--jini-space-1:calc(.25rem * var(--jini-density));--jini-space-2:calc(.5rem * var(--jini-density));--jini-space-3:calc(.75rem * var(--jini-density));--jini-space-4:calc(1rem * var(--jini-density));--jini-space-5:calc(1.25rem * var(--jini-density));--jini-space-6:calc(1.5rem * var(--jini-density));--jini-space-7:calc(2rem * var(--jini-density));--jini-space-8:calc(2.5rem * var(--jini-density));--jini-font-size-2xs:.6875rem;--jini-font-size-xs:.75rem;--jini-font-size-sm:.8125rem;--jini-font-size-base:.875rem;--jini-font-size-md:.95rem;--jini-font-size-lg:1.05rem;--jini-font-size-xl:1.65rem;--jini-font-weight-normal:400;--jini-font-weight-medium:500;--jini-font-weight-semibold:600;--jini-font-weight-bold:700;--jini-line-tight:1.25;--jini-line-normal:1.5;--jini-line-relaxed:1.7;--jini-duration-fast:.12s;--jini-duration-base:.2s;--jini-duration-slow:.32s;--jini-ease-out:cubic-bezier(.23, 1, .32, 1);--jini-ease-in-out:cubic-bezier(.4, 0, .2, 1);--jini-transition-base:var(--jini-duration-base) var(--jini-ease-out);--jini-z-dropdown:100;--jini-z-sticky:200;--jini-z-overlay:300;--jini-z-modal:400;--jini-z-toast:500;--jini-modal-padding:24px;--jini-sidebar-width:240px;--jini-app-bg:var(--jini-theme-app-bg,var(--jini-default-app-bg));--jini-shell-bg:var(--jini-theme-shell-bg,var(--jini-bg));--jini-panel-bg:var(--jini-theme-panel-bg,var(--jini-default-panel-bg));--jini-panel-border:var(--jini-theme-panel-border,var(--jini-default-panel-border));--jini-panel-shadow:var(--jini-theme-panel-shadow,var(--jini-default-panel-shadow));--jini-panel-backdrop:var(--jini-theme-panel-backdrop);--jini-panel-texture:var(--jini-theme-panel-texture);--jini-rail-bg:var(--jini-theme-rail-bg,var(--jini-panel-bg));--jini-rail-border:var(--jini-theme-rail-border,var(--jini-panel-border));--jini-rail-shadow:var(--jini-theme-rail-shadow,none);--jini-rail-backdrop:var(--jini-theme-rail-backdrop,var(--jini-panel-backdrop,none));--jini-overlay-bg:var(--jini-theme-overlay-bg,var(--jini-default-overlay-bg));--jini-overlay-backdrop:var(--jini-theme-overlay-backdrop);--jini-overlay-shadow:var(--jini-theme-overlay-shadow,var(--jini-default-overlay-shadow));--jini-control-preview-backdrop:var(--jini-theme-control-preview-backdrop,blur(6px));--jini-control-bg:var(--jini-theme-control-bg,var(--jini-default-control-bg));--jini-control-border:var(--jini-theme-control-border,var(--jini-default-control-border));--jini-control-shadow:var(--jini-theme-control-shadow);--jini-control-shadow-hover:var(--jini-theme-control-shadow-hover);--jini-control-shadow-pressed:var(--jini-theme-control-shadow-pressed);--jini-control-shadow-inset:var(--jini-theme-control-shadow-inset);--jini-border-width:var(--jini-theme-border-width);--jini-control-chevron-image:var(--jini-theme-control-chevron-image,url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 14 14' fill='none'%3E%3Cpath d='M3.5 5.5 7 9l3.5-3.5' stroke='%23666C75' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E"));--jini-overlay-tooltip-bg:var(--jini-theme-overlay-tooltip-bg,#fff);--jini-overlay-tooltip-text:var(--jini-theme-overlay-tooltip-text,#111);--jini-overlay-tooltip-border:var(--jini-theme-overlay-tooltip-border,#0000001a);--jini-overlay-bg-preview:var(--jini-theme-overlay-bg-preview,oklch(0% 0 0/.55));--jini-overlay-bg-navigation:var(--jini-theme-overlay-bg-navigation,oklch(0% 0 0/.4));--jini-code-string:var(--jini-theme-code-string,#4caf7a);--jini-code-number:var(--jini-theme-code-number,#d1975a);--jini-control-thumb-bg:var(--jini-theme-control-thumb-bg,#fff);--jini-control-solid-ink:var(--jini-theme-control-solid-ink,#fff);--jini-overlay-bg-lightbox:var(--jini-theme-overlay-bg-lightbox,oklch(0% 0 0/.6));--jini-lightbox-bg:var(--jini-theme-lightbox-bg,oklch(23% .005 256));--jini-lightbox-ink:var(--jini-theme-lightbox-ink,oklch(97% 0 0));--jini-lightbox-ink-muted:var(--jini-theme-lightbox-ink-muted,oklch(97% 0 0/.58));--jini-lightbox-media-bg:var(--jini-theme-lightbox-media-bg,oklch(0% 0 0/.25));--jini-lightbox-document-bg:var(--jini-theme-lightbox-document-bg,#fff);--jini-lightbox-button-border:var(--jini-theme-lightbox-button-border,oklch(100% 0 0/.16));--jini-lightbox-button-bg:var(--jini-theme-lightbox-button-bg,oklch(100% 0 0/.07));--jini-lightbox-button-bg-hover:var(--jini-theme-lightbox-button-bg-hover,oklch(100% 0 0/.15));--jini-lightbox-button-border-hover:var(--jini-theme-lightbox-button-border-hover,oklch(100% 0 0/.28));--jini-control-media-bg:var(--jini-theme-control-media-bg,oklch(0% 0 0/.55));--jini-control-media-ink:var(--jini-theme-control-media-ink,oklch(100% 0 0));--jini-control-media-border:var(--jini-theme-control-media-border,oklch(100% 0 0/.35));--jini-control-media-bg-hover:var(--jini-theme-control-media-bg-hover,oklch(0% 0 0/.72));--jini-overlay-bg-source:var(--jini-theme-overlay-bg-source,oklch(0% 0 0/.48));--jini-file-icon-folder:var(--jini-theme-file-icon-folder,oklch(72% .12 75));--jini-file-icon-json:var(--jini-theme-file-icon-json,oklch(72% .13 90));--jini-file-icon-markdown:var(--jini-theme-file-icon-markdown,oklch(62% .12 245));--jini-file-icon-javascript:var(--jini-theme-file-icon-javascript,oklch(76% .15 95));--jini-file-icon-typescript:var(--jini-theme-file-icon-typescript,oklch(60% .13 250));--jini-file-icon-config:var(--jini-theme-file-icon-config,oklch(62% .14 20));--jini-file-icon-html:var(--jini-theme-file-icon-html,oklch(64% .17 40));--jini-file-icon-css:var(--jini-theme-file-icon-css,oklch(62% .13 280));--jini-file-icon-image:var(--jini-theme-file-icon-image,oklch(64% .12 160));--jini-file-icon-shell:var(--jini-theme-file-icon-shell,oklch(64% .12 145));--jini-status-complete-ink-fallback:var(--jini-theme-status-complete-ink-fallback,oklch(99% 0 none));--jini-control-preview-ink:var(--jini-theme-control-preview-ink,#fff);--jini-control-preview-bg:var(--jini-theme-control-preview-bg,#1111116b);--jini-control-preview-bg-hover:var(--jini-theme-control-preview-bg-hover,#111111b8);--jini-control-preview-tip-bg:var(--jini-theme-control-preview-tip-bg,#111111e0);--jini-panel-border-muted:var(--jini-theme-panel-border-muted,#d9d9d9);--jini-control-composer-border-focus:var(--jini-theme-control-composer-border-focus,oklch(70% .012 255));--jini-overlay-bg-chat:var(--jini-theme-overlay-bg-chat,#00000073);--jini-control-hover-neutral-bg:var(--jini-theme-control-hover-neutral-bg,#7f7f7f26);--jini-control-recording-bg:var(--jini-theme-control-recording-bg,#dc2626);--jini-control-recording-ink:var(--jini-theme-control-recording-ink,#fff);--jini-control-recording-bg-hover:var(--jini-theme-control-recording-bg-hover,#b91c1c);--jini-control-shadow-focus:var(--jini-theme-control-shadow-focus,0 0 0 3px var(--jini-accent-ring));--jini-overlay-tooltip-shadow:var(--jini-theme-overlay-tooltip-shadow,0 4px 16px #00000040);--jini-control-shadow-focus-subtle:var(--jini-theme-control-shadow-focus-subtle,0 0 0 2px var(--jini-neutral-accent-soft));--jini-overlay-toast-shadow:var(--jini-theme-overlay-toast-shadow,0 8px 24px #00000038);--jini-status-danger-shadow:var(--jini-theme-status-danger-shadow,inset 3px 0 0 var(--jini-danger));--jini-control-thumb-shadow-strong:var(--jini-theme-control-thumb-shadow-strong,0 1px 2px #1c1b1a47);--jini-panel-shadow-divider:var(--jini-theme-panel-shadow-divider,inset 0 -1px 0 var(--jini-border));--jini-control-shadow-focus-accent:var(--jini-theme-control-shadow-focus-accent,0 0 0 3px var(--jini-accent))}@supports (color:color-mix(in lab, red, red)){:root,[data-admin-theme],[data-color-scheme]{--jini-control-shadow-focus-accent:var(--jini-theme-control-shadow-focus-accent,0 0 0 3px color-mix(in srgb, var(--jini-accent) 18%, transparent))}}:root,[data-admin-theme],[data-color-scheme]{--jini-overlay-menu-shadow-above:var(--jini-theme-overlay-menu-shadow-above,0 -4px 14px #141c2d17, 0 -1px 4px #141c2d0f);--jini-control-shadow-selected:var(--jini-theme-control-shadow-selected,0 0 0 1px var(--jini-accent));--jini-control-shadow-swatch-selected:var(--jini-theme-control-shadow-swatch-selected,0 0 0 2px var(--jini-bg-panel), 0 0 0 4px var(--jini-accent));--jini-control-shadow-segment:var(--jini-theme-control-shadow-segment,0 1px 2px #00000014);--jini-panel-shadow-sticky:var(--jini-theme-panel-shadow-sticky,0 6px 8px -6px #00000024);--jini-overlay-menu-shadow:var(--jini-theme-overlay-menu-shadow,0 12px 32px #0000001f);--jini-control-shadow-segment-raised:var(--jini-theme-control-shadow-segment-raised,0 1px 2px #0000001f);--jini-control-thumb-shadow:var(--jini-theme-control-thumb-shadow,0 1px 2px #00000040);--jini-panel-shadow-banner:var(--jini-theme-panel-shadow-banner,0 2px 8px #0000001f);--jini-status-warning-shadow:var(--jini-theme-status-warning-shadow,inset 2px 0 0 var(--jini-warning));--jini-panel-shadow-flat:var(--jini-theme-panel-shadow-flat,none)}:root{--jini-chat-font-body:var(--jini-theme-chat-font-body,-apple-system, BlinkMacSystemFont, "Segoe UI", "Microsoft YaHei UI", "Noto Sans", Roboto, "Helvetica Neue", Arial, sans-serif);--jini-chat-font-mono:var(--jini-theme-chat-font-mono,ui-monospace, SFMono-Regular, Menlo, monospace);--jini-chat-popover-shadow:var(--jini-theme-chat-popover-shadow,0 18px 46px #0d0c0a26, 0 2px 8px #0d0c0a0f);--jini-chat-bg:var(--jini-theme-chat-bg);--jini-chat-panel:var(--jini-theme-chat-panel);--jini-chat-text:var(--jini-theme-chat-text);--jini-chat-text-strong:var(--jini-theme-chat-text-strong);--jini-chat-muted:var(--jini-theme-chat-muted);--jini-chat-faint:var(--jini-theme-chat-faint);--jini-chat-border:var(--jini-theme-chat-border);--jini-chat-border-strong:var(--jini-theme-chat-border-strong);--jini-chat-border-soft:var(--jini-theme-chat-border-soft);--jini-chat-subtle:var(--jini-theme-chat-subtle);--jini-chat-accent:var(--jini-theme-chat-accent);--jini-chat-accent-soft:var(--jini-theme-chat-accent-soft);--jini-chat-danger:var(--jini-theme-chat-danger);--jini-chat-radius:var(--jini-theme-chat-radius);--jini-chat-radius-lg:var(--jini-theme-chat-radius-lg);--jini-chat-user-bubble:var(--jini-theme-chat-user-bubble);--jini-chat-user-bubble-ink:var(--jini-theme-chat-user-bubble-ink)}@layer theme{:root,:host{--spacing:.25rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--font-weight-medium:500;--font-weight-semibold:600;--tracking-tight:-.025em;--radius-sm:.25rem;--radius-md:.375rem;--radius-xl:.75rem;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1)}}@layer base,components;@layer utilities{.visible{visibility:visible}.absolute{position:absolute}.fixed{position:fixed}.relative{position:relative}.sticky{position:sticky}.right-2{right:calc(var(--spacing) * 2)}.z-50{z-index:50}.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}}.block{display:block}.flex{display:flex}.grid{display:grid}.inline-flex{display:inline-flex}.table{display:table}.table-cell{display:table-cell}.table-row{display:table-row}.aspect-square{aspect-ratio:1}.h-3\.5{height:calc(var(--spacing) * 3.5)}.h-4{height:calc(var(--spacing) * 4)}.h-8{height:calc(var(--spacing) * 8)}.h-9{height:calc(var(--spacing) * 9)}.h-10{height:calc(var(--spacing) * 10)}.h-\[var\(--radix-select-trigger-height\)\]{height:var(--radix-select-trigger-height)}.max-h-\[--radix-select-content-available-height\]{max-height:--radix-select-content-available-height}.w-3\.5{width:calc(var(--spacing) * 3.5)}.w-4{width:calc(var(--spacing) * 4)}.w-9{width:calc(var(--spacing) * 9)}.w-full{width:100%}.min-w-\[8rem\]{min-width:8rem}.min-w-\[var\(--radix-select-trigger-width\)\]{min-width:var(--radix-select-trigger-width)}.shrink-0{flex-shrink:0}.caption-bottom{caption-side:bottom}.origin-\[--radix-select-content-transform-origin\]{transform-origin:--radix-select-content-transform-origin}.cursor-default{cursor:default}.flex-col{flex-direction:column}.place-content-center{place-content:center}.items-center{align-items:center}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-2{gap:calc(var(--spacing) * 2)}:where(.space-y-1\.5>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1.5) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1.5) * calc(1 - var(--tw-space-y-reverse)))}.overflow-x-auto{overflow-x:auto}.overflow-x-hidden{overflow-x:hidden}.overflow-y-auto{overflow-y:auto}.rounded-full{border-radius:3.40282e38px}.rounded-md{border-radius:var(--radius-md)}.rounded-sm{border-radius:var(--radius-sm)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-input{border-color:var(--jini-border)}.border-primary{border-color:var(--jini-primary)}.bg-background{background-color:var(--jini-bg)}.bg-destructive{background-color:var(--jini-danger)}.bg-primary{background-color:var(--jini-primary)}.bg-secondary{background-color:var(--jini-surface)}.bg-transparent{background-color:#0000}.fill-primary{fill:var(--jini-primary)}.p-1{padding:var(--spacing)}.p-2{padding:calc(var(--spacing) * 2)}.p-6{padding:calc(var(--spacing) * 6)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.px-8{padding-inline:calc(var(--spacing) * 8)}.py-1{padding-block:var(--spacing)}.py-1\.5{padding-block:calc(var(--spacing) * 1.5)}.py-2{padding-block:calc(var(--spacing) * 2)}.pt-0{padding-top:0}.pr-8{padding-right:calc(var(--spacing) * 8)}.pl-2{padding-left:calc(var(--spacing) * 2)}.text-left{text-align:left}.align-middle{vertical-align:middle}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.leading-none{--tw-leading:1;line-height:1}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.tracking-tight{--tw-tracking:var(--tracking-tight);letter-spacing:var(--tracking-tight)}.whitespace-nowrap{white-space:nowrap}.text-current{color:currentColor}.text-destructive-foreground{color:var(--jini-bg)}.text-foreground{color:var(--jini-text)}.text-input{color:var(--jini-border)}.text-muted-foreground{color:var(--jini-muted)}.text-primary{color:var(--jini-primary)}.text-primary-foreground{color:var(--jini-primary-ink)}.text-secondary-foreground{color:var(--jini-text)}.underline-offset-4{text-underline-offset:4px}.opacity-50{opacity:.5}.shadow{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.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-sm{--tw-shadow:0 1px 3px 0 var(--tw-shadow-color,#0000001a), 0 1px 2px -1px var(--tw-shadow-color,#0000001a);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.ring-offset-background{--tw-ring-offset-color:var(--jini-bg)}.outline{outline-style:var(--tw-outline-style);outline-width:1px}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.outline-none{--tw-outline-style:none;outline-style:none}.select-none{-webkit-user-select:none;user-select:none}.peer-disabled\:cursor-not-allowed:is(:where(.peer):disabled~*){cursor:not-allowed}.peer-disabled\:opacity-70:is(:where(.peer):disabled~*){opacity:.7}.file\:border-0::file-selector-button{border-style:var(--tw-border-style);border-width:0}.file\:bg-transparent::file-selector-button{background-color:#0000}.file\:text-sm::file-selector-button{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.file\:font-medium::file-selector-button{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.file\:text-foreground::file-selector-button{color:var(--jini-text)}.placeholder\:text-muted-foreground::placeholder{color:var(--jini-muted)}@media (hover:hover){.hover\:bg-accent:hover{background-color:var(--jini-surface)}.hover\:bg-destructive\/90:hover{background-color:var(--jini-danger)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-destructive\/90:hover{background-color:color-mix(in oklab, var(--jini-danger) 90%, transparent)}}.hover\:bg-muted\/50:hover{background-color:var(--jini-surface)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-muted\/50:hover{background-color:color-mix(in oklab, var(--jini-surface) 50%, transparent)}}.hover\:bg-primary\/90:hover{background-color:var(--jini-primary)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-primary\/90:hover{background-color:color-mix(in oklab, var(--jini-primary) 90%, transparent)}}.hover\:bg-secondary\/80:hover{background-color:var(--jini-surface)}@supports (color:color-mix(in lab, red, red)){.hover\:bg-secondary\/80:hover{background-color:color-mix(in oklab, var(--jini-surface) 80%, transparent)}}.hover\:text-accent-foreground:hover{color:var(--jini-text)}.hover\:underline:hover{text-decoration-line:underline}}.focus\:bg-accent:focus{background-color:var(--jini-surface)}.focus\:text-accent-foreground:focus{color:var(--jini-text)}.focus\:ring-1:focus{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus\:ring-ring:focus{--tw-ring-color:var(--jini-primary)}.focus\:outline-none:focus{--tw-outline-style:none;outline-style:none}.focus-visible\:ring-1:focus-visible{--tw-ring-shadow:var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color,currentcolor);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.focus-visible\:ring-ring:focus-visible{--tw-ring-color:var(--jini-primary)}.focus-visible\:outline-none:focus-visible{--tw-outline-style:none;outline-style:none}.disabled\:pointer-events-none:disabled{pointer-events:none}.disabled\:cursor-not-allowed:disabled{cursor:not-allowed}.disabled\:opacity-50:disabled{opacity:.5}.has-aria-expanded\:bg-muted\/50:has([aria-expanded=true]){background-color:var(--jini-surface)}@supports (color:color-mix(in lab, red, red)){.has-aria-expanded\:bg-muted\/50:has([aria-expanded=true]){background-color:color-mix(in oklab, var(--jini-surface) 50%, transparent)}}.data-\[disabled\]\:pointer-events-none[data-disabled]{pointer-events:none}.data-\[disabled\]\:opacity-50[data-disabled]{opacity:.5}.data-\[placeholder\]\:text-muted-foreground[data-placeholder]{color:var(--jini-muted)}.data-\[side\=bottom\]\:translate-y-1[data-side=bottom]{--tw-translate-y:var(--spacing);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[side\=left\]\:-translate-x-1[data-side=left]{--tw-translate-x:calc(var(--spacing) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[side\=right\]\:translate-x-1[data-side=right]{--tw-translate-x:var(--spacing);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[side\=top\]\:-translate-y-1[data-side=top]{--tw-translate-y:calc(var(--spacing) * -1);translate:var(--tw-translate-x) var(--tw-translate-y)}.data-\[state\=checked\]\:bg-primary[data-state=checked]{background-color:var(--jini-primary)}.data-\[state\=checked\]\:text-primary-foreground[data-state=checked]{color:var(--jini-primary-ink)}.data-\[state\=selected\]\:bg-muted[data-state=selected]{background-color:var(--jini-surface)}@media (min-width:48rem){.md\:text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}}.\[\&_svg\]\:pointer-events-none svg{pointer-events:none}.\[\&_svg\]\:size-4 svg{width:calc(var(--spacing) * 4);height:calc(var(--spacing) * 4)}.\[\&_svg\]\:shrink-0 svg{flex-shrink:0}.\[\&_tr\]\:border-b tr{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.\[\&_tr\:last-child\]\:border-0 tr:last-child{border-style:var(--tw-border-style);border-width:0}.\[\&\:has\(\[role\=checkbox\]\)\]\:pr-0:has([role=checkbox]){padding-right:0}.\[\&\>span\]\:line-clamp-1>span{-webkit-line-clamp:1;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}}.jini-data-table-frame{border:1px solid var(--jini-border);border-radius:var(--jini-radius);background:var(--jini-bg);min-width:0;max-width:100%;color:var(--jini-text);overflow:hidden}.jini-data-table-scroll,.jini-data-table-frame>[data-slot=table-container]{overscroll-behavior-x:contain;width:100%;max-height:28rem;overflow:auto}.jini-data-table{border-collapse:separate;border-spacing:0;width:100%;font-family:var(--jini-font-body);font-size:var(--jini-font-size-sm);line-height:var(--jini-line-normal);font-variant-numeric:tabular-nums}.jini-data-table th,.jini-data-table td{text-align:left;vertical-align:middle;white-space:nowrap;border-bottom:1px solid var(--jini-border);height:2.5rem;padding:.625rem .875rem}.jini-data-table th{z-index:1;background:var(--jini-surface);color:var(--jini-muted);font-size:var(--jini-font-size-xs);font-weight:var(--jini-font-weight-semibold);position:sticky;top:0}.jini-data-table tbody tr:last-child td{border-bottom:0}.jini-data-table tbody tr:nth-child(2n){background:var(--jini-bg-subtle)}.jini-data-table tbody tr:hover,.jini-data-table tbody tr:focus-visible{background:var(--jini-surface)}.jini-data-table tbody tr[role=button]{cursor:pointer}.jini-data-table [data-numeric=true]{text-align:right}.jini-data-table-sort{width:100%;min-height:1.5rem;color:inherit;font:inherit;text-align:inherit;cursor:pointer;background:0 0;border:0;justify-content:space-between;align-items:center;gap:.625rem;padding:0;display:inline-flex}.jini-data-table [data-numeric=true] .jini-data-table-sort{justify-content:flex-end}.jini-data-table th[aria-sort=ascending],.jini-data-table th[aria-sort=descending],.jini-data-table-sort:hover{color:var(--jini-text)}.jini-data-table td.jini-data-table-empty{height:8rem;color:var(--jini-muted);text-align:center}.jini-data-table-pagination{border-top:1px solid var(--jini-border);color:var(--jini-muted);font-size:var(--jini-font-size-xs);font-variant-numeric:tabular-nums;flex-wrap:wrap;justify-content:space-between;align-items:center;gap:.75rem;padding:.625rem .875rem;display:flex}.jini-data-table-pagination-controls{gap:.5rem;display:flex}.jini-data-table-pagination button{border:1px solid var(--jini-border);border-radius:var(--jini-radius-sm);background:var(--jini-bg);min-height:2rem;color:var(--jini-text);font:inherit;cursor:pointer;padding:.375rem .75rem}.jini-data-table-pagination button:hover:not(:disabled){background:var(--jini-surface)}.jini-data-table-pagination button:disabled{opacity:.5;cursor:default}.jini-data-table-sort:focus-visible,.jini-data-table-pagination button:focus-visible,.jini-data-table tr[role=button]:focus-visible{outline:2px solid var(--jini-primary);outline-offset:-2px}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-leading{syntax:"*";inherits:false}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-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}@property --tw-outline-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-translate-x{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-y{syntax:"*";inherits:false;initial-value:0}@property --tw-translate-z{syntax:"*";inherits:false;initial-value:0}
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Ported
|
|
2
|
+
* Ported from shadcn's `new-york` style registry (`ui.shadcn.com/r/styles/new-york/button.json`
|
|
3
3
|
* — the same JSON the CLI's `npx shadcn@latest add button` fetches, 2026-08-18). Only the `cn`
|
|
4
4
|
* import path changed (`@/lib/utils` -> `./lib/utils.js`), same as `table.tsx`; every class name,
|
|
5
|
-
* variant, and
|
|
5
|
+
* variant, and size below is unmodified CLI output.
|
|
6
|
+
* The unused private `asChild` option is omitted: `ActionButton` always renders a button.
|
|
6
7
|
*/
|
|
7
8
|
import * as React from 'react';
|
|
8
9
|
import { type VariantProps } from 'class-variance-authority';
|
|
@@ -10,9 +11,10 @@ declare const buttonVariants: (props?: ({
|
|
|
10
11
|
variant?: "link" | "default" | "ghost" | "outline" | "destructive" | "secondary" | null | undefined;
|
|
11
12
|
size?: "default" | "icon" | "sm" | "lg" | null | undefined;
|
|
12
13
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
13
|
-
export
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
14
|
+
export type ButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & VariantProps<typeof buttonVariants>;
|
|
15
|
+
declare const Button: React.ForwardRefExoticComponent<React.ButtonHTMLAttributes<HTMLButtonElement> & VariantProps<(props?: ({
|
|
16
|
+
variant?: "link" | "default" | "ghost" | "outline" | "destructive" | "secondary" | null | undefined;
|
|
17
|
+
size?: "default" | "icon" | "sm" | "lg" | null | undefined;
|
|
18
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string> & React.RefAttributes<HTMLButtonElement>>;
|
|
17
19
|
export { Button, buttonVariants };
|
|
18
20
|
//# sourceMappingURL=button.d.ts.map
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
/**
|
|
3
|
-
* Ported
|
|
3
|
+
* Ported from shadcn's `new-york` style registry (`ui.shadcn.com/r/styles/new-york/button.json`
|
|
4
4
|
* — the same JSON the CLI's `npx shadcn@latest add button` fetches, 2026-08-18). Only the `cn`
|
|
5
5
|
* import path changed (`@/lib/utils` -> `./lib/utils.js`), same as `table.tsx`; every class name,
|
|
6
|
-
* variant, and
|
|
6
|
+
* variant, and size below is unmodified CLI output.
|
|
7
|
+
* The unused private `asChild` option is omitted: `ActionButton` always renders a button.
|
|
7
8
|
*/
|
|
8
9
|
import * as React from 'react';
|
|
9
|
-
import { Slot } from '@radix-ui/react-slot';
|
|
10
10
|
import { cva } from 'class-variance-authority';
|
|
11
11
|
import { cn } from './lib/utils.js';
|
|
12
12
|
const buttonVariants = cva('inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0', {
|
|
@@ -31,9 +31,8 @@ const buttonVariants = cva('inline-flex items-center justify-center gap-2 whites
|
|
|
31
31
|
size: 'default',
|
|
32
32
|
},
|
|
33
33
|
});
|
|
34
|
-
const Button = React.forwardRef(({ className, variant, size,
|
|
35
|
-
|
|
36
|
-
return _jsx(Comp, { className: cn(buttonVariants({ variant, size, className })), ref: ref, ...props });
|
|
34
|
+
const Button = React.forwardRef(({ className, variant, size, ...props }, ref) => {
|
|
35
|
+
return _jsx("button", { className: cn(buttonVariants({ variant, size, className })), ref: ref, ...props });
|
|
37
36
|
});
|
|
38
37
|
Button.displayName = 'Button';
|
|
39
38
|
export { Button, buttonVariants };
|