@kpritam/grimoire-output-docusaurus 0.1.8

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.
Files changed (65) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +25 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/index.d.ts +1 -0
  5. package/dist/index.js +1 -0
  6. package/dist/internal/assets.d.ts +9 -0
  7. package/dist/internal/assets.js +50 -0
  8. package/dist/internal/docusaurusConfig.d.ts +9 -0
  9. package/dist/internal/docusaurusConfig.js +259 -0
  10. package/dist/internal/spellbookAssets.d.ts +39 -0
  11. package/dist/internal/spellbookAssets.js +68 -0
  12. package/dist/layer.d.ts +3 -0
  13. package/dist/layer.js +6 -0
  14. package/dist/shared.d.ts +10 -0
  15. package/dist/shared.js +36 -0
  16. package/dist/upstream.d.ts +6 -0
  17. package/dist/upstream.js +84 -0
  18. package/package.json +59 -0
  19. package/src/index.ts +1 -0
  20. package/src/internal/assets.ts +66 -0
  21. package/src/internal/docusaurusConfig.ts +281 -0
  22. package/src/internal/spellbookAssets.ts +80 -0
  23. package/src/layer.ts +12 -0
  24. package/src/shared.ts +43 -0
  25. package/src/upstream.ts +119 -0
  26. package/templates/spellbook/spellbookPlugin.ts +156 -0
  27. package/templates/spellbook/src/components/SpellbookChat/ChatEngine.ts +79 -0
  28. package/templates/spellbook/src/components/SpellbookChat/ChatErrorBoundary.tsx +65 -0
  29. package/templates/spellbook/src/components/SpellbookChat/Markdown.tsx +259 -0
  30. package/templates/spellbook/src/components/SpellbookChat/README.md +111 -0
  31. package/templates/spellbook/src/components/SpellbookChat/SettingsPanel.tsx +376 -0
  32. package/templates/spellbook/src/components/SpellbookChat/VoiceMode.tsx +867 -0
  33. package/templates/spellbook/src/components/SpellbookChat/index.tsx +744 -0
  34. package/templates/spellbook/src/components/SpellbookChat/markdown.module.css +343 -0
  35. package/templates/spellbook/src/components/SpellbookChat/secretStore.ts +106 -0
  36. package/templates/spellbook/src/components/SpellbookChat/streamProviders/anthropic.ts +36 -0
  37. package/templates/spellbook/src/components/SpellbookChat/streamProviders/createCloudProvider.ts +112 -0
  38. package/templates/spellbook/src/components/SpellbookChat/streamProviders/google.ts +33 -0
  39. package/templates/spellbook/src/components/SpellbookChat/streamProviders/index.ts +32 -0
  40. package/templates/spellbook/src/components/SpellbookChat/streamProviders/mapFinishReason.ts +23 -0
  41. package/templates/spellbook/src/components/SpellbookChat/streamProviders/ollama.ts +44 -0
  42. package/templates/spellbook/src/components/SpellbookChat/streamProviders/openai.ts +34 -0
  43. package/templates/spellbook/src/components/SpellbookChat/streamProviders/openaiRealtime.ts +320 -0
  44. package/templates/spellbook/src/components/SpellbookChat/streamProviders/types.ts +172 -0
  45. package/templates/spellbook/src/components/SpellbookChat/streamProviders/webllm.ts +214 -0
  46. package/templates/spellbook/src/components/SpellbookChat/styles.module.css +852 -0
  47. package/templates/spellbook/src/components/SpellbookChat/systemPrompt.ts +107 -0
  48. package/templates/spellbook/src/components/SpellbookChat/transformers-ssr-stub.ts +16 -0
  49. package/templates/spellbook/src/components/SpellbookChat/types.ts +52 -0
  50. package/templates/spellbook/src/components/SpellbookChat/useBundleLoader.ts +46 -0
  51. package/templates/spellbook/src/components/SpellbookChat/useChatEngine.ts +524 -0
  52. package/templates/spellbook/src/components/SpellbookChat/useEmbeddings.ts +147 -0
  53. package/templates/spellbook/src/components/SpellbookChat/useRetrieval.ts +377 -0
  54. package/templates/spellbook/src/components/SpellbookChat/useSileroVAD.ts +236 -0
  55. package/templates/spellbook/src/components/SpellbookChat/useSpeechRecognition.ts +271 -0
  56. package/templates/spellbook/src/components/SpellbookChat/useSpeechSynthesis.ts +229 -0
  57. package/templates/spellbook/src/components/SpellbookChat/useUnifiedSTT.ts +134 -0
  58. package/templates/spellbook/src/components/SpellbookChat/useWhisperSTT.ts +411 -0
  59. package/templates/spellbook/src/components/SpellbookChat/vad-ssr-stub.ts +25 -0
  60. package/templates/spellbook/src/components/SpellbookChat/voiceDebug.ts +60 -0
  61. package/templates/spellbook/src/components/SpellbookChat/voiceFsm.ts +196 -0
  62. package/templates/spellbook/src/components/SpellbookChat/voiceStyles.module.css +334 -0
  63. package/templates/spellbook/src/components/SpellbookChat/webllm-ssr-stub.ts +8 -0
  64. package/templates/spellbook/src/components/SpellbookChatDisabled.tsx +20 -0
  65. package/templates/spellbook/src/theme/Root.tsx +29 -0
