@vllm-sr/dsh 0.5.0 → 0.5.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/README.md CHANGED
@@ -75,8 +75,8 @@ instead of whole passages:
75
75
 
76
76
  ## See it in the Web UI
77
77
 
78
- In `dsh web`, System One shows up in the conversation itself, where it acted, marked with an ember **System One**
79
- badge that carries the decision's latency:
78
+ In `dsh web`, System One shows up in the conversation itself, where it acted, marked with a blue **System One** badge
79
+ (the blue of the vLLM logo) that carries the decision's latency:
80
80
 
81
81
  - **Triage**: a card under your request with the kind of work, the effort, how unclear and how risky it is, and the
82
82
  brief System Two was given.
@@ -94,9 +94,9 @@ badge that carries the decision's latency:
94
94
 
95
95
  Routine checks (an allowed call, a clean result) are one line and fold with the turn's work. Cards stay visible when
96
96
  the work folds, so a finished turn still shows what System One decided. Parallel calls in one step share one line or
97
- card, and every decision pops in with a short animation the first time it appears (none with reduced motion). Each
98
- element shows the Decision API's own answer: the probabilities, the model (in bold, as `vllm-sr/d3-ultra`) and the
99
- measured latency.
97
+ card. A decision that takes longer than a moment shows as **Deciding** until its answer takes its place, and every
98
+ decision fades in once, the first time it appears (no motion with reduced motion). Each element shows the Decision
99
+ API's own answer: the probabilities, the model (in bold, as `vllm-sr/d3-ultra`) and the measured latency.
100
100
 
101
101
  Set `systemOneUi` to `compact` for one line per decision, or to `off` to hide them.
102
102
 
@@ -109,18 +109,18 @@ attributes that say what it shows:
109
109
  | --- | --- |
110
110
  | `data-system-one` | `card`, `compact` (one line), `tool` (the `system_one` row) or `notice` (the free-key line) |
111
111
  | `data-system-one-reflex` | `triage`, `guard`, `shield`, `privacy`, `done`, `tool` or `key` |
112
- | `data-system-one-verdict` | triage `brief`; guard `allow`, `ask` or `deny`; shield `clean`, `removed` or `flagged`; privacy `masked`; done-check `stop` or `continue`; tool `running` or `done`; key `created` or `failed`; `error` when System One did not answer |
112
+ | `data-system-one-verdict` | triage `brief`; guard `allow`, `ask` or `deny`; shield `clean`, `removed` or `flagged`; privacy `masked` or `clean`; done-check `stop` or `continue`; tool `running` or `done`; key `created` or `failed`; `deciding` while System One has not answered yet, `cancelled` when the turn stopped first; `error` when System One did not answer |
113
113
  | `data-system-one-outcome` | guard, once you answer its approval: `allowed`, `rejected`, `cancelled` or `failed` |
114
114
  | `data-system-one-why` | done-check: `complete`, `waiting`, `unfinished`, `unchecked` or `unsupported` |
115
- | `data-system-one-tone` | its colour: `ok` (green), `info` (ember), `warn` (amber), `bad` (red) or `muted` |
115
+ | `data-system-one-tone` | its colour: `ok` (green), `info` (blue), `warn` (amber), `bad` (red) or `muted` |
116
116
  | `data-system-one-count` | how many decisions it holds (a batch: how many items) |
117
117
  | `data-system-one-turn`, `data-system-one-step` | where it acted (the step for guard and shield) |
118
118
  | `data-system-one-model` | the model that answered, as `vllm-sr/d3-ultra` |
119
119
  | `data-system-one-span-model`, `data-system-one-spans` | the span model that marked words, as `vllm-sr/vela3-turbo`, and how many |
120
120
 
121
- Inside a root, `data-system-one-part` marks `badge` (the ember **System One** pill), `latency`, `reflex`, `summary`,
121
+ Inside a root, `data-system-one-part` marks `badge` (the blue **System One** pill), `latency`, `reflex`, `summary`,
122
122
  `model`, `head`, `toggle` (the button of a one-line element), `rows`, `verdict`, `outcome`, `subject`, `facts`,
123
- `note` and `more`, in the batch row also `stack`, `legend`, `failed`, `results` and `raw`, and in the free-key line
123
+ `note`, `more` and `progress` (the line that moves while it decides), in the batch row also `stack`, `legend`, `failed`, `results` and `raw`, and in the free-key line
124
124
  `badge` (the **System Duo** pill), `summary` and `links`. Span answers add `excerpts`, each `excerpt`, every marked
125
125
  `span` (with `data-system-one-span-label` and `data-system-one-probability`) and, in a Privacy card, the `labels`. Each
126
126
  number is a `data-system-one-fact`: `kind`, `effort`, `unclear` and `risky` (triage), `risk`, `leaks` and `on-task`
