vanilla-breeze 0.1.3 → 0.2.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 (282) hide show
  1. package/custom-elements.json +25084 -6649
  2. package/dist/cdn/components/accessibility-specimen.js +11 -0
  3. package/dist/cdn/components/accordion-wc.js +1 -1
  4. package/dist/cdn/components/activity-feed.js +2 -0
  5. package/dist/cdn/components/adr-wc.js +17 -17
  6. package/dist/cdn/components/ai-chat.js +28 -0
  7. package/dist/cdn/components/ai-summary.js +10 -0
  8. package/dist/cdn/components/analytics-panel.js +5 -5
  9. package/dist/cdn/components/audio-player.js +3 -3
  10. package/dist/cdn/components/audio-visualizer.js +2 -2
  11. package/dist/cdn/components/author-index.js +2 -2
  12. package/dist/cdn/components/brand-mark.js +1 -1
  13. package/dist/cdn/components/bread-crumb.js +2 -0
  14. package/dist/cdn/components/breakpoint-specimen.js +26 -0
  15. package/dist/cdn/components/burndown-chart.js +2 -0
  16. package/dist/cdn/components/calendar-wc.js +2 -2
  17. package/dist/cdn/components/capacity-plan.js +25 -0
  18. package/dist/cdn/components/card-list.js +1 -1
  19. package/dist/cdn/components/carousel-wc.js +1 -1
  20. package/dist/cdn/components/change-set.js +2 -2
  21. package/dist/cdn/components/chart-wc.js +58 -36
  22. package/dist/cdn/components/chat-input.js +1 -1
  23. package/dist/cdn/components/chat-window.js +1 -1
  24. package/dist/cdn/components/color-palette.js +9 -9
  25. package/dist/cdn/components/color-picker.js +1 -1
  26. package/dist/cdn/components/combo-box.js +1 -1
  27. package/dist/cdn/components/command-palette.js +1 -1
  28. package/dist/cdn/components/comment-box.js +60 -0
  29. package/dist/cdn/components/comment-thread.js +60 -0
  30. package/dist/cdn/components/comment-wc.js +1 -1
  31. package/dist/cdn/components/compare-surface.js +1 -1
  32. package/dist/cdn/components/component-sampler.js +2 -2
  33. package/dist/cdn/components/consent-banner.js +1 -1
  34. package/dist/cdn/components/content-lens.js +1 -1
  35. package/dist/cdn/components/content-swap.js +1 -1
  36. package/dist/cdn/components/context-menu.js +1 -1
  37. package/dist/cdn/components/data-table.js +1 -1
  38. package/dist/cdn/components/date-picker.js +1 -1
  39. package/dist/cdn/components/day-view.js +1 -1
  40. package/dist/cdn/components/diagram-wc.js +3 -0
  41. package/dist/cdn/components/drag-surface.js +1 -1
  42. package/dist/cdn/components/drop-down.js +1 -1
  43. package/dist/cdn/components/emoji-picker.js +1 -1
  44. package/dist/cdn/components/empathy-map.js +41 -43
  45. package/dist/cdn/components/flow-diagram.js +1 -1
  46. package/dist/cdn/components/font-pairer.js +81 -81
  47. package/dist/cdn/components/foot-notes.js +1 -1
  48. package/dist/cdn/components/form-field.js +1 -1
  49. package/dist/cdn/components/gantt-chart.js +1 -1
  50. package/dist/cdn/components/geo-map.js +25 -23
  51. package/dist/cdn/components/glossary-index.js +1 -1
  52. package/dist/cdn/components/glossary-wc.js +1 -1
  53. package/dist/cdn/components/gradient-builder.js +29 -29
  54. package/dist/cdn/components/heading-links.js +1 -1
  55. package/dist/cdn/components/highlight-wc.js +2 -2
  56. package/dist/cdn/components/icon-wc.js +4 -4
  57. package/dist/cdn/components/image-gallery.js +1 -1
  58. package/dist/cdn/components/image-map.js +1 -1
  59. package/dist/cdn/components/impact-effort.js +1 -1
  60. package/dist/cdn/components/include-file.js +1 -1
  61. package/dist/cdn/components/iron-triangle.js +2 -0
  62. package/dist/cdn/components/kanban-board.js +1 -1
  63. package/dist/cdn/components/layout-specimen.js +35 -0
  64. package/dist/cdn/components/manifest.json +227 -103
  65. package/dist/cdn/components/markdown-editor.js +1 -1
  66. package/dist/cdn/components/markdown-viewer.js +12 -12
  67. package/dist/cdn/components/motion-specimen.js +12 -12
  68. package/dist/cdn/components/nav-bar.js +2 -0
  69. package/dist/cdn/components/note-wc.js +2 -2
  70. package/dist/cdn/components/notification-wc.js +4 -4
  71. package/dist/cdn/components/page-info.js +4 -4
  72. package/dist/cdn/components/page-stats.js +1 -1
  73. package/dist/cdn/components/page-toc.js +1 -1
  74. package/dist/cdn/components/page-tools.js +1 -1
  75. package/dist/cdn/components/page-tour.js +6 -6
  76. package/dist/cdn/components/pager-wc.js +2 -0
  77. package/dist/cdn/components/palette-generator.js +11 -11
  78. package/dist/cdn/components/poll-wc.js +2 -0
  79. package/dist/cdn/components/pop-over.js +2 -0
  80. package/dist/cdn/components/popularity-index.js +2 -2
  81. package/dist/cdn/components/print-page.js +1 -1
  82. package/dist/cdn/components/product-roadmap.js +3 -0
  83. package/dist/cdn/components/progress-tracker.js +2 -0
  84. package/dist/cdn/components/qr-code.js +1 -1
  85. package/dist/cdn/components/quadrant-grid.js +3 -0
  86. package/dist/cdn/components/quality-target.js +12 -0
  87. package/dist/cdn/components/reaction-bar.js +2 -0
  88. package/dist/cdn/components/reader-view.js +3 -3
  89. package/dist/cdn/components/reading-progress.js +2 -0
  90. package/dist/cdn/components/recently-visited.js +10 -10
  91. package/dist/cdn/components/requirement-card.js +122 -0
  92. package/dist/cdn/components/review-surface.js +34 -40
  93. package/dist/cdn/components/risk-register.js +25 -0
  94. package/dist/cdn/components/roadmap.js +3 -0
  95. package/dist/cdn/components/score-card.js +197 -0
  96. package/dist/cdn/components/selection-menu.js +1 -1
  97. package/dist/cdn/components/semantic-palette.js +15 -15
  98. package/dist/cdn/components/settings-panel.js +12 -12
  99. package/dist/cdn/components/share-wc.js +2 -2
  100. package/dist/cdn/components/short-cuts.js +1 -1
  101. package/dist/cdn/components/site-index.js +4 -4
  102. package/dist/cdn/components/site-map-wc.js +1 -1
  103. package/dist/cdn/components/site-map.js +1 -1
  104. package/dist/cdn/components/site-search.js +9 -9
  105. package/dist/cdn/components/slide-accept.js +1 -1
  106. package/dist/cdn/components/social-embed.js +1 -1
  107. package/dist/cdn/components/spacing-specimen.js +5 -5
  108. package/dist/cdn/components/split-surface.js +1 -1
  109. package/dist/cdn/components/star-rating.js +1 -1
  110. package/dist/cdn/components/status-wc.js +2 -0
  111. package/dist/cdn/components/stepper-wc.js +2 -0
  112. package/dist/cdn/components/story-map.js +1 -1
  113. package/dist/cdn/components/tab-set.js +1 -1
  114. package/dist/cdn/components/text-reader.js +2 -2
  115. package/dist/cdn/components/theme-catalog.js +28 -0
  116. package/dist/cdn/components/theme-export.js +20 -12
  117. package/dist/cdn/components/theme-import.js +44 -0
  118. package/dist/cdn/components/theme-picker.js +29 -26
  119. package/dist/cdn/components/time-index.js +2 -2
  120. package/dist/cdn/components/time-picker.js +1 -1
  121. package/dist/cdn/components/toast-msg.js +3 -3
  122. package/dist/cdn/components/token-specimen.js +14 -14
  123. package/dist/cdn/components/tool-tip.js +1 -1
  124. package/dist/cdn/components/topic-map.js +3 -3
  125. package/dist/cdn/components/traceability-matrix.js +3 -0
  126. package/dist/cdn/components/trust-filter.js +3 -3
  127. package/dist/cdn/components/type-specimen.js +15 -15
  128. package/dist/cdn/components/user-journey.js +63 -70
  129. package/dist/cdn/components/user-persona.js +75 -13
  130. package/dist/cdn/components/user-story.js +12 -11
  131. package/dist/cdn/components/version-switcher.js +17 -0
  132. package/dist/cdn/components/video-player.js +3 -3
  133. package/dist/cdn/components/watch-wc.js +2 -2
  134. package/dist/cdn/components/week-view.js +1 -1
  135. package/dist/cdn/components/work-item.js +29 -28
  136. package/dist/cdn/components/youtube-player.js +1 -1
  137. package/dist/cdn/icons/bold.css +17 -0
  138. package/dist/cdn/icons/bold.json +1 -0
  139. package/dist/cdn/icons/custom.css +6 -0
  140. package/dist/cdn/icons/custom.json +1 -0
  141. package/dist/cdn/icons/lucide.css +1914 -0
  142. package/dist/cdn/icons/lucide.json +1 -0
  143. package/dist/cdn/icons/mage.css +17 -0
  144. package/dist/cdn/icons/mage.json +1 -0
  145. package/dist/cdn/icons/phosphor.css +17 -0
  146. package/dist/cdn/icons/phosphor.json +1 -0
  147. package/dist/cdn/icons/tabler.css +17 -0
  148. package/dist/cdn/icons/tabler.json +1 -0
  149. package/dist/cdn/packs/design-system.full.js +59 -51
  150. package/dist/cdn/packs/effects.full.js +1 -1
  151. package/dist/cdn/packs/icons.effects.js +1 -1
  152. package/dist/cdn/packs/icons.full.js +1 -1
  153. package/dist/cdn/packs/kawaii.full.css +1 -1
  154. package/dist/cdn/packs/kawaii.full.js +6 -6
  155. package/dist/cdn/packs/kawaii.theme.css +1 -1
  156. package/dist/cdn/packs/manifest.json +11 -11
  157. package/dist/cdn/packs/ui.full.css +1 -1
  158. package/dist/cdn/packs/ui.full.js +54 -51
  159. package/dist/cdn/packs/ux-planning.full.css +1 -1
  160. package/dist/cdn/packs/ux-planning.full.js +318 -243
  161. package/dist/cdn/themes/8bit.css +1 -1
  162. package/dist/cdn/themes/8bit.tokens.json +662 -0
  163. package/dist/cdn/themes/alpha1999-dark.tokens.json +693 -0
  164. package/dist/cdn/themes/alpha1999.css +1 -1
  165. package/dist/cdn/themes/alpha1999.tokens.json +869 -0
  166. package/dist/cdn/themes/anthropic.css +2 -0
  167. package/dist/cdn/themes/anthropic.tokens.json +564 -0
  168. package/dist/cdn/themes/art-deco-dark.tokens.json +407 -0
  169. package/dist/cdn/themes/art-deco.css +1 -1
  170. package/dist/cdn/themes/art-deco.tokens.json +581 -0
  171. package/dist/cdn/themes/bauhaus-dark.tokens.json +260 -0
  172. package/dist/cdn/themes/bauhaus.css +1 -1
  173. package/dist/cdn/themes/bauhaus.tokens.json +589 -0
  174. package/dist/cdn/themes/brutalist-dark.tokens.json +503 -0
  175. package/dist/cdn/themes/brutalist.tokens.json +677 -0
  176. package/dist/cdn/themes/catalog/atlassian.tokens.json +303 -0
  177. package/dist/cdn/themes/catalog/bootstrap.tokens.json +304 -0
  178. package/dist/cdn/themes/catalog/carbon.tokens.json +301 -0
  179. package/dist/cdn/themes/catalog/catppuccin-mocha.tokens.json +301 -0
  180. package/dist/cdn/themes/catalog/govuk.tokens.json +301 -0
  181. package/dist/cdn/themes/catalog/manifest.json +132 -0
  182. package/dist/cdn/themes/catalog/material.tokens.json +289 -0
  183. package/dist/cdn/themes/catalog/salesforce.tokens.json +301 -0
  184. package/dist/cdn/themes/catalog/tailwind.tokens.json +302 -0
  185. package/dist/cdn/themes/catppuccin-frappe.css +1 -1
  186. package/dist/cdn/themes/catppuccin-frappe.tokens.json +608 -0
  187. package/dist/cdn/themes/catppuccin-latte-dark.tokens.json +472 -0
  188. package/dist/cdn/themes/catppuccin-latte.css +1 -1
  189. package/dist/cdn/themes/catppuccin-latte.tokens.json +608 -0
  190. package/dist/cdn/themes/catppuccin-macchiato.css +1 -1
  191. package/dist/cdn/themes/catppuccin-macchiato.tokens.json +608 -0
  192. package/dist/cdn/themes/catppuccin-mocha.tokens.json +608 -0
  193. package/dist/cdn/themes/classic-dark.tokens.json +503 -0
  194. package/dist/cdn/themes/classic.tokens.json +640 -0
  195. package/dist/cdn/themes/claymorphism-dark.tokens.json +493 -0
  196. package/dist/cdn/themes/claymorphism.css +1 -1
  197. package/dist/cdn/themes/claymorphism.tokens.json +626 -0
  198. package/dist/cdn/themes/clinical-dark.tokens.json +472 -0
  199. package/dist/cdn/themes/clinical.tokens.json +608 -0
  200. package/dist/cdn/themes/cottagecore-dark.tokens.json +412 -0
  201. package/dist/cdn/themes/cottagecore.css +1 -1
  202. package/dist/cdn/themes/cottagecore.tokens.json +544 -0
  203. package/dist/cdn/themes/cyber.tokens.json +668 -0
  204. package/dist/cdn/themes/dawn-dark.tokens.json +472 -0
  205. package/dist/cdn/themes/dawn.css +1 -1
  206. package/dist/cdn/themes/dawn.tokens.json +608 -0
  207. package/dist/cdn/themes/dracula.tokens.json +534 -0
  208. package/dist/cdn/themes/dusk.tokens.json +533 -0
  209. package/dist/cdn/themes/editorial-dark.tokens.json +400 -0
  210. package/dist/cdn/themes/editorial.tokens.json +690 -0
  211. package/dist/cdn/themes/financial-dark.tokens.json +472 -0
  212. package/dist/cdn/themes/financial.css +1 -1
  213. package/dist/cdn/themes/financial.tokens.json +607 -0
  214. package/dist/cdn/themes/genai.tokens.json +534 -0
  215. package/dist/cdn/themes/glassmorphism-dark.tokens.json +489 -0
  216. package/dist/cdn/themes/glassmorphism.css +1 -1
  217. package/dist/cdn/themes/glassmorphism.tokens.json +632 -0
  218. package/dist/cdn/themes/government-dark.tokens.json +472 -0
  219. package/dist/cdn/themes/government.tokens.json +608 -0
  220. package/dist/cdn/themes/gruvbox-dark.tokens.json +472 -0
  221. package/dist/cdn/themes/gruvbox.tokens.json +608 -0
  222. package/dist/cdn/themes/high-noon-dark.tokens.json +397 -0
  223. package/dist/cdn/themes/high-noon.tokens.json +533 -0
  224. package/dist/cdn/themes/ibm.css +2 -0
  225. package/dist/cdn/themes/ibm.tokens.json +568 -0
  226. package/dist/cdn/themes/kawaii-dark.tokens.json +549 -0
  227. package/dist/cdn/themes/kawaii.css +1 -1
  228. package/dist/cdn/themes/kawaii.tokens.json +641 -0
  229. package/dist/cdn/themes/magna-dark.tokens.json +482 -0
  230. package/dist/cdn/themes/magna.css +1 -1
  231. package/dist/cdn/themes/magna.tokens.json +632 -0
  232. package/dist/cdn/themes/manifest.json +162 -62
  233. package/dist/cdn/themes/mcdonalds.css +2 -0
  234. package/dist/cdn/themes/mcdonalds.tokens.json +533 -0
  235. package/dist/cdn/themes/midnight.tokens.json +534 -0
  236. package/dist/cdn/themes/minimal-dark.tokens.json +294 -0
  237. package/dist/cdn/themes/minimal.tokens.json +494 -0
  238. package/dist/cdn/themes/modern-dark.tokens.json +490 -0
  239. package/dist/cdn/themes/modern.tokens.json +573 -0
  240. package/dist/cdn/themes/nes-dark.tokens.json +564 -0
  241. package/dist/cdn/themes/nes.css +1 -1
  242. package/dist/cdn/themes/nes.tokens.json +687 -0
  243. package/dist/cdn/themes/neumorphism-dark.tokens.json +471 -0
  244. package/dist/cdn/themes/neumorphism.css +1 -1
  245. package/dist/cdn/themes/neumorphism.tokens.json +589 -0
  246. package/dist/cdn/themes/nord-dark.tokens.json +484 -0
  247. package/dist/cdn/themes/nord.tokens.json +619 -0
  248. package/dist/cdn/themes/organic-dark.tokens.json +532 -0
  249. package/dist/cdn/themes/organic.tokens.json +685 -0
  250. package/dist/cdn/themes/rose-pine-dark.tokens.json +472 -0
  251. package/dist/cdn/themes/rose-pine.tokens.json +608 -0
  252. package/dist/cdn/themes/rough-dark.tokens.json +515 -0
  253. package/dist/cdn/themes/rough.css +1 -1
  254. package/dist/cdn/themes/rough.tokens.json +650 -0
  255. package/dist/cdn/themes/solarized-dark.tokens.json +397 -0
  256. package/dist/cdn/themes/solarized.tokens.json +532 -0
  257. package/dist/cdn/themes/starbucks.css +2 -0
  258. package/dist/cdn/themes/starbucks.tokens.json +593 -0
  259. package/dist/cdn/themes/startup-dark.tokens.json +522 -0
  260. package/dist/cdn/themes/startup.css +1 -1
  261. package/dist/cdn/themes/startup.tokens.json +607 -0
  262. package/dist/cdn/themes/super2026-dark.tokens.json +667 -0
  263. package/dist/cdn/themes/super2026.tokens.json +863 -0
  264. package/dist/cdn/themes/swiss-dark.tokens.json +390 -0
  265. package/dist/cdn/themes/swiss.tokens.json +750 -0
  266. package/dist/cdn/themes/terminal.css +1 -1
  267. package/dist/cdn/themes/terminal.tokens.json +689 -0
  268. package/dist/cdn/themes/tokyo-night-dark.tokens.json +472 -0
  269. package/dist/cdn/themes/tokyo-night.tokens.json +608 -0
  270. package/dist/cdn/themes/vaporwave-dark.tokens.json +413 -0
  271. package/dist/cdn/themes/vaporwave.tokens.json +549 -0
  272. package/dist/cdn/themes/win9x-dark.tokens.json +563 -0
  273. package/dist/cdn/themes/win9x.tokens.json +700 -0
  274. package/dist/cdn/vanilla-breeze-charts.css +1 -1
  275. package/dist/cdn/vanilla-breeze-charts.js +58 -36
  276. package/dist/cdn/vanilla-breeze-core.css +1 -1
  277. package/dist/cdn/vanilla-breeze-core.js +246 -51
  278. package/dist/cdn/vanilla-breeze-dev.js +1 -1
  279. package/dist/cdn/vanilla-breeze-extras.js +90 -80
  280. package/dist/cdn/vanilla-breeze.css +1 -1
  281. package/dist/cdn/vanilla-breeze.js +1370 -405
  282. package/package.json +12 -4
