@crievo/omni 0.1.2 → 0.1.4

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 (122) hide show
  1. package/docs/onboarding.md +69 -161
  2. package/omnivideo.config.example.json +1 -1
  3. package/package.json +2 -1
  4. package/reference/learnings.md +12 -0
  5. package/reference/omnichat.md +5 -4
  6. package/reference/publish.md +9 -9
  7. package/reference/studio.md +1 -1
  8. package/studio/api/app.ts +2 -2
  9. package/studio/api/routes/sound.ts +22 -3
  10. package/studio/api/services/onboarding.ts +242 -21
  11. package/studio/api/services/settings.ts +4 -2
  12. package/studio/api/services/sound.ts +45 -0
  13. package/studio/shared/types/api.ts +26 -1
  14. package/studio/studio.ts +1 -0
  15. package/studio/web/components/AppShell.tsx +3 -1
  16. package/studio/web/components/CloneVoiceDialog/RecordStep.tsx +3 -0
  17. package/studio/web/components/CloneVoiceDialog/RecorderBar.tsx +37 -20
  18. package/studio/web/components/CloneVoiceDialog/useCloneVoice.ts +39 -12
  19. package/studio/web/components/MissingDmsPanel/BatchSend.tsx +13 -4
  20. package/studio/web/components/Omni/OmniWidget.tsx +14 -5
  21. package/studio/web/components/Omni/PendingActions.tsx +25 -6
  22. package/studio/web/components/OmnichatRulePanel/RuleConfig.tsx +13 -3
  23. package/studio/web/components/OmnichatRulePanel/RuleEnableConfirm.tsx +14 -4
  24. package/studio/web/components/ResultMessage.tsx +12 -3
  25. package/studio/web/components/Sidebar.tsx +63 -24
  26. package/studio/web/components/StageStepper.tsx +105 -34
  27. package/studio/web/components/Toaster.tsx +25 -0
  28. package/studio/web/components/VoiceCarousel.tsx +19 -16
  29. package/studio/web/components/VoiceProfilesSettings.tsx +8 -3
  30. package/studio/web/components/bencho/ActionNode.tsx +456 -0
  31. package/studio/web/components/bencho/AssigneePicker.tsx +246 -0
  32. package/studio/web/components/bencho/BenchoScope.tsx +8 -0
  33. package/studio/web/components/bencho/Checklist.tsx +421 -0
  34. package/studio/web/components/bencho/CreateMenu.tsx +258 -0
  35. package/studio/web/components/bencho/GenerateImage.tsx +290 -0
  36. package/studio/web/components/bencho/ImageAccordion.tsx +273 -0
  37. package/studio/web/components/bencho/LiquidToggle.tsx +289 -0
  38. package/studio/web/components/bencho/MagnifyDock.tsx +200 -0
  39. package/studio/web/components/bencho/NowPlaying.tsx +403 -0
  40. package/studio/web/components/bencho/OneTimeCode.tsx +374 -0
  41. package/studio/web/components/bencho/PullToRefresh.tsx +527 -0
  42. package/studio/web/components/bencho/SlideToConfirm.tsx +385 -0
  43. package/studio/web/components/bencho/SloshSlider.tsx +394 -0
  44. package/studio/web/components/bencho/StackedBars.tsx +342 -0
  45. package/studio/web/components/bencho/ToastStack.tsx +263 -0
  46. package/studio/web/components/bencho/UploadDropzone.tsx +394 -0
  47. package/studio/web/components/bencho/VoiceNote.tsx +705 -0
  48. package/studio/web/components/icons.tsx +27 -0
  49. package/studio/web/components/ui/slider.tsx +34 -1
  50. package/studio/web/components/ui/switch.tsx +18 -5
  51. package/studio/web/hooks/useOnboarding.ts +24 -6
  52. package/studio/web/index.html +1 -1
  53. package/studio/web/lib/alerts.ts +10 -0
  54. package/studio/web/lib/omni-panel.ts +4 -1
  55. package/studio/web/lib/toast.ts +196 -0
  56. package/studio/web/lib/upload.ts +24 -0
  57. package/studio/web/pages/BenchoPage/index.tsx +74 -0
  58. package/studio/web/pages/BenchoPage/registry.ts +174 -0
  59. package/studio/web/pages/GettingStartedPage/components/ComputerCard.tsx +102 -0
  60. package/studio/web/pages/GettingStartedPage/index.tsx +84 -58
  61. package/studio/web/pages/NewVideoPage/index.tsx +6 -2
  62. package/studio/web/pages/ReferencesPage/index.tsx +4 -1
  63. package/studio/web/pages/SettingsPage/components/AgentAccounts.tsx +30 -3
  64. package/studio/web/pages/VideoPage/components/ChangedVoices.tsx +14 -17
  65. package/studio/web/pages/VideoPage/components/LineTextEditor.tsx +1 -1
  66. package/studio/web/pages/VideoPage/components/PublishForm.tsx +24 -17
  67. package/studio/web/pages/VideoPage/components/ScheduledInfo.tsx +2 -1
  68. package/studio/web/pages/VideoPage/components/SoundTimeline/AddSound.tsx +12 -14
  69. package/studio/web/pages/VideoPage/components/SoundTimeline/BedRow.tsx +27 -11
  70. package/studio/web/pages/VideoPage/components/SoundTimeline/CaptionSaveBar.tsx +22 -18
  71. package/studio/web/pages/VideoPage/components/SoundTimeline/TimelineFooter.tsx +3 -4
  72. package/studio/web/pages/VideoPage/components/SoundTimeline/UploadTrack.tsx +59 -0
  73. package/studio/web/pages/VideoPage/components/SoundTimeline/useSoundTimeline.ts +1 -0
  74. package/studio/web/pages/VideoPage/components/VoicePauseBanner.tsx +4 -6
  75. package/studio/web/pages/VideoPage/index.tsx +4 -0
  76. package/studio/web/pages/VideosPage/components/VideoRow.tsx +2 -4
  77. package/studio/web/router.tsx +8 -0
  78. package/studio/web/styles/components/bencho/action-node.css +227 -0
  79. package/studio/web/styles/components/bencho/checklist.css +182 -0
  80. package/studio/web/styles/components/bencho/dock.css +188 -0
  81. package/studio/web/styles/components/bencho/gallery.css +109 -0
  82. package/studio/web/styles/components/bencho/generate.css +151 -0
  83. package/studio/web/styles/components/bencho/image-accordion.css +37 -0
  84. package/studio/web/styles/components/bencho/liq-create.css +279 -0
  85. package/studio/web/styles/components/bencho/liq-toggle.css +106 -0
  86. package/studio/web/styles/components/bencho/one-time-code.css +148 -0
  87. package/studio/web/styles/components/bencho/picker.css +204 -0
  88. package/studio/web/styles/components/bencho/pull.css +313 -0
  89. package/studio/web/styles/components/bencho/scope.css +42 -0
  90. package/studio/web/styles/components/bencho/slide-confirm.css +139 -0
  91. package/studio/web/styles/components/bencho/slosh.css +137 -0
  92. package/studio/web/styles/components/bencho/sound.css +260 -0
  93. package/studio/web/styles/components/bencho/stacked-bars.css +334 -0
  94. package/studio/web/styles/components/bencho/toast-stack.css +192 -0
  95. package/studio/web/styles/components/bencho/tokens.css +243 -0
  96. package/studio/web/styles/components/bencho/upload-dropzone.css +352 -0
  97. package/studio/web/styles/components/bencho/voice-note.css +337 -0
  98. package/studio/web/styles/components/clone-voice.css +12 -2
  99. package/studio/web/styles/components/omni.css +6 -1
  100. package/studio/web/styles/components/stepper.css +123 -7
  101. package/studio/web/styles/components/toaster.css +10 -0
  102. package/studio/web/styles/components/ui/slider.css +6 -16
  103. package/studio/web/styles/components/ui/switch.css +2 -41
  104. package/studio/web/styles/components/voice-carousel.css +46 -4
  105. package/studio/web/styles/index.css +23 -0
  106. package/studio/web/styles/pages/getting-started.css +46 -0
  107. package/studio/web/styles/pages/settings/shell.css +4 -0
  108. package/studio/web/styles/pages/video/layout.css +1 -4
  109. package/studio/web/styles/pages/video/sound-timeline.css +8 -0
  110. package/studio/web/styles/theme/identity/shell.css +10 -26
  111. package/tools/lib/agents.mjs +24 -13
  112. package/tools/lib/claude-settings.mjs +32 -3
  113. package/tools/lib/deps.mjs +24 -0
  114. package/tools/lib/platforms/instagram.mjs +1 -1
  115. package/tools/lib/up.mjs +5 -2
  116. package/tools/omni.mjs +7 -5
  117. package/tools/omnichat.mjs +5 -7
  118. package/tools/package.mjs +5 -3
  119. package/tools/publish.mjs +40 -137
  120. package/tools/reference.mjs +1 -1
  121. package/tools/setup.mjs +16 -15
  122. package/tools/sound.mjs +67 -3
