super-agent-sdk 1.0.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 +1316 -0
- package/dist/index.cjs +5 -0
- package/dist/index.d.ts +96 -0
- package/dist/index.mjs +345 -0
- package/dist/widget.cjs +1124 -0
- package/dist/widget.d.ts +394 -0
- package/dist/widget.mjs +2077 -0
- package/package.json +50 -0
package/dist/widget.d.ts
ADDED
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
import { ComponentType } from 'react';
|
|
2
|
+
import { default as default_2 } from 'react';
|
|
3
|
+
import { JSX as JSX_2 } from 'react';
|
|
4
|
+
import { RefObject } from 'react';
|
|
5
|
+
|
|
6
|
+
export declare function ActionBar({ message, onCopy, onRegenerate, onFeedback }: ActionBarProps): JSX_2.Element | null;
|
|
7
|
+
|
|
8
|
+
export declare interface ActionBarProps {
|
|
9
|
+
message: UIMessage;
|
|
10
|
+
onCopy: () => void;
|
|
11
|
+
onRegenerate: () => void;
|
|
12
|
+
onFeedback?: (messageId: string, feedback: 'like' | 'dislike') => void;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export declare interface AvatarConfig {
|
|
16
|
+
/** Assistant avatar: URL string, emoji, or React node */
|
|
17
|
+
assistant?: string;
|
|
18
|
+
/** User avatar: URL string, emoji, or React node */
|
|
19
|
+
user?: string;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
declare interface ChatEvent {
|
|
23
|
+
type: "user" | "thinking" | "ai" | "tool_call" | "tool_result" | "done" | "error";
|
|
24
|
+
content: string;
|
|
25
|
+
toolName?: string;
|
|
26
|
+
toolCallId?: string;
|
|
27
|
+
args?: string;
|
|
28
|
+
sessionId?: string;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
declare interface ChatOptions {
|
|
32
|
+
sessionId: string;
|
|
33
|
+
message: string;
|
|
34
|
+
stream?: boolean;
|
|
35
|
+
onMessage?: (event: ChatEvent) => void;
|
|
36
|
+
onError?: (error: Error) => void;
|
|
37
|
+
onDone?: (result: {
|
|
38
|
+
sessionId: string;
|
|
39
|
+
content: string;
|
|
40
|
+
}) => void;
|
|
41
|
+
signal?: AbortSignal;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
export declare function ChatProvider({ sdk, hooks, children }: ChatProviderProps): default_2.JSX.Element;
|
|
45
|
+
|
|
46
|
+
declare interface ChatProviderProps {
|
|
47
|
+
sdk: SuperAgentSDK;
|
|
48
|
+
hooks?: EventHooks;
|
|
49
|
+
children: default_2.ReactNode;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
export declare interface ChatState {
|
|
53
|
+
status: ChatStatus;
|
|
54
|
+
error: Error | null;
|
|
55
|
+
messages: UIMessage[];
|
|
56
|
+
conversations: Conversation[];
|
|
57
|
+
activeConversationId: string | null;
|
|
58
|
+
isThreadListOpen: boolean;
|
|
59
|
+
sendMessage: (content: string) => void;
|
|
60
|
+
stop: () => void;
|
|
61
|
+
regenerate: () => void;
|
|
62
|
+
switchConversation: (sessionId: string) => void;
|
|
63
|
+
newConversation: () => void;
|
|
64
|
+
deleteConversation: (sessionId: string) => void;
|
|
65
|
+
renameConversation: (sessionId: string, title: string) => void;
|
|
66
|
+
toggleThreadList: () => void;
|
|
67
|
+
feedback: (messageId: string, feedback: 'like' | 'dislike') => void;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export declare type ChatStatus = 'ready' | 'submitted' | 'streaming' | 'error';
|
|
71
|
+
|
|
72
|
+
export declare function ChatWidget(props: ChatWidgetProps): JSX_2.Element | null;
|
|
73
|
+
|
|
74
|
+
declare interface ChatWidgetProps extends MountOptions {
|
|
75
|
+
initialOpen?: boolean;
|
|
76
|
+
onOpenChange?: (isOpen: boolean) => void;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export declare function Composer(): default_2.JSX.Element;
|
|
80
|
+
|
|
81
|
+
export declare interface ComposerProps {
|
|
82
|
+
status: ChatStatus;
|
|
83
|
+
onSend: (content: string) => void;
|
|
84
|
+
onStop: () => void;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
declare interface Conversation {
|
|
88
|
+
sessionId: string;
|
|
89
|
+
botId: number;
|
|
90
|
+
title: string | null;
|
|
91
|
+
createTime: string;
|
|
92
|
+
updateTime: string;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
export declare const defaultTheme: Required<ThemeConfig>;
|
|
96
|
+
|
|
97
|
+
export declare function ErrorPart({ content, onRetry }: ErrorPartProps): JSX_2.Element;
|
|
98
|
+
|
|
99
|
+
export declare interface ErrorPartProps {
|
|
100
|
+
content: string;
|
|
101
|
+
onRetry?: () => void;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export declare interface EventHooks {
|
|
105
|
+
onOpen?: () => void;
|
|
106
|
+
onClose?: () => void;
|
|
107
|
+
onMessageSend?: (message: string) => void;
|
|
108
|
+
onStreamStart?: (sessionId: string) => void;
|
|
109
|
+
onStreamEnd?: (sessionId: string) => void;
|
|
110
|
+
onError?: (error: Error) => void;
|
|
111
|
+
onConversationChange?: (sessionId: string) => void;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export declare function FullpageLayout({ title, slots, welcomeMessage, suggestedPrompts, sidebarDefaultOpen, onClose, avatar }: FullpageLayoutProps): default_2.JSX.Element;
|
|
115
|
+
|
|
116
|
+
declare interface FullpageLayoutProps {
|
|
117
|
+
title: string;
|
|
118
|
+
slots: Slots;
|
|
119
|
+
welcomeMessage?: string;
|
|
120
|
+
suggestedPrompts?: string[];
|
|
121
|
+
sidebarDefaultOpen?: boolean;
|
|
122
|
+
onClose?: () => void;
|
|
123
|
+
avatar?: AvatarConfig;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export declare function Header({ title, onClose, onToggleThreadList, showClose }: InternalHeaderProps): JSX_2.Element;
|
|
127
|
+
|
|
128
|
+
export declare interface HeaderProps {
|
|
129
|
+
title: string;
|
|
130
|
+
onClose: () => void;
|
|
131
|
+
onToggleThreadList: () => void;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export declare function Icon({ name, size, color, className, style }: IconProps): default_2.JSX.Element;
|
|
135
|
+
|
|
136
|
+
declare interface IconProps {
|
|
137
|
+
name: string;
|
|
138
|
+
size?: number;
|
|
139
|
+
color?: string;
|
|
140
|
+
className?: string;
|
|
141
|
+
style?: default_2.CSSProperties;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
declare interface InternalHeaderProps {
|
|
145
|
+
title: string;
|
|
146
|
+
onClose: () => void;
|
|
147
|
+
onToggleThreadList: () => void;
|
|
148
|
+
showClose?: boolean;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
declare interface InternalMessageProps {
|
|
152
|
+
message: UIMessage;
|
|
153
|
+
isStreaming: boolean;
|
|
154
|
+
isLast: boolean;
|
|
155
|
+
slots: Slots;
|
|
156
|
+
avatar?: AvatarConfig;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
declare interface ListConversationsParams {
|
|
160
|
+
page?: number;
|
|
161
|
+
size?: number;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
declare interface ListConversationsResult {
|
|
165
|
+
items: Conversation[];
|
|
166
|
+
total: number;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
export declare function Message({ message, isStreaming, isLast, slots, avatar }: InternalMessageProps): JSX_2.Element;
|
|
170
|
+
|
|
171
|
+
declare type MessagePart = {
|
|
172
|
+
type: "text";
|
|
173
|
+
content: string;
|
|
174
|
+
} | {
|
|
175
|
+
type: "thinking";
|
|
176
|
+
content: string;
|
|
177
|
+
} | {
|
|
178
|
+
type: "tool_call";
|
|
179
|
+
toolName: string;
|
|
180
|
+
toolCallId: string;
|
|
181
|
+
args: string;
|
|
182
|
+
} | {
|
|
183
|
+
type: "tool_result";
|
|
184
|
+
toolName: string;
|
|
185
|
+
toolCallId: string;
|
|
186
|
+
content: string;
|
|
187
|
+
} | {
|
|
188
|
+
type: "error";
|
|
189
|
+
content: string;
|
|
190
|
+
};
|
|
191
|
+
|
|
192
|
+
export declare interface MessageProps {
|
|
193
|
+
message: UIMessage;
|
|
194
|
+
isStreaming: boolean;
|
|
195
|
+
isLast: boolean;
|
|
196
|
+
avatar?: AvatarConfig;
|
|
197
|
+
slots: Slots;
|
|
198
|
+
onCopy: () => void;
|
|
199
|
+
onRegenerate: () => void;
|
|
200
|
+
onFeedback?: (messageId: string, feedback: 'like' | 'dislike') => void;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export declare function mount(target: string | HTMLElement, options: MountOptions): WidgetInstance;
|
|
204
|
+
|
|
205
|
+
export declare interface MountOptions {
|
|
206
|
+
sdk: SuperAgentSDK;
|
|
207
|
+
mode?: WidgetMode;
|
|
208
|
+
theme?: ThemeConfig;
|
|
209
|
+
slots?: Slots;
|
|
210
|
+
hooks?: EventHooks;
|
|
211
|
+
welcomeMessage?: string;
|
|
212
|
+
suggestedPrompts?: string[];
|
|
213
|
+
title?: string;
|
|
214
|
+
sidebarDefaultOpen?: boolean;
|
|
215
|
+
avatar?: AvatarConfig;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
export declare interface Slots {
|
|
219
|
+
Trigger?: ComponentType<TriggerProps>;
|
|
220
|
+
Header?: ComponentType<HeaderProps>;
|
|
221
|
+
Message?: ComponentType<MessageProps>;
|
|
222
|
+
Composer?: ComponentType<ComposerProps>;
|
|
223
|
+
ActionBar?: ComponentType<ActionBarProps>;
|
|
224
|
+
ThreadList?: ComponentType<ThreadListProps>;
|
|
225
|
+
ThinkingPart?: ComponentType<ThinkingPartProps>;
|
|
226
|
+
TextPart?: ComponentType<TextPartProps>;
|
|
227
|
+
ToolCallPart?: ComponentType<ToolCallPartProps>;
|
|
228
|
+
ToolResultPart?: ComponentType<ToolResultPartProps>;
|
|
229
|
+
ErrorPart?: ComponentType<ErrorPartProps>;
|
|
230
|
+
WelcomeScreen?: ComponentType<WelcomeScreenProps>;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
declare interface SuperAgentSDK {
|
|
234
|
+
/** 获取 token(调用 POST /token),自动设置内部凭证 */
|
|
235
|
+
getToken(): Promise<{
|
|
236
|
+
appId: string;
|
|
237
|
+
token: string;
|
|
238
|
+
}>;
|
|
239
|
+
/** 创建新会话,返回 sessionId */
|
|
240
|
+
createSession(): Promise<string>;
|
|
241
|
+
chat(options: ChatOptions): AbortController;
|
|
242
|
+
listConversations(params?: ListConversationsParams): Promise<ListConversationsResult>;
|
|
243
|
+
renameConversation(sessionId: string, title: string): Promise<void>;
|
|
244
|
+
deleteConversation(sessionId: string): Promise<void>;
|
|
245
|
+
getMessages(sessionId: string): Promise<UIMessage[]>;
|
|
246
|
+
setToken(appId: string, token: string): void;
|
|
247
|
+
feedback(sessionId: string, type: "like" | "dislike"): void;
|
|
248
|
+
onFeedback?: (sessionId: string, type: "like" | "dislike") => void;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
export declare function TextPart({ content }: TextPartProps): default_2.JSX.Element;
|
|
252
|
+
|
|
253
|
+
export declare interface TextPartProps {
|
|
254
|
+
content: string;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export declare interface ThemeConfig {
|
|
258
|
+
primaryColor?: string;
|
|
259
|
+
backgroundColor?: string;
|
|
260
|
+
fontFamily?: string;
|
|
261
|
+
borderRadius?: number;
|
|
262
|
+
panelWidth?: number;
|
|
263
|
+
panelHeight?: number;
|
|
264
|
+
zIndex?: number;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
/** Convert ThemeConfig to CSS custom properties string */
|
|
268
|
+
export declare function themeToCSSVars(theme: ThemeConfig): string;
|
|
269
|
+
|
|
270
|
+
export declare function ThinkingPart({ content }: ThinkingPartProps): JSX_2.Element;
|
|
271
|
+
|
|
272
|
+
export declare interface ThinkingPartProps {
|
|
273
|
+
content: string;
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
export declare function Thread({ slots, welcomeMessage, suggestedPrompts, avatar }: ThreadProps): JSX_2.Element;
|
|
277
|
+
|
|
278
|
+
export declare function ThreadList(): JSX_2.Element | null;
|
|
279
|
+
|
|
280
|
+
export declare interface ThreadListProps {
|
|
281
|
+
conversations: Conversation[];
|
|
282
|
+
activeSessionId: string | null;
|
|
283
|
+
onSwitch: (sessionId: string) => void;
|
|
284
|
+
onNew: () => void;
|
|
285
|
+
onDelete: (sessionId: string) => void;
|
|
286
|
+
onRename: (sessionId: string, title: string) => void;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
declare interface ThreadProps {
|
|
290
|
+
slots: Slots;
|
|
291
|
+
welcomeMessage?: string;
|
|
292
|
+
suggestedPrompts?: string[];
|
|
293
|
+
avatar?: AvatarConfig;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
export declare function ToolCallPart({ toolName, toolCallId, args }: ToolCallPartProps): JSX_2.Element;
|
|
297
|
+
|
|
298
|
+
export declare interface ToolCallPartProps {
|
|
299
|
+
toolName: string;
|
|
300
|
+
toolCallId: string;
|
|
301
|
+
args: string;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export declare function ToolResultPart({ toolName, toolCallId, content }: ToolResultPartProps): JSX_2.Element;
|
|
305
|
+
|
|
306
|
+
export declare interface ToolResultPartProps {
|
|
307
|
+
toolName: string;
|
|
308
|
+
toolCallId: string;
|
|
309
|
+
content: string;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export declare function Trigger({ isOpen, onClick }: TriggerProps): JSX_2.Element;
|
|
313
|
+
|
|
314
|
+
export declare interface TriggerProps {
|
|
315
|
+
isOpen: boolean;
|
|
316
|
+
onClick: () => void;
|
|
317
|
+
unreadCount?: number;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
declare interface UIMessage {
|
|
321
|
+
id: string;
|
|
322
|
+
role: "user" | "assistant";
|
|
323
|
+
parts: MessagePart[];
|
|
324
|
+
timestamp: number;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
export declare function useAutoScroll(deps: any[]): {
|
|
328
|
+
containerRef: RefObject<HTMLDivElement>;
|
|
329
|
+
scrollToBottom: () => void;
|
|
330
|
+
};
|
|
331
|
+
|
|
332
|
+
export declare function useChat(options: UseChatOptions): UseChatReturn;
|
|
333
|
+
|
|
334
|
+
export declare function useChatContext(): ChatState;
|
|
335
|
+
|
|
336
|
+
declare interface UseChatOptions {
|
|
337
|
+
sdk: SuperAgentSDK;
|
|
338
|
+
sessionId: string | null;
|
|
339
|
+
onSessionCreated?: (sessionId: string) => void;
|
|
340
|
+
onStreamStart?: (sessionId: string) => void;
|
|
341
|
+
onStreamEnd?: (sessionId: string) => void;
|
|
342
|
+
onError?: (error: Error) => void;
|
|
343
|
+
onMessageSend?: (message: string) => void;
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
declare interface UseChatReturn {
|
|
347
|
+
messages: UIMessage[];
|
|
348
|
+
status: ChatStatus;
|
|
349
|
+
error: Error | null;
|
|
350
|
+
sendMessage: (content: string) => void;
|
|
351
|
+
stop: () => void;
|
|
352
|
+
regenerate: () => void;
|
|
353
|
+
setMessages: (messages: UIMessage[]) => void;
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
export declare function useConversations(options: UseConversationsOptions): UseConversationsReturn;
|
|
357
|
+
|
|
358
|
+
declare interface UseConversationsOptions {
|
|
359
|
+
sdk: SuperAgentSDK;
|
|
360
|
+
onConversationChange?: (sessionId: string) => void;
|
|
361
|
+
enabled?: boolean;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
declare interface UseConversationsReturn {
|
|
365
|
+
conversations: Conversation[];
|
|
366
|
+
activeConversationId: string | null;
|
|
367
|
+
loading: boolean;
|
|
368
|
+
loadConversations: () => Promise<void>;
|
|
369
|
+
switchConversation: (sessionId: string) => Promise<UIMessage[]>;
|
|
370
|
+
newConversation: () => void;
|
|
371
|
+
deleteConversation: (sessionId: string) => Promise<void>;
|
|
372
|
+
renameConversation: (sessionId: string, title: string) => Promise<void>;
|
|
373
|
+
setActiveConversationId: (id: string | null) => void;
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
export declare function WelcomeScreen({ message, suggestedPrompts, onPromptClick }: WelcomeScreenProps): JSX_2.Element;
|
|
377
|
+
|
|
378
|
+
export declare interface WelcomeScreenProps {
|
|
379
|
+
message?: string;
|
|
380
|
+
suggestedPrompts?: string[];
|
|
381
|
+
onPromptClick: (prompt: string) => void;
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
export declare interface WidgetInstance {
|
|
385
|
+
open(): void;
|
|
386
|
+
close(): void;
|
|
387
|
+
destroy(): void;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
export declare type WidgetMode = 'floating' | 'fullpage';
|
|
391
|
+
|
|
392
|
+
export declare const widgetStyles = "\n [data-super-agent-widget] {\n --sa-primary-dark: color-mix(in srgb, var(--sa-primary) 82%, #000);\n --sa-primary-light: color-mix(in srgb, var(--sa-primary) 10%, #fff);\n --sa-text: #1f2937;\n --sa-text-muted: #6b7280;\n --sa-border: #e5e7eb;\n --sa-surface: #f9fafb;\n\n font-family: var(--sa-font);\n color: var(--sa-text);\n line-height: 1.5;\n -webkit-font-smoothing: antialiased;\n text-rendering: optimizeLegibility;\n }\n\n [data-super-agent-widget] *,\n [data-super-agent-widget] *::before,\n [data-super-agent-widget] *::after {\n box-sizing: border-box;\n margin: 0;\n padding: 0;\n }\n\n [data-super-agent-widget] button {\n font-family: inherit;\n }\n\n /* \u2500\u2500 Trigger \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n .sa-trigger {\n position: fixed;\n bottom: 24px;\n right: 24px;\n width: 56px;\n height: 56px;\n border: none;\n border-radius: 50%;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n background: linear-gradient(135deg, var(--sa-primary), var(--sa-primary-dark));\n color: #ffffff;\n font-size: 24px;\n box-shadow: 0 8px 24px color-mix(in srgb, var(--sa-primary) 35%, transparent);\n z-index: var(--sa-z-index, 9999);\n transition: transform 0.2s ease, box-shadow 0.2s ease;\n }\n\n .sa-trigger:hover {\n transform: scale(1.08);\n box-shadow: 0 12px 32px color-mix(in srgb, var(--sa-primary) 45%, transparent);\n }\n\n .sa-trigger:active {\n transform: scale(0.94);\n }\n\n .sa-trigger-open {\n transform: rotate(90deg);\n }\n\n /* \u2500\u2500 Panel \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n .sa-panel {\n position: fixed;\n bottom: 96px;\n right: 24px;\n width: var(--sa-panel-width, 380px);\n height: var(--sa-panel-height, 520px);\n max-height: calc(100vh - 120px);\n display: flex;\n flex-direction: column;\n overflow: hidden;\n background: var(--sa-bg);\n border: 1px solid var(--sa-border);\n border-radius: var(--sa-radius, 16px);\n box-shadow: 0 20px 60px rgba(0, 0, 0, 0.18);\n z-index: var(--sa-z-index, 9999);\n animation: sa-slide-up 0.25s cubic-bezier(0.16, 1, 0.3, 1);\n }\n\n /* \u2500\u2500 Header \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n .sa-header {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 14px 16px;\n color: #ffffff;\n background: linear-gradient(135deg, var(--sa-primary), var(--sa-primary-dark));\n flex-shrink: 0;\n }\n\n .sa-header-left {\n display: flex;\n align-items: center;\n gap: 10px;\n flex: 1;\n }\n\n .sa-header-avatar {\n width: 28px;\n height: 28px;\n border-radius: 50%;\n background: rgba(255,255,255,0.2);\n display: flex;\n align-items: center;\n justify-content: center;\n font-size: 12px;\n font-weight: 600;\n }\n\n .sa-header-info {\n display: flex;\n flex-direction: column;\n }\n\n .sa-header-status {\n font-size: 11px;\n opacity: 0.8;\n color: #a5f3a6;\n }\n\n .sa-header-actions {\n display: flex;\n gap: 4px;\n }\n\n .sa-header-title {\n flex: 1;\n font-size: 16px;\n font-weight: 600;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n }\n\n .sa-header-btn {\n width: 30px;\n height: 30px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: #ffffff;\n font-size: 16px;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.15s ease;\n }\n\n .sa-header-btn:hover {\n background: rgba(255, 255, 255, 0.18);\n }\n\n /* \u2500\u2500 Thread / messages \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n .sa-thread {\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: 14px;\n overflow-y: auto;\n padding: 16px;\n background: var(--sa-surface);\n scroll-behavior: smooth;\n }\n\n .sa-thread::-webkit-scrollbar {\n width: 6px;\n }\n\n .sa-thread::-webkit-scrollbar-thumb {\n background: rgba(0, 0, 0, 0.14);\n border-radius: 3px;\n }\n\n .sa-thread::-webkit-scrollbar-thumb:hover {\n background: rgba(0, 0, 0, 0.24);\n }\n\n .sa-message {\n display: flex;\n align-items: flex-start;\n gap: 10px;\n width: 100%;\n }\n\n .sa-message-user {\n justify-content: flex-end;\n }\n\n .sa-message-body {\n max-width: 78%;\n display: flex;\n flex-direction: column;\n gap: 4px;\n }\n\n .sa-message-user .sa-message-body {\n padding: 10px 14px;\n border-radius: 16px;\n border-bottom-right-radius: 4px;\n background: var(--sa-primary);\n color: #ffffff;\n font-size: 14px;\n line-height: 1.55;\n word-break: break-word;\n }\n\n .sa-message-assistant .sa-message-body {\n padding: 10px 14px;\n border-radius: 16px;\n border-bottom-left-radius: 4px;\n background: #ffffff;\n color: var(--sa-text);\n font-size: 14px;\n line-height: 1.55;\n word-break: break-word;\n box-shadow: 0 1px 2px rgba(0, 0, 0, 0.06);\n }\n\n .sa-avatar {\n width: 28px;\n height: 28px;\n flex-shrink: 0;\n border-radius: 50%;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #ffffff;\n font-size: 12px;\n font-weight: 600;\n overflow: hidden;\n }\n\n .sa-avatar-assistant {\n background: linear-gradient(135deg, var(--sa-primary), var(--sa-primary-dark));\n }\n\n .sa-avatar-user {\n background: linear-gradient(135deg, #64748b, #475569);\n }\n\n /* \u2500\u2500 Text part (markdown) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n .sa-text-part {\n font-size: 14px;\n line-height: 1.6;\n word-break: break-word;\n }\n\n .sa-text-part p {\n margin: 0 0 8px;\n }\n\n .sa-text-part p:last-child {\n margin-bottom: 0;\n }\n\n .sa-text-part strong {\n font-weight: 600;\n }\n\n .sa-text-part em {\n font-style: italic;\n }\n\n .sa-text-part h1,\n .sa-text-part h2,\n .sa-text-part h3,\n .sa-text-part h4,\n .sa-text-part h5,\n .sa-text-part h6 {\n margin: 12px 0 6px;\n font-weight: 600;\n line-height: 1.3;\n }\n\n .sa-text-part h1 {\n font-size: 1.4em;\n }\n\n .sa-text-part h2 {\n font-size: 1.25em;\n }\n\n .sa-text-part h3 {\n font-size: 1.1em;\n }\n\n .sa-text-part h4,\n .sa-text-part h5,\n .sa-text-part h6 {\n font-size: 1em;\n }\n\n .sa-text-part a {\n color: var(--sa-primary);\n text-decoration: underline;\n text-underline-offset: 2px;\n }\n\n .sa-text-part a:hover {\n color: var(--sa-primary-dark);\n }\n\n .sa-inline-code {\n padding: 2px 5px;\n border-radius: 4px;\n background: rgba(0, 0, 0, 0.06);\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 0.9em;\n }\n\n .sa-code-block {\n margin: 8px 0;\n padding: 12px 14px;\n border-radius: 10px;\n background: #1e293b;\n color: #e2e8f0;\n overflow-x: auto;\n font-size: 13px;\n line-height: 1.55;\n }\n\n .sa-code-block code {\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n white-space: pre;\n }\n\n .sa-list {\n margin: 6px 0;\n padding-left: 22px;\n }\n\n .sa-list li {\n margin: 3px 0;\n line-height: 1.5;\n }\n\n ul.sa-list {\n list-style: disc;\n }\n\n ol.sa-list {\n list-style: decimal;\n }\n\n /* \u2500\u2500 Thinking part \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n .sa-thinking-part {\n margin: 6px 0;\n padding: 8px 12px;\n border-left: 3px solid var(--sa-primary);\n border-radius: 8px;\n background: var(--sa-primary-light);\n cursor: pointer;\n font-size: 13px;\n }\n\n .sa-thinking-header {\n display: flex;\n align-items: center;\n gap: 6px;\n color: var(--sa-primary-dark);\n font-weight: 500;\n user-select: none;\n }\n\n .sa-thinking-icon {\n font-size: 14px;\n line-height: 1;\n }\n\n .sa-thinking-label {\n flex: 1;\n }\n\n .sa-thinking-arrow {\n font-size: 12px;\n transition: transform 0.2s ease;\n }\n\n .sa-thinking-arrow.expanded {\n transform: rotate(90deg);\n }\n\n .sa-thinking-content {\n margin-top: 8px;\n color: #4b5563;\n white-space: pre-wrap;\n line-height: 1.55;\n }\n\n /* \u2500\u2500 Tool call / result \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n .sa-tool-call-part {\n margin: 6px 0;\n border: 1px solid var(--sa-border);\n border-radius: 10px;\n overflow: hidden;\n background: #ffffff;\n }\n\n .sa-tool-call-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n cursor: pointer;\n font-size: 13px;\n user-select: none;\n }\n\n .sa-tool-call-header:hover {\n background: var(--sa-surface);\n }\n\n .sa-tool-icon {\n font-size: 14px;\n line-height: 1;\n }\n\n .sa-tool-name {\n flex: 1;\n color: #374151;\n font-weight: 500;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n\n .sa-tool-args {\n margin: 0;\n padding: 10px 12px;\n border-top: 1px solid var(--sa-border);\n background: var(--sa-surface);\n color: #374151;\n font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n font-size: 12px;\n line-height: 1.5;\n white-space: pre;\n overflow-x: auto;\n }\n\n .sa-tool-result-part {\n margin: 6px 0;\n border: 1px solid var(--sa-border);\n border-radius: 10px;\n overflow: hidden;\n background: #ffffff;\n }\n\n .sa-tool-result-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 12px;\n border-bottom: 1px solid var(--sa-border);\n background: var(--sa-surface);\n color: #374151;\n font-size: 13px;\n font-weight: 500;\n }\n\n .sa-tool-result-content {\n padding: 10px 12px;\n color: #4b5563;\n font-size: 13px;\n line-height: 1.55;\n white-space: pre-wrap;\n word-break: break-word;\n }\n\n /* \u2500\u2500 Error part \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n .sa-error-part {\n margin: 6px 0;\n padding: 10px 12px;\n border: 1px solid #fecaca;\n border-radius: 10px;\n background: #fef2f2;\n color: #b91c1c;\n }\n\n .sa-error-content {\n display: flex;\n align-items: flex-start;\n gap: 8px;\n font-size: 13px;\n line-height: 1.5;\n }\n\n .sa-error-icon {\n font-size: 14px;\n line-height: 1.4;\n }\n\n .sa-error-retry {\n margin-top: 8px;\n padding: 6px 14px;\n border: none;\n border-radius: 8px;\n background: #ef4444;\n color: #ffffff;\n font-size: 13px;\n cursor: pointer;\n transition: background 0.2s ease;\n }\n\n .sa-error-retry:hover {\n background: #dc2626;\n }\n\n /* \u2500\u2500 Action bar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n .sa-action-bar {\n display: flex;\n gap: 6px;\n margin-top: 6px;\n }\n\n .sa-action-btn {\n padding: 4px 10px;\n border: none;\n border-radius: 6px;\n background: transparent;\n color: var(--sa-text-muted);\n font-size: 12px;\n cursor: pointer;\n transition: color 0.15s ease, background 0.15s ease;\n }\n\n .sa-action-btn:hover {\n color: var(--sa-text);\n background: rgba(0, 0, 0, 0.05);\n }\n\n .sa-action-btn-active {\n color: var(--sa-primary) !important;\n background: var(--sa-primary-light) !important;\n }\n\n .sa-action-divider {\n width: 1px;\n height: 16px;\n background: var(--sa-border);\n margin: 0 2px;\n align-self: center;\n }\n\n /* \u2500\u2500 Composer \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n .sa-composer {\n display: flex;\n align-items: flex-end;\n gap: 10px;\n padding: 12px 14px;\n border-top: 1px solid var(--sa-border);\n background: var(--sa-bg);\n flex-shrink: 0;\n }\n\n .sa-composer-input {\n flex: 1;\n min-height: 38px;\n max-height: 120px;\n padding: 9px 14px;\n border: 1px solid var(--sa-border);\n border-radius: 19px;\n background: var(--sa-surface);\n color: var(--sa-text);\n font-family: var(--sa-font);\n font-size: 14px;\n line-height: 1.5;\n resize: none;\n outline: none;\n transition: border-color 0.2s ease, background 0.2s ease;\n }\n\n .sa-composer-input::placeholder {\n color: #9ca3af;\n }\n\n .sa-composer-input:focus {\n border-color: var(--sa-primary);\n background: #ffffff;\n }\n\n .sa-composer-send,\n .sa-composer-stop {\n width: 38px;\n height: 38px;\n flex-shrink: 0;\n border: none;\n border-radius: 50%;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n color: #ffffff;\n font-size: 16px;\n transition: transform 0.15s ease, background 0.2s ease;\n }\n\n .sa-composer-send {\n background: var(--sa-primary);\n }\n\n .sa-composer-send:hover {\n background: var(--sa-primary-dark);\n transform: scale(1.05);\n }\n\n .sa-composer-send:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n transform: none;\n }\n\n .sa-composer-stop {\n background: #ef4444;\n }\n\n .sa-composer-stop:hover {\n background: #dc2626;\n transform: scale(1.05);\n }\n\n /* \u2500\u2500 Thread list \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n .sa-thread-list-overlay {\n position: absolute;\n inset: 0;\n background: rgba(0,0,0,0.3);\n z-index: 19;\n }\n\n .sa-thread-list {\n position: absolute;\n top: 0;\n left: 0;\n bottom: 0;\n width: 100%;\n display: flex;\n flex-direction: column;\n background: #ffffff;\n z-index: 20;\n box-shadow: 0 0 40px rgba(0, 0, 0, 0.15);\n animation: sa-slide-in-left 0.25s cubic-bezier(0.16, 1, 0.3, 1);\n }\n\n .sa-thread-list-header {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 14px 16px;\n border-bottom: 1px solid var(--sa-border);\n flex-shrink: 0;\n }\n\n .sa-thread-list-items {\n flex: 1;\n overflow-y: auto;\n }\n\n .sa-thread-list-empty {\n padding: 24px 16px;\n text-align: center;\n color: var(--sa-text-muted);\n font-size: 13px;\n }\n\n .sa-thread-list-new {\n display: block;\n width: calc(100% - 24px);\n margin: 12px;\n padding: 10px;\n border: 1px dashed var(--sa-border);\n border-radius: 10px;\n background: transparent;\n color: var(--sa-primary);\n font-size: 14px;\n cursor: pointer;\n text-align: center;\n transition: background 0.15s, border-color 0.15s;\n }\n\n .sa-thread-list-new:hover {\n background: var(--sa-primary-light);\n border-color: var(--sa-primary);\n }\n\n .sa-thread-item {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: 8px;\n padding: 12px 16px;\n border-bottom: 1px solid #f3f4f6;\n color: #374151;\n font-size: 14px;\n cursor: pointer;\n transition: background 0.15s ease;\n }\n\n .sa-thread-item:hover {\n background: var(--sa-surface);\n }\n\n .sa-thread-item.active {\n background: var(--sa-primary-light);\n color: var(--sa-primary-dark);\n font-weight: 500;\n }\n\n .sa-thread-item-title {\n flex: 1;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n\n .sa-thread-item-edit {\n width: 100%;\n padding: 4px 8px;\n border: 1px solid var(--sa-primary);\n border-radius: 6px;\n font-size: 13px;\n outline: none;\n background: var(--sa-bg);\n color: var(--sa-text);\n }\n\n .sa-thread-item-delete {\n border: none;\n background: transparent;\n color: var(--sa-text-muted);\n font-size: 14px;\n cursor: pointer;\n opacity: 0;\n transition: opacity 0.15s ease, color 0.15s ease;\n }\n\n .sa-thread-item:hover .sa-thread-item-delete {\n opacity: 1;\n }\n\n .sa-thread-item-delete:hover {\n color: #ef4444;\n }\n\n /* \u2500\u2500 Welcome \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n .sa-welcome {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 24px;\n text-align: center;\n }\n\n .sa-welcome-icon {\n font-size: 40px;\n margin-bottom: 12px;\n }\n\n .sa-welcome-message {\n margin-bottom: 20px;\n font-size: 14px;\n color: var(--sa-text-muted);\n line-height: 1.6;\n }\n\n .sa-welcome-prompts {\n display: flex;\n flex-direction: column;\n gap: 8px;\n width: 100%;\n }\n\n .sa-welcome-prompt {\n padding: 10px 16px;\n border: 1px solid var(--sa-border);\n border-radius: 999px;\n background: #ffffff;\n color: #374151;\n font-size: 13px;\n cursor: pointer;\n transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;\n }\n\n .sa-welcome-prompt:hover {\n border-color: var(--sa-primary);\n background: var(--sa-primary-light);\n color: var(--sa-primary-dark);\n }\n\n /* \u2500\u2500 Streaming cursor \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n .sa-streaming-cursor {\n display: inline-block;\n width: 2px;\n height: 1em;\n margin-left: 2px;\n background: var(--sa-primary);\n vertical-align: text-bottom;\n animation: sa-blink 1s steps(2, start) infinite;\n }\n\n /* \u2500\u2500 Animations \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n @keyframes sa-slide-up {\n from {\n opacity: 0;\n transform: translateY(16px) scale(0.98);\n }\n to {\n opacity: 1;\n transform: translateY(0) scale(1);\n }\n }\n\n @keyframes sa-blink {\n 0%,\n 100% {\n opacity: 1;\n }\n 50% {\n opacity: 0;\n }\n }\n\n @keyframes sa-slide-in-left {\n from {\n opacity: 0;\n transform: translateX(-100%);\n }\n to {\n opacity: 1;\n transform: translateX(0);\n }\n }\n\n /* \u2500\u2500 Fullpage Layout (DeepSeek-style) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */\n\n .sa-fullpage {\n position: fixed;\n inset: 0;\n width: 100vw;\n height: 100vh;\n display: flex;\n background: #f7f7f8;\n z-index: var(--sa-z-index, 9999);\n }\n\n /* Sidebar */\n .sa-fp-sidebar {\n width: 260px;\n display: flex;\n flex-direction: column;\n background: #f2f2f3;\n flex-shrink: 0;\n transition: width 0.2s cubic-bezier(0.16,1,0.3,1);\n overflow: hidden;\n border-right: 1px solid #e8e8ea;\n }\n\n .sa-fp-sidebar-collapsed {\n width: 52px;\n align-items: center;\n padding-top: 12px;\n gap: 4px;\n border-right: 1px solid #e8e8ea;\n }\n\n .sa-fp-sidebar-header {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 12px 12px 8px;\n flex-shrink: 0;\n }\n\n .sa-fp-sidebar-toggle {\n width: 32px;\n height: 32px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: #71717a;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.12s, color 0.12s;\n flex-shrink: 0;\n }\n\n .sa-fp-sidebar-toggle:hover {\n background: #e4e4e7;\n color: #18181b;\n }\n\n .sa-fp-sidebar-new {\n flex: 1;\n padding: 7px 12px;\n border: 1px solid #d4d4d8;\n border-radius: 8px;\n background: #fff;\n color: #3f3f46;\n font-size: 13px;\n font-weight: 500;\n cursor: pointer;\n display: flex;\n align-items: center;\n gap: 6px;\n transition: border-color 0.12s, box-shadow 0.12s;\n }\n\n .sa-fp-sidebar-new:hover {\n border-color: #a1a1aa;\n box-shadow: 0 1px 3px rgba(0,0,0,0.06);\n }\n\n .sa-fp-sidebar-new span {\n font-size: 13px;\n }\n\n .sa-fp-sidebar-list {\n flex: 1;\n overflow-y: auto;\n padding: 4px 8px 12px;\n }\n\n .sa-fp-sidebar-list::-webkit-scrollbar {\n width: 4px;\n }\n\n .sa-fp-sidebar-list::-webkit-scrollbar-thumb {\n background: rgba(0,0,0,0.08);\n border-radius: 2px;\n }\n\n .sa-fp-sidebar-list::-webkit-scrollbar-thumb:hover {\n background: rgba(0,0,0,0.15);\n }\n\n .sa-fp-sidebar-group {\n padding: 12px 8px 4px;\n font-size: 11px;\n font-weight: 500;\n color: #a1a1aa;\n letter-spacing: 0.3px;\n }\n\n .sa-fp-sidebar-item {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 10px;\n margin: 1px 0;\n border-radius: 8px;\n cursor: pointer;\n color: #3f3f46;\n font-size: 13px;\n line-height: 1.4;\n transition: background 0.1s;\n }\n\n .sa-fp-sidebar-item:hover {\n background: #e8e8ea;\n }\n\n .sa-fp-sidebar-item.active {\n background: #e4e4e7;\n color: #18181b;\n font-weight: 500;\n }\n\n .sa-fp-sidebar-item-title {\n flex: 1;\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n }\n\n .sa-fp-sidebar-item-action {\n width: 24px;\n height: 24px;\n border: none;\n border-radius: 6px;\n background: transparent;\n color: #a1a1aa;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n transition: color 0.1s, background 0.1s;\n }\n\n .sa-fp-sidebar-item-action:hover {\n color: #71717a;\n background: rgba(0,0,0,0.05);\n }\n\n .sa-fp-sidebar-item-action.danger {\n color: #ef4444;\n }\n\n .sa-fp-sidebar-item-action.danger:hover {\n color: #dc2626;\n background: rgba(239,68,68,0.08);\n }\n\n .sa-fp-sidebar-empty {\n padding: 32px 12px;\n text-align: center;\n color: #a1a1aa;\n font-size: 13px;\n }\n\n /* Sidebar wrapper (for custom ThreadList slot) */\n .sa-fp-sidebar-wrapper {\n width: 260px;\n flex-shrink: 0;\n overflow: hidden;\n border-right: 1px solid #e8e8ea;\n background: #f2f2f3;\n transition: width 0.2s cubic-bezier(0.16,1,0.3,1);\n }\n\n .sa-fp-sidebar-wrapper-collapsed {\n width: 0;\n }\n\n /* Main area */\n .sa-fp-main {\n flex: 1;\n display: flex;\n flex-direction: column;\n min-width: 0;\n background: #fff;\n }\n\n .sa-fp-header {\n display: flex;\n align-items: center;\n gap: 12px;\n padding: 10px 16px;\n border-bottom: 1px solid #f0f0f0;\n background: #fff;\n flex-shrink: 0;\n min-height: 52px;\n }\n\n .sa-fp-header-title {\n flex: 1;\n font-size: 15px;\n font-weight: 500;\n color: #18181b;\n letter-spacing: -0.2px;\n }\n\n .sa-fp-header-actions {\n display: flex;\n gap: 4px;\n }\n\n .sa-fp-header-btn {\n width: 34px;\n height: 34px;\n border: none;\n border-radius: 8px;\n background: transparent;\n color: #71717a;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.12s, color 0.12s;\n }\n\n .sa-fp-header-btn:hover {\n background: #f4f4f5;\n color: #18181b;\n }\n\n /* Fullpage thread/composer override */\n .sa-fp-main .sa-thread {\n margin: 0 auto;\n width: 100%;\n padding: 24px 24px;\n }\n\n .sa-fp-main .sa-composer {\n margin: 0 auto;\n width: 100%;\n padding: 12px 24px 20px;\n border-top: none;\n background: transparent;\n }\n\n .sa-fp-main .sa-composer-input {\n background: #f7f7f8;\n border: 1px solid #e4e4e7;\n box-shadow: none;\n }\n\n .sa-fp-main .sa-composer-input:focus {\n background: #fff;\n border-color: #d4d4d8;\n box-shadow: 0 0 0 3px rgba(99,102,241,0.08);\n }\n";
|
|
393
|
+
|
|
394
|
+
export { }
|