rift-ds 1.2.0 → 1.4.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.
- package/README.md +2 -2
- package/components/Attachment/Attachment.css +1036 -0
- package/components/Attachment/AttachmentDropZone.d.ts +39 -0
- package/components/Attachment/AttachmentDropZone.js +76 -0
- package/components/Attachment/AttachmentGroup.d.ts +60 -0
- package/components/Attachment/AttachmentGroup.js +179 -0
- package/components/Attachment/AttachmentTile.d.ts +80 -0
- package/components/Attachment/AttachmentTile.js +143 -0
- package/components/Attachment/AttachmentViewer.d.ts +66 -0
- package/components/Attachment/AttachmentViewer.js +215 -0
- package/components/Attachment/fileTypes.d.ts +101 -0
- package/components/Attachment/fileTypes.js +182 -0
- package/components/Attachment/typeMark.d.ts +11 -0
- package/components/Attachment/typeMark.js +51 -0
- package/components/Attachment/useAttachments.d.ts +65 -0
- package/components/Attachment/useAttachments.js +201 -0
- package/components/Chart/BarChart.js +1 -1
- package/components/Chart/ComboChart.js +1 -1
- package/components/Chart/Treemap.js +83 -6
- package/components/ChatMessage/ChatMessage.css +24 -0
- package/components/ChatMessage/ChatMessage.d.ts +6 -0
- package/components/ChatMessage/ChatMessage.js +8 -5
- package/components/ColorPicker/ColorPicker.js +1 -1
- package/components/Composer/Composer.css +140 -5
- package/components/Composer/Composer.d.ts +71 -14
- package/components/Composer/Composer.js +204 -11
- package/components/DatePicker/DatePicker.css +1 -1
- package/components/DocumentChip/DocumentChip.d.ts +7 -5
- package/components/EventCalendar/EventCalendar.css +2 -2
- package/components/FileInput/FileInput.css +1 -1
- package/components/FileInput/FileInput.js +1 -7
- package/components/Globe/Globe.d.ts +5 -3
- package/components/Globe/Globe.js +18 -2
- package/components/Inspector/Inspector.css +108 -3
- package/components/Inspector/InspectorColorPicker.d.ts +43 -0
- package/components/Inspector/InspectorColorPicker.js +51 -0
- package/components/Instructions/Instructions.css +4 -4
- package/components/MessageCard/MessageCard.d.ts +1 -1
- package/components/Prose/Prose.css +27 -0
- package/components/Sparkline/Sparkline.css +2 -2
- package/components/Spinner/Spinner.css +1 -1
- package/components/Timeline/Timeline.css +1 -1
- package/components/WorldMap/land.d.ts +1 -1
- package/components/registry.json +48 -3
- package/components/registry.json.d.ts +48 -3
- package/components/registry.json.js +1 -1
- package/index.d.ts +5 -0
- package/index.js +21 -0
- package/package.json +9 -1
- package/tokens/motion.d.ts +2 -0
- package/tokens/motion.js +2 -0
- package/tokens/presets/contrast.css +2 -4
- package/tokens/presets/coral.css +2 -4
- package/tokens/presets/forest.css +2 -4
- package/tokens/presets/gold.css +4 -4
- package/tokens/presets/mono.css +0 -2
- package/tokens/presets/pink.css +4 -4
- package/tokens/presets/terminal.css +5 -4
- package/tokens/presets/violet.css +2 -4
- package/tokens/presets/warm.css +3 -4
- package/tokens/presets/zest.css +2 -4
- package/tokens/registry.json +5 -0
- package/tokens/registry.json.d.ts +5 -0
- package/tokens/registry.json.js +1 -1
- package/tokens/tokens-dark.css +14 -5
- package/tokens/tokens-light.css +16 -2
- package/tokens/tokens-motion.css +2 -0
- package/tokens/tokens-primitives.css +10 -0
|
@@ -0,0 +1,1036 @@
|
|
|
1
|
+
/* ============================================
|
|
2
|
+
ATTACHMENT FAMILY
|
|
3
|
+
AttachmentTile: one file as a square.
|
|
4
|
+
AttachmentGroup: the files on a sent message.
|
|
5
|
+
AttachmentViewer: the preview dialog.
|
|
6
|
+
AttachmentDropZone: the drop target over a chat.
|
|
7
|
+
One stylesheet, shared by every member.
|
|
8
|
+
============================================ */
|
|
9
|
+
|
|
10
|
+
/* ============================================
|
|
11
|
+
TYPE MARK — what kind of file this is
|
|
12
|
+
Shared by the tile and the viewer. Every mark, and every glyph a tile
|
|
13
|
+
swaps it for (spinner, alert, unavailable), fills one square box of the
|
|
14
|
+
same edge, so a file changing state never moves or resizes anything.
|
|
15
|
+
============================================ */
|
|
16
|
+
|
|
17
|
+
.ds-attachment-mark {
|
|
18
|
+
/* Consumer and parent hook: the square's edge */
|
|
19
|
+
--ds-attachment-mark-edge: var(--ds-attachment-mark-size, var(--icon-size-800));
|
|
20
|
+
|
|
21
|
+
flex: none;
|
|
22
|
+
color: var(--color-text-secondary);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.ds-attachment-mark--pdf {
|
|
26
|
+
color: var(--color-file-pdf);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.ds-attachment-mark--spreadsheet {
|
|
30
|
+
color: var(--color-file-spreadsheet);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.ds-attachment-mark--document {
|
|
34
|
+
color: var(--color-file-document);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
.ds-attachment-mark--presentation {
|
|
38
|
+
color: var(--color-file-presentation);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/* ---------- Icon form: one square ---------- */
|
|
42
|
+
|
|
43
|
+
.ds-attachment-mark--icon {
|
|
44
|
+
display: inline-flex;
|
|
45
|
+
align-items: center;
|
|
46
|
+
justify-content: center;
|
|
47
|
+
width: var(--ds-attachment-mark-edge);
|
|
48
|
+
height: var(--ds-attachment-mark-edge);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.ds-attachment-mark__glyph {
|
|
52
|
+
display: block;
|
|
53
|
+
width: 100%;
|
|
54
|
+
height: 100%;
|
|
55
|
+
overflow: visible;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/* The folded corner: a darker flap, as on the icons these formats wear in
|
|
59
|
+
the wild. The scrim over the silhouette deepens whichever colour is
|
|
60
|
+
beneath it, so no second colour per format is needed. */
|
|
61
|
+
.ds-attachment-mark__fold {
|
|
62
|
+
fill: var(--color-scrim);
|
|
63
|
+
opacity: 0.45;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/* The lettering under the page. */
|
|
67
|
+
/* ds-allow(typography): lettering inside an icon. The size and weight are
|
|
68
|
+
in the glyph's own 32-unit drawing space and scale with the mark, like a
|
|
69
|
+
stroke width; they are not a step on the type scale. */
|
|
70
|
+
.ds-attachment-mark__letters {
|
|
71
|
+
/* A text colour, never the format colour: the letters have to be read,
|
|
72
|
+
and a presentation's yellow cannot carry text on a light tile */
|
|
73
|
+
fill: var(--color-text-secondary);
|
|
74
|
+
font-family: var(--font-family-body);
|
|
75
|
+
font-size: 10px;
|
|
76
|
+
font-weight: 800;
|
|
77
|
+
letter-spacing: 0.04em;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/* A neutral file's extension, as a chip centred in the same square. It may
|
|
81
|
+
run wider than the square (a five-letter extension) but never taller. */
|
|
82
|
+
.ds-attachment-mark__chip,
|
|
83
|
+
.ds-attachment-mark--badge {
|
|
84
|
+
display: inline-flex;
|
|
85
|
+
align-items: center;
|
|
86
|
+
padding: var(--padding-050) var(--padding-150);
|
|
87
|
+
border-radius: var(--radius-100);
|
|
88
|
+
background-color: var(--color-bg-container-secondary);
|
|
89
|
+
font-family: var(--font-caption-family);
|
|
90
|
+
font-size: var(--font-caption-size);
|
|
91
|
+
font-weight: var(--font-overline-weight);
|
|
92
|
+
line-height: var(--font-caption-line-height);
|
|
93
|
+
letter-spacing: var(--font-caption-letter-spacing);
|
|
94
|
+
text-transform: uppercase;
|
|
95
|
+
white-space: nowrap;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/* ---------- Badge form: the label alone, over a preview's corner ---------- */
|
|
99
|
+
|
|
100
|
+
.ds-attachment-mark--badge {
|
|
101
|
+
gap: var(--gap-100);
|
|
102
|
+
background-color: var(--color-bg-container-primary);
|
|
103
|
+
/* The label reads in a text colour; the format's own colour rides in
|
|
104
|
+
the dot beside it */
|
|
105
|
+
color: var(--color-text-secondary);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
.ds-attachment-mark__dot {
|
|
109
|
+
flex: none;
|
|
110
|
+
width: var(--gap-200);
|
|
111
|
+
height: var(--gap-200);
|
|
112
|
+
border-radius: var(--radius-050);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.ds-attachment-mark--pdf .ds-attachment-mark__dot {
|
|
116
|
+
background-color: var(--color-file-pdf);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
.ds-attachment-mark--spreadsheet .ds-attachment-mark__dot {
|
|
120
|
+
background-color: var(--color-file-spreadsheet);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
.ds-attachment-mark--document .ds-attachment-mark__dot {
|
|
124
|
+
background-color: var(--color-file-document);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.ds-attachment-mark--presentation .ds-attachment-mark__dot {
|
|
128
|
+
background-color: var(--color-file-presentation);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/* ============================================
|
|
132
|
+
TILE
|
|
133
|
+
============================================ */
|
|
134
|
+
|
|
135
|
+
.ds-attachment-tile {
|
|
136
|
+
/* Consumer and parent hooks. A parent that seats tiles inside its own
|
|
137
|
+
rounded shell (Composer's tray) repoints the radius so the corners
|
|
138
|
+
stay concentric; the size is the one number that sets the whole tile.
|
|
139
|
+
The edge lengths are raw values: a tile is a fixed object like an
|
|
140
|
+
avatar or an icon button, not a step on the spacing scale. */
|
|
141
|
+
--ds-attachment-tile-edge: var(--ds-attachment-tile-size, 136px);
|
|
142
|
+
--ds-attachment-tile-corner: var(--ds-attachment-tile-radius, var(--radius-400));
|
|
143
|
+
/* Border indirection, so the error state repoints one variable */
|
|
144
|
+
--ds-attachment-tile-border: var(--color-bg-container-border);
|
|
145
|
+
/* The remove button's diameter; its offset derives from it */
|
|
146
|
+
--ds-attachment-tile-remove-size: 24px;
|
|
147
|
+
|
|
148
|
+
position: relative;
|
|
149
|
+
flex: none;
|
|
150
|
+
box-sizing: border-box;
|
|
151
|
+
display: inline-flex;
|
|
152
|
+
width: var(--ds-attachment-tile-edge);
|
|
153
|
+
height: var(--ds-attachment-tile-edge);
|
|
154
|
+
border: var(--border-025) solid var(--ds-attachment-tile-border);
|
|
155
|
+
border-radius: var(--ds-attachment-tile-corner);
|
|
156
|
+
background-color: var(--color-bg-container-primary);
|
|
157
|
+
color: var(--color-text-primary);
|
|
158
|
+
transition: border-color var(--motion-duration-base) var(--motion-ease-standard);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.ds-attachment-tile--compact {
|
|
162
|
+
--ds-attachment-tile-edge: var(--ds-attachment-tile-size, 96px);
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
/* ---------- State ---------- */
|
|
166
|
+
|
|
167
|
+
.ds-attachment-tile--error {
|
|
168
|
+
--ds-attachment-tile-border: var(--color-status-error-border);
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/* ============================================
|
|
172
|
+
BODY — the whole square; a button when clickable
|
|
173
|
+
============================================ */
|
|
174
|
+
|
|
175
|
+
.ds-attachment-tile__body {
|
|
176
|
+
position: relative;
|
|
177
|
+
box-sizing: border-box;
|
|
178
|
+
display: flex;
|
|
179
|
+
align-items: center;
|
|
180
|
+
justify-content: center;
|
|
181
|
+
width: 100%;
|
|
182
|
+
height: 100%;
|
|
183
|
+
min-width: 0;
|
|
184
|
+
margin: 0;
|
|
185
|
+
padding: var(--padding-300);
|
|
186
|
+
border: none;
|
|
187
|
+
/* Inside the border, so the inner corner is the outer one less the line */
|
|
188
|
+
border-radius: calc(var(--ds-attachment-tile-corner) - var(--border-025));
|
|
189
|
+
background: none;
|
|
190
|
+
font: inherit;
|
|
191
|
+
letter-spacing: inherit;
|
|
192
|
+
color: inherit;
|
|
193
|
+
text-align: center;
|
|
194
|
+
/* Full-bleed content is clipped to the tile's own corner */
|
|
195
|
+
overflow: hidden;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
button.ds-attachment-tile__body {
|
|
199
|
+
cursor: pointer;
|
|
200
|
+
transition: background-color var(--motion-duration-base) var(--motion-ease-standard);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
/* Hover: a pressable tile lifts its border and warms its surface, and a
|
|
204
|
+
picture brightens under a light wash. The same answer on every tile, so
|
|
205
|
+
the grid reads as one set of controls. */
|
|
206
|
+
button.ds-attachment-tile__body:hover {
|
|
207
|
+
background-color: var(--color-bg-container-secondary);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
.ds-attachment-tile--clickable:hover {
|
|
211
|
+
--ds-attachment-tile-border: var(--color-text-tertiary);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
.ds-attachment-tile--clickable.ds-attachment-tile--error:hover {
|
|
215
|
+
--ds-attachment-tile-border: var(--color-status-error-border);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
.ds-attachment-tile__preview,
|
|
219
|
+
.ds-attachment-group__single-image {
|
|
220
|
+
transition:
|
|
221
|
+
opacity var(--motion-duration-base) var(--motion-ease-standard),
|
|
222
|
+
transform var(--motion-duration-slow) var(--motion-ease-emphasized);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
button.ds-attachment-tile__body:hover .ds-attachment-tile__preview,
|
|
226
|
+
button.ds-attachment-group__single:hover .ds-attachment-group__single-image {
|
|
227
|
+
opacity: 0.88;
|
|
228
|
+
transform: scale(1.03);
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/* Full-bleed tiles give the whole square to their content */
|
|
232
|
+
.ds-attachment-tile--preview .ds-attachment-tile__body,
|
|
233
|
+
.ds-attachment-tile--excerpt .ds-attachment-tile__body {
|
|
234
|
+
padding: 0;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/* ============================================
|
|
238
|
+
STACK — type mark, name, secondary line
|
|
239
|
+
============================================ */
|
|
240
|
+
|
|
241
|
+
.ds-attachment-tile__stack {
|
|
242
|
+
display: flex;
|
|
243
|
+
flex-direction: column;
|
|
244
|
+
align-items: center;
|
|
245
|
+
gap: var(--gap-050);
|
|
246
|
+
width: 100%;
|
|
247
|
+
min-width: 0;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
.ds-attachment-tile__mark {
|
|
251
|
+
display: inline-flex;
|
|
252
|
+
align-items: center;
|
|
253
|
+
justify-content: center;
|
|
254
|
+
/* One square seat for every mark: the type mark, the spinner and the
|
|
255
|
+
state glyphs all fill it exactly */
|
|
256
|
+
width: var(--ds-attachment-tile-mark, var(--icon-size-800));
|
|
257
|
+
height: var(--ds-attachment-tile-mark, var(--icon-size-800));
|
|
258
|
+
margin-bottom: var(--gap-100);
|
|
259
|
+
/* The chip of a long extension may run wider than its seat */
|
|
260
|
+
overflow: visible;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
.ds-attachment-tile__mark > * {
|
|
264
|
+
--ds-attachment-mark-size: var(--ds-attachment-tile-mark, var(--icon-size-800));
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
.ds-attachment-tile--compact {
|
|
268
|
+
--ds-attachment-tile-mark: var(--icon-size-600);
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
.ds-attachment-tile--compact .ds-attachment-tile__mark {
|
|
272
|
+
margin-bottom: var(--gap-050);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
/* ---------- State glyphs ---------- */
|
|
276
|
+
|
|
277
|
+
.ds-attachment-tile__state {
|
|
278
|
+
--icon-size: var(--ds-attachment-tile-mark, var(--icon-size-800));
|
|
279
|
+
color: var(--color-icon-primary);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
.ds-attachment-tile--error .ds-attachment-tile__state {
|
|
283
|
+
color: var(--color-status-error-icon);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
.ds-attachment-tile__spinner {
|
|
287
|
+
display: inline-flex;
|
|
288
|
+
width: var(--ds-attachment-tile-mark, var(--icon-size-800));
|
|
289
|
+
height: var(--ds-attachment-tile-mark, var(--icon-size-800));
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
.ds-attachment-tile__spinner svg {
|
|
293
|
+
width: 100%;
|
|
294
|
+
height: 100%;
|
|
295
|
+
animation: ds-attachment-tile-spin var(--motion-duration-loop-spin) var(--motion-ease-linear)
|
|
296
|
+
infinite;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
.ds-attachment-tile__spinner-track {
|
|
300
|
+
stroke: var(--color-bg-container-tertiary);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
.ds-attachment-tile__spinner-arc {
|
|
304
|
+
stroke: var(--color-text-secondary);
|
|
305
|
+
/* A quarter of the ring (circumference 56.5 at r=9), the rest gap. The
|
|
306
|
+
ring is drawn to a state glyph's own circle: same diameter, same
|
|
307
|
+
stroke, so the spinner and the alert beside it weigh the same. */
|
|
308
|
+
stroke-dasharray: 14 42.5;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
@keyframes ds-attachment-tile-spin {
|
|
312
|
+
from {
|
|
313
|
+
transform: rotate(0deg);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
to {
|
|
317
|
+
transform: rotate(360deg);
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
/* ---------- Name: middle truncation ----------
|
|
322
|
+
Two halves on one line. The head gives way and ellipsizes; the tail (the
|
|
323
|
+
end of the stem plus the extension) never shrinks, so a long name still
|
|
324
|
+
says what the file is. Pure layout: no measuring, no script. */
|
|
325
|
+
|
|
326
|
+
.ds-attachment-tile__name {
|
|
327
|
+
display: flex;
|
|
328
|
+
justify-content: center;
|
|
329
|
+
max-width: 100%;
|
|
330
|
+
min-width: 0;
|
|
331
|
+
font-family: var(--font-paragraph-sm-family);
|
|
332
|
+
font-size: var(--font-paragraph-sm-size);
|
|
333
|
+
font-weight: var(--font-paragraph-sm-weight);
|
|
334
|
+
line-height: var(--font-paragraph-sm-line-height);
|
|
335
|
+
letter-spacing: var(--font-paragraph-sm-letter-spacing);
|
|
336
|
+
color: var(--color-text-primary);
|
|
337
|
+
/* Spaces at the cut are part of the name */
|
|
338
|
+
white-space: pre;
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
.ds-attachment-tile__name-head {
|
|
342
|
+
flex: 0 1 auto;
|
|
343
|
+
min-width: 0;
|
|
344
|
+
overflow: hidden;
|
|
345
|
+
text-overflow: ellipsis;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
.ds-attachment-tile__name-tail {
|
|
349
|
+
flex: none;
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
.ds-attachment-tile__meta {
|
|
353
|
+
max-width: 100%;
|
|
354
|
+
overflow: hidden;
|
|
355
|
+
text-overflow: ellipsis;
|
|
356
|
+
white-space: nowrap;
|
|
357
|
+
font-family: var(--font-caption-family);
|
|
358
|
+
font-size: var(--font-caption-size);
|
|
359
|
+
font-weight: var(--font-caption-weight);
|
|
360
|
+
line-height: var(--font-caption-line-height);
|
|
361
|
+
letter-spacing: var(--font-caption-letter-spacing);
|
|
362
|
+
font-variant-numeric: tabular-nums;
|
|
363
|
+
color: var(--color-text-tertiary);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
.ds-attachment-tile--error .ds-attachment-tile__meta {
|
|
367
|
+
color: var(--color-status-error-icon);
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/* ============================================
|
|
371
|
+
FULL BLEED — a preview or a pasted excerpt
|
|
372
|
+
============================================ */
|
|
373
|
+
|
|
374
|
+
.ds-attachment-tile__preview {
|
|
375
|
+
display: block;
|
|
376
|
+
width: 100%;
|
|
377
|
+
height: 100%;
|
|
378
|
+
object-fit: cover;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.ds-attachment-tile__excerpt {
|
|
382
|
+
box-sizing: border-box;
|
|
383
|
+
display: block;
|
|
384
|
+
width: 100%;
|
|
385
|
+
height: 100%;
|
|
386
|
+
padding: var(--padding-200) var(--padding-300);
|
|
387
|
+
overflow: hidden;
|
|
388
|
+
font-family: var(--font-caption-family);
|
|
389
|
+
font-size: var(--font-caption-size);
|
|
390
|
+
font-weight: var(--font-caption-weight);
|
|
391
|
+
line-height: var(--font-caption-line-height);
|
|
392
|
+
letter-spacing: var(--font-caption-letter-spacing);
|
|
393
|
+
color: var(--color-text-secondary);
|
|
394
|
+
text-align: left;
|
|
395
|
+
white-space: pre-wrap;
|
|
396
|
+
overflow-wrap: anywhere;
|
|
397
|
+
/* The text fades out toward the foot instead of being cut mid-line */
|
|
398
|
+
/* ds-allow(color): mask luminance keying — the #000 paints alpha coverage
|
|
399
|
+
for the fade, not a theme colour */
|
|
400
|
+
mask-image: linear-gradient(to bottom, #000 45%, transparent 92%);
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/* The type mark over a full-bleed tile's bottom-left corner. It sits on a
|
|
404
|
+
plate of the tile surface so it reads over any picture. */
|
|
405
|
+
.ds-attachment-tile__corner {
|
|
406
|
+
position: absolute;
|
|
407
|
+
left: var(--padding-150);
|
|
408
|
+
bottom: var(--padding-150);
|
|
409
|
+
display: inline-flex;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
/* ============================================
|
|
413
|
+
REMOVE — a small circle straddling the corner
|
|
414
|
+
============================================ */
|
|
415
|
+
|
|
416
|
+
.ds-attachment-tile__remove {
|
|
417
|
+
position: absolute;
|
|
418
|
+
/* A third of the button hangs outside the tile, as the corner control of
|
|
419
|
+
a removable thumbnail does on every platform */
|
|
420
|
+
top: calc(var(--ds-attachment-tile-remove-size) / -3);
|
|
421
|
+
right: calc(var(--ds-attachment-tile-remove-size) / -3);
|
|
422
|
+
display: inline-flex;
|
|
423
|
+
align-items: center;
|
|
424
|
+
justify-content: center;
|
|
425
|
+
width: var(--ds-attachment-tile-remove-size);
|
|
426
|
+
height: var(--ds-attachment-tile-remove-size);
|
|
427
|
+
margin: 0;
|
|
428
|
+
padding: 0;
|
|
429
|
+
border: var(--border-025) solid var(--color-bg-container-border);
|
|
430
|
+
border-radius: var(--radius-pill);
|
|
431
|
+
background-color: var(--color-bg-container-primary);
|
|
432
|
+
color: var(--color-text-secondary);
|
|
433
|
+
cursor: pointer;
|
|
434
|
+
/* Opacity, never visibility: a hidden button would leave the tab order
|
|
435
|
+
and a keyboard user could never reveal it (ChatMessage's actions row
|
|
436
|
+
owns the same rule) */
|
|
437
|
+
opacity: 0;
|
|
438
|
+
transition:
|
|
439
|
+
opacity var(--motion-duration-fast) var(--motion-ease-standard),
|
|
440
|
+
color var(--motion-duration-base) var(--motion-ease-standard),
|
|
441
|
+
background-color var(--motion-duration-base) var(--motion-ease-standard);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
.ds-attachment-tile__remove .material-symbols-rounded {
|
|
445
|
+
/* ds-allow(icon-size): a 16px close glyph inside the 24px remove circle,
|
|
446
|
+
one step under the scale's 20px floor */
|
|
447
|
+
--icon-size: 16px;
|
|
448
|
+
color: inherit;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
.ds-attachment-tile:hover .ds-attachment-tile__remove,
|
|
452
|
+
.ds-attachment-tile:focus-within .ds-attachment-tile__remove,
|
|
453
|
+
.ds-attachment-tile--error .ds-attachment-tile__remove {
|
|
454
|
+
opacity: 1;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
/* Touch has no hover to reveal it */
|
|
458
|
+
@media (hover: none) {
|
|
459
|
+
.ds-attachment-tile__remove {
|
|
460
|
+
opacity: 1;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
.ds-attachment-tile__remove:hover {
|
|
465
|
+
background-color: var(--color-bg-container-secondary);
|
|
466
|
+
color: var(--color-text-primary);
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
.ds-attachment-tile__remove:disabled {
|
|
470
|
+
opacity: 0.4;
|
|
471
|
+
cursor: not-allowed;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
/* ============================================
|
|
475
|
+
FOCUS
|
|
476
|
+
============================================ */
|
|
477
|
+
|
|
478
|
+
button.ds-attachment-tile__body:focus-visible,
|
|
479
|
+
.ds-attachment-tile__remove:focus-visible {
|
|
480
|
+
outline: 2px solid var(--color-action-primary-bg);
|
|
481
|
+
outline-offset: 2px;
|
|
482
|
+
}
|
|
483
|
+
|
|
484
|
+
/* ============================================
|
|
485
|
+
VISUALLY HIDDEN
|
|
486
|
+
============================================ */
|
|
487
|
+
|
|
488
|
+
.ds-attachment-tile__sr-only,
|
|
489
|
+
.ds-attachment-group__sr-only {
|
|
490
|
+
position: absolute;
|
|
491
|
+
width: 1px;
|
|
492
|
+
height: 1px;
|
|
493
|
+
padding: 0;
|
|
494
|
+
margin: -1px;
|
|
495
|
+
overflow: hidden;
|
|
496
|
+
clip: rect(0, 0, 0, 0);
|
|
497
|
+
white-space: nowrap;
|
|
498
|
+
border: 0;
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/* ============================================
|
|
502
|
+
REDUCED MOTION
|
|
503
|
+
The global guard collapses the spin to a still arc, which still reads as
|
|
504
|
+
"in progress" beside the words under it.
|
|
505
|
+
============================================ */
|
|
506
|
+
|
|
507
|
+
@media (prefers-reduced-motion: reduce) {
|
|
508
|
+
.ds-attachment-tile__spinner svg {
|
|
509
|
+
animation: none;
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
|
|
513
|
+
/* ============================================
|
|
514
|
+
GROUP — the files on a sent message
|
|
515
|
+
============================================ */
|
|
516
|
+
|
|
517
|
+
.ds-attachment-group {
|
|
518
|
+
display: flex;
|
|
519
|
+
flex-direction: column;
|
|
520
|
+
align-items: flex-start;
|
|
521
|
+
gap: var(--gap-200);
|
|
522
|
+
/* The full width of whatever holds it, so the grid can ask how much room
|
|
523
|
+
it has (the container query below); `align` still places the content */
|
|
524
|
+
width: 100%;
|
|
525
|
+
min-width: 0;
|
|
526
|
+
container-type: inline-size;
|
|
527
|
+
}
|
|
528
|
+
|
|
529
|
+
.ds-attachment-group--end {
|
|
530
|
+
align-items: flex-end;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
/* ---------- Grid ---------- */
|
|
534
|
+
|
|
535
|
+
.ds-attachment-group__grid {
|
|
536
|
+
display: flex;
|
|
537
|
+
flex-wrap: wrap;
|
|
538
|
+
gap: var(--gap-200);
|
|
539
|
+
margin: 0;
|
|
540
|
+
padding: 0;
|
|
541
|
+
list-style: none;
|
|
542
|
+
max-width: 100%;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
.ds-attachment-group--end .ds-attachment-group__grid {
|
|
546
|
+
justify-content: flex-end;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
.ds-attachment-group__cell {
|
|
550
|
+
display: flex;
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
/* Four cells that cannot share a row would wrap three and one, which reads
|
|
554
|
+
as a mistake. Below the width four tiles need, they sit two by two. The
|
|
555
|
+
thresholds restate the default tile edges (136px, 96px compact) and the
|
|
556
|
+
grid gap, because a container query cannot read a custom property; a
|
|
557
|
+
host that resizes the tiles gets the plain wrap. */
|
|
558
|
+
@container (max-width: 567px) {
|
|
559
|
+
.ds-attachment-group--default .ds-attachment-group__grid[data-cells='4'] {
|
|
560
|
+
max-width: calc(2 * var(--ds-attachment-tile-size, 136px) + var(--gap-200));
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
@container (max-width: 407px) {
|
|
565
|
+
.ds-attachment-group--compact .ds-attachment-group__grid[data-cells='4'] {
|
|
566
|
+
max-width: calc(2 * var(--ds-attachment-tile-size, 96px) + var(--gap-200));
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/* The "+N" cell: the next file, dimmed under a scrim that carries the
|
|
571
|
+
count. The button is the whole cell; the tile beneath is only a picture. */
|
|
572
|
+
.ds-attachment-group__cell--more {
|
|
573
|
+
position: relative;
|
|
574
|
+
}
|
|
575
|
+
|
|
576
|
+
.ds-attachment-group__peek {
|
|
577
|
+
display: flex;
|
|
578
|
+
pointer-events: none;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
.ds-attachment-group__more {
|
|
582
|
+
position: absolute;
|
|
583
|
+
inset: 0;
|
|
584
|
+
display: inline-flex;
|
|
585
|
+
align-items: center;
|
|
586
|
+
justify-content: center;
|
|
587
|
+
margin: 0;
|
|
588
|
+
padding: 0;
|
|
589
|
+
border: none;
|
|
590
|
+
border-radius: var(--ds-attachment-tile-radius, var(--radius-400));
|
|
591
|
+
background-color: var(--color-scrim);
|
|
592
|
+
font-family: var(--font-title-body-family);
|
|
593
|
+
font-size: var(--font-title-body-size);
|
|
594
|
+
font-weight: var(--font-title-body-weight);
|
|
595
|
+
line-height: var(--font-title-body-line-height);
|
|
596
|
+
letter-spacing: var(--font-title-body-letter-spacing);
|
|
597
|
+
font-variant-numeric: tabular-nums;
|
|
598
|
+
/* ds-allow(color): on-scrim text. The scrim is dark in both themes, so
|
|
599
|
+
its label lives in scrim-world, not page-world (Lightbox's caption owns
|
|
600
|
+
the same rule) */
|
|
601
|
+
color: #ffffff;
|
|
602
|
+
cursor: pointer;
|
|
603
|
+
transition: opacity var(--motion-duration-base) var(--motion-ease-standard);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
.ds-attachment-group__more:hover {
|
|
607
|
+
opacity: 0.88;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
/* "Show fewer": a quiet text button under the expanded grid */
|
|
611
|
+
.ds-attachment-group__less {
|
|
612
|
+
margin: 0;
|
|
613
|
+
padding: var(--padding-050) var(--padding-200);
|
|
614
|
+
border: none;
|
|
615
|
+
border-radius: var(--radius-pill);
|
|
616
|
+
background: none;
|
|
617
|
+
font-family: var(--font-paragraph-sm-emphasis-family);
|
|
618
|
+
font-size: var(--font-paragraph-sm-emphasis-size);
|
|
619
|
+
font-weight: var(--font-paragraph-sm-emphasis-weight);
|
|
620
|
+
line-height: var(--font-paragraph-sm-emphasis-line-height);
|
|
621
|
+
letter-spacing: var(--font-paragraph-sm-emphasis-letter-spacing);
|
|
622
|
+
color: var(--color-text-secondary);
|
|
623
|
+
cursor: pointer;
|
|
624
|
+
transition:
|
|
625
|
+
background-color var(--motion-duration-base) var(--motion-ease-standard),
|
|
626
|
+
color var(--motion-duration-base) var(--motion-ease-standard);
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
.ds-attachment-group__less:hover {
|
|
630
|
+
background-color: var(--color-bg-container-secondary);
|
|
631
|
+
color: var(--color-text-primary);
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
/* ---------- Single image: its own shape, not a square ---------- */
|
|
635
|
+
|
|
636
|
+
.ds-attachment-group__single {
|
|
637
|
+
position: relative;
|
|
638
|
+
display: block;
|
|
639
|
+
max-width: min(100%, var(--ds-attachment-single-max-width, 320px));
|
|
640
|
+
margin: 0;
|
|
641
|
+
padding: 0;
|
|
642
|
+
border: var(--border-025) solid var(--color-bg-container-border);
|
|
643
|
+
/* The bubble's radius: a lone picture is a message surface in its own right */
|
|
644
|
+
border-radius: var(--radius-600);
|
|
645
|
+
background: none;
|
|
646
|
+
overflow: hidden;
|
|
647
|
+
/* Collapse the inline gap under the image */
|
|
648
|
+
line-height: 0;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
button.ds-attachment-group__single {
|
|
652
|
+
cursor: zoom-in;
|
|
653
|
+
transition: border-color var(--motion-duration-base) var(--motion-ease-standard);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
button.ds-attachment-group__single:hover {
|
|
657
|
+
border-color: var(--color-text-tertiary);
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
/* The extension, on a plate of the surface so it reads over any picture */
|
|
661
|
+
.ds-attachment-group__single-mark {
|
|
662
|
+
position: absolute;
|
|
663
|
+
left: var(--padding-200);
|
|
664
|
+
bottom: var(--padding-200);
|
|
665
|
+
display: inline-flex;
|
|
666
|
+
line-height: normal;
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
.ds-attachment-group__single-image {
|
|
670
|
+
display: block;
|
|
671
|
+
max-width: 100%;
|
|
672
|
+
max-height: var(--ds-attachment-single-max-height, 320px);
|
|
673
|
+
width: auto;
|
|
674
|
+
height: auto;
|
|
675
|
+
}
|
|
676
|
+
|
|
677
|
+
.ds-attachment-group__more:focus-visible,
|
|
678
|
+
.ds-attachment-group__less:focus-visible,
|
|
679
|
+
button.ds-attachment-group__single:focus-visible {
|
|
680
|
+
outline: 2px solid var(--color-action-primary-bg);
|
|
681
|
+
outline-offset: 2px;
|
|
682
|
+
}
|
|
683
|
+
|
|
684
|
+
/* ============================================
|
|
685
|
+
VIEWER — the preview dialog
|
|
686
|
+
A centred dialog on a wide screen, a full-screen sheet on a narrow one.
|
|
687
|
+
============================================ */
|
|
688
|
+
|
|
689
|
+
.ds-attachment-viewer {
|
|
690
|
+
position: fixed;
|
|
691
|
+
inset: 0;
|
|
692
|
+
z-index: 100;
|
|
693
|
+
display: flex;
|
|
694
|
+
align-items: center;
|
|
695
|
+
justify-content: center;
|
|
696
|
+
padding: var(--padding-1000);
|
|
697
|
+
opacity: 0;
|
|
698
|
+
visibility: hidden; /* keeps the panel's controls out of the tab order when closed */
|
|
699
|
+
pointer-events: none;
|
|
700
|
+
transition:
|
|
701
|
+
opacity var(--motion-duration-base) var(--motion-ease-standard),
|
|
702
|
+
visibility var(--motion-duration-base) var(--motion-ease-standard);
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
.ds-attachment-viewer--open {
|
|
706
|
+
opacity: 1;
|
|
707
|
+
visibility: visible;
|
|
708
|
+
pointer-events: auto;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
.ds-attachment-viewer__backdrop {
|
|
712
|
+
position: absolute;
|
|
713
|
+
inset: 0;
|
|
714
|
+
background-color: var(--color-scrim);
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
.ds-attachment-viewer__panel {
|
|
718
|
+
position: relative;
|
|
719
|
+
z-index: 1;
|
|
720
|
+
display: flex;
|
|
721
|
+
flex-direction: column;
|
|
722
|
+
/* The dialog's footprint: wide enough for a page or a landscape picture,
|
|
723
|
+
never taller than the viewport it sits in. Lengths with no token family. */
|
|
724
|
+
width: min(100%, 960px);
|
|
725
|
+
height: min(100%, 720px);
|
|
726
|
+
border: var(--border-025) solid var(--color-bg-container-border);
|
|
727
|
+
border-radius: var(--radius-300);
|
|
728
|
+
background-color: var(--color-bg-page-primary);
|
|
729
|
+
box-shadow: var(--shadow-modal);
|
|
730
|
+
overflow: hidden;
|
|
731
|
+
outline: none;
|
|
732
|
+
transform: scale(0.96);
|
|
733
|
+
transition: transform var(--motion-duration-base) var(--motion-ease-standard);
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
.ds-attachment-viewer--open .ds-attachment-viewer__panel {
|
|
737
|
+
transform: scale(1);
|
|
738
|
+
}
|
|
739
|
+
|
|
740
|
+
/* ---------- Header ---------- */
|
|
741
|
+
|
|
742
|
+
.ds-attachment-viewer__header {
|
|
743
|
+
flex: none;
|
|
744
|
+
display: flex;
|
|
745
|
+
align-items: center;
|
|
746
|
+
gap: var(--gap-300);
|
|
747
|
+
padding: var(--padding-300) var(--padding-400);
|
|
748
|
+
border-bottom: var(--border-025) solid var(--color-bg-container-border);
|
|
749
|
+
background-color: var(--color-bg-container-primary);
|
|
750
|
+
}
|
|
751
|
+
|
|
752
|
+
.ds-attachment-viewer__header-mark {
|
|
753
|
+
display: inline-flex;
|
|
754
|
+
flex: none;
|
|
755
|
+
}
|
|
756
|
+
|
|
757
|
+
.ds-attachment-viewer__heading {
|
|
758
|
+
flex: 1;
|
|
759
|
+
min-width: 0;
|
|
760
|
+
display: flex;
|
|
761
|
+
flex-direction: column;
|
|
762
|
+
}
|
|
763
|
+
|
|
764
|
+
.ds-attachment-viewer__title {
|
|
765
|
+
margin: 0;
|
|
766
|
+
overflow: hidden;
|
|
767
|
+
text-overflow: ellipsis;
|
|
768
|
+
white-space: nowrap;
|
|
769
|
+
font-family: var(--font-paragraph-sm-emphasis-family);
|
|
770
|
+
font-size: var(--font-paragraph-sm-emphasis-size);
|
|
771
|
+
font-weight: var(--font-overline-weight);
|
|
772
|
+
line-height: var(--font-paragraph-sm-emphasis-line-height);
|
|
773
|
+
letter-spacing: var(--font-paragraph-sm-emphasis-letter-spacing);
|
|
774
|
+
color: var(--color-text-primary);
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
.ds-attachment-viewer__subtitle {
|
|
778
|
+
margin: 0;
|
|
779
|
+
font-family: var(--font-caption-family);
|
|
780
|
+
font-size: var(--font-caption-size);
|
|
781
|
+
font-weight: var(--font-caption-weight);
|
|
782
|
+
line-height: var(--font-caption-line-height);
|
|
783
|
+
letter-spacing: var(--font-caption-letter-spacing);
|
|
784
|
+
font-variant-numeric: tabular-nums;
|
|
785
|
+
color: var(--color-text-tertiary);
|
|
786
|
+
}
|
|
787
|
+
|
|
788
|
+
.ds-attachment-viewer__download {
|
|
789
|
+
flex: none;
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
/* ---------- Stage ---------- */
|
|
793
|
+
|
|
794
|
+
.ds-attachment-viewer__stage {
|
|
795
|
+
flex: 1;
|
|
796
|
+
min-height: 0;
|
|
797
|
+
display: flex;
|
|
798
|
+
/* `safe` keeps the top of tall content reachable: plain centring would
|
|
799
|
+
push it above the scroll origin */
|
|
800
|
+
align-items: safe center;
|
|
801
|
+
justify-content: safe center;
|
|
802
|
+
padding: var(--padding-400);
|
|
803
|
+
overflow: auto;
|
|
804
|
+
/* A dotted working-canvas ground: the file sits on a surface that reads
|
|
805
|
+
as "a place things are laid out", not a flat fill. Dot size and pitch
|
|
806
|
+
are drawing geometry, not spacing roles, and match the docs site's
|
|
807
|
+
dotted stages so every one shares a texture. */
|
|
808
|
+
background-color: var(--color-bg-page-primary);
|
|
809
|
+
background-image: radial-gradient(
|
|
810
|
+
circle,
|
|
811
|
+
var(--color-bg-container-border) 1.25px,
|
|
812
|
+
transparent 1.25px
|
|
813
|
+
);
|
|
814
|
+
background-size: 26px 26px;
|
|
815
|
+
}
|
|
816
|
+
|
|
817
|
+
.ds-attachment-viewer__image {
|
|
818
|
+
display: block;
|
|
819
|
+
max-width: 100%;
|
|
820
|
+
max-height: 100%;
|
|
821
|
+
width: auto;
|
|
822
|
+
height: auto;
|
|
823
|
+
border-radius: var(--radius-200);
|
|
824
|
+
}
|
|
825
|
+
|
|
826
|
+
.ds-attachment-viewer__text {
|
|
827
|
+
align-self: flex-start;
|
|
828
|
+
width: 100%;
|
|
829
|
+
margin: 0;
|
|
830
|
+
font-family: var(--font-paragraph-sm-family);
|
|
831
|
+
font-size: var(--font-paragraph-sm-size);
|
|
832
|
+
font-weight: var(--font-paragraph-sm-weight);
|
|
833
|
+
line-height: var(--font-paragraph-sm-line-height);
|
|
834
|
+
letter-spacing: var(--font-paragraph-sm-letter-spacing);
|
|
835
|
+
color: var(--color-text-primary);
|
|
836
|
+
white-space: pre-wrap;
|
|
837
|
+
overflow-wrap: anywhere;
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
/* Nothing to draw, or a file that failed: a small centred statement */
|
|
841
|
+
.ds-attachment-viewer__empty {
|
|
842
|
+
display: flex;
|
|
843
|
+
flex-direction: column;
|
|
844
|
+
align-items: center;
|
|
845
|
+
gap: var(--gap-100);
|
|
846
|
+
max-width: 100%;
|
|
847
|
+
text-align: center;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
.ds-attachment-viewer__empty-mark {
|
|
851
|
+
display: inline-flex;
|
|
852
|
+
align-items: center;
|
|
853
|
+
justify-content: center;
|
|
854
|
+
/* A tile-sized seat for the type mark, so the empty state shows the same
|
|
855
|
+
object the person pressed */
|
|
856
|
+
width: 88px;
|
|
857
|
+
height: 88px;
|
|
858
|
+
margin-bottom: var(--gap-200);
|
|
859
|
+
border: var(--border-025) solid var(--color-bg-container-border);
|
|
860
|
+
border-radius: var(--radius-400);
|
|
861
|
+
background-color: var(--color-bg-container-primary);
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
.ds-attachment-viewer__empty-title {
|
|
865
|
+
margin: 0;
|
|
866
|
+
font-family: var(--font-title-body-family);
|
|
867
|
+
font-size: var(--font-title-body-size);
|
|
868
|
+
font-weight: var(--font-title-body-weight);
|
|
869
|
+
line-height: var(--font-title-body-line-height);
|
|
870
|
+
letter-spacing: var(--font-title-body-letter-spacing);
|
|
871
|
+
color: var(--color-text-primary);
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
.ds-attachment-viewer__empty-detail {
|
|
875
|
+
margin: 0;
|
|
876
|
+
font-family: var(--font-paragraph-sm-family);
|
|
877
|
+
font-size: var(--font-paragraph-sm-size);
|
|
878
|
+
font-weight: var(--font-paragraph-sm-weight);
|
|
879
|
+
line-height: var(--font-paragraph-sm-line-height);
|
|
880
|
+
letter-spacing: var(--font-paragraph-sm-letter-spacing);
|
|
881
|
+
color: var(--color-text-secondary);
|
|
882
|
+
overflow-wrap: anywhere;
|
|
883
|
+
}
|
|
884
|
+
|
|
885
|
+
.ds-attachment-viewer__empty-actions {
|
|
886
|
+
display: flex;
|
|
887
|
+
flex-wrap: wrap;
|
|
888
|
+
justify-content: center;
|
|
889
|
+
gap: var(--gap-200);
|
|
890
|
+
margin-top: var(--gap-300);
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
/* ---------- Footer ---------- */
|
|
894
|
+
|
|
895
|
+
.ds-attachment-viewer__footer {
|
|
896
|
+
flex: none;
|
|
897
|
+
display: flex;
|
|
898
|
+
align-items: center;
|
|
899
|
+
justify-content: center;
|
|
900
|
+
gap: var(--gap-300);
|
|
901
|
+
padding: var(--padding-200) var(--padding-400);
|
|
902
|
+
border-top: var(--border-025) solid var(--color-bg-container-border);
|
|
903
|
+
background-color: var(--color-bg-container-primary);
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
.ds-attachment-viewer__position {
|
|
907
|
+
/* Room for the widest count, so stepping never shifts the buttons */
|
|
908
|
+
min-width: 7ch;
|
|
909
|
+
text-align: center;
|
|
910
|
+
font-family: var(--font-paragraph-sm-family);
|
|
911
|
+
font-size: var(--font-paragraph-sm-size);
|
|
912
|
+
font-weight: var(--font-paragraph-sm-weight);
|
|
913
|
+
line-height: var(--font-paragraph-sm-line-height);
|
|
914
|
+
letter-spacing: var(--font-paragraph-sm-letter-spacing);
|
|
915
|
+
font-variant-numeric: tabular-nums;
|
|
916
|
+
color: var(--color-text-secondary);
|
|
917
|
+
}
|
|
918
|
+
|
|
919
|
+
/* ---------- Narrow: a full-screen sheet ----------
|
|
920
|
+
Below 30rem there is no room for a floating dialog and its margin, so
|
|
921
|
+
the panel takes the whole viewport. */
|
|
922
|
+
|
|
923
|
+
@media (max-width: 30rem) {
|
|
924
|
+
.ds-attachment-viewer {
|
|
925
|
+
padding: 0;
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
.ds-attachment-viewer__panel {
|
|
929
|
+
width: 100%;
|
|
930
|
+
height: 100%;
|
|
931
|
+
border: none;
|
|
932
|
+
border-radius: 0;
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
/* ============================================
|
|
937
|
+
DROP ZONE — a whole surface as a drop target
|
|
938
|
+
============================================ */
|
|
939
|
+
|
|
940
|
+
.ds-attachment-drop-zone {
|
|
941
|
+
position: relative;
|
|
942
|
+
}
|
|
943
|
+
|
|
944
|
+
.ds-attachment-drop-zone__overlay {
|
|
945
|
+
/* The frost's strength and the glow's spread: effect lengths with no
|
|
946
|
+
token family, chosen by eye (Lightbox's frost and Composer's glow are
|
|
947
|
+
the precedents) */
|
|
948
|
+
--ds-attachment-drop-zone-frost: 10px;
|
|
949
|
+
--ds-attachment-drop-zone-glow: 14px;
|
|
950
|
+
|
|
951
|
+
position: absolute;
|
|
952
|
+
/* Flush with the surface it covers, corners and all, so the edge reads
|
|
953
|
+
as the surface's own outline lighting up */
|
|
954
|
+
inset: 0;
|
|
955
|
+
z-index: 10;
|
|
956
|
+
display: flex;
|
|
957
|
+
align-items: center;
|
|
958
|
+
justify-content: center;
|
|
959
|
+
padding: var(--padding-400);
|
|
960
|
+
/* A solid edge in the active-input colour: while files hover, the whole
|
|
961
|
+
surface is the input that is about to take them, and it wears the same
|
|
962
|
+
border a focused field does (Composer's own drop state uses it too) */
|
|
963
|
+
border: var(--border-050) solid var(--color-input-border-selected);
|
|
964
|
+
border-radius: inherit;
|
|
965
|
+
/* Frosted, not painted over: the surface blurs and dims behind the
|
|
966
|
+
message, so the person still sees what they are dropping onto without
|
|
967
|
+
its text competing with the overlay's */
|
|
968
|
+
background-color: color-mix(in srgb, var(--color-bg-container-primary) 60%, transparent);
|
|
969
|
+
backdrop-filter: blur(var(--ds-attachment-drop-zone-frost));
|
|
970
|
+
/* Never a target itself: the zone hears the drag, and an overlay that
|
|
971
|
+
caught the pointer would fire a leave on everything beneath it */
|
|
972
|
+
pointer-events: none;
|
|
973
|
+
opacity: 0;
|
|
974
|
+
visibility: hidden;
|
|
975
|
+
transition:
|
|
976
|
+
opacity var(--motion-duration-fast) var(--motion-ease-standard),
|
|
977
|
+
visibility var(--motion-duration-fast) var(--motion-ease-standard);
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
/* The glow: the edge's own colour, blurred, hugging the border inside and
|
|
981
|
+
out. A colour effect like the Composer's AI ring, not an elevation
|
|
982
|
+
shadow, so depth stays token-owned. */
|
|
983
|
+
.ds-attachment-drop-zone__overlay::before {
|
|
984
|
+
content: '';
|
|
985
|
+
position: absolute;
|
|
986
|
+
inset: calc(-1 * var(--border-050));
|
|
987
|
+
/* Twice the edge's weight, so the blur has enough colour to spread */
|
|
988
|
+
border: calc(var(--border-050) * 2) solid var(--color-input-border-selected);
|
|
989
|
+
border-radius: inherit;
|
|
990
|
+
filter: blur(var(--ds-attachment-drop-zone-glow));
|
|
991
|
+
opacity: 0.8;
|
|
992
|
+
pointer-events: none;
|
|
993
|
+
}
|
|
994
|
+
|
|
995
|
+
.ds-attachment-drop-zone--active .ds-attachment-drop-zone__overlay {
|
|
996
|
+
opacity: 1;
|
|
997
|
+
visibility: visible;
|
|
998
|
+
}
|
|
999
|
+
|
|
1000
|
+
.ds-attachment-drop-zone__message {
|
|
1001
|
+
display: flex;
|
|
1002
|
+
flex-direction: column;
|
|
1003
|
+
align-items: center;
|
|
1004
|
+
gap: var(--gap-100);
|
|
1005
|
+
text-align: center;
|
|
1006
|
+
}
|
|
1007
|
+
|
|
1008
|
+
.ds-attachment-drop-zone__icon {
|
|
1009
|
+
display: inline-flex;
|
|
1010
|
+
margin-bottom: var(--gap-100);
|
|
1011
|
+
/* The edge's own colour: the icon and the outline light up together */
|
|
1012
|
+
color: var(--color-input-border-selected);
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
.ds-attachment-drop-zone__icon .material-symbols-rounded {
|
|
1016
|
+
--icon-size: var(--icon-size-800);
|
|
1017
|
+
color: inherit;
|
|
1018
|
+
}
|
|
1019
|
+
|
|
1020
|
+
.ds-attachment-drop-zone__label {
|
|
1021
|
+
font-family: var(--font-title-body-family);
|
|
1022
|
+
font-size: var(--font-title-body-size);
|
|
1023
|
+
font-weight: var(--font-title-body-weight);
|
|
1024
|
+
line-height: var(--font-title-body-line-height);
|
|
1025
|
+
letter-spacing: var(--font-title-body-letter-spacing);
|
|
1026
|
+
color: var(--color-text-primary);
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
.ds-attachment-drop-zone__hint {
|
|
1030
|
+
font-family: var(--font-paragraph-sm-family);
|
|
1031
|
+
font-size: var(--font-paragraph-sm-size);
|
|
1032
|
+
font-weight: var(--font-paragraph-sm-weight);
|
|
1033
|
+
line-height: var(--font-paragraph-sm-line-height);
|
|
1034
|
+
letter-spacing: var(--font-paragraph-sm-letter-spacing);
|
|
1035
|
+
color: var(--color-text-secondary);
|
|
1036
|
+
}
|