@braincrew-lab/langchain-canvas 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.
@@ -0,0 +1,1066 @@
1
+ /* Canvas SDK — default stylesheet.
2
+ *
3
+ * Import once at your app root: `import "@braincrew-lab/langchain-canvas/styles.css";`
4
+ * Everything is namespaced under `cv-` and driven by CSS variables, so you can
5
+ * retheme by overriding the `--cv-*` tokens without forking this file.
6
+ */
7
+
8
+ :root {
9
+ --cv-bg: #ffffff;
10
+ --cv-surface: #f7f7f8;
11
+ --cv-border: #e5e7eb;
12
+ --cv-text: #1f2328;
13
+ --cv-muted: #6b7280;
14
+ --cv-accent: #6366f1;
15
+ --cv-accent-weak: #eef2ff;
16
+ --cv-radius: 12px;
17
+ --cv-font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
18
+ --cv-mono: "SF Mono", "JetBrains Mono", Menlo, Consolas, monospace;
19
+ }
20
+
21
+ @media (prefers-color-scheme: dark) {
22
+ :root {
23
+ --cv-bg: #0f1115;
24
+ --cv-surface: #171a21;
25
+ --cv-border: #262b36;
26
+ --cv-text: #e6e8eb;
27
+ --cv-muted: #9aa4b2;
28
+ --cv-accent: #818cf8;
29
+ --cv-accent-weak: #1e2130;
30
+ }
31
+ }
32
+
33
+ /* --- entrance animations ------------------------------------------------------ */
34
+
35
+ @keyframes cv-fade {
36
+ from { opacity: 0; }
37
+ to { opacity: 1; }
38
+ }
39
+ @keyframes cv-pop {
40
+ from { opacity: 0; transform: translateY(6px) scale(0.98); }
41
+ to { opacity: 1; transform: none; }
42
+ }
43
+ /* Containers fade only — never `transform`. A transform on an ancestor creates a
44
+ * containing block that breaks the free-canvas drag math and the fixed-position
45
+ * Present overlay, so the entrance for panels/bodies is strictly opacity. */
46
+ .cv-canvas:not(.cv-canvas--empty) { animation: cv-fade 0.32s ease; }
47
+ .cv-body { animation: cv-fade 0.34s ease; }
48
+ .cv-header { animation: cv-fade 0.4s ease; }
49
+ .cv-canvas--empty .cv-empty { animation: cv-fade 0.45s ease; }
50
+ /* Small, self-contained overlays/cards can safely rise/pop (no interactive
51
+ * absolutely-positioned or fixed descendants). */
52
+ .cv-card { animation: cv-pop 0.26s cubic-bezier(0.22, 1, 0.36, 1); }
53
+ .cv-selection, .cv-style { animation: cv-pop 0.18s ease; }
54
+
55
+ @media (prefers-reduced-motion: reduce) {
56
+ .cv-canvas, .cv-body, .cv-header, .cv-card, .cv-empty, .cv-selection, .cv-style { animation: none !important; }
57
+ }
58
+
59
+ /* --- panel shell -------------------------------------------------------------- */
60
+
61
+ .cv-canvas {
62
+ position: relative;
63
+ display: flex;
64
+ flex-direction: column;
65
+ height: 100%;
66
+ /* min-width: 0 so the panel can shrink below its content's min width in a flex/
67
+ grid host — otherwise a wide spreadsheet toolbar pushes the whole page wider. */
68
+ min-width: 0;
69
+ background: var(--cv-bg);
70
+ color: var(--cv-text);
71
+ font-family: var(--cv-font);
72
+ border-left: 1px solid var(--cv-border);
73
+ overflow: hidden;
74
+ }
75
+
76
+ .cv-canvas--empty {
77
+ align-items: center;
78
+ justify-content: center;
79
+ }
80
+
81
+ .cv-tabs {
82
+ display: flex;
83
+ gap: 4px;
84
+ padding: 8px 12px 0;
85
+ overflow-x: auto;
86
+ border-bottom: 1px solid var(--cv-border);
87
+ scrollbar-width: none;
88
+ }
89
+ .cv-tabs::-webkit-scrollbar { display: none; }
90
+
91
+ .cv-tab {
92
+ padding: 8px 14px;
93
+ border: none;
94
+ background: transparent;
95
+ color: var(--cv-muted);
96
+ font-size: 13px;
97
+ font-weight: 500;
98
+ border-radius: 8px 8px 0 0;
99
+ cursor: pointer;
100
+ white-space: nowrap;
101
+ transition: color 0.15s, background 0.15s;
102
+ }
103
+ .cv-tab:hover { color: var(--cv-text); background: var(--cv-surface); }
104
+ .cv-tab.is-active { color: var(--cv-accent); background: var(--cv-accent-weak); }
105
+
106
+ /* --- header ------------------------------------------------------------------- */
107
+
108
+ .cv-header {
109
+ display: flex;
110
+ align-items: center;
111
+ justify-content: space-between;
112
+ gap: 12px;
113
+ padding: 14px 18px;
114
+ border-bottom: 1px solid var(--cv-border);
115
+ }
116
+
117
+ .cv-header__title { display: flex; align-items: center; gap: 10px; min-width: 0; }
118
+ .cv-header__title h2 {
119
+ margin: 0;
120
+ font-size: 15px;
121
+ font-weight: 600;
122
+ white-space: nowrap;
123
+ overflow: hidden;
124
+ text-overflow: ellipsis;
125
+ }
126
+
127
+ .cv-badge {
128
+ font-size: 11px;
129
+ font-weight: 600;
130
+ padding: 2px 8px;
131
+ border-radius: 999px;
132
+ white-space: nowrap;
133
+ }
134
+ .cv-badge--streaming { color: var(--cv-accent); background: var(--cv-accent-weak); }
135
+ .cv-badge--complete { color: #059669; background: rgba(16, 185, 129, 0.12); }
136
+ .cv-badge--error { color: #dc2626; background: rgba(239, 68, 68, 0.12); }
137
+
138
+ .cv-undo { display: inline-flex; gap: 2px; }
139
+ .cv-undo button {
140
+ width: 30px; height: 30px; border: 1px solid var(--cv-border); border-radius: 7px;
141
+ background: var(--cv-bg); color: var(--cv-text); cursor: pointer; font-size: 15px; line-height: 1;
142
+ }
143
+ .cv-undo button:hover:not(:disabled) { background: var(--cv-surface); }
144
+ .cv-undo button:disabled { opacity: 0.35; cursor: default; }
145
+
146
+ .cv-versions { display: flex; align-items: center; gap: 6px; }
147
+ .cv-versions__label { font-size: 12px; color: var(--cv-muted); font-variant-numeric: tabular-nums; }
148
+ .cv-versions__nav {
149
+ width: 24px;
150
+ height: 24px;
151
+ border: 1px solid var(--cv-border);
152
+ border-radius: 6px;
153
+ background: var(--cv-surface);
154
+ color: var(--cv-text);
155
+ cursor: pointer;
156
+ line-height: 1;
157
+ }
158
+ .cv-versions__nav:disabled { opacity: 0.4; cursor: default; }
159
+
160
+ .cv-header__actions { display: flex; align-items: center; gap: 10px; }
161
+
162
+ /* --- export menu -------------------------------------------------------------- */
163
+
164
+ .cv-export { position: relative; }
165
+ .cv-export__btn {
166
+ padding: 6px 12px;
167
+ border: 1px solid var(--cv-border);
168
+ border-radius: 8px;
169
+ background: var(--cv-surface);
170
+ color: var(--cv-text);
171
+ font-size: 13px;
172
+ font-weight: 500;
173
+ cursor: pointer;
174
+ }
175
+ .cv-export__btn:hover { border-color: var(--cv-accent); }
176
+ .cv-export__scrim { position: fixed; inset: 0; z-index: 10; }
177
+ .cv-export__menu {
178
+ position: absolute;
179
+ right: 0;
180
+ top: calc(100% + 6px);
181
+ z-index: 11;
182
+ min-width: 160px;
183
+ padding: 6px;
184
+ background: var(--cv-bg);
185
+ border: 1px solid var(--cv-border);
186
+ border-radius: 10px;
187
+ box-shadow: 0 8px 28px rgba(0, 0, 0, 0.16);
188
+ display: flex;
189
+ flex-direction: column;
190
+ gap: 2px;
191
+ }
192
+ .cv-export__menu button {
193
+ display: flex;
194
+ justify-content: space-between;
195
+ align-items: center;
196
+ gap: 12px;
197
+ padding: 8px 10px;
198
+ border: none;
199
+ border-radius: 7px;
200
+ background: transparent;
201
+ color: var(--cv-text);
202
+ font-size: 13px;
203
+ text-align: left;
204
+ cursor: pointer;
205
+ }
206
+ .cv-export__menu button:hover { background: var(--cv-surface); }
207
+ .cv-export__ext { color: var(--cv-muted); font-family: var(--cv-mono); font-size: 11px; }
208
+
209
+ /* --- body --------------------------------------------------------------------- */
210
+
211
+ .cv-body { flex: 1; overflow: auto; padding: 24px; }
212
+ .cv-body--flush { padding: 0; overflow: hidden; }
213
+ .cv-fallback { color: var(--cv-muted); font-size: 14px; }
214
+
215
+ /* --- inline editing (document / table / slides) ------------------------------- */
216
+
217
+ .cv-edit-toolbar { display: flex; justify-content: flex-end; margin-bottom: 10px; }
218
+ .cv-edit-btn {
219
+ padding: 5px 14px;
220
+ border: 1px solid var(--cv-border);
221
+ border-radius: 8px;
222
+ background: var(--cv-surface);
223
+ color: var(--cv-text);
224
+ font-size: 13px;
225
+ font-weight: 500;
226
+ cursor: pointer;
227
+ }
228
+ .cv-edit-btn:hover { border-color: var(--cv-accent); }
229
+ .cv-edit-btn.is-primary { background: var(--cv-accent); color: #fff; border-color: var(--cv-accent); }
230
+
231
+ .cv-doc-wrap { max-width: 720px; margin: 0 auto; }
232
+ .cv-doc-wrap .cv-doc { max-width: none; margin: 0; }
233
+ .cv-doc-editor {
234
+ width: 100%;
235
+ min-height: 60vh;
236
+ padding: 16px;
237
+ border: 1px solid var(--cv-border);
238
+ border-radius: 10px;
239
+ background: var(--cv-bg);
240
+ color: var(--cv-text);
241
+ font-family: var(--cv-mono);
242
+ font-size: 14px;
243
+ line-height: 1.6;
244
+ outline: none;
245
+ resize: vertical;
246
+ }
247
+ .cv-doc-editor:focus { border-color: var(--cv-accent); }
248
+
249
+ .cv-table td.is-editable { outline: 1px dashed var(--cv-border); cursor: text; }
250
+ .cv-table td.is-editable:focus { outline: 2px solid var(--cv-accent); }
251
+
252
+ .cv-slide__title-input {
253
+ width: 100%;
254
+ margin: 0 0 20px;
255
+ border: none;
256
+ border-bottom: 2px solid var(--cv-border);
257
+ background: transparent;
258
+ color: var(--cv-text);
259
+ font: inherit;
260
+ font-size: 30px;
261
+ font-weight: 700;
262
+ outline: none;
263
+ }
264
+ .cv-slide__title-input:focus { border-color: var(--cv-accent); }
265
+ .cv-slide__bullet-edit { display: flex; align-items: center; gap: 8px; }
266
+ .cv-slide__bullet-edit input {
267
+ flex: 1;
268
+ padding: 6px 10px;
269
+ border: 1px solid var(--cv-border);
270
+ border-radius: 7px;
271
+ background: var(--cv-bg);
272
+ color: var(--cv-text);
273
+ font: inherit;
274
+ font-size: 17px;
275
+ outline: none;
276
+ }
277
+ .cv-slide__bullet-edit button {
278
+ border: none;
279
+ background: transparent;
280
+ color: var(--cv-muted);
281
+ cursor: pointer;
282
+ font-size: 18px;
283
+ }
284
+ .cv-slide__add {
285
+ align-self: flex-start;
286
+ margin-top: 14px;
287
+ padding: 6px 12px;
288
+ border: 1px dashed var(--cv-border);
289
+ border-radius: 8px;
290
+ background: transparent;
291
+ color: var(--cv-muted);
292
+ font-size: 13px;
293
+ cursor: pointer;
294
+ }
295
+
296
+ /* --- Word viewer (document page) ---------------------------------------------- */
297
+
298
+ .cv-word { background: #edeef1; padding: 28px 16px; min-height: 100%; }
299
+ .cv-word .cv-edit-toolbar { max-width: 816px; margin: 0 auto 12px; }
300
+ .cv-word__page {
301
+ width: 816px;
302
+ max-width: 100%;
303
+ margin: 0 auto;
304
+ background: #fff;
305
+ color: #1f2328;
306
+ padding: 76px 88px;
307
+ min-height: 1040px;
308
+ border-radius: 2px;
309
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.14), 0 8px 30px rgba(0, 0, 0, 0.1);
310
+ }
311
+ .cv-word__page .cv-doc { max-width: none; margin: 0; color: #1f2328; }
312
+ .cv-word__page .cv-doc code { background: #f0f1f3; }
313
+ .cv-word__page .cv-doc pre { background: #f6f8fa; }
314
+ .cv-word__page .cv-doc th, .cv-word__page .cv-doc td { border-color: #e0e2e6; }
315
+ @media (prefers-color-scheme: dark) { .cv-word { background: #0a0c10; } }
316
+
317
+ /* --- Excel viewer (spreadsheet grid) ------------------------------------------ */
318
+
319
+ .cv-xl { display: flex; flex-direction: column; height: 100%; }
320
+ .cv-xl--empty { display: grid; place-items: center; height: 200px; color: var(--cv-muted); }
321
+ .cv-xl__grid {
322
+ flex: 1;
323
+ min-height: 0;
324
+ display: grid;
325
+ grid-template-columns: 46px repeat(var(--cols), minmax(116px, 1fr));
326
+ align-content: start;
327
+ overflow: auto;
328
+ background: #fff;
329
+ border-top: 1px solid #d4d7dd;
330
+ border-left: 1px solid #d4d7dd;
331
+ font-size: 13px;
332
+ }
333
+ .cv-xl__corner, .cv-xl__colhead, .cv-xl__rownum {
334
+ position: sticky;
335
+ display: flex;
336
+ align-items: center;
337
+ justify-content: center;
338
+ padding: 4px;
339
+ background: #f3f4f6;
340
+ color: #57606a;
341
+ font-weight: 600;
342
+ border-right: 1px solid #d4d7dd;
343
+ border-bottom: 1px solid #d4d7dd;
344
+ }
345
+ .cv-xl__corner { top: 0; left: 0; z-index: 3; }
346
+ .cv-xl__colhead { top: 0; z-index: 2; }
347
+ .cv-xl__rownum { left: 0; z-index: 1; }
348
+ .cv-xl__cell {
349
+ min-height: 26px;
350
+ padding: 4px 8px;
351
+ line-height: 18px;
352
+ color: #1f2328;
353
+ background: #fff;
354
+ border-right: 1px solid #e3e5e9;
355
+ border-bottom: 1px solid #e3e5e9;
356
+ white-space: nowrap;
357
+ overflow: hidden;
358
+ text-overflow: ellipsis;
359
+ }
360
+ .cv-xl__cell--label { font-weight: 600; background: #fafbfc; }
361
+ .cv-xl__cell[contenteditable="true"] { cursor: text; }
362
+ .cv-xl__cell[contenteditable="true"]:focus { outline: 2px solid #217346; outline-offset: -2px; }
363
+ .cv-xl__tabs { display: flex; gap: 2px; padding: 6px 8px 0; background: #f3f4f6; border-top: 1px solid #d4d7dd; }
364
+ .cv-xl__tab {
365
+ padding: 5px 14px;
366
+ font-size: 12px;
367
+ color: #57606a;
368
+ background: #fff;
369
+ border: 1px solid #d4d7dd;
370
+ border-bottom: none;
371
+ border-radius: 4px 4px 0 0;
372
+ }
373
+ .cv-xl__tab.is-active { color: #217346; font-weight: 700; box-shadow: inset 0 2px 0 #217346; }
374
+
375
+ /* --- Excel viewer (Fortune-sheet workbook) ------------------------------------ */
376
+
377
+ .cv-sheet-panel { display: flex; flex-direction: column; height: 100%; min-height: 0; min-width: 0; }
378
+ .cv-sheet-tools { display: flex; align-items: center; gap: 6px; padding: 6px 10px; border-bottom: 1px solid var(--cv-border); background: var(--cv-bg); flex: 0 0 auto; }
379
+ .cv-sheet-tools button {
380
+ font-size: 12px; font-weight: 600; padding: 4px 10px; border: 1px solid var(--cv-border);
381
+ border-radius: 6px; background: var(--cv-bg); color: var(--cv-text); cursor: pointer;
382
+ }
383
+ .cv-sheet-tools button:hover { border-color: var(--cv-accent, #6366f1); color: var(--cv-accent, #6366f1); }
384
+ .cv-sheet-tools__hint { margin-left: auto; font-size: 11px; color: var(--cv-muted); }
385
+ .cv-sheet { position: relative; width: 100%; flex: 1; height: auto; min-height: 0; }
386
+ .cv-sheet .fortune-container { height: 100% !important; width: 100% !important; }
387
+ .cv-sheet--empty { display: grid; place-items: center; height: 200px; color: var(--cv-muted); font-size: 14px; }
388
+
389
+ /* --- PowerPoint viewer (deck: rail + stage) ----------------------------------- */
390
+
391
+ .cv-deck { display: flex; gap: 14px; height: 100%; }
392
+ .cv-deck--empty { display: grid; place-items: center; color: var(--cv-muted); }
393
+ .cv-deck__rail {
394
+ width: 160px;
395
+ flex-shrink: 0;
396
+ overflow-y: auto;
397
+ display: flex;
398
+ flex-direction: column;
399
+ gap: 10px;
400
+ padding-right: 6px;
401
+ }
402
+ .cv-deck__thumb {
403
+ display: flex;
404
+ width: 100%; /* fill the rail — thumbnails hold only absolutely-positioned
405
+ elements (no in-flow width), so the button must be told to
406
+ span the rail or it shrink-to-fits to the number and the
407
+ 16:9 preview collapses to a sliver. */
408
+ box-sizing: border-box;
409
+ gap: 6px;
410
+ border: none;
411
+ background: none;
412
+ padding: 0;
413
+ text-align: left;
414
+ cursor: pointer;
415
+ }
416
+ .cv-deck__thumb-n { flex: 0 0 14px; padding-top: 3px; font-size: 11px; color: var(--cv-muted); }
417
+ .cv-deck__thumb-slide {
418
+ position: relative;
419
+ flex: 1 1 auto;
420
+ min-width: 0;
421
+ aspect-ratio: 16 / 9;
422
+ background: var(--cv-bg);
423
+ border: 1px solid var(--cv-border);
424
+ border-radius: 5px;
425
+ overflow: hidden;
426
+ }
427
+ .cv-deck__thumb.is-active .cv-deck__thumb-slide { border-color: var(--cv-accent); box-shadow: 0 0 0 1px var(--cv-accent); }
428
+ .cv-deck__thumb-slide b { display: block; margin-bottom: 3px; font-size: 9px; line-height: 1.2; }
429
+ .cv-deck__thumb-slide ul { margin: 0; padding-left: 9px; }
430
+ .cv-deck__thumb-slide li { font-size: 7px; line-height: 1.5; color: var(--cv-muted); list-style: disc; }
431
+ .cv-deck__thumb-wrap { cursor: grab; }
432
+ .cv-deck__thumb-wrap:active { cursor: grabbing; }
433
+ .cv-deck__thumb-wrap.is-dragging { opacity: 0.4; }
434
+ .cv-deck__thumb-wrap.is-active .cv-deck__thumb-slide { border-color: var(--cv-accent); box-shadow: 0 0 0 1px var(--cv-accent); }
435
+ .cv-deck__thumb-slide i { display: block; font-size: 7px; color: var(--cv-muted); margin-bottom: 3px; }
436
+ .cv-deck__addslide {
437
+ margin-top: 4px;
438
+ padding: 8px;
439
+ border: 1px dashed var(--cv-border);
440
+ border-radius: 7px;
441
+ background: transparent;
442
+ color: var(--cv-muted);
443
+ font-size: 12px;
444
+ cursor: pointer;
445
+ }
446
+ .cv-deck__addslide:hover { border-color: var(--cv-accent); color: var(--cv-accent); }
447
+
448
+ .cv-deck__main {
449
+ flex: 1;
450
+ min-width: 0;
451
+ display: flex;
452
+ flex-direction: column;
453
+ gap: 10px;
454
+ padding: 16px 20px;
455
+ background: var(--cv-surface);
456
+ border-radius: 10px;
457
+ }
458
+ .cv-deck__toolbar { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
459
+ .cv-deck__toolbar select {
460
+ padding: 5px 8px;
461
+ border: 1px solid var(--cv-border);
462
+ border-radius: 7px;
463
+ background: var(--cv-bg);
464
+ color: var(--cv-text);
465
+ font: inherit;
466
+ font-size: 13px;
467
+ }
468
+ .cv-deck__spacer { flex: 1; }
469
+ .cv-deck__toolbar button {
470
+ display: inline-flex;
471
+ align-items: center;
472
+ justify-content: center;
473
+ gap: 4px;
474
+ min-width: 30px; /* icon buttons stay ~square; text buttons (+ Text / + Image
475
+ / ▶ Present) grow to fit their label instead of clipping. */
476
+ height: 30px;
477
+ padding: 0 8px;
478
+ white-space: nowrap;
479
+ border: 1px solid var(--cv-border);
480
+ border-radius: 7px;
481
+ background: var(--cv-bg);
482
+ cursor: pointer;
483
+ font-size: 13px;
484
+ line-height: 1;
485
+ }
486
+ .cv-deck__toolbar button:disabled { opacity: 0.4; cursor: default; }
487
+ .cv-deck__nav {
488
+ display: flex;
489
+ align-items: center;
490
+ justify-content: center;
491
+ gap: 12px;
492
+ }
493
+ .cv-deck__nav button {
494
+ width: 30px;
495
+ height: 30px;
496
+ border: 1px solid var(--cv-border);
497
+ border-radius: 7px;
498
+ background: var(--cv-bg);
499
+ color: var(--cv-text);
500
+ cursor: pointer;
501
+ }
502
+ .cv-deck__nav button:disabled { opacity: 0.4; cursor: default; }
503
+ .cv-deck__nav span { font-size: 13px; color: var(--cv-muted); font-variant-numeric: tabular-nums; }
504
+ .cv-deck__notes {
505
+ min-height: 60px;
506
+ max-height: 120px;
507
+ resize: vertical;
508
+ padding: 10px 12px;
509
+ border: 1px solid var(--cv-border);
510
+ border-radius: 8px;
511
+ background: var(--cv-bg);
512
+ color: var(--cv-text);
513
+ font: inherit;
514
+ font-size: 13px;
515
+ outline: none;
516
+ }
517
+ .cv-deck__notes:focus { border-color: var(--cv-accent); }
518
+
519
+ /* slide layouts */
520
+ .cv-slide { margin: 0 auto; }
521
+ .cv-slide--title, .cv-slide--section { align-items: center; text-align: center; }
522
+ .cv-slide--title .cv-slide__title { font-size: 40px; }
523
+ .cv-slide--section .cv-slide__title { font-size: 32px; }
524
+ .cv-slide__subtitle {
525
+ margin: 6px 0 0;
526
+ font-size: 20px;
527
+ color: inherit;
528
+ opacity: 0.72;
529
+ text-align: center;
530
+ }
531
+ .cv-slide__subtitle:focus, .cv-slide__subtitle:empty::before {
532
+ content: attr(data-placeholder);
533
+ }
534
+ .cv-slide__subtitle:empty::before { color: var(--cv-muted); opacity: 0.5; }
535
+ .cv-slide__image { max-width: 100%; max-height: 68%; object-fit: contain; border-radius: 6px; margin-top: 12px; }
536
+ .cv-slide__imgdrop {
537
+ margin-top: 16px;
538
+ padding: 44px 24px;
539
+ border: 2px dashed var(--cv-border);
540
+ border-radius: 10px;
541
+ background: transparent;
542
+ color: var(--cv-muted);
543
+ font-size: 14px;
544
+ cursor: pointer;
545
+ }
546
+ .cv-slide__imgdrop:hover { border-color: var(--cv-accent); color: var(--cv-accent); }
547
+
548
+ /* two-column layout */
549
+ .cv-slide__cols { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; width: 100%; align-items: start; }
550
+
551
+ /* blank / free-canvas layout */
552
+ .cv-slide { position: relative; }
553
+ .cv-slide--blank { display: block; padding: 0; }
554
+ .cv-free { position: absolute; inset: 0; }
555
+ .cv-free__el { position: absolute; box-sizing: border-box; cursor: move; }
556
+ .cv-free__guide { position: absolute; z-index: 6; background: #f43f5e; pointer-events: none; }
557
+ .cv-free__guide--v { top: 0; bottom: 0; width: 1px; }
558
+ .cv-free__guide--h { left: 0; right: 0; height: 1px; }
559
+ .cv-free__el.is-selected { outline: 1.5px solid var(--cv-accent); outline-offset: 1px; }
560
+ .cv-free__text { width: 100%; height: 100%; outline: none; overflow: hidden; line-height: 1.3; }
561
+ .cv-free__img { width: 100%; height: 100%; object-fit: contain; pointer-events: none; }
562
+ .cv-free__resize {
563
+ position: absolute; right: -5px; bottom: -5px; width: 12px; height: 12px;
564
+ background: var(--cv-accent); border: 2px solid #fff; border-radius: 3px; cursor: nwse-resize;
565
+ }
566
+ .cv-free__ctl {
567
+ position: absolute; top: -32px; right: 0; display: flex; gap: 2px;
568
+ padding: 3px; background: var(--cv-bg); border: 1px solid var(--cv-border);
569
+ border-radius: 7px; box-shadow: 0 4px 14px rgba(0, 0, 0, 0.14);
570
+ }
571
+ /* Flip below the element when it sits near the top edge, so the controls never
572
+ clip against the slide edge or cover the element's own text. */
573
+ .cv-free__ctl--below { top: auto; bottom: -32px; }
574
+ .cv-free__ctl button { width: 22px; height: 22px; border: none; border-radius: 5px; background: transparent; color: var(--cv-text); cursor: pointer; font-size: 12px; }
575
+ .cv-free__ctl button:hover { background: var(--cv-surface); }
576
+ .cv-free__ctl-del:hover { background: #fee2e2 !important; color: #dc2626; }
577
+ .cv-free__fmt {
578
+ position: absolute; top: -42px; left: 0; z-index: 5;
579
+ display: flex; align-items: center; gap: 4px;
580
+ padding: 4px 6px; background: var(--cv-bg); border: 1px solid var(--cv-border);
581
+ border-radius: 8px; box-shadow: 0 6px 20px rgba(0,0,0,0.16); cursor: default;
582
+ }
583
+ /* Flip below when the element hugs the top edge (title boxes), so the format
584
+ bar doesn't overflow above the slide and clip. */
585
+ .cv-free__fmt--below { top: calc(100% + 6px); }
586
+ .cv-free__fmt button {
587
+ min-width: 24px; height: 24px; padding: 0 5px;
588
+ border: 1px solid var(--cv-border); border-radius: 5px; background: var(--cv-bg); color: var(--cv-text); cursor: pointer; font-size: 12px;
589
+ }
590
+ .cv-free__fmt button.is-on { background: var(--cv-accent); color: #fff; border-color: var(--cv-accent); }
591
+ .cv-free__fmt input[type="number"] { width: 46px; height: 24px; border: 1px solid var(--cv-border); border-radius: 5px; background: var(--cv-bg); color: var(--cv-text); font-size: 12px; padding: 0 4px; }
592
+ .cv-free__fmt input[type="color"] { width: 26px; height: 24px; padding: 0; border: 1px solid var(--cv-border); border-radius: 5px; background: none; cursor: pointer; }
593
+
594
+ /* toolbar: background swatch + present button */
595
+ .cv-deck__bg input[type="color"] {
596
+ width: 30px; height: 30px; padding: 0;
597
+ border: 1px solid var(--cv-border); border-radius: 7px; background: none; cursor: pointer;
598
+ }
599
+ .cv-deck__present {
600
+ width: auto !important; padding: 0 12px !important;
601
+ background: var(--cv-accent) !important; color: #fff !important;
602
+ border-color: var(--cv-accent) !important; font-weight: 600;
603
+ }
604
+ .cv-deck__freeform { width: auto !important; padding: 0 10px !important; font-size: 12px; white-space: nowrap; }
605
+
606
+ /* presentation mode (full screen) */
607
+ .cv-present {
608
+ position: fixed; inset: 0; z-index: 100;
609
+ display: flex; flex-direction: column; align-items: center; justify-content: center;
610
+ gap: 16px; background: #0b0d12; cursor: pointer;
611
+ }
612
+ .cv-present__slide {
613
+ width: min(92vw, 1280px); max-width: none; aspect-ratio: 16 / 9;
614
+ padding: 6% 8%; box-shadow: 0 20px 80px rgba(0, 0, 0, 0.5);
615
+ }
616
+ .cv-present__slide .cv-slide__title { font-size: clamp(28px, 5vw, 60px); }
617
+ .cv-present__slide .cv-slide__subtitle { font-size: clamp(16px, 2.6vw, 30px); }
618
+ .cv-present__slide .cv-slide__bullets li { font-size: clamp(16px, 2.4vw, 30px); }
619
+ .cv-present__hint { color: #9aa4b2; font-size: 13px; }
620
+
621
+ /* in-place editing cues */
622
+ .cv-word .cv-doc { cursor: text; }
623
+ .cv-slide__title[contenteditable], .cv-slide__bullets li[contenteditable] { cursor: text; border-radius: 4px; }
624
+ .cv-slide__title:focus, .cv-slide__bullets li:focus { outline: 2px solid var(--cv-accent); outline-offset: 2px; }
625
+ .cv-slide__title:empty::before { content: attr(data-placeholder); color: var(--cv-muted); }
626
+
627
+ /* --- document renderer -------------------------------------------------------- */
628
+
629
+ .cv-doc {
630
+ max-width: 720px;
631
+ margin: 0 auto;
632
+ line-height: 1.7;
633
+ font-size: 15px;
634
+ }
635
+ .cv-doc h1 { font-size: 1.7em; margin: 0.6em 0 0.4em; }
636
+ .cv-doc h2 { font-size: 1.35em; margin: 1.2em 0 0.4em; }
637
+ .cv-doc h3 { font-size: 1.1em; margin: 1em 0 0.3em; }
638
+ .cv-doc p { margin: 0.7em 0; }
639
+ .cv-doc ul, .cv-doc ol { padding-left: 1.4em; margin: 0.7em 0; }
640
+ .cv-doc code {
641
+ font-family: var(--cv-mono);
642
+ font-size: 0.88em;
643
+ background: var(--cv-surface);
644
+ padding: 0.15em 0.4em;
645
+ border-radius: 5px;
646
+ }
647
+ .cv-doc pre {
648
+ background: var(--cv-surface);
649
+ padding: 14px 16px;
650
+ border-radius: 10px;
651
+ overflow-x: auto;
652
+ }
653
+ .cv-doc pre code { background: none; padding: 0; }
654
+ .cv-doc blockquote {
655
+ margin: 0.8em 0;
656
+ padding-left: 1em;
657
+ border-left: 3px solid var(--cv-border);
658
+ color: var(--cv-muted);
659
+ }
660
+ .cv-doc table { border-collapse: collapse; width: 100%; margin: 0.8em 0; }
661
+ .cv-doc th, .cv-doc td { border: 1px solid var(--cv-border); padding: 8px 12px; text-align: left; }
662
+
663
+ .cv-caret {
664
+ display: inline-block;
665
+ width: 8px;
666
+ height: 1.1em;
667
+ margin-left: 2px;
668
+ vertical-align: text-bottom;
669
+ background: var(--cv-accent);
670
+ border-radius: 1px;
671
+ animation: cv-blink 1s steps(2, start) infinite;
672
+ }
673
+ @keyframes cv-blink { to { visibility: hidden; } }
674
+
675
+ /* --- chart renderer ----------------------------------------------------------- */
676
+
677
+ .cv-chart { width: 100%; }
678
+ .cv-chart__toolbar { display: flex; align-items: center; gap: 14px; margin-bottom: 12px; }
679
+ .cv-chart__types { display: flex; gap: 4px; }
680
+ .cv-chart__types .cv-edit-btn { text-transform: capitalize; }
681
+ .cv-chart__stack { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--cv-muted); cursor: pointer; }
682
+ .cv-chart__spacer { flex: 1; }
683
+
684
+ /* --- chart editor ------------------------------------------------------------- */
685
+ .cv-chart__editor {
686
+ display: flex; flex-direction: column; gap: 12px;
687
+ margin-bottom: 12px; padding: 12px 14px;
688
+ border: 1px solid var(--cv-border); border-radius: 10px; background: var(--cv-surface);
689
+ }
690
+ .cv-chart__legend { display: flex; flex-wrap: wrap; gap: 10px; }
691
+ .cv-chart__swatch { display: inline-flex; align-items: center; gap: 6px; }
692
+ .cv-chart__swatch input[type="color"] { width: 24px; height: 24px; padding: 0; border: 1px solid var(--cv-border); border-radius: 5px; background: none; cursor: pointer; }
693
+ .cv-chart__swatch-label { font-size: 13px; color: var(--cv-text); }
694
+ .cv-chart__series-name { width: 120px; height: 26px; padding: 0 7px; border: 1px solid var(--cv-border); border-radius: 6px; background: var(--cv-bg); color: var(--cv-text); font: inherit; font-size: 13px; }
695
+ .cv-chart__ylabel { display: inline-flex; align-items: center; gap: 8px; font-size: 13px; color: var(--cv-muted); }
696
+ .cv-chart__ylabel input { width: 180px; height: 28px; padding: 0 8px; border: 1px solid var(--cv-border); border-radius: 6px; background: var(--cv-bg); color: var(--cv-text); font: inherit; font-size: 13px; }
697
+
698
+ .cv-chart__grid { overflow-x: auto; }
699
+ .cv-chart__grid table { border-collapse: collapse; width: 100%; }
700
+ .cv-chart__grid th { text-align: left; font-size: 11px; font-weight: 600; color: var(--cv-muted); padding: 2px 6px; text-transform: uppercase; letter-spacing: 0.02em; }
701
+ .cv-chart__grid td { padding: 2px 4px; }
702
+ .cv-chart__grid input { width: 100%; min-width: 72px; height: 28px; padding: 0 7px; border: 1px solid var(--cv-border); border-radius: 6px; background: var(--cv-bg); color: var(--cv-text); font: inherit; font-size: 13px; }
703
+ .cv-chart__grid input[type="number"] { text-align: right; }
704
+ .cv-chart__row-del { width: 26px; height: 26px; border: 1px solid var(--cv-border); border-radius: 6px; background: var(--cv-bg); color: var(--cv-muted); cursor: pointer; }
705
+ .cv-chart__row-del:hover:not(:disabled) { background: #fee2e2; color: #dc2626; border-color: #fecaca; }
706
+ .cv-chart__row-del:disabled { opacity: 0.4; cursor: default; }
707
+ .cv-chart__addrow { align-self: flex-start; margin-top: 4px; padding: 6px 12px; border: 1px dashed var(--cv-border); border-radius: 7px; background: transparent; color: var(--cv-muted); font-size: 13px; cursor: pointer; }
708
+ .cv-chart__addrow:hover { border-color: var(--cv-accent); color: var(--cv-accent); }
709
+ .cv-chart--empty {
710
+ display: grid;
711
+ place-items: center;
712
+ height: 320px;
713
+ color: var(--cv-muted);
714
+ font-size: 14px;
715
+ }
716
+
717
+ /* --- slides renderer ----------------------------------------------------------- */
718
+
719
+ .cv-slides { display: flex; flex-direction: column; align-items: center; gap: 14px; }
720
+ .cv-slide {
721
+ width: 100%;
722
+ max-width: 780px;
723
+ aspect-ratio: 16 / 9;
724
+ padding: 48px 56px;
725
+ border: 1px solid var(--cv-border);
726
+ border-radius: 14px;
727
+ background: linear-gradient(160deg, var(--cv-bg), var(--cv-surface));
728
+ box-shadow: 0 8px 30px rgba(0, 0, 0, 0.08);
729
+ display: flex;
730
+ flex-direction: column;
731
+ justify-content: center;
732
+ overflow: hidden;
733
+ }
734
+ .cv-slide__title { margin: 0 0 20px; font-size: 30px; font-weight: 700; }
735
+ .cv-slide__bullets { margin: 0; padding-left: 1.1em; display: flex; flex-direction: column; gap: 12px; }
736
+ .cv-slide__bullets li { font-size: 18px; line-height: 1.4; }
737
+ .cv-slides--empty { display: grid; place-items: center; height: 200px; color: var(--cv-muted); }
738
+ .cv-slides__nav { display: flex; align-items: center; gap: 12px; }
739
+ .cv-slides__nav button {
740
+ width: 34px; height: 34px;
741
+ border: 1px solid var(--cv-border);
742
+ border-radius: 8px;
743
+ background: var(--cv-surface);
744
+ color: var(--cv-text);
745
+ cursor: pointer;
746
+ font-size: 16px;
747
+ }
748
+ .cv-slides__nav button:disabled { opacity: 0.4; cursor: default; }
749
+ .cv-slides__nav span { font-size: 13px; color: var(--cv-muted); font-variant-numeric: tabular-nums; }
750
+
751
+ /* --- html renderer (base substrate) ------------------------------------------- */
752
+
753
+ .cv-html-wrap { display: flex; flex-direction: column; height: 100%; gap: 10px; }
754
+ .cv-html-bar {
755
+ display: flex; align-items: center; flex-wrap: wrap; gap: 5px;
756
+ padding: 7px 9px; border: 1px solid var(--cv-border); border-radius: 9px; background: var(--cv-surface);
757
+ }
758
+ .cv-html-bar__sep { width: 1px; height: 18px; background: var(--cv-border); margin: 0 4px; }
759
+ .cv-html-bar__label { font-size: 11px; color: var(--cv-muted); text-transform: uppercase; letter-spacing: 0.03em; }
760
+ .cv-html-seg { display: inline-flex; border: 1px solid var(--cv-border); border-radius: 7px; overflow: hidden; }
761
+ .cv-html-seg button { border: 0; background: var(--cv-bg); color: var(--cv-text); font: inherit; font-size: 12px; padding: 5px 10px; cursor: pointer; }
762
+ .cv-html-seg button + button { border-left: 1px solid var(--cv-border); }
763
+ .cv-html-seg button.is-on { background: var(--cv-accent); color: #fff; }
764
+ .cv-html-add {
765
+ border: 1px solid var(--cv-border); border-radius: 7px; background: var(--cv-bg); color: var(--cv-text);
766
+ font: inherit; font-size: 12px; padding: 5px 9px; cursor: pointer;
767
+ }
768
+ .cv-html-add:hover { border-color: var(--cv-accent); color: var(--cv-accent); }
769
+ .cv-html-tpl {
770
+ height: 30px; padding: 0 8px; border: 1px solid var(--cv-border); border-radius: 7px;
771
+ background: var(--cv-bg); color: var(--cv-text); font: inherit; font-size: 12px; cursor: pointer;
772
+ }
773
+ .cv-html-actbtn {
774
+ height: 28px; padding: 0 10px; border: 1px solid var(--cv-accent); border-radius: 7px;
775
+ background: color-mix(in srgb, var(--cv-accent) 12%, var(--cv-bg)); color: var(--cv-accent);
776
+ font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; white-space: nowrap;
777
+ }
778
+ .cv-html-actbtn:hover:not(:disabled) { background: color-mix(in srgb, var(--cv-accent) 22%, var(--cv-bg)); }
779
+ .cv-html-actbtn:disabled { opacity: 0.45; cursor: default; border-color: var(--cv-border); color: var(--cv-muted); background: var(--cv-bg); }
780
+ .cv-html-act {
781
+ width: 30px; height: 28px; border: 1px solid var(--cv-border); border-radius: 7px;
782
+ background: var(--cv-bg); color: var(--cv-text); cursor: pointer; font-size: 13px;
783
+ }
784
+ .cv-html-act:hover { background: var(--cv-surface); }
785
+ .cv-html-act--del:hover { background: #fee2e2; color: #dc2626; border-color: #fecaca; }
786
+ .cv-html-bar__spacer { flex: 1; }
787
+ .cv-html-stage {
788
+ flex: 1; min-height: 0; overflow: auto; display: flex; justify-content: center;
789
+ padding: 10px; background: var(--cv-surface); border-radius: 10px;
790
+ }
791
+ .cv-html-code {
792
+ flex: 1; min-height: 0; width: 100%; resize: none;
793
+ padding: 14px 16px; border: 1px solid var(--cv-border); border-radius: 10px;
794
+ background: var(--cv-bg); color: var(--cv-text);
795
+ font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, monospace; font-size: 12.5px; line-height: 1.6;
796
+ tab-size: 2;
797
+ }
798
+ .cv-html-code:focus { outline: none; border-color: var(--cv-accent); }
799
+ .cv-html {
800
+ width: 100%;
801
+ height: 100%;
802
+ min-height: 70vh;
803
+ border: 0;
804
+ border-radius: 10px;
805
+ background: #fff;
806
+ box-shadow: 0 1px 4px rgba(0, 0, 0, 0.08);
807
+ transition: width 0.2s ease;
808
+ }
809
+
810
+ /* --- selection quick-edit bar ------------------------------------------------- */
811
+
812
+ .cv-selection {
813
+ position: absolute;
814
+ left: 50%;
815
+ bottom: 20px;
816
+ transform: translateX(-50%);
817
+ z-index: 20;
818
+ display: flex;
819
+ align-items: center;
820
+ gap: 8px;
821
+ max-width: min(560px, calc(100% - 32px));
822
+ padding: 8px 10px;
823
+ background: var(--cv-bg);
824
+ border: 1px solid var(--cv-border);
825
+ border-radius: 12px;
826
+ box-shadow: 0 10px 34px rgba(0, 0, 0, 0.22);
827
+ }
828
+ .cv-selection__chip {
829
+ flex-shrink: 0;
830
+ max-width: 140px;
831
+ padding: 4px 9px;
832
+ border-radius: 7px;
833
+ background: var(--cv-accent-weak);
834
+ color: var(--cv-accent);
835
+ font-family: var(--cv-mono);
836
+ font-size: 12px;
837
+ white-space: nowrap;
838
+ overflow: hidden;
839
+ text-overflow: ellipsis;
840
+ }
841
+ .cv-selection__input {
842
+ flex: 1;
843
+ min-width: 160px;
844
+ border: none;
845
+ background: transparent;
846
+ color: var(--cv-text);
847
+ font: inherit;
848
+ font-size: 14px;
849
+ outline: none;
850
+ }
851
+ .cv-selection__apply {
852
+ flex-shrink: 0;
853
+ padding: 6px 14px;
854
+ border: none;
855
+ border-radius: 8px;
856
+ background: var(--cv-accent);
857
+ color: #fff;
858
+ font-weight: 600;
859
+ font-size: 13px;
860
+ cursor: pointer;
861
+ }
862
+ .cv-selection__apply:disabled { opacity: 0.5; cursor: default; }
863
+ .cv-selection__clear {
864
+ flex-shrink: 0;
865
+ width: 26px;
866
+ height: 26px;
867
+ border: none;
868
+ border-radius: 7px;
869
+ background: transparent;
870
+ color: var(--cv-muted);
871
+ cursor: pointer;
872
+ }
873
+ .cv-selection__clear:hover { background: var(--cv-surface); }
874
+
875
+ /* --- style panel -------------------------------------------------------------- */
876
+
877
+ .cv-style__bg { display: flex; flex-direction: column; gap: 6px; margin-top: 2px; }
878
+ .cv-style__bg > span { font-size: 12px; color: var(--cv-muted); }
879
+ .cv-style__grads { display: flex; flex-wrap: wrap; gap: 6px; }
880
+ .cv-style__grad {
881
+ width: 26px; height: 26px; border: 1px solid var(--cv-border); border-radius: 6px;
882
+ background-size: cover; cursor: pointer; padding: 0; font-size: 12px;
883
+ display: inline-flex; align-items: center; justify-content: center;
884
+ }
885
+ .cv-style__grad--img, .cv-style__grad--none { background: var(--cv-bg); color: var(--cv-muted); }
886
+ .cv-style__grad:hover { outline: 2px solid var(--cv-accent); outline-offset: 1px; }
887
+
888
+ .cv-style {
889
+ position: absolute;
890
+ /* Anchor to the lower-LEFT: the resize handle sits at an element's bottom-right,
891
+ so a right-docked panel hid it on wide elements. Left keeps the handle clear
892
+ and stays below the top editing toolbar. */
893
+ left: 16px;
894
+ bottom: 72px;
895
+ z-index: 20;
896
+ width: 210px;
897
+ padding: 12px 14px;
898
+ background: var(--cv-bg);
899
+ border: 1px solid var(--cv-border);
900
+ border-radius: 12px;
901
+ box-shadow: 0 10px 34px rgba(0, 0, 0, 0.18);
902
+ display: flex;
903
+ flex-direction: column;
904
+ gap: 8px;
905
+ }
906
+ .cv-style__title {
907
+ font-size: 11px;
908
+ font-weight: 700;
909
+ text-transform: uppercase;
910
+ letter-spacing: 0.05em;
911
+ color: var(--cv-muted);
912
+ }
913
+ .cv-style__row {
914
+ display: flex;
915
+ align-items: center;
916
+ justify-content: space-between;
917
+ gap: 10px;
918
+ font-size: 13px;
919
+ }
920
+ .cv-style__row input[type="color"] {
921
+ width: 34px;
922
+ height: 24px;
923
+ padding: 0;
924
+ border: 1px solid var(--cv-border);
925
+ border-radius: 6px;
926
+ background: none;
927
+ }
928
+ .cv-style__row input[type="number"],
929
+ .cv-style__row select {
930
+ width: 84px;
931
+ padding: 4px 6px;
932
+ border: 1px solid var(--cv-border);
933
+ border-radius: 6px;
934
+ background: var(--cv-bg);
935
+ color: var(--cv-text);
936
+ font: inherit;
937
+ font-size: 13px;
938
+ }
939
+ .cv-style__done {
940
+ margin-top: 4px;
941
+ padding: 7px;
942
+ border: none;
943
+ border-radius: 8px;
944
+ background: var(--cv-accent);
945
+ color: #fff;
946
+ font-weight: 600;
947
+ font-size: 13px;
948
+ cursor: pointer;
949
+ }
950
+
951
+ /* --- table renderer ----------------------------------------------------------- */
952
+
953
+ .cv-table { width: 100%; overflow-x: auto; }
954
+ .cv-table table { border-collapse: collapse; width: 100%; font-size: 14px; }
955
+ .cv-table th,
956
+ .cv-table td {
957
+ padding: 9px 14px;
958
+ border-bottom: 1px solid var(--cv-border);
959
+ white-space: nowrap;
960
+ }
961
+ .cv-table th {
962
+ position: sticky;
963
+ top: 0;
964
+ background: var(--cv-surface);
965
+ font-weight: 600;
966
+ color: var(--cv-muted);
967
+ font-size: 12px;
968
+ text-transform: uppercase;
969
+ letter-spacing: 0.03em;
970
+ }
971
+ .cv-table tbody tr:hover { background: var(--cv-surface); }
972
+ .cv-table--empty {
973
+ display: grid;
974
+ place-items: center;
975
+ height: 200px;
976
+ color: var(--cv-muted);
977
+ }
978
+
979
+ /* --- inline artifact card (for the transcript) -------------------------------- */
980
+
981
+ .cv-card {
982
+ display: flex;
983
+ align-items: center;
984
+ gap: 10px;
985
+ width: 100%;
986
+ max-width: 320px;
987
+ margin-top: 8px;
988
+ padding: 10px 12px;
989
+ border: 1px solid var(--cv-border);
990
+ border-radius: 12px;
991
+ background: var(--cv-bg);
992
+ color: var(--cv-text);
993
+ text-align: left;
994
+ cursor: pointer;
995
+ transition: border-color 0.15s;
996
+ }
997
+ .cv-card:hover { border-color: var(--cv-accent); }
998
+ .cv-card__icon { font-size: 22px; line-height: 1; }
999
+ .cv-card__meta { display: flex; flex-direction: column; min-width: 0; }
1000
+ .cv-card__meta b { font-size: 13px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
1001
+ .cv-card__meta span { font-size: 11px; color: var(--cv-muted); }
1002
+
1003
+ /* --- renderer error fallback -------------------------------------------------- */
1004
+
1005
+ .cv-renderer-error {
1006
+ display: flex; flex-direction: column; gap: 6px;
1007
+ max-width: 460px; margin: 32px auto; padding: 18px 20px;
1008
+ border: 1px solid var(--cv-border); border-radius: 10px;
1009
+ background: var(--cv-surface); text-align: center;
1010
+ }
1011
+ .cv-renderer-error__title { margin: 0; font-size: 14px; font-weight: 600; }
1012
+ .cv-renderer-error__detail { margin: 0; font-size: 12px; color: var(--cv-muted); word-break: break-word; }
1013
+
1014
+ /* --- empty state -------------------------------------------------------------- */
1015
+
1016
+ .cv-empty { text-align: center; max-width: 320px; }
1017
+ .cv-empty__title { font-size: 15px; font-weight: 600; margin: 0 0 6px; }
1018
+ .cv-empty__hint { font-size: 13px; color: var(--cv-muted); margin: 0; line-height: 1.5; }
1019
+ .cv-empty__open {
1020
+ margin: 16px auto 8px; padding: 8px 18px;
1021
+ border: 1px solid var(--cv-accent); border-radius: 8px;
1022
+ background: var(--cv-accent); color: #fff; font: inherit; font-size: 13px; font-weight: 500; cursor: pointer;
1023
+ }
1024
+ .cv-empty__open:hover { filter: brightness(1.05); }
1025
+ .cv-empty__formats { font-size: 11px; color: var(--cv-muted); margin: 0; letter-spacing: 0.02em; }
1026
+
1027
+ /* --- file drop overlay -------------------------------------------------------- */
1028
+ .cv-canvas__drop {
1029
+ position: absolute; inset: 10px; z-index: 50;
1030
+ display: flex; align-items: center; justify-content: center;
1031
+ border: 2px dashed var(--cv-accent); border-radius: 12px;
1032
+ background: color-mix(in srgb, var(--cv-accent) 8%, var(--cv-bg));
1033
+ color: var(--cv-accent); font-size: 15px; font-weight: 600; pointer-events: none;
1034
+ }
1035
+
1036
+ /* --- responsive --------------------------------------------------------------- */
1037
+
1038
+ /* Tablet / narrow desktop: tighten paddings, let toolbars wrap. */
1039
+ @media (max-width: 900px) {
1040
+ .cv-body { padding: 16px; }
1041
+ .cv-header { flex-wrap: wrap; gap: 8px; row-gap: 8px; }
1042
+ .cv-tabs { flex-wrap: wrap; }
1043
+ .cv-deck__main { padding: 12px; }
1044
+ }
1045
+
1046
+ /* Phone: stack the PPT rail into a horizontal filmstrip above the stage, and
1047
+ * make every toolbar wrap instead of overflowing. */
1048
+ @media (max-width: 640px) {
1049
+ .cv-deck { flex-direction: column; gap: 10px; }
1050
+ .cv-deck__rail {
1051
+ width: 100%;
1052
+ flex-direction: row;
1053
+ overflow-x: auto;
1054
+ overflow-y: hidden;
1055
+ padding: 0 0 6px;
1056
+ gap: 8px;
1057
+ }
1058
+ .cv-deck__thumb-wrap { flex: 0 0 auto; }
1059
+ .cv-deck__thumb-slide { width: 128px; }
1060
+ .cv-deck__addslide { flex: 0 0 auto; align-self: center; margin-top: 0; white-space: nowrap; }
1061
+ .cv-deck__main { border-radius: 8px; }
1062
+
1063
+ .cv-body { padding: 12px; }
1064
+ .cv-toolbar, .cv-word__toolbar, .cv-chart__toolbar { flex-wrap: wrap; }
1065
+ .cv-export__menu { right: auto; left: 0; }
1066
+ }