@@ -182,12 +182,12 @@ var v=`
182
182
  }
183
183
 
184
184
  .rs-popover__btn--delete {
185
- color: #dc2626;
185
+ color: var(--color-error-text, var(--color-error, #dc2626));
186
186
  }
187
187
 
188
188
  .rs-popover__btn--delete:hover {
189
- background: #fef2f2;
190
- color: #dc2626;
189
+ background: color-mix(in oklch, var(--color-error, #dc2626) 8%, var(--_card));
190
+ color: var(--color-error-text, var(--color-error, #dc2626));
191
191
  }
192
192
 
193
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 */
@@ -211,7 +211,7 @@ var v=`
211
211
  display: flex;
212
212
  align-items: center;
213
213
  justify-content: center;
214
- color: #fff;
214
+ color: var(--color-text-inverted, #fff);
215
215
  flex-shrink: 0;
216
216
  }
217
217
 
@@ -293,7 +293,7 @@ var v=`
293
293
  border: none;
294
294
  border-radius: 6px;
295
295
  background: var(--_accent);
296
- color: #fff;
296
+ color: var(--color-text-inverted, #fff);
297
297
  cursor: pointer;
298
298
  padding: 0;
299
299
  flex-shrink: 0;
@@ -355,7 +355,7 @@ var v=`
355
355
 
