@gemboss/ui 0.12.0 → 0.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/chat.css CHANGED
@@ -1,432 +1 @@
1
- /*
2
- * The chat BODY — what an answer looks like, wherever a GemBoss surface puts a chat (01/10/2026).
3
- *
4
- * Chris: every surface's AI assistant (gemcare, content-radar, partner-radar, GemCommunity) must be built from the
5
- * GemBoss UI framework. Until today only the FRAME was shared (assistant.css: popup / bar / full screen; shell.css:
6
- * the thread rail); the body lived in the admin's gemboss-shell.css and the exporter left it out on purpose, so every
7
- * surface drew its own bubbles, markdown and composer. These are those rules, moved here VERBATIM (same selectors,
8
- * same values, same order) — the admin @imports this file at the top of its shell, so it is still the one owner.
9
- *
10
- * What is here: the header (`.gemboss-ec-head/title/sub`), the message list (`.gemboss-ec-scroll`), messages and
11
- * bubbles (`.gemboss-ec-msg.user|.assistant`, `.gemboss-ec-bubble`), the working indicator and the streaming cursor
12
- * (`.gemboss-ec-pending*`, `.gemboss-ec-cursor`), markdown (`.gemboss-md-*`, `.gemboss-ec-md-link`), step narration
13
- * (`.gemboss-narr*`), starters and option chips (`.gemboss-ec-starter(s)`, `.gemboss-ec-chip(s)`), and the composer
14
- * (`.gemboss-ec-input` with its textarea and submit button).
15
- * What is NOT: the panel's geometry (`.gemboss-ec` width, editor columns, tabs), attachments, CTA / action cards,
16
- * the engine picker and work mode — those are still the admin's, and a surface brings its own. ONE exception, on
17
- * purpose: the chat panel's touch / mouse TARGET blocks (`@media (pointer: coarse|fine)` below) name every control
18
- * of the panel, the admin-only ones (tabs, upload, engine picker, work mode, attach, stop) included. They are one
19
- * rule per pointer kind; split in two they wrote their declarations twice and the admin's shell budget had no room.
20
- * Those selectors match nothing on a surface without those controls. (`.gemboss-ec-workmode`: the click-area
21
- * `::before` is here, its label-sizing `::after` stays the admin's.)
22
- *
23
- * Markup: see the catalog's "Thân chat" section. Behaviour (streaming, stop, keyboard) belongs to the surface.
24
- */
25
-
26
- .gemboss-ec-head { padding: 16px 16px; border-bottom: 1px solid var(--gemboss-divider); display: flex; flex-direction: column; gap: 2px; }
27
- .gemboss-ec-title { font-family: var(--gemboss-serif); font-size: 15px; font-weight: 600; }
28
- .gemboss-ec-sub { font-size: 12px; color: var(--gemboss-text-muted); }
29
- .gemboss-ec-scroll { flex: 1; min-height: 0; overflow-y: auto; padding: 16px; display: flex; flex-direction: column; gap: 16px; scrollbar-gutter: stable; }
30
- /* Visible thin scrollbar on the chat message list — the default macOS overlay bar is
31
- hidden until you actively scroll, so the list reads as "can't scroll" (esp. on the
32
- dedicated Assistant page, a fixed-height chat where the page itself doesn't scroll).
33
- A persistent thin bar makes the scroll affordance obvious; matches the composer input. */
34
- .gemboss-ec-scroll { scrollbar-width: thin; scrollbar-color: rgba(31,30,29,0.22) transparent; }
35
- .gemboss-ec-scroll::-webkit-scrollbar { width: 9px; }
36
- .gemboss-ec-scroll::-webkit-scrollbar-track { background: transparent; }
37
- .gemboss-ec-scroll::-webkit-scrollbar-thumb { background: rgba(31,30,29,0.2); border-radius: 6px; border: 2px solid transparent; background-clip: content-box; }
38
- .gemboss-ec-msg { display: flex; flex-direction: column; gap: 8px; max-width: 100%; }
39
- .gemboss-ec-msg.user { align-items: flex-end; }
40
- .gemboss-ec-msg.assistant { align-items: flex-start; }
41
- .gemboss-ec-bubble {
42
- /* Cap reading measure: a chat reply stays at a readable line length, not the bubble's full 90%. */
43
- font-size: var(--gemboss-fs-body); line-height: 1.5; padding: 12px 12px; border-radius: 16px; max-width: min(90%, 68ch);
44
- white-space: pre-wrap; word-break: break-word;
45
- }
46
- .gemboss-ec-msg.user .gemboss-ec-bubble { background: var(--gemboss-primary); color: var(--gemboss-on-primary, #fff); border-bottom-right-radius: 4px; }
47
- .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; }
48
- .gemboss-ec-input button[type="submit"] svg { width: 18px; height: 18px; fill: currentColor; }
49
- /* Live "working" heartbeat — the Claude-Code-style running asterisk shown before the first token.
50
- Slim, muted, single line so the chat stays clean; the motion (pulsing ✳, crossfading verb, live
51
- counter) is what makes the wait feel fast instead of frozen. */
52
- .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); }
53
- .gemboss-ec-pending-star { color: var(--gemboss-primary); font-size: 12px; line-height: 1; animation: gemboss-star-pulse 1.1s ease-in-out infinite; }
54
- .gemboss-ec-pending-verb { color: var(--gemboss-text); animation: gemboss-verb-in 0.4s ease-out; }
55
- .gemboss-ec-pending-meta { font-variant-numeric: tabular-nums; opacity: 0.7; font-size: var(--gemboss-fs-caption); }
56
- @keyframes gemboss-star-pulse { 0%,100% { transform: scale(0.85); opacity: 0.55; } 50% { transform: scale(1.15); opacity: 1; } }
57
- @keyframes gemboss-verb-in { from { opacity: 0; transform: translateY(2px); } to { opacity: 1; transform: none; } }
58
- /* Typewriter cursor — a thin blinking bar trailing the answer while tokens stream in. */
59
- .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; }
60
- @keyframes gemboss-cursor-blink { 0%,45% { opacity: 1; } 50%,95% { opacity: 0.15; } 100% { opacity: 1; } }
61
- @media (prefers-reduced-motion: reduce) {
62
- .gemboss-ec-pending-star, .gemboss-ec-cursor { animation: none; }
63
- }
64
- /* Markdown link inside the answer bubble — a friendly inline link, never a raw path. */
65
- .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; }
66
- .gemboss-ec-md-link:hover { border-bottom-color: var(--gemboss-primary); }
67
- /* Suggestion starters = compact wrapping CHIPS (pills), not stacked full-width boxes —
68
- reads as a chat's quick-reply chips and stops one prompt eating a whole row. */
69
- .gemboss-ec-starters { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }
70
- .gemboss-ec-starter {
71
- text-align: left; font-size: 13px; padding: 6px 12px; border-radius: var(--gemboss-radius-full); cursor: pointer;
72
- background: var(--gemboss-surface); border: 1px solid var(--gemboss-divider); color: var(--gemboss-text);
73
- white-space: nowrap; max-width: 100%;
74
- }
75
- .gemboss-ec-starter:hover { border-color: var(--gemboss-primary); background: rgba(86, 97, 245, 0.06); }
76
- /* (removed) dead legacy rail styles — `.icon-nav-assistant` + the hover-flyout submenu
77
- (`.icon-nav-flyout*`). The current nav (IconNav.tsx) is a persistent 240px labeled
78
- sidebar using `.gnav-*` classes with route-driven sub-nav; there is no 72px icon rail
79
- and no hover flyout, so these selectors matched nothing. */
80
-
81
- /* Composer = ONE bordered rounded shell (ChatGPT/Claude-style): the textarea sits borderless
82
- inside it and the attach (📎) + send (↑) buttons float within the same box — cleaner than the
83
- old three-separate-boxes row. The shell is inset from the panel edges (margin) and lifts its
84
- border to primary on focus-within, so the whole composer reads as one focused field. */
85
- /* TWO ROWS when there are chips (ChatComposer): the textarea on its own full-width row, the toolbar
86
- under it. The toolbar is where chips of any length live, and when they shared a row with the text
87
- box the send button was the thing that gave way — measured 22/09/2026 at 320px, it wrapped to a
88
- THIRD line. With no chips at all, ONE row — see `:has` below.
89
- 8px inside, not 6: at 6 the text sat 13px from the border and the box read as cramped. What the
90
- toolbar SAYS at each width is ChatComposer's job (data-density), measured rather than guessed. */
91
- .gemboss-ec-input {
92
- display: flex; flex-wrap: wrap; align-items: center; gap: 4px;
93
- margin: 12px; padding: 8px;
94
- border: 1px solid var(--gemboss-divider); border-radius: 16px;
95
- background: var(--gemboss-surface);
96
- transition: border-color var(--gemboss-transition-fast) ease, box-shadow var(--gemboss-transition-fast) ease;
97
- }
98
- .gemboss-ec-input:focus-within {
99
- border-color: var(--gemboss-primary);
100
- box-shadow: 0 0 0 3px color-mix(in srgb, var(--gemboss-primary) 12%, transparent);
101
- }
102
- .gemboss-ec-input textarea {
103
- flex: 1 0 100%; min-width: 0; width: 100%; box-sizing: border-box; resize: none; border-radius: 0; background: transparent;
104
- /* The CHIP's box model — a transparent 1px border and 8px of padding — so the first letter typed
105
- lines up with the first letter of "Claude Code" below it. It was 6px with no border: the text
106
- started 3px left of the chips, measured on every host at every width, and the box read as two
107
- columns. (Box model rather than nine pixels of padding: nine is off the spacing scale the CI guard holds.) */
108
- border: 1px solid transparent;
109
- padding: 6px 8px; font-size: var(--gemboss-fs-body); font-family: inherit;
110
- /* Starts at one line; GemChat's auto-grow JS expands it up to ~3 lines (max-height),
111
- then scrolls inside (ChatGPT/Gemini-style), and writes overflow-y itself (hidden until
112
- the cap, auto past it). The DEFAULT here is auto, for every surface that has no such
113
- JS: it was hidden, and there a message taller than the box could not be scrolled at
114
- all — wheel and touch do nothing under overflow:hidden. Measured 02/10/2026 in Chromium:
115
- wheel scrolled 0/9 overflowing boxes with hidden, 9/9 with auto; a box whose text
116
- fits showed no overflow at 13.5 / 14 / 15px (no rounding scrollbar). Found on
117
- partner-radar's assistant: 264px of text in a 75px box, unreadable. */
118
- min-height: 0; max-height: 84px; line-height: 1.5; overflow-y: auto;
119
- scrollbar-width: thin; scrollbar-color: rgba(31,30,29,0.22) transparent; /* thin, not the OS bar */
120
- }
121
- .gemboss-ec-input textarea::-webkit-scrollbar { width: 7px; }
122
- .gemboss-ec-input textarea::-webkit-scrollbar-track { background: transparent; }
123
- .gemboss-ec-input textarea::-webkit-scrollbar-thumb { background: rgba(31,30,29,0.2); border-radius: 4px; border: 2px solid transparent; background-clip: content-box; }
124
- .gemboss-ec-input textarea:focus { outline: none; }
125
- /* Send button — a filled primary circle floating at the shell's bottom-right. inline-flex centers
126
- the ↑ SVG (the old rule had no flex-centering, so the icon sat high).
127
-
128
- SCOPED TO THE SUBMIT BUTTON, and that word is load-bearing. This rule used to read
129
- `.gemboss-ec-input button`, which reached EVERY button in the composer — including whatever a host
130
- passes in through `composerLeading`, a slot that exists precisely so hosts can put their own
131
- controls here. The 📎 attach button already had to fight it back with a class of its own (see the
132
- comment above `.gemboss-ec-attach-btn`), which was the first sign that this selector owns more than
133
- it should. The second was the engine picker: a Polaris Button, rendered into the slot, came out as a
134
- 34px black circle with its label ("Claude Code · Opus") clipped to three characters. Nothing was
135
- wrong with the picker — this rule was painting it.
136
-
137
- §9.3: one visual owner per component. The composer owns its own send button and nothing that is
138
- handed to it. Guarded by composer-owns-only-its-own-buttons.test.ts.
139
-
140
- 44px, not 34: it is a CONTROL (§9.1, Apple HIG / WCAG 2.5.5 AAA). This branch had already raised
141
- it — but on the OLD unscoped selector, the very rule main had just narrowed. The two changes were
142
- fixing different faults in one declaration, so both are kept: main's scope, this branch's size. */
143
- .gemboss-ec-input button[type="submit"] {
144
- flex: 0 0 auto; width: 44px; height: 44px; min-width: 44px; min-height: 44px; border-radius: 50%; border: 0; cursor: pointer;
145
- display: inline-flex; align-items: center; justify-content: center;
146
- background: var(--gemboss-primary); color: var(--gemboss-on-primary, #fff); font-size: 16px; font-weight: 700;
147
- transition: background var(--gemboss-transition-fast) ease, filter var(--gemboss-transition-fast) ease;
148
- }
149
- .gemboss-ec-input button[type="submit"]:hover:not(:disabled) { background: var(--gemboss-primary-dark); }
150
- .gemboss-ec-input button[type="submit"]:active:not(:disabled) { background: var(--gemboss-primary-dark); filter: brightness(0.94); }
151
- .gemboss-ec-input button[type="submit"]:focus-visible { outline: 2px solid var(--gemboss-primary); outline-offset: 2px; }
152
- /* Disabled (empty input): a clear neutral grey circle with a muted arrow — reads as
153
- "inactive" rather than a washed-out faint-primary blob. */
154
- .gemboss-ec-input button[type="submit"]:disabled { background: var(--gemboss-divider); color: var(--gemboss-text-muted); opacity: 1; cursor: default; }
155
- /* ── Narration timeline ── */
156
- .gemboss-narr { list-style: none; margin: 0; padding: 8px 0 0; display: flex; flex-direction: column; gap: 8px; }
157
- .gemboss-narr-row { display: flex; align-items: center; gap: 8px; font-size: var(--gemboss-fs-caption); color: var(--gemboss-text-muted); }
158
- .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; }
159
- .gemboss-narr-row.ok .gemboss-narr-dot { background: var(--gemboss-active-bg); color: var(--gemboss-active-fg); }
160
- .gemboss-narr-row.failed .gemboss-narr-dot { background: #fde8e6; color: var(--gemboss-danger); }
161
- .gemboss-narr-row.running .gemboss-narr-dot { background: transparent; }
162
- /* THE ENGINE'S MARK, in the dot's slot. No pill behind it: the ✓/✕ dots earn their background by
163
- being a glyph in a circle, and a logo in a coloured circle reads as a badge the engine awarded
164
- itself. It takes the ROW's colour, so a failed turn's mark goes red with everything else — a mark
165
- that stayed brand-coloured over a failure would be the one cheerful thing on a broken row. */
166
- .gemboss-narr-dot-engine { background: transparent !important; color: inherit; }
167
- .gemboss-narr-row.ok .gemboss-narr-dot-engine { color: var(--gemboss-text); }
168
- .gemboss-narr-row.failed .gemboss-narr-dot-engine { color: var(--gemboss-danger); }
169
- .gemboss-narr-row.ok .gemboss-narr-text, .gemboss-narr-row.failed .gemboss-narr-text { color: var(--gemboss-text); }
170
- /* A message the seller typed INTO the running turn. It reads as THEIR line, not as a step the agent
171
- took: full-strength text (the timeline is muted by default) against the page's own text colour, and
172
- a `❯` prompt caret instead of a status dot. It must be legible at a glance while the agent is still
173
- writing above it — a seller scanning a long timeline needs to find the moment they interrupted. */
174
- .gemboss-narr-row.steer .gemboss-narr-dot { background: transparent; color: var(--gemboss-text-muted); }
175
- /* `anywhere`, not `normal`: a seller correcting a turn pastes URLs and product handles, and one
176
- unbroken 60-character token in a 320px chat column is a row that pushes the panel sideways. Measured
177
- 2026-09-23 — the default `overflow-wrap: normal` on this row does not break such a token. */
178
- .gemboss-narr-steer { color: var(--gemboss-text); font-weight: 500; overflow-wrap: anywhere; }
179
- .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 0.7s linear infinite; }
180
- @keyframes gemboss-spin { to { transform: rotate(360deg); } }
181
- /* Live-reasoning ("thinking") row: muted + italic while streaming, collapsible once settled. */
182
- .gemboss-narr-row.thinking { align-items: flex-start; }
183
- .gemboss-narr-row.thinking .gemboss-narr-dot { color: var(--gemboss-text-muted); background: transparent; }
184
- .gemboss-narr-thinking-live { font-style: italic; color: var(--gemboss-text-muted); white-space: pre-wrap; opacity: 0.9; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
185
- .gemboss-narr-thinking { font-size: var(--gemboss-fs-caption); }
186
- .gemboss-narr-thinking > summary { cursor: pointer; color: var(--gemboss-text-muted); list-style: none; user-select: none; }
187
- .gemboss-narr-thinking > summary::-webkit-details-marker { display: none; }
188
- .gemboss-narr-thinking > summary::before { content: "▸ "; }
189
- .gemboss-narr-thinking[open] > summary::before { content: "▾ "; }
190
- .gemboss-narr-thinking-body { margin-top: 6px; padding: 8px 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; }
191
- /* TOOL TRANSCRIPT rows — the Claude-Code shape: a monospace call line, its return value folded
192
- behind a disclosure. Muted on purpose: the transcript is evidence you can audit, not the answer. */
193
- .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; }
194
- .gemboss-narr-trace-call { color: var(--gemboss-text-muted); display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
195
- .gemboss-narr-trace { font-size: var(--gemboss-fs-caption); min-width: 0; }
196
- .gemboss-narr-trace > summary { cursor: pointer; color: var(--gemboss-text-muted); list-style: none; user-select: none;
197
- /* A tool call with real arguments is long and the chat panel is narrow: a full payload wrapped to five
198
- lines buries the rows around it. Clamp while closed; opening the row shows the call in full. */
199
- display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
200
- .gemboss-narr-trace[open] > summary { display: block; overflow: visible; }
201
- .gemboss-narr-trace > summary::-webkit-details-marker { display: none; }
202
- /* The fold is now the ONLY way to see a payload or a finished thought (both start closed), so its
203
- summary is a target: ≥24px tall, the list-link tier of Gems/CLAUDE.md §9.1 (WCAG 2.5.8). Measured
204
- 21px before, 13/09. */
205
- .gemboss-narr-trace > summary, .gemboss-narr-thinking > summary { min-height: 24px; box-sizing: border-box; padding-block: 2px; }
206
- .gemboss-narr-trace > summary::before { content: "▸ "; }
207
- .gemboss-narr-trace[open] > summary::before { content: "▾ "; }
208
- .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; }
209
- @media (max-width: 640px) {
210
- /* Composer auto-grows from one line (see GemChat) — no fixed floor needed here. */
211
- .gemboss-ec-input textarea { min-height: 0; }
212
- .gemboss-ec-scroll { padding: 12px; }
213
- }
214
- /* ── Chat option chips (persona/goal polling) ── */
215
- .gemboss-ec-chips { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 4px; }
216
- /* 44px because a chip is a CONTROL, not a link in a list — Apple HIG / WCAG 2.5.5 AAA, Gems CLAUDE.md
217
- §9.1. Measured 2026-09-09 at 390px and 1366px: padding alone rendered these at 34px, ten short, and
218
- they are the only way to answer a poll or resume an unfinished run on a phone. `min-height` rather
219
- than `height` so a wrapped two-line label still grows instead of clipping. */
220
- .gemboss-ec-chip {
221
- background: var(--gemboss-surface); border: 1px solid var(--gemboss-divider); border-radius: var(--gemboss-radius-full);
222
- padding: 8px 16px; font-size: 13px; cursor: pointer; color: var(--gemboss-text);
223
- min-height: 44px;
224
- }
225
- .gemboss-ec-chip:hover { border-color: var(--gemboss-primary); color: var(--gemboss-active-fg); }
226
- .gemboss-ec-chip:disabled { opacity: 0.5; cursor: default; }
227
- /* ════ Mouse targets — the same 44px, bought with an overlay instead of a bigger box ═══════
228
- §9.1 asks 44px of a CONTROL, and it does not say "on touch only". The chat panel's controls are
229
- 28-37px under a mouse, which clears WCAG 2.5.8 AA (24px) and not 2.5.5 AAA (44px). The dense look
230
- is deliberate and worth keeping, so the TARGET grows and the ink does not — the same trick the
231
- editor topbar already uses on its device buttons.
232
-
233
- WHICH ONES, AND WHY NOT THE REST. A target that reaches into a neighbour steals clicks meant for
234
- it, which is worse than a small one. So this was decided by measuring the gap between every pair
235
- of vertically adjacent controls at 390 / 768 / 1366 and asking whether BOTH could grow into it —
236
- a control's own clearance is not enough, because its neighbour is growing too. Measured
237
- 2026-09-09, three pairs could not:
238
-
239
- starter chips, row to row gap 8px, both need 7 -> the ROW GAP goes to 16px below, which buys
240
- it without changing how the chips look
241
- textarea / engine picker gap 8px, needs 10 -> the textarea does not grow (see below)
242
- textarea / send gap 6px, needs 9 -> same
243
-
244
- THE MESSAGE BOX IS EXCLUDED ON PURPOSE. It is a full-width field 37px tall: its AREA is already
245
- enormous, the only dimension short of 44 is its height, and it is the one control here you reach
246
- by clicking INTO text rather than at a point. Growing it also collides with both of its
247
- neighbours. With it left alone, everything else fits: send needs 5 of the 6px above it, the
248
- picker needs 8 of 8.
249
-
250
- Height only. Horizontally these controls are already 34-196px wide, and an overlay that also grew
251
- sideways would collide with the chip beside it, which is 8px away. */
252
- @media (pointer: fine) {
253
- .gemboss-ec-starters { row-gap: 16px; }
254
- .gemboss-ec-tab,
255
- .gemboss-ec-starter,
256
- .gemboss-ec-upload,
257
- .gemboss-ec-enginepick button,
258
- .gemboss-ec-workmode,
259
- .gemboss-ec-input .gemboss-ec-attach-btn,
260
- .gemboss-ec-stop,
261
- /* Shares the toolbar row with Stop, which is already 44px tall — so a 44px overlay here grows into
262
- a row that is that tall already, and reaches into nothing above or below it. */
263
- .gemboss-ec-stop-send,
264
- .gemboss-ec-input button[type="submit"] { position: relative; }
265
- .gemboss-ec-tab::after,
266
- .gemboss-ec-starter::after,
267
- .gemboss-ec-upload::after,
268
- .gemboss-ec-enginepick button::after,
269
- /* `::before` on the work-mode wrapper: its `::after` is the invisible label that SIZES it, and a
270
- second use of the same pseudo-element would silently replace that. */
271
- .gemboss-ec-workmode::before,
272
- .gemboss-ec-input .gemboss-ec-attach-btn::after,
273
- .gemboss-ec-stop::after,
274
- .gemboss-ec-stop-send::after,
275
- .gemboss-ec-input button[type="submit"]::after {
276
- content: "";
277
- position: absolute;
278
- left: 0; right: 0;
279
- top: 50%;
280
- transform: translateY(-50%);
281
- height: 44px;
282
- /* No background at all: a pseudo-element is transparent already, and the `background` shorthand
283
- is banned in this family because it resets `background-image` — the work-mode caret. My own
284
- guard from #2158 caught this line, which is the guard doing exactly what it was written for. */
285
- pointer-events: auto;
286
- /* Above the panel chrome it overhangs — the chrome is not interactive, so a click landing on the
287
- control the overlay belongs to is the point.
288
- This does NOT rescue a control sitting flush against the top of `.gemboss-ec-scroll`: an
289
- overflow container clips its absolutely-positioned descendants, and z-index cannot cross that.
290
- Measured at 768px, where the first row of starter chips begins at the exact pixel the header
291
- ends: their target is 37px until the list scrolls, and 44px after. A scroll position, not a
292
- layout constant — the same chips measure 44px at 390, 1366 and 1920. Left alone rather than
293
- bought with padding on the scroll area, which every seller would see all the time to fix a
294
- target in one transient position. */
295
- z-index: 1;
296
- }
297
- }
298
- @media (pointer: coarse) {
299
- .gemboss-ec-input button[type="submit"] { width: 44px; height: 44px; font-size: 17px; }
300
- .gemboss-ec-starter, .gemboss-ec-opt { min-height: 44px; }
301
- .gemboss-ec-input textarea { min-height: 44px; }
302
- }
303
- /* ── The answer bubble's markdown ────────────────────────────────────────────────────────────────
304
- *
305
- * The bubble understood bold, links and line breaks. The models writing into it do not restrict
306
- * themselves to three things: a question about pages came back as a markdown TABLE and rendered as
307
- * literal pipes down the page. These are the styles for what it actually writes. */
308
-
309
- .gemboss-md-p { margin: 0 0 8px; }
310
- .gemboss-md-p:last-child { margin-bottom: 0; }
311
- /* Demoted one level in the markup (h1 → h3) because the bubble sits under the page's own headings.
312
- * The SIZE hierarchy is kept here, because that is what a reader uses to skim. */
313
- .gemboss-md-h { margin: 16px 0 6px; font-weight: 650; line-height: 1.3; }
314
- .gemboss-md-h:first-child { margin-top: 0; }
315
- /* RESTORED after #3370 deleted these three. MarkdownLite.tsx builds the class by interpolation —
316
- * `gemboss-md-h gemboss-md-h${b.level}` — so the literal `gemboss-md-h1` exists in no source file
317
- * and in no compiled chunk, and all three of that PR's detection passes read them as dead. The gate
318
- * now carries the prefix rule that catches this shape. Do not "clean" these up. */
319
- .gemboss-md-h1 { font-size: 17px; }
320
- .gemboss-md-h2 { font-size: 15px; }
321
- .gemboss-md-h3 { font-size: var(--gemboss-fs-body); color: var(--gemboss-text-subdued, #616161); }
322
- .gemboss-md-list { margin: 0 0 8px; padding-left: 20px; }
323
- .gemboss-md-list li { margin: 2px 0; }
324
- .gemboss-md-quote {
325
- margin: 0 0 8px;
326
- padding: 2px 0 2px 12px;
327
- border-left: 3px solid var(--gemboss-border, #e3e3e3);
328
- color: var(--gemboss-text-subdued, #616161);
329
- }
330
- .gemboss-md-rule { margin: 12px 0; border: 0; border-top: 1px solid var(--gemboss-border, #e3e3e3); }
331
- /* Inline code: a chip, so an identifier stops reading as prose. */
332
- .gemboss-md-code {
333
- padding: 1px 6px;
334
- border-radius: 6px;
335
- background: var(--gemboss-surface-subdued, #f1f1f1);
336
- font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
337
- font-size: 0.9em;
338
- word-break: break-word;
339
- }
340
- /* Tables scroll INSIDE their own box. The chat lives in a 380px sidebar in the theme editor, and a
341
- * five-column table there would otherwise push the whole panel sideways — §9.1's rule that wide
342
- * content scrolls in its own container, not the page. */
343
- .gemboss-md-tablewrap { margin: 0 0 12px; overflow-x: auto; }
344
- .gemboss-md-table { border-collapse: collapse; font-size: var(--gemboss-fs-caption); min-width: 100%; }
345
- .gemboss-md-table th,
346
- .gemboss-md-table td {
347
- border: 1px solid var(--gemboss-border, #e3e3e3);
348
- padding: 6px 8px;
349
- text-align: left;
350
- vertical-align: top;
351
- white-space: nowrap;
352
- }
353
- .gemboss-md-table th { background: var(--gemboss-surface-subdued, #f7f7f7); font-weight: 600; }
354
- /* A picture in an answer (only from hosts markdown-blocks.ts trusts). Never wider than the bubble — the
355
- * chat can sit in a 380px sidebar — and capped in height so five thumbnails read as a shortlist, not
356
- * five screens. The link around it is the tap target: keyboard focus has to be visible on it. */
357
- .gemboss-md-imglink { display: inline-block; max-width: 100%; margin: 4px 0 8px; border-radius: 8px; line-height: 0; }
358
- .gemboss-md-imglink:focus-visible { outline: 2px solid var(--gemboss-focus, var(--ui-focus, #5661f5)); outline-offset: 2px; }
359
- .gemboss-md-img {
360
- display: block;
361
- max-width: 100%;
362
- max-height: 320px;
363
- height: auto;
364
- border: 1px solid var(--gemboss-border, #e3e3e3);
365
- border-radius: 8px;
366
- background: var(--gemboss-surface-subdued, #f7f7f7);
367
- object-fit: contain;
368
- }
369
- /* A code block, with the fold. A 200-line answer should not push everything after it off screen. */
370
- .gemboss-md-codeblock {
371
- position: relative;
372
- margin: 0 0 12px;
373
- border: 1px solid var(--gemboss-border, #e3e3e3);
374
- border-radius: 8px;
375
- background: var(--gemboss-surface-subdued, #f7f7f7);
376
- overflow: hidden;
377
- }
378
- .gemboss-md-codelang {
379
- display: block;
380
- padding: 4px 12px 0;
381
- color: var(--gemboss-text-subdued, #8a8a8a);
382
- font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
383
- font-size: 11px;
384
- }
385
- .gemboss-md-codeblock pre { margin: 0; padding: 8px 12px; overflow-x: auto; }
386
- .gemboss-md-codeblock code {
387
- font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
388
- font-size: 12px;
389
- line-height: 1.5;
390
- white-space: pre;
391
- }
392
- .gemboss-md-codemore {
393
- display: block;
394
- width: 100%;
395
- padding: 6px 12px;
396
- border: 0;
397
- border-top: 1px solid var(--gemboss-border, #e3e3e3);
398
- background: transparent;
399
- color: var(--gemboss-text-subdued, #616161);
400
- font-size: 12px;
401
- text-align: left;
402
- cursor: pointer;
403
- }
404
- .gemboss-md-codemore:hover { background: rgba(0, 0, 0, 0.03); }
405
- /* ── The payload, live, in the chat ──────────────────────────────────────────────────────────────
406
- A trace row said `apply_section_edit(section_id:"hero")` — that something happened, and nothing about
407
- what. This is what. Open by default: folding it would put the answer back behind a click. */
408
- .gemboss-narr-row.source { align-items: flex-start; }
409
- .gemboss-narr-source { min-width: 0; flex: 1; }
410
- .gemboss-narr-source-head { font-size: 11px; color: var(--gemboss-text-muted, #686b71); margin-bottom: 4px; }
411
- .gemboss-narr-source-head code { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; }
412
- .gemboss-narr-source-code {
413
- margin: 0; padding: 8px 12px; border-radius: 8px; max-height: 220px; overflow: auto;
414
- background: var(--gemboss-primary-soft, #f2f3f5); border: 1px solid var(--gemboss-divider, #e5e7ea);
415
- font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--gemboss-fs-micro); line-height: 17px;
416
- white-space: pre; tab-size: 2;
417
- }
418
- /* Light-ground syntax colours for the payload rows (the code-highlight.ts `c-*` spans). Contrast checked
419
- against #fff: every one clears 4.5:1. (The page editor's Code tab shared them until it was removed, #2651.) */
420
- .gemboss-narr-source-code .c-com { color: #6a7a86; font-style: italic; }
421
- .gemboss-narr-source-code .c-str { color: #9a3412; }
422
- .gemboss-narr-source-code .c-num { color: #1d6fa5; }
423
- .gemboss-narr-source-code .c-kw { color: #7c3aed; font-weight: 600; }
424
- .gemboss-narr-source-code .c-key { color: #0b6b3a; }
425
- .gemboss-narr-source-code .c-tag { color: #b0197a; }
426
- .gemboss-narr-source-code .c-attr{ color: #7c3aed; }
427
- .gemboss-narr-source-code .c-pun { color: #6a6d73; }
428
- @media (max-width: 520px) {
429
- .gemboss-narr-source-code { max-height: 160px; font-size: 11px; }
430
- }
431
- /* A checklist row's box IS its marker; the dot column stays for alignment and shows nothing. */
432
- .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-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}
@@ -0,0 +1 @@
1
+ :root{--ui-coll-head-bg: color-mix(in srgb, var(--ui-text, #1b1c1e) 3.5%, var(--ui-surface, #fff));--ui-coll-hover: color-mix(in srgb, var(--ui-text, #1b1c1e) 3.5%, var(--ui-surface, #fff));--ui-coll-selected: color-mix(in srgb, var(--ui-text, #1b1c1e) 6%, var(--ui-surface, #fff));--ui-coll-check-w: 40px}.ui-table--sticky-first tr{background:var(--ui-surface)}.ui-table--sticky-first tbody tr:hover{background:var(--ui-surface-2)}.ui-table--sticky-first :is(th,td):first-child{position:sticky;left:0;z-index:1;background:inherit}@supports (animation-timeline: scroll()){.ui-table-wrap:has(>.ui-table--sticky-first){scroll-timeline:--ui-coll-x inline}.ui-table--sticky-first :is(th,td):first-child{animation:ui-coll-edge linear both;animation-timeline:--ui-coll-x;animation-range:0 24px}}@keyframes ui-coll-edge{0%{box-shadow:none}to{box-shadow:1px 0 0 var(--ui-border),6px 0 8px -6px #0000002e}}.ui-table--compact :is(td,tbody th){padding-block:6px}.ui-table--compact thead th{padding-block:6px}.ui-table__totals>tr{background:var(--ui-coll-head-bg)}.ui-table__totals>tr>:is(td,th){background:var(--ui-coll-head-bg);font-weight:650;color:var(--ui-text);border-top:1px solid var(--ui-border);border-bottom:0}.ui-table__footer{padding:8px 12px;background:var(--ui-coll-head-bg);border-top:1px solid var(--ui-border);color:var(--ui-text-muted);font-size:var(--ui-fs-body);text-align:center}.ui-table th.ui-table__rowhead{font-weight:450;color:var(--ui-text);text-align:left}.ui-table th.ui-table__rowhead:not(.is-num){white-space:normal;min-width:9.0625rem}.ui-table th.ui-table__rowhead>a,.ui-table:where(:not(.ui-table--index)) tbody :is(td,th) li>a{display:inline-flex;align-items:center;min-height:24px}.ui-table:where(:not(.ui-table--index)) tbody :is(td,th){vertical-align:top}.ui-table:where(:not(.ui-table--index)) tbody :is(td>a,th.ui-table__rowhead>a,:is(td,th) li>a){margin-block:calc((1lh - 24px)/2)}.ui-table__sort{display:flex;width:max-content;max-width:100%;align-items:center;gap:4px;min-height:24px;margin-block:-2px;padding:0;border:0;background:none;color:inherit;font:inherit;text-align:inherit;text-decoration:none;cursor:pointer;white-space:nowrap}.ui-table__sort:hover{color:var(--ui-text)}.ui-table__sort:focus-visible{outline:2px solid var(--ui-focus);outline-offset:2px;border-radius:4px}.ui-table__sort:after{content:"";flex:none;width:16px;height:16px;background:currentColor;opacity:0;-webkit-mask:var(--ui-coll-arrow) center / 16px no-repeat;mask:var(--ui-coll-arrow) center / 16px no-repeat;--ui-coll-arrow: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M8 3.5v9M4.5 9 8 12.5 11.5 9' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E")}.ui-table__sort:is(:hover,:focus-visible):after{opacity:.45}th[aria-sort=ascending]>.ui-table__sort:after,th[aria-sort=descending]>.ui-table__sort:after{opacity:1}th[aria-sort=ascending]>.ui-table__sort:after{transform:rotate(180deg)}th[aria-sort=ascending]>.ui-table__sort,th[aria-sort=descending]>.ui-table__sort{color:var(--ui-text)}.ui-table .is-num>.ui-table__sort{flex-direction:row-reverse;margin-left:auto}.ui-trunc{display:block;max-width:var(--ui-trunc, 32ch);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-clamp-2{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden;white-space:normal;overflow-wrap:anywhere}.ui-index{position:relative;container:ui-index / inline-size;min-width:0}.ui-table--index{font-size:var(--ui-fs-body)}.ui-table--index tr{background:var(--ui-surface)}.ui-table.ui-table--index thead th{padding:8px 6px;background:var(--ui-coll-head-bg);color:var(--ui-text-muted);font-size:var(--ui-fs-caption);line-height:20px;font-weight:550;text-transform:none;letter-spacing:0}.ui-table.ui-table--index :is(td,tbody th){padding:6px;line-height:20px;white-space:nowrap;vertical-align:middle;border-bottom:0;border-top:1px solid var(--ui-border)}.ui-table.ui-table--index :is(th,td):where(:first-child){padding-left:var(--ui-space-3)}.ui-table.ui-table--index :is(th,td):where(:last-child){padding-right:var(--ui-space-3)}.ui-table--index tbody tr:hover{background:var(--ui-coll-hover)}.ui-table--index tbody tr:is(.is-selected,[aria-selected=true]){background:var(--ui-coll-selected)}.ui-table--index tbody tr:is([data-href],.is-linked){cursor:pointer}.ui-table--index tbody tr:has(.ui-table__title:focus-visible){outline:2px solid var(--ui-focus);outline-offset:-2px}.ui-table__title:focus-visible{outline:none}.ui-table__primary{min-width:0}.ui-table__primary-inner{display:flex;align-items:center;gap:var(--ui-space-3);min-width:0}.ui-table__primary-text{min-width:0}.ui-table__title{display:block;max-width:var(--ui-trunc, 40ch);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ui-text);font-weight:650;text-decoration:none}a.ui-table__title:hover{text-decoration:underline}.ui-table--index .ui-table__title+.ui-sub,.ui-table--index .ui-sub{display:block;max-width:var(--ui-trunc, 40ch);overflow:hidden;text-overflow:ellipsis;white-space:nowrap;margin-top:0;line-height:16px}.ui-table--index td>a.ui-table__title{display:block;min-height:0}.ui-table--index td>.ui-table__primary-inner>a.ui-table__title,.ui-table--index .ui-table__primary-text>a.ui-table__title{line-height:20px}.ui-table.ui-table--index .ui-table__check{width:var(--ui-coll-check-w);padding:6px 8px 6px 12px}.ui-table.ui-table--index thead .ui-table__check{padding:8px 8px 8px 12px}.ui-table__checkbox{display:flex;width:max-content;align-items:center;justify-content:center;min-width:24px;min-height:24px;margin:-2px 0;cursor:pointer}.ui-table__checkbox>input,.ui-list__check>input{width:16px;height:16px;margin:0;accent-color:var(--ui-accent);cursor:pointer}.ui-table__checkbox>input:focus-visible,.ui-list__check>input:focus-visible{outline:2px solid var(--ui-focus);outline-offset:2px}.ui-table--index :is(.ui-table__check,.ui-table__primary){position:sticky;z-index:1;background:inherit}.ui-table--index .ui-table__check,.ui-table--index .ui-table__primary{left:0}.ui-table--index:has(.ui-table__check) .ui-table__primary{left:var(--ui-coll-check-w)}.ui-table__actions{width:1%;text-align:right}.ui-table__actions>*{vertical-align:middle}.ui-row-actions{display:inline-flex;align-items:center;gap:var(--ui-space-2)}.ui-bulkbar{position:relative;z-index:3;display:flex;flex-wrap:wrap;align-items:center;gap:var(--ui-space-2);box-sizing:border-box;min-height:38px;margin-bottom:-38px;padding:4px 8px 4px 12px;background:var(--ui-surface);border:1px solid var(--ui-border);border-bottom-color:transparent;border-radius:var(--ui-radius-lg) var(--ui-radius-lg) 0 0;font-size:var(--ui-fs-body)}.ui-bulkbar[hidden]{display:none}.ui-bulkbar__count{font-weight:550;font-variant-numeric:tabular-nums}.ui-bulkbar__actions{display:inline-flex;flex-wrap:wrap;gap:var(--ui-space-2);margin-left:auto}.ui-bulkbar .ui-table__checkbox{margin-right:4px}.ui-index__sortbar{display:none}@container ui-index (max-width: 768px){.ui-table--index,.ui-table--index tbody{display:block;width:100%}.ui-table--index thead{display:none}.ui-table--index tbody tr{position:relative;display:flex;flex-wrap:wrap;align-items:baseline;gap:2px 12px;min-height:44px;box-sizing:border-box;padding:10px 12px;border-top:1px solid var(--ui-border)}.ui-table--index tbody tr:first-child{border-top:0}.ui-table--index tbody tr:has(>.ui-table__check){padding-left:48px}.ui-table.ui-table--index tbody :is(td,th){display:block;padding:0;border:0;position:static;background:none;white-space:nowrap}.ui-table--index tbody .ui-table__primary{flex:1 0 100%;white-space:normal}.ui-table--index tbody td:not(.ui-table__primary,.ui-table__check,.ui-table__actions){flex:none;max-width:100%;overflow:hidden;text-overflow:ellipsis;color:var(--ui-text-muted);font-size:var(--ui-fs-caption);line-height:18px}.ui-table--index tbody td[data-label]:not(.ui-table__primary):before{content:attr(data-label) " ";color:var(--ui-text-muted)}.ui-table--index tbody td:not(.ui-table__primary,.ui-table__check,.ui-table__actions) .ui-trunc{display:inline-block;vertical-align:bottom}.ui-table--index tbody td:not(.ui-table__primary,.ui-table__check,.ui-table__actions) .ui-sub{display:inline;margin-left:6px}.ui-table--index tbody td.is-num{text-align:left}.ui-table--index tbody td[data-condensed=hide]{display:none}.ui-table.ui-table--index tbody .ui-table__check{position:absolute;left:4px;top:4px;width:auto;padding:0}.ui-table.ui-table--index tbody .ui-table__actions{order:99;margin-left:auto;width:auto;padding:0;align-self:center}.ui-table--index .ui-table__checkbox{min-width:44px;min-height:44px;margin:0}.ui-table--index .ui-table__title,.ui-table--index .ui-sub{max-width:none}.ui-index__sortbar{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ui-space-2);margin:0 0 var(--ui-space-3);font-size:var(--ui-fs-caption);color:var(--ui-text-muted)}.ui-index .ui-bulkbar{margin-bottom:var(--ui-space-2);border-bottom-color:var(--ui-border);border-radius:var(--ui-radius-lg)}.ui-index .ui-table-wrap{overflow-x:visible}}.ui-list{container:ui-list / inline-size;margin:0;padding:0;list-style:none;background:var(--ui-surface);border:1px solid var(--ui-border);border-radius:var(--ui-radius-lg);box-shadow:var(--ui-card-shadow)}.ui-list--flush{border:0;border-radius:0;box-shadow:none;background:transparent}.ui-list__item{position:relative;display:flex;align-items:flex-start;gap:var(--ui-space-3);box-sizing:border-box;padding:var(--ui-space-3);min-height:44px;border-top:1px solid var(--ui-border)}.ui-list>.ui-list__item:first-child{border-top:0}.ui-list>.ui-list__item:first-child{border-top-left-radius:inherit;border-top-right-radius:inherit}.ui-list>.ui-list__item:last-child{border-bottom-left-radius:inherit;border-bottom-right-radius:inherit}.ui-list__item:has(.ui-list__title[href]):hover{background:var(--ui-coll-hover)}.ui-list__item:is(.is-selected,[aria-selected=true]){background:var(--ui-coll-selected)}.ui-list__item:has(.ui-list__title:focus-visible){outline:2px solid var(--ui-focus);outline-offset:-2px}.ui-list__media{flex:none;display:flex;align-items:center;min-height:40px}.ui-list__body{flex:1 1 auto;min-width:0}.ui-list__title{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ui-text);font-size:var(--ui-fs-body);line-height:20px;font-weight:650;text-decoration:none}.ui-list__title[href]:after{content:"";position:absolute;inset:0;z-index:0}.ui-list__title:focus-visible{outline:none}.ui-list__sub{margin:0;color:var(--ui-text-muted);font-size:var(--ui-fs-body);line-height:20px;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden;overflow-wrap:anywhere}.ui-list__meta{margin:2px 0 0;color:var(--ui-text-muted);font-size:var(--ui-fs-caption);line-height:16px}.ui-list__badges{display:flex;flex-wrap:wrap;gap:4px;margin-top:4px}.ui-list__aside{flex:none;align-self:center;color:var(--ui-text);font-variant-numeric:tabular-nums;text-align:right}.ui-list__actions{flex:none;align-self:center;display:inline-flex;align-items:center;gap:var(--ui-space-2)}.ui-list__item :is(.ui-list__actions,.ui-list__aside a,.ui-list__body a:not(.ui-list__title),button,input,select,textarea,label,summary,details){position:relative;z-index:1}@container ui-list (max-width: 400px){.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item{display:grid;grid-template-columns:auto minmax(0,1fr) auto;grid-template-areas:"media body body" "media aside actions";gap:0;align-items:start}.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item>.ui-list__media{grid-area:media;margin-inline-end:var(--ui-space-3)}.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item>.ui-list__body{grid-area:body}.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item>.ui-list__aside{grid-area:aside;justify-self:start;align-self:center;margin-top:4px;text-align:left}.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item>.ui-list__actions{grid-area:actions;justify-self:end;align-self:center;margin:4px 0 0 var(--ui-space-3)}.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item:has(>.ui-list__body>.ui-list__title:only-child){grid-template-columns:auto minmax(0,1fr) auto auto;grid-template-areas:"media body aside actions";align-items:center}.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item:has(>.ui-list__body>.ui-list__title:only-child)>:is(.ui-list__aside,.ui-list__actions){margin-top:0}.ui-list:not(.ui-list--compact,.ui-skeleton--list)>.ui-list__item:has(>.ui-list__body>.ui-list__title:only-child)>.ui-list__aside{margin-inline-start:var(--ui-space-3);text-align:right}}.ui-resource>.ui-bulkbar{margin-bottom:0;border-bottom-color:var(--ui-border)}.ui-resource>.ui-bulkbar:has(+.ui-list--flush){border-width:0 0 1px;border-radius:0}.ui-resource>.ui-list,.ui-resource>[aria-busy]>.ui-list{border-top:0;border-top-left-radius:0;border-top-right-radius:0}.ui-list__check{display:flex;flex:none;align-items:center;justify-content:center;min-width:24px;min-height:24px;cursor:pointer}.ui-list__check:not(:last-child){margin-inline-end:8px}@media (pointer: coarse),(max-width: 47.9975em){.ui-list__check{min-width:44px;min-height:44px;margin-block:-2px;margin-inline-start:-12px}.ui-list__check:not(:last-child){margin-inline-end:-2px}.ui-resource>.ui-bulkbar>.ui-table__checkbox{min-width:44px;min-height:44px;margin:-8px -8px -8px -12px}}.ui-thumb{display:block;flex:none;width:40px;height:40px;box-sizing:border-box;border:1px solid var(--ui-border);border-radius:var(--ui-radius-md);background:var(--ui-surface-2);overflow:hidden;object-fit:cover}.ui-thumb--xs{width:24px;height:24px;border-radius:var(--ui-radius-sm)}.ui-thumb--md{width:60px;height:60px}.ui-thumb--lg{width:80px;height:80px}.ui-thumb>img{display:block;width:100%;height:100%;object-fit:cover}.ui-list--compact>.ui-list__item{display:block;padding:0;min-height:0}.ui-list__row{display:flex;align-items:center;gap:var(--ui-space-2);box-sizing:border-box;width:100%;min-height:36px;padding:8px 12px;border:0;background:none;color:var(--ui-text);font:inherit;font-size:var(--ui-fs-body);line-height:20px;text-align:left;text-decoration:none;border-radius:inherit}:is(a,button).ui-list__row{cursor:pointer}:is(a,button).ui-list__row:hover{background:var(--ui-coll-hover)}:is(a,button).ui-list__row:focus-visible{outline:2px solid var(--ui-focus);outline-offset:-2px}.ui-list__row[aria-current=page],.ui-list__row.is-selected{background:var(--ui-coll-selected)}.ui-list__icon{flex:none;display:inline-flex;width:20px;height:20px;align-items:center;justify-content:center;color:var(--ui-text-muted)}.ui-list__icon>svg{width:16px;height:16px}.ui-list__label{flex:1 1 auto;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-list__row>.ui-list__meta{flex:none;margin:0;font-variant-numeric:tabular-nums}@media (pointer: coarse),(max-width: 47.9975em){.ui-list__row{min-height:44px}}.ui-list--activity>.ui-list__item{display:grid;grid-template-columns:20px minmax(0,1fr) auto;column-gap:var(--ui-space-2);align-items:start;padding:8px 12px;min-height:36px;border-top:0}.ui-list--activity>.ui-list__item:before{content:"";position:absolute;left:21.5px;top:0;bottom:0;width:1px;background:var(--ui-border)}.ui-list--activity>.ui-list__item:first-child:before{top:14px}.ui-list--activity>.ui-list__item:last-child:before{bottom:calc(100% - 14px)}.ui-list--activity>.ui-list__item:only-child:before{display:none}.ui-list__dot{position:relative;z-index:1;width:8px;height:8px;margin:6px 0 0 6px;border-radius:50%;background:var(--ui-text-muted);box-shadow:0 0 0 3px var(--ui-surface)}.ui-list__dot--success{background:var(--gemboss-success, #0a8f6a)}.ui-list__dot--warning{background:var(--gemboss-warning, #b25e09)}.ui-list__dot--critical{background:var(--gemboss-danger-strong, #c70a24)}.ui-list__dot--info{background:var(--gemboss-accent, #5661f5)}.ui-list--activity .ui-list__label{display:block;white-space:nowrap}.ui-list--activity .ui-list__detail{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;color:var(--ui-text-muted);font-size:var(--ui-fs-caption);line-height:16px}.ui-list--activity time,.ui-list--activity .ui-list__time{color:var(--ui-text-muted);font-size:var(--ui-fs-caption);line-height:20px;white-space:nowrap;font-variant-numeric:tabular-nums}.ui-list__content{margin-top:4px;color:var(--ui-text);font-size:var(--ui-fs-body);line-height:20px;overflow-wrap:anywhere}.ui-list__content>p{margin:0}.ui-list__content>p+p{margin-top:4px}.ui-list--wrap .ui-list__label,.ui-list--wrap .ui-list__detail{white-space:normal;overflow:visible;text-overflow:clip;overflow-wrap:anywhere}.ui-list--wrap .ui-list__row{align-items:flex-start}@media (pointer: coarse),(max-width: 47.9975em){.ui-list--wrap .ui-list__row{padding-block:12px}}.ui-list--wrap .ui-list__row>.ui-list__meta{line-height:20px}.ui-cardgrid{--ui-cardgrid-min: 240px;display:grid;grid-template-columns:repeat(auto-fill,minmax(min(var(--ui-cardgrid-min),100%),1fr));gap:var(--ui-space-4);margin:0;padding:0;list-style:none}.ui-cardgrid[data-min="200"]{--ui-cardgrid-min: 200px}.ui-cardgrid[data-min="320"]{--ui-cardgrid-min: 320px}.ui-cardgrid>*{min-width:0}.ui-board{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(240px,1fr);gap:var(--ui-space-4);align-items:start;overflow-x:auto;overscroll-behavior-x:contain;scroll-snap-type:x mandatory;padding-bottom:4px}@media (max-width: 47.9975em){.ui-board{grid-auto-columns:78%}}.ui-board__col{display:flex;flex-direction:column;gap:var(--ui-space-2);min-width:0;padding:var(--ui-space-2);scroll-snap-align:start;background:var(--ui-coll-head-bg);border-radius:var(--ui-radius-lg)}.ui-board__head{display:flex;align-items:center;gap:var(--ui-space-2);min-height:28px;padding:0 4px;font-size:var(--ui-fs-body);font-weight:650}.ui-board__name{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.ui-board__count{margin-left:auto;color:var(--ui-text-muted);font-weight:450;font-variant-numeric:tabular-nums}.ui-board__dot{flex:none;width:8px;height:8px;border-radius:50%;background:var(--ui-text-muted)}.ui-board__dot--success{background:var(--gemboss-success, #0a8f6a)}.ui-board__dot--warning{background:var(--gemboss-warning, #b25e09)}.ui-board__dot--critical{background:var(--gemboss-danger-strong, #c70a24)}.ui-board__dot--info{background:var(--gemboss-accent, #5661f5)}.ui-board__list{display:grid;gap:var(--ui-space-2);margin:0;padding:0;list-style:none}.ui-board__list>li{min-width:0}.ui-board__empty{margin:0;padding:var(--ui-space-4) var(--ui-space-2);color:var(--ui-text-muted);font-size:var(--ui-fs-body);text-align:center;border:1px dashed var(--ui-border);border-radius:var(--ui-radius-md)}.ui-board__more>summary{list-style:none;justify-self:center;margin:4px auto 0;width:fit-content}.ui-board__more>summary::-webkit-details-marker{display:none}.ui-board__more[open]>summary{display:none}.ui-board__more{display:grid;gap:var(--ui-space-2)}.ui-board__next.ui-more{padding:4px 0 0}.ui-board__next .ui-more__error{color:var(--gemboss-danger-strong, #c70a24)}.ui-board[data-gb-move] .ui-board__list>li[data-id]{position:relative;border-radius:var(--ui-radius-lg);cursor:grab}.ui-board[data-gb-move] .ui-board__list>li[data-id]:focus-visible{outline:2px solid var(--ui-focus);outline-offset:2px}.ui-board__list>li[data-gb-lifted]{outline:2px solid var(--ui-focus);outline-offset:2px;box-shadow:var(--gemboss-shadow-md, 0 4px 12px rgba(0,0,0,.12));border-radius:var(--ui-radius-lg)}.ui-board[data-gb-dragging] .ui-board__list>li[data-gb-lifted]{outline:0;opacity:.4}.ui-board__col[data-gb-over]{background:color-mix(in srgb,var(--ui-focus) 10%,var(--ui-coll-head-bg))}.ui-board__list>li[data-gb-drop]:before{content:"";position:absolute;left:0;right:0;height:2px;border-radius:1px;background:var(--ui-focus);pointer-events:none}.ui-board__list>li[data-gb-drop=before]:before{top:-5px}.ui-board__list>li[data-gb-drop=after]:before{bottom:-5px}.ui-empty--no-match{padding-block:32px}.ui-coll-error{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ui-space-2) var(--ui-space-3);margin:var(--ui-space-3)}.ui-coll-error>:first-child{flex:1 1 240px;min-width:0}.ui-coll-count{margin-left:auto;color:var(--ui-text-muted);font-size:var(--ui-fs-body);font-variant-numeric:tabular-nums;white-space:nowrap}.ui-chip__x{margin-right:-4px;font-size:14px;line-height:1;opacity:.7}:is(.ui-table-wrap,.ui-index,.ui-list,.ui-cardgrid,.ui-board)[aria-busy=true]{position:relative}:is(.ui-table-wrap,.ui-index,.ui-list,.ui-cardgrid,.ui-board)[aria-busy=true]>:not(.ui-bulkbar,.ui-coll-busy){opacity:.55;pointer-events:none;transition:opacity .15s}.ui-coll-busy{position:absolute;top:8px;right:8px;z-index:4}:is(.ui-skeleton--table,.ui-skeleton--list,.ui-skeleton--compact,.ui-skeleton--grid,.ui-skeleton--board) .ui-skeleton__line{height:8px;border-radius:4px}.ui-skeleton--table td .ui-skeleton__line{width:70%;margin-block:6px}.ui-skeleton--table td:first-child .ui-skeleton__line{width:85%}.ui-skeleton--table tbody tr:hover{background:none}.ui-skeleton__block{display:block;flex:none;width:40px;height:40px;border-radius:var(--ui-radius-md);background:var(--ui-surface-2)}.ui-skeleton__block--round{border-radius:50%;width:32px;height:32px}.ui-skeleton--list>.ui-list__item{align-items:center}.ui-skeleton--list .ui-list__body{display:grid;gap:12px}.ui-skeleton--list .ui-list__body>.ui-skeleton__line:last-child{width:60%}.ui-skeleton--compact .ui-list__row{gap:12px}.ui-skeleton--compact .ui-list__row>.ui-skeleton__line{flex:1 1 auto;max-width:60%}.ui-skeleton--grid .ui-card__body{display:grid;gap:12px;justify-items:stretch}.ui-skeleton--grid .ui-card__body>.ui-skeleton__line:last-child{width:50%}.ui-skeleton--board .ui-board__list>li{height:72px;border-radius:var(--ui-radius-md);background:var(--ui-surface)}@media (pointer: coarse){.ui-table__sort{min-height:44px;margin-block:-12px}.ui-table__checkbox{min-width:44px;min-height:44px;margin:-12px 0}}@media (pointer: coarse),(max-width: 47.9975em){.ui-table__sort{min-width:44px}}@media (prefers-reduced-motion: reduce){.ui-table--sticky-first :is(th,td):first-child{animation:none}:is(.ui-table-wrap,.ui-index,.ui-list,.ui-cardgrid,.ui-board)[aria-busy=true]>*{transition:none}.ui-board{scroll-behavior:auto}}