@ash-qw/dsh-theme-prts 2.2.0 → 2.3.1
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 +22 -0
- package/README.en.md +10 -0
- package/README.md +10 -0
- package/THIRD_PARTY_NOTICES.md +1 -1
- package/THIRD_PARTY_NOTICES.zh-CN.md +1 -1
- package/lib/client.js +733 -62
- package/package.json +2 -2
- package/src/client/background-layout.js +59 -0
- package/src/client/background-region-editor.js +103 -0
- package/src/client/conversation-control-adapter.js +2 -0
- package/src/client/cursor-adapter.js +1 -1
- package/src/client/custom-background.js +23 -6
- package/src/client/index.js +10 -0
- package/src/client/native-preferences.js +31 -0
- package/src/client/operations-shell-v2.js +2 -2
- package/src/client/particle-field-adapter.js +67 -14
- package/src/client/preferences.js +3 -1
- package/src/client/session-card-reveal.js +125 -0
- package/src/client/sidebar-control-adapter.js +40 -35
- package/src/client/theme-controller-v2.js +2 -1
- package/src/client/theme-settings-workbench.js +13 -5
- package/src/client/theme-transfer-panel.js +98 -0
- package/src/client/theme-transfer.js +170 -0
- package/src/server/backgrounds.js +10 -6
- package/src/shared/background-region.js +21 -0
- package/src/styles/cursor.css +8 -0
- package/src/styles/custom-background.css +83 -13
- package/src/styles/prts.css +2 -2
- package/src/styles/refinement.css +28 -0
- package/src/styles/theme-settings-workbench.css +87 -2
|
@@ -2,6 +2,7 @@ import { mkdir, readFile, writeFile, rename, rm } from 'node:fs/promises'
|
|
|
2
2
|
import { join } from 'node:path'
|
|
3
3
|
import { randomUUID } from 'node:crypto'
|
|
4
4
|
import sharp from 'sharp'
|
|
5
|
+
import { validBackgroundRegion } from '../shared/background-region.js'
|
|
5
6
|
import { body, json, isBase64 } from './api.js'
|
|
6
7
|
import { fault } from './emblems.js'
|
|
7
8
|
|
|
@@ -26,8 +27,11 @@ export async function createBackgroundService(directory) {
|
|
|
26
27
|
const task = queue.then(async () => {
|
|
27
28
|
if (!BACKGROUND_SLOTS.includes(data?.slot)) throw fault(400, '背景区域无效')
|
|
28
29
|
if (data.revision !== state.revision) throw fault(409, '背景已在其他页面更新,请重新操作')
|
|
29
|
-
|
|
30
|
-
if (data.
|
|
30
|
+
const regionOnly = Object.hasOwn(data, 'region') && !Object.hasOwn(data, 'image')
|
|
31
|
+
if (Object.hasOwn(data, 'region') && !validBackgroundRegion(data.region)) throw fault(400, '背景保护区域无效')
|
|
32
|
+
if (regionOnly && !state[data.slot]) throw fault(400, '请先上传背景图片')
|
|
33
|
+
let entry = regionOnly ? { ...state[data.slot], region: data.region } : null, output
|
|
34
|
+
if (!regionOnly && data.image !== null) {
|
|
31
35
|
if (!isBase64(data.image) || data.image.length > 14 * 1024 * 1024) throw fault(400, '请上传不超过 10 MB 的图片')
|
|
32
36
|
const bytes = Buffer.from(data.image, 'base64')
|
|
33
37
|
if (!bytes.length || bytes.length > 10 * 1024 * 1024) throw fault(400, '请上传不超过 10 MB 的图片')
|
|
@@ -37,22 +41,22 @@ export async function createBackgroundService(directory) {
|
|
|
37
41
|
if (!['png', 'jpeg', 'webp', 'avif'].includes(metadata.format)) throw Error('format')
|
|
38
42
|
const result = await input.rotate().resize({ width: 3840, height: 2160, fit: 'inside', withoutEnlargement: true }).webp({ quality: 86 }).toBuffer({ resolveWithObject: true })
|
|
39
43
|
output = result.data
|
|
40
|
-
entry = { id: randomUUID(), width: result.info.width, height: result.info.height }
|
|
44
|
+
entry = { id: randomUUID(), width: result.info.width, height: result.info.height, region: data.region ?? null }
|
|
41
45
|
} catch { throw fault(400, '无法读取图片,请使用 PNG、JPEG、WebP 或 AVIF(最多 4000 万像素)') }
|
|
42
46
|
}
|
|
43
47
|
const next = { ...state, revision: state.revision + 1, [data.slot]: entry }
|
|
44
48
|
const temporary = configurationPath + '.' + randomUUID() + '.tmp'
|
|
45
49
|
try {
|
|
46
|
-
if (
|
|
50
|
+
if (output) await writeFile(join(directory, entry.id + '.webp'), output, { mode: 0o600 })
|
|
47
51
|
await writeFile(temporary, JSON.stringify(next), { mode: 0o600 })
|
|
48
52
|
await rename(temporary, configurationPath)
|
|
49
53
|
} catch (error) {
|
|
50
|
-
if (
|
|
54
|
+
if (output) await rm(join(directory, entry.id + '.webp'), { force: true }).catch(() => {})
|
|
51
55
|
throw error
|
|
52
56
|
} finally { await rm(temporary, { force: true }).catch(() => {}) }
|
|
53
57
|
const previous = state[data.slot]
|
|
54
58
|
state = next
|
|
55
|
-
if (previous) await rm(join(directory, previous.id + '.webp'), { force: true }).catch(() => {})
|
|
59
|
+
if (previous && previous.id !== entry?.id) await rm(join(directory, previous.id + '.webp'), { force: true }).catch(() => {})
|
|
56
60
|
for (const listener of listeners) { try { listener(state.revision) } catch {} }
|
|
57
61
|
return snapshot()
|
|
58
62
|
})
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
// Coordinates are fractions of the oriented, stored image.
|
|
2
|
+
export function validBackgroundRegion(region) {
|
|
3
|
+
return region === null || (region && typeof region === 'object' && !Array.isArray(region)
|
|
4
|
+
&& ['x','y','width','height'].every(key => Number.isFinite(region[key]))
|
|
5
|
+
&& region.x >= 0 && region.y >= 0 && region.width > 0 && region.height > 0
|
|
6
|
+
&& region.x + region.width <= 1.000001 && region.y + region.height <= 1.000001)
|
|
7
|
+
}
|
|
8
|
+
export function backgroundPlacement(imageWidth, imageHeight, width, height, region = null) {
|
|
9
|
+
if (![imageWidth,imageHeight,width,height].every(v => Number.isFinite(v) && v > 0)) return {x:0,y:0,width:0,height:0,clipped:false}
|
|
10
|
+
const scale = Math.max(width / imageWidth, height / imageHeight)
|
|
11
|
+
const w = imageWidth * scale, h = imageHeight * scale
|
|
12
|
+
const clamp = (v,a,b) => Math.max(a,Math.min(b,v))
|
|
13
|
+
const axis = (size, viewport, start, length, vertical = false) => {
|
|
14
|
+
const centered = (viewport-size)/2
|
|
15
|
+
if (!region) return centered
|
|
16
|
+
if (length*size > viewport) return clamp(vertical ? -start*size : viewport/2-(start+length/2)*size,viewport-size,0)
|
|
17
|
+
return clamp(centered, Math.max(viewport-size,-start*size), Math.min(0,viewport-(start+length)*size))
|
|
18
|
+
}
|
|
19
|
+
return {x:axis(w,width,region?.x,region?.width),y:axis(h,height,region?.y,region?.height,true),width:w,height:h,
|
|
20
|
+
clipped:Boolean(region && (region.width*w > width+.01 || region.height*h > height+.01))}
|
|
21
|
+
}
|
package/src/styles/cursor.css
CHANGED
|
@@ -33,3 +33,11 @@
|
|
|
33
33
|
html[data-dsh-prts] :is([data-prts-emblem-sort-active],[data-prts-emblem-sort-active] *) {
|
|
34
34
|
cursor: var(--prts-sort-cursor, grabbing) !important;
|
|
35
35
|
}
|
|
36
|
+
|
|
37
|
+
/* The crop surface uses one native cursor family, including during pointer capture. */
|
|
38
|
+
html[data-dsh-prts] [data-prts-region-stage] { cursor:default; }
|
|
39
|
+
html[data-dsh-prts] [data-prts-region-stage] [data-prts-region-box] { cursor:move; }
|
|
40
|
+
html[data-dsh-prts] [data-prts-region-stage] [data-prts-region-handle] { cursor:ns-resize!important; }
|
|
41
|
+
html[data-dsh-prts] [data-prts-region-stage] :is([data-prts-region-handle="e"],[data-prts-region-handle="w"]) { cursor:ew-resize!important; }
|
|
42
|
+
html[data-dsh-prts] [data-prts-region-stage] :is([data-prts-region-handle="nw"],[data-prts-region-handle="se"]) { cursor:nwse-resize!important; }
|
|
43
|
+
html[data-dsh-prts] [data-prts-region-stage] :is([data-prts-region-handle="ne"],[data-prts-region-handle="sw"]) { cursor:nesw-resize!important; }
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
/* Viewport-aligned wallpaper. */
|
|
2
2
|
html[data-dsh-prts] { --prts-background-wash: color-mix(in srgb, var(--prts-canvas) var(--prts-background-shade, 45%), transparent); }
|
|
3
3
|
html[data-dsh-prts][data-prts-background-mode="full"][data-prts-background-full] :is([data-prts-region="frame"], [data-prts-nav-rail]) {
|
|
4
|
-
background: linear-gradient(var(--prts-background-wash), var(--prts-background-wash)), var(--prts-background-full)
|
|
4
|
+
background: linear-gradient(var(--prts-background-wash), var(--prts-background-wash)), var(--prts-background-full) var(--prts-protected-full-x, 50%) var(--prts-protected-full-y, 50%) / cover fixed;
|
|
5
5
|
}
|
|
6
6
|
html[data-dsh-prts][data-prts-background-mode="full"][data-prts-background-full] :is([data-prts-region="sessions"], [data-prts-region="operation"]) { background: transparent; }
|
|
7
7
|
html[data-dsh-prts][data-prts-background-mode="split"][data-prts-background-sidebar] {
|
|
8
|
-
--prts-wall-width:max(calc(var(--prts-sidebar-width,280px) + var(--prts-nav-width)),calc((100dvh - var(--prts-host-top-inset)) * var(--prts-sidebar-image-ratio,1)));
|
|
9
|
-
--prts-wall-x:calc((var(--prts-sidebar-width,280px) + var(--prts-nav-width) - var(--prts-wall-width)) / 2);
|
|
10
|
-
& :is([data-prts-region="sessions"],[data-prts-nav-rail]){background:linear-gradient(var(--prts-background-wash),var(--prts-background-wash)),var(--prts-background-sidebar) var(--prts-wall-x)
|
|
11
|
-
& [data-prts-region="sessions"]{background-position:center,calc(var(--prts-wall-x) - var(--prts-nav-width))
|
|
8
|
+
--prts-wall-width:var(--prts-protected-sidebar-width,max(calc(var(--prts-sidebar-width,280px) + var(--prts-nav-width)),calc((100dvh - var(--prts-host-top-inset)) * var(--prts-sidebar-image-ratio,1))));
|
|
9
|
+
--prts-wall-x:var(--prts-protected-sidebar-x,calc((var(--prts-sidebar-width,280px) + var(--prts-nav-width) - var(--prts-wall-width)) / 2));
|
|
10
|
+
& :is([data-prts-region="sessions"],[data-prts-nav-rail]){background:linear-gradient(var(--prts-background-wash),var(--prts-background-wash)),var(--prts-background-sidebar) var(--prts-wall-x) var(--prts-protected-sidebar-y, 50%) / var(--prts-wall-width) auto no-repeat}
|
|
11
|
+
& [data-prts-region="sessions"]{background-position:center,calc(var(--prts-wall-x) - var(--prts-nav-width)) var(--prts-protected-sidebar-y, 50%)}
|
|
12
12
|
}
|
|
13
13
|
html[data-dsh-prts][data-prts-rail-mode="overlay"]:is([data-prts-background-mode="split"][data-prts-background-sidebar],[data-prts-background-mode="full"][data-prts-background-full]) [data-prts-nav-rail] { background: transparent; }
|
|
14
14
|
html[data-dsh-prts][data-prts-background-mode="split"][data-prts-background-conversation] [data-prts-region="operation"] {
|
|
15
|
-
background: linear-gradient(var(--prts-background-wash), var(--prts-background-wash)), var(--prts-background-conversation)
|
|
15
|
+
background: linear-gradient(var(--prts-background-wash), var(--prts-background-wash)), var(--prts-background-conversation) var(--prts-protected-conversation-x, 50%) var(--prts-protected-conversation-y, 50%) / cover no-repeat;
|
|
16
16
|
}
|
|
17
17
|
html[data-dsh-prts][data-prts-background-mode="full"][data-prts-background-full] [data-prts-ambient-layer],
|
|
18
18
|
html[data-dsh-prts][data-prts-background-mode="split"][data-prts-background-conversation] [data-prts-ambient-layer] { display: none !important; }
|
|
@@ -34,13 +34,23 @@ html[data-dsh-prts][data-prts-background-mode="split"][data-prts-background-conv
|
|
|
34
34
|
[data-prts-background-images] { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 14px; }
|
|
35
35
|
[data-prts-background-card="full"] { grid-column: 1 / -1; }
|
|
36
36
|
[data-prts-background-card-heading] { display: flex; justify-content: space-between; align-items: center; min-height: 30px; margin-bottom: 6px; font-size: 13px; }
|
|
37
|
-
[data-prts-background-
|
|
38
|
-
[data-prts-background-card="full"] [data-prts-background-
|
|
39
|
-
[data-prts-background-
|
|
40
|
-
[data-prts-background-
|
|
41
|
-
[data-prts-background-
|
|
42
|
-
[data-prts-background-
|
|
43
|
-
|
|
37
|
+
[data-prts-background-image-controls] { position:relative;display:grid;place-items:center;min-height:140px;border:1px dashed var(--prts-line);border-radius:8px;background:var(--prts-panel);overflow:hidden; }
|
|
38
|
+
[data-prts-background-card="full"] [data-prts-background-image-controls] { min-height:180px; }
|
|
39
|
+
[data-prts-background-image-controls][data-has-image] { border-style:solid; }
|
|
40
|
+
[data-prts-background-thumbnail] { position:absolute;inset:0;background:center / cover no-repeat;pointer-events:none; }
|
|
41
|
+
[data-prts-background-empty] {font-size:12px;color:var(--prts-muted);padding-bottom:40px}
|
|
42
|
+
[data-has-image] [data-prts-background-empty] {visibility:hidden}
|
|
43
|
+
/* One compact toolbar stays legible over either bright or dark photography. */
|
|
44
|
+
[data-prts-background-image-actions] {position:absolute;bottom:10px;right:10px;display:flex;align-items:center;gap:2px;padding:2px;border:1px solid #ffffff26;border-radius:7px;background:rgb(20 26 30 / 82%);backdrop-filter:blur(12px);-webkit-backdrop-filter:blur(12px);box-shadow:0 2px 8px #0002;color:#edf2f3}
|
|
45
|
+
[data-prts-background-image-actions] button {display:inline-flex;align-items:center;justify-content:center;gap:5px;min-height:26px;padding:4px 7px;border:0;border-radius:5px;background:transparent;color:inherit;box-shadow:none;font:500 11px/1.2 var(--prts-body);white-space:nowrap;cursor:pointer;transition:background-color 120ms ease,color 120ms ease}
|
|
46
|
+
[data-prts-background-image-actions] button + button {position:relative}
|
|
47
|
+
[data-prts-background-image-actions] button + button::before {content:"";position:absolute;left:-1px;top:7px;bottom:7px;width:1px;background:#ffffff24}
|
|
48
|
+
[data-prts-background-image-actions] button[hidden] + button::before {display:none}
|
|
49
|
+
[data-prts-background-image-actions] svg {width:13px;height:13px;flex:none;fill:none;stroke:currentColor;stroke-width:1.4;stroke-linecap:round;stroke-linejoin:round;opacity:.8}
|
|
50
|
+
[data-prts-background-image-actions] button:hover {background:#ffffff18;color:#fff}
|
|
51
|
+
[data-prts-background-image-actions] button:active {background:#ffffff28}
|
|
52
|
+
[data-prts-background-image-actions] button:disabled {opacity:.45;cursor:wait}
|
|
53
|
+
[data-prts-background-settings] [data-prts-background-image-actions] button:focus-visible {outline:2px solid #b9e6ee;outline-offset:-2px}
|
|
44
54
|
[data-prts-background-remove] { padding: 4px 8px; background: transparent; color: var(--prts-muted); border: 0; border-radius: 4px; font-size: 12px; cursor: pointer; }
|
|
45
55
|
[data-prts-background-remove]:hover { color: var(--prts-red); background: color-mix(in srgb, var(--prts-red) 8%, transparent); }
|
|
46
56
|
[data-prts-background-shade] { display: grid; gap: 8px; font-size: 13px; padding-top: 14px; border-top: 1px solid var(--prts-line); }
|
|
@@ -329,3 +339,63 @@ animation: prts-baker-typing 1.2s linear infinite;
|
|
|
329
339
|
33% { background: currentColor; box-shadow: -10px 0 0 color-mix(in srgb,currentColor 30%,transparent), 10px 0 0 color-mix(in srgb,currentColor 30%,transparent); }
|
|
330
340
|
66% { background: color-mix(in srgb,currentColor 30%,transparent); box-shadow: -10px 0 0 color-mix(in srgb,currentColor 30%,transparent), 10px 0 0 currentColor; }
|
|
331
341
|
}
|
|
342
|
+
|
|
343
|
+
/* Keep the hero treatment beside the background readability controls. */
|
|
344
|
+
html[data-dsh-prts] [data-prts-background-hero-setting] {
|
|
345
|
+
padding:16px 0 2px; border-top:1px solid var(--prts-line);
|
|
346
|
+
& [data-prts-setting-row] { display:grid; grid-template-columns:minmax(0,1fr) auto; align-items:center; gap:20px; margin:0; padding:0; border:0; background:none; }
|
|
347
|
+
& [data-prts-setting-row] > span { display:grid; gap:5px; min-width:0; }
|
|
348
|
+
& strong { font:500 13px/1.5 var(--prts-body); color:var(--prts-ink); }
|
|
349
|
+
& small { max-width:36em; font:400 12px/1.6 var(--prts-body); color:var(--prts-muted); }
|
|
350
|
+
& [data-prts-setting-switch] { justify-self:end; align-self:center; margin:0; }
|
|
351
|
+
}
|
|
352
|
+
html[data-dsh-prts] [data-prts-background-hero-setting][hidden] { display:none; }
|
|
353
|
+
|
|
354
|
+
/* Windows chrome must not clip a different canvas color into the conversation. */
|
|
355
|
+
html[data-dsh-prts][data-windows-titlebar] [data-prts-region="operation"] { border-radius: 0; }
|
|
356
|
+
|
|
357
|
+
[data-prts-region-editor] { width:min(1000px,calc(100vw - 32px));max-width:none;max-height:calc(100dvh - 32px);box-sizing:border-box;margin:auto;padding:24px;border:1px solid var(--prts-line);border-radius:14px;background:var(--prts-panel);color:var(--prts-ink);overflow:auto; }
|
|
358
|
+
[data-prts-region-editor]:not([open]) {display:none}
|
|
359
|
+
[data-prts-region-editor]::backdrop {background:#0009;backdrop-filter:blur(5px)}
|
|
360
|
+
[data-prts-region-editor] > header {display:flex;justify-content:space-between;align-items:start;gap:20px;margin-bottom:24px}
|
|
361
|
+
[data-prts-region-editor] > header strong {font-size:18px}
|
|
362
|
+
[data-prts-region-workspace] {display:grid;grid-template-columns:minmax(0,1.5fr) minmax(290px,1fr);gap:28px}
|
|
363
|
+
[data-prts-region-original],[data-prts-region-samples] {display:grid;align-content:start;gap:12px;min-width:0}
|
|
364
|
+
[data-prts-region-original] {padding:0 8px 0 24px}
|
|
365
|
+
[data-prts-region-stage] {margin:24px 0 12px}
|
|
366
|
+
[data-prts-region-preview-grid] {display:grid;grid-template-columns:minmax(0,1.5fr) minmax(0,1fr);gap:14px;align-items:start;margin-top:12px}
|
|
367
|
+
[data-prts-region-preview-grid] figure {display:grid;justify-items:center;align-content:start;gap:12px;margin:0;min-width:0}
|
|
368
|
+
[data-prts-region-preview-grid] figcaption {font-size:11px;color:var(--prts-muted)}
|
|
369
|
+
[data-prts-region-editor] > footer {display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-top:24px;padding-top:16px;border-top:1px solid var(--prts-line)}
|
|
370
|
+
[data-prts-region-editor] > footer > span {flex:1}
|
|
371
|
+
[data-prts-region-ruler] {position:absolute;pointer-events:none;color:var(--prts-muted);font:10px/1 var(--prts-mono)}
|
|
372
|
+
[data-prts-region-ruler="x"] {left:0;right:0;top:-20px;height:10px;border-bottom:1px solid var(--prts-line)}
|
|
373
|
+
[data-prts-region-ruler="y"] {top:0;bottom:0;left:-24px;width:16px;border-right:1px solid var(--prts-line)}
|
|
374
|
+
[data-prts-region-ruler] span,[data-prts-region-ruler] b {position:absolute;font-weight:400}
|
|
375
|
+
[data-prts-region-ruler="x"] span,[data-prts-region-ruler="x"] b {transform:translateX(-50%)}
|
|
376
|
+
[data-prts-region-ruler="y"] span,[data-prts-region-ruler="y"] b {transform:translateY(-50%)}
|
|
377
|
+
[data-prts-region-ruler] b {background:var(--prts-panel);color:var(--prts-cyan);z-index:1}
|
|
378
|
+
@media(max-width:760px){[data-prts-region-editor]{padding:18px;width:calc(100vw - 16px);max-height:calc(100dvh - 16px)}[data-prts-region-workspace]{grid-template-columns:1fr}[data-prts-region-preview-grid]{grid-template-columns:1fr 1fr}[data-prts-region-editor] > footer > span{display:none}}
|
|
379
|
+
[data-prts-region-editor] p { margin:0;font-size:12px;color:var(--prts-muted); }
|
|
380
|
+
[data-prts-region-stage] { position:relative;max-width:100%;justify-self:center;touch-action:none;user-select:none;cursor:default; }
|
|
381
|
+
[data-prts-region-stage] img { display:block;width:100%;height:auto;pointer-events:none; }
|
|
382
|
+
[data-prts-region-box] { position:absolute;box-sizing:border-box;border:2px solid #fff;outline:1px solid #111;box-shadow:0 0 0 1px #111;background:#ffffff08;cursor:move;touch-action:none; }
|
|
383
|
+
[data-prts-region-box] > span { position:absolute;top:4px;left:4px;background:#111b;color:#fff;font-size:10px;white-space:nowrap;pointer-events:none; }
|
|
384
|
+
[data-prts-region-handle] { position:absolute;width:16px!important;height:16px!important;min-width:0!important;padding:0!important;border:1px solid #111!important;background:#fff!important;border-radius:3px!important;touch-action:none; }
|
|
385
|
+
[data-prts-region-handle="nw"] {left:-8px;top:-8px;cursor:nwse-resize}
|
|
386
|
+
[data-prts-region-handle="ne"] {right:-8px;top:-8px;cursor:nesw-resize}
|
|
387
|
+
[data-prts-region-handle="sw"] {left:-8px;bottom:-8px;cursor:nesw-resize}
|
|
388
|
+
[data-prts-region-handle="se"] {right:-8px;bottom:-8px;cursor:nwse-resize}
|
|
389
|
+
[data-prts-region-preview] { position:relative;justify-self:center;max-width:100%;overflow:hidden;background-repeat:no-repeat;border:1px solid var(--prts-line);box-sizing:content-box; }
|
|
390
|
+
[data-prts-region-preview] i { position:absolute;border:1px solid #fff;box-shadow:0 0 0 1px #111;box-sizing:border-box;pointer-events:none; }
|
|
391
|
+
[data-prts-region-actions] { display:flex;gap:8px;flex-wrap:wrap; }
|
|
392
|
+
[data-prts-region-editor] button { padding:6px 10px;border:1px solid var(--prts-line);border-radius:5px;background:var(--prts-panel);color:var(--prts-ink);cursor:pointer;font-size:12px; }
|
|
393
|
+
[data-prts-region-save] { border-color:var(--prts-cyan)!important; }
|
|
394
|
+
[data-prts-region-status]:empty {display:none}
|
|
395
|
+
|
|
396
|
+
[data-prts-region-editor="sidebar"] [data-prts-region-preview-grid] {grid-template-columns:minmax(0,1fr) minmax(0,1.45fr)}
|
|
397
|
+
|
|
398
|
+
[data-prts-region-handle="n"] {left:50%;top:-8px;transform:translateX(-50%);cursor:ns-resize}
|
|
399
|
+
[data-prts-region-handle="s"] {left:50%;bottom:-8px;transform:translateX(-50%);cursor:ns-resize}
|
|
400
|
+
[data-prts-region-handle="w"] {left:-8px;top:50%;transform:translateY(-50%);cursor:ew-resize}
|
|
401
|
+
[data-prts-region-handle="e"] {right:-8px;top:50%;transform:translateY(-50%);cursor:ew-resize}
|
package/src/styles/prts.css
CHANGED
|
@@ -1907,12 +1907,12 @@ html[data-dsh-prts][data-prts-conversation-style="deck-chat"] {
|
|
|
1907
1907
|
& [data-message-role="assistant"]::after,
|
|
1908
1908
|
& :is([data-chat-flow-kind="user"], [data-submission-echo]:not([data-pending-steering])) [class$="_bubble"]::before,
|
|
1909
1909
|
& [data-message-role="user"]::before {
|
|
1910
|
-
content: ""; position: absolute; top: 0; left: -
|
|
1910
|
+
content: ""; position: absolute; top: 0; left: -10px; width: 10px; height: 18px; pointer-events: none;
|
|
1911
1911
|
background: var(--prts-bubble-surface, var(--prts-chat-user-surface));
|
|
1912
1912
|
mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 10 18'%3E%3Cpath d='M0 0H10V18Q10 6 0 0Z'/%3E%3C/svg%3E") center / 100% 100% no-repeat;
|
|
1913
1913
|
}
|
|
1914
1914
|
& :is([data-chat-flow-kind="user"], [data-submission-echo]:not([data-pending-steering])) [class$="_bubble"]::before,
|
|
1915
|
-
& [data-message-role="user"]::before { left: auto; right: -
|
|
1915
|
+
& [data-message-role="user"]::before { left: auto; right: -10px; transform: scaleX(-1); }
|
|
1916
1916
|
}
|
|
1917
1917
|
|
|
1918
1918
|
/* The upstream component replaces only the composer's two background plates. */
|
|
@@ -393,6 +393,12 @@ html[data-dsh-prts] [data-prts-conversation-control="danger"] {
|
|
|
393
393
|
}
|
|
394
394
|
|
|
395
395
|
/* Empty session: emblem owns the upper field, composer anchors in the lower third. */
|
|
396
|
+
/* Reserve the native blank header before session restoration adds its controls.
|
|
397
|
+
Otherwise its height grows from 0 to 40px after the emblem has been positioned. */
|
|
398
|
+
html[data-dsh-prts] [data-phase="hero"] > [data-slot="conversation.header"] > header {
|
|
399
|
+
min-height: 40px;
|
|
400
|
+
}
|
|
401
|
+
|
|
396
402
|
html[data-dsh-prts] [data-prts-hero-active] {
|
|
397
403
|
--prts-hero-narrow-spacer: clamp(24px, 8dvh, 72px);
|
|
398
404
|
--prts-hero-wide-spacer: clamp(96px, 22dvh, 340px);
|
|
@@ -482,3 +488,25 @@ html[data-dsh-prts][data-prts-conversation-style="deck-chat"] :is([class$="_bubb
|
|
|
482
488
|
padding:2px 7px!important;border-radius:6px!important;
|
|
483
489
|
&:is(:hover,:focus-visible){border-color:var(--prts-cyan)!important}
|
|
484
490
|
}
|
|
491
|
+
|
|
492
|
+
/* Notification cards own one surface across the disclosure and its content. */
|
|
493
|
+
html[data-dsh-prts] [data-turn-trigger] {
|
|
494
|
+
background:var(--prts-glass-soft-surface);
|
|
495
|
+
border:1px solid var(--prts-line);
|
|
496
|
+
border-radius:var(--dsw-radius-xl,16px);
|
|
497
|
+
-webkit-backdrop-filter:blur(12px);
|
|
498
|
+
backdrop-filter:blur(12px);
|
|
499
|
+
color:var(--prts-ink);
|
|
500
|
+
& > button {
|
|
501
|
+
background:transparent;
|
|
502
|
+
border:0;
|
|
503
|
+
border-radius:inherit;
|
|
504
|
+
color:inherit;
|
|
505
|
+
&:hover { background:color-mix(in srgb,var(--prts-ink) 5%,transparent); }
|
|
506
|
+
&:focus-visible { outline:2px solid var(--prts-cyan); outline-offset:-3px; }
|
|
507
|
+
& time { color:var(--prts-muted); }
|
|
508
|
+
}
|
|
509
|
+
& > div { border-top:1px solid var(--prts-line); }
|
|
510
|
+
& > div > p { color:var(--prts-muted); }
|
|
511
|
+
& [data-context-text] { color:var(--prts-ink); }
|
|
512
|
+
}
|
|
@@ -757,9 +757,9 @@ html[data-dsh-prts] [data-prts-theme-settings] {
|
|
|
757
757
|
& [data-prts-reset-confirm] > span { flex-basis:100%; }
|
|
758
758
|
@media(max-width:720px) {
|
|
759
759
|
& [data-prts-settings-sidebar] { flex-direction:row; border:0; border-bottom:1px solid var(--prts-line); }
|
|
760
|
-
& [data-prts-settings-nav] { flex:1; padding:8px 4px; border:0; }
|
|
760
|
+
& [data-prts-settings-nav] { flex:1; min-width:0; overflow-x:auto; padding:8px 4px; border:0; }
|
|
761
761
|
& [data-prts-settings-jump] { padding:10px 8px; }
|
|
762
|
-
& [data-prts-settings-actions] { margin:0; padding:8px 4px; align-self:center; }
|
|
762
|
+
& [data-prts-settings-actions] { flex:0 0 auto; white-space:nowrap; margin:0; padding:8px 4px; align-self:center; }
|
|
763
763
|
& [data-prts-reset-confirm], & [data-prts-persistence-error] { left:auto; right:8px; top:100%; bottom:auto; max-width:calc(100vw - 32px); }
|
|
764
764
|
}
|
|
765
765
|
& [data-prts-reset-zone] { padding: 0; }
|
|
@@ -929,3 +929,88 @@ html[data-dsh-prts] [data-prts-ai-tools] blockquote { margin:12px 0;padding:8px
|
|
|
929
929
|
html[data-dsh-prts] [data-prts-ai-tools] summary { cursor:pointer; }
|
|
930
930
|
html[data-dsh-prts] [data-prts-ai-tools] dt { margin-top:12px; }
|
|
931
931
|
html[data-dsh-prts] [data-prts-ai-tools] dd { margin:3px 0 0; }
|
|
932
|
+
|
|
933
|
+
html[data-dsh-prts] [data-prts-transfer] {
|
|
934
|
+
display: grid;
|
|
935
|
+
gap: 16px;
|
|
936
|
+
padding-block: 16px;
|
|
937
|
+
& header { display: grid; gap: 8px; }
|
|
938
|
+
& p, & small { margin: 0; color: var(--prts-muted); line-height: 1.7; overflow-wrap: anywhere; }
|
|
939
|
+
& label { display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
|
|
940
|
+
& input[type="file"] { max-width: 100%; min-width: 0; }
|
|
941
|
+
& input[type="checkbox"] { accent-color: var(--prts-yellow); }
|
|
942
|
+
& button { justify-self: start; padding: 8px 14px; border: 1px solid var(--prts-line-strong); border-radius: 0; background: var(--prts-panel-raised); color: var(--prts-ink); font: inherit; cursor: pointer; }
|
|
943
|
+
& button:hover:not(:disabled) { border-color: var(--prts-yellow); }
|
|
944
|
+
& button:focus-visible { outline: 2px solid var(--prts-yellow); outline-offset: 3px; }
|
|
945
|
+
& button:disabled { opacity: .55; cursor: wait; }
|
|
946
|
+
& [data-prts-transfer-export], & [data-prts-transfer-apply] { border-color: var(--prts-yellow); }
|
|
947
|
+
& hr { width: 100%; border: 0; border-top: 1px solid var(--prts-line); }
|
|
948
|
+
& [data-prts-transfer-preview], & [data-prts-transfer-recovery] { display: grid; gap: 12px; padding: 16px; border: 1px solid var(--prts-line); }
|
|
949
|
+
& [hidden] { display: none !important; }
|
|
950
|
+
}
|
|
951
|
+
|
|
952
|
+
html[data-dsh-prts] [data-prts-theme-settings] [data-prts-settings-actions] { display:flex; flex-direction:column; align-items:stretch; gap:8px; }
|
|
953
|
+
html[data-dsh-prts] [data-prts-transfer-open] { display:flex; align-items:center; gap:8px; width:100%; padding:10px 8px; background:none; border:1px solid var(--prts-line); border-radius:4px; color:var(--prts-ink); font:500 12px/1.4 var(--prts-body); cursor:pointer; }
|
|
954
|
+
html[data-dsh-prts] [data-prts-transfer-open]:hover { border-color:var(--prts-yellow); }
|
|
955
|
+
html[data-dsh-prts] [data-prts-transfer-dialog] { box-sizing:border-box; width:min(660px,calc(100vw - 32px)); max-height:calc(100dvh - 48px); padding:0; border:1px solid var(--prts-line-strong); border-radius:8px; background:var(--prts-canvas); color:var(--prts-ink); box-shadow:0 24px 80px #0006; font:13px/1.6 var(--prts-body); overflow:auto; }
|
|
956
|
+
html[data-dsh-prts] [data-prts-transfer-dialog]::backdrop { background:#0007; }
|
|
957
|
+
html[data-dsh-prts] [data-prts-transfer] {
|
|
958
|
+
padding:24px; gap:20px;
|
|
959
|
+
& [data-prts-transfer-heading] { display:flex; align-items:center; justify-content:space-between; gap:16px; }
|
|
960
|
+
& h2 { margin:4px 0 0; font-size:20px; line-height:1.4; }
|
|
961
|
+
& h3 { margin:0; font-size:14px; }
|
|
962
|
+
& [data-prts-transfer-close] { padding:2px 10px; font-size:24px; border:0; background:none; }
|
|
963
|
+
& [data-prts-transfer-columns] { display:grid; grid-template-columns:1fr 1fr; gap:24px; }
|
|
964
|
+
& [data-prts-transfer-card] { display:flex; flex-direction:column; gap:12px; min-width:0; }
|
|
965
|
+
& [data-prts-transfer-card] + section { padding-left:24px; border-left:1px solid var(--prts-line); }
|
|
966
|
+
& [data-prts-transfer-card] > button { margin-top:auto; display:flex; align-items:center; justify-content:space-between; }
|
|
967
|
+
& [data-prts-transfer-option] { align-items:flex-start; flex-wrap:nowrap; padding:12px 0 0; }
|
|
968
|
+
& [data-prts-transfer-option] input { margin:5px 0 0; }
|
|
969
|
+
& [data-prts-transfer-option] small { display:block; margin-top:4px; }
|
|
970
|
+
& [data-prts-transfer-file-hint] { display:grid; place-items:center; flex:1; gap:6px; padding:12px; border:1px dashed var(--prts-line-strong); }
|
|
971
|
+
& [data-prts-transfer-file-hint] > span { font-size:24px; color:var(--prts-muted); }
|
|
972
|
+
& [data-prts-transfer-buttons] { display:flex; gap:8px; }
|
|
973
|
+
& [data-prts-transfer-recovery] { border:0; border-top:1px solid var(--prts-line); padding:16px 0 0; }
|
|
974
|
+
& [data-prts-transfer-status]:empty { display:none; }
|
|
975
|
+
}
|
|
976
|
+
@media(max-width:720px) {
|
|
977
|
+
html[data-dsh-prts] [data-prts-theme-settings] [data-prts-settings-body] { grid-template-rows:auto minmax(0,1fr) auto; }
|
|
978
|
+
html[data-dsh-prts] [data-prts-theme-settings] [data-prts-settings-sidebar] { display:contents; }
|
|
979
|
+
html[data-dsh-prts] [data-prts-theme-settings] [data-prts-settings-nav] { grid-row:1; }
|
|
980
|
+
html[data-dsh-prts] [data-prts-theme-settings] [data-prts-theme-settings-scroll] { grid-row:2; }
|
|
981
|
+
html[data-dsh-prts] [data-prts-theme-settings] [data-prts-settings-actions] { grid-row:3; position:relative; flex-direction:row; align-items:center; justify-content:space-between; padding:12px 16px; border-top:1px solid var(--prts-line); background:var(--prts-canvas); }
|
|
982
|
+
html[data-dsh-prts] [data-prts-transfer-open] { width:auto; }
|
|
983
|
+
html[data-dsh-prts] [data-prts-theme-settings] :is([data-prts-reset-confirm],[data-prts-persistence-error]) { top:auto; bottom:100%; }
|
|
984
|
+
}
|
|
985
|
+
@media(max-width:540px) {
|
|
986
|
+
html[data-dsh-prts] [data-prts-transfer] { padding:20px; }
|
|
987
|
+
html[data-dsh-prts] [data-prts-transfer] [data-prts-transfer-columns] { grid-template-columns:1fr; gap:20px; }
|
|
988
|
+
html[data-dsh-prts] [data-prts-transfer] [data-prts-transfer-card] + section { padding:20px 0 0; border-left:0; border-top:1px solid var(--prts-line); }
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
/* Shared quiet actions below the settings categories. */
|
|
992
|
+
html[data-dsh-prts] [data-prts-theme-settings] [data-prts-settings-actions] {
|
|
993
|
+
padding:12px 10px; gap:2px; border-top:1px solid var(--prts-line);
|
|
994
|
+
}
|
|
995
|
+
html[data-dsh-prts] [data-prts-theme-settings] [data-prts-footer-action] {
|
|
996
|
+
display:flex; align-items:center; justify-content:flex-start; gap:10px;
|
|
997
|
+
width:100%; min-height:40px; padding:10px; margin:0;
|
|
998
|
+
border:0; border-radius:5px; clip-path:none; box-shadow:none;
|
|
999
|
+
background:transparent; color:var(--prts-muted);
|
|
1000
|
+
font:500 12px/1.4 var(--prts-body); text-align:left; cursor:pointer;
|
|
1001
|
+
}
|
|
1002
|
+
html[data-dsh-prts] [data-prts-footer-action] svg {
|
|
1003
|
+
width:16px; height:16px; flex:none; fill:none; stroke:currentColor;
|
|
1004
|
+
stroke-width:1.5; stroke-linecap:round; stroke-linejoin:round;
|
|
1005
|
+
}
|
|
1006
|
+
html[data-dsh-prts] [data-prts-theme-settings] [data-prts-footer-action]:hover {
|
|
1007
|
+
background:var(--prts-panel-raised); color:var(--prts-ink);
|
|
1008
|
+
}
|
|
1009
|
+
html[data-dsh-prts] [data-prts-theme-settings] [data-prts-footer-action]:focus-visible {
|
|
1010
|
+
outline:2px solid var(--prts-yellow); outline-offset:-2px;
|
|
1011
|
+
}
|
|
1012
|
+
html[data-dsh-prts] [data-prts-theme-settings] [data-prts-footer-action][hidden] { display:none; }
|
|
1013
|
+
@media(max-width:720px) {
|
|
1014
|
+
html[data-dsh-prts] [data-prts-theme-settings] [data-prts-settings-actions] { display:grid; grid-template-columns:1fr 1fr; gap:8px; padding:8px 12px; }
|
|
1015
|
+
html[data-dsh-prts] [data-prts-theme-settings] [data-prts-reset-zone] { width:100%; }
|
|
1016
|
+
}
|