@tangle-network/charts 0.21.21 → 0.21.22

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.
@@ -83,7 +83,7 @@
83
83
  .fw-root .fw-title-line { display: flex; align-items: center; gap: 8px; min-width: 0; }
84
84
  .fw-root .fw-title-glyph { display: inline-flex; color: var(--fw-accent); }
85
85
  .fw-root .fw-title { font-size: 14px; line-height: 20px; font-weight: 600; letter-spacing: -.005em; white-space: nowrap; }
86
- .fw-root .fw-state { display: inline-flex; align-items: center; gap: 8px; height: 20px; padding: 0 8px; border-radius: var(--radius-pill); font-size: 12px; font-weight: 600; color: var(--fw-muted); background: var(--fw-well); flex-shrink: 0; }
86
+ .fw-root .fw-state { display: inline-flex; align-items: center; gap: 8px; height: 20px; padding: 0 8px; border-radius: var(--radius-pill); font-size: 14px; font-weight: 600; color: var(--fw-muted); background: var(--fw-well); flex-shrink: 0; }
87
87
  .fw-root .fw-state::before { content: ""; width: 6px; height: 6px; border-radius: 50%; background: currentColor; }
88
88
  .fw-root .fw-state-live { color: var(--fw-accent); background: color-mix(in oklab, var(--fw-accent) 12%, transparent); }
89
89
  .fw-root .fw-state-live::before { animation: fw-pulse 1.6s var(--fw-ease) infinite; }
@@ -104,16 +104,16 @@
104
104
  .fw-root .fw-summary { display: grid; grid-template-columns: repeat(6, minmax(0, 1fr)); border-bottom: 1px solid var(--fw-border); }
105
105
  .fw-root .fw-summary > div { padding: 12px 16px; min-width: 0; }
106
106
  .fw-root .fw-summary > div + div { border-left: 1px solid var(--fw-border); }
107
- .fw-root .fw-summary dt { font-size: 12px; line-height: 16px; color: var(--fw-muted); }
107
+ .fw-root .fw-summary dt { font-size: 14px; line-height: 18px; color: var(--fw-muted); }
108
108
  .fw-root .fw-value { margin-top: 4px; font-size: 18px; line-height: 24px; font-weight: 600; letter-spacing: -.01em; font-variant-numeric: tabular-nums; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
109
109
  .fw-root .fw-has-errors .fw-value { color: var(--fw-failed); }
110
110
 
111
111
  /* Axis */
112
- .fw-root .fw-axis { display: grid; grid-template-columns: var(--fw-label-col) minmax(0, 1fr); height: 32px; color: var(--fw-muted); font-size: 12px; }
112
+ .fw-root .fw-axis { display: grid; grid-template-columns: var(--fw-label-col) minmax(0, 1fr); height: 32px; color: var(--fw-muted); font-size: 14px; }
113
113
  .fw-root .fw-axis-top { border-bottom: 1px solid var(--fw-border); }
114
114
  .fw-root .fw-axis-label { position: relative; display: flex; align-items: center; gap: 8px; padding: 0 12px 0 16px; border-right: 1px solid var(--fw-border); min-width: 0; }
115
115
  .fw-root .fw-branch-controls { margin-left: auto; display: flex; gap: 4px; }
116
- .fw-root .fw-text-button { appearance: none; border: 0; background: transparent; height: 24px; padding: 0 8px; border-radius: var(--radius-sm); font-size: 12px; color: var(--fw-muted); cursor: pointer; white-space: nowrap; }
116
+ .fw-root .fw-text-button { appearance: none; border: 0; background: transparent; height: 24px; padding: 0 8px; border-radius: var(--radius-sm); font-size: 14px; color: var(--fw-muted); cursor: pointer; white-space: nowrap; }
117
117
  .fw-root .fw-text-button:hover { background: var(--fw-hover); color: var(--fw-text); }
118
118
  .fw-root .fw-resize { position: absolute; top: 0; right: -4px; width: 8px; height: 100%; cursor: col-resize; z-index: 2; }
119
119
  .fw-root .fw-resize:hover, .fw-root .fw-resize:focus-visible { background: linear-gradient(90deg, transparent 3px, var(--fw-accent) 3px 5px, transparent 5px); outline: 0; }
@@ -142,14 +142,14 @@
142
142
  .fw-root .fw-pause { top: 0; bottom: 0; background: color-mix(in oklab, var(--fw-text) 4%, transparent); border-inline: 1px dashed color-mix(in oklab, var(--fw-text) 18%, transparent); }
143
143
  .fw-root .fw-pause-mark { bottom: 3px; height: 6px; border-radius: 2px; cursor: help;
144
144
  background: repeating-linear-gradient(-45deg, var(--fw-hatch) 0 1px, transparent 1px 4px); box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--fw-text) 18%, transparent); }