356
356
  .rs-toolbar__btn[aria-pressed="true"] {
357
357
  background: var(--_accent);
358
- color: #fff;
358
+ color: var(--color-text-inverted, #fff);
359
359
  border-color: var(--_accent);
360
360
  }
361
361
 
@@ -445,63 +445,57 @@ var v=`
445
445
 
446
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
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>
448
+ .state-msg--error { color: var(--color-error-text, var(--color-error, #dc2626)); }
449
+ `;var q=window.matchMedia("(prefers-reduced-motion: reduce)");var T=new Map;function C(r,e,t={}){let a=t.priority??10,s={impl:e,bundle:t.bundle,contract:t.contract,priority:a},o=T.get(r);if(customElements.get(r)){if(!o||o.priority>=a){o&&o.priority===a&&o.impl!==e&&console.warn(`[VB Bundle] Tag <${r}> already registered by "${o.bundle}" (priority ${o.priority}). Skipping "${t.bundle}".`);return}console.warn(`[VB Bundle] Tag <${r}> defined by "${o.bundle}" cannot be replaced (customElements.define is permanent). "${t.bundle}" has higher priority but arrived late.`);return}if(o&&o.priority>=a){o.priority===a&&console.warn(`[VB Bundle] Tag <${r}> already registered by "${o.bundle}". Skipping "${t.bundle}" (first wins at equal priority).`);return}T.set(r,s),customElements.define(r,e)}function c(r){return String(r).replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;")}function g(r){return r.split(" ").map(e=>e[0]).join("").toUpperCase().slice(0,2)}function y(r){let e=0;for(let a=0;a<r.length;a++)e=r.charCodeAt(a)+((e<<5)-e);return`hsl(${(e%360+360)%360}, 65%, 55%)`}function p(r){return`<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">${r}</svg>`}var l={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"/>'},V={says:{label:"Says",icon:l.messageCircle,color:"#3b82f6"},thinks:{label:"Thinks",icon:l.lightbulb,color:"#8b5cf6"},does:{label:"Does",icon:l.wrench,color:"#f59e0b"},feels:{label:"Feels",icon:l.heart,color:"#ef4444"}};function I(){let r=globalThis.localStorage;if(!r)throw new Error("VBStore: localStorage is not available in this environment");return{async getRaw(e){return r.getItem(e)},async setRaw(e,t){r.setItem(e,t)},async removeRaw(e){r.removeItem(e)},async keys(e){let t=[];for(let a=0;a<r.length;a++){let s=r.key(a);s&&s.startsWith(e)&&t.push(s)}return t}}}var f=null;function u(){return f||(f=I()),f}function x(r,e){if(typeof r!="string"||!r)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:${r}:${e}`}function P(r){if(typeof r!="string"||!r)throw new TypeError("VBStore: namespace must be a non-empty string");return`vb:${r}:`}function S(r){try{let e=JSON.parse(r);if(e&&typeof e=="object"&&typeof e.timestamp=="number")return e}catch{}return null}var _={configure(r={}){f=r.backend??null},async set(r,e,t){let a={data:t,timestamp:Date.now()};await u().setRaw(x(r,e),JSON.stringify(a))},async get(r,e,t){let a=await u().getRaw(x(r,e));if(a==null)return null;let s=S(a);return!s||t?.maxAge!=null&&Date.now()-s.timestamp>t.maxAge?null:s.data},async remove(r,e){await u().removeRaw(x(r,e))},async list(r){let e=P(r),t=await u().keys(e),a=[];for(let s of t){let o=await u().getRaw(s);if(o==null)continue;let i=S(o);i&&a.push({key:s.slice(e.length),data:i.data,timestamp:i.timestamp})}return a},async clear(r){let e=P(r),t=await u().keys(e);for(let a of t)await u().removeRaw(a)},async clearAll(){let r=await u().keys("vb:");for(let e of r)await u().removeRaw(e)},async setMany(r,e){for(let[t,a]of e)await _.set(r,t,a)}};var k="[data-copy], [data-copy-target], [data-paste-target]",L="Copied to clipboard",D="Pasted from clipboard",w=new WeakMap;async function A(r,e={}){if(r==null||r==="")return!1;let{button:t,announceMessage:a=L,duration:s=1500}=e;try{await navigator.clipboard.writeText(r)}catch{return!1}return R({button:t,duration:s,announceMessage:a,eventDetail:{text:r}}),!0}function R({button:r,duration:e,announceMessage:t,eventDetail:a,state:s="copied",eventName:o="copy"}){if(r){r.dataset.state=s;let i=w.get(r);i&&clearTimeout(i),w.set(r,setTimeout(()=>{delete r.dataset.state,w.delete(r)},e)),r.dispatchEvent(new CustomEvent(o,{bubbles:!0,detail:a}))}U(t,r??document.body)}async function j(r,e={}){let{button:t,announceMessage:a=D,duration:s=1500}=e,o;try{o=await navigator.clipboard.readText()}catch{return null}return r&&("value"in r&&(r instanceof HTMLInputElement||r instanceof HTMLTextAreaElement||r instanceof HTMLSelectElement)?r.value=o:r.textContent=o,r.dispatchEvent(new Event("input",{bubbles:!0}))),R({button:t,duration:s,announceMessage:a,eventDetail:{text:o},state:"pasted",eventName:"paste"}),o}function M(r=document){r.querySelectorAll(k).forEach(E)}function E(r){r.hasAttribute("data-copy-init")||(r.setAttribute("data-copy-init",""),r.addEventListener("click",()=>{if(r.dataset.pasteTarget){let t=document.querySelector(r.dataset.pasteTarget);if(!t)return;j(t,{button:r});return}let e=z(r);e&&A(e,{button:r})}))}function z(r){if(r.dataset.copy)return r.dataset.copy;if(r.dataset.copyTarget){let e=document.querySelector(r.dataset.copyTarget);if(!e)return"";let t=r.dataset.copyAttr;return t?e.getAttribute(t)??"":e.textContent??""}return""}function U(r,e){let t=document.createElement("div");t.setAttribute("role","status"),t.setAttribute("aria-live","polite"),t.className="visually-hidden",t.textContent=r,e.appendChild(t),setTimeout(()=>t.remove(),1e3)}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>M()):M();var B=new MutationObserver(r=>{for(let e of r)for(let t of e.addedNodes){if(t.nodeType!==Node.ELEMENT_NODE)continue;let a=t;a.matches(k)&&E(a),a.querySelectorAll(k).forEach(s=>E(s))}});B.observe(document.documentElement,{childList:!0,subtree:!0});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 a=this.#e.get(e);if(!a)throw new Error(`Pin ${e} not found`);return Object.assign(a,t),a}async remove(e){this.#e.delete(e)}},m=class{#e;constructor(e="default"){this.#e=e}async#t(){let e=await _.get("reviews",this.#e);return Array.isArray(e)?e:[]}async#r(e){await _.set("reviews",this.#e,e)}async load(){return this.#t()}async save(e){e.id||(e.id=crypto.randomUUID());let t=await this.#t();return t.push(e),await this.#r(t),e}async update(e,t){let a=await this.#t(),s=a.findIndex(o=>o.id===e);if(s===-1)throw new Error(`Pin ${e} not found`);return Object.assign(a[s],t),await this.#r(a),a[s]}async remove(e){let t=(await this.#t()).filter(a=>a.id!==e);await this.#r(t)}},b=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 a=await fetch(`${this.#e}/${encodeURIComponent(e)}`,{method:"PATCH",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)});if(!a.ok)throw new Error(`HTTP ${a.status}`);return a.json()}async remove(e){let t=await fetch(`${this.#e}/${encodeURIComponent(e)}`,{method:"DELETE"});if(!t.ok)throw new Error(`HTTP ${t.status}`)}},$=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){let t=Array.isArray(e)?e:[];this.__pins!==t&&(this.__pins=t,this.isConnected&&this._render(),this.dispatchEvent(new CustomEvent("review-surface:pins-changed",{detail:{pins:t,source:"property"},bubbles:!0,composed:!0})))}get adapter(){return this.__adapter}set adapter(e){this.__adapter=e,this.isConnected&&this._loadFromAdapter()}#t(){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.#t(),this.setAttribute("data-upgraded",""),this.#r(),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.#r(),this._loadFromAdapter()):this._render())}#r(){if(this.__adapter&&!(this.__adapter instanceof h)&&!(this.__adapter instanceof m)&&!(this.__adapter instanceof b))return;switch(this.getAttribute("adapter")||"memory"){case"local":this.__adapter=new m(this.getAttribute("storage-key")||"default");break;case"rest":try{this.__adapter=new b(this.getAttribute("endpoint")??"")}catch{this.__adapter=new h}break;default:this.__adapter=new h}}async _loadSrc(e){if(!(!e||!this.shadowRoot)){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 a=await t.json();this.__pins=Array.isArray(a)?a:a.pins||[],this._render()}catch(t){let a=t instanceof Error?t.message:String(t);this.shadowRoot.innerHTML=`<style>${v}</style><div class="state-msg state-msg--error">Could not load pins: ${c(a)}</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.#a(`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(a=>a.id===e);t&&(this.__adapter&&await this.__adapter.remove(e),this.__pins=this.__pins.filter(a=>a.id!==e),this._activePin===e&&(this._activePin=null),this._render(),this.#a("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 a={resolved:!0,resolvedBy:this.getAttribute("author")||"Anonymous",resolvedAt:new Date().toISOString()};this.__adapter&&await this.__adapter.update(e,a),Object.assign(t,a),this._render(),this.#a("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 a={resolved:!1,resolvedBy:null,resolvedAt:null};this.__adapter&&await this.__adapter.update(e,a),Object.assign(t,a),this._render(),this.#a("Pin re-opened"),this.dispatchEvent(new CustomEvent("review-surface:update",{bubbles:!0,composed:!0,detail:{pin:t,changes:a}}))}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,a)=>new Date(t.createdAt??0).getTime()-new Date(a.createdAt??0).getTime())}_render(){if(!this.shadowRoot)return;let e=this.hasAttribute("editable"),t=this.#s(),a=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
450
  <div class="rs-container">
