phonon-studio 0.0.0-stage → 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.
@@ -0,0 +1,1234 @@
1
+ /* ── Theme tokens ────────────────────────────────────────────────────────── */
2
+ :root {
3
+ color-scheme: dark;
4
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
5
+
6
+ --bg: #10131b;
7
+ --bg-grad: #273252;
8
+ --fg: #edf0fa;
9
+ --fg-muted: #9ba5bd;
10
+ --fg-dim: #778198;
11
+ --fg-subtle: #aab4c9;
12
+ --fg-btn: #b4bdd1;
13
+ --fg-input: #f2f3fb;
14
+ --border: #343d50;
15
+ --border-alt: #30384b;
16
+ --panel: #191e2a;
17
+ --well: #111621;
18
+ --tab-off: #7a8499;
19
+ --tab-hover: #c4cfdf;
20
+ --accent: #a78bfa;
21
+ --accent2: #4f83ff;
22
+ --accent-dim: #c4b5fd;
23
+ --success: #86efac;
24
+ --warning: #fcd34d;
25
+ --error: #fca5a5;
26
+ --drop-bg: #1e2638cc;
27
+ }
28
+
29
+ html.light {
30
+ color-scheme: light;
31
+ --bg: #f4f6fb;
32
+ --bg-grad: #dde6f8;
33
+ --fg: #1a1f2e;
34
+ --fg-muted: #5a6278;
35
+ --fg-dim: #8892a4;
36
+ --fg-subtle: #6b7590;
37
+ --fg-btn: #4a5470;
38
+ --fg-input: #1a1f2e;
39
+ --border: #ccd3e0;
40
+ --border-alt: #d6dcea;
41
+ --panel: #ffffff;
42
+ --well: #f0f3fa;
43
+ --tab-off: #8892a4;
44
+ --tab-hover: #2e3554;
45
+ --accent: #7c3aed;
46
+ --accent2: #2563eb;
47
+ --accent-dim: #6d28d9;
48
+ --success: #15803d;
49
+ --warning: #b45309;
50
+ --error: #b91c1c;
51
+ --drop-bg: #dde6f8cc;
52
+ }
53
+
54
+ * { box-sizing: border-box; }
55
+
56
+ body {
57
+ margin: 0;
58
+ min-height: 100vh;
59
+ background:
60
+ radial-gradient(ellipse at 50% 0%, var(--bg-grad) 0%, transparent 55%),
61
+ var(--bg);
62
+ color: var(--fg);
63
+ transition: background 0.25s, color 0.25s;
64
+ }
65
+
66
+ .app {
67
+ width: min(900px, 92%);
68
+ margin: auto;
69
+ padding: 30px 0 40px;
70
+ }
71
+
72
+ /* ── Sticky topbar ── */
73
+ .topbar {
74
+ position: sticky;
75
+ top: 0;
76
+ z-index: 200;
77
+ width: 100%;
78
+ background: color-mix(in srgb, var(--bg) 88%, transparent);
79
+ backdrop-filter: blur(18px);
80
+ -webkit-backdrop-filter: blur(18px);
81
+ border-bottom: 1px solid var(--border-alt);
82
+ }
83
+
84
+ .topbar-inner {
85
+ display: flex;
86
+ align-items: center;
87
+ justify-content: space-between;
88
+ gap: 16px;
89
+ width: min(900px, 92%);
90
+ margin: auto;
91
+ padding: 10px 0;
92
+ }
93
+
94
+ .topbar-right { display: flex; align-items: center; gap: 10px; }
95
+
96
+ .brand, .panel-heading, .editor-footer,
97
+ .controls, footer {
98
+ display: flex;
99
+ align-items: center;
100
+ justify-content: space-between;
101
+ gap: 16px;
102
+ }
103
+
104
+ .brand { justify-content: flex-start; }
105
+
106
+ .logo {
107
+ display: grid;
108
+ place-items: center;
109
+ width: 45px;
110
+ height: 45px;
111
+ border-radius: 14px;
112
+ background: linear-gradient(135deg, var(--accent), var(--accent2));
113
+ color: white;
114
+ font-size: 25px;
115
+ font-weight: 800;
116
+ flex-shrink: 0;
117
+ }
118
+
119
+ h1, h2, h3, p { margin-top: 0; }
120
+ h1 { font-size: 18px; margin-bottom: 4px; }
121
+ .brand p, .panel-heading p { color: var(--fg-muted); margin-bottom: 0; font-size: 13px; }
122
+
123
+ .status, .tag {
124
+ border: 1px solid var(--border);
125
+ border-radius: 99px;
126
+ padding: 8px 12px;
127
+ color: var(--fg-muted);
128
+ font-size: 12px;
129
+ font-weight: 600;
130
+ white-space: nowrap;
131
+ }
132
+
133
+ .theme-toggle {
134
+ background: transparent;
135
+ border: 1px solid var(--border);
136
+ border-radius: 99px;
137
+ padding: 6px 11px;
138
+ color: var(--fg-muted);
139
+ font-size: 15px;
140
+ cursor: pointer;
141
+ line-height: 1;
142
+ transition: border-color 0.15s, color 0.15s;
143
+ }
144
+ .theme-toggle:hover { border-color: var(--accent); color: var(--fg); }
145
+
146
+ .hero { padding: 65px 0 35px; }
147
+ .eyebrow { color: var(--accent); letter-spacing: 2px; font-size: 11px; font-weight: 700; }
148
+ .hero h2 { font-size: clamp(42px, 7vw, 66px); line-height: 1.04; margin-bottom: 18px; letter-spacing: -2px; }
149
+ .hero h2 span { color: var(--accent); }
150
+ .hero > p:last-child { color: var(--fg-subtle); line-height: 1.6; }
151
+
152
+ /* ── Tabs ── */
153
+ .tabs {
154
+ display: flex;
155
+ gap: 4px;
156
+ margin-bottom: -1px;
157
+ position: relative;
158
+ z-index: 1;
159
+ }
160
+
161
+ .tab {
162
+ background: transparent;
163
+ border: 1px solid transparent;
164
+ border-bottom: none;
165
+ border-radius: 10px 10px 0 0;
166
+ padding: 10px 18px;
167
+ color: var(--tab-off);
168
+ font: inherit;
169
+ font-size: 13px;
170
+ cursor: pointer;
171
+ position: relative;
172
+ transition: color 0.15s;
173
+ }
174
+
175
+ .tab:hover { color: var(--tab-hover); }
176
+
177
+ .tab.active {
178
+ background: var(--panel);
179
+ border-color: var(--border-alt);
180
+ color: var(--fg);
181
+ }
182
+
183
+ .badge {
184
+ display: inline-flex;
185
+ align-items: center;
186
+ justify-content: center;
187
+ min-width: 18px;
188
+ height: 18px;
189
+ background: var(--accent);
190
+ color: white;
191
+ border-radius: 99px;
192
+ font-size: 10px;
193
+ font-weight: 700;
194
+ padding: 0 5px;
195
+ margin-left: 5px;
196
+ vertical-align: middle;
197
+ }
198
+
199
+ /* ── Panel ── */
200
+ .panel {
201
+ background: var(--panel);
202
+ border: 1px solid var(--border-alt);
203
+ border-radius: 0 16px 22px 22px;
204
+ padding: 28px;
205
+ box-shadow: 0 20px 70px #0003;
206
+ }
207
+
208
+ .tab-content[hidden] { display: none; }
209
+ .panel-heading { margin-bottom: 22px; }
210
+ .panel-heading h3 { margin-bottom: 6px; }
211
+ .tag { color: var(--accent-dim); }
212
+
213
+ /* ── Editor ── */
214
+ .drop-zone { position: relative; }
215
+ .drop-zone.drag-over::after {
216
+ content: "Drop .txt file here";
217
+ position: absolute;
218
+ inset: 0;
219
+ background: var(--drop-bg);
220
+ border: 2px dashed var(--accent);
221
+ border-radius: 13px;
222
+ display: flex;
223
+ align-items: center;
224
+ justify-content: center;
225
+ color: var(--accent);
226
+ font-size: 18px;
227
+ font-weight: 600;
228
+ pointer-events: none;
229
+ }
230
+
231
+ textarea {
232
+ display: block;
233
+ width: 100%;
234
+ min-height: 180px;
235
+ resize: vertical;
236
+ background: var(--well);
237
+ color: var(--fg-input);
238
+ border: 1px solid var(--border);
239
+ border-radius: 13px;
240
+ padding: 17px;
241
+ font: inherit;
242
+ font-size: 15px;
243
+ line-height: 1.7;
244
+ outline: none;
245
+ transition: border-color 0.15s;
246
+ }
247
+
248
+ textarea:focus, select:focus { border-color: var(--accent); }
249
+ .editor-footer { margin: 10px 0 16px; color: var(--fg-dim); font-size: 12px; }
250
+ .editor-meta { display: flex; align-items: center; gap: 12px; }
251
+ .duration-hint { color: var(--accent-dim); font-size: 11px; }
252
+ .btn-row { display: flex; gap: 8px; }
253
+
254
+ .url-fetch-row {
255
+ display: flex;
256
+ gap: 8px;
257
+ margin: 10px 0 8px;
258
+ }
259
+ .url-input {
260
+ flex: 1;
261
+ background: var(--well);
262
+ color: var(--fg-input);
263
+ border: 1px solid var(--border);
264
+ border-radius: 10px;
265
+ padding: 9px 13px;
266
+ font: inherit;
267
+ font-size: 13px;
268
+ outline: none;
269
+ transition: border-color 0.15s;
270
+ }
271
+ .url-input:focus { border-color: var(--accent); }
272
+ .url-input::placeholder { color: var(--fg-dim); }
273
+
274
+ .cleanup-label {
275
+ display: flex;
276
+ align-items: center;
277
+ gap: 6px;
278
+ font-size: 12px;
279
+ color: var(--fg-subtle);
280
+ cursor: pointer;
281
+ white-space: nowrap;
282
+ position: relative;
283
+ }
284
+ .cleanup-label input[type=checkbox] { accent-color: var(--accent); width: 14px; height: 14px; }
285
+
286
+ .pdf-pagination {
287
+ display: flex;
288
+ align-items: center;
289
+ gap: 10px;
290
+ margin: 6px 0 10px;
291
+ padding: 9px 14px;
292
+ background: color-mix(in srgb, var(--accent) 8%, var(--well));
293
+ border: 1px solid color-mix(in srgb, var(--accent) 25%, var(--border));
294
+ border-radius: 10px;
295
+ flex-wrap: wrap;
296
+ }
297
+ .pdf-pagination[hidden] { display: none; }
298
+
299
+ .pdf-nav-btn {
300
+ border: 1px solid var(--border);
301
+ border-radius: 8px;
302
+ padding: 5px 13px;
303
+ font-size: 13px;
304
+ transition: border-color 0.15s, color 0.15s;
305
+ }
306
+ .pdf-nav-btn:hover:not(:disabled) { border-color: var(--accent); color: var(--fg); }
307
+ .pdf-nav-btn:disabled { opacity: 0.35; cursor: default; }
308
+
309
+ .pdf-page-info {
310
+ font-size: 13px;
311
+ font-weight: 600;
312
+ color: var(--accent);
313
+ min-width: 90px;
314
+ text-align: center;
315
+ }
316
+
317
+ .pdf-page-hint {
318
+ font-size: 11px;
319
+ color: var(--fg-dim);
320
+ margin-left: auto;
321
+ }
322
+ button, select { font: inherit; cursor: pointer; border-radius: 10px; }
323
+ button { border: 0; padding: 12px 17px; font-weight: 650; }
324
+ .subtle { background: transparent; color: var(--fg-btn); padding: 6px 10px; }
325
+ .subtle:hover { color: var(--fg); }
326
+
327
+ .controls { align-items: center; gap: 12px; }
328
+ .controls > label:first-child { flex: 0 0 auto; color: var(--fg-subtle); font-size: 12px; }
329
+ .controls-opts {
330
+ display: flex;
331
+ align-items: center;
332
+ gap: 8px;
333
+ flex-wrap: wrap;
334
+ }
335
+ .controls-divider {
336
+ width: 1px;
337
+ height: 18px;
338
+ background: var(--border);
339
+ margin: 0 2px;
340
+ flex-shrink: 0;
341
+ }
342
+ .controls-action-btn {
343
+ font-size: 12px !important;
344
+ font-weight: 500 !important;
345
+ padding: 5px 10px !important;
346
+ color: var(--fg-subtle);
347
+ border: 1px solid var(--border);
348
+ border-radius: 8px;
349
+ }
350
+ .controls-action-btn:hover { color: var(--fg); border-color: var(--fg-subtle); }
351
+ select {
352
+ display: block;
353
+ width: 100%;
354
+ margin-top: 9px;
355
+ padding: 13px;
356
+ color: var(--fg-input);
357
+ background: var(--well);
358
+ border: 1px solid var(--border);
359
+ }
360
+
361
+ .primary {
362
+ color: white;
363
+ background: linear-gradient(110deg, var(--accent), var(--accent2));
364
+ min-height: 45px;
365
+ white-space: nowrap;
366
+ }
367
+ .primary:disabled { opacity: .55; cursor: wait; }
368
+ .primary:hover:not(:disabled) { filter: brightness(1.1); }
369
+
370
+ #message { margin: 20px 0 0; font-size: 13px; color: var(--fg-subtle); min-height: 20px; }
371
+
372
+ /* ── Result ── */
373
+ #result { margin-top: 24px; padding-top: 20px; border-top: 1px solid var(--border-alt); }
374
+
375
+ .result-header {
376
+ display: flex;
377
+ align-items: center;
378
+ justify-content: space-between;
379
+ margin-bottom: 14px;
380
+ gap: 16px;
381
+ flex-wrap: wrap;
382
+ }
383
+ .result-header h3 { margin: 0; font-size: 15px; }
384
+
385
+ .speed-control { display: flex; align-items: center; gap: 10px; font-size: 12px; color: var(--fg-subtle); }
386
+ .speed-control input[type=range] { width: 100px; accent-color: var(--accent); }
387
+
388
+ .sync-row {
389
+ display: flex;
390
+ align-items: center;
391
+ gap: 10px;
392
+ margin-bottom: 10px;
393
+ font-size: 12px;
394
+ color: var(--fg-subtle);
395
+ }
396
+ .sync-row[hidden] { display: none; }
397
+ .sync-row label { white-space: nowrap; }
398
+ .sync-row input[type=range] { width: 120px; accent-color: var(--accent2); }
399
+
400
+ #waveform {
401
+ display: block;
402
+ width: 100%;
403
+ background: var(--well);
404
+ border-radius: 10px;
405
+ margin-bottom: 10px;
406
+ }
407
+
408
+ .word-display {
409
+ background: var(--well);
410
+ border: 1px solid var(--border);
411
+ border-radius: 10px;
412
+ padding: 14px 16px;
413
+ margin-bottom: 10px;
414
+ font-size: 14px;
415
+ line-height: 1.85;
416
+ color: var(--fg-muted);
417
+ max-height: 200px;
418
+ overflow-y: auto;
419
+ scroll-behavior: smooth;
420
+ }
421
+ .word-display[hidden] { display: none; }
422
+
423
+ .line-token {
424
+ display: inline;
425
+ border-radius: 4px;
426
+ padding: 2px 4px;
427
+ transition: background 0.2s, color 0.2s, box-shadow 0.2s;
428
+ cursor: default;
429
+ }
430
+ .line-token.speaking {
431
+ background: color-mix(in srgb, var(--accent) 22%, transparent);
432
+ color: var(--fg);
433
+ font-weight: 500;
434
+ box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent) 30%, transparent);
435
+ }
436
+
437
+ audio { width: 100%; margin: 0 0 14px; }
438
+
439
+ .download-row { display: flex; gap: 10px; flex-wrap: wrap; }
440
+
441
+ .download-btn {
442
+ display: inline-flex;
443
+ align-items: center;
444
+ padding: 9px 16px;
445
+ border: 1px solid var(--border);
446
+ border-radius: 10px;
447
+ color: var(--accent-dim);
448
+ text-decoration: none;
449
+ font-size: 13px;
450
+ background: transparent;
451
+ cursor: pointer;
452
+ transition: border-color 0.15s, color 0.15s;
453
+ }
454
+ .download-btn:hover { border-color: var(--accent); color: var(--fg); }
455
+ .mp3-btn { color: var(--success); }
456
+ .mp3-btn:hover { border-color: var(--success); }
457
+
458
+ /* ── Voice Compare ── */
459
+ .voice-grid {
460
+ display: grid;
461
+ grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
462
+ gap: 16px;
463
+ margin-top: 16px;
464
+ }
465
+
466
+ .voice-card {
467
+ background: var(--well);
468
+ border: 1px solid var(--border);
469
+ border-radius: 14px;
470
+ padding: 16px;
471
+ }
472
+
473
+ .voice-card-name {
474
+ font-size: 13px;
475
+ font-weight: 700;
476
+ color: var(--accent-dim);
477
+ margin-bottom: 10px;
478
+ letter-spacing: 0.5px;
479
+ }
480
+
481
+ .error-text { color: var(--error); font-size: 12px; margin: 8px 0 0; }
482
+
483
+ /* ── LLM Chat ── */
484
+ .field-label { display: block; color: var(--fg-subtle); font-size: 12px; }
485
+ .field-label select, .field-label textarea { margin-top: 9px; width: 100%; }
486
+ .field-label textarea { min-height: 80px; resize: vertical; }
487
+
488
+ .chat-actions { display: flex; justify-content: flex-end; margin-top: 12px; }
489
+
490
+ .response-box {
491
+ background: var(--well);
492
+ border: 1px solid var(--border);
493
+ border-radius: 13px;
494
+ padding: 16px;
495
+ margin-top: 18px;
496
+ line-height: 1.7;
497
+ color: var(--fg-input);
498
+ font-size: 14px;
499
+ white-space: pre-wrap;
500
+ }
501
+ .response-box p { margin: 0; }
502
+
503
+ .chat-response-actions { display: flex; gap: 10px; margin-top: 12px; }
504
+
505
+ #chat-message { margin: 12px 0 0; font-size: 13px; color: var(--fg-subtle); min-height: 18px; }
506
+
507
+ /* ── History ── */
508
+ .history-controls { display: flex; align-items: center; gap: 10px; }
509
+ .history-controls select {
510
+ padding: 7px 10px;
511
+ font-size: 12px;
512
+ width: auto;
513
+ margin: 0;
514
+ border-radius: 8px;
515
+ }
516
+
517
+ .history-group-label {
518
+ font-size: 10px;
519
+ font-weight: 700;
520
+ text-transform: uppercase;
521
+ letter-spacing: 1.5px;
522
+ color: var(--accent);
523
+ padding: 4px 0 2px;
524
+ margin-bottom: 4px;
525
+ }
526
+
527
+ .pin-btn {
528
+ background: transparent;
529
+ border: none;
530
+ padding: 2px 6px;
531
+ font-size: 16px;
532
+ line-height: 1;
533
+ color: var(--fg-dim);
534
+ cursor: pointer;
535
+ border-radius: 6px;
536
+ transition: color 0.15s;
537
+ }
538
+ .pin-btn:hover { color: var(--accent); }
539
+ .pin-btn.pinned { color: var(--accent); }
540
+
541
+ .pin-badge {
542
+ font-size: 10px;
543
+ font-weight: 700;
544
+ background: color-mix(in srgb, var(--accent) 15%, transparent);
545
+ color: var(--accent);
546
+ border-radius: 99px;
547
+ padding: 2px 7px;
548
+ letter-spacing: 0.5px;
549
+ }
550
+
551
+ #history-list { display: flex; flex-direction: column; gap: 14px; margin-top: 4px; }
552
+
553
+ .history-item {
554
+ background: var(--well);
555
+ border: 1px solid var(--border);
556
+ border-radius: 14px;
557
+ padding: 16px;
558
+ }
559
+
560
+ .history-meta { display: flex; justify-content: space-between; align-items: center; margin-bottom: 6px; }
561
+
562
+ .history-voice {
563
+ font-size: 11px;
564
+ font-weight: 700;
565
+ color: var(--accent-dim);
566
+ text-transform: uppercase;
567
+ letter-spacing: 1px;
568
+ }
569
+
570
+ .history-time { font-size: 11px; color: var(--fg-dim); }
571
+
572
+ .history-text {
573
+ font-size: 13px;
574
+ color: var(--fg-muted);
575
+ margin: 0 0 8px;
576
+ white-space: nowrap;
577
+ overflow: hidden;
578
+ text-overflow: ellipsis;
579
+ }
580
+
581
+ .download-link { display: inline-block; color: var(--accent-dim); font-size: 12px; text-decoration: none; margin-top: 6px; }
582
+ .download-link:hover { color: var(--fg); }
583
+
584
+ .empty-state { color: var(--fg-dim); font-size: 14px; text-align: center; padding: 24px 0; margin: 0; }
585
+
586
+ footer { margin-top: 28px; color: var(--fg-dim); font-size: 10px; letter-spacing: 1px; }
587
+
588
+ @media (max-width: 600px) {
589
+ .app { padding-top: 18px; }
590
+ .hero { padding-top: 45px; }
591
+ .panel { padding: 18px; }
592
+ .tabs { overflow-x: auto; }
593
+ .controls { align-items: stretch; flex-direction: column; }
594
+ .controls-opts { flex-wrap: wrap; }
595
+ .primary { width: 100%; }
596
+ .result-header { flex-direction: column; align-items: flex-start; }
597
+ .voice-grid { grid-template-columns: 1fr; }
598
+ footer { align-items: flex-start; flex-direction: column; gap: 8px; }
599
+ }
600
+
601
+ /* ── Splash ──────────────────────────────────────────────────────────────────── */
602
+ .splash {
603
+ position: fixed;
604
+ inset: 0;
605
+ z-index: 1000;
606
+ background:
607
+ radial-gradient(ellipse at 50% 25%, var(--bg-grad) 0%, transparent 60%),
608
+ var(--bg);
609
+ display: flex;
610
+ align-items: center;
611
+ justify-content: center;
612
+ transition: opacity 0.5s ease;
613
+ }
614
+ .splash.hiding { opacity: 0; pointer-events: none; }
615
+
616
+ .splash-inner {
617
+ text-align: center;
618
+ padding: 40px 24px;
619
+ max-width: 500px;
620
+ width: 100%;
621
+ animation: splashIn 0.65s cubic-bezier(0.22, 1, 0.36, 1) both;
622
+ }
623
+ @keyframes splashIn {
624
+ from { opacity: 0; transform: translateY(30px); }
625
+ to { opacity: 1; transform: translateY(0); }
626
+ }
627
+
628
+ .splash-logo {
629
+ width: 84px;
630
+ height: 84px;
631
+ border-radius: 26px;
632
+ background: linear-gradient(135deg, var(--accent), var(--accent2));
633
+ color: white;
634
+ font-size: 46px;
635
+ font-weight: 800;
636
+ display: grid;
637
+ place-items: center;
638
+ margin: 0 auto 26px;
639
+ animation: logoPulse 2.8s ease-in-out infinite;
640
+ }
641
+ @keyframes logoPulse {
642
+ 0%, 100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--accent) 50%, transparent); }
643
+ 50% { box-shadow: 0 0 0 18px transparent; }
644
+ }
645
+
646
+ .splash-title {
647
+ font-size: clamp(28px, 6vw, 40px);
648
+ font-weight: 800;
649
+ letter-spacing: -1.5px;
650
+ margin: 0 0 10px;
651
+ }
652
+ .splash-sub {
653
+ color: var(--fg-muted);
654
+ font-size: 15px;
655
+ line-height: 1.55;
656
+ margin: 0 0 28px;
657
+ }
658
+ .splash-features {
659
+ display: flex;
660
+ flex-wrap: wrap;
661
+ gap: 9px;
662
+ justify-content: center;
663
+ margin-bottom: 30px;
664
+ }
665
+ .splash-feat {
666
+ display: flex;
667
+ align-items: center;
668
+ gap: 6px;
669
+ background: var(--well);
670
+ border: 1px solid var(--border);
671
+ border-radius: 99px;
672
+ padding: 7px 14px;
673
+ font-size: 13px;
674
+ color: var(--fg-muted);
675
+ }
676
+ .splash-btn {
677
+ display: inline-flex;
678
+ align-items: center;
679
+ gap: 8px;
680
+ padding: 14px 34px;
681
+ font-size: 16px;
682
+ border-radius: 14px;
683
+ margin-bottom: 20px;
684
+ cursor: pointer;
685
+ }
686
+ .splash-note {
687
+ font-size: 11px;
688
+ color: var(--fg-dim);
689
+ letter-spacing: 0.3px;
690
+ margin: 0;
691
+ }
692
+
693
+ /* ── Modal ───────────────────────────────────────────────────────────────────── */
694
+ .modal-overlay {
695
+ position: fixed;
696
+ inset: 0;
697
+ z-index: 900;
698
+ background: rgba(0,0,0,0.55);
699
+ display: flex;
700
+ align-items: center;
701
+ justify-content: center;
702
+ padding: 20px;
703
+ backdrop-filter: blur(4px);
704
+ }
705
+ .modal-overlay[hidden] { display: none; }
706
+ .modal {
707
+ background: var(--panel);
708
+ border: 1px solid var(--border-alt);
709
+ border-radius: 20px;
710
+ width: min(560px, 100%);
711
+ max-height: 82vh;
712
+ overflow: hidden;
713
+ display: flex;
714
+ flex-direction: column;
715
+ box-shadow: 0 32px 80px #0006;
716
+ animation: modalIn 0.2s ease;
717
+ }
718
+ @keyframes modalIn {
719
+ from { opacity: 0; transform: scale(0.95) translateY(8px); }
720
+ to { opacity: 1; transform: scale(1) translateY(0); }
721
+ }
722
+ .modal-header {
723
+ display: flex;
724
+ align-items: center;
725
+ justify-content: space-between;
726
+ padding: 20px 24px 16px;
727
+ border-bottom: 1px solid var(--border-alt);
728
+ flex-shrink: 0;
729
+ }
730
+ .modal-header h3 { margin: 0; font-size: 17px; }
731
+ .modal-close { font-size: 16px; padding: 4px 9px; }
732
+ .modal-body {
733
+ overflow-y: auto;
734
+ padding: 20px 24px 28px;
735
+ display: flex;
736
+ flex-direction: column;
737
+ gap: 22px;
738
+ }
739
+ .help-section h4 {
740
+ font-size: 10px;
741
+ font-weight: 700;
742
+ text-transform: uppercase;
743
+ letter-spacing: 1.5px;
744
+ color: var(--accent);
745
+ margin: 0 0 12px;
746
+ }
747
+ .shortcut-row {
748
+ display: flex;
749
+ align-items: center;
750
+ gap: 8px;
751
+ margin-bottom: 9px;
752
+ font-size: 13px;
753
+ color: var(--fg-muted);
754
+ }
755
+ kbd {
756
+ display: inline-flex;
757
+ align-items: center;
758
+ justify-content: center;
759
+ background: var(--well);
760
+ border: 1px solid var(--border);
761
+ border-bottom-width: 2px;
762
+ border-radius: 5px;
763
+ padding: 2px 8px;
764
+ font-family: inherit;
765
+ font-size: 12px;
766
+ color: var(--fg);
767
+ white-space: nowrap;
768
+ }
769
+ .help-dl { margin: 0; }
770
+ .help-dl dt { font-size: 13px; font-weight: 700; color: var(--fg); margin-top: 12px; }
771
+ .help-dl dd { margin: 3px 0 0; font-size: 13px; color: var(--fg-muted); line-height: 1.55; }
772
+ .help-tips {
773
+ margin: 0;
774
+ padding-left: 18px;
775
+ display: flex;
776
+ flex-direction: column;
777
+ gap: 7px;
778
+ }
779
+ .help-tips li { font-size: 13px; color: var(--fg-muted); line-height: 1.55; }
780
+ .help-tips code, .help-hint code {
781
+ background: var(--well);
782
+ border: 1px solid var(--border);
783
+ border-radius: 4px;
784
+ padding: 1px 5px;
785
+ font-family: "SF Mono", "Fira Mono", ui-monospace, monospace;
786
+ font-size: 11px;
787
+ color: var(--accent-dim);
788
+ }
789
+ .help-status { display: flex; align-items: center; gap: 7px; font-size: 13px; color: var(--fg-muted); margin: 5px 0; }
790
+ .help-hint { font-size: 12px; color: var(--fg-dim); margin: 8px 0 0; }
791
+ .dot-green { color: #86efac; font-size: 15px; }
792
+ .dot-red { color: #fca5a5; font-size: 15px; }
793
+ html.light .dot-green { color: #16a34a; }
794
+ html.light .dot-red { color: #dc2626; }
795
+
796
+ /* ── CSS Tooltips ────────────────────────────────────────────────────────────── */
797
+ [data-tooltip] { position: relative; }
798
+ [data-tooltip]::after {
799
+ content: attr(data-tooltip);
800
+ position: absolute;
801
+ bottom: calc(100% + 8px);
802
+ left: 50%;
803
+ transform: translateX(-50%);
804
+ background: var(--panel);
805
+ border: 1px solid var(--border-alt);
806
+ border-radius: 8px;
807
+ padding: 6px 11px;
808
+ font-size: 12px;
809
+ font-weight: 400;
810
+ color: var(--fg);
811
+ white-space: nowrap;
812
+ pointer-events: none;
813
+ opacity: 0;
814
+ transition: opacity 0.15s 0.35s;
815
+ z-index: 500;
816
+ box-shadow: 0 4px 16px #0003;
817
+ }
818
+ [data-tooltip]:hover::after { opacity: 1; }
819
+
820
+ /* ── Splash tour link ────────────────────────────────────────────────────────── */
821
+ .splash-tour-link {
822
+ display: block;
823
+ margin: 0 auto 18px;
824
+ font-size: 13px;
825
+ color: var(--fg-muted);
826
+ text-decoration: underline;
827
+ text-underline-offset: 3px;
828
+ background: transparent;
829
+ border: none;
830
+ padding: 4px 0;
831
+ cursor: pointer;
832
+ }
833
+ .splash-tour-link:hover { color: var(--fg); }
834
+
835
+ /* ── Guided tour ─────────────────────────────────────────────────────────────── */
836
+ #tour-overlay {
837
+ position: fixed;
838
+ inset: 0;
839
+ z-index: 800;
840
+ pointer-events: none;
841
+ }
842
+ #tour-overlay[hidden] { display: none; }
843
+
844
+ .tour-spot {
845
+ position: fixed;
846
+ border-radius: 10px;
847
+ box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.72);
848
+ pointer-events: none;
849
+ transition: top 0.3s ease, left 0.3s ease, width 0.3s ease, height 0.3s ease;
850
+ z-index: 801;
851
+ }
852
+
853
+ .tour-bubble {
854
+ position: fixed;
855
+ z-index: 802;
856
+ background: var(--panel);
857
+ border: 1px solid var(--border-alt);
858
+ border-radius: 16px;
859
+ padding: 20px 22px 16px;
860
+ width: min(320px, calc(100vw - 40px));
861
+ box-shadow: 0 24px 60px #0008;
862
+ pointer-events: all;
863
+ animation: bubbleIn 0.22s cubic-bezier(0.22, 1, 0.36, 1) both;
864
+ }
865
+ @keyframes bubbleIn {
866
+ from { opacity: 0; transform: scale(0.92) translateY(8px); }
867
+ to { opacity: 1; transform: scale(1) translateY(0); }
868
+ }
869
+
870
+ .tour-step-num {
871
+ font-size: 10px;
872
+ font-weight: 700;
873
+ letter-spacing: 1.5px;
874
+ text-transform: uppercase;
875
+ color: var(--accent);
876
+ margin-bottom: 8px;
877
+ }
878
+
879
+ .tour-bubble h4 {
880
+ margin: 0 0 8px;
881
+ font-size: 15px;
882
+ }
883
+
884
+ .tour-bubble p {
885
+ margin: 0 0 16px;
886
+ font-size: 13px;
887
+ color: var(--fg-muted);
888
+ line-height: 1.6;
889
+ }
890
+
891
+ .tour-actions {
892
+ display: flex;
893
+ align-items: center;
894
+ justify-content: space-between;
895
+ gap: 10px;
896
+ }
897
+
898
+ .tour-nav {
899
+ display: flex;
900
+ align-items: center;
901
+ gap: 8px;
902
+ }
903
+
904
+ .tour-skip-btn { font-size: 12px; color: var(--fg-dim); padding: 6px 8px; }
905
+ .tour-skip-btn:hover { color: var(--fg); }
906
+
907
+ .tour-arrow {
908
+ padding: 6px 12px;
909
+ font-size: 15px;
910
+ border: 1px solid var(--border);
911
+ border-radius: 8px;
912
+ color: var(--fg-muted);
913
+ }
914
+ .tour-arrow:hover:not(:disabled) { border-color: var(--accent); color: var(--fg); }
915
+ .tour-arrow:disabled { opacity: 0.3; cursor: default; }
916
+
917
+ /* ── Pronunciations modal ─────────────────────────────────────────────────── */
918
+ .pron-add-row {
919
+ display: flex;
920
+ align-items: center;
921
+ gap: 8px;
922
+ margin-top: 14px;
923
+ flex-wrap: wrap;
924
+ }
925
+ .pron-add-row input { flex: 1; min-width: 100px; }
926
+ .pron-arrow-label { color: var(--fg-subtle); font-size: 18px; }
927
+ .pron-row {
928
+ display: flex;
929
+ align-items: center;
930
+ gap: 8px;
931
+ padding: 7px 0;
932
+ border-bottom: 1px solid var(--border);
933
+ font-size: 14px;
934
+ }
935
+ .pron-row:last-child { border-bottom: none; }
936
+ .pron-word { font-weight: 600; color: var(--fg); }
937
+ .pron-spoken { flex: 1; color: var(--accent-dim); }
938
+ .pron-del-btn {
939
+ background: none;
940
+ border: none;
941
+ padding: 2px 6px;
942
+ font-size: 13px;
943
+ color: var(--fg-subtle);
944
+ cursor: pointer;
945
+ border-radius: 4px;
946
+ }
947
+ .pron-del-btn:hover { color: var(--error); background: color-mix(in srgb, var(--error) 12%, transparent); }
948
+
949
+ /* ── Karaoke / focus mode overlay ────────────────────────────────────────── */
950
+ #karaoke-overlay {
951
+ position: fixed;
952
+ inset: 0;
953
+ z-index: 400;
954
+ background: var(--bg);
955
+ display: flex;
956
+ align-items: center;
957
+ justify-content: center;
958
+ }
959
+ #karaoke-overlay[hidden] { display: none; }
960
+ .karaoke-inner {
961
+ text-align: center;
962
+ padding: 40px 5vw;
963
+ max-width: 820px;
964
+ width: 100%;
965
+ }
966
+ .karaoke-progress-wrap {
967
+ width: 100%;
968
+ height: 4px;
969
+ background: var(--well);
970
+ border-radius: 2px;
971
+ margin-bottom: 32px;
972
+ }
973
+ .karaoke-progress-bar {
974
+ height: 100%;
975
+ background: var(--accent);
976
+ border-radius: 2px;
977
+ width: 0%;
978
+ transition: width 0.15s linear;
979
+ }
980
+ .karaoke-line {
981
+ font-size: clamp(1.6rem, 4vw, 2.8rem);
982
+ font-weight: 600;
983
+ line-height: 1.4;
984
+ color: var(--fg);
985
+ min-height: 120px;
986
+ display: flex;
987
+ align-items: center;
988
+ justify-content: center;
989
+ }
990
+ .karaoke-exit-btn { margin-top: 32px; font-size: 13px; color: var(--fg-subtle); }
991
+ .karaoke-launch-btn { font-size: 12px; padding: 4px 10px; }
992
+
993
+ /* ── Audio bookmarks ──────────────────────────────────────────────────────── */
994
+ .bookmark-row { margin-bottom: 10px; }
995
+ .bookmark-row[hidden] { display: none; }
996
+ .bookmark-hint { font-size: 12px; color: var(--fg-subtle); }
997
+ .bookmark-hint kbd {
998
+ background: var(--well);
999
+ border: 1px solid var(--border);
1000
+ border-radius: 4px;
1001
+ padding: 0 5px;
1002
+ font-size: 11px;
1003
+ }
1004
+ .bookmark-list {
1005
+ display: flex;
1006
+ flex-wrap: wrap;
1007
+ gap: 6px;
1008
+ margin-top: 8px;
1009
+ align-items: center;
1010
+ }
1011
+ .bm-chip {
1012
+ display: inline-flex;
1013
+ align-items: center;
1014
+ gap: 4px;
1015
+ font-size: 12px;
1016
+ padding: 3px 8px;
1017
+ border: 1px solid var(--border);
1018
+ border-radius: 20px;
1019
+ background: var(--well);
1020
+ color: var(--fg-muted);
1021
+ }
1022
+ .bm-seek {
1023
+ background: none;
1024
+ border: none;
1025
+ padding: 0;
1026
+ color: inherit;
1027
+ cursor: pointer;
1028
+ font-size: 12px;
1029
+ }
1030
+ .bm-seek:hover { color: var(--accent); }
1031
+ .bm-del {
1032
+ background: none;
1033
+ border: none;
1034
+ padding: 0 2px;
1035
+ font-size: 11px;
1036
+ color: var(--fg-dim);
1037
+ cursor: pointer;
1038
+ line-height: 1;
1039
+ }
1040
+ .bm-del:hover { color: var(--error); }
1041
+
1042
+ /* ── Subtitle download buttons ───────────────────────────────────────────── */
1043
+ .subtitle-btn { color: var(--fg-muted); border-color: var(--border); }
1044
+ .subtitle-btn:hover { color: var(--accent); border-color: var(--accent); }
1045
+
1046
+ /* ── Batch queue panel ───────────────────────────────────────────────────── */
1047
+ .queue-panel {
1048
+ background: var(--well);
1049
+ border: 1px solid var(--border);
1050
+ border-radius: 10px;
1051
+ padding: 12px 14px;
1052
+ margin-top: 8px;
1053
+ }
1054
+ .queue-panel[hidden] { display: none; }
1055
+ .queue-panel-header {
1056
+ display: flex;
1057
+ align-items: center;
1058
+ justify-content: space-between;
1059
+ font-size: 13px;
1060
+ font-weight: 600;
1061
+ color: var(--fg);
1062
+ margin-bottom: 10px;
1063
+ }
1064
+ .queue-clear-btn { font-size: 12px; }
1065
+ .queue-item {
1066
+ display: flex;
1067
+ align-items: center;
1068
+ gap: 8px;
1069
+ padding: 6px 0;
1070
+ border-bottom: 1px solid var(--border-alt);
1071
+ font-size: 13px;
1072
+ }
1073
+ .queue-item:last-child { border-bottom: none; }
1074
+ .queue-num { width: 22px; color: var(--fg-subtle); text-align: right; flex-shrink: 0; font-size: 12px; }
1075
+ .queue-preview { flex: 1; color: var(--fg-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 12px; }
1076
+ .queue-status-cell { color: var(--fg-subtle); font-size: 12px; white-space: nowrap; }
1077
+ .queue-item--generating .queue-status-cell { color: var(--accent); }
1078
+ .queue-item--done .queue-status-cell { color: var(--success); }
1079
+ .queue-item--error .queue-status-cell { color: var(--error); }
1080
+
1081
+ .tour-next-btn { padding: 8px 16px; font-size: 13px; border-radius: 8px; min-height: unset; }
1082
+
1083
+ /* ── Line-token click-to-seek ────────────────────────────────────────────── */
1084
+ .line-token { cursor: pointer; }
1085
+ .line-token:hover { background: color-mix(in srgb, var(--fg-subtle) 10%, transparent); }
1086
+
1087
+ /* ── Bookmark actions row ────────────────────────────────────────────────── */
1088
+ .bookmark-actions {
1089
+ display: flex;
1090
+ align-items: center;
1091
+ justify-content: space-between;
1092
+ gap: 8px;
1093
+ margin-bottom: 6px;
1094
+ }
1095
+
1096
+ /* ── A/B loop row ────────────────────────────────────────────────────────── */
1097
+ .loop-row {
1098
+ display: flex;
1099
+ align-items: center;
1100
+ gap: 10px;
1101
+ padding: 6px 10px;
1102
+ margin-bottom: 10px;
1103
+ background: color-mix(in srgb, var(--accent) 8%, transparent);
1104
+ border: 1px solid color-mix(in srgb, var(--accent) 25%, transparent);
1105
+ border-radius: 8px;
1106
+ font-size: 12px;
1107
+ }
1108
+ .loop-row[hidden] { display: none; }
1109
+ .loop-label { font-weight: 600; color: var(--accent-dim); white-space: nowrap; }
1110
+ .loop-hint { color: var(--fg-subtle); flex: 1; }
1111
+ .loop-hint kbd {
1112
+ background: var(--well);
1113
+ border: 1px solid var(--border);
1114
+ border-radius: 4px;
1115
+ padding: 0 4px;
1116
+ font-size: 11px;
1117
+ }
1118
+
1119
+ /* ── Sent text panel ─────────────────────────────────────────────────────── */
1120
+ .sent-text-toggle {
1121
+ font-size: 12px;
1122
+ margin-top: 4px;
1123
+ display: inline-block;
1124
+ color: var(--fg-subtle);
1125
+ }
1126
+ .sent-text-row {
1127
+ margin: 8px 0 4px;
1128
+ border: 1px solid var(--border);
1129
+ border-radius: 8px;
1130
+ overflow: hidden;
1131
+ }
1132
+ .sent-text-row[hidden] { display: none; }
1133
+ .sent-text-content {
1134
+ margin: 0;
1135
+ padding: 10px 12px;
1136
+ font-size: 12px;
1137
+ font-family: inherit;
1138
+ color: var(--fg-muted);
1139
+ background: var(--well);
1140
+ white-space: pre-wrap;
1141
+ word-break: break-word;
1142
+ max-height: 120px;
1143
+ overflow-y: auto;
1144
+ }
1145
+ .sent-text-row #copy-sent {
1146
+ display: block;
1147
+ width: 100%;
1148
+ border-radius: 0;
1149
+ border-top: 1px solid var(--border);
1150
+ font-size: 12px;
1151
+ padding: 6px;
1152
+ }
1153
+
1154
+ /* ── Text templates modal ────────────────────────────────────────────────── */
1155
+ .templates-save-row {
1156
+ display: flex;
1157
+ gap: 8px;
1158
+ margin-top: 14px;
1159
+ align-items: center;
1160
+ }
1161
+ .templates-save-row input { flex: 1; }
1162
+ .template-row {
1163
+ display: flex;
1164
+ align-items: center;
1165
+ gap: 8px;
1166
+ padding: 7px 0;
1167
+ border-bottom: 1px solid var(--border);
1168
+ font-size: 13px;
1169
+ }
1170
+ .template-row:last-child { border-bottom: none; }
1171
+ .template-name { font-weight: 600; color: var(--fg); white-space: nowrap; }
1172
+ .template-preview { flex: 1; color: var(--fg-subtle); font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
1173
+ .template-load-btn, .template-del-btn { flex-shrink: 0; font-size: 12px; }
1174
+
1175
+ /* ── Voice → Text tab ────────────────────────────────────────────────────── */
1176
+ .transcribe-unsupported {
1177
+ background: color-mix(in srgb, var(--error) 10%, transparent);
1178
+ border: 1px solid color-mix(in srgb, var(--error) 25%, transparent);
1179
+ border-radius: 10px;
1180
+ padding: 16px 18px;
1181
+ color: var(--fg-muted);
1182
+ font-size: 14px;
1183
+ }
1184
+ .transcribe-controls {
1185
+ display: flex;
1186
+ align-items: flex-end;
1187
+ gap: 16px;
1188
+ margin-bottom: 16px;
1189
+ flex-wrap: wrap;
1190
+ }
1191
+ .transcribe-lang-label { flex: 0 0 auto; min-width: 220px; }
1192
+ .transcribe-toggle-btn { white-space: nowrap; }
1193
+ .transcribe-toggle-btn.recording {
1194
+ background: var(--error) !important;
1195
+ color: #fff !important;
1196
+ }
1197
+ .transcribe-toggle-btn.recording::before {
1198
+ content: "";
1199
+ display: inline-block;
1200
+ width: 8px;
1201
+ height: 8px;
1202
+ background: #fff;
1203
+ border-radius: 50%;
1204
+ margin-right: 8px;
1205
+ vertical-align: middle;
1206
+ animation: rec-pulse 1s ease-in-out infinite;
1207
+ }
1208
+ @keyframes rec-pulse {
1209
+ 0%, 100% { opacity: 1; transform: scale(1); }
1210
+ 50% { opacity: 0.3; transform: scale(0.7); }
1211
+ }
1212
+ .transcribe-status {
1213
+ font-size: 13px;
1214
+ color: var(--fg-subtle);
1215
+ min-height: 20px;
1216
+ margin: 0 0 12px;
1217
+ }
1218
+ .transcript-display {
1219
+ background: var(--well);
1220
+ border: 1px solid var(--border);
1221
+ border-radius: 10px;
1222
+ padding: 16px 18px;
1223
+ font-size: 15px;
1224
+ line-height: 1.75;
1225
+ min-height: 120px;
1226
+ max-height: 360px;
1227
+ overflow-y: auto;
1228
+ margin-bottom: 12px;
1229
+ cursor: text;
1230
+ user-select: text;
1231
+ }
1232
+ .transcript-final { color: var(--fg); }
1233
+ .transcript-interim { color: var(--fg-subtle); font-style: italic; }
1234
+ .transcribe-actions { display: flex; gap: 10px; flex-wrap: wrap; align-items: center; }