145
- .fw-root .fw-marker-label { position: absolute; top: 2px; left: 3px; max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 0 4px; border-radius: var(--radius-tag); font-size: 12px; line-height: 16px; color: var(--fw-marker); background: var(--fw-surface); box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--fw-marker) 40%, transparent); }
145
+ .fw-root .fw-marker-label { position: absolute; top: 2px; left: 3px; max-width: 160px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; padding: 0 4px; border-radius: var(--radius-tag); font-size: 14px; line-height: 18px; color: var(--fw-marker); background: var(--fw-surface); box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--fw-marker) 40%, transparent); }
146
146
  .fw-root .fw-marker-label-left { left: auto; right: 3px; }
147
147
  .fw-root .fw-marker[data-tone="warn"], .fw-root .fw-event[data-tone="warn"] { --fw-marker: var(--fw-amber); }
148
148
  /* The event track: one dot per marker on the axis; click or N/P moves the cursor there. */
149
149
  .fw-root .fw-event { --fw-marker: var(--fw-muted); position: absolute; bottom: 2px; width: 8px; height: 8px; margin-left: -4px; padding: 0; border: 0; border-radius: 50%; background: var(--fw-marker); box-shadow: 0 0 0 2px var(--fw-surface); cursor: pointer; z-index: 4; left: calc(var(--fw-pad) + (var(--s) - var(--fw-v0)) * var(--fw-k) * 1px); }
150
150
  .fw-root .fw-event[data-tone="ok"] { --fw-marker: var(--fw-ok); }
151
151
  .fw-root .fw-event[aria-pressed="true"] { box-shadow: 0 0 0 2px var(--fw-surface), 0 0 0 4px var(--fw-marker); }
152
- .fw-root .fw-event-label { position: absolute; bottom: 14px; z-index: 5; transform: translateX(-50%); left: calc(var(--fw-pad) + (var(--s) - var(--fw-v0)) * var(--fw-k) * 1px); padding: 0 8px; border-radius: var(--radius-tag); background: var(--fw-surface); box-shadow: inset 0 0 0 1px var(--fw-border); color: var(--fw-text); font-size: 12px; line-height: 20px; white-space: nowrap; pointer-events: none; }
152
+ .fw-root .fw-event-label { position: absolute; bottom: 14px; z-index: 5; transform: translateX(-50%); left: calc(var(--fw-pad) + (var(--s) - var(--fw-v0)) * var(--fw-k) * 1px); padding: 0 8px; border-radius: var(--radius-tag); background: var(--fw-surface); box-shadow: inset 0 0 0 1px var(--fw-border); color: var(--fw-text); font-size: 14px; line-height: 20px; white-space: nowrap; pointer-events: none; }
153
153
  .fw-root .fw-event[data-tone="failed"] { --fw-marker: var(--fw-failed); }
154
154
  .fw-root .fw-event:hover, .fw-root .fw-event:focus-visible { transform: scale(1.4); outline: 0; }
155
155
  .fw-root .fw-cursor { position: absolute; top: 0; bottom: 0; width: 1px; background: color-mix(in oklab, var(--fw-text) 70%, transparent); left: calc(var(--fw-pad) + (var(--fw-t) - var(--fw-v0)) * var(--fw-k) * 1px); }
@@ -188,7 +188,7 @@
188
188
  .fw-root .fw-detail { color: var(--fw-muted); overflow: hidden; min-width: 0; display: inline-flex; align-items: center; gap: 4px; max-width: 100%; }
189
189
  .fw-root .fw-detail-icon { display: inline-flex; }
190
190
  .fw-root .fw-detail-icon :is(svg, img) { width: 12px; height: 12px; }
191
- .fw-root .fw-count { flex-shrink: 0; height: 18px; padding: 0 8px; border-radius: var(--radius-pill); background: var(--fw-well); border: 1px solid var(--fw-border); color: var(--fw-muted); font-size: 12px; line-height: 16px; font-variant-numeric: tabular-nums; }
191
+ .fw-root .fw-count { flex-shrink: 0; height: 18px; padding: 0 8px; border-radius: var(--radius-pill); background: var(--fw-well); border: 1px solid var(--fw-border); color: var(--fw-muted); font-size: 14px; line-height: 18px; font-variant-numeric: tabular-nums; }
192
192
  .fw-root .fw-alert { display: inline-flex; color: var(--fw-failed); flex-shrink: 0; }
