@liberation-data/desk 0.4.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,231 @@
1
+ /* ── Conversation ── */
2
+
3
+ .desk-thread {
4
+ position: relative;
5
+ display: flex;
6
+ flex-direction: column;
7
+ min-height: 0;
8
+ height: 100%;
9
+ font-family: var(--desk-font);
10
+ }
11
+
12
+ .desk-thread-scroll {
13
+ flex: 1;
14
+ min-height: 0;
15
+ overflow-y: auto;
16
+ display: flex;
17
+ flex-direction: column;
18
+ gap: var(--desk-space-1);
19
+ padding: var(--desk-space-4);
20
+ }
21
+
22
+ .desk-message {
23
+ display: flex;
24
+ flex-direction: column;
25
+ align-items: flex-start;
26
+ max-width: min(80%, 60ch);
27
+ }
28
+
29
+ .desk-message[data-mine] {
30
+ align-self: flex-end;
31
+ align-items: flex-end;
32
+ }
33
+
34
+ /* A new run of messages from the same person gets air; the rest stay close. */
35
+ .desk-message[data-run-start] {
36
+ margin-top: var(--desk-space-3);
37
+ }
38
+
39
+ .desk-message:first-child {
40
+ margin-top: 0;
41
+ }
42
+
43
+ .desk-message-author {
44
+ margin-bottom: 2px;
45
+ padding: 0 var(--desk-space-1);
46
+ font-size: 11.5px;
47
+ font-weight: 600;
48
+ color: var(--desk-muted);
49
+ }
50
+
51
+ .desk-bubble {
52
+ padding: var(--desk-space-2) var(--desk-space-3);
53
+ border: 1px solid var(--desk-rule);
54
+ border-radius: 14px;
55
+ background: var(--desk-surface);
56
+ font-size: 13.5px;
57
+ line-height: 1.5;
58
+ white-space: pre-wrap;
59
+ overflow-wrap: anywhere;
60
+ }
61
+
62
+ .desk-message[data-mine] .desk-bubble {
63
+ border-color: transparent;
64
+ background: var(--desk-accent);
65
+ color: var(--desk-on-accent);
66
+ border-bottom-right-radius: 5px;
67
+ }
68
+
69
+ .desk-message:not([data-mine]) .desk-bubble {
70
+ border-bottom-left-radius: 5px;
71
+ }
72
+
73
+ .desk-message[data-state="sending"] .desk-bubble {
74
+ opacity: .6;
75
+ }
76
+
77
+ .desk-message[data-state="failed"] .desk-bubble {
78
+ border-color: var(--desk-bad);
79
+ }
80
+
81
+ .desk-message-foot {
82
+ display: flex;
83
+ align-items: center;
84
+ gap: var(--desk-space-2);
85
+ padding: 2px var(--desk-space-1) 0;
86
+ font-size: 11px;
87
+ color: var(--desk-muted);
88
+ }
89
+
90
+ .desk-message-foot:empty {
91
+ display: none;
92
+ }
93
+
94
+ .desk-message-failed {
95
+ color: var(--desk-bad);
96
+ }
97
+
98
+ .desk-typing {
99
+ align-self: flex-start;
100
+ margin-top: var(--desk-space-2);
101
+ padding: var(--desk-space-2) var(--desk-space-3);
102
+ border: 1px solid var(--desk-rule);
103
+ border-radius: 14px;
104
+ border-bottom-left-radius: 5px;
105
+ background: var(--desk-surface);
106
+ }
107
+
108
+ .desk-typing-dots {
109
+ display: flex;
110
+ gap: 4px;
111
+ }
112
+
113
+ .desk-typing-dots i {
114
+ width: 5px;
115
+ height: 5px;
116
+ border-radius: 50%;
117
+ background: var(--desk-muted);
118
+ animation: desk-typing 1.2s var(--desk-ease) infinite;
119
+ }
120
+
121
+ .desk-typing-dots i:nth-child(2) {
122
+ animation-delay: .15s;
123
+ }
124
+
125
+ .desk-typing-dots i:nth-child(3) {
126
+ animation-delay: .3s;
127
+ }
128
+
129
+ @keyframes desk-typing {
130
+ 0%, 60%, 100% {
131
+ opacity: .3;
132
+ }
133
+ 30% {
134
+ opacity: 1;
135
+ }
136
+ }
137
+
138
+ .desk-thread-jump {
139
+ position: absolute;
140
+ left: 50%;
141
+ bottom: var(--desk-space-3);
142
+ transform: translateX(-50%);
143
+ box-shadow: var(--desk-shadow);
144
+ }
145
+
146
+ .desk-composer {
147
+ flex: none;
148
+ display: flex;
149
+ align-items: flex-end;
150
+ gap: var(--desk-space-2);
151
+ padding: var(--desk-space-3) var(--desk-space-4);
152
+ border-top: 1px solid var(--desk-rule);
153
+ }
154
+
155
+ .desk-composer-field {
156
+ flex: 1;
157
+ min-width: 0;
158
+ min-height: var(--desk-control-height);
159
+ max-height: 40vh;
160
+ padding: var(--desk-space-2) var(--desk-space-3);
161
+ border: 1px solid var(--desk-rule);
162
+ border-radius: var(--desk-control-radius);
163
+ background: var(--desk-field-bg);
164
+ color: var(--desk-ink);
165
+ font-family: var(--desk-font);
166
+ font-size: 13.5px;
167
+ line-height: 20px;
168
+ resize: none;
169
+ }
170
+
171
+ .desk-composer-field:focus-visible {
172
+ outline: 2px solid var(--desk-accent);
173
+ outline-offset: 2px;
174
+ }
175
+
176
+ .desk-composer-field::placeholder {
177
+ color: var(--desk-muted);
178
+ }
179
+
180
+ @media (prefers-reduced-motion: reduce) {
181
+ .desk-typing-dots i {
182
+ animation: none;
183
+ }
184
+ }
185
+
186
+ /* ── Input bar: one place to type, which reaches the key window ── */
187
+
188
+ .desk-inputbar-scrim {
189
+ position: fixed;
190
+ inset: 0;
191
+ z-index: 1450;
192
+ display: grid;
193
+ justify-items: center;
194
+ align-content: center;
195
+ padding: var(--desk-space-4);
196
+ background: rgb(0 0 0 / 30%);
197
+ animation: desk-fade .14s var(--desk-ease);
198
+ }
199
+
200
+ .desk-inputbar[data-mode="summoned"] {
201
+ animation: desk-alert-in .16s var(--desk-ease);
202
+ }
203
+
204
+ .desk-inputbar {
205
+ box-sizing: border-box;
206
+ width: min(720px, 100%);
207
+ border: 1px solid var(--desk-rule);
208
+ border-radius: 14px;
209
+ background: var(--desk-dock-glass);
210
+ backdrop-filter: blur(28px) saturate(170%);
211
+ -webkit-backdrop-filter: blur(28px) saturate(170%);
212
+ box-shadow: var(--desk-shadow-floating);
213
+ }
214
+
215
+ .desk-inputbar .desk-composer {
216
+ border-top: 0;
217
+ padding: var(--desk-space-2);
218
+ }
219
+
220
+ .desk-inputbar-target {
221
+ display: block;
222
+ padding: 0 var(--desk-space-3) var(--desk-space-2);
223
+ font-family: var(--desk-font);
224
+ font-size: 11px;
225
+ color: var(--desk-muted);
226
+ }
227
+
228
+ .desk-inputbar-target b {
229
+ font-weight: 600;
230
+ color: var(--desk-ink);
231
+ }
@@ -0,0 +1,271 @@
1
+ /* ── Dock ── */
2
+
3
+ .desk-dock {
4
+ box-sizing: border-box;
5
+ display: flex;
6
+ align-items: flex-end;
7
+ gap: 6px;
8
+ padding: 7px 9px;
9
+ max-width: calc(100% - 24px);
10
+ border-radius: 20px;
11
+ background: var(--desk-dock-glass);
12
+ backdrop-filter: blur(28px) saturate(170%);
13
+ -webkit-backdrop-filter: blur(28px) saturate(170%);
14
+ border: 1px solid var(--desk-rule);
15
+ box-shadow: var(--desk-shadow-floating);
16
+ font-family: var(--desk-font);
17
+ color: var(--desk-ink);
18
+ }
19
+
20
+ .desk-dock[data-placement="overlay"] {
21
+ position: absolute;
22
+ left: 50%;
23
+ bottom: 12px;
24
+ z-index: 1000;
25
+ transform: translateX(-50%);
26
+ }
27
+
28
+ .desk-dock-separator {
29
+ flex: none;
30
+ align-self: stretch;
31
+ width: 1px;
32
+ margin: 6px 4px;
33
+ background: var(--desk-rule);
34
+ }
35
+
36
+ .desk-dock-slot {
37
+ position: relative;
38
+ display: flex;
39
+ }
40
+
41
+ .desk-dock-item {
42
+ position: relative;
43
+ flex: none;
44
+ width: var(--desk-dock-size);
45
+ height: var(--desk-dock-size);
46
+ padding: 0;
47
+ display: grid;
48
+ place-items: center;
49
+ border: 1px solid var(--desk-rule);
50
+ border-radius: calc(var(--desk-dock-size) / 4);
51
+ background: var(--desk-dock-icon);
52
+ color: var(--desk-ink);
53
+ cursor: pointer;
54
+ transition: transform .18s var(--desk-ease), margin .18s var(--desk-ease);
55
+ }
56
+
57
+ .desk-dock-item:disabled,
58
+ .desk-dock-item[aria-disabled="true"] {
59
+ opacity: .45;
60
+ cursor: not-allowed;
61
+ }
62
+
63
+ .desk-dock-item:focus-visible,
64
+ .desk-stack-item:focus-visible {
65
+ outline: 2px solid var(--desk-accent);
66
+ outline-offset: 2px;
67
+ }
68
+
69
+ @media (hover: hover) and (pointer: fine) {
70
+ .desk-dock-item:hover:not(:disabled) {
71
+ transform: translateY(-8px) scale(1.14);
72
+ margin: 0 5px;
73
+ }
74
+ }
75
+
76
+ .desk-dock-icon {
77
+ position: relative;
78
+ display: grid;
79
+ place-items: center;
80
+ width: 46%;
81
+ height: 46%;
82
+ }
83
+
84
+ .desk-dock-icon > svg {
85
+ width: 100%;
86
+ height: 100%;
87
+ }
88
+
89
+ .desk-dock-item[data-stack] .desk-dock-icon {
90
+ width: 72%;
91
+ height: 72%;
92
+ }
93
+
94
+ .desk-dock-preview {
95
+ width: 100%;
96
+ height: 100%;
97
+ display: grid;
98
+ grid-template-columns: 1fr 1fr;
99
+ gap: 3px;
100
+ }
101
+
102
+ .desk-dock-preview > span {
103
+ display: grid;
104
+ place-items: center;
105
+ padding: 3px;
106
+ border-radius: 4px;
107
+ background: color-mix(in srgb, var(--desk-ink) 10%, transparent);
108
+ color: var(--desk-muted);
109
+ }
110
+
111
+ .desk-dock-preview svg {
112
+ width: 100%;
113
+ height: 100%;
114
+ }
115
+
116
+ /* A dot for "a window is open", brighter when it has focus. */
117
+ .desk-dock-item[data-running]::after {
118
+ content: "";
119
+ position: absolute;
120
+ left: 50%;
121
+ bottom: -6px;
122
+ width: 4px;
123
+ height: 4px;
124
+ margin-left: -2px;
125
+ border-radius: 50%;
126
+ background: var(--desk-muted);
127
+ }
128
+
129
+ .desk-dock-item[data-focused]::after {
130
+ background: var(--desk-accent);
131
+ }
132
+
133
+ .desk-dock-badge {
134
+ position: absolute;
135
+ top: -5px;
136
+ right: -5px;
137
+ min-width: 18px;
138
+ height: 18px;
139
+ padding: 0 5px;
140
+ box-sizing: border-box;
141
+ display: grid;
142
+ place-items: center;
143
+ border-radius: 9px;
144
+ border: 2px solid var(--desk-surface);
145
+ background: var(--desk-badge);
146
+ color: var(--desk-badge-ink);
147
+ font-size: 10px;
148
+ font-weight: 700;
149
+ font-variant-numeric: tabular-nums;
150
+ line-height: 1;
151
+ }
152
+
153
+ .desk-dock-tip {
154
+ position: absolute;
155
+ bottom: calc(100% + 14px);
156
+ left: 50%;
157
+ transform: translateX(-50%);
158
+ padding: 3px 9px;
159
+ border-radius: 6px;
160
+ border: 1px solid var(--desk-rule);
161
+ background: var(--desk-surface);
162
+ color: var(--desk-ink);
163
+ font-size: 12px;
164
+ white-space: nowrap;
165
+ pointer-events: none;
166
+ opacity: 0;
167
+ transition: opacity .12s;
168
+ }
169
+
170
+ .desk-dock-item:hover .desk-dock-tip,
171
+ .desk-dock-item:focus-visible .desk-dock-tip {
172
+ opacity: 1;
173
+ }
174
+
175
+ .desk-dock-item[aria-expanded="true"] .desk-dock-tip {
176
+ opacity: 0;
177
+ }
178
+
179
+ /* ── Stack: a dock folder, fanned out ── */
180
+
181
+ .desk-stack {
182
+ position: absolute;
183
+ bottom: calc(100% + 18px);
184
+ left: 50%;
185
+ transform: translateX(-50%);
186
+ box-sizing: border-box;
187
+ width: max-content;
188
+ max-width: min(420px, calc(100vw - 32px));
189
+ padding: 12px;
190
+ border-radius: 18px;
191
+ border: 1px solid var(--desk-rule);
192
+ /* It carries labels, so it needs a surface behind them: glass alone let the window under it read through. */
193
+ background: var(--desk-surface);
194
+ backdrop-filter: blur(30px) saturate(160%);
195
+ -webkit-backdrop-filter: blur(30px) saturate(160%);
196
+ box-shadow: var(--desk-shadow-floating);
197
+ animation: desk-pop .18s var(--desk-ease);
198
+ }
199
+
200
+ @keyframes desk-pop {
201
+ from {
202
+ opacity: 0;
203
+ transform: translateX(-50%) translateY(6px) scale(.98);
204
+ }
205
+ }
206
+
207
+ .desk-stack-title {
208
+ margin: 0 0 8px 4px;
209
+ font-size: 11px;
210
+ font-weight: 700;
211
+ letter-spacing: .08em;
212
+ text-transform: uppercase;
213
+ color: var(--desk-muted);
214
+ }
215
+
216
+ .desk-stack-grid {
217
+ display: grid;
218
+ grid-template-columns: repeat(auto-fill, minmax(92px, 1fr));
219
+ width: min(380px, calc(100vw - 56px));
220
+ gap: 6px;
221
+ }
222
+
223
+ .desk-stack-item {
224
+ display: flex;
225
+ flex-direction: column;
226
+ align-items: center;
227
+ gap: 5px;
228
+ padding: 8px 4px;
229
+ border: 0;
230
+ border-radius: 11px;
231
+ background: none;
232
+ color: inherit;
233
+ font: inherit;
234
+ text-align: center;
235
+ cursor: pointer;
236
+ }
237
+
238
+ .desk-stack-item:hover:not(:disabled) {
239
+ background: color-mix(in srgb, var(--desk-ink) 7%, transparent);
240
+ }
241
+
242
+ .desk-stack-item .desk-dock-icon {
243
+ width: 40px;
244
+ height: 40px;
245
+ padding: 10px;
246
+ box-sizing: border-box;
247
+ border-radius: 10px;
248
+ border: 1px solid var(--desk-rule);
249
+ background: var(--desk-dock-icon);
250
+ }
251
+
252
+ .desk-stack-label {
253
+ font-size: 12px;
254
+ font-weight: 560;
255
+ }
256
+
257
+ .desk-stack-description {
258
+ font-size: 10.5px;
259
+ line-height: 1.3;
260
+ color: var(--desk-muted);
261
+ }
262
+
263
+ /* Something carried to the dock: the dock lights up, and a kept item shows where it would go in front. */
264
+ .desk-dock-item[data-desk-drop][data-ready] {
265
+ outline: none;
266
+ background: var(--desk-dock-icon);
267
+ }
268
+
269
+ .desk-dock-item[data-desk-drop][data-over] {
270
+ box-shadow: -6px 0 0 -2px var(--desk-accent);
271
+ }
@@ -0,0 +1,203 @@
1
+ /* ── Menu bar ── */
2
+
3
+ .desk-menubar {
4
+ position: relative;
5
+ z-index: 1100;
6
+ box-sizing: border-box;
7
+ display: flex;
8
+ align-items: center;
9
+ gap: 2px;
10
+ height: 30px;
11
+ padding: 0 10px;
12
+ background: var(--desk-dock-glass);
13
+ backdrop-filter: blur(24px) saturate(160%);
14
+ -webkit-backdrop-filter: blur(24px) saturate(160%);
15
+ border-bottom: 1px solid var(--desk-rule);
16
+ color: var(--desk-ink);
17
+ font-family: var(--desk-font);
18
+ font-size: 13px;
19
+ user-select: none;
20
+ }
21
+
22
+ .desk-menubar-leading,
23
+ .desk-menubar-trailing {
24
+ display: flex;
25
+ align-items: center;
26
+ gap: 8px;
27
+ padding: 0 6px;
28
+ }
29
+
30
+ .desk-menubar-leading {
31
+ font-weight: 700;
32
+ }
33
+
34
+ .desk-menubar-trailing {
35
+ color: var(--desk-muted);
36
+ font-size: 12px;
37
+ font-variant-numeric: tabular-nums;
38
+ }
39
+
40
+ .desk-menubar-spacer {
41
+ flex: 1;
42
+ }
43
+
44
+ .desk-menubar-slot {
45
+ position: relative;
46
+ }
47
+
48
+ .desk-menubar-title {
49
+ display: flex;
50
+ align-items: center;
51
+ gap: 6px;
52
+ height: 22px;
53
+ padding: 0 9px;
54
+ border: 0;
55
+ border-radius: 6px;
56
+ background: none;
57
+ color: inherit;
58
+ font: inherit;
59
+ white-space: nowrap;
60
+ cursor: default;
61
+ }
62
+
63
+ .desk-menubar-title[data-emphasis] {
64
+ font-weight: 700;
65
+ }
66
+
67
+ .desk-menubar-title:hover,
68
+ .desk-menubar-title[aria-expanded="true"] {
69
+ background: color-mix(in srgb, var(--desk-ink) 12%, transparent);
70
+ }
71
+
72
+ .desk-menubar-title:focus-visible {
73
+ outline: 2px solid var(--desk-accent);
74
+ outline-offset: -2px;
75
+ }
76
+
77
+ .desk-menubar-title svg {
78
+ width: 15px;
79
+ height: 15px;
80
+ }
81
+
82
+ /* A context menu is the same menu, opened where the pointer is rather than under a title. */
83
+ .desk-context-menu {
84
+ position: fixed;
85
+ z-index: 1300;
86
+ outline: none;
87
+ }
88
+
89
+ .desk-menubar-slot[data-align="end"] .desk-menu {
90
+ left: auto;
91
+ right: 0;
92
+ }
93
+
94
+ .desk-menu {
95
+ position: absolute;
96
+ top: calc(100% + 4px);
97
+ left: 0;
98
+ box-sizing: border-box;
99
+ min-width: 220px;
100
+ max-width: min(360px, calc(100vw - 24px));
101
+ padding: 5px;
102
+ border-radius: 10px;
103
+ border: 1px solid var(--desk-rule);
104
+ /* Opaque, like every other popup. A menu sits inside the menu bar's own backdrop blur, and a nested
105
+ backdrop-filter does not blur what is behind the bar, so a translucent menu let window text read through. */
106
+ background: var(--desk-surface);
107
+ box-shadow: var(--desk-shadow-floating);
108
+ animation: desk-menu-in .12s var(--desk-ease);
109
+ }
110
+
111
+ @keyframes desk-menu-in {
112
+ from {
113
+ opacity: 0;
114
+ transform: translateY(-3px);
115
+ }
116
+ }
117
+
118
+ .desk-menu-item {
119
+ display: flex;
120
+ align-items: center;
121
+ gap: 6px;
122
+ min-height: 24px;
123
+ padding: 2px 10px 2px 4px;
124
+ border-radius: 5px;
125
+ cursor: default;
126
+ }
127
+
128
+ .desk-menu-item[data-active] {
129
+ background: var(--desk-accent);
130
+ color: #fff;
131
+ }
132
+
133
+ .desk-menu-item[aria-disabled="true"] {
134
+ color: var(--desk-muted);
135
+ opacity: .55;
136
+ }
137
+
138
+ .desk-menu-check {
139
+ flex: none;
140
+ width: 14px;
141
+ text-align: center;
142
+ font-size: 12px;
143
+ }
144
+
145
+ .desk-menu-label {
146
+ flex: 1;
147
+ min-width: 0;
148
+ white-space: nowrap;
149
+ overflow: hidden;
150
+ text-overflow: ellipsis;
151
+ }
152
+
153
+ .desk-menu-detail,
154
+ .desk-menu-shortcut {
155
+ flex: none;
156
+ color: var(--desk-muted);
157
+ font-size: 12px;
158
+ }
159
+
160
+ .desk-menu-shortcut {
161
+ margin-left: 18px;
162
+ font-family: var(--desk-font);
163
+ letter-spacing: .04em;
164
+ }
165
+
166
+ .desk-menu-item[data-active] .desk-menu-detail,
167
+ .desk-menu-item[data-active] .desk-menu-shortcut {
168
+ color: rgb(255 255 255 / 80%);
169
+ }
170
+
171
+ .desk-menu-separator {
172
+ height: 1px;
173
+ margin: 5px 8px;
174
+ background: var(--desk-rule);
175
+ }
176
+
177
+ .desk-menu-header {
178
+ padding: 5px 10px 2px 24px;
179
+ font-size: 11px;
180
+ font-weight: 600;
181
+ color: var(--desk-muted);
182
+ }
183
+
184
+ @media (max-width: 640px) {
185
+ .desk-stage {
186
+ grid-template-columns: minmax(0, 1fr);
187
+ grid-auto-rows: minmax(320px, auto);
188
+ overflow-y: auto;
189
+ }
190
+ }
191
+
192
+ @media (prefers-reduced-motion: reduce) {
193
+ .desk-window,
194
+ .desk-dock-item,
195
+ .desk-dock-tip {
196
+ transition: none;
197
+ }
198
+
199
+ .desk-stack,
200
+ .desk-menu {
201
+ animation: none;
202
+ }
203
+ }