457
451
  <slot></slot>
458
452
  <div class="rs-overlay" role="img" aria-label="Review annotation surface">
459
453
  ${t.map((s,o)=>this._renderPin(s,o+1)).join("")}
460
454
  </div>
461
- ${r?this._renderPopover(r,e):""}
455
+ ${a?this._renderPopover(a,e):""}
462
456
  </div>
463
457
  ${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)}"
458
+ <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 a=e.text?e.text.slice(0,50):"Empty pin";return`<button class="rs-pin"
459
+ data-pin-id="${c(e.id)}"
466
460
  ${e.resolved?"data-resolved":""}
467
461
  ${this._activePin===e.id?"data-active":""}
468
462
  style="left:${e.x}%;top:${e.y}%"
469
- aria-label="Pin ${t}: ${n(r)}"
463
+ aria-label="Pin ${t}: ${c(a)}"
470
464
  aria-expanded="${this._activePin===e.id}"
471
465
  aria-haspopup="dialog">
472
466
  <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
467
+ </button>`}_renderPopover(e,t){let a=this.#s().findIndex(s=>s.id===e.id)+1;return`<div class="rs-popover" data-open
474
468
  style="left:${Math.min(e.x,70)}%;top:${e.y}%"
475
469
  role="dialog"
476
- aria-labelledby="rs-popover-title-${n(e.id)}">
470
+ aria-labelledby="rs-popover-title-${c(e.id)}">
477
471
 
478
472
  <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>`:""}
473
+ <span class="rs-popover__title" id="rs-popover-title-${c(e.id)}">
474
+ Pin ${a}
475
+ ${e.resolved?`<span class="rs-resolved-badge">${p(l.checkCircle)} Resolved</span>`:""}
482
476
  </span>
483
477
  <div class="rs-popover__actions">
484
478
  ${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>`:""}
479
+ <button class="rs-popover__btn rs-popover__btn--resolve" data-action="resolve" data-pin-id="${c(e.id)}"
480
+ aria-label="Resolve pin" title="Resolve">${p(l.checkCircle)}</button>`:""}
487
481
  ${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>`:""}
482
+ <button class="rs-popover__btn" data-action="unresolve" data-pin-id="${c(e.id)}"
483
+ aria-label="Re-open pin" title="Re-open">${p(l.messageCircle)}</button>`:""}
490
484
  ${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>`:""}
485
+ <button class="rs-popover__btn rs-popover__btn--delete" data-action="delete" data-pin-id="${c(e.id)}"
486
+ aria-label="Delete pin" title="Delete">${p(l.x)}</button>`:""}
493
487
  <button class="rs-popover__btn" data-action="close"
494
- aria-label="Close">${l(c.x)}</button>
488
+ aria-label="Close">${p(l.x)}</button>
495
489
  </div>
496
490
  </div>
497
491
 
498
492
  <div class="rs-comment">
499
493
  <div class="rs-comment__meta">
500
494
  <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>
495
+ <span class="rs-comment__author">${c(e.author||"Anonymous")}</span>
502
496
  <span class="rs-comment__time">${this.#i(e.createdAt)}</span>
503
497
  </div>
504
- <div class="rs-comment__text">${n(e.text)}</div>
498
+ <div class="rs-comment__text">${c(e.text)}</div>
505
499
  </div>
506
500
 
507
501
  ${e.replies?.length?`
@@ -510,10 +504,10 @@ var v=`
510
504
  <div class="rs-reply">
511
505
  <div class="rs-comment__meta">
512
506
  <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>
507
+ <span class="rs-comment__author">${c(s.author||"Anonymous")}</span>
514
508
  <span class="rs-comment__time">${this.#i(s.createdAt)}</span>
515
509
  </div>
516
- <div class="rs-comment__text">${n(s.text)}</div>
510
+ <div class="rs-comment__text">${c(s.text)}</div>
517
511
  </div>
518
512
  `).join("")}
519
513
  </div>`:""}
@@ -521,21 +515,21 @@ var v=`
521
515
  ${t?`
522
516
  <div class="rs-input">
523
517
  <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>
518
+ aria-label="Reply to pin ${a}"></textarea>
519
+ <button class="rs-input__submit" data-action="reply" data-pin-id="${c(e.id)}"
520
+ aria-label="Send reply">${p(l.send)}</button>
527
521
  </div>`:""}
528
522
 
529
523
  </div>`}_renderToolbar(e){return`<div class="rs-toolbar" role="toolbar" aria-label="Review tools">
530
524
  <button class="rs-toolbar__btn" data-action="toggle-mode"
531
525
  aria-pressed="${this._annotating}"
532
526
  title="Toggle annotate mode">
533
- ${l(c.mapPin)} Annotate
527
+ ${p(l.mapPin)} Annotate
534
528
  </button>
535
529
  <button class="rs-toolbar__btn" data-action="export"
536
530
  title="Export pins as JSON">
537
- ${l(c.download)} Export
531
+ ${p(l.download)} Export
538
532
  </button>
539
533
  <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};