@@ -0,0 +1,852 @@
1
+ /* Spellbook Chat — scoped panel; uses global :root / custom.css tokens */
2
+
3
+ .launcher {
4
+ position: fixed;
5
+ right: var(--grim-space-lg);
6
+ bottom: var(--grim-space-lg);
7
+ z-index: calc(var(--ifm-z-index-fixed, 200) + 20);
8
+ display: flex;
9
+ flex-direction: column;
10
+ align-items: center;
11
+ gap: var(--grim-space-2xs);
12
+ padding: 0;
13
+ margin: 0;
14
+ border: none;
15
+ background: transparent;
16
+ cursor: pointer;
17
+ font-family: var(--grim-font-ui);
18
+ color: var(--grim-text-muted);
19
+ transition: color var(--grim-dur-med) var(--grim-ease-out);
20
+ }
21
+
22
+ .launcher:hover,
23
+ .launcher:focus-visible {
24
+ color: var(--grim-violet);
25
+ }
26
+
27
+ .launcher:focus-visible {
28
+ outline: 2px solid var(--grim-violet);
29
+ outline-offset: 3px;
30
+ border-radius: var(--grim-radius-lg);
31
+ }
32
+
33
+ .launcherSigil {
34
+ position: relative;
35
+ width: 3.25rem;
36
+ height: 3.25rem;
37
+ border-radius: 50%;
38
+ background: radial-gradient(
39
+ circle at 35% 30%,
40
+ oklch(0.88 0.08 300 / 0.55),
41
+ transparent 55%
42
+ ),
43
+ radial-gradient(circle at 50% 100%, var(--grim-surface-2), var(--grim-bg-deep));
44
+ box-shadow: var(--grim-glow-violet);
45
+ border: 1px solid var(--grim-rule-strong);
46
+ display: grid;
47
+ place-items: center;
48
+ animation: sigilPulse 2.6s var(--grim-ease-out-quart) infinite;
49
+ }
50
+
51
+ .launcherSigilInner {
52
+ width: 1.35rem;
53
+ height: 1.35rem;
54
+ border-radius: 50%;
55
+ border: 2px solid var(--grim-violet);
56
+ box-shadow: inset 0 0 12px oklch(0.72 0.2 300 / 0.45);
57
+ opacity: 0.95;
58
+ }
59
+
60
+ .launcherLabel {
61
+ font-size: 0.7rem;
62
+ font-weight: 600;
63
+ letter-spacing: 0.04em;
64
+ text-transform: uppercase;
65
+ max-width: 6.5rem;
66
+ text-align: center;
67
+ line-height: 1.25;
68
+ }
69
+
70
+ .backdrop {
71
+ position: fixed;
72
+ inset: 0;
73
+ background: oklch(0.06 0.02 280 / 0.55);
74
+ z-index: calc(var(--ifm-z-index-fixed, 200) + 15);
75
+ opacity: 0;
76
+ pointer-events: none;
77
+ transition: opacity var(--grim-dur-med) var(--grim-ease-out);
78
+ }
79
+
80
+ .backdropVisible {
81
+ opacity: 1;
82
+ pointer-events: auto;
83
+ }
84
+
85
+ .panel {
86
+ position: fixed;
87
+ top: 0;
88
+ right: 0;
89
+ bottom: 0;
90
+ width: min(420px, 100vw);
91
+ z-index: calc(var(--ifm-z-index-fixed, 200) + 25);
92
+ background: var(--grim-bg-deep);
93
+ border-left: 1px solid var(--grim-rule);
94
+ box-shadow: -20px 0 48px oklch(0.05 0.02 280 / 0.55);
95
+ transform: translateX(102%);
96
+ transition: transform var(--grim-dur-slow) var(--grim-ease-spring),
97
+ width var(--grim-dur-med) var(--grim-ease-out-quart);
98
+ display: flex;
99
+ flex-direction: column;
100
+ font-family: var(--grim-font-ui);
101
+ }
102
+
103
+ .panelOpen {
104
+ transform: translateX(0);
105
+ }
106
+
107
+ .panelExpanded {
108
+ width: min(960px, 96vw);
109
+ box-shadow: -32px 0 80px oklch(0.04 0.02 280 / 0.7);
110
+ }
111
+
112
+ .panelInner {
113
+ display: flex;
114
+ flex-direction: column;
115
+ flex: 1;
116
+ min-height: 0;
117
+ }
118
+
119
+ .header {
120
+ display: flex;
121
+ align-items: flex-start;
122
+ gap: var(--grim-space-sm);
123
+ padding: var(--grim-space-md);
124
+ padding-top: var(--grim-space-lg);
125
+ border-bottom: 1px solid var(--grim-rule);
126
+ background: linear-gradient(
127
+ 180deg,
128
+ oklch(0.16 0.03 282 / 0.95),
129
+ var(--grim-bg-deep)
130
+ );
131
+ }
132
+
133
+ .headerMain {
134
+ flex: 1;
135
+ min-width: 0;
136
+ }
137
+
138
+ .kicker {
139
+ display: inline-flex;
140
+ align-items: baseline;
141
+ gap: 0.35em;
142
+ font-family: var(--grim-font-sc);
143
+ text-transform: uppercase;
144
+ letter-spacing: 0.12em;
145
+ font-size: 0.65rem;
146
+ color: var(--grim-text-subtle);
147
+ }
148
+
149
+ .kickerNum {
150
+ color: var(--grim-gold);
151
+ font-weight: 600;
152
+ }
153
+
154
+ .titleRow {
155
+ display: flex;
156
+ align-items: center;
157
+ justify-content: space-between;
158
+ gap: var(--grim-space-sm);
159
+ margin-top: var(--grim-space-xs);
160
+ }
161
+
162
+ .title {
163
+ font-family: var(--grim-font-display);
164
+ font-size: 1.35rem;
165
+ line-height: 1.2;
166
+ color: var(--grim-text);
167
+ margin: 0;
168
+ }
169
+
170
+ .repo {
171
+ margin: var(--grim-space-xs) 0 0;
172
+ font-size: 0.78rem;
173
+ color: var(--grim-text-muted);
174
+ white-space: nowrap;
175
+ overflow: hidden;
176
+ text-overflow: ellipsis;
177
+ }
178
+
179
+ .headerActions {
180
+ display: flex;
181
+ align-items: center;
182
+ gap: 0.3rem;
183
+ flex-shrink: 0;
184
+ }
185
+
186
+ .iconButton {
187
+ flex-shrink: 0;
188
+ width: 2rem;
189
+ height: 2rem;
190
+ padding: 0;
191
+ border-radius: var(--grim-radius-sm);
192
+ border: 1px solid var(--grim-rule);
193
+ background: var(--grim-surface);
194
+ color: var(--grim-text-muted);
195
+ cursor: pointer;
196
+ display: grid;
197
+ place-items: center;
198
+ transition: color var(--grim-dur-fast) var(--grim-ease-out),
199
+ border-color var(--grim-dur-fast) var(--grim-ease-out),
200
+ background var(--grim-dur-fast) var(--grim-ease-out),
201
+ transform var(--grim-dur-fast) var(--grim-ease-out);
202
+ }
203
+
204
+ .iconButton:hover:not(:disabled) {
205
+ color: var(--grim-gold);
206
+ border-color: var(--grim-rule-strong);
207
+ background: var(--grim-surface-2);
208
+ }
209
+
210
+ .iconButton:active:not(:disabled) {
211
+ transform: scale(0.94);
212
+ }
213
+
214
+ .iconButton:disabled {
215
+ opacity: 0.35;
216
+ cursor: not-allowed;
217
+ }
218
+
219
+ .iconButton[aria-pressed="true"] {
220
+ color: var(--grim-gold);
221
+ background: oklch(0.22 0.05 285);
222
+ border-color: oklch(0.55 0.18 78 / 0.55);
223
+ }
224
+
225
+ .iconButton:focus-visible {
226
+ outline: 2px solid var(--grim-violet);
227
+ outline-offset: 2px;
228
+ }
229
+
230
+ .closeButton {
231
+ composes: iconButton;
232
+ }
233
+
234
+ .settingsButton {
235
+ composes: iconButton;
236
+ }
237
+
238
+ .statusBar {
239
+ padding: var(--grim-space-sm) var(--grim-space-md);
240
+ border-bottom: 1px solid var(--grim-rule);
241
+ background: var(--grim-surface);
242
+ }
243
+
244
+ .statusText {
245
+ font-size: 0.78rem;
246
+ color: var(--grim-text-muted);
247
+ margin: 0 0 var(--grim-space-xs);
248
+ }
249
+
250
+ .progressTrack {
251
+ height: 3px;
252
+ border-radius: 999px;
253
+ background: var(--grim-surface-3);
254
+ overflow: hidden;
255
+ }
256
+
257
+ .progressFill {
258
+ height: 100%;
259
+ background: linear-gradient(90deg, var(--grim-violet-deep), var(--grim-violet));
260
+ border-radius: inherit;
261
+ transition: width var(--grim-dur-med) var(--grim-ease-out);
262
+ }
263
+
264
+ .progressFillIndeterminate {
265
+ height: 100%;
266
+ width: 42%;
267
+ border-radius: inherit;
268
+ background: linear-gradient(
269
+ 90deg,
270
+ var(--grim-violet-deep),
271
+ var(--grim-violet),
272
+ var(--grim-cyan-deep)
273
+ );
274
+ animation: progressSweep 1.35s var(--grim-ease-out-quart) infinite;
275
+ }
276
+
277
+ @keyframes progressSweep {
278
+ 0% {
279
+ transform: translateX(-100%);
280
+ }
281
+ 100% {
282
+ transform: translateX(280%);
283
+ }
284
+ }
285
+
286
+ .errorBanner {
287
+ margin: var(--grim-space-md);
288
+ padding: var(--grim-space-sm) var(--grim-space-md);
289
+ border-radius: var(--grim-radius-md);
290
+ border: 1px solid oklch(0.55 0.18 25 / 0.45);
291
+ background: oklch(0.22 0.05 25 / 0.45);
292
+ color: oklch(0.92 0.04 25);
293
+ font-size: 0.85rem;
294
+ line-height: 1.45;
295
+ }
296
+
297
+ .errorActions {
298
+ margin-top: var(--grim-space-sm);
299
+ display: flex;
300
+ gap: var(--grim-space-sm);
301
+ }
302
+
303
+ .messages {
304
+ flex: 1;
305
+ overflow: auto;
306
+ padding: var(--grim-space-md);
307
+ display: flex;
308
+ flex-direction: column;
309
+ gap: var(--grim-space-md);
310
+ scroll-behavior: smooth;
311
+ }
312
+
313
+ .panelExpanded .messages {
314
+ padding: var(--grim-space-lg) var(--grim-space-xl);
315
+ }
316
+
317
+ .panelExpanded .bubble {
318
+ max-width: 78%;
319
+ font-size: 0.95rem;
320
+ }
321
+
322
+ .panelExpanded .bubbleRow {
323
+ margin: 0 auto;
324
+ width: 100%;
325
+ max-width: 780px;
326
+ }
327
+
328
+ .panelExpanded .footer {
329
+ padding: var(--grim-space-md) var(--grim-space-xl);
330
+ }
331
+
332
+ .panelExpanded .composer {
333
+ margin: 0 auto;
334
+ width: 100%;
335
+ max-width: 780px;
336
+ }
337
+
338
+ .bubbleRow {
339
+ display: flex;
340
+ }
341
+
342
+ .bubbleRowUser {
343
+ justify-content: flex-end;
344
+ }
345
+
346
+ .bubble {
347
+ max-width: 92%;
348
+ padding: 0.7rem 0.95rem;
349
+ border-radius: var(--grim-radius-lg);
350
+ font-family: var(--grim-font-chat);
351
+ font-size: 0.92rem;
352
+ line-height: 1.55;
353
+ letter-spacing: 0;
354
+ color: var(--grim-text);
355
+ font-feature-settings: "ss01", "cv11";
356
+ }
357
+
358
+ .bubbleUser {
359
+ background: linear-gradient(
360
+ 135deg,
361
+ oklch(0.28 0.06 300 / 0.9),
362
+ var(--grim-surface-2)
363
+ );
364
+ border: 1px solid var(--grim-rule);
365
+ white-space: pre-wrap;
366
+ }
367
+
368
+ .bubbleAssistant {
369
+ background: var(--grim-surface);
370
+ border: 1px solid var(--grim-rule);
371
+ }
372
+
373
+ .bubbleAssistantError {
374
+ border-color: oklch(0.55 0.18 25 / 0.55);
375
+ background: oklch(0.22 0.05 25 / 0.4);
376
+ }
377
+
378
+ .typingDots {
379
+ display: inline-flex;
380
+ align-items: center;
381
+ gap: 0.25rem;
382
+ padding: 0.15rem 0;
383
+ }
384
+
385
+ .typingDots > span {
386
+ width: 6px;
387
+ height: 6px;
388
+ border-radius: 50%;
389
+ background: var(--grim-text-subtle);
390
+ animation: typingPulse 1.1s var(--grim-ease-out-quart) infinite;
391
+ }
392
+
393
+ .typingDots > span:nth-child(2) {
394
+ animation-delay: 0.18s;
395
+ }
396
+
397
+ .typingDots > span:nth-child(3) {
398
+ animation-delay: 0.36s;
399
+ }
400
+
401
+ @keyframes typingPulse {
402
+ 0%,
403
+ 100% {
404
+ opacity: 0.3;
405
+ transform: translateY(0);
406
+ }
407
+ 50% {
408
+ opacity: 1;
409
+ transform: translateY(-2px);
410
+ }
411
+ }
412
+
413
+ .bubbleMeta {
414
+ margin-top: var(--grim-space-xs);
415
+ font-size: 0.72rem;
416
+ color: var(--grim-text-subtle);
417
+ font-family: var(--grim-font-mono);
418
+ }
419
+
420
+ .truncatedNotice {
421
+ margin: var(--grim-space-sm) 0 0;
422
+ padding: var(--grim-space-xs) var(--grim-space-sm);
423
+ border-radius: var(--grim-radius-sm, 6px);
424
+ background: oklch(0.32 0.07 80 / 0.32);
425
+ border: 1px solid oklch(0.55 0.12 80 / 0.45);
426
+ color: var(--grim-text);
427
+ font-size: 0.78rem;
428
+ line-height: 1.35;
429
+ }
430
+
431
+ .citations {
432
+ margin-top: var(--grim-space-md);
433
+ display: flex;
434
+ flex-direction: column;
435
+ gap: var(--grim-space-xs);
436
+ }
437
+
438
+ .citationsTitle {
439
+ font-size: 0.68rem;
440
+ font-family: var(--grim-font-sc);
441
+ letter-spacing: 0.1em;
442
+ text-transform: uppercase;
443
+ color: var(--grim-text-subtle);
444
+ margin: 0 0 var(--grim-space-2xs);
445
+ }
446
+
447
+ .citationCard {
448
+ display: block;
449
+ padding: var(--grim-space-sm) var(--grim-space-md);
450
+ border-radius: var(--grim-radius-md);
451
+ border: 1px solid var(--grim-rule);
452
+ background: var(--grim-bg);
453
+ text-decoration: none;
454
+ color: inherit;
455
+ transition: border-color var(--grim-dur-fast) var(--grim-ease-out),
456
+ box-shadow var(--grim-dur-fast) var(--grim-ease-out);
457
+ }
458
+
459
+ .citationCard[href]:hover {
460
+ border-color: var(--grim-violet);
461
+ box-shadow: var(--grim-glow-violet);
462
+ }
463
+
464
+ .citationPath {
465
+ font-family: var(--grim-font-mono);
466
+ font-size: 0.78rem;
467
+ color: var(--grim-gold);
468
+ word-break: break-all;
469
+ }
470
+
471
+ .citationHeadings {
472
+ margin: var(--grim-space-2xs) 0 0;
473
+ font-size: 0.76rem;
474
+ color: var(--grim-text-muted);
475
+ }
476
+
477
+ .footer {
478
+ padding: var(--grim-space-md);
479
+ border-top: 1px solid var(--grim-rule);
480
+ background: linear-gradient(0deg, var(--grim-bg-deep), var(--grim-surface));
481
+ display: flex;
482
+ flex-direction: column;
483
+ gap: var(--grim-space-sm);
484
+ }
485
+
486
+ .modeTabs {
487
+ display: inline-flex;
488
+ align-self: flex-start;
489
+ padding: 0.2rem;
490
+ gap: 0.2rem;
491
+ border-radius: var(--grim-radius-md);
492
+ background: var(--grim-bg);
493
+ border: 1px solid var(--grim-rule);
494
+ }
495
+
496
+ .modeTab {
497
+ appearance: none;
498
+ border: none;
499
+ background: transparent;
500
+ color: var(--grim-text-muted);
501
+ font-family: var(--grim-font-ui);
502
+ font-size: 0.78rem;
503
+ letter-spacing: 0.02em;
504
+ padding: 0.4rem 0.8rem;
505
+ border-radius: calc(var(--grim-radius-md) - 0.2rem);
506
+ cursor: pointer;
507
+ transition: color var(--grim-dur-fast) var(--grim-ease-out),
508
+ background var(--grim-dur-fast) var(--grim-ease-out);
509
+ }
510
+
511
+ .modeTab:hover:not([aria-selected="true"]) {
512
+ color: var(--grim-text);
513
+ }
514
+
515
+ .modeTabActive,
516
+ .modeTab[aria-selected="true"] {
517
+ background: linear-gradient(
518
+ 135deg,
519
+ oklch(0.32 0.14 300 / 0.65),
520
+ oklch(0.22 0.08 300 / 0.65)
521
+ );
522
+ color: var(--grim-text);
523
+ box-shadow: 0 0 0 1px oklch(0.72 0.2 300 / 0.4);
524
+ }
525
+
526
+ .composer {
527
+ display: flex;
528
+ gap: var(--grim-space-sm);
529
+ align-items: flex-end;
530
+ }
531
+
532
+ .textarea {
533
+ flex: 1;
534
+ min-height: 3.25rem;
535
+ max-height: 8rem;
536
+ resize: vertical;
537
+ padding: var(--grim-space-sm) var(--grim-space-md);
538
+ border-radius: var(--grim-radius-md);
539
+ border: 1px solid var(--grim-rule);
540
+ background: var(--grim-bg);
541
+ color: var(--grim-text);
542
+ font-family: var(--grim-font-ui);
543
+ font-size: 0.9rem;
544
+ line-height: 1.45;
545
+ }
546
+
547
+ .textarea:focus {
548
+ outline: none;
549
+ border-color: var(--grim-violet);
550
+ box-shadow: 0 0 0 1px oklch(0.72 0.2 300 / 0.35);
551
+ }
552
+
553
+ .textarea:disabled {
554
+ opacity: 0.55;
555
+ }
556
+
557
+ .sendButton {
558
+ flex-shrink: 0;
559
+ height: 2.75rem;
560
+ padding: 0 var(--grim-space-md);
561
+ border-radius: var(--grim-radius-md);
562
+ border: none;
563
+ font-family: var(--grim-font-ui);
564
+ font-weight: 600;
565
+ font-size: 0.82rem;
566
+ cursor: pointer;
567
+ background: linear-gradient(
568
+ 135deg,
569
+ var(--grim-gold-deep),
570
+ oklch(0.68 0.16 78)
571
+ );
572
+ color: var(--grim-accent-contrast);
573
+ box-shadow: var(--grim-glow-gold);
574
+ transition: transform var(--grim-dur-fast) var(--grim-ease-spring),
575
+ filter var(--grim-dur-fast) var(--grim-ease-out);
576
+ }
577
+
578
+ .sendButton:hover:not(:disabled) {
579
+ transform: translateY(-1px);
580
+ filter: brightness(1.06);
581
+ }
582
+
583
+ .sendButton:disabled {
584
+ opacity: 0.45;
585
+ cursor: not-allowed;
586
+ box-shadow: none;
587
+ }
588
+
589
+ .settingsInline {
590
+ padding: var(--grim-space-md);
591
+ }
592
+
593
+ .settingsCard {
594
+ composes: settingsInline;
595
+ margin: var(--grim-space-md);
596
+ border-radius: var(--grim-radius-lg);
597
+ border: 1px solid var(--grim-rule);
598
+ background: var(--grim-surface);
599
+ }
600
+
601
+ .settingsTitle {
602
+ font-family: var(--grim-font-display);
603
+ font-size: 1.05rem;
604
+ margin: 0 0 var(--grim-space-sm);
605
+ color: var(--grim-text);
606
+ }
607
+
608
+ .settingsHelp {
609
+ margin: 0 0 var(--grim-space-md);
610
+ font-size: 0.86rem;
611
+ line-height: 1.55;
612
+ color: var(--grim-text-muted);
613
+ }
614
+
615
+ .settingsHelp em {
616
+ color: var(--grim-violet);
617
+ font-style: italic;
618
+ }
619
+
620
+ .settingsForm {
621
+ display: flex;
622
+ flex-direction: column;
623
+ gap: var(--grim-space-xs);
624
+ }
625
+
626
+ .settingsLabel {
627
+ font-size: 0.7rem;
628
+ font-weight: 600;
629
+ letter-spacing: 0.06em;
630
+ text-transform: uppercase;
631
+ color: var(--grim-text-subtle);
632
+ }
633
+
634
+ .settingsSelect {
635
+ width: 100%;
636
+ padding: var(--grim-space-sm) var(--grim-space-md);
637
+ border-radius: var(--grim-radius-md);
638
+ border: 1px solid var(--grim-rule);
639
+ background: var(--grim-bg);
640
+ color: var(--grim-text);
641
+ font-family: var(--grim-font-ui);
642
+ font-size: 0.82rem;
643
+ }
644
+
645
+ .providerTagline {
646
+ margin: 0 0 var(--grim-space-sm);
647
+ font-size: 0.76rem;
648
+ line-height: 1.45;
649
+ color: var(--grim-text-subtle);
650
+ }
651
+
652
+ .settingsFieldGroup {
653
+ display: flex;
654
+ flex-direction: column;
655
+ gap: var(--grim-space-2xs);
656
+ }
657
+
658
+ .fieldHelp {
659
+ margin: 0;
660
+ font-size: 0.74rem;
661
+ line-height: 1.45;
662
+ color: var(--grim-text-subtle);
663
+ }
664
+
665
+ .preloadPanel {
666
+ margin: var(--grim-space-sm) 0 var(--grim-space-md);
667
+ padding: var(--grim-space-sm) 0 0;
668
+ border-top: 1px solid var(--grim-rule);
669
+ }
670
+
671
+ .preloadText {
672
+ margin: 0 0 var(--grim-space-xs);
673
+ font-size: 0.78rem;
674
+ color: var(--grim-text-muted);
675
+ }
676
+
677
+ .settingsInput {
678
+ width: 100%;
679
+ padding: var(--grim-space-sm) var(--grim-space-md);
680
+ border-radius: var(--grim-radius-md);
681
+ border: 1px solid var(--grim-rule);
682
+ background: var(--grim-bg);
683
+ color: var(--grim-text);
684
+ font-family: var(--grim-font-mono);
685
+ font-size: 0.82rem;
686
+ }
687
+
688
+ .settingsActions {
689
+ display: flex;
690
+ flex-wrap: wrap;
691
+ gap: var(--grim-space-sm);
692
+ margin-top: var(--grim-space-sm);
693
+ }
694
+
695
+ .buttonPrimary {
696
+ padding: var(--grim-space-xs) var(--grim-space-md);
697
+ border-radius: var(--grim-radius-md);
698
+ border: none;
699
+ background: var(--grim-violet-deep);
700
+ color: var(--grim-text);
701
+ font-family: var(--grim-font-ui);
702
+ font-weight: 600;
703
+ font-size: 0.82rem;
704
+ cursor: pointer;
705
+ }
706
+
707
+ .buttonPrimary:hover {
708
+ filter: brightness(1.08);
709
+ }
710
+
711
+ .buttonGhost {
712
+ padding: var(--grim-space-xs) var(--grim-space-md);
713
+ border-radius: var(--grim-radius-md);
714
+ border: 1px solid var(--grim-rule);
715
+ background: transparent;
716
+ color: var(--grim-text-muted);
717
+ font-family: var(--grim-font-ui);
718
+ font-size: 0.82rem;
719
+ cursor: pointer;
720
+ }
721
+
722
+ .buttonGhost:hover {
723
+ border-color: var(--grim-rule-strong);
724
+ color: var(--grim-text);
725
+ }
726
+
727
+ .degraded {
728
+ padding: var(--grim-space-md);
729
+ display: flex;
730
+ flex-direction: column;
731
+ align-items: center;
732
+ text-align: center;
733
+ gap: var(--grim-space-sm);
734
+ color: var(--grim-text-muted);
735
+ font-size: 0.88rem;
736
+ line-height: 1.55;
737
+ }
738
+
739
+ .degradedIcon {
740
+ font-size: 2rem;
741
+ line-height: 1;
742
+ filter: grayscale(0.2);
743
+ }
744
+
745
+ .screenReader {
746
+ position: absolute;
747
+ width: 1px;
748
+ height: 1px;
749
+ padding: 0;
750
+ margin: -1px;
751
+ overflow: hidden;
752
+ clip: rect(0, 0, 0, 0);
753
+ white-space: nowrap;
754
+ border: 0;
755
+ }
756
+
757
+ @keyframes sigilPulse {
758
+ 0%,
759
+ 100% {
760
+ box-shadow: var(--grim-glow-violet);
761
+ transform: scale(1);
762
+ }
763
+ 50% {
764
+ box-shadow: 0 0 0 1px oklch(0.72 0.2 300 / 0.35),
765
+ 0 10px 36px -10px oklch(0.72 0.2 300 / 0.65);
766
+ transform: scale(1.03);
767
+ }
768
+ }
769
+
770
+ /* =============================================================
771
+ LIGHT THEME OVERRIDES — hardcoded dark oklch() values above
772
+ don't respond to the theme switch; correct them here.
773
+ ============================================================= */
774
+
775
+ /* Backdrop: warm parchment scrim instead of near-black */
776
+ :global([data-theme="light"]) .backdrop {
777
+ background: oklch(0.55 0.015 72 / 0.22);
778
+ }
779
+
780
+ :global([data-theme="light"]) .panel {
781
+ box-shadow: -20px 0 48px oklch(0.55 0.05 68 / 0.12);
782
+ }
783
+
784
+ :global([data-theme="light"]) .panelExpanded {
785
+ box-shadow: -32px 0 80px oklch(0.55 0.05 68 / 0.15);
786
+ }
787
+
788
+ /* Header: amber-kissed parchment gradient instead of flat near-white */
789
+ :global([data-theme="light"]) .header {
790
+ background: linear-gradient(
791
+ 180deg,
792
+ color-mix(in oklch, var(--grim-gold) 8%, oklch(0.968 0.012 80 / 0.98)),
793
+ var(--grim-bg-deep)
794
+ );
795
+ border-bottom-color: color-mix(in oklch, var(--grim-gold) 35%, var(--grim-rule));
796
+ }
797
+
798
+ /* Kicker label: warm amber-adjacent rather than cool gray */
799
+ :global([data-theme="light"]) .kicker {
800
+ color: oklch(0.52 0.05 68);
801
+ }
802
+
803
+ /* User bubble — first stop was hardcoded dark violet */
804
+ :global([data-theme="light"]) .bubbleUser {
805
+ background: linear-gradient(
806
+ 135deg,
807
+ oklch(0.9 0.05 298 / 0.75),
808
+ var(--grim-surface-2)
809
+ );
810
+ }
811
+
812
+ /* Pressed icon button — hardcoded dark background */
813
+ :global([data-theme="light"]) .iconButton[aria-pressed="true"] {
814
+ background: oklch(0.92 0.04 285);
815
+ border-color: oklch(0.5 0.22 298 / 0.4);
816
+ color: var(--grim-violet-deep);
817
+ }
818
+
819
+ /* Active mode tab — hardcoded dark gradient */
820
+ :global([data-theme="light"]) .modeTabActive,
821
+ :global([data-theme="light"]) .modeTab[aria-selected="true"] {
822
+ background: linear-gradient(
823
+ 135deg,
824
+ oklch(0.88 0.07 298 / 0.65),
825
+ oklch(0.92 0.04 298 / 0.65)
826
+ );
827
+ box-shadow: 0 0 0 1px oklch(0.5 0.22 298 / 0.3);
828
+ color: var(--grim-violet-deep);
829
+ }
830
+
831
+ /* Footer: amber-tinted separator + grounded gradient */
832
+ :global([data-theme="light"]) .footer {
833
+ background: linear-gradient(
834
+ 0deg,
835
+ var(--grim-surface),
836
+ color-mix(in oklch, var(--grim-gold) 4%, var(--grim-bg-deep))
837
+ );
838
+ border-top-color: color-mix(in oklch, var(--grim-gold) 30%, var(--grim-rule));
839
+ }
840
+
841
+ /* Truncated notice: amber wash instead of dark warm overlay */
842
+ :global([data-theme="light"]) .truncatedNotice {
843
+ background: color-mix(in oklch, var(--grim-gold) 10%, var(--grim-surface));
844
+ border-color: color-mix(in oklch, var(--grim-gold) 28%, var(--grim-rule));
845
+ }
846
+
847
+ /* Error banner: light-appropriate warm red */
848
+ :global([data-theme="light"]) .errorBanner {
849
+ background: oklch(0.97 0.015 25);
850
+ border-color: oklch(0.65 0.18 25 / 0.5);
851
+ color: oklch(0.36 0.18 25);
852
+ }