@veluai/velu 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.js +11 -0
- package/package.json +52 -0
- package/runtime/velu-ui/base.css +311 -0
- package/runtime/velu-ui/components/Accordion.jsx +64 -0
- package/runtime/velu-ui/components/ApiClient.jsx +121 -0
- package/runtime/velu-ui/components/ApiField.jsx +87 -0
- package/runtime/velu-ui/components/ApiPath.jsx +63 -0
- package/runtime/velu-ui/components/ApiSidebar.jsx +122 -0
- package/runtime/velu-ui/components/AskBar.jsx +71 -0
- package/runtime/velu-ui/components/Callout.jsx +114 -0
- package/runtime/velu-ui/components/Card.jsx +131 -0
- package/runtime/velu-ui/components/Chatbot.jsx +596 -0
- package/runtime/velu-ui/components/CodeBlock.jsx +375 -0
- package/runtime/velu-ui/components/Columns.jsx +56 -0
- package/runtime/velu-ui/components/Field.jsx +81 -0
- package/runtime/velu-ui/components/Image.jsx +163 -0
- package/runtime/velu-ui/components/MethodBadge.jsx +31 -0
- package/runtime/velu-ui/components/NavSelect.jsx +108 -0
- package/runtime/velu-ui/components/PageFeedback.jsx +219 -0
- package/runtime/velu-ui/components/PageFooter.jsx +213 -0
- package/runtime/velu-ui/components/PageHeader.jsx +414 -0
- package/runtime/velu-ui/components/PageNav.jsx +77 -0
- package/runtime/velu-ui/components/PoweredBy.jsx +51 -0
- package/runtime/velu-ui/components/Prompt.jsx +115 -0
- package/runtime/velu-ui/components/Search.jsx +366 -0
- package/runtime/velu-ui/components/Sidebar.jsx +191 -0
- package/runtime/velu-ui/components/Steps.jsx +65 -0
- package/runtime/velu-ui/components/ThemeToggle.jsx +48 -0
- package/runtime/velu-ui/components/Toc.jsx +537 -0
- package/runtime/velu-ui/components/TocBar.jsx +195 -0
- package/runtime/velu-ui/components/Tree.jsx +87 -0
- package/runtime/velu-ui/components/TryItBar.jsx +90 -0
- package/runtime/velu-ui/components/accordion.css +92 -0
- package/runtime/velu-ui/components/api.css +479 -0
- package/runtime/velu-ui/components/ask-bar.css +94 -0
- package/runtime/velu-ui/components/card.css +105 -0
- package/runtime/velu-ui/components/chatbot.css +617 -0
- package/runtime/velu-ui/components/code-block.css +263 -0
- package/runtime/velu-ui/components/docs-layout.css +775 -0
- package/runtime/velu-ui/components/field.css +82 -0
- package/runtime/velu-ui/components/image.css +237 -0
- package/runtime/velu-ui/components/nav-select.css +157 -0
- package/runtime/velu-ui/components/page-feedback.css +241 -0
- package/runtime/velu-ui/components/page-footer.css +130 -0
- package/runtime/velu-ui/components/page-header.css +520 -0
- package/runtime/velu-ui/components/page-nav.css +50 -0
- package/runtime/velu-ui/components/powered-by.css +66 -0
- package/runtime/velu-ui/components/prompt.css +99 -0
- package/runtime/velu-ui/components/search.css +307 -0
- package/runtime/velu-ui/components/sidebar.css +144 -0
- package/runtime/velu-ui/components/steps.css +77 -0
- package/runtime/velu-ui/components/theme-toggle.css +70 -0
- package/runtime/velu-ui/components/toc-bar.css +234 -0
- package/runtime/velu-ui/components/tree.css +49 -0
- package/runtime/velu-ui/index.js +45 -0
- package/runtime/velu-ui/lib/copyText.js +64 -0
- package/runtime/velu-ui/lib/lang-icons.jsx +156 -0
- package/runtime/velu-ui/lib/prism-langs.js +957 -0
- package/runtime/velu-ui/lib/prism-loader.js +74 -0
- package/runtime/velu-ui/lib/resolveIcon.jsx +29 -0
- package/runtime/velu-ui/lib/scrollIntoNearestView.js +66 -0
- package/runtime/velu-ui/mdx-components.jsx +85 -0
- package/runtime/velu-ui/primitives/Cluster.jsx +49 -0
- package/runtime/velu-ui/primitives/Stack.jsx +63 -0
- package/runtime/velu-ui/primitives/Switcher.jsx +57 -0
- package/runtime/velu-ui/primitives/stack.css +3 -0
- package/runtime/velu-ui/primitives/switcher.css +25 -0
- package/runtime/velu-ui/styles.css +43 -0
- package/runtime/velu-ui/tokens.css +4 -0
- package/schema/velu.schema.json +167 -0
- package/src/navigation.js +434 -0
- package/src/runtime/App.jsx +1473 -0
- package/src/runtime/client-entry.jsx +22 -0
- package/src/runtime/server-entry.jsx +16 -0
- package/src/template.html +48 -0
- package/templates/starter/ai-tools/claude-code.mdx +26 -0
- package/templates/starter/ai-tools/cursor.mdx +17 -0
- package/templates/starter/api-reference/endpoint/create.mdx +24 -0
- package/templates/starter/api-reference/endpoint/get.mdx +27 -0
- package/templates/starter/api-reference/introduction.mdx +28 -0
- package/templates/starter/development.mdx +19 -0
- package/templates/starter/essentials/code.mdx +28 -0
- package/templates/starter/essentials/images.mdx +29 -0
- package/templates/starter/essentials/markdown.mdx +25 -0
- package/templates/starter/essentials/navigation.mdx +39 -0
- package/templates/starter/essentials/settings.mdx +30 -0
- package/templates/starter/favicon.svg +6 -0
- package/templates/starter/index.mdx +31 -0
- package/templates/starter/quickstart.mdx +31 -0
- package/templates/starter/velu.json +33 -0
|
@@ -0,0 +1,617 @@
|
|
|
1
|
+
/* Chatbot — the Velu "Ask AI" slide-out panel. Ported from the
|
|
2
|
+
Claude-Design handoff and retokenized: every design literal is mapped
|
|
3
|
+
onto velu-ui's scale, so the panel themes for free via [data-theme].
|
|
4
|
+
crimson → --accent-color
|
|
5
|
+
gray-100/hover → --surface-color
|
|
6
|
+
gray-200/300 → --border-color
|
|
7
|
+
gray-500/600 → --muted-color
|
|
8
|
+
fg-1 (black) → --text-color
|
|
9
|
+
white → --page-bg
|
|
10
|
+
4px spacing → --s-6 … and up the modular scale
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/* ── Panel + slide ──────────────────────────────────────────────────── */
|
|
14
|
+
/* Fixed panel width via `--vchat-width` (overridable, like --card-min);
|
|
15
|
+
capped at 100vw so it can never exceed the viewport. */
|
|
16
|
+
.velu-chatbot {
|
|
17
|
+
/* Comfortable fixed panel width. The panel slides OVER the right
|
|
18
|
+
edge (it's a floating overlay, z-50) so the article doesn't
|
|
19
|
+
reflow when it opens. (Mobile/tablet use a full-width bottom
|
|
20
|
+
sheet — see the @container override below.) */
|
|
21
|
+
--vchat-width: 24rem;
|
|
22
|
+
position: fixed;
|
|
23
|
+
inset-block: 0;
|
|
24
|
+
inset-inline-end: 0;
|
|
25
|
+
z-index: 50;
|
|
26
|
+
inline-size: var(--vchat-width);
|
|
27
|
+
max-inline-size: 100vw;
|
|
28
|
+
display: flex;
|
|
29
|
+
flex-direction: column;
|
|
30
|
+
background: var(--page-bg);
|
|
31
|
+
color: var(--text-color);
|
|
32
|
+
/* Panel edge — match the page header / TocBar / footer hairline
|
|
33
|
+
recipe (--surface-color), not the stronger card/button border
|
|
34
|
+
color. Keeps the chatbot consistent with other surface
|
|
35
|
+
containers in the product. */
|
|
36
|
+
border-inline-start: var(--border-width) solid var(--surface-color);
|
|
37
|
+
font-weight: var(--weight-light);
|
|
38
|
+
/* Closed: fully off the inline-end edge. Open: slid to 0. */
|
|
39
|
+
transform: translateX(100%);
|
|
40
|
+
transition: transform 0.28s cubic-bezier(0.4, 0, 0.2, 1);
|
|
41
|
+
}
|
|
42
|
+
.velu-chatbot--open {
|
|
43
|
+
transform: translateX(0);
|
|
44
|
+
box-shadow:
|
|
45
|
+
0 0 var(--s2) color-mix(in srgb, #000 18%, transparent),
|
|
46
|
+
0 0 var(--s0) color-mix(in srgb, #000 8%, transparent);
|
|
47
|
+
}
|
|
48
|
+
/* base.css applies a global `* { max-width: 66ch }`; reset it so the
|
|
49
|
+
panel's structural elements size to flex/the panel, not 66ch. */
|
|
50
|
+
.velu-chatbot * {
|
|
51
|
+
max-inline-size: none;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/* Drag handle is mobile-only — the @container block below flips it
|
|
55
|
+
on; this default hide keeps the desktop slide-out clean. */
|
|
56
|
+
.velu-chatbot__drag-handle {
|
|
57
|
+
display: none;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/* ── Bottom-sheet variant (tablet + mobile, < 1024px) ─────────────── */
|
|
61
|
+
/* At narrow / mobile widths the side-panel layout doesn't fit — the
|
|
62
|
+
chatbot instead opens as a bottom sheet covering most of the
|
|
63
|
+
viewport. Override the inline anchoring with block-end anchoring,
|
|
64
|
+
full-width sizing, and a translateY transform that slides up from
|
|
65
|
+
the bottom edge. The leading-edge border becomes a top-edge border
|
|
66
|
+
and the sheet picks up top corner rounding so it reads as a
|
|
67
|
+
separate surface lifting out of the viewport bottom. Threshold
|
|
68
|
+
matches the rest of the responsive layout (sidebar collapse,
|
|
69
|
+
right-rail TOC drop, etc.). */
|
|
70
|
+
@container docs (max-width: 1024px) {
|
|
71
|
+
.velu-chatbot {
|
|
72
|
+
inset-inline: 0;
|
|
73
|
+
inset-block-end: 0;
|
|
74
|
+
inset-block-start: auto;
|
|
75
|
+
inline-size: 100vw;
|
|
76
|
+
max-inline-size: 100vw;
|
|
77
|
+
block-size: min(85vh, 40rem);
|
|
78
|
+
transform: translateY(100%);
|
|
79
|
+
border-inline-start: 0;
|
|
80
|
+
border-block-start: var(--border-width) solid var(--surface-color);
|
|
81
|
+
border-start-start-radius: var(--radius-md);
|
|
82
|
+
border-start-end-radius: var(--radius-md);
|
|
83
|
+
/* Make room at the top for the drag-handle pill (the ::before
|
|
84
|
+
below) so it doesn't overlap the existing header content. */
|
|
85
|
+
padding-block-start: var(--s1);
|
|
86
|
+
}
|
|
87
|
+
/* Drag handle — full-width touch-capture strip across the top of
|
|
88
|
+
the sheet. The pill VISUAL is a centered ::before pseudo; the
|
|
89
|
+
strip itself stays invisible but is tall enough to grab. Pointer
|
|
90
|
+
events here drive the drag-to-dismiss gesture (see Chatbot.jsx).
|
|
91
|
+
`touch-action: none` prevents the browser from interpreting the
|
|
92
|
+
vertical drag as a scroll / pull-to-refresh. */
|
|
93
|
+
.velu-chatbot__drag-handle {
|
|
94
|
+
display: block;
|
|
95
|
+
position: absolute;
|
|
96
|
+
inset-block-start: 0;
|
|
97
|
+
inset-inline: 0;
|
|
98
|
+
block-size: var(--s1);
|
|
99
|
+
touch-action: none;
|
|
100
|
+
cursor: grab;
|
|
101
|
+
z-index: 10;
|
|
102
|
+
}
|
|
103
|
+
.velu-chatbot__drag-handle::before {
|
|
104
|
+
content: '';
|
|
105
|
+
position: absolute;
|
|
106
|
+
inset-block-start: var(--s-3);
|
|
107
|
+
inset-inline-start: 50%;
|
|
108
|
+
inline-size: var(--s2);
|
|
109
|
+
block-size: var(--s-5);
|
|
110
|
+
background: var(--border-color);
|
|
111
|
+
border-radius: 999px;
|
|
112
|
+
transform: translateX(-50%);
|
|
113
|
+
pointer-events: none;
|
|
114
|
+
}
|
|
115
|
+
.velu-chatbot__drag-handle:active {
|
|
116
|
+
cursor: grabbing;
|
|
117
|
+
}
|
|
118
|
+
.velu-chatbot--open {
|
|
119
|
+
transform: translateY(0);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/* ── Header ─────────────────────────────────────────────────────────── */
|
|
124
|
+
/* Layout (flex/gap/justify) comes from <Cluster>; this owns chrome. */
|
|
125
|
+
.velu-chatbot__header {
|
|
126
|
+
flex: none;
|
|
127
|
+
padding: var(--s-2) var(--s-1);
|
|
128
|
+
/* Section divider — --surface-color hairline like the page
|
|
129
|
+
header's own bottom border, not the stronger --border-color. */
|
|
130
|
+
border-block-end: var(--border-width) solid var(--surface-color);
|
|
131
|
+
background: var(--page-bg);
|
|
132
|
+
}
|
|
133
|
+
.velu-chatbot__mark {
|
|
134
|
+
flex: none;
|
|
135
|
+
color: var(--accent-color);
|
|
136
|
+
}
|
|
137
|
+
.velu-chatbot__brand {
|
|
138
|
+
display: inline-flex;
|
|
139
|
+
align-items: baseline;
|
|
140
|
+
gap: var(--s-5);
|
|
141
|
+
}
|
|
142
|
+
.velu-chatbot__brand-name {
|
|
143
|
+
font-size: var(--f-h5);
|
|
144
|
+
font-weight: var(--weight-light);
|
|
145
|
+
color: var(--text-color);
|
|
146
|
+
}
|
|
147
|
+
.velu-chatbot__brand-sep {
|
|
148
|
+
color: var(--muted-color);
|
|
149
|
+
}
|
|
150
|
+
.velu-chatbot__brand-title {
|
|
151
|
+
font-size: var(--f-h6);
|
|
152
|
+
font-weight: var(--weight-medium);
|
|
153
|
+
color: var(--muted-color);
|
|
154
|
+
}
|
|
155
|
+
.velu-chatbot__iconbtn {
|
|
156
|
+
flex: none;
|
|
157
|
+
display: inline-flex;
|
|
158
|
+
align-items: center;
|
|
159
|
+
justify-content: center;
|
|
160
|
+
inline-size: 1.75em;
|
|
161
|
+
block-size: 1.75em;
|
|
162
|
+
padding: 0;
|
|
163
|
+
background: transparent;
|
|
164
|
+
border: 0;
|
|
165
|
+
border-radius: var(--radius-sm);
|
|
166
|
+
color: var(--muted-color);
|
|
167
|
+
cursor: pointer;
|
|
168
|
+
transition: background 0.12s ease, color 0.12s ease;
|
|
169
|
+
}
|
|
170
|
+
.velu-chatbot__iconbtn:hover {
|
|
171
|
+
background: var(--surface-color);
|
|
172
|
+
color: var(--text-color);
|
|
173
|
+
}
|
|
174
|
+
.velu-chatbot__iconbtn.is-active {
|
|
175
|
+
background: color-mix(in srgb, var(--accent-color) 12%, transparent);
|
|
176
|
+
color: var(--accent-color);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/* Shared eyebrow label (Suggested / Sources / Follow up / Recent chats) */
|
|
180
|
+
.velu-chatbot__eyebrow {
|
|
181
|
+
font-size: var(--f-h7);
|
|
182
|
+
font-weight: var(--weight-medium);
|
|
183
|
+
letter-spacing: 0.04em;
|
|
184
|
+
text-transform: uppercase;
|
|
185
|
+
color: var(--muted-color);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/* ── History overlay ────────────────────────────────────────────────── */
|
|
189
|
+
.velu-chatbot__history {
|
|
190
|
+
position: absolute;
|
|
191
|
+
inset: 0;
|
|
192
|
+
z-index: 5;
|
|
193
|
+
display: flex;
|
|
194
|
+
flex-direction: column;
|
|
195
|
+
background: var(--page-bg);
|
|
196
|
+
/* Inherit the chatbot's corner radii — at desktop this is 0 (no
|
|
197
|
+
change); at mobile the parent has top-start / top-end rounded,
|
|
198
|
+
so the history overlay picks them up too rather than painting
|
|
199
|
+
square corners over the parent's curves. */
|
|
200
|
+
border-radius: inherit;
|
|
201
|
+
}
|
|
202
|
+
.velu-chatbot__history-head {
|
|
203
|
+
flex: none;
|
|
204
|
+
padding: var(--s-2) var(--s-1);
|
|
205
|
+
/* Same hairline recipe as the main chatbot header. */
|
|
206
|
+
border-block-end: var(--border-width) solid var(--surface-color);
|
|
207
|
+
}
|
|
208
|
+
.velu-chatbot__history-list {
|
|
209
|
+
flex: 1 1 auto;
|
|
210
|
+
overflow-y: auto;
|
|
211
|
+
padding: var(--s-3);
|
|
212
|
+
}
|
|
213
|
+
.velu-chatbot__history-item {
|
|
214
|
+
display: flex;
|
|
215
|
+
flex-direction: column;
|
|
216
|
+
align-items: flex-start;
|
|
217
|
+
gap: var(--s-6);
|
|
218
|
+
padding: var(--s-3) var(--s-2);
|
|
219
|
+
background: transparent;
|
|
220
|
+
border: 0;
|
|
221
|
+
border-radius: var(--radius-sm);
|
|
222
|
+
text-align: start;
|
|
223
|
+
font: inherit;
|
|
224
|
+
cursor: pointer;
|
|
225
|
+
transition: background 0.12s ease;
|
|
226
|
+
}
|
|
227
|
+
.velu-chatbot__history-item:hover {
|
|
228
|
+
background: var(--surface-color);
|
|
229
|
+
}
|
|
230
|
+
.velu-chatbot__history-item-title {
|
|
231
|
+
font-size: var(--f-h6);
|
|
232
|
+
font-weight: var(--weight-normal);
|
|
233
|
+
color: var(--text-color);
|
|
234
|
+
}
|
|
235
|
+
.velu-chatbot__history-item-when {
|
|
236
|
+
font-size: var(--f-h6);
|
|
237
|
+
font-weight: var(--weight-light);
|
|
238
|
+
color: var(--muted-color);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/* ── Body ───────────────────────────────────────────────────────────── */
|
|
242
|
+
.velu-chatbot__body {
|
|
243
|
+
flex: 1 1 auto;
|
|
244
|
+
overflow-y: auto;
|
|
245
|
+
padding: var(--s0) var(--s-1) var(--s-3);
|
|
246
|
+
scroll-behavior: smooth;
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
/* ── Welcome / suggestions ──────────────────────────────────────────── */
|
|
250
|
+
.velu-chatbot__welcome-hi {
|
|
251
|
+
margin: 0;
|
|
252
|
+
font-size: var(--f-h4);
|
|
253
|
+
font-weight: var(--weight-medium);
|
|
254
|
+
line-height: var(--lh-h4);
|
|
255
|
+
color: var(--text-color);
|
|
256
|
+
}
|
|
257
|
+
.velu-chatbot__suggest {
|
|
258
|
+
display: flex;
|
|
259
|
+
align-items: center;
|
|
260
|
+
justify-content: space-between;
|
|
261
|
+
gap: var(--s-2);
|
|
262
|
+
padding: var(--s-2) var(--s-1);
|
|
263
|
+
background: var(--page-bg);
|
|
264
|
+
border: var(--border-width) solid var(--border-color);
|
|
265
|
+
border-radius: var(--radius-sm);
|
|
266
|
+
font: inherit;
|
|
267
|
+
font-size: var(--f-h6);
|
|
268
|
+
font-weight: var(--weight-light);
|
|
269
|
+
line-height: var(--lh-h6);
|
|
270
|
+
color: var(--text-color);
|
|
271
|
+
text-align: start;
|
|
272
|
+
cursor: pointer;
|
|
273
|
+
transition: border-color 0.12s ease, background 0.12s ease;
|
|
274
|
+
}
|
|
275
|
+
.velu-chatbot__suggest:hover {
|
|
276
|
+
border-color: var(--accent-color);
|
|
277
|
+
background: color-mix(in srgb, var(--accent-color) 6%, transparent);
|
|
278
|
+
}
|
|
279
|
+
.velu-chatbot__suggest svg {
|
|
280
|
+
flex: none;
|
|
281
|
+
color: var(--muted-color);
|
|
282
|
+
}
|
|
283
|
+
.velu-chatbot__suggest:hover svg {
|
|
284
|
+
color: var(--accent-color);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
/* ── Messages ───────────────────────────────────────────────────────── */
|
|
288
|
+
.velu-chatbot__msg {
|
|
289
|
+
display: flex;
|
|
290
|
+
flex-direction: column;
|
|
291
|
+
gap: var(--s-3);
|
|
292
|
+
}
|
|
293
|
+
.velu-chatbot__msg--user {
|
|
294
|
+
align-items: flex-end;
|
|
295
|
+
}
|
|
296
|
+
.velu-chatbot__bubble {
|
|
297
|
+
max-inline-size: 84%;
|
|
298
|
+
padding: var(--s-3) var(--s-1);
|
|
299
|
+
background: var(--surface-color);
|
|
300
|
+
color: var(--text-color);
|
|
301
|
+
border-radius: var(--radius-md) var(--radius-md) var(--radius-sm)
|
|
302
|
+
var(--radius-md);
|
|
303
|
+
font-size: var(--f-h6);
|
|
304
|
+
line-height: var(--lh-body);
|
|
305
|
+
}
|
|
306
|
+
.velu-chatbot__role {
|
|
307
|
+
font-size: var(--f-h6);
|
|
308
|
+
font-weight: var(--weight-medium);
|
|
309
|
+
letter-spacing: 0.04em;
|
|
310
|
+
text-transform: uppercase;
|
|
311
|
+
color: var(--muted-color);
|
|
312
|
+
}
|
|
313
|
+
.velu-chatbot__role svg {
|
|
314
|
+
flex: none;
|
|
315
|
+
color: var(--accent-color);
|
|
316
|
+
}
|
|
317
|
+
.velu-chatbot__role.is-thinking {
|
|
318
|
+
color: var(--accent-color);
|
|
319
|
+
}
|
|
320
|
+
/* Shimmer sweep on the "Velu is thinking" label. */
|
|
321
|
+
.velu-chatbot__role.is-thinking span {
|
|
322
|
+
background: linear-gradient(
|
|
323
|
+
90deg,
|
|
324
|
+
var(--muted-color) 0%,
|
|
325
|
+
var(--muted-color) 35%,
|
|
326
|
+
var(--accent-color) 50%,
|
|
327
|
+
var(--muted-color) 65%,
|
|
328
|
+
var(--muted-color) 100%
|
|
329
|
+
);
|
|
330
|
+
background-size: 200% 100%;
|
|
331
|
+
-webkit-background-clip: text;
|
|
332
|
+
background-clip: text;
|
|
333
|
+
-webkit-text-fill-color: transparent;
|
|
334
|
+
animation: velu-chatbot-shimmer 1.8s linear infinite;
|
|
335
|
+
}
|
|
336
|
+
@keyframes velu-chatbot-shimmer {
|
|
337
|
+
0% { background-position: 100% 0; }
|
|
338
|
+
100% { background-position: -100% 0; }
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
/* "Thinking" loader — 3x3 squares, opacity wave along the anti-diagonal. */
|
|
342
|
+
.velu-chatbot__wave {
|
|
343
|
+
display: block;
|
|
344
|
+
flex: none;
|
|
345
|
+
inline-size: 1em;
|
|
346
|
+
block-size: 1em;
|
|
347
|
+
}
|
|
348
|
+
.velu-chatbot__wave rect {
|
|
349
|
+
fill: var(--accent-color);
|
|
350
|
+
animation: velu-chatbot-wave 1.3s ease-in-out infinite;
|
|
351
|
+
}
|
|
352
|
+
.velu-chatbot__wave rect[data-cell="0"] { animation-delay: 0s; }
|
|
353
|
+
.velu-chatbot__wave rect[data-cell="1"] { animation-delay: 0.1s; }
|
|
354
|
+
.velu-chatbot__wave rect[data-cell="2"] { animation-delay: 0.2s; }
|
|
355
|
+
.velu-chatbot__wave rect[data-cell="3"] { animation-delay: 0.3s; }
|
|
356
|
+
.velu-chatbot__wave rect[data-cell="4"] { animation-delay: 0.4s; }
|
|
357
|
+
@keyframes velu-chatbot-wave {
|
|
358
|
+
0%, 60%, 100% { opacity: 0.2; }
|
|
359
|
+
30% { opacity: 1; }
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
/* ── AI answer body ─────────────────────────────────────────────────── */
|
|
363
|
+
.velu-chatbot__answer {
|
|
364
|
+
font-size: var(--f-h6);
|
|
365
|
+
line-height: var(--lh-body);
|
|
366
|
+
color: var(--text-color);
|
|
367
|
+
}
|
|
368
|
+
.velu-chatbot__answer p {
|
|
369
|
+
margin: 0 0 var(--s-3);
|
|
370
|
+
}
|
|
371
|
+
.velu-chatbot__answer p:last-child {
|
|
372
|
+
margin-block-end: 0;
|
|
373
|
+
}
|
|
374
|
+
.velu-chatbot__answer code {
|
|
375
|
+
font-family: var(--font-mono);
|
|
376
|
+
font-size: var(--f-h7);
|
|
377
|
+
padding: 0 var(--s-5);
|
|
378
|
+
background: var(--surface-color);
|
|
379
|
+
border: var(--border-width) solid var(--border-color);
|
|
380
|
+
border-radius: var(--radius-sm);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/* Inline citation chip */
|
|
384
|
+
.velu-chatbot__cite {
|
|
385
|
+
display: inline-flex;
|
|
386
|
+
align-items: center;
|
|
387
|
+
justify-content: center;
|
|
388
|
+
min-inline-size: 1.5em;
|
|
389
|
+
block-size: 1.5em;
|
|
390
|
+
padding: 0 var(--s-5);
|
|
391
|
+
font-family: var(--font-mono);
|
|
392
|
+
font-size: var(--f-h7);
|
|
393
|
+
font-weight: var(--weight-medium);
|
|
394
|
+
color: var(--accent-color);
|
|
395
|
+
background: color-mix(in srgb, var(--accent-color) 14%, transparent);
|
|
396
|
+
border: var(--border-width) solid transparent;
|
|
397
|
+
border-radius: var(--radius-sm);
|
|
398
|
+
text-decoration: none;
|
|
399
|
+
cursor: pointer;
|
|
400
|
+
transition: background 0.12s ease, border-color 0.12s ease;
|
|
401
|
+
}
|
|
402
|
+
.velu-chatbot__cite:hover {
|
|
403
|
+
background: var(--page-bg);
|
|
404
|
+
border-color: var(--accent-color);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/* Streaming caret */
|
|
408
|
+
.velu-chatbot__caret {
|
|
409
|
+
display: inline-block;
|
|
410
|
+
inline-size: var(--s-4);
|
|
411
|
+
block-size: 1em;
|
|
412
|
+
vertical-align: text-bottom;
|
|
413
|
+
background: var(--accent-color);
|
|
414
|
+
animation: velu-chatbot-caret 0.9s steps(2) infinite;
|
|
415
|
+
}
|
|
416
|
+
@keyframes velu-chatbot-caret {
|
|
417
|
+
50% { opacity: 0; }
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/* Sources card list */
|
|
421
|
+
.velu-chatbot__sources {
|
|
422
|
+
margin-block-start: var(--s-2);
|
|
423
|
+
}
|
|
424
|
+
.velu-chatbot__source {
|
|
425
|
+
display: flex;
|
|
426
|
+
align-items: flex-start;
|
|
427
|
+
gap: var(--s-2);
|
|
428
|
+
padding: var(--s-3) var(--s-2);
|
|
429
|
+
background: var(--page-bg);
|
|
430
|
+
border: var(--border-width) solid var(--border-color);
|
|
431
|
+
border-radius: var(--radius-sm);
|
|
432
|
+
text-decoration: none;
|
|
433
|
+
color: inherit;
|
|
434
|
+
transition: border-color 0.12s ease;
|
|
435
|
+
}
|
|
436
|
+
.velu-chatbot__source:hover {
|
|
437
|
+
border-color: var(--accent-color);
|
|
438
|
+
}
|
|
439
|
+
.velu-chatbot__source-num {
|
|
440
|
+
flex: none;
|
|
441
|
+
display: inline-flex;
|
|
442
|
+
align-items: center;
|
|
443
|
+
justify-content: center;
|
|
444
|
+
inline-size: 1.5em;
|
|
445
|
+
block-size: 1.5em;
|
|
446
|
+
font-family: var(--font-mono);
|
|
447
|
+
font-size: var(--f-h7);
|
|
448
|
+
font-weight: var(--weight-medium);
|
|
449
|
+
color: var(--accent-color);
|
|
450
|
+
background: color-mix(in srgb, var(--accent-color) 14%, transparent);
|
|
451
|
+
border-radius: var(--radius-sm);
|
|
452
|
+
}
|
|
453
|
+
.velu-chatbot__source-meta {
|
|
454
|
+
display: flex;
|
|
455
|
+
flex-direction: column;
|
|
456
|
+
gap: var(--s-6);
|
|
457
|
+
min-inline-size: 0;
|
|
458
|
+
}
|
|
459
|
+
.velu-chatbot__source-title {
|
|
460
|
+
font-size: var(--f-h6);
|
|
461
|
+
font-weight: var(--weight-medium);
|
|
462
|
+
color: var(--text-color);
|
|
463
|
+
}
|
|
464
|
+
.velu-chatbot__source-path {
|
|
465
|
+
font-family: var(--font-mono);
|
|
466
|
+
font-size: var(--f-h7);
|
|
467
|
+
color: var(--muted-color);
|
|
468
|
+
white-space: nowrap;
|
|
469
|
+
overflow: hidden;
|
|
470
|
+
text-overflow: ellipsis;
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/* Follow-ups */
|
|
474
|
+
.velu-chatbot__followups {
|
|
475
|
+
margin-block-start: var(--s-1);
|
|
476
|
+
}
|
|
477
|
+
.velu-chatbot__followup {
|
|
478
|
+
display: flex;
|
|
479
|
+
align-items: center;
|
|
480
|
+
justify-content: space-between;
|
|
481
|
+
gap: var(--s-2);
|
|
482
|
+
padding: var(--s-3) var(--s-2);
|
|
483
|
+
background: transparent;
|
|
484
|
+
border: var(--border-width) solid var(--border-color);
|
|
485
|
+
border-radius: var(--radius-sm);
|
|
486
|
+
font: inherit;
|
|
487
|
+
font-size: var(--f-h6);
|
|
488
|
+
font-weight: var(--weight-light);
|
|
489
|
+
color: var(--text-color);
|
|
490
|
+
text-align: start;
|
|
491
|
+
cursor: pointer;
|
|
492
|
+
transition: border-color 0.12s ease, color 0.12s ease;
|
|
493
|
+
}
|
|
494
|
+
.velu-chatbot__followup:hover {
|
|
495
|
+
border-color: var(--accent-color);
|
|
496
|
+
color: var(--accent-color);
|
|
497
|
+
}
|
|
498
|
+
.velu-chatbot__followup svg {
|
|
499
|
+
flex: none;
|
|
500
|
+
}
|
|
501
|
+
|
|
502
|
+
/* Message hover actions */
|
|
503
|
+
.velu-chatbot__msg-actions {
|
|
504
|
+
margin-inline-start: calc(var(--s-3) * -1);
|
|
505
|
+
opacity: 0;
|
|
506
|
+
transition: opacity 0.12s ease;
|
|
507
|
+
}
|
|
508
|
+
.velu-chatbot__msg--ai:hover .velu-chatbot__msg-actions {
|
|
509
|
+
opacity: 1;
|
|
510
|
+
}
|
|
511
|
+
.velu-chatbot__msg-action {
|
|
512
|
+
display: inline-flex;
|
|
513
|
+
align-items: center;
|
|
514
|
+
justify-content: center;
|
|
515
|
+
inline-size: 1.625em;
|
|
516
|
+
block-size: 1.625em;
|
|
517
|
+
padding: 0;
|
|
518
|
+
background: transparent;
|
|
519
|
+
border: 0;
|
|
520
|
+
border-radius: var(--radius-sm);
|
|
521
|
+
color: var(--muted-color);
|
|
522
|
+
cursor: pointer;
|
|
523
|
+
}
|
|
524
|
+
.velu-chatbot__msg-action:hover {
|
|
525
|
+
background: var(--surface-color);
|
|
526
|
+
color: var(--text-color);
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
/* ── Composer ───────────────────────────────────────────────────────── */
|
|
530
|
+
.velu-chatbot__composer {
|
|
531
|
+
flex: none;
|
|
532
|
+
padding: var(--s-1);
|
|
533
|
+
background: var(--page-bg);
|
|
534
|
+
/* Section divider — --surface-color hairline matching the
|
|
535
|
+
chatbot's other structural section borders. The input field
|
|
536
|
+
INSIDE the composer keeps its --border-color (it's an
|
|
537
|
+
interactive element, not a section divider). */
|
|
538
|
+
border-block-start: var(--border-width) solid var(--surface-color);
|
|
539
|
+
}
|
|
540
|
+
.velu-chatbot__input-wrap {
|
|
541
|
+
display: flex;
|
|
542
|
+
align-items: flex-end;
|
|
543
|
+
gap: var(--s-3);
|
|
544
|
+
padding: var(--s-3);
|
|
545
|
+
background: var(--page-bg);
|
|
546
|
+
border: var(--border-width) solid var(--border-color);
|
|
547
|
+
border-radius: var(--radius-sm);
|
|
548
|
+
transition: border-color 0.12s ease, box-shadow 0.12s ease;
|
|
549
|
+
}
|
|
550
|
+
.velu-chatbot__input-wrap:focus-within {
|
|
551
|
+
border-color: var(--accent-color);
|
|
552
|
+
box-shadow: 0 0 0 var(--border-width) var(--accent-color);
|
|
553
|
+
}
|
|
554
|
+
.velu-chatbot__input {
|
|
555
|
+
flex: 1 1 auto;
|
|
556
|
+
min-inline-size: 0;
|
|
557
|
+
/* ~4 lines of body leading before the textarea starts scrolling. */
|
|
558
|
+
max-block-size: calc(1em * var(--lh-body) * 4);
|
|
559
|
+
padding: 0;
|
|
560
|
+
border: 0;
|
|
561
|
+
outline: none;
|
|
562
|
+
resize: none;
|
|
563
|
+
background: transparent;
|
|
564
|
+
font: inherit;
|
|
565
|
+
font-size: var(--f-h6);
|
|
566
|
+
font-weight: var(--weight-light);
|
|
567
|
+
line-height: var(--lh-body);
|
|
568
|
+
color: var(--text-color);
|
|
569
|
+
}
|
|
570
|
+
.velu-chatbot__input::placeholder {
|
|
571
|
+
color: var(--muted-color);
|
|
572
|
+
}
|
|
573
|
+
.velu-chatbot__send {
|
|
574
|
+
flex: none;
|
|
575
|
+
display: inline-flex;
|
|
576
|
+
align-items: center;
|
|
577
|
+
justify-content: center;
|
|
578
|
+
inline-size: 1.75em;
|
|
579
|
+
block-size: 1.75em;
|
|
580
|
+
padding: 0;
|
|
581
|
+
border: 0;
|
|
582
|
+
border-radius: var(--radius-sm);
|
|
583
|
+
background: var(--surface-color);
|
|
584
|
+
color: var(--muted-color);
|
|
585
|
+
cursor: pointer;
|
|
586
|
+
transition: background 0.12s ease, color 0.12s ease;
|
|
587
|
+
}
|
|
588
|
+
.velu-chatbot__send.is-active {
|
|
589
|
+
background: var(--accent-color);
|
|
590
|
+
color: #fff;
|
|
591
|
+
}
|
|
592
|
+
.velu-chatbot__send:disabled {
|
|
593
|
+
cursor: not-allowed;
|
|
594
|
+
}
|
|
595
|
+
.velu-chatbot__foot {
|
|
596
|
+
margin-block-start: var(--s-3);
|
|
597
|
+
padding-inline: var(--s-5);
|
|
598
|
+
font-size: var(--f-h6);
|
|
599
|
+
font-weight: var(--weight-light);
|
|
600
|
+
color: var(--muted-color);
|
|
601
|
+
}
|
|
602
|
+
.velu-chatbot__foot kbd {
|
|
603
|
+
font-family: var(--font-mono);
|
|
604
|
+
font-size: var(--f-h7);
|
|
605
|
+
padding: 0 var(--s-5);
|
|
606
|
+
background: var(--page-bg);
|
|
607
|
+
border: var(--border-width) solid var(--border-color);
|
|
608
|
+
border-radius: var(--radius-sm);
|
|
609
|
+
color: var(--muted-color);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
@media (prefers-reduced-motion: reduce) {
|
|
613
|
+
.velu-chatbot { transition: none; }
|
|
614
|
+
.velu-chatbot__wave rect,
|
|
615
|
+
.velu-chatbot__role.is-thinking span,
|
|
616
|
+
.velu-chatbot__caret { animation: none; }
|
|
617
|
+
}
|