@joewinke/jatui 0.38.6 → 0.39.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.
Files changed (62) hide show
  1. package/CLAUDE.md +31 -0
  2. package/THIRD_PARTY_NOTICES.md +51 -0
  3. package/dist/components/BulkActionBar.svelte +32 -2
  4. package/dist/components/BulkActionBar.svelte.d.ts +5 -1
  5. package/dist/components/FloatingActionBar.svelte +102 -34
  6. package/dist/components/FloatingActionBar.svelte.d.ts +9 -0
  7. package/dist/components/MediaExplorer.svelte +249 -0
  8. package/dist/components/MediaExplorer.svelte.d.ts +37 -0
  9. package/dist/components/NotificationCenter.svelte +481 -0
  10. package/dist/components/NotificationCenter.svelte.d.ts +29 -0
  11. package/dist/components/SearchDropdown.svelte +54 -8
  12. package/dist/components/SearchDropdown.svelte.d.ts +12 -0
  13. package/dist/components/agent/AgentLog.svelte +217 -0
  14. package/dist/components/agent/AgentLog.svelte.d.ts +72 -0
  15. package/dist/components/agent/AgentLogRow.svelte +281 -0
  16. package/dist/components/agent/AgentLogRow.svelte.d.ts +21 -0
  17. package/dist/components/agent/AgentTaskList.svelte +607 -0
  18. package/dist/components/agent/AgentTaskList.svelte.d.ts +40 -0
  19. package/dist/components/agent/AgentThinking.svelte +280 -0
  20. package/dist/components/agent/AgentThinking.svelte.d.ts +22 -0
  21. package/dist/components/agent/ComposerGlow.svelte +265 -0
  22. package/dist/components/agent/ComposerGlow.svelte.d.ts +18 -0
  23. package/dist/components/agent/ContextMeter.svelte +277 -0
  24. package/dist/components/agent/ContextMeter.svelte.d.ts +21 -0
  25. package/dist/components/agent/Questionnaire.svelte +767 -0
  26. package/dist/components/agent/Questionnaire.svelte.d.ts +29 -0
  27. package/dist/components/agent/ShimmerText.svelte +100 -0
  28. package/dist/components/agent/ShimmerText.svelte.d.ts +19 -0
  29. package/dist/components/agent/StreamedText.svelte +135 -0
  30. package/dist/components/agent/StreamedText.svelte.d.ts +13 -0
  31. package/dist/components/agent/agentLog.d.ts +22 -0
  32. package/dist/components/agent/agentLog.js +26 -0
  33. package/dist/components/agent/agentTaskList.d.ts +90 -0
  34. package/dist/components/agent/agentTaskList.js +93 -0
  35. package/dist/components/agent/agentThinking.d.ts +46 -0
  36. package/dist/components/agent/agentThinking.js +78 -0
  37. package/dist/components/agent/contextMeter.d.ts +97 -0
  38. package/dist/components/agent/contextMeter.js +156 -0
  39. package/dist/components/agent/questionnaire.d.ts +104 -0
  40. package/dist/components/agent/questionnaire.js +225 -0
  41. package/dist/components/agent/revealCore.d.ts +74 -0
  42. package/dist/components/agent/revealCore.js +160 -0
  43. package/dist/components/agent/revealTicker.d.ts +34 -0
  44. package/dist/components/agent/revealTicker.js +73 -0
  45. package/dist/components/agent/streamedText.d.ts +28 -0
  46. package/dist/components/agent/streamedText.js +59 -0
  47. package/dist/components/messaging/MessageInput.svelte +34 -4
  48. package/dist/components/messaging/MessageInput.svelte.d.ts +7 -0
  49. package/dist/components/messaging/MessageItem.svelte +2 -2
  50. package/dist/components/notificationCenter.d.ts +65 -0
  51. package/dist/components/notificationCenter.js +110 -0
  52. package/dist/components/progress/Steps.svelte +269 -5
  53. package/dist/components/progress/Steps.svelte.d.ts +16 -1
  54. package/dist/components/progress/stepsSummary.d.ts +14 -0
  55. package/dist/components/progress/stepsSummary.js +32 -0
  56. package/dist/index.d.ts +34 -0
  57. package/dist/index.js +29 -0
  58. package/dist/selection/clickSelection.d.ts +89 -0
  59. package/dist/selection/clickSelection.js +152 -0
  60. package/dist/selection/createClickSelection.d.ts +79 -0
  61. package/dist/selection/createClickSelection.js +134 -0
  62. package/package.json +3 -2
