vanilla-breeze 0.1.0 → 0.1.2

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 (99) hide show
  1. package/dist/cdn/components/adr-record.js +383 -0
  2. package/dist/cdn/components/adr-wc.js +403 -0
  3. package/dist/cdn/components/analytics-panel.js +34 -0
  4. package/dist/cdn/components/author-index.js +3 -0
  5. package/dist/cdn/components/brand-mark.js +2 -0
  6. package/dist/cdn/components/calendar-wc.js +2 -2
  7. package/dist/cdn/components/carousel-wc.js +1 -1
  8. package/dist/cdn/components/chart-wc.js +25 -25
  9. package/dist/cdn/components/color-palette.js +13 -7
  10. package/dist/cdn/components/comment-wc.js +2 -0
  11. package/dist/cdn/components/consent-banner.js +1 -1
  12. package/dist/cdn/components/content-lens.js +2 -0
  13. package/dist/cdn/components/day-view.js +2 -0
  14. package/dist/cdn/components/empathy-map.js +42 -25
  15. package/dist/cdn/components/flow-diagram.js +2 -0
  16. package/dist/cdn/components/font-pairer.js +108 -0
  17. package/dist/cdn/components/gantt-chart.js +2 -0
  18. package/dist/cdn/components/geo-map.js +7 -7
  19. package/dist/cdn/components/glossary-wc.js +2 -0
  20. package/dist/cdn/components/gradient-builder.js +52 -0
  21. package/dist/cdn/components/highlight-wc.js +3 -0
  22. package/dist/cdn/components/manifest.json +134 -26
  23. package/dist/cdn/components/markdown-viewer.js +3 -3
  24. package/dist/cdn/components/motion-specimen.js +21 -0
  25. package/dist/cdn/components/note-wc.js +3 -0
  26. package/dist/cdn/components/notification-wc.js +37 -0
  27. package/dist/cdn/components/page-info.js +55 -24
  28. package/dist/cdn/components/page-toc.js +1 -1
  29. package/dist/cdn/components/popularity-index.js +9 -0
  30. package/dist/cdn/components/print-page.js +1 -1
  31. package/dist/cdn/components/recently-visited.js +3 -0
  32. package/dist/cdn/components/review-surface.js +541 -0
  33. package/dist/cdn/components/selection-menu.js +2 -0
  34. package/dist/cdn/components/semantic-palette.js +30 -0
  35. package/dist/cdn/components/settings-panel.js +55 -51
  36. package/dist/cdn/components/share-wc.js +2 -2
  37. package/dist/cdn/components/site-map-wc.js +2 -0
  38. package/dist/cdn/components/spacing-specimen.js +5 -5
  39. package/dist/cdn/components/split-surface.js +1 -1
  40. package/dist/cdn/components/text-reader.js +2 -2
  41. package/dist/cdn/components/theme-export.js +18 -0
  42. package/dist/cdn/components/theme-picker.js +58 -58
  43. package/dist/cdn/components/token-specimen.js +25 -20
  44. package/dist/cdn/components/topic-map.js +3 -0
  45. package/dist/cdn/components/trust-filter.js +4 -0
  46. package/dist/cdn/components/type-specimen.js +16 -13
  47. package/dist/cdn/components/user-journey.js +48 -30
  48. package/dist/cdn/components/user-persona.js +17 -15
  49. package/dist/cdn/components/user-story.js +55 -22
  50. package/dist/cdn/components/watch-wc.js +3 -0
  51. package/dist/cdn/components/week-view.js +2 -0
  52. package/dist/cdn/components/work-item.js +446 -0
  53. package/dist/cdn/packs/design-system.full.js +124 -47
  54. package/dist/cdn/packs/effects.full.js +1 -1
  55. package/dist/cdn/packs/kawaii.full.css +1 -1
  56. package/dist/cdn/packs/kawaii.full.js +1 -1
  57. package/dist/cdn/packs/kawaii.theme.css +1 -1
  58. package/dist/cdn/packs/manifest.json +10 -40
  59. package/dist/cdn/packs/prototype.full.js +1 -1
  60. package/dist/cdn/packs/ui.full.css +1 -1
  61. package/dist/cdn/packs/ui.full.js +50 -50
  62. package/dist/cdn/packs/ux-planning.full.css +1 -1
  63. package/dist/cdn/packs/ux-planning.full.js +1546 -92
  64. package/dist/cdn/themes/8bit.css +1 -1
  65. package/dist/cdn/themes/alpha1999.css +1 -1
  66. package/dist/cdn/themes/bauhaus.css +1 -1
  67. package/dist/cdn/themes/brutalist.css +1 -1
  68. package/dist/cdn/themes/claymorphism.css +1 -1
  69. package/dist/cdn/themes/cottagecore.css +1 -1
  70. package/dist/cdn/themes/cyber.css +1 -1
  71. package/dist/cdn/themes/genai.css +1 -1
  72. package/dist/cdn/themes/glassmorphism.css +1 -1
  73. package/dist/cdn/themes/kawaii.css +1 -1
  74. package/dist/cdn/themes/magna.css +1 -1
  75. package/dist/cdn/themes/manifest.json +20 -20
  76. package/dist/cdn/themes/nes.css +1 -1
  77. package/dist/cdn/themes/neumorphism.css +1 -1
  78. package/dist/cdn/themes/organic.css +1 -1
  79. package/dist/cdn/themes/rough.css +1 -1
  80. package/dist/cdn/themes/startup.css +1 -1
  81. package/dist/cdn/themes/super2026.css +1 -1
  82. package/dist/cdn/themes/terminal.css +1 -1
  83. package/dist/cdn/themes/vaporwave.css +1 -1
  84. package/dist/cdn/themes/win9x.css +1 -1
  85. package/dist/cdn/vanilla-breeze-charts.js +25 -25
  86. package/dist/cdn/vanilla-breeze-core.css +1 -1
  87. package/dist/cdn/vanilla-breeze-core.js +119 -47
  88. package/dist/cdn/vanilla-breeze-dev.js +1 -1
  89. package/dist/cdn/vanilla-breeze-extras.js +154 -74
  90. package/dist/cdn/vanilla-breeze.css +1 -1
  91. package/dist/cdn/vanilla-breeze.js +1988 -248
  92. package/package.json +8 -6
  93. package/dist/cdn/packs/retro.bundle.js +0 -2
  94. package/dist/cdn/packs/retro.components.js +0 -1
  95. package/dist/cdn/packs/retro.effects.css +0 -2
  96. package/dist/cdn/packs/retro.effects.js +0 -16
  97. package/dist/cdn/packs/retro.full.css +0 -5
  98. package/dist/cdn/packs/retro.full.js +0 -16
  99. package/dist/cdn/packs/retro.theme.css +0 -2