534
+ </div>`}_bindListeners(e){let t=this.shadowRoot;if(!t)return;t.querySelectorAll(".rs-pin").forEach(o=>{o.addEventListener("click",i=>{i.stopPropagation();let d=o.dataset.pinId??null;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(n=>n.id===d)}}))})});let a=t.querySelector(".rs-overlay");a&&e&&a.addEventListener("click",o=>{if(!this._annotating)return;let i=o;if(i.target?.closest(".rs-pin"))return;let n=a.getBoundingClientRect(),O=(i.clientX-n.left)/n.width*100,N=(i.clientY-n.top)/n.height*100;this.#n(O,N)}),t.querySelectorAll("[data-action]").forEach(o=>{o.addEventListener("click",i=>{i.stopPropagation();let d=o.dataset.action,n=o.dataset.pinId;switch(d){case"close":this._activePin=null,this._render();break;case"resolve":n&&this.resolvePin(n);break;case"unresolve":n&&this.unresolvePin(n);break;case"delete":n&&this.removePin(n);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(n);break}})});let s=t.querySelector(".rs-input__field");s&&s.addEventListener("keydown",o=>{let i=o;if(i.key==="Enter"&&!i.shiftKey){i.preventDefault();let n=t.querySelector('[data-action="reply"]')?.dataset.pinId;n&&this.#o(n)}}),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 a=this.getAttribute("author")||"Anonymous",s=await this.addPin({x:e,y:t,text:"",author:a});this._activePin=s.id,this._render(),requestAnimationFrame(()=>{(this.shadowRoot?.querySelector(".rs-input__field")??null)?.focus()})}async#o(e){let t=this.shadowRoot?.querySelector(".rs-input__field")??null;if(!t)return;let a=t.value.trim();if(!a)return;let s=this.__pins.find(i=>i.id===e);if(!s)return;let o={id:crypto.randomUUID(),text:a,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=a,this.__adapter&&await this.__adapter.update(e,{text:a})),this._render(),this.#a("Reply added"),requestAnimationFrame(()=>{(this.shadowRoot?.querySelector(".rs-input__field")??null)?.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);if(await A(e,{announceMessage:"Pins copied to clipboard"}))return;let a=new Blob([e],{type:"application/json"}),s=URL.createObjectURL(a),o=document.createElement("a");o.href=s,o.download="review-pins.json",o.click(),URL.revokeObjectURL(s),this.#a("Pins exported as file")}#i(e){if(!e)return"";try{let t=new Date(e),s=new Date().getTime()-t.getTime(),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""}}#a(e){let t=this.shadowRoot?.querySelector(".rs-live");t&&(t.textContent=e)}};C("review-surface",$);export{m as LocalStorageAdapter,h as MemoryAdapter,b as RestAdapter,$ as ReviewSurface};
541
535
  //# sourceMappingURL=review-surface.js.map
@@ -0,0 +1,25 @@
1
+ var m=window.matchMedia("(prefers-reduced-motion: reduce)");var c=new Map;function l(o,e,t={}){let r=t.priority??10,i={impl:e,bundle:t.bundle,contract:t.contract,priority:r},n=c.get(o);if(customElements.get(o)){if(!n||n.priority>=r){n&&n.priority===r&&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>=r){n.priority===r&&console.warn(`[VB Bundle] Tag <${o}> already registered by "${n.bundle}". Skipping "${t.bundle}" (first wins at equal priority).`);return}c.set(o,i),customElements.define(o,e)}var a=class extends HTMLElement{#e=[];#t;connectedCallback(){this.hasAttribute("data-upgraded")||this.setup()!==!1&&(this.setAttribute("data-upgraded",""),queueMicrotask(()=>{this.dispatchEvent(new CustomEvent(`${this.localName}:upgraded`,{bubbles:!0}))}))}disconnectedCallback(){for(let e of this.#e)e();this.#e=[],this.removeAttribute("data-upgraded"),this.teardown()}listen(e,t,r,i){e.addEventListener(t,r,i),this.#e.push(()=>e.removeEventListener(t,r,i))}setup(){}teardown(){}setState(e,t){this.#t||(this.#t=this.attachInternals());let r=this.#t.states;try{t?r.add(e):r.delete(e)}catch{let i=`--${e}`;t?r.add(i):r.delete(i)}}_adoptInternals(e){this.#t||(this.#t=e)}};var u=5,d=class o extends a{setup(){let e=this.querySelector(":scope > template"),t=e?o.#t(e):[];if(this.hasAttribute("src")){this.#e(this.getAttribute("src"));return}this.#r(t)}async#e(e){try{let r=await(await fetch(e)).json();this.#r(Array.isArray(r)?r:[])}catch(t){console.warn("risk-register: failed to load src",e,t),this.#r([])}}static#t(e){let t=[],r=e.content.querySelectorAll("tr");for(let i of r){let n=[...i.children],s=n[0]?.textContent?.trim()||"",h=i.getAttribute("data-id")||s.toLowerCase().replace(/\s+/g,"-")||`risk-${t.length}`;t.push({id:h,title:s,likelihood:parseInt(n[1]?.textContent??"",10)||0,impact:parseInt(n[2]?.textContent??"",10)||0,owner:n[3]?.textContent?.trim()||"",mitigation:n[4]?.textContent?.trim()||""})}return t}#r(e){this.#n=e,[...this.children].forEach(i=>{i.tagName!=="TEMPLATE"&&i.remove()});let t=this.getAttribute("label");if(t){let i=document.createElement("header");i.className="rr-label",i.textContent=t,this.appendChild(i)}let r=document.createElement("div");r.className="rr-layout",r.appendChild(this.#o(e)),r.appendChild(this.#s(e)),this.appendChild(r),queueMicrotask(()=>{this.dispatchEvent(new CustomEvent("risk-register:ready",{bubbles:!0,detail:{count:e.length}}))})}#o(e){let t=document.createElement("data-table"),r=document.createElement("table");return r.innerHTML=`
2
+ <thead>
3
+ <tr>
4
+ <th data-sort="string">Title</th>
5
+ <th data-sort="number">Likelihood</th>
6
+ <th data-sort="number">Impact</th>
7
+ <th data-sort="number" data-rollup="product" data-heatmap="low-good">Severity</th>
8
+ <th data-sort="string">Owner</th>
9
+ <th data-sort="string">Mitigation</th>
10
+ </tr>
11
+ </thead>
12
+ <tbody>
13
+ ${e.map(i=>`
14
+ <tr data-id="${o.#i(i.id)}">
15
+ <td>${o.#i(i.title)}</td>
16
+ <td>${i.likelihood||""}</td>
17
+ <td>${i.impact||""}</td>
18
+ <td></td>
19
+ <td>${o.#i(i.owner)}</td>
20
+ <td>${o.#i(i.mitigation)}</td>
21
+ </tr>
22
+ `).join("")}
23
+ </tbody>
24
+ `,t.appendChild(r),t}#s(e){let t=document.createElement("quadrant-grid");t.setAttribute("x-label","Likelihood"),t.setAttribute("y-label","Impact"),t.setAttribute("x-low","Rare"),t.setAttribute("x-high","Likely"),t.setAttribute("y-low","Minor"),t.setAttribute("y-high","Severe"),t.setAttribute("q1-label","Avoid"),t.setAttribute("q2-label","Plan"),t.setAttribute("q3-label","Accept"),t.setAttribute("q4-label","Mitigate");for(let r of e){if(!r.likelihood||!r.impact)continue;let i=document.createElement("span"),n=Math.min(1,Math.max(0,r.likelihood/u)),s=Math.min(1,Math.max(0,r.impact/u));i.setAttribute("data-x",n.toFixed(3)),i.setAttribute("data-y",s.toFixed(3)),i.setAttribute("data-id",r.id),i.setAttribute("title",`${r.title} \u2014 likelihood ${r.likelihood}, impact ${r.impact}`),i.textContent=r.title,t.appendChild(i)}return t}static#i(e){return String(e??"").replace(/[&<>"']/g,t=>({"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#39;"})[t])}#n=[];get rows(){return[...this.#n]}set rows(e){this.#r(Array.isArray(e)?e:[])}};l("risk-register",d);export{d as RiskRegister};
25
+ //# sourceMappingURL=risk-register.js.map
@@ -0,0 +1,3 @@
1
+ var y=window.matchMedia("(prefers-reduced-motion: reduce)");var g=new Map;function b(o,t,e={}){let n=e.priority??10,r={impl:t,bundle:e.bundle,contract:e.contract,priority:n},s=g.get(o);if(customElements.get(o)){if(!s||s.priority>=n){s&&s.priority===n&&s.impl!==t&&console.warn(`[VB Bundle] Tag <${o}> already registered by "${s.bundle}" (priority ${s.priority}). Skipping "${e.bundle}".`);return}console.warn(`[VB Bundle] Tag <${o}> defined by "${s.bundle}" cannot be replaced (customElements.define is permanent). "${e.bundle}" has higher priority but arrived late.`);return}if(s&&s.priority>=n){s.priority===n&&console.warn(`[VB Bundle] Tag <${o}> already registered by "${s.bundle}". Skipping "${e.bundle}" (first wins at equal priority).`);return}g.set(o,r),customElements.define(o,t)}var p=class extends HTMLElement{#s=[];#a;connectedCallback(){this.hasAttribute("data-upgraded")||this.setup()!==!1&&(this.setAttribute("data-upgraded",""),queueMicrotask(()=>{this.dispatchEvent(new CustomEvent(`${this.localName}:upgraded`,{bubbles:!0}))}))}disconnectedCallback(){for(let t of this.#s)t();this.#s=[],this.removeAttribute("data-upgraded"),this.teardown()}listen(t,e,n,r){t.addEventListener(e,n,r),this.#s.push(()=>t.removeEventListener(e,n,r))}setup(){}teardown(){}setState(t,e){this.#a||(this.#a=this.attachInternals());let n=this.#a.states;try{e?n.add(t):n.delete(t)}catch{let r=`--${t}`;e?n.add(r):n.delete(r)}}_adoptInternals(t){this.#a||(this.#a=t)}};var f=class o extends p{setup(){let t=this.getAttribute("start"),e=this.getAttribute("end");if(!t||!e)return console.warn("roadmap: start and end attributes required"),!1;let n=o.#l(t,"start"),r=o.#l(e,"end");if(!n||!r||r<=n)return console.warn("roadmap: invalid start/end",t,e),!1;this.#t=n,this.#e=r,this.#p=r.getTime()-n.getTime(),this.#f=this.getAttribute("view")==="month"?"month":"quarter",this.#u=this.hasAttribute("editable");let s=[...this.querySelectorAll(":scope > section[data-lane]")];if(!s.length)return console.warn("roadmap: no <section data-lane> children found"),!1;this.#o=s,this.#s()}attributeChangedCallback(){this.isConnected&&this.#o.length&&this.#s()}#s(){[...this.children].forEach(r=>{this.#o.includes(r)||r.remove()}),this.#o.forEach(r=>{r.hidden=!0});let t=document.createElement("div");t.className="rm-wrapper";let e=this.#a();t.appendChild(e);let n=document.createElement("div");n.className="rm-lanes";for(let r of this.#o){let s=r.getAttribute("data-lane")||"",i=document.createElement("section");i.className="rm-lane",i.dataset.lane=s;let d=document.createElement("header");d.className="rm-lane-label",d.textContent=s,i.appendChild(d);let c=document.createElement("div");c.className="rm-track",c.dataset.lane=s;let a=[...r.querySelectorAll(":scope > article[data-start][data-end]")];for(let h of a){let l=this.#y(h,s);l&&c.appendChild(l)}this.#u&&(c.addEventListener("dragover",this.#v),c.addEventListener("drop",this.#F)),i.appendChild(c),n.appendChild(i)}if(t.appendChild(n),this.hasAttribute("today-marker")){let r=new Date;if(r>=this.#t&&r<=this.#e){let s=document.createElement("div");s.className="rm-today",s.style.setProperty("--rm-x",this.#n(r).toFixed(4)),s.title=`Today: ${o.#d(r)}`,n.appendChild(s)}}this.appendChild(t),this.#C=t}#a(){let t=document.createElement("header");t.className="rm-axis";let e=this.#x();for(let n of e){let r=document.createElement("div");r.className="rm-tick",r.style.setProperty("--rm-x",n.startFraction.toFixed(4)),r.style.setProperty("--rm-w",(n.endFraction-n.startFraction).toFixed(4)),r.textContent=n.label,t.appendChild(r)}return t}#y(t,e){let n=o.#l(t.getAttribute("data-start"),"start"),r=o.#l(t.getAttribute("data-end"),"end");if(!n||!r)return null;let s=n<this.#t?this.#t:n,i=r>this.#e?this.#e:r;if(s>=i)return null;let d=this.#n(s),c=this.#n(i)-d,a=document.createElement("article");a.className="rm-bar",a.style.setProperty("--rm-x",d.toFixed(4)),a.style.setProperty("--rm-w",c.toFixed(4)),a.dataset.lane=e,a.dataset.start=o.#d(n),a.dataset.end=o.#d(r),t.dataset.status&&(a.dataset.status=t.dataset.status),t.id&&(a.dataset.sourceId=t.id),this.#u&&a.setAttribute("draggable","true");let h=t.querySelector("h1, h2, h3, h4, h5, h6"),l=document.createElement("span");if(l.className="rm-bar-title",l.textContent=h?h.textContent.trim():(t.textContent||"").trim().split(`
2
+ `)[0],a.appendChild(l),a.setAttribute("aria-label",`${l.textContent} \u2014 ${a.dataset.start} to ${a.dataset.end} in ${e}`),a.addEventListener("click",m=>{this.#r||this.dispatchEvent(new CustomEvent("roadmap:select",{bubbles:!0,detail:{initiative:t,lane:e,start:a.dataset.start,end:a.dataset.end,status:a.dataset.status||null}}))}),this.#u){let m=document.createElement("span");m.className="rm-bar-handle",m.setAttribute("aria-label","Resize end date"),a.appendChild(m),m.addEventListener("pointerdown",u=>this.#w(u,a,t)),a.addEventListener("pointerdown",u=>{u.target!==m&&this.#E(u,a,t)}),a.addEventListener("dragstart",u=>{u.dataTransfer.effectAllowed="move",u.dataTransfer.setData("text/plain",t.id||a.dataset.sourceId||""),this.#c=t,this.#g=e}),a.addEventListener("dragend",()=>{this.#c=null,this.#g=null})}return a}#E(t,e,n){if(t.button!==0)return;t.preventDefault();let r=e.parentElement.getBoundingClientRect(),s=t.clientX,i=parseFloat(e.style.getPropertyValue("--rm-x"))||0,d=parseFloat(e.style.getPropertyValue("--rm-w"))||0;this.#r={kind:"move",bar:e,initiative:n,trackRect:r,startX:s,startFraction:i,widthFraction:d},e.setPointerCapture(t.pointerId),e.addEventListener("pointermove",this.#h),e.addEventListener("pointerup",this.#i),e.addEventListener("pointercancel",this.#i)}#w(t,e,n){if(t.button!==0)return;t.preventDefault(),t.stopPropagation();let r=e.parentElement.getBoundingClientRect(),s=t.clientX,i=parseFloat(e.style.getPropertyValue("--rm-x"))||0,d=parseFloat(e.style.getPropertyValue("--rm-w"))||0;this.#r={kind:"resize",bar:e,initiative:n,trackRect:r,startX:s,startFraction:i,widthFraction:d},e.setPointerCapture(t.pointerId),e.addEventListener("pointermove",this.#h),e.addEventListener("pointerup",this.#i),e.addEventListener("pointercancel",this.#i)}#h=t=>{if(!this.#r)return;let{kind:e,bar:n,trackRect:r,startX:s,startFraction:i,widthFraction:d}=this.#r,c=(t.clientX-s)/r.width;if(e==="move"){let a=Math.max(0,Math.min(1-d,i+c));n.style.setProperty("--rm-x",a.toFixed(4))}else if(e==="resize"){let a=Math.max(.02,Math.min(1-i,d+c));n.style.setProperty("--rm-w",a.toFixed(4))}};#i=t=>{if(!this.#r)return;let{kind:e,bar:n,initiative:r}=this.#r;n.releasePointerCapture(t.pointerId),n.removeEventListener("pointermove",this.#h),n.removeEventListener("pointerup",this.#i),n.removeEventListener("pointercancel",this.#i);let s=parseFloat(n.style.getPropertyValue("--rm-x"))||0,i=parseFloat(n.style.getPropertyValue("--rm-w"))||0,d=this.#m(this.#b(s)),c=this.#m(this.#b(s+i));n.dataset.start=o.#d(d),n.dataset.end=o.#d(c);let a=this.#n(d),h=this.#n(c)-a;n.style.setProperty("--rm-x",a.toFixed(4)),n.style.setProperty("--rm-w",h.toFixed(4)),r.setAttribute("data-start",n.dataset.start),r.setAttribute("data-end",n.dataset.end),this.dispatchEvent(new CustomEvent(e==="move"?"roadmap:reschedule":"roadmap:resize",{bubbles:!0,detail:{initiative:r,lane:n.dataset.lane,start:n.dataset.start,end:n.dataset.end}})),setTimeout(()=>{this.#r=null},0)};#v=t=>{this.#c&&(t.preventDefault(),t.dataTransfer.dropEffect="move")};#F=t=>{if(!this.#c)return;t.preventDefault();let e=t.currentTarget.dataset.lane,n=this.#c,r=this.#g;if(e===r)return;let s=this.#o.find(i=>i.getAttribute("data-lane")===e);s&&s.appendChild(n),this.dispatchEvent(new CustomEvent("roadmap:move",{bubbles:!0,detail:{initiative:n,fromLane:r,toLane:e,start:n.getAttribute("data-start"),end:n.getAttribute("data-end")}})),this.#s()};#n(t){let e=t.getTime()-this.#t.getTime();return Math.max(0,Math.min(1,e/this.#p))}#b(t){return new Date(this.#t.getTime()+t*this.#p)}#m(t){if(this.#f==="month")return new Date(t.getFullYear(),t.getMonth(),1);let e=t.getMonth(),n=Math.floor(e/3)*3;return new Date(t.getFullYear(),n,1)}#x(){let t=[];if(this.#f==="quarter"){let e=this.#m(this.#t);for(;e<this.#e;){let n=new Date(e.getFullYear(),e.getMonth()+3,1),r=this.#n(e<this.#t?this.#t:e),s=this.#n(n>this.#e?this.#e:n),i=Math.floor(e.getMonth()/3)+1;t.push({startFraction:r,endFraction:s,label:`Q${i} ${e.getFullYear()}`}),e=n}}else{let e=new Date(this.#t.getFullYear(),this.#t.getMonth(),1);for(;e<this.#e;){let n=new Date(e.getFullYear(),e.getMonth()+1,1),r=this.#n(e<this.#t?this.#t:e),s=this.#n(n>this.#e?this.#e:n),i=e.toLocaleString(void 0,{month:"short"});t.push({startFraction:r,endFraction:s,label:`${i} ${e.getFullYear()}`}),e=n}}return t}static#l(t,e){if(!t)return null;let n=String(t).match(/^(\d{4})-Q([1-4])$/i);if(n){let i=Number(n[1]),c=(Number(n[2])-1)*3;return e==="end"?new Date(i,c+3,0):new Date(i,c,1)}let r=String(t).match(/^(\d{4})-(\d{2})-(\d{2})/);if(r)return new Date(Number(r[1]),Number(r[2])-1,Number(r[3]));let s=new Date(t);return isNaN(s.getTime())?null:s}static#d(t){let e=String(t.getMonth()+1).padStart(2,"0"),n=String(t.getDate()).padStart(2,"0");return`${t.getFullYear()}-${e}-${n}`}#t=null;#e=null;#p=0;#f="quarter";#u=!1;#o=[];#C=null;#r=null;#c=null;#g=null};b("roadmap",f);export{f as Roadmap};
3
+ //# sourceMappingURL=roadmap.js.map
@@ -0,0 +1,197 @@
1
+ var c=`
2
+ :host {
3
+ --_padding: var(--score-card-padding, var(--size-l, 1.5rem));
4
+ --_radius: var(--score-card-radius, var(--radius-m, 0.5rem));
5
+ --_gap: var(--score-card-gap, var(--size-s, 0.75rem));
6
+ --_value-size: var(--score-card-value-size, var(--font-size-3xl, 2rem));
7
+ --_value-weight: var(--score-card-value-weight, var(--font-weight-bold, 700));
8
+ --_title-size: var(--score-card-title-size, var(--font-size-sm, 0.875rem));
9
+ --_meta-size: var(--score-card-meta-size, var(--font-size-sm, 0.875rem));
10
+ --_sparkline-h: var(--score-card-sparkline-height, 40px);
11
+ --_surface: var(--score-card-surface, var(--color-surface, #fff));
12
+ --_border: var(--score-card-border, 1px solid var(--color-border-subtle, var(--color-border, #e5e7eb)));
13
+ --_text: var(--score-card-text, var(--color-text, #1a1a1a));
14
+ --_muted: var(--score-card-muted, var(--color-text-muted, #6b7280));
15
+ --_accent: var(--score-card-tone-accent, var(--color-interactive, var(--color-primary, #6366f1)));
16
+ --_trend-up: var(--score-card-trend-up, var(--color-success, #16a34a));
17
+ --_trend-down: var(--score-card-trend-down, var(--color-error, #dc2626));
18
+ --_trend-flat: var(--score-card-trend-flat, var(--color-text-muted, #6b7280));
19
+ --_focus: var(--color-focus-ring, var(--color-interactive, currentColor));
20
+ --_duration: var(--score-card-duration, var(--duration-fast, 150ms));
21
+ --_ease: var(--score-card-ease, var(--ease-default, ease));
22
+
23
+ display: block;
24
+ box-sizing: border-box;
25
+ color: var(--_text);
26
+ background: var(--_surface);
27
+ border: var(--_border);
28
+ border-radius: var(--_radius);
29
+ padding: var(--_padding);
30
+ container-type: inline-size;
31
+ }
32
+
33
+ *, *::before, *::after { box-sizing: border-box; }
34
+
35
+ /* \u2500\u2500 Tone accent \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 */
36
+ :host([tone="success"]) { --_accent: var(--color-success, #16a34a); }
37
+ :host([tone="warning"]) { --_accent: var(--color-warning, #d97706); }
38
+ :host([tone="error"]) { --_accent: var(--color-error, #dc2626); }
39
+ :host([tone="info"]) { --_accent: var(--color-info, #2563eb); }
40
+
41
+ /* \u2500\u2500 Layout grid \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 */
42
+ .card {
43
+ display: grid;
44
+ grid-template-columns: 1fr auto;
45
+ grid-template-areas:
46
+ "title icon"
47
+ "value icon"
48
+ "change change"
49
+ "sparkline sparkline"
50
+ "description description";
51
+ gap: var(--_gap);
52
+ align-items: start;
53
+ }
54
+
55
+ /* cluster: icon stays right, value+change wrap on the left */
56
+ :host([layout="cluster"]) .card {
57
+ grid-template-areas:
58
+ "title icon"
59
+ "value icon"
60
+ "change icon"
61
+ "sparkline sparkline"
62
+ "description description";
63
+ }
64
+
65
+ /* compact: dense vertical, smaller value */
66
+ :host([layout="compact"]) {
67
+ --_padding: var(--size-m, 1rem);
68
+ --_value-size: var(--font-size-2xl, 1.5rem);
69
+ --_gap: var(--size-2xs, 0.25rem);
70
+ }
71
+
72
+ /* \u2500\u2500 Slot regions \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 */
73
+ .title { grid-area: title; }
74
+ .value { grid-area: value; }
75
+ .change { grid-area: change; }
76
+ .sparkline { grid-area: sparkline; }
77
+ .description { grid-area: description; }
78
+ .icon { grid-area: icon; }
79
+
80
+ .title ::slotted(*) {
81
+ margin: 0;
82
+ font-size: var(--_title-size);
83
+ font-weight: var(--font-weight-medium, 500);
84
+ color: var(--_muted);
85
+ line-height: 1.3;
86
+ }
87
+
88
+ .value ::slotted(*) {
89
+ font-size: var(--_value-size);
90
+ font-weight: var(--_value-weight);
91
+ line-height: 1.1;
92
+ color: var(--_text);
93
+ font-variant-numeric: tabular-nums;
94
+ }
95
+
96
+ .change ::slotted(*) {
97
+ display: inline-flex;
98
+ align-items: center;
99
+ gap: var(--size-2xs, 0.25rem);
100
+ font-size: var(--_meta-size);
101
+ color: var(--_muted);
102
+ line-height: 1.4;
103
+ }
104
+
105
+ .description ::slotted(*) {
106
+ font-size: var(--_meta-size);
107
+ color: var(--_muted);
108
+ line-height: 1.4;
109
+ margin: 0;
110
+ }
111
+
112
+ /* Empty optional slots collapse to zero so they don't reserve grid rows.
113
+ :state(has-*) is set by JS when slotchange fires with assigned nodes. */
114
+ .change, .sparkline, .description, .icon { display: none; }
115
+ :host(:state(has-change)) .change { display: block; }
116
+ :host(:state(has-sparkline)) .sparkline { display: block; min-block-size: var(--_sparkline-h); overflow: hidden; }
117
+ :host(:state(has-description)) .description { display: block; }
118
+ :host(:state(has-icon)) .icon { display: inline-flex; align-items: center; justify-content: center; }
119
+
120
+ .sparkline ::slotted(*) {
121
+ display: block;
122
+ inline-size: 100%;
123
+ block-size: var(--_sparkline-h);
124
+ max-block-size: var(--_sparkline-h);
125
+ }
126
+
127
+ /* icon region \u2014 accent color from tone */
128
+ .icon ::slotted(*) {
129
+ color: var(--_accent);
130
+ --icon-color: var(--_accent);
131
+ }
132
+
133
+ /* \u2500\u2500 Trend coloring (drives change row) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
134
+ :host(:state(trend-up)) .change ::slotted(*) { color: var(--_trend-up); }
135
+ :host(:state(trend-down)) .change ::slotted(*) { color: var(--_trend-down); }
136
+ :host(:state(trend-flat)) .change ::slotted(*) { color: var(--_trend-flat); }
137
+
138
+ /* \u2500\u2500 Interactive (wrapped in <a>) \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 */
139
+ :host(:state(interactive)) {
140
+ cursor: pointer;
141
+ transition: transform var(--_duration) var(--_ease),
142
+ box-shadow var(--_duration) var(--_ease),
143
+ border-color var(--_duration) var(--_ease);
144
+ }
145
+
146
+ /* Lift on hover of the wrapping anchor. We can't reach the anchor from
147
+ shadow CSS, so consumers should use the :has() partner rule in their
148
+ light-DOM stylesheet (documented in the spec). The transition above
149
+ still applies to any state changes the consumer drives. */
150
+
151
+ /* \u2500\u2500 Loading skeleton \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 */
152
+ :host(:state(loading)) .value,
153
+ :host(:state(loading)) .sparkline,
154
+ :host(:state(loading)) .change {
155
+ background: linear-gradient(
156
+ 90deg,
157
+ color-mix(in oklch, var(--_muted) 12%, transparent),
158
+ color-mix(in oklch, var(--_muted) 24%, transparent),
159
+ color-mix(in oklch, var(--_muted) 12%, transparent)
160
+ );
161
+ background-size: 200% 100%;
162
+ border-radius: var(--radius-s, 0.25rem);
163
+ color: transparent;
164
+ animation: score-card-shimmer 1.4s var(--_ease) infinite;
165
+ }
166
+ :host(:state(loading)) .value ::slotted(*),
167
+ :host(:state(loading)) .change ::slotted(*),
168
+ :host(:state(loading)) .sparkline ::slotted(*) {
169
+ visibility: hidden;
170
+ }
171
+ :host(:state(loading)) .value { min-block-size: var(--_value-size); }
172
+ :host(:state(loading)) .change { min-block-size: 1.4em; }
173
+
174
+ @keyframes score-card-shimmer {
175
+ from { background-position: 200% 0; }
176
+ to { background-position: -200% 0; }
177
+ }
178
+ @media (prefers-reduced-motion: reduce) {
179
+ :host(:state(loading)) .value,
180
+ :host(:state(loading)) .sparkline,
181
+ :host(:state(loading)) .change {
182
+ animation: none;
183
+ background: color-mix(in oklch, var(--_muted) 18%, transparent);
184
+ }
185
+ }
186
+ `;var n=class extends HTMLElement{#t=[];#e;connectedCallback(){this.hasAttribute("data-upgraded")||this.setup()!==!1&&(this.setAttribute("data-upgraded",""),queueMicrotask(()=>{this.dispatchEvent(new CustomEvent(`${this.localName}:upgraded`,{bubbles:!0}))}))}disconnectedCallback(){for(let e of this.#t)e();this.#t=[],this.removeAttribute("data-upgraded"),this.teardown()}listen(e,t,r,o){e.addEventListener(t,r,o),this.#t.push(()=>e.removeEventListener(t,r,o))}setup(){}teardown(){}setState(e,t){this.#e||(this.#e=this.attachInternals());let r=this.#e.states;try{t?r.add(e):r.delete(e)}catch{let o=`--${e}`;t?r.add(o):r.delete(o)}}_adoptInternals(e){this.#e||(this.#e=e)}};var m=window.matchMedia("(prefers-reduced-motion: reduce)");var l=new Map;function d(s,e,t={}){let r=t.priority??10,o={impl:e,bundle:t.bundle,contract:t.contract,priority:r},a=l.get(s);if(customElements.get(s)){if(!a||a.priority>=r){a&&a.priority===r&&a.impl!==e&&console.warn(`[VB Bundle] Tag <${s}> already registered by "${a.bundle}" (priority ${a.priority}). Skipping "${t.bundle}".`);return}console.warn(`[VB Bundle] Tag <${s}> defined by "${a.bundle}" cannot be replaced (customElements.define is permanent). "${t.bundle}" has higher priority but arrived late.`);return}if(a&&a.priority>=r){a.priority===r&&console.warn(`[VB Bundle] Tag <${s}> already registered by "${a.bundle}". Skipping "${t.bundle}" (first wins at equal priority).`);return}l.set(s,o),customElements.define(s,e)}var u=new Set(["up","down","flat"]),h=["change","sparkline","description","icon"],p=`
187
+ <style>${c}</style>
188
+ <div class="card" part="card">
189
+ <span class="title" part="title"><slot name="title"></slot></span>
190
+ <span class="value" part="value"><slot name="value"><slot></slot></slot></span>
191
+ <span class="change" part="change"><slot name="change" data-slot="change"></slot></span>
192
+ <span class="sparkline" part="sparkline"><slot name="sparkline" data-slot="sparkline"></slot></span>
193
+ <span class="description" part="description"><slot name="description" data-slot="description"></slot></span>
194
+ <span class="icon" part="icon"><slot name="icon" data-slot="icon"></slot></span>
195
+ </div>
196
+ `,i=class extends n{static get observedAttributes(){return["trend","loading"]}setup(){if(this.shadowRoot)for(let e of h){let t=this.shadowRoot.querySelector(`slot[name="${e}"]`);this.#t(e,t)}else{let e=this.attachShadow({mode:"open"});e.innerHTML=p;for(let t of h){let r=e.querySelector(`slot[name="${t}"]`);r?.addEventListener("slotchange",()=>this.#t(t,r)),this.#t(t,r)}}this.#e(),this.#r(),this.#a()}attributeChangedCallback(e){this.isConnected&&(e==="trend"?this.#e():e==="loading"&&this.#r())}#t(e,t){let r=!!t&&t.assignedNodes({flatten:!0}).some(o=>o.nodeType===Node.ELEMENT_NODE||o.nodeType===Node.TEXT_NODE&&o.textContent.trim().length>0);this.setState(`has-${e}`,r)}#e(){let e=(this.getAttribute("trend")||"").toLowerCase();for(let t of u)this.setState(`trend-${t}`,t===e)}#r(){this.setState("loading",this.hasAttribute("loading"))}#a(){let e=this.closest("a[href]");this.setState("interactive",!!e)}};d("score-card",i);export{i as ScoreCard};
197
+ //# sourceMappingURL=score-card.js.map
@@ -1,2 +1,2 @@
1
- var d=class extends HTMLElement{#e=[];connectedCallback(){this.hasAttribute("data-upgraded")||this.setup()!==!1&&(this.setAttribute("data-upgraded",""),this.dispatchEvent(new CustomEvent(`${this.localName}:upgraded`,{bubbles:!0})))}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);
1
+ var c=class extends HTMLElement{#e=[];#s;connectedCallback(){this.hasAttribute("data-upgraded")||this.setup()!==!1&&(this.setAttribute("data-upgraded",""),queueMicrotask(()=>{this.dispatchEvent(new CustomEvent(`${this.localName}:upgraded`,{bubbles:!0}))}))}disconnectedCallback(){for(let t of this.#e)t();this.#e=[],this.removeAttribute("data-upgraded"),this.teardown()}listen(t,e,s,i){t.addEventListener(e,s,i),this.#e.push(()=>t.removeEventListener(e,s,i))}setup(){}teardown(){}setState(t,e){this.#s||(this.#s=this.attachInternals());let s=this.#s.states;try{e?s.add(t):s.delete(t)}catch{let i=`--${t}`;e?s.add(i):s.delete(i)}}_adoptInternals(t){this.#s||(this.#s=t)}};var w=window.matchMedia("(prefers-reduced-motion: reduce)");var f=new Map;function h(r,t,e={}){let s=e.priority??10,i={impl:t,bundle:e.bundle,contract:e.contract,priority:s},o=f.get(r);if(customElements.get(r)){if(!o||o.priority>=s){o&&o.priority===s&&o.impl!==t&&console.warn(`[VB Bundle] Tag <${r}> already registered by "${o.bundle}" (priority ${o.priority}). Skipping "${e.bundle}".`);return}console.warn(`[VB Bundle] Tag <${r}> defined by "${o.bundle}" cannot be replaced (customElements.define is permanent). "${e.bundle}" has higher priority but arrived late.`);return}if(o&&o.priority>=s){o.priority===s&&console.warn(`[VB Bundle] Tag <${r}> already registered by "${o.bundle}". Skipping "${e.bundle}" (first wins at equal priority).`);return}f.set(r,i),customElements.define(r,t)}var l=CSS.supports("anchor-name","--x"),b=CSS.supports("position-area","bottom"),g=0,d=class extends c{#e=null;#s=null;#o=null;#t=null;setup(){this.id||(this.id=`pop-over-${++g}`);let t=this.dataset.mode||"auto";this.hasAttribute("popover")||this.setAttribute("popover",t),this.#n(),this.#a(),this.#o=e=>{let s=e.newState==="open"?"show":"hide";this.dispatchEvent(new CustomEvent(`pop-over:${s}`,{detail:{state:e.newState},bubbles:!0,composed:!0})),!l&&e.newState==="open"&&this.#e&&this.#r()},this.listen(this,"beforetoggle",this.#o),l||(this.#t=()=>{this.matches(":popover-open")&&this.#e&&this.#r()},this.listen(window,"resize",this.#t),this.listen(window,"scroll",this.#t,{capture:!0,passive:!0}))}show(){this.matches(":popover-open")||this.showPopover()}hide(){this.matches(":popover-open")&&this.hidePopover()}toggle(){this.matches(":popover-open")?this.hide():this.show()}get open(){return this.matches(":popover-open")}#n(){let t=this.dataset.anchor;t?this.#e=document.getElementById(t)||document.querySelector(t):this.#e=document.querySelector(`[popovertarget="${CSS.escape(this.id)}"]`)}#a(){if(!(!this.#e||!l)&&(this.#s=`--pop-over-anchor-${this.id}`,this.#e.style.setProperty("anchor-name",this.#s),this.style.setProperty("position-anchor",this.#s),this.setAttribute("data-anchor-name",this.#s||""),!b)){let t=this.dataset.position||"bottom";this.#c(t)}}#c(t){let e="var(--_pop-over-offset, var(--size-xs))",s={top:{bottom:`calc(anchor(top) + ${e})`,left:"anchor(left)"},bottom:{top:`calc(anchor(bottom) + ${e})`,left:"anchor(left)"},left:{right:`calc(anchor(left) + ${e})`,top:"anchor(top)"},right:{left:`calc(anchor(right) + ${e})`,top:"anchor(top)"}},i=t.split("-")[0],o=s[i]||s.bottom;Object.entries(o).forEach(([a,n])=>this.style.setProperty(a,n))}#r(){if(!this.#e)return;let t=this.#e.getBoundingClientRect(),e=this.dataset.position||"bottom",s=this.#i(),i,o;switch(e.split("-")[0]){case"top":i=t.top-this.offsetHeight-s,o=t.left;break;case"left":i=t.top,o=t.left-this.offsetWidth-s;break;case"right":i=t.top,o=t.right+s;break;default:i=t.bottom+s,o=t.left;break}e.endsWith("-end")&&(e.startsWith("top")||e.startsWith("bottom")?o=t.right-this.offsetWidth:i=t.bottom-this.offsetHeight),this.style.position="fixed",this.style.top=`${Math.round(i)}px`,this.style.left=`${Math.round(o)}px`,this.style.margin="0"}#i(){let t={none:0,xs:4,s:8,m:16,l:24};return t[this.dataset.offset]??t.xs}};h("pop-over",d);var m=8,u=8,y=0,p=class extends c{#e=null;#s=new Set;#o=!1;#t;setup(){let t=this.querySelector(":scope > pop-over[data-selection-menu-host]");if(t)this.#t=t;else{this.#t=document.createElement("pop-over"),this.#t.setAttribute("data-selection-menu-host",""),this.#t.dataset.mode="manual",this.#t.id=`selection-menu-${++y}`;let e=[...this.children];for(let s of e)s!==this.#t&&this.#t.appendChild(s);this.appendChild(this.#t)}this.hidden=!1,this.#n(),this.listen(document,"pointerup",this.#a),this.listen(document,"pointerdown",this.#h),this.listen(document,"keydown",this.#l),this.id&&new MutationObserver(()=>this.#n()).observe(document.body,{childList:!0,subtree:!0,attributeFilter:["data-selection-menu"]})}getSelection(){return this.#e?{...this.#e}:null}dismiss(){this.#i()}get actions(){return[...(this.#t||this).children].map(e=>({tag:e.tagName.toLowerCase(),attrs:Object.fromEntries([...e.attributes].map(s=>[s.name,s.value])),html:e.innerHTML||void 0}))}set actions(t){let e=Array.isArray(t)?t:[],s=this.#t||this;for(;s.firstChild;)s.firstChild.remove();for(let i of e){if(i instanceof Element){s.appendChild(i);continue}if(!i?.tag)continue;let o=document.createElement(i.tag);if(i.attrs)for(let[a,n]of Object.entries(i.attrs))n==null||n===!1||o.setAttribute(a,n===!0?"":String(n));i.html&&(o.innerHTML=i.html),s.appendChild(o)}this.dispatchEvent(new CustomEvent("selection-menu:actions-changed",{detail:{actions:this.actions,source:"property"},bubbles:!0}))}#n(){this.#s.clear();let t=this.getAttribute("for");if(t){let e=document.getElementById(t);e&&(this.#s.add(e),e.hasAttribute("data-selection-menu")||e.setAttribute("data-selection-menu",this.id||""))}this.id&&document.querySelectorAll(`[data-selection-menu="${this.id}"]`).forEach(e=>{this.#s.add(e)})}#a=()=>{requestAnimationFrame(()=>{this.isConnected&&this.#c()})};#c(){let t=window.getSelection();if(!t||t.isCollapsed||!t.toString().trim())return;let e=t.getRangeAt(0),s=e.commonAncestorContainer,i=s.nodeType===Node.ELEMENT_NODE?s:s.parentElement,o=null;for(let n of this.#s)if(n.contains(i)){o=n;break}if(!o)return;let a=t.toString().trim();this.#e={range:e.cloneRange(),text:a,target:o},this.dispatchEvent(new CustomEvent("selection-menu:select",{detail:{range:this.#e.range,text:a,target:o},bubbles:!0})),this.#r(e.getBoundingClientRect())}#r(t){this.#t&&(this.#t.show(),this.#o=!0,requestAnimationFrame(()=>{let e=this.#t.getBoundingClientRect(),s=e.width||200,i=e.height||40,o=t.top-i-m,a=t.left+t.width/2-s/2;o<u&&(o=t.bottom+m);let n=window.innerWidth-s-u;a=Math.max(u,Math.min(a,n)),this.#t.style.top=`${o}px`,this.#t.style.left=`${a}px`}))}#i(){this.#t&&this.#t.hide(),this.#o=!1,this.#e=null,this.dispatchEvent(new CustomEvent("selection-menu:dismiss",{bubbles:!0}))}#h=t=>{this.#o&&(this.#t?.contains(t.target)||this.contains(t.target)||this.#i())};#l=t=>{t.key==="Escape"&&this.#o&&this.#i()}};h("selection-menu",p);
2
2
  //# sourceMappingURL=selection-menu.js.map