193
193
  .fw-root .fw-alert svg { width: 13px; height: 13px; }
194
194
  .fw-root .fw-spinner { width: 10px; height: 10px; border-radius: 50%; border: 1.5px solid color-mix(in oklab, var(--fw-accent) 30%, transparent); border-top-color: var(--fw-accent); animation: fw-spin .8s linear infinite; flex-shrink: 0; }
@@ -198,13 +198,13 @@
198
198
  .fw-root .fw-view-agents .fw-names { flex-direction: column; align-items: flex-start; gap: 0; }
199
199
  .fw-root .fw-view-agents .fw-span-name { font-weight: 600; line-height: 18px; }
200
200
  /* One 16 px line that wraps its last parts out of sight: when the line is full a count drops whole, never "48 …". */
201
- .fw-root .fw-view-agents .fw-subtitle { display: flex; align-items: center; column-gap: 4px; height: 16px; overflow: hidden; max-width: 100%; min-width: 0; color: var(--fw-muted); font-size: 12px; line-height: 16px; }
201
+ .fw-root .fw-view-agents .fw-subtitle { display: flex; align-items: center; column-gap: 4px; height: 18px; overflow: hidden; max-width: 100%; min-width: 0; color: var(--fw-muted); font-size: 14px; line-height: 18px; }
202
202
  .fw-root .fw-view-agents .fw-subtitle-extra { flex: none; white-space: nowrap; }
203
203
  /* Only the tail wraps, so the first part is always on its line and shrinks with an ellipsis; later parts wrap out of sight. */
204
- .fw-root .fw-view-agents .fw-subtitle-tail { display: flex; flex-wrap: wrap; column-gap: 4px; height: 16px; overflow: hidden; min-width: 0; flex: 0 1 auto; }
204
+ .fw-root .fw-view-agents .fw-subtitle-tail { display: flex; flex-wrap: wrap; column-gap: 4px; height: 18px; overflow: hidden; min-width: 0; flex: 0 1 auto; }
205
205
  .fw-root .fw-view-agents .fw-subtitle-text { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
206
206
  .fw-root .fw-view-agents .fw-detail-icon { flex: none; width: 16px; height: 16px; align-items: center; justify-content: center; overflow: hidden; }
207
- .fw-root .fw-view-agents .fw-detail { font-size: 12px; line-height: 16px; }
207
+ .fw-root .fw-view-agents .fw-detail { font-size: 14px; line-height: 18px; }
208
208
  .fw-root .fw-agent-dot { flex: 0 0 8px; width: 8px; height: 8px; border-radius: 50%; background: var(--line, var(--fw-muted)); }
209
209
  /* The dot is outcome only (critique P0 #3): an agent with no recorded outcome gets a hollow ring, never its lane hue. */
210
210
  .fw-root .fw-row:not([data-outcome]) .fw-agent-dot:not([data-outcome]) { background: transparent; box-shadow: inset 0 0 0 1.5px var(--fw-muted); }
@@ -268,7 +268,7 @@
268
268
  .fw-root [data-outcome="failed"], .fw-root [data-outcome="failed"] [data-tone] { --tone: var(--fw-failed); }
269
269
  .fw-root [data-outcome="warn"], .fw-root [data-outcome="warn"] [data-tone] { --tone: var(--fw-amber); }
270
270
  .fw-root [data-outcome="neutral"], .fw-root [data-outcome="neutral"] [data-tone] { --tone: var(--fw-muted); }
271
- .fw-root .fw-legend { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 8px 0 0; padding: 0; list-style: none; color: var(--fw-muted); font-size: 12px; line-height: 16px; }
271
+ .fw-root .fw-legend { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 8px 0 0; padding: 0; list-style: none; color: var(--fw-muted); font-size: 14px; line-height: 18px; }
272
272
  .fw-root .fw-legend li { display: inline-flex; align-items: center; gap: 8px; }
273
273
  .fw-root .fw-legends { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 24px; margin-top: 8px; }
274
274
  .fw-root .fw-legends .fw-legend { margin: 0; }
@@ -303,7 +303,7 @@
303
303
  .fw-root.fw-fill-agent .fw-view-agents :is(.fw-seg-tool, .fw-seg-failed) { background: light-dark(oklch(from var(--tone) 0.80 min(c, 0.10) h), oklch(from var(--tone) 0.64 min(c, 0.10) h)); box-shadow: none; }
304
304
  /* A failed turn is still the agent's work: it keeps the agent's hue, and the red cross on the ending turn says it failed. */
305
305
  .fw-root.fw-fill-agent .fw-view-agents .fw-seg-failed { box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--fw-failed) 55%, transparent); }
