@gemboss/ui 0.25.0 → 0.30.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +178 -0
- package/README.md +259 -21
- package/catalog/editor.html +1 -1
- package/catalog/index.html +785 -63
- package/gemboss-ui.css +3 -3
- package/package.json +14 -2
- package/parts/components.css +1 -1
- package/parts/core.css +1 -1
- package/parts/shell.css +1 -1
- package/src/action-card.css +1 -0
- package/src/action-card.tsx +149 -0
- package/src/assistant/chat-markdown.ts +279 -0
- package/src/assistant/chat-turns.ts +120 -0
- package/src/assistant/chat.tsx +871 -0
- package/src/assistant/engine-mark-art.ts +45 -0
- package/src/assistant/engine-mark.tsx +39 -0
- package/src/assistant/engine.tsx +98 -8
- package/src/assistant/host.tsx +2 -1
- package/src/assistant/index.ts +5 -0
- package/src/assistant-chat.css +1 -0
- package/src/assistant-engine.css +1 -1
- package/src/auth.css +1 -1
- package/src/auth.tsx +17 -2
- package/src/chat-composer.css +1 -1
- package/src/chat-plain.js +6 -0
- package/src/chat.css +1 -1
- package/src/editor/frame.tsx +11 -4
- package/src/editor/index.ts +1 -1
- package/src/editor.css +1 -1
- package/src/engine-plain.js +1 -0
- package/src/index.ts +4 -1
- package/src/kit-plain.js +1 -1
- package/src/minichart.css +1 -0
- package/src/minichart.tsx +165 -0
- package/src/setup-guide.css +1 -0
- package/src/setup-guide.tsx +116 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Each engine's MARK, the artwork only (0.29.0), moved from the admin (apps/admin/src/lib/engine-mark-art.ts, which now
|
|
3
|
+
* re-exports this file). No JSX and no stylesheet, so a node test and a server module can import it
|
|
4
|
+
* (`@gemboss/ui/assistant/engine-mark-art`); `EngineMark` (engine-mark.tsx) draws it.
|
|
5
|
+
*
|
|
6
|
+
* One shape per engine, never a shared one: a mark that is right for one engine and wrong for the other reads as evidence
|
|
7
|
+
* while naming the wrong thing.
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** The Claude asterisk: eight tapered arms from one centre, generated (eight hand-typed arms are eight chances to be off). */
|
|
11
|
+
function claudeAsterisk(): string {
|
|
12
|
+
const c = 12, root = 1.7, tip = 0.5, len = 9.6;
|
|
13
|
+
const f = (n: number) => Math.round(n * 100) / 100;
|
|
14
|
+
const p = (x: number, y: number) => `${f(x)} ${f(y)}`;
|
|
15
|
+
return Array.from({ length: 8 }, (_, i) => {
|
|
16
|
+
const a = (i * Math.PI) / 4;
|
|
17
|
+
const [dx, dy] = [Math.cos(a), Math.sin(a)];
|
|
18
|
+
const [px, py] = [-dy, dx];
|
|
19
|
+
return [
|
|
20
|
+
`M${p(c + px * root, c + py * root)}`,
|
|
21
|
+
`L${p(c + dx * len + px * tip, c + dy * len + py * tip)}`,
|
|
22
|
+
`Q${p(c + dx * (len + 0.6), c + dy * (len + 0.6))} ${p(c + dx * len - px * tip, c + dy * len - py * tip)}`,
|
|
23
|
+
`L${p(c - px * root, c - py * root)}`,
|
|
24
|
+
"Z",
|
|
25
|
+
].join("");
|
|
26
|
+
}).join(" ");
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Codex: a hexagonal ring. Not OpenAI's knot (no official asset here; one drawn from memory would be a wrong logo). */
|
|
30
|
+
const CODEX_HEX = "M12 2.6 20.1 7.3V16.7L12 21.4 3.9 16.7V7.3ZM12 6.9 7.6 9.45v5.1L12 17.1l4.4-2.55v-5.1Z";
|
|
31
|
+
|
|
32
|
+
/** NONZERO: the asterisk's eight subpaths all start at the centre, and under evenodd the overlaps cancel (measured in the
|
|
33
|
+
* admin: the centre came back 0/400 inked, a hollow compass rose). */
|
|
34
|
+
export const ENGINE_MARK_FILL_RULE = "nonzero" as const;
|
|
35
|
+
|
|
36
|
+
export type EngineMarkId = "claude" | "codex";
|
|
37
|
+
export interface EngineMarkArt { path: string; label: string }
|
|
38
|
+
export const ENGINE_MARK_ART: Record<EngineMarkId, EngineMarkArt> = {
|
|
39
|
+
claude: { path: claudeAsterisk(), label: "Claude Code" },
|
|
40
|
+
codex: { path: CODEX_HEX, label: "Codex" },
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export function isEngineMarkId(v: unknown): v is EngineMarkId {
|
|
44
|
+
return typeof v === "string" && Object.prototype.hasOwnProperty.call(ENGINE_MARK_ART, v);
|
|
45
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Each engine's MARK (0.29.0), moved from the admin (apps/admin/src/lib/engine-mark-art.ts + components/chat/EngineMark.tsx).
|
|
3
|
+
*
|
|
4
|
+
* Where it shows: on the engine chip when the composer row is too narrow for the name (a name cut to "Clau…" says
|
|
5
|
+
* nothing; a mark still says whose model answers), and in a narration row that stands for the turn itself.
|
|
6
|
+
*
|
|
7
|
+
* One shape per engine, never a shared one: a mark that is right for one engine and wrong for the other reads as evidence
|
|
8
|
+
* while naming the wrong thing. An engine with no artwork draws NOTHING (silence rather than somebody else's logo), and
|
|
9
|
+
* the chip then keeps its name.
|
|
10
|
+
*/
|
|
11
|
+
import "../assistant-engine.css"; // the mark's size (`.gemboss-engine-mark`), with the chip that shows it
|
|
12
|
+
import React from "react";
|
|
13
|
+
|
|
14
|
+
import { ENGINE_MARK_ART, ENGINE_MARK_FILL_RULE, isEngineMarkId } from "./engine-mark-art";
|
|
15
|
+
export { ENGINE_MARK_ART, ENGINE_MARK_FILL_RULE, isEngineMarkId, type EngineMarkArt, type EngineMarkId } from "./engine-mark-art";
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
/** The mark as an image with a NAME (the hover text and the accessible name), or nothing when the engine has no artwork. */
|
|
19
|
+
export function EngineMark({ engine, title, className = "gemboss-engine-mark", decorative = false }: {
|
|
20
|
+
engine: string;
|
|
21
|
+
title?: string;
|
|
22
|
+
className?: string;
|
|
23
|
+
/** Inside a control that already names the engine (the chip): hidden from assistive tech, no hover title. */
|
|
24
|
+
decorative?: boolean;
|
|
25
|
+
}) {
|
|
26
|
+
if (!isEngineMarkId(engine)) return null;
|
|
27
|
+
const art = ENGINE_MARK_ART[engine];
|
|
28
|
+
const name = title || art.label;
|
|
29
|
+
return decorative ? (
|
|
30
|
+
<svg className={className} viewBox="0 0 24 24" fill="currentColor" aria-hidden="true" focusable="false">
|
|
31
|
+
<path d={art.path} fillRule={ENGINE_MARK_FILL_RULE} />
|
|
32
|
+
</svg>
|
|
33
|
+
) : (
|
|
34
|
+
<svg className={className} viewBox="0 0 24 24" fill="currentColor" role="img" aria-label={name}>
|
|
35
|
+
<title>{name}</title>
|
|
36
|
+
<path d={art.path} fillRule={ENGINE_MARK_FILL_RULE} />
|
|
37
|
+
</svg>
|
|
38
|
+
);
|
|
39
|
+
}
|
package/src/assistant/engine.tsx
CHANGED
|
@@ -28,6 +28,7 @@ import "../assistant-engine.css"; // its own entry (0.25.0): not in gemboss-ui.c
|
|
|
28
28
|
import React, { useCallback, useEffect, useId, useLayoutEffect, useRef, useState, type ReactNode } from "react";
|
|
29
29
|
import { createPortal } from "react-dom";
|
|
30
30
|
import { canFloatMenus, placeFloating } from "../menu-layer";
|
|
31
|
+
import { EngineMark, isEngineMarkId } from "./engine-mark";
|
|
31
32
|
|
|
32
33
|
const cx = (...p: Array<string | false | null | undefined>) => p.filter(Boolean).join(" ");
|
|
33
34
|
const useBeforePaint = typeof window === "undefined" ? useEffect : useLayoutEffect;
|
|
@@ -47,6 +48,12 @@ export interface EngineChoice {
|
|
|
47
48
|
badgeTone?: "success" | "warning" | "critical" | "info";
|
|
48
49
|
/** Cannot be picked right now. Say why in `note`. */
|
|
49
50
|
disabled?: boolean;
|
|
51
|
+
/** The engine's mark ("claude", "codex": `ENGINE_MARK_ART`). The chip shows it in place of the name when the composer row
|
|
52
|
+
* is too narrow for the name (`ChatComposer` density "icon"); an engine without one keeps its (cut) name. 0.29.0. */
|
|
53
|
+
mark?: string;
|
|
54
|
+
/** THIS engine's models. Give them on every engine and the Engine tab lists each engine with its own models, all at
|
|
55
|
+
* once, and one click picks the engine and the model together (`onPick`): the admin's popup. 0.29.0. */
|
|
56
|
+
models?: readonly Choice[];
|
|
50
57
|
}
|
|
51
58
|
|
|
52
59
|
export interface Choice {
|
|
@@ -139,6 +146,13 @@ export interface EnginePickerProps {
|
|
|
139
146
|
effortDisabled?: boolean | string;
|
|
140
147
|
/** Quiet lines under the Engine tab's fields: who pays, what this bridge version cannot do yet. */
|
|
141
148
|
notes?: ReactNode;
|
|
149
|
+
/** With models per engine (`EngineChoice.models`): one click on a model picks both, and closes the panel. Without it the
|
|
150
|
+
* picker calls `onEngineChange` (when the engine changes) then `onModelChange`. 0.29.0. */
|
|
151
|
+
onPick?: (engine: string, model: string) => void;
|
|
152
|
+
/** A switch that did not go through ("Wait for the current answer to finish"): one red line on the Engine tab. 0.29.0. */
|
|
153
|
+
problem?: ReactNode;
|
|
154
|
+
/** The chip itself is disabled (a switch in flight). `locked` keeps the chip and disables the choices. 0.29.0. */
|
|
155
|
+
disabled?: boolean;
|
|
142
156
|
/** The bridge on the user's machine. Omit for an engine set that runs on the server only: no dot, no Status tab. */
|
|
143
157
|
bridge?: BridgeStatus;
|
|
144
158
|
/** The dot on the chip (default true when `bridge` is given). False when the current engine does not go through the
|
|
@@ -192,8 +206,9 @@ function useTabs(p: Pick<EnginePickerProps, "bridge" | "setup" | "tab" | "onTabC
|
|
|
192
206
|
|
|
193
207
|
/** What the chip says out loud: the engine, the model, and the bridge when it is not fine. */
|
|
194
208
|
export function engineChipName(p: Pick<EnginePickerProps, "engines" | "engine" | "models" | "model" | "bridge">, L: EnginePickerLabels = ENGINE_PICKER_EN): string {
|
|
195
|
-
const
|
|
196
|
-
const
|
|
209
|
+
const cur = p.engines.find((e) => e.id === p.engine);
|
|
210
|
+
const eng = cur?.label ?? p.engine;
|
|
211
|
+
const model = p.model ? (cur?.models ?? p.models)?.find((m) => m.id === p.model)?.label : undefined;
|
|
197
212
|
const bridge = p.bridge && p.bridge.state !== "running" ? `. ${L.bridge}: ${L[STATE_LABEL[p.bridge.state]]}` : "";
|
|
198
213
|
return `${L.chip}: ${eng}${model ? ` · ${model}` : ""}${bridge}`;
|
|
199
214
|
}
|
|
@@ -242,17 +257,31 @@ export function EnginePicker(props: EnginePickerProps) {
|
|
|
242
257
|
if (!panel || !chip) return undefined;
|
|
243
258
|
// Escape with focus in the panel or on the chip closes the panel only: captured first and stopped, so the surface's
|
|
244
259
|
// own Escape (hide the assistant) does not fire on the same key. With focus elsewhere (the composer), it closes the
|
|
245
|
-
// panel and leaves focus and the key
|
|
260
|
+
// panel and leaves focus alone, and marks the key handled (0.27.0): a surface whose "Escape hides the assistant"
|
|
261
|
+
// checks `defaultPrevented` waits for the next Escape. Before 0.27.0 the key went on unmarked, and React re-renders
|
|
262
|
+
// between this listener and the surface's, so every surface (gemlabs #922, gemfeedback #66) needed a window-capture
|
|
263
|
+
// marker to tell "this Escape closed the picker" from "this one is mine".
|
|
246
264
|
const onKey = (e: KeyboardEvent) => {
|
|
247
265
|
if (e.key !== "Escape" || e.defaultPrevented) return;
|
|
266
|
+
// Not ours: an IME composition (Escape cancels it; the kit's rule, kit-plain.js), or a modal opened from the panel.
|
|
267
|
+
if (e.isComposing || e.keyCode === 229) return;
|
|
248
268
|
const a = document.activeElement;
|
|
249
|
-
|
|
269
|
+
const modal = a?.closest?.('dialog[open], [aria-modal="true"]');
|
|
270
|
+
if (modal && !panel.contains(modal)) return;
|
|
271
|
+
e.preventDefault();
|
|
272
|
+
if (a && (panel.contains(a) || chip.contains(a))) { e.stopPropagation(); closeToChip(); }
|
|
250
273
|
else setOpen(false);
|
|
251
274
|
};
|
|
252
275
|
const onDown = (e: PointerEvent) => {
|
|
253
276
|
const t = e.target as Node;
|
|
254
277
|
if (!panel.contains(t) && !chip.contains(t)) setOpen(false);
|
|
255
278
|
};
|
|
279
|
+
// A modal opened from the panel (a confirm behind a Status action) takes the screen: the panel would stay above it in
|
|
280
|
+
// the top layer, over its buttons (review #3903). Close the panel when focus enters a modal that is not the panel.
|
|
281
|
+
const onFocusIn = (e: FocusEvent) => {
|
|
282
|
+
const m = (e.target as Element | null)?.closest?.('dialog[open], [aria-modal="true"]');
|
|
283
|
+
if (m && !panel.contains(m)) setOpen(false);
|
|
284
|
+
};
|
|
256
285
|
const replace = () => placeFloating(panel, chip, end);
|
|
257
286
|
// A scroll moves the panel's anchor only when it scrolls something that holds the chip (the page, a frame around the
|
|
258
287
|
// composer): a chat log streaming beside it does not. One placement per frame at most.
|
|
@@ -278,12 +307,14 @@ export function EnginePicker(props: EnginePickerProps) {
|
|
|
278
307
|
if (pane) ro?.observe(pane);
|
|
279
308
|
document.addEventListener("keydown", onKey, true);
|
|
280
309
|
document.addEventListener("pointerdown", onDown, true);
|
|
310
|
+
document.addEventListener("focusin", onFocusIn, true);
|
|
281
311
|
document.addEventListener("scroll", onScroll, true);
|
|
282
312
|
window.addEventListener("resize", replace);
|
|
283
313
|
return () => {
|
|
284
314
|
document.removeEventListener("keydown", onKey, true);
|
|
285
315
|
cancelAnimationFrame(frame);
|
|
286
316
|
document.removeEventListener("pointerdown", onDown, true);
|
|
317
|
+
document.removeEventListener("focusin", onFocusIn, true);
|
|
287
318
|
document.removeEventListener("scroll", onScroll, true);
|
|
288
319
|
window.removeEventListener("resize", replace);
|
|
289
320
|
ro?.disconnect();
|
|
@@ -301,7 +332,8 @@ export function EnginePicker(props: EnginePickerProps) {
|
|
|
301
332
|
}, [open]);
|
|
302
333
|
|
|
303
334
|
const current = engines.find((e) => e.id === engine);
|
|
304
|
-
const modelLabel = model ? models?.find((m) => m.id === model)?.label : undefined;
|
|
335
|
+
const modelLabel = model ? (current?.models ?? models)?.find((m) => m.id === model)?.label : undefined;
|
|
336
|
+
const mark = current?.mark && isEngineMarkId(current.mark) ? current.mark : null;
|
|
305
337
|
const tone = bridge && props.showBridgeDot !== false ? BRIDGE_TONE[bridge.state] : null;
|
|
306
338
|
const name = engineChipName(props.showBridgeDot === false ? { ...props, bridge: undefined } : props, L);
|
|
307
339
|
|
|
@@ -310,7 +342,8 @@ export function EnginePicker(props: EnginePickerProps) {
|
|
|
310
342
|
<button
|
|
311
343
|
ref={chipRef}
|
|
312
344
|
type="button"
|
|
313
|
-
className="gb-engine-chip"
|
|
345
|
+
className={mark ? "gb-engine-chip has-mark" : "gb-engine-chip"}
|
|
346
|
+
disabled={props.disabled || undefined}
|
|
314
347
|
aria-haspopup="dialog"
|
|
315
348
|
aria-expanded={open}
|
|
316
349
|
aria-controls={panelId}
|
|
@@ -323,6 +356,8 @@ export function EnginePicker(props: EnginePickerProps) {
|
|
|
323
356
|
{current?.label ?? engine}
|
|
324
357
|
{modelLabel ? <span className="gb-engine-chipsub"> · {modelLabel}</span> : null}
|
|
325
358
|
</span>
|
|
359
|
+
{/* Shown instead of the name when the composer is too narrow for it (assistant-engine.css, ChatComposer density). */}
|
|
360
|
+
{mark ? <span className="gb-engine-chipmark"><EngineMark engine={mark} decorative /></span> : null}
|
|
326
361
|
</button>
|
|
327
362
|
{(() => { const panelEl = (<div
|
|
328
363
|
ref={panelRef}
|
|
@@ -456,8 +491,62 @@ function Options({ label, items, value, onChange, locked, onPicked, disabledReas
|
|
|
456
491
|
);
|
|
457
492
|
}
|
|
458
493
|
|
|
459
|
-
|
|
494
|
+
/** Every engine with its own models, all at once; one click picks both (the admin's popup, 0.29.0). */
|
|
495
|
+
function EngineGroups({ engines, engine, model, onPick, onEngineChange, onModelChange, locked, L, onPicked }: EnginePickerProps & { L: EnginePickerLabels; onPicked?: () => void }) {
|
|
496
|
+
const id = useId();
|
|
497
|
+
const choose = (e: EngineChoice, m: Choice) => {
|
|
498
|
+
// The pick already in force: close, change nothing (a surface that starts a new conversation on a switch must not).
|
|
499
|
+
if (e.id === engine && (model ?? "") === m.id) { onPicked?.(); return; }
|
|
500
|
+
if (onPick) onPick(e.id, m.id);
|
|
501
|
+
else { if (e.id !== engine) onEngineChange?.(e.id); onModelChange?.(m.id); }
|
|
502
|
+
onPicked?.();
|
|
503
|
+
};
|
|
504
|
+
const canChoose = Boolean(onPick || onEngineChange || onModelChange);
|
|
505
|
+
return (
|
|
506
|
+
<div className="gb-engine-field">
|
|
507
|
+
<span className="gb-engine-label" id={id}>{L.engine}</span>
|
|
508
|
+
<div className="gb-engine-groups" role="group" aria-labelledby={id}>
|
|
509
|
+
{engines.map((e) => {
|
|
510
|
+
const chosen = e.id === engine;
|
|
511
|
+
const items = e.models && e.models.length ? e.models : [{ id: "", label: L.defaultChoice }];
|
|
512
|
+
return (
|
|
513
|
+
<div key={e.id} className="gb-engine-group" data-current={chosen ? "" : undefined}>
|
|
514
|
+
<span className="gb-engine-rowhead">
|
|
515
|
+
<span className="gb-engine-rowname">{e.label}</span>
|
|
516
|
+
{e.badge ? <span className={e.badgeTone ? BADGE_CLASS[e.badgeTone] : "ui-badge"}>{e.badge}</span> : null}
|
|
517
|
+
</span>
|
|
518
|
+
{e.note ? <span className="gb-engine-note">{e.note}</span> : null}
|
|
519
|
+
<div className="gb-engine-opts" role="group" aria-label={e.label}>
|
|
520
|
+
{items.map((m) => (
|
|
521
|
+
<button key={m.id || "default"} type="button" className="gb-engine-opt" title={m.title}
|
|
522
|
+
aria-pressed={chosen && (model ?? "") === m.id}
|
|
523
|
+
disabled={locked || e.disabled || !canChoose}
|
|
524
|
+
onClick={() => choose(e, m)}>
|
|
525
|
+
{m.label}
|
|
526
|
+
</button>
|
|
527
|
+
))}
|
|
528
|
+
</div>
|
|
529
|
+
</div>
|
|
530
|
+
);
|
|
531
|
+
})}
|
|
532
|
+
</div>
|
|
533
|
+
</div>
|
|
534
|
+
);
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
function EngineTab(props: EnginePickerProps & { L: EnginePickerLabels; onPicked?: () => void }) {
|
|
538
|
+
const { engines, engine, onEngineChange, models, model, onModelChange, modelControl, efforts, effort, onEffortChange, effortDisabled, notes, locked, L, onPicked } = props;
|
|
460
539
|
const id = useId();
|
|
540
|
+
if (engines.some((e) => e.models && e.models.length)) {
|
|
541
|
+
return (
|
|
542
|
+
<>
|
|
543
|
+
<EngineGroups {...props} />
|
|
544
|
+
{efforts && efforts.length ? <Options label={L.effort} items={efforts} value={effort} onChange={onEffortChange} locked={locked} onPicked={onPicked} disabledReason={effortDisabled} /> : null}
|
|
545
|
+
{props.problem ? <p className="gb-engine-problem" role="alert">{props.problem}</p> : null}
|
|
546
|
+
{notes ? <div className="gb-engine-notes">{notes}</div> : null}
|
|
547
|
+
</>
|
|
548
|
+
);
|
|
549
|
+
}
|
|
461
550
|
// The ARIA radio pattern: one Tab stop (the checked engine, else the first that can be picked); arrows move AND pick.
|
|
462
551
|
const can = (e: EngineChoice) => !(locked || e.disabled || !onEngineChange);
|
|
463
552
|
const stop = engines.find((e) => e.id === engine && can(e))?.id ?? engines.find(can)?.id;
|
|
@@ -503,13 +592,14 @@ function EngineTab({ engines, engine, onEngineChange, models, model, onModelChan
|
|
|
503
592
|
<div className="gb-engine-field"><span className="gb-engine-label">{L.model}</span>{modelControl}</div>
|
|
504
593
|
) : models && models.length ? <Options label={L.model} items={models} value={model} onChange={onModelChange} locked={locked} onPicked={onPicked} /> : null}
|
|
505
594
|
{efforts && efforts.length ? <Options label={L.effort} items={efforts} value={effort} onChange={onEffortChange} locked={locked} onPicked={onPicked} disabledReason={effortDisabled} /> : null}
|
|
595
|
+
{props.problem ? <p className="gb-engine-problem" role="alert">{props.problem}</p> : null}
|
|
506
596
|
{notes ? <div className="gb-engine-notes">{notes}</div> : null}
|
|
507
597
|
</>
|
|
508
598
|
);
|
|
509
599
|
}
|
|
510
600
|
|
|
511
601
|
/** Copies through the async clipboard, else through a selected textarea (an http:// page, an old Safari). */
|
|
512
|
-
async function copyText(text: string): Promise<boolean> {
|
|
602
|
+
export async function copyText(text: string): Promise<boolean> {
|
|
513
603
|
try {
|
|
514
604
|
if (navigator.clipboard?.writeText) { await navigator.clipboard.writeText(text); return true; }
|
|
515
605
|
} catch { /* permission refused: try the old way */ }
|
package/src/assistant/host.tsx
CHANGED
|
@@ -305,7 +305,8 @@ export function AssistantHost({
|
|
|
305
305
|
aria-label={mode === "hidden" ? undefined : title}
|
|
306
306
|
>
|
|
307
307
|
{mode === "full" ? (
|
|
308
|
-
|
|
308
|
+
// data-gb-dock-chrome: what AssistantChat measures to keep its first line clear of these buttons (0.29.0).
|
|
309
|
+
<div className="gb-dock-fullchrome" data-gb-dock-chrome="">
|
|
309
310
|
{fullActions}
|
|
310
311
|
<button type="button" className="gb-dock-shrink" onClick={onShrink}>
|
|
311
312
|
{/* Two arrows pulled INTO the centre. The first attempt drew two corner brackets, which at 16px
|
package/src/assistant/index.ts
CHANGED
|
@@ -5,3 +5,8 @@ export { AssistantProvider, SIDE_WIDTH_VAR, useAssistant, useAssistantPageFacts,
|
|
|
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";
|
|
7
7
|
export { BRIDGE_TONE, BridgeNotice, ENGINE_PICKER_EN, EnginePanel, EnginePicker, engineChipName, useEnginePicker, type BridgeSetup, type BridgeState, type BridgeStatus, type Choice, type EngineChoice, type EnginePickerLabels, type EnginePickerProps, type EnginePickerTab } from "./engine";
|
|
8
|
+
// 0.29.0: the chat BODY as components (the surface hands in messages and actions), its markdown, and each engine's mark.
|
|
9
|
+
export { AssistantChat, ChatAttach, ChatBubble, ChatComposer, ChatError, ChatLabelsProvider, ChatMarkdown, ChatMessage, ChatMeta, ChatNote, ChatPending, ChatStarters, ChatSteps, ChatThread, CHAT_EN, PaperclipIcon, useComposerDensity, useFullChromeRoom, type AssistantChatProps, type ChatComposerProps, type ChatFix, type ChatLabels, type ChatMarkdownProps, type ChatMessageData, type ChatStarter, type ChatStep, type ComposerDensity } from "./chat";
|
|
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
|
+
export { ENGINE_MARK_ART, ENGINE_MARK_FILL_RULE, EngineMark, isEngineMarkId, type EngineMarkArt, type EngineMarkId } from "./engine-mark";
|
|
12
|
+
export { atBridge, BRIDGE_GONE, bridgeTurnError, PAIRING_REJECTED, useChatTurns, type ChatTurns, type TurnError } from "./chat-turns";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.gb-chat{display:flex;flex-direction:column;min-width:0;min-height:0;height:100%;background:var(--gemboss-surface, #fff)}.gemboss-assistant-layout:not(.is-dock) .gb-chat{background:transparent}.gb-chat>.gemboss-ec-scroll{flex:1 1 auto}.gb-dock:not(.gb-dock-full) .gb-chat-head{display:none}.gb-chat-head{flex:none;box-sizing:border-box;justify-content:center}.gb-chat[data-chrome]>.gb-chat-head{padding-right:var(--gb-chat-chrome-w);min-height:var(--gb-chat-chrome-h)}.gb-chat[data-chrome]:not(:has(>.gb-chat-head))>.gemboss-ec-scroll{padding-top:var(--gb-chat-chrome-h)}.gemboss-ec-starter.gb-chat-starter{white-space:normal;border-radius:12px;text-align:left;overflow-wrap:anywhere}.gb-chat-starter-hint{display:block;margin-bottom:4px;color:var(--gemboss-text-muted);font-size:var(--gemboss-fs-caption, 12px)}.gb-chat-label{margin:0;color:var(--gemboss-text-muted);font-size:var(--gemboss-fs-caption, 12px)}.gb-chat-target{color:var(--gemboss-text-muted)}.gb-chat-meta{display:flex;flex-wrap:wrap;align-items:center;gap:8px;color:var(--gemboss-text-muted);font-size:var(--gemboss-fs-caption, 12px)}.gb-chat-copy{flex:none}.gb-chat-note{margin:0;align-self:center;text-align:center;color:var(--gemboss-text-muted);font-size:var(--gemboss-fs-caption, 12px)}.gb-chat-notice{margin:0}.gb-chat-error{display:grid;gap:8px;margin:0;overflow-wrap:anywhere}.gb-chat-cmd{display:block;padding:6px 8px;border-radius:8px;background:#0000000d;color:var(--gemboss-text);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:16px;overflow-wrap:anywhere;user-select:all}.gb-chat-original>summary{cursor:pointer;min-height:24px;display:flex;align-items:center}.gemboss-ec-input .gemboss-ec-attach-btn{flex:0 0 auto;width:44px;height:44px;border-radius:50%;padding:0;display:inline-flex;align-items:center;justify-content:center;border:0;background-color:transparent;color:var(--gemboss-text-muted);cursor:pointer}.gemboss-ec-input .gemboss-ec-attach-btn:hover:not(:disabled){background-color:var(--gemboss-hover, rgba(0, 0, 0, .05));color:var(--gemboss-text)}.gemboss-ec-input .gemboss-ec-attach-btn:focus-visible{outline:2px solid var(--gemboss-focus, var(--ui-focus, #5661f5));outline-offset:2px}.gemboss-ec-input .gemboss-ec-attach-btn:disabled{opacity:.5;cursor:default}.gemboss-ec-input .gemboss-ec-attach-btn svg{width:24px;height:24px}@media (pointer: fine){.gemboss-ec-input .gb-engine-chip{position:relative}.gemboss-ec-input .gb-engine-chip:after{content:"";position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);height:44px;z-index:1}}@media (pointer: coarse),(max-width: 47.9975em){.gb-chat-original>summary{min-height:44px}}@media (max-width: 560px){.gb-dock-fullchrome .gb-dock-shrink:not(:has(svg)){padding:0 12px;width:auto}.gb-dock-fullchrome .gb-dock-shrink:not(:has(svg)) span{position:static;width:auto;height:auto;overflow:visible;clip:auto}}
|
package/src/assistant-engine.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.gb-engine{display:inline-flex;min-width:0;max-width:100%}.gb-engine-chip{display:inline-flex;align-items:center;gap:6px;min-width:0;max-width:100%;box-sizing:border-box;height:var(--ui-btn-h, 28px);padding:0 24px 0 8px;font:inherit;font-size:var(--ui-fs-caption, 12px);font-weight:500;line-height:20px;white-space:nowrap;color:var(--ui-text-muted);background-color:transparent;border:1px solid transparent;border-radius:var(--ui-radius-md, 8px);cursor:pointer;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23686b71' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 8px center}@media (hover: hover){.gb-engine-chip:hover{color:var(--ui-text);background-color:var(--gemboss-hover, rgba(0,0,0,.05))}}@media (hover: none){.gb-engine-chip{color:var(--ui-text)}}.gb-engine-chip[aria-expanded=true]{color:var(--ui-text);background-color:var(--gemboss-hover, rgba(0,0,0,.05))}.gb-engine-chip:focus-visible{color:var(--ui-text);outline:2px solid var(--ui-focus);outline-offset:2px}.gb-engine-chiplabel{min-width:0;overflow:hidden;text-overflow:ellipsis}.gb-engine-chipsub{font-weight:450}.gb-engine-dot{flex:none;display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--ui-text-muted);vertical-align:middle}.gb-engine-dot--ok{background:var(--gemboss-success, #007f5f)}.gb-engine-dot--warn{background:#e8a10a;box-shadow:0 0 0 1px var(--gemboss-warning, #9a6700) inset}.gb-engine-dot--down{background:var(--gemboss-danger, #d72c0d)}.gb-engine-dot--idle{background:transparent;box-shadow:0 0 0 1.5px var(--ui-text-muted) inset}.gb-engine-panel{position:fixed;z-index:1000;inset:auto;margin:0;width:min(360px,calc(100vw - 16px));box-sizing:border-box;overflow:auto;overscroll-behavior:contain;padding:0 0 var(--ui-space-3, 12px);color:var(--ui-text);font-size:var(--ui-fs-caption, 12px);line-height:16px}.gb-engine-panel[hidden],.gb-engine-panel[popover]:not(:popover-open):not([data-open]){display:none}:where(.gb-engine-panel[popover]){border:0;background:none;color:inherit}.gb-engine-panel--inline{position:static;z-index:auto;overflow:visible}.gb-engine-tabs{padding:0 var(--ui-space-2, 8px)}.gb-engine-tabs>button{gap:6px}.gb-engine-pane{display:grid;gap:var(--ui-space-3, 12px);padding:var(--ui-space-3, 12px) var(--ui-space-3, 12px) 0}.gb-engine-pane p{margin:0}.gb-engine-field{display:grid;gap:6px}.gb-engine-label{font-weight:550;color:var(--ui-text-strong, var(--ui-text))}.gb-engine-note{color:var(--ui-text-muted)}.gb-engine-list{display:grid;border:1px solid var(--ui-border);border-radius:var(--ui-radius-md, 8px);overflow:hidden}.gb-engine-row{display:grid;gap:2px;min-height:44px;padding:6px 10px 6px 32px;box-sizing:border-box;position:relative;font:inherit;text-align:left;color:inherit;background:transparent;border:0;cursor:pointer}.gb-engine-row+.gb-engine-row{border-top:1px solid var(--ui-border)}.gb-engine-row:before{content:"";position:absolute;left:10px;top:50%;width:14px;height:14px;margin-top:-7px;box-sizing:border-box;border:1.5px solid var(--ui-text-muted);border-radius:50%}.gb-engine-row[aria-checked=true]{background:var(--gemboss-active-bg, #f0f1f4)}.gb-engine-row[aria-checked=true]:before{border:4.5px solid var(--ui-accent)}.gb-engine-row[aria-checked=true] .gb-engine-rowname{font-weight:600}@media (hover: hover){.gb-engine-row:hover:not(:disabled){background:var(--ui-surface-2)}}.gb-engine-row:focus-visible{outline:2px solid var(--ui-focus);outline-offset:-2px}.gb-engine-row:disabled{cursor:not-allowed}.gb-engine-row:disabled .gb-engine-rowname{color:var(--ui-text-muted)}.gb-engine-rowhead{display:flex;align-items:center;gap:var(--ui-space-2, 8px);min-width:0}.gb-engine-rowname{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:450}.gb-engine-opts{display:flex;flex-wrap:wrap;gap:var(--ui-space-2, 8px)}.gb-engine-opt{height:var(--ui-btn-h, 28px);padding:0 10px;box-sizing:border-box;font:inherit;font-weight:500;color:var(--ui-text);background:transparent;border:1px solid var(--ui-border);border-radius:var(--ui-radius-md, 8px);cursor:pointer}@media (hover: hover){.gb-engine-opt:hover:not(:disabled){background:var(--ui-surface-2)}}.gb-engine-opt[aria-pressed=true]{background:var(--gemboss-active-bg, #f0f1f4);border-color:var(--ui-text);font-weight:600}.gb-engine-opt:focus-visible{outline:2px solid var(--ui-focus);outline-offset:2px}.gb-engine-opt:disabled{opacity:.5;cursor:not-allowed}.gb-engine-select{width:100%}.gb-engine-notes{display:grid;gap:4px;color:var(--ui-text-muted)}.gb-engine-notes p{margin:0}.gb-engine-callout{padding:8px 10px;border-radius:var(--ui-radius-md, 8px);border:1px solid}.gb-engine-callout--warn{background:var(--gemboss-warning-soft, #fff8e0);border-color:var(--gemboss-warning-border, #f5d569);color:var(--gemboss-warning, #9a6700)}.gb-engine-callout--down{background:var(--gemboss-danger-soft, #fff0e9);border-color:var(--gemboss-danger-border, #f5c9bc);color:var(--gemboss-danger-strong, #b42318)}.gb-engine-steps ol,.gb-engine-steps ul{margin:0;padding-left:18px;display:grid;gap:4px}.gb-engine-cmd{margin:0;padding:8px 10px;border-radius:var(--ui-radius-md, 8px);background:var(--ui-surface-2);border:1px solid var(--ui-border);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11.5px;line-height:16px;white-space:pre-wrap;word-break:break-all;user-select:all;max-height:96px;overflow:auto}.gb-engine-cmd code{padding:0;border:0;background:none;font:inherit;color:inherit}.gb-engine-actions{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ui-space-2, 8px)}.gb-engine-said{color:var(--ui-text-muted)}.gb-engine-said:empty{display:none}.gb-engine-code code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-weight:600;letter-spacing:.04em;user-select:all}.gb-engine-rows{display:grid;grid-template-columns:auto 1fr;gap:6px 12px;margin:0}.gb-engine-rows dt{color:var(--ui-text-muted)}.gb-engine-rows dd{margin:0;display:flex;align-items:center;gap:6px;min-width:0;overflow-wrap:anywhere}.gb-engine-notice{display:
|
|
1
|
+
.gb-engine{display:inline-flex;min-width:0;max-width:100%}.gb-engine-chip{display:inline-flex;align-items:center;gap:6px;min-width:0;max-width:100%;box-sizing:border-box;height:var(--ui-btn-h, 28px);padding:0 24px 0 8px;font:inherit;font-size:var(--ui-fs-caption, 12px);font-weight:500;line-height:20px;white-space:nowrap;color:var(--ui-text-muted);background-color:transparent;border:1px solid transparent;border-radius:var(--ui-radius-md, 8px);cursor:pointer;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='6' viewBox='0 0 10 6'%3E%3Cpath d='M1 1l4 4 4-4' fill='none' stroke='%23686b71' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 8px center}@media (hover: hover){.gb-engine-chip:hover{color:var(--ui-text);background-color:var(--gemboss-hover, rgba(0,0,0,.05))}}@media (hover: none){.gb-engine-chip{color:var(--ui-text)}}.gb-engine-chip[aria-expanded=true]{color:var(--ui-text);background-color:var(--gemboss-hover, rgba(0,0,0,.05))}.gb-engine-chip:focus-visible{color:var(--ui-text);outline:2px solid var(--ui-focus);outline-offset:2px}.gb-engine-chiplabel{min-width:0;overflow:hidden;text-overflow:ellipsis}.gb-engine-chipsub{font-weight:450}.gb-engine-chip:disabled{cursor:default;opacity:.55}.gemboss-engine-mark{display:block;width:14px;height:14px;flex:0 0 auto}.gb-engine-chipmark{display:none}.gb-engine-chipmark .gemboss-engine-mark{width:16px;height:16px}.gemboss-ec-input:not([data-density=full]) .gb-engine-chipsub{display:none}.gemboss-ec-input:is([data-density=icon],[data-density=tight]) .gb-engine-chip.has-mark .gb-engine-chiplabel{display:none}.gemboss-ec-input:is([data-density=icon],[data-density=tight]) .gb-engine-chip.has-mark .gb-engine-chipmark{display:block}.gemboss-ec-input:is([data-density=icon],[data-density=tight]) .gb-engine:has(.has-mark){flex-shrink:0}.gb-engine-dot{flex:none;display:inline-block;width:8px;height:8px;border-radius:50%;background:var(--ui-text-muted);vertical-align:middle}.gb-engine-dot--ok{background:var(--gemboss-success, #007f5f)}.gb-engine-dot--warn{background:#e8a10a;box-shadow:0 0 0 1px var(--gemboss-warning, #9a6700) inset}.gb-engine-dot--down{background:var(--gemboss-danger, #d72c0d)}.gb-engine-dot--idle{background:transparent;box-shadow:0 0 0 1.5px var(--ui-text-muted) inset}.gb-engine-panel{position:fixed;z-index:1000;inset:auto;margin:0;width:min(360px,calc(100vw - 16px));box-sizing:border-box;overflow:auto;overscroll-behavior:contain;padding:0 0 var(--ui-space-3, 12px);color:var(--ui-text);font-size:var(--ui-fs-caption, 12px);line-height:16px}.gb-engine-panel[hidden],.gb-engine-panel[popover]:not(:popover-open):not([data-open]){display:none}:where(.gb-engine-panel[popover]){border:0;background:none;color:inherit}.gb-engine-panel--inline{position:static;z-index:auto;overflow:visible}.gb-engine-tabs{padding:0 var(--ui-space-2, 8px)}.gb-engine-tabs>button{gap:6px}.gb-engine-pane{display:grid;gap:var(--ui-space-3, 12px);padding:var(--ui-space-3, 12px) var(--ui-space-3, 12px) 0}.gb-engine-pane p{margin:0}.gb-engine-field{display:grid;gap:6px}.gb-engine-label{font-weight:550;color:var(--ui-text-strong, var(--ui-text))}.gb-engine-note{color:var(--ui-text-muted)}.gb-engine-list{display:grid;border:1px solid var(--ui-border);border-radius:var(--ui-radius-md, 8px);overflow:hidden}.gb-engine-row{display:grid;gap:2px;min-height:44px;padding:6px 10px 6px 32px;box-sizing:border-box;position:relative;font:inherit;text-align:left;color:inherit;background:transparent;border:0;cursor:pointer}.gb-engine-row+.gb-engine-row{border-top:1px solid var(--ui-border)}.gb-engine-row:before{content:"";position:absolute;left:10px;top:50%;width:14px;height:14px;margin-top:-7px;box-sizing:border-box;border:1.5px solid var(--ui-text-muted);border-radius:50%}.gb-engine-row[aria-checked=true]{background:var(--gemboss-active-bg, #f0f1f4)}.gb-engine-row[aria-checked=true]:before{border:4.5px solid var(--ui-accent)}.gb-engine-row[aria-checked=true] .gb-engine-rowname{font-weight:600}@media (hover: hover){.gb-engine-row:hover:not(:disabled){background:var(--ui-surface-2)}}.gb-engine-row:focus-visible{outline:2px solid var(--ui-focus);outline-offset:-2px}.gb-engine-row:disabled{cursor:not-allowed}.gb-engine-row:disabled .gb-engine-rowname{color:var(--ui-text-muted)}.gb-engine-rowhead{display:flex;align-items:center;gap:var(--ui-space-2, 8px);min-width:0}.gb-engine-rowname{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-weight:450}.gb-engine-opts{display:flex;flex-wrap:wrap;gap:var(--ui-space-2, 8px)}.gb-engine-opt{height:var(--ui-btn-h, 28px);padding:0 10px;box-sizing:border-box;font:inherit;font-weight:500;color:var(--ui-text);background:transparent;border:1px solid var(--ui-border);border-radius:var(--ui-radius-md, 8px);cursor:pointer}@media (hover: hover){.gb-engine-opt:hover:not(:disabled){background:var(--ui-surface-2)}}.gb-engine-opt[aria-pressed=true]{background:var(--gemboss-active-bg, #f0f1f4);border-color:var(--ui-text);font-weight:600}.gb-engine-opt:focus-visible{outline:2px solid var(--ui-focus);outline-offset:2px}.gb-engine-opt:disabled{opacity:.5;cursor:not-allowed}.gb-engine-select{width:100%}.gb-engine-groups{display:grid;gap:var(--ui-space-3, 12px)}.gb-engine-group{display:grid;gap:6px}.gb-engine-group+.gb-engine-group{padding-top:var(--ui-space-3, 12px);border-top:1px solid var(--ui-border)}.gb-engine-group[data-current] .gb-engine-rowname{font-weight:600}.gb-engine-problem{color:var(--gemboss-danger-strong, #b42318)}.gb-engine-notes{display:grid;gap:4px;color:var(--ui-text-muted)}.gb-engine-notes p{margin:0}.gb-engine-callout{padding:8px 10px;border-radius:var(--ui-radius-md, 8px);border:1px solid}.gb-engine-callout--warn{background:var(--gemboss-warning-soft, #fff8e0);border-color:var(--gemboss-warning-border, #f5d569);color:var(--gemboss-warning, #9a6700)}.gb-engine-callout--down{background:var(--gemboss-danger-soft, #fff0e9);border-color:var(--gemboss-danger-border, #f5c9bc);color:var(--gemboss-danger-strong, #b42318)}.gb-engine-steps ol,.gb-engine-steps ul{margin:0;padding-left:18px;display:grid;gap:4px}.gb-engine-cmd{margin:0;padding:8px 10px;border-radius:var(--ui-radius-md, 8px);background:var(--ui-surface-2);border:1px solid var(--ui-border);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11.5px;line-height:16px;white-space:pre-wrap;word-break:break-all;user-select:all;max-height:96px;overflow:auto}.gb-engine-cmd code{padding:0;border:0;background:none;font:inherit;color:inherit}.gb-engine-actions{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ui-space-2, 8px)}.gb-engine-said{color:var(--ui-text-muted)}.gb-engine-said:empty{display:none}.gb-engine-code code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-weight:600;letter-spacing:.04em;user-select:all}.gb-engine-rows{display:grid;grid-template-columns:auto 1fr;gap:6px 12px;margin:0}.gb-engine-rows dt{color:var(--ui-text-muted)}.gb-engine-rows dd{margin:0;display:flex;align-items:center;gap:6px;min-width:0;overflow-wrap:anywhere}.gb-engine-notice{display:grid;grid-template-columns:auto minmax(0,1fr);align-items:start;gap:4px 6px;margin:0;padding:4px 0;font-size:var(--ui-fs-caption, 12px);line-height:16px;color:var(--ui-text-muted)}.gb-engine-notice>.gb-engine-dot{margin-top:4px}.gb-engine-notice>.gb-engine-notice-link{grid-column:2;justify-self:start}.gb-engine-notice--down .gb-engine-notice-text,.gb-engine-notice--warn .gb-engine-notice-text{color:var(--ui-text)}.gb-engine-notice-text{min-width:0;overflow-wrap:anywhere}.gb-engine-notice-link{flex:none;display:inline-flex;align-items:center;min-height:24px;margin:-4px 0 -4px -4px;padding:0 4px;border:0;border-radius:4px;background:none;font:inherit;font-weight:550;color:var(--ui-accent);text-decoration:underline;text-underline-offset:2px;cursor:pointer}.gb-engine-notice-link:focus-visible{outline:2px solid var(--ui-focus);outline-offset:0}@media (pointer: coarse),(max-width: 47.9975em){.gb-engine-chip{min-height:44px}.gb-engine-opt{min-height:44px;min-width:44px}.gb-engine-notice-link{min-height:44px;margin:-14px 0 -14px -8px;padding:0 8px}}@media (prefers-reduced-motion: no-preference){.gb-engine-chip,.gb-engine-opt,.gb-engine-row{transition:background-color .12s ease,color .12s ease}}
|
package/src/auth.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.gb-auth{--gb-surface: #ffffff;--gb-ink: var(--gemboss-text-strong, #1b1c1e);--gb-muted: #6d7175;--gb-line: #e1e3e5;--gb-field-line: #c9cccf;--gb-field-bg: #ffffff;--gb-field-hover: #fafafa;--gb-placeholder: #868b94;--gb-accent: #5661f5;--gb-btn: linear-gradient(120deg, #1b1c1e 0%, #000000 100%);--gb-btn-ink: #ffffff;--gb-wordmark: linear-gradient(120deg, #1b1c1e 0%, #000000 100%);--gb-hover: #f7f7f5;--gb-hover-line: #b9bbc0;--gb-err-bg: #fee2e2;--gb-err-ink: #b91c1c;--gb-err-line: transparent;--gb-card-shadow: 0 24px 64px rgba(15, 23, 42, .08);--gb-mark-bg: #0b0b0c;--gb-facet: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 120'%3E%3Cg fill='none' stroke='%23ffffff' stroke-width='0.45' stroke-linejoin='round'%3E%3Cpath d='M26,14 74,14 96,50 50,110 4,50Z'/%3E%3Cpath d='M4,50H96M26,14 34,50M74,14 66,50M34,50 50,110M66,50 50,110'/%3E%3C/g%3E%3C/svg%3E");--gb-page: radial-gradient(1200px 600px at 20% 10%, rgba(27, 28, 30, .05), transparent 60%), radial-gradient(1000px 500px at 80% 90%, rgba(86, 97, 245, .06), transparent 60%), #fafafb;--gb-page-flat: #ffffff;--gb-panel-bg: radial-gradient(900px 520px at 78% 12%, rgba(86, 97, 245, .26), transparent 62%), radial-gradient(700px 480px at 12% 96%, rgba(86, 97, 245, .12), transparent 60%), #0b0b0c;--gb-panel-ink: #f4f4f2;--gb-panel-muted: rgba(244, 244, 242, .72);--gb-panel-eyebrow: #8a93ff;--gb-panel-facet-o: .05;color-scheme:light dark;position:fixed;top:var(--vvt, 0px);left:0;right:0;height:100vh;height:var(--vvh, 100dvh);container:gb-auth / size;overflow-y:auto;background:var(--gb-page);color:var(--gb-ink);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.gb-auth-split{display:grid;grid-template-columns:1fr;min-height:100%}.gb-auth-stage{box-sizing:border-box;display:flex;min-height:100%;padding:clamp(12px,3cqh,24px) clamp(16px,4vw,24px)}.gb-auth-panel-in{position:relative;box-sizing:border-box;width:100%;max-width:520px;padding:48px clamp(32px,5vw,64px)}.gb-auth-eyebrow{margin:0 0 20px;font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,monospace;font-size:12px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--gb-panel-eyebrow)}.gb-auth-panel-h{margin:0 0 16px;font-size:clamp(28px,3.2vw,40px);line-height:1.15;letter-spacing:-.02em;font-weight:700;color:var(--gb-panel-ink)}.gb-auth-panel-p{margin:0;font-size:15px;line-height:1.6;color:var(--gb-panel-muted)}.gb-auth-panel{display:none}@container gb-auth (min-width: 900px) and (min-height: 520px){.gb-auth-split{grid-template-columns:minmax(420px,1fr) minmax(0,1.05fr)}.gb-auth-split .gb-auth-stage{background:var(--gb-surface)}.gb-auth-split .gb-auth-card{border:none;box-shadow:none;max-width:400px}.gb-auth-panel{display:flex;align-items:center;position:relative;overflow:hidden;background:var(--gb-panel-bg);color:var(--gb-panel-ink)}.gb-auth-panel:before{content:"";position:absolute;inset:-45% -38% auto auto;width:132%;aspect-ratio:1;background-image:var(--gb-facet);background-size:contain;background-repeat:no-repeat;opacity:var(--gb-panel-facet-o);pointer-events:none}}.gb-auth-card{width:100%;max-width:380px;margin:auto;background:var(--gb-surface);border:1px solid var(--gb-line);border-radius:14px;padding:clamp(18px,3.5cqh,28px) 28px;box-shadow:var(--gb-card-shadow)}.gb-auth-header{text-align:center;margin-bottom:clamp(12px,3cqh,24px)}.gb-auth-mark{display:inline-flex;margin-bottom:clamp(6px,calc(6px + (100cqh - 480px)*.075),12px)}.gb-auth-mark svg,.gb-auth-mark img{width:clamp(32px,calc(32px + (100cqh - 480px)*.3),56px);height:clamp(32px,calc(32px + (100cqh - 480px)*.3),56px)}@container gb-auth (max-height: 479.98px){.gb-auth-mark{display:none}}.gb-auth-header h1{font-size:clamp(19px,2.75cqh,22px);font-weight:700;margin:0 0 clamp(0px,calc((100cqh - 560px)*.1),4px);background:var(--gb-wordmark);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.gb-auth-header p{margin:0;font-size:13px;color:var(--gb-muted)}@container gb-auth (max-height: 599.98px){.gb-auth-header p{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}}.gb-auth-form{display:flex;flex-direction:column;gap:clamp(8px,1.5cqh,12px)}.gb-auth-form label{display:flex;flex-direction:column;gap:clamp(4px,.75cqh,6px);font-size:12px;font-weight:500;color:var(--gb-ink)}.gb-auth-input{box-sizing:border-box;height:32px;min-height:44px;min-width:0;padding:0 12px;font:inherit;font-size:13px;line-height:20px;border:1px solid;border-radius:8px}@media (max-width: 47.9975em){.gb-auth-input{font-size:16px}}@media (pointer: coarse){.gb-auth-input{height:auto}}.gb-auth-form input{width:100%;box-sizing:border-box;background-color:var(--gb-field-bg);border-color:var(--gb-field-line);color:var(--gb-ink)}.gb-auth-form input::placeholder{color:var(--gb-placeholder)}.gb-auth-form input:hover:not(:disabled){background-color:var(--gb-field-hover);border-color:var(--gb-hover-line)}.gb-auth-form input:focus-visible{outline:2px solid var(--gb-ink);outline-offset:1px;border-color:var(--gb-ink)}.gb-auth-field{display:flex;flex-direction:column;gap:clamp(4px,.75cqh,6px);font-size:12px;font-weight:500;color:var(--gb-ink)}.gb-auth-pw{position:relative;display:flex}.gb-auth-pw input{width:100%;padding-right:48px}.gb-auth-pw-toggle{min-height:44px;min-width:44px;position:absolute;right:0;top:0;bottom:0;display:inline-flex;align-items:center;justify-content:center;padding:0;margin:0;background:none;border:none;border-radius:8px;cursor:pointer;color:var(--gb-muted);transition:none}.gb-auth-pw-toggle:hover{color:var(--gb-ink)}.gb-auth-pw-toggle:focus-visible{outline:2px solid var(--gemboss-primary, #1b1c1e);outline-offset:-2px}.gb-auth-error{background:var(--gb-err-bg);border:1px solid var(--gb-err-line);color:var(--gb-err-ink);padding:8px 10px;font-size:13px;border-radius:6px}.gb-auth-form>.gb-auth-submit{margin-top:clamp(2px,.75cqh,6px);min-height:44px;font-size:14px;font-weight:600;border:none;border-radius:8px;background:var(--gb-btn);color:var(--gb-btn-ink);cursor:pointer;font-family:inherit;transition:opacity .15s ease,transform .15s ease}.gb-auth-form>.gb-auth-submit:hover:not(:disabled){transform:translateY(-1px)}.gb-auth-form>.gb-auth-submit:disabled{opacity:.6;cursor:not-allowed}.gb-auth-foot{margin:clamp(10px,2cqh,16px) 0 0;font-size:13px;color:var(--gb-muted);text-align:center;line-height:1.5}.gb-auth-foot a{display:inline-block;min-height:24px;line-height:24px;padding:0 2px;color:var(--gb-accent);font-weight:600;text-decoration:none}.gb-auth-foot a:hover,.gb-auth-foot a:focus-visible{text-decoration:underline}.gb-auth-card .gb-auth-help{margin:clamp(8px,1.75cqh,14px) 0 0;font-size:12px;color:var(--gb-muted);text-align:center;line-height:1.5}.gb-auth-card .gb-auth-help a{display:inline-block;min-height:24px;line-height:24px;color:var(--gb-accent);font-weight:600;text-decoration:none}.gb-auth-card .gb-auth-help a:hover,.gb-auth-card .gb-auth-help a:focus-visible{text-decoration:underline}@media (max-width: 480px){.gb-auth{background:var(--gb-page-flat)}.gb-auth-stage{padding:max(clamp(10px,3cqh,20px),env(safe-area-inset-top)) max(16px,env(safe-area-inset-right)) max(clamp(10px,3cqh,20px),env(safe-area-inset-bottom)) max(16px,env(safe-area-inset-left))}.gb-auth-card{border:none;border-radius:0;box-shadow:none;padding:0}}@container gb-auth (max-height: 399.98px){.gb-auth-header{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}}@container gb-auth (max-height: 359.98px){.gb-auth-card .gb-auth-help,.gb-auth-foot{display:none}.gb-auth-stage{padding-top:max(8px,env(safe-area-inset-top));padding-bottom:max(8px,env(safe-area-inset-bottom))}}@container gb-auth (max-height: 359.98px) and (min-width: 481px){.gb-auth-card{padding-top:14px;padding-bottom:14px}}@media (prefers-color-scheme: dark){:root:not([data-theme=light]) .gb-auth{--gb-surface: #141517;--gb-ink: #f4f4f3;--gb-muted: #969c97;--gb-line: rgba(255, 255, 255, .11);--gb-field-line: rgba(255, 255, 255, .17);--gb-field-bg: #1b1c1f;--gb-field-hover: #212226;--gb-placeholder: #7f838c;--gb-accent: #8a93ff;--gb-btn: linear-gradient(120deg, #f4f4f3 0%, #dfe0e4 100%);--gb-btn-ink: #0b0b0c;--gb-wordmark: linear-gradient(120deg, #f4f4f3 0%, #c9cbd2 100%);--gb-hover: rgba(255, 255, 255, .06);--gb-hover-line: rgba(255, 255, 255, .28);--gb-err-bg: rgba(215, 44, 13, .16);--gb-err-ink: #ff9d88;--gb-err-line: rgba(245, 120, 95, .4);--gb-card-shadow: 0 24px 64px rgba(0, 0, 0, .55);--gb-mark-bg: #202127;--gb-page: radial-gradient(1200px 600px at 20% 10%, rgba(255, 255, 255, .05), transparent 60%), radial-gradient(1000px 500px at 80% 90%, rgba(138, 147, 255, .1), transparent 60%), #0b0b0c;--gb-page-flat: #0b0b0c}}:root[data-theme=dark] .gb-auth{--gb-surface: #141517;--gb-ink: #f4f4f3;--gb-muted: #969c97;--gb-line: rgba(255, 255, 255, .11);--gb-field-line: rgba(255, 255, 255, .17);--gb-field-bg: #1b1c1f;--gb-field-hover: #212226;--gb-placeholder: #7f838c;--gb-accent: #8a93ff;--gb-btn: linear-gradient(120deg, #f4f4f3 0%, #dfe0e4 100%);--gb-btn-ink: #0b0b0c;--gb-wordmark: linear-gradient(120deg, #f4f4f3 0%, #c9cbd2 100%);--gb-hover: rgba(255, 255, 255, .06);--gb-hover-line: rgba(255, 255, 255, .28);--gb-err-bg: rgba(215, 44, 13, .16);--gb-err-ink: #ff9d88;--gb-err-line: rgba(245, 120, 95, .4);--gb-card-shadow: 0 24px 64px rgba(0, 0, 0, .55);--gb-mark-bg: #202127;--gb-page: radial-gradient(1200px 600px at 20% 10%, rgba(255, 255, 255, .05), transparent 60%), radial-gradient(1000px 500px at 80% 90%, rgba(138, 147, 255, .1), transparent 60%), #0b0b0c;--gb-page-flat: #0b0b0c}
|
|
1
|
+
.gb-auth{--gb-surface: #ffffff;--gb-ink: var(--gemboss-text-strong, #1b1c1e);--gb-muted: #6d7175;--gb-line: #e1e3e5;--gb-field-line: #c9cccf;--gb-field-bg: #ffffff;--gb-field-hover: #fafafa;--gb-placeholder: #868b94;--gb-accent: #5661f5;--gb-btn: linear-gradient(120deg, #1b1c1e 0%, #000000 100%);--gb-btn-ink: #ffffff;--gb-wordmark: linear-gradient(120deg, #1b1c1e 0%, #000000 100%);--gb-hover: #f7f7f5;--gb-hover-line: #b9bbc0;--gb-err-bg: #fee2e2;--gb-err-ink: #b91c1c;--gb-err-line: transparent;--gb-card-shadow: 0 24px 64px rgba(15, 23, 42, .08);--gb-mark-bg: #0b0b0c;--gb-facet: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 100 120'%3E%3Cg fill='none' stroke='%23ffffff' stroke-width='0.45' stroke-linejoin='round'%3E%3Cpath d='M26,14 74,14 96,50 50,110 4,50Z'/%3E%3Cpath d='M4,50H96M26,14 34,50M74,14 66,50M34,50 50,110M66,50 50,110'/%3E%3C/g%3E%3C/svg%3E");--gb-page: radial-gradient(1200px 600px at 20% 10%, rgba(27, 28, 30, .05), transparent 60%), radial-gradient(1000px 500px at 80% 90%, rgba(86, 97, 245, .06), transparent 60%), #fafafb;--gb-page-flat: #ffffff;--gb-panel-bg: radial-gradient(900px 520px at 78% 12%, rgba(86, 97, 245, .26), transparent 62%), radial-gradient(700px 480px at 12% 96%, rgba(86, 97, 245, .12), transparent 60%), #0b0b0c;--gb-panel-ink: #f4f4f2;--gb-panel-muted: rgba(244, 244, 242, .72);--gb-panel-eyebrow: #8a93ff;--gb-panel-facet-o: .05;--gb-panel-grid-bg: linear-gradient(160deg, #1b1c22 0%, #0b0b0c 72%);--gb-panel-grid-line: rgba(138, 147, 255, .1);--gb-panel-grid-size: 34px;--gb-panel-grid-fade: radial-gradient(90% 80% at 30% 20%, #000, transparent 75%);color-scheme:light dark;position:fixed;top:var(--vvt, 0px);left:0;right:0;height:100vh;height:var(--vvh, 100dvh);container:gb-auth / size;overflow-y:auto;background:var(--gb-page);color:var(--gb-ink);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,system-ui,sans-serif}.gb-auth-split{display:grid;grid-template-columns:1fr;min-height:100%}.gb-auth-stage{box-sizing:border-box;display:flex;min-height:100%;padding:clamp(12px,3cqh,24px) clamp(16px,4vw,24px)}.gb-auth-panel-in{position:relative;box-sizing:border-box;width:100%;max-width:520px;padding:48px clamp(32px,5vw,64px)}.gb-auth-eyebrow{margin:0 0 20px;font-family:ui-monospace,SFMono-Regular,SF Mono,Menlo,monospace;font-size:12px;font-weight:500;letter-spacing:.12em;text-transform:uppercase;color:var(--gb-panel-eyebrow)}.gb-auth-panel-h{margin:0 0 16px;font-size:clamp(28px,3.2vw,40px);line-height:1.15;letter-spacing:-.02em;font-weight:700;color:var(--gb-panel-ink)}.gb-auth-panel-p{margin:0;font-size:15px;line-height:1.6;color:var(--gb-panel-muted)}.gb-auth-panel{display:none}@container gb-auth (min-width: 900px) and (min-height: 520px){.gb-auth-split{grid-template-columns:minmax(420px,1fr) minmax(0,1.05fr)}.gb-auth-split .gb-auth-stage{background:var(--gb-surface)}.gb-auth-split .gb-auth-card{border:none;box-shadow:none;max-width:400px}.gb-auth-panel{display:flex;align-items:center;position:relative;overflow:hidden;background:var(--gb-panel-bg);color:var(--gb-panel-ink)}.gb-auth-panel:before{content:"";position:absolute;inset:-45% -38% auto auto;width:132%;aspect-ratio:1;background-image:var(--gb-facet);background-size:contain;background-repeat:no-repeat;opacity:var(--gb-panel-facet-o);pointer-events:none}.gb-auth-split .gb-auth-panel--grid{background:var(--gb-panel-grid-bg)}.gb-auth-panel.gb-auth-panel--grid:before{inset:0;width:auto;aspect-ratio:auto;background-image:linear-gradient(var(--gb-panel-grid-line) 1px,transparent 1px),linear-gradient(90deg,var(--gb-panel-grid-line) 1px,transparent 1px);background-size:var(--gb-panel-grid-size) var(--gb-panel-grid-size);background-repeat:repeat;opacity:1;-webkit-mask-image:var(--gb-panel-grid-fade);mask-image:var(--gb-panel-grid-fade)}.gb-auth-panel.gb-auth-panel--none:before{content:none}}.gb-auth-card{width:100%;max-width:380px;margin:auto;background:var(--gb-surface);border:1px solid var(--gb-line);border-radius:14px;padding:clamp(18px,3.5cqh,28px) 28px;box-shadow:var(--gb-card-shadow)}.gb-auth-header{text-align:center;margin-bottom:clamp(12px,3cqh,24px)}.gb-auth-mark{display:inline-flex;margin-bottom:clamp(6px,calc(6px + (100cqh - 480px)*.075),12px)}.gb-auth-mark svg,.gb-auth-mark img{width:clamp(32px,calc(32px + (100cqh - 480px)*.3),56px);height:clamp(32px,calc(32px + (100cqh - 480px)*.3),56px)}@container gb-auth (max-height: 479.98px){.gb-auth-mark{display:none}}.gb-auth-header h1{font-size:clamp(19px,2.75cqh,22px);font-weight:700;margin:0 0 clamp(0px,calc((100cqh - 560px)*.1),4px);background:var(--gb-wordmark);-webkit-background-clip:text;-webkit-text-fill-color:transparent;background-clip:text}.gb-auth-header p{margin:0;font-size:13px;color:var(--gb-muted)}@container gb-auth (max-height: 599.98px){.gb-auth-header p{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}}.gb-auth-form{display:flex;flex-direction:column;gap:clamp(8px,1.5cqh,12px)}.gb-auth-form label{display:flex;flex-direction:column;gap:clamp(4px,.75cqh,6px);font-size:12px;font-weight:500;color:var(--gb-ink)}.gb-auth-input{box-sizing:border-box;height:32px;min-height:44px;min-width:0;padding:0 12px;font:inherit;font-size:13px;line-height:20px;border:1px solid;border-radius:8px}@media (max-width: 47.9975em){.gb-auth-input{font-size:16px}}@media (pointer: coarse){.gb-auth-input{height:auto}}.gb-auth-form input{width:100%;box-sizing:border-box;background-color:var(--gb-field-bg);border-color:var(--gb-field-line);color:var(--gb-ink)}.gb-auth-form input::placeholder{color:var(--gb-placeholder)}.gb-auth-form input:hover:not(:disabled){background-color:var(--gb-field-hover);border-color:var(--gb-hover-line)}.gb-auth-form input:focus-visible{outline:2px solid var(--gb-ink);outline-offset:1px;border-color:var(--gb-ink)}.gb-auth-field{display:flex;flex-direction:column;gap:clamp(4px,.75cqh,6px);font-size:12px;font-weight:500;color:var(--gb-ink)}.gb-auth-pw{position:relative;display:flex}.gb-auth-pw input{width:100%;padding-right:48px}.gb-auth-pw-toggle{min-height:44px;min-width:44px;position:absolute;right:0;top:0;bottom:0;display:inline-flex;align-items:center;justify-content:center;padding:0;margin:0;background:none;border:none;border-radius:8px;cursor:pointer;color:var(--gb-muted);transition:none}.gb-auth-pw-toggle:hover{color:var(--gb-ink)}.gb-auth-pw-toggle:focus-visible{outline:2px solid var(--gemboss-primary, #1b1c1e);outline-offset:-2px}.gb-auth-error{background:var(--gb-err-bg);border:1px solid var(--gb-err-line);color:var(--gb-err-ink);padding:8px 10px;font-size:13px;border-radius:6px}.gb-auth-form>.gb-auth-submit{margin-top:clamp(2px,.75cqh,6px);min-height:44px;font-size:14px;font-weight:600;border:none;border-radius:8px;background:var(--gb-btn);color:var(--gb-btn-ink);cursor:pointer;font-family:inherit;transition:opacity .15s ease,transform .15s ease}.gb-auth-form>.gb-auth-submit:hover:not(:disabled){transform:translateY(-1px)}.gb-auth-form>.gb-auth-submit:disabled{opacity:.6;cursor:not-allowed}.gb-auth-foot{margin:clamp(10px,2cqh,16px) 0 0;font-size:13px;color:var(--gb-muted);text-align:center;line-height:1.5}.gb-auth-foot a{display:inline-block;min-height:24px;line-height:24px;padding:0 2px;color:var(--gb-accent);font-weight:600;text-decoration:none}.gb-auth-foot a:hover,.gb-auth-foot a:focus-visible{text-decoration:underline}.gb-auth-card .gb-auth-help{margin:clamp(8px,1.75cqh,14px) 0 0;font-size:12px;color:var(--gb-muted);text-align:center;line-height:1.5}.gb-auth-card .gb-auth-help a{display:inline-block;min-height:24px;line-height:24px;color:var(--gb-accent);font-weight:600;text-decoration:none}.gb-auth-card .gb-auth-help a:hover,.gb-auth-card .gb-auth-help a:focus-visible{text-decoration:underline}@media (max-width: 480px){.gb-auth{background:var(--gb-page-flat)}.gb-auth-stage{padding:max(clamp(10px,3cqh,20px),env(safe-area-inset-top)) max(16px,env(safe-area-inset-right)) max(clamp(10px,3cqh,20px),env(safe-area-inset-bottom)) max(16px,env(safe-area-inset-left))}.gb-auth-card{border:none;border-radius:0;box-shadow:none;padding:0}}@container gb-auth (max-height: 399.98px){.gb-auth-header{position:absolute;width:1px;height:1px;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}}@container gb-auth (max-height: 359.98px){.gb-auth-card .gb-auth-help,.gb-auth-foot{display:none}.gb-auth-stage{padding-top:max(8px,env(safe-area-inset-top));padding-bottom:max(8px,env(safe-area-inset-bottom))}}@container gb-auth (max-height: 359.98px) and (min-width: 481px){.gb-auth-card{padding-top:14px;padding-bottom:14px}}@media (prefers-color-scheme: dark){:root:not([data-theme=light]) .gb-auth{--gb-surface: #141517;--gb-ink: #f4f4f3;--gb-muted: #969c97;--gb-line: rgba(255, 255, 255, .11);--gb-field-line: rgba(255, 255, 255, .17);--gb-field-bg: #1b1c1f;--gb-field-hover: #212226;--gb-placeholder: #7f838c;--gb-accent: #8a93ff;--gb-btn: linear-gradient(120deg, #f4f4f3 0%, #dfe0e4 100%);--gb-btn-ink: #0b0b0c;--gb-wordmark: linear-gradient(120deg, #f4f4f3 0%, #c9cbd2 100%);--gb-hover: rgba(255, 255, 255, .06);--gb-hover-line: rgba(255, 255, 255, .28);--gb-err-bg: rgba(215, 44, 13, .16);--gb-err-ink: #ff9d88;--gb-err-line: rgba(245, 120, 95, .4);--gb-card-shadow: 0 24px 64px rgba(0, 0, 0, .55);--gb-mark-bg: #202127;--gb-page: radial-gradient(1200px 600px at 20% 10%, rgba(255, 255, 255, .05), transparent 60%), radial-gradient(1000px 500px at 80% 90%, rgba(138, 147, 255, .1), transparent 60%), #0b0b0c;--gb-page-flat: #0b0b0c}}:root[data-theme=dark] .gb-auth{--gb-surface: #141517;--gb-ink: #f4f4f3;--gb-muted: #969c97;--gb-line: rgba(255, 255, 255, .11);--gb-field-line: rgba(255, 255, 255, .17);--gb-field-bg: #1b1c1f;--gb-field-hover: #212226;--gb-placeholder: #7f838c;--gb-accent: #8a93ff;--gb-btn: linear-gradient(120deg, #f4f4f3 0%, #dfe0e4 100%);--gb-btn-ink: #0b0b0c;--gb-wordmark: linear-gradient(120deg, #f4f4f3 0%, #c9cbd2 100%);--gb-hover: rgba(255, 255, 255, .06);--gb-hover-line: rgba(255, 255, 255, .28);--gb-err-bg: rgba(215, 44, 13, .16);--gb-err-ink: #ff9d88;--gb-err-line: rgba(245, 120, 95, .4);--gb-card-shadow: 0 24px 64px rgba(0, 0, 0, .55);--gb-mark-bg: #202127;--gb-page: radial-gradient(1200px 600px at 20% 10%, rgba(255, 255, 255, .05), transparent 60%), radial-gradient(1000px 500px at 80% 90%, rgba(138, 147, 255, .1), transparent 60%), #0b0b0c;--gb-page-flat: #0b0b0c}
|
package/src/auth.tsx
CHANGED
|
@@ -20,11 +20,24 @@ import { GemMark } from "./GemMark";
|
|
|
20
20
|
|
|
21
21
|
const cx = (...parts: Array<string | false | null | undefined>) => parts.filter(Boolean).join(" ");
|
|
22
22
|
|
|
23
|
+
/**
|
|
24
|
+
* What the brand panel's ground draws (0.30.0).
|
|
25
|
+
* - `"facet"` (the default, unchanged since 28/09/2026): the mark's facet lines, oversized, at 5%, over iris washes on ink.
|
|
26
|
+
* - `"grid"`: a 34px iris grid that fades out from the panel's top-left corner, on an ink gradient. gemform's sign-in
|
|
27
|
+
* drew it under its logo; Chris liked it (08/10/2026: "cái background bên dưới logo cũng đẹp"), so any sign-in can
|
|
28
|
+
* pick it. Re-tune it with `--gb-panel-grid-*` on `.gb-auth`, never by restyling the class.
|
|
29
|
+
* - `"none"`: the panel's ground alone, no pattern.
|
|
30
|
+
* A page that writes the markup itself puts `gb-auth-panel--grid` / `gb-auth-panel--none` beside `gb-auth-panel`.
|
|
31
|
+
*/
|
|
32
|
+
export type AuthBackdrop = "facet" | "grid" | "none";
|
|
33
|
+
// Whole class names, not `gb-auth-panel--${backdrop}`: written out, grep and the admin's orphan-rule gate can see them.
|
|
34
|
+
const BACKDROP: Record<AuthBackdrop, string> = { facet: "", grid: "gb-auth-panel--grid", none: "gb-auth-panel--none" };
|
|
35
|
+
|
|
23
36
|
/**
|
|
24
37
|
* The whole screen. `children` is everything inside the card below the heading: the form, then any
|
|
25
38
|
* lines under it.
|
|
26
39
|
*/
|
|
27
|
-
export function AuthLayout({ brand, tagline, mark, panel, className, children }: {
|
|
40
|
+
export function AuthLayout({ brand, tagline, mark, panel, backdrop = "facet", className, children }: {
|
|
28
41
|
/** The page heading (h1) in the card. */
|
|
29
42
|
brand: React.ReactNode;
|
|
30
43
|
/** One line under the heading; the first thing shed on a short screen. */
|
|
@@ -33,6 +46,8 @@ export function AuthLayout({ brand, tagline, mark, panel, className, children }:
|
|
|
33
46
|
mark?: React.ReactNode;
|
|
34
47
|
/** The brand panel beside the card — shown only where there is room (900 wide AND 520 tall). */
|
|
35
48
|
panel?: { eyebrow?: React.ReactNode; heading: React.ReactNode; body?: React.ReactNode };
|
|
49
|
+
/** The panel's ground pattern; see `AuthBackdrop`. Only drawn where the panel is (900 wide AND 520 tall). */
|
|
50
|
+
backdrop?: AuthBackdrop;
|
|
36
51
|
className?: string;
|
|
37
52
|
children?: React.ReactNode;
|
|
38
53
|
}) {
|
|
@@ -89,7 +104,7 @@ export function AuthLayout({ brand, tagline, mark, panel, className, children }:
|
|
|
89
104
|
{/* Left OUT of aria-hidden: the words are an invitation and a screen-reader user should hear
|
|
90
105
|
them. Nothing in it is focusable — it is decoration beside the form, not a second path. */}
|
|
91
106
|
{panel ? (
|
|
92
|
-
<aside className="gb-auth-panel">
|
|
107
|
+
<aside className={cx("gb-auth-panel", BACKDROP[backdrop])}>
|
|
93
108
|
<div className="gb-auth-panel-in">
|
|
94
109
|
{panel.eyebrow ? <p className="gb-auth-eyebrow">{panel.eyebrow}</p> : null}
|
|
95
110
|
<h2 className="gb-auth-panel-h">{panel.heading}</h2>
|
package/src/chat-composer.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.gemboss-ec-toolbar{flex:1 0 100%;display:flex;align-items:center;gap:4px;min-width:0}.gemboss-ec-toolbar-lead{flex:1 1 auto;display:flex;align-items:center;gap:4px;min-width:0}.gemboss-ec-toolbar-lead:empty{display:none}.gemboss-ec-toolbar-lead:empty+*{margin-left:auto}.gemboss-ec-toolbar-tools{display:flex;align-items:center;gap:4px;flex:none;min-width:0}.gemboss-ec-toolbar-tools:empty{display:none}.gemboss-ec-input:has(>.gemboss-ec-toolbar>.gemboss-ec-toolbar-lead:empty){flex-wrap:nowrap;align-items:flex-end}.gemboss-ec-input:has(>.gemboss-ec-toolbar>.gemboss-ec-toolbar-lead:empty)>textarea{flex:1 1 0}.gemboss-ec-input:has(>.gemboss-ec-toolbar>.gemboss-ec-toolbar-lead:empty)>.gemboss-ec-toolbar{flex:0 0 auto}
|
|
1
|
+
.gemboss-ec-toolbar{flex:1 0 100%;display:flex;align-items:center;gap:4px;min-width:0}.gemboss-ec-toolbar-lead{flex:1 1 auto;display:flex;align-items:center;gap:4px;min-width:0}.gemboss-ec-toolbar-lead:empty{display:none}.gemboss-ec-toolbar-lead:empty+*{margin-left:auto}.gemboss-ec-toolbar-tools{display:flex;align-items:center;gap:4px;flex:none;min-width:0}.gemboss-ec-toolbar-tools:empty{display:none}.gemboss-ec-input:has(>.gemboss-ec-toolbar>.gemboss-ec-toolbar-lead:empty){flex-wrap:nowrap;align-items:flex-end}.gemboss-ec-input:has(>.gemboss-ec-toolbar>.gemboss-ec-toolbar-lead:empty)>textarea{flex:1 1 0}.gemboss-ec-input:has(>.gemboss-ec-toolbar>.gemboss-ec-toolbar-lead:empty)>.gemboss-ec-toolbar{flex:0 0 auto}@media (pointer: coarse){.gemboss-ec-input .gemboss-ec-stop{width:44px;height:44px;min-width:44px}.gemboss-ec-input .gemboss-ec-stop-send{min-height:44px}}.gemboss-ec-stop{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:44px;height:44px;min-width:44px;border:none;border-radius:50%;background:var(--gemboss-critical, #d72c0d);color:#fff;cursor:pointer}.gemboss-ec-stop svg{width:12px;height:12px;fill:currentColor}.gemboss-ec-stop:disabled{opacity:.6;cursor:default}.gemboss-ec-stop:hover{filter:brightness(1.08)}.gemboss-ec-stop:focus-visible{outline:2px solid var(--gemboss-focus, var(--ui-focus, #5661f5));outline-offset:2px}
|
|
@@ -0,0 +1,6 @@
|
|
|
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(`
|
|
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
|
+
`)});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
|
+
`),t=r.length>j,a=!1,i=l("code",{text:t?r.slice(0,j).join(`
|
|
5
|
+
`):e.body}),s=l("div",{className:"gemboss-md-codeblock"},[e.lang?l("span",{className:"gemboss-md-codelang",text:e.lang}):null,l("pre",null,i)]);if(t){var o=l("button",{type:"button",className:"gemboss-md-codemore","aria-expanded":"false",text:n.showAll.replace("{n}",String(r.length))});o.addEventListener("click",function(){a=!a,i.textContent=a?e.body:r.slice(0,j).join(`
|
|
6
|
+
`),o.textContent=a?n.showLess:n.showAll.replace("{n}",String(r.length)),o.setAttribute("aria-expanded",String(a))}),s.appendChild(o)}return s}var ue={1:"h3",2:"h4",3:"h5"};function G(e,n,r){n=n||{};var t=Object.assign({},b,r||n.labels||{}),a=document.createDocumentFragment();return K(e).forEach(function(i){var s;i.t==="heading"?s=l(ue[i.level],{className:"gemboss-md-h gemboss-md-h"+i.level},L(i.text,n,t)):i.t==="code"?s=oe(i,t):i.t==="table"?s=l("div",{className:"gemboss-md-tablewrap"},l("table",{className:"gemboss-md-table"},[l("thead",null,l("tr",null,i.head.map(function(o){return l("th",null,L(o,n,t))}))),l("tbody",null,i.rows.map(function(o){return l("tr",null,i.head.map(function(d,f){return l("td",null,L(o[f]||"",n,t))}))}))])):i.t==="list"?s=l(i.ordered?"ol":"ul",{className:"gemboss-md-list",start:i.ordered&&i.start!==void 0?i.start:null},i.items.map(function(o){return l("li",null,L(o,n,t))})):i.t==="quote"?s=l("blockquote",{className:"gemboss-md-quote"},z(i.lines,n,t)):i.t==="rule"?s=l("hr",{className:"gemboss-md-rule"}):s=l("p",{className:"gemboss-md-p"},z(i.lines,n,t)),a.appendChild(s)}),a}function ce(){for(var e=12,n=1.7,r=.5,t=9.6,a=[],i=function(g){return Math.round(g*100)/100},s=function(g,m){return i(g)+" "+i(m)},o=0;o<8;o++){var d=o*Math.PI/4,f=Math.cos(d),c=Math.sin(d),p=-c,h=f;a.push(["M"+s(e+p*n,e+h*n),"L"+s(e+f*t+p*r,e+c*t+h*r),"Q"+s(e+f*(t+.6),e+c*(t+.6))+" "+s(e+f*t-p*r,e+c*t-h*r),"L"+s(e-p*n,e-h*n),"Z"].join(""))}return a.join(" ")}var V={claude:{path:ce(),label:"Claude Code"},codex:{path:"M12 2.6 20.1 7.3V16.7L12 21.4 3.9 16.7V7.3ZM12 6.9 7.6 9.45v5.1L12 17.1l4.4-2.55v-5.1Z",label:"Codex"}};function Y(e,n){var r=Object.prototype.hasOwnProperty.call(V,e)?V[e]:null;if(!r)return null;n=n||{};var t=document.createElementNS(S,"svg");if(t.setAttribute("class",n.className||"gemboss-engine-mark"),t.setAttribute("viewBox","0 0 24 24"),t.setAttribute("fill","currentColor"),n.decorative)t.setAttribute("aria-hidden","true"),t.setAttribute("focusable","false");else{t.setAttribute("role","img"),t.setAttribute("aria-label",n.title||r.label);var a=document.createElementNS(S,"title");a.textContent=n.title||r.label,t.appendChild(a)}var i=document.createElementNS(S,"path");return i.setAttribute("d",r.path),i.setAttribute("fill-rule","nonzero"),t.appendChild(i),t}function Z(e,n){var r=Object.assign({},b,n||{});return!e||!e.length?null:l("ul",{className:"gemboss-narr","aria-label":r.steps},e.map(function(t){var a=t.state||"ok",i;if(t.kind==="thinking")return i=[l("span",{className:"gemboss-narr-dot","aria-hidden":"true",text:"\u2733"}),a==="running"||!t.detail?l("span",{className:"gemboss-narr-text gemboss-narr-thinking-live"},t.label||r.thinking):l("details",{className:"gemboss-narr-thinking"},[l("summary",null,t.label||r.thought),l("div",{className:"gemboss-narr-thinking-body",text:t.detail})])],l("li",{className:"gemboss-narr-row thinking "+a},i);if(t.kind==="steer")return l("li",{className:"gemboss-narr-row steer "+a},[l("span",{className:"gemboss-narr-dot","aria-hidden":"true",text:"\u276F"}),l("span",{className:"gemboss-narr-text gemboss-narr-steer"},t.label)]);if(t.kind==="trace")return l("li",{className:"gemboss-narr-row trace "+a,title:t.error||null},[l("span",{className:"gemboss-narr-dot","aria-hidden":"true",text:a==="failed"?"\u2715":"\u23FA"}),t.detail?l("details",{className:"gemboss-narr-trace"},[l("summary",null,l("code",null,t.label)),l("div",{className:"gemboss-narr-trace-body"},l("code",{text:t.detail}))]):l("code",{className:"gemboss-narr-text gemboss-narr-trace-call"},t.label)]);var s=t.engine?Y(t.engine):null;return l("li",{className:"gemboss-narr-row "+a,title:t.error||null},[s?l("span",{className:"gemboss-narr-dot gemboss-narr-dot-engine"},s):l("span",{className:"gemboss-narr-dot","aria-hidden":"true",text:a==="ok"?"\u2713":a==="failed"?"\u2715":"\xB7"}),l("span",{className:"gemboss-narr-text"},[t.label,t.target?l("span",{className:"gb-chat-target"},[" ",t.target]):null])])}))}function J(e,n){e=e||{};var r=Object.assign({},b,n||{}),t=e.verbs&&e.verbs.length?e.verbs:[r.working],a=l("span",{className:"gemboss-ec-pending-verb","aria-hidden":"true",text:t[0]+"\u2026"}),i=l("span",{className:"gemboss-ec-pending-meta","aria-hidden":"true",text:"0s"}),s=l("div",{className:"gemboss-ec-pending",role:"status"},[l("span",{className:"gemboss-assistant-sronly",text:e.label||t[0]}),l("span",{className:"gemboss-ec-pending-star","aria-hidden":"true",text:"\u2733"}),e.compact?null:a,i]),o=e.since||Date.now(),d=!1,f=-1,c=function(){var h=Math.max(0,Math.floor((Date.now()-o)/1e3));i.textContent=(e.tokens>0?e.tokens+" token"+(e.tokens===1?"":"s")+" \xB7 ":"")+h+"s";var g=t.length>1?Math.floor(h/2)%t.length:0;if(g!==f&&!e.compact){f=g;var m=l("span",{className:"gemboss-ec-pending-verb","aria-hidden":"true",text:t[f]+"\u2026"});a.replaceWith(m),a=m}};c();var p=setInterval(function(){if(s.isConnected)d=!0;else if(d||Date.now()-o>6e5){clearInterval(p);return}c()},250);return s}function I(e,n,r){r=r||{};var t=document.createDocumentFragment();return!e||!e.length||(r.title&&t.appendChild(l("p",{className:"gb-chat-label"},r.title)),t.appendChild(l("div",{className:"gemboss-ec-starters"},e.map(function(a){var i=l("button",{type:"button",className:"gemboss-ec-starter gb-chat-starter"},[a.hint?l("span",{className:"gb-chat-starter-hint",text:a.hint}):null,a.label]);return i.addEventListener("click",function(){n(a)}),i})))),t}function de(e){var n=function(){try{var r=l("textarea",{readonly:!0});r.value=e,r.style.position="fixed",r.style.opacity="0",document.body.appendChild(r),r.select();var t=document.execCommand("copy");return r.remove(),t}catch{return!1}};try{if(navigator.clipboard&&navigator.clipboard.writeText)return navigator.clipboard.writeText(e).then(function(){return!0},n)}catch{}return Promise.resolve(n())}function Q(e,n,r){var t=l("button",{type:"button",className:"ui-btn ui-btn--ghost gb-chat-copy",text:n}),a=0;return t.addEventListener("click",function(){de(e).then(function(i){i&&(t.textContent=r,clearTimeout(a),a=setTimeout(function(){t.textContent=n},1500))})}),t}function X(e,n,r){var t=Object.assign({},b,r||{}),a=(n||[]).filter(function(i){return i!=null&&i!==!1&&i!==""});return!e&&!a.length?null:l("div",{className:"gb-chat-meta"},[e?Q(e,t.copy,t.copied):null].concat(a.map(function(i){return l("span",null,i)})))}function ee(e,n,r){var t=Object.assign({},b,r||{});return n?l("div",{className:"ui-notice ui-notice--danger gb-chat-error",role:"alert"},[l("div",null,n.text),n.command?l("code",{className:"gb-chat-cmd",text:n.command}):null,n.command?l("div",null,Q(n.command,t.copyCommand,t.copied)):null,l("details",{className:"gb-chat-original"},[l("summary",{text:t.originalError}),l("span",null,e)])]):l("p",{className:"ui-notice ui-notice--danger gb-chat-error",role:"alert"},e)}function _(e){return l("p",{className:"gb-chat-note"},e)}var fe={warn:"gb-engine-notice gb-engine-notice--warn",down:"gb-engine-notice gb-engine-notice--down"},he={warn:"gb-engine-dot gb-engine-dot--warn",down:"gb-engine-dot gb-engine-dot--down"};function te(e,n,r,t){if(N.bridgeNotice)return N.bridgeNotice({text:A(e)?void 0:e,node:A(e)?e:void 0,tone:n,action:r,onOpenSetup:t});var a=n==="warn"?"warn":"down",i=l("p",{className:fe[a],role:"status"},[l("span",{className:he[a],"aria-hidden":"true"}),l("span",{className:"gb-engine-notice-text"},e)]);if(t){var s=l("button",{type:"button",className:"gb-engine-notice-link",text:r||"Open setup"});s.addEventListener("click",t),i.appendChild(s)}return i}function B(e,n){return l("div",{className:"gemboss-ec-bubble"},[e,n?l("span",{className:"gemboss-ec-cursor","aria-hidden":"true"}):null])}function ne(e,n){n=n||{};var r=Object.assign({},b,n.labels||{});if(e.role==="note")return e.tone==="warn"||e.tone==="down"?te(e.text,e.tone,e.action&&e.action.label,e.action&&e.action.onClick):_(e.text);if(e.role==="user")return l("div",{className:"gemboss-ec-msg user",lang:e.lang||null},B(e.text));var t=!!e.text;return l("div",{className:"gemboss-ec-msg assistant",lang:e.lang||null},[e.steps&&e.steps.length?Z(e.steps,r):null,t?B(e.markdown===!1?e.text:G(e.text,n,r),e.pending):e.pending?J({verbs:n.pendingVerbs,since:n.since},r):null,n.renderExtra?n.renderExtra(e):null,e.warn?l("p",{className:"ui-notice ui-notice--warning gb-chat-notice"},e.warn):null,e.error?e.bridge?te(e.error,"down",null,n.onOpenSetup):ee(e.error,e.fix,r):null,e.stopped?_(r.stopped):null,!e.pending&&t?X(e.text,e.meta,r):null])}function ge(e){try{return JSON.stringify(e,function(n,r){return typeof r=="function"?"fn":A(r)?"node:"+(r.textContent||""):r})}catch{return String(Math.random())}}function pe(e,n){var r=e.querySelectorAll("details"),t=n.querySelectorAll("details"),a;for(a=0;a<r.length&&a<t.length;a++)r[a].open&&(t[a].open=!0);for(r=e.querySelectorAll(".gemboss-md-codemore"),t=n.querySelectorAll(".gemboss-md-codemore"),a=0;a<r.length&&a<t.length;a++)r[a].getAttribute("aria-expanded")==="true"&&t[a].click()}function me(e,n,r){r=r||{};var t=Object.assign({},b,r.labels||{}),a=e.__gbChat||(e.__gbChat={els:new Map,since:new Map}),i=[],s=new Map;if(!n.length&&(r.intro||r.starters&&r.starters.length)){var o=function(d){r.onStarter&&r.onStarter(d)};i.push(l("div",{className:"gemboss-ec-msg assistant"},[r.intro?B(r.intro):null,r.starters&&r.starters.length?I(r.starters,o,{title:r.startersTitle}):null,r.moreStarters&&r.moreStarters.length?I(r.moreStarters,o,{title:r.moreStartersTitle}):null]))}return n.forEach(function(d,f){var c=d.id!==void 0&&d.id!==null?"id:"+d.id:"at:"+f,p=ge(d),h=a.els.get(c);d.pending&&!d.text&&!a.since.has(c)&&a.since.set(c,Date.now());var g;h&&h.look===p?g=h.el:(g=ne(d,Object.assign({},r,{labels:t,since:a.since.get(c)})),h&&pe(h.el,g)),s.set(c,{el:g,look:p}),i.push(g)}),a.els=s,a.since.forEach(function(d,f){s.has(f)||a.since.delete(f)}),e.replaceChildren.apply(e,i),e}function ve(e,n){n=n||{};var r=Object.assign({},b,n.labels||{});e.classList.add("gemboss-ec-scroll"),e.setAttribute("role","log"),e.hasAttribute("aria-label")||e.setAttribute("aria-label",n.label||r.thread);var t=!0,a=0,i=0,s=0,o=!1,d=null,f=function(){e.scrollTop=e.scrollHeight,d=e.scrollTop},c=function(){!t||a||(a=requestAnimationFrame(function(){a=0,t&&f()}))},p=function(){i=Date.now(),o=!0,t=!1},h=function(){o=!1},g=function(){var u=e.scrollHeight-e.clientHeight-e.scrollTop,w=d!==null&&e.scrollTop===d;d=null,u>24&&!w?t=!1:u<=4&&(!o||Date.now()-i>400)&&(t=!0)},m=function(u){u.deltaY<0?p():u.deltaY>0&&h()},v=function(u){s=u.touches[0]?u.touches[0].clientY:0},y=function(u){var w=u.touches[0]?u.touches[0].clientY:0;w>s+2?p():w<s-2&&h()},k=function(u){u.key==="ArrowUp"||u.key==="PageUp"||u.key==="Home"?p():(u.key==="ArrowDown"||u.key==="PageDown"||u.key==="End")&&h()};e.addEventListener("scroll",g,{passive:!0}),e.addEventListener("wheel",m,{passive:!0}),e.addEventListener("touchstart",v,{passive:!0}),e.addEventListener("touchmove",y,{passive:!0}),e.addEventListener("keydown",k),e.addEventListener("load",c,!0);var x=new MutationObserver(c);x.observe(e,{childList:!0,subtree:!0,characterData:!0});var E=typeof ResizeObserver>"u"?null:new ResizeObserver(c);return E&&E.observe(e),f(),{el:e,setBusy:function(u){u?e.setAttribute("aria-busy","true"):e.removeAttribute("aria-busy")},toEnd:function(){t=!0,f()},destroy:function(){cancelAnimationFrame(a),e.removeEventListener("scroll",g),e.removeEventListener("wheel",m),e.removeEventListener("touchstart",v),e.removeEventListener("touchmove",y),e.removeEventListener("keydown",k),e.removeEventListener("load",c,!0),x.disconnect(),E&&E.disconnect()}}}function be(){return M("0 0 24 24",[{d:"M21.4 11.1l-8.5 8.5a5.5 5.5 0 01-7.8-7.8l8.5-8.5a3.7 3.7 0 015.2 5.2l-8.5 8.5a1.8 1.8 0 01-2.6-2.6l7.8-7.8",fill:"none",stroke:"currentColor","stroke-width":"2","stroke-linecap":"round","stroke-linejoin":"round"}])}function ye(e){e=e||{};var n=e.label||b.attach,r=l("input",{type:"file",hidden:!0,accept:e.accept||null,multiple:e.multiple||null,tabindex:"-1"}),t=l("button",{type:"button",className:"gemboss-ec-attach-btn","aria-label":n,title:e.title||n,disabled:e.disabled||null},be());t.addEventListener("click",function(){r.click()}),r.addEventListener("change",function(){var i=Array.prototype.slice.call(r.files||[]);r.value="",i.length&&e.onFiles&&e.onFiles(i)});var a=document.createDocumentFragment();return a.appendChild(t),a.appendChild(r),a}var W=["full","compact","icon","tight"];function we(e){var n=e.querySelector(".gemboss-ec-toolbar-lead"),r=e.querySelector(".gemboss-ec-toolbar");if(n&&n.scrollWidth>n.clientWidth+1||r&&r.scrollWidth>r.clientWidth+1)return!0;var t,a=e.querySelectorAll(".gemboss-ec-chiplabel, .gb-engine-chiplabel");for(t=0;t<a.length;t++)if(a[t].offsetParent!==null&&a[t].scrollWidth>a[t].clientWidth+1)return!0;for(a=e.querySelectorAll(".gemboss-ec-chipctl, .gb-engine-chip"),t=0;t<a.length;t++)if(a[t].offsetParent!==null&&a[t].tagName!=="SELECT"&&a[t].scrollWidth>a[t].clientWidth+1)return!0;return!1}function Ne(e,n){e&&!A(e)&&(n=e,e=null),n=n||{};var r=Object.assign({},b,n.labels||{}),t=!1,a=l("textarea",{rows:n.rows||1,maxlength:n.maxLength||null,"aria-label":n.label||r.message,placeholder:n.placeholder||null}),i=l("div",{className:"gemboss-ec-toolbar-lead"},n.leading||null),s=n.tools?l("div",{className:"gemboss-ec-toolbar-tools"},n.tools):null,o=l("button",{type:"submit",disabled:!0,"aria-label":r.send,title:r.send},M("0 0 20 20",[{d:"M10.53 4.47a.75.75 0 0 0-1.06 0l-4.5 4.5a.75.75 0 0 0 1.06 1.06l3.22-3.22v8.69a.75.75 0 0 0 1.5 0v-8.69l3.22 3.22a.75.75 0 1 0 1.06-1.06l-4.5-4.5Z"}])),d=l("button",{type:"button",className:"gemboss-ec-stop","aria-label":r.stop,title:r.stop},M("0 0 12 12",[{tag:"rect",x:"1",y:"1",width:"10",height:"10",rx:"2"}])),f=l("div",{className:"gemboss-ec-toolbar"},[i,s,n.status||null,o]),c=l("div",{className:"gemboss-ec-input","data-density":"full"},[n.top||null,a,f]);e&&e.appendChild(c);var p=function(){return!a.disabled&&a.value.trim()!==""&&(!t||n.sendWhileBusy||!n.onStop)},h=function(){var u=t&&!!n.onStop,w=u?d:o,re=u?o:d;re.parentNode&&re.replaceWith(w),o.disabled=!p()},g=function(){p()&&(n.onSend&&n.onSend(a.value),n.thread&&n.thread.toEnd&&n.thread.toEnd(),n.keepValue||(a.value="",m(),h()))},m=function(){if(!(a.offsetParent===null||a.scrollHeight===0)){var u=parseFloat(getComputedStyle(a).maxHeight)||84;a.style.height="auto";var w=a.scrollHeight+(a.offsetHeight-a.clientHeight);a.style.height=Math.min(w,u)+"px",a.style.overflowY=w>u?"auto":"hidden"}};a.addEventListener("input",function(){m(),h(),n.onChange&&n.onChange(a.value)}),a.addEventListener("keydown",function(u){n.onKeyDown&&n.onKeyDown(u),!u.defaultPrevented&&u.key==="Enter"&&!u.shiftKey&&!u.isComposing&&u.keyCode!==229&&(u.preventDefault(),g())}),o.addEventListener("click",function(u){u.preventDefault(),g()}),d.addEventListener("click",function(){n.onStop&&n.onStop(),a.focus()});var v=!1,y=function(){if(!(v||c.offsetParent===null)){v=!0;for(var u=0;u<W.length&&(c.setAttribute("data-density",W[u]),!(u===W.length-1||!we(c)));u++);v=!1,n.onDensity&&n.onDensity(c.getAttribute("data-density"))}},k=-1,x=typeof ResizeObserver>"u"?null:new ResizeObserver(function(){c.clientWidth!==k&&(k=c.clientWidth,y(),m())});x&&x.observe(c);var E=new MutationObserver(function(){v||y()});return E.observe(i,{childList:!0,subtree:!0,attributes:!0,attributeFilter:["data-label","title","aria-label"]}),document.fonts&&document.fonts.ready&&document.fonts.ready.then(y),requestAnimationFrame(function(){y(),m()}),{el:c,textarea:a,value:function(){return a.value},setValue:function(u){a.value=u==null?"":String(u),m(),h()},setBusy:function(u){t=!!u,h()},setDisabled:function(u){a.disabled=!!u,h()},focus:function(){a.focus()},measure:y,destroy:function(){x&&x.disconnect(),E.disconnect(),c.remove()}}}var xe="The bridge on your machine is not responding: it was stopped, or the machine just slept. The panel is checking again; rerun the install command if it does not come back.",Ee="The bridge on your machine rejected this browser's pairing code (it was installed with another code). Pair again in Setup.";function Se(e,n){return e&&typeof e=="object"&&(e.atBridge=!0,n!==void 0&&(e.status=n)),e}function Ae(e,n){return n=n||{},e&&e.name==="AbortError"?{error:null,bridge:!1,stopped:!0}:e&&e.atBridge&&e.status===401?{error:n.rejected||Ee,bridge:!0,stopped:!1}:e&&e.atBridge&&(e instanceof TypeError||e.name==="TimeoutError")?{error:n.gone||xe,bridge:!0,stopped:!1}:{error:e&&e.message||String(e),bridge:!1,stopped:!1}}N.engineMark||(N.engineMark=Y),N.chat={markdown:G,parseBlocks:K,parseInline:F,linkTarget:C,imageSource:H,message:ne,render:me,thread:ve,steps:Z,pending:J,starters:I,meta:X,error:ee,note:_,composer:Ne,attach:ye,labels:b,atBridge:Se,turnError:Ae}})(typeof globalThis<"u"?globalThis:this);
|
package/src/chat.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
.gemboss-ec-head{padding:16px;border-bottom:1px solid var(--gemboss-divider);display:flex;flex-direction:column;gap:2px}.gemboss-ec-title{font-family:var(--gemboss-serif);font-size:15px;font-weight:600}.gemboss-ec-sub{font-size:12px;color:var(--gemboss-text-muted)}.gemboss-ec-scroll{flex:1;min-height:0;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:16px;scrollbar-gutter:stable}.gemboss-ec-scroll{scrollbar-width:thin;scrollbar-color:rgba(31,30,29,.22) transparent}.gemboss-ec-scroll::-webkit-scrollbar{width:9px}.gemboss-ec-scroll::-webkit-scrollbar-track{background:transparent}.gemboss-ec-scroll::-webkit-scrollbar-thumb{background:#1f1e1d33;border-radius:6px;border:2px solid transparent;background-clip:content-box}.gemboss-ec-msg{display:flex;flex-direction:column;gap:8px;max-width:100%}.gemboss-ec-msg.user{align-items:flex-end}.gemboss-ec-msg.assistant{align-items:flex-start}.gemboss-ec-bubble{font-size:var(--gemboss-fs-body);line-height:1.5;padding:12px;border-radius:16px;max-width:min(90%,68ch);white-space:pre-wrap;word-break:break-word}.gemboss-ec-msg.user .gemboss-ec-bubble{background:var(--gemboss-primary);color:var(--gemboss-on-primary, #fff);border-bottom-right-radius:4px}.gemboss-ec-msg.assistant .gemboss-ec-bubble{background:var(--gemboss-surface);color:var(--gemboss-text);border:1px solid var(--gemboss-divider);border-bottom-left-radius:4px}.gemboss-ec-input button[type=submit] svg{width:18px;height:18px;fill:currentColor}.gemboss-ec-pending{display:inline-flex;align-items:center;gap:8px;padding:6px 2px;font-size:var(--gemboss-fs-caption);color:var(--gemboss-text-muted)}.gemboss-ec-pending-star{color:var(--gemboss-primary);font-size:12px;line-height:1;animation:gemboss-star-pulse 1.1s ease-in-out infinite}.gemboss-ec-pending-verb{color:var(--gemboss-text);animation:gemboss-verb-in .4s ease-out}.gemboss-ec-pending-meta{font-variant-numeric:tabular-nums;opacity:.7;font-size:var(--gemboss-fs-caption)}@keyframes gemboss-star-pulse{0%,to{transform:scale(.85);opacity:.55}50%{transform:scale(1.15);opacity:1}}@keyframes gemboss-verb-in{0%{opacity:0;transform:translateY(2px)}to{opacity:1;transform:none}}.gemboss-ec-cursor{display:inline-block;width:2px;height:1.05em;margin-left:2px;vertical-align:-2px;background:var(--gemboss-primary);border-radius:2px;animation:gemboss-cursor-blink 1s steps(1) infinite}@keyframes gemboss-cursor-blink{0%,45%{opacity:1}50%,95%{opacity:.15}to{opacity:1}}@media (prefers-reduced-motion: reduce){.gemboss-ec-pending-star,.gemboss-ec-cursor{animation:none}}.gemboss-ec-md-link{color:var(--gemboss-primary-dark);font-weight:600;text-decoration:none;border-bottom:1px solid color-mix(in srgb,var(--gemboss-primary) 35%,transparent);cursor:pointer}.gemboss-ec-md-link:hover{border-bottom-color:var(--gemboss-primary)}.gemboss-ec-starters{display:flex;flex-wrap:wrap;gap:8px;margin-top:4px}.gemboss-ec-starter{text-align:left;font-size:13px;padding:6px 12px;border-radius:var(--gemboss-radius-full);cursor:pointer;background:var(--gemboss-surface);border:1px solid var(--gemboss-divider);color:var(--gemboss-text);white-space:nowrap;max-width:100%}.gemboss-ec-starter:hover{border-color:var(--gemboss-primary);background:#5661f50f}.gemboss-ec-input{display:flex;flex-wrap:wrap;align-items:center;gap:4px;margin:12px;padding:8px;border:1px solid var(--gemboss-divider);border-radius:16px;background:var(--gemboss-surface);transition:border-color var(--gemboss-transition-fast) ease,box-shadow var(--gemboss-transition-fast) ease}.gemboss-ec-input:focus-within{border-color:var(--gemboss-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--gemboss-primary) 12%,transparent)}.gemboss-ec-input textarea{flex:1 0 100%;min-width:0;width:100%;box-sizing:border-box;resize:none;border-radius:0;background:transparent;border:1px solid transparent;padding:6px 8px;font-size:var(--gemboss-fs-body);font-family:inherit;min-height:0;max-height:84px;line-height:1.5;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(31,30,29,.22) transparent}.gemboss-ec-input textarea::-webkit-scrollbar{width:7px}.gemboss-ec-input textarea::-webkit-scrollbar-track{background:transparent}.gemboss-ec-input textarea::-webkit-scrollbar-thumb{background:#1f1e1d33;border-radius:4px;border:2px solid transparent;background-clip:content-box}.gemboss-ec-input textarea:focus{outline:none}.gemboss-ec-input button[type=submit]{flex:0 0 auto;width:44px;height:44px;min-width:44px;min-height:44px;border-radius:50%;border:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;background:var(--gemboss-primary);color:var(--gemboss-on-primary, #fff);font-size:16px;font-weight:700;transition:background var(--gemboss-transition-fast) ease,filter var(--gemboss-transition-fast) ease}.gemboss-ec-input button[type=submit]:hover:not(:disabled){background:var(--gemboss-primary-dark)}.gemboss-ec-input button[type=submit]:active:not(:disabled){background:var(--gemboss-primary-dark);filter:brightness(.94)}.gemboss-ec-input button[type=submit]:focus-visible{outline:2px solid var(--gemboss-primary);outline-offset:2px}.gemboss-ec-input button[type=submit]:disabled{background:var(--gemboss-divider);color:var(--gemboss-text-muted);opacity:1;cursor:default}.gemboss-narr{list-style:none;margin:0;padding:8px 0 0;display:flex;flex-direction:column;gap:8px}.gemboss-narr-row{display:flex;align-items:center;gap:8px;font-size:var(--gemboss-fs-caption);color:var(--gemboss-text-muted)}.gemboss-narr-dot{width:16px;height:16px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-size:10px;flex:0 0 auto}.gemboss-narr-row.ok .gemboss-narr-dot{background:var(--gemboss-active-bg);color:var(--gemboss-active-fg)}.gemboss-narr-row.failed .gemboss-narr-dot{background:#fde8e6;color:var(--gemboss-danger)}.gemboss-narr-row.running .gemboss-narr-dot{background:transparent}.gemboss-narr-dot-engine{background:transparent!important;color:inherit}.gemboss-narr-row.ok .gemboss-narr-dot-engine{color:var(--gemboss-text)}.gemboss-narr-row.failed .gemboss-narr-dot-engine{color:var(--gemboss-danger)}.gemboss-narr-row.ok .gemboss-narr-text,.gemboss-narr-row.failed .gemboss-narr-text{color:var(--gemboss-text)}.gemboss-narr-row.steer .gemboss-narr-dot{background:transparent;color:var(--gemboss-text-muted)}.gemboss-narr-steer{color:var(--gemboss-text);font-weight:500;overflow-wrap:anywhere}.gemboss-narr-spin{width:11px;height:11px;border:2px solid var(--gemboss-divider-soft);border-top-color:var(--gemboss-primary);border-radius:50%;animation:gemboss-spin .7s linear infinite}@keyframes gemboss-spin{to{transform:rotate(360deg)}}.gemboss-narr-row.thinking{align-items:flex-start}.gemboss-narr-row.thinking .gemboss-narr-dot{color:var(--gemboss-text-muted);background:transparent}.gemboss-narr-thinking-live{font-style:italic;color:var(--gemboss-text-muted);white-space:pre-wrap;opacity:.9;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}.gemboss-narr-thinking{font-size:var(--gemboss-fs-caption)}.gemboss-narr-thinking>summary{cursor:pointer;color:var(--gemboss-text-muted);list-style:none;user-select:none}.gemboss-narr-thinking>summary::-webkit-details-marker{display:none}.gemboss-narr-thinking>summary:before{content:"\25b8 "}.gemboss-narr-thinking[open]>summary:before{content:"\25be "}.gemboss-narr-thinking-body{margin-top:6px;padding:8px;border-left:2px solid var(--gemboss-divider-soft);color:var(--gemboss-text-muted);font-style:italic;white-space:pre-wrap;line-height:1.5}.gemboss-narr-row.trace code{font-family:var(--gemboss-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);font-size:var(--gemboss-fs-caption);word-break:break-word}.gemboss-narr-trace-call{color:var(--gemboss-text-muted);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.gemboss-narr-trace{font-size:var(--gemboss-fs-caption);min-width:0}.gemboss-narr-trace>summary{cursor:pointer;color:var(--gemboss-text-muted);list-style:none;user-select:none;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.gemboss-narr-trace[open]>summary{display:block;overflow:visible}.gemboss-narr-trace>summary::-webkit-details-marker{display:none}.gemboss-narr-trace>summary,.gemboss-narr-thinking>summary{min-height:24px;box-sizing:border-box;padding-block:2px}.gemboss-narr-trace>summary:before{content:"\25b8 "}.gemboss-narr-trace[open]>summary:before{content:"\25be "}.gemboss-narr-trace-body{margin-top:6px;padding:8px;border-left:2px solid var(--gemboss-divider-soft);color:var(--gemboss-text-muted);white-space:pre-wrap;line-height:1.5;overflow-x:auto}@media (max-width: 640px){.gemboss-ec-input textarea{min-height:0}.gemboss-ec-scroll{padding:12px}}.gemboss-ec-chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:4px}.gemboss-ec-chip{background:var(--gemboss-surface);border:1px solid var(--gemboss-divider);border-radius:var(--gemboss-radius-full);padding:8px 16px;font-size:13px;cursor:pointer;color:var(--gemboss-text);min-height:44px}.gemboss-ec-chip:hover{border-color:var(--gemboss-primary);color:var(--gemboss-active-fg)}.gemboss-ec-chip:disabled{opacity:.5;cursor:default}@media (pointer: fine){.gemboss-ec-starters{row-gap:16px}.gemboss-ec-tab,.gemboss-ec-starter,.gemboss-ec-upload,.gemboss-ec-enginepick button,.gemboss-ec-workmode,.gemboss-ec-input .gemboss-ec-attach-btn,.gemboss-ec-stop,.gemboss-ec-stop-send,.gemboss-ec-input button[type=submit]{position:relative}.gemboss-ec-tab:after,.gemboss-ec-starter:after,.gemboss-ec-upload:after,.gemboss-ec-enginepick button:after,.gemboss-ec-workmode:before,.gemboss-ec-input .gemboss-ec-attach-btn:after,.gemboss-ec-stop:after,.gemboss-ec-stop-send:after,.gemboss-ec-input button[type=submit]:after{content:"";position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);height:44px;pointer-events:auto;z-index:1}}@media (pointer: coarse){.gemboss-ec-input button[type=submit]{width:44px;height:44px;font-size:17px}.gemboss-ec-starter,.gemboss-ec-opt,.gemboss-ec-input textarea{min-height:44px}}.gemboss-md-p{margin:0 0 8px}.gemboss-md-p:last-child{margin-bottom:0}.gemboss-md-h{margin:16px 0 6px;font-weight:650;line-height:1.3}.gemboss-md-h:first-child{margin-top:0}.gemboss-md-h1{font-size:17px}.gemboss-md-h2{font-size:15px}.gemboss-md-h3{font-size:var(--gemboss-fs-body);color:var(--gemboss-text-subdued, #616161)}.gemboss-md-list{margin:0 0 8px;padding-left:20px}.gemboss-md-list li{margin:2px 0}.gemboss-md-quote{margin:0 0 8px;padding:2px 0 2px 12px;border-left:3px solid var(--gemboss-border, #e3e3e3);color:var(--gemboss-text-subdued, #616161)}.gemboss-md-rule{margin:12px 0;border:0;border-top:1px solid var(--gemboss-border, #e3e3e3)}.gemboss-md-code{padding:1px 6px;border-radius:6px;background:var(--gemboss-surface-subdued, #f1f1f1);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.9em;word-break:break-word}.gemboss-md-tablewrap{margin:0 0 12px;overflow-x:auto}.gemboss-md-table{border-collapse:collapse;font-size:var(--gemboss-fs-caption);min-width:100%}.gemboss-md-table th,.gemboss-md-table td{border:1px solid var(--gemboss-border, #e3e3e3);padding:6px 8px;text-align:left;vertical-align:top;white-space:nowrap}.gemboss-md-table th{background:var(--gemboss-surface-subdued, #f7f7f7);font-weight:600}.gemboss-md-imglink{display:inline-block;max-width:100%;margin:4px 0 8px;border-radius:8px;line-height:0}.gemboss-md-imglink:focus-visible{outline:2px solid var(--gemboss-focus, var(--ui-focus, #5661f5));outline-offset:2px}.gemboss-md-img{display:block;max-width:100%;max-height:320px;height:auto;border:1px solid var(--gemboss-border, #e3e3e3);border-radius:8px;background:var(--gemboss-surface-subdued, #f7f7f7);object-fit:contain}.gemboss-md-codeblock{position:relative;margin:0 0 12px;border:1px solid var(--gemboss-border, #e3e3e3);border-radius:8px;background:var(--gemboss-surface-subdued, #f7f7f7);overflow:hidden}.gemboss-md-codelang{display:block;padding:4px 12px 0;color:var(--gemboss-text-subdued, #8a8a8a);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px}.gemboss-md-codeblock pre{margin:0;padding:8px 12px;overflow-x:auto}.gemboss-md-codeblock code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:1.5;white-space:pre}.gemboss-md-codemore{display:block;width:100%;padding:6px 12px;border:0;border-top:1px solid var(--gemboss-border, #e3e3e3);background:transparent;color:var(--gemboss-text-subdued, #616161);font-size:12px;text-align:left;cursor:pointer}.gemboss-md-codemore:hover{background:#00000008}.gemboss-narr-row.source{align-items:flex-start}.gemboss-narr-source{min-width:0;flex:1}.gemboss-narr-source-head{font-size:11px;color:var(--gemboss-text-muted, #686b71);margin-bottom:4px}.gemboss-narr-source-head code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.gemboss-narr-source-code{margin:0;padding:8px 12px;border-radius:8px;max-height:220px;overflow:auto;background:var(--gemboss-primary-soft, #f2f3f5);border:1px solid var(--gemboss-divider, #e5e7ea);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:var(--gemboss-fs-micro);line-height:17px;white-space:pre;tab-size:2}.gemboss-narr-source-code .c-com{color:#6a7a86;font-style:italic}.gemboss-narr-source-code .c-str{color:#9a3412}.gemboss-narr-source-code .c-num{color:#1d6fa5}.gemboss-narr-source-code .c-kw{color:#7c3aed;font-weight:600}.gemboss-narr-source-code .c-key{color:#0b6b3a}.gemboss-narr-source-code .c-tag{color:#b0197a}.gemboss-narr-source-code .c-attr{color:#7c3aed}.gemboss-narr-source-code .c-pun{color:#6a6d73}@media (max-width: 520px){.gemboss-narr-source-code{max-height:160px;font-size:11px}}.gemboss-narr-dot-quiet{visibility:hidden}
|
|
1
|
+
.gemboss-ec-head{padding:16px;border-bottom:1px solid var(--gemboss-divider);display:flex;flex-direction:column;gap:2px}.gemboss-ec-title{font-family:var(--gemboss-serif);font-size:15px;font-weight:600}.gemboss-ec-sub{font-size:12px;color:var(--gemboss-text-muted)}.gemboss-ec-scroll{flex:1;min-height:0;overflow-y:auto;padding:16px;display:flex;flex-direction:column;gap:16px;scrollbar-gutter:stable}.gemboss-ec-scroll{scrollbar-width:thin;scrollbar-color:rgba(31,30,29,.22) transparent}.gemboss-ec-scroll::-webkit-scrollbar{width:9px}.gemboss-ec-scroll::-webkit-scrollbar-track{background:transparent}.gemboss-ec-scroll::-webkit-scrollbar-thumb{background:#1f1e1d33;border-radius:6px;border:2px solid transparent;background-clip:content-box}.gemboss-ec-msg{display:flex;flex-direction:column;gap:8px;max-width:100%}.gemboss-ec-msg.user{align-items:flex-end}.gemboss-ec-msg.assistant{align-items:flex-start}.gemboss-ec-bubble{font-size:var(--gemboss-fs-body);line-height:1.5;padding:12px;border-radius:16px;max-width:min(90%,68ch);white-space:pre-wrap;word-break:break-word}.gemboss-ec-msg.user .gemboss-ec-bubble{background:var(--gemboss-primary);color:var(--gemboss-on-primary, #fff);border-bottom-right-radius:4px}.gemboss-ec-msg.assistant .gemboss-ec-bubble{background:var(--gemboss-surface);color:var(--gemboss-text);border:1px solid var(--gemboss-divider);border-bottom-left-radius:4px}.gemboss-ec-toolbar>button[type=submit] svg{width:18px;height:18px;fill:currentColor}.gemboss-ec-pending{display:inline-flex;align-items:center;gap:8px;padding:6px 2px;font-size:var(--gemboss-fs-caption);color:var(--gemboss-text-muted)}.gemboss-ec-pending-star{color:var(--gemboss-primary);font-size:12px;line-height:1;animation:gemboss-star-pulse 1.1s ease-in-out infinite}.gemboss-ec-pending-verb{color:var(--gemboss-text);animation:gemboss-verb-in .4s ease-out}.gemboss-ec-pending-meta{font-variant-numeric:tabular-nums;opacity:.7;font-size:var(--gemboss-fs-caption)}@keyframes gemboss-star-pulse{0%,to{transform:scale(.85);opacity:.55}50%{transform:scale(1.15);opacity:1}}@keyframes gemboss-verb-in{0%{opacity:0;transform:translateY(2px)}to{opacity:1;transform:none}}.gemboss-ec-cursor{display:inline-block;width:2px;height:1.05em;margin-left:2px;vertical-align:-2px;background:var(--gemboss-primary);border-radius:2px;animation:gemboss-cursor-blink 1s steps(1) infinite}@keyframes gemboss-cursor-blink{0%,45%{opacity:1}50%,95%{opacity:.15}to{opacity:1}}@media (prefers-reduced-motion: reduce){.gemboss-ec-pending-star,.gemboss-ec-cursor{animation:none}}.gemboss-ec-md-link{color:var(--gemboss-primary-dark);font-weight:600;text-decoration:none;border-bottom:1px solid color-mix(in srgb,var(--gemboss-primary) 35%,transparent);cursor:pointer}.gemboss-ec-md-link:hover{border-bottom-color:var(--gemboss-primary)}.gemboss-ec-starters{display:flex;flex-wrap:wrap;gap:8px;margin-top:4px}.gemboss-ec-starter{text-align:left;font-size:13px;padding:6px 12px;border-radius:var(--gemboss-radius-full);cursor:pointer;background:var(--gemboss-surface);border:1px solid var(--gemboss-divider);color:var(--gemboss-text);white-space:nowrap;max-width:100%}.gemboss-ec-starter:hover{border-color:var(--gemboss-primary);background:#5661f50f}.gemboss-ec-input{display:flex;flex-wrap:wrap;align-items:center;gap:4px;margin:12px;padding:8px;border:1px solid var(--gemboss-divider);border-radius:16px;background:var(--gemboss-surface);transition:border-color var(--gemboss-transition-fast) ease,box-shadow var(--gemboss-transition-fast) ease}.gemboss-ec-input:focus-within{border-color:var(--gemboss-primary);box-shadow:0 0 0 3px color-mix(in srgb,var(--gemboss-primary) 12%,transparent)}.gemboss-ec-input textarea{flex:1 0 100%;min-width:0;width:100%;box-sizing:border-box;resize:none;border-radius:0;background:transparent;border:1px solid transparent;padding:6px 8px;font-size:var(--gemboss-fs-body);font-family:inherit;min-height:0;max-height:84px;line-height:1.5;overflow-y:auto;scrollbar-width:thin;scrollbar-color:rgba(31,30,29,.22) transparent}.gemboss-ec-input textarea::-webkit-scrollbar{width:7px}.gemboss-ec-input textarea::-webkit-scrollbar-track{background:transparent}.gemboss-ec-input textarea::-webkit-scrollbar-thumb{background:#1f1e1d33;border-radius:4px;border:2px solid transparent;background-clip:content-box}.gemboss-ec-input textarea:focus{outline:none}.gemboss-ec-toolbar>button[type=submit]{flex:0 0 auto;width:44px;height:44px;min-width:44px;min-height:44px;border-radius:50%;border:0;cursor:pointer;display:inline-flex;align-items:center;justify-content:center;background:var(--gemboss-primary);color:var(--gemboss-on-primary, #fff);font-size:16px;font-weight:700;transition:background var(--gemboss-transition-fast) ease,filter var(--gemboss-transition-fast) ease}.gemboss-ec-toolbar>button[type=submit]:hover:not(:disabled){background:var(--gemboss-primary-dark)}.gemboss-ec-toolbar>button[type=submit]:active:not(:disabled){background:var(--gemboss-primary-dark);filter:brightness(.94)}.gemboss-ec-toolbar>button[type=submit]:focus-visible{outline:2px solid var(--gemboss-primary);outline-offset:2px}.gemboss-ec-toolbar>button[type=submit]:disabled{background:var(--gemboss-divider);color:var(--gemboss-text-muted);opacity:1;cursor:default}.gemboss-narr{list-style:none;margin:0;padding:8px 0 0;display:flex;flex-direction:column;gap:8px}.gemboss-narr-row{display:flex;align-items:center;gap:8px;font-size:var(--gemboss-fs-caption);color:var(--gemboss-text-muted)}.gemboss-narr-dot{width:16px;height:16px;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;font-size:10px;flex:0 0 auto}.gemboss-narr-row.ok .gemboss-narr-dot{background:var(--gemboss-active-bg);color:var(--gemboss-active-fg)}.gemboss-narr-row.failed .gemboss-narr-dot{background:#fde8e6;color:var(--gemboss-danger)}.gemboss-narr-row.running .gemboss-narr-dot{background:transparent}.gemboss-narr-dot-engine{background:transparent!important;color:inherit}.gemboss-narr-row.ok .gemboss-narr-dot-engine{color:var(--gemboss-text)}.gemboss-narr-row.failed .gemboss-narr-dot-engine{color:var(--gemboss-danger)}.gemboss-narr-row.ok .gemboss-narr-text,.gemboss-narr-row.failed .gemboss-narr-text{color:var(--gemboss-text)}.gemboss-narr-row.steer .gemboss-narr-dot{background:transparent;color:var(--gemboss-text-muted)}.gemboss-narr-steer{color:var(--gemboss-text);font-weight:500;overflow-wrap:anywhere}.gemboss-narr-spin{width:11px;height:11px;border:2px solid var(--gemboss-divider-soft);border-top-color:var(--gemboss-primary);border-radius:50%;animation:gemboss-spin .7s linear infinite}@keyframes gemboss-spin{to{transform:rotate(360deg)}}.gemboss-narr-row.thinking{align-items:flex-start}.gemboss-narr-row.thinking .gemboss-narr-dot{color:var(--gemboss-text-muted);background:transparent}.gemboss-narr-thinking-live{font-style:italic;color:var(--gemboss-text-muted);white-space:pre-wrap;opacity:.9;display:-webkit-box;-webkit-line-clamp:3;-webkit-box-orient:vertical;overflow:hidden}.gemboss-narr-thinking{font-size:var(--gemboss-fs-caption)}.gemboss-narr-thinking>summary{cursor:pointer;color:var(--gemboss-text-muted);list-style:none;user-select:none}.gemboss-narr-thinking>summary::-webkit-details-marker{display:none}.gemboss-narr-thinking>summary:before{content:"\25b8 "}.gemboss-narr-thinking[open]>summary:before{content:"\25be "}.gemboss-narr-thinking-body{margin-top:6px;padding:8px;border-left:2px solid var(--gemboss-divider-soft);color:var(--gemboss-text-muted);font-style:italic;white-space:pre-wrap;line-height:1.5}.gemboss-narr-row.trace code{font-family:var(--gemboss-font-mono, ui-monospace, SFMono-Regular, Menlo, monospace);font-size:var(--gemboss-fs-caption);word-break:break-word}.gemboss-narr-trace-call{color:var(--gemboss-text-muted);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.gemboss-narr-trace{font-size:var(--gemboss-fs-caption);min-width:0}.gemboss-narr-trace>summary{cursor:pointer;color:var(--gemboss-text-muted);list-style:none;user-select:none;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden}.gemboss-narr-trace[open]>summary{display:block;overflow:visible}.gemboss-narr-trace>summary::-webkit-details-marker{display:none}.gemboss-narr-trace>summary,.gemboss-narr-thinking>summary{min-height:24px;box-sizing:border-box;padding-block:2px}.gemboss-narr-trace>summary:before{content:"\25b8 "}.gemboss-narr-trace[open]>summary:before{content:"\25be "}.gemboss-narr-trace-body{margin-top:6px;padding:8px;border-left:2px solid var(--gemboss-divider-soft);color:var(--gemboss-text-muted);white-space:pre-wrap;line-height:1.5;overflow-x:auto}@media (max-width: 640px){.gemboss-ec-input textarea{min-height:0}.gemboss-ec-scroll{padding:12px}}.gemboss-ec-chips{display:flex;flex-wrap:wrap;gap:8px;margin-top:4px}.gemboss-ec-chip{background:var(--gemboss-surface);border:1px solid var(--gemboss-divider);border-radius:var(--gemboss-radius-full);padding:8px 16px;font-size:13px;cursor:pointer;color:var(--gemboss-text);min-height:44px}.gemboss-ec-chip:hover{border-color:var(--gemboss-primary);color:var(--gemboss-active-fg)}.gemboss-ec-chip:disabled{opacity:.5;cursor:default}@media (pointer: fine){.gemboss-ec-starters{row-gap:16px}.gemboss-ec-tab,.gemboss-ec-starter,.gemboss-ec-upload,.gemboss-ec-workmode,.gemboss-ec-input .gemboss-ec-attach-btn,.gemboss-ec-stop,.gemboss-ec-stop-send,.gemboss-ec-toolbar>button[type=submit]{position:relative}.gemboss-ec-tab:after,.gemboss-ec-starter:after,.gemboss-ec-upload:after,.gemboss-ec-workmode:before,.gemboss-ec-input .gemboss-ec-attach-btn:after,.gemboss-ec-stop:after,.gemboss-ec-stop-send:after,.gemboss-ec-toolbar>button[type=submit]:after{content:"";position:absolute;left:0;right:0;top:50%;transform:translateY(-50%);height:44px;pointer-events:auto;z-index:1}}@media (pointer: coarse){.gemboss-ec-toolbar>button[type=submit]{width:44px;height:44px;font-size:17px}.gemboss-ec-starter,.gemboss-ec-opt,.gemboss-ec-input textarea{min-height:44px}}.gemboss-md-p{margin:0 0 8px}.gemboss-md-p:last-child{margin-bottom:0}.gemboss-md-h{margin:16px 0 6px;font-weight:650;line-height:1.3}.gemboss-md-h:first-child{margin-top:0}.gemboss-md-h1{font-size:17px}.gemboss-md-h2{font-size:15px}.gemboss-md-h3{font-size:var(--gemboss-fs-body);color:var(--gemboss-text-subdued, #616161)}.gemboss-md-list{margin:0 0 8px;padding-left:20px}.gemboss-md-list li{margin:2px 0}.gemboss-md-quote{margin:0 0 8px;padding:2px 0 2px 12px;border-left:3px solid var(--gemboss-border, #e3e3e3);color:var(--gemboss-text-subdued, #616161)}.gemboss-md-rule{margin:12px 0;border:0;border-top:1px solid var(--gemboss-border, #e3e3e3)}.gemboss-md-code{padding:1px 6px;border-radius:6px;background:var(--gemboss-surface-subdued, #f1f1f1);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:.9em;word-break:break-word}.gemboss-md-tablewrap{margin:0 0 12px;overflow-x:auto}.gemboss-md-table{border-collapse:collapse;font-size:var(--gemboss-fs-caption);min-width:100%}.gemboss-md-table th,.gemboss-md-table td{border:1px solid var(--gemboss-border, #e3e3e3);padding:6px 8px;text-align:left;vertical-align:top;white-space:nowrap}.gemboss-md-table th{background:var(--gemboss-surface-subdued, #f7f7f7);font-weight:600}.gemboss-md-imglink{display:inline-block;max-width:100%;margin:4px 0 8px;border-radius:8px;line-height:0}.gemboss-md-imglink:focus-visible{outline:2px solid var(--gemboss-focus, var(--ui-focus, #5661f5));outline-offset:2px}.gemboss-md-img{display:block;max-width:100%;max-height:320px;height:auto;border:1px solid var(--gemboss-border, #e3e3e3);border-radius:8px;background:var(--gemboss-surface-subdued, #f7f7f7);object-fit:contain}.gemboss-md-codeblock{position:relative;margin:0 0 12px;border:1px solid var(--gemboss-border, #e3e3e3);border-radius:8px;background:var(--gemboss-surface-subdued, #f7f7f7);overflow:hidden}.gemboss-md-codelang{display:block;padding:4px 12px 0;color:var(--gemboss-text-subdued, #8a8a8a);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:11px}.gemboss-md-codeblock pre{margin:0;padding:8px 12px;overflow-x:auto}.gemboss-md-codeblock code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:12px;line-height:1.5;white-space:pre}.gemboss-md-codemore{display:block;width:100%;padding:6px 12px;border:0;border-top:1px solid var(--gemboss-border, #e3e3e3);background:transparent;color:var(--gemboss-text-subdued, #616161);font-size:12px;text-align:left;cursor:pointer}.gemboss-md-codemore:hover{background:#00000008}.gemboss-narr-row.source{align-items:flex-start}.gemboss-narr-source{min-width:0;flex:1}.gemboss-narr-source-head{font-size:11px;color:var(--gemboss-text-muted, #686b71);margin-bottom:4px}.gemboss-narr-source-head code{font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.gemboss-narr-source-code{margin:0;padding:8px 12px;border-radius:8px;max-height:220px;overflow:auto;background:var(--gemboss-primary-soft, #f2f3f5);border:1px solid var(--gemboss-divider, #e5e7ea);font-family:ui-monospace,SFMono-Regular,Menlo,monospace;font-size:var(--gemboss-fs-micro);line-height:17px;white-space:pre;tab-size:2}.gemboss-narr-source-code .c-com{color:#6a7a86;font-style:italic}.gemboss-narr-source-code .c-str{color:#9a3412}.gemboss-narr-source-code .c-num{color:#1d6fa5}.gemboss-narr-source-code .c-kw{color:#7c3aed;font-weight:600}.gemboss-narr-source-code .c-key{color:#0b6b3a}.gemboss-narr-source-code .c-tag{color:#b0197a}.gemboss-narr-source-code .c-attr{color:#7c3aed}.gemboss-narr-source-code .c-pun{color:#6a6d73}@media (max-width: 520px){.gemboss-narr-source-code{max-height:160px;font-size:11px}}.gemboss-narr-dot-quiet{visibility:hidden}
|