@@ -0,0 +1,243 @@
1
+ /* Bencho's own palette, kept as it is on bencho.dev so the ported components keep their colors until the owner decides
2
+ whether the studio's tokens replace them. Two scopes:
3
+ - .bencho: the /bencho gallery page; `data-theme` picks the page palette, `data-fill` on a stage the card color
4
+ every component draws with (--fill-slab / --fill-on); `data-surface="glass"` adds the glass tokens.
5
+ - .bn-scope: wraps one ported component inside a real studio screen. It carries the light palette with a white fill
6
+ and follows the system theme (the studio reads prefers-color-scheme, not a class) for the dark fill.
7
+ Nothing here reaches the rest of the studio, which has its own --ok, --surface-2… */
8
+
9
+ .bencho,
10
+ .bn-scope {
11
+ --glass: 100;
12
+ --wash: 0.06;
13
+ --ink-rgb: 23, 24, 26;
14
+ --surface-rgb: 247, 247, 246;
15
+ --elev-rgb: 255, 255, 255;
16
+ --glass-rgb: 255, 255, 255;
17
+ --shadow-rgb: 23, 24, 26;
18
+ --bg: #fff;
19
+ --surface: #f7f7f6;
20
+ --surface-2: #f1f1f0;
21
+ --surface-3: #ecebe7;
22
+ --board: #fff;
23
+ --canvas-bg: #f7f7f6;
24
+ --pick: #0d99ff;
25
+ --pick-rgb: 13, 153, 255;
26
+ --guide: #ff3b6b;
27
+ --guide-on: #fff;
28
+ --bar-slot: 38px;
29
+ --bar-pad: 6px;
30
+ --bar-gap: 2px;
31
+ --card: #f7f7f6;
32
+ --solid: #0e0f11;
33
+ --solid-ink: #f4f3f1;
34
+ --pill-thumb: #fff;
35
+ --ink: #17181a;
36
+ --ink-2: #3c3b37;
37
+ --ink-3: #5c5b56;
38
+ --ink-4: #6f6e68;
39
+ --ink-5: #85847e;
40
+ --lock: #adaca6;
41
+ --on-ink: #fff;
42
+ --on-ink-rgb: 255, 255, 255;
43
+ --slab: var(--ink);
44
+ --on-slab: var(--on-ink);
45
+ --on-slab-rgb: var(--on-ink-rgb);
46
+ --glass-a: 0.35;
47
+ --glass-edge-a: 0.4;
48
+ --edge-hi: 0.75;
49
+ --edge-lo: 0.18;
50
+ --edge-far: 0.42;
51
+ --slab-dark: #0e0f11;
52
+ --spec-max: 0.35;
53
+ --ring-max: 0.4;
54
+ --lift-max: 0.06;
55
+ --bright-max: 0;
56
+ --pane: rgba(var(--glass-rgb), var(--glass-a));
57
+ --pane-edge: rgba(var(--glass-rgb), var(--glass-edge-a));
58
+ --pane-thumb: #ffffffd1;
59
+ --inlay: #ffffff8c;
60
+ --inlay-hi: #ffffffc7;
61
+ --ok: #15803d;
62
+ --paper: #dcd9cf;
63
+ --paper-2: #e9e7df;
64
+ --rule: #17181a29;
65
+ --signal: #2231dd;
66
+ --ember: #b8431c;
67
+ --font-head: "Google Sans", "Inter Head", var(--font-ui);
68
+ --font-ui:
69
+ "Inter", "Maison Neue", "MaisonNeue-Book", "Instrument Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
70
+ --font-mono: var(--font-ui);
71
+ --font-num: var(--font-ui);
72
+ --font-code: ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;
73
+ }
74
+ .bencho {
75
+ color-scheme: light;
76
+ }
77
+ .bencho[data-theme="dark"] {
78
+ color-scheme: dark;
79
+ --ink-rgb: 255, 255, 255;
80
+ --surface-rgb: 15, 15, 15;
81
+ --elev-rgb: 32, 32, 32;
82
+ --glass-rgb: 255, 255, 255;
83
+ --shadow-rgb: 0, 0, 0;
84
+ --bg: #000;
85
+ --surface: #0f0f0f;
86
+ --surface-2: #181818;
87
+ --surface-3: #202020;
88
+ --board: #1a1a1a;
89
+ --canvas-bg: #000;
90
+ --pick: #3aa9ff;
91
+ --guide: #ff5c84;
92
+ --guide-on: #fff;
93
+ --pick-rgb: 58, 169, 255;
94
+ --card: #0a0a0a;
95
+ --solid: #000;
96
+ --solid-ink: #fff;
97
+ --pill-thumb: #ffffff29;
98
+ --ink: #fff;
99
+ --ink-2: #b4b4b4;
100
+ --ink-3: #9a9a9a;
101
+ --ink-4: #828282;
102
+ --ink-5: #6b6b6b;
103
+ --lock: #525252;
104
+ --on-ink: #000;
105
+ --on-ink-rgb: 0, 0, 0;
106
+ --slab: var(--board);
107
+ --on-slab: var(--ink);
108
+ --on-slab-rgb: var(--ink-rgb);
109
+ --glass-a: 0.16;
110
+ --glass-edge-a: 0.2;
111
+ --edge-hi: 0.38;
112
+ --edge-lo: 0.06;
113
+ --edge-far: 0.2;
114
+ --slab-dark: #262626;
115
+ --spec-max: 0.15;
116
+ --ring-max: 0.14;
117
+ --lift-max: 0.5;
118
+ --bright-max: 22;
119
+ --pane-thumb: #ffffff21;
120
+ --inlay: #ffffff12;
121
+ --inlay-hi: #ffffff1f;
122
+ --wash: 0.09;
123
+ --ok: #34d17a;
124
+ }
125
+ .bencho [data-fill="light"],
126
+ .bn-scope {
127
+ --fill-slab: #fff;
128
+ --fill-on: #17181a;
129
+ --fill-on-rgb: 23, 24, 26;
130
+ --ink: #17181a;
131
+ --ink-rgb: 23, 24, 26;
132
+ --ink-2: #3c3b37;
133
+ --ink-3: #5c5b56;
134
+ --ink-4: #6f6e68;
135
+ --ink-5: #85847e;
136
+ --on-ink: #fff;
137
+ --on-ink-rgb: 255, 255, 255;
138
+ --board: #fff;
139
+ --card: #f7f7f6;
140
+ --surface: #f7f7f6;
141
+ --surface-2: #f1f1f0;
142
+ --surface-3: #ecebe7;
143
+ --elev-rgb: 255, 255, 255;
144
+ --glass-rgb: 255, 255, 255;
145
+ --pill-thumb: #fff;
146
+ --inlay: #ffffff8c;
147
+ --slab-btn: #fff;
148
+ }
149
+ .bencho [data-fill="dark"] {
150
+ --fill-slab: var(--slab-dark);
151
+ --fill-on: #fff;
152
+ --fill-on-rgb: 255, 255, 255;
153
+ --ink: #fff;
154
+ --ink-rgb: 255, 255, 255;
155
+ --ink-2: #b4b4b4;
156
+ --ink-3: #9a9a9a;
157
+ --ink-4: #828282;
158
+ --ink-5: #6b6b6b;
159
+ --on-ink: #000;
160
+ --on-ink-rgb: 0, 0, 0;
161
+ --board: #1a1a1a;
162
+ --card: #0a0a0a;
163
+ --surface: #0f0f0f;
164
+ --surface-2: #181818;
165
+ --surface-3: #202020;
166
+ --elev-rgb: 32, 32, 32;
167
+ --glass-rgb: 255, 255, 255;
168
+ --pill-thumb: #ffffff29;
169
+ --inlay: #ffffff1a;
170
+ --slab-btn: var(--slab-dark);
171
+ }
172
+ .bencho [data-surface="glass"],
173
+ .bn-scope {
174
+ --g: calc(var(--glass, 100) * 1%);
175
+ --pane: color-mix(in srgb, rgba(var(--glass-rgb), var(--glass-a)) var(--g), var(--fill-slab, var(--board)));
176
+ --pane-edge: color-mix(in srgb, rgba(var(--glass-rgb), var(--glass-edge-a)) var(--g), rgba(var(--ink-rgb), 0.08));
177
+ --pane-thumb: color-mix(in srgb, #ffffffd1 var(--g), rgba(var(--ink-rgb), 0.07));
178
+ --inlay: color-mix(in srgb, #ffffff8c var(--g), rgba(var(--ink-rgb), 0.05));
179
+ --inlay-hi: color-mix(in srgb, #ffffffc7 var(--g), rgba(var(--ink-rgb), 0.09));
180
+ --k: calc(var(--glass, 100) / 100);
181
+ --g-blur: calc(var(--glass, 100) * 0.25px);
182
+ --g-sat: calc(100% + var(--glass, 100) * 0.9%);
183
+ --g-bright: calc(100% + var(--bright-max) * var(--glass, 100) * 0.01%);
184
+ --g-spec: calc(var(--spec-max) * var(--k));
185
+ --g-ring: calc(var(--ring-max) * var(--k));
186
+ --g-lift: calc(var(--lift-max) * var(--k));
187
+ --g-edge-hi: calc(var(--edge-hi) * var(--k));
188
+ --g-edge-lo: calc(var(--edge-lo) * var(--k));
189
+ --g-edge-far: calc(var(--edge-far) * var(--k));
190
+ }
191
+ @media (prefers-color-scheme: dark) {
192
+ .bn-scope {
193
+ --surface-rgb: 15, 15, 15;
194
+ --shadow-rgb: 0, 0, 0;
195
+ --bg: #000;
196
+ --canvas-bg: #000;
197
+ --pick: #3aa9ff;
198
+ --guide: #ff5c84;
199
+ --guide-on: #fff;
200
+ --pick-rgb: 58, 169, 255;
201
+ --solid: #000;
202
+ --solid-ink: #fff;
203
+ --lock: #525252;
204
+ --slab: var(--board);
205
+ --on-slab: var(--ink);
206
+ --on-slab-rgb: var(--ink-rgb);
207
+ --glass-a: 0.16;
208
+ --glass-edge-a: 0.2;
209
+ --edge-hi: 0.38;
210
+ --edge-lo: 0.06;
211
+ --edge-far: 0.2;
212
+ --slab-dark: #262626;
213
+ --spec-max: 0.15;
214
+ --ring-max: 0.14;
215
+ --lift-max: 0.5;
216
+ --bright-max: 22;
217
+ --pane-thumb: #ffffff21;
218
+ --inlay-hi: #ffffff1f;
219
+ --wash: 0.09;
220
+ --ok: #34d17a;
221
+ --fill-slab: var(--slab-dark);
222
+ --fill-on: #fff;
223
+ --fill-on-rgb: 255, 255, 255;
224
+ --ink: #fff;
225
+ --ink-rgb: 255, 255, 255;
226
+ --ink-2: #b4b4b4;
227
+ --ink-3: #9a9a9a;
228
+ --ink-4: #828282;
229
+ --ink-5: #6b6b6b;
230
+ --on-ink: #000;
231
+ --on-ink-rgb: 0, 0, 0;
232
+ --board: #1a1a1a;
233
+ --card: #0a0a0a;
234
+ --surface: #0f0f0f;
235
+ --surface-2: #181818;
236
+ --surface-3: #202020;
237
+ --elev-rgb: 32, 32, 32;
238
+ --glass-rgb: 255, 255, 255;
239
+ --pill-thumb: #ffffff29;
240
+ --inlay: #ffffff1a;
241
+ --slab-btn: var(--slab-dark);
242
+ }
243
+ }
@@ -0,0 +1,352 @@
1
+ /* ══ Upload dropzone ═════════════════════════════════════ */
2
+ .bn-upl {
3
+ display: flex;
4
+ flex-direction: column;
5
+ gap: 12px;
6
+ width: 300px;
7
+ font-family: var(--font-ui);
8
+ color: var(--fill-on, var(--ink));
9
+ user-select: none;
10
+ -webkit-user-select: none;
11
+ }
12
+
13
+ /* a slot of fixed size, so the box can close in round an upload
14
+ without moving anything below it */
15
+ .bn-upl-zone-wrap {
16
+ flex: none;
17
+ display: flex;
18
+ align-items: center;
19
+ justify-content: center;
20
+ height: 176px;
21
+ }
22
+
23
+ .bn-upl-zone {
24
+ position: relative;
25
+ display: flex;
26
+ flex-direction: column;
27
+ align-items: center;
28
+ justify-content: center;
29
+ gap: 12px;
30
+ width: 100%;
31
+ /* 176, up from 128: the drop target is the block, and a short
32
+ one read as a banner rather than a place to put something */
33
+ height: 176px;
34
+ padding: 0 16px;
35
+ overflow: hidden;
36
+ border-radius: var(--upl-r);
37
+ background: var(--fill-slab, var(--card));
38
+ /* a file over it and it grows, with a bounce; an upload and it
39
+ closes in round it */
40
+ transition:
41
+ scale 420ms cubic-bezier(0.24, 1.34, 0.38, 1),
42
+ width 420ms cubic-bezier(0.24, 1.34, 0.38, 1),
43
+ height 420ms cubic-bezier(0.24, 1.34, 0.38, 1),
44
+ background-color 220ms ease;
45
+ }
46
+
47
+ .bn-upl-zone[data-over] {
48
+ scale: 1.02;
49
+ }
50
+
51
+ /* the gulp: in a little as the file goes down, out past its size,
52
+ and settle */
53
+ .bn-upl-zone[data-gulp] {
54
+ animation: bn-upl-gulp 460ms cubic-bezier(0.3, 1.2, 0.4, 1);
55
+ }
56
+
57
+ .bn-upl-zone[data-gulp] .bn-upl-icon {
58
+ animation: bn-upl-open 460ms cubic-bezier(0.3, 1.4, 0.4, 1);
59
+ }
60
+
61
+ [data-stroke="on"] .bn-upl-zone {
62
+ box-shadow: 0 0 0 1px var(--pane-edge);
63
+ }
64
+
65
+ .bn-upl-icon {
66
+ display: grid;
67
+ place-items: center;
68
+ width: 38px;
69
+ height: 38px;
70
+ border-radius: 10px;
71
+ /* a light grey tile, no edge — the fill's own ink walked most
72
+ of the way to its slab, so it is a pale grey on the light fill
73
+ and a lifted grey on the dark one */
74
+ background: color-mix(in srgb, var(--fill-on, #17181a) 6%, var(--fill-slab, #ffffff));
75
+ color: color-mix(in srgb, var(--fill-on, #17181a) 72%, var(--fill-slab, #ffffff));
76
+ transition:
77
+ translate 420ms cubic-bezier(0.24, 1.34, 0.38, 1),
78
+ background-color 220ms ease,
79
+ color 220ms ease;
80
+ }
81
+
82
+ /* over the box the tile only lifts, and its arrow goes to full
83
+ ink — no colour of its own */
84
+ .bn-upl-zone[data-over] .bn-upl-icon {
85
+ translate: 0 -4px;
86
+ color: var(--fill-on, var(--ink));
87
+ }
88
+
89
+ .bn-upl-say {
90
+ display: flex;
91
+ flex-direction: column;
92
+ align-items: center;
93
+ gap: 4px;
94
+ font-size: 13px;
95
+ text-align: center;
96
+ letter-spacing: 0em;
97
+ }
98
+
99
+ .bn-upl-say b {
100
+ font-weight: 500;
101
+ }
102
+
103
+ .bn-upl-say span {
104
+ font-size: 12px;
105
+ color: color-mix(in srgb, var(--fill-on, #17181a) 52%, var(--fill-slab, #ffffff));
106
+ letter-spacing: 0em;
107
+ }
108
+
109
+ .bn-upl-zone[data-refuse] .bn-upl-say b {
110
+ color: #e5484d;
111
+ }
112
+
113
+ /* the file, arrived in the box */
114
+ .bn-upl-now {
115
+ display: flex;
116
+ align-items: center;
117
+ gap: 12px;
118
+ width: max-content;
119
+ flex: none;
120
+ animation: bn-upl-land 420ms var(--upl-spring) both;
121
+ }
122
+
123
+ .bn-upl-text {
124
+ display: flex;
125
+ flex-direction: column;
126
+ gap: 4px;
127
+ width: 150px;
128
+ }
129
+
130
+ .bn-upl-name {
131
+ overflow: hidden;
132
+ font-size: 13px;
133
+ font-weight: 500;
134
+ white-space: nowrap;
135
+ text-overflow: ellipsis;
136
+ letter-spacing: 0em;
137
+ }
138
+
139
+ .bn-upl-meta {
140
+ display: flex;
141
+ align-items: center;
142
+ gap: 4px;
143
+ height: 14px;
144
+ font-size: 12px;
145
+ font-variant-numeric: tabular-nums;
146
+ color: color-mix(in srgb, var(--fill-on, #17181a) 52%, var(--fill-slab, #ffffff));
147
+ letter-spacing: 0em;
148
+ }
149
+
150
+ .bn-upl-track {
151
+ position: relative;
152
+ height: 4px;
153
+ margin-top: 4px;
154
+ overflow: hidden;
155
+ border-radius: 2px;
156
+ background: color-mix(in srgb, var(--fill-on, #17181a) 6%, var(--fill-slab, #ffffff));
157
+ }
158
+
159
+ .bn-upl-bar {
160
+ position: absolute;
161
+ inset: 0;
162
+ border-radius: inherit;
163
+ background: var(--signal, #2231dd);
164
+ transform-origin: left center;
165
+ }
166
+
167
+ .bn-upl-roll {
168
+ display: inline-flex;
169
+ line-height: 1em;
170
+ height: 1em;
171
+ overflow: hidden;
172
+ }
173
+
174
+ .bn-upl-roll-col {
175
+ display: inline-block;
176
+ height: 1em;
177
+ overflow: hidden;
178
+ }
179
+
180
+ .bn-upl-roll-strip {
181
+ display: flex;
182
+ flex-direction: column;
183
+ transition: transform 220ms cubic-bezier(0.24, 1.34, 0.38, 1);
184
+ }
185
+
186
+ .bn-upl-roll-strip > span {
187
+ height: 1em;
188
+ }
189
+
190
+ .bn-upl-end {
191
+ display: grid;
192
+ place-items: center;
193
+ flex: none;
194
+ width: 22px;
195
+ height: 22px;
196
+ }
197
+
198
+ .bn-upl-tick {
199
+ display: grid;
200
+ place-items: center;
201
+ flex: none;
202
+ width: 22px;
203
+ height: 22px;
204
+ border-radius: 50%;
205
+ background: var(--ok, #15803d);
206
+ color: #fff;
207
+ animation: bn-upl-pop 380ms cubic-bezier(0.3, 1.6, 0.4, 1) both;
208
+ }
209
+
210
+ /* the tray: three files lying under the box */
211
+ .bn-upl-tray {
212
+ display: flex;
213
+ justify-content: center;
214
+ gap: 20px;
215
+ }
216
+
217
+ .bn-upl-slot {
218
+ position: relative;
219
+ width: 76px;
220
+ height: 75px;
221
+ }
222
+
223
+ .bn-upl-file {
224
+ position: relative;
225
+ z-index: 1;
226
+ display: flex;
227
+ flex-direction: column;
228
+ align-items: center;
229
+ gap: 8px;
230
+ padding-top: 4px;
231
+ cursor: grab;
232
+ touch-action: none;
233
+ outline: none;
234
+ /* home is a spring; the Bounce knob sets its overshoot */
235
+ transition:
236
+ transform 420ms var(--upl-spring),
237
+ opacity 220ms ease;
238
+ }
239
+
240
+ .bn-upl-file[data-held] {
241
+ z-index: 5;
242
+ cursor: grabbing;
243
+ transition: none;
244
+ }
245
+
246
+ .bn-upl-file[data-gone] {
247
+ opacity: 0;
248
+ pointer-events: none;
249
+ transition: none;
250
+ }
251
+
252
+ .bn-upl-file:not([data-gone]) {
253
+ animation: bn-upl-back 360ms var(--upl-spring) both;
254
+ }
255
+
256
+ .bn-upl-file:focus-visible .bn-upl-page {
257
+ outline: 2px solid var(--signal, #2231dd);
258
+ outline-offset: 3px;
259
+ border-radius: 6px;
260
+ }
261
+
262
+ .bn-upl-page {
263
+ overflow: visible;
264
+ }
265
+
266
+ .bn-upl-page-line {
267
+ stroke: color-mix(in srgb, var(--fill-on, #17181a) 32%, var(--fill-slab, #ffffff));
268
+ stroke-width: 1.5;
269
+ /* outline only: the page is drawn, not filled */
270
+ fill: none;
271
+ }
272
+
273
+ .bn-upl-page-ext {
274
+ fill: #fff;
275
+ font-family: var(--font-ui);
276
+ /* size is the <text>'s own fontSize, in the icon's units */
277
+ font-weight: 500;
278
+ letter-spacing: 0em;
279
+ }
280
+
281
+ .bn-upl-label {
282
+ max-width: 76px;
283
+ overflow: hidden;
284
+ font-size: 11px;
285
+ white-space: nowrap;
286
+ text-overflow: ellipsis;
287
+ color: color-mix(in srgb, var(--fill-on, #17181a) 72%, var(--fill-slab, #ffffff));
288
+ letter-spacing: 0em;
289
+ }
290
+
291
+ /* the tray sits on the STAGE, not on the block, so when Fill
292
+ takes the block the other way from the page its names would be
293
+ coloured for the wrong ground — light grey on a light stage.
294
+ Across that split they take the page's own ink instead. */
295
+ /* the page's outline goes with its name, the same colour */
296
+ :root:not([data-theme="dark"]) [data-fill="dark"] .bn-upl-label {
297
+ color: color-mix(in srgb, var(--fill-on, var(--ink)) 70%, #ffffff);
298
+ }
299
+
300
+ :root:not([data-theme="dark"]) [data-fill="dark"] .bn-upl-page-line {
301
+ stroke: color-mix(in srgb, var(--fill-on, var(--ink)) 70%, #ffffff);
302
+ }
303
+
304
+ :root[data-theme="dark"] [data-fill="light"] .bn-upl-label {
305
+ color: color-mix(in srgb, #f4f3f1 70%, var(--fill-on, var(--ink)));
306
+ }
307
+
308
+ :root[data-theme="dark"] [data-fill="light"] .bn-upl-page-line {
309
+ stroke: color-mix(in srgb, #f4f3f1 70%, var(--fill-on, var(--ink)));
310
+ }
311
+
312
+ @keyframes bn-upl-gulp {
313
+ 0% {
314
+ scale: 1.02;
315
+ }
316
+ 35% {
317
+ scale: 0.985;
318
+ }
319
+ 70% {
320
+ scale: 1.006;
321
+ }
322
+ 100% {
323
+ scale: 1;
324
+ }
325
+ }
326
+
327
+ @keyframes bn-upl-open {
328
+ 40% {
329
+ scale: 1.08;
330
+ }
331
+ }
332
+
333
+ @keyframes bn-upl-land {
334
+ from {
335
+ opacity: 0;
336
+ scale: 0.85;
337
+ translate: 0 10px;
338
+ }
339
+ }
340
+
341
+ @keyframes bn-upl-pop {
342
+ from {
343
+ scale: 0;
344
+ }
345
+ }
346
+
347
+ @keyframes bn-upl-back {
348
+ from {
349
+ scale: 0.7;
350
+ opacity: 0;
351
+ }
352
+ }