@@ -0,0 +1,217 @@
1
+ <!--
2
+ AgentLog — a streaming agent transcript that draws itself down the page:
3
+ rows arrive one at a time, each growing in (height, a brief blur and a small
4
+ lift, a soft fading clip edge) while a curved tree guide strokes alongside
5
+ them, plus an optional "working" line at the tail.
6
+
7
+ This is the machinery only; what a row says is yours. Two ways to fill it:
8
+
9
+ items + row snippet <AgentLog items={visible} key={(s) => s.id}>
10
+ {#snippet row(step)}{step.label}{/snippet}
11
+ </AgentLog>
12
+ children <AgentLog>
13
+ <AgentLogRow first>…</AgentLogRow>
14
+ <AgentLogRow last>…</AgentLogRow>
15
+ </AgentLog>
16
+
17
+ Pacing is separate: slice your items with createRevealTicker (timer or
18
+ real-event driven). Rows already present on the log's first render rest;
19
+ only rows added afterwards animate (pass `appear` to animate those too).
20
+
21
+ Adapted from BoardUI's agent-log (WorkingRow, GuideBridge, the overall
22
+ structure): MIT License — Copyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)
23
+ The working row sits deliberately OFF the guide: the tree records what the
24
+ agent did, and that one line has not happened yet.
25
+ -->
26
+ <script lang="ts" generics="T">
27
+ import { onMount, type Snippet } from 'svelte';
28
+ import AgentThinking from './AgentThinking.svelte';
29
+ import AgentLogRow from './AgentLogRow.svelte';
30
+ import { getAgentLogContext, setAgentLogContext } from './agentLog';
31
+ import { prefersReducedMotion } from '../../motion/level';
32
+
33
+ interface Props {
34
+ /** Rows to render (already sliced to what should be visible). */
35
+ items?: T[];
36
+ /** Row content for `items`. */
37
+ row?: Snippet<[item: T, index: number]>;
38
+ /** Stable key per item. Default: index. */
39
+ key?: (item: T, index: number) => string | number;
40
+ /** Extra classes per row (items mode). */
41
+ rowClass?: (item: T, index: number) => string;
42
+ /** Manual rows (AgentLogRow) instead of `items`. */
43
+ children?: Snippet;
44
+ /**
45
+ * Working line at the tail (AgentThinking "stars"): a label, or
46
+ * false/null/'' for none.
47
+ */
48
+ working?: string | false | null;
49
+ /** Elapsed timer on the working line. */
50
+ workingTimer?: boolean;
51
+ /** When the work started (epoch ms) — keeps the working timer honest across re-mounts. */
52
+ workingStartedAt?: number;
53
+ /**
54
+ * Draw the tree guide. Default true.
55
+ */
56
+ guide?: boolean;
57
+ /**
58
+ * Nested list: draw a stretch of trunk this many px ABOVE the first row
59
+ * (from the parent row's glyph down to this list) and make the first branch
60
+ * wait for it, so the two levels read as one line. 0 = none.
61
+ */
62
+ bridge?: number;
63
+ /**
64
+ * Animate rows present on the first render. Default: inherit — a log
65
+ * mounted inside a row that is itself growing in animates; a top-level log
66
+ * does not.
67
+ */
68
+ appear?: boolean;
69
+ /**
70
+ * Announce additions to screen readers (role="log", polite). Turn off for a
71
+ * log nested inside another live region.
72
+ */
73
+ live?: boolean;
74
+ /** Accessible name for the log. */
75
+ ariaLabel?: string;
76
+ /** aria-busy while work is in progress. Default: a working line is shown. */
77
+ busy?: boolean;
78
+ class?: string;
79
+ listClass?: string;
80
+ }
81
+
82
+ let {
83
+ items,
84
+ row,
85
+ key,
86
+ rowClass,
87
+ children,
88
+ working = null,
89
+ workingTimer = false,
90
+ workingStartedAt,
91
+ guide = true,
92
+ bridge = 0,
93
+ appear,
94
+ live = true,
95
+ ariaLabel,
96
+ busy,
97
+ class: className = '',
98
+ listClass = ''
99
+ }: Props = $props();
100
+
101
+ const parent = getAgentLogContext();
102
+ // Plain (non-reactive) flag: each row reads it once, when it mounts.
103
+ // svelte-ignore state_referenced_locally
104
+ const flag = { live: appear ?? parent?.isLive() ?? false };
105
+ const reduced = prefersReducedMotion();
106
+
107
+ setAgentLogContext({
108
+ isLive: () => flag.live,
109
+ get bridged() {
110
+ return bridge > 0;
111
+ }
112
+ });
113
+
114
+ onMount(() => {
115
+ flag.live = true;
116
+ });
117
+
118
+ const keyOf = (item: T, i: number) => (key ? key(item, i) : i);
119
+ const showWorking = $derived(!!working);
120
+ </script>
121
+
122
+ <div
123
+ class="agent-log {className}"
124
+ role={live ? 'log' : undefined}
125
+ aria-live={live ? 'polite' : undefined}
126
+ aria-relevant={live ? 'additions' : undefined}
127
+ aria-label={ariaLabel}
128
+ aria-busy={busy ?? showWorking}
129
+ >
130
+ {#if bridge > 0 && guide && ((items && items.length > 0) || children)}
131
+ <span
132
+ class="al-bridge"
133
+ class:is-drawing={!reduced && flag.live}
134
+ style:top="-{bridge}px"
135
+ style:height="{bridge}px"
136
+ aria-hidden="true"
137
+ ></span>
138
+ {/if}
139
+ <ol class="al-list {listClass}" class:has-bridge={bridge > 0} role="list">
140
+ {#if items && row}
141
+ {#each items as item, i (keyOf(item, i))}
142
+ <AgentLogRow
143
+ first={i === 0}
144
+ last={i === items.length - 1}
145
+ {guide}
146
+ class={rowClass?.(item, i) ?? ''}
147
+ >
148
+ {@render row(item, i)}
149
+ </AgentLogRow>
150
+ {/each}
151
+ {:else if children}
152
+ {@render children()}
153
+ {/if}
154
+ </ol>
155
+
156
+ {#if showWorking}
157
+ <AgentLogRow as="div" guide={false} class="al-working">
158
+ <div class="al-working-inner">
159
+ <AgentThinking
160
+ variant="stars"
161
+ size="sm"
162
+ label={working || 'Working'}
163
+ showTimer={workingTimer}
164
+ startedAt={workingStartedAt}
165
+ />
166
+ </div>
167
+ </AgentLogRow>
168
+ {/if}
169
+ </div>
170
+
171
+ <style>
172
+ .agent-log {
173
+ position: relative;
174
+ min-width: 0;
175
+ }
176
+ .al-list {
177
+ position: relative;
178
+ margin: 0;
179
+ padding: 0;
180
+ list-style: none;
181
+ /* rows must touch: each row's trunk meets the next row's branch */
182
+ display: flex;
183
+ flex-direction: column;
184
+ gap: 0;
185
+ }
186
+
187
+ /* From the parent row's glyph down into this list's first branch. */
188
+ .al-bridge {
189
+ pointer-events: none;
190
+ position: absolute;
191
+ inset-inline-start: 0;
192
+ width: 1px;
193
+ background: color-mix(in oklab, var(--color-base-content) 24%, transparent);
194
+ transform-origin: top;
195
+ }
196
+ .al-bridge.is-drawing {
197
+ animation: al-bridge calc(var(--motion-fast, 150ms) * 0.8) linear both;
198
+ }
199
+ @keyframes al-bridge {
200
+ from {
201
+ transform: scaleY(0);
202
+ }
203
+ to {
204
+ transform: scaleY(1);
205
+ }
206
+ }
207
+
208
+ .al-working-inner {
209
+ padding-block: 0.25rem;
210
+ }
211
+
212
+ @media (prefers-reduced-motion: reduce) {
213
+ .al-bridge.is-drawing {
214
+ animation: none;
215
+ }
216
+ }
217
+ </style>
@@ -0,0 +1,72 @@
1
+ import { type Snippet } from 'svelte';
2
+ declare function $$render<T>(): {
3
+ props: {
4
+ /** Rows to render (already sliced to what should be visible). */
5
+ items?: T[];
6
+ /** Row content for `items`. */
7
+ row?: Snippet<[item: T, index: number]>;
8
+ /** Stable key per item. Default: index. */
9
+ key?: (item: T, index: number) => string | number;
10
+ /** Extra classes per row (items mode). */
11
+ rowClass?: (item: T, index: number) => string;
12
+ /** Manual rows (AgentLogRow) instead of `items`. */
13
+ children?: Snippet;
14
+ /**
15
+ * Working line at the tail (AgentThinking "stars"): a label, or
16
+ * false/null/'' for none.
17
+ */
18
+ working?: string | false | null;
19
+ /** Elapsed timer on the working line. */
20
+ workingTimer?: boolean;
21
+ /** When the work started (epoch ms) — keeps the working timer honest across re-mounts. */
22
+ workingStartedAt?: number;
23
+ /**
24
+ * Draw the tree guide. Default true.
25
+ */
26
+ guide?: boolean;
27
+ /**
28
+ * Nested list: draw a stretch of trunk this many px ABOVE the first row
29
+ * (from the parent row's glyph down to this list) and make the first branch
30
+ * wait for it, so the two levels read as one line. 0 = none.
31
+ */
32
+ bridge?: number;
33
+ /**
34
+ * Animate rows present on the first render. Default: inherit — a log
35
+ * mounted inside a row that is itself growing in animates; a top-level log
36
+ * does not.
37
+ */
38
+ appear?: boolean;
39
+ /**
40
+ * Announce additions to screen readers (role="log", polite). Turn off for a
41
+ * log nested inside another live region.
42
+ */
43
+ live?: boolean;
44
+ /** Accessible name for the log. */
45
+ ariaLabel?: string;
46
+ /** aria-busy while work is in progress. Default: a working line is shown. */
47
+ busy?: boolean;
48
+ class?: string;
49
+ listClass?: string;
50
+ };
51
+ exports: {};
52
+ bindings: "";
53
+ slots: {};
54
+ events: {};
55
+ };
56
+ declare class __sveltets_Render<T> {
57
+ props(): ReturnType<typeof $$render<T>>['props'];
58
+ events(): ReturnType<typeof $$render<T>>['events'];
59
+ slots(): ReturnType<typeof $$render<T>>['slots'];
60
+ bindings(): "";
61
+ exports(): {};
62
+ }
63
+ interface $$IsomorphicComponent {
64
+ new <T>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
65
+ $$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
66
+ } & ReturnType<__sveltets_Render<T>['exports']>;
67
+ <T>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
68
+ z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
69
+ }
70
+ declare const AgentLog: $$IsomorphicComponent;
71
+ type AgentLog<T> = InstanceType<typeof AgentLog<T>>;
72
+ export default AgentLog;
@@ -0,0 +1,281 @@
1
+ <!--
2
+ AgentLogRow — one row of an AgentLog: the grow-in reveal, the soft clipping
3
+ edge that keeps it from being cut as it grows, and the stretch of tree guide
4
+ that belongs to it.
5
+
6
+ Adapted from BoardUI's agent-log (LogRow / RowConnector / useRevealMask):
7
+ MIT License — Copyright (c) 2026 Mertcan Dundar Esmergul (BoardUI)
8
+ What changed in the port: the `motion` library is replaced by CSS — height
9
+ 0 → auto is a grid-template-rows 0fr → 1fr keyframe, the soft edge is a
10
+ registered `--jatui-reveal-fade` length animated inside a mask gradient,
11
+ the branch draws with stroke-dashoffset on pathLength=1 and the trunk with
12
+ a scaleY. Durations come from --motion-* tokens (so data-motion levels
13
+ rescale them) with glide easing; the guide pen stays linear on purpose so
14
+ junctions don't stall. Rows present on the log's first render rest instead
15
+ of animating.
16
+
17
+ At rest a row carries no mask, no blur, no overflow clip and no
18
+ compositing layer. Under prefers-reduced-motion it always renders at rest.
19
+ -->
20
+ <script lang="ts">
21
+ import type { Snippet } from 'svelte';
22
+ import { prefersReducedMotion } from '../../motion/level';
23
+ import { BRANCH_PATH, BRANCH_WIDTH, BRANCH_Y, getAgentLogContext } from './agentLog';
24
+
25
+ interface Props {
26
+ /** First row of its list: its branch starts with the row (no tail above to wait for). */
27
+ first?: boolean;
28
+ /** Last row of its list: no trunk below the elbow, so the guide ends on the corner. */
29
+ last?: boolean;
30
+ /** Draw the tree guide. false for rows that are not findings (e.g. the working row). */
31
+ guide?: boolean;
32
+ /**
33
+ * Force the grow-in on or off. Default: animate when the row is added after
34
+ * its AgentLog's first render (always, when used outside an AgentLog).
35
+ */
36
+ animate?: boolean;
37
+ /** Element to render: `li` inside a list, `div` elsewhere. */
38
+ as?: 'li' | 'div';
39
+ class?: string;
40
+ children: Snippet;
41
+ }
42
+
43
+ let {
44
+ first = false,
45
+ last = false,
46
+ guide = true,
47
+ animate,
48
+ as = 'li',
49
+ class: className = '',
50
+ children
51
+ }: Props = $props();
52
+
53
+ const ctx = getAgentLogContext();
54
+ const reduced = prefersReducedMotion();
55
+ // Decided once, at mount: a row never starts animating later.
56
+ // svelte-ignore state_referenced_locally
57
+ const live = !reduced && (animate ?? ctx?.isLive() ?? true);
58
+ // svelte-ignore state_referenced_locally
59
+ const waitForTail = !first || (first && !!ctx?.bridged);
60
+
61
+ let entering = $state(live);
62
+
63
+ $effect(() => {
64
+ if (!entering) return;
65
+ // Backstop in case animationend never arrives (a hidden ancestor, a host
66
+ // stylesheet overriding the animation).
67
+ const id = setTimeout(() => (entering = false), 2000);
68
+ return () => clearTimeout(id);
69
+ });
70
+
71
+ function onAnimationEnd(e: AnimationEvent) {
72
+ if (e.animationName.endsWith('al-fade')) entering = false;
73
+ }
74
+
75
+ /** Trunk/branch draw only for rows (or trunks) that arrive live. */
76
+ function trunkLive(): boolean {
77
+ return !reduced && (animate ?? ctx?.isLive() ?? true);
78
+ }
79
+ </script>
80
+
81
+ <svelte:element
82
+ this={as}
83
+ class="al-row {className}"
84
+ class:is-entering={entering}
85
+ onanimationend={onAnimationEnd}
86
+ >
87
+ <div class="al-clip">
88
+ <div class="al-body" class:has-guide={guide}>
89
+ {#if guide}
90
+ <span class="al-guide" aria-hidden="true">
91
+ <svg
92
+ class="al-svg"
93
+ width={BRANCH_WIDTH}
94
+ height={BRANCH_Y + 1}
95
+ viewBox="0 0 {BRANCH_WIDTH} {BRANCH_Y + 1}"
96
+ fill="none"
97
+ >
98
+ <path
99
+ class="al-branch"
100
+ class:is-drawing={live}
101
+ class:waits={waitForTail}
102
+ d={BRANCH_PATH}
103
+ pathLength="1"
104
+ stroke="currentColor"
105
+ stroke-width="1"
106
+ />
107
+ </svg>
108
+ {#if !last}
109
+ <span class="al-trunk" class:is-drawing={trunkLive()}></span>
110
+ {/if}
111
+ </span>
112
+ {/if}
113
+ {@render children()}
114
+ </div>
115
+ </div>
116
+ </svelte:element>
117
+
118
+ <style>
119
+ @property --jatui-reveal-fade {
120
+ syntax: '<length>';
121
+ inherits: false;
122
+ initial-value: 0px;
123
+ }
124
+
125
+ .al-row {
126
+ /* Timings: lengths of the BoardUI reveal, expressed on motion tokens. */
127
+ --al-grow-d: calc(var(--motion-move, 300ms) * 1.27);
128
+ --al-in-d: calc(var(--motion-move, 300ms) * 1.4);
129
+ --al-fade-d: calc(var(--motion-move, 300ms) * 1.47);
130
+ /* One pen speed (~160px/s): the tail above, then this row's branch. */
131
+ --al-tail-d: calc(var(--motion-fast, 150ms) * 0.8);
132
+ --al-branch-d: calc(var(--motion-fast, 150ms) * 0.93);
133
+
134
+ position: relative;
135
+ display: grid;
136
+ grid-template-rows: 1fr;
137
+ list-style: none;
138
+ margin: 0;
139
+ padding: 0;
140
+ }
141
+
142
+ .al-clip {
143
+ position: relative;
144
+ min-height: 0;
145
+ min-width: 0;
146
+ }
147
+
148
+ .al-body {
149
+ position: relative;
150
+ min-width: 0;
151
+ }
152
+ .al-body.has-guide {
153
+ padding-inline-start: 1rem;
154
+ }
155
+
156
+ /* ── grow-in ──────────────────────────────────────────────────────── */
157
+ .al-row.is-entering {
158
+ animation: al-grow var(--al-grow-d) var(--motion-glide, ease-out) both;
159
+ }
160
+ .al-row.is-entering > .al-clip {
161
+ overflow: hidden;
162
+ /* Mask stops are alpha only (not a theme colour). The transparent stop
163
+ sits 1px past the box: two stops at exactly 100% make a degenerate
164
+ gradient that softens the last pixel row and breaks the guide where
165
+ rows meet. */
166
+ -webkit-mask-image: linear-gradient(
167
+ to bottom,
168
+ black calc(100% - var(--jatui-reveal-fade)),
169
+ transparent calc(100% + 1px)
170
+ );
171
+ mask-image: linear-gradient(
172
+ to bottom,
173
+ black calc(100% - var(--jatui-reveal-fade)),
174
+ transparent calc(100% + 1px)
175
+ );
176
+ animation:
177
+ al-in var(--al-in-d) var(--motion-glide, ease-out) both,
178
+ al-fade var(--al-fade-d) var(--motion-glide, ease-out) both;
179
+ }
180
+
181
+ @keyframes al-grow {
182
+ from {
183
+ grid-template-rows: 0fr;
184
+ }
185
+ to {
186
+ grid-template-rows: 1fr;
187
+ }
188
+ }
189
+ @keyframes al-in {
190
+ from {
191
+ opacity: 0;
192
+ translate: 0 calc(var(--motion-travel, 16px) * 0.25);
193
+ filter: blur(6px);
194
+ }
195
+ to {
196
+ opacity: 1;
197
+ translate: 0 0;
198
+ filter: blur(0);
199
+ }
200
+ }
201
+ /* Longer than a text line, so a row is faintest exactly where it is clipped. */
202
+ @keyframes al-fade {
203
+ from {
204
+ --jatui-reveal-fade: 22px;
205
+ }
206
+ to {
207
+ --jatui-reveal-fade: 0px;
208
+ }
209
+ }
210
+
211
+ /* ── tree guide ───────────────────────────────────────────────────── */
212
+ .al-guide {
213
+ pointer-events: none;
214
+ position: absolute;
215
+ inset-block: 0;
216
+ inset-inline-start: 0;
217
+ width: 0.75rem;
218
+ color: color-mix(in oklab, var(--color-base-content) 24%, transparent);
219
+ }
220
+ .al-svg {
221
+ position: absolute;
222
+ top: 0;
223
+ inset-inline-start: 0;
224
+ overflow: visible;
225
+ }
226
+ .al-svg:dir(rtl) {
227
+ scale: -1 1;
228
+ }
229
+ .al-branch.is-drawing {
230
+ stroke-dasharray: 1;
231
+ stroke-dashoffset: 1;
232
+ animation: al-draw var(--al-branch-d) linear forwards;
233
+ }
234
+ .al-branch.is-drawing.waits {
235
+ animation-delay: var(--al-tail-d);
236
+ }
237
+ @keyframes al-draw {
238
+ to {
239
+ stroke-dashoffset: 0;
240
+ }
241
+ }
242
+
243
+ .al-trunk {
244
+ position: absolute;
245
+ inset-inline-start: 0;
246
+ top: 8px; /* BRANCH_Y - BRANCH_RADIUS */
247
+ bottom: 0;
248
+ width: 1px;
249
+ background: currentColor;
250
+ transform-origin: top;
251
+ }
252
+ .al-trunk.is-drawing {
253
+ animation: al-scale var(--al-tail-d) linear both;
254
+ }
255
+ @keyframes al-scale {
256
+ from {
257
+ transform: scaleY(0);
258
+ }
259
+ to {
260
+ transform: scaleY(1);
261
+ }
262
+ }
263
+
264
+ /* Reduced motion: final state — no growth, no mask, no blur, no draw. */
265
+ @media (prefers-reduced-motion: reduce) {
266
+ .al-row.is-entering,
267
+ .al-row.is-entering > .al-clip,
268
+ .al-branch.is-drawing,
269
+ .al-trunk.is-drawing {
270
+ animation: none;
271
+ }
272
+ .al-row.is-entering > .al-clip {
273
+ overflow: visible;
274
+ -webkit-mask-image: none;
275
+ mask-image: none;
276
+ }
277
+ .al-branch.is-drawing {
278
+ stroke-dashoffset: 0;
279
+ }
280
+ }
281
+ </style>
@@ -0,0 +1,21 @@
1
+ import type { Snippet } from 'svelte';
2
+ interface Props {
3
+ /** First row of its list: its branch starts with the row (no tail above to wait for). */
4
+ first?: boolean;
5
+ /** Last row of its list: no trunk below the elbow, so the guide ends on the corner. */
6
+ last?: boolean;
7
+ /** Draw the tree guide. false for rows that are not findings (e.g. the working row). */
8
+ guide?: boolean;
9
+ /**
10
+ * Force the grow-in on or off. Default: animate when the row is added after
11
+ * its AgentLog's first render (always, when used outside an AgentLog).
12
+ */
13
+ animate?: boolean;
14
+ /** Element to render: `li` inside a list, `div` elsewhere. */
15
+ as?: 'li' | 'div';
16
+ class?: string;
17
+ children: Snippet;
18
+ }
19
+ declare const AgentLogRow: import("svelte").Component<Props, {}, "">;
20
+ type AgentLogRow = ReturnType<typeof AgentLogRow>;
21
+ export default AgentLogRow;