@profpowell/vb-project-planning 0.1.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 (106) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +93 -0
  3. package/dist/vb-project-planning.css +1603 -0
  4. package/dist/vb-project-planning.js +11138 -0
  5. package/dist/vb-project-planning.min.css +1 -0
  6. package/dist/vb-project-planning.min.js +3312 -0
  7. package/package.json +80 -0
  8. package/src/index.css +14 -0
  9. package/src/index.js +26 -0
  10. package/src/lib/bundle-registry.js +156 -0
  11. package/src/lib/diff-by-key.js +86 -0
  12. package/src/lib/portrait-url.js +87 -0
  13. package/src/lib/vb-collection.js +122 -0
  14. package/src/lib/vb-element.js +96 -0
  15. package/src/lib/vb-store.js +200 -0
  16. package/src/lib/vb-view-transition.js +44 -0
  17. package/src/utils/copy-init.js +287 -0
  18. package/src/web-components/_ux-base.js +106 -0
  19. package/src/web-components/adr-wc/README.md +77 -0
  20. package/src/web-components/adr-wc/api.json +26 -0
  21. package/src/web-components/adr-wc/logic.js +376 -0
  22. package/src/web-components/adr-wc/static.html +17 -0
  23. package/src/web-components/adr-wc/styles.js +338 -0
  24. package/src/web-components/burndown-chart/api.json +74 -0
  25. package/src/web-components/burndown-chart/logic.js +198 -0
  26. package/src/web-components/burndown-chart/static.html +31 -0
  27. package/src/web-components/burndown-chart/styles.css +59 -0
  28. package/src/web-components/capacity-plan/_capacity-utils.js +56 -0
  29. package/src/web-components/capacity-plan/api.json +20 -0
  30. package/src/web-components/capacity-plan/logic.js +222 -0
  31. package/src/web-components/capacity-plan/static.html +24 -0
  32. package/src/web-components/capacity-plan/styles.css +84 -0
  33. package/src/web-components/empathy-map/api.json +31 -0
  34. package/src/web-components/empathy-map/logic.js +502 -0
  35. package/src/web-components/empathy-map/static.html +32 -0
  36. package/src/web-components/empathy-map/styles.js +534 -0
  37. package/src/web-components/gantt-chart/README.md +91 -0
  38. package/src/web-components/gantt-chart/api.json +20 -0
  39. package/src/web-components/gantt-chart/logic.js +812 -0
  40. package/src/web-components/gantt-chart/static.html +60 -0
  41. package/src/web-components/gantt-chart/styles.css +391 -0
  42. package/src/web-components/impact-effort/api.json +21 -0
  43. package/src/web-components/impact-effort/logic.js +392 -0
  44. package/src/web-components/impact-effort/static.html +23 -0
  45. package/src/web-components/impact-effort/styles.css +193 -0
  46. package/src/web-components/iron-triangle/_capacity.js +83 -0
  47. package/src/web-components/iron-triangle/_triangle-geometry.js +322 -0
  48. package/src/web-components/iron-triangle/api.json +26 -0
  49. package/src/web-components/iron-triangle/logic.js +474 -0
  50. package/src/web-components/iron-triangle/static.html +28 -0
  51. package/src/web-components/iron-triangle/styles.css +158 -0
  52. package/src/web-components/kanban-board/api.json +24 -0
  53. package/src/web-components/kanban-board/logic.js +698 -0
  54. package/src/web-components/kanban-board/static.html +20 -0
  55. package/src/web-components/kanban-board/styles.css +242 -0
  56. package/src/web-components/product-roadmap/api.json +118 -0
  57. package/src/web-components/product-roadmap/logic.js +460 -0
  58. package/src/web-components/product-roadmap/static.html +44 -0
  59. package/src/web-components/product-roadmap/styles.css +158 -0
  60. package/src/web-components/quadrant-grid/api.json +125 -0
  61. package/src/web-components/quadrant-grid/logic.js +397 -0
  62. package/src/web-components/quadrant-grid/static.html +49 -0
  63. package/src/web-components/quadrant-grid/styles.css +184 -0
  64. package/src/web-components/quality-target/_quality-utils.js +460 -0
  65. package/src/web-components/quality-target/api.json +30 -0
  66. package/src/web-components/quality-target/logic.js +516 -0
  67. package/src/web-components/quality-target/static.html +22 -0
  68. package/src/web-components/quality-target/styles.css +203 -0
  69. package/src/web-components/requirement-card/api.json +25 -0
  70. package/src/web-components/requirement-card/logic.js +166 -0
  71. package/src/web-components/requirement-card/static.html +36 -0
  72. package/src/web-components/requirement-card/styles.js +114 -0
  73. package/src/web-components/review-surface/README.md +178 -0
  74. package/src/web-components/review-surface/api.json +30 -0
  75. package/src/web-components/review-surface/logic.js +807 -0
  76. package/src/web-components/review-surface/static.html +33 -0
  77. package/src/web-components/review-surface/styles.js +459 -0
  78. package/src/web-components/risk-register/api.json +47 -0
  79. package/src/web-components/risk-register/logic.js +180 -0
  80. package/src/web-components/risk-register/static.html +46 -0
  81. package/src/web-components/risk-register/styles.css +37 -0
  82. package/src/web-components/story-map/api.json +22 -0
  83. package/src/web-components/story-map/logic.js +445 -0
  84. package/src/web-components/story-map/static.html +35 -0
  85. package/src/web-components/story-map/styles.css +169 -0
  86. package/src/web-components/traceability-matrix/api.json +84 -0
  87. package/src/web-components/traceability-matrix/logic.js +243 -0
  88. package/src/web-components/traceability-matrix/static.html +41 -0
  89. package/src/web-components/traceability-matrix/styles.css +94 -0
  90. package/src/web-components/user-journey/api.json +84 -0
  91. package/src/web-components/user-journey/logic.js +368 -0
  92. package/src/web-components/user-journey/static.html +14 -0
  93. package/src/web-components/user-journey/styles.js +317 -0
  94. package/src/web-components/user-persona/api.json +35 -0
  95. package/src/web-components/user-persona/logic.js +502 -0
  96. package/src/web-components/user-persona/static.html +20 -0
  97. package/src/web-components/user-persona/styles.js +299 -0
  98. package/src/web-components/user-story/api.json +35 -0
  99. package/src/web-components/user-story/logic.js +567 -0
  100. package/src/web-components/user-story/static.html +27 -0
  101. package/src/web-components/user-story/styles.js +332 -0
  102. package/src/web-components/work-item/README.md +85 -0
  103. package/src/web-components/work-item/api.json +30 -0
  104. package/src/web-components/work-item/logic.js +414 -0
  105. package/src/web-components/work-item/static.html +24 -0
  106. package/src/web-components/work-item/styles.js +376 -0
