@tutti-os/workbench-surface 0.0.64 → 0.0.66

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.
package/LICENSE CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  Apache License
3
2
  Version 2.0, January 2004
4
3
  http://www.apache.org/licenses/
@@ -187,7 +186,7 @@
187
186
  same "printed page" as the copyright notice for easier
188
187
  identification within third-party archives.
189
188
 
190
- Copyright [yyyy] [name of copyright owner]
189
+ Copyright 2025-2026 The Tutti Authors
191
190
 
192
191
  Licensed under the Apache License, Version 2.0 (the "License");
193
192
  you may not use this file except in compliance with the License.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tutti-os/workbench-surface",
3
- "version": "0.0.64",
3
+ "version": "0.0.66",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "types": "./dist/index.d.ts",
@@ -34,10 +34,10 @@
34
34
  "@tutti-os/config-tsconfig": "0.0.0"
35
35
  },
36
36
  "dependencies": {
37
- "@tutti-os/ui-i18n-runtime": "0.0.64",
38
- "@tutti-os/ui-react-hooks": "0.0.64",
39
- "@tutti-os/workbench-snapshot": "0.0.64",
40
- "@tutti-os/ui-system": "0.0.64"
37
+ "@tutti-os/ui-i18n-runtime": "0.0.66",
38
+ "@tutti-os/ui-react-hooks": "0.0.66",
39
+ "@tutti-os/workbench-snapshot": "0.0.66",
40
+ "@tutti-os/ui-system": "0.0.66"
41
41
  },
