@gemboss/ui 0.30.2 → 0.33.1
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 +150 -0
- package/README.md +115 -4
- package/catalog/editor.html +1 -1
- package/catalog/index.html +321 -160
- package/gemboss-ui.css +4 -4
- package/package.json +1 -1
- package/parts/components.css +2 -2
- package/parts/core.css +1 -1
- package/parts/shell.css +2 -2
- package/src/assistant/bridge.tsx +636 -0
- package/src/assistant/chat-markdown.ts +3 -2
- package/src/assistant/chat.tsx +45 -7
- package/src/assistant/engine.tsx +21 -4
- package/src/assistant/host.tsx +113 -31
- package/src/assistant/index.ts +3 -1
- package/src/assistant.css +1 -1
- package/src/chat-plain.js +1 -1
- package/src/collections.css +1 -1
- package/src/editor.css +1 -1
- package/src/index-table.tsx +4 -2
- package/src/portal.css +1 -1
- package/src/resource-list-select.tsx +4 -2
- package/src/search-dialog.tsx +67 -13
- package/src/selection.tsx +71 -8
- package/src/shell.css +1 -1
- package/src/shell.tsx +88 -0
- package/src/ui.css +1 -1
package/src/assistant/chat.tsx
CHANGED
|
@@ -32,7 +32,7 @@ import React, {
|
|
|
32
32
|
import { BridgeNotice, copyText } from "./engine";
|
|
33
33
|
import { EngineMark } from "./engine-mark";
|
|
34
34
|
import { isEngineMarkId } from "./engine-mark-art";
|
|
35
|
-
import { CODE_FOLD_LINES, parseBlocks, parseInline, type Block, type ImageHost } from "./chat-markdown";
|
|
35
|
+
import { CODE_FOLD_LINES, linkTarget, parseBlocks, parseInline, type Block, type ImageHost } from "./chat-markdown";
|
|
36
36
|
|
|
37
37
|
const cx = (...p: Array<string | false | null | undefined>) => p.filter(Boolean).join(" ");
|
|
38
38
|
const useBeforePaint = typeof window === "undefined" ? useEffect : useLayoutEffect;
|
|
@@ -171,14 +171,31 @@ export interface ChatMarkdownProps {
|
|
|
171
171
|
onNavigate?: (href: string) => void;
|
|
172
172
|
/** More hosts whose pictures may be drawn (added to the fleet's). */
|
|
173
173
|
imageHosts?: readonly ImageHost[];
|
|
174
|
-
/** A link scheme of the surface's own (`customer:12`): `ownLink` says which, `renderLink` draws it.
|
|
174
|
+
/** A link scheme of the surface's own (`customer:12`): `ownLink` says which, `renderLink` draws it. Kept for the surfaces
|
|
175
|
+
* that use it; `linkPolicy` says the same in one prop and wins when both are given. */
|
|
175
176
|
ownLink?: (href: string) => boolean;
|
|
176
177
|
renderLink?: (href: string, label: string) => ReactNode;
|
|
178
|
+
/**
|
|
179
|
+
* What EVERY link in an answer becomes (0.32.0), asked with the href as the model wrote it (before any normalising),
|
|
180
|
+
* its words, and `target`: what the kit would link (`linkTarget`: an in-app path or http(s), normalised) or null when the
|
|
181
|
+
* kit refuses it (`javascript:`, `//host`, a tab inside the scheme). Return `true` (or undefined) = the kit's link (in-app
|
|
182
|
+
* through `onNavigate`, https in a new tab; still words when `target` is null); `false` (or null) = its words, no link;
|
|
183
|
+
* anything else is drawn as given (a router link, a button for `customer:12`). A policy that draws its OWN link for an
|
|
184
|
+
* ordinary URL builds it from `target.href`, never from `href`: the raw one is unchecked (review #3952). Bare URLs and
|
|
185
|
+
* pictures from other hosts (drawn as links) ask it too. Three surfaces had to say "this link is text" through the pair
|
|
186
|
+
* above: `ownLink` claiming it, `renderLink` giving back the label (partner-radar, search-radar), or claiming EVERY link
|
|
187
|
+
* and re-implementing the kit's link (GemFeedback, whose bare URLs then skipped its rule).
|
|
188
|
+
* `linkPolicy={(href) => !keepAsText(href)}`.
|
|
189
|
+
*/
|
|
190
|
+
linkPolicy?: (href: string, label: string, target: { href: string; internal: boolean } | null) => ReactNode;
|
|
177
191
|
}
|
|
178
192
|
|
|
193
|
+
/** Claims every written link raw for `linkPolicy` (the decision is made at render, with the label). */
|
|
194
|
+
const CLAIM_ALL = () => true;
|
|
195
|
+
|
|
179
196
|
function Inline({ text, p }: { text: string; p: ChatMarkdownProps }) {
|
|
180
197
|
const L = useLabels();
|
|
181
|
-
const toks = parseInline(text, { imageHosts: p.imageHosts, ownLink: p.ownLink });
|
|
198
|
+
const toks = parseInline(text, { imageHosts: p.imageHosts, ownLink: p.linkPolicy ? CLAIM_ALL : p.ownLink });
|
|
182
199
|
return (
|
|
183
200
|
<>
|
|
184
201
|
{toks.map((tok, key) => {
|
|
@@ -188,8 +205,17 @@ function Inline({ text, p }: { text: string; p: ChatMarkdownProps }) {
|
|
|
188
205
|
case "bold": return <strong key={key}>{tok.text}</strong>;
|
|
189
206
|
case "italic": return <em key={key}>{tok.text}</em>;
|
|
190
207
|
case "link": {
|
|
191
|
-
|
|
192
|
-
|
|
208
|
+
let target: { href: string; internal: boolean } | null = tok;
|
|
209
|
+
if (p.linkPolicy) {
|
|
210
|
+
// A claimed (raw) href passes the kit's own rule; a bare URL or a picture's link already did.
|
|
211
|
+
target = tok.own ? linkTarget(tok.href) : { href: tok.href, internal: tok.internal };
|
|
212
|
+
const d = p.linkPolicy(tok.href, tok.label, target);
|
|
213
|
+
if (d === false || d === null) return <Fragment key={key}>{tok.label}</Fragment>;
|
|
214
|
+
if (d !== true && d !== undefined) return <Fragment key={key}>{d}</Fragment>;
|
|
215
|
+
if (!target) return <Fragment key={key}>{tok.label}</Fragment>;
|
|
216
|
+
} else if (p.ownLink?.(tok.href) && p.renderLink) return <Fragment key={key}>{p.renderLink(tok.href, tok.label)}</Fragment>;
|
|
217
|
+
const { href, internal } = target;
|
|
218
|
+
const { label } = tok;
|
|
193
219
|
return (
|
|
194
220
|
<a key={key} className="gemboss-ec-md-link" href={href}
|
|
195
221
|
target={internal ? undefined : "_blank"} rel={internal ? undefined : "noopener noreferrer"}
|
|
@@ -755,10 +781,22 @@ export function AssistantChat(p: AssistantChatProps) {
|
|
|
755
781
|
const setDraft = (v: string) => { if (!controlled) setOwnDraft(v); p.onDraftChange?.(v); };
|
|
756
782
|
const ownInput = useRef<HTMLTextAreaElement | null>(null);
|
|
757
783
|
const inputRef = p.inputRef ?? ownInput;
|
|
758
|
-
const md: ChatMarkdownProps = { text: "", onNavigate: p.onNavigate, imageHosts: p.imageHosts, ownLink: p.ownLink, renderLink: p.renderLink };
|
|
784
|
+
const md: ChatMarkdownProps = { text: "", onNavigate: p.onNavigate, imageHosts: p.imageHosts, ownLink: p.ownLink, renderLink: p.renderLink, linkPolicy: p.linkPolicy };
|
|
759
785
|
// Back to the end on a send, and when another conversation is shown (its first message is another one, or it is empty).
|
|
786
|
+
// 0.32.0: and when a NEW user message appears, wherever it was sent from. A question sent by a button outside the chat (a
|
|
787
|
+
// page's "Ask about this partner", the 📎 upload, a starter of the surface's own) never went through the composer, so the
|
|
788
|
+
// log stayed where the reader had scrolled and the answer streamed out of sight (partner-radar #968 scrolled by hand).
|
|
789
|
+
// Only a message ADDED counts (more user messages than before): an edit that drops one, or a temporary id swapped for the
|
|
790
|
+
// server's, does not pull a reader who scrolled up (review #3952). Counted once per list, not per streamed token.
|
|
760
791
|
const [sent, setSent] = useState(0);
|
|
761
|
-
const
|
|
792
|
+
const users = useMemo(() => p.messages.reduce((n, m) => n + (m.role === "user" ? 1 : 0), 0), [p.messages]);
|
|
793
|
+
const usersBefore = useRef(users);
|
|
794
|
+
const [asked, setAsked] = useState(0);
|
|
795
|
+
useEffect(() => {
|
|
796
|
+
if (users > usersBefore.current) setAsked((n) => n + 1);
|
|
797
|
+
usersBefore.current = users;
|
|
798
|
+
}, [users]);
|
|
799
|
+
const pinKey = `${sent}:${p.messages[0]?.id ?? ""}:${p.messages.length === 0}:${asked}`;
|
|
762
800
|
const send = (text: string) => { p.onSend(text); setSent((n) => n + 1); if (!controlled) setOwnDraft(""); };
|
|
763
801
|
const rootRef = useRef<HTMLDivElement>(null);
|
|
764
802
|
useFullChromeRoom(rootRef);
|
package/src/assistant/engine.tsx
CHANGED
|
@@ -171,19 +171,30 @@ export interface EnginePickerProps {
|
|
|
171
171
|
locked?: boolean;
|
|
172
172
|
/** Align the panel's right edge with the chip's (a chip near the right edge of a narrow frame). */
|
|
173
173
|
end?: boolean;
|
|
174
|
+
/** The chip button, for the surface (`useEnginePicker` passes its own: `close()` puts focus back on it). 0.32.0. */
|
|
175
|
+
chipRef?: React.Ref<HTMLButtonElement>;
|
|
174
176
|
labels?: Partial<EnginePickerLabels>;
|
|
175
177
|
className?: string;
|
|
176
178
|
}
|
|
177
179
|
|
|
178
180
|
/** The open state and tab of one picker, for a surface that also renders a `BridgeNotice`:
|
|
179
|
-
* `const p = useEnginePicker(); <EnginePicker {...p.props} …/> <BridgeNotice onOpenSetup={() => p.openTab("setup")} …/>`
|
|
181
|
+
* `const p = useEnginePicker(); <EnginePicker {...p.props} …/> <BridgeNotice onOpenSetup={() => p.openTab("setup")} …/>`
|
|
182
|
+
*
|
|
183
|
+
* `close()` (0.32.0) is the surface's close: a button inside the panel that acts and then shuts it (Stop bridge, Remove
|
|
184
|
+
* from this machine, before a confirm opens). The button that had focus goes away with the panel, so focus would fall to
|
|
185
|
+
* <body> and the confirm would record <body> as where to return; `close()` puts it on the chip first. Every surface
|
|
186
|
+
* wrote that by hand (`querySelector(".gb-engine-chip").focus()`: partner-radar, search-radar, gemwatcher #922). An
|
|
187
|
+
* outside click still closes without moving focus (`props.onOpenChange(false)`). */
|
|
180
188
|
export function useEnginePicker(initial: EnginePickerTab = "engine") {
|
|
181
189
|
const [open, setOpen] = useState(false);
|
|
182
190
|
const [tab, setTab] = useState<EnginePickerTab>(initial);
|
|
191
|
+
const chipRef = useRef<HTMLButtonElement | null>(null);
|
|
183
192
|
const openTab = useCallback((t: EnginePickerTab) => { setTab(t); setOpen(true); }, []);
|
|
184
193
|
// Closing goes back to Engine: after "Open setup" the next click on the chip is about the engine again (review #3885).
|
|
185
194
|
const onOpenChange = useCallback((v: boolean) => { setOpen(v); if (!v) setTab(initial); }, [initial]);
|
|
186
|
-
|
|
195
|
+
const focusChip = useCallback(() => { chipRef.current?.focus(); }, []);
|
|
196
|
+
const close = useCallback(() => { onOpenChange(false); focusChip(); }, [onOpenChange, focusChip]);
|
|
197
|
+
return { open, tab, setOpen, setTab, openTab, close, focusChip, chipRef, props: { open, onOpenChange, tab, onTabChange: setTab, chipRef } };
|
|
187
198
|
}
|
|
188
199
|
|
|
189
200
|
function availableTabs(p: Pick<EnginePickerProps, "bridge" | "setup">): EnginePickerTab[] {
|
|
@@ -224,7 +235,13 @@ export function EnginePicker(props: EnginePickerProps) {
|
|
|
224
235
|
// Decided after mount, so the server and the first client render agree.
|
|
225
236
|
const [portal, setPortal] = useState(false);
|
|
226
237
|
useEffect(() => { setPortal(!canFloatMenus()); }, []);
|
|
227
|
-
const chipRef = useRef<HTMLButtonElement>(null);
|
|
238
|
+
const chipRef = useRef<HTMLButtonElement | null>(null);
|
|
239
|
+
const outerChipRef = props.chipRef;
|
|
240
|
+
const setChip = useCallback((el: HTMLButtonElement | null) => {
|
|
241
|
+
chipRef.current = el;
|
|
242
|
+
if (typeof outerChipRef === "function") outerChipRef(el);
|
|
243
|
+
else if (outerChipRef) (outerChipRef as { current: HTMLButtonElement | null }).current = el;
|
|
244
|
+
}, [outerChipRef]);
|
|
228
245
|
const panelRef = useRef<HTMLDivElement>(null);
|
|
229
246
|
const panelId = useId();
|
|
230
247
|
|
|
@@ -340,7 +357,7 @@ export function EnginePicker(props: EnginePickerProps) {
|
|
|
340
357
|
return (
|
|
341
358
|
<span className={cx("gb-engine", className)}>
|
|
342
359
|
<button
|
|
343
|
-
ref={
|
|
360
|
+
ref={setChip}
|
|
344
361
|
type="button"
|
|
345
362
|
className={mark ? "gb-engine-chip has-mark" : "gb-engine-chip"}
|
|
346
363
|
disabled={props.disabled || undefined}
|
package/src/assistant/host.tsx
CHANGED
|
@@ -39,6 +39,7 @@ export interface AssistantHostLabels {
|
|
|
39
39
|
close: string; closeBusy: string; closeBusyTitle: string;
|
|
40
40
|
shrinkToPopup: string; tablist: string; primaryTab: string;
|
|
41
41
|
pinSide: string; floatPopup: string; sideGrip: string; backToSide: string;
|
|
42
|
+
more: string; clearHistory: string;
|
|
42
43
|
}
|
|
43
44
|
const EN: AssistantHostLabels = {
|
|
44
45
|
ready: "Ready", working: "Working", done: "Done — tap to see it",
|
|
@@ -52,8 +53,88 @@ const EN: AssistantHostLabels = {
|
|
|
52
53
|
shrinkToPopup: "Shrink to popup", tablist: "Assistant or a person", primaryTab: "Assistant",
|
|
53
54
|
pinSide: "Pin to the side", floatPopup: "Float as a popup", sideGrip: "Drag to resize the assistant; left and right arrows work too",
|
|
54
55
|
backToSide: "Back to the side panel",
|
|
56
|
+
more: "More", clearHistory: "Clear history",
|
|
55
57
|
};
|
|
56
58
|
|
|
59
|
+
/**
|
|
60
|
+
* One row of the header's ⋯ menu (0.31.0). The fleet's menu row (`ui-menu__item`, shell.css, which every surface with
|
|
61
|
+
* the shell loads, the admin too). A surface's own rows go in `menuItems`.
|
|
62
|
+
* It closes the menu and puts focus on ⋯ BEFORE its handler (review #3941): closing after it hid the focused row, so focus
|
|
63
|
+
* fell to <body>, and a confirm the handler opened (content-radar's Clear history) saved that hidden row as the place to
|
|
64
|
+
* return to. No `role="menuitem"`: like the kit's Menu, a disclosure of buttons; the menu role promises arrow keys.
|
|
65
|
+
*/
|
|
66
|
+
export function AssistantMenuItem({ danger, disabled, onClick, className, children }: {
|
|
67
|
+
danger?: boolean;
|
|
68
|
+
disabled?: boolean;
|
|
69
|
+
onClick?: React.MouseEventHandler<HTMLButtonElement>;
|
|
70
|
+
className?: string;
|
|
71
|
+
children?: ReactNode;
|
|
72
|
+
}) {
|
|
73
|
+
return (
|
|
74
|
+
<button
|
|
75
|
+
type="button"
|
|
76
|
+
className={["ui-menu__item", danger ? "ui-menu__item--danger" : "", className ?? ""].filter(Boolean).join(" ")}
|
|
77
|
+
disabled={disabled}
|
|
78
|
+
onClick={(e) => {
|
|
79
|
+
const menu = e.currentTarget.closest("details");
|
|
80
|
+
menu?.removeAttribute("open");
|
|
81
|
+
menu?.querySelector("summary")?.focus();
|
|
82
|
+
onClick?.(e);
|
|
83
|
+
}}
|
|
84
|
+
>
|
|
85
|
+
{children}
|
|
86
|
+
</button>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* The header's ⋯ (0.31.0, Chris 08/10/2026: "clear history lên topbar … nhiều icon rồi nên cần gom nhóm"). A `<details>`
|
|
92
|
+
* like the kit's Menu, but its position and trigger are the host's (assistant.css): the kit's `.ui-menu` rules live in
|
|
93
|
+
* kit-plain.css, which the admin does not load, while the row (`ui-menu__item`) and the surface
|
|
94
|
+
* (`gemboss-popover-surface`) are shell.css, which it does. Escape and an outside press close it, the way the engine
|
|
95
|
+
* picker's popup closes (engine.tsx): Escape with focus inside goes back to ⋯ and is stopped, so the surface's own
|
|
96
|
+
* "Escape hides the assistant" does not fire on the same key; an Escape meant for a modal elsewhere is left to it. It also
|
|
97
|
+
* closes when the window loses focus (a click into an iframe), like the kit's plain menus (kit-plain.js initMenus).
|
|
98
|
+
*/
|
|
99
|
+
function HostMenu({ label, trigger = "gb-dock-icon", children }: { label: string; trigger?: string; children: ReactNode }) {
|
|
100
|
+
const ref = useRef<HTMLDetailsElement>(null);
|
|
101
|
+
// Listening all the time and asking `el.open`, like the kit's Menu: gating the listeners on an `open` state left the
|
|
102
|
+
// render between the toggle and the effect unguarded, and a press outside in that window kept the menu open (measured
|
|
103
|
+
// in the browser test under load).
|
|
104
|
+
useEffect(() => {
|
|
105
|
+
const el = ref.current;
|
|
106
|
+
if (!el) return undefined;
|
|
107
|
+
const onKey = (e: KeyboardEvent) => {
|
|
108
|
+
if (!el.open || e.key !== "Escape" || e.defaultPrevented || e.isComposing || e.keyCode === 229) return;
|
|
109
|
+
const modal = (document.activeElement as Element | null)?.closest?.('dialog[open], [aria-modal="true"]');
|
|
110
|
+
if (modal && !el.contains(modal)) return;
|
|
111
|
+
e.preventDefault();
|
|
112
|
+
if (el.contains(document.activeElement)) { e.stopPropagation(); el.open = false; el.querySelector("summary")?.focus(); }
|
|
113
|
+
else el.open = false;
|
|
114
|
+
};
|
|
115
|
+
const onDown = (e: PointerEvent) => { if (el.open && !el.contains(e.target as Node)) el.open = false; };
|
|
116
|
+
const onBlur = () => { if (el.open) el.open = false; };
|
|
117
|
+
window.addEventListener("keydown", onKey, true);
|
|
118
|
+
document.addEventListener("pointerdown", onDown, true);
|
|
119
|
+
window.addEventListener("blur", onBlur);
|
|
120
|
+
return () => {
|
|
121
|
+
window.removeEventListener("keydown", onKey, true);
|
|
122
|
+
document.removeEventListener("pointerdown", onDown, true);
|
|
123
|
+
window.removeEventListener("blur", onBlur);
|
|
124
|
+
};
|
|
125
|
+
}, []);
|
|
126
|
+
return (
|
|
127
|
+
<details ref={ref} className="gb-dock-menu">
|
|
128
|
+
<summary className={trigger} title={label} aria-label={label}>
|
|
129
|
+
<svg viewBox="0 0 20 20" aria-hidden><circle cx="5" cy="10" r="1.5" fill="currentColor"/><circle cx="10" cy="10" r="1.5" fill="currentColor"/><circle cx="15" cy="10" r="1.5" fill="currentColor"/></svg>
|
|
130
|
+
</summary>
|
|
131
|
+
{/* title="": the popup's header carries "Drag this bar…" as its title, and a browser shows an ancestor's title on
|
|
132
|
+
any child without one of its own, so every row said it (review #3941). */}
|
|
133
|
+
<div className="gemboss-popover-surface gb-dock-menu-list" title="">{children}</div>
|
|
134
|
+
</details>
|
|
135
|
+
);
|
|
136
|
+
}
|
|
137
|
+
|
|
57
138
|
/** An optional second tab in the popup (the admin: a person on the Gem team, through gemcare). */
|
|
58
139
|
export interface AssistantSecondTab {
|
|
59
140
|
label: ReactNode;
|
|
@@ -88,14 +169,23 @@ function useSideFits(): boolean {
|
|
|
88
169
|
}
|
|
89
170
|
|
|
90
171
|
export function AssistantHost({
|
|
91
|
-
title, labels, onNewChat,
|
|
92
|
-
miniHint, allowSide = true, children,
|
|
172
|
+
title, labels, onNewChat, onClearHistory, canClearHistory = true, menuItems, onExpand, onShrink, fullActions, secondTab,
|
|
173
|
+
view = "primary", onViewChange, miniHint, allowSide = true, children,
|
|
93
174
|
}: {
|
|
94
175
|
/** "Gem assistant" in the admin. Names the region, the popup header and the status bar. */
|
|
95
176
|
title: string;
|
|
96
177
|
labels?: Partial<AssistantHostLabels>;
|
|
97
178
|
/** The popup header's +. Omit it and the button is not drawn. */
|
|
98
179
|
onNewChat?: () => void;
|
|
180
|
+
/**
|
|
181
|
+
* "Clear history" in the ⋯ menu (0.31.0), in the panel's header and in full screen's chrome. The surface confirms (it
|
|
182
|
+
* knows what is cleared: this browser's chats, an engine's session). Omit it and the row is not drawn.
|
|
183
|
+
*/
|
|
184
|
+
onClearHistory?: () => void;
|
|
185
|
+
/** False greys "Clear history" out (nothing to clear). */
|
|
186
|
+
canClearHistory?: boolean;
|
|
187
|
+
/** The surface's own rows at the top of the ⋯ menu, as `AssistantMenuItem`s. */
|
|
188
|
+
menuItems?: ReactNode;
|
|
99
189
|
/** Popup → full screen. The surface decides what that means (the admin navigates to its page). */
|
|
100
190
|
onExpand: () => void;
|
|
101
191
|
/** Full screen → popup, e.g. open the dock and go back to the screen they came from. */
|
|
@@ -196,8 +286,8 @@ export function AssistantHost({
|
|
|
196
286
|
return { min: 8, max: Math.max(8, Math.floor(track - width - 8)) };
|
|
197
287
|
}, []);
|
|
198
288
|
const onHeaderDown = useCallback((e: React.PointerEvent<HTMLElement>) => {
|
|
199
|
-
// Buttons in the header keep their clicks; only the bare strip drags.
|
|
200
|
-
if ((e.target as HTMLElement).closest("button")) return;
|
|
289
|
+
// Buttons in the header keep their clicks — the ⋯ menu's <summary> and its rows too; only the bare strip drags.
|
|
290
|
+
if ((e.target as HTMLElement).closest("button, summary, .gb-dock-menu")) return;
|
|
201
291
|
(e.currentTarget as HTMLElement).setPointerCapture(e.pointerId);
|
|
202
292
|
setDragging(true);
|
|
203
293
|
slideRef.current = { startX: e.clientX, startOffset: dock.dockOffsetRight, moved: false };
|
|
@@ -291,6 +381,11 @@ export function AssistantHost({
|
|
|
291
381
|
// real ceiling for this window, which changes when the window does.
|
|
292
382
|
const maxDockHeight = clampDockHeight(Number.MAX_SAFE_INTEGER, typeof window === "undefined" ? 900 : window.innerHeight);
|
|
293
383
|
const statusText = dock.busy ? L.working : dock.unread ? L.done : L.ready;
|
|
384
|
+
// The surface's rows of the ⋯ menu, in the panel's header and in full screen's chrome alike.
|
|
385
|
+
const clearRow = onClearHistory ? (
|
|
386
|
+
<AssistantMenuItem danger disabled={!canClearHistory} onClick={onClearHistory}>{L.clearHistory}</AssistantMenuItem>
|
|
387
|
+
) : null;
|
|
388
|
+
const surfaceRows = menuItems || clearRow ? <>{menuItems}{clearRow}</> : null;
|
|
294
389
|
// Full screen is the assistant's own page and has no tab strip; the second tab lives in the popup.
|
|
295
390
|
const secondVisible = isPanel && !!secondTab && view === "secondary";
|
|
296
391
|
const secondBadge = secondTab?.badge || 0;
|
|
@@ -308,6 +403,7 @@ export function AssistantHost({
|
|
|
308
403
|
// data-gb-dock-chrome: what AssistantChat measures to keep its first line clear of these buttons (0.29.0).
|
|
309
404
|
<div className="gb-dock-fullchrome" data-gb-dock-chrome="">
|
|
310
405
|
{fullActions}
|
|
406
|
+
{surfaceRows ? <HostMenu label={L.more} trigger="gb-dock-shrink gb-dock-menu-pill">{surfaceRows}</HostMenu> : null}
|
|
311
407
|
<button type="button" className="gb-dock-shrink" onClick={onShrink}>
|
|
312
408
|
{/* Two arrows pulled INTO the centre. The first attempt drew two corner brackets, which at 16px
|
|
313
409
|
reads as a plus sign — the opposite of "make this smaller". */}
|
|
@@ -406,29 +502,6 @@ export function AssistantHost({
|
|
|
406
502
|
<span className="gb-dock-sr">{L.newChat}</span>
|
|
407
503
|
</button>
|
|
408
504
|
) : null}
|
|
409
|
-
{/* On `dock.sideAllowed`, not the prop: it already folds in the window width (SIDE_FITS_QUERY), so the pin
|
|
410
|
-
never shows where pressing it would only drop the working shape to "dock" (review #3744). */}
|
|
411
|
-
{isDock && dock.sideAllowed ? (
|
|
412
|
-
<button type="button" className="gb-dock-icon gb-dock-action gb-dock-pinside" title={L.pinSide} onClick={dock.openSide}>
|
|
413
|
-
{/* A window with its right third filled: the panel it will become. */}
|
|
414
|
-
<svg viewBox="0 0 20 20" aria-hidden>
|
|
415
|
-
<rect x="3.5" y="4.5" width="13" height="11" rx="1.5" stroke="currentColor" strokeWidth="1.5" fill="none"/>
|
|
416
|
-
<path d="M12 4.5v11" stroke="currentColor" strokeWidth="1.5"/>
|
|
417
|
-
<path d="M12.75 5.25h3v9.5h-3z" fill="currentColor"/>
|
|
418
|
-
</svg>
|
|
419
|
-
<span className="gb-dock-sr">{L.pinSide}</span>
|
|
420
|
-
</button>
|
|
421
|
-
) : null}
|
|
422
|
-
{isSide ? (
|
|
423
|
-
<button type="button" className="gb-dock-icon gb-dock-action" title={L.floatPopup} onClick={dock.openDock}>
|
|
424
|
-
{/* The same window with a small box floating in its bottom-right corner: the popup. */}
|
|
425
|
-
<svg viewBox="0 0 20 20" aria-hidden>
|
|
426
|
-
<rect x="3.5" y="4.5" width="13" height="11" rx="1.5" stroke="currentColor" strokeWidth="1.5" fill="none"/>
|
|
427
|
-
<rect x="10" y="10" width="5" height="4" rx="0.75" fill="currentColor"/>
|
|
428
|
-
</svg>
|
|
429
|
-
<span className="gb-dock-sr">{L.floatPopup}</span>
|
|
430
|
-
</button>
|
|
431
|
-
) : null}
|
|
432
505
|
<button
|
|
433
506
|
type="button"
|
|
434
507
|
className="gb-dock-icon"
|
|
@@ -442,10 +515,19 @@ export function AssistantHost({
|
|
|
442
515
|
</svg>
|
|
443
516
|
<span className="gb-dock-sr">{L.openFull}</span>
|
|
444
517
|
</button>
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
518
|
+
{/* ⋯ (0.31.0): what is used once in a while — the surface's rows, Clear history, and the two window controls
|
|
519
|
+
that were icons (pin / float, minimise). Four controls stay in sight: +, full screen, ⋯, ×. On
|
|
520
|
+
`dock.sideAllowed`, not the prop, for the pin: it already folds in the window width (SIDE_FITS_QUERY),
|
|
521
|
+
so it is never offered where pressing it would only drop the working shape to "dock" (review #3744). */}
|
|
522
|
+
<HostMenu label={L.more}>
|
|
523
|
+
{surfaceRows}
|
|
524
|
+
{surfaceRows ? <hr className="gb-dock-menu-sep" /> : null}
|
|
525
|
+
{isDock && dock.sideAllowed ? (
|
|
526
|
+
<AssistantMenuItem className="gb-dock-pinside" onClick={dock.openSide}>{L.pinSide}</AssistantMenuItem>
|
|
527
|
+
) : null}
|
|
528
|
+
{isSide ? <AssistantMenuItem onClick={dock.openDock}>{L.floatPopup}</AssistantMenuItem> : null}
|
|
529
|
+
<AssistantMenuItem onClick={dock.minimize}>{L.minimizeTitle}</AssistantMenuItem>
|
|
530
|
+
</HostMenu>
|
|
449
531
|
<button
|
|
450
532
|
type="button"
|
|
451
533
|
className="gb-dock-icon"
|
package/src/assistant/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// The assistant's frame: popup, status bar, full screen — and the rules for when each shows.
|
|
2
2
|
// A separate entry from the shell/auth barrel so a surface that never opens an assistant pays nothing for it.
|
|
3
|
-
export { AssistantHost, type AssistantHostLabels, type AssistantSecondTab } from "./host";
|
|
3
|
+
export { AssistantHost, AssistantMenuItem, type AssistantHostLabels, type AssistantSecondTab } from "./host";
|
|
4
4
|
export { AssistantProvider, SIDE_WIDTH_VAR, useAssistant, useAssistantPageFacts, type AssistantDockApi, type AssistantOptions } from "./provider";
|
|
5
5
|
export * from "./dock";
|
|
6
6
|
export { AssistantWorkspaceLayout, OpenChatTabs, SessionRail, SESSION_RAIL_EN, groupSessions, normalizeForSearch, relativeTime, type AssistantSession, type SessionGroup, type SessionRailIcons, type SessionRailLabels } from "./sessions";
|
|
@@ -10,3 +10,5 @@ export { AssistantChat, ChatAttach, ChatBubble, ChatComposer, ChatError, ChatLab
|
|
|
10
10
|
export { bareUrl, CODE_FOLD_LINES, FLEET_IMAGE_HOSTS, imageSource, linkTarget, parseBlocks, parseInline, type Block, type ImageHost, type Inline, type InlineOptions } from "./chat-markdown";
|
|
11
11
|
export { ENGINE_MARK_ART, ENGINE_MARK_FILL_RULE, EngineMark, isEngineMarkId, type EngineMarkArt, type EngineMarkId } from "./engine-mark";
|
|
12
12
|
export { atBridge, BRIDGE_GONE, bridgeTurnError, PAIRING_REJECTED, useChatTurns, type ChatTurns, type TurnError } from "./chat-turns";
|
|
13
|
+
// 0.32.0: the bridge on the user's machine, seen from the browser (the radars' copies, once): client, state, picker props.
|
|
14
|
+
export { BRIDGE_CLOSED_EARLY, BRIDGE_SETUP_EN, BridgePairForm, SERVER_CLOSED_EARLY, bridgeControlNote, bridgePickerProps, createBridgeClient, isLocalPage, localNetworkPermission, mergeBridgeEngines, pickerBridgeState, postTurn, readTurnEvents, useBridge, type BridgeApi, type BridgeClient, type BridgeClientOptions, type BridgeEngineStatus, type BridgeEngines, type BridgePickerOptions, type BridgeProbe, type BridgeProbeState, type BridgeSetupLabels, type TurnEvent, type UseBridgeOptions } from "./bridge";
|
package/src/assistant.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.gb-dock{position:fixed;z-index:320;right:24px;bottom:0;width:min(460px,calc(100vw - 288px));display:flex;flex-direction:column;min-height:0;background:var(--gemboss-surface);background:color-mix(in srgb,var(--gemboss-surface) 93%,transparent);-webkit-backdrop-filter:blur(14px) saturate(1.4);backdrop-filter:blur(14px) saturate(1.4);border:1px solid var(--gemboss-divider);border-bottom:0;border-radius:12px 12px 0 0;box-shadow:0 -2px 6px #0f172a0d,0 24px 64px #0f172a2e;overflow:hidden;transition:transform .14s cubic-bezier(.2,.8,.3,1),opacity .14s ease-out}@starting-style{.gb-dock-dock,.gb-dock-mini{transform:translateY(10px);opacity:0}.gb-dock-side{transform:translate(12px);opacity:0}}.gb-dock-dragging,.gb-dock-dragging *{transition:none!important}@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))){.gb-dock{background:var(--gemboss-surface)}}@media (prefers-reduced-motion: reduce){.gb-dock{transition:none}}.gb-dock-hidden{display:none}.gb-dock-full{z-index:4;inset:56px 0 0 240px;width:auto;border:0;border-radius:0;box-shadow:none;background:var(--gemboss-app-bg)}.gb-dock-side{z-index:290;top:56px;right:0;bottom:0;width:var(--gb-dock-side-w, 400px);background:var(--gemboss-surface);-webkit-backdrop-filter:none;backdrop-filter:none;border:0;border-left:1px solid var(--gemboss-divider);border-radius:0;box-shadow:none;overflow:visible}.gb-dock-side .gb-dock-body,.gb-dock-side .gb-dock-pane{overflow:hidden}.gb-dock-side .gb-dock-header{cursor:default;touch-action:auto}.gb-dock-side .gb-dock-status{flex:0 0 auto;position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.gb-dock-side .gb-dock-header:active{cursor:default}.gb-dock-side>.gb-dock-sidegrip{position:absolute;top:0;bottom:0;left:-3px;width:5px;z-index:3}@media (min-width: 1100px){body.gemboss-assistant-side .gemboss-platform-main{margin-right:var(--gb-assistant-side-w, 400px)}}.gb-dock-fullchrome{position:absolute;top:10px;right:16px;z-index:1;display:flex;gap:8px}.gb-dock-shrink{display:inline-flex;align-items:center;gap:6px;min-height:44px;padding:0 12px;border:1px solid var(--gemboss-divider);border-radius:var(--gemboss-radius-full);background:var(--gemboss-surface);color:var(--gemboss-text-muted);font:inherit;font-size:var(--gemboss-fs-caption);cursor:pointer;white-space:nowrap}.gb-dock-shrink:hover{background:var(--gemboss-hover);color:var(--gemboss-text)}.gb-dock-shrink:focus-visible{outline:2px solid var(--gemboss-primary);outline-offset:2px}.gb-dock-shrink svg{width:16px;height:16px;flex:0 0 auto}@media (max-width: 560px){.gb-dock-shrink span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}.gb-dock-shrink{padding:0;width:44px;justify-content:center}.gb-dock-shrink-keep span{position:static;width:auto;height:auto;overflow:visible;clip:auto}.gb-dock-shrink-keep{padding:0 12px;width:auto}.gb-dock-fullchrome{position:static;justify-content:flex-end;padding:8px 12px 0}}.gb-dock-mini{height:auto;width:min(320px,calc(100vw - 288px));-webkit-backdrop-filter:blur(14px) saturate(1.4);backdrop-filter:blur(14px) saturate(1.4);border-radius:12px 12px 0 0}.gb-dock-mini .gb-dock-body{display:none}.gb-dock-minirow{display:flex;align-items:center;padding-right:4px}.gb-dock-minirow .gb-dock-minibar{flex:1 1 auto;min-width:0}.gb-dock-minirow .gb-dock-icon{flex:0 0 auto}.gb-dock-minibar{display:flex;align-items:center;gap:8px;width:100%;min-height:48px;padding:0 12px;border:0;background:transparent;font:inherit;color:var(--gemboss-text-strong);cursor:pointer;text-align:left}.gb-dock-minibar:hover{background:var(--gemboss-hover)}.gb-dock-minibar strong{font-size:13px;font-weight:600;flex:0 0 auto}.gb-dock-ministatus{flex:1 1 auto;min-width:0;font-size:12px;color:var(--gemboss-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gb-dock-minichevron{font-size:10px;color:var(--gemboss-text-muted)}.gb-dock-grip{position:absolute;top:0;left:0;right:0;height:14px;z-index:2;display:grid;place-items:center;cursor:ns-resize;touch-action:none;background:transparent}.gb-dock-grip>span{display:block;width:44px;height:4px;border-radius:2px;background:var(--gemboss-divider)}.gb-dock-grip:hover>span,.gb-dock-grip:focus-visible>span{background:var(--gemboss-text-muted)}.gb-dock-grip:focus-visible{outline:2px solid var(--gemboss-primary);outline-offset:-2px}.gb-dock-header{flex:0 0 auto;cursor:grab;touch-action:none;user-select:none;display:flex;align-items:center;gap:8px;padding:0 4px 0 16px;min-height:48px;border-bottom:1px solid var(--gemboss-divider);background:transparent}.gb-dock-title{font-size:13px;font-weight:600;color:var(--gemboss-text-strong);white-space:nowrap;flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis}.gb-dock-status{flex:1 1 auto;min-width:0;font-size:12px;color:var(--gemboss-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gb-dock-header:active{cursor:grabbing}.gb-dock-actions{display:flex;align-items:center;gap:2px;cursor:default;margin-left:auto}.gb-dock-action{margin-right:8px}.gb-dock-icon{width:44px;height:44px;display:grid;place-items:center;border:0;border-radius:8px;background:transparent;color:var(--gemboss-text-muted);cursor:pointer;padding:0}.gb-dock-icon:hover{background:var(--gemboss-hover);color:var(--gemboss-text-strong)}.gb-dock-icon:focus-visible{outline:2px solid var(--gemboss-primary);outline-offset:-2px}.gb-dock-icon svg{width:18px;height:18px}.gb-dock-icon-on{color:var(--gemboss-active-fg);background:var(--gemboss-active-bg)}.gb-dock-dot{flex:0 0 auto;width:8px;height:8px;border-radius:50%;background:var(--gemboss-divider)}.gb-dock-dot-busy{background:var(--gemboss-primary);animation:gb-dock-pulse 1.4s ease-in-out infinite}.gb-dock-dot-unread{background:var(--gemboss-success-strong)}@keyframes gb-dock-pulse{0%,to{opacity:1}50%{opacity:.35}}@media (prefers-reduced-motion: reduce){.gb-dock-dot-busy{animation:none}}.gb-dock-tabs{flex:0 0 auto;display:flex;gap:4px;padding:0 8px;border-bottom:1px solid var(--gemboss-divider)}.gb-dock-tab{position:relative;display:inline-flex;align-items:center;gap:6px;min-height:44px;padding:0 12px;border:0;border-bottom:2px solid transparent;background:transparent;color:var(--gemboss-text-muted);font:inherit;font-size:13px;cursor:pointer;white-space:nowrap}.gb-dock-tab:hover{color:var(--gemboss-text-strong)}.gb-dock-tab[aria-selected=true]{color:var(--gemboss-text-strong);font-weight:600;border-bottom-color:var(--gemboss-primary)}.gb-dock-tab:focus-visible{outline:2px solid var(--gemboss-primary);outline-offset:-2px}.gb-dock-badge{min-width:18px;padding:0 6px;border-radius:var(--gemboss-radius-full);background:var(--gemboss-primary);color:var(--gemboss-on-primary, #fff);font-size:11px;font-weight:700;line-height:18px;text-align:center}.gb-dock-body{flex:1 1 auto;min-height:0;display:flex;min-width:0}.gb-dock-body>*{flex:1 1 auto;min-width:0;min-height:0}.gb-dock-pane{display:flex;min-width:0;min-height:0}.gb-dock-pane>*{flex:1 1 auto;min-width:0;min-height:0}.gb-dock-body .gemboss-assistant-layout,.gb-dock-body .gemboss-assistant-page{height:auto;min-height:0}.gb-dock-pane[hidden]{display:none}.gb-dock-booting{flex:1 1 auto;display:grid;place-items:center;padding:24px;color:var(--gemboss-text-muted);font-size:14px}.gb-dock-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}@media (max-width: 420px){.gb-dock-status{display:none}}@media (max-width: 760px){.gb-dock{right:8px;left:8px;width:auto;padding-bottom:env(safe-area-inset-bottom);border-radius:12px 12px 0 0}.gb-dock-mini{width:auto}.gb-dock-full{inset:56px 0 0;border-radius:0}.gb-dock-side{left:0;right:0;width:auto;border-left:0;border-radius:0}.gb-dock-sidegrip,.gb-dock-pinside{display:none}}@media (min-width: 761px) and (max-width: 1099.98px){.gb-dock-side{left:240px;width:auto}.gb-dock-side .gb-dock-sidegrip,.gb-dock-pinside{display:none}}.gb-assistant-launcher{display:inline-flex;align-items:center;gap:8px;border:0;cursor:pointer;font-family:var(--gemboss-font-sans, system-ui, sans-serif)}.gb-assistant-launcher svg{flex:0 0 auto}.gb-assistant-launcher:focus-visible{outline:2px solid var(--gemboss-accent, #5661f5);outline-offset:2px}.gb-assistant-launcher--rail{width:100%;min-height:44px;margin:8px 0 4px;padding:0 12px;border-radius:var(--gemboss-radius-md, 8px);background:var(--gemboss-accent-soft);color:var(--gemboss-accent-strong);font-size:13px;font-weight:600;line-height:1;text-align:left}.gb-assistant-launcher--rail:hover{background:color-mix(in srgb,var(--gemboss-accent) 16%,var(--gemboss-surface))}.gb-assistant-launcher--rail .gb-assistant-launcher-label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gb-assistant-launcher-kbd{font:inherit;font-size:11px;opacity:.7;border:1px solid currentColor;border-radius:5px;padding:1px 5px}.gb-assistant-launcher--topbar{display:none;position:relative;justify-content:center;flex:0 0 auto;width:44px;height:44px;padding:0;border-radius:var(--gemboss-radius-md, 8px);background:transparent;color:var(--gemboss-text, #1b1c1e)}.gb-assistant-launcher--topbar:hover,.gb-assistant-launcher--topbar:active{background:var(--gemboss-hover, #eceef2)}.gb-assistant-launcher--topbar .gb-assistant-launcher-label,.gb-assistant-launcher--topbar .gb-assistant-launcher-kbd{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}@media (max-width: 760px){.gb-assistant-launcher--rail{display:none}.gb-assistant-launcher--topbar{display:inline-flex}}
|
|
1
|
+
.gb-dock{position:fixed;z-index:320;right:24px;bottom:0;width:min(460px,calc(100vw - 288px));display:flex;flex-direction:column;min-height:0;background:var(--gemboss-surface);background:color-mix(in srgb,var(--gemboss-surface) 93%,transparent);-webkit-backdrop-filter:blur(14px) saturate(1.4);backdrop-filter:blur(14px) saturate(1.4);border:1px solid var(--gemboss-divider);border-bottom:0;border-radius:12px 12px 0 0;box-shadow:0 -2px 6px #0f172a0d,0 24px 64px #0f172a2e;overflow:hidden;transition:transform .14s cubic-bezier(.2,.8,.3,1),opacity .14s ease-out}@starting-style{.gb-dock-dock,.gb-dock-mini{transform:translateY(10px);opacity:0}.gb-dock-side{transform:translate(12px);opacity:0}}.gb-dock-dragging,.gb-dock-dragging *{transition:none!important}@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))){.gb-dock{background:var(--gemboss-surface)}}@media (prefers-reduced-motion: reduce){.gb-dock{transition:none}}.gb-dock-hidden{display:none}.gb-dock-full{z-index:4;inset:56px 0 0 240px;width:auto;border:0;border-radius:0;box-shadow:none;background:var(--gemboss-app-bg)}.gb-dock-side{z-index:290;top:56px;right:0;bottom:0;width:var(--gb-dock-side-w, 400px);background:var(--gemboss-surface);-webkit-backdrop-filter:none;backdrop-filter:none;border:0;border-left:1px solid var(--gemboss-divider);border-radius:0;box-shadow:none;overflow:visible}.gb-dock-side .gb-dock-body,.gb-dock-side .gb-dock-pane{overflow:hidden}.gb-dock-side .gb-dock-header{cursor:default;touch-action:auto}.gb-dock-side .gb-dock-status{flex:0 0 auto;position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.gb-dock-side .gb-dock-header:active{cursor:default}.gb-dock-side>.gb-dock-sidegrip{position:absolute;top:0;bottom:0;left:-3px;width:5px;z-index:3}@media (min-width: 1100px){body.gemboss-assistant-side .gemboss-platform-main{margin-right:var(--gb-assistant-side-w, 400px)}}.gb-dock-fullchrome{position:absolute;top:10px;right:16px;z-index:1;display:flex;gap:8px}.gb-dock-shrink{display:inline-flex;align-items:center;gap:6px;min-height:44px;padding:0 12px;border:1px solid var(--gemboss-divider);border-radius:var(--gemboss-radius-full);background:var(--gemboss-surface);color:var(--gemboss-text-muted);font:inherit;font-size:var(--gemboss-fs-caption);cursor:pointer;white-space:nowrap}.gb-dock-shrink:hover{background:var(--gemboss-hover);color:var(--gemboss-text)}.gb-dock-shrink:focus-visible{outline:2px solid var(--gemboss-primary);outline-offset:2px}.gb-dock-shrink svg{width:16px;height:16px;flex:0 0 auto}@media (max-width: 560px){.gb-dock-shrink span{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}.gb-dock-shrink{padding:0;width:44px;justify-content:center}.gb-dock-shrink-keep span{position:static;width:auto;height:auto;overflow:visible;clip:auto}.gb-dock-shrink-keep{padding:0 12px;width:auto}.gb-dock-fullchrome{position:static;justify-content:flex-end;padding:8px 12px 0}}.gb-dock-mini{height:auto;width:min(320px,calc(100vw - 288px));-webkit-backdrop-filter:blur(14px) saturate(1.4);backdrop-filter:blur(14px) saturate(1.4);border-radius:12px 12px 0 0}.gb-dock-mini .gb-dock-body{display:none}.gb-dock-minirow{display:flex;align-items:center;padding-right:4px}.gb-dock-minirow .gb-dock-minibar{flex:1 1 auto;min-width:0}.gb-dock-minirow .gb-dock-icon{flex:0 0 auto}.gb-dock-minibar{display:flex;align-items:center;gap:8px;width:100%;min-height:48px;padding:0 12px;border:0;background:transparent;font:inherit;color:var(--gemboss-text-strong);cursor:pointer;text-align:left}.gb-dock-minibar:hover{background:var(--gemboss-hover)}.gb-dock-minibar strong{font-size:13px;font-weight:600;flex:0 0 auto}.gb-dock-ministatus{flex:1 1 auto;min-width:0;font-size:12px;color:var(--gemboss-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gb-dock-minichevron{font-size:10px;color:var(--gemboss-text-muted)}.gb-dock-grip{position:absolute;top:0;left:0;right:0;height:14px;z-index:2;display:grid;place-items:center;cursor:ns-resize;touch-action:none;background:transparent}.gb-dock-grip>span{display:block;width:44px;height:4px;border-radius:2px;background:var(--gemboss-divider)}.gb-dock-grip:hover>span,.gb-dock-grip:focus-visible>span{background:var(--gemboss-text-muted)}.gb-dock-grip:focus-visible{outline:2px solid var(--gemboss-primary);outline-offset:-2px}.gb-dock-header{flex:0 0 auto;cursor:grab;touch-action:none;user-select:none;display:flex;align-items:center;gap:8px;padding:0 4px 0 16px;min-height:48px;border-bottom:1px solid var(--gemboss-divider);background:transparent}.gb-dock-title{font-size:13px;font-weight:600;color:var(--gemboss-text-strong);white-space:nowrap;flex:0 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis}.gb-dock-status{flex:1 1 auto;min-width:0;font-size:12px;color:var(--gemboss-text-muted);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gb-dock-header:active{cursor:grabbing}.gb-dock-actions{display:flex;align-items:center;gap:2px;cursor:default;margin-left:auto}.gb-dock-action{margin-right:8px}.gb-dock-menu{position:relative}.gb-dock-menu>summary{list-style:none}.gb-dock-menu>summary::-webkit-details-marker{display:none}.gb-dock-menu[open]>summary{color:var(--gemboss-text-strong);background:var(--gemboss-hover)}.gb-dock-menu-list{position:absolute;top:calc(100% + 4px);right:0;z-index:5;display:grid;min-width:220px;padding:4px;box-sizing:border-box;cursor:default}.gb-dock-menu-list>.ui-menu__item{border-radius:8px}.gb-dock-menu-list>.ui-menu__item:disabled{opacity:.5;cursor:not-allowed;background:transparent}.gb-dock-menu-sep{height:1px;margin:4px 0;border:0;background:var(--gemboss-divider)}.gb-dock-menu-pill{width:44px;padding:0;justify-content:center}.gb-dock-menu-pill svg{width:18px;height:18px}.gb-dock-icon{width:44px;height:44px;display:grid;place-items:center;border:0;border-radius:8px;background:transparent;color:var(--gemboss-text-muted);cursor:pointer;padding:0}.gb-dock-icon:hover{background:var(--gemboss-hover);color:var(--gemboss-text-strong)}.gb-dock-icon:focus-visible{outline:2px solid var(--gemboss-primary);outline-offset:-2px}.gb-dock-icon svg{width:18px;height:18px}.gb-dock-icon-on{color:var(--gemboss-active-fg);background:var(--gemboss-active-bg)}.gb-dock-dot{flex:0 0 auto;width:8px;height:8px;border-radius:50%;background:var(--gemboss-divider)}.gb-dock-dot-busy{background:var(--gemboss-primary);animation:gb-dock-pulse 1.4s ease-in-out infinite}.gb-dock-dot-unread{background:var(--gemboss-success-strong)}@keyframes gb-dock-pulse{0%,to{opacity:1}50%{opacity:.35}}@media (prefers-reduced-motion: reduce){.gb-dock-dot-busy{animation:none}}.gb-dock-tabs{flex:0 0 auto;display:flex;gap:4px;padding:0 8px;border-bottom:1px solid var(--gemboss-divider)}.gb-dock-tab{position:relative;display:inline-flex;align-items:center;gap:6px;min-height:44px;padding:0 12px;border:0;border-bottom:2px solid transparent;background:transparent;color:var(--gemboss-text-muted);font:inherit;font-size:13px;cursor:pointer;white-space:nowrap}.gb-dock-tab:hover{color:var(--gemboss-text-strong)}.gb-dock-tab[aria-selected=true]{color:var(--gemboss-text-strong);font-weight:600;border-bottom-color:var(--gemboss-primary)}.gb-dock-tab:focus-visible{outline:2px solid var(--gemboss-primary);outline-offset:-2px}.gb-dock-badge{min-width:18px;padding:0 6px;border-radius:var(--gemboss-radius-full);background:var(--gemboss-primary);color:var(--gemboss-on-primary, #fff);font-size:11px;font-weight:700;line-height:18px;text-align:center}.gb-dock-body{flex:1 1 auto;min-height:0;display:flex;min-width:0}.gb-dock-body>*{flex:1 1 auto;min-width:0;min-height:0}.gb-dock-pane{display:flex;min-width:0;min-height:0}.gb-dock-pane>*{flex:1 1 auto;min-width:0;min-height:0}.gb-dock-body .gemboss-assistant-layout,.gb-dock-body .gemboss-assistant-page{height:auto;min-height:0}.gb-dock-pane[hidden]{display:none}.gb-dock-booting{flex:1 1 auto;display:grid;place-items:center;padding:24px;color:var(--gemboss-text-muted);font-size:14px}.gb-dock-sr{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}@media (max-width: 420px){.gb-dock-status{display:none}}@media (max-width: 760px){.gb-dock{right:8px;left:8px;width:auto;padding-bottom:env(safe-area-inset-bottom);border-radius:12px 12px 0 0}.gb-dock-mini{width:auto}.gb-dock-full{inset:56px 0 0;border-radius:0}.gb-dock-side{left:0;right:0;width:auto;border-left:0;border-radius:0}.gb-dock-sidegrip,.gb-dock-pinside{display:none}.gb-dock-menu-list>.gb-dock-pinside{display:none}}@media (min-width: 761px) and (max-width: 1099.98px){.gb-dock-side{left:240px;width:auto}.gb-dock-side .gb-dock-sidegrip,.gb-dock-pinside{display:none}.gb-dock-menu-list>.gb-dock-pinside{display:none}}.gb-assistant-launcher{display:inline-flex;align-items:center;gap:8px;border:0;cursor:pointer;font-family:var(--gemboss-font-sans, system-ui, sans-serif)}.gb-assistant-launcher svg{flex:0 0 auto}.gb-assistant-launcher:focus-visible{outline:2px solid var(--gemboss-accent, #5661f5);outline-offset:2px}.gb-assistant-launcher--rail{width:100%;min-height:44px;margin:8px 0 4px;padding:0 12px;border-radius:var(--gemboss-radius-md, 8px);background:var(--gemboss-accent-soft);color:var(--gemboss-accent-strong);font-size:13px;font-weight:600;line-height:1;text-align:left}.gb-assistant-launcher--rail:hover{background:color-mix(in srgb,var(--gemboss-accent) 16%,var(--gemboss-surface))}.gb-assistant-launcher--rail .gb-assistant-launcher-label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gb-assistant-launcher-kbd{font:inherit;font-size:11px;opacity:.7;border:1px solid currentColor;border-radius:5px;padding:1px 5px}.gb-assistant-launcher--topbar{display:none;position:relative;justify-content:center;flex:0 0 auto;width:44px;height:44px;padding:0;border-radius:var(--gemboss-radius-md, 8px);background:transparent;color:var(--gemboss-text, #1b1c1e)}.gb-assistant-launcher--topbar:hover,.gb-assistant-launcher--topbar:active{background:var(--gemboss-hover, #eceef2)}.gb-assistant-launcher--topbar .gb-assistant-launcher-label,.gb-assistant-launcher--topbar .gb-assistant-launcher-kbd{position:absolute;width:1px;height:1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}@media (max-width: 760px){.gb-assistant-launcher--rail{display:none}.gb-assistant-launcher--topbar{display:inline-flex}}
|
package/src/chat-plain.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(function(O){"use strict";var N=O.gembossUI;if(!N){O.console&&O.console.error("@gemboss/ui chat-plain.js: load kit-plain.js first (it defines gembossUI)");return}if(N.chat)return;var b={thread:"Conversation",message:"Message",send:"Send",stop:"Stop",attach:"Attach a file",copy:"Copy",copied:"Copied",copyCommand:"Copy command",originalError:"Original error",stopped:"Stopped",steps:"What it is doing",thought:"Thought",thinking:"Thinking",working:"Working",showLess:"Show less",showAll:"Show all {n} lines",openImage:"Open image"},S="http://www.w3.org/2000/svg",A=function(e){return typeof Node<"u"&&e instanceof Node};function l(e,n,r){var t=document.createElement(e);if(n)for(var a in n){var i=n[a];i==null||i===!1||(a==="text"?t.textContent=String(i):a==="className"?t.className=i:t.setAttribute(a,i===!0?"":String(i)))}return R(t,r),t}function R(e,n){return n==null||n===!1?e:Array.isArray(n)?(n.forEach(function(r){R(e,r)}),e):(e.appendChild(A(n)?n:document.createTextNode(String(n))),e)}function M(e,n,r){var t=document.createElementNS(S,"svg");if(t.setAttribute("viewBox",e),t.setAttribute("aria-hidden","true"),t.setAttribute("focusable","false"),n.forEach(function(i){var s=document.createElementNS(S,i.tag||"path");for(var o in i)o!=="tag"&&s.setAttribute(o,i[o]);t.appendChild(s)}),r)for(var a in r)t.setAttribute(a,r[a]);return t}var ae=[{host:"gemwatcher-api-production.up.railway.app",path:"/watch/artifacts/"},{host:"gemmedia-api-production.up.railway.app",path:"/"},{host:"media.gemboss.ai",path:"/v1/theme-media/assets/"},{host:"gemmedia.ops.gemboss.ai",path:"/v1/theme-media/assets/"},{host:"gemmedia.gemboss.ai",path:"/v1/theme-media/assets/"},{host:"cdn.shopify.com",path:"/"}],q=/[\u0000-\u001f\u007f]/g;function C(e){var n=String(e).replace(q,"").trim();return n?n.charAt(0)==="/"?n.charAt(1)==="/"||n.charAt(1)==="\\"?null:{href:n,internal:!0}:/^(https?:\/\/|mailto:)/i.test(n)?{href:n,internal:!1}:null:null}var D="https://same-origin.invalid",ie=/^\/[^/]+(\/[^/]+)*\/$/;function H(e,n){var r=String(e).replace(q,"").trim(),t;if(r.charAt(0)==="/"){var a=(n||[]).filter(function(s){return!s.host&&ie.test(s.path)});if(!a.length||r.charAt(1)==="/"||r.indexOf("\\")>=0||/%(2f|5c|25)|;/i.test(r))return null;try{t=new URL(r,D)}catch{return null}return t.origin!==D||/\.\.|%2e/i.test(t.pathname)?null:a.some(function(s){return t.pathname.indexOf(s.path)===0})?t.href.slice(D.length):null}try{t=new URL(r)}catch{return null}if(t.protocol!=="https:"||t.username||t.password||t.port)return null;var i=t.hostname.toLowerCase();return ae.concat(n||[]).some(function(s){return s.host===i&&t.pathname.indexOf(s.path)===0})?t.href:null}var T=function(e,n){return e.split(n).length-1};function P(e,n){var r=e.length,t,a,i,s,o=T(e,"("),d=T(e,")"),f=T(e,"["),c=T(e,"]");for(n=n!==!1;n&&r>0;)t=e.charAt(r-1),/[.,:;!?_~'"]/.test(t)?r-=1:t===")"&&o<d?(r-=1,d-=1):t==="]"&&f<c?(r-=1,c-=1):n=!1;if(s=e.slice(0,r),a=C(s),!a||a.internal)return null;try{i=new URL(a.href)}catch{return null}return!/^https?:$/.test(i.protocol)||!i.hostname?null:{href:a.href,rest:e.slice(r)}}var le=/(`([^`]+)`)|(\*\*([^*]+)\*\*)|(\*([^*\n]+)\*)|(!\[([^\]]*)\]\(([^)\s]+)\))|(\[([^\]]+)\]\(([^)\s]+)\))|(<(https?:\/\/[^\s<>]+)>)|(https?:\/\/[^\s<>`"*\u2000-\u206f\u3000-\u9fff\uff00-\uffef]+)/gi;function F(e,n){n=n||{};for(var r=[],t=function(m){if(m){var v=r[r.length-1];v&&v.t==="text"?v.text+=m:r.push({t:"text",text:m})}},a=new RegExp(le.source,"gi"),i=0,s;(s=a.exec(e))!==null;){if(t(e.slice(i,s.index)),s[2]!=null)r.push({t:"code",text:s[2]});else if(s[4]!=null)r.push({t:"bold",text:s[4]});else if(s[6]!=null)r.push({t:"italic",text:s[6]});else if(s[7]!=null){var o=H(s[9],n.imageHosts),d=s[8].trim();if(o)r.push({t:"image",alt:d,src:o});else{var f=C(s[9]);f&&!f.internal?r.push({t:"link",label:d||"image",href:f.href,internal:!1}):t(d)}}else if(s[10]!=null){var c=s[12],p=n.ownLink&&n.ownLink(c)?{href:c,internal:!0}:C(c);p?r.push({t:"link",label:s[11],href:p.href,internal:p.internal}):t(s[11])}else{var h=s[15]!=null&&s.index>0&&/[a-z\d]/i.test(e.charAt(s.index-1)),g=h?null:s[14]!=null?P(s[14],!1):P(s[15]);g?(r.push({t:"link",label:g.href,href:g.href,internal:!1}),t(g.rest)):t(s[0])}i=s.index+s[0].length}return t(e.slice(i)),r}var $=function(e){return/^\s*\|.*\|\s*$/.test(e)},se=function(e){return/^\s*\|?[\s:-]*-[-\s:|]*\|?\s*$/.test(e)&&e.indexOf("-")>=0},U=function(e){return e.trim().replace(/^\||\|$/g,"").split("|").map(function(n){return n.trim()})};function K(e){for(var n=String(e??"").split(`
|
|
1
|
+
(function(O){"use strict";var N=O.gembossUI;if(!N){O.console&&O.console.error("@gemboss/ui chat-plain.js: load kit-plain.js first (it defines gembossUI)");return}if(N.chat)return;var b={thread:"Conversation",message:"Message",send:"Send",stop:"Stop",attach:"Attach a file",copy:"Copy",copied:"Copied",copyCommand:"Copy command",originalError:"Original error",stopped:"Stopped",steps:"What it is doing",thought:"Thought",thinking:"Thinking",working:"Working",showLess:"Show less",showAll:"Show all {n} lines",openImage:"Open image"},S="http://www.w3.org/2000/svg",A=function(e){return typeof Node<"u"&&e instanceof Node};function l(e,n,r){var t=document.createElement(e);if(n)for(var a in n){var i=n[a];i==null||i===!1||(a==="text"?t.textContent=String(i):a==="className"?t.className=i:t.setAttribute(a,i===!0?"":String(i)))}return R(t,r),t}function R(e,n){return n==null||n===!1?e:Array.isArray(n)?(n.forEach(function(r){R(e,r)}),e):(e.appendChild(A(n)?n:document.createTextNode(String(n))),e)}function M(e,n,r){var t=document.createElementNS(S,"svg");if(t.setAttribute("viewBox",e),t.setAttribute("aria-hidden","true"),t.setAttribute("focusable","false"),n.forEach(function(i){var s=document.createElementNS(S,i.tag||"path");for(var o in i)o!=="tag"&&s.setAttribute(o,i[o]);t.appendChild(s)}),r)for(var a in r)t.setAttribute(a,r[a]);return t}var ae=[{host:"gemwatcher-api-production.up.railway.app",path:"/watch/artifacts/"},{host:"gemmedia-api-production.up.railway.app",path:"/"},{host:"media.gemboss.ai",path:"/v1/theme-media/assets/"},{host:"gemmedia.ops.gemboss.ai",path:"/v1/theme-media/assets/"},{host:"gemmedia.gemboss.ai",path:"/v1/theme-media/assets/"},{host:"cdn.shopify.com",path:"/"}],q=/[\u0000-\u001f\u007f]/g;function C(e){var n=String(e).replace(q,"").trim();return n?n.charAt(0)==="/"?n.charAt(1)==="/"||n.charAt(1)==="\\"?null:{href:n,internal:!0}:/^(https?:\/\/|mailto:)/i.test(n)?{href:n,internal:!1}:null:null}var D="https://same-origin.invalid",ie=/^\/[^/]+(\/[^/]+)*\/$/;function H(e,n){var r=String(e).replace(q,"").trim(),t;if(r.charAt(0)==="/"){var a=(n||[]).filter(function(s){return!s.host&&ie.test(s.path)});if(!a.length||r.charAt(1)==="/"||r.indexOf("\\")>=0||/%(2f|5c|25)|;/i.test(r))return null;try{t=new URL(r,D)}catch{return null}return t.origin!==D||/\.\.|%2e/i.test(t.pathname)?null:a.some(function(s){return t.pathname.indexOf(s.path)===0})?t.href.slice(D.length):null}try{t=new URL(r)}catch{return null}if(t.protocol!=="https:"||t.username||t.password||t.port)return null;var i=t.hostname.toLowerCase();return ae.concat(n||[]).some(function(s){return s.host===i&&t.pathname.indexOf(s.path)===0})?t.href:null}var T=function(e,n){return e.split(n).length-1};function P(e,n){var r=e.length,t,a,i,s,o=T(e,"("),d=T(e,")"),f=T(e,"["),c=T(e,"]");for(n=n!==!1;n&&r>0;)t=e.charAt(r-1),/[.,:;!?_~'"]/.test(t)?r-=1:t===")"&&o<d?(r-=1,d-=1):t==="]"&&f<c?(r-=1,c-=1):n=!1;if(s=e.slice(0,r),a=C(s),!a||a.internal)return null;try{i=new URL(a.href)}catch{return null}return!/^https?:$/.test(i.protocol)||!i.hostname?null:{href:a.href,rest:e.slice(r)}}var le=/(`([^`]+)`)|(\*\*([^*]+)\*\*)|(\*([^*\n]+)\*)|(!\[([^\]]*)\]\(([^)\s]+)\))|(\[([^\]]+)\]\(([^)\s]+)\))|(<(https?:\/\/[^\s<>]+)>)|(https?:\/\/[^\s<>`"*\u2000-\u206f\u3000-\u9fff\uff00-\uffef]+)/gi;function F(e,n){n=n||{};for(var r=[],t=function(m){if(m){var v=r[r.length-1];v&&v.t==="text"?v.text+=m:r.push({t:"text",text:m})}},a=new RegExp(le.source,"gi"),i=0,s;(s=a.exec(e))!==null;){if(t(e.slice(i,s.index)),s[2]!=null)r.push({t:"code",text:s[2]});else if(s[4]!=null)r.push({t:"bold",text:s[4]});else if(s[6]!=null)r.push({t:"italic",text:s[6]});else if(s[7]!=null){var o=H(s[9],n.imageHosts),d=s[8].trim();if(o)r.push({t:"image",alt:d,src:o});else{var f=C(s[9]);f&&!f.internal?r.push({t:"link",label:d||"image",href:f.href,internal:!1}):t(d)}}else if(s[10]!=null){var c=s[12],p=n.ownLink&&n.ownLink(c)?{href:c,internal:!0,own:!0}:C(c);p?r.push({t:"link",label:s[11],href:p.href,internal:p.internal}):t(s[11])}else{var h=s[15]!=null&&s.index>0&&/[a-z\d]/i.test(e.charAt(s.index-1)),g=h?null:s[14]!=null?P(s[14],!1):P(s[15]);g?(r.push({t:"link",label:g.href,href:g.href,internal:!1}),t(g.rest)):t(s[0])}i=s.index+s[0].length}return t(e.slice(i)),r}var $=function(e){return/^\s*\|.*\|\s*$/.test(e)},se=function(e){return/^\s*\|?[\s:-]*-[-\s:|]*\|?\s*$/.test(e)&&e.indexOf("-")>=0},U=function(e){return e.trim().replace(/^\||\|$/g,"").split("|").map(function(n){return n.trim()})};function K(e){for(var n=String(e??"").split(`
|
|
2
2
|
`),r=[],t=0,a=[],i=function(){a.length&&r.push({t:"para",lines:a.slice()}),a.length=0};t<n.length;){var s=n[t],o;if(o=/^\s*```([\w#+.-]*)\s*$/.exec(s)){i();var d=[];for(t+=1;t<n.length&&!/^\s*```\s*$/.test(n[t]);)d.push(n[t]),t+=1;t+=1,r.push({t:"code",lang:o[1]||"",body:d.join(`
|
|
3
3
|
`)});continue}if(o=/^(#{1,6})\s+(.*)$/.exec(s)){i(),o[2].trim()&&r.push({t:"heading",level:Math.min(o[1].length,3),text:o[2].trim()}),t+=1;continue}if(/^\s*(---|\*\*\*|___)\s*$/.test(s)){i(),r.push({t:"rule"}),t+=1;continue}if($(s)&&t+1<n.length&&se(n[t+1])){i();var f=U(s),c=[];for(t+=2;t<n.length&&$(n[t]);)c.push(U(n[t])),t+=1;r.push({t:"table",head:f,rows:c});continue}if(o=/^\s*([-*+]|\d+[.)])\s+(.*)$/.exec(s)){i();for(var p=/\d/.test(o[1]),h=p?parseInt(o[1],10):void 0,g=[];t<n.length;){var m=/^\s*([-*+]|\d+[.)])\s+(.*)$/.exec(n[t]);if(!m||/\d/.test(m[1])!==p)break;g.push(m[2]),t+=1}var v={t:"list",ordered:p,items:g};h!==void 0&&h!==1&&(v.start=h),r.push(v);continue}if(/^\s*>\s?/.test(s)){i();for(var y=[];t<n.length&&/^\s*>\s?/.test(n[t]);)y.push(n[t].replace(/^\s*>\s?/,"")),t+=1;r.push({t:"quote",lines:y});continue}if(s.trim()===""){i(),t+=1;continue}a.push(s),t+=1}return i(),r}var j=12;function L(e,n,r){return F(e,n).map(function(t){if(t.t==="text")return document.createTextNode(t.text);if(t.t==="code")return l("code",{className:"gemboss-md-code",text:t.text});if(t.t==="bold")return l("strong",{text:t.text});if(t.t==="italic")return l("em",{text:t.text});if(t.t==="link"){if(n.ownLink&&n.ownLink(t.href)&&n.renderLink)return n.renderLink(t.href,t.label)||document.createTextNode(t.label);var a=l("a",{className:"gemboss-ec-md-link",href:t.href,target:t.internal?null:"_blank",rel:t.internal?null:"noopener noreferrer",text:t.label});return t.internal&&n.onNavigate&&a.addEventListener("click",function(i){i.metaKey||i.ctrlKey||i.shiftKey||(i.preventDefault(),n.onNavigate(t.href))}),a}return l("a",{className:"gemboss-md-imglink",href:t.src,target:"_blank",rel:"noopener noreferrer","aria-label":t.alt?null:r.openImage},l("img",{className:"gemboss-md-img",src:t.src,alt:t.alt,loading:"lazy",referrerpolicy:"no-referrer"}))})}function z(e,n,r){var t=[];return e.forEach(function(a,i){t=t.concat(L(a,n,r)),i<e.length-1&&t.push(l("br"))}),t}function oe(e,n){var r=e.body.split(`
|
|
4
4
|
`),t=r.length>j,a=!1,i=l("code",{text:t?r.slice(0,j).join(`
|
package/src/collections.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
:root{--ui-coll-head-bg: color-mix(in srgb, var(--ui-text, #1b1c1e) 3.5%, var(--ui-surface, #fff));--ui-coll-hover: color-mix(in srgb, var(--ui-text, #1b1c1e) 3.5%, var(--ui-surface, #fff));--ui-coll-selected: color-mix(in srgb, var(--ui-text, #1b1c1e) 6%, var(--ui-surface, #fff));--ui-coll-check-w: 40px}.ui-table--sticky-first tr{background:var(--ui-surface)}.ui-table--sticky-first tbody tr:hover{background:var(--ui-surface-2)}.ui-table--sticky-first :is(th,td):first-child{position:sticky;left:0;z-index:1;background:inherit}@supports (animation-timeline: scroll()){.ui-table-wrap:has(>.ui-table--sticky-first){scroll-timeline:--ui-coll-x inline}.ui-table--sticky-first :is(th,td):first-child{animation:ui-coll-edge linear both;animation-timeline:--ui-coll-x;animation-range:0 24px}}@keyframes ui-coll-edge{0%{box-shadow:none}to{box-shadow:1px 0 0 var(--ui-border),6px 0 8px -6px #0000002e}}.ui-table--compact :is(td,tbody th){padding-block:6px}.ui-table--compact thead th{padding-block:6px}.ui-table__totals>tr{background:var(--ui-coll-head-bg)}.ui-table__totals>tr>:is(td,th){background:var(--ui-coll-head-bg);font-weight:650;color:var(--ui-text);border-top:1px solid var(--ui-border);border-bottom:0}.ui-table__footer{padding:8px 12px;background:var(--ui-coll-head-bg);border-top:1px solid var(--ui-border);color:var(--ui-text-muted);font-size:var(--ui-fs-body);text-align:center}.ui-table th.ui-table__rowhead{font-weight:450;color:var(--ui-text);text-align:left}.ui-table th.ui-table__rowhead:not(.is-num){white-space:normal;min-width:9.0625rem}.ui-table th.ui-table__rowhead>a,.ui-table:where(:not(.ui-table--index)) tbody :is(td,th) li>a{display:inline-flex;align-items:center;min-height:24px}.ui-table:where(:not(.ui-table--index)) tbody :is(td,th){vertical-align:top}.ui-table:where(:not(.ui-table--index)) tbody :is(td>a,th.ui-table__rowhead>a,:is(td,th) li>a){margin-block:calc((1lh - 24px)/2)}.ui-table__sort{display:flex;width:max-content;max-width:100%;align-items:center;gap:4px;min-height:24px;margin-block:-2px;padding:0;border:0;background:none;color:inherit;font:inherit;text-align:inherit;text-decoration:none;cursor:pointer;white-space:nowrap}.ui-table__sort:hover{color:var(--ui-text)}.ui-table__sort:focus-visible{outline:2px solid var(--ui-focus);outline-offset:2px;border-radius:4px}.ui-table__sort:after{content:"";flex:none;width:16px;height:16px;background:currentColor;opacity:0;-webkit-mask:var(--ui-coll-arrow) center / 16px no-repeat;mask:var(--ui-coll-arrow) center / 16px no-repeat;--ui-coll-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 3.5v9M4.5 9 8 12.5 11.5 9' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")}.ui-table__sort:is(:hover,:focus-visible):after{opacity:.45}th[aria-sort=ascending]>.ui-table__sort:after,th[aria-sort=descending]>.ui-table__sort:after{opacity:1}th[aria-sort=ascending]>.ui-table__sort:after{transform:rotate(180deg)}th[aria-sort=ascending]>.ui-table__sort,th[aria-sort=descending]>.ui-table__sort{color:var(--ui-text)}.ui-table .is-num>.ui-table__sort{flex-direction:row-reverse;margin-left:auto}.ui-trunc{display:block;max-width:var(--ui-trunc, 32ch);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-clamp-2{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden;white-space:normal;overflow-wrap:anywhere}.ui-index{position:relative;container:ui-index / inline-size;min-width:0}.ui-table--index{font-size:var(--ui-fs-body)}.ui-table--index tr{background:var(--ui-surface)}.ui-table.ui-table--index thead th{padding:8px 6px;background:var(--ui-coll-head-bg);color:var(--ui-text-muted);font-size:var(--ui-fs-caption);line-height:20px;font-weight:550;text-transform:none;letter-spacing:0}.ui-table.ui-table--index :is(td,tbody th){padding:6px;line-height:20px;white-space:nowrap;vertical-align:middle;border-bottom:0;border-top:1px solid var(--ui-border)}.ui-table.ui-table--index :is(th,td):where(:first-child){padding-left:var(--ui-space-3)}.ui-table.ui-table--index :is(th,td):where(:last-child){padding-right:var(--ui-space-3)}.ui-table--index tbody tr:hover{background:var(--ui-coll-hover)}.ui-table--index tbody tr:is(.is-selected,[aria-selected=true]){background:var(--ui-coll-selected)}.ui-table--index tbody tr:is([data-href],.is-linked){cursor:pointer}.ui-table--index tbody tr:has(.ui-table__title:focus-visible){outline:2px solid var(--ui-focus);outline-offset:-2px}.ui-table__title:focus-visible{outline:none}.ui-table__primary{min-width:0}.ui-table__primary-inner{display:flex;align-items:center;gap:var(--ui-space-3);min-width:0}.ui-table__primary-text{min-width:0}.ui-table__title{display:block;max-width:var(--ui-trunc, 40ch);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ui-text);font-weight:650;text-decoration:none}a.ui-table__title:hover{text-decoration:underline}.ui-table--index .ui-table__title+.ui-sub,.ui-table--index .ui-sub{display:block;max-width:var(--ui-trunc, 40ch);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-top:0;line-height:16px}.ui-table--index td>a.ui-table__title{display:block;min-height:0}.ui-table--index td>.ui-table__primary-inner>a.ui-table__title,.ui-table--index .ui-table__primary-text>a.ui-table__title{line-height:20px}.ui-table.ui-table--index .ui-table__check{width:var(--ui-coll-check-w);padding:6px 8px 6px 12px}.ui-table.ui-table--index thead .ui-table__check{padding:8px 8px 8px 12px}.ui-table__checkbox{display:flex;width:max-content;align-items:center;justify-content:center;min-width:24px;min-height:24px;margin:-2px 0;cursor:pointer}.ui-table__checkbox>input,.ui-list__check>input{width:16px;height:16px;margin:0;accent-color:var(--ui-accent);cursor:pointer}.ui-table__checkbox>input:focus-visible,.ui-list__check>input:focus-visible{outline:2px solid var(--ui-focus);outline-offset:2px}.ui-table--index :is(.ui-table__check,.ui-table__primary){position:sticky;z-index:1;background:inherit}.ui-table--index .ui-table__check,.ui-table--index .ui-table__primary{left:0}.ui-table--index:has(.ui-table__check) .ui-table__primary{left:var(--ui-coll-check-w)}.ui-table__actions{width:1%;text-align:right}.ui-table__actions>*{vertical-align:middle}.ui-row-actions{display:inline-flex;align-items:center;gap:var(--ui-space-2)}.ui-bulkbar{position:relative;z-index:3;display:flex;flex-wrap:wrap;align-items:center;gap:var(--ui-space-2);box-sizing:border-box;min-height:38px;margin-bottom:-38px;padding:4px 8px 4px 12px;background:var(--ui-surface);border:1px solid var(--ui-border);border-bottom-color:transparent;border-radius:var(--ui-radius-lg) var(--ui-radius-lg) 0 0;font-size:var(--ui-fs-body)}.ui-bulkbar[hidden]{display:none}.ui-bulkbar__count{font-weight:550;font-variant-numeric:tabular-nums}.ui-bulkbar__actions{display:inline-flex;flex-wrap:wrap;gap:var(--ui-space-2);margin-left:auto}.ui-bulkbar .ui-table__checkbox{margin-right:4px}.ui-index__sortbar{display:none}@container ui-index (max-width: 768px){.ui-table--index,.ui-table--index tbody{display:block;width:100%}.ui-table--index thead{display:none}.ui-table--index tbody tr{position:relative;display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 12px;min-height:44px;box-sizing:border-box;padding:10px 12px;border-top:1px solid var(--ui-border)}.ui-table--index tbody tr:first-child{border-top:0}.ui-table--index tbody tr:has(>.ui-table__check){padding-left:48px}.ui-table.ui-table--index tbody :is(td,th){display:block;padding:0;border:0;position:static;background:none;white-space:nowrap}.ui-table--index tbody .ui-table__primary{flex:1 0 100%;white-space:normal}.ui-table--index tbody td:not(.ui-table__primary,.ui-table__check,.ui-table__actions){flex:none;max-width:100%;overflow:hidden;text-overflow:ellipsis;color:var(--ui-text-muted);font-size:var(--ui-fs-caption);line-height:18px}.ui-table--index tbody td[data-label]:not(.ui-table__primary):before{content:attr(data-label) " ";color:var(--ui-text-muted)}.ui-table--index tbody td:not(.ui-table__primary,.ui-table__check,.ui-table__actions) .ui-trunc{display:inline-block;vertical-align:bottom}.ui-table--index tbody td:not(.ui-table__primary,.ui-table__check,.ui-table__actions) .ui-sub{display:inline;margin-left:6px}.ui-table--index tbody td.is-num{text-align:left}.ui-table--index tbody td[data-condensed=hide]{display:none}.ui-table.ui-table--index tbody .ui-table__check{position:absolute;left:4px;top:4px;width:auto;padding:0}.ui-table.ui-table--index tbody .ui-table__actions{order:99;margin-left:auto;width:auto;padding:0;align-self:center}.ui-table--index .ui-table__checkbox{min-width:44px;min-height:44px;margin:0}.ui-table--index .ui-table__title,.ui-table--index .ui-sub{max-width:none}.ui-index__sortbar{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ui-space-2);margin:0 0 var(--ui-space-3);font-size:var(--ui-fs-caption);color:var(--ui-text-muted)}.ui-index .ui-bulkbar{margin-bottom:var(--ui-space-2);border-bottom-color:var(--ui-border);border-radius:var(--ui-radius-lg)}.ui-index .ui-table-wrap{overflow-x:visible}}.ui-list{container:ui-list / inline-size;margin:0;padding:0;list-style:none;background:var(--ui-surface);border:1px solid var(--ui-border);border-radius:var(--ui-radius-lg);box-shadow:var(--ui-card-shadow)}.ui-list--flush{border:0;border-radius:0;box-shadow:none;background:transparent}.ui-list__item{position:relative;display:flex;align-items:flex-start;gap:var(--ui-space-3);box-sizing:border-box;padding:var(--ui-space-3);min-height:44px;border-top:1px solid var(--ui-border)}.ui-list>.ui-list__item:first-child{border-top:0}.ui-list>.ui-list__item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.ui-list>.ui-list__item:last-child{border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.ui-list__item:has(.ui-list__title[href]):hover{background:var(--ui-coll-hover)}.ui-list__item:is(.is-selected,[aria-selected=true]){background:var(--ui-coll-selected)}.ui-list__item:has(.ui-list__title:focus-visible){outline:2px solid var(--ui-focus);outline-offset:-2px}.ui-list__media{flex:none;display:flex;align-items:center;min-height:40px}.ui-list__body{flex:1 1 auto;min-width:0}.ui-list__title{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ui-text);font-size:var(--ui-fs-body);line-height:20px;font-weight:650;text-decoration:none}.ui-list__title[href]:after{content:"";position:absolute;inset:0;z-index:0}.ui-list__title:focus-visible{outline:none}.ui-list__sub{margin:0;color:var(--ui-text-muted);font-size:var(--ui-fs-body);line-height:20px;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden;overflow-wrap:anywhere}.ui-list__meta{margin:2px 0 0;color:var(--ui-text-muted);font-size:var(--ui-fs-caption);line-height:16px}.ui-list__badges{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px}.ui-list__aside{flex:none;align-self:center;color:var(--ui-text);font-variant-numeric:tabular-nums;text-align:right}.ui-list__actions{flex:none;align-self:center;display:inline-flex;align-items:center;gap:var(--ui-space-2)}.ui-list__item :is(.ui-list__actions,.ui-list__aside a,.ui-list__body a:not(.ui-list__title),button,input,select,textarea,label,summary,details){position:relative;z-index:1}@container ui-list (max-width: 400px){.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item{display:grid;grid-template-columns:auto minmax(0,1fr) auto;grid-template-areas:"media body body" "media aside actions";gap:0;align-items:start}.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item>.ui-list__media{grid-area:media;margin-inline-end:var(--ui-space-3)}.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item>.ui-list__body{grid-area:body}.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item>.ui-list__aside{grid-area:aside;justify-self:start;align-self:center;margin-top:4px;text-align:left}.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item>.ui-list__actions{grid-area:actions;justify-self:end;align-self:center;margin:4px 0 0 var(--ui-space-3)}.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item:has(>.ui-list__body>.ui-list__title:only-child){grid-template-columns:auto minmax(0,1fr) auto auto;grid-template-areas:"media body aside actions";align-items:center}.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item:has(>.ui-list__body>.ui-list__title:only-child)>:is(.ui-list__aside,.ui-list__actions){margin-top:0}.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item:has(>.ui-list__body>.ui-list__title:only-child)>.ui-list__aside{margin-inline-start:var(--ui-space-3);text-align:right}}.ui-resource>.ui-bulkbar{margin-bottom:0;border-bottom-color:var(--ui-border)}.ui-resource>.ui-bulkbar:has(+.ui-list--flush){border-width:0 0 1px;border-radius:0}.ui-resource>.ui-list,.ui-resource>[aria-busy]>.ui-list{border-top:0;border-top-left-radius:0;border-top-right-radius:0}.ui-list__check{display:flex;flex:none;align-items:center;justify-content:center;min-width:24px;min-height:24px;cursor:pointer}.ui-list__check:not(:last-child){margin-inline-end:8px}@media (pointer: coarse),(max-width: 47.9975em){.ui-list__check{min-width:44px;min-height:44px;margin-block:-2px;margin-inline-start:-12px}.ui-list__check:not(:last-child){margin-inline-end:-2px}.ui-resource>.ui-bulkbar>.ui-table__checkbox{min-width:44px;min-height:44px;margin:-8px -8px -8px -12px}}.ui-thumb{display:block;flex:none;width:40px;height:40px;box-sizing:border-box;border:1px solid var(--ui-border);border-radius:var(--ui-radius-md);background:var(--ui-surface-2);overflow:hidden;object-fit:cover}.ui-thumb--xs{width:24px;height:24px;border-radius:var(--ui-radius-sm)}.ui-thumb--md{width:60px;height:60px}.ui-thumb--lg{width:80px;height:80px}.ui-thumb>img{display:block;width:100%;height:100%;object-fit:cover}.ui-list--compact>.ui-list__item{display:block;padding:0;min-height:0}.ui-list__row{display:flex;align-items:center;gap:var(--ui-space-2);box-sizing:border-box;width:100%;min-height:36px;padding:8px 12px;border:0;background:none;color:var(--ui-text);font:inherit;font-size:var(--ui-fs-body);line-height:20px;text-align:left;text-decoration:none;border-radius:inherit}:is(a,button).ui-list__row{cursor:pointer}:is(a,button).ui-list__row:hover{background:var(--ui-coll-hover)}:is(a,button).ui-list__row:focus-visible{outline:2px solid var(--ui-focus);outline-offset:-2px}.ui-list__row[aria-current=page],.ui-list__row.is-selected{background:var(--ui-coll-selected)}.ui-list__icon{flex:none;display:inline-flex;width:20px;height:20px;align-items:center;justify-content:center;color:var(--ui-text-muted)}.ui-list__icon>svg{width:16px;height:16px}.ui-list__label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-list__row>.ui-list__meta{flex:none;margin:0;font-variant-numeric:tabular-nums}@media (pointer: coarse),(max-width: 47.9975em){.ui-list__row{min-height:44px}}.ui-list--activity>.ui-list__item{display:grid;grid-template-columns:20px minmax(0,1fr) auto;column-gap:var(--ui-space-2);align-items:start;padding:8px 12px;min-height:36px;border-top:0}.ui-list--activity>.ui-list__item:before{content:"";position:absolute;left:21.5px;top:0;bottom:0;width:1px;background:var(--ui-border)}.ui-list--activity>.ui-list__item:first-child:before{top:14px}.ui-list--activity>.ui-list__item:last-child:before{bottom:calc(100% - 14px)}.ui-list--activity>.ui-list__item:only-child:before{display:none}.ui-list__dot{position:relative;z-index:1;width:8px;height:8px;margin:6px 0 0 6px;border-radius:50%;background:var(--ui-text-muted);box-shadow:0 0 0 3px var(--ui-surface)}.ui-list__dot--success{background:var(--gemboss-success, #0a8f6a)}.ui-list__dot--warning{background:var(--gemboss-warning, #b25e09)}.ui-list__dot--critical{background:var(--gemboss-danger-strong, #c70a24)}.ui-list__dot--info{background:var(--gemboss-accent, #5661f5)}.ui-list--activity .ui-list__label{display:block;white-space:nowrap}.ui-list--activity .ui-list__detail{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ui-text-muted);font-size:var(--ui-fs-caption);line-height:16px}.ui-list--activity time,.ui-list--activity .ui-list__time{color:var(--ui-text-muted);font-size:var(--ui-fs-caption);line-height:20px;white-space:nowrap;font-variant-numeric:tabular-nums}.ui-list__content{margin-top:4px;color:var(--ui-text);font-size:var(--ui-fs-body);line-height:20px;overflow-wrap:anywhere}.ui-list__content>p{margin:0}.ui-list__content>p+p{margin-top:4px}.ui-list--wrap .ui-list__label,.ui-list--wrap .ui-list__detail{white-space:normal;overflow:visible;text-overflow:clip;overflow-wrap:anywhere}.ui-list--wrap .ui-list__row{align-items:flex-start}@media (pointer: coarse),(max-width: 47.9975em){.ui-list--wrap .ui-list__row{padding-block:12px}}.ui-list--wrap .ui-list__row>.ui-list__meta{line-height:20px}.ui-cardgrid{--ui-cardgrid-min: 240px;display:grid;grid-template-columns:repeat(auto-fill,minmax(min(var(--ui-cardgrid-min),100%),1fr));gap:var(--ui-space-4);margin:0;padding:0;list-style:none}.ui-cardgrid[data-min="200"]{--ui-cardgrid-min: 200px}.ui-cardgrid[data-min="320"]{--ui-cardgrid-min: 320px}.ui-cardgrid>*{min-width:0}.ui-board{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(240px,1fr);gap:var(--ui-space-4);align-items:start;overflow-x:auto;overscroll-behavior-x:contain;scroll-snap-type:x mandatory;padding-bottom:4px}@media (max-width: 47.9975em){.ui-board{grid-auto-columns:78%}}.ui-board__col{display:flex;flex-direction:column;gap:var(--ui-space-2);min-width:0;padding:var(--ui-space-2);scroll-snap-align:start;background:var(--ui-coll-head-bg);border-radius:var(--ui-radius-lg)}.ui-board__head{display:flex;align-items:center;gap:var(--ui-space-2);min-height:28px;padding:0 4px;font-size:var(--ui-fs-body);font-weight:650}.ui-board__name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-board__count{margin-left:auto;color:var(--ui-text-muted);font-weight:450;font-variant-numeric:tabular-nums}.ui-board__dot{flex:none;width:8px;height:8px;border-radius:50%;background:var(--ui-text-muted)}.ui-board__dot--success{background:var(--gemboss-success, #0a8f6a)}.ui-board__dot--warning{background:var(--gemboss-warning, #b25e09)}.ui-board__dot--critical{background:var(--gemboss-danger-strong, #c70a24)}.ui-board__dot--info{background:var(--gemboss-accent, #5661f5)}.ui-board__list{display:grid;gap:var(--ui-space-2);margin:0;padding:0;list-style:none}.ui-board__list>li{min-width:0}.ui-board__empty{margin:0;padding:var(--ui-space-4) var(--ui-space-2);color:var(--ui-text-muted);font-size:var(--ui-fs-body);text-align:center;border:1px dashed var(--ui-border);border-radius:var(--ui-radius-md)}.ui-board__more>summary{list-style:none;justify-self:center;margin:4px auto 0;width:fit-content}.ui-board__more>summary::-webkit-details-marker{display:none}.ui-board__more[open]>summary{display:none}.ui-board__more{display:grid;gap:var(--ui-space-2)}.ui-board__next.ui-more{padding:4px 0 0}.ui-board__next .ui-more__error{color:var(--gemboss-danger-strong, #c70a24)}.ui-board[data-gb-move] .ui-board__list>li[data-id]{position:relative;border-radius:var(--ui-radius-lg);cursor:grab}.ui-board[data-gb-move] .ui-board__list>li[data-id]:focus-visible{outline:2px solid var(--ui-focus);outline-offset:2px}.ui-board__list>li[data-gb-lifted]{outline:2px solid var(--ui-focus);outline-offset:2px;box-shadow:var(--gemboss-shadow-md, 0 4px 12px rgba(0,0,0,.12));border-radius:var(--ui-radius-lg)}.ui-board[data-gb-dragging] .ui-board__list>li[data-gb-lifted]{outline:0;opacity:.4}.ui-board__col[data-gb-over]{background:color-mix(in srgb,var(--ui-focus) 10%,var(--ui-coll-head-bg))}.ui-board__list>li[data-gb-drop]:before{content:"";position:absolute;left:0;right:0;height:2px;border-radius:1px;background:var(--ui-focus);pointer-events:none}.ui-board__list>li[data-gb-drop=before]:before{top:-5px}.ui-board__list>li[data-gb-drop=after]:before{bottom:-5px}.ui-empty--no-match{padding-block:32px}.ui-coll-error{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ui-space-2) var(--ui-space-3);margin:var(--ui-space-3)}.ui-coll-error>:first-child{flex:1 1 240px;min-width:0}.ui-coll-count{margin-left:auto;color:var(--ui-text-muted);font-size:var(--ui-fs-body);font-variant-numeric:tabular-nums;white-space:nowrap}.ui-chip__x{margin-right:-4px;font-size:14px;line-height:1;opacity:.7}:is(.ui-table-wrap,.ui-index,.ui-list,.ui-cardgrid,.ui-board)[aria-busy=true]{position:relative}:is(.ui-table-wrap,.ui-index,.ui-list,.ui-cardgrid,.ui-board)[aria-busy=true]>:not(.ui-bulkbar,.ui-coll-busy){opacity:.55;pointer-events:none;transition:opacity .15s}.ui-coll-busy{position:absolute;top:8px;right:8px;z-index:4}:is(.ui-skeleton--table,.ui-skeleton--list,.ui-skeleton--compact,.ui-skeleton--grid,.ui-skeleton--board) .ui-skeleton__line{height:8px;border-radius:4px}.ui-skeleton--table td .ui-skeleton__line{width:70%;margin-block:6px}.ui-skeleton--table td:first-child .ui-skeleton__line{width:85%}.ui-skeleton--table tbody tr:hover{background:none}.ui-skeleton__block{display:block;flex:none;width:40px;height:40px;border-radius:var(--ui-radius-md);background:var(--ui-surface-2)}.ui-skeleton__block--round{border-radius:50%;width:32px;height:32px}.ui-skeleton--list>.ui-list__item{align-items:center}.ui-skeleton--list .ui-list__body{display:grid;gap:12px}.ui-skeleton--list .ui-list__body>.ui-skeleton__line:last-child{width:60%}.ui-skeleton--compact .ui-list__row{gap:12px}.ui-skeleton--compact .ui-list__row>.ui-skeleton__line{flex:1 1 auto;max-width:60%}.ui-skeleton--grid .ui-card__body{display:grid;gap:12px;justify-items:stretch}.ui-skeleton--grid .ui-card__body>.ui-skeleton__line:last-child{width:50%}.ui-skeleton--board .ui-board__list>li{height:72px;border-radius:var(--ui-radius-md);background:var(--ui-surface)}@media (pointer: coarse){.ui-table__sort{min-height:44px;margin-block:-12px}.ui-table__checkbox{min-width:44px;min-height:44px;margin:-12px 0}}@media (pointer: coarse),(max-width: 47.9975em){.ui-table__sort{min-width:44px}}@media (prefers-reduced-motion: reduce){.ui-table--sticky-first :is(th,td):first-child{animation:none}:is(.ui-table-wrap,.ui-index,.ui-list,.ui-cardgrid,.ui-board)[aria-busy=true]>*{transition:none}.ui-board{scroll-behavior:auto}}
|
|
1
|
+
:root{--ui-coll-head-bg: color-mix(in srgb, var(--ui-text, #1b1c1e) 3.5%, var(--ui-surface, #fff));--ui-coll-hover: color-mix(in srgb, var(--ui-text, #1b1c1e) 3.5%, var(--ui-surface, #fff));--ui-coll-selected: color-mix(in srgb, var(--ui-text, #1b1c1e) 6%, var(--ui-surface, #fff));--ui-coll-check-w: 40px}.ui-table--sticky-first tr{background:var(--ui-surface)}.ui-table--sticky-first tbody tr:hover{background:var(--ui-surface-2)}.ui-table--sticky-first :is(th,td):first-child{position:sticky;left:0;z-index:1;background:inherit}@supports (animation-timeline: scroll()){.ui-table-wrap:has(>.ui-table--sticky-first){scroll-timeline:--ui-coll-x inline}.ui-table--sticky-first :is(th,td):first-child{animation:ui-coll-edge linear both;animation-timeline:--ui-coll-x;animation-range:0 24px}}@keyframes ui-coll-edge{0%{box-shadow:none}to{box-shadow:1px 0 0 var(--ui-border),6px 0 8px -6px #0000002e}}.ui-table--compact :is(td,tbody th){padding-block:6px}.ui-table--compact thead th{padding-block:6px}.ui-table__totals>tr{background:var(--ui-coll-head-bg)}.ui-table__totals>tr>:is(td,th){background:var(--ui-coll-head-bg);font-weight:650;color:var(--ui-text);border-top:1px solid var(--ui-border);border-bottom:0}.ui-table__footer{padding:8px 12px;background:var(--ui-coll-head-bg);border-top:1px solid var(--ui-border);color:var(--ui-text-muted);font-size:var(--ui-fs-body);text-align:center}.ui-table th.ui-table__rowhead{font-weight:450;color:var(--ui-text);text-align:left}.ui-table th.ui-table__rowhead:not(.is-num){white-space:normal;min-width:9.0625rem}.ui-table th.ui-table__rowhead>a,.ui-table:where(:not(.ui-table--index)) tbody :is(td,th) li>a{display:inline-flex;align-items:center;min-height:24px}.ui-table:where(:not(.ui-table--index)) tbody :is(td,th){vertical-align:top}.ui-table:where(:not(.ui-table--index)) tbody :is(td>a,th.ui-table__rowhead>a,:is(td,th) li>a){margin-block:calc((1lh - 24px)/2)}.ui-table__sort{display:flex;width:max-content;max-width:100%;align-items:center;gap:4px;min-height:24px;margin-block:-2px;padding:0;border:0;background:none;color:inherit;font:inherit;text-align:inherit;text-decoration:none;cursor:pointer;white-space:nowrap}.ui-table__sort:hover{color:var(--ui-text)}.ui-table__sort:focus-visible{outline:2px solid var(--ui-focus);outline-offset:2px;border-radius:4px}.ui-table__sort:after{content:"";flex:none;width:16px;height:16px;background:currentColor;opacity:0;-webkit-mask:var(--ui-coll-arrow) center / 16px no-repeat;mask:var(--ui-coll-arrow) center / 16px no-repeat;--ui-coll-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 3.5v9M4.5 9 8 12.5 11.5 9' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")}.ui-table__sort:is(:hover,:focus-visible):after{opacity:.45}th[aria-sort=ascending]>.ui-table__sort:after,th[aria-sort=descending]>.ui-table__sort:after{opacity:1}th[aria-sort=ascending]>.ui-table__sort:after{transform:rotate(180deg)}th[aria-sort=ascending]>.ui-table__sort,th[aria-sort=descending]>.ui-table__sort{color:var(--ui-text)}.ui-table .is-num>.ui-table__sort{flex-direction:row-reverse;margin-left:auto}.ui-trunc{display:block;max-width:var(--ui-trunc, 32ch);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-clamp-2{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden;white-space:normal;overflow-wrap:anywhere}.ui-index{position:relative;container:ui-index / inline-size;min-width:0}.ui-table--index{font-size:var(--ui-fs-body)}.ui-table--index tr{background:var(--ui-surface)}.ui-table.ui-table--index thead th{padding:8px 6px;background:var(--ui-coll-head-bg);color:var(--ui-text-muted);font-size:var(--ui-fs-caption);line-height:20px;font-weight:550;text-transform:none;letter-spacing:0}.ui-table.ui-table--index :is(td,tbody th){padding:6px;line-height:20px;white-space:nowrap;vertical-align:middle;border-bottom:0;border-top:1px solid var(--ui-border)}.ui-table.ui-table--index :is(th,td):where(:first-child){padding-left:var(--ui-space-3)}.ui-table.ui-table--index :is(th,td):where(:last-child){padding-right:var(--ui-space-3)}.ui-table--index tbody tr:hover{background:var(--ui-coll-hover)}.ui-table--index tbody tr:is(.is-selected,[aria-selected=true]){background:var(--ui-coll-selected)}.ui-table--index tbody tr:is([data-href],.is-linked){cursor:pointer}.ui-table--index tbody tr:has(.ui-table__title:focus-visible){outline:2px solid var(--ui-focus);outline-offset:-2px}.ui-table__title:focus-visible{outline:none}.ui-table__primary{min-width:0}.ui-table__primary-inner{display:flex;align-items:center;gap:var(--ui-space-3);min-width:0}.ui-table__primary-text{min-width:0}.ui-table__title{display:block;max-width:var(--ui-trunc, 40ch);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ui-text);font-weight:650;text-decoration:none}a.ui-table__title:hover{text-decoration:underline}.ui-table--index .ui-table__title+.ui-sub,.ui-table--index .ui-sub{display:block;max-width:var(--ui-trunc, 40ch);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-top:0;line-height:16px}.ui-table--index td>a.ui-table__title{display:block;min-height:0}.ui-table--index td>.ui-table__primary-inner>a.ui-table__title,.ui-table--index .ui-table__primary-text>a.ui-table__title{line-height:20px}.ui-table.ui-table--index .ui-table__check{width:var(--ui-coll-check-w);padding:6px 8px 6px 12px}.ui-table.ui-table--index thead .ui-table__check{padding:8px 8px 8px 12px}.ui-table__checkbox{display:flex;width:max-content;align-items:center;justify-content:center;min-width:24px;min-height:24px;margin:-2px 0;cursor:pointer}.ui-table__checkbox>input,.ui-list__check>input{width:16px;height:16px;margin:0;accent-color:var(--ui-accent);cursor:pointer}.ui-table__checkbox>input:focus-visible,.ui-list__check>input:focus-visible{outline:2px solid var(--ui-focus);outline-offset:2px}.ui-table--index :is(.ui-table__check,.ui-table__primary){position:sticky;z-index:1;background:inherit}.ui-table--index .ui-table__check,.ui-table--index .ui-table__primary{left:0}.ui-table--index:has(.ui-table__check) .ui-table__primary{left:var(--ui-coll-check-w)}.ui-table__actions{width:1%;text-align:right}.ui-table__actions>*{vertical-align:middle}.ui-row-actions{display:inline-flex;align-items:center;gap:var(--ui-space-2)}.ui-bulkbar{position:relative;z-index:3;display:flex;flex-wrap:wrap;align-items:center;gap:var(--ui-space-2);box-sizing:border-box;min-height:38px;margin-bottom:-38px;padding:4px 8px 4px 12px;background:var(--ui-surface);border:1px solid var(--ui-border);border-bottom-color:transparent;border-radius:var(--ui-radius-lg) var(--ui-radius-lg) 0 0;font-size:var(--ui-fs-body)}.ui-bulkbar[hidden]{display:none}.ui-bulkbar__count{flex:none;font-weight:550;font-variant-numeric:tabular-nums;white-space:nowrap}.ui-bulkbar__actions{display:inline-flex;flex-wrap:wrap;gap:var(--ui-space-2);margin-left:auto}.ui-bulkbar .ui-table__checkbox{margin-right:4px}.ui-bulkbar[data-fit=pending]{flex-wrap:nowrap}.ui-bulkbar[data-fit=pending]>.ui-bulkbar__actions{flex:0 1 auto;flex-wrap:nowrap;min-width:0;overflow:hidden}.ui-bulkbar__actions>.ui-bulkbar__more{flex:none}.ui-bulkbar__measure{position:absolute;top:0;left:0;display:inline-flex;gap:var(--ui-space-2);height:0;overflow:hidden;visibility:hidden;pointer-events:none;white-space:nowrap}.ui-bulkbar__measure>*{flex:none}.ui-index__sortbar{display:none}@container ui-index (max-width: 768px){.ui-table--index,.ui-table--index tbody{display:block;width:100%}.ui-table--index thead{display:none}.ui-table--index tbody tr{position:relative;display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 12px;min-height:44px;box-sizing:border-box;padding:10px 12px;border-top:1px solid var(--ui-border)}.ui-table--index tbody tr:first-child{border-top:0}.ui-table--index tbody tr:has(>.ui-table__check){padding-left:48px}.ui-table.ui-table--index tbody :is(td,th){display:block;padding:0;border:0;position:static;background:none;white-space:nowrap}.ui-table--index tbody .ui-table__primary{flex:1 0 100%;white-space:normal}.ui-table--index tbody td:not(.ui-table__primary,.ui-table__check,.ui-table__actions){flex:none;max-width:100%;overflow:hidden;text-overflow:ellipsis;color:var(--ui-text-muted);font-size:var(--ui-fs-caption);line-height:18px}.ui-table--index tbody td[data-label]:not(.ui-table__primary):before{content:attr(data-label) " ";color:var(--ui-text-muted)}.ui-table--index tbody td:not(.ui-table__primary,.ui-table__check,.ui-table__actions) .ui-trunc{display:inline-block;vertical-align:bottom}.ui-table--index tbody td:not(.ui-table__primary,.ui-table__check,.ui-table__actions) .ui-sub{display:inline;margin-left:6px}.ui-table--index tbody td.is-num{text-align:left}.ui-table--index tbody td[data-condensed=hide]{display:none}.ui-table.ui-table--index tbody .ui-table__check{position:absolute;left:4px;top:4px;width:auto;padding:0}.ui-table.ui-table--index tbody .ui-table__actions{order:99;margin-left:auto;width:auto;padding:0;align-self:center}.ui-table--index .ui-table__checkbox{min-width:44px;min-height:44px;margin:0}.ui-table--index .ui-table__title,.ui-table--index .ui-sub{max-width:none}.ui-index__sortbar{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ui-space-2);margin:0 0 var(--ui-space-3);font-size:var(--ui-fs-caption);color:var(--ui-text-muted)}.ui-index .ui-bulkbar{margin-bottom:var(--ui-space-2);border-bottom-color:var(--ui-border);border-radius:var(--ui-radius-lg)}.ui-index .ui-table-wrap{overflow-x:visible}}.ui-list{container:ui-list / inline-size;margin:0;padding:0;list-style:none;background:var(--ui-surface);border:1px solid var(--ui-border);border-radius:var(--ui-radius-lg);box-shadow:var(--ui-card-shadow)}.ui-list--flush{border:0;border-radius:0;box-shadow:none;background:transparent}.ui-list__item{position:relative;display:flex;align-items:flex-start;gap:var(--ui-space-3);box-sizing:border-box;padding:var(--ui-space-3);min-height:44px;border-top:1px solid var(--ui-border)}.ui-list>.ui-list__item:first-child{border-top:0}.ui-list>.ui-list__item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.ui-list>.ui-list__item:last-child{border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.ui-list__item:has(.ui-list__title[href]):hover{background:var(--ui-coll-hover)}.ui-list__item:is(.is-selected,[aria-selected=true]){background:var(--ui-coll-selected)}.ui-list__item:has(.ui-list__title:focus-visible){outline:2px solid var(--ui-focus);outline-offset:-2px}.ui-list__media{flex:none;display:flex;align-items:center;min-height:40px}.ui-list__body{flex:1 1 auto;min-width:0}.ui-list__title{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ui-text);font-size:var(--ui-fs-body);line-height:20px;font-weight:650;text-decoration:none}.ui-list__title[href]:after{content:"";position:absolute;inset:0;z-index:0}.ui-list__title:focus-visible{outline:none}.ui-list__sub{margin:0;color:var(--ui-text-muted);font-size:var(--ui-fs-body);line-height:20px;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden;overflow-wrap:anywhere}.ui-list__meta{margin:2px 0 0;color:var(--ui-text-muted);font-size:var(--ui-fs-caption);line-height:16px}.ui-list__badges{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px}.ui-list__aside{flex:none;align-self:center;color:var(--ui-text);font-variant-numeric:tabular-nums;text-align:right}.ui-list__actions{flex:none;align-self:center;display:inline-flex;align-items:center;gap:var(--ui-space-2)}.ui-list__item :is(.ui-list__actions,.ui-list__aside a,.ui-list__body a:not(.ui-list__title),button,input,select,textarea,label,summary,details){position:relative;z-index:1}@container ui-list (max-width: 400px){.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item{display:grid;grid-template-columns:auto minmax(0,1fr) auto;grid-template-areas:"media body body" "media aside actions";gap:0;align-items:start}.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item>.ui-list__media{grid-area:media;margin-inline-end:var(--ui-space-3)}.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item>.ui-list__body{grid-area:body}.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item>.ui-list__aside{grid-area:aside;justify-self:start;align-self:center;margin-top:4px;text-align:left}.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item>.ui-list__actions{grid-area:actions;justify-self:end;align-self:center;margin:4px 0 0 var(--ui-space-3)}.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item:has(>.ui-list__body>.ui-list__title:only-child){grid-template-columns:auto minmax(0,1fr) auto auto;grid-template-areas:"media body aside actions";align-items:center}.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item:has(>.ui-list__body>.ui-list__title:only-child)>:is(.ui-list__aside,.ui-list__actions){margin-top:0}.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item:has(>.ui-list__body>.ui-list__title:only-child)>.ui-list__aside{margin-inline-start:var(--ui-space-3);text-align:right}}.ui-resource>.ui-bulkbar{margin-bottom:0;border-bottom-color:var(--ui-border)}.ui-resource>.ui-bulkbar:has(+.ui-list--flush){border-width:0 0 1px;border-radius:0}.ui-resource>.ui-list,.ui-resource>[aria-busy]>.ui-list{border-top:0;border-top-left-radius:0;border-top-right-radius:0}.ui-list__check{display:flex;flex:none;align-items:center;justify-content:center;min-width:24px;min-height:24px;cursor:pointer}.ui-list__check:not(:last-child){margin-inline-end:8px}@media (pointer: coarse),(max-width: 47.9975em){.ui-list__check{min-width:44px;min-height:44px;margin-block:-2px;margin-inline-start:-12px}.ui-list__check:not(:last-child){margin-inline-end:-2px}.ui-resource>.ui-bulkbar>.ui-table__checkbox{min-width:44px;min-height:44px;margin:-8px -8px -8px -12px}}.ui-thumb{display:block;flex:none;width:40px;height:40px;box-sizing:border-box;border:1px solid var(--ui-border);border-radius:var(--ui-radius-md);background:var(--ui-surface-2);overflow:hidden;object-fit:cover}.ui-thumb--xs{width:24px;height:24px;border-radius:var(--ui-radius-sm)}.ui-thumb--md{width:60px;height:60px}.ui-thumb--lg{width:80px;height:80px}.ui-thumb>img{display:block;width:100%;height:100%;object-fit:cover}.ui-list--compact>.ui-list__item{display:block;padding:0;min-height:0}.ui-list__row{display:flex;align-items:center;gap:var(--ui-space-2);box-sizing:border-box;width:100%;min-height:36px;padding:8px 12px;border:0;background:none;color:var(--ui-text);font:inherit;font-size:var(--ui-fs-body);line-height:20px;text-align:left;text-decoration:none;border-radius:inherit}:is(a,button).ui-list__row{cursor:pointer}:is(a,button).ui-list__row:hover{background:var(--ui-coll-hover)}:is(a,button).ui-list__row:focus-visible{outline:2px solid var(--ui-focus);outline-offset:-2px}.ui-list__row[aria-current=page],.ui-list__row.is-selected{background:var(--ui-coll-selected)}.ui-list__icon{flex:none;display:inline-flex;width:20px;height:20px;align-items:center;justify-content:center;color:var(--ui-text-muted)}.ui-list__icon>svg{width:16px;height:16px}.ui-list__label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-list__row>.ui-list__meta{flex:none;margin:0;font-variant-numeric:tabular-nums}@media (pointer: coarse),(max-width: 47.9975em){.ui-list__row{min-height:44px}}.ui-list--activity>.ui-list__item{display:grid;grid-template-columns:20px minmax(0,1fr) auto;column-gap:var(--ui-space-2);align-items:start;padding:8px 12px;min-height:36px;border-top:0}.ui-list--activity>.ui-list__item:before{content:"";position:absolute;left:21.5px;top:0;bottom:0;width:1px;background:var(--ui-border)}.ui-list--activity>.ui-list__item:first-child:before{top:14px}.ui-list--activity>.ui-list__item:last-child:before{bottom:calc(100% - 14px)}.ui-list--activity>.ui-list__item:only-child:before{display:none}.ui-list__dot{position:relative;z-index:1;width:8px;height:8px;margin:6px 0 0 6px;border-radius:50%;background:var(--ui-text-muted);box-shadow:0 0 0 3px var(--ui-surface)}.ui-list__dot--success{background:var(--gemboss-success, #0a8f6a)}.ui-list__dot--warning{background:var(--gemboss-warning, #b25e09)}.ui-list__dot--critical{background:var(--gemboss-danger-strong, #c70a24)}.ui-list__dot--info{background:var(--gemboss-accent, #5661f5)}.ui-list--activity .ui-list__label{display:block;white-space:nowrap}.ui-list--activity a.ui-list__label{position:relative;color:var(--ui-text);text-decoration:none;padding-block:2px;margin-block:-2px}.ui-list--activity a.ui-list__label:hover{text-decoration:underline}.ui-list--activity a.ui-list__label:focus-visible{outline:2px solid var(--ui-focus);outline-offset:0;border-radius:4px}.ui-list--activity .ui-list__detail{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ui-text-muted);font-size:var(--ui-fs-caption);line-height:16px}.ui-list--activity time,.ui-list--activity .ui-list__time{color:var(--ui-text-muted);font-size:var(--ui-fs-caption);line-height:20px;white-space:nowrap;font-variant-numeric:tabular-nums}.ui-list__content{margin-top:4px;color:var(--ui-text);font-size:var(--ui-fs-body);line-height:20px;overflow-wrap:anywhere}.ui-list__content>p{margin:0}.ui-list__content>p+p{margin-top:4px}.ui-list--wrap .ui-list__label,.ui-list--wrap .ui-list__detail{white-space:normal;overflow:visible;text-overflow:clip;overflow-wrap:anywhere}.ui-list--wrap .ui-list__row{align-items:flex-start}@media (pointer: coarse),(max-width: 47.9975em){.ui-list--wrap .ui-list__row{padding-block:12px}}.ui-list--wrap .ui-list__row>.ui-list__meta{line-height:20px}.ui-cardgrid{--ui-cardgrid-min: 240px;display:grid;grid-template-columns:repeat(auto-fill,minmax(min(var(--ui-cardgrid-min),100%),1fr));gap:var(--ui-space-4);margin:0;padding:0;list-style:none}.ui-cardgrid[data-min="200"]{--ui-cardgrid-min: 200px}.ui-cardgrid[data-min="320"]{--ui-cardgrid-min: 320px}.ui-cardgrid>*{min-width:0}.ui-board{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(240px,1fr);gap:var(--ui-space-4);align-items:start;overflow-x:auto;overscroll-behavior-x:contain;scroll-snap-type:x mandatory;padding-bottom:4px}@media (max-width: 47.9975em){.ui-board{grid-auto-columns:78%}}.ui-board__col{display:flex;flex-direction:column;gap:var(--ui-space-2);min-width:0;padding:var(--ui-space-2);scroll-snap-align:start;background:var(--ui-coll-head-bg);border-radius:var(--ui-radius-lg)}.ui-board__head{display:flex;align-items:center;gap:var(--ui-space-2);min-height:28px;padding:0 4px;font-size:var(--ui-fs-body);font-weight:650}.ui-board__name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-board__count{margin-left:auto;color:var(--ui-text-muted);font-weight:450;font-variant-numeric:tabular-nums}.ui-board__dot{flex:none;width:8px;height:8px;border-radius:50%;background:var(--ui-text-muted)}.ui-board__dot--success{background:var(--gemboss-success, #0a8f6a)}.ui-board__dot--warning{background:var(--gemboss-warning, #b25e09)}.ui-board__dot--critical{background:var(--gemboss-danger-strong, #c70a24)}.ui-board__dot--info{background:var(--gemboss-accent, #5661f5)}.ui-board__list{display:grid;gap:var(--ui-space-2);margin:0;padding:0;list-style:none}.ui-board__list>li{min-width:0}.ui-board__empty{margin:0;padding:var(--ui-space-4) var(--ui-space-2);color:var(--ui-text-muted);font-size:var(--ui-fs-body);text-align:center;border:1px dashed var(--ui-border);border-radius:var(--ui-radius-md)}.ui-board__more>summary{list-style:none;justify-self:center;margin:4px auto 0;width:fit-content}.ui-board__more>summary::-webkit-details-marker{display:none}.ui-board__more[open]>summary{display:none}.ui-board__more{display:grid;gap:var(--ui-space-2)}.ui-board__next.ui-more{padding:4px 0 0}.ui-board__next .ui-more__error{color:var(--gemboss-danger-strong, #c70a24)}.ui-board[data-gb-move] .ui-board__list>li[data-id]{position:relative;border-radius:var(--ui-radius-lg);cursor:grab}.ui-board[data-gb-move] .ui-board__list>li[data-id]:focus-visible{outline:2px solid var(--ui-focus);outline-offset:2px}.ui-board__list>li[data-gb-lifted]{outline:2px solid var(--ui-focus);outline-offset:2px;box-shadow:var(--gemboss-shadow-md, 0 4px 12px rgba(0,0,0,.12));border-radius:var(--ui-radius-lg)}.ui-board[data-gb-dragging] .ui-board__list>li[data-gb-lifted]{outline:0;opacity:.4}.ui-board__col[data-gb-over]{background:color-mix(in srgb,var(--ui-focus) 10%,var(--ui-coll-head-bg))}.ui-board__list>li[data-gb-drop]:before{content:"";position:absolute;left:0;right:0;height:2px;border-radius:1px;background:var(--ui-focus);pointer-events:none}.ui-board__list>li[data-gb-drop=before]:before{top:-5px}.ui-board__list>li[data-gb-drop=after]:before{bottom:-5px}.ui-empty--no-match{padding-block:32px}.ui-coll-error{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ui-space-2) var(--ui-space-3);margin:var(--ui-space-3)}.ui-coll-error>:first-child{flex:1 1 240px;min-width:0}.ui-coll-count{margin-left:auto;color:var(--ui-text-muted);font-size:var(--ui-fs-body);font-variant-numeric:tabular-nums;white-space:nowrap}.ui-chip__x{margin-right:-4px;font-size:14px;line-height:1;opacity:.7}:is(.ui-table-wrap,.ui-index,.ui-list,.ui-cardgrid,.ui-board)[aria-busy=true]{position:relative}:is(.ui-table-wrap,.ui-index,.ui-list,.ui-cardgrid,.ui-board)[aria-busy=true]>:not(.ui-bulkbar,.ui-coll-busy){opacity:.55;pointer-events:none;transition:opacity .15s}.ui-coll-busy{position:absolute;top:8px;right:8px;z-index:4}:is(.ui-skeleton--table,.ui-skeleton--list,.ui-skeleton--compact,.ui-skeleton--grid,.ui-skeleton--board) .ui-skeleton__line{height:8px;border-radius:4px}.ui-skeleton--table td .ui-skeleton__line{width:70%;margin-block:6px}.ui-skeleton--table td:first-child .ui-skeleton__line{width:85%}.ui-skeleton--table tbody tr:hover{background:none}.ui-skeleton__block{display:block;flex:none;width:40px;height:40px;border-radius:var(--ui-radius-md);background:var(--ui-surface-2)}.ui-skeleton__block--round{border-radius:50%;width:32px;height:32px}.ui-skeleton--list>.ui-list__item{align-items:center}.ui-skeleton--list .ui-list__body{display:grid;gap:12px}.ui-skeleton--list .ui-list__body>.ui-skeleton__line:last-child{width:60%}.ui-skeleton--compact .ui-list__row{gap:12px}.ui-skeleton--compact .ui-list__row>.ui-skeleton__line{flex:1 1 auto;max-width:60%}.ui-skeleton--grid .ui-card__body{display:grid;gap:12px;justify-items:stretch}.ui-skeleton--grid .ui-card__body>.ui-skeleton__line:last-child{width:50%}.ui-skeleton--board .ui-board__list>li{height:72px;border-radius:var(--ui-radius-md);background:var(--ui-surface)}@media (pointer: coarse){.ui-table__sort{min-height:44px;margin-block:-12px}.ui-table__checkbox{min-width:44px;min-height:44px;margin:-12px 0}}@media (pointer: coarse),(max-width: 47.9975em){.ui-table__sort{min-width:44px}}@media (prefers-reduced-motion: reduce){.ui-table--sticky-first :is(th,td):first-child{animation:none}:is(.ui-table-wrap,.ui-index,.ui-list,.ui-cardgrid,.ui-board)[aria-busy=true]>*{transition:none}.ui-board{scroll-behavior:auto}}
|