306
- .fw-root .fw-view-agents .fw-seg { container-type: inline-size; justify-content: flex-start; font-size: 12px; line-height: 16px; white-space: nowrap; color: var(--fw-seg-ink); }
306
+ .fw-root .fw-view-agents .fw-seg { container-type: inline-size; justify-content: flex-start; font-size: 14px; line-height: 18px; white-space: nowrap; color: var(--fw-seg-ink); }
307
307
  /* Label ink holds 4.5:1 on its fill: page-light on the dark light-theme model step (L 0.50), page-dark on every other step
308
308
  (light tool 0.80, dark pastels 0.82 and 0.64). */
309
309
  .fw-root .fw-view-agents .fw-seg-model { --fw-seg-ink: light-dark(var(--fw-surface), hsl(var(--hsl-background))); }
@@ -333,9 +333,9 @@
333
333
  .fw-root .fw-end { z-index: 2; display: inline-flex; align-items: center; gap: 8px; top: calc(50% + var(--fw-bar-shift) - var(--fw-bar-h) / 2); height: var(--fw-bar-h);
334
334
  left: min(calc(var(--x0) + max(var(--w), 3px) + 4px), calc(100% - var(--fw-end-w, 0px) - 4px)); padding: 0 4px; border-radius: var(--radius-tag);
335
335
  background: linear-gradient(var(--fw-tint, transparent) 0 0), var(--fw-surface); white-space: nowrap; pointer-events: none; }
336
- .fw-root .fw-duration { font-size: 12px; color: var(--fw-muted); font-variant-numeric: tabular-nums; }
336
+ .fw-root .fw-duration { font-size: 14px; color: var(--fw-muted); font-variant-numeric: tabular-nums; }
337
337
  .fw-root .fw-k-failed ~ .fw-end .fw-duration { color: var(--fw-failed); }
338
- .fw-root .fw-badge { height: 18px; padding: 0 8px; border-radius: var(--radius-pill); font-size: 12px; line-height: 16px; font-weight: 600; color: var(--fw-amber); background: color-mix(in oklab, var(--fw-amber) 13%, transparent); border: 1px solid color-mix(in oklab, var(--fw-amber) 28%, transparent); }
338
+ .fw-root .fw-badge { height: 18px; padding: 0 8px; border-radius: var(--radius-pill); font-size: 14px; line-height: 18px; font-weight: 600; color: var(--fw-amber); background: color-mix(in oklab, var(--fw-amber) 13%, transparent); border: 1px solid color-mix(in oklab, var(--fw-amber) 28%, transparent); }
339
339
 
340
340
  /* Handoff elbows: 1.5 px stroke, 6 px radius, a 5 px dot where the handoff leaves its sender. */
341
341
  /* Under the rows (which follow it), so end labels and badges always sit above the connectors. */
@@ -369,13 +369,13 @@
369
369
  /* A hover card never covers the next mark: only a pinned card (a dialog) takes the pointer. */
370
370
  .fw-root .fw-card[role="tooltip"] { pointer-events: none; }
371
371
  .fw-root .fw-card-above .fw-card { transform: translateY(-100%); animation-name: fw-arrive-above; }
372
- .fw-root .fw-card-agent { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; font-size: 12px; font-weight: 600; }
372
+ .fw-root .fw-card-agent { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; font-size: 14px; font-weight: 600; }
373
373
  .fw-root .fw-card-agent .fw-agent-dot { align-self: center; }
374
374
  .fw-root .fw-card-head { display: flex; align-items: center; gap: 8px; margin-bottom: 8px; }
375
375
  .fw-root .fw-card-head .fw-icon-tile { flex-basis: 28px; width: 28px; height: 28px; border-radius: var(--radius-md); }
376
376
  .fw-root .fw-card-head .fw-icon-tile :is(svg, img) { width: 16px; height: 16px; }
377
377
  .fw-root .fw-card-name { flex: 1; min-width: 0; font-size: 14px; line-height: 20px; font-weight: 600; overflow-wrap: anywhere; }
378
- .fw-root .fw-pill { flex-shrink: 0; height: 20px; padding: 0 8px; border-radius: var(--radius-pill); font-size: 12px; line-height: 20px; font-weight: 600; }
378
+ .fw-root .fw-pill { flex-shrink: 0; height: 20px; padding: 0 8px; border-radius: var(--radius-pill); font-size: 14px; line-height: 20px; font-weight: 600; }
379
379
  .fw-root .fw-pill-done { color: var(--fw-ok); background: color-mix(in oklab, var(--fw-ok) 13%, transparent); }
