fablecut 0.0.0-stage → 1.12.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.
Files changed (82) hide show
  1. package/CLAUDE.md +1198 -0
  2. package/LICENSE +21 -0
  3. package/README.md +571 -2
  4. package/analyze.js +289 -0
  5. package/app.js +13339 -0
  6. package/audio-fx.js +241 -0
  7. package/cli.js +31 -0
  8. package/color.js +1043 -0
  9. package/denoise.js +120 -0
  10. package/ducking.js +127 -0
  11. package/edit-ops.js +962 -0
  12. package/encode-profiles.js +302 -0
  13. package/encoding-profiles.json +68 -0
  14. package/export-jobs.js +163 -0
  15. package/favicon.svg +14 -0
  16. package/fx-worklet.js +162 -0
  17. package/icons/favicon-32.png +0 -0
  18. package/import-url.js +293 -0
  19. package/index.html +420 -0
  20. package/library/README.md +15 -0
  21. package/library/elements/.gitkeep +0 -0
  22. package/library/elements/bokeh-drift.svg +19 -0
  23. package/library/elements/light-leak-cool.svg +16 -0
  24. package/library/elements/light-leak-warm.svg +22 -0
  25. package/library/elements/vhs-scanlines.svg +18 -0
  26. package/library/elements/vignette-frame.svg +14 -0
  27. package/library/fonts/.gitkeep +0 -0
  28. package/library/fonts/Abril Fatface.woff2 +0 -0
  29. package/library/fonts/Anton.woff2 +0 -0
  30. package/library/fonts/Archivo Black.woff2 +0 -0
  31. package/library/fonts/Bangers.woff2 +0 -0
  32. package/library/fonts/Barlow.woff2 +0 -0
  33. package/library/fonts/Bebas Neue.woff2 +0 -0
  34. package/library/fonts/Bungee.woff2 +0 -0
  35. package/library/fonts/Caveat.woff2 +0 -0
  36. package/library/fonts/DM Sans.woff2 +0 -0
  37. package/library/fonts/Inter.woff2 +0 -0
  38. package/library/fonts/LICENSES.md +31 -0
  39. package/library/fonts/Lato.woff2 +0 -0
  40. package/library/fonts/Montserrat.woff2 +0 -0
  41. package/library/fonts/Oswald.woff2 +0 -0
  42. package/library/fonts/Pacifico.woff2 +0 -0
  43. package/library/fonts/Playfair Display.woff2 +0 -0
  44. package/library/fonts/Poppins.woff2 +0 -0
  45. package/library/fonts/Righteous.woff2 +0 -0
  46. package/library/fonts/Roboto.woff2 +0 -0
  47. package/library/fonts/Rubik.woff2 +0 -0
  48. package/library/fonts/Teko.woff2 +0 -0
  49. package/library/sfx/README.md +18 -0
  50. package/library/svg/ai-star.svg +17 -0
  51. package/library/svg/arrow-bounce.svg +18 -0
  52. package/library/svg/arrow-scribble.svg +13 -0
  53. package/library/svg/burst-lines.svg +30 -0
  54. package/library/svg/checkmark-success.svg +19 -0
  55. package/library/svg/confetti-burst.svg +23 -0
  56. package/library/svg/countdown-ring.svg +92 -0
  57. package/library/svg/equalizer.svg +18 -0
  58. package/library/svg/glow-orbs.svg +29 -0
  59. package/library/svg/heart-pop.svg +28 -0
  60. package/library/svg/loading-dots.svg +16 -0
  61. package/library/svg/location-pin.svg +25 -0
  62. package/library/svg/lower-third.svg +17 -0
  63. package/library/svg/new-badge.svg +18 -0
  64. package/library/svg/progress-bar.svg +16 -0
  65. package/library/svg/radial-pulse.svg +19 -0
  66. package/library/svg/rating-stars.svg +25 -0
  67. package/library/svg/rec-indicator.svg +41 -0
  68. package/library/svg/sparkles.svg +17 -0
  69. package/library/svg/spawning-hearts.svg +39 -0
  70. package/library/svg/speech-bubble.svg +23 -0
  71. package/library/svg/subscribe-bell.svg +29 -0
  72. package/library/svg/subscribe-pill.svg +22 -0
  73. package/library/svg/swipe-up.svg +46 -0
  74. package/library/svg/underline-swoosh.svg +15 -0
  75. package/loudness.js +135 -0
  76. package/mcp-server.js +1421 -0
  77. package/meter-worklet.js +229 -0
  78. package/package.json +45 -4
  79. package/paths.js +106 -0
  80. package/ruler-worker.js +120 -0
  81. package/server.js +775 -0
  82. package/style.css +3563 -0