@@ -137,7 +137,8 @@ number is a `data-system-one-fact`: `kind`, `effort`, `unclear` and `risky` (tri
137
137
  | A routine check (one line) | `[data-system-one="compact"][data-system-one-reflex="guard"]`, and `"shield"` |
138
138
  | Done-check | `[data-system-one-reflex="done"]` |
139
139
  | Batch row, finished | `[data-system-one="tool"][data-system-one-verdict="done"]` |
140
- | The ember badge, and its latency | `[data-system-one-part="badge"]`, `[data-system-one-part="latency"]` |
140
+ | The blue badge, and its latency | `[data-system-one-part="badge"]`, `[data-system-one-part="latency"]` |
141
+ | System One still deciding | `[data-system-one-verdict="deciding"]`, and its `[data-system-one-part="progress"]` |
141
142
  | "Dangerous", and "You rejected it" | `[data-system-one-fact="risk"]`, `[data-system-one-part="outcome"]` |
142
143
  | The reason | `[data-system-one-part="note"]` |
143
144
  | The model's name (bold) | `[data-system-one-part="model"]` |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vllm-sr/dsh",
3
- "version": "0.5.0",
3
+ "version": "0.5.1",
4
4
  "description": "System Duo for DeepSeek Harness. Thinking, fast and slow: System One decision models guard, shield, triage and check your agent around System Two (vllm-sr/auto), with a free app.vllm-sr.ai key.",
5
5
  "keywords": [
6
6
  "deepseek-harness",
package/src/index.js CHANGED
@@ -89,6 +89,8 @@ export const Config = z.object({
89
89
  const SOURCE = { kind: 'system-one' }
90
90
  // how long a step waits for the free keys of the first run before it goes on without them
91
91
  const KEYS_WAIT_MS = 20000
92
+ // a decision that takes longer than this shows in Chat as deciding until its answer takes its place
93
+ export const DECIDING_MS = 700
92
94
 
93
95
  const PROMPT = `# System One
94
96
  You are System Two: you plan, reason and act. Beside you runs System One, a fast decision model that answers typed questions with calibrated probabilities in a fraction of a second. It watches the loop:
@@ -175,6 +177,33 @@ export function apply(ctx, config) {
175
177
  })
176
178
  const sessions = new Map()
177
179
 
180
+ // One decision's record. It is written once the answer is there, unless the answer takes longer than DECIDING_MS:
181
+ // then a deciding record goes first, and the answer, which carries the same decision id, takes its place in Chat.
182
+ let decisions = 0
183
+ function deciding(session, data) {
184
+ const decision = `${Date.now().toString(36)}.${(decisions++).toString(36)}`
185
+ let shown = false
186
+ const timer = setTimeout(() => {
187
+ shown = record(session, { ...data, decision, pending: true })
188
+ }, DECIDING_MS)
189
+ timer.unref?.()
190
+ return {
191
+ // the answer is in, and its record waits for the rest of the step
192
+ hold() {
193
+ clearTimeout(timer)
194
+ },
195
+ answer(final) {
196
+ clearTimeout(timer)
197
+ return record(session, { ...data, decision, ...final })
198
+ },
199
+ // no answer: a record that said deciding now says the turn stopped first
200
+ drop() {
201
+ clearTimeout(timer)
202
+ if (shown) record(session, { ...data, decision, verdict: 'cancelled' })
203
+ },
204
+ }
205
+ }
206
+
178
207
  // Whether spanModel answers span questions: `auto` asks the published models list, again every ten minutes.
179
208
  let spanCheck
180
209
  function spansOn() {
@@ -375,15 +404,16 @@ export function apply(ctx, config) {
375
404
  `The agent now wants to run:\n${describeCall(exec)}`,
376
405
  ].join('\n\n')
377
406
  const base = { reflex: 'guard', turn: state?.turn, step: state?.step, callId: exec.callId, tool: exec.name, call: subject(relativeTo(briefCall(exec), workspace, homedir())) }
407
+ const decision = deciding(exec.agent.session, base)
378
408
  let response
379
409
  try {
380
410
  response = await client.ask({ model: config.model, questions: GUARD, inputs: [{ state: situation }], signal: exec.signal, timeoutMs: config.hookTimeoutMs, retries: config.hookRetries })
381
411
  } catch (error) {
382
412
  trace({ ev: 's1', reflex: 'guard', session: state?.id, tool: exec.name, call: briefCall(exec), error: String(error?.message ?? error) })
383
413
  if (!exec.signal?.aborted) {
384
- record(exec.agent.session, { ...base, verdict: config.guardOnError, error: subject(error?.message ?? error) })
414
+ decision.answer({ verdict: config.guardOnError, error: subject(error?.message ?? error) })
385
415
  if (config.guardOnError === 'ask') state?.asked.set(exec.callId, base)
386
- }
416
+ } else decision.drop()
387
417
  if (config.guardOnError === 'deny') return { kind: 'deny', reason: `System One is unavailable (${error?.message ?? error}); the call was not run.` }
388
418
  if (config.guardOnError === 'ask') return { kind: 'ask', reason: 'System One is unavailable', displayReason: { en: 'System One is unavailable: allow this call?' } }
389
419
  return next()
@@ -425,8 +455,8 @@ export function apply(ctx, config) {
425
455
  ev: 's1', reflex: 'guard', session: state?.id, turn: state?.turn, tool: exec.name, call: briefCall(exec), model: response.model,
426
456
  ms: ms(response.ms), verdict, why, answers: answersOf(answers), ...(danger ? { spanModel: danger.model, danger: danger.spans } : {}),
427
457
  })
428
- record(exec.agent.session, {
429
- ...base, model: response.model, ms: ms(response.ms), requestId: response.requestId, answers: answersOf(answers), verdict, why,
458
+ decision.answer({
459
+ model: response.model, ms: ms(response.ms), requestId: response.requestId, answers: answersOf(answers), verdict, why,
430
460
  ...(danger ? { spanModel: danger.model, spanMs: ms(danger.ms), danger: danger.spans } : {}),
431
461
  })
432
462
  if (verdict === 'ask') state?.asked.set(exec.callId, base)
@@ -476,7 +506,9 @@ export function apply(ctx, config) {
476
506
 
477
507
  let verdict
478
508
  let elapsed
509
+ let shielding
479
510
  if (screens && full.length >= config.shieldMinChars) {
511
+ shielding = deciding(exec.agent.session, { reflex: 'shield', ...target })
480
512
  const started = performance.now()
481
513
  try {
482
514
  verdict = await screen({
@@ -486,9 +518,11 @@ export function apply(ctx, config) {
486
518
  })
487
519
  } catch (error) {
488
520
  trace({ ev: 's1', reflex: 'shield', session: state?.id, tool: exec.name, call: briefCall(exec), error: String(error?.message ?? error) })
489
- if (!exec.signal?.aborted) record(exec.agent.session, { reflex: 'shield', ...target, error: subject(error?.message ?? error) })
521
+ if (!exec.signal?.aborted) shielding.answer({ error: subject(error?.message ?? error) })
522
+ else shielding.drop()
490
523
  }
491
524
  elapsed = performance.now() - started
525
+ shielding.hold()
492
526
  }
493
527
  if (verdict) {
494
528
  trace({
@@ -498,14 +532,20 @@ export function apply(ctx, config) {
498
532
  flagged: verdict.flagged.map(entry => ({ p: round3(entry.p), text: clip(entry.text, 400), lines: entry.lines.map(line => ({ p: round3(line.p), text: line.text })), spans: entry.spans })),
499
533
  })
500
534
  }
501
- const downstream = await next()
535
+ let downstream
536
+ try {
537
+ downstream = await next()
538
+ } catch (error) {
539
+ shielding?.drop()
540
+ throw error
541
+ }
502
542
  const removed = verdict && (verdict.removedLines > 0 || verdict.removedSpans > 0)
503
543
  if (verdict) {
504
544
  // A later handler that blocks the result keeps the whole passage from the model, so the injection was found, not removed.
505
545
  const outcome = !removed ? 'clean' : downstream.kind === 'block' ? 'flagged' : 'removed'
506
546
  const shown = verdict.flagged.flatMap(entry => entry.excerpts).slice(0, 2)
507
- record(exec.agent.session, {
508
- reflex: 'shield', ...target, model: verdict.model, ms: ms(elapsed), passages: verdict.passages, flagged: verdict.flagged.length,
547
+ shielding.answer({
548
+ model: verdict.model, ms: ms(elapsed), passages: verdict.passages, flagged: verdict.flagged.length,
509
549
  removedLines: verdict.removedLines, maxP: round3(verdict.maxP), verdict: outcome,
510
550
  ...(verdict.spanModel ? { spanModel: verdict.spanModel, spanMs: ms(verdict.spanMs) } : {}),
511
551
  ...(verdict.removedSpans ? { removedSpans: verdict.removedSpans, removedChars: verdict.removedChars, excerpts: shown } : {}),
@@ -521,7 +561,9 @@ export function apply(ctx, config) {
521
561
  state.privacyOff = true
522
562
  record(exec.agent.session, { reflex: 'privacy', ...target, verdict: 'error', error: `${config.spanModel} answers no span questions yet` })
523
563
  }
564
+ let masking
524
565
  if (masks && spans) {
566
+ masking = deciding(exec.agent.session, { reflex: 'privacy', ...target })
525
567
  const started = performance.now()
526
568
  try {
527
569
  const parts = windows(body, 12000)
@@ -538,19 +580,17 @@ export function apply(ctx, config) {
538
580
  privacy = { model, ms: performance.now() - started, spans: found }
539
581
  } catch (error) {
540
582
  trace({ ev: 's1', reflex: 'privacy', session: state?.id, tool: exec.name, call: briefCall(exec), error: String(error?.message ?? error) })
541
- if (!exec.signal?.aborted) record(exec.agent.session, { reflex: 'privacy', ...target, verdict: 'error', error: subject(error?.message ?? error) })
583
+ if (!exec.signal?.aborted) masking.answer({ verdict: 'error', error: subject(error?.message ?? error) })
584
+ else masking.drop()
542
585
  }
543
586
  }
544
587
  const hidden = privacy?.spans.length ? privacy.spans : []
545
588
  if (privacy) {
546
589
  const labels = labelCounts(hidden)
547
590
  trace({ ev: 's1', reflex: 'privacy', session: state?.id, turn: state?.turn, tool: exec.name, call: briefCall(exec), model: privacy.model, ms: ms(privacy.ms), masked: hidden.length, labels })
548
- if (hidden.length) {
549
- record(exec.agent.session, {
550
- reflex: 'privacy', ...target, model: privacy.model, ms: ms(privacy.ms), verdict: 'masked', masked: hidden.length, labels,
551
- excerpts: excerpts(body, hidden, { hide: true, around: 40, max: 3 }),
552
- })
553
- }
591
+ masking.answer(hidden.length
592
+ ? { model: privacy.model, ms: ms(privacy.ms), verdict: 'masked', masked: hidden.length, labels, excerpts: excerpts(body, hidden, { hide: true, around: 40, max: 3 }) }
593
+ : { model: privacy.model, ms: ms(privacy.ms), verdict: 'clean', masked: 0 })
554
594
  }
555
595
  if (!removed && hidden.length === 0) return downstream
556
596
 
@@ -593,6 +633,7 @@ export function apply(ctx, config) {
593
633
  const reads = state.reads ?? []
594
634
  // a plain cut: clip's "(+N chars)" would read as a claim of the answer
595
635
  const answered = (state.assistant || '').slice(0, 8000)
636
+ const decision = deciding(agent.session, { reflex: 'done', turn, step: state.step })
596
637
  let haluTask
597
638
  if (config.doneHalu && reads.length > 0 && answered && (await spansOn())) {
598
639
  const evidence = []
@@ -617,7 +658,8 @@ export function apply(ctx, config) {
617
658
  response = await client.ask({ model: config.model, questions: DONE, inputs: [{ state: situation }], signal, timeoutMs: config.hookTimeoutMs, retries: config.hookRetries })
618
659
  } catch (error) {
619
660
  trace({ ev: 's1', reflex: 'done', session: state.id, turn, error: String(error?.message ?? error) })
620
- if (!signal?.aborted) record(agent.session, { reflex: 'done', turn, step: state.step, error: subject(error?.message ?? error) })
661
+ if (!signal?.aborted) decision.answer({ error: subject(error?.message ?? error) })
662
+ else decision.drop()
621
663
  return
622
664
  }
623
665
  const answers = response.answers[0]
@@ -635,8 +677,8 @@ export function apply(ctx, config) {
635
677
  ev: 's1', reflex: 'done', session: state.id, turn, model: response.model, ms: ms(response.ms), verdict: steer ? 'continue' : 'stop',
636
678
  answers: answersOf(answers), calls: state.calls.length, ...(halu ? { spanModel: halu.model, halu: unsupported.map(span => ({ text: clip(span.text, 200), p: round3(span.probability) })) } : {}),
637
679
  })
638
- record(agent.session, {
639
- reflex: 'done', turn, step: state.step, model: response.model, ms: ms(response.ms), requestId: response.requestId, answers: answersOf(answers),
680
+ decision.answer({
681
+ model: response.model, ms: ms(response.ms), requestId: response.requestId, answers: answersOf(answers),
640
682
  verdict: steer ? 'continue' : 'stop', why,
641
683
  steers: state.steers + (steer ? 1 : 0), maxSteers: config.doneMaxSteers, calls: state.calls.length,
642
684
  ...(halu ? { spanModel: halu.model, spanMs: ms(halu.ms), unsupported: unsupported.length, excerpts: excerpts(answered, unsupported, { around: 50, max: 3 }) } : {}),
package/web/client.js CHANGED
@@ -34,8 +34,9 @@ window.__ModuleLoader__.load({
34
34
  const KINDS = { code: 'Code', data: 'Data', research: 'Research', writing: 'Writing', ops: 'Ops', chat: 'Chat' }
35
35
  const EFFORT = ['Trivial', 'Small', 'Medium', 'Large']
36
36
  const RISK = ['Safe', 'Normal', 'Dangerous', 'Critical']
37
- const HUES = ['#2F9BFF', '#14C4E8', '#7357F6', '#F2A100', '#A95BF2', '#1F9D5B', '#4A6CFF', '#EF5630']
38
- const RAMP = ['#14C4E8', '#2F9BFF', '#7357F6', '#A95BF2', '#F2A100', '#EF5630', '#D9441F']
37
+ // the vLLM logo's blue (#30A2FF) leads; its gold and cool neighbours tell the other options apart
38
+ const HUES = ['#30A2FF', '#1559B5', '#7CCBFF', '#6E7CF5', '#FDB515', '#2BB3A3', '#A9C6FF', '#0B3A75']
39
+ const RAMP = ['#C5E5FF', '#97D0FF', '#63B8FF', '#30A2FF', '#1E85E3', '#1667C4', '#0F4C94']
39
40
  const SEVERITY = { muted: 0, ok: 1, info: 2, warn: 3, bad: 4 }
40
41
 
41
42
  const GUARD = {
@@ -90,6 +91,8 @@ window.__ModuleLoader__.load({
90
91
  const step = Number.isSafeInteger(data.step) ? data.step : undefined
91
92
  if (data.reflex === 'triage' && turn !== undefined) return `t${turn}:triage`
92
93
  if (['guard', 'shield', 'privacy'].includes(data.reflex) && turn !== undefined && step !== undefined) return `t${turn}:s${step}:${data.reflex}`
94
+ // a done-check that was still deciding and its answer share one element
95
+ if (data.reflex === 'done' && typeof data.decision === 'string') return `d:${data.decision}`
93
96
  return `r${seq}`
94
97
  }
95
98
 
@@ -106,12 +109,25 @@ window.__ModuleLoader__.load({
106
109
  return { ...base, rows }
107
110
  }
108
111
  }
109
- return { ...base, rows: [...base.rows, { ...data, seq: event.seq, time: event.time }] }
112
+ const row = { ...data, seq: event.seq, time: event.time }
113
+ // a decision's answer takes the place of the row that showed it deciding
114
+ if (typeof data.decision === 'string') {
115
+ const at = base.rows.findIndex(other => other.decision === data.decision)
116
+ if (at >= 0) {
117
+ const rows = base.rows.slice()
118
+ rows[at] = row
119
+ return { ...base, rows }
120
+ }
121
+ }
122
+ return { ...base, rows: [...base.rows, row] }
110
123
  }
111
124
 
112
125
  // Triage and done-check frame the turn and stay visible when it folds; so does a guard or shield card that
113
126
  // stopped something. A routine one sits with the work it checked and folds with it.
114
127
  function standsOut(state) {
128
+ // a decision still deciding, or stopped, is one line until its answer comes
129
+ if (state.rows.every(row => row.pending || row.verdict === 'cancelled')) return false
130
+ if (state.reflex === 'privacy') return state.rows.some(row => row.verdict === 'masked' || row.error)
115
131
  if (state.reflex !== 'guard' && state.reflex !== 'shield') return true
116
132
  return state.rows.some(row => SEVERITY[viewOf(state.reflex, row).tone] >= SEVERITY.warn)
117
133
  }
@@ -228,6 +244,9 @@ window.__ModuleLoader__.load({
228
244
 
229
245
  function privacyView(row) {
230
246
  if (row.error) return errorView(row, { text: 'so the result went to System Two unmasked', tone: 'warn' })
247
+ if (row.verdict === 'clean') {
248
+ return { verdict: 'clean', label: 'Nothing to mask', short: 'nothing to mask', tone: 'ok', subject: row.call ? { tool: row.tool, text: row.call } : undefined, facts: [{ id: 'masked', label: 'Masked', value: '0' }] }
249
+ }
231
250
  const masked = num(row.masked) ?? 0
232
251
  const labels = row.labels && typeof row.labels === 'object' ? Object.entries(row.labels).filter(([, n]) => num(n)) : []
233
252
  return {
@@ -265,7 +284,18 @@ window.__ModuleLoader__.load({
265
284
  }
266
285
  }
267
286
 
287
+ // what a decision that has no answer yet says, and one whose turn stopped before it was answered
288
+ const WAITING = {
289
+ guard: 'reviewing the call', shield: 'screening the result', privacy: 'looking for personal data', done: 'checking the work', triage: 'reading the request',
290
+ }
291
+ function waitingView(reflex, row) {
292
+ const subject = row.call ? { tool: row.tool, text: row.call } : undefined
293
+ if (row.pending) return { verdict: 'deciding', label: 'Deciding', short: 'deciding', tone: 'info', pending: true, detail: WAITING[reflex] ?? 'thinking', subject, facts: [] }
294
+ return { verdict: 'cancelled', label: 'Stopped', short: 'stopped', tone: 'muted', detail: 'the turn stopped before System One answered', subject, facts: [] }
295
+ }
296
+
268
297
  function viewOf(reflex, row) {
298
+ if (row.pending || row.verdict === 'cancelled') return waitingView(reflex, row)
269
299
  switch (reflex) {
270
300
  case 'triage': return triageView(row)
271
301
  case 'guard': return guardView(row)
@@ -300,6 +330,7 @@ window.__ModuleLoader__.load({
300
330
  function compactLine(view) {
301
331
  const label = view.outcome ? `${view.label} → ${view.outcome.label}` : view.label
302
332
  const rest = []
333
+ if (view.detail) rest.push(view.detail)
303
334
  if (view.subject?.text) rest.push(`${view.subject.tool ?? ''} ${view.subject.text}`.trim())
304
335
  const lead = view.facts.find(fact => ['risk', 'injection', 'complete', 'effort', 'masked'].includes(fact.id))
305
336
  if (lead) rest.push(`${lead.label.toLowerCase()} ${lead.value}`)
@@ -395,10 +426,11 @@ window.__ModuleLoader__.load({
395
426
  h('b', null, value))
396
427
  }
397
428
 
398
- function Row({ row, view, single }) {
429
+ function Row({ row, view, single, index = 0 }) {
399
430
  const fresh = useFresh(`row:${idOf(row)}`, row.time)
400
431
  return h('div', {
401
432
  className: cx('vsr-s1__row', fresh && 'vsr-s1__row--fresh'),
433
+ style: fresh ? { '--vsr-s1-i': Math.min(index, 6) } : undefined,
402
434
  'data-system-one-decision': view.verdict,
403
435
  'data-system-one-outcome': view.outcomeKey,
404
436
  'data-system-one-call': row.callId,
@@ -424,7 +456,7 @@ window.__ModuleLoader__.load({
424
456
  const hidden = all ? 0 : Math.max(0, rows.length - ROWS_SHOWN)
425
457
  return h('div', { className: 'vsr-s1__rows', 'data-system-one-part': 'rows' },
426
458
  hidden > 0 ? h('button', { type: 'button', className: 'vsr-s1__more', 'data-system-one-part': 'more', onClick: () => setAll(true) }, `Show ${plural(hidden, `earlier ${reflex === 'guard' ? 'call' : 'result'}`)}`) : null,
427
- rows.slice(hidden).map((row, index) => h(Row, { key: idOf(row), row, view: views[hidden + index], single: rows.length === 1 })))
459
+ rows.slice(hidden).map((row, index) => h(Row, { key: idOf(row), row, view: views[hidden + index], single: rows.length === 1, index })))
428
460
  }
429
461
 
430
462
  const whole = value => (Number.isSafeInteger(value) ? String(value) : undefined)
@@ -489,20 +521,23 @@ window.__ModuleLoader__.load({
489
521
  const reflex = REFLEX[state.reflex] ?? state.reflex
490
522
  const line = views.length === 1 ? compactLine(views[0]) : { label: headlineOf(state.reflex, views), tone: undefined, rest: '' }
491
523
  const said = line.rest ? `${line.label} · ${line.rest}` : line.label
524
+ const deciding = views.some(view => view.pending)
492
525
  return h('div', {
493
- className: cx('vsr-s1', 'vsr-s1--compact', `vsr-s1--${worst.tone}`, open && 'vsr-s1--open', fresh && 'vsr-s1--fresh'),
526
+ className: cx('vsr-s1', 'vsr-s1--compact', `vsr-s1--${worst.tone}`, open && 'vsr-s1--open', fresh && 'vsr-s1--fresh', deciding && 'vsr-s1--deciding'),
494
527
  role: 'group',
495
528
  'aria-label': `System One ${reflex}: ${said}`,
496
- ...attributes('compact', state, worst),
529
+ 'aria-busy': deciding || undefined,
530
+ ...attributes('compact', state, deciding ? views.find(view => view.pending) : worst),
497
531
  },
498
532
  h('button', { type: 'button', className: 'vsr-s1__chip', 'data-system-one-part': 'toggle', 'aria-expanded': open, onClick: () => setOpen(!open) },
499
- h(Badge, { key: idOf(last), id: idOf(last), ms: last.ms, time: last.time }),
533
+ h(Badge, { key: idOf(last), id: idOf(last), ms: deciding ? undefined : last.ms, time: last.time }),
500
534
  h('span', { className: 'vsr-s1__reflex', 'data-system-one-part': 'reflex' }, reflex),
501
- h('span', { className: 'vsr-s1__summary', 'data-system-one-part': 'summary', title: said },
535
+ h('span', { className: cx('vsr-s1__summary', deciding && 'vsr-s1__shimmer'), 'data-system-one-part': 'summary', title: said },
502
536
  h('span', { className: cx('vsr-s1__verdict', line.tone && `vsr-s1__verdict--${line.tone}`), 'data-system-one-part': 'verdict' }, line.label),
503
537
  line.rest ? ` · ${line.rest}` : null),
504
- open ? h(Model, { model: last.model, also: state.rows.find(row => row.spanModel)?.spanModel }) : null,
538
+ open && !deciding ? h(Model, { model: last.model, also: state.rows.find(row => row.spanModel)?.spanModel }) : null,
505
539
  h(Chevron)),
540
+ deciding ? h('span', { className: 'vsr-s1__progress', 'data-system-one-part': 'progress', 'aria-hidden': true }) : null,
506
541
  open ? h(Rows, { reflex: state.reflex, rows: state.rows, views }) : null)
507
542
  }
508
543
 
@@ -603,7 +638,7 @@ window.__ModuleLoader__.load({
603
638
  }
604
639
  }
605
640
  if (summary?.type === 'noul') {
606
- return { parts: [{ label: 'yes', n: summary.yes ?? 0, color: '#EF5630' }, { label: 'no', n: summary.no ?? 0, color: 'var(--vsr-s1-track)' }] }
641
+ return { parts: [{ label: 'yes', n: summary.yes ?? 0, color: '#30A2FF' }, { label: 'no', n: summary.no ?? 0, color: 'var(--vsr-s1-track)' }] }
607
642
  }
608
643
  if (summary?.type === 'score') {
609
644
  const levels = Object.entries(summary.levels ?? {})
@@ -649,11 +684,12 @@ window.__ModuleLoader__.load({
649
684
 
650
685
  if (phase !== 'result') {
651
686
  const line = phase === 'preparing' ? 'Preparing a batch' : `Answering ${plural(asked, 'question')}${source ? ` over ${source}` : ''}`
652
- return h('div', { className: 'vsr-s1 vsr-s1--compact vsr-s1--running', 'data-system-one': 'tool', ...common, 'data-system-one-verdict': 'running', 'data-system-one-tone': 'info' },
687
+ return h('div', { className: 'vsr-s1 vsr-s1--compact vsr-s1--running vsr-s1--deciding', 'aria-busy': true, 'data-system-one': 'tool', ...common, 'data-system-one-verdict': 'running', 'data-system-one-tone': 'info' },
653
688
  h('div', { className: 'vsr-s1__chip vsr-s1__chip--static' },
654
689
  h(Badge, { id: `${callId}:running`, time: Date.now() }),
655
690
  h('span', { className: 'vsr-s1__reflex', 'data-system-one-part': 'reflex' }, REFLEX.tool),
656
- h('span', { className: 'vsr-s1__summary vsr-s1__shimmer', 'data-system-one-part': 'summary' }, line)))
691
+ h('span', { className: 'vsr-s1__summary vsr-s1__shimmer', 'data-system-one-part': 'summary' }, line)),
692
+ h('span', { className: 'vsr-s1__progress', 'data-system-one-part': 'progress', 'aria-hidden': true }))
657
693
  }
658
694
 
659
695
  if (block?.isError || !meta || ui === 'off') {
@@ -706,31 +742,33 @@ window.__ModuleLoader__.load({
706
742
  return h(Contained, null, h(ToolRow, props))
707
743
  }
708
744
 
709
- // ---- styles: the Web UI's theme tokens, with System One's ember from the launch film ----
745
+ // ---- styles: the Web UI's theme tokens, with the blue of the vLLM logo (#30A2FF) for System One ----
710
746
 
711
747
  const CSS = `
712
- .vsr-s1{--vsr-s1-ember:#EF5630;--vsr-s1-ember-deep:#D9441F;--vsr-s1-gold:#F5B82E;--vsr-s1-ok:var(--dsw-alias-state-success-primary,#1F9D5B);--vsr-s1-warn:var(--dsw-alias-state-warn-primary,#E8A100);--vsr-s1-bad:var(--dsw-alias-state-error-primary,#E5484D);--vsr-s1-info:var(--dsw-alias-brand-primary,#2F7BF6);--vsr-s1-text:var(--dsw-alias-label-primary,#1F2329);--vsr-s1-text-2:var(--dsw-alias-label-secondary,#545961);--vsr-s1-text-3:var(--dsw-alias-label-tertiary,#8A8F98);--vsr-s1-line:var(--dsw-alias-border-l2,rgba(127,127,127,.22));--vsr-s1-track:color-mix(in srgb,var(--vsr-s1-text-3) 28%,transparent);--vsr-s1-mono:ui-monospace,SFMono-Regular,"JetBrains Mono",Menlo,Consolas,monospace;position:relative;box-sizing:border-box;width:100%;margin:6px 0;color:var(--vsr-s1-text);font-size:13.5px;line-height:1.45;text-align:left}
748
+ .vsr-s1{--vsr-s1-blue:#30A2FF;--vsr-s1-blue-soft:#7CC4FF;--vsr-s1-blue-deep:#1E7FE0;--vsr-s1-ink:#166BC9;--vsr-s1-badge-a:#2290F0;--vsr-s1-badge-b:#135CB8;--vsr-s1-tint:6%;--vsr-s1-tint-2:1.5%;--vsr-s1-edge:24%;--vsr-s1-lift:rgba(16,42,84,.05);--vsr-s1-ok:var(--dsw-alias-state-success-primary,#1F9D5B);--vsr-s1-warn:var(--dsw-alias-state-warn-primary,#E8A100);--vsr-s1-bad:var(--dsw-alias-state-error-primary,#E5484D);--vsr-s1-text:var(--dsw-alias-label-primary,#1F2329);--vsr-s1-text-2:var(--dsw-alias-label-secondary,#545961);--vsr-s1-text-3:var(--dsw-alias-label-tertiary,#8A8F98);--vsr-s1-line:var(--dsw-alias-border-l2,rgba(127,127,127,.22));--vsr-s1-track:color-mix(in srgb,var(--vsr-s1-text-3) 26%,transparent);--vsr-s1-mono:ui-monospace,SFMono-Regular,"JetBrains Mono",Menlo,Consolas,monospace;--vsr-s1-ease:cubic-bezier(.22,1,.36,1);position:relative;box-sizing:border-box;width:100%;margin:6px 0;color:var(--vsr-s1-text);font-size:13.5px;line-height:1.45;text-align:left}
749
+ body[data-ds-dark-theme] .vsr-s1{--vsr-s1-blue-soft:#4DB0FF;--vsr-s1-ink:#6BBEFF;--vsr-s1-badge-a:#2A98F5;--vsr-s1-badge-b:#1667C9;--vsr-s1-tint:9%;--vsr-s1-tint-2:3%;--vsr-s1-edge:32%;--vsr-s1-lift:rgba(0,0,0,.28)}
713
750
  .vsr-s1 *{box-sizing:border-box}
714
- .vsr-s1--card{padding:11px 14px 12px 17px;border:1px solid color-mix(in srgb,var(--vsr-s1-ember) 30%,var(--vsr-s1-line));border-radius:12px;background:linear-gradient(180deg,color-mix(in srgb,var(--vsr-s1-ember) 7%,transparent),color-mix(in srgb,var(--vsr-s1-ember) 2.5%,transparent))}
715
- .vsr-s1--card.vsr-s1--bad{border-color:color-mix(in srgb,var(--vsr-s1-bad) 50%,var(--vsr-s1-line));background:linear-gradient(180deg,color-mix(in srgb,var(--vsr-s1-bad) 9%,transparent),color-mix(in srgb,var(--vsr-s1-bad) 3%,transparent))}
716
- .vsr-s1--card.vsr-s1--warn{border-color:color-mix(in srgb,var(--vsr-s1-warn) 50%,var(--vsr-s1-line));background:linear-gradient(180deg,color-mix(in srgb,var(--vsr-s1-warn) 9%,transparent),color-mix(in srgb,var(--vsr-s1-warn) 3%,transparent))}
751
+ .vsr-s1--card{--vsr-s1-tone:var(--vsr-s1-blue);padding:11px 14px 12px 17px;border:1px solid color-mix(in srgb,var(--vsr-s1-tone) var(--vsr-s1-edge),var(--vsr-s1-line));border-radius:12px;background:linear-gradient(180deg,color-mix(in srgb,var(--vsr-s1-tone) var(--vsr-s1-tint),transparent),color-mix(in srgb,var(--vsr-s1-tone) var(--vsr-s1-tint-2),transparent));box-shadow:0 1px 2px var(--vsr-s1-lift),0 10px 24px -16px color-mix(in srgb,var(--vsr-s1-tone) 55%,transparent)}
752
+ .vsr-s1--card.vsr-s1--bad{--vsr-s1-tone:var(--vsr-s1-bad);--vsr-s1-edge:44%}
753
+ .vsr-s1--card.vsr-s1--warn{--vsr-s1-tone:var(--vsr-s1-warn);--vsr-s1-edge:46%}
717
754
  .vsr-s1__sheen{position:absolute;inset:0;border-radius:inherit;overflow:hidden;pointer-events:none}
718
- .vsr-s1__sheen::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:linear-gradient(180deg,var(--vsr-s1-ember),var(--vsr-s1-gold))}
755
+ .vsr-s1__sheen::before{content:"";position:absolute;left:0;top:0;bottom:0;width:3px;background:linear-gradient(180deg,var(--vsr-s1-blue-soft),var(--vsr-s1-blue) 45%,var(--vsr-s1-blue-deep));transform-origin:top center}
719
756
  .vsr-s1--bad>.vsr-s1__sheen::before{background:var(--vsr-s1-bad)}
720
757
  .vsr-s1--warn>.vsr-s1__sheen::before{background:var(--vsr-s1-warn)}
721
758
  .vsr-s1__head{position:relative;display:flex;align-items:center;gap:9px;min-width:0}
722
- .vsr-s1__badge{position:relative;display:inline-flex;flex:none;align-items:center;gap:6px;height:22px;padding:0 9px 0 8px;border-radius:999px;color:#fff;font-size:12px;font-weight:650;letter-spacing:-.005em;white-space:nowrap;background:linear-gradient(160deg,var(--vsr-s1-ember) 0%,var(--vsr-s1-ember-deep) 100%);box-shadow:0 1px 2px rgba(217,68,31,.28),inset 0 1px 0 rgba(255,255,255,.35)}
723
- .vsr-s1__dot{flex:none;width:6px;height:6px;border-radius:50%;background:#fff;box-shadow:0 0 6px #fff}
724
- .vsr-s1__ms{padding-left:7px;border-left:1px solid rgba(255,255,255,.5);font-weight:750;font-variant-numeric:tabular-nums}
759
+ .vsr-s1__badge{position:relative;display:inline-flex;flex:none;align-items:center;gap:6px;height:22px;padding:0 9px 0 8px;border-radius:999px;color:#fff;font-size:12px;font-weight:650;letter-spacing:-.005em;white-space:nowrap;background:linear-gradient(135deg,var(--vsr-s1-badge-a),var(--vsr-s1-badge-b));box-shadow:0 1px 2px color-mix(in srgb,var(--vsr-s1-badge-b) 35%,transparent),inset 0 1px 0 rgba(255,255,255,.26),inset 0 0 0 .5px rgba(255,255,255,.14)}
760
+ .vsr-s1__dot{flex:none;width:6px;height:6px;border-radius:50%;background:#fff;box-shadow:0 0 0 2px rgba(255,255,255,.2)}
761
+ .vsr-s1__ms{padding-left:7px;border-left:1px solid rgba(255,255,255,.42);font-weight:750;font-variant-numeric:tabular-nums}
725
762
  .vsr-s1__reflex{flex:none;font-weight:650;color:var(--vsr-s1-text);white-space:nowrap}
726
763
  .vsr-s1__summary{flex:1;min-width:0;overflow:hidden;color:var(--vsr-s1-text-2);white-space:nowrap;text-overflow:ellipsis}
727
764
  .vsr-s1__summary--bad{color:var(--vsr-s1-bad)}
728
765
  .vsr-s1__verdict{font-weight:600;color:var(--vsr-s1-text)}
729
- .vsr-s1__verdict--ok{color:var(--vsr-s1-ok)}.vsr-s1__verdict--warn{color:color-mix(in srgb,var(--vsr-s1-warn) 82%,var(--vsr-s1-text))}.vsr-s1__verdict--bad{color:var(--vsr-s1-bad)}.vsr-s1__verdict--info{color:var(--vsr-s1-ember-deep)}.vsr-s1__verdict--muted{color:var(--vsr-s1-text-3)}
766
+ .vsr-s1__verdict--ok{color:var(--vsr-s1-ok)}.vsr-s1__verdict--warn{color:color-mix(in srgb,var(--vsr-s1-warn) 82%,var(--vsr-s1-text))}.vsr-s1__verdict--bad{color:var(--vsr-s1-bad)}.vsr-s1__verdict--info{color:var(--vsr-s1-ink)}.vsr-s1__verdict--muted{color:var(--vsr-s1-text-3)}
730
767
  .vsr-s1__model{flex:none;color:var(--vsr-s1-text-2);font-size:12px;font-weight:700;letter-spacing:-.005em;white-space:nowrap}
731
768
  .vsr-s1--notice{display:flex;align-items:center;gap:9px;min-width:0;margin:4px 0;padding:3px 0}
732
769
  .vsr-s1--notice .vsr-s1__summary{white-space:normal}
733
- .vsr-s1__duo{position:relative;display:inline-flex;flex:none;align-items:center;gap:5px;height:22px;padding:0 9px 0 8px;border-radius:999px;color:#fff;font-size:12px;font-weight:650;white-space:nowrap;background:linear-gradient(110deg,var(--vsr-s1-ember) 0%,#B04FD0 58%,#2F7BF6 100%);box-shadow:0 1px 2px rgba(90,60,170,.25),inset 0 1px 0 rgba(255,255,255,.32)}
770
+ .vsr-s1__duo{position:relative;display:inline-flex;flex:none;align-items:center;gap:5px;height:22px;padding:0 9px 0 8px;border-radius:999px;color:#fff;font-size:12px;font-weight:650;white-space:nowrap;background:linear-gradient(110deg,var(--vsr-s1-badge-b) 0%,var(--vsr-s1-badge-a) 55%,var(--vsr-s1-blue) 100%);box-shadow:0 1px 2px color-mix(in srgb,var(--vsr-s1-badge-b) 35%,transparent),inset 0 1px 0 rgba(255,255,255,.26)}
771
+ .vsr-s1__duo .vsr-s1__glyph{color:#FFD56B}
734
772
  .vsr-s1__glyph{flex:none}
735
773
  .vsr-s1__links{display:inline-flex;flex:none;gap:10px}
736
774
  a.vsr-s1__link{text-decoration:none}
@@ -738,10 +776,10 @@ a.vsr-s1__link{text-decoration:none}
738
776
  .vsr-s1__rows>*{grid-column:1/-1}
739
777
  .vsr-s1__row{display:grid;grid-template-columns:auto minmax(0,1fr) auto;grid-template-columns:subgrid;column-gap:12px;align-items:start}
740
778
  .vsr-s1__verdicts{display:flex;flex-direction:column;align-items:flex-start;gap:4px;min-width:92px}
741
- .vsr-s1__pill{--tone:var(--vsr-s1-text-3);display:inline-flex;align-items:center;gap:6px;padding:1px 8px 1px 7px;border-radius:6px;color:var(--tone);background:color-mix(in srgb,var(--tone) 13%,transparent);font-size:12px;font-weight:650;line-height:20px;white-space:nowrap}
779
+ .vsr-s1__pill{--tone:var(--vsr-s1-text-3);display:inline-flex;align-items:center;gap:6px;padding:1px 8px 1px 7px;border-radius:6px;color:var(--tone);background:color-mix(in srgb,var(--tone) 12%,transparent);box-shadow:inset 0 0 0 .5px color-mix(in srgb,var(--tone) 22%,transparent);font-size:12px;font-weight:650;line-height:20px;white-space:nowrap}
742
780
  .vsr-s1__pill::before{content:"";flex:none;width:6px;height:6px;border-radius:50%;background:currentColor}
743
781
  .vsr-s1__pill--then::before{width:auto;height:auto;border-radius:0;background:none;content:"\\21B3"}
744
- .vsr-s1__pill--ok{--tone:var(--vsr-s1-ok)}.vsr-s1__pill--warn{--tone:color-mix(in srgb,var(--vsr-s1-warn) 82%,var(--vsr-s1-text))}.vsr-s1__pill--bad{--tone:var(--vsr-s1-bad)}.vsr-s1__pill--info{--tone:var(--vsr-s1-ember-deep)}.vsr-s1__pill--muted{--tone:var(--vsr-s1-text-3)}
782
+ .vsr-s1__pill--ok{--tone:var(--vsr-s1-ok)}.vsr-s1__pill--warn{--tone:color-mix(in srgb,var(--vsr-s1-warn) 82%,var(--vsr-s1-text))}.vsr-s1__pill--bad{--tone:var(--vsr-s1-bad)}.vsr-s1__pill--info{--tone:var(--vsr-s1-ink)}.vsr-s1__pill--muted{--tone:var(--vsr-s1-text-3)}
745
783
  .vsr-s1__main{display:grid;gap:3px;min-width:0}
746
784
  .vsr-s1__subject{display:flex;align-items:baseline;gap:7px;min-width:0;line-height:22px}
747
785
  .vsr-s1__tool{flex:none;color:var(--vsr-s1-text-2);font-weight:600}
@@ -750,20 +788,20 @@ a.vsr-s1__link{text-decoration:none}
750
788
  .vsr-s1__fact{display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
751
789
  .vsr-s1__fact b{color:var(--vsr-s1-text);font-weight:600;font-variant-numeric:tabular-nums}
752
790
  .vsr-s1__bar{position:relative;width:34px;height:4px;border-radius:2px;overflow:hidden;background:var(--vsr-s1-track)}
753
- .vsr-s1__bar>i{position:absolute;inset:0;border-radius:inherit;background:color-mix(in srgb,var(--vsr-s1-ember) 70%,var(--vsr-s1-text-3));transform-origin:left center;transform:scaleX(var(--p))}
791
+ .vsr-s1__bar>i{position:absolute;inset:0;border-radius:inherit;background:var(--vsr-s1-blue);transform-origin:left center;transform:scaleX(var(--p))}
754
792
  .vsr-s1__bar--ok>i{background:var(--vsr-s1-ok)}.vsr-s1__bar--warn>i{background:var(--vsr-s1-warn)}.vsr-s1__bar--bad>i{background:var(--vsr-s1-bad)}
755
793
  .vsr-s1__note{color:var(--vsr-s1-text-2);font-size:12.5px}
756
794
  .vsr-s1__span{padding:0 3px;border-radius:4px;color:inherit;background:none;font:inherit}
757
- .vsr-s1__span--removed{color:var(--vsr-s1-bad);background:color-mix(in srgb,var(--vsr-s1-bad) 15%,transparent);text-decoration:line-through;text-decoration-thickness:1.5px}
758
- .vsr-s1__span--dangerous{color:var(--vsr-s1-bad);background:color-mix(in srgb,var(--vsr-s1-bad) 17%,transparent);box-shadow:inset 0 -2px 0 var(--vsr-s1-bad);font-weight:650}
759
- .vsr-s1__span--unsupported{background:color-mix(in srgb,var(--vsr-s1-warn) 24%,transparent);text-decoration:underline wavy color-mix(in srgb,var(--vsr-s1-warn) 85%,var(--vsr-s1-text));text-decoration-thickness:1.5px;text-underline-offset:3px}
795
+ .vsr-s1__span--removed{color:var(--vsr-s1-bad);background:color-mix(in srgb,var(--vsr-s1-bad) 14%,transparent);text-decoration:line-through;text-decoration-thickness:1.5px}
796
+ .vsr-s1__span--dangerous{color:var(--vsr-s1-bad);background:color-mix(in srgb,var(--vsr-s1-bad) 16%,transparent);box-shadow:inset 0 -2px 0 var(--vsr-s1-bad);font-weight:650}
797
+ .vsr-s1__span--unsupported{background:color-mix(in srgb,var(--vsr-s1-warn) 22%,transparent);text-decoration:underline wavy color-mix(in srgb,var(--vsr-s1-warn) 85%,var(--vsr-s1-text));text-decoration-thickness:1.5px;text-underline-offset:3px}
760
798
  .vsr-s1__span--masked{display:inline-block;padding:0 6px;color:var(--dsw-alias-bg-layer-1,#fff);background:repeating-linear-gradient(135deg,color-mix(in srgb,var(--vsr-s1-text) 80%,transparent) 0 6px,color-mix(in srgb,var(--vsr-s1-text) 66%,transparent) 6px 12px);font-family:var(--vsr-s1-mono);font-size:11px;font-weight:650;letter-spacing:.02em;line-height:17px}
761
799
  .vsr-s1__excerpts{display:grid;gap:5px;margin:3px 0 1px}
762
- .vsr-s1__excerpt{padding:6px 9px;border-left:2px solid color-mix(in srgb,var(--vsr-s1-ember) 50%,transparent);border-radius:0 6px 6px 0;color:var(--vsr-s1-text-2);background:color-mix(in srgb,var(--vsr-s1-text-3) 9%,transparent);font-family:var(--vsr-s1-mono);font-size:12px;line-height:1.6;white-space:pre-wrap;word-break:break-word}
800
+ .vsr-s1__excerpt{padding:6px 9px;border-left:2px solid color-mix(in srgb,var(--vsr-s1-blue) 50%,transparent);border-radius:0 6px 6px 0;color:var(--vsr-s1-text-2);background:color-mix(in srgb,var(--vsr-s1-text-3) 8%,transparent);font-family:var(--vsr-s1-mono);font-size:12px;line-height:1.6;white-space:pre-wrap;word-break:break-word}
763
801
  .vsr-s1--bad .vsr-s1__excerpt{border-left-color:color-mix(in srgb,var(--vsr-s1-bad) 55%,transparent)}
764
802
  .vsr-s1--warn .vsr-s1__excerpt{border-left-color:color-mix(in srgb,var(--vsr-s1-warn) 60%,transparent)}
765
803
  .vsr-s1__labels{display:flex;flex-wrap:wrap;gap:4px 6px}
766
- .vsr-s1__label{display:inline-flex;align-items:center;gap:5px;padding:0 7px;border-radius:5px;color:var(--vsr-s1-text-2);background:color-mix(in srgb,var(--vsr-s1-text-3) 14%,transparent);font-family:var(--vsr-s1-mono);font-size:11.5px;line-height:20px}
804
+ .vsr-s1__label{display:inline-flex;align-items:center;gap:5px;padding:0 7px;border-radius:5px;color:var(--vsr-s1-text-2);background:color-mix(in srgb,var(--vsr-s1-blue) 10%,transparent);font-family:var(--vsr-s1-mono);font-size:11.5px;line-height:20px}
767
805
  .vsr-s1__label b{color:var(--vsr-s1-text);font-weight:650}
768
806
  .vsr-s1__rowms{color:var(--vsr-s1-text-3);font-size:12px;line-height:22px;font-variant-numeric:tabular-nums;white-space:nowrap}
769
807
  .vsr-s1__more,.vsr-s1__link{justify-self:start;padding:0;border:0;background:none;color:var(--dsw-alias-link,#2F7BF6);font:inherit;font-size:12.5px;cursor:pointer}
@@ -771,9 +809,10 @@ a.vsr-s1__link{text-decoration:none}
771
809
  .vsr-s1--compact{margin:4px 0}
772
810
  .vsr-s1__chip{display:flex;align-items:center;gap:9px;width:100%;min-width:0;padding:3px 0;border:0;background:none;color:inherit;font:inherit;text-align:left;cursor:pointer}
773
811
  .vsr-s1__chip--static{cursor:default}
774
- .vsr-s1__chev{flex:none;color:var(--vsr-s1-text-3);transition:transform .16s ease}
812
+ .vsr-s1__chev{flex:none;color:var(--vsr-s1-text-3);transition:transform .2s var(--vsr-s1-ease),color .2s ease}
813
+ .vsr-s1__chip:hover .vsr-s1__chev{color:var(--vsr-s1-text-2)}
775
814
  .vsr-s1--open .vsr-s1__chev{transform:rotate(90deg)}
776
- .vsr-s1--compact>.vsr-s1__rows{margin:4px 0 8px 3px;padding-left:12px;border-left:2px solid color-mix(in srgb,var(--vsr-s1-ember) 45%,transparent)}
815
+ .vsr-s1--compact>.vsr-s1__rows{margin:4px 0 8px 3px;padding-left:12px;border-left:2px solid color-mix(in srgb,var(--vsr-s1-blue) 40%,transparent)}
777
816
  .vsr-s1--plain .vsr-s1__reflex{color:var(--vsr-s1-text-2)}
778
817
  .vsr-s1__raw{margin:4px 0 8px;padding:8px 10px;max-height:320px;overflow:auto;border-radius:8px;background:color-mix(in srgb,var(--vsr-s1-text-3) 10%,transparent);font-family:var(--vsr-s1-mono);font-size:12px;white-space:pre-wrap}
779
818
  .vsr-s1__q{display:grid;grid-template-columns:minmax(80px,140px) minmax(0,1fr);column-gap:14px;align-items:start}
@@ -789,29 +828,30 @@ a.vsr-s1__link{text-decoration:none}
789
828
  .vsr-s1__swatch{flex:none;width:8px;height:8px;margin-right:6px;border-radius:2px}
790
829
  .vsr-s1__foot{color:var(--vsr-s1-text-3);font-size:12.5px}
791
830
  .vsr-s1__foot code{font-family:var(--vsr-s1-mono)}
792
- @keyframes vsr-s1-in{from{opacity:0;transform:translateY(8px) scale(.985)}to{opacity:1;transform:none}}
793
- @keyframes vsr-s1-glow{0%{box-shadow:0 0 0 0 rgba(239,86,48,0)}25%{box-shadow:0 0 0 5px rgba(239,86,48,.2),0 8px 28px rgba(239,86,48,.18)}100%{box-shadow:0 0 0 0 rgba(239,86,48,0),0 0 0 rgba(239,86,48,0)}}
794
- @keyframes vsr-s1-sweep{from{transform:translateX(-110%)}to{transform:translateX(110%)}}
795
- @keyframes vsr-s1-pop{0%{transform:scale(.55)}55%{transform:scale(1.09)}100%{transform:scale(1)}}
796
- @keyframes vsr-s1-ring{0%{opacity:.7;transform:scale(1)}100%{opacity:0;transform:scale(1.45,2.1)}}
797
- @keyframes vsr-s1-row{from{opacity:0;transform:translateX(-10px)}to{opacity:1;transform:none}}
831
+ .vsr-s1__progress{position:relative;display:block;height:2px;margin:0 0 4px 1px;border-radius:2px;overflow:hidden;background:color-mix(in srgb,var(--vsr-s1-blue) 12%,transparent)}
832
+ .vsr-s1__progress::before{content:"";position:absolute;top:0;bottom:0;left:0;width:36%;border-radius:inherit;background:linear-gradient(90deg,transparent,var(--vsr-s1-blue) 55%,transparent)}
833
+ .vsr-s1--deciding .vsr-s1__badge::after{content:"";position:absolute;inset:0;border-radius:inherit;background:linear-gradient(100deg,transparent 35%,rgba(255,255,255,.42) 50%,transparent 65%);background-size:220% 100%;pointer-events:none}
834
+ .vsr-s1__shimmer{background:linear-gradient(90deg,var(--vsr-s1-text-2) 35%,var(--vsr-s1-blue) 50%,var(--vsr-s1-text-2) 65%);background-size:250% 100%;-webkit-background-clip:text;background-clip:text;color:transparent}
835
+ @keyframes vsr-s1-reveal{from{opacity:0;transform:translateY(6px)}to{opacity:1;transform:none}}
836
+ @keyframes vsr-s1-rise{from{opacity:0;transform:translateY(3px)}to{opacity:1;transform:none}}
837
+ @keyframes vsr-s1-draw{from{transform:scaleY(0)}to{transform:scaleY(1)}}
798
838
  @keyframes vsr-s1-fill{from{transform:scaleX(0)}}
799
839
  @keyframes vsr-s1-grow{from{transform:scaleX(0)}to{transform:scaleX(1)}}
800
- @keyframes vsr-s1-blink{0%,100%{opacity:1}50%{opacity:.25}}
801
- @keyframes vsr-s1-shimmer{from{background-position:120% 0}to{background-position:-20% 0}}
802
- .vsr-s1--fresh{animation:vsr-s1-in .3s cubic-bezier(.2,.8,.2,1) both}
803
- .vsr-s1--card.vsr-s1--fresh{animation:vsr-s1-in .3s cubic-bezier(.2,.8,.2,1) both,vsr-s1-glow 1.3s ease-out .08s both}
804
- .vsr-s1--fresh>.vsr-s1__sheen::after{content:"";position:absolute;top:0;bottom:0;left:0;width:100%;background:linear-gradient(100deg,transparent 30%,rgba(255,170,110,.32) 50%,transparent 70%);animation:vsr-s1-sweep 1s cubic-bezier(.3,.7,.2,1) .1s both}
805
- .vsr-s1__badge--fresh{animation:vsr-s1-pop .55s cubic-bezier(.3,1.5,.5,1) both}
806
- .vsr-s1__badge--fresh::after{content:"";position:absolute;inset:-1px;border:2px solid var(--vsr-s1-ember);border-radius:inherit;pointer-events:none;animation:vsr-s1-ring .85s ease-out .06s both}
807
- .vsr-s1__row--fresh{animation:vsr-s1-row .34s cubic-bezier(.2,.8,.2,1) .06s both}
808
- .vsr-s1__row--fresh .vsr-s1__bar>i{animation:vsr-s1-fill .7s cubic-bezier(.2,.8,.2,1) .2s both}
809
- @keyframes vsr-s1-mark{0%{outline:2px solid color-mix(in srgb,var(--vsr-s1-ember) 70%,transparent);outline-offset:3px}100%{outline:2px solid transparent;outline-offset:0}}
810
- .vsr-s1__row--fresh .vsr-s1__span{animation:vsr-s1-mark .9s ease-out .35s both}
811
- .vsr-s1__stack--fresh>i{animation:vsr-s1-grow .6s cubic-bezier(.2,.8,.2,1) both}
812
- .vsr-s1--running .vsr-s1__dot{animation:vsr-s1-blink 1s ease-in-out infinite}
813
- .vsr-s1__shimmer{background:linear-gradient(90deg,var(--vsr-s1-text-2) 35%,var(--vsr-s1-ember) 50%,var(--vsr-s1-text-2) 65%);background-size:250% 100%;-webkit-background-clip:text;background-clip:text;color:transparent;animation:vsr-s1-shimmer 1.6s linear infinite}
814
- @media (prefers-reduced-motion:reduce){.vsr-s1,.vsr-s1 *,.vsr-s1 *::before,.vsr-s1 *::after{animation:none!important;transition:none!important}.vsr-s1__shimmer{color:var(--vsr-s1-text-2)}}
840
+ @keyframes vsr-s1-ink{from{background-color:transparent;box-shadow:none}}
841
+ @keyframes vsr-s1-breathe{0%,100%{opacity:1}50%{opacity:.4}}
842
+ @keyframes vsr-s1-shimmer{from{background-position:130% 0}to{background-position:-30% 0}}
843
+ @keyframes vsr-s1-scan{from{transform:translateX(-100%)}to{transform:translateX(280%)}}
844
+ .vsr-s1--fresh{animation:vsr-s1-reveal .22s var(--vsr-s1-ease) both}
845
+ .vsr-s1--fresh>.vsr-s1__sheen::before{animation:vsr-s1-draw .42s var(--vsr-s1-ease) .06s both}
846
+ .vsr-s1__row--fresh{animation:vsr-s1-rise .24s var(--vsr-s1-ease) both;animation-delay:calc(60ms + var(--vsr-s1-i,0) * 45ms)}
847
+ .vsr-s1__row--fresh .vsr-s1__bar>i{animation:vsr-s1-fill .6s var(--vsr-s1-ease) .16s both}
848
+ .vsr-s1__row--fresh .vsr-s1__span{animation:vsr-s1-ink .5s ease-out .26s both}
849
+ .vsr-s1__stack--fresh>i{animation:vsr-s1-grow .6s var(--vsr-s1-ease) both}
850
+ .vsr-s1--deciding .vsr-s1__dot{animation:vsr-s1-breathe 1.4s ease-in-out infinite}
851
+ .vsr-s1--deciding .vsr-s1__badge::after{animation:vsr-s1-shimmer 1.8s linear infinite}
852
+ .vsr-s1__progress::before{animation:vsr-s1-scan 1.6s cubic-bezier(.45,0,.55,1) infinite}
853
+ .vsr-s1__shimmer{animation:vsr-s1-shimmer 2s linear infinite}
854
+ @media (prefers-reduced-motion:reduce){.vsr-s1,.vsr-s1 *,.vsr-s1 *::before,.vsr-s1 *::after{animation:none!important;transition:none!important}.vsr-s1__shimmer{color:var(--vsr-s1-text-2);background:none}.vsr-s1--deciding .vsr-s1__badge::after{display:none}.vsr-s1__progress::before{width:100%;opacity:.45;background:var(--vsr-s1-blue)}}
815
855
  `
816
856
  if (typeof document !== 'undefined') {
817
857
  const tagId = `${PACKAGE}/system-one.css`