vanilla-breeze 0.3.0 → 0.4.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 (224) hide show
  1. package/README.md +33 -4
  2. package/dist/cdn/components/activity-feed.js +1 -1
  3. package/dist/cdn/components/audio-player.js +2 -2
  4. package/dist/cdn/components/carousel-wc.js +1 -1
  5. package/dist/cdn/components/comment-box.js +16 -16
  6. package/dist/cdn/components/comment-thread.js +20 -20
  7. package/dist/cdn/components/comment-wc.js +1 -1
  8. package/dist/cdn/components/content-lens.js +1 -1
  9. package/dist/cdn/components/context-menu.js +1 -1
  10. package/dist/cdn/components/diagram-wc.js +1 -1
  11. package/dist/cdn/components/drop-down.js +1 -1
  12. package/dist/cdn/components/image-gallery.js +1 -1
  13. package/dist/cdn/components/manifest.json +44 -20
  14. package/dist/cdn/components/reaction-bar.js +1 -1
  15. package/dist/cdn/components/score-card.js +2 -2
  16. package/dist/cdn/components/settings-panel.js +15 -15
  17. package/dist/cdn/components/site-search.js +1 -1
  18. package/dist/cdn/components/social-embed.js +1 -1
  19. package/dist/cdn/components/tab-set.js +1 -1
  20. package/dist/cdn/components/theme-picker.js +45 -45
  21. package/dist/cdn/components/time-index.js +2 -2
  22. package/dist/cdn/components/time-picker.js +1 -1
  23. package/dist/cdn/components/version-switcher.js +1 -1
  24. package/dist/cdn/packs/effects.full.js +1 -1
  25. package/dist/cdn/packs/journal.effects.css +1 -1
  26. package/dist/cdn/packs/journal.full.css +1 -1
  27. package/dist/cdn/packs/kawaii.effects.css +1 -1
  28. package/dist/cdn/packs/kawaii.full.css +2 -2
  29. package/dist/cdn/packs/kawaii.full.js +4 -4
  30. package/dist/cdn/packs/kawaii.theme.css +1 -1
  31. package/dist/cdn/packs/manifest.json +11 -11
  32. package/dist/cdn/packs/memphis.full.css +1 -1
  33. package/dist/cdn/packs/memphis.theme.css +1 -1
  34. package/dist/cdn/packs/ui.full.css +1 -1
  35. package/dist/cdn/packs/ui.full.js +52 -52
  36. package/dist/cdn/themes/8bit.css +1 -1
  37. package/dist/cdn/themes/8bit.tokens.json +4 -4
  38. package/dist/cdn/themes/alpha1999-dark.tokens.json +4 -4
  39. package/dist/cdn/themes/alpha1999.css +1 -1
  40. package/dist/cdn/themes/alpha1999.tokens.json +4 -4
  41. package/dist/cdn/themes/anthropic.css +1 -1
  42. package/dist/cdn/themes/anthropic.tokens.json +4 -4
  43. package/dist/cdn/themes/art-deco-dark.tokens.json +4 -4
  44. package/dist/cdn/themes/art-deco.css +1 -1
  45. package/dist/cdn/themes/art-deco.tokens.json +4 -4
  46. package/dist/cdn/themes/bauhaus-dark.tokens.json +1 -1
  47. package/dist/cdn/themes/bauhaus.css +1 -1
  48. package/dist/cdn/themes/bauhaus.tokens.json +4 -4
  49. package/dist/cdn/themes/brutalist-dark.tokens.json +4 -4
  50. package/dist/cdn/themes/brutalist.css +1 -1
  51. package/dist/cdn/themes/brutalist.tokens.json +4 -4
  52. package/dist/cdn/themes/catalog/atlassian.tokens.json +2 -2
  53. package/dist/cdn/themes/catalog/bootstrap.tokens.json +2 -2
  54. package/dist/cdn/themes/catalog/carbon.tokens.json +2 -2
  55. package/dist/cdn/themes/catalog/catppuccin-mocha.tokens.json +2 -2
  56. package/dist/cdn/themes/catalog/govuk.tokens.json +2 -2
  57. package/dist/cdn/themes/catalog/manifest.json +1 -1
  58. package/dist/cdn/themes/catalog/material.tokens.json +2 -2
  59. package/dist/cdn/themes/catalog/salesforce.tokens.json +2 -2
  60. package/dist/cdn/themes/catalog/tailwind.tokens.json +2 -2
  61. package/dist/cdn/themes/catppuccin-frappe.css +1 -1
  62. package/dist/cdn/themes/catppuccin-frappe.tokens.json +4 -4
  63. package/dist/cdn/themes/catppuccin-latte-dark.tokens.json +4 -4
  64. package/dist/cdn/themes/catppuccin-latte.css +1 -1
  65. package/dist/cdn/themes/catppuccin-latte.tokens.json +4 -4
  66. package/dist/cdn/themes/catppuccin-macchiato.css +1 -1
  67. package/dist/cdn/themes/catppuccin-macchiato.tokens.json +4 -4
  68. package/dist/cdn/themes/catppuccin-mocha.css +1 -1
  69. package/dist/cdn/themes/catppuccin-mocha.tokens.json +4 -4
  70. package/dist/cdn/themes/classic-dark.tokens.json +4 -4
  71. package/dist/cdn/themes/classic.css +1 -1
  72. package/dist/cdn/themes/classic.tokens.json +4 -4
  73. package/dist/cdn/themes/claymorphism-dark.tokens.json +10 -10
  74. package/dist/cdn/themes/claymorphism.css +1 -1
  75. package/dist/cdn/themes/claymorphism.tokens.json +10 -10
  76. package/dist/cdn/themes/clinical-dark.tokens.json +4 -4
  77. package/dist/cdn/themes/clinical.css +1 -1
  78. package/dist/cdn/themes/clinical.tokens.json +4 -4
  79. package/dist/cdn/themes/cottagecore-dark.tokens.json +4 -4
  80. package/dist/cdn/themes/cottagecore.css +1 -1
  81. package/dist/cdn/themes/cottagecore.tokens.json +4 -4
  82. package/dist/cdn/themes/cyber.css +1 -1
  83. package/dist/cdn/themes/cyber.tokens.json +4 -5
  84. package/dist/cdn/themes/dawn-dark.tokens.json +4 -4
  85. package/dist/cdn/themes/dawn.css +1 -1
  86. package/dist/cdn/themes/dawn.tokens.json +4 -4
  87. package/dist/cdn/themes/dracula.css +1 -1
  88. package/dist/cdn/themes/dracula.tokens.json +4 -4
  89. package/dist/cdn/themes/dusk.css +1 -1
  90. package/dist/cdn/themes/dusk.tokens.json +4 -4
  91. package/dist/cdn/themes/editorial-dark.tokens.json +3 -3
  92. package/dist/cdn/themes/editorial.css +1 -1
  93. package/dist/cdn/themes/editorial.tokens.json +4 -4
  94. package/dist/cdn/themes/financial-dark.tokens.json +4 -4
  95. package/dist/cdn/themes/financial.css +1 -1
  96. package/dist/cdn/themes/financial.tokens.json +4 -4
  97. package/dist/cdn/themes/genai.css +1 -1
  98. package/dist/cdn/themes/genai.tokens.json +4 -4
  99. package/dist/cdn/themes/glassmorphism-dark.tokens.json +4 -4
  100. package/dist/cdn/themes/glassmorphism.css +1 -1
  101. package/dist/cdn/themes/glassmorphism.tokens.json +4 -4
  102. package/dist/cdn/themes/government-dark.tokens.json +4 -4
  103. package/dist/cdn/themes/government.css +1 -1
  104. package/dist/cdn/themes/government.tokens.json +4 -4
  105. package/dist/cdn/themes/gruvbox-dark.tokens.json +4 -4
  106. package/dist/cdn/themes/gruvbox.css +1 -1
  107. package/dist/cdn/themes/gruvbox.tokens.json +4 -4
  108. package/dist/cdn/themes/high-noon-dark.tokens.json +4 -4
  109. package/dist/cdn/themes/high-noon.css +1 -1
  110. package/dist/cdn/themes/high-noon.tokens.json +4 -4
  111. package/dist/cdn/themes/ibm.css +1 -1
  112. package/dist/cdn/themes/ibm.tokens.json +6 -6
  113. package/dist/cdn/themes/journal-dark.tokens.json +4 -4
  114. package/dist/cdn/themes/journal.css +1 -1
  115. package/dist/cdn/themes/journal.tokens.json +4 -4
  116. package/dist/cdn/themes/kawaii-dark.tokens.json +4 -4
  117. package/dist/cdn/themes/kawaii.css +1 -1
  118. package/dist/cdn/themes/kawaii.tokens.json +4 -4
  119. package/dist/cdn/themes/magna-dark.tokens.json +4 -4
  120. package/dist/cdn/themes/magna.css +1 -1
  121. package/dist/cdn/themes/magna.tokens.json +4 -4
  122. package/dist/cdn/themes/manifest.json +48 -48
  123. package/dist/cdn/themes/mcdonalds.css +1 -1
  124. package/dist/cdn/themes/mcdonalds.tokens.json +4 -4
  125. package/dist/cdn/themes/midnight.css +1 -1
  126. package/dist/cdn/themes/midnight.tokens.json +4 -4
  127. package/dist/cdn/themes/minimal-dark.tokens.json +4 -4
  128. package/dist/cdn/themes/minimal.css +1 -1
  129. package/dist/cdn/themes/minimal.tokens.json +4 -4
  130. package/dist/cdn/themes/modern-dark.tokens.json +4 -4
  131. package/dist/cdn/themes/modern.css +1 -1
  132. package/dist/cdn/themes/modern.tokens.json +4 -4
  133. package/dist/cdn/themes/nes-dark.tokens.json +4 -4
  134. package/dist/cdn/themes/nes.css +1 -1
  135. package/dist/cdn/themes/nes.tokens.json +4 -4
  136. package/dist/cdn/themes/neumorphism-dark.tokens.json +10 -10
  137. package/dist/cdn/themes/neumorphism.css +1 -1
  138. package/dist/cdn/themes/neumorphism.tokens.json +10 -10
  139. package/dist/cdn/themes/nord-dark.tokens.json +4 -4
  140. package/dist/cdn/themes/nord.css +1 -1
  141. package/dist/cdn/themes/nord.tokens.json +4 -4
  142. package/dist/cdn/themes/organic-dark.tokens.json +4 -4
  143. package/dist/cdn/themes/organic.css +1 -1
  144. package/dist/cdn/themes/organic.tokens.json +4 -4
  145. package/dist/cdn/themes/rose-pine-dark.tokens.json +4 -4
  146. package/dist/cdn/themes/rose-pine.css +1 -1
  147. package/dist/cdn/themes/rose-pine.tokens.json +4 -4
  148. package/dist/cdn/themes/rough-dark.tokens.json +4 -5
  149. package/dist/cdn/themes/rough.css +1 -1
  150. package/dist/cdn/themes/rough.tokens.json +5 -6
  151. package/dist/cdn/themes/solarized-dark.tokens.json +4 -4
  152. package/dist/cdn/themes/solarized.css +1 -1
  153. package/dist/cdn/themes/solarized.tokens.json +4 -4
  154. package/dist/cdn/themes/starbucks.css +1 -1
  155. package/dist/cdn/themes/starbucks.tokens.json +4 -4
  156. package/dist/cdn/themes/startup-dark.tokens.json +4 -4
  157. package/dist/cdn/themes/startup.css +1 -1
  158. package/dist/cdn/themes/startup.tokens.json +4 -4
  159. package/dist/cdn/themes/super2026-dark.tokens.json +4 -4
  160. package/dist/cdn/themes/super2026.css +1 -1
  161. package/dist/cdn/themes/super2026.tokens.json +4 -4
  162. package/dist/cdn/themes/swiss-dark.tokens.json +1 -1
  163. package/dist/cdn/themes/swiss.css +1 -1
  164. package/dist/cdn/themes/swiss.tokens.json +4 -4
  165. package/dist/cdn/themes/terminal.css +1 -1
  166. package/dist/cdn/themes/terminal.tokens.json +4 -4
  167. package/dist/cdn/themes/tokyo-night-dark.tokens.json +4 -4
  168. package/dist/cdn/themes/tokyo-night.css +1 -1
  169. package/dist/cdn/themes/tokyo-night.tokens.json +4 -4
  170. package/dist/cdn/themes/vaporwave-dark.tokens.json +4 -4
  171. package/dist/cdn/themes/vaporwave.css +1 -1
  172. package/dist/cdn/themes/vaporwave.tokens.json +4 -4
  173. package/dist/cdn/themes/win9x-dark.tokens.json +4 -4
  174. package/dist/cdn/themes/win9x.css +1 -1
  175. package/dist/cdn/themes/win9x.tokens.json +4 -4
  176. package/dist/cdn/vanilla-breeze-charts.css +1 -1
  177. package/dist/cdn/vanilla-breeze-core.css +1 -1
  178. package/dist/cdn/vanilla-breeze-core.js +62 -62
  179. package/dist/cdn/vanilla-breeze-dev.css +1 -1
  180. package/dist/cdn/vanilla-breeze-extras.js +19 -19
  181. package/dist/cdn/vanilla-breeze-labs.css +1 -1
  182. package/dist/cdn/vanilla-breeze.css +1 -1
  183. package/dist/cdn/vanilla-breeze.js +170 -170
  184. package/package.json +5 -8
  185. package/dist/cdn/components/accessibility-specimen.js +0 -11
  186. package/dist/cdn/components/adr-wc.js +0 -403
  187. package/dist/cdn/components/breakpoint-specimen.js +0 -26
  188. package/dist/cdn/components/burndown-chart.js +0 -2
  189. package/dist/cdn/components/capacity-plan.js +0 -25
  190. package/dist/cdn/components/color-palette.js +0 -16
  191. package/dist/cdn/components/component-sampler.js +0 -45
  192. package/dist/cdn/components/empathy-map.js +0 -582
  193. package/dist/cdn/components/font-pairer.js +0 -108
  194. package/dist/cdn/components/gantt-chart.js +0 -2
  195. package/dist/cdn/components/gradient-builder.js +0 -52
  196. package/dist/cdn/components/impact-effort.js +0 -2
  197. package/dist/cdn/components/iron-triangle.js +0 -2
  198. package/dist/cdn/components/kanban-board.js +0 -2
  199. package/dist/cdn/components/layout-specimen.js +0 -35
  200. package/dist/cdn/components/motion-specimen.js +0 -21
  201. package/dist/cdn/components/palette-generator.js +0 -15
  202. package/dist/cdn/components/product-roadmap.js +0 -3
  203. package/dist/cdn/components/quadrant-grid.js +0 -3
  204. package/dist/cdn/components/quality-target.js +0 -12
  205. package/dist/cdn/components/requirement-card.js +0 -122
  206. package/dist/cdn/components/review-surface.js +0 -535
  207. package/dist/cdn/components/risk-register.js +0 -25
  208. package/dist/cdn/components/semantic-palette.js +0 -30
  209. package/dist/cdn/components/spacing-specimen.js +0 -6
  210. package/dist/cdn/components/story-map.js +0 -2
  211. package/dist/cdn/components/theme-catalog.js +0 -28
  212. package/dist/cdn/components/theme-export.js +0 -26
  213. package/dist/cdn/components/theme-import.js +0 -44
  214. package/dist/cdn/components/token-specimen.js +0 -26
  215. package/dist/cdn/components/traceability-matrix.js +0 -3
  216. package/dist/cdn/components/type-specimen.js +0 -19
  217. package/dist/cdn/components/user-journey.js +0 -366
  218. package/dist/cdn/components/user-persona.js +0 -402
  219. package/dist/cdn/components/user-story.js +0 -411
  220. package/dist/cdn/components/work-item.js +0 -447
  221. package/dist/cdn/packs/design-system.full.css +0 -2
  222. package/dist/cdn/packs/design-system.full.js +0 -175
  223. package/dist/cdn/packs/ux-planning.full.css +0 -2
  224. package/dist/cdn/packs/ux-planning.full.js +0 -3160
