@ash-qw/dsh-theme-prts 1.2.0 → 1.2.2
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/CHANGELOG.md +14 -0
- package/lib/client.js +61 -31
- package/package.json +1 -1
- package/src/client/emblem-reorder.js +29 -8
- package/src/client/facility-vector.js +49 -32
- package/src/client/sidebar-control-adapter.js +7 -8
- package/src/styles/cursor.css +7 -1
- package/src/styles/prts.css +1 -3
- package/src/styles/theme-settings-workbench.css +3 -3
package/package.json
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
//
|
|
1
|
+
// Cards own touch gestures: immediate swipes scroll, while a hold locks into sorting.
|
|
2
2
|
export function mountEmblemReorder({ list, window, status, canStart, onStart, onCommit }) {
|
|
3
3
|
let gesture = null, holdTimer, frame, previousTime = 0, suppressClick = false
|
|
4
4
|
const rows = () => [...list.children].filter(row => row.hasAttribute('data-emblem-key'))
|
|
@@ -13,6 +13,7 @@ export function mountEmblemReorder({ list, window, status, canStart, onStart, on
|
|
|
13
13
|
gesture = null; clear()
|
|
14
14
|
current.ghost?.remove();current.row.removeAttribute('data-prts-emblem-dragging')
|
|
15
15
|
list.removeAttribute('data-prts-emblem-sorting')
|
|
16
|
+
scroller?.removeAttribute('data-prts-emblem-sort-active')
|
|
16
17
|
current.handle.setAttribute('aria-pressed','false')
|
|
17
18
|
try { if (list.hasPointerCapture?.(current.pointerId)) list.releasePointerCapture(current.pointerId) } catch {}
|
|
18
19
|
const ordered = rows().map(row=>row.dataset.emblemKey)
|
|
@@ -59,6 +60,7 @@ export function mountEmblemReorder({ list, window, status, canStart, onStart, on
|
|
|
59
60
|
current.handle.setAttribute('aria-pressed','true')
|
|
60
61
|
list.setAttribute('data-prts-emblem-sorting','')
|
|
61
62
|
if (!current.keyboard) {
|
|
63
|
+
scroller?.setAttribute('data-prts-emblem-sort-active','')
|
|
62
64
|
const box=current.row.getBoundingClientRect()
|
|
63
65
|
const ghost=current.row.cloneNode(true)
|
|
64
66
|
ghost.removeAttribute('data-emblem-key');ghost.setAttribute('data-prts-emblem-drag-ghost','')
|
|
@@ -81,22 +83,41 @@ export function mountEmblemReorder({ list, window, status, canStart, onStart, on
|
|
|
81
83
|
const row=event.target.closest('[data-emblem-key]')
|
|
82
84
|
const handle=row?.querySelector('[data-prts-emblem-reorder]')
|
|
83
85
|
suppressClick=false
|
|
84
|
-
if (!handle ||
|
|
85
|
-
|
|
86
|
-
|
|
86
|
+
if (!handle || event.button!==0 || event.isPrimary===false) return
|
|
87
|
+
const sortable = !handle.disabled && canStart() && rows().length>=2
|
|
88
|
+
// touch-action:none also applies to a single/temporarily disabled card.
|
|
89
|
+
// It still needs swipe scrolling even when sorting cannot start.
|
|
90
|
+
if (!sortable && event.pointerType!=='touch') return
|
|
91
|
+
gesture={handle,row,pointerType:event.pointerType,pointerId:event.pointerId,startX:event.clientX,startY:event.clientY,x:event.clientX,y:event.clientY,original:rows(),active:false}
|
|
92
|
+
if (sortable) holdTimer=window.setTimeout(activate,400)
|
|
87
93
|
}
|
|
88
94
|
const move = event => {
|
|
89
95
|
if (!gesture || gesture.pointerId!==event.pointerId) return
|
|
96
|
+
const previousY=gesture.y
|
|
90
97
|
gesture.x=event.clientX;gesture.y=event.clientY
|
|
91
|
-
if (!gesture.active && Math.hypot(gesture.x-gesture.startX,gesture.y-gesture.startY)>8) {
|
|
92
|
-
|
|
98
|
+
if (!gesture.active && !gesture.scrolling && Math.hypot(gesture.x-gesture.startX,gesture.y-gesture.startY)>8) {
|
|
99
|
+
if (gesture.pointerType !== 'touch') {finish();return}
|
|
100
|
+
window.clearTimeout(holdTimer)
|
|
101
|
+
gesture.scrolling=true;suppressClick=true
|
|
102
|
+
try {list.setPointerCapture(gesture.pointerId)}catch{finish();return}
|
|
103
|
+
// Include the movement accumulated while deciding between a tap and a swipe.
|
|
104
|
+
if(scroller)scroller.scrollTop += gesture.startY-previousY
|
|
105
|
+
}
|
|
106
|
+
if (gesture.scrolling && scroller) scroller.scrollTop += previousY-gesture.y
|
|
107
|
+
if (gesture.active || gesture.scrolling) event.preventDefault()
|
|
93
108
|
}
|
|
94
109
|
const up = event => {
|
|
95
110
|
if (gesture?.pointerId!==event.pointerId) return
|
|
111
|
+
if (gesture.scrolling) {finish();return}
|
|
96
112
|
const box=list.getBoundingClientRect(), viewport=(scroller || list).getBoundingClientRect()
|
|
97
113
|
finish(event.clientX>=box.left && event.clientX<=box.right && event.clientY>=viewport.top && event.clientY<=viewport.bottom)
|
|
98
114
|
}
|
|
99
115
|
const cancelPointer = event => {if (gesture?.pointerId===event.pointerId) finish()}
|
|
116
|
+
// A touch initially belongs to its hit target. Transferring capture to the
|
|
117
|
+
// list emits a bubbling loss event from that child, not a canceled drag.
|
|
118
|
+
const lostCapture = event => {
|
|
119
|
+
if (event.target === list && !list.hasPointerCapture(event.pointerId)) cancelPointer(event)
|
|
120
|
+
}
|
|
100
121
|
const cancel = () => finish()
|
|
101
122
|
const visibility = () => {if (window.document.hidden) finish()}
|
|
102
123
|
const keydown = event => {
|
|
@@ -128,7 +149,7 @@ export function mountEmblemReorder({ list, window, status, canStart, onStart, on
|
|
|
128
149
|
window.addEventListener('pointermove',move,{passive:false})
|
|
129
150
|
window.addEventListener('pointerup',up)
|
|
130
151
|
window.addEventListener('pointercancel',cancelPointer)
|
|
131
|
-
list.addEventListener('lostpointercapture',
|
|
152
|
+
list.addEventListener('lostpointercapture',lostCapture)
|
|
132
153
|
window.addEventListener('keydown',keydown,true)
|
|
133
154
|
window.addEventListener('blur',cancel)
|
|
134
155
|
window.addEventListener('resize',cancel)
|
|
@@ -137,7 +158,7 @@ export function mountEmblemReorder({ list, window, status, canStart, onStart, on
|
|
|
137
158
|
finish()
|
|
138
159
|
list.removeEventListener('touchmove',touchmove);list.removeEventListener('pointerdown',down);list.removeEventListener('contextmenu',context);list.removeEventListener('click',click,true)
|
|
139
160
|
window.removeEventListener('pointermove',move);window.removeEventListener('pointerup',up);window.removeEventListener('pointercancel',cancelPointer)
|
|
140
|
-
list.removeEventListener('lostpointercapture',
|
|
161
|
+
list.removeEventListener('lostpointercapture',lostCapture);window.removeEventListener('keydown',keydown,true);window.removeEventListener('blur',cancel);window.removeEventListener('resize',cancel)
|
|
141
162
|
window.document.removeEventListener('visibilitychange',visibility)
|
|
142
163
|
} }
|
|
143
164
|
}
|
|
@@ -21,6 +21,7 @@ const SILHOUETTE_PATHS = Object.freeze({
|
|
|
21
21
|
})
|
|
22
22
|
|
|
23
23
|
let silhouetteId = 0
|
|
24
|
+
const renderStates = new WeakMap()
|
|
24
25
|
|
|
25
26
|
export const FACILITY_TEXTURES = Object.freeze(['none', 'grid', 'scanline', 'silhouette', 'pickup'])
|
|
26
27
|
|
|
@@ -86,6 +87,7 @@ export function ensureFacilityTextureDefs(document) {
|
|
|
86
87
|
}
|
|
87
88
|
|
|
88
89
|
function appendSilhouetteScene(document, graphic) {
|
|
90
|
+
renderStates.delete(graphic)
|
|
89
91
|
const clipId = `prts-facility-silhouette-clip-${++silhouetteId}`
|
|
90
92
|
const defs = svgNode(document, 'defs')
|
|
91
93
|
const clip = svgNode(document, 'clipPath', { id: clipId, clipPathUnits: 'userSpaceOnUse' })
|
|
@@ -112,6 +114,7 @@ function appendSilhouetteScene(document, graphic) {
|
|
|
112
114
|
}
|
|
113
115
|
|
|
114
116
|
function appendSessionPickup(document, graphic) {
|
|
117
|
+
renderStates.delete(graphic)
|
|
115
118
|
const clipId = `prts-facility-pickup-clip-${++silhouetteId}`
|
|
116
119
|
const defs = svgNode(document, 'defs')
|
|
117
120
|
const clip = svgNode(document, 'clipPath', { id: clipId, clipPathUnits: 'userSpaceOnUse' })
|
|
@@ -171,6 +174,7 @@ function appendSessionStatusUnderlay(document, graphic) {
|
|
|
171
174
|
const surface = graphic.querySelector('[data-prts-facility-layer="surface"]')
|
|
172
175
|
if (!surface) return
|
|
173
176
|
if (!graphic.querySelector('[data-prts-session-status-underlay]')) {
|
|
177
|
+
renderStates.delete(graphic)
|
|
174
178
|
graphic.insertBefore(svgNode(document, 'path', {
|
|
175
179
|
'data-prts-session-status-underlay': '',
|
|
176
180
|
'aria-hidden': 'true',
|
|
@@ -179,6 +183,7 @@ function appendSessionStatusUnderlay(document, graphic) {
|
|
|
179
183
|
}), surface)
|
|
180
184
|
}
|
|
181
185
|
if (!graphic.querySelector('[data-prts-session-idle-indicator]')) {
|
|
186
|
+
renderStates.delete(graphic)
|
|
182
187
|
graphic.insertBefore(svgNode(document, 'rect', {
|
|
183
188
|
'data-prts-session-idle-indicator': '',
|
|
184
189
|
'aria-hidden': 'true',
|
|
@@ -249,48 +254,60 @@ export function renderFacilityGraphic(owner, { width, height } = {}) {
|
|
|
249
254
|
const graphic = owner?.querySelector?.(':scope > svg[data-prts-facility-svg]')
|
|
250
255
|
const topNotch = graphic?.hasAttribute('data-prts-top-notch')
|
|
251
256
|
const sessionNotch = graphic?.hasAttribute('data-prts-session-notch')
|
|
252
|
-
|
|
253
|
-
|
|
257
|
+
if (!graphic || !Number.isFinite(width) || !Number.isFinite(height) || width <= 2 || height <= FACILITY_GEOMETRY.sideOpening + 2) {
|
|
258
|
+
if (graphic) renderStates.delete(graphic)
|
|
254
259
|
owner?.removeAttribute?.('data-prts-facility-size')
|
|
255
260
|
setReady(owner, false)
|
|
256
261
|
return false
|
|
257
262
|
}
|
|
258
263
|
|
|
259
264
|
const size = `${Number(width.toFixed(3))}x${Number(height.toFixed(3))}:${topNotch ? 't' : '-'}${sessionNotch ? 's' : '-'}`
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
265
|
+
let state = renderStates.get(graphic)
|
|
266
|
+
if (state?.size === size) {
|
|
267
|
+
setReady(owner, true)
|
|
268
|
+
return true
|
|
269
|
+
}
|
|
270
|
+
if (!state) {
|
|
271
|
+
state = {
|
|
272
|
+
layers: graphic.querySelectorAll('[data-prts-facility-layer], [data-prts-facility-clip]'),
|
|
273
|
+
statusUnderlay: graphic.querySelector('[data-prts-session-status-underlay]'),
|
|
274
|
+
idleIndicator: graphic.querySelector('[data-prts-session-idle-indicator]'),
|
|
275
|
+
silhouette: graphic.querySelector('[data-prts-facility-silhouette]'),
|
|
276
|
+
pickup: graphic.querySelector('[data-prts-session-pickup]'),
|
|
277
|
+
lifeline: graphic.querySelector('[data-prts-session-lifeline]'),
|
|
273
278
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
279
|
+
renderStates.set(graphic, state)
|
|
280
|
+
}
|
|
281
|
+
const { statusUnderlay, idleIndicator, silhouette, pickup, lifeline } = state
|
|
282
|
+
const path = createFacilityPath({ width, height, topNotch, sessionNotch })
|
|
283
|
+
graphic.setAttribute('viewBox', `0 0 ${Number(width.toFixed(3))} ${Number(height.toFixed(3))}`)
|
|
284
|
+
for (const layer of state.layers) layer.setAttribute('d', path)
|
|
285
|
+
statusUnderlay?.setAttribute('d', createFacilityPath({ width, height }))
|
|
286
|
+
idleIndicator?.setAttribute('x', String(Number((width / 2 - 25).toFixed(3))))
|
|
287
|
+
if (silhouette && state.height !== height) {
|
|
288
|
+
const availableHeight = Math.max(1, height - 2)
|
|
289
|
+
silhouette.setAttribute('transform', `translate(0 1) scale(1 ${Number((availableHeight / 38).toFixed(5))})`)
|
|
290
|
+
}
|
|
291
|
+
if (pickup && state.height !== height) {
|
|
292
|
+
const center = Number((height / 2).toFixed(3))
|
|
293
|
+
for (const baseline of pickup.querySelectorAll('[data-prts-session-pickup-baseline]')) {
|
|
294
|
+
baseline.setAttribute('y1', String(center))
|
|
295
|
+
baseline.setAttribute('y2', String(center))
|
|
288
296
|
}
|
|
289
|
-
|
|
290
|
-
|
|
297
|
+
for (const indicator of pickup.querySelectorAll('[data-prts-session-pickup-indicator]')) {
|
|
298
|
+
indicator.setAttribute('cy', String(center))
|
|
291
299
|
}
|
|
292
|
-
|
|
300
|
+
for (const bar of pickup.querySelectorAll('[data-prts-session-pickup-bar]')) {
|
|
301
|
+
const barHeight = Number(bar.getAttribute('height')) || 0
|
|
302
|
+
bar.setAttribute('y', String(Number((center - barHeight / 2).toFixed(3))))
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
if (lifeline) {
|
|
306
|
+
configureSessionLifeline(lifeline, sessionLifelineGeometry(width, height))
|
|
293
307
|
}
|
|
308
|
+
state.size = size
|
|
309
|
+
state.height = height
|
|
310
|
+
owner.setAttribute('data-prts-facility-size', size)
|
|
294
311
|
setReady(owner, true)
|
|
295
312
|
return true
|
|
296
313
|
}
|
|
@@ -193,7 +193,6 @@ export function createSidebarControlAdapter({ document, window, sessions, worksp
|
|
|
193
193
|
let observer
|
|
194
194
|
let resizeObserver
|
|
195
195
|
let resizeFrame
|
|
196
|
-
let resizeTimer
|
|
197
196
|
let scanFrame
|
|
198
197
|
let stopSessionList = () => {}
|
|
199
198
|
let stopWorkspaceList = () => {}
|
|
@@ -363,6 +362,10 @@ export function createSidebarControlAdapter({ document, window, sessions, worksp
|
|
|
363
362
|
}
|
|
364
363
|
|
|
365
364
|
function flushVectors() {
|
|
365
|
+
if (resizeFrame !== undefined) {
|
|
366
|
+
if (window?.cancelAnimationFrame) window.cancelAnimationFrame(resizeFrame)
|
|
367
|
+
else window?.clearTimeout?.(resizeFrame)
|
|
368
|
+
}
|
|
366
369
|
resizeFrame = undefined
|
|
367
370
|
const measurements = []
|
|
368
371
|
for (const [owner, observedSize] of dirtyVectors) {
|
|
@@ -533,11 +536,9 @@ export function createSidebarControlAdapter({ document, window, sessions, worksp
|
|
|
533
536
|
const rect = entry.contentRect
|
|
534
537
|
dirtyVectors.set(entry.target, rect ? { width: rect.width, height: rect.height } : undefined)
|
|
535
538
|
}
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
scheduleVectors()
|
|
540
|
-
}, 160)
|
|
539
|
+
// ResizeObserver runs before paint. Update only the SVG geometry here so
|
|
540
|
+
// the previous viewBox is never stretched across the new card width.
|
|
541
|
+
flushVectors()
|
|
541
542
|
})
|
|
542
543
|
}
|
|
543
544
|
scan()
|
|
@@ -580,8 +581,6 @@ export function createSidebarControlAdapter({ document, window, sessions, worksp
|
|
|
580
581
|
else window?.clearTimeout?.(resizeFrame)
|
|
581
582
|
}
|
|
582
583
|
resizeFrame = undefined
|
|
583
|
-
if (resizeTimer !== undefined) window?.clearTimeout?.(resizeTimer)
|
|
584
|
-
resizeTimer = undefined
|
|
585
584
|
lifelineAnimator.dispose()
|
|
586
585
|
clear()
|
|
587
586
|
},
|
package/src/styles/cursor.css
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
html[data-dsh-prts][data-prts-cursor="prts"] {
|
|
4
4
|
--prts-hand-cursor: var(--prts-hand-frame, url("__PRTS_HAND__") 7 6);
|
|
5
5
|
--prts-text-cursor: var(--prts-text-frame, url("__PRTS_TEXT__") 24 24);
|
|
6
|
+
--prts-sort-cursor: url("__PRTS_GRABBING__") 22 19, grabbing;
|
|
6
7
|
--prts-link-cursor: url("__PRTS_LINK__") 7 7;
|
|
7
8
|
cursor: var(--prts-hand-cursor), default;
|
|
8
9
|
}
|
|
@@ -15,13 +16,18 @@
|
|
|
15
16
|
html[data-dsh-prts][data-prts-cursor="prts"] :is(textarea, input:not([type]), input[type="text"], input[type="search"], input[type="email"], input[type="url"], input[type="password"], input[type="number"], input[type="tel"], [contenteditable=""], [contenteditable="true"], [contenteditable="plaintext-only"]) {
|
|
16
17
|
cursor: var(--prts-text-cursor), text;
|
|
17
18
|
}
|
|
19
|
+
html[data-dsh-prts][data-prts-cursor="prts"] [data-emblem-key],
|
|
18
20
|
html[data-dsh-prts][data-prts-cursor="prts"] :is(.dsh-partner-pendant-hit, .dsh-partner-pendant-anchor, [data-prts-emblem-reorder]):enabled {
|
|
19
21
|
cursor: url("__PRTS_GRAB__") 22 19, grab;
|
|
20
22
|
}
|
|
21
23
|
html[data-dsh-prts][data-prts-cursor="prts"] :is(.dsh-partner-pendant-hit, .dsh-partner-pendant-anchor, [data-prts-emblem-reorder]):enabled:active {
|
|
22
|
-
cursor:
|
|
24
|
+
cursor: var(--prts-sort-cursor);
|
|
23
25
|
}
|
|
24
26
|
html[data-dsh-prts][data-prts-cursor="prts"] :is(:disabled, [aria-disabled="true"]) {
|
|
25
27
|
cursor: url("__PRTS_NOT_ALLOWED__") 7 7, not-allowed !important;
|
|
26
28
|
}
|
|
27
29
|
}
|
|
30
|
+
|
|
31
|
+
html[data-dsh-prts] :is([data-prts-emblem-sort-active],[data-prts-emblem-sort-active] *) {
|
|
32
|
+
cursor: var(--prts-sort-cursor, grabbing) !important;
|
|
33
|
+
}
|
package/src/styles/prts.css
CHANGED
|
@@ -20,8 +20,6 @@ html[data-dsh-prts] {
|
|
|
20
20
|
--prts-host-top-inset: 0px;
|
|
21
21
|
--prts-rail-width: 52px;
|
|
22
22
|
--prts-nav-width: 52px;
|
|
23
|
-
--prts-sessions-width: 286px;
|
|
24
|
-
--prts-sessions-compact: 54px;
|
|
25
23
|
--prts-workspace-height: 38px;
|
|
26
24
|
--prts-session-height: 36px;
|
|
27
25
|
--prts-facility-gap: 7px;
|
|
@@ -843,7 +841,7 @@ html[data-dsh-prts] [data-prts-region="sessions"] :is(
|
|
|
843
841
|
[data-rc7-sidebar-root], [data-slot="sidebar"] > :first-child) {
|
|
844
842
|
box-sizing: border-box;
|
|
845
843
|
width: 100% !important;
|
|
846
|
-
min-width:
|
|
844
|
+
min-width: 0;
|
|
847
845
|
padding: 14px 10px;
|
|
848
846
|
overflow: hidden auto;
|
|
849
847
|
background: transparent !important;
|
|
@@ -325,7 +325,7 @@ padding-block: 9px;
|
|
|
325
325
|
}
|
|
326
326
|
html[data-dsh-prts] [data-prts-settings-common] [data-prts-session-flow-color-workbench] {
|
|
327
327
|
display: grid;
|
|
328
|
-
grid-template-columns:
|
|
328
|
+
grid-template-columns: repeat(auto-fit, minmax(min(100%, 240px), 1fr));
|
|
329
329
|
align-items: center;
|
|
330
330
|
gap: 10px;
|
|
331
331
|
}
|
|
@@ -745,7 +745,7 @@ color: var(--prts-ink);
|
|
|
745
745
|
}
|
|
746
746
|
html[data-dsh-prts] [data-prts-theme-settings] {
|
|
747
747
|
& [data-prts-setting-row="sessionFlowPalette"] > div { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); }
|
|
748
|
-
& [data-prts-setting-row="sessionFlowColors"] { grid-template-columns: minmax(0, 1fr); }
|
|
748
|
+
& [data-prts-settings-common] [data-prts-setting-row="sessionFlowColors"] { grid-template-columns: minmax(0, 1fr); }
|
|
749
749
|
& [data-prts-settings-advanced] { border-top: 1px solid var(--prts-line); }
|
|
750
750
|
& [data-prts-settings-advanced] > [data-prts-section-heading] { padding: 22px 0; }
|
|
751
751
|
& [data-prts-settings-section][hidden] { display: none !important; }
|
|
@@ -851,7 +851,7 @@ margin-bottom: 20px;
|
|
|
851
851
|
& [data-prts-custom-emblem] header { display: grid; gap: 6px; }
|
|
852
852
|
& [data-prts-custom-emblem] :is(small, p) { font: 400 12px/1.6 var(--prts-body); color: var(--prts-muted); margin: 0; }
|
|
853
853
|
& [data-prts-custom-emblem] label { display: grid; grid-template-columns: 110px minmax(0, 1fr); align-items: center; gap: 12px; font-size: 13px; }
|
|
854
|
-
& [data-prts-emblem-editor]{display:grid;gap:14px;}& [data-prts-custom-emblem] :is(input,select){min-width:0;max-width:100%;}& [data-prts-custom-emblem] select{padding:8px;background:var(--prts-panel-raised);color:var(--prts-ink);border:1px solid var(--prts-line);}& [data-prts-emblem-preview]{touch-action:none;cursor:grab;width:min(100%,280px);height:auto;justify-self:center;border:1px solid var(--prts-line);border-radius:4px;}& [data-prts-emblem-actions]{display:flex;flex-wrap:wrap;gap:10px;}& [data-prts-emblem-actions] button{padding:10px 14px;border:1px solid var(--prts-line);border-radius:4px;color:var(--prts-ink);background:var(--prts-panel-raised);}& [data-prts-emblem-actions] button:disabled{opacity:.45;}& [data-prts-custom-emblem] h4{margin:8px 0 12px;font:600 14px/1.5 var(--prts-body);}& [data-prts-emblem-list]{display:grid;gap:10px;list-style:none;padding:0;margin:14px 0;}& :is([data-prts-emblem-list] > li,[data-prts-emblem-hero-row]){display:flex;align-items:center;flex-wrap:wrap;gap:10px;padding:12px;border:1px solid var(--prts-line);border-radius:4px;}& :is([data-prts-emblem-list],[data-prts-emblem-hero-row]) canvas{width:48px;height:48px;flex:none;border-radius:3px;}& :is([data-prts-emblem-list] > li,[data-prts-emblem-hero-row]) > span{flex:1;min-width:100px;overflow-wrap:anywhere;font-size:13px;}& [data-emblem-action]{padding:7px 10px;border:1px solid var(--prts-line);border-radius:4px;background:var(--prts-panel-raised);color:var(--prts-ink);}& [data-emblem-action]:disabled{opacity:.4;}& [data-prts-emblem-reorder]{padding:0;border:0;background:transparent;cursor:grab;}& [data-emblem-key]{user-select:none;-webkit-touch-callout:none}& [data-prts-emblem-reorder]:focus-visible{outline:2px solid var(--prts-ink);outline-offset:3px;}& [data-prts-emblem-sorting]{user-select:none;}& [data-prts-emblem-dragging]{opacity:.35;border-style:dashed !important;}& [data-prts-emblem-drag-ghost]{background:var(--prts-panel-raised);box-shadow:0 8px 28px #0005;opacity:.95;}& :is([data-prts-emblem-reset-confirm],[data-prts-emblem-workspace],[data-prts-emblem-discard]){position:fixed;inset:0;margin:auto;width:min(460px,calc(100vw - 32px));max-height:80dvh;box-sizing:border-box;overflow:auto;padding:24px;border:1px solid var(--prts-line);border-radius:8px;background:var(--prts-panel-raised);color:var(--prts-ink);box-shadow:0 16px 64px #0008;font:13px/1.7 var(--prts-body);}& :is([data-prts-emblem-reset-confirm],[data-prts-emblem-workspace],[data-prts-emblem-discard])::backdrop{background:#0008;}& [data-prts-emblem-reset-confirm]{& > strong{display:block;font-size:16px;}& > p{margin:12px 0 18px;}& > [data-prts-emblem-actions]{justify-content:flex-end;padding-top:16px;border-top:1px solid var(--prts-line);}& [data-prts-emblem-reset-cancel]{border:0;background:transparent;}& [data-emblem-action]{display:flex;gap:6px;padding:5px 10px;font-size:12px;background:transparent;}& [data-prts-emblem-reset-status]:empty{display:none;}}& [data-prts-emblem-reset-exports]{display:grid;gap:8px;margin:18px 0;}& [data-prts-emblem-reset-asset]{display:grid;grid-template-columns:36px minmax(0,1fr) auto;gap:12px;align-items:center;padding:12px;border:1px solid var(--prts-line);border-radius:4px;}& [data-prts-emblem-reset-asset] > span{overflow-wrap:anywhere;line-height:1.5;}& [data-prts-emblem-reset-asset] canvas{width:36px;height:36px;border-radius:3px;}& [data-prts-emblem-workspace]{width:min(820px,calc(100vw - 24px));padding:0;max-height:90dvh;}
|
|
854
|
+
& [data-prts-emblem-editor]{display:grid;gap:14px;}& [data-prts-custom-emblem] :is(input,select){min-width:0;max-width:100%;}& [data-prts-custom-emblem] select{padding:8px;background:var(--prts-panel-raised);color:var(--prts-ink);border:1px solid var(--prts-line);}& [data-prts-emblem-preview]{touch-action:none;cursor:grab;width:min(100%,280px);height:auto;justify-self:center;border:1px solid var(--prts-line);border-radius:4px;}& [data-prts-emblem-actions]{display:flex;flex-wrap:wrap;gap:10px;}& [data-prts-emblem-actions] button{padding:10px 14px;border:1px solid var(--prts-line);border-radius:4px;color:var(--prts-ink);background:var(--prts-panel-raised);}& [data-prts-emblem-actions] button:disabled{opacity:.45;}& [data-prts-custom-emblem] h4{margin:8px 0 12px;font:600 14px/1.5 var(--prts-body);}& [data-prts-emblem-list]{display:grid;gap:10px;list-style:none;padding:0;margin:14px 0;}& :is([data-prts-emblem-list] > li,[data-prts-emblem-hero-row]){display:flex;align-items:center;flex-wrap:wrap;gap:10px;padding:12px;border:1px solid var(--prts-line);border-radius:4px;}& :is([data-prts-emblem-list],[data-prts-emblem-hero-row]) canvas{width:48px;height:48px;flex:none;border-radius:3px;}& :is([data-prts-emblem-list] > li,[data-prts-emblem-hero-row]) > span{flex:1;min-width:100px;overflow-wrap:anywhere;font-size:13px;}& [data-emblem-action]{padding:7px 10px;border:1px solid var(--prts-line);border-radius:4px;background:var(--prts-panel-raised);color:var(--prts-ink);}& [data-emblem-action]:disabled{opacity:.4;}& [data-prts-emblem-reorder]{padding:0;border:0;background:transparent;cursor:grab;}& [data-emblem-key]{touch-action:none;cursor:grab;user-select:none;-webkit-touch-callout:none}& [data-prts-emblem-reorder]:focus-visible{outline:2px solid var(--prts-ink);outline-offset:3px;}& [data-prts-emblem-sorting]{user-select:none;}& [data-prts-emblem-dragging]{opacity:.35;border-style:dashed !important;}& [data-prts-emblem-drag-ghost]{background:var(--prts-panel-raised);box-shadow:0 8px 28px #0005;opacity:.95;}& :is([data-prts-emblem-reset-confirm],[data-prts-emblem-workspace],[data-prts-emblem-discard]){position:fixed;inset:0;margin:auto;width:min(460px,calc(100vw - 32px));max-height:80dvh;box-sizing:border-box;overflow:auto;padding:24px;border:1px solid var(--prts-line);border-radius:8px;background:var(--prts-panel-raised);color:var(--prts-ink);box-shadow:0 16px 64px #0008;font:13px/1.7 var(--prts-body);}& :is([data-prts-emblem-reset-confirm],[data-prts-emblem-workspace],[data-prts-emblem-discard])::backdrop{background:#0008;}& [data-prts-emblem-reset-confirm]{& > strong{display:block;font-size:16px;}& > p{margin:12px 0 18px;}& > [data-prts-emblem-actions]{justify-content:flex-end;padding-top:16px;border-top:1px solid var(--prts-line);}& [data-prts-emblem-reset-cancel]{border:0;background:transparent;}& [data-emblem-action]{display:flex;gap:6px;padding:5px 10px;font-size:12px;background:transparent;}& [data-prts-emblem-reset-status]:empty{display:none;}}& [data-prts-emblem-reset-exports]{display:grid;gap:8px;margin:18px 0;}& [data-prts-emblem-reset-asset]{display:grid;grid-template-columns:36px minmax(0,1fr) auto;gap:12px;align-items:center;padding:12px;border:1px solid var(--prts-line);border-radius:4px;}& [data-prts-emblem-reset-asset] > span{overflow-wrap:anywhere;line-height:1.5;}& [data-prts-emblem-reset-asset] canvas{width:36px;height:36px;border-radius:3px;}& [data-prts-emblem-workspace]{width:min(820px,calc(100vw - 24px));padding:0;max-height:90dvh;}
|
|
855
855
|
& [data-prts-emblem-edit-header],& [data-prts-emblem-edit-bar]{display:flex;align-items:center;justify-content:space-between;gap:16px;padding:18px 22px;}
|
|
856
856
|
& [data-prts-emblem-edit-header]{border-bottom:1px solid var(--prts-line);}
|
|
857
857
|
& [data-prts-emblem-edit-header] button{border:0;background:none;color:inherit;font-size:22px;}
|