@@ -0,0 +1,541 @@
1
+ var v=`
2
+ :host {
3
+ display: block;
4
+ position: relative;
5
+ font-family: var(--_font-sans);
6
+ line-height: 1.5;
7
+ color: var(--_text);
8
+ container-type: inline-size;
9
+
10
+ --_bg: var(--review-surface-bg, var(--color-surface, #ffffff));
11
+ --_card: var(--review-surface-card, var(--color-surface-raised, #f8f9fa));
12
+ --_border: var(--review-surface-border, var(--color-border, #e0e0e0));
13
+ --_text: var(--review-surface-text, var(--color-text, #1a1a1a));
14
+ --_muted: var(--review-surface-muted, var(--color-text-muted, #666666));
15
+ --_accent: var(--review-surface-accent, var(--color-interactive, #0066cc));
16
+ --_pin-bg: var(--review-surface-pin-bg, var(--color-interactive, #0066cc));
17
+ --_pin-text: var(--review-surface-pin-text, #ffffff);
18
+ --_pin-size: var(--review-surface-pin-size, 28px);
19
+ --_resolved: var(--review-surface-resolved, var(--color-success, #16a34a));
20
+ --_radius: var(--review-surface-radius, var(--radius-xl, 1rem));
21
+ --_radius-m: var(--review-surface-radius-m, var(--radius-m, 0.5rem));
22
+ --_radius-full: var(--review-surface-radius-full, var(--radius-full, 9999px));
23
+ --_font-sans: var(--review-surface-font, var(--font-sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif));
24
+ --_font-xs: var(--review-surface-font-xs, var(--font-size-xs, 0.75rem));
25
+ --_font-sm: var(--review-surface-font-sm, var(--font-size-sm, 0.875rem));
26
+ --_font-md: var(--review-surface-font-md, var(--font-size-md, 1rem));
27
+ --_space-2xs: var(--review-surface-space-2xs, var(--size-2xs, 0.25rem));
28
+ --_space-xs: var(--review-surface-space-xs, var(--size-xs, 0.5rem));
29
+ --_space-s: var(--review-surface-space-s, var(--size-s, 0.75rem));
30
+ --_space-m: var(--review-surface-space-m, var(--size-m, 1rem));
31
+ --_space-l: var(--review-surface-space-l, var(--size-l, 1.5rem));
32
+ --_duration: var(--review-surface-duration, var(--duration-normal, 200ms));
33
+ --_duration-fast: var(--review-surface-duration-fast, var(--duration-fast, 100ms));
34
+ --_ease: var(--review-surface-ease, var(--ease-default, ease));
35
+ }
36
+
37
+ *, *::before, *::after { box-sizing: border-box; margin: 0; }
38
+
39
+ /* \u2500\u2500 Container \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
40
+ .rs-container {
41
+ position: relative;
42
+ display: grid;
43
+ }
44
+
45
+ .rs-container > ::slotted(*),
46
+ .rs-container > .rs-overlay {
47
+ grid-area: 1 / 1;
48
+ }
49
+
50
+ /* \u2500\u2500 Overlay \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
51
+ .rs-overlay {
52
+ position: relative;
53
+ z-index: 10;
54
+ pointer-events: none;
55
+ cursor: default;
56
+ }
57
+
58
+ :host([data-annotating]) .rs-overlay {
59
+ pointer-events: auto;
60
+ cursor: crosshair;
61
+ }
62
+
63
+ /* \u2500\u2500 Pin markers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
64
+ .rs-pin {
65
+ position: absolute;
66
+ transform: translate(-50%, -50%);
67
+ width: var(--_pin-size);
68
+ height: var(--_pin-size);
69
+ border-radius: var(--_radius-full);
70
+ background: var(--_pin-bg);
71
+ color: var(--_pin-text);
72
+ border: 2px solid var(--_pin-text);
73
+ font-size: var(--_font-xs);
74
+ font-weight: 700;
75
+ font-family: inherit;
76
+ display: inline-flex;
77
+ align-items: center;
78
+ justify-content: center;
79
+ cursor: pointer;
80
+ pointer-events: auto;
81
+ padding: 0;
82
+ line-height: 1;
83
+ box-shadow: 0 2px 6px rgba(0, 0, 0, 0.2);
84
+ transition: transform var(--_duration-fast) var(--_ease),
85
+ box-shadow var(--_duration-fast) var(--_ease);
86
+ z-index: 11;
87
+ }
88
+
89
+ .rs-pin:hover {
90
+ transform: translate(-50%, -50%) scale(1.15);
91
+ box-shadow: 0 3px 10px rgba(0, 0, 0, 0.25);
92
+ }
93
+
94
+ .rs-pin:focus-visible {
95
+ outline: 2px solid var(--_accent);
96
+ outline-offset: 2px;
97
+ }
98
+
99
+ .rs-pin[data-resolved] {
100
+ background: var(--_resolved);
101
+ }
102
+
103
+ .rs-pin[data-active] {
104
+ transform: translate(-50%, -50%) scale(1.2);
105
+ box-shadow: 0 0 0 3px color-mix(in srgb, var(--_pin-bg) 30%, transparent);
106
+ }
107
+
108
+ /* \u2500\u2500 Popover \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
109
+ .rs-popover {
110
+ position: absolute;
111
+ z-index: 20;
112
+ width: 300px;
113
+ max-height: 400px;
114
+ overflow-y: auto;
115
+ background: var(--_bg);
116
+ border: 1px solid var(--_border);
117
+ border-radius: var(--_radius-m);
118
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12), 0 2px 8px rgba(0, 0, 0, 0.08);
119
+ padding: 0;
120
+ opacity: 0;
121
+ transform: translateY(4px);
122
+ transition: opacity var(--_duration) var(--_ease), transform var(--_duration) var(--_ease);
123
+ pointer-events: none;
124
+ }
125
+
126
+ .rs-popover[data-open] {
127
+ opacity: 1;
128
+ transform: translateY(0);
129
+ pointer-events: auto;
130
+ }
131
+
132
+ .rs-popover__header {
133
+ display: flex;
134
+ align-items: center;
135
+ justify-content: space-between;
136
+ padding: 10px 12px 8px;
137
+ border-block-end: 1px solid var(--_border);
138
+ }
139
+
140
+ .rs-popover__title {
141
+ font-size: var(--_font-sm);
142
+ font-weight: 700;
143
+ color: var(--_text);
144
+ }
145
+
146
+ .rs-popover__actions {
147
+ display: flex;
148
+ gap: 4px;
149
+ }
150
+
151
+ .rs-popover__btn {
152
+ display: inline-flex;
153
+ align-items: center;
154
+ justify-content: center;
155
+ width: 26px;
156
+ height: 26px;
157
+ border: none;
158
+ border-radius: 4px;
159
+ background: transparent;
160
+ color: var(--_muted);
161
+ cursor: pointer;
162
+ padding: 0;
163
+ transition: background var(--_duration-fast) var(--_ease), color var(--_duration-fast) var(--_ease);
164
+ }
165
+
166
+ .rs-popover__btn svg {
167
+ width: 14px;
168
+ height: 14px;
169
+ }
170
+
171
+ .rs-popover__btn:hover {
172
+ background: var(--_border);
173
+ color: var(--_text);
174
+ }
175
+
176
+ .rs-popover__btn--resolve {
177
+ color: var(--_resolved);
178
+ }
179
+
180
+ .rs-popover__btn--resolve:hover {
181
+ background: color-mix(in srgb, var(--_resolved) 15%, transparent);
182
+ }
183
+
184
+ .rs-popover__btn--delete {
185
+ color: #dc2626;
186
+ }
187
+
188
+ .rs-popover__btn--delete:hover {
189
+ background: #fef2f2;
190
+ color: #dc2626;
191
+ }
192
+
193
+ /* \u2500\u2500 Comment thread \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
194
+ .rs-comment {
195
+ padding: 10px 12px;
196
+ }
197
+
198
+ .rs-comment__meta {
199
+ display: flex;
200
+ align-items: center;
201
+ gap: 6px;
202
+ margin-block-end: 4px;
203
+ }
204
+
205
+ .rs-comment__avatar {
206
+ width: 22px;
207
+ height: 22px;
208
+ border-radius: var(--_radius-full);
209
+ font-size: 10px;
210
+ font-weight: 700;
211
+ display: flex;
212
+ align-items: center;
213
+ justify-content: center;
214
+ color: #fff;
215
+ flex-shrink: 0;
216
+ }
217
+
218
+ .rs-comment__author {
219
+ font-size: var(--_font-xs);
220
+ font-weight: 600;
221
+ color: var(--_text);
222
+ }
223
+
224
+ .rs-comment__time {
225
+ font-size: 11px;
226
+ color: var(--_muted);
227
+ }
228
+
229
+ .rs-comment__text {
230
+ font-size: var(--_font-sm);
231
+ color: var(--_text);
232
+ line-height: 1.5;
233
+ white-space: pre-wrap;
234
+ word-break: break-word;
235
+ }
236
+
237
+ /* Replies */
238
+ .rs-replies {
239
+ border-block-start: 1px solid var(--_border);
240
+ }
241
+
242
+ .rs-reply {
243
+ padding: 8px 12px;
244
+ border-block-end: 1px solid color-mix(in srgb, var(--_border) 50%, transparent);
245
+ }
246
+
247
+ .rs-reply:last-child {
248
+ border-block-end: none;
249
+ }
250
+
251
+ /* \u2500\u2500 Input area \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
252
+ .rs-input {
253
+ display: flex;
254
+ gap: 6px;
255
+ padding: 8px 12px;
256
+ border-block-start: 1px solid var(--_border);
257
+ background: var(--_card);
258
+ border-radius: 0 0 var(--_radius-m) var(--_radius-m);
259
+ }
260
+
261
+ .rs-input__field {
262
+ flex: 1;
263
+ min-height: 32px;
264
+ max-height: 80px;
265
+ padding: 6px 10px;
266
+ border: 1px solid var(--_border);
267
+ border-radius: 6px;
268
+ font-family: inherit;
269
+ font-size: var(--_font-xs);
270
+ line-height: 1.4;
271
+ color: var(--_text);
272
+ background: var(--_bg);
273
+ resize: none;
274
+ }
275
+
276
+ .rs-input__field:focus {
277
+ outline: 2px solid var(--_accent);
278
+ outline-offset: -1px;
279
+ border-color: var(--_accent);
280
+ }
281
+
282
+ .rs-input__field::placeholder {
283
+ color: var(--_muted);
284
+ }
285
+
286
+ .rs-input__submit {
287
+ align-self: flex-end;
288
+ display: inline-flex;
289
+ align-items: center;
290
+ justify-content: center;
291
+ width: 32px;
292
+ height: 32px;
293
+ border: none;
294
+ border-radius: 6px;
295
+ background: var(--_accent);
296
+ color: #fff;
297
+ cursor: pointer;
298
+ padding: 0;
299
+ flex-shrink: 0;
300
+ transition: background var(--_duration-fast) var(--_ease);
301
+ }
302
+
303
+ .rs-input__submit svg {
304
+ width: 14px;
305
+ height: 14px;
306
+ }
307
+
308
+ .rs-input__submit:hover {
309
+ background: color-mix(in srgb, var(--_accent) 85%, #000);
310
+ }
311
+
312
+ .rs-input__submit:disabled {
313
+ opacity: 0.4;
314
+ cursor: not-allowed;
315
+ }
316
+
317
+ /* \u2500\u2500 Toolbar \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
318
+ .rs-toolbar {
319
+ display: flex;
320
+ align-items: center;
321
+ gap: var(--_space-xs);
322
+ padding: var(--_space-xs) var(--_space-s);
323
+ background: var(--_card);
324
+ border: 1px solid var(--_border);
325
+ border-radius: var(--_radius-m);
326
+ margin-block-start: var(--_space-xs);
327
+ }
328
+
329
+ .rs-toolbar__btn {
330
+ display: inline-flex;
331
+ align-items: center;
332
+ gap: 5px;
333
+ padding: 4px 10px;
334
+ border: 1px solid var(--_border);
335
+ border-radius: 6px;
336
+ background: var(--_bg);
337
+ color: var(--_text);
338
+ font-family: inherit;
339
+ font-size: var(--_font-xs);
340
+ font-weight: 600;
341
+ cursor: pointer;
342
+ line-height: 1;
343
+ transition: background var(--_duration-fast) var(--_ease),
344
+ border-color var(--_duration-fast) var(--_ease);
345
+ }
346
+
347
+ .rs-toolbar__btn svg {
348
+ width: 14px;
349
+ height: 14px;
350
+ }
351
+
352
+ .rs-toolbar__btn:hover {
353
+ background: var(--_border);
354
+ }
355
+
356
+ .rs-toolbar__btn[aria-pressed="true"] {
357
+ background: var(--_accent);
358
+ color: #fff;
359
+ border-color: var(--_accent);
360
+ }
361
+
362
+ .rs-toolbar__count {
363
+ font-size: var(--_font-xs);
364
+ color: var(--_muted);
365
+ margin-inline-start: auto;
366
+ }
367
+
368
+ /* \u2500\u2500 Resolved badge \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
369
+ .rs-resolved-badge {
370
+ display: inline-flex;
371
+ align-items: center;
372
+ gap: 4px;
373
+ font-size: 11px;
374
+ font-weight: 600;
375
+ color: var(--_resolved);
376
+ padding: 2px 8px;
377
+ border-radius: var(--_radius-full);
378
+ background: color-mix(in srgb, var(--_resolved) 12%, transparent);
379
+ }
380
+
381
+ .rs-resolved-badge svg {
382
+ width: 12px;
383
+ height: 12px;
384
+ }
385
+
386
+ /* \u2500\u2500 Live region \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
387
+ .rs-live {
388
+ position: absolute;
389
+ width: 1px;
390
+ height: 1px;
391
+ overflow: hidden;
392
+ clip: rect(0, 0, 0, 0);
393
+ white-space: nowrap;
394
+ }
395
+
396
+ /* \u2500\u2500 Compact \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
397
+ :host([compact]) {
398
+ --_pin-size: 22px;
399
+ }
400
+
401
+ :host([compact]) .rs-popover {
402
+ width: 250px;
403
+ max-height: 300px;
404
+ }
405
+
406
+ :host([compact]) .rs-toolbar {
407
+ padding: 3px var(--_space-xs);
408
+ }
409
+
410
+ :host([compact]) .rs-toolbar__btn {
411
+ font-size: 11px;
412
+ padding: 3px 8px;
413
+ }
414
+
415
+ /* \u2500\u2500 Responsive \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
416
+ @container (max-width: 400px) {
417
+ .rs-popover {
418
+ width: 240px;
419
+ }
420
+
421
+ .rs-toolbar {
422
+ flex-wrap: wrap;
423
+ }
424
+ }
425
+
426
+ /* \u2500\u2500 Motion \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
427
+ @media (prefers-reduced-motion: reduce) {
428
+ .rs-pin,
429
+ .rs-popover,
430
+ .rs-toolbar__btn,
431
+ .rs-popover__btn,
432
+ .rs-input__submit {
433
+ transition: none;
434
+ }
435
+ }
436
+
437
+ /* \u2500\u2500 Print \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
438
+ @media print {
439
+ .rs-overlay,
440
+ .rs-toolbar,
441
+ .rs-popover {
442
+ display: none;
443
+ }
444
+ }
445
+
446
+ /* \u2500\u2500 Utility \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
447
+ .state-msg { padding: var(--_space-l); font-size: var(--_font-sm); color: var(--_muted); font-style: italic; }
448
+ .state-msg--error { color: #dc2626; }
449
+
450
+ @media (prefers-color-scheme: dark) {
451
+ .rs-popover__btn--delete:hover {
452
+ background: #450a0a;
453
+ }
454
+ }
455
+ `;var C=window.matchMedia("(prefers-reduced-motion: reduce)");var k=new Map;function $(a,e,t={}){let r=t.priority??10,s={impl:e,bundle:t.bundle,contract:t.contract,priority:r},o=k.get(a);if(customElements.get(a)){if(!o||o.priority>=r){o&&o.priority===r&&o.impl!==e&&console.warn(`[VB Bundle] Tag <${a}> already registered by "${o.bundle}" (priority ${o.priority}). Skipping "${t.bundle}".`);return}console.warn(`[VB Bundle] Tag <${a}> defined by "${o.bundle}" cannot be replaced (customElements.define is permanent). "${t.bundle}" has higher priority but arrived late.`);return}if(o&&o.priority>=r){o.priority===r&&console.warn(`[VB Bundle] Tag <${a}> already registered by "${o.bundle}". Skipping "${t.bundle}" (first wins at equal priority).`);return}k.set(a,s),customElements.define(a,e)}function n(a){return String(a).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function g(a){return a.split(" ").map(e=>e[0]).join("").toUpperCase().slice(0,2)}function y(a){let e=0;for(let r=0;r<a.length;r++)e=a.charCodeAt(r)+((e<<5)-e);return`hsl(${(e%360+360)%360}, 65%, 55%)`}function l(a){return`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${a}</svg>`}var c={user:'<path d="M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2"/><circle cx="12" cy="7" r="4"/>',pencil:'<path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/><path d="m15 5 4 4"/>',check:'<path d="M20 6 9 17l-5-5"/>',target:'<circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/>',alertTriangle:'<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3"/><path d="M12 9v4"/><path d="M12 17h.01"/>',messageCircle:'<path d="M2.992 16.342a2 2 0 0 1 .094 1.167l-1.065 3.29a1 1 0 0 0 1.236 1.168l3.413-.998a2 2 0 0 1 1.099.092 10 10 0 1 0-4.777-4.719"/>',lightbulb:'<path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/>',wrench:'<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.106-3.105c.32-.322.863-.22.983.218a6 6 0 0 1-8.259 7.057l-7.91 7.91a1 1 0 0 1-2.999-3l7.91-7.91a6 6 0 0 1 7.057-8.259c.438.12.54.662.219.984z"/>',heart:'<path d="M2 9.5a5.5 5.5 0 0 1 9.591-3.676.56.56 0 0 0 .818 0A5.49 5.49 0 0 1 22 9.5c0 2.29-1.5 4-3 5.5l-5.492 5.313a2 2 0 0 1-3 .019L5 15c-1.5-1.5-3-3.2-3-5.5"/>',mapPin:'<path d="M20 10c0 4.993-5.539 10.193-7.399 11.799a1 1 0 0 1-1.202 0C9.539 20.193 4 14.993 4 10a8 8 0 0 1 16 0"/><circle cx="12" cy="10" r="3"/>',checkCircle:'<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"/><path d="m9 11 3 3L22 4"/>',x:'<path d="M18 6 6 18"/><path d="m6 6 12 12"/>',download:'<path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/><polyline points="7 10 12 15 17 10"/><line x1="12" x2="12" y1="15" y2="3"/>',send:'<path d="M14.536 21.686a.5.5 0 0 0 .937-.024l6.5-19a.496.496 0 0 0-.635-.635l-19 6.5a.5.5 0 0 0-.024.937l7.93 3.18a2 2 0 0 1 1.112 1.11z"/><path d="m21.854 2.147-10.94 10.939"/>'},R={says:{label:"Says",icon:c.messageCircle,color:"#3b82f6"},thinks:{label:"Thinks",icon:c.lightbulb,color:"#8b5cf6"},does:{label:"Does",icon:c.wrench,color:"#f59e0b"},feels:{label:"Feels",icon:c.heart,color:"#ef4444"}};function P(){let a=globalThis.localStorage;if(!a)throw new Error("VBStore: localStorage is not available in this environment");return{async getRaw(e){return a.getItem(e)},async setRaw(e,t){a.setItem(e,t)},async removeRaw(e){a.removeItem(e)},async keys(e){let t=[];for(let r=0;r<a.length;r++){let s=a.key(r);s&&s.startsWith(e)&&t.push(s)}return t}}}var f=null;function p(){return f||(f=P()),f}function x(a,e){if(typeof a!="string"||!a)throw new TypeError("VBStore: namespace must be a non-empty string");if(typeof e!="string"||!e)throw new TypeError("VBStore: key must be a non-empty string");return`vb:${a}:${e}`}function E(a){if(typeof a!="string"||!a)throw new TypeError("VBStore: namespace must be a non-empty string");return`vb:${a}:`}function A(a){try{let e=JSON.parse(a);if(e&&typeof e=="object"&&typeof e.timestamp=="number")return e}catch{}return null}var _={configure(a={}){f=a.backend??null},async set(a,e,t){let r={data:t,timestamp:Date.now()};await p().setRaw(x(a,e),JSON.stringify(r))},async get(a,e,t){let r=await p().getRaw(x(a,e));if(r==null)return null;let s=A(r);return!s||t?.maxAge!=null&&Date.now()-s.timestamp>t.maxAge?null:s.data},async remove(a,e){await p().removeRaw(x(a,e))},async list(a){let e=E(a),t=await p().keys(e),r=[];for(let s of t){let o=await p().getRaw(s);if(o==null)continue;let i=A(o);i&&r.push({key:s.slice(e.length),data:i.data,timestamp:i.timestamp})}return r},async clear(a){let e=E(a),t=await p().keys(e);for(let r of t)await p().removeRaw(r)},async clearAll(){let a=await p().keys("vb:");for(let e of a)await p().removeRaw(e)},async setMany(a,e){for(let[t,r]of e)await _.set(a,t,r)}};var h=class{#e=new Map;async load(){return[...this.#e.values()]}async save(e){return e.id||(e.id=crypto.randomUUID()),this.#e.set(e.id,e),e}async update(e,t){let r=this.#e.get(e);if(!r)throw new Error(`Pin ${e} not found`);return Object.assign(r,t),r}async remove(e){this.#e.delete(e)}},b=class{#e;constructor(e="default"){this.#e=e}async#r(){let e=await _.get("reviews",this.#e);return Array.isArray(e)?e:[]}async#a(e){await _.set("reviews",this.#e,e)}async load(){return this.#r()}async save(e){e.id||(e.id=crypto.randomUUID());let t=await this.#r();return t.push(e),await this.#a(t),e}async update(e,t){let r=await this.#r(),s=r.findIndex(o=>o.id===e);if(s===-1)throw new Error(`Pin ${e} not found`);return Object.assign(r[s],t),await this.#a(r),r[s]}async remove(e){let t=(await this.#r()).filter(r=>r.id!==e);await this.#a(t)}},m=class{#e;constructor(e){if(!e)throw new Error("RestAdapter requires an endpoint URL");this.#e=e.replace(/\/$/,"")}async load(){let e=await fetch(this.#e);if(!e.ok)throw new Error(`HTTP ${e.status}`);let t=await e.json();return Array.isArray(t)?t:t.pins||[]}async save(e){let t=await fetch(this.#e,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!t.ok)throw new Error(`HTTP ${t.status}`);return t.json()}async update(e,t){let r=await fetch(`${this.#e}/${encodeURIComponent(e)}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!r.ok)throw new Error(`HTTP ${r.status}`);return r.json()}async remove(e){let t=await fetch(`${this.#e}/${encodeURIComponent(e)}`,{method:"DELETE"});if(!t.ok)throw new Error(`HTTP ${t.status}`)}},w=class extends HTMLElement{static get observedAttributes(){return["src","editable","adapter","endpoint","storage-key","author","compact","show-resolved"]}#e=new Map;constructor(){super(),this.attachShadow({mode:"open"}),this.__pins=[],this.__adapter=null,this._activePin=null,this._annotating=!1}get pins(){return this.__pins}set pins(e){this.__pins=Array.isArray(e)?e:[],this.isConnected&&this._render()}get adapter(){return this.__adapter}set adapter(e){this.__adapter=e,this.isConnected&&this._loadFromAdapter()}#r(){for(let e of this.children){let t=e.getAttribute("slot");t&&this.#e.set(t,e.textContent.trim())}}_resolve(e){return this.getAttribute(e)||this.#e.get(e)||""}connectedCallback(){this.#r(),this.setAttribute("data-upgraded",""),this.#a(),this.hasAttribute("src")?this._loadSrc(this.getAttribute("src")):this._loadFromAdapter()}disconnectedCallback(){this.removeAttribute("data-upgraded"),this.removeAttribute("data-annotating")}attributeChangedCallback(e){this.isConnected&&(e==="src"?this._loadSrc(this.getAttribute("src")):e==="adapter"||e==="endpoint"||e==="storage-key"?(this.#a(),this._loadFromAdapter()):this._render())}#a(){if(this.__adapter&&!(this.__adapter instanceof h)&&!(this.__adapter instanceof b)&&!(this.__adapter instanceof m))return;switch(this.getAttribute("adapter")||"memory"){case"local":this.__adapter=new b(this.getAttribute("storage-key")||"default");break;case"rest":try{this.__adapter=new m(this.getAttribute("endpoint"))}catch{this.__adapter=new h}break;default:this.__adapter=new h}}async _loadSrc(e){if(e){this.shadowRoot.innerHTML=`<style>${v}</style><div class="state-msg">Loading\u2026</div>`;try{let t=await fetch(e);if(!t.ok)throw new Error(`HTTP ${t.status}`);let r=await t.json();this.__pins=Array.isArray(r)?r:r.pins||[],this._render()}catch(t){this.shadowRoot.innerHTML=`<style>${v}</style><div class="state-msg state-msg--error">Could not load pins: ${n(t.message)}</div>`}}}async _loadFromAdapter(){if(this.__adapter){try{this.__pins=await this.__adapter.load()}catch{this.__pins=[]}this._render()}}async addPin(e){let t={id:crypto.randomUUID(),x:Math.max(0,Math.min(100,e.x)),y:Math.max(0,Math.min(100,e.y)),text:e.text||"",author:e.author||this.getAttribute("author")||"Anonymous",createdAt:new Date().toISOString(),resolved:!1,resolvedBy:null,resolvedAt:null,replies:[]};return this.__adapter&&await this.__adapter.save(t),this.__pins.push(t),this._render(),this.#t(`Pin ${this.#s().length} added`),this.dispatchEvent(new CustomEvent("review-surface:add",{bubbles:!0,composed:!0,detail:{pin:t}})),t}async removePin(e){let t=this.__pins.find(r=>r.id===e);t&&(this.__adapter&&await this.__adapter.remove(e),this.__pins=this.__pins.filter(r=>r.id!==e),this._activePin===e&&(this._activePin=null),this._render(),this.#t("Pin removed"),this.dispatchEvent(new CustomEvent("review-surface:remove",{bubbles:!0,composed:!0,detail:{pin:t}})))}async resolvePin(e){let t=this.__pins.find(s=>s.id===e);if(!t)return;let r={resolved:!0,resolvedBy:this.getAttribute("author")||"Anonymous",resolvedAt:new Date().toISOString()};this.__adapter&&await this.__adapter.update(e,r),Object.assign(t,r),this._render(),this.#t("Pin resolved"),this.dispatchEvent(new CustomEvent("review-surface:resolve",{bubbles:!0,composed:!0,detail:{pin:t}}))}async unresolvePin(e){let t=this.__pins.find(s=>s.id===e);if(!t)return;let r={resolved:!1,resolvedBy:null,resolvedAt:null};this.__adapter&&await this.__adapter.update(e,r),Object.assign(t,r),this._render(),this.#t("Pin re-opened"),this.dispatchEvent(new CustomEvent("review-surface:update",{bubbles:!0,composed:!0,detail:{pin:t,changes:r}}))}exportPins(){return structuredClone(this.__pins)}importPins(e){this.__pins=Array.isArray(e)?structuredClone(e):[],this._activePin=null,this._render()}#s(){let e=this.hasAttribute("show-resolved");return this.__pins.filter(t=>e||!t.resolved).sort((t,r)=>new Date(t.createdAt)-new Date(r.createdAt))}_render(){let e=this.hasAttribute("editable"),t=this.#s(),r=this._activePin?this.__pins.find(s=>s.id===this._activePin):null;this.setAttribute("pin-count",String(t.length)),this.shadowRoot.innerHTML=`<style>${v}</style>
456
+ <div class="rs-container">
457
+ <slot></slot>
458
+ <div class="rs-overlay" role="img" aria-label="Review annotation surface">
459
+ ${t.map((s,o)=>this._renderPin(s,o+1)).join("")}
460
+ </div>
461
+ ${r?this._renderPopover(r,e):""}
462
+ </div>
463
+ ${e?this._renderToolbar(t.length):""}
464
+ <div class="rs-live" aria-live="polite" aria-atomic="true"></div>`,this._bindListeners(e),this.dispatchEvent(new CustomEvent("review-surface:ready",{bubbles:!0,composed:!0,detail:{pinCount:t.length}}))}_renderPin(e,t){let r=e.text?e.text.slice(0,50):"Empty pin";return`<button class="rs-pin"
465
+ data-pin-id="${n(e.id)}"
466
+ ${e.resolved?"data-resolved":""}
467
+ ${this._activePin===e.id?"data-active":""}
468
+ style="left:${e.x}%;top:${e.y}%"
469
+ aria-label="Pin ${t}: ${n(r)}"
470
+ aria-expanded="${this._activePin===e.id}"
471
+ aria-haspopup="dialog">
472
+ <span class="rs-pin__number">${t}</span>
473
+ </button>`}_renderPopover(e,t){let r=this.#s().findIndex(s=>s.id===e.id)+1;return`<div class="rs-popover" data-open
474
+ style="left:${Math.min(e.x,70)}%;top:${e.y}%"
475
+ role="dialog"
476
+ aria-labelledby="rs-popover-title-${n(e.id)}">
477
+
478
+ <div class="rs-popover__header">
479
+ <span class="rs-popover__title" id="rs-popover-title-${n(e.id)}">
480
+ Pin ${r}
481
+ ${e.resolved?`<span class="rs-resolved-badge">${l(c.checkCircle)} Resolved</span>`:""}
482
+ </span>
483
+ <div class="rs-popover__actions">
484
+ ${t&&!e.resolved?`
485
+ <button class="rs-popover__btn rs-popover__btn--resolve" data-action="resolve" data-pin-id="${n(e.id)}"
486
+ aria-label="Resolve pin" title="Resolve">${l(c.checkCircle)}</button>`:""}
487
+ ${t&&e.resolved?`
488
+ <button class="rs-popover__btn" data-action="unresolve" data-pin-id="${n(e.id)}"
489
+ aria-label="Re-open pin" title="Re-open">${l(c.messageCircle)}</button>`:""}
490
+ ${t?`
491
+ <button class="rs-popover__btn rs-popover__btn--delete" data-action="delete" data-pin-id="${n(e.id)}"
492
+ aria-label="Delete pin" title="Delete">${l(c.x)}</button>`:""}
493
+ <button class="rs-popover__btn" data-action="close"
494
+ aria-label="Close">${l(c.x)}</button>
495
+ </div>
496
+ </div>
497
+
498
+ <div class="rs-comment">
499
+ <div class="rs-comment__meta">
500
+ <span class="rs-comment__avatar" style="background:${y(e.author||"Anonymous")}">${g(e.author||"Anonymous")}</span>
501
+ <span class="rs-comment__author">${n(e.author||"Anonymous")}</span>
502
+ <span class="rs-comment__time">${this.#i(e.createdAt)}</span>
503
+ </div>
504
+ <div class="rs-comment__text">${n(e.text)}</div>
505
+ </div>
506
+
507
+ ${e.replies?.length?`
508
+ <div class="rs-replies">
509
+ ${e.replies.map(s=>`
510
+ <div class="rs-reply">
511
+ <div class="rs-comment__meta">
512
+ <span class="rs-comment__avatar" style="background:${y(s.author||"Anonymous")}">${g(s.author||"Anonymous")}</span>
513
+ <span class="rs-comment__author">${n(s.author||"Anonymous")}</span>
514
+ <span class="rs-comment__time">${this.#i(s.createdAt)}</span>
515
+ </div>
516
+ <div class="rs-comment__text">${n(s.text)}</div>
517
+ </div>
518
+ `).join("")}
519
+ </div>`:""}
520
+
521
+ ${t?`
522
+ <div class="rs-input">
523
+ <textarea class="rs-input__field" placeholder="Reply\u2026" rows="1"
524
+ aria-label="Reply to pin ${r}"></textarea>
525
+ <button class="rs-input__submit" data-action="reply" data-pin-id="${n(e.id)}"
526
+ aria-label="Send reply">${l(c.send)}</button>
527
+ </div>`:""}
528
+
529
+ </div>`}_renderToolbar(e){return`<div class="rs-toolbar" role="toolbar" aria-label="Review tools">
530
+ <button class="rs-toolbar__btn" data-action="toggle-mode"
531
+ aria-pressed="${this._annotating}"
532
+ title="Toggle annotate mode">
533
+ ${l(c.mapPin)} Annotate
534
+ </button>
535
+ <button class="rs-toolbar__btn" data-action="export"
536
+ title="Export pins as JSON">
537
+ ${l(c.download)} Export
538
+ </button>
539
+ <output class="rs-toolbar__count">${e} pin${e!==1?"s":""}</output>
540
+ </div>`}_bindListeners(e){let t=this.shadowRoot;t.querySelectorAll(".rs-pin").forEach(o=>{o.addEventListener("click",i=>{i.stopPropagation();let d=o.dataset.pinId;this._activePin=this._activePin===d?null:d,this._render(),this._activePin&&this.dispatchEvent(new CustomEvent("review-surface:select",{bubbles:!0,composed:!0,detail:{pin:this.__pins.find(u=>u.id===d)}}))})});let r=t.querySelector(".rs-overlay");r&&e&&r.addEventListener("click",o=>{if(!this._annotating||o.target.closest(".rs-pin"))return;let i=r.getBoundingClientRect(),d=(o.clientX-i.left)/i.width*100,u=(o.clientY-i.top)/i.height*100;this.#n(d,u)}),t.querySelectorAll("[data-action]").forEach(o=>{o.addEventListener("click",i=>{i.stopPropagation();let d=o.dataset.action,u=o.dataset.pinId;switch(d){case"close":this._activePin=null,this._render();break;case"resolve":this.resolvePin(u);break;case"unresolve":this.unresolvePin(u);break;case"delete":this.removePin(u);break;case"toggle-mode":this._annotating=!this._annotating,this._annotating?this.setAttribute("data-annotating",""):this.removeAttribute("data-annotating"),this._render(),this.dispatchEvent(new CustomEvent("review-surface:mode",{bubbles:!0,composed:!0,detail:{mode:this._annotating?"annotate":"view"}}));break;case"export":this.#c();break;case"reply":this.#o(u);break}})});let s=t.querySelector(".rs-input__field");s&&s.addEventListener("keydown",o=>{if(o.key==="Enter"&&!o.shiftKey){o.preventDefault();let i=t.querySelector('[data-action="reply"]')?.dataset.pinId;i&&this.#o(i)}}),t.addEventListener("keydown",o=>{o.key==="Escape"&&(this._activePin?(this._activePin=null,this._render()):this._annotating&&(this._annotating=!1,this.removeAttribute("data-annotating"),this._render(),this.dispatchEvent(new CustomEvent("review-surface:mode",{bubbles:!0,composed:!0,detail:{mode:"view"}}))))})}async#n(e,t){let r=this.getAttribute("author")||"Anonymous",s=await this.addPin({x:e,y:t,text:"",author:r});this._activePin=s.id,this._render(),requestAnimationFrame(()=>{let o=this.shadowRoot.querySelector(".rs-input__field");o&&o.focus()})}async#o(e){let t=this.shadowRoot.querySelector(".rs-input__field");if(!t)return;let r=t.value.trim();if(!r)return;let s=this.__pins.find(i=>i.id===e);if(!s)return;let o={id:crypto.randomUUID(),text:r,author:this.getAttribute("author")||"Anonymous",createdAt:new Date().toISOString()};s.replies||(s.replies=[]),s.text?(s.replies.push(o),this.__adapter&&await this.__adapter.update(e,{replies:s.replies})):(s.text=r,this.__adapter&&await this.__adapter.update(e,{text:r})),this._render(),this.#t("Reply added"),requestAnimationFrame(()=>{let i=this.shadowRoot.querySelector(".rs-input__field");i&&i.focus()}),this.dispatchEvent(new CustomEvent("review-surface:update",{bubbles:!0,composed:!0,detail:{pin:s,changes:{replies:s.replies}}}))}async#c(){let e=JSON.stringify(this.exportPins(),null,2);try{await navigator.clipboard.writeText(e),this.#t("Pins copied to clipboard")}catch{let t=new Blob([e],{type:"application/json"}),r=URL.createObjectURL(t),s=document.createElement("a");s.href=r,s.download="review-pins.json",s.click(),URL.revokeObjectURL(r),this.#t("Pins exported as file")}}#i(e){if(!e)return"";try{let t=new Date(e),s=new Date-t,o=Math.floor(s/6e4);if(o<1)return"just now";if(o<60)return`${o}m ago`;let i=Math.floor(o/60);if(i<24)return`${i}h ago`;let d=Math.floor(i/24);return d<7?`${d}d ago`:t.toLocaleDateString()}catch{return""}}#t(e){let t=this.shadowRoot.querySelector(".rs-live");t&&(t.textContent=e)}};$("review-surface",w);export{b as LocalStorageAdapter,h as MemoryAdapter,m as RestAdapter,w as ReviewSurface};
541
+ //# sourceMappingURL=review-surface.js.map
@@ -0,0 +1,2 @@
1
+ var d=class extends HTMLElement{#e=[];connectedCallback(){this.hasAttribute("data-upgraded")||this.setup()!==!1&&this.setAttribute("data-upgraded","")}disconnectedCallback(){for(let e of this.#e)e();this.#e=[],this.removeAttribute("data-upgraded"),this.teardown()}listen(e,t,i,s){e.addEventListener(t,i,s),this.#e.push(()=>e.removeEventListener(t,i,s))}setup(){}teardown(){}};var p=window.matchMedia("(prefers-reduced-motion: reduce)");var u=new Map;function h(o,e,t={}){let i=t.priority??10,s={impl:e,bundle:t.bundle,contract:t.contract,priority:i},n=u.get(o);if(customElements.get(o)){if(!n||n.priority>=i){n&&n.priority===i&&n.impl!==e&&console.warn(`[VB Bundle] Tag <${o}> already registered by "${n.bundle}" (priority ${n.priority}). Skipping "${t.bundle}".`);return}console.warn(`[VB Bundle] Tag <${o}> defined by "${n.bundle}" cannot be replaced (customElements.define is permanent). "${t.bundle}" has higher priority but arrived late.`);return}if(n&&n.priority>=i){n.priority===i&&console.warn(`[VB Bundle] Tag <${o}> already registered by "${n.bundle}". Skipping "${t.bundle}" (first wins at equal priority).`);return}u.set(o,s),customElements.define(o,e)}var f=8,l=8,a=class extends d{#e=null;#t=new Set;#n=!1;setup(){this.hidden=!0,this.#o(),this.listen(document,"pointerup",this.#s),this.listen(document,"pointerdown",this.#d),this.listen(document,"keydown",this.#l),this.id&&new MutationObserver(()=>this.#o()).observe(document.body,{childList:!0,subtree:!0,attributeFilter:["data-selection-menu"]})}getSelection(){return this.#e?{...this.#e}:null}dismiss(){this.#i()}#o(){this.#t.clear();let e=this.getAttribute("for");if(e){let t=document.getElementById(e);t&&(this.#t.add(t),t.hasAttribute("data-selection-menu")||t.setAttribute("data-selection-menu",this.id||""))}this.id&&document.querySelectorAll(`[data-selection-menu="${this.id}"]`).forEach(t=>{this.#t.add(t)})}#s=()=>{requestAnimationFrame(()=>{this.isConnected&&this.#r()})};#r(){let e=window.getSelection();if(!e||e.isCollapsed||!e.toString().trim())return;let t=e.getRangeAt(0),i=t.commonAncestorContainer,s=i.nodeType===Node.ELEMENT_NODE?i:i.parentElement,n=null;for(let c of this.#t)if(c.contains(s)){n=c;break}if(!n)return;let r=e.toString().trim();this.#e={range:t.cloneRange(),text:r,target:n},this.dispatchEvent(new CustomEvent("selection-menu:select",{detail:{range:this.#e.range,text:r,target:n},bubbles:!0})),this.#c(t.getBoundingClientRect())}#c(e){this.hidden=!1,this.#n=!0,requestAnimationFrame(()=>{let t=this.getBoundingClientRect(),i=t.width||200,s=t.height||40,n=e.top-s-f,r=e.left+e.width/2-i/2;n<l&&(n=e.bottom+f);let c=window.innerWidth-i-l;r=Math.max(l,Math.min(r,c)),this.style.top=`${n}px`,this.style.left=`${r}px`})}#i(){this.hidden=!0,this.#n=!1,this.#e=null,this.dispatchEvent(new CustomEvent("selection-menu:dismiss",{bubbles:!0}))}#d=e=>{this.#n&&(this.contains(e.target)||this.#i())};#l=e=>{e.key==="Escape"&&this.#n&&this.#i()}};h("selection-menu",a);
2
+ //# sourceMappingURL=selection-menu.js.map
@@ -0,0 +1,30 @@
1
+ var at=window.matchMedia("(prefers-reduced-motion: reduce)");var q=new Map;function F(r,e,t={}){let o=t.priority??10,s={impl:e,bundle:t.bundle,contract:t.contract,priority:o},n=q.get(r);if(customElements.get(r)){if(!n||n.priority>=o){n&&n.priority===o&&n.impl!==e&&console.warn(`[VB Bundle] Tag <${r}> already registered by "${n.bundle}" (priority ${n.priority}). Skipping "${t.bundle}".`);return}console.warn(`[VB Bundle] Tag <${r}> defined by "${n.bundle}" cannot be replaced (customElements.define is permanent). "${t.bundle}" has higher priority but arrived late.`);return}if(n&&n.priority>=o){n.priority===o&&console.warn(`[VB Bundle] Tag <${r}> already registered by "${n.bundle}". Skipping "${t.bundle}" (first wins at equal priority).`);return}q.set(r,s),customElements.define(r,e)}var v=class extends HTMLElement{#t=[];connectedCallback(){this.hasAttribute("data-upgraded")||this.setup()!==!1&&this.setAttribute("data-upgraded","")}disconnectedCallback(){for(let e of this.#t)e();this.#t=[],this.removeAttribute("data-upgraded"),this.teardown()}listen(e,t,o,s){e.addEventListener(t,o,s),this.#t.push(()=>e.removeEventListener(t,o,s))}setup(){}teardown(){}};function X(r,e,t){e/=100,t/=100;let o=i=>(i+r/30)%12,s=e*Math.min(t,1-t),n=i=>t-s*Math.max(-1,Math.min(o(i)-3,9-o(i),1));return{r:Math.round(n(0)*255),g:Math.round(n(8)*255),b:Math.round(n(4)*255)}}function G(r,e,t){r/=255,e/=255,t/=255;let o=Math.max(r,e,t),s=Math.min(r,e,t),n=(o+s)/2,i=0,l=0;if(o!==s){let a=o-s;switch(l=n>.5?a/(2-o-s):a/(o+s),o){case r:i=((e-t)/a+(e<t?6:0))/6;break;case e:i=((t-r)/a+2)/6;break;case t:i=((r-e)/a+4)/6;break}}return{h:Math.round(i*360),s:Math.round(l*100),l:Math.round(n*100)}}function S(r){r=r.replace(/^#/,""),r.length===3&&(r=r[0]+r[0]+r[1]+r[1]+r[2]+r[2]);let e=parseInt(r,16);return{r:e>>16&255,g:e>>8&255,b:e&255}}function k(r,e,t){return"#"+[r,e,t].map(o=>Math.max(0,Math.min(255,Math.round(o))).toString(16).padStart(2,"0")).join("")}function N(r){let{r:e,g:t,b:o}=S(r);return G(e,t,o)}function c(r,e,t){let{r:o,g:s,b:n}=X(r,e,t);return k(o,s,n)}var E=r=>r<=.04045?r/12.92:Math.pow((r+.055)/1.055,2.4),z=r=>r<=.0031308?12.92*r:1.055*Math.pow(r,1/2.4)-.055,A=r=>r<0?0:r>1?1:r;function h(r){let{r:e,g:t,b:o}=S(r),s=E(e/255),n=E(t/255),i=E(o/255),l=.4122214708*s+.5363325363*n+.0514459929*i,a=.2119034982*s+.6806995451*n+.1073969566*i,d=.0883024619*s+.2817188376*n+.6299787005*i,p=Math.cbrt(l),f=Math.cbrt(a),b=Math.cbrt(d),M=.2104542553*p+.793617785*f-.0040720468*b,g=1.9779984951*p-2.428592205*f+.4505937099*b,y=.0259040371*p+.7827717662*f-.808675766*b,T=Math.sqrt(g*g+y*y),x=Math.atan2(y,g)*180/Math.PI;return x<0&&(x+=360),{l:M,c:T,h:x}}function $(r,e,t){let o=t*Math.PI/180,s=e*Math.cos(o),n=e*Math.sin(o),i=r+.3963377774*s+.2158037573*n,l=r-.1055613458*s-.0638541728*n,a=r-.0894841775*s-1.291485548*n,d=i*i*i,p=l*l*l,f=a*a*a,b=4.0767416621*d-3.3077115913*p+.2309699292*f,M=-1.2684380046*d+2.6097574011*p-.3413193965*f,g=-.0041960863*d-.7034186147*p+1.707614701*f,y=A(z(b)),T=A(z(M)),x=A(z(g));return k(Math.round(y*255),Math.round(T*255),Math.round(x*255))}function B(r,e){if(!r)return null;let t=String(r).trim();if(/^#[0-9a-f]{6}$/i.test(t))return t.toLowerCase();if(/^#[0-9a-f]{3}$/i.test(t))return("#"+t.slice(1).split("").map(i=>i+i).join("")).toLowerCase();if(typeof document>"u")return null;let o=e||document.createElement("span");e||(o.style.display="none",document.body.appendChild(o)),o.style.color="",o.style.color=t;let s=getComputedStyle(o).color;e||o.remove();let n=s.match(/rgba?\(\s*([0-9.]+)[\s,]+([0-9.]+)[\s,]+([0-9.]+)/);return n?k(Math.round(+n[1]),Math.round(+n[2]),Math.round(+n[3])):null}function P({l:r,c:e,h:t}){return`oklch(${(r*100).toFixed(1)}% ${e.toFixed(3)} ${t.toFixed(1)})`}function C(r){let{r:e,g:t,b:o}=S(r),s=n=>{let i=n/255;return i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4)};return .2126*s(e)+.7152*s(t)+.0722*s(o)}function _(r,e){let t=C(r),o=C(e),s=Math.max(t,o),n=Math.min(t,o);return(s+.05)/(n+.05)}function V(r){return r>=7?"AAA":r>=4.5?"AA":"Fail"}function L(r){return C(r)>.4?"#000000":"#ffffff"}var u=r=>(r%360+360)%360;function K(r,e,t){return{colors:[c(r,e,t),c(u(r+180),e,t)],names:["Base","Complement"]}}function Q(r,e,t){return{colors:[c(u(r-30),e,t),c(r,e,t),c(u(r+30),e,t)],names:["Analog A","Base","Analog B"]}}function Y(r,e,t){return{colors:[c(r,e,t),c(u(r+120),e,t),c(u(r+240),e,t)],names:["Base","Triad A","Triad B"]}}function Z(r,e,t){return{colors:[c(r,e,t),c(u(r+150),e,t),c(u(r+210),e,t)],names:["Base","Split A","Split B"]}}function tt(r,e,t){return{colors:[c(r,e,t),c(u(r+90),e,t),c(u(r+180),e,t),c(u(r+270),e,t)],names:["Base","Tetrad A","Tetrad B","Tetrad C"]}}var et=[{label:"50",l:96},{label:"100",l:90},{label:"200",l:80},{label:"300",l:70},{label:"400",l:60},{label:"500",l:50},{label:"600",l:40},{label:"700",l:30},{label:"800",l:22},{label:"900",l:15},{label:"950",l:10}];function rt(r,e,t){let o=[],s=[];for(let n of et){let i=n.l>85||n.l<20?Math.max(e*.6,5):e;o.push(c(r,Math.round(i),n.l)),s.push(n.label)}return{colors:o,names:s}}var D={complementary:K,analogous:Q,triadic:Y,"split-complementary":Z,tetradic:tt,monochromatic:rt};function I(r,e){let{h:t,s:o,l:s}=N(r);return(D[e]||D.complementary)(t,o,s)}var w=["primary","secondary","accent"],W=["success","warning","error","info"],ot=[...w,...W],U={primary:"Primary",secondary:"Secondary",accent:"Accent",success:"Success",warning:"Warning",error:"Error",info:"Info"},nt={aaa:{bg:"oklch(92% 0.08 145)",fg:"oklch(30% 0.12 145)"},aa:{bg:"oklch(94% 0.08 90)",fg:"oklch(35% 0.12 70)"},fail:{bg:"oklch(92% 0.08 25)",fg:"oklch(35% 0.15 25)"}},O="var(--font-mono, monospace)",R="var(--color-text-muted, #666)",H="var(--color-border, #ddd)",J="var(--color-surface, #fff)",st="var(--color-text, #222)",m="var(--radius-s, 0.25rem)",it="var(--radius-m, 0.5rem)",j=class extends v{static observedAttributes=["colors","roles","show-export","label"];#t=[];#o=[];#b=null;#l=null;#e=null;setup(){this.#e=document.createElement("span"),this.#e.style.cssText="position:absolute;visibility:hidden;pointer-events:none",this.append(this.#e),this.#b=this.querySelector("color-palette, palette-generator"),this.#d(),this.#s(),this.#u(),this.#a("init"),this.#v(),this.#p(),this.#c("init")}attributeChangedCallback(e){!this.isConnected||!this.hasAttribute("data-upgraded")||(e==="roles"&&this.#d(),e==="colors"&&this.#s(),this.#u(),this.#a("attribute"),this.#p(),this.#c("attribute"))}teardown(){this.#e?.remove(),this.#e=null}#s(){let e=this.querySelector("color-palette");if(e){if(typeof e.colors<"u"&&e.colors.length){this.#t=e.colors.slice();return}let n=(e.getAttribute("colors")||"").split(",").map(i=>i.trim()).filter(Boolean);if(n.length){this.#t=n;return}}let t=this.querySelector("palette-generator");if(t){let s=t.getAttribute("seed")||t.querySelector('input[type="color"]')?.value||"",n=t.getAttribute("harmony")||"complementary";if(s)try{let{colors:i}=I(s,n);this.#t=i.slice();return}catch{}}let o=this.getAttribute("colors")||"";this.#t=o.split(",").map(s=>s.trim()).filter(Boolean)}#d(){let t=(this.getAttribute("roles")||w.join(",")).split(",").map(o=>o.trim().toLowerCase()).filter(o=>ot.includes(o));this.#o=t.length?t:[...w]}#i(){let e={};for(let t=0;t<this.#o.length;t++)e[this.#o[t]]=this.#t[t]||this.#t[this.#t.length-1]||"#888888";return e}#u(){let e=this.querySelector(":scope > .sp-shell");e&&e.remove();let t=this.getAttribute("label"),o=this.hasAttribute("show-export"),s=document.createElement("div");if(s.className="sp-shell",s.style.cssText="display:flex;flex-direction:column;gap:var(--size-m,1rem);margin-block-start:var(--size-s,0.75rem)",t){let i=document.createElement("p");i.style.cssText="font-weight:600;margin:0",i.textContent=t,s.append(i)}let n=document.createElement("section");n.className="sp-previews",n.setAttribute("aria-label","Role previews"),n.style.cssText="display:grid;grid-template-columns:repeat(auto-fill,minmax(min(22rem,100%),1fr));gap:var(--size-m,1rem)",s.append(n),this.#l=n,o&&s.insertAdjacentHTML("beforeend",this.#$()),this.append(s)}#a(e){if(!this.#l)return;let t=this.#i();this.#l.innerHTML=this.#o.map(o=>this.#g(o,t[o])).join("")}#g(e,t){let o=U[e]||e,n=W.includes(e)?this.#x(e,t):this.#y(e,t),i=`display:flex;flex-direction:column;gap:var(--size-s,0.75rem);padding:var(--size-m,1rem);border:1px solid ${H};border-radius:${it};background:${J};min-inline-size:0`;return`<article class="sp-card" data-role="${e}" aria-label="${o} role preview" style="${i}">
2
+ <header style="display:flex;align-items:center;justify-content:space-between;gap:var(--size-s,0.75rem)">
3
+ <div>
4
+ <code style="font-family:${O};font-size:var(--font-size-sm,0.875rem);font-weight:600">${e}</code>
5
+ <span style="display:block;font-size:var(--font-size-xs,0.75rem);color:${R}">${o}</span>
6
+ </div>
7
+ <div style="display:flex;align-items:center;gap:0.5rem">
8
+ <span class="sp-swatch" style="display:inline-block;inline-size:1.75rem;block-size:1.75rem;border-radius:${m};border:1px solid oklch(0% 0 0 / 0.15);background:${t}"></span>
9
+ <code style="font-family:${O};font-size:var(--font-size-xs,0.75rem);color:${R}">${t}</code>
10
+ </div>
11
+ </header>
12
+ <div class="sp-samples" style="display:flex;flex-wrap:wrap;gap:var(--size-s,0.75rem);align-items:flex-start">${n}</div>
13
+ </article>`}#y(e,t){let o=this.#S(e,t),s=this.#f(),n=this.#k(e,t),i=this.#T(t);return[this.#r({render:`<button type="button" tabindex="-1" style="all:unset;display:inline-block;padding:0.375rem 0.875rem;border-radius:${m};background:${t};color:${o};font-family:inherit;font-size:var(--font-size-sm,0.875rem);font-weight:600;cursor:default">Button</button>`,fg:o,bg:t,caption:"On role"}),this.#r({render:`<span style="color:${t};background:${s};padding:0.25rem 0.5rem;border-radius:${m};font-size:var(--font-size-sm,0.875rem);font-weight:500;text-decoration:underline">Linked text</span>`,fg:t,bg:s||"#ffffff",caption:"On surface"}),this.#r({render:`<span style="display:inline-block;padding:0.125rem 0.5rem;border-radius:999px;background:${n};color:${i};font-size:var(--font-size-xs,0.75rem);font-weight:600;letter-spacing:0.04em;text-transform:uppercase">Badge</span>`,fg:i,bg:n,caption:"Subtle"})].join("")}#x(e,t){let o=this.#f(),s=this.#w(e,t),n=this.#M(e,t),i=L(t);return[this.#r({render:`<div style="display:flex;align-items:center;gap:0.5rem;padding:0.5rem 0.75rem;border-radius:${m};background:${s};color:${n};border:1px solid ${t};font-size:var(--font-size-sm,0.875rem);max-inline-size:100%">
14
+ <span style="display:inline-block;inline-size:0.5rem;block-size:0.5rem;border-radius:50%;background:${t};flex-shrink:0"></span>
15
+ <span><strong>${U[e]||e}</strong> \u2014 message text</span>
16
+ </div>`,fg:n,bg:s,caption:"Alert"}),this.#r({render:`<span style="display:inline-block;padding:0.125rem 0.5rem;border-radius:999px;background:${t};color:${i};font-size:var(--font-size-xs,0.75rem);font-weight:700;letter-spacing:0.04em;text-transform:uppercase">${e}</span>`,fg:i,bg:t,caption:"Badge"}),this.#r({render:`<span style="color:${t};background:${o};padding:0.25rem 0.5rem;border-radius:${m};font-size:var(--font-size-sm,0.875rem);font-weight:600">Inline status</span>`,fg:t,bg:o||"#ffffff",caption:"On surface"})].join("")}#r({render:e,fg:t,bg:o,caption:s}){let n=B(t,this.#e)||"#000000",i=B(o,this.#e)||"#ffffff",l=_(n,i),a=V(l).toLowerCase(),d=nt[a],p=`display:inline-flex;align-items:center;gap:0.25rem;padding:0.125rem 0.375rem;border-radius:${m};font-family:${O};font-size:var(--font-size-xs,0.75rem);background:${d.bg};color:${d.fg}`;return`<div style="display:flex;flex-direction:column;gap:0.25rem;align-items:flex-start;min-inline-size:0;max-inline-size:100%">
17
+ <div style="max-inline-size:100%">${e}</div>
18
+ <div style="display:flex;align-items:center;gap:0.375rem;font-size:var(--font-size-xs,0.75rem);color:${R}">
19
+ <span style="${p}" title="${s}: ${l.toFixed(2)}:1">${l.toFixed(2)} <small>${a.toUpperCase()}</small></span>
20
+ <span>${s}</span>
21
+ </div>
22
+ </div>`}#$(){let e=`display:flex;gap:var(--size-2xs,0.375rem);padding-block-start:var(--size-xs,0.5rem);border-block-start:1px solid ${H}`,t=`padding:0.375rem 0.875rem;border:1px solid ${H};border-radius:${m};background:${J};color:${st};cursor:pointer;font:inherit;font-size:var(--font-size-sm,0.875rem)`;return`<div class="sp-export" role="toolbar" aria-label="Export semantic palette" style="${e}">
23
+ <button type="button" class="sp-copy-css" style="${t}">Copy Theme CSS</button>
24
+ <button type="button" class="sp-copy-json" style="${t}">Copy JSON</button>
25
+ </div>`}#v(){let e=this.querySelector("color-palette");e&&this.listen(e,"color-palette:change",()=>{this.#s(),this.#a("palette"),this.#c("palette")});let t=this.querySelector("palette-generator");t&&this.listen(t,"palette-generator:generate",()=>{this.#s(),this.#a("palette"),this.#c("palette")})}#p(){let e=this.querySelector(".sp-copy-css"),t=this.querySelector(".sp-copy-json");e&&this.listen(e,"click",()=>{navigator.clipboard?.writeText(this.#m()),this.#h(e,"Copy Theme CSS")}),t&&this.listen(t,"click",()=>{navigator.clipboard?.writeText(JSON.stringify(this.#i(),null,2)),this.#h(t,"Copy JSON")})}#n(){return getComputedStyle(this)}#f(){return this.#n().getPropertyValue("--color-surface").trim()||"#ffffff"}#S(e,t){return this.#n().getPropertyValue(`--color-text-on-${e}`).trim()||L(t)}#k(e,t){let o=this.#n().getPropertyValue(`--color-${e}-subtle`).trim();if(o)return o;let{h:s}=h(t);return $(.95,.03,s)}#w(e,t){let o=this.#n().getPropertyValue(`--color-${e}-subtle`).trim();if(o)return o;let{h:s}=h(t);return $(.94,.05,s)}#M(e,t){let o=this.#n().getPropertyValue(`--color-${e}-text`).trim();if(o)return o;let{h:s}=h(t);return $(.3,.14,s)}#T(e){let{l:t,c:o,h:s}=h(e);return $(Math.max(.2,t-.25),o,s)}#m(){let e=this.#i(),t=[],o=[];for(let n of this.#o){let i=e[n];if(!i)continue;let{l,c:a,h:d}=h(i);w.includes(n)?t.push(` --hue-${n}: ${d.toFixed(1)};`,` --lightness-${n}: ${(l*100).toFixed(1)}%;`,` --chroma-${n}: ${a.toFixed(3)};`):o.push(` --color-${n}: ${P({l,c:a,h:d})};`)}let s=[];return t.length&&s.push(" /* Brand seeds */",...t),o.length&&(t.length&&s.push(""),s.push(" /* Status colors */",...o)),`:root {
26
+ ${s.join(`
27
+ `)}
28
+ }
29
+ `}#h(e,t){e.textContent="Copied!",setTimeout(()=>{e.textContent=t},1500)}#c(e){this.dispatchEvent(new CustomEvent("semantic-palette:change",{bubbles:!0,detail:{mapping:this.#i(),tokens:this.#m(),source:e}}))}};F("semantic-palette",j);
30
+ //# sourceMappingURL=semantic-palette.js.map