@ash-qw/dsh-theme-prts 1.3.1 → 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.
@@ -1,3 +1,4 @@
1
+ import { createSessionSummaryPreview, scrollSummaryTitle } from './session-summary-preview.js'
1
2
  import { ensureFacilityGraphic, ensureFacilityTextureDefs, renderFacilityGraphic } from './facility-vector.js'
2
3
  import { createSessionLifelineAnimator } from './session-lifeline.js'
3
4
 
@@ -189,7 +190,8 @@ function ensureFacilitySpine(document, row, kind, next) {
189
190
  }
190
191
 
191
192
 
192
- export function createSidebarControlAdapter({ document, window, sessions, workspaces, getSessionStatus, getUiWorkspace }) {
193
+ export function createSidebarControlAdapter({ document, window, sessions, workspaces, getSessionStatus, getUiWorkspace, getUiConversation, getSessions }) {
194
+ let previewPreferences = {}
193
195
  let observer
194
196
  let resizeObserver
195
197
  let resizeFrame
@@ -201,6 +203,9 @@ export function createSidebarControlAdapter({ document, window, sessions, worksp
201
203
  let statusSourcesStarted = false
202
204
  let summaryRoot
203
205
  let summarySignature = ''
206
+ const preview = createSessionSummaryPreview({ document, window, sessions, getUiConversation, getSessions, getSessionStatus, openSession, getPreviewPreferences: () => previewPreferences })
207
+ let stopTitles = []
208
+ function clearSummaryEffects() { preview.stop(false); for (const stop of stopTitles) stop(); stopTitles = [] }
204
209
  let owned = new Set()
205
210
  let vectorOwners = new Set()
206
211
  const dirtyVectors = new Map()
@@ -269,6 +274,19 @@ export function createSidebarControlAdapter({ document, window, sessions, worksp
269
274
  hint.textContent = '选择会话'
270
275
  heading.append(headingLabel, hint)
271
276
  popover.append(heading)
277
+ const reply = document.createElement('section')
278
+ reply.setAttribute('data-prts-summary-reply', '')
279
+ reply.setAttribute('role', 'note')
280
+ reply.setAttribute('popover', 'manual')
281
+ reply.hidden = true
282
+ reply.append(document.createElement('strong'), document.createElement('p'))
283
+ group.addEventListener('pointerleave', () => preview.leave())
284
+ group.addEventListener('focusout', event => {
285
+ if (!group.contains(event.relatedTarget)) preview.leave()
286
+ })
287
+ const list = document.createElement('span')
288
+ list.setAttribute('data-prts-summary-list', '')
289
+ popover.append(list)
272
290
  for (const item of items) {
273
291
  const button = document.createElement('button')
274
292
  button.type = 'button'
@@ -276,8 +294,21 @@ export function createSidebarControlAdapter({ document, window, sessions, worksp
276
294
  button.setAttribute('data-prts-session-summary-item', item.id)
277
295
  button.append(statusSignal(document, state))
278
296
  const title = document.createElement('span')
279
- title.textContent = item.title
297
+ title.setAttribute('data-prts-summary-title', '')
298
+ const text = document.createElement('span')
299
+ text.textContent = item.title
300
+ title.append(text)
280
301
  button.append(title)
302
+ button.setAttribute('aria-label', item.title)
303
+ stopTitles.push(scrollSummaryTitle(button, title, text, window))
304
+ const showReply = () => {
305
+ const key = {ongoing:'previewOngoing',warning:'previewWarning',done:'previewDone'}[state]
306
+ if (previewPreferences[key] === false) { preview.stop(); return }
307
+ preview.show(item.id, reply, item.title, button)
308
+ }
309
+ button.addEventListener('pointerenter', showReply)
310
+ button.addEventListener('pointerleave', () => preview.leave())
311
+ button.addEventListener('focus', showReply)
281
312
  if (item.statusLabel) {
282
313
  const detail = document.createElement('small')
283
314
  detail.setAttribute('data-prts-session-summary-item-status', '')
@@ -287,17 +318,21 @@ export function createSidebarControlAdapter({ document, window, sessions, worksp
287
318
  }
288
319
  button.addEventListener('click', event => {
289
320
  event.stopPropagation()
321
+ preview.stop()
290
322
  openSession(item.id)
291
323
  })
292
- popover.append(button)
324
+ list.append(button)
293
325
  }
326
+ popover.append(reply)
294
327
  group.append(trigger, popover)
295
328
  return group
296
329
  }
297
330
 
298
331
  function syncSummary(root, next) {
299
332
  const { header, label } = resolveSectionHeader(root)
300
- if (!header || !label) {
333
+ if (previewPreferences.sessionPreview === false || !header || !label) {
334
+ preview.stop()
335
+ clearSummaryEffects()
301
336
  summaryRoot?.remove()
302
337
  summaryRoot = undefined
303
338
  summarySignature = ''
@@ -349,10 +384,12 @@ export function createSidebarControlAdapter({ document, window, sessions, worksp
349
384
  summaryRoot.hidden = warning.length === 0 && ongoing.length === 0 && done.length === 0
350
385
  if (signature === summarySignature) return
351
386
  summarySignature = signature
387
+ clearSummaryEffects()
352
388
  summaryRoot.replaceChildren()
353
389
  if (warning.length) summaryRoot.append(buildSummaryGroup('warning', '等待处理的会话', warning))
354
390
  if (ongoing.length) summaryRoot.append(buildSummaryGroup('ongoing', '运行中的会话', ongoing))
355
391
  if (done.length) summaryRoot.append(buildSummaryGroup('done', '完成未查看', done))
392
+ preview.reanchor(summaryRoot)
356
393
  }
357
394
 
358
395
  function scheduleVectors() {
@@ -487,6 +524,8 @@ export function createSidebarControlAdapter({ document, window, sessions, worksp
487
524
  }
488
525
  syncSummary(root, next)
489
526
  } else {
527
+ preview.stop()
528
+ clearSummaryEffects()
490
529
  summaryRoot?.remove()
491
530
  summaryRoot = undefined
492
531
  summarySignature = ''
@@ -508,6 +547,8 @@ export function createSidebarControlAdapter({ document, window, sessions, worksp
508
547
  }
509
548
 
510
549
  function clear() {
550
+ preview.stop()
551
+ clearSummaryEffects()
511
552
  lifelineAnimator.setTarget(undefined, undefined)
512
553
  for (const node of document?.querySelectorAll?.('[data-prts-owned-projection], [data-prts-owned-facility], [data-prts-owned-facility-spine], [data-prts-owned-facility-vector], [data-prts-owned-facility-defs]') ?? []) node.remove()
513
554
  for (const node of owned) {
@@ -525,7 +566,10 @@ export function createSidebarControlAdapter({ document, window, sessions, worksp
525
566
  }
526
567
 
527
568
  return {
528
- start() {
569
+ start(preferences = {}) {
570
+ const keys = ['sessionPreview','previewOngoing','previewWarning','previewDone','previewDoubleClick']
571
+ if (keys.some(key => previewPreferences[key] !== preferences[key])) preview.stop()
572
+ previewPreferences = Object.fromEntries(keys.map(key => [key, preferences[key]]))
529
573
  if (!document) return
530
574
  lifelineAnimator.start()
531
575
  ensureFacilityTextureDefs(document)
@@ -550,7 +594,9 @@ export function createSidebarControlAdapter({ document, window, sessions, worksp
550
594
  if (observer || !window?.MutationObserver) return
551
595
  const observationRoot = document.querySelector('[data-prts-region="sessions"]')
552
596
  if (!observationRoot) return
553
- observer = new window.MutationObserver(queueScan)
597
+ observer = new window.MutationObserver(mutations => {
598
+ if (mutations.some(mutation => !mutation.target.closest?.('[data-prts-owned-session-summary]'))) queueScan()
599
+ })
554
600
  observer.observe(observationRoot, {
555
601
  subtree: true,
556
602
  childList: true,
@@ -40,6 +40,10 @@ const PARTICLE_OPTIONS = [
40
40
  ['precise', '精细', 18],
41
41
  ]
42
42
 
43
+ function previewSetting(key, label, description) {
44
+ return settingButtons(key, label, []).replace('</strong>', `</strong><small data-prts-preview-setting-description>${description}</small>`)
45
+ }
46
+
43
47
  function settingButtons(key, label, options) {
44
48
  const note = key === 'glass'
45
49
  ? '<small data-prts-setting-note data-prts-transparency-status hidden>系统当前要求降低透明度</small>'
@@ -60,7 +64,7 @@ function settingButtons(key, label, options) {
60
64
  : key === 'sessionFlowPalette'
61
65
  ? '<small data-prts-setting-note>同时适配日间与夜间模式</small>'
62
66
  : ''
63
- if (['cursor', 'railDefaultHidden', 'sessionFlow', 'sessionGlow', 'bakerGroupAvatars', 'conversationEmblem'].includes(key)) return `<div data-prts-setting-row="${key}">
67
+ if (['cursor', 'railDefaultHidden', 'sessionFlow', 'sessionGlow', 'bakerGroupAvatars', 'conversationEmblem', 'sessionPreview', 'previewOngoing', 'previewWarning', 'previewDone', 'previewDoubleClick'].includes(key)) return `<div data-prts-setting-row="${key}">
64
68
  <span><strong>${label}</strong>${note}</span>
65
69
  <button type="button" role="switch" aria-label="${label}" aria-checked="false" data-prts-setting-switch="${key}" ${key === 'cursor' ? 'data-prts-cursor-switch' : ''}><span aria-hidden="true"></span></button>
66
70
  </div>`
@@ -132,6 +136,7 @@ export function themeSettingsMarkup() {
132
136
  <button type="button" data-prts-settings-jump="interaction" role="tab" id="prts-tab-interaction" aria-controls="prts-page-interaction" aria-selected="false" tabindex="-1">交互</button>
133
137
  <button type="button" data-prts-settings-jump="flow" role="tab" id="prts-tab-flow" aria-controls="prts-page-flow" aria-selected="false" tabindex="-1">会话流线</button>
134
138
  <button type="button" data-prts-settings-jump="particles" role="tab" id="prts-tab-particles" aria-controls="prts-page-particles" aria-selected="false" tabindex="-1">粒子效果</button>
139
+ <button type="button" data-prts-settings-jump="assistance" role="tab" id="prts-tab-assistance" aria-controls="prts-page-assistance" aria-selected="false" tabindex="-1">辅助功能</button>
135
140
  </nav>
136
141
  <footer data-prts-settings-actions aria-label="全局主题设置操作">
137
142
  <div data-prts-persistence-error hidden role="alert">
@@ -142,7 +147,7 @@ export function themeSettingsMarkup() {
142
147
 
143
148
  <button type="button" data-prts-reset-visual title="恢复全部外观设置" aria-label="恢复全部外观设置">恢复默认</button>
144
149
  <div data-prts-reset-confirm hidden role="group" aria-label="确认恢复全部外观设置">
145
- <span>重置四个分类的外观参数,保留主题开关、启动动画和徽记配置。</span>
150
+ <span>重置全部分类的主题设置,保留主题开关、启动动画和徽记配置。</span>
146
151
  <button type="button" data-prts-reset-confirm-action>确认恢复</button>
147
152
  <button type="button" data-prts-reset-cancel>取消</button>
148
153
  </div>
@@ -180,6 +185,26 @@ export function themeSettingsMarkup() {
180
185
  ${COMMON_CONTROLS.filter(([key]) => ['cursor', 'railDefaultHidden', 'motion'].includes(key)).map(([key, label, options]) => settingButtons(key, label, options)).join('')}
181
186
  </div>
182
187
  </section>
188
+ <section data-prts-settings-section="assistance" role="tabpanel" id="prts-page-assistance" aria-labelledby="prts-tab-assistance" tabindex="0" hidden>
189
+ <header data-prts-section-heading><strong>辅助功能</strong><small>会话状态查看与快捷操作</small></header>
190
+ <section data-prts-preview-settings>
191
+ <div data-prts-preview-master>
192
+ ${previewSetting('sessionPreview', '会话状态预览', '在工作区右侧查看会话进度,无需切换当前会话')}
193
+ </div>
194
+ <div data-prts-preview-options>
195
+ <section data-prts-preview-setting-group>
196
+ <header><strong>悬停预览</strong><small>选择哪些状态显示详细浮窗</small></header>
197
+ ${previewSetting('previewOngoing', '运行中预览', '逐轮查看已完成的回复,最新内容置顶')}
198
+ ${previewSetting('previewWarning', '待处理预览(回答与审批)', '查看问题或审批请求,并直接提交选择')}
199
+ ${previewSetting('previewDone', '已完成预览', '查看本轮最终回复')}
200
+ </section>
201
+ <section data-prts-preview-setting-group>
202
+ <header><strong>快捷操作</strong></header>
203
+ ${previewSetting('previewDoubleClick', '双击浮窗进入会话', '双击正文或空白区域,打开对应会话')}
204
+ </section>
205
+ </div>
206
+ </section>
207
+ </section>
183
208
  <section data-prts-settings-common data-prts-settings-section="flow" role="tabpanel" id="prts-page-flow" aria-labelledby="prts-tab-flow" tabindex="0" hidden>
184
209
  <header data-prts-section-heading><strong>会话流线</strong><small>当前会话的流线与辉光</small></header>
185
210
  <div data-prts-settings-common-grid>
@@ -490,6 +515,8 @@ export function createThemeSettingsOverlay({
490
515
  toggle.setAttribute('aria-checked', String(enabled))
491
516
  toggle.classList.toggle('is-active', enabled)
492
517
  }
518
+ const previewOptions = panel.querySelector('[data-prts-preview-options]')
519
+ if (previewOptions) previewOptions.hidden = currentPreferences.sessionPreview === false
493
520
  for (const key of ['sessionGlow', 'sessionFlowPalette', 'sessionFlowColors', 'sessionFlowSpeed']) {
494
521
  const row = panel.querySelector(`[data-prts-setting-row="${key}"]`)
495
522
  if (row) row.hidden = currentPreferences.sessionFlow === false
@@ -187,7 +187,7 @@ html[data-dsh-prts] [data-prts-session-summary-popover] {
187
187
  opacity: 0;
188
188
  visibility: hidden;
189
189
  transform: translate3d(0, -4px, 0);
190
- transition: opacity 120ms ease, transform 160ms var(--prts-ease-snap), visibility 0s linear 160ms;
190
+ transition: opacity 70ms ease, transform 90ms var(--prts-ease-snap), visibility 0s linear 90ms;
191
191
  pointer-events: none;
192
192
  }
193
193
 
@@ -201,7 +201,7 @@ html[data-dsh-prts] [data-prts-session-summary-popover]::before {
201
201
  height: 16px;
202
202
  }
203
203
 
204
- html[data-dsh-prts] [data-prts-session-summary-group]:is(:hover, :has(:focus-visible)) [data-prts-session-summary-popover] {
204
+ html[data-dsh-prts] [data-prts-session-summary-group]:is(:hover, :has(:focus-visible), [data-prts-preview-open]) [data-prts-session-summary-popover] {
205
205
  opacity: 1;
206
206
  visibility: visible;
207
207
  transform: translate3d(0, 0, 0);
@@ -271,7 +271,7 @@ html[data-dsh-prts] [data-prts-session-summary-item-status] {
271
271
  font: 700 9px/1 var(--prts-mono);
272
272
  }
273
273
 
274
- html[data-dsh-prts] [data-prts-session-summary-item]:is(:hover, :focus-visible) {
274
+ html[data-dsh-prts] [data-prts-session-summary-item]:is(:hover, :focus-visible, [data-prts-preview-active]) {
275
275
  background: color-mix(in srgb, currentColor 9%, transparent);
276
276
  }
277
277
 
@@ -687,3 +687,91 @@ html[data-dsh-prts] :is(
687
687
  --prts-facility-outline: var(--prts-yellow);
688
688
  background: transparent !important;
689
689
  }
690
+
691
+ html[data-dsh-prts] [data-prts-summary-title] { flex:1; }
692
+ html[data-dsh-prts] [data-prts-summary-title] > span { display:block;width:max-content;min-width:100%; }
693
+ html[data-dsh-prts] [data-prts-summary-reply] {
694
+ position:fixed;
695
+ inset:auto;
696
+ width:296px;
697
+ color:var(--prts-ink);
698
+ box-sizing:border-box;
699
+ margin:0;
700
+ padding:12px 14px;
701
+ border:1px solid var(--prts-line);
702
+ border-radius:8px;
703
+ background:color-mix(in srgb, var(--prts-panel) 85%, transparent);
704
+ box-shadow:var(--prts-shadow-glass-overlay);
705
+ }
706
+ html[data-dsh-prts] [data-prts-summary-reply]::before {
707
+ content:"";
708
+ position:absolute;
709
+ top:0;
710
+ bottom:0;
711
+ right:100%;
712
+ width:12px;
713
+ }
714
+ html[data-dsh-prts] [data-prts-summary-reply][hidden] { display:none; }
715
+ html[data-dsh-prts] [data-prts-summary-reply] strong { display:block;color:var(--prts-muted);font:600 10px/1.5 var(--prts-body);letter-spacing:.04em;padding-bottom:8px;border-bottom:1px solid var(--prts-line); }
716
+ html[data-dsh-prts] [data-prts-summary-reply] [data-prts-preview-body] { margin:9px 0 0;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:4;max-height:6.6em;overflow:hidden;white-space:normal;overflow-wrap:anywhere;font:12px/1.65 var(--prts-body); }
717
+ html[data-dsh-prts] [data-prts-summary-list] { display:block;max-height:min(32dvh,260px);overflow-y:auto; }
718
+
719
+ html[data-dsh-prts] [data-prts-summary-reply][data-prts-preview-question] > strong { color:var(--prts-yellow); }
720
+ html[data-dsh-prts] [data-prts-summary-reply][data-prts-preview-question] > [data-prts-preview-body] { -webkit-line-clamp:2;max-height:3.3em;font-weight:500; }
721
+ html[data-dsh-prts] [data-prts-preview-choices] { display:flex;flex-wrap:wrap;gap:5px;margin-top:10px; }
722
+ html[data-dsh-prts] [data-prts-preview-choices][hidden] { display:none; }
723
+ html[data-dsh-prts] [data-prts-preview-choices] > span {
724
+ max-width:100%;box-sizing:border-box;padding:3px 7px;border-radius:4px;
725
+ background:color-mix(in srgb,var(--prts-ink) 7%,transparent);
726
+ color:var(--prts-muted);font:11px/1.5 var(--prts-body);
727
+ overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
728
+ }
729
+
730
+ html[data-dsh-prts] [data-prts-preview-actions] { display:flex;gap:6px;flex-wrap:wrap;margin-top:10px; }
731
+ html[data-dsh-prts] [data-prts-preview-actions]:empty { display:none; }
732
+ html[data-dsh-prts] [data-prts-preview-actions] button,
733
+ html[data-dsh-prts] [data-prts-preview-choices] button {
734
+ font:11px/1.5 var(--prts-body);color:var(--prts-ink);
735
+ background:color-mix(in srgb,var(--prts-ink) 6%,transparent);
736
+ border:1px solid var(--prts-line);border-radius:5px;padding:5px 9px;cursor:pointer;
737
+ }
738
+ html[data-dsh-prts] [data-prts-preview-actions] button:hover,
739
+ html[data-dsh-prts] [data-prts-preview-choices] button[aria-pressed="true"] { border-color:var(--prts-yellow);background:color-mix(in srgb,var(--prts-yellow) 12%,transparent); }
740
+ html[data-dsh-prts] [data-prts-preview-actions] button:disabled { opacity:.45;cursor:default; }
741
+ html[data-dsh-prts] [data-prts-preview-editing] { max-height:calc(100dvh - 16px);overflow:auto;background:color-mix(in srgb,var(--prts-panel) 95%,transparent); }
742
+ html[data-dsh-prts] [data-prts-preview-editing] > [data-prts-preview-body] { display:block;max-height:none; }
743
+ html[data-dsh-prts] [data-prts-preview-editing] [data-prts-preview-choices] { flex-direction:column; }
744
+ html[data-dsh-prts] [data-prts-preview-choices] button { text-align:left;white-space:normal;overflow-wrap:anywhere; }
745
+ html[data-dsh-prts] [data-prts-preview-actions] small { width:100%;color:var(--prts-muted);font:11px/1.5 var(--prts-body); }
746
+ html[data-dsh-prts] [data-prts-preview-choices] button small { display:block;margin-top:3px;color:var(--prts-muted);font:10px/1.5 var(--prts-body); }
747
+ html[data-dsh-prts] [data-prts-preview-state="ongoing"] > strong { color:var(--dsw-static-deepseek-450,var(--prts-cyan)); }
748
+ html[data-dsh-prts] [data-prts-preview-state="done"] > strong { color:var(--dsw-alias-state-success-primary,var(--prts-green)); }
749
+ html[data-dsh-prts] [data-prts-preview-state]:not([data-prts-preview-question]) > strong::before {
750
+ content:"";display:inline-block;width:5px;height:5px;margin-right:7px;background:currentColor;border-radius:50%;vertical-align:1px;
751
+ }
752
+ html[data-dsh-prts] [data-prts-preview-empty] > [data-prts-preview-body] { color:var(--prts-muted); }
753
+
754
+ html[data-dsh-prts] [data-prts-summary-reply]:not([data-prts-preview-question]) > [data-prts-preview-body] {
755
+ display:block;max-height:160px;white-space:normal;overflow:auto;overscroll-behavior:contain;
756
+ scrollbar-width:thin;scrollbar-color:var(--prts-muted) transparent;padding-right:5px;
757
+ }
758
+ html[data-dsh-prts] [data-prts-preview-body] :is(p,ul,ol,blockquote,pre,table,h1,h2,h3,h4,h5,h6) { margin:0 0 8px; }
759
+ html[data-dsh-prts] [data-prts-preview-body] > :last-child { margin-bottom:0; }
760
+ html[data-dsh-prts] [data-prts-preview-body] :is(h1,h2,h3,h4,h5,h6) { font:600 12px/1.6 var(--prts-body);color:var(--prts-ink); }
761
+ html[data-dsh-prts] [data-prts-preview-body] strong { display:inline;font:inherit;font-weight:600;color:inherit;letter-spacing:normal;padding:0;border:0; }
762
+ html[data-dsh-prts] [data-prts-preview-body] :is(ul,ol) { padding-left:18px; }
763
+ html[data-dsh-prts] [data-prts-preview-body] blockquote { padding-left:9px;border-left:2px solid var(--prts-line);color:var(--prts-muted); }
764
+ html[data-dsh-prts] [data-prts-preview-body] table { border-collapse:collapse;font-size:11px;min-width:100%; }
765
+ html[data-dsh-prts] [data-prts-preview-body] :is(th,td) { border:1px solid var(--prts-line);padding:4px 7px;text-align:left;min-width:64px; }
766
+ html[data-dsh-prts] [data-prts-preview-body] code { font:11px/1.6 var(--prts-mono);background:color-mix(in srgb,var(--prts-ink) 6%,transparent);border-radius:3px;padding:1px 3px; }
767
+ html[data-dsh-prts] [data-prts-preview-body] pre { padding:7px;background:color-mix(in srgb,var(--prts-ink) 5%,transparent);border-radius:4px;white-space:pre; }
768
+ html[data-dsh-prts] [data-prts-preview-body] pre code { background:none;padding:0; }
769
+ html[data-dsh-prts] [data-prts-preview-body] a { color:var(--prts-cyan);text-decoration:underline; }
770
+ html[data-dsh-prts] [data-prts-preview-message] + [data-prts-preview-message] { margin-top:5px; }
771
+ html[data-dsh-prts] [data-prts-preview-message] > small { display:block;margin-bottom:6px;color:var(--prts-muted);font:10px/1.5 var(--prts-mono); }
772
+
773
+ html[data-dsh-prts] [data-prts-reply-entry] { display:flex;align-items:flex-start;gap:8px;width:100%;padding:6px 8px;text-align:left;border:1px solid var(--prts-line);border-radius:5px;background:transparent;color:var(--prts-ink);cursor:pointer; }
774
+ html[data-dsh-prts] [data-prts-reply-entry]:is(:hover,:focus-visible,[data-prts-reply-active]) { background:color-mix(in srgb,var(--prts-ink) 7%,transparent);border-color:var(--prts-muted); }
775
+ html[data-dsh-prts] [data-prts-reply-entry] small { flex:0 0 auto;white-space:nowrap;padding-top:2px;color:var(--prts-muted);font:10px/1.5 var(--prts-mono); }
776
+ html[data-dsh-prts] [data-prts-reply-entry] span { min-width:0;flex:1;display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;overflow:hidden;font:12px/1.6 var(--prts-body);overflow-wrap:anywhere; }
777
+ html[data-dsh-prts] [data-prts-reply-detail]:not([data-prts-preview-question]) > [data-prts-preview-body] { max-height:190px; }
@@ -904,12 +904,6 @@ html[data-dsh-prts] [data-prts-session-row]::before {
904
904
  inset: 0 auto 0 0;
905
905
  width: var(--prts-spine-width);
906
906
  background: var(--prts-line-strong);
907
- clip-path: polygon(
908
- 3px 0, calc(100% - 3px) 0, 100% 3px,
909
- 100% calc(50% - 5px), calc(100% - 2px) calc(50% - 3px), calc(100% - 2px) calc(50% + 3px), 100% calc(50% + 5px),
910
- 100% calc(100% - 3px), calc(100% - 3px) 100%, 3px 100%, 0 calc(100% - 3px),
911
- 0 calc(50% + 5px), 2px calc(50% + 3px), 2px calc(50% - 3px), 0 calc(50% - 5px), 0 3px
912
- );
913
907
  transform: scaleX(var(--prts-spine-rest));
914
908
  transform-origin: left center;
915
909
  transition: transform 220ms var(--prts-ease-spring), background-color 160ms ease;
@@ -935,9 +929,9 @@ html[data-dsh-prts] [data-prts-facility-face] {
935
929
  3px 0,
936
930
  calc(50% - 25px) 0, calc(50% - 20px) 3.333px, calc(50% + 20px) 3.333px, calc(50% + 25px) 0,
937
931
  calc(100% - 3px) 0, 100% 3px,
938
- 100% calc(50% - 5px), calc(100% - 2px) calc(50% - 3px), calc(100% - 2px) calc(50% + 3px), 100% calc(50% + 5px),
932
+ 100% calc(50% - 5px), calc(100% - .824px) calc(50% - 3px), calc(100% - .824px) calc(50% + 3px), 100% calc(50% + 5px),
939
933
  100% calc(100% - 3px), calc(100% - 3px) 100%, 3px 100%, 0 calc(100% - 3px),
940
- 0 calc(50% + 5px), 2px calc(50% + 3px), 2px calc(50% - 3px), 0 calc(50% - 5px), 0 3px
934
+ 0 calc(50% + 5px), .824px calc(50% + 3px), .824px calc(50% - 3px), 0 calc(50% - 5px), 0 3px
941
935
  );
942
936
  transform: translate3d(var(--prts-row-shift), 0, 0);
943
937
  transition: transform 220ms var(--prts-ease-spring), border-color 160ms ease, background-color 160ms ease;
@@ -1036,7 +1030,7 @@ html[data-dsh-prts] [data-prts-session-actions] button {
1036
1030
  border-radius: 0 !important;
1037
1031
  background: var(--prts-panel-raised) !important;
1038
1032
  color: var(--prts-muted) !important;
1039
- clip-path: polygon(3px 0, calc(100% - 3px) 0, 100% 3px, 100% calc(50% - 5px), calc(100% - 2px) calc(50% - 3px), calc(100% - 2px) calc(50% + 3px), 100% calc(50% + 5px), 100% calc(100% - 3px), calc(100% - 3px) 100%, 3px 100%, 0 calc(100% - 3px), 0 calc(50% + 5px), 2px calc(50% + 3px), 2px calc(50% - 3px), 0 calc(50% - 5px), 0 3px);
1033
+ clip-path: polygon(3px 0, calc(100% - 3px) 0, 100% 3px, 100% calc(50% - 5px), calc(100% - .824px) calc(50% - 3px), calc(100% - .824px) calc(50% + 3px), 100% calc(50% + 5px), 100% calc(100% - 3px), calc(100% - 3px) 100%, 3px 100%, 0 calc(100% - 3px), 0 calc(50% + 5px), .824px calc(50% + 3px), .824px calc(50% - 3px), 0 calc(50% - 5px), 0 3px);
1040
1034
  cursor: pointer;
1041
1035
  }
1042
1036
 
@@ -55,9 +55,9 @@ html[data-dsh-prts] [data-prts-workspace-row]::before,
55
55
  html[data-dsh-prts] [data-prts-session-row]::before {
56
56
  clip-path: polygon(
57
57
  1px 0, calc(100% - 1px) 0, 100% 1px,
58
- 100% calc(50% - 5px), calc(100% - 2px) calc(50% - 3px), calc(100% - 2px) calc(50% + 3px), 100% calc(50% + 5px),
58
+ 100% calc(50% - 5px), 88.235% calc(50% - 3px), 88.235% calc(50% + 3px), 100% calc(50% + 5px),
59
59
  100% calc(100% - 1px), calc(100% - 1px) 100%, 1px 100%, 0 calc(100% - 1px),
60
- 0 calc(50% + 5px), 2px calc(50% + 3px), 2px calc(50% - 3px), 0 calc(50% - 5px), 0 1px
60
+ 0 calc(50% + 5px), 11.765% calc(50% + 3px), 11.765% calc(50% - 3px), 0 calc(50% - 5px), 0 1px
61
61
  ) !important;
62
62
  }
63
63
 
@@ -72,9 +72,9 @@ html[data-dsh-prts] [data-prts-facility-face] {
72
72
  1px 0,
73
73
  calc(50% - 25px) 0, calc(50% - 20px) 3.333px, calc(50% + 20px) 3.333px, calc(50% + 25px) 0,
74
74
  calc(100% - 1px) 0, 100% 1px,
75
- 100% calc(50% - 5px), calc(100% - 2px) calc(50% - 3px), calc(100% - 2px) calc(50% + 3px), 100% calc(50% + 5px),
75
+ 100% calc(50% - 5px), calc(100% - .824px) calc(50% - 3px), calc(100% - .824px) calc(50% + 3px), 100% calc(50% + 5px),
76
76
  100% calc(100% - 1px), calc(100% - 1px) 100%, 1px 100%, 0 calc(100% - 1px),
77
- 0 calc(50% + 5px), 2px calc(50% + 3px), 2px calc(50% - 3px), 0 calc(50% - 5px), 0 1px
77
+ 0 calc(50% + 5px), .824px calc(50% + 3px), .824px calc(50% - 3px), 0 calc(50% - 5px), 0 1px
78
78
  ) !important;
79
79
  }
80
80
 
@@ -87,9 +87,9 @@ html[data-dsh-prts] [data-prts-facility-face]::after {
87
87
  0 0,
88
88
  calc(50% - 24px) 0, calc(50% - 19px) 3.333px, calc(50% + 19px) 3.333px, calc(50% + 24px) 0,
89
89
  100% 0,
90
- 100% calc(50% - 4px), calc(100% - 2px) calc(50% - 2px), calc(100% - 2px) calc(50% + 2px), 100% calc(50% + 4px),
90
+ 100% calc(50% - 4px), calc(100% - .824px) calc(50% - 2px), calc(100% - .824px) calc(50% + 2px), 100% calc(50% + 4px),
91
91
  100% 100%, 0 100%,
92
- 0 calc(50% + 4px), 2px calc(50% + 2px), 2px calc(50% - 2px), 0 calc(50% - 4px)
92
+ 0 calc(50% + 4px), .824px calc(50% + 2px), .824px calc(50% - 2px), 0 calc(50% - 4px)
93
93
  );
94
94
  }
95
95
 
@@ -113,9 +113,9 @@ html[data-dsh-prts] [data-prts-session-actions] button {
113
113
  background: var(--prts-line) !important;
114
114
  clip-path: polygon(
115
115
  1px 0, calc(100% - 1px) 0, 100% 1px,
116
- 100% calc(50% - 5px), calc(100% - 2px) calc(50% - 3px), calc(100% - 2px) calc(50% + 3px), 100% calc(50% + 5px),
116
+ 100% calc(50% - 5px), calc(100% - .824px) calc(50% - 3px), calc(100% - .824px) calc(50% + 3px), 100% calc(50% + 5px),
117
117
  100% calc(100% - 1px), calc(100% - 1px) 100%, 1px 100%, 0 calc(100% - 1px),
118
- 0 calc(50% + 5px), 2px calc(50% + 3px), 2px calc(50% - 3px), 0 calc(50% - 5px), 0 1px
118
+ 0 calc(50% + 5px), .824px calc(50% + 3px), .824px calc(50% - 3px), 0 calc(50% - 5px), 0 1px
119
119
  ) !important;
120
120
  }
121
121
 
@@ -128,9 +128,9 @@ html[data-dsh-prts] [data-prts-session-actions] button::before {
128
128
  background: var(--prts-panel-raised);
129
129
  clip-path: polygon(
130
130
  0 0, 100% 0,
131
- 100% calc(50% - 4px), calc(100% - 2px) calc(50% - 2px), calc(100% - 2px) calc(50% + 2px), 100% calc(50% + 4px),
131
+ 100% calc(50% - 4px), calc(100% - .824px) calc(50% - 2px), calc(100% - .824px) calc(50% + 2px), 100% calc(50% + 4px),
132
132
  100% 100%, 0 100%,
133
- 0 calc(50% + 4px), 2px calc(50% + 2px), 2px calc(50% - 2px), 0 calc(50% - 4px)
133
+ 0 calc(50% + 4px), .824px calc(50% + 2px), .824px calc(50% - 2px), 0 calc(50% - 4px)
134
134
  );
135
135
  pointer-events: none;
136
136
  }
@@ -915,3 +915,23 @@ html[data-dsh-prts]{
915
915
  [data-prts-avatar-crop] [data-prts-avatar-upload]{padding:6px 10px;font-size:12px}
916
916
  }
917
917
  @media(max-width:480px){html[data-dsh-prts] [data-prts-conversation-cards]{grid-template-columns:1fr}}
918
+ html[data-dsh-prts] [data-prts-preview-settings] {
919
+ & { border:1px solid var(--prts-line);border-radius:8px;overflow:hidden;background:var(--prts-panel); }
920
+ & [data-prts-setting-row] { display:flex;align-items:center;justify-content:space-between;gap:20px;padding:14px 0;border:0;background:none; }
921
+ & [data-prts-setting-row] > span { display:grid;gap:5px;min-width:0; }
922
+ & [data-prts-setting-row] strong { font:600 12px/1.5 var(--prts-body); }
923
+ & [data-prts-preview-setting-description] { color:var(--prts-muted);font:400 11px/1.6 var(--prts-body); }
924
+ & [data-prts-preview-master] { padding:8px 20px;background:color-mix(in srgb,var(--prts-yellow) 5%,transparent); }
925
+ & [data-prts-preview-master] [data-prts-setting-row] strong { font-size:14px; }
926
+ & [data-prts-preview-options] { padding:0 20px 6px;border-top:1px solid var(--prts-line); }
927
+ & [data-prts-preview-setting-group] { padding:18px 0 4px; }
928
+ & [data-prts-preview-setting-group] + [data-prts-preview-setting-group] { border-top:1px solid var(--prts-line); }
929
+ & [data-prts-preview-setting-group] > header { display:flex;flex-wrap:wrap;align-items:baseline;gap:6px 12px;margin-bottom:3px; }
930
+ & [data-prts-preview-setting-group] > header strong { color:var(--prts-muted);font:600 11px/1.5 var(--prts-body); }
931
+ & [data-prts-preview-setting-group] > header small { color:var(--prts-muted);font:400 10px/1.5 var(--prts-body); }
932
+ @media(max-width:640px) {
933
+ & [data-prts-preview-master] { padding-inline:14px; }
934
+ & [data-prts-preview-options] { padding-inline:14px; }
935
+ & [data-prts-setting-row] { gap:12px; }
936
+ }
937
+ }