@automattic/agenttic-ui 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/README.md ADDED
@@ -0,0 +1,488 @@
1
+ # @automattic/agenttic-ui
2
+
3
+ React UI components for AI agent chat interfaces. A pure UI layer designed to work seamlessly with `@automattic/agenttic-client` hooks or any agent communication system.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @automattic/agenttic-ui
9
+ ```
10
+
11
+ ## Key Features
12
+
13
+ - Pure UI components with no agent communication logic
14
+ - Floating and embedded chat variants
15
+ - Smooth animations and drag-and-drop positioning
16
+ - Message actions and markdown rendering
17
+ - TypeScript support with comprehensive types
18
+ - Storybook component documentation
19
+ - Modular component architecture for custom layouts
20
+
21
+ ## Quick Start
22
+
23
+ ### Complete Chat Interface
24
+
25
+ ```tsx
26
+ import { useAgentChat } from '@automattic/agenttic-client';
27
+ import { AgentUI } from '@automattic/agenttic-ui';
28
+
29
+ function ChatApplication() {
30
+ const {
31
+ messages,
32
+ isProcessing,
33
+ error,
34
+ onSubmit,
35
+ suggestions,
36
+ clearSuggestions,
37
+ messageRenderer
38
+ } = useAgentChat({
39
+ agentId: 'big-sky',
40
+ sessionId: 'my-session'
41
+ });
42
+
43
+ return (
44
+ <AgentUI
45
+ messages={messages}
46
+ isProcessing={isProcessing}
47
+ error={error}
48
+ onSubmit={onSubmit}
49
+ suggestions={suggestions}
50
+ clearSuggestions={clearSuggestions}
51
+ messageRenderer={messageRenderer}
52
+ variant="floating"
53
+ placeholder="Ask me anything..."
54
+ />
55
+ );
56
+ }
57
+ ```
58
+
59
+ ### Embedded Chat
60
+
61
+ ```tsx
62
+ <AgentUI
63
+ messages={messages}
64
+ isProcessing={isProcessing}
65
+ error={error}
66
+ onSubmit={onSubmit}
67
+ variant="embedded"
68
+ placeholder="How can I help you?"
69
+ />
70
+ ```
71
+
72
+ ## Core Components
73
+
74
+ ### AgentUI
75
+
76
+ The main component that provides a complete chat interface.
77
+
78
+ ```tsx
79
+ interface AgentUIProps {
80
+ // Core chat data
81
+ messages: Message[];
82
+ isProcessing: boolean;
83
+ error?: string | null;
84
+ onSubmit: (message: string) => void;
85
+
86
+ // UI configuration
87
+ variant?: 'floating' | 'embedded';
88
+ placeholder?: string;
89
+ triggerIcon?: React.ReactNode;
90
+ notice?: NoticeConfig;
91
+ emptyView?: React.ReactNode;
92
+
93
+ // Chat state management (floating variant)
94
+ floatingChatState?: ChatState;
95
+ onOpen?: () => void;
96
+ onExpand?: () => void;
97
+ onClose?: () => void;
98
+
99
+ // Suggestions
100
+ suggestions?: Suggestion[];
101
+ clearSuggestions?: () => void;
102
+
103
+ // Message rendering
104
+ messageRenderer?: ComponentType<{ children: string }>;
105
+
106
+ // Styling
107
+ className?: string;
108
+ style?: React.CSSProperties;
109
+ }
110
+ ```
111
+
112
+ **Variants:**
113
+ - `floating` - Draggable chat widget with collapsed/compact/expanded states
114
+ - `embedded` - Fixed chat interface for integration in existing layouts
115
+
116
+ ### Individual Components
117
+
118
+ For custom chat layouts, use individual components:
119
+
120
+ ```tsx
121
+ import {
122
+ Chat,
123
+ Messages,
124
+ Message,
125
+ ChatInput,
126
+ Suggestions
127
+ } from '@automattic/agenttic-ui';
128
+
129
+ function CustomChat() {
130
+ return (
131
+ <div className="my-chat-container">
132
+ <Messages messages={messages} messageRenderer={messageRenderer} />
133
+ <Suggestions
134
+ suggestions={suggestions}
135
+ onSuggestionClick={onSubmit}
136
+ onClear={clearSuggestions}
137
+ />
138
+ <ChatInput
139
+ value={inputValue}
140
+ onChange={setInputValue}
141
+ onSubmit={onSubmit}
142
+ placeholder="Type a message..."
143
+ isProcessing={isProcessing}
144
+ />
145
+ </div>
146
+ );
147
+ }
148
+ ```
149
+
150
+ ## Component APIs
151
+
152
+ ### Chat
153
+
154
+ Main chat component supporting both floating and embedded variants.
155
+
156
+ ```tsx
157
+ <Chat
158
+ messages={messages}
159
+ isProcessing={isProcessing}
160
+ error={error}
161
+ onSubmit={onSubmit}
162
+ variant="floating"
163
+ placeholder="Ask anything..."
164
+ suggestions={suggestions}
165
+ clearSuggestions={clearSuggestions}
166
+ messageRenderer={messageRenderer}
167
+ />
168
+ ```
169
+
170
+ ### Messages
171
+
172
+ Container for displaying message history.
173
+
174
+ ```tsx
175
+ <Messages
176
+ messages={messages}
177
+ messageRenderer={messageRenderer}
178
+ emptyView={<div>No messages yet</div>}
179
+ />
180
+ ```
181
+
182
+ ### Message
183
+
184
+ Individual message component with action support.
185
+
186
+ ```tsx
187
+ <Message
188
+ message={message}
189
+ messageRenderer={messageRenderer}
190
+ showIcon={true}
191
+ />
192
+ ```
193
+
194
+ ### ChatInput
195
+
196
+ Text input with auto-resize and submit handling.
197
+
198
+ ```tsx
199
+ <ChatInput
200
+ value={value}
201
+ onChange={setValue}
202
+ onSubmit={handleSubmit}
203
+ onKeyDown={handleKeyDown}
204
+ placeholder="Type a message..."
205
+ isProcessing={false}
206
+ textareaRef={textareaRef}
207
+ />
208
+ ```
209
+
210
+ ### Suggestions
211
+
212
+ Quick action suggestions for users.
213
+
214
+ ```tsx
215
+ <Suggestions
216
+ suggestions={[
217
+ { id: '1', label: 'Help me code', prompt: 'Can you help me write code?' },
218
+ { id: '2', label: 'Explain concept', prompt: 'Explain this concept to me' }
219
+ ]}
220
+ onSuggestionClick={onSubmit}
221
+ onClear={clearSuggestions}
222
+ />
223
+ ```
224
+
225
+ ## Hooks
226
+
227
+ ### useChat
228
+
229
+ Manages chat state for floating variant.
230
+
231
+ ```tsx
232
+ const {
233
+ state, // 'collapsed' | 'compact' | 'expanded'
234
+ setState,
235
+ isOpen, // boolean
236
+ open, // () => void
237
+ close, // () => void
238
+ toggle // () => void
239
+ } = useChat(initialState);
240
+ ```
241
+
242
+ ### useInput
243
+
244
+ Manages text input state with auto-resize and keyboard handling.
245
+
246
+ ```tsx
247
+ const {
248
+ value,
249
+ setValue,
250
+ clear,
251
+ textareaRef,
252
+ handleKeyDown,
253
+ adjustHeight
254
+ } = useInput({
255
+ value: inputValue,
256
+ setValue: setInputValue,
257
+ onSubmit: handleSubmit,
258
+ isProcessing: false
259
+ });
260
+ ```
261
+
262
+ ## Icons
263
+
264
+ Pre-built icon components for consistent UI:
265
+
266
+ ```tsx
267
+ import {
268
+ ThumbsUpIcon,
269
+ ThumbsDownIcon,
270
+ CopyIcon,
271
+ StopIcon,
272
+ ArrowUpIcon,
273
+ XIcon,
274
+ BigSkyIcon,
275
+ StylesIcon
276
+ } from '@automattic/agenttic-ui';
277
+ ```
278
+
279
+ ## Type Definitions
280
+
281
+ ```tsx
282
+ interface Message {
283
+ id: string;
284
+ role: 'user' | 'agent';
285
+ content: Array<{
286
+ type: 'text' | 'image_url' | 'component';
287
+ text?: string;
288
+ image_url?: string;
289
+ component?: React.ComponentType;
290
+ componentProps?: any;
291
+ }>;
292
+ timestamp: number;
293
+ archived: boolean;
294
+ showIcon: boolean;
295
+ icon?: string;
296
+ actions?: MessageAction[];
297
+ }
298
+
299
+ interface MessageAction {
300
+ id: string;
301
+ icon: React.ReactNode;
302
+ label: string;
303
+ onClick: (message: Message) => void | Promise<void>;
304
+ tooltip?: string;
305
+ disabled?: boolean;
306
+ }
307
+
308
+ interface Suggestion {
309
+ id: string;
310
+ label: string;
311
+ prompt: string;
312
+ }
313
+
314
+ interface NoticeConfig {
315
+ icon?: React.ReactNode;
316
+ message: string;
317
+ action?: {
318
+ label: string;
319
+ onClick: () => void;
320
+ };
321
+ dismissible?: boolean;
322
+ onDismiss?: () => void;
323
+ }
324
+
325
+ type ChatState = 'collapsed' | 'compact' | 'expanded';
326
+ ```
327
+
328
+ ## Styling
329
+
330
+ ### CSS Import
331
+
332
+ Components automatically import their styles. For manual control:
333
+
334
+ ```css
335
+ /* In your CSS */
336
+ @import '@automattic/agenttic-ui/index.css';
337
+ ```
338
+
339
+ ```tsx
340
+ // In JavaScript/TypeScript
341
+ import '@automattic/agenttic-ui/index.css';
342
+ ```
343
+
344
+ ### Customization
345
+
346
+ Components use CSS Modules with design tokens. Override styles using CSS custom properties:
347
+
348
+ ```css
349
+ :root {
350
+ --agenttic-primary-color: #your-brand-color;
351
+ --agenttic-border-radius: 8px;
352
+ --agenttic-spacing-unit: 16px;
353
+ }
354
+ ```
355
+
356
+ ## Advanced Usage
357
+
358
+ ### Custom Message Renderer
359
+
360
+ Provide a custom markdown renderer:
361
+
362
+ ```tsx
363
+ import { ReactMarkdown } from 'react-markdown';
364
+
365
+ const customRenderer = ({ children }: { children: string }) => (
366
+ <ReactMarkdown
367
+ remarkPlugins={[remarkGfm]}
368
+ components={{
369
+ code: ({ children }) => <code className="custom-code">{children}</code>
370
+ }}
371
+ >
372
+ {children}
373
+ </ReactMarkdown>
374
+ );
375
+
376
+ <AgentUI
377
+ messages={messages}
378
+ messageRenderer={customRenderer}
379
+ // ... other props
380
+ />
381
+ ```
382
+
383
+ ### Message Actions
384
+
385
+ Messages can include interactive actions:
386
+
387
+ ```tsx
388
+ const messagesWithActions = messages.map(message => ({
389
+ ...message,
390
+ actions: message.role === 'agent' ? [
391
+ {
392
+ id: 'copy',
393
+ icon: <CopyIcon />,
394
+ label: 'Copy',
395
+ onClick: () => navigator.clipboard.writeText(message.content[0].text)
396
+ },
397
+ {
398
+ id: 'feedback',
399
+ icon: <ThumbsUpIcon />,
400
+ label: 'Good response',
401
+ onClick: () => console.log('Positive feedback')
402
+ }
403
+ ] : []
404
+ }));
405
+ ```
406
+
407
+ ### Controlled Chat State
408
+
409
+ For floating variant, control the chat state externally:
410
+
411
+ ```tsx
412
+ const [chatState, setChatState] = useState<ChatState>('collapsed');
413
+
414
+ <AgentUI
415
+ variant="floating"
416
+ floatingChatState={chatState}
417
+ onOpen={() => setChatState('compact')}
418
+ onExpand={() => setChatState('expanded')}
419
+ onClose={() => setChatState('collapsed')}
420
+ // ... other props
421
+ />
422
+ ```
423
+
424
+ ### Custom Empty View
425
+
426
+ Provide custom content when there are no messages:
427
+
428
+ ```tsx
429
+ <AgentUI
430
+ messages={[]}
431
+ emptyView={
432
+ <div className="welcome-message">
433
+ <h3>Welcome to AI Assistant</h3>
434
+ <p>I'm here to help you with any questions.</p>
435
+ </div>
436
+ }
437
+ // ... other props
438
+ />
439
+ ```
440
+
441
+ ## Development
442
+
443
+ ```bash
444
+ # Build the package
445
+ pnpm build
446
+
447
+ # Run in development mode
448
+ pnpm dev
449
+
450
+ # Run tests
451
+ pnpm test
452
+
453
+ # Type checking
454
+ pnpm type-check
455
+
456
+ # Start Storybook
457
+ pnpm storybook
458
+ ```
459
+
460
+ ## Storybook Documentation
461
+
462
+ Interactive component documentation is available via Storybook:
463
+
464
+ ```bash
465
+ pnpm storybook
466
+ ```
467
+
468
+ Visit `http://localhost:6006` to explore component examples and documentation.
469
+
470
+ ## Integration with agenttic-client
471
+
472
+ This UI package is designed to work seamlessly with `@automattic/agenttic-client`:
473
+
474
+ ```tsx
475
+ import { useAgentChat } from '@automattic/agenttic-client';
476
+ import { AgentUI } from '@automattic/agenttic-ui';
477
+
478
+ function App() {
479
+ const agentProps = useAgentChat({
480
+ agentId: 'big-sky',
481
+ // ... configuration
482
+ });
483
+
484
+ return <AgentUI {...agentProps} variant="floating" />;
485
+ }
486
+ ```
487
+
488
+ The `useAgentChat` hook returns props that match the `AgentUI` interface perfectly, making integration seamless.
package/dist/index.css ADDED
@@ -0,0 +1 @@
1
+ :root{--color-background: oklch(.99 0 0);--color-foreground: oklch(.241 0 0);--color-primary: oklch(.53 .22 268.05);--color-primary-foreground: oklch(1 0 0);--color-ring: var(--color-primary);--color-destructive: oklch(.492 .2095 28.09);--color-muted: color-mix(in srgb, var(--color-foreground) 10%, var(--color-background));--color-muted-foreground: color-mix(in srgb, var(--color-background) 40%, var(--color-foreground));--font-sans: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-weight-medium: 450;--text-sm: .875rem;--text-sm--line-height: 1.65;--text-base: .9375rem;--text-base--line-height: 1.625;--text-base--tracking: -.01em;--spacing: .25rem;--spacing-1: var(--spacing);--spacing-1\.5: calc(var(--spacing) * 1.5);--spacing-2: calc(var(--spacing) * 2);--spacing-3: calc(var(--spacing) * 3);--spacing-4: calc(var(--spacing) * 4);--spacing-5: calc(var(--spacing) * 5);--spacing-6: calc(var(--spacing) * 6);--spacing-7: calc(var(--spacing) * 7);--spacing-8: calc(var(--spacing) * 8);--spacing-9: calc(var(--spacing) * 9);--spacing-10: calc(var(--spacing) * 10);--spacing-20: calc(var(--spacing) * 20);--radius: 1rem;--radius-xs: calc(var(--radius) - 10px);--radius-sm: calc(var(--radius) - 8px);--radius-md: calc(var(--radius) - 2px);--radius-lg: var(--radius);--radius-xl: calc(var(--radius) + 8px);--radius-full: 9999px;--shadow-sm: 0 0 0 1px color-mix(in srgb, var(--color-foreground) 10%, transparent), 0 0 6px color-mix(in srgb, var(--color-foreground) 5%, transparent);--shadow-lg: 0 0 0 1px rgba(0, 0, 0, .075), 0 2px 24px rgba(0, 0, 0, .075);--shadow-outline: 0 0 0 1px rgba(0, 0, 0, .1);--transition-colors: color, background-color, border-color, text-decoration-color, fill, stroke .15s cubic-bezier(.4, 0, .2, 1)}@layer base{*,:before,:after,::backdrop,::file-selector-button{box-sizing:border-box;margin:0;padding:0;border:0 solid}*{outline-color:var(--color-ring)}button,input,select,optgroup,textarea,::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;background-color:transparent;opacity:1}input,select,optgroup,textarea,::file-selector-button{color:inherit;border-radius:0}}.button-module_button{align-items:center;border-radius:var(--radius-sm);border:1px solid transparent;cursor:pointer;display:inline-flex;flex-shrink:0;font-weight:var(--font-weight-medium);font-size:var(--text-sm);gap:calc(var(--spacing) * .5);justify-content:center;outline:none;transition-duration:.1s;transition:var(--transition-colors);letter-spacing:var(--text-base--tracking);white-space:nowrap;height:var(--spacing-8);padding:var(--spacing-2) var(--spacing-3)}.button-module_button:disabled{pointer-events:none;background-color:var(--color-muted);color:var(--color-muted-foreground)}.button-module_button:focus-visible{outline:2px solid var(--color-ring);outline-offset:1.5px}.button-module_primary{background-color:var(--color-primary);color:var(--color-primary-foreground)}.button-module_primary:hover:not(:disabled){background-color:color-mix(in srgb,var(--color-primary) 85%,#000)}.button-module_ghost{background-color:transparent;color:var(--color-foreground)}.button-module_ghost svg{color:var(--color-muted-foreground)}.button-module_ghost:hover:not(:disabled){background:transparent;color:var(--color-primary)}.button-module_ghost:hover:not(:disabled) svg{color:var(--color-foreground)}.button-module_ghost:focus-visible{outline-offset:0}.button-module_outline{box-shadow:var(--shadow-outline);background-color:var(--color-background);height:calc(var(--spacing-8) - 1px)}.button-module_outline:hover:not(:disabled){color:var(--color-primary)}.button-module_outline:focus-visible{outline-offset:2.5px}.button-module_link{background-color:transparent;color:var(--color-primary);font-weight:var(--font-weight-medium)}.button-module_link:hover:not(:disabled){color:color-mix(in srgb,var(--color-primary) 85%,#000)}.button-module_icon{border-radius:var(--radius-xs);height:var(--spacing-8);width:var(--spacing-8);padding:0}.button-module_sm{height:var(--spacing-6);width:var(--spacing-6);padding:0}.button-module_withTextAndIcon{padding-left:var(--spacing-1)}.button-module_button svg{flex-shrink:0;pointer-events:none;height:var(--spacing-6);width:var(--spacing-6)}.CollapsedView-module_button{border-radius:var(--radius-lg);height:var(--spacing-10);width:var(--spacing-10)}.Textarea-module_textarea{display:flex;width:100%;border-radius:var(--radius-md);border:0;background-color:transparent;min-height:var(--spacing-10);padding-left:var(--spacing-3);padding-right:var(--spacing-3);padding-top:var(--spacing-2);padding-bottom:var(--spacing-2);scrollbar-width:none;resize:none}.Textarea-module_textarea::-moz-placeholder{color:var(--color-muted-foreground);font-weight:var(--font-weight-medium)}.Textarea-module_textarea::placeholder{color:var(--color-muted-foreground);font-weight:var(--font-weight-medium)}.Textarea-module_textarea:focus-visible{outline:none}.Textarea-module_textarea:disabled{cursor:not-allowed;opacity:.5}.ChatInput-module_container{display:flex;align-items:end;gap:var(--spacing)}.ChatInput-module_textareaContainer{flex:1;width:100%}.ChatInput-module_actions{display:flex;flex-direction:row;padding-left:var(--spacing);padding-right:var(--spacing);height:var(--spacing-10);gap:var(--spacing);align-items:center}.ChatInput-module_button{border-radius:var(--radius-full)}.ChatHeader-module_container{display:flex;align-items:center;justify-content:flex-end;gap:var(--spacing);cursor:grab}.ChatHeader-module_container:active{cursor:grabbing}.MessageActions-module_container{display:flex;gap:var(--spacing-1);align-items:center;margin-top:var(--spacing-2)}.MessageActions-module_container button[aria-hidden=true]{display:none}.Message-module_message{display:flex;align-items:flex-start;padding:0 var(--spacing-3);color:var(--color-foreground)}.Message-module_message.Message-module_user .Message-module_bubble{background-color:var(--color-muted);max-width:85%;padding:var(--spacing-3) var(--spacing-4);border-radius:var(--radius-xl);border-bottom-right-radius:var(--radius-sm)}.Message-module_message.Message-module_error{color:var(--color-destructive)}.Message-module_content{flex:1;text-align:start;word-break:break-word;white-space:normal}.Message-module_message.Message-module_user .Message-module_content{display:flex;justify-content:flex-end}.Message-module_message p{text-wrap-style:pretty;margin-bottom:var(--spacing-3)}.Message-module_message a{color:var(--color-primary)}.Message-module_message p:last-child{margin-bottom:0}.Message-module_message strong{font-weight:550}.Message-module_message ol,.Message-module_message ul{margin-bottom:var(--spacing-3);padding-left:var(--spacing-5)}.Message-module_message p+:where(ol,ul){margin-top:0}.Message-module_message li{margin-bottom:var(--spacing-2)}.Message-module_message li::marker{font-size:var(--text-sm)}.Message-module_message table{width:100%;margin:12px 0;border-collapse:collapse}.Message-module_message th,.Message-module_message td{padding:8px 12px;border:1px solid #ddd;text-align:left}.Message-module_message th{background-color:var(--color-muted);font-weight:600}.Messages-module_container{display:flex;flex-direction:column;flex:1;padding-top:var(--spacing-2);padding-bottom:var(--spacing-20);gap:var(--spacing-8);overflow-y:auto;height:100%;position:relative;z-index:10}.Messages-module_container [data-role=user]:has(+[data-role=user]),.Messages-module_container [data-role=agent]:has(+[data-role=agent]){margin-bottom:calc(-1 * var(--spacing-6))}.Messages-module_emptyState{display:flex;flex-direction:column;align-items:center;justify-content:center}.Thinking-module_container{display:flex;align-items:center;gap:var(--spacing-2);padding-left:var(--spacing-3);padding-right:var(--spacing-3);color:var(--color-muted-foreground);font-size:var(--text-sm)}.Thinking-module_icon{display:flex;align-items:center;justify-content:center}.Thinking-module_icon svg{width:var(--spacing-4);height:var(--spacing-4)}.Thinking-module_content{background:linear-gradient(90deg,color-mix(in srgb,currentColor 30%,transparent),currentColor,color-mix(in srgb,currentColor 30%,transparent));background-size:200% 100%;background-clip:text;-webkit-background-clip:text;-webkit-text-fill-color:transparent;animation:Thinking-module_shimmer 2s infinite linear 0ms}@keyframes Thinking-module_shimmer{0%{background-position:200% 0}to{background-position:-200% 0}}.Notice-module_container{position:relative;display:flex;align-items:center;min-height:var(--spacing-10);padding:var(--spacing) var(--spacing) var(--spacing) var(--spacing-4);gap:var(--spacing-3);background-color:var(--color-muted);border-radius:var(--radius-sm);color:var(--color-foreground);font-size:var(--text-sm);font-weight:var(--font-weight-medium);line-height:var(--text-sm--line-height)}.Notice-module_containerWithIcon{padding-left:var(--spacing-3)}.Notice-module_content{align-items:center;display:flex;flex:1;gap:var(--spacing);min-width:0}.Notice-module_actions{align-items:center;display:flex;flex-shrink:0;gap:var(--spacing)}.Notice-module_icon{align-items:center;display:flex;flex-shrink:0;justify-content:center}.Notice-module_icon svg{display:block;height:var(--spacing-5);width:var(--spacing-5)}.Notice-module_dismissible{position:absolute;top:calc(var(--spacing) * -1.5);right:calc(var(--spacing) * -1.5);opacity:0;transform:scale(.9);border-radius:var(--radius-full);transition:all .15s ease}.Notice-module_dismissible:focus,.Notice-module_dismissible:focus-visible,.Notice-module_container:hover .Notice-module_dismissible{opacity:1;transform:scale(1)}.Notice-module_dismissible svg{display:block;width:var(--spacing-4);height:var(--spacing-4);background-color:var(--color-muted-foreground);color:var(--color-background);border-radius:inherit;box-shadow:0 0 0 2.5px var(--color-background);opacity:.8}.Notice-module_dismissible:hover svg{opacity:1}.Suggestions-module_container{position:absolute;top:0;left:0;right:0;display:flex;flex-wrap:nowrap;gap:var(--spacing-2);padding:var(--spacing-2) var(--spacing-1\.5);overflow-x:auto;overflow-y:hidden;scrollbar-width:none;-ms-overflow-style:none}.Suggestions-module_container::-webkit-scrollbar{display:none}.ConversationView-module_container{display:flex;flex-direction:column;height:100%;justify-content:flex-end}.ConversationView-module_container.ConversationView-module_withHeader{justify-content:space-between}.ConversationView-module_inputWrapper{position:relative}.ConversationView-module_inputContainer{box-shadow:var(--shadow-sm);padding:var(--spacing-2);background-color:var(--color-background);border-radius:calc(var(--radius-lg) + 1px);color:var(--color-foreground);position:relative;z-index:10;filter:brightness(1.1)}.ConversationView-module_inputContainerInner{display:flex;flex-direction:column;gap:var(--spacing-2)}.Chat-module_container{font-size:var(--text-base);line-height:var(--text-base--line-height);font-weight:400;font-family:var(--font-sans);letter-spacing:var(--text-base--tracking);text-rendering:optimizeLegibility;-webkit-font-smoothing:antialiased}.Chat-module_container.Chat-module_embedded{height:100%}.Chat-module_container.Chat-module_floating{position:fixed;z-index:50}.Chat-module_container.Chat-module_floating .Chat-module_content{background-color:var(--color-background);color:var(--color-foreground);overflow:hidden;min-height:56px;padding:var(--spacing-2);box-shadow:var(--shadow-lg)}