380
380
  .fw-root .fw-pill-running { color: var(--fw-accent); background: color-mix(in oklab, var(--fw-accent) 13%, transparent); }
381
381
  .fw-root .fw-pill-failed { color: var(--fw-failed); background: color-mix(in oklab, var(--fw-failed) 13%, transparent); }
@@ -383,9 +383,9 @@
383
383
  .fw-root .fw-icon-button:hover:not(:disabled) { background: var(--fw-hover); color: var(--fw-text); }
384
384
  .fw-root .fw-card-close { width: 20px; height: 20px; margin-right: -4px; }
385
385
  /* The card's table: label and value on one line each, every value with its unit; a tool breakdown sits under its total. */
386
- .fw-root .fw-card-table { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 6px 16px; padding-top: 8px; border-top: 1px solid var(--fw-border); font-size: 12px; line-height: 16px; }
386
+ .fw-root .fw-card-table { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 6px 16px; padding-top: 8px; border-top: 1px solid var(--fw-border); font-size: 14px; line-height: 18px; }
387
387
  .fw-root .fw-card-table > div { display: contents; }
388
- .fw-root .fw-card-table dt, .fw-root .fw-card-label { font-size: 12px; line-height: 16px; color: var(--fw-muted); }
388
+ .fw-root .fw-card-table dt, .fw-root .fw-card-label { font-size: 14px; line-height: 18px; color: var(--fw-muted); }
389
389
  .fw-root .fw-card-table dd { min-width: 0; font-weight: 500; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
390
390
  /* A value of several parts wraps between parts, never inside one ("4.0M" / "cached"). */
391
391
  .fw-root .fw-card-parts { display: flex; flex-wrap: wrap; column-gap: 4px; }
@@ -399,7 +399,7 @@
399
399
  .fw-root .fw-card-compact .fw-card-agent { font-size: 14px; line-height: 20px; }
400
400
  .fw-root .fw-card-who { min-width: 0; flex: 1; overflow: hidden; overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
401
401
  .fw-root .fw-pill-outcome { color: var(--line); background: color-mix(in oklab, var(--tone) 16%, transparent); box-shadow: inset 0 0 0 1px color-mix(in oklab, var(--tone) 35%, transparent); }
402
- .fw-root .fw-card-step { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--fw-border); color: var(--fw-muted); font-size: 12px; line-height: 16px; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
402
+ .fw-root .fw-card-step { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--fw-border); color: var(--fw-muted); font-size: 14px; line-height: 18px; font-variant-numeric: tabular-nums; overflow-wrap: anywhere; }
403
403
  .fw-root .fw-card-result { margin-top: 8px; font-size: 14px; line-height: 20px; overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
404
404
  .fw-root .fw-card-text p { margin-top: 4px; color: var(--fw-text); overflow-wrap: anywhere; display: -webkit-box; -webkit-line-clamp: 4; -webkit-box-orient: vertical; overflow: hidden; }
405
405
 
@@ -3656,8 +3656,9 @@ const FlowRow = memo(function FlowRow(props) {
3656
3656
  });
3657
3657
  }, (a, b) => a.row === b.row && a.view === b.view && a.top === b.top && a.collapsed === b.collapsed && a.searching === b.searching && a.slowest === b.slowest && a.costliest === b.costliest && a.critical === b.critical && a.matched === b.matched && a.active === b.active && a.focusable === b.focusable && a.selected === b.selected && a.sticky === b.sticky && a.motion === b.motion && a.renderIcon === b.renderIcon && a.fillByAgent === b.fillByAgent && a.sharedDetail === b.sharedDetail && a.sharedOutcome === b.sharedOutcome && a.expanded === b.expanded && (a.clockMs === b.clockMs || !open(a.row, a.clockMs) && !open(b.row, b.clockMs)));
3658
3658
  /** An elbow connector between two rows at one moment, drawn in the row's tone; appears when the clock reaches it. */