@@ -1,535 +0,0 @@
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: var(--color-error-text, var(--color-error, #dc2626));
186
- }
187
-
188
- .rs-popover__btn--delete:hover {
189
- background: color-mix(in oklch, var(--color-error, #dc2626) 8%, var(--_card));
190
- color: var(--color-error-text, var(--color-error, #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: var(--color-text-inverted, #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: var(--color-text-inverted, #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: var(--color-text-inverted, #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: 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>
450
- <div class="rs-container">
451
- <slot></slot>
452
- <div class="rs-overlay" role="img" aria-label="Review annotation surface">
453
- ${t.map((s,o)=>this._renderPin(s,o+1)).join("")}
454
- </div>
455
- ${a?this._renderPopover(a,e):""}
456
- </div>
457
- ${e?this._renderToolbar(t.length):""}
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)}"
460
- ${e.resolved?"data-resolved":""}
461
- ${this._activePin===e.id?"data-active":""}
462
- style="left:${e.x}%;top:${e.y}%"
463
- aria-label="Pin ${t}: ${c(a)}"
464
- aria-expanded="${this._activePin===e.id}"
465
- aria-haspopup="dialog">
466
- <span class="rs-pin__number">${t}</span>
467
- </button>`}_renderPopover(e,t){let a=this.#s().findIndex(s=>s.id===e.id)+1;return`<div class="rs-popover" data-open
468
- style="left:${Math.min(e.x,70)}%;top:${e.y}%"
469
- role="dialog"
470
- aria-labelledby="rs-popover-title-${c(e.id)}">
471
-
472
- <div class="rs-popover__header">
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>`:""}
476
- </span>
477
- <div class="rs-popover__actions">
478
- ${t&&!e.resolved?`
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>`:""}
481
- ${t&&e.resolved?`
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>`:""}
484
- ${t?`
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>`:""}
487
- <button class="rs-popover__btn" data-action="close"
488
- aria-label="Close">${p(l.x)}</button>
489
- </div>
490
- </div>
491
-
492
- <div class="rs-comment">
493
- <div class="rs-comment__meta">
494
- <span class="rs-comment__avatar" style="background:${y(e.author||"Anonymous")}">${g(e.author||"Anonymous")}</span>
495
- <span class="rs-comment__author">${c(e.author||"Anonymous")}</span>
496
- <span class="rs-comment__time">${this.#i(e.createdAt)}</span>
497
- </div>
498
- <div class="rs-comment__text">${c(e.text)}</div>
499
- </div>
500
-
501
- ${e.replies?.length?`
502
- <div class="rs-replies">
503
- ${e.replies.map(s=>`
504
- <div class="rs-reply">
505
- <div class="rs-comment__meta">
506
- <span class="rs-comment__avatar" style="background:${y(s.author||"Anonymous")}">${g(s.author||"Anonymous")}</span>
507
- <span class="rs-comment__author">${c(s.author||"Anonymous")}</span>
508
- <span class="rs-comment__time">${this.#i(s.createdAt)}</span>
509
- </div>
510
- <div class="rs-comment__text">${c(s.text)}</div>
511
- </div>
512
- `).join("")}
513
- </div>`:""}
514
-
515
- ${t?`
516
- <div class="rs-input">
517
- <textarea class="rs-input__field" placeholder="Reply\u2026" rows="1"
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>
521
- </div>`:""}
522
-
523
- </div>`}_renderToolbar(e){return`<div class="rs-toolbar" role="toolbar" aria-label="Review tools">
524
- <button class="rs-toolbar__btn" data-action="toggle-mode"
525
- aria-pressed="${this._annotating}"
526
- title="Toggle annotate mode">
527
- ${p(l.mapPin)} Annotate
528
- </button>
529
- <button class="rs-toolbar__btn" data-action="export"
530
- title="Export pins as JSON">
531
- ${p(l.download)} Export
532
- </button>
533
- <output class="rs-toolbar__count">${e} pin${e!==1?"s":""}</output>
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};
535
- //# sourceMappingURL=review-surface.js.map
@@ -1,25 +0,0 @@
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