42
42
  "peerDependencies": {
43
43
  "react": "^19.1.0",
@@ -1,561 +0,0 @@
1
- import assert from "node:assert/strict";
2
- import { readFileSync } from "node:fs";
3
- import { resolve } from "node:path";
4
- import test from "node:test";
5
-
6
- test("floating window bodies do not reserve a right-side content margin", () => {
7
- const css = readFileSync(resolve("src/styles/workbench.css"), "utf8");
8
-
9
- assert.doesNotMatch(
10
- css,
11
- /\.workbench-window\[data-display-mode="floating"\]\s+\.workbench-window__body\s*{[^}]*margin-right/s
12
- );
13
- });
14
-
15
- test("traffic lights keep visual layout while expanding the pointer hit area", () => {
16
- const css = readFileSync(resolve("src/styles/workbench.css"), "utf8");
17
-
18
- assert.match(
19
- css,
20
- /\.workbench-window-traffic-light\s*{[^}]*width:\s*20px;[^}]*height:\s*20px;[^}]*margin:\s*-4px;[^}]*cursor:\s*pointer;[^}]*transition:\s*opacity 160ms ease;/s
21
- );
22
- assert.match(
23
- css,
24
- /\.workbench-window-traffic-light::before\s*{[^}]*inset:\s*4px;[^}]*content:\s*"";[^}]*transition:\s*background-color 160ms ease;/s
25
- );
26
- assert.match(
27
- css,
28
- /\.workbench-window-traffic-light__icon\s*{[^}]*inset:\s*5px;[^}]*width:\s*10px;[^}]*height:\s*10px;[^}]*opacity:\s*0;[^}]*transition:\s*opacity 120ms ease;/s
29
- );
30
- assert.match(
31
- css,
32
- /\.workbench-window-traffic-lights:hover\s+\.workbench-window-traffic-light__icon,\s*\.workbench-window-traffic-lights:focus-within\s+\.workbench-window-traffic-light__icon\s*{[^}]*opacity:\s*1;/s
33
- );
34
- assert.match(
35
- css,
36
- /\.workbench-window-traffic-lights:hover\s+\.workbench-window-traffic-light\[data-workbench-traffic-light="close"\]::before,\s*\.workbench-window-traffic-lights:focus-within\s+\.workbench-window-traffic-light\[data-workbench-traffic-light="close"\]::before\s*{[^}]*background-color:\s*#ff5f57;/s
37
- );
38
- });
39
-
40
- test("floating window corner resize handles do not intrude further than the edge handles", () => {
41
- const css = readFileSync(resolve("src/styles/workbench.css"), "utf8");
42
-
43
- // Resize handles render outside `.workbench-window`, which keeps most of
44
- // the corner hot zone outside the clipped window while still leaving a small
45
- // diagonal resize target over the visible border.
46
- assert.match(
47
- css,
48
- /\.workbench-window__resize-handle\[data-handle="north-east"\],\s*\.workbench-window__resize-handle\[data-handle="north-west"\],\s*\.workbench-window__resize-handle\[data-handle="south-east"\],\s*\.workbench-window__resize-handle\[data-handle="south-west"\]\s*{[^}]*width:\s*16px;[^}]*height:\s*16px;/s
49
- );
50
- assert.match(
51
- css,
52
- /\.workbench-window__resize-handle\[data-handle="south-west"\]\s*{[^}]*bottom:\s*-12px;[^}]*left:\s*-12px;/s
53
- );
54
- });
55
-
56
- test("mission control hidden presentation windows are invisible and inert", () => {
57
- const css = readFileSync(resolve("src/styles/workbench.css"), "utf8");
58
-
59
- assert.match(
60
- css,
61
- /\.workbench-window-shell\[data-presentation-visibility="hidden"\]\s*{[^}]*visibility:\s*hidden;[^}]*opacity:\s*0;[^}]*pointer-events:\s*none;/s
62
- );
63
- });
64
-
65
- test("mission control overlay lets layout controls sit above dialog overlays", () => {
66
- const css = readFileSync(resolve("src/styles/workbench.css"), "utf8");
67
- const source = readFileSync(
68
- resolve("src/mission-control/WorkbenchMissionControlOverlay.tsx"),
69
- "utf8"
70
- );
71
-
72
- assert.match(
73
- css,
74
- /\.workbench-mission-control\s*{[^}]*z-index:\s*var\(--z-tooltip,\s*100700\);/s
75
- );
76
- assert.match(
77
- source,
78
- /className="workbench-mission-control pointer-events-none absolute inset-0 overflow-hidden"/
79
- );
80
- assert.match(
81
- source,
82
- /className="workbench-mission-control__layout-dock desktop-dock-plate pointer-events-auto"/
83
- );
84
- assert.match(
85
- css,
86
- /\.desktop-dock-plate\.workbench-mission-control__layout-dock\s*{[^}]*pointer-events:\s*auto;/s
87
- );
88
- });
89
-
90
- test("mission control backdrop uses the shared dark scrim value", () => {
91
- const css = readFileSync(resolve("src/styles/workbench.css"), "utf8");
92
-
93
- assert.match(
94
- css,
95
- /\.workbench-surface\s*{[^}]*--workbench-chrome-active-foreground:\s*var\(--foreground\);/s
96
- );
97
- assert.match(
98
- css,
99
- /\.workbench-surface\[data-mission-control-phase="entering"\],[\s\S]*?\.workbench-surface\[data-presentation-mode="mission-control"\]\s*{[^}]*--workbench-chrome-active-foreground:\s*var\(--white-stationary\);[^}]*--workbench-chrome-foreground:\s*var\(--white-stationary\);/s
100
- );
101
- assert.match(
102
- css,
103
- /\.workbench-mission-control-backdrop\s*{[^}]*background:\s*rgb\(0 0 0 \/ 60%\);[^}]*box-shadow:\s*none;/s
104
- );
105
- assert.match(
106
- css,
107
- /\.workbench-mission-control-backdrop::before\s*{[^}]*background:\s*none;[^}]*opacity:\s*0;/s
108
- );
109
- assert.match(
110
- css,
111
- /\.workbench-mission-control-backdrop::after\s*{[^}]*background:\s*none;[^}]*opacity:\s*0;/s
112
- );
113
- assert.doesNotMatch(
114
- css,
115
- /\.workbench-mission-control-backdrop\s*{[^}]*var\(--workbench-surface-background\)/s
116
- );
117
- });
118
-
119
- test("dialog popover node layer sits above dialog overlays and remains clickable", () => {
120
- const css = readFileSync(resolve("src/styles/workbench.css"), "utf8");
121
-
122
- assert.match(
123
- css,
124
- /\.workbench-node-layer--dialog-popover\s*{[^}]*position:\s*fixed;[^}]*z-index:\s*var\(--z-dialog-popover\);[^}]*pointer-events:\s*none;/s
125
- );
126
- assert.match(
127
- css,
128
- /\.workbench-node-layer--dialog-popover\[data-workbench-interactive="true"\]\s+\.workbench-window-shell\[data-minimized-mount="visible"\]\[data-genie-state="visible"\]\s*{[^}]*pointer-events:\s*auto;/s
129
- );
130
- });
131
-
132
- test("dock retained entry removal animates width and icon exit", () => {
133
- const css = readFileSync(resolve("src/styles/workbench.css"), "utf8");
134
-
135
- assert.match(
136
- css,
137
- /\.desktop-dock-plate\s*{[^}]*transition:\s*width 220ms cubic-bezier\(0\.22, 1, 0\.36, 1\);/s
138
- );
139
- assert.match(
140
- css,
141
- /\.desktop-dock\[data-dock-placement="left"\]\s*{[^}]*transition:\s*height 600ms cubic-bezier\(0\.16, 1, 0\.3, 1\);/s
142
- );
143
- assert.match(
144
- css,
145
- /\.desktop-dock__slot\[data-presence="exiting"\]\s*{[^}]*animation:\s*desktop-dock-slot-collapse 600ms cubic-bezier\(0\.4, 0, 0\.2, 1\)[^}]*both;/s
146
- );
147
- assert.match(
148
- css,
149
- /\.desktop-dock__slot\[data-presence="exiting"\]\s+\.desktop-dock__icon-shell\s*{[^}]*animation:\s*desktop-dock-presence-exit 420ms cubic-bezier\(0\.4, 0, 0\.2, 1\)[^}]*both;/s
150
- );
151
- assert.match(
152
- css,
153
- /\.desktop-dock__separator\[data-presence="exiting"\]\s*{[^}]*animation:\s*desktop-dock-separator-collapse 600ms/s
154
- );
155
- assert.match(css, /@keyframes desktop-dock-slot-collapse/);
156
- assert.match(css, /@keyframes desktop-dock-slot-collapse-left/);
157
- assert.match(css, /@keyframes desktop-dock-separator-collapse/);
158
- assert.match(css, /@keyframes desktop-dock-separator-collapse-left/);
159
- });
160
-
161
- test("dock transparent hover padding lets clicks reach windows behind it", () => {
162
- const css = readFileSync(resolve("src/styles/workbench.css"), "utf8");
163
-
164
- assert.match(
165
- css,
166
- /\.desktop-dock-plate\s*{[^}]*pointer-events:\s*none;[^}]*transition:\s*width 220ms/s
167
- );
168
- assert.match(
169
- css,
170
- /\.desktop-dock\s*{[^}]*pointer-events:\s*none;[^}]*transition:\s*width 600ms/s
171
- );
172
- assert.match(css, /\.desktop-dock__items\s*{[^}]*pointer-events:\s*none;/s);
173
- assert.match(css, /\.desktop-dock__slot\s*{[^}]*pointer-events:\s*auto;/s);
174
- assert.match(
175
- css,
176
- /\.desktop-dock\[data-dock-pointer-active="true"\]\s+\.desktop-dock__btn\[data-dock-hover-panel-trigger="true"\],[\s\S]*?pointer-events:\s*auto;/s
177
- );
178
- assert.match(
179
- css,
180
- /\.desktop-dock__hover-panel\s*{[^}]*pointer-events:\s*auto;/s
181
- );
182
- });
183
-
184
- test("dock badge chrome uses inverted outlines and 11px count text", () => {
185
- const css = readFileSync(resolve("src/styles/workbench.css"), "utf8");
186
-
187
- assert.match(
188
- css,
189
- /\.desktop-dock__icon-shell,\s*\.desktop-dock__minimized-stack-icon\s*{[^}]*--desktop-dock-loading-badge-offset:\s*-3\.6px;[^}]*--desktop-dock-loading-badge-size:\s*16\.2px;/s
190
- );
191
- assert.match(
192
- css,
193
- /\.desktop-dock__icon-shell\[data-entry-state="loading"\]::before,\s*\.desktop-dock__count-badge\s*{[^}]*border:\s*1px solid var\(--text-inverted\);/s
194
- );
195
- assert.match(
196
- css,
197
- /\.desktop-dock__count-badge\s*{[^}]*color:\s*var\(--text-inverted\);[^}]*font-size:\s*11px;/s
198
- );
199
- assert.match(
200
- css,
201
- /\.desktop-dock__status-badge\s*{[^}]*border:\s*1\.8px solid var\(--text-inverted\);/s
202
- );
203
- assert.match(
204
- css,
205
- /\.desktop-dock__slot--minimized\s+\.desktop-dock__count-badge\s*{[^}]*right:\s*-12px;[^}]*bottom:\s*var\(--desktop-dock-loading-badge-offset\);/s
206
- );
207
- });
208
-
209
- test("left dock placement owns vertical frame and popup placement styles", () => {
210
- const css = readFileSync(resolve("src/styles/workbench.css"), "utf8");
211
-
212
- assert.match(
213
- css,
214
- /\.workbench-dock-frame\s*{[^}]*--workbench-left-dock-bottom-inset:\s*24px;[^}]*--workbench-left-dock-left-inset:\s*4px;[^}]*--workbench-left-dock-top-inset:\s*54px;/s
215
- );
216
- assert.match(
217
- css,
218
- /\.workbench-dock-frame\[data-dock-placement="left"\]\s*{[^}]*top:\s*var\(--workbench-left-dock-top-inset\);[^}]*bottom:\s*var\(--workbench-left-dock-bottom-inset\);[^}]*left:\s*var\(--workbench-left-dock-left-inset\);[^}]*align-items:\s*center;/s
219
- );
220
- assert.match(
221
- css,
222
- /\.desktop-dock\[data-dock-placement="left"\]\s+\.desktop-dock__items\s*{[^}]*align-items:\s*flex-start;[^}]*flex-direction:\s*column;/s
223
- );
224
- assert.match(
225
- css,
226
- /\.desktop-dock__hover-panel\[data-dock-placement="left"\]\s*{[^}]*left:\s*calc\(\s*var\(--desktop-dock-hover-panel-anchor-left\)\s*\+\s*var\(--desktop-dock-hover-panel-anchor-width\)\s*\+\s*var\(--desktop-dock-hover-panel-gap, 12px\)\s*\);/s
227
- );
228
- assert.match(
229
- css,
230
- /\.desktop-dock-popup-root\s*{[^}]*z-index:\s*var\(--z-popover, 100200\);/s
231
- );
232
- assert.match(
233
- css,
234
- /body\[data-desktop-dock-minimized-stack-open="true"\]\s+\.workbench-dock-frame,\s*body\[data-desktop-dock-minimized-stack-open="true"\]\s+\.desktop-dock-plate,\s*body\[data-desktop-dock-minimized-stack-open="true"\]\s+\.desktop-dock\s*{[^}]*z-index:\s*0;/s
235
- );
236
- assert.match(
237
- css,
238
- /\.desktop-dock-popup-root\[data-dock-placement="bottom"\]\s*{[^}]*transform:\s*translate\(-50%, -100%\);/s
239
- );
240
- assert.match(
241
- css,
242
- /\.desktop-dock-popup\[data-popup-variant="minimized-stack"\]\s*>\s*div:nth-child\(2\)\s*{[^}]*overflow:\s*visible;/s
243
- );
244
- assert.match(
245
- css,
246
- /\.desktop-dock-popup-root\[data-dock-placement="left"\]\s*{[^}]*transform:\s*translate\(0, -50%\);/s
247
- );
248
- assert.match(
249
- css,
250
- /\.desktop-dock-popup-root\[data-dock-placement="left"\]\[data-popup-variant="minimized-stack"\]\s*{[^}]*z-index:\s*100300;[^}]*pointer-events:\s*none;[^}]*transform:\s*translate\(0, -100%\);/s
251
- );
252
- assert.match(
253
- css,
254
- /\.desktop-dock-popup-root\[data-dock-placement="left"\]\s+\.desktop-dock-popup__fan-title-tip\s*{[^}]*right:\s*auto;[^}]*left:\s*calc\(100% \+ 12px\);/s
255
- );
256
- assert.doesNotMatch(css, /desktop-dock-left-stack-card-fan-in/);
257
- assert.match(
258
- css,
259
- /\.desktop-dock\[data-dock-placement="left"\]\s+\.desktop-dock__slot\[data-node-state="open"\]::before,[\s\S]*?\.desktop-dock\[data-dock-placement="left"\]\s+\.desktop-dock__slot\[data-node-state="minimized"\]::before\s*{[^}]*right:\s*auto;[^}]*left:\s*calc\(var\(--desktop-dock-indicator-offset\) - 2px\);/s
260
- );
261
- assert.match(
262
- css,
263
- /\.desktop-dock__slot\[data-node-state="open"\]::before,[\s\S]*?\.desktop-dock__slot\[data-node-state="minimized"\]::before\s*{[^}]*--desktop-dock-indicator-color:\s*rgb\(0 0 0 \/ 46%\);[^}]*bottom:\s*calc\(var\(--desktop-dock-indicator-offset\) - 2px\);[^}]*width:\s*5px;[^}]*height:\s*5px;[^}]*background:\s*var\(--desktop-dock-indicator-color\);[^}]*box-shadow:\s*0 0 0 0\.5px rgb\(0 0 0 \/ 12%\);/s
264
- );
265
- assert.match(
266
- css,
267
- /\.desktop-dock__slot\[data-node-state="open"\]\[data-wallpaper-tone="dark"\]::before,[\s\S]*?\.desktop-dock__slot\[data-node-state="minimized"\]\[data-wallpaper-tone="dark"\]::before\s*{[^}]*--desktop-dock-indicator-color:\s*rgb\(255 255 255 \/ 78%\);[^}]*box-shadow:\s*0 0 0 0\.5px rgb\(0 0 0 \/ 42%\);/s
268
- );
269
- assert.match(
270
- css,
271
- /\.desktop-dock__slot\[data-node-state="open"\]\[data-wallpaper-tone="light"\]::before,[\s\S]*?\.desktop-dock__slot\[data-node-state="minimized"\]\[data-wallpaper-tone="light"\]::before\s*{[^}]*--desktop-dock-indicator-color:\s*rgb\(0 0 0 \/ 46%\);[^}]*box-shadow:\s*0 0 0 0\.5px rgb\(255 255 255 \/ 58%\);/s
272
- );
273
- assert.doesNotMatch(
274
- css,
275
- /\.desktop-dock__slot\[data-node-state="minimized"\]::before\s*{[^}]*opacity:/s
276
- );
277
- });
278
-
279
- test("dock overflow keeps scroll controls viewport-bound", () => {
280
- const css = readFileSync(resolve("src/styles/workbench.css"), "utf8");
281
-
282
- assert.match(
283
- css,
284
- /\.desktop-dock-plate\s*{[^}]*--desktop-dock-safe-inline:\s*64px;/s
285
- );
286
- assert.match(
287
- css,
288
- /\.desktop-dock-plate\s*{[^}]*max-width:\s*calc\(100vw - var\(--desktop-dock-safe-inline\) \* 2\);/s
289
- );
290
- assert.match(
291
- css,
292
- /\.desktop-dock\s*{[^}]*max-width:\s*calc\(100vw - var\(--desktop-dock-safe-inline\) \* 2\);/s
293
- );
294
- assert.match(
295
- css,
296
- /\.desktop-dock-plate\s*{[^}]*--desktop-dock-viewport-size:\s*88px;/s
297
- );
298
- assert.match(
299
- css,
300
- /\.desktop-dock-plate\s*{[^}]*--desktop-dock-left-viewport-size:\s*124px;/s
301
- );
302
- assert.match(
303
- css,
304
- /\.desktop-dock-plate\s*{[^}]*--desktop-dock-icon-half-size:\s*21\.6px;[^}]*--desktop-dock-icon-center-block-end:\s*calc\(\s*var\(--desktop-dock-items-padding-block-end\)\s*\+\s*var\(--desktop-dock-icon-half-size\)\s*\);/s
305
- );
306
- assert.match(
307
- css,
308
- /\.desktop-dock-plate\s*{[^}]*--desktop-dock-separator-center-offset:\s*calc\(\s*var\(--desktop-dock-icon-half-size\)\s*-\s*var\(--desktop-dock-separator-length\)\s*\/\s*2\s*\);/s
309
- );
310
- assert.match(
311
- css,
312
- /\.desktop-dock-plate\s*{[^}]*--desktop-dock-plate-padding-block-end:\s*0px;[^}]*--desktop-dock-plate-padding-block-start:\s*21\.6px;/s
313
- );
314
- assert.match(
315
- css,
316
- /\.desktop-dock\s*{[^}]*height:\s*var\(--desktop-dock-viewport-size\);/s
317
- );
318
- assert.match(
319
- css,
320
- /\.desktop-dock\s*{[^}]*--desktop-dock-scroll-button-gap:\s*32px;/s
321
- );
322
- assert.match(
323
- css,
324
- /\.desktop-dock\s*{[^}]*--desktop-dock-tooltip-gap:\s*32px;/s
325
- );
326
- assert.match(
327
- css,
328
- /\.desktop-dock\s*{[^}]*--desktop-dock-hover-panel-gap:\s*12px;/s
329
- );
330
- assert.match(
331
- css,
332
- /\.desktop-dock__hover-panel\s*{[^}]*top:\s*var\(--desktop-dock-hover-panel-anchor-top\);[^}]*pointer-events:\s*auto;[^}]*var\(--desktop-dock-hover-panel-gap, 12px\)/s
333
- );
334
- assert.match(
335
- css,
336
- /\.desktop-dock__label-tooltip\s*{[^}]*top:\s*var\(--desktop-dock-label-tooltip-anchor-top\);[^}]*pointer-events:\s*none;[^}]*var\(--desktop-dock-tooltip-gap, 32px\)/s
337
- );
338
- assert.match(
339
- css,
340
- /\.desktop-dock__label-tooltip\s*{[^}]*width:\s*max-content;[^}]*overflow:\s*hidden;[^}]*text-overflow:\s*ellipsis;[^}]*white-space:\s*nowrap;/s
341
- );
342
- assert.match(
343
- css,
344
- /\.desktop-dock__label-tooltip\s*{[^}]*max-width:\s*min\(180px, calc\(100vw - 32px\)\);[^}]*padding:\s*4px 7px;[^}]*border-radius:\s*6px;[^}]*font-size:\s*11px;[^}]*line-height:\s*14px;/s
345
- );
346
- assert.match(
347
- css,
348
- /\.desktop-dock__label-tooltip\[data-dock-placement="left"\]\s*{[^}]*left:\s*calc\(\s*var\(--desktop-dock-label-tooltip-anchor-left\)\s*\+\s*var\(--desktop-dock-label-tooltip-anchor-width\)\s*\+\s*var\(--desktop-dock-tooltip-gap, 32px\)\s*\);/s
349
- );
350
- assert.match(
351
- css,
352
- /\.desktop-dock\[data-dock-pointer-active="true"\]:not\(\s*\[data-dock-hover-panel-open="true"\]\s*\)\s+\.desktop-dock__hover-panel\s*{[^}]*visibility:\s*hidden;[^}]*pointer-events:\s*none;/s
353
- );
354
- assert.match(
355
- css,
356
- /\.desktop-dock\s*{[^}]*--desktop-dock-scroll-button-z-index:\s*120;/s
357
- );
358
- assert.match(
359
- css,
360
- /\.desktop-dock\s*{[^}]*--desktop-dock-scroll-fade-size:\s*48px;/s
361
- );
362
- assert.match(
363
- css,
364
- /\.desktop-dock\[data-scroll-overflow="true"\]\s+\.desktop-dock__items\s*{[^}]*padding-right:\s*calc\(\s*var\(--desktop-dock-scroll-button-size\)\s*\+\s*var\(--desktop-dock-scroll-button-gap\)\s*\);[^}]*padding-left:\s*calc\(\s*var\(--desktop-dock-scroll-button-size\)\s*\+\s*var\(--desktop-dock-scroll-button-gap\)\s*\);/s
365
- );
366
- assert.match(
367
- css,
368
- /\.desktop-dock\[data-dock-placement="left"\]\s*{[^}]*width:\s*var\(--desktop-dock-left-viewport-size\);[^}]*max-height:\s*calc\(\s*100vh - var\(--workbench-left-dock-top-inset\) -\s*var\(--workbench-left-dock-bottom-inset\)\s*\);/s
369
- );
370
- assert.match(
371
- css,
372
- /\.desktop-dock__items\s*{[^}]*align-items:\s*flex-end;[^}]*overflow:\s*visible;[^}]*scrollbar-width:\s*none;/s
373
- );
374
- assert.match(
375
- css,
376
- /\.desktop-dock\[data-scroll-overflow="true"\]\s+\.desktop-dock__items\s*{[^}]*overflow-x:\s*auto;[^}]*overflow-y:\s*hidden;/s
377
- );
378
- assert.match(
379
- css,
380
- /\.desktop-dock-plate\s*{[^}]*--desktop-dock-left-indicator-gutter:\s*8px;/s
381
- );
382
- assert.match(
383
- css,
384
- /\.desktop-dock\[data-dock-placement="left"\]\s+\.desktop-dock__items\s*{[^}]*width:\s*var\(--desktop-dock-left-viewport-size\);[^}]*padding:\s*var\(--desktop-dock-left-items-padding-block\) 0\s*var\(--desktop-dock-left-items-padding-block\)\s*var\(--desktop-dock-left-indicator-gutter\);/s
385
- );
386
- assert.match(
387
- css,
388
- /\.desktop-dock\[data-dock-placement="left"\]\[data-scroll-overflow="true"\]\s+\.desktop-dock__items\s*{[^}]*overflow-x:\s*visible;[^}]*overflow-y:\s*auto;/s
389
- );
390
- assert.match(
391
- css,
392
- /\.desktop-dock\[data-dock-placement="left"\]\s+\.desktop-dock__icon-shell\s*{[^}]*transform-origin:\s*left center;/s
393
- );
394
- assert.match(
395
- css,
396
- /\.desktop-dock\[data-dock-placement="left"\]\s+\.desktop-dock__minimized-preview\s*{[^}]*transform-origin:\s*left center;/s
397
- );
398
- assert.match(
399
- css,
400
- /\.desktop-dock__minimized-preview--component\s*{[^}]*padding:\s*0;[^}]*background:\s*var\(--background-panel\);/s
401
- );
402
- assert.match(
403
- css,
404
- /\.desktop-dock__minimized-preview--component > \*\s*{[^}]*width:\s*100%;[^}]*height:\s*100%;/s
405
- );
406
- assert.match(
407
- css,
408
- /\.desktop-dock__minimized-preview-freeze-source\s*{[^}]*visibility:\s*hidden;[^}]*pointer-events:\s*none;/s
409
- );
410
- assert.match(
411
- css,
412
- /\.desktop-dock__minimized-preview-frozen-content\s*{[^}]*display:\s*block;[^}]*overflow:\s*hidden;/s
413
- );
414
- assert.doesNotMatch(css, /\.workbench-genie-preview-capture__fallback/);
415
- assert.match(css, /\.desktop-dock__slot\s*{[^}]*flex:\s*0 0 auto;/s);
416
- assert.match(
417
- css,
418
- /\.desktop-dock__separator\s*{[^}]*--desktop-dock-separator-color:\s*var\(--line-1\);[^}]*flex:\s*0 0 auto;[^}]*margin:\s*0 4px var\(--desktop-dock-separator-center-offset\);[^}]*align-self:\s*flex-end;[^}]*background:\s*var\(--desktop-dock-separator-color\);/s
419
- );
420
- assert.match(
421
- css,
422
- /\.desktop-dock__separator\[data-wallpaper-tone="dark"\]\s*{[^}]*--desktop-dock-separator-color:\s*rgb\(255 255 255 \/ 15%\);/s
423
- );
424
- assert.match(
425
- css,
426
- /\.desktop-dock__separator\[data-wallpaper-tone="light"\]\s*{[^}]*--desktop-dock-separator-color:\s*rgb\(0 0 0 \/ 12%\);/s
427
- );
428
- assert.match(
429
- css,
430
- /\.desktop-dock\[data-dock-placement="left"\]\s+\.desktop-dock__separator\s*{[^}]*align-self:\s*flex-start;[^}]*margin:\s*4px 0 4px var\(--desktop-dock-separator-center-offset\);/s
431
- );
432
- assert.match(
433
- css,
434
- /\.desktop-dock\[data-scroll-overflow="true"\]:hover\s+\.desktop-dock__scroll-button:not\(:disabled\)/s
435
- );
436
- assert.match(
437
- css,
438
- /\.desktop-dock\[data-dock-pointer-active="true"\]\s+\.desktop-dock__items\s*{[^}]*mask-image:\s*none;/s
439
- );
440
- assert.doesNotMatch(
441
- css,
442
- /\.desktop-dock\[data-dock-pointer-active="true"\]\s+\[data-radix-popper-content-wrapper\]\s*{[^}]*display:\s*none !important;/s
443
- );
444
- assert.match(
445
- css,
446
- /\.desktop-dock\[data-dock-pointer-active="true"\]:not\(\s*\[data-dock-hover-panel-open="true"\]\s*\)\s+\.desktop-dock__hover-panel\s*{[^}]*visibility:\s*hidden;/s
447
- );
448
- assert.match(
449
- css,
450
- /\.desktop-dock\[data-dock-hover-panel-open="true"\]\s+\.desktop-dock__items\s*{[^}]*mask-image:\s*none;/s
451
- );
452
- assert.match(css, /@keyframes desktop-dock-bounce-translate/s);
453
- assert.match(
454
- css,
455
- /@keyframes desktop-dock-bounce-translate\s*{[\s\S]*?45%\s*{[^}]*translate:\s*0 -14px;/s
456
- );
457
- assert.match(
458
- css,
459
- /@keyframes desktop-dock-bounce-translate-left\s*{[\s\S]*?45%\s*{[^}]*translate:\s*14px 0;/s
460
- );
461
- assert.match(
462
- css,
463
- /\.desktop-dock__slot\[data-bouncing="true"\]\s+\.desktop-dock__icon-content,/s
464
- );
465
- assert.doesNotMatch(
466
- css,
467
- /\.desktop-dock__slot\[data-bouncing="true"\]\s+\.desktop-dock__icon-shell,/s
468
- );
469
- assert.match(
470
- css,
471
- /\.desktop-dock:not\(\[data-dock-pointer-active="true"\]\)\s+\.desktop-dock__btn\[data-interactive="true"\]:active\s*{[^}]*transform:\s*translateY\(-1px\) scale\(0\.99\);/s
472
- );
473
- assert.match(
474
- css,
475
- /\.desktop-dock\[data-dock-placement="left"\]:not\(\[data-dock-pointer-active="true"\]\)\s+\.desktop-dock__btn\[data-interactive="true"\]:active\s*{[^}]*transform:\s*translateX\(1px\) scale\(0\.99\);/s
476
- );
477
- assert.match(
478
- css,
479
- /\.desktop-dock\[data-dock-pointer-active="true"\]\s+\.desktop-dock__btn\s*{[^}]*transition:\s*none;/s
480
- );
481
- assert.match(
482
- css,
483
- /\.desktop-dock__slot--minimized\[data-presence="entering"\]\s*{[^}]*animation:\s*none;/s
484
- );
485
- assert.match(
486
- css,
487
- /\.desktop-dock__slot--minimized\[data-promoted-from-stack="true"\]\[data-presence="entering"\]\s*{[^}]*animation:\s*none;/s
488
- );
489
- assert.match(
490
- css,
491
- /@keyframes desktop-dock-minimized-preview-promote\s*{[\s\S]*?translate:\s*28px 10px;/s
492
- );
493
- assert.match(
494
- css,
495
- /\.desktop-dock:not\(\[data-dock-pointer-active="true"\]\)\s+\.desktop-dock__minimized-stack-layer\s*{[^}]*transition:[^}]*transform 520ms/s
496
- );
497
- assert.match(
498
- css,
499
- /\.desktop-dock\[data-dock-placement="left"\]\s+\.desktop-dock__slot--minimized\[data-presence="entering"\]\s*{[^}]*animation:\s*none;/s
500
- );
501
- assert.match(
502
- css,
503
- /\.desktop-dock__slot--minimized\[data-presence="entering"\]\s+\.desktop-dock__minimized-preview,[\s\S]*?\.desktop-dock__slot--minimized\[data-presence="entering"\]\s+\.desktop-dock__minimized-stack-icon\s*{[^}]*animation:\s*desktop-dock-minimized-icon-appear 640ms/s
504
- );
505
- assert.match(
506
- css,
507
- /\.desktop-dock__slot--minimized\[data-pending-minimize="true"\]\[data-presence="entering"\]\s+\.desktop-dock__minimized-preview,[\s\S]*?\.desktop-dock__slot--minimized\[data-pending-minimize="true"\]\[data-presence="entering"\]\s+\.desktop-dock__minimized-stack-icon\s*{[^}]*animation:\s*none;/s
508
- );
509
- assert.match(
510
- css,
511
- /\.desktop-dock__slot--minimized\[data-collapsing="true"\],[\s\S]*?\.desktop-dock__slot--minimized\[data-presence="exiting"\]\s*{[^}]*animation:\s*desktop-dock-minimized-slot-collapse 720ms[^}]*pointer-events:\s*none;/s
512
- );
513
- assert.match(
514
- css,
515
- /\.desktop-dock\[data-dock-placement="left"\]\s+\.desktop-dock__slot--minimized\[data-collapsing="true"\],[\s\S]*?\.desktop-dock\[data-dock-placement="left"\]\s+\.desktop-dock__slot--minimized\[data-presence="exiting"\]\s*{[^}]*animation-name:\s*desktop-dock-minimized-slot-collapse-left;/s
516
- );
517
- assert.match(
518
- css,
519
- /@keyframes desktop-dock-minimized-slot-collapse\s*{[\s\S]*?width:\s*var\(--desktop-dock-collapse-inline-size, var\(--desktop-dock-size\)\);[\s\S]*?width:\s*0;[\s\S]*?margin-inline:\s*calc\(var\(--desktop-dock-gap\) \/ -2\);/
520
- );
521
- assert.match(
522
- css,
523
- /@keyframes desktop-dock-minimized-icon-disappear\s*{[\s\S]*?scale:\s*0\.08 0\.92;/
524
- );
525
- assert.match(
526
- css,
527
- /\.desktop-dock-popup\[data-popup-variant="minimized-stack"\]\s+\[data-desktop-dock-popup-card="true"\]\[data-launching="true"\]\s*{[^}]*opacity:\s*0;[^}]*scale:\s*0\.94;[^}]*pointer-events:\s*none;/s
528
- );
529
- assert.match(
530
- css,
531
- /\.desktop-dock__scroll-button--backward\s*{[^}]*top:\s*calc\(100% - var\(--desktop-dock-icon-center-block-end\)\);[^}]*left:\s*0;/s
532
- );
533
- assert.match(
534
- css,
535
- /\.desktop-dock__scroll-button--forward\s*{[^}]*top:\s*calc\(100% - var\(--desktop-dock-icon-center-block-end\)\);[^}]*right:\s*0;/s
536
- );
537
- assert.match(
538
- css,
539
- /\.desktop-dock__scroll-button\s*{[^}]*z-index:\s*var\(--desktop-dock-scroll-button-z-index\);/s
540
- );
541
- assert.match(
542
- css,
543
- /\.desktop-dock__scroll-button\s*{[^}]*background:\s*var\(--background-fronted\);/s
544
- );
545
- assert.match(
546
- css,
547
- /\.desktop-dock\[data-dock-placement="left"\]\s+\.desktop-dock__scroll-button\s*{[^}]*left:\s*calc\(\s*var\(--desktop-dock-left-indicator-gutter\)\s*\+\s*var\(--desktop-dock-icon-half-size\)\s*\);/s
548
- );
549
- assert.match(
550
- css,
551
- /\.desktop-dock\[data-scroll-forward="true"\]\s+\.desktop-dock__items\s*{[^}]*mask-image:\s*linear-gradient\(\s*to right,/s
552
- );
553
- assert.match(
554
- css,
555
- /\.desktop-dock\[data-scroll-backward="true"\]\[data-scroll-forward="true"\]\s+\.desktop-dock__items\s*{[^}]*transparent 0,[^}]*transparent 100%/s
556
- );
557
- assert.match(
558
- css,
559
- /\.desktop-dock\[data-dock-placement="left"\]\[data-scroll-forward="true"\]\s+\.desktop-dock__items\s*{[^}]*mask-image:\s*linear-gradient\(\s*to bottom,/s
560
- );
561
- });