package/style.css ADDED
@@ -0,0 +1,3563 @@
1
+ /* ══════════════════ FableCut — Premiere-style dark theme ══════════════════ */
2
+ :root {
3
+ --bg: #0e0e10;
4
+ --panel: #1b1b1f;
5
+ --panel-2: #232329;
6
+ --border: #2d2d34;
7
+ --text: #d7d7dc;
8
+ --dim: #8b8b93;
9
+ --accent: #7b6cff;
10
+ --accent-2: #4f8cff;
11
+ --danger: #e5484d;
12
+ --clip-video: linear-gradient(180deg, #3d5afe22, #3d5afe11), #2b3b8f;
13
+ --track-h-video: 58px;
14
+ --track-h-audio: 42px;
15
+ --side-panel-w: 320px;
16
+ }
17
+
18
+ * {
19
+ box-sizing: border-box;
20
+ margin: 0;
21
+ padding: 0;
22
+ user-select: none;
23
+ }
24
+
25
+ html,
26
+ body {
27
+ height: 100%;
28
+ overflow: hidden;
29
+ }
30
+
31
+ body {
32
+ background: var(--bg);
33
+ color: var(--text);
34
+ font: 13px/1.45 "Segoe UI", system-ui, -apple-system, sans-serif;
35
+ }
36
+
37
+ .app {
38
+ display: flex;
39
+ flex-direction: column;
40
+ height: 100vh;
41
+ gap: 6px;
42
+ padding: 6px;
43
+ }
44
+
45
+ .topbar {
46
+ flex: 0 0 46px;
47
+ }
48
+
49
+ .upper {
50
+ flex: 1 1 0;
51
+ min-height: 140px;
52
+ min-width: 0;
53
+ }
54
+
55
+ .timeline-panel {
56
+ flex: 0 0 var(--timeline-h, 400px);
57
+ min-height: 180px;
58
+ overflow: hidden;
59
+ }
60
+
61
+ .v-split {
62
+ flex: 0 0 6px;
63
+ cursor: ns-resize;
64
+ position: relative;
65
+ z-index: 5;
66
+ border-radius: 3px;
67
+ }
68
+
69
+ .v-split::after {
70
+ content: "";
71
+ position: absolute;
72
+ left: 18%;
73
+ right: 18%;
74
+ top: 2px;
75
+ height: 2px;
76
+ border-radius: 1px;
77
+ background: var(--border);
78
+ transition: background .15s;
79
+ }
80
+
81
+ .v-split:hover::after,
82
+ .v-split.dragging::after {
83
+ background: var(--accent);
84
+ }
85
+
86
+ body.resizing-panels {
87
+ cursor: ns-resize !important;
88
+ }
89
+
90
+ body.resizing-panels * {
91
+ cursor: ns-resize !important;
92
+ user-select: none !important;
93
+ }
94
+
95
+ .hidden {
96
+ display: none !important;
97
+ }
98
+
99
+ .dim {
100
+ color: var(--dim);
101
+ display: inline-flex;
102
+ }
103
+
104
+ .flex-spacer {
105
+ flex: 1;
106
+ }
107
+
108
+ /* Visually hidden but still activatable (file picker via <label for>) */
109
+ .sr-only {
110
+ position: absolute;
111
+ width: 1px;
112
+ height: 1px;
113
+ padding: 0;
114
+ margin: -1px;
115
+ overflow: hidden;
116
+ clip: rect(0, 0, 0, 0);
117
+ white-space: nowrap;
118
+ border: 0;
119
+ }
120
+
121
+ /* ── Top bar ── */
122
+ .topbar {
123
+ display: flex;
124
+ align-items: center;
125
+ gap: 12px;
126
+ padding: 0 12px;
127
+ background: var(--panel);
128
+ border: 1px solid var(--border);
129
+ border-radius: 8px;
130
+ }
131
+
132
+ .logo {
133
+ display: flex;
134
+ align-items: center;
135
+ font-size: 15px;
136
+ letter-spacing: .3px;
137
+ color: #fff;
138
+ }
139
+
140
+ .logo b {
141
+ color: var(--accent);
142
+ }
143
+
144
+ .logo-mark {
145
+ display: inline-flex;
146
+ flex: none;
147
+ width: 22px;
148
+ height: 22px;
149
+ border-radius: 6px;
150
+ margin-right: 6px;
151
+ background: linear-gradient(135deg, var(--accent), var(--accent-2));
152
+ color: #fff;
153
+ font-size: 10px;
154
+ align-items: center;
155
+ justify-content: center;
156
+ }
157
+
158
+ .topbar-center {
159
+ flex: 1;
160
+ text-align: center;
161
+ color: var(--dim);
162
+ }
163
+
164
+ .topbar-right {
165
+ display: flex;
166
+ gap: 8px;
167
+ align-items: center;
168
+ }
169
+
170
+ .layout-tools {
171
+ display: flex;
172
+ align-items: center;
173
+ gap: 6px;
174
+ margin-right: 4px;
175
+ }
176
+
177
+ .btn-group {
178
+ display: inline-flex;
179
+ gap: 0px;
180
+ }
181
+
182
+ .btn-group .btn:first-child {
183
+ border-radius: 5px 0 0 5px;
184
+ }
185
+
186
+ .btn-group .btn:not(:first-child):not(:last-child) {
187
+ border-radius: 0;
188
+ margin: 0;
189
+ }
190
+
191
+ .btn-group .btn:last-child {
192
+ border-radius: 0 5px 5px 0;
193
+ }
194
+
195
+ .btn-group .btn.on {
196
+ border-color: var(--accent);
197
+ z-index: 1;
198
+ }
199
+
200
+ body.track-size-s .clip .clip-label {
201
+ font-size: 10px;
202
+ padding: 0 6px;
203
+ }
204
+
205
+ body.track-size-s .clip .fade {
206
+ display: none;
207
+ }
208
+
209
+ body.track-size-s .clip.c-audio .clip-body::after {
210
+ height: 12px;
211
+ }
212
+
213
+ body.track-size-s .clip {
214
+ border-width: 1px;
215
+ border-radius: 2px;
216
+ box-shadow: none;
217
+ }
218
+
219
+ body.track-size-s .clip .handle.l {
220
+ border-left-width: 1px;
221
+ }
222
+
223
+ body.track-size-s .clip .handle.r {
224
+ border-right-width: 1px;
225
+ }
226
+
227
+ body.track-size-s .clip.selected {
228
+ outline-width: 1px;
229
+ box-shadow: 0 0 0 1px #7b6cff55;
230
+ }
231
+
232
+ /* ── Title-style picker (inspector) ── */
233
+ .style-picker-btn {
234
+ flex: 1;
235
+ min-width: 0;
236
+ text-align: left;
237
+ overflow: hidden;
238
+ text-overflow: ellipsis;
239
+ }
240
+
241
+ .style-menu {
242
+ position: fixed;
243
+ z-index: 100;
244
+ min-width: 190px;
245
+ max-height: 330px;
246
+ overflow-y: auto;
247
+ background: var(--panel-2);
248
+ border: 1px solid var(--border);
249
+ border-radius: 8px;
250
+ padding: 4px;
251
+ box-shadow: 0 12px 32px #000c;
252
+ }
253
+
254
+ .style-opt {
255
+ padding: 7px 10px;
256
+ border-radius: 5px;
257
+ font-size: 15px;
258
+ line-height: 1.25;
259
+ color: var(--text);
260
+ cursor: pointer;
261
+ white-space: nowrap;
262
+ }
263
+
264
+ .style-opt:hover {
265
+ background: #7b6cff26;
266
+ }
267
+
268
+ .style-opt.on {
269
+ color: #cfc8ff;
270
+ background: #7b6cff14;
271
+ }
272
+
273
+ .ctx-menu {
274
+ position: fixed;
275
+ z-index: 200;
276
+ min-width: 160px;
277
+ background: var(--panel-2);
278
+ border: 1px solid var(--border);
279
+ border-radius: 8px;
280
+ padding: 4px;
281
+ box-shadow: 0 12px 32px #000c;
282
+ }
283
+ .ctx-opt {
284
+ padding: 7px 12px;
285
+ border-radius: 5px;
286
+ font-size: 13px;
287
+ color: var(--text);
288
+ cursor: pointer;
289
+ white-space: nowrap;
290
+ }
291
+ .ctx-opt:hover {
292
+ background: #7b6cff26;
293
+ }
294
+ /* media-replace picker reuses .style-menu/.style-opt but lists plain file
295
+ names, not font previews — match the app's normal UI text size */
296
+ .style-opt.media-opt {
297
+ font-size: 12px;
298
+ line-height: 1.3;
299
+ max-width: 260px;
300
+ overflow: hidden;
301
+ text-overflow: ellipsis;
302
+ }
303
+
304
+ /* ── Buttons ── */
305
+ .btn {
306
+ display: inline-block;
307
+ background: var(--panel-2);
308
+ color: var(--text);
309
+ border: 1px solid var(--border);
310
+ border-radius: 6px;
311
+ padding: 6px 12px;
312
+ font: inherit;
313
+ cursor: pointer;
314
+ white-space: nowrap;
315
+ }
316
+
317
+ .btn:hover {
318
+ background: #2c2c34;
319
+ border-color: #3c3c46;
320
+ }
321
+
322
+ .btn:active {
323
+ transform: translateY(1px);
324
+ }
325
+
326
+ .btn.primary {
327
+ background: linear-gradient(135deg, var(--accent), var(--accent-2));
328
+ border: none;
329
+ color: #fff;
330
+ font-weight: 600;
331
+ }
332
+
333
+ .btn.primary:hover {
334
+ filter: brightness(1.12);
335
+ }
336
+
337
+ .btn.ghost {
338
+ background: transparent;
339
+ }
340
+
341
+ .btn.tiny {
342
+ padding: 3px 9px;
343
+ font-size: 12px;
344
+ border-radius: 5px;
345
+ }
346
+
347
+ .btn .ico {
348
+ display: inline-block;
349
+ vertical-align: -2px;
350
+ margin-right: 2px;
351
+ }
352
+
353
+ .btn.tiny.accent {
354
+ border-color: var(--accent);
355
+ color: #cfc8ff;
356
+ }
357
+
358
+ .btn.icon {
359
+ width: 34px;
360
+ padding: 6px 0;
361
+ text-align: center;
362
+ }
363
+
364
+ .btn.icon.big {
365
+ width: 44px;
366
+ font-size: 15px;
367
+ }
368
+
369
+ .btn.toggle.on {
370
+ border-color: var(--accent);
371
+ color: #cfc8ff;
372
+ background: #7b6cff1a;
373
+ }
374
+
375
+ /* ── Panels ── */
376
+ .panel {
377
+ background: var(--panel);
378
+ border: 1px solid var(--border);
379
+ border-radius: 8px;
380
+ display: flex;
381
+ flex-direction: column;
382
+ min-height: 0;
383
+ min-width: 0;
384
+ }
385
+
386
+ .panel-head {
387
+ display: flex;
388
+ align-items: center;
389
+ justify-content: space-between;
390
+ padding: 7px 10px;
391
+ font-size: 12px;
392
+ font-weight: 600;
393
+ letter-spacing: .4px;
394
+ color: var(--dim);
395
+ text-transform: uppercase;
396
+ border-bottom: 1px solid var(--border);
397
+ }
398
+
399
+ .panel-head-title {
400
+ display: inline-flex;
401
+ align-items: center;
402
+ gap: 8px;
403
+ min-width: 0;
404
+ }
405
+
406
+ .panel-head-title .btn {
407
+ text-transform: none;
408
+ letter-spacing: normal;
409
+ font-weight: 600;
410
+ }
411
+
412
+ .panel-head-actions {
413
+ display: flex;
414
+ gap: 6px;
415
+ text-transform: none;
416
+ flex-wrap: wrap;
417
+ justify-content: flex-end;
418
+ align-items: center;
419
+ }
420
+
421
+ /* Media bin: the add buttons share one row, no heading beside them. */
422
+ .panel-head-actions.bin-actions {
423
+ flex: 1;
424
+ flex-wrap: nowrap;
425
+ min-width: 0;
426
+ }
427
+
428
+ .panel-head-actions.bin-actions .btn {
429
+ flex: 1;
430
+ min-width: 0;
431
+ justify-content: center;
432
+ text-align: center;
433
+ white-space: nowrap;
434
+ }
435
+
436
+ .upper {
437
+ display: grid;
438
+ grid-template-columns: var(--side-panel-w) minmax(0, 1fr) var(--side-panel-w);
439
+ gap: 6px;
440
+ min-height: 0;
441
+ }
442
+
443
+ .panel.bin,
444
+ .panel.inspector {
445
+ min-width: 0;
446
+ overflow: hidden;
447
+ }
448
+
449
+ .panel.bin {
450
+ z-index: 1;
451
+ }
452
+
453
+ /* keep overflowing head buttons above the monitor */
454
+
455
+ /* ── Media bin ── */
456
+ .bin-tabs {
457
+ display: flex;
458
+ gap: 2px;
459
+ padding: 6px 8px 0;
460
+ border-bottom: 1px solid var(--border);
461
+ }
462
+
463
+ .bin-tabs button {
464
+ flex: 1;
465
+ background: none;
466
+ border: none;
467
+ border-bottom: 2px solid transparent;
468
+ color: var(--dim);
469
+ font: 600 11px/1.2 "Segoe UI", sans-serif;
470
+ padding: 5px 2px 7px;
471
+ cursor: pointer;
472
+ letter-spacing: .2px;
473
+ white-space: nowrap;
474
+ }
475
+
476
+ .bin-tabs button:hover {
477
+ color: var(--text);
478
+ }
479
+
480
+ .bin-tabs button.on {
481
+ color: #cfc8ff;
482
+ border-bottom-color: var(--accent);
483
+ }
484
+
485
+ .bin-list {
486
+ flex: 1;
487
+ overflow-y: auto;
488
+ padding: 8px;
489
+ display: flex;
490
+ flex-direction: column;
491
+ gap: 4px;
492
+ }
493
+
494
+ .lib-item .lib-play,
495
+ .lib-item .lib-add {
496
+ flex: none;
497
+ width: 26px;
498
+ padding: 3px 0;
499
+ text-align: center;
500
+ }
501
+
502
+ .bin-thumb.svg {
503
+ background-color: #2a2a33;
504
+ background-size: contain;
505
+ background-repeat: no-repeat;
506
+ background-position: center;
507
+ }
508
+
509
+ .bin-empty {
510
+ margin: auto;
511
+ text-align: center;
512
+ color: var(--dim);
513
+ padding: 20px 10px;
514
+ }
515
+
516
+ .bin-empty-icon {
517
+ font-size: 34px;
518
+ margin-bottom: 10px;
519
+ opacity: .8;
520
+ }
521
+
522
+ .bin-empty .hint {
523
+ margin-top: 8px;
524
+ font-size: 11px;
525
+ opacity: .7;
526
+ }
527
+
528
+ .bin-item,
529
+ .bin-folder {
530
+ display: flex;
531
+ gap: 8px;
532
+ align-items: center;
533
+ padding: 6px;
534
+ padding-left: calc(6px + var(--bin-depth, 0) * 14px);
535
+ border-radius: 6px;
536
+ background: var(--panel-2);
537
+ border: 1px solid var(--border);
538
+ cursor: grab;
539
+ }
540
+
541
+ .bin-item:hover,
542
+ .bin-folder:hover {
543
+ border-color: #454552;
544
+ }
545
+
546
+ .bin-item.selected {
547
+ border-color: var(--accent);
548
+ background: #7b6cff18;
549
+ box-shadow: inset 0 0 0 1px #7b6cff44;
550
+ }
551
+
552
+ .bin-item:active,
553
+ .bin-folder:active {
554
+ cursor: grabbing;
555
+ }
556
+
557
+ .bin-item.bin-dragging,
558
+ .bin-folder.bin-dragging {
559
+ opacity: .45;
560
+ }
561
+
562
+ .bin-folder {
563
+ background: #1a1a20;
564
+ cursor: default;
565
+ }
566
+
567
+ .bin-folder .bin-folder-twist {
568
+ flex: none;
569
+ width: 18px;
570
+ height: 22px;
571
+ padding: 0;
572
+ border: 0;
573
+ background: transparent;
574
+ color: var(--dim);
575
+ cursor: pointer;
576
+ font-size: 9px;
577
+ line-height: 22px;
578
+ }
579
+
580
+ .bin-folder-icon {
581
+ flex: none;
582
+ font-size: 14px;
583
+ line-height: 1;
584
+ }
585
+
586
+ .bin-folder-name {
587
+ flex: 1;
588
+ min-width: 0;
589
+ font-size: 12px;
590
+ font-weight: 600;
591
+ white-space: nowrap;
592
+ overflow: hidden;
593
+ text-overflow: ellipsis;
594
+ outline: none;
595
+ border-radius: 3px;
596
+ }
597
+
598
+ .bin-folder-name[contenteditable="true"] {
599
+ background: var(--panel);
600
+ border: 1px solid var(--accent);
601
+ padding: 1px 4px;
602
+ cursor: text;
603
+ }
604
+
605
+ .bin-folder-count {
606
+ flex: none;
607
+ font-size: 10px;
608
+ color: var(--dim);
609
+ font-variant-numeric: tabular-nums;
610
+ }
611
+
612
+ .bin-folder-add {
613
+ flex: none;
614
+ width: 20px;
615
+ height: 20px;
616
+ padding: 0;
617
+ border: 0;
618
+ border-radius: 4px;
619
+ background: transparent;
620
+ color: var(--dim);
621
+ cursor: pointer;
622
+ opacity: 0;
623
+ font-size: 14px;
624
+ line-height: 20px;
625
+ }
626
+
627
+ .bin-folder:hover .bin-folder-add {
628
+ opacity: 1;
629
+ }
630
+
631
+ .bin-folder-add:hover {
632
+ color: var(--text);
633
+ background: #2a2a33;
634
+ }
635
+
636
+ .bin-item.bin-drop-over,
637
+ .bin-folder.bin-drop-over,
638
+ .bin-drop-root.bin-drop-over {
639
+ border-color: var(--accent);
640
+ box-shadow: inset 0 0 0 1px var(--accent);
641
+ background: #7b6cff18;
642
+ }
643
+
644
+ .bin-drop-root {
645
+ margin-top: 4px;
646
+ padding: 8px;
647
+ border-radius: 6px;
648
+ border: 1px dashed transparent;
649
+ color: var(--dim);
650
+ font-size: 11px;
651
+ text-align: center;
652
+ opacity: 0;
653
+ transition: opacity .12s, border-color .12s;
654
+ pointer-events: none;
655
+ }
656
+
657
+ .bin-list:has(.bin-dragging) .bin-drop-root {
658
+ opacity: 1;
659
+ pointer-events: auto;
660
+ border-color: #454552;
661
+ }
662
+
663
+ .bin-thumb {
664
+ width: 58px;
665
+ height: 34px;
666
+ border-radius: 4px;
667
+ flex: none;
668
+ background: #000 center/cover no-repeat;
669
+ display: flex;
670
+ align-items: center;
671
+ justify-content: center;
672
+ font-size: 16px;
673
+ }
674
+
675
+ .bin-meta {
676
+ min-width: 0;
677
+ flex: 1;
678
+ }
679
+
680
+ .bin-name {
681
+ font-size: 12px;
682
+ white-space: nowrap;
683
+ overflow: hidden;
684
+ text-overflow: ellipsis;
685
+ color: #e8e8ee;
686
+ }
687
+
688
+ .bin-sub {
689
+ font-size: 11px;
690
+ color: var(--dim);
691
+ white-space: nowrap;
692
+ overflow: hidden;
693
+ text-overflow: ellipsis;
694
+ }
695
+
696
+ .bin-del {
697
+ flex: none;
698
+ align-self: flex-start;
699
+ color: var(--dim);
700
+ cursor: pointer;
701
+ font-size: 12px;
702
+ line-height: 1;
703
+ padding: 2px 4px;
704
+ opacity: 0;
705
+ pointer-events: none;
706
+ transition: opacity .12s;
707
+ }
708
+
709
+ .bin-item:hover .bin-del,
710
+ .bin-folder:hover .bin-del {
711
+ opacity: 1;
712
+ pointer-events: auto;
713
+ }
714
+
715
+ .bin-del:hover {
716
+ color: var(--danger);
717
+ }
718
+
719
+ /* ── Monitor ── */
720
+ .monitor-mode {
721
+ display: inline-flex;
722
+ gap: 2px;
723
+ text-transform: none;
724
+ letter-spacing: normal;
725
+ }
726
+ .monitor-mode .btn {
727
+ min-width: 4.2em;
728
+ font-weight: 700;
729
+ }
730
+ .monitor-mode .btn.on {
731
+ background: #7b6cff;
732
+ border-color: #9a8fff;
733
+ color: #fff;
734
+ }
735
+ .monitor-clip-name {
736
+ max-width: 18em;
737
+ overflow: hidden;
738
+ text-overflow: ellipsis;
739
+ white-space: nowrap;
740
+ font-weight: 500;
741
+ text-transform: none;
742
+ letter-spacing: normal;
743
+ font-size: 11px;
744
+ }
745
+ .panel.monitor[data-mode="source"] .monitor-clip-name:empty::before {
746
+ content: "No clip loaded";
747
+ opacity: .55;
748
+ }
749
+
750
+ .source-scrub {
751
+ flex: 0 0 auto;
752
+ padding: 0 14px 6px;
753
+ }
754
+ .source-scrub-track {
755
+ position: relative;
756
+ height: 10px;
757
+ border-radius: 5px;
758
+ background: #1a1a20;
759
+ border: 1px solid var(--border);
760
+ cursor: pointer;
761
+ }
762
+ .source-scrub-range {
763
+ position: absolute;
764
+ top: 0; bottom: 0;
765
+ left: 0; width: 0;
766
+ background: #7b6cff44;
767
+ border-radius: 4px;
768
+ pointer-events: none;
769
+ will-change: transform, width;
770
+ }
771
+ .source-scrub-mark {
772
+ position: absolute;
773
+ top: -2px; bottom: -2px;
774
+ left: 0;
775
+ width: 2px;
776
+ margin-left: -1px;
777
+ background: #ffd166;
778
+ pointer-events: none;
779
+ will-change: transform;
780
+ }
781
+ .source-scrub-mark.out { background: #ff8a65; }
782
+ .source-scrub-head {
783
+ position: absolute;
784
+ top: -3px; bottom: -3px;
785
+ left: 0;
786
+ width: 3px;
787
+ margin-left: -1.5px;
788
+ background: #fff;
789
+ border-radius: 1px;
790
+ pointer-events: none;
791
+ box-shadow: 0 0 0 1px #0008;
792
+ will-change: transform;
793
+ }
794
+
795
+ .monitor-stage {
796
+ flex: 1;
797
+ display: flex;
798
+ flex-direction: column;
799
+ background: #000;
800
+ min-height: 0;
801
+ margin: 8px;
802
+ border-radius: 6px;
803
+ overflow: hidden;
804
+ position: relative;
805
+ }
806
+ @keyframes monitor-flash-border {
807
+ 0% { opacity: 0; }
808
+ 20% { opacity: 1; }
809
+ 70% { opacity: 1; }
810
+ 100% { opacity: 0; }
811
+ }
812
+ /* White ring painted over the preview canvas */
813
+ .monitor-flash-ring {
814
+ position: absolute;
815
+ z-index: 30;
816
+ pointer-events: none;
817
+ box-shadow: inset 0 0 0 3px #fff;
818
+ opacity: 0;
819
+ border-radius: 0;
820
+ }
821
+ .monitor-flash-ring.on {
822
+ animation: monitor-flash-border 0.35s ease-out forwards;
823
+ }
824
+
825
+ .monitor-scroll {
826
+ flex: 1;
827
+ min-height: 0;
828
+ min-width: 0;
829
+ display: flex;
830
+ align-items: center;
831
+ justify-content: center;
832
+ overflow: hidden;
833
+ /* Below monitor chrome (VU, keyframe graphs) so the export-frame shade
834
+ cannot dim them. Flex item z-index is enough — no position needed. */
835
+ z-index: 1;
836
+ }
837
+
838
+ .monitor-scroll.is-zoomed {
839
+ display: block;
840
+ overflow: auto;
841
+ cursor: grab;
842
+ }
843
+
844
+ .monitor-scroll.is-zoomed.is-panning {
845
+ cursor: grabbing;
846
+ }
847
+
848
+ .monitor-zoom-inner {
849
+ position: relative;
850
+ line-height: 0;
851
+ flex-shrink: 0;
852
+ }
853
+
854
+ /* Fit mode: fill the scrollport so #preview max-% resolves against the stage */
855
+ .monitor-scroll:not(.is-zoomed) .monitor-zoom-inner {
856
+ width: 100%;
857
+ height: 100%;
858
+ display: flex;
859
+ align-items: center;
860
+ justify-content: center;
861
+ }
862
+
863
+ .monitor-scroll.is-zoomed .monitor-zoom-inner {
864
+ display: inline-block;
865
+ }
866
+
867
+ #preview {
868
+ max-width: 100%;
869
+ max-height: 100%;
870
+ display: block;
871
+ background: #000;
872
+ }
873
+
874
+ .monitor-scroll.is-zoomed #preview {
875
+ max-width: none;
876
+ max-height: none;
877
+ }
878
+
879
+ /* ── Keyframe graphs (left gutter of program monitor) ── */
880
+ .kf-graphs {
881
+ position: absolute;
882
+ left: 6px;
883
+ top: 6px;
884
+ bottom: 6px;
885
+ width: min(168px, 28%);
886
+ z-index: 4;
887
+ display: flex;
888
+ flex-direction: column;
889
+ gap: 6px;
890
+ overflow-x: hidden;
891
+ overflow-y: auto;
892
+ pointer-events: none;
893
+ }
894
+ .kf-graphs[hidden] { display: none; }
895
+ .kf-graphs.source-hidden { display: none !important; }
896
+ .kf-graph {
897
+ pointer-events: auto;
898
+ flex: 0 0 auto;
899
+ background: #000a;
900
+ border: 1px solid #ffffff18;
901
+ border-radius: 4px;
902
+ padding: 4px 5px 3px;
903
+ user-select: none;
904
+ }
905
+ .kf-graph-head {
906
+ display: flex;
907
+ align-items: center;
908
+ justify-content: space-between;
909
+ gap: 4px;
910
+ margin-bottom: 2px;
911
+ font: 700 9px/1 ui-sans-serif, system-ui, sans-serif;
912
+ letter-spacing: .35px;
913
+ color: #c8c8d0;
914
+ }
915
+ .kf-graph-head button {
916
+ margin: 0;
917
+ padding: 0 3px;
918
+ border: 0;
919
+ background: transparent;
920
+ color: #8b8b93;
921
+ font: 700 11px/1 ui-sans-serif, system-ui, sans-serif;
922
+ cursor: pointer;
923
+ opacity: .75;
924
+ }
925
+ .kf-graph-head button:hover { color: #fff; opacity: 1; }
926
+ .kf-graph canvas {
927
+ display: block;
928
+ width: 100%;
929
+ height: 52px;
930
+ cursor: crosshair;
931
+ border-radius: 2px;
932
+ background: #0a0a0ccc;
933
+ }
934
+
935
+ .insp-row label.kf-graph-toggle {
936
+ cursor: pointer;
937
+ border-radius: 3px;
938
+ margin: -1px -2px;
939
+ padding: 1px 2px;
940
+ }
941
+ .insp-row label.kf-graph-toggle:hover {
942
+ color: #cfc8ff;
943
+ background: #7b6cff22;
944
+ }
945
+ .insp-row label.kf-graph-toggle.on {
946
+ color: #b9baff;
947
+ background: #7b6cff33;
948
+ }
949
+ .insp-row label.kf-graph-toggle.has-kf::after {
950
+ content: " ◆";
951
+ font-size: 8px;
952
+ opacity: .7;
953
+ }
954
+ /* ── Per-track VU (RMS / LUFS / Peak) ── */
955
+ .vu-meter {
956
+ position: absolute;
957
+ right: 2px;
958
+ bottom: 10px;
959
+ display: flex;
960
+ flex-direction: column;
961
+ align-items: stretch;
962
+ gap: 4px;
963
+ z-index: 7;
964
+ pointer-events: auto;
965
+ padding: 5px 2px 4px 5px;
966
+ background: #000a;
967
+ user-select: none;
968
+ transform-origin: bottom right;
969
+ }
970
+ .vu-channels {
971
+ display: flex;
972
+ align-items: flex-end;
973
+ gap: 0;
974
+ }
975
+ .vu-tracks-wrap {
976
+ display: none;
977
+ align-items: flex-end;
978
+ gap: 2px;
979
+ }
980
+ .vu-meter.vu-tracks-open .vu-tracks-wrap { display: flex; }
981
+ .vu-scale-master {
982
+ display: flex;
983
+ align-items: flex-end;
984
+ gap: 0;
985
+ }
986
+ .vu-master-stack {
987
+ display: grid;
988
+ grid-template-columns: auto 30px;
989
+ grid-template-rows: auto auto;
990
+ column-gap: 0;
991
+ row-gap: 1px;
992
+ }
993
+ .vu-tracks-toggle {
994
+ grid-row: 1;
995
+ grid-column: 1;
996
+ align-self: center;
997
+ display: flex;
998
+ align-items: center;
999
+ justify-content: center;
1000
+ width: 10px;
1001
+ height: 14px;
1002
+ margin: 0;
1003
+ padding: 0;
1004
+ border: 0;
1005
+ background: transparent;
1006
+ color: #a8a8b0;
1007
+ font: 700 14px/1 ui-sans-serif, system-ui, sans-serif;
1008
+ cursor: pointer;
1009
+ opacity: .9;
1010
+ }
1011
+ .vu-tracks-toggle:hover { opacity: 1; color: #fff; }
1012
+ .vu-mode {
1013
+ grid-row: 1;
1014
+ grid-column: 2;
1015
+ box-sizing: border-box;
1016
+ width: 30px;
1017
+ justify-self: center;
1018
+ margin: 0;
1019
+ padding: 0;
1020
+ border: 0;
1021
+ background: transparent;
1022
+ color: #c8c8d0;
1023
+ font: 700 9px/1 ui-sans-serif, system-ui, sans-serif;
1024
+ letter-spacing: .6px;
1025
+ text-align: center;
1026
+ cursor: pointer;
1027
+ opacity: .85;
1028
+ white-space: nowrap;
1029
+ overflow: hidden;
1030
+ }
1031
+ .vu-mode:hover { opacity: 1; color: #fff; }
1032
+ .vu-master {
1033
+ grid-row: 2;
1034
+ grid-column: 2;
1035
+ box-sizing: border-box;
1036
+ width: 30px;
1037
+ justify-self: center;
1038
+ display: flex;
1039
+ gap: 3px;
1040
+ justify-content: center;
1041
+ padding-left: 0;
1042
+ margin-left: 0;
1043
+ border-left: none;
1044
+ }
1045
+ .vu-scale {
1046
+ position: relative;
1047
+ /* Match .vu-segs height: 16×12px + 15×2px gap */
1048
+ width: 16px;
1049
+ height: 222px;
1050
+ flex-shrink: 0;
1051
+ pointer-events: none;
1052
+ }
1053
+ .vu-scale-tick {
1054
+ position: absolute;
1055
+ right: 0;
1056
+ transform: translateY(-50%);
1057
+ font: 700 8px/1 ui-sans-serif, system-ui, sans-serif;
1058
+ color: #8b8b93;
1059
+ letter-spacing: .2px;
1060
+ white-space: nowrap;
1061
+ }
1062
+ .vu-scale-tick:first-child { transform: translateY(0); }
1063
+ .vu-scale-tick:last-child { transform: translateY(-100%); }
1064
+ .vu-master-stack.vu-master-only {
1065
+ grid-template-columns: 30px;
1066
+ }
1067
+ .vu-master-stack.vu-master-only .vu-mode,
1068
+ .vu-master-stack.vu-master-only .vu-master {
1069
+ grid-column: 1;
1070
+ }
1071
+ .vu-master .vu-label { color: #d4d4dc; }
1072
+ .vu-channel {
1073
+ display: flex;
1074
+ flex-direction: column;
1075
+ align-items: center;
1076
+ gap: 3px;
1077
+ }
1078
+ .vu-segs {
1079
+ display: block;
1080
+ /* size is set inline via JS (makeMeterCanvas) to match devicePixelRatio */
1081
+ }
1082
+ .vu-label {
1083
+ font-size: 9px;
1084
+ font-weight: 700;
1085
+ color: #8b8b93;
1086
+ letter-spacing: .3px;
1087
+ line-height: 1;
1088
+ }
1089
+
1090
+ .head-select {
1091
+ background: var(--panel-2);
1092
+ border: 1px solid var(--border);
1093
+ color: var(--text);
1094
+ border-radius: 5px;
1095
+ padding: 2px 6px;
1096
+ font: 12px "Segoe UI", sans-serif;
1097
+ max-width: 170px;
1098
+ }
1099
+ #fpsSel.head-select { max-width: 88px; }
1100
+
1101
+ /* ── Safe-area guides (positioned over the canvas by JS) ── */
1102
+ #safeOverlay {
1103
+ position: absolute;
1104
+ pointer-events: none;
1105
+ z-index: 5;
1106
+ }
1107
+
1108
+ #safeOverlay .sa-action {
1109
+ position: absolute;
1110
+ inset: 5%;
1111
+ border: 1px dashed #ffffff59;
1112
+ }
1113
+
1114
+ #safeOverlay .sa-title {
1115
+ position: absolute;
1116
+ inset: 10%;
1117
+ border: 1px dashed #ffffff30;
1118
+ }
1119
+
1120
+ #safeOverlay .sa-ui-bottom,
1121
+ #safeOverlay .sa-ui-right {
1122
+ display: none;
1123
+ }
1124
+
1125
+ #safeOverlay.vertical .sa-ui-bottom {
1126
+ display: block;
1127
+ position: absolute;
1128
+ left: 0;
1129
+ right: 0;
1130
+ bottom: 0;
1131
+ height: 34%;
1132
+ background: repeating-linear-gradient(45deg, #ff4d6a14 0 8px, transparent 8px 16px);
1133
+ border-top: 1px dashed #ff4d6a80;
1134
+ }
1135
+
1136
+ #safeOverlay.vertical .sa-ui-right {
1137
+ display: block;
1138
+ position: absolute;
1139
+ top: 30%;
1140
+ right: 0;
1141
+ bottom: 0;
1142
+ width: 13%;
1143
+ background: repeating-linear-gradient(45deg, #ff4d6a14 0 8px, transparent 8px 16px);
1144
+ border-left: 1px dashed #ff4d6a80;
1145
+ }
1146
+
1147
+ /* ── Export frame overlay (dimmed overscan, preview-only) ── */
1148
+ #exportFrameOverlay {
1149
+ position: absolute;
1150
+ pointer-events: none;
1151
+ z-index: 6;
1152
+ }
1153
+ #exportFrameOverlay .ef-shade {
1154
+ position: absolute;
1155
+ box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.6);
1156
+ border: 1px solid rgba(255, 255, 255, 0.88);
1157
+ pointer-events: none;
1158
+ }
1159
+ #exportFrameOverlay.is-crop .ef-shade {
1160
+ box-shadow: 0 0 0 9999px #000;
1161
+ }
1162
+ #btnExportFrameDim .ico { margin-right: 0; }
1163
+ #btnExportFrameDim .ef-bulb-rays { opacity: 0; }
1164
+ #btnExportFrameDim.on .ef-bulb-rays { opacity: 1; }
1165
+ #btnExportFrameDim.on .ef-bulb-glass { fill: currentColor; fill-opacity: .22; }
1166
+ #exportFrameOverlay .ef-handle {
1167
+ position: absolute;
1168
+ display: inline-flex;
1169
+ align-items: center;
1170
+ justify-content: flex-start;
1171
+ width: auto;
1172
+ min-width: 0;
1173
+ height: 20px;
1174
+ box-sizing: border-box;
1175
+ margin: 0;
1176
+ padding: 0 6px;
1177
+ font: 600 10px/1 ui-sans-serif, system-ui, sans-serif;
1178
+ font-family: inherit;
1179
+ text-transform: uppercase;
1180
+ color: #fff;
1181
+ background: color-mix(in srgb, var(--accent) 62%, transparent);
1182
+ border: 1px solid color-mix(in srgb, var(--accent) 45%, #fff);
1183
+ border-radius: 4px;
1184
+ cursor: move;
1185
+ pointer-events: auto;
1186
+ touch-action: none;
1187
+ white-space: nowrap;
1188
+ overflow: hidden;
1189
+ text-overflow: ellipsis;
1190
+ user-select: none;
1191
+ transition: background 0.12s ease, filter 0.12s ease;
1192
+ appearance: none;
1193
+ -webkit-appearance: none;
1194
+ }
1195
+ #exportFrameOverlay .ef-handle:focus-visible {
1196
+ outline: 2px solid #fff;
1197
+ outline-offset: 2px;
1198
+ }
1199
+ #exportFrameOverlay .ef-handle:hover {
1200
+ background: color-mix(in srgb, var(--accent) 82%, transparent);
1201
+ }
1202
+ #exportFrameOverlay.is-dragging .ef-handle,
1203
+ #exportFrameOverlay .ef-handle:active {
1204
+ background: color-mix(in srgb, var(--accent) 72%, transparent);
1205
+ }
1206
+ #exportFrameOverlay .ef-edge {
1207
+ position: absolute;
1208
+ pointer-events: auto;
1209
+ touch-action: none;
1210
+ cursor: move;
1211
+ user-select: none;
1212
+ }
1213
+ #exportFrameOverlay .ef-edge-t,
1214
+ #exportFrameOverlay .ef-edge-b {
1215
+ height: 10px;
1216
+ }
1217
+ #exportFrameOverlay .ef-edge-l,
1218
+ #exportFrameOverlay .ef-edge-r {
1219
+ width: 10px;
1220
+ }
1221
+
1222
+ .transport {
1223
+ display: grid;
1224
+ grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr);
1225
+ align-items: center;
1226
+ padding: 4px 14px 8px;
1227
+ gap: 10px;
1228
+ min-height: 50px;
1229
+ }
1230
+
1231
+ .transport-btns {
1232
+ display: flex;
1233
+ align-items: center;
1234
+ gap: 4px;
1235
+ }
1236
+
1237
+ .transport-end {
1238
+ display: flex;
1239
+ align-items: center;
1240
+ justify-self: end;
1241
+ gap: 10px;
1242
+ min-width: 0;
1243
+ }
1244
+
1245
+ .transport-end .btn.icon {
1246
+ flex-shrink: 0;
1247
+ width: 26px;
1248
+ height: 26px;
1249
+ padding: 0;
1250
+ display: inline-flex;
1251
+ align-items: center;
1252
+ justify-content: center;
1253
+ line-height: 0;
1254
+ }
1255
+
1256
+ .transport-end .btn.icon svg {
1257
+ display: block;
1258
+ flex-shrink: 0;
1259
+ }
1260
+
1261
+ .transport-end .btn.icon:disabled {
1262
+ opacity: 0.4;
1263
+ cursor: not-allowed;
1264
+ }
1265
+
1266
+ .transport-btns .btn.icon {
1267
+ width: 26px;
1268
+ height: 26px;
1269
+ padding: 0;
1270
+ font-size: 11px;
1271
+ display: inline-flex;
1272
+ align-items: center;
1273
+ justify-content: center;
1274
+ line-height: 1;
1275
+ }
1276
+
1277
+ .transport-btns .btn.icon.big {
1278
+ width: 40px;
1279
+ height: 34px;
1280
+ font-size: 16px;
1281
+ }
1282
+
1283
+ #btnPlay.on {
1284
+ background: #7b6cff;
1285
+ border-color: #9a8fff;
1286
+ color: #fff;
1287
+ font-size: 19.2px; /* 16px × 1.2 — pause glyph reads smaller than ▶ */
1288
+ /* ⏸ sits low in the em-box; padding shifts the flex content up to optical center */
1289
+ padding-bottom: 3px;
1290
+ }
1291
+
1292
+ #btnPlay.on:hover {
1293
+ background: #8d80ff;
1294
+ border-color: #b0a6ff;
1295
+ }
1296
+
1297
+ .timecode {
1298
+ font: 600 14px/1 Consolas, monospace;
1299
+ color: #b9b3ff;
1300
+ min-width: 0;
1301
+ height: auto;
1302
+ line-height: 1;
1303
+ }
1304
+
1305
+ .timecode.dim {
1306
+ color: var(--dim);
1307
+ }
1308
+
1309
+ .tc-playhead {
1310
+ justify-self: start;
1311
+ display: flex;
1312
+ align-items: baseline;
1313
+ gap: 5px;
1314
+ min-width: 0;
1315
+ }
1316
+
1317
+ .tc-slash {
1318
+ color: var(--dim);
1319
+ font: 600 13px/1 Consolas, monospace;
1320
+ }
1321
+
1322
+ .tc-io {
1323
+ justify-self: end;
1324
+ display: grid;
1325
+ grid-template-columns: auto 8ch;
1326
+ align-items: center;
1327
+ column-gap: 6px;
1328
+ row-gap: 1px;
1329
+ }
1330
+
1331
+ .tc-io.idle {
1332
+ visibility: hidden;
1333
+ }
1334
+
1335
+ .tc-io-item {
1336
+ display: contents;
1337
+ }
1338
+
1339
+ .tc-io-lab {
1340
+ font: 700 9px/1 "Segoe UI", system-ui, sans-serif;
1341
+ letter-spacing: 0.05em;
1342
+ color: var(--dim);
1343
+ text-align: right;
1344
+ }
1345
+
1346
+ .tc-io-item.in .tc-io-lab { color: #5eead4; }
1347
+ .tc-io-item.out .tc-io-lab { color: #fb923c; }
1348
+
1349
+ .tc-io .timecode {
1350
+ min-width: 8ch;
1351
+ font-size: 12px;
1352
+ text-align: right;
1353
+ color: #d7d7dc;
1354
+ }
1355
+
1356
+ .tc-io .timecode.unset {
1357
+ color: var(--dim);
1358
+ opacity: 0.55;
1359
+ }
1360
+
1361
+ /* ── Inspector ── */
1362
+ .inspector-body {
1363
+ flex: 1;
1364
+ min-width: 0;
1365
+ overflow-x: hidden;
1366
+ overflow-y: auto;
1367
+ padding: 10px;
1368
+ }
1369
+
1370
+ .inspector-empty {
1371
+ margin: auto;
1372
+ text-align: center;
1373
+ color: var(--dim);
1374
+ padding-top: 40px;
1375
+ }
1376
+
1377
+ /* ── Mixer (side-panel tab) ── */
1378
+ .side-tabs {
1379
+ flex: none;
1380
+ }
1381
+
1382
+ .mixer {
1383
+ flex: 1;
1384
+ min-height: 0;
1385
+ overflow-x: auto;
1386
+ overflow-y: hidden;
1387
+ padding: 10px 8px;
1388
+ }
1389
+
1390
+ .mixer-strips {
1391
+ display: flex;
1392
+ gap: 6px;
1393
+ width: max-content;
1394
+ min-width: 100%;
1395
+ height: 100%;
1396
+ min-height: 220px;
1397
+ }
1398
+
1399
+ .mix-strip {
1400
+ --strip-color: var(--border);
1401
+ flex: none;
1402
+ width: 54px;
1403
+ display: flex;
1404
+ flex-direction: column;
1405
+ align-items: stretch;
1406
+ gap: 6px;
1407
+ padding: 6px 5px;
1408
+ background: var(--panel-2);
1409
+ border: 1px solid var(--border);
1410
+ border-top: 3px solid var(--strip-color);
1411
+ border-radius: 6px;
1412
+ }
1413
+
1414
+ /* Master stays in view while many A-tracks scroll under it. */
1415
+ .mix-strip.master {
1416
+ width: 66px;
1417
+ margin-left: auto;
1418
+ position: sticky;
1419
+ right: 0;
1420
+ z-index: 1;
1421
+ border-top-color: var(--accent);
1422
+ box-shadow: -6px 0 8px -4px #0008;
1423
+ }
1424
+
1425
+ .mix-strip.bus {
1426
+ background: color-mix(in srgb, var(--panel-2) 88%, #c58cff);
1427
+ }
1428
+
1429
+ .mix-out,
1430
+ .mix-rename {
1431
+ width: 100%;
1432
+ min-width: 0;
1433
+ background: var(--bg);
1434
+ border: 1px solid var(--border);
1435
+ border-radius: 4px;
1436
+ color: var(--text);
1437
+ font: 10px/1.2 "Segoe UI", sans-serif;
1438
+ padding: 2px 1px;
1439
+ }
1440
+
1441
+ .mix-add {
1442
+ flex: none;
1443
+ align-self: flex-start;
1444
+ background: none;
1445
+ border: 1px dashed var(--border);
1446
+ border-radius: 6px;
1447
+ color: var(--dim);
1448
+ font: 600 11px/1 "Segoe UI", sans-serif;
1449
+ padding: 8px 6px;
1450
+ cursor: pointer;
1451
+ }
1452
+
1453
+ .mix-add:hover {
1454
+ color: var(--text);
1455
+ border-color: #c58cff;
1456
+ }
1457
+
1458
+ .mix-btns .mix-x:hover {
1459
+ color: #e5484d;
1460
+ }
1461
+
1462
+ .mix-strip.muted .mix-body {
1463
+ opacity: .45;
1464
+ }
1465
+
1466
+ .mix-name {
1467
+ font: 600 11px/1.2 "Segoe UI", sans-serif;
1468
+ color: var(--text);
1469
+ text-align: center;
1470
+ white-space: nowrap;
1471
+ overflow: hidden;
1472
+ text-overflow: ellipsis;
1473
+ }
1474
+
1475
+ .mix-pan-row {
1476
+ display: flex;
1477
+ flex-direction: column;
1478
+ align-items: center;
1479
+ gap: 2px;
1480
+ height: 30px;
1481
+ justify-content: center;
1482
+ }
1483
+
1484
+ .mix-pan {
1485
+ width: 100%;
1486
+ accent-color: var(--accent);
1487
+ }
1488
+
1489
+ .mix-pan-val,
1490
+ .mix-lufs {
1491
+ font: 10px/1 Consolas, monospace;
1492
+ color: var(--dim);
1493
+ text-align: center;
1494
+ }
1495
+
1496
+ .mix-lufs {
1497
+ white-space: nowrap;
1498
+ }
1499
+
1500
+ .mix-body {
1501
+ flex: 1;
1502
+ min-height: 0;
1503
+ display: flex;
1504
+ justify-content: center;
1505
+ gap: 6px;
1506
+ }
1507
+
1508
+ .mix-meter {
1509
+ width: 8px;
1510
+ height: 100%;
1511
+ border-radius: 2px;
1512
+ }
1513
+
1514
+ .mix-strip.master .mix-meter {
1515
+ width: 18px;
1516
+ }
1517
+
1518
+ .mix-body .mix-fader {
1519
+ writing-mode: vertical-lr;
1520
+ direction: rtl;
1521
+ width: 20px;
1522
+ height: auto;
1523
+ align-self: stretch;
1524
+ margin: 0;
1525
+ accent-color: var(--accent);
1526
+ cursor: ns-resize;
1527
+ }
1528
+
1529
+ .mix-db {
1530
+ width: 100%;
1531
+ background: var(--bg);
1532
+ border: 1px solid var(--border);
1533
+ border-radius: 4px;
1534
+ color: var(--text);
1535
+ font: 11px/1 Consolas, monospace;
1536
+ text-align: center;
1537
+ padding: 3px 0;
1538
+ user-select: text;
1539
+ }
1540
+
1541
+ .mix-db:focus {
1542
+ outline: none;
1543
+ border-color: var(--accent);
1544
+ }
1545
+
1546
+ .mix-fx {
1547
+ background: var(--bg);
1548
+ border: 1px solid var(--border);
1549
+ border-radius: 4px;
1550
+ color: var(--dim);
1551
+ font: 600 10px/1 "Segoe UI", sans-serif;
1552
+ padding: 4px 0;
1553
+ cursor: pointer;
1554
+ }
1555
+
1556
+ .mix-fx:hover {
1557
+ color: var(--text);
1558
+ }
1559
+
1560
+ .mix-fx.on {
1561
+ border-color: var(--accent);
1562
+ color: #cfc8ff;
1563
+ }
1564
+
1565
+ .mixer-fx {
1566
+ display: flex;
1567
+ flex-direction: column;
1568
+ height: 100%;
1569
+ min-height: 0;
1570
+ width: 100%;
1571
+ }
1572
+
1573
+ .mixer-fx-head {
1574
+ display: flex;
1575
+ align-items: center;
1576
+ gap: 10px;
1577
+ padding-bottom: 8px;
1578
+ font: 600 12px/1.2 "Segoe UI", sans-serif;
1579
+ color: var(--text);
1580
+ }
1581
+
1582
+ .mixer-fx-body {
1583
+ flex: 1;
1584
+ min-height: 0;
1585
+ overflow-y: auto;
1586
+ padding-right: 2px;
1587
+ }
1588
+
1589
+ /* ── Effect chains (inspector + mixer) ── */
1590
+ .fx-tools-row {
1591
+ display: flex;
1592
+ flex-wrap: wrap;
1593
+ gap: 6px;
1594
+ margin-bottom: 8px;
1595
+ }
1596
+
1597
+ .fx-tools-row select {
1598
+ flex: 1;
1599
+ min-width: 0;
1600
+ background: var(--panel-2);
1601
+ border: 1px solid var(--border);
1602
+ color: var(--text);
1603
+ border-radius: 4px;
1604
+ padding: 4px 6px;
1605
+ font: inherit;
1606
+ }
1607
+
1608
+ .fx-card {
1609
+ border: 1px solid var(--border);
1610
+ border-radius: 6px;
1611
+ background: var(--panel-2);
1612
+ padding: 6px 8px;
1613
+ margin-bottom: 6px;
1614
+ }
1615
+
1616
+ .fx-card.off {
1617
+ opacity: .55;
1618
+ }
1619
+
1620
+ .fx-head {
1621
+ display: flex;
1622
+ align-items: center;
1623
+ justify-content: space-between;
1624
+ gap: 6px;
1625
+ margin-bottom: 4px;
1626
+ font: 600 11.5px/1.2 "Segoe UI", sans-serif;
1627
+ color: var(--text);
1628
+ }
1629
+
1630
+ .fx-head label {
1631
+ display: flex;
1632
+ align-items: center;
1633
+ gap: 6px;
1634
+ cursor: pointer;
1635
+ }
1636
+
1637
+ .fx-btns {
1638
+ display: flex;
1639
+ gap: 2px;
1640
+ }
1641
+
1642
+ .fx-btns button {
1643
+ background: none;
1644
+ border: 1px solid transparent;
1645
+ border-radius: 4px;
1646
+ color: var(--dim);
1647
+ font-size: 10px;
1648
+ line-height: 1;
1649
+ padding: 3px 5px;
1650
+ cursor: pointer;
1651
+ }
1652
+
1653
+ .fx-btns button:hover:not(:disabled) {
1654
+ color: var(--text);
1655
+ border-color: var(--border);
1656
+ }
1657
+
1658
+ .fx-btns button:disabled {
1659
+ opacity: .3;
1660
+ cursor: default;
1661
+ }
1662
+
1663
+ .fx-param {
1664
+ display: grid;
1665
+ grid-template-columns: 62px minmax(0, 1fr) 58px 26px;
1666
+ align-items: center;
1667
+ gap: 6px;
1668
+ font-size: 11px;
1669
+ color: var(--dim);
1670
+ }
1671
+
1672
+ .fx-param input[type=range] {
1673
+ width: 100%;
1674
+ }
1675
+
1676
+ .fx-kf {
1677
+ padding: 2px 3px;
1678
+ justify-self: end;
1679
+ }
1680
+
1681
+ .fx-val {
1682
+ text-align: right;
1683
+ font: 10.5px/1 Consolas, monospace;
1684
+ color: var(--text);
1685
+ white-space: nowrap;
1686
+ }
1687
+
1688
+ .mix-btns {
1689
+ display: flex;
1690
+ gap: 4px;
1691
+ }
1692
+
1693
+ .mix-btns button {
1694
+ flex: 1;
1695
+ background: var(--bg);
1696
+ border: 1px solid var(--border);
1697
+ border-radius: 4px;
1698
+ color: var(--dim);
1699
+ font: 600 11px/1 "Segoe UI", sans-serif;
1700
+ padding: 4px 0;
1701
+ cursor: pointer;
1702
+ }
1703
+
1704
+ .mix-btns button:hover {
1705
+ color: var(--text);
1706
+ }
1707
+
1708
+ .mix-btns .mix-m.on {
1709
+ background: #4a2326;
1710
+ border-color: var(--danger);
1711
+ color: #ffb4b6;
1712
+ }
1713
+
1714
+ .mix-btns .mix-s.on {
1715
+ background: #4a4020;
1716
+ border-color: #f0c14a;
1717
+ color: #ffe6a3;
1718
+ }
1719
+
1720
+ /* Enable / lock / link toggles at the top of the inspector. */
1721
+ .clip-flags {
1722
+ display: flex;
1723
+ gap: 6px;
1724
+ margin-bottom: 12px;
1725
+ }
1726
+
1727
+ .clip-flag {
1728
+ flex: 1;
1729
+ padding: 4px 6px;
1730
+ border: 1px solid var(--border);
1731
+ border-radius: 5px;
1732
+ background: var(--panel-2);
1733
+ color: var(--dim);
1734
+ font: inherit;
1735
+ font-size: 11px;
1736
+ cursor: pointer;
1737
+ }
1738
+
1739
+ .clip-flag:hover {
1740
+ color: #fff;
1741
+ }
1742
+
1743
+ .clip-flag.on[data-clip-cmd="disable"] {
1744
+ color: #ffd0d1;
1745
+ background: #e5484d2e;
1746
+ border-color: #e5484d88;
1747
+ }
1748
+
1749
+ .clip-flag.on[data-clip-cmd="lock"] {
1750
+ color: #111;
1751
+ background: #ffb454;
1752
+ border-color: #ffb454;
1753
+ }
1754
+
1755
+ .clip-flag.on[data-clip-cmd="link"] {
1756
+ color: #e8e8ff;
1757
+ background: #7b6cff33;
1758
+ border-color: #7b6cff88;
1759
+ }
1760
+
1761
+ #inspector.locked .insp-section {
1762
+ opacity: .6;
1763
+ }
1764
+
1765
+ .insp-note {
1766
+ margin: 2px 0 4px;
1767
+ font-size: 11px;
1768
+ color: var(--dim);
1769
+ }
1770
+
1771
+ .insp-multi {
1772
+ margin-bottom: 12px;
1773
+ padding: 7px 9px;
1774
+ border-radius: 6px;
1775
+ font-size: 11px;
1776
+ color: #cfd0ff;
1777
+ background: #7b6cff1c;
1778
+ border: 1px solid #7b6cff44;
1779
+ }
1780
+
1781
+ .insp-section {
1782
+ margin-bottom: 14px;
1783
+ }
1784
+
1785
+ .insp-section h3 {
1786
+ font-size: 11px;
1787
+ text-transform: uppercase;
1788
+ letter-spacing: .5px;
1789
+ color: var(--dim);
1790
+ border-bottom: 1px solid var(--border);
1791
+ padding-bottom: 4px;
1792
+ margin-bottom: 8px;
1793
+ }
1794
+
1795
+ .insp-row {
1796
+ display: flex;
1797
+ align-items: center;
1798
+ gap: 8px;
1799
+ margin-bottom: 6px;
1800
+ min-width: 0;
1801
+ }
1802
+
1803
+ .insp-row label {
1804
+ flex: 0 0 72px;
1805
+ font-size: 12px;
1806
+ color: var(--dim);
1807
+ }
1808
+
1809
+ .insp-row label.insp-reset {
1810
+ cursor: help;
1811
+ }
1812
+
1813
+ .insp-row label.insp-reset:hover {
1814
+ color: #cfc8ff;
1815
+ }
1816
+
1817
+ .insp-ctrls {
1818
+ display: flex;
1819
+ flex: 1;
1820
+ min-width: 0;
1821
+ gap: 6px;
1822
+ align-items: center;
1823
+ }
1824
+
1825
+ .insp-ctrls select,
1826
+ .insp-ctrls input[type=number] {
1827
+ flex: 1;
1828
+ min-width: 0;
1829
+ }
1830
+
1831
+ .insp-ctrls .insp-dur {
1832
+ flex: none;
1833
+ width: 52px;
1834
+ }
1835
+
1836
+ .insp-ctrls input[type=color],
1837
+ .insp-ctrls .btn {
1838
+ flex: none;
1839
+ }
1840
+
1841
+ .insp-row input[type=range] {
1842
+ flex: 1;
1843
+ }
1844
+
1845
+ .insp-row .val {
1846
+ width: 42px;
1847
+ flex: none;
1848
+ text-align: right;
1849
+ font-size: 11px;
1850
+ color: var(--text);
1851
+ font-family: Consolas, monospace;
1852
+ }
1853
+
1854
+ .insp-row input[type=number],
1855
+ .insp-row input[type=text],
1856
+ .insp-row select {
1857
+ flex: 1;
1858
+ min-width: 0;
1859
+ background: var(--panel-2);
1860
+ border: 1px solid var(--border);
1861
+ color: var(--text);
1862
+ border-radius: 4px;
1863
+ padding: 4px 6px;
1864
+ font: inherit;
1865
+ }
1866
+
1867
+ .insp-row input[type=color] {
1868
+ width: 40px;
1869
+ height: 26px;
1870
+ padding: 0;
1871
+ border: 1px solid var(--border);
1872
+ border-radius: 4px;
1873
+ background: none;
1874
+ }
1875
+
1876
+ .insp-row textarea {
1877
+ flex: 1;
1878
+ background: var(--panel-2);
1879
+ border: 1px solid var(--border);
1880
+ color: var(--text);
1881
+ border-radius: 4px;
1882
+ padding: 4px 6px;
1883
+ font: inherit;
1884
+ resize: vertical;
1885
+ min-height: 48px;
1886
+ }
1887
+
1888
+ input[type=range] {
1889
+ accent-color: var(--accent);
1890
+ height: 18px;
1891
+ }
1892
+
1893
+ .kf-ctl {
1894
+ display: flex;
1895
+ gap: 2px;
1896
+ flex: none;
1897
+ }
1898
+
1899
+ .kf-btn {
1900
+ background: none;
1901
+ border: 1px solid var(--border);
1902
+ color: var(--dim);
1903
+ border-radius: 4px;
1904
+ font-size: 10px;
1905
+ padding: 2px 5px;
1906
+ cursor: pointer;
1907
+ line-height: 1;
1908
+ }
1909
+
1910
+ .kf-btn:hover:not(:disabled) {
1911
+ color: #fff;
1912
+ border-color: #4a4a56;
1913
+ }
1914
+
1915
+ .kf-btn.has {
1916
+ color: #ffd166;
1917
+ border-color: #ffd16666;
1918
+ }
1919
+
1920
+ .kf-btn.has.on {
1921
+ background: #ffd166;
1922
+ color: #1a1a22;
1923
+ border-color: #ffd166;
1924
+ }
1925
+
1926
+ /* Playhead off the clip: keyframed fields are read-only (edge value shown) */
1927
+ .inspector input:disabled,
1928
+ .inspector .kf-btn:disabled {
1929
+ opacity: .4;
1930
+ cursor: not-allowed;
1931
+ }
1932
+
1933
+ /* ── Timeline ── */
1934
+ .timeline-toolbar {
1935
+ display: flex;
1936
+ align-items: center;
1937
+ gap: 8px;
1938
+ padding: 6px 10px;
1939
+ border-bottom: 1px solid var(--border);
1940
+ }
1941
+
1942
+ .tiny-label {
1943
+ font-size: 11px;
1944
+ }
1945
+
1946
+ #zoomSlider {
1947
+ width: 130px;
1948
+ }
1949
+
1950
+ .timeline {
1951
+ flex: 1;
1952
+ display: flex;
1953
+ min-height: 0;
1954
+ }
1955
+
1956
+ .track-headers {
1957
+ width: 86px;
1958
+ flex: none;
1959
+ border-right: 1px solid var(--border);
1960
+ padding-top: 0;
1961
+ background: var(--panel);
1962
+ z-index: 2;
1963
+ overflow: hidden;
1964
+ display: flex;
1965
+ flex-direction: column;
1966
+ }
1967
+
1968
+ .track-head-tools {
1969
+ height: 26px;
1970
+ flex: none;
1971
+ display: flex;
1972
+ align-items: center;
1973
+ justify-content: center;
1974
+ gap: 2px;
1975
+ border-bottom: 1px solid var(--border);
1976
+ box-sizing: border-box;
1977
+ }
1978
+
1979
+ .track-head-tools .btn {
1980
+ padding: 1px 4px;
1981
+ font-size: 10px;
1982
+ font-weight: 700;
1983
+ letter-spacing: 0;
1984
+ line-height: 1.2;
1985
+ min-width: 0;
1986
+ }
1987
+
1988
+ #trackHeadInner {
1989
+ flex: 1;
1990
+ min-height: 0;
1991
+ }
1992
+
1993
+ .track-head {
1994
+ display: flex;
1995
+ align-items: center;
1996
+ gap: 2px;
1997
+ padding: 0 4px;
1998
+ border-bottom: 1px solid #232328;
1999
+ font-size: 11px;
2000
+ font-weight: 700;
2001
+ color: var(--dim);
2002
+ letter-spacing: .5px;
2003
+ }
2004
+
2005
+ /* The track name doubles as the targeting toggle (Premiere's blue patch):
2006
+ lit = edits touch this lane. */
2007
+ .track-head .track-id {
2008
+ flex: 1;
2009
+ min-width: 0;
2010
+ max-width: 4ch;
2011
+ margin: 0;
2012
+ padding: 1px 3px;
2013
+ border: 1px solid transparent;
2014
+ border-radius: 3px;
2015
+ background: transparent;
2016
+ color: inherit;
2017
+ font: inherit;
2018
+ letter-spacing: inherit;
2019
+ text-align: left;
2020
+ cursor: pointer;
2021
+ }
2022
+
2023
+ .track-head .track-id:hover {
2024
+ color: #fff;
2025
+ background: #ffffff12;
2026
+ }
2027
+
2028
+ .track-head .track-id[aria-pressed="true"] {
2029
+ color: #e8e8ff;
2030
+ background: #7b6cff33;
2031
+ border-color: #7b6cff88;
2032
+ }
2033
+
2034
+ .track-head .track-id[aria-pressed="true"]:hover {
2035
+ background: #7b6cff4d;
2036
+ }
2037
+
2038
+ .track-lock {
2039
+ display: inline-flex;
2040
+ align-items: center;
2041
+ justify-content: center;
2042
+ flex: none;
2043
+ width: 16px;
2044
+ height: 16px;
2045
+ margin: 0;
2046
+ padding: 0;
2047
+ border: 1px solid transparent;
2048
+ border-radius: 3px;
2049
+ background: transparent;
2050
+ color: var(--dim);
2051
+ opacity: .55;
2052
+ cursor: pointer;
2053
+ }
2054
+
2055
+ .track-lock .track-ico {
2056
+ display: block;
2057
+ width: 11px;
2058
+ height: 11px;
2059
+ pointer-events: none;
2060
+ }
2061
+
2062
+ .track-lock:hover {
2063
+ color: #fff;
2064
+ opacity: 1;
2065
+ background: #ffffff12;
2066
+ }
2067
+
2068
+ .track-lock.on {
2069
+ color: #111;
2070
+ opacity: 1;
2071
+ background: #ffb454;
2072
+ border-color: #ffb454;
2073
+ }
2074
+
2075
+ .track-solo {
2076
+ display: inline-flex;
2077
+ align-items: center;
2078
+ justify-content: center;
2079
+ flex: none;
2080
+ width: 16px;
2081
+ height: 16px;
2082
+ margin: 0;
2083
+ padding: 0;
2084
+ border: 1px solid transparent;
2085
+ border-radius: 3px;
2086
+ background: transparent;
2087
+ color: var(--dim);
2088
+ font: inherit;
2089
+ font-size: 9px;
2090
+ font-weight: 800;
2091
+ letter-spacing: 0;
2092
+ line-height: 1;
2093
+ cursor: pointer;
2094
+ }
2095
+
2096
+ .track-solo:hover {
2097
+ color: #fff;
2098
+ background: #ffffff12;
2099
+ }
2100
+
2101
+ .track-solo.on {
2102
+ color: #111;
2103
+ background: #ffd166;
2104
+ border-color: #ffd166;
2105
+ }
2106
+
2107
+ .track-head.disabled {
2108
+ opacity: .55;
2109
+ }
2110
+
2111
+ .track-head.solo:not(.disabled) {
2112
+ opacity: 1;
2113
+ }
2114
+
2115
+ .ctx-menu {
2116
+ position: fixed;
2117
+ z-index: 10000;
2118
+ min-width: 140px;
2119
+ padding: 4px;
2120
+ background: var(--panel, #1c1c22);
2121
+ border: 1px solid var(--border, #2e2e36);
2122
+ border-radius: 6px;
2123
+ box-shadow: 0 8px 24px #00000088;
2124
+ }
2125
+
2126
+ .ctx-menu .ctx-item {
2127
+ display: flex;
2128
+ justify-content: space-between;
2129
+ gap: 18px;
2130
+ width: 100%;
2131
+ margin: 0;
2132
+ padding: 6px 10px;
2133
+ border: 0;
2134
+ border-radius: 4px;
2135
+ background: transparent;
2136
+ color: #e8e8ec;
2137
+ font: inherit;
2138
+ font-size: 12px;
2139
+ text-align: left;
2140
+ cursor: pointer;
2141
+ }
2142
+
2143
+ .ctx-menu .ctx-item:hover:not(:disabled) {
2144
+ background: #ffffff14;
2145
+ }
2146
+
2147
+ .ctx-menu .ctx-item:disabled {
2148
+ opacity: .45;
2149
+ cursor: default;
2150
+ }
2151
+
2152
+ .ctx-menu .ctx-item kbd {
2153
+ color: var(--dim);
2154
+ font: inherit;
2155
+ font-size: 11px;
2156
+ }
2157
+
2158
+ .track-toggle {
2159
+ display: inline-flex;
2160
+ align-items: center;
2161
+ justify-content: center;
2162
+ flex: none;
2163
+ margin: 0;
2164
+ padding: 2px;
2165
+ border: 0;
2166
+ background: transparent;
2167
+ cursor: pointer;
2168
+ border-radius: 4px;
2169
+ color: inherit;
2170
+ }
2171
+
2172
+ .track-toggle:hover {
2173
+ background: #ffffff12;
2174
+ }
2175
+
2176
+ .track-toggle .track-ico {
2177
+ display: block;
2178
+ width: 15px;
2179
+ height: 15px;
2180
+ pointer-events: none;
2181
+ }
2182
+
2183
+ .track-toggle .track-ico-off {
2184
+ display: none;
2185
+ }
2186
+
2187
+ .track-toggle[aria-pressed="false"] {
2188
+ color: var(--dim) !important;
2189
+ }
2190
+
2191
+ .track-toggle[aria-pressed="false"] .track-ico-off {
2192
+ display: block;
2193
+ }
2194
+
2195
+ .track.disabled {
2196
+ opacity: .4;
2197
+ }
2198
+
2199
+ /* Edit-tool picker in the timeline toolbar. */
2200
+ .tool-seg {
2201
+ display: inline-flex;
2202
+ gap: 0;
2203
+ margin-right: 4px;
2204
+ border: 1px solid var(--border);
2205
+ border-radius: 6px;
2206
+ overflow: hidden;
2207
+ }
2208
+
2209
+ .tool-seg .btn {
2210
+ border: 0;
2211
+ border-radius: 0;
2212
+ padding: 3px 7px;
2213
+ }
2214
+
2215
+ .tool-seg .btn + .btn {
2216
+ border-left: 1px solid var(--border);
2217
+ }
2218
+
2219
+ .tool-seg .btn.on {
2220
+ color: #fff;
2221
+ background: #7b6cff55;
2222
+ }
2223
+
2224
+ .tool-seg .ico {
2225
+ display: block;
2226
+ }
2227
+
2228
+ /* Cursors say what a drag will do with the active tool. */
2229
+ #tracksContent[data-tool="ripple"] .clip .handle.l { cursor: w-resize; }
2230
+ #tracksContent[data-tool="ripple"] .clip .handle.r { cursor: e-resize; }
2231
+ #tracksContent[data-tool="roll"] .clip .handle { cursor: col-resize; }
2232
+ #tracksContent[data-tool="slip"] .clip,
2233
+ #tracksContent[data-tool="slip"] .clip .handle { cursor: ew-resize; }
2234
+ #tracksContent[data-tool="slide"] .clip,
2235
+ #tracksContent[data-tool="slide"] .clip .handle { cursor: move; }
2236
+ #tracksContent[data-tool="ripple"] .clip .handle,
2237
+ #tracksContent[data-tool="roll"] .clip .handle {
2238
+ background: #ffd16655;
2239
+ }
2240
+
2241
+ .trim-readout {
2242
+ position: fixed;
2243
+ z-index: 10001;
2244
+ padding: 3px 7px;
2245
+ border-radius: 4px;
2246
+ background: #000c;
2247
+ color: #fff;
2248
+ font-size: 11px;
2249
+ font-variant-numeric: tabular-nums;
2250
+ pointer-events: none;
2251
+ white-space: nowrap;
2252
+ }
2253
+
2254
+ /* Locked lane / clip: hatched, no trim handles, not-allowed cursor. */
2255
+ .track.locked {
2256
+ background-image: repeating-linear-gradient(135deg, #ffffff07 0 6px, transparent 6px 12px);
2257
+ }
2258
+
2259
+ .clip.locked {
2260
+ cursor: not-allowed;
2261
+ }
2262
+
2263
+ .clip.locked .handle {
2264
+ display: none;
2265
+ }
2266
+
2267
+ .clip.locked .clip-body::after {
2268
+ content: "";
2269
+ position: absolute;
2270
+ inset: 0;
2271
+ background: repeating-linear-gradient(135deg, transparent 0 6px, #00000055 6px 8px);
2272
+ pointer-events: none;
2273
+ }
2274
+
2275
+ .clip.locked .clip-body::before {
2276
+ content: "";
2277
+ position: absolute;
2278
+ z-index: 2;
2279
+ top: 3px;
2280
+ right: 4px;
2281
+ width: 9px;
2282
+ height: 10px;
2283
+ background: #ffb454;
2284
+ -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='black' stroke-width='2' d='M5 7V5a3 3 0 0 1 6 0v2'/%3E%3Crect x='3' y='7' width='10' height='8' rx='1.5'/%3E%3C/svg%3E") center / contain no-repeat;
2285
+ mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath fill='none' stroke='black' stroke-width='2' d='M5 7V5a3 3 0 0 1 6 0v2'/%3E%3Crect x='3' y='7' width='10' height='8' rx='1.5'/%3E%3C/svg%3E") center / contain no-repeat;
2286
+ pointer-events: none;
2287
+ }
2288
+
2289
+ /* Disabled clip: still on the timeline, gone from preview and export. */
2290
+ .clip.disabled .clip-body {
2291
+ opacity: .35;
2292
+ filter: grayscale(1);
2293
+ }
2294
+
2295
+ .clip.disabled .clip-label {
2296
+ text-decoration: line-through;
2297
+ }
2298
+
2299
+ .timeline-scroll {
2300
+ flex: 1;
2301
+ min-height: 0;
2302
+ overflow-x: auto;
2303
+ overflow-y: auto;
2304
+ position: relative;
2305
+ }
2306
+
2307
+ .ruler {
2308
+ position: sticky;
2309
+ top: 0;
2310
+ left: 0;
2311
+ display: block;
2312
+ height: 26px;
2313
+ z-index: 3;
2314
+ cursor: ew-resize;
2315
+ background: var(--panel-2);
2316
+ }
2317
+
2318
+ .tracks-content {
2319
+ position: relative;
2320
+ /* clip so abspos playhead `left` cannot grow the scroller's overflow */
2321
+ overflow: clip;
2322
+ overflow-clip-margin: 8px;
2323
+ }
2324
+ .work-dim {
2325
+ position: absolute;
2326
+ top: 0;
2327
+ bottom: 0;
2328
+ background: #00000066;
2329
+ pointer-events: none;
2330
+ z-index: 1;
2331
+ }
2332
+ .work-dim-l {
2333
+ left: 0;
2334
+ border-right: 1px solid #5eead4aa;
2335
+ }
2336
+ .work-dim-r {
2337
+ border-left: 1px solid #fb923caa;
2338
+ }
2339
+ .work-dim.hidden {
2340
+ display: none;
2341
+ }
2342
+
2343
+ .track {
2344
+ position: relative;
2345
+ border-bottom: 1px solid #232328;
2346
+ background: repeating-linear-gradient(90deg, transparent 0 59px, #ffffff05 59px 60px);
2347
+ }
2348
+
2349
+ .track.drop-hint {
2350
+ background-color: #7b6cff14;
2351
+ }
2352
+
2353
+ /* Same-track audio overlap — hatched band over the shared time range */
2354
+ .track-overlap {
2355
+ position: absolute;
2356
+ top: 3px;
2357
+ bottom: 3px;
2358
+ z-index: 2;
2359
+ pointer-events: none;
2360
+ border-radius: 3px;
2361
+ background: repeating-linear-gradient(
2362
+ -45deg,
2363
+ transparent 0 3px,
2364
+ #ff5a5a55 3px 6px
2365
+ );
2366
+ box-shadow: inset 0 0 0 1px #ff6b6bcc;
2367
+ }
2368
+
2369
+ /* ── Clips ── */
2370
+ .clip {
2371
+ position: absolute;
2372
+ top: 3px;
2373
+ bottom: 3px;
2374
+ border-radius: 5px;
2375
+ overflow: visible;
2376
+ border: 1px solid #0007;
2377
+ cursor: grab;
2378
+ min-width: 8px;
2379
+ box-shadow: 0 1px 3px #0006;
2380
+ }
2381
+
2382
+ /* rounded clip content — trans wedges sit outside this so corners stay sharp */
2383
+ .clip-body {
2384
+ position: absolute;
2385
+ inset: 0;
2386
+ border-radius: inherit;
2387
+ overflow: hidden;
2388
+ }
2389
+
2390
+ .clip:active {
2391
+ cursor: grabbing;
2392
+ }
2393
+
2394
+ .clip.selected {
2395
+ outline: 2px solid #b9baff;
2396
+ outline-offset: -1px;
2397
+ box-shadow: 0 0 0 3px #7b6cff55;
2398
+ }
2399
+
2400
+ .clip.selected.primary {
2401
+ outline-color: #fff;
2402
+ }
2403
+
2404
+ /* rubber-band selection box drawn while dragging on empty timeline area */
2405
+ .marquee {
2406
+ position: absolute;
2407
+ z-index: 5;
2408
+ pointer-events: none;
2409
+ border: 1px solid #7b6cffcc;
2410
+ background: #7b6cff22;
2411
+ border-radius: 2px;
2412
+ }
2413
+
2414
+ .clip .clip-label {
2415
+ position: absolute;
2416
+ inset: 0;
2417
+ display: flex;
2418
+ align-items: center;
2419
+ padding: 0 8px;
2420
+ font-size: 11px;
2421
+ font-weight: 600;
2422
+ line-height: 1;
2423
+ color: #fff;
2424
+ text-shadow: 0 1px 2px #000c;
2425
+ white-space: nowrap;
2426
+ overflow: hidden;
2427
+ text-overflow: ellipsis;
2428
+ pointer-events: none;
2429
+ z-index: 3;
2430
+ }
2431
+
2432
+ /* Keyframe diamonds on the clip — same size/color as ruler beat markers */
2433
+ .clip .clip-kfs {
2434
+ position: absolute;
2435
+ left: 0;
2436
+ right: 0;
2437
+ bottom: 1px;
2438
+ height: 8px;
2439
+ pointer-events: none;
2440
+ z-index: 4;
2441
+ }
2442
+ .clip .clip-kf {
2443
+ position: absolute;
2444
+ top: 0;
2445
+ /* rotated square → ~8×8 tip-to-tip, matching ruler markers */
2446
+ width: 6px;
2447
+ height: 6px;
2448
+ margin-left: -3px;
2449
+ background: #ffd166;
2450
+ transform: rotate(45deg);
2451
+ pointer-events: auto;
2452
+ cursor: pointer;
2453
+ }
2454
+ .clip .clip-kf:hover {
2455
+ background: #ffe28a;
2456
+ }
2457
+ /* Count badge when ≥2 channels share this time (diamond stays rotated; numeral counter-rotates) */
2458
+ .clip .clip-kf.multi {
2459
+ width: 8px;
2460
+ height: 8px;
2461
+ margin-left: -4px;
2462
+ top: -1px;
2463
+ }
2464
+ .clip .clip-kf-n {
2465
+ position: absolute;
2466
+ inset: 0;
2467
+ display: flex;
2468
+ align-items: center;
2469
+ justify-content: center;
2470
+ transform: rotate(-45deg);
2471
+ font: 700 7px/1 ui-sans-serif, system-ui, sans-serif;
2472
+ color: #1a1a1e;
2473
+ pointer-events: none;
2474
+ user-select: none;
2475
+ }
2476
+ body.track-size-s .clip .clip-kf-n {
2477
+ font-size: 6px;
2478
+ }
2479
+
2480
+ /* ── Volume line + fade grips on audio clips (volBandHtml / fadeGripsHtml) ── */
2481
+ .clip .vol-band {
2482
+ position: absolute;
2483
+ left: 0;
2484
+ top: 0;
2485
+ overflow: visible;
2486
+ pointer-events: none;
2487
+ z-index: 3;
2488
+ }
2489
+
2490
+ .clip .vol-line {
2491
+ fill: none;
2492
+ stroke: #ffd166;
2493
+ stroke-width: 1.25;
2494
+ opacity: .85;
2495
+ }
2496
+
2497
+ .clip .vol-duck {
2498
+ fill: none;
2499
+ stroke: #ffd166;
2500
+ stroke-width: 1;
2501
+ stroke-dasharray: 3 3;
2502
+ opacity: .7;
2503
+ }
2504
+
2505
+ /* invisible fat stroke = the grab area for the line */
2506
+ .clip .vol-hit {
2507
+ fill: none;
2508
+ stroke: transparent;
2509
+ stroke-width: 9;
2510
+ pointer-events: stroke;
2511
+ cursor: ns-resize;
2512
+ }
2513
+
2514
+ .clip:hover .vol-line {
2515
+ opacity: 1;
2516
+ stroke-width: 1.5;
2517
+ }
2518
+
2519
+ .clip .vol-pt {
2520
+ position: absolute;
2521
+ width: 7px;
2522
+ height: 7px;
2523
+ margin: -3.5px 0 0 -3.5px;
2524
+ border-radius: 50%;
2525
+ background: #ffd166;
2526
+ border: 1px solid #1a1a22;
2527
+ z-index: 5;
2528
+ cursor: move;
2529
+ }
2530
+
2531
+ .clip .vol-pt:hover {
2532
+ transform: scale(1.4);
2533
+ }
2534
+
2535
+ .clip .fade-grip {
2536
+ position: absolute;
2537
+ top: 1px;
2538
+ width: 8px;
2539
+ height: 8px;
2540
+ margin: 0 -4px;
2541
+ background: #ffffffcc;
2542
+ border: 1px solid #1a1a22;
2543
+ border-radius: 2px;
2544
+ z-index: 6;
2545
+ cursor: ew-resize;
2546
+ opacity: 0;
2547
+ transition: opacity .12s;
2548
+ }
2549
+
2550
+ .clip:hover .fade-grip,
2551
+ .clip.selected .fade-grip {
2552
+ opacity: 1;
2553
+ }
2554
+
2555
+ body.track-size-s .clip .fade-grip {
2556
+ display: none;
2557
+ }
2558
+
2559
+ /* transition wedges — width from transition duration × pps (see transitionMarksHtml) */
2560
+ .clip .trans-mark {
2561
+ position: absolute;
2562
+ top: 0;
2563
+ bottom: 0;
2564
+ height: auto;
2565
+ pointer-events: none;
2566
+ z-index: 2;
2567
+ overflow: hidden;
2568
+ }
2569
+ .clip .trans-mark svg {
2570
+ display: block;
2571
+ width: 100%;
2572
+ height: 100%;
2573
+ pointer-events: none;
2574
+ }
2575
+ .clip .trans-mark.in {
2576
+ left: 0;
2577
+ border-top-left-radius: inherit;
2578
+ border-bottom-left-radius: inherit;
2579
+ }
2580
+ .clip .trans-mark.out {
2581
+ right: 0;
2582
+ border-top-right-radius: inherit;
2583
+ border-bottom-right-radius: inherit;
2584
+ }
2585
+ .clip .trans-mark polygon {
2586
+ fill: #ffffff55;
2587
+ stroke: #ffffffcc;
2588
+ stroke-width: 1;
2589
+ vector-effect: non-scaling-stroke;
2590
+ pointer-events: auto;
2591
+ cursor: pointer;
2592
+ }
2593
+ .clip .trans-mark.focused polygon {
2594
+ fill: #7b6cff88;
2595
+ stroke: #cfc8ff;
2596
+ stroke-width: 1.5;
2597
+ }
2598
+ /* duration handle — invisible drag strip at the wedge edge */
2599
+ .clip .trans-dur-handle {
2600
+ position: absolute;
2601
+ top: 0;
2602
+ bottom: 0;
2603
+ width: 10px;
2604
+ cursor: ew-resize;
2605
+ pointer-events: auto;
2606
+ z-index: 3;
2607
+ }
2608
+ .clip .trans-mark.in .trans-dur-handle {
2609
+ right: 0;
2610
+ }
2611
+ .clip .trans-mark.out .trans-dur-handle {
2612
+ left: 0;
2613
+ }
2614
+
2615
+ .insp-row.trans-active {
2616
+ background: #7b6cff18;
2617
+ border-radius: 6px;
2618
+ margin: 0 -6px;
2619
+ padding: 2px 6px;
2620
+ }
2621
+
2622
+ .clip .fade {
2623
+ position: absolute;
2624
+ inset: 0;
2625
+ background: linear-gradient(180deg, #ffffff1f, transparent 40%);
2626
+ pointer-events: none;
2627
+ z-index: 0;
2628
+ }
2629
+
2630
+ .clip .handle {
2631
+ position: absolute;
2632
+ top: 0;
2633
+ bottom: 0;
2634
+ width: 8px;
2635
+ cursor: ew-resize;
2636
+ z-index: 4;
2637
+ }
2638
+
2639
+ .clip .handle.l {
2640
+ left: 0;
2641
+ border-left: 3px solid #ffffff55;
2642
+ }
2643
+
2644
+ .clip .handle.r {
2645
+ right: 0;
2646
+ border-right: 3px solid #ffffff55;
2647
+ }
2648
+
2649
+ .clip.c-video .clip-body {
2650
+ background: linear-gradient(180deg, #4c66ff33, #4c66ff11), #273575;
2651
+ }
2652
+
2653
+ .clip.c-video .thumbs {
2654
+ position: absolute;
2655
+ inset: 0;
2656
+ background-repeat: repeat-x;
2657
+ background-size: auto 100%;
2658
+ opacity: .5;
2659
+ pointer-events: none;
2660
+ }
2661
+
2662
+ .clip.c-image .clip-body {
2663
+ background: linear-gradient(180deg, #2dbd8533, #2dbd8511), #1d5b45;
2664
+ }
2665
+
2666
+ .clip.c-audio .clip-body {
2667
+ background: linear-gradient(180deg, #7ec24933, #7ec24911), #33531f;
2668
+ }
2669
+
2670
+ .clip.c-audio .clip-body::after {
2671
+ content: "";
2672
+ position: absolute;
2673
+ left: 0;
2674
+ right: 0;
2675
+ top: 50%;
2676
+ height: 22px;
2677
+ transform: translateY(-50%);
2678
+ background: repeating-linear-gradient(90deg, #a5e07588 0 2px, transparent 2px 5px);
2679
+ clip-path: polygon(0 50%, 5% 20%, 10% 70%, 15% 35%, 20% 80%, 25% 25%, 30% 60%, 35% 15%, 40% 75%, 45% 40%, 50% 85%, 55% 30%, 60% 65%, 65% 20%, 70% 78%, 75% 42%, 80% 68%, 85% 25%, 90% 72%, 95% 38%, 100% 50%, 100% 100%, 0 100%);
2680
+ opacity: .55;
2681
+ pointer-events: none;
2682
+ }
2683
+
2684
+ .clip.c-audio.has-wave .clip-body::after {
2685
+ display: none;
2686
+ }
2687
+
2688
+ /* real waveform replaces the CSS placeholder */
2689
+ .clip .wave {
2690
+ position: absolute;
2691
+ inset: 3px 0;
2692
+ width: 100%;
2693
+ height: calc(100% - 6px);
2694
+ pointer-events: none;
2695
+ }
2696
+
2697
+ .clip.c-text .clip-body {
2698
+ background: linear-gradient(180deg, #ff7ac833, #ff7ac811), #6b2a53;
2699
+ }
2700
+
2701
+ .clip.c-svg .clip-body {
2702
+ background: linear-gradient(180deg, #ffd16633, #ffd16611), #6b5420;
2703
+ }
2704
+
2705
+ .clip.c-adjust .clip-body {
2706
+ background: repeating-linear-gradient(135deg, #38bdf822 0 10px, transparent 10px 20px), #155e75;
2707
+ }
2708
+
2709
+ /* ── Playhead ── */
2710
+ .playhead {
2711
+ position: absolute;
2712
+ top: 0;
2713
+ bottom: 0;
2714
+ width: 1px;
2715
+ background: #ff4d6a;
2716
+ z-index: 4;
2717
+ pointer-events: none;
2718
+ contain: layout;
2719
+ }
2720
+
2721
+ .playhead-cap {
2722
+ position: absolute;
2723
+ top: 0;
2724
+ left: -6px;
2725
+ width: 13px;
2726
+ height: 14px;
2727
+ background: #ff4d6a;
2728
+ clip-path: polygon(0 0, 100% 0, 100% 55%, 50% 100%, 0 55%);
2729
+ }
2730
+
2731
+ /* ── Overlays / dialogs ── */
2732
+ .overlay {
2733
+ position: fixed;
2734
+ inset: 0;
2735
+ background: #000a;
2736
+ backdrop-filter: blur(3px);
2737
+ display: flex;
2738
+ align-items: center;
2739
+ justify-content: center;
2740
+ z-index: 50;
2741
+ }
2742
+
2743
+ .dialog {
2744
+ background: var(--panel);
2745
+ border: 1px solid var(--border);
2746
+ border-radius: 12px;
2747
+ padding: 24px 28px;
2748
+ width: 420px;
2749
+ box-shadow: 0 20px 60px #000a;
2750
+ }
2751
+
2752
+ .dialog h2 {
2753
+ font-size: 16px;
2754
+ margin-bottom: 6px;
2755
+ color: #fff;
2756
+ }
2757
+
2758
+ .dialog p {
2759
+ margin-bottom: 16px;
2760
+ }
2761
+
2762
+ .progress {
2763
+ height: 8px;
2764
+ border-radius: 4px;
2765
+ background: var(--panel-2);
2766
+ overflow: hidden;
2767
+ margin-bottom: 18px;
2768
+ }
2769
+
2770
+ .progress-fill {
2771
+ height: 100%;
2772
+ width: 0%;
2773
+ background: linear-gradient(90deg, var(--accent), var(--accent-2));
2774
+ transition: width .2s;
2775
+ }
2776
+
2777
+ .import-url-field {
2778
+ display: block;
2779
+ margin-bottom: 14px;
2780
+ }
2781
+
2782
+ .import-url-field input {
2783
+ width: 100%;
2784
+ background: var(--panel-2);
2785
+ border: 1px solid var(--border);
2786
+ color: var(--text);
2787
+ border-radius: 6px;
2788
+ padding: 8px 10px;
2789
+ font: inherit;
2790
+ user-select: text;
2791
+ }
2792
+
2793
+ .import-url-field input:focus {
2794
+ outline: none;
2795
+ border-color: var(--accent);
2796
+ }
2797
+
2798
+ .import-url-status {
2799
+ margin: -6px 0 12px;
2800
+ }
2801
+
2802
+ .progress-fill.indeterminate {
2803
+ width: 36%;
2804
+ transition: none;
2805
+ animation: import-url-slide 1.15s ease-in-out infinite;
2806
+ }
2807
+
2808
+ @keyframes import-url-slide {
2809
+ 0% { transform: translateX(-120%); }
2810
+ 100% { transform: translateX(280%); }
2811
+ }
2812
+
2813
+ .dialog-actions {
2814
+ display: flex;
2815
+ justify-content: flex-end;
2816
+ gap: 8px;
2817
+ }
2818
+
2819
+ .engine-opt {
2820
+ display: flex;
2821
+ gap: 10px;
2822
+ align-items: flex-start;
2823
+ padding: 10px 12px;
2824
+ margin-bottom: 10px;
2825
+ border: 1px solid var(--border);
2826
+ border-radius: 8px;
2827
+ cursor: pointer;
2828
+ background: var(--panel-2);
2829
+ }
2830
+
2831
+ .engine-opt:hover {
2832
+ border-color: #454552;
2833
+ }
2834
+
2835
+ .engine-opt:has(input:checked) {
2836
+ border-color: var(--accent);
2837
+ background: #7b6cff12;
2838
+ }
2839
+
2840
+ .engine-opt:has(input:disabled) {
2841
+ opacity: .5;
2842
+ cursor: not-allowed;
2843
+ }
2844
+
2845
+ .engine-opt input {
2846
+ margin-top: 3px;
2847
+ accent-color: var(--accent);
2848
+ }
2849
+
2850
+ .engine-opt .dim {
2851
+ font-size: 12px;
2852
+ }
2853
+
2854
+ .export-wc-opts {
2855
+ display: flex;
2856
+ flex-wrap: wrap;
2857
+ gap: 10px 16px;
2858
+ align-items: flex-end;
2859
+ margin: -4px 0 12px;
2860
+ padding: 10px 12px;
2861
+ border: 1px solid var(--border);
2862
+ border-radius: 8px;
2863
+ background: var(--panel-2);
2864
+ }
2865
+ .export-wc-opts.hidden { display: none; }
2866
+ .export-wc-field {
2867
+ display: flex;
2868
+ flex-direction: column;
2869
+ gap: 4px;
2870
+ font-size: 12px;
2871
+ color: var(--muted, #9a9aaa);
2872
+ }
2873
+ .export-wc-sel {
2874
+ min-width: 160px;
2875
+ padding: 6px 8px;
2876
+ border: 1px solid var(--border);
2877
+ border-radius: 6px;
2878
+ background: var(--panel, #1a1a22);
2879
+ color: inherit;
2880
+ font: inherit;
2881
+ }
2882
+ .export-wc-hint {
2883
+ flex: 1 1 100%;
2884
+ margin: 0;
2885
+ font-size: 12px;
2886
+ }
2887
+
2888
+ .export-track-warn {
2889
+ margin: 0 0 12px;
2890
+ padding: 9px 12px;
2891
+ border: 1px solid #8a6a28;
2892
+ border-radius: 8px;
2893
+ background: #3a2e12;
2894
+ color: #f0c14a;
2895
+ font-size: 12px;
2896
+ line-height: 1.4;
2897
+ }
2898
+
2899
+ .export-profile-row {
2900
+ margin: 0 0 12px;
2901
+ padding: 10px 12px;
2902
+ border: 1px solid var(--border);
2903
+ border-radius: 8px;
2904
+ background: var(--panel-2);
2905
+ }
2906
+
2907
+ .export-profile-label {
2908
+ display: block;
2909
+ font-size: 12px;
2910
+ font-weight: 600;
2911
+ margin-bottom: 6px;
2912
+ }
2913
+
2914
+ .export-profile-sel {
2915
+ width: 100%;
2916
+ padding: 6px 10px;
2917
+ border: 1px solid var(--border);
2918
+ border-radius: 6px;
2919
+ background: var(--panel);
2920
+ color: var(--text);
2921
+ font: inherit;
2922
+ font-size: 12px;
2923
+ }
2924
+
2925
+ .export-profile-note,
2926
+ .export-profile-hint {
2927
+ margin: 6px 0 0;
2928
+ font-size: 12px;
2929
+ line-height: 1.4;
2930
+ }
2931
+
2932
+ .export-profile-hint {
2933
+ opacity: 0.75;
2934
+ }
2935
+
2936
+ .export-track-warn.hidden {
2937
+ display: none;
2938
+ }
2939
+
2940
+ .dialog.help {
2941
+ width: min(820px, 94vw);
2942
+ max-height: min(90vh, 640px);
2943
+ overflow: auto;
2944
+ }
2945
+
2946
+ .dialog.settings {
2947
+ width: min(440px, 92vw);
2948
+ }
2949
+
2950
+ .dialog.settings .settings-intro {
2951
+ margin-bottom: 14px;
2952
+ font-size: 12px;
2953
+ }
2954
+
2955
+ .dialog.settings .settings-section h3 {
2956
+ font-size: 11px;
2957
+ font-weight: 700;
2958
+ letter-spacing: .4px;
2959
+ text-transform: uppercase;
2960
+ color: var(--dim);
2961
+ margin: 0 0 8px;
2962
+ }
2963
+
2964
+ .settings-row {
2965
+ display: flex;
2966
+ gap: 10px;
2967
+ align-items: flex-start;
2968
+ padding: 10px 12px;
2969
+ margin-bottom: 8px;
2970
+ border: 1px solid var(--border);
2971
+ border-radius: 8px;
2972
+ cursor: pointer;
2973
+ background: var(--panel-2);
2974
+ }
2975
+
2976
+ .settings-row:hover {
2977
+ border-color: #454552;
2978
+ }
2979
+
2980
+ .settings-row input {
2981
+ margin-top: 2px;
2982
+ flex: none;
2983
+ }
2984
+
2985
+ .settings-label {
2986
+ display: block;
2987
+ color: #e8e8ec;
2988
+ font-size: 13px;
2989
+ font-weight: 600;
2990
+ margin-bottom: 4px;
2991
+ }
2992
+
2993
+ .settings-hint {
2994
+ display: block;
2995
+ font-size: 12px;
2996
+ color: var(--dim);
2997
+ line-height: 1.35;
2998
+ }
2999
+
3000
+ #btnSettings {
3001
+ display: inline-flex;
3002
+ align-items: center;
3003
+ justify-content: center;
3004
+ width: 34px;
3005
+ padding: 6px 0;
3006
+ }
3007
+
3008
+ #btnSettings .ico {
3009
+ margin: 0;
3010
+ vertical-align: 0;
3011
+ }
3012
+
3013
+ .dialog.help .keys-cols {
3014
+ display: grid;
3015
+ grid-template-columns: 1fr 1fr;
3016
+ gap: 0 28px;
3017
+ margin-bottom: 12px;
3018
+ align-items: start;
3019
+ }
3020
+
3021
+ .dialog.help .keys {
3022
+ width: 100%;
3023
+ border-collapse: collapse;
3024
+ margin-bottom: 0;
3025
+ }
3026
+
3027
+ .dialog.help .keys td {
3028
+ padding: 5px 6px;
3029
+ border-bottom: 1px solid #26262c;
3030
+ font-size: 12px;
3031
+ vertical-align: top;
3032
+ }
3033
+
3034
+ .dialog.help .keys td:first-child {
3035
+ width: 40%;
3036
+ color: var(--dim);
3037
+ white-space: nowrap;
3038
+ }
3039
+
3040
+ @media (max-width: 700px) {
3041
+ .dialog.help .keys-cols {
3042
+ grid-template-columns: 1fr;
3043
+ }
3044
+ }
3045
+
3046
+ kbd {
3047
+ background: var(--panel-2);
3048
+ border: 1px solid var(--border);
3049
+ border-bottom-width: 2px;
3050
+ border-radius: 4px;
3051
+ padding: 1px 6px;
3052
+ font: 11px Consolas, monospace;
3053
+ color: #fff;
3054
+ }
3055
+
3056
+ /* ── Scrollbars ── */
3057
+ ::-webkit-scrollbar {
3058
+ width: 10px;
3059
+ height: 10px;
3060
+ }
3061
+
3062
+ ::-webkit-scrollbar-thumb {
3063
+ background: #35353e;
3064
+ border-radius: 5px;
3065
+ border: 2px solid var(--panel);
3066
+ }
3067
+
3068
+ ::-webkit-scrollbar-track {
3069
+ background: transparent;
3070
+ }
3071
+
3072
+ /* ── Toast ── */
3073
+ #toast {
3074
+ position: fixed;
3075
+ left: 50%;
3076
+ bottom: 26px;
3077
+ transform: translate(-50%, 20px);
3078
+ background: var(--panel-2);
3079
+ border: 1px solid var(--border);
3080
+ color: var(--text);
3081
+ padding: 9px 16px;
3082
+ border-radius: 8px;
3083
+ font-size: 12px;
3084
+ box-shadow: 0 8px 30px #000a;
3085
+ opacity: 0;
3086
+ pointer-events: none;
3087
+ transition: opacity .25s, transform .25s;
3088
+ z-index: 80;
3089
+ max-width: 60vw;
3090
+ }
3091
+
3092
+ #toast.show {
3093
+ opacity: 1;
3094
+ transform: translate(-50%, 0);
3095
+ }
3096
+
3097
+ /* ── Inspector checkboxes ── */
3098
+ .insp-row input[type=checkbox] {
3099
+ width: 15px;
3100
+ height: 15px;
3101
+ accent-color: var(--accent);
3102
+ flex: none;
3103
+ }
3104
+
3105
+ /* ── Drop highlight ── */
3106
+ body.file-drag::after {
3107
+ content: "Drop files to import";
3108
+ position: fixed;
3109
+ inset: 10px;
3110
+ border: 2px dashed var(--accent);
3111
+ border-radius: 14px;
3112
+ background: #7b6cff14;
3113
+ color: #cfc8ff;
3114
+ font-size: 18px;
3115
+ font-weight: 600;
3116
+ display: flex;
3117
+ align-items: center;
3118
+ justify-content: center;
3119
+ z-index: 99;
3120
+ pointer-events: none;
3121
+ }
3122
+ /* ── Round 3: snap targets, markers, typed timecode ── */
3123
+ .snap-seg {
3124
+ display: inline-flex;
3125
+ }
3126
+
3127
+ .snap-seg #btnSnap {
3128
+ border-top-right-radius: 0;
3129
+ border-bottom-right-radius: 0;
3130
+ }
3131
+
3132
+ #btnSnapMenu {
3133
+ padding: 3px 5px;
3134
+ border-left: 0;
3135
+ border-top-left-radius: 0;
3136
+ border-bottom-left-radius: 0;
3137
+ }
3138
+
3139
+ .snap-line {
3140
+ position: absolute;
3141
+ top: 0;
3142
+ bottom: 0;
3143
+ width: 1px;
3144
+ background: #5eead4;
3145
+ box-shadow: 0 0 0 1px #5eead433;
3146
+ z-index: 5;
3147
+ pointer-events: none;
3148
+ }
3149
+
3150
+ .snap-menu {
3151
+ min-width: 170px;
3152
+ }
3153
+
3154
+ .snap-menu-head,
3155
+ .marker-pop-head {
3156
+ padding: 4px 10px 6px;
3157
+ font-size: 11px;
3158
+ }
3159
+
3160
+ .ctx-menu .snap-opt {
3161
+ justify-content: flex-start;
3162
+ gap: 8px;
3163
+ align-items: center;
3164
+ }
3165
+
3166
+ .snap-opt input {
3167
+ accent-color: var(--accent);
3168
+ }
3169
+
3170
+ .marker-pop {
3171
+ width: 216px;
3172
+ }
3173
+
3174
+ .marker-pop-head {
3175
+ display: flex;
3176
+ justify-content: space-between;
3177
+ align-items: baseline;
3178
+ padding-left: 6px;
3179
+ padding-right: 6px;
3180
+ }
3181
+
3182
+ .marker-pop-head .timecode {
3183
+ font-size: 12px;
3184
+ }
3185
+
3186
+ .marker-name {
3187
+ width: 100%;
3188
+ margin: 0 0 8px;
3189
+ padding: 5px 7px;
3190
+ border: 1px solid var(--border);
3191
+ border-radius: 4px;
3192
+ background: var(--bg);
3193
+ color: var(--text);
3194
+ font: inherit;
3195
+ font-size: 12px;
3196
+ user-select: text;
3197
+ }
3198
+
3199
+ .marker-name:focus {
3200
+ outline: none;
3201
+ border-color: var(--accent);
3202
+ }
3203
+
3204
+ .marker-swatches {
3205
+ display: grid;
3206
+ grid-template-columns: repeat(8, 1fr);
3207
+ gap: 4px;
3208
+ margin: 0 2px 6px;
3209
+ }
3210
+
3211
+ .marker-swatch {
3212
+ aspect-ratio: 1;
3213
+ border: 2px solid transparent;
3214
+ border-radius: 50%;
3215
+ background: var(--c);
3216
+ cursor: pointer;
3217
+ }
3218
+
3219
+ .marker-swatch.on {
3220
+ border-color: #fff;
3221
+ }
3222
+
3223
+ .marker-swatch:focus-visible {
3224
+ outline: 2px solid var(--accent);
3225
+ outline-offset: 1px;
3226
+ }
3227
+
3228
+ .marker-list {
3229
+ min-width: 240px;
3230
+ max-height: 320px;
3231
+ overflow-y: auto;
3232
+ }
3233
+
3234
+ .marker-row {
3235
+ display: flex;
3236
+ align-items: center;
3237
+ gap: 2px;
3238
+ }
3239
+
3240
+ .ctx-menu .marker-go {
3241
+ justify-content: flex-start;
3242
+ align-items: center;
3243
+ gap: 8px;
3244
+ flex: 1;
3245
+ min-width: 0;
3246
+ }
3247
+
3248
+ .marker-go .timecode {
3249
+ font-size: 12px;
3250
+ }
3251
+
3252
+ .marker-label {
3253
+ overflow: hidden;
3254
+ text-overflow: ellipsis;
3255
+ white-space: nowrap;
3256
+ }
3257
+
3258
+ .marker-dot {
3259
+ flex: none;
3260
+ width: 8px;
3261
+ height: 8px;
3262
+ background: var(--c);
3263
+ transform: rotate(45deg);
3264
+ }
3265
+
3266
+ .marker-edit {
3267
+ flex: none;
3268
+ }
3269
+
3270
+ .marker-clear {
3271
+ margin-top: 4px !important;
3272
+ border-top: 1px solid var(--border) !important;
3273
+ border-radius: 0 0 4px 4px !important;
3274
+ }
3275
+
3276
+ .marker-empty {
3277
+ padding: 8px 10px;
3278
+ font-size: 12px;
3279
+ }
3280
+
3281
+ #tcCurrent,
3282
+ #tcIn,
3283
+ #tcOut {
3284
+ cursor: text;
3285
+ border-radius: 3px;
3286
+ }
3287
+
3288
+ #tcCurrent:hover,
3289
+ #tcIn:hover,
3290
+ #tcOut:hover {
3291
+ background: #ffffff12;
3292
+ }
3293
+
3294
+ .timecode.editing {
3295
+ visibility: hidden;
3296
+ }
3297
+
3298
+ .tc-input {
3299
+ position: fixed;
3300
+ z-index: 10000;
3301
+ box-sizing: border-box;
3302
+ padding: 0 2px;
3303
+ border: 1px solid var(--accent);
3304
+ border-radius: 3px;
3305
+ background: var(--bg);
3306
+ color: #fff;
3307
+ line-height: 1;
3308
+ outline: none;
3309
+ user-select: text;
3310
+ }
3311
+
3312
+ /* ── Color workspace: scopes (left) + grade page (side tab) ── */
3313
+ .panel.scopes {
3314
+ display: none;
3315
+ flex-direction: column;
3316
+ gap: 6px;
3317
+ padding: 6px;
3318
+ min-width: 0;
3319
+ overflow: hidden;
3320
+ }
3321
+
3322
+ .app.ws-color .panel.bin {
3323
+ display: none;
3324
+ }
3325
+
3326
+ .app.ws-color .panel.scopes {
3327
+ display: flex;
3328
+ }
3329
+
3330
+ .app.ws-color .upper {
3331
+ grid-template-columns: 360px minmax(0, 1fr) 340px;
3332
+ }
3333
+
3334
+ .scope-slot {
3335
+ flex: 1;
3336
+ min-height: 0;
3337
+ display: flex;
3338
+ flex-direction: column;
3339
+ background: #0b0b0e;
3340
+ border: 1px solid var(--border);
3341
+ border-radius: 6px;
3342
+ overflow: hidden;
3343
+ }
3344
+
3345
+ .scope-head {
3346
+ display: flex;
3347
+ padding: 4px 6px;
3348
+ border-bottom: 1px solid var(--border);
3349
+ }
3350
+
3351
+ .scope-head select {
3352
+ background: var(--panel-2);
3353
+ color: var(--text);
3354
+ border: 1px solid var(--border);
3355
+ border-radius: 4px;
3356
+ font-size: 11px;
3357
+ padding: 2px 4px;
3358
+ }
3359
+
3360
+ .scope-cv {
3361
+ flex: 1;
3362
+ min-height: 0;
3363
+ width: 100%;
3364
+ display: block;
3365
+ }
3366
+
3367
+ .color-page {
3368
+ flex: 1;
3369
+ min-height: 0;
3370
+ overflow-x: hidden;
3371
+ overflow-y: auto;
3372
+ padding: 10px;
3373
+ }
3374
+
3375
+ .color-page.locked {
3376
+ opacity: 0.6;
3377
+ }
3378
+
3379
+ .cp-head {
3380
+ display: flex;
3381
+ gap: 6px;
3382
+ align-items: center;
3383
+ margin-bottom: 8px;
3384
+ }
3385
+
3386
+ .cp-head .cp-name {
3387
+ flex: 1;
3388
+ min-width: 0;
3389
+ font-weight: 600;
3390
+ overflow: hidden;
3391
+ text-overflow: ellipsis;
3392
+ white-space: nowrap;
3393
+ }
3394
+
3395
+ .cp-tools .btn {
3396
+ flex: 1;
3397
+ justify-content: center;
3398
+ }
3399
+
3400
+ .cp-wheels {
3401
+ display: grid;
3402
+ grid-template-columns: 1fr 1fr;
3403
+ gap: 12px 10px;
3404
+ margin: 4px 0 14px;
3405
+ }
3406
+
3407
+ .cw {
3408
+ display: flex;
3409
+ flex-direction: column;
3410
+ align-items: center;
3411
+ gap: 4px;
3412
+ min-width: 0;
3413
+ }
3414
+
3415
+ .cw-head {
3416
+ width: 100%;
3417
+ font-size: 12px;
3418
+ color: var(--dim);
3419
+ text-align: center;
3420
+ }
3421
+
3422
+ .cw-disc {
3423
+ width: 100%;
3424
+ max-width: 132px;
3425
+ aspect-ratio: 1;
3426
+ cursor: grab;
3427
+ touch-action: none;
3428
+ }
3429
+
3430
+ .cw-disc:active {
3431
+ cursor: grabbing;
3432
+ }
3433
+
3434
+ .cw-master {
3435
+ width: 100%;
3436
+ max-width: 132px;
3437
+ }
3438
+
3439
+ .cw-vals {
3440
+ font: 10px/1.3 ui-monospace, Consolas, monospace;
3441
+ color: var(--dim);
3442
+ white-space: nowrap;
3443
+ }
3444
+
3445
+ .cp-label {
3446
+ cursor: default;
3447
+ }
3448
+
3449
+ .cp-label:hover {
3450
+ color: #cfc8ff;
3451
+ }
3452
+
3453
+ .cp-row input[type=range] {
3454
+ flex: 1;
3455
+ min-width: 0;
3456
+ }
3457
+
3458
+ .cp-row .cp-num {
3459
+ flex: none;
3460
+ width: 60px;
3461
+ }
3462
+
3463
+ #preview.wb-picking {
3464
+ cursor: crosshair;
3465
+ }
3466
+
3467
+ .cv-tabs {
3468
+ display: grid;
3469
+ grid-template-columns: repeat(5, 1fr);
3470
+ gap: 3px;
3471
+ margin-bottom: 6px;
3472
+ }
3473
+
3474
+ .cv-tabs .btn {
3475
+ justify-content: center;
3476
+ padding-left: 0;
3477
+ padding-right: 0;
3478
+ font-size: 10.5px;
3479
+ }
3480
+
3481
+ .cv-bar {
3482
+ display: flex;
3483
+ align-items: center;
3484
+ gap: 4px;
3485
+ margin-bottom: 6px;
3486
+ }
3487
+
3488
+ .cv-bar .cv-sp {
3489
+ flex: 1;
3490
+ }
3491
+
3492
+ .cv-bar .cv-label {
3493
+ font-size: 12px;
3494
+ color: var(--dim);
3495
+ }
3496
+
3497
+ .cv-ch {
3498
+ min-width: 26px;
3499
+ justify-content: center;
3500
+ color: var(--cv);
3501
+ }
3502
+
3503
+ .cv-ed {
3504
+ display: block;
3505
+ width: 100%;
3506
+ aspect-ratio: 16 / 9;
3507
+ border: 1px solid var(--border);
3508
+ border-radius: 6px;
3509
+ cursor: crosshair;
3510
+ touch-action: none;
3511
+ }
3512
+
3513
+ .cv-ed.square {
3514
+ aspect-ratio: 1;
3515
+ }
3516
+
3517
+ /* Color tab: layers (secondaries) */
3518
+ .cp-layers {
3519
+ display: flex;
3520
+ flex-wrap: wrap;
3521
+ gap: 3px;
3522
+ margin: 2px 0 8px;
3523
+ padding-top: 8px;
3524
+ border-top: 1px solid var(--border);
3525
+ }
3526
+ .cl-chip { max-width: 110px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
3527
+ .cl-chip.off { opacity: 0.55; text-decoration: line-through; }
3528
+ .cl-row {
3529
+ display: flex;
3530
+ flex-wrap: wrap;
3531
+ align-items: center;
3532
+ gap: 4px;
3533
+ margin-bottom: 6px;
3534
+ }
3535
+ .cl-name {
3536
+ flex: 1 1 90px;
3537
+ min-width: 0;
3538
+ background: var(--panel-2);
3539
+ border: 1px solid var(--border);
3540
+ border-radius: 4px;
3541
+ color: var(--text);
3542
+ font: inherit;
3543
+ font-size: 11.5px;
3544
+ padding: 3px 6px;
3545
+ }
3546
+ .cl-note { color: var(--dim); font-size: 10.5px; margin: 2px 0 0; }
3547
+ .cq-block { margin-bottom: 6px; }
3548
+ .cq-block.off .cp-row { opacity: 0.4; }
3549
+ .cq-on { display: flex; align-items: center; gap: 5px; font-size: 11px; color: var(--text); margin-bottom: 2px; cursor: pointer; }
3550
+ input[type="range"].cq-hue {
3551
+ background: linear-gradient(90deg, #f33, #ff3, #3f3, #3ff, #33f, #f3f, #f33);
3552
+ border-radius: 3px;
3553
+ height: 6px;
3554
+ }
3555
+ .dialog.help .keys tr.keys-head td {
3556
+ padding-top: 12px;
3557
+ color: var(--text);
3558
+ font-weight: 600;
3559
+ font-size: 11px;
3560
+ letter-spacing: 0.04em;
3561
+ text-transform: uppercase;
3562
+ white-space: normal;
3563
+ }