@@ -0,0 +1,299 @@
1
+ const styles = `
2
+ :host {
3
+ display: block;
4
+ font-family: var(--user-persona-font, var(--font-sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif));
5
+ --_bg: var(--user-persona-bg, var(--color-surface, #ffffff));
6
+ --_text: var(--user-persona-text, var(--color-text, #1a1a1a));
7
+ --_border: var(--user-persona-border, var(--color-border, #e0e0e0));
8
+ --_muted: var(--user-persona-muted, var(--color-text-muted, #666));
9
+ --_accent: var(--user-persona-accent, var(--color-interactive, #0066cc));
10
+ --_card-bg: var(--user-persona-card-bg, var(--color-surface-raised, #f8f9fa));
11
+ --_radius: var(--user-persona-radius, var(--radius-xl, 1rem));
12
+ --_avatar-size: var(--user-persona-avatar-size, 80px);
13
+ --_goals: var(--user-persona-goals, #22c55e);
14
+ --_frustrations: var(--user-persona-frustrations, #ef4444);
15
+ --_behaviors: var(--user-persona-behaviors, #8b5cf6);
16
+ --_stories: var(--user-persona-stories, #3b82f6);
17
+ --_shadow: var(--user-persona-shadow, var(--shadow-md));
18
+ --_space-2xs: var(--user-persona-space-2xs, var(--size-2xs, 0.25rem));
19
+ --_space-xs: var(--user-persona-space-xs, var(--size-xs, 0.5rem));
20
+ --_space-s: var(--user-persona-space-s, var(--size-s, 0.75rem));
21
+ --_space-m: var(--user-persona-space-m, var(--size-m, 1rem));
22
+ --_space-l: var(--user-persona-space-l, var(--size-l, 1.5rem));
23
+ --_font-xs: var(--user-persona-font-xs, var(--font-size-xs, 0.75rem));
24
+ --_font-sm: var(--user-persona-font-sm, var(--font-size-sm, 0.875rem));
25
+ --_font-md: var(--user-persona-font-md, var(--font-size-md, 1rem));
26
+ --_font-2xl: var(--user-persona-font-2xl, var(--font-size-2xl, 1.5rem));
27
+ --_radius-m: var(--user-persona-radius-m, var(--radius-m, 0.5rem));
28
+ --_radius-l: var(--user-persona-radius-l, var(--radius-l, 0.75rem));
29
+ }
30
+
31
+ .persona-card {
32
+ background: var(--_bg);
33
+ border: 1px solid var(--_border);
34
+ border-radius: var(--_radius);
35
+ overflow: hidden;
36
+ box-shadow: var(--_shadow);
37
+ }
38
+
39
+ .persona-header {
40
+ display: flex;
41
+ align-items: center;
42
+ gap: var(--_space-l);
43
+ padding: var(--_space-l);
44
+ background: var(--_card-bg);
45
+ border-bottom: 1px solid var(--_border);
46
+ }
47
+
48
+ :host([compact]) .persona-header {
49
+ padding: var(--_space-m);
50
+ gap: var(--_space-m);
51
+ }
52
+
53
+ .avatar {
54
+ width: var(--_avatar-size);
55
+ height: var(--_avatar-size);
56
+ border-radius: 50%;
57
+ display: flex;
58
+ align-items: center;
59
+ justify-content: center;
60
+ font-size: 28px;
61
+ font-weight: 600;
62
+ color: white;
63
+ flex-shrink: 0;
64
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
65
+ }
66
+
67
+ :host([compact]) .avatar {
68
+ width: 56px;
69
+ height: 56px;
70
+ font-size: 20px;
71
+ }
72
+
73
+ .header-info {
74
+ flex: 1;
75
+ min-width: 0;
76
+ }
77
+
78
+ .persona-name {
79
+ font-size: var(--_font-2xl);
80
+ font-weight: 700;
81
+ color: var(--_text);
82
+ margin: 0 0 var(--_space-2xs) 0;
83
+ }
84
+
85
+ :host([compact]) .persona-name {
86
+ font-size: 18px;
87
+ }
88
+
89
+ .persona-role {
90
+ font-size: var(--_font-md);
91
+ color: var(--_accent);
92
+ font-weight: 500;
93
+ margin: 0;
94
+ }
95
+
96
+ :host([compact]) .persona-role {
97
+ font-size: var(--_font-sm);
98
+ }
99
+
100
+ .persona-meta {
101
+ display: flex;
102
+ gap: var(--_space-m);
103
+ margin-top: var(--_space-xs);
104
+ flex-wrap: wrap;
105
+ }
106
+
107
+ .meta-item {
108
+ display: flex;
109
+ align-items: center;
110
+ gap: 6px;
111
+ font-size: 13px;
112
+ color: var(--_muted);
113
+ }
114
+
115
+ .meta-item svg {
116
+ width: 14px;
117
+ height: 14px;
118
+ fill: currentColor;
119
+ opacity: 0.7;
120
+ }
121
+
122
+ .persona-quote {
123
+ padding: 20px var(--_space-l);
124
+ background: var(--_card-bg);
125
+ border-bottom: 1px solid var(--_border);
126
+ position: relative;
127
+ }
128
+
129
+ :host([compact]) .persona-quote {
130
+ padding: var(--_space-m);
131
+ }
132
+
133
+ .quote-mark {
134
+ position: absolute;
135
+ top: 12px;
136
+ left: 16px;
137
+ font-size: 48px;
138
+ line-height: 1;
139
+ color: var(--_accent);
140
+ opacity: 0.2;
141
+ font-family: Georgia, serif;
142
+ }
143
+
144
+ .quote-text {
145
+ font-size: var(--_font-md);
146
+ font-style: italic;
147
+ color: var(--_text);
148
+ line-height: 1.6;
149
+ margin: 0;
150
+ padding-left: var(--_space-l);
151
+ }
152
+
153
+ :host([compact]) .quote-text {
154
+ font-size: var(--_font-sm);
155
+ }
156
+
157
+ .persona-body {
158
+ padding: var(--_space-l);
159
+ display: grid;
160
+ grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
161
+ gap: var(--_space-l);
162
+ }
163
+
164
+ :host([compact]) .persona-body {
165
+ padding: var(--_space-m);
166
+ gap: var(--_space-m);
167
+ }
168
+
169
+ .section {
170
+ background: var(--_card-bg);
171
+ border-radius: var(--_radius-l);
172
+ padding: var(--_space-m);
173
+ }
174
+
175
+ .section-header {
176
+ display: flex;
177
+ align-items: center;
178
+ gap: var(--_space-xs);
179
+ margin-bottom: var(--_space-s);
180
+ }
181
+
182
+ .section-icon {
183
+ width: 28px;
184
+ height: 28px;
185
+ border-radius: var(--_radius-m);
186
+ display: flex;
187
+ align-items: center;
188
+ justify-content: center;
189
+ }
190
+
191
+ .section-icon svg {
192
+ width: 16px;
193
+ height: 16px;
194
+ fill: white;
195
+ }
196
+
197
+ .section-icon.bio { background: var(--_accent); }
198
+ .section-icon.goals { background: var(--_goals); }
199
+ .section-icon.frustrations { background: var(--_frustrations); }
200
+ .section-icon.behaviors { background: var(--_behaviors); }
201
+ .section-icon.stories { background: var(--_stories); }
202
+
203
+ /* Stories section — auto-rendered list of related <user-story> elements */
204
+ .section-count {
205
+ margin-inline-start: var(--_space-2xs);
206
+ padding: 0.05em 0.5ch;
207
+ border-radius: 999px;
208
+ background: var(--color-surface-raised, oklch(95% 0 0));
209
+ color: var(--color-text-muted);
210
+ font-size: 0.75em;
211
+ font-weight: 600;
212
+ }
213
+ .story-list {
214
+ list-style: none;
215
+ margin: 0;
216
+ padding: 0;
217
+ display: grid;
218
+ gap: var(--_space-2xs);
219
+ }
220
+ .story-item {
221
+ display: flex;
222
+ align-items: center;
223
+ gap: var(--_space-s);
224
+ padding-block: var(--_space-2xs);
225
+ border-block-end: 1px solid var(--color-border-muted, var(--color-border, #e5e7eb));
226
+ }
227
+ .story-item:last-child { border-block-end: none; }
228
+ .story-item a {
229
+ color: var(--color-interactive, currentColor);
230
+ text-decoration: none;
231
+ flex: 1;
232
+ }
233
+ .story-item a:hover { text-decoration: underline; }
234
+ .story-meta {
235
+ font-size: var(--_font-xs);
236
+ color: var(--color-text-muted);
237
+ text-transform: uppercase;
238
+ letter-spacing: 0.05em;
239
+ padding: 0 0.5ch;
240
+ border: 1px solid var(--color-border-muted, var(--color-border, #e5e7eb));
241
+ border-radius: var(--_radius-m);
242
+ }
243
+ .empty-stories {
244
+ margin: 0;
245
+ color: var(--color-text-muted);
246
+ font-style: italic;
247
+ }
248
+
249
+ .section-title {
250
+ font-size: var(--_font-sm);
251
+ font-weight: 600;
252
+ color: var(--_text);
253
+ text-transform: uppercase;
254
+ letter-spacing: 0.5px;
255
+ }
256
+
257
+ .section-content {
258
+ color: var(--_text);
259
+ font-size: var(--_font-sm);
260
+ line-height: 1.6;
261
+ }
262
+
263
+ .section-content ::slotted(ul),
264
+ .section-content ::slotted(ol) {
265
+ margin: 0;
266
+ padding-left: 20px;
267
+ }
268
+
269
+ .section-content ::slotted(li) {
270
+ margin-bottom: var(--_space-xs);
271
+ }
272
+
273
+ .section-content ::slotted(p) {
274
+ margin: 0;
275
+ }
276
+
277
+ @media (max-width: 600px) {
278
+ .persona-header {
279
+ flex-direction: column;
280
+ text-align: center;
281
+ }
282
+
283
+ .persona-meta {
284
+ justify-content: center;
285
+ }
286
+
287
+ .persona-body {
288
+ grid-template-columns: 1fr;
289
+ }
290
+ }
291
+
292
+ @media (prefers-reduced-motion: reduce) {
293
+ * {
294
+ transition: none !important;
295
+ }
296
+ }
297
+ `;
298
+
299
+ export { styles };
@@ -0,0 +1,35 @@
1
+ {
2
+ "$schema": "../../../schemas/api.schema.json",
3
+ "element": "user-story",
4
+ "type": "web-component",
5
+ "description": "Agile user story card — 'As a [persona], I want [action] so that [benefit]' with slotted content and state attributes",
6
+ "htmlvalidate": {
7
+ "flow": true,
8
+ "permittedContent": ["@flow"]
9
+ },
10
+ "attributes": [
11
+ { "name": "persona-id", "kind": "host-api", "purpose": "config", "type": "string", "description": "Links to a user-persona element by id" },
12
+ { "name": "priority", "kind": "host-api", "purpose": "config", "type": "enum", "values": ["critical", "high", "medium", "low"], "description": "Story priority level" },
13
+ { "name": "status", "kind": "host-api", "purpose": "config", "type": "enum", "values": ["backlog", "to-do", "in-progress", "review", "done"], "description": "Workflow status" },
14
+ { "name": "points", "kind": "host-api", "purpose": "config", "type": "string", "description": "Story point estimate" },
15
+ { "name": "epic", "kind": "host-api", "purpose": "config", "type": "string", "description": "Parent epic label" },
16
+ { "name": "story-id", "kind": "host-api", "purpose": "config", "type": "string", "description": "Ticket or story identifier, auto-sets HTML id" },
17
+ { "name": "detail", "kind": "host-api", "purpose": "config", "type": "enum", "values": ["full", "compact", "minimal"], "description": "Detail level" },
18
+ { "name": "compact", "kind": "host-api", "purpose": "config", "type": "boolean", "description": "Alias for detail=compact" },
19
+ { "name": "src", "kind": "host-api", "purpose": "config", "type": "string", "description": "URL to JSON data" }
20
+ ],
21
+ "slots": [
22
+ { "name": "persona", "description": "The 'As a...' role (e.g., <span>)" },
23
+ { "name": "action", "description": "The 'I want...' description (e.g., <span>)" },
24
+ { "name": "benefit", "description": "The 'so that...' outcome (e.g., <span>)" },
25
+ { "name": "title", "description": "Short label for minimal mode (e.g., <h3>)" },
26
+ { "name": "acceptance-criteria", "description": "Acceptance criteria checklist (e.g., <ul>)" },
27
+ { "name": "tasks", "description": "Implementation task list (e.g., <ul>)" },
28
+ { "name": "notes", "description": "Additional context (e.g., <p>)" }
29
+ ],
30
+ "events": [
31
+ { "name": "story-ready", "detail": "{ id, persona, action, benefit, priority, status, points }", "description": "Fired after render" },
32
+ { "name": "status-changed", "detail": "{ status, storyId }", "description": "Fired when updateStatus() is called" },
33
+ { "name": "priority-changed", "detail": "{ priority, storyId }", "description": "Fired when updatePriority() is called" }
34
+ ]
35
+ }