3659
- function LinkMark({ link, rowHeight, hot }) {
3660
- const upper = Math.min(link.from, link.to), lower = Math.max(link.from, link.to);
3659
+ /** `short`: only the last row of the connector, an elbow into the row it reaches. */
3660
+ function LinkMark({ link, rowHeight, hot, short }) {
3661
+ const lower = Math.max(link.from, link.to), upper = short ? Math.max(Math.min(link.from, link.to), lower - 1) : Math.min(link.from, link.to);
3661
3662
  const style = {
3662
3663
  ...at(link.atMs, link.atMs),
3663
3664
  top: upper * rowHeight + rowHeight / 2 + 5,
@@ -4187,11 +4188,16 @@ function FlowBody(props) {
4187
4188
  children: [/* @__PURE__ */ jsx("div", {
4188
4189
  className: "fw-links",
4189
4190
  "aria-hidden": true,
4190
- children: links.filter((link) => Math.max(link.from, link.to) >= first && Math.min(link.from, link.to) <= last).map((link) => /* @__PURE__ */ jsx(LinkMark, {
4191
- link,
4192
- rowHeight,
4193
- hot: props.focusId !== void 0 && (rows[link.from]?.id === props.focusId || rows[link.to]?.id === props.focusId)
4194
- }, link.id))
4191
+ children: links.filter((link) => Math.max(link.from, link.to) >= first && Math.min(link.from, link.to) <= last).map((link) => {
4192
+ const hot = props.focusId !== void 0 && (rows[link.from]?.id === props.focusId || rows[link.to]?.id === props.focusId);
4193
+ if (view === "agents" && !hot && link.id.startsWith("r-")) return null;
4194
+ return /* @__PURE__ */ jsx(LinkMark, {
4195
+ link,
4196
+ rowHeight,
4197
+ hot,
4198
+ short: view === "agents" && !hot
4199
+ }, link.id);
4200
+ })
4195
4201
  }), rows.slice(first, last).map((item, offset) => row(item, first + offset))]
4196
4202
  }), rows.length === 0 && /* @__PURE__ */ jsx("p", {
4197
4203
  role: "status",
@@ -4861,15 +4867,17 @@ function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defa
4861
4867
  if (!box) return;
4862
4868
  const hostTop = root.current.getBoundingClientRect().top;
4863
4869
  const room = {
4864
- above: hostTop + card.anchorTop - 16,
4870
+ above: card.anchorTop - 16,
4865
4871
  below: globalThis.innerHeight - (hostTop + card.anchorBottom) - 16
4866
4872
  };
4867
4873
  const preferred = card.above ? room.above : room.below;
4868
4874
  const other = card.above ? room.below : room.above;
4875
+ const above = box.height <= preferred || box.height > other && preferred >= other ? card.above : !card.above;
4869
4876
  setCard({
4870
4877
  ...card,
4871
4878
  fitted: true,
4872
- above: box.height <= preferred || box.height > other && preferred >= other ? card.above : !card.above
4879
+ above,
4880
+ top: above ? Math.max(8, card.anchorTop - 8 - box.height) : card.anchorBottom + 8
4873
4881
  });
4874
4882
  }, [card, cardId]);
4875
4883
  latest.current.inspect = (target, element, x) => {
@@ -5145,7 +5153,7 @@ function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defa
5145
5153
  onCollapseAll: () => setCollapsed(new Set(rows.filter((row) => row.hasChildren).map((row) => row.id)))
5146
5154
  }),
5147
5155
  card && cardRow && /* @__PURE__ */ jsx("div", {
5148
- className: `fw-card-anchor${card.above ? " fw-card-above" : ""}`,
5156
+ className: `fw-card-anchor${card.above && card.top === void 0 ? " fw-card-above" : ""}`,
5149
5157
  onPointerEnter: () => clearTimeout(hideTimer.current),
5150
5158
  onPointerLeave: card.pinned ? void 0 : leave,
5151
5159
  children: /* @__PURE__ */ jsx(SpanCard, {
@@ -5154,7 +5162,7 @@ function FlowWaterfall({ trace, live, startedAt, label = "Trace waterfall", defa
5154
5162
  agent: cardAgent,
5155
5163
  clockMs,
5156
5164
  left: card.left,
5157
- top: card.above ? card.anchorTop - 8 : card.anchorBottom + 8,
5165
+ top: card.top ?? (card.above ? card.anchorTop - 8 : card.anchorBottom + 8),
5158
5166
  pinned: card.pinned,
5159
5167
  onClose: closeCard,
5160
5168
  renderIcon,
@@ -1,30 +1,30 @@
1
1
  /* Shared live charts. Consumers may set --chart-live-* tokens on an ancestor. Sizes are px on the 12/14 type scale and a
2
2
  4 px grid, so a host's font size never rescales them. */
3
- .ov-empty { margin: 0; color: var(--chart-live-faint, #777); font-size: 12px; }
3
+ .ov-empty { margin: 0; color: var(--chart-live-faint, #777); font-size: 14px; }
4
4
  .ov-plot { position: relative; min-width: 0; }
5
5
  .ov-plot svg { display: block; overflow: visible; }
6
6
  line.ov-gridline { stroke: color-mix(in srgb, var(--chart-live-faint, #777) 22%, transparent); stroke-width: 1; }
7
7
  .ov-axis { fill: var(--chart-live-muted, #666); font: 12px/16px var(--chart-live-font-mono, monospace); font-variant-numeric: tabular-nums; }
8
8
  .ov-crosshair { stroke: var(--chart-live-faint, #777); stroke-dasharray: 3 3; }
9
- .ov-tip { position: absolute; z-index: 4; display: grid; gap: 4px; min-width: 160px; max-width: 240px; padding: 8px 12px; background: var(--chart-live-raised, #fff); border: 1px solid var(--chart-live-border, #aaa); border-radius: 8px; box-shadow: 0 10px 24px -12px #000; font-size: 12px; line-height: 16px; pointer-events: none; }
9
+ .ov-tip { position: absolute; z-index: 4; display: grid; gap: 4px; min-width: 160px; max-width: 240px; padding: 8px 12px; background: var(--chart-live-raised, #fff); border: 1px solid var(--chart-live-border, #aaa); border-radius: 8px; box-shadow: 0 10px 24px -12px #000; font-size: 14px; line-height: 20px; pointer-events: none; }
10
10
  .ov-tip-line { display: grid; grid-template-columns: auto 1fr auto; gap: 8px; align-items: center; color: var(--chart-live-muted, #666); }
11
11
  .ov-tip-line b { color: var(--chart-live-fg, #222); font-variant-numeric: tabular-nums; }
12
12
  .ov-hbars { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: minmax(0, max-content) minmax(33%, 1fr) max-content; gap: 4px 12px; }
13
13
  .ov-hbars li { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; }
14
14
  .ov-hbars li > a, .ov-hbars li > div { display: grid; grid-column: 1 / -1; grid-template-columns: subgrid; row-gap: 0; align-items: center; padding: 4px; border-radius: 6px; color: inherit; text-decoration: none; }
15
- .ov-hbars-more { grid-column: 1 / -1; padding: 0 4px; font-size: 12px; color: var(--chart-live-faint, #777); }
15
+ .ov-hbars-more { grid-column: 1 / -1; padding: 0 4px; font-size: 14px; color: var(--chart-live-faint, #777); }
16
16
  .ov-hbars li > a:hover, .ov-hbars li > div:hover { background: var(--chart-live-hover, #eee); text-decoration: none; }
17
17
  .ov-hbar-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-size: 14px; line-height: 20px; color: var(--chart-live-fg, #222); }
18
18
  .ov-hbar-track { height: 8px; border-radius: 3px; background: color-mix(in srgb, var(--chart-live-faint, #777) 14%, transparent); overflow: hidden; }
19
19
  .ov-hbar-track > span { display: block; height: 100%; border-radius: 3px; }
20
20
  .ov-hbar-value { font: 12px/16px var(--chart-live-font-mono, monospace); font-variant-numeric: tabular-nums; text-align: right; color: var(--chart-live-fg, #222); }
21
- .ov-hbar-note { grid-column: 1 / -1; font-size: 12px; color: var(--chart-live-faint, #777); }
21
+ .ov-hbar-note { grid-column: 1 / -1; font-size: 14px; color: var(--chart-live-faint, #777); }
22
22
  .ov-meter { display: grid; gap: 4px; min-width: 0; }
23
23
  .ov-meter-track { display: block; height: 8px; border-radius: 3px; background: color-mix(in srgb, var(--chart-live-faint, #777) 14%, transparent); overflow: hidden; }
24
24
  .ov-meter-track > span { display: block; height: 100%; border-radius: 3px; }
25
25
  .ov-meter-text { font: 12px/16px var(--chart-live-font-mono, monospace); font-variant-numeric: tabular-nums; color: var(--chart-live-muted, #666); }
26
26
  .ov-spark { display: block; width: 112px; height: 24px; }
27
- .ov-spark-empty { font-size: 12px; color: var(--chart-live-faint, #777); }
27
+ .ov-spark-empty { font-size: 14px; color: var(--chart-live-faint, #777); }
28
28
  .ov-tip-line i { display: inline-block; width: 8px; height: 8px; border-radius: 2px; margin-right: 4px; vertical-align: 0; }
29
29
  /* Recorded events and spans. Colours come from Brand tokens; kinds also differ by stroke pattern and glyph. */
30
30
  .ov-mark { stroke-width: 1.5; fill: none; }
@@ -45,7 +45,7 @@ line.ov-gridline { stroke: color-mix(in srgb, var(--chart-live-faint, #777) 22%,
45
45
  .ov-verdict-fail .ov-mark-head { fill: var(--chart-live-danger, var(--chart-breach, var(--status-error))); }
46
46
  .ov-verdict-unknown .ov-mark { stroke: var(--chart-live-faint, var(--chart-muted)); }
47
47
  .ov-verdict-unknown .ov-mark-head { fill: var(--chart-live-faint, var(--chart-muted)); }
48
- .ov-mark-label { fill: var(--chart-live-fg, var(--chart-ink)); font-size: 12px; paint-order: stroke; stroke: var(--chart-live-surface, var(--chart-canvas)); stroke-width: 3px; stroke-linejoin: round; }
48
+ .ov-mark-label { fill: var(--chart-live-fg, var(--chart-ink)); font-size: 14px; paint-order: stroke; stroke: var(--chart-live-surface, var(--chart-canvas)); stroke-width: 3px; stroke-linejoin: round; }
49
49
  .ov-band-after-pass { fill: color-mix(in srgb, var(--chart-live-pass, var(--chart-pass, var(--status-running))) 12%, transparent); }
50
50
  .ov-band-idle { fill: var(--chart-live-hover, var(--chart-shade)); }
51
51
  .ov-band-blocked { fill: color-mix(in srgb, var(--chart-live-danger, var(--chart-breach, var(--status-error))) 9%, transparent); }
@@ -57,7 +57,7 @@ line.ov-gridline { stroke: color-mix(in srgb, var(--chart-live-faint, #777) 22%,
57
57
  .ov-hatched { background: repeating-linear-gradient(135deg, var(--chart-live-faint, var(--chart-muted)) 0 1px, transparent 1px 5px), color-mix(in srgb, var(--chart-live-faint, var(--chart-muted)) 10%, transparent); }
58
58
  .ov-now { stroke: var(--chart-live-fg, var(--chart-ink)); stroke-width: 1.5; }
59
59
  .ov-gantt-open { stroke: var(--chart-live-fg, var(--chart-ink)); stroke-width: 1.5; stroke-dasharray: 3 2; }
60
- .ov-events, .ov-key, .ov-meter-key { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 4px 16px; font-size: 12px; line-height: 16px; color: var(--chart-live-muted, var(--chart-ink-muted)); }
60
+ .ov-events, .ov-key, .ov-meter-key { list-style: none; margin: 4px 0 0; padding: 0; display: flex; flex-wrap: wrap; gap: 4px 16px; font-size: 14px; line-height: 20px; color: var(--chart-live-muted, var(--chart-ink-muted)); }
61
61
  .ov-key li, .ov-events li, .ov-meter-key li { display: inline-flex; align-items: center; gap: 8px; }
62
62
  .ov-meter-key b { font-weight: 600; color: var(--chart-live-fg, var(--chart-ink)); font-family: var(--chart-live-font-mono, monospace); font-variant-numeric: tabular-nums; }
63
63
  .ov-meter-key i, .ov-event-swatch { display: inline-block; width: 12px; height: 12px; border-radius: 2px; }
@@ -73,7 +73,7 @@ line.ov-gridline { stroke: color-mix(in srgb, var(--chart-live-faint, #777) 22%,
73
73
  .ov-event-after-pass { background: color-mix(in srgb, var(--chart-live-pass, var(--chart-pass, var(--status-running))) 25%, transparent); }
74
74
  .ov-event-idle { background: var(--chart-live-hover, var(--chart-shade)); }
75
75
  .ov-event-missing { background: repeating-linear-gradient(135deg, var(--chart-live-faint, var(--chart-muted)) 0 1px, transparent 1px 4px); }
76
- .ov-refusal { margin: 0; color: var(--chart-live-muted, var(--chart-ink-muted)); font-size: 12px; }
76
+ .ov-refusal { margin: 0; color: var(--chart-live-muted, var(--chart-ink-muted)); font-size: 14px; }
77
77
 
78
78
  /*
79
79
  * DotMap: thousands of dots on one canvas. A categorical lens names at most three categories in colour, the first
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/charts",
3
- "version": "0.21.21",
3
+ "version": "0.21.22",
4
4
  "description": "Static SVG and HTML figures for benchmarks and operational timing. Draws from producer data and refuses what it cannot draw honestly.",
5
5
  "type": "module",
6
6
  "license": "MIT",