@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,1603 @@
1
+ /* src/web-components/impact-effort/styles.css */
2
+ impact-effort {
3
+ display: block;
4
+ container-type: inline-size;
5
+ }
6
+ impact-effort:not(:defined) {
7
+ display: block;
8
+ }
9
+ .ie-wrapper {
10
+ display: flex;
11
+ align-items: stretch;
12
+ }
13
+ .ie-y-label {
14
+ writing-mode: vertical-rl;
15
+ transform: rotate(180deg);
16
+ font-size: 0.7rem;
17
+ font-weight: 600;
18
+ color: var(--color-text-muted, #666);
19
+ text-align: center;
20
+ padding: 0 var(--size-xs, 8px);
21
+ display: flex;
22
+ align-items: center;
23
+ justify-content: center;
24
+ user-select: none;
25
+ }
26
+ .ie-x-label {
27
+ font-size: 0.7rem;
28
+ font-weight: 600;
29
+ color: var(--color-text-muted, #666);
30
+ text-align: center;
31
+ padding: var(--size-xs, 8px) 0;
32
+ user-select: none;
33
+ }
34
+ .ie-grid {
35
+ grid-template-columns: 1fr 1fr;
36
+ grid-template-rows: 1fr 1fr;
37
+ gap: 1px;
38
+ background: var(--color-border, #e0e0e0);
39
+ border: 1px solid var(--color-border, #e0e0e0);
40
+ border-radius: var(--radius-l, 0.75rem);
41
+ overflow: hidden;
42
+ min-height: 24rem;
43
+ display: grid;
44
+ flex: 1;
45
+ }
46
+ .ie-quadrant {
47
+ background: var(--color-surface, #fff);
48
+ padding: var(--size-m, 16px);
49
+ display: flex;
50
+ flex-direction: column;
51
+ gap: var(--size-xs, 8px);
52
+ }
53
+ .ie-quadrant-label {
54
+ font-size: 0.75rem;
55
+ font-weight: 700;
56
+ text-transform: uppercase;
57
+ letter-spacing: 0.05em;
58
+ color: var(--color-text-muted, #666);
59
+ margin-bottom: var(--size-xs, 8px);
60
+ }
61
+ .ie-quadrant-desc {
62
+ font-size: 0.65rem;
63
+ font-weight: 400;
64
+ text-transform: none;
65
+ letter-spacing: normal;
66
+ color: var(--color-text-muted, #999);
67
+ display: block;
68
+ }
69
+ [data-quadrant-zone=quick-wins] {
70
+ background: color-mix(in oklch, var(--color-success, #22c55e) 6%, var(--color-surface, #fff));
71
+ }
72
+ [data-quadrant-zone=big-bets] {
73
+ background: color-mix(in oklch, var(--color-warning, #f59e0b) 6%, var(--color-surface, #fff));
74
+ }
75
+ [data-quadrant-zone=fill-ins] {
76
+ background: color-mix(in oklch, var(--color-info, #3b82f6) 6%, var(--color-surface, #fff));
77
+ }
78
+ [data-quadrant-zone=money-pit] {
79
+ background: color-mix(in oklch, var(--color-error, #ef4444) 6%, var(--color-surface, #fff));
80
+ }
81
+ impact-effort drag-surface {
82
+ min-block-size: 6rem;
83
+ flex: 1;
84
+ }
85
+ .ie-live-region {
86
+ position: absolute;
87
+ width: 1px;
88
+ height: 1px;
89
+ overflow: hidden;
90
+ clip: rect(0, 0, 0, 0);
91
+ white-space: nowrap;
92
+ border: 0;
93
+ padding: 0;
94
+ margin: -1px;
95
+ }
96
+ impact-effort[compact] .ie-grid {
97
+ min-height: 16rem;
98
+ }
99
+ impact-effort[compact] .ie-quadrant {
100
+ padding: var(--size-xs, 8px);
101
+ gap: var(--size-2xs, 4px);
102
+ }
103
+ impact-effort[compact] .ie-quadrant-label {
104
+ font-size: 0.65rem;
105
+ margin-bottom: var(--size-2xs, 4px);
106
+ }
107
+ impact-effort[compact] .ie-quadrant-desc {
108
+ font-size: 0.6rem;
109
+ }
110
+ impact-effort[compact] drag-surface {
111
+ min-block-size: 4rem;
112
+ }
113
+ impact-effort[compact] .ie-y-label,
114
+ impact-effort[compact] .ie-x-label {
115
+ font-size: 0.6rem;
116
+ }
117
+ @container (max-width: 30rem) {
118
+ .ie-grid {
119
+ grid-template-columns: 1fr;
120
+ grid-template-rows: auto;
121
+ }
122
+ }
123
+ @media (prefers-reduced-motion: reduce) {
124
+ impact-effort,
125
+ impact-effort * {
126
+ transition: none;
127
+ }
128
+ }
129
+ @media print {
130
+ .ie-grid {
131
+ border: 1px solid #ccc;
132
+ gap: 0;
133
+ min-height: auto;
134
+ }
135
+ .ie-quadrant {
136
+ border: 0.5pt solid #ccc;
137
+ break-inside: avoid;
138
+ }
139
+ impact-effort drag-surface {
140
+ min-block-size: auto;
141
+ }
142
+ impact-effort [draggable] {
143
+ cursor: default;
144
+ }
145
+ }
146
+
147
+ /* src/web-components/quadrant-grid/styles.css */
148
+ quadrant-grid:not(:defined) {
149
+ display: block;
150
+ }
151
+ quadrant-grid {
152
+ display: block;
153
+ font-family: var(--font-sans, system-ui);
154
+ color: var(--color-text, #1a1a1a);
155
+ }
156
+ @scope (quadrant-grid) {
157
+ .qg-wrapper {
158
+ display: grid;
159
+ grid-template-columns: max-content max-content 1fr;
160
+ grid-template-rows: max-content 1fr max-content max-content;
161
+ grid-template-areas: "y-label . ." "y-scale grid grid" ". x-scale x-scale" ". x-label x-label";
162
+ gap: var(--size-2xs, 0.25rem);
163
+ margin: 0;
164
+ }
165
+ .qg-y-label {
166
+ grid-area: y-label;
167
+ font-size: var(--font-size-xs, 0.75rem);
168
+ font-weight: 700;
169
+ text-transform: uppercase;
170
+ letter-spacing: 0.06em;
171
+ color: var(--color-text-muted, #666);
172
+ text-align: start;
173
+ padding-inline-end: var(--size-xs, 0.5rem);
174
+ }
175
+ .qg-x-label {
176
+ grid-area: x-label;
177
+ font-size: var(--font-size-xs, 0.75rem);
178
+ font-weight: 700;
179
+ text-transform: uppercase;
180
+ letter-spacing: 0.06em;
181
+ color: var(--color-text-muted, #666);
182
+ text-align: end;
183
+ }
184
+ .qg-y-scale {
185
+ grid-area: y-scale;
186
+ display: flex;
187
+ flex-direction: column;
188
+ justify-content: space-between;
189
+ padding-block: var(--size-2xs, 0.25rem);
190
+ font-family: var(--font-mono, ui-monospace, monospace);
191
+ font-size: var(--font-size-xs, 0.75rem);
192
+ color: var(--color-text-muted, #666);
193
+ text-align: end;
194
+ padding-inline-end: var(--size-xs, 0.5rem);
195
+ min-inline-size: 3rem;
196
+ }
197
+ .qg-x-scale {
198
+ grid-area: x-scale;
199
+ display: flex;
200
+ justify-content: space-between;
201
+ font-family: var(--font-mono, ui-monospace, monospace);
202
+ font-size: var(--font-size-xs, 0.75rem);
203
+ color: var(--color-text-muted, #666);
204
+ padding-block-start: var(--size-2xs, 0.25rem);
205
+ }
206
+ .qg-grid {
207
+ grid-area: grid;
208
+ display: grid;
209
+ grid-template-columns: 1fr 1fr;
210
+ grid-template-rows: 1fr 1fr;
211
+ gap: var(--size-2xs, 0.25rem);
212
+ min-block-size: var(--qg-min-size, 24rem);
213
+ background: var(--color-border, oklch(85% 0 0));
214
+ padding: 1px;
215
+ border-radius: var(--radius-m, 0.5rem);
216
+ }
217
+ .qg-quadrant {
218
+ position: relative;
219
+ background: var(--color-surface, #fff);
220
+ padding: var(--size-s, 0.75rem);
221
+ display: flex;
222
+ flex-direction: column;
223
+ gap: var(--size-xs, 0.5rem);
224
+ overflow: hidden;
225
+ }
226
+ .qg-quadrant[data-quadrant-zone="0"] {
227
+ grid-row: 1;
228
+ grid-column: 2;
229
+ border-radius: 0 var(--radius-m, 0.5rem) 0 0;
230
+ }
231
+ .qg-quadrant[data-quadrant-zone="1"] {
232
+ grid-row: 1;
233
+ grid-column: 1;
234
+ border-radius: var(--radius-m, 0.5rem) 0 0 0;
235
+ }
236
+ .qg-quadrant[data-quadrant-zone="2"] {
237
+ grid-row: 2;
238
+ grid-column: 1;
239
+ border-radius: 0 0 0 var(--radius-m, 0.5rem);
240
+ }
241
+ .qg-quadrant[data-quadrant-zone="3"] {
242
+ grid-row: 2;
243
+ grid-column: 2;
244
+ border-radius: 0 0 var(--radius-m, 0.5rem) 0;
245
+ }
246
+ .qg-quadrant-label {
247
+ font-size: var(--font-size-xs, 0.75rem);
248
+ font-weight: 700;
249
+ text-transform: uppercase;
250
+ letter-spacing: 0.06em;
251
+ color: var(--color-text-muted, #666);
252
+ margin: 0;
253
+ }
254
+ .qg-items {
255
+ list-style: none;
256
+ margin: 0;
257
+ padding: 0;
258
+ display: flex;
259
+ flex-direction: column;
260
+ gap: var(--size-2xs, 0.25rem);
261
+ }
262
+ .qg-items > li {
263
+ background: var(--color-surface-raised, oklch(96% 0 0));
264
+ padding: var(--size-2xs, 0.25rem) var(--size-xs, 0.5rem);
265
+ border-radius: var(--radius-s, 0.25rem);
266
+ font-size: var(--font-size-sm, 0.875rem);
267
+ }
268
+ .qg-pinned {
269
+ position: absolute;
270
+ inline-size: max-content;
271
+ max-inline-size: calc(100% - var(--size-xs, 0.5rem));
272
+ padding: var(--size-3xs, 0.125rem) var(--size-xs, 0.5rem);
273
+ background: var(--color-accent, oklch(45% 0.18 260));
274
+ color: var(--color-text-on-primary, #fff);
275
+ border-radius: var(--radius-s, 0.25rem);
276
+ font-size: var(--font-size-xs, 0.75rem);
277
+ inset-inline-start: clamp(var(--qg-pin-half-w, 1.5rem), calc(var(--qg-local-x, 0.5) * 100%), calc(100% - var(--qg-pin-half-w, 1.5rem)));
278
+ inset-block-end: clamp(var(--qg-pin-half-h, 0.75rem), calc(var(--qg-local-y, 0.5) * 100%), calc(100% - var(--qg-pin-half-h, 0.75rem)));
279
+ transform: translate(calc(-50% + var(--qg-fan-x, 0px)), calc(50% + var(--qg-fan-y, 0px)));
280
+ box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
281
+ filter: hue-rotate(var(--qg-pin-hue, 0deg));
282
+ transition:
283
+ transform 180ms ease,
284
+ box-shadow 180ms ease,
285
+ z-index 0s;
286
+ }
287
+ .qg-quadrant:hover .qg-pinned.qg-clustered,
288
+ .qg-quadrant:focus-within .qg-pinned.qg-clustered {
289
+ --qg-fan-angle: calc((var(--qg-cluster-i, 0) / var(--qg-cluster-n, 1)) * 360deg);
290
+ --qg-fan-radius: calc(var(--qg-pin-half-w, 1.5rem) * 1.4);
291
+ --qg-fan-x: calc(cos(var(--qg-fan-angle)) * var(--qg-fan-radius));
292
+ --qg-fan-y: calc(sin(var(--qg-fan-angle)) * var(--qg-fan-radius) * -1);
293
+ }
294
+ .qg-pinned.qg-clustered:hover,
295
+ .qg-pinned.qg-clustered:focus-visible {
296
+ z-index: 2;
297
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.25);
298
+ }
299
+ }
300
+ @media (prefers-reduced-motion: reduce) {
301
+ quadrant-grid * {
302
+ transition: none !important;
303
+ }
304
+ }
305
+ @media print {
306
+ quadrant-grid .qg-y-label,
307
+ quadrant-grid .qg-x-label,
308
+ quadrant-grid .qg-y-scale,
309
+ quadrant-grid .qg-x-scale {
310
+ color: #000;
311
+ }
312
+ }
313
+
314
+ /* src/web-components/risk-register/styles.css */
315
+ risk-register:not(:defined) {
316
+ display: block;
317
+ }
318
+ risk-register {
319
+ display: block;
320
+ font-family: var(--font-sans, system-ui);
321
+ color: var(--color-text, #1a1a1a);
322
+ }
323
+ @scope (risk-register) {
324
+ .rr-label {
325
+ display: block;
326
+ font-size: var(--font-size-xs, 0.75rem);
327
+ font-weight: 700;
328
+ text-transform: uppercase;
329
+ letter-spacing: 0.06em;
330
+ color: var(--color-text-muted, #666);
331
+ margin-block-end: var(--size-s, 0.75rem);
332
+ }
333
+ .rr-layout {
334
+ display: grid;
335
+ grid-template-columns: 1fr;
336
+ gap: var(--size-l, 1.5rem);
337
+ }
338
+ @media (width >= 64rem) {
339
+ .rr-layout {
340
+ grid-template-columns: minmax(0, 1.4fr) minmax(0, 1fr);
341
+ align-items: start;
342
+ }
343
+ }
344
+ }
345
+
346
+ /* src/web-components/traceability-matrix/styles.css */
347
+ traceability-matrix:not(:defined) {
348
+ display: block;
349
+ }
350
+ traceability-matrix {
351
+ display: block;
352
+ font-family: var(--font-sans, system-ui);
353
+ color: var(--color-text, #1a1a1a);
354
+ }
355
+ @scope (traceability-matrix) {
356
+ .tm-label {
357
+ display: block;
358
+ font-size: var(--font-size-xs, 0.75rem);
359
+ font-weight: 700;
360
+ text-transform: uppercase;
361
+ letter-spacing: 0.06em;
362
+ color: var(--color-text-muted, #666);
363
+ margin-block-end: var(--size-s, 0.75rem);
364
+ }
365
+ .tm-empty {
366
+ color: var(--color-text-muted, #666);
367
+ font-style: italic;
368
+ }
369
+ td[data-linked] {
370
+ background: oklch(94% 0.05 145 / 0.55);
371
+ text-align: center;
372
+ font-weight: 600;
373
+ color: var(--color-accent, oklch(45% 0.18 260));
374
+ }
375
+ td:not([data-linked]) {
376
+ color: var(--color-text-muted, #666);
377
+ text-align: center;
378
+ }
379
+ th[scope=row] {
380
+ text-align: start;
381
+ font-weight: 600;
382
+ background: var(--color-surface-raised, oklch(96% 0 0));
383
+ white-space: nowrap;
384
+ }
385
+ tr[data-state-highlighted] {
386
+ outline: 2px solid var(--color-accent, oklch(45% 0.18 260));
387
+ outline-offset: -2px;
388
+ }
389
+ td[data-state-highlighted],
390
+ th[data-state-highlighted] {
391
+ background: oklch(85% 0.12 145 / 0.7);
392
+ }
393
+ tr[data-orphan] th[scope=row]::after,
394
+ th[data-orphan]::after {
395
+ content: " \26a0";
396
+ color: var(--color-warning, oklch(60% 0.15 60));
397
+ font-weight: 700;
398
+ }
399
+ td,
400
+ th {
401
+ padding: var(--size-2xs, 0.25rem) var(--size-s, 0.75rem);
402
+ border-block-end: var(--border-width-thin, 1px) solid var(--color-border, oklch(85% 0 0));
403
+ cursor: default;
404
+ }
405
+ td[data-linked] {
406
+ cursor: pointer;
407
+ }
408
+ }
409
+ [data-state-highlighted]:not(traceability-matrix *) {
410
+ outline: 2px solid var(--color-accent, oklch(45% 0.18 260));
411
+ outline-offset: 2px;
412
+ scroll-margin-block: var(--size-l, 1.5rem);
413
+ }
414
+ @media print {
415
+ traceability-matrix td[data-state-highlighted],
416
+ traceability-matrix tr[data-state-highlighted] {
417
+ outline: none;
418
+ background: none;
419
+ }
420
+ }
421
+
422
+ /* src/web-components/burndown-chart/styles.css */
423
+ burndown-chart:not(:defined) {
424
+ display: block;
425
+ }
426
+ burndown-chart {
427
+ display: block;
428
+ font-family: var(--font-sans, system-ui);
429
+ color: var(--color-text, #1a1a1a);
430
+ }
431
+ @scope (burndown-chart) {
432
+ .bdc-label {
433
+ display: block;
434
+ font-size: var(--font-size-xs, 0.75rem);
435
+ font-weight: 700;
436
+ text-transform: uppercase;
437
+ letter-spacing: 0.06em;
438
+ color: var(--color-text-muted, #666);
439
+ margin-block-end: var(--size-s, 0.75rem);
440
+ }
441
+ chart-wc {
442
+ display: block;
443
+ min-block-size: var(--burndown-min-height, 18rem);
444
+ }
445
+ .bdc-scope-changes {
446
+ margin-block-start: var(--size-m, 1rem);
447
+ padding: var(--size-s, 0.75rem) var(--size-m, 1rem);
448
+ background: var(--color-surface-raised, oklch(96% 0 0));
449
+ border-inline-start: var(--border-width-medium, 3px) solid var(--color-warning, oklch(70% 0.15 60));
450
+ border-radius: var(--radius-s, 0.25rem);
451
+ font-size: var(--font-size-sm, 0.875rem);
452
+ }
453
+ .bdc-scope-changes h4 {
454
+ margin: 0 0 var(--size-2xs, 0.25rem);
455
+ font-size: var(--font-size-xs, 0.75rem);
456
+ text-transform: uppercase;
457
+ letter-spacing: 0.06em;
458
+ color: var(--color-text-muted, #666);
459
+ }
460
+ .bdc-scope-changes ul {
461
+ margin: 0;
462
+ padding-inline-start: var(--size-m, 1rem);
463
+ }
464
+ .bdc-scope-changes li {
465
+ margin-block: var(--size-3xs, 0.125rem);
466
+ }
467
+ .bdc-scope-changes time {
468
+ font-family: var(--font-mono, ui-monospace, monospace);
469
+ color: var(--color-text-muted, #666);
470
+ }
471
+ }
472
+
473
+ /* src/web-components/product-roadmap/styles.css */
474
+ product-roadmap:not(:defined) {
475
+ display: block;
476
+ }
477
+ product-roadmap {
478
+ display: block;
479
+ font-family: var(--font-sans, system-ui);
480
+ color: var(--color-text, #1a1a1a);
481
+ }
482
+ product-roadmap > section[data-lane] {
483
+ display: none;
484
+ }
485
+ @scope (product-roadmap) {
486
+ .rm-wrapper {
487
+ display: grid;
488
+ grid-template-columns: minmax(8rem, max-content) 1fr;
489
+ gap: var(--size-2xs, 0.25rem);
490
+ }
491
+ .rm-axis {
492
+ grid-column: 2;
493
+ position: relative;
494
+ block-size: var(--size-l, 1.5rem);
495
+ border-block-end: var(--border-width-thin, 1px) solid var(--color-border, oklch(85% 0 0));
496
+ margin-block-end: var(--size-2xs, 0.25rem);
497
+ }
498
+ .rm-tick {
499
+ position: absolute;
500
+ inset-block: 0;
501
+ inset-inline-start: calc(var(--rm-x) * 100%);
502
+ inline-size: calc(var(--rm-w) * 100%);
503
+ border-inline-end: var(--border-width-thin, 1px) dashed var(--color-border, oklch(85% 0 0));
504
+ padding-inline: var(--size-2xs, 0.25rem);
505
+ font-size: var(--font-size-xs, 0.75rem);
506
+ font-weight: 600;
507
+ text-transform: uppercase;
508
+ letter-spacing: 0.06em;
509
+ color: var(--color-text-muted, #666);
510
+ overflow: hidden;
511
+ white-space: nowrap;
512
+ text-overflow: ellipsis;
513
+ }
514
+ .rm-lanes {
515
+ grid-column: 1 / -1;
516
+ display: grid;
517
+ grid-template-columns: subgrid;
518
+ gap: var(--size-2xs, 0.25rem);
519
+ position: relative;
520
+ }
521
+ .rm-lane {
522
+ display: contents;
523
+ }
524
+ .rm-lane-label {
525
+ grid-column: 1;
526
+ font-size: var(--font-size-sm, 0.875rem);
527
+ font-weight: 600;
528
+ color: var(--color-text, currentColor);
529
+ padding: var(--size-xs, 0.5rem) var(--size-s, 0.75rem);
530
+ background: var(--color-surface-raised, oklch(96% 0 0));
531
+ border-radius: var(--radius-s, 0.25rem);
532
+ align-self: stretch;
533
+ display: flex;
534
+ align-items: center;
535
+ }
536
+ .rm-track {
537
+ grid-column: 2;
538
+ position: relative;
539
+ min-block-size: var(--size-2xl, 3rem);
540
+ background:
541
+ repeating-linear-gradient(
542
+ to right,
543
+ var(--color-surface, transparent),
544
+ var(--color-surface, transparent) calc(var(--rm-tick-w, 25%) - 1px),
545
+ var(--color-border, oklch(85% 0 0 / 0.4)) calc(var(--rm-tick-w, 25%) - 1px),
546
+ var(--color-border, oklch(85% 0 0 / 0.4)) var(--rm-tick-w, 25%));
547
+ border-radius: var(--radius-s, 0.25rem);
548
+ }
549
+ .rm-bar {
550
+ position: absolute;
551
+ inset-block: var(--size-2xs, 0.25rem);
552
+ inset-inline-start: calc(var(--rm-x) * 100%);
553
+ inline-size: calc(var(--rm-w) * 100%);
554
+ background: var(--color-accent, oklch(45% 0.18 260));
555
+ color: var(--color-text-on-primary, #fff);
556
+ border-radius: var(--radius-s, 0.25rem);
557
+ padding: var(--size-2xs, 0.25rem) var(--size-s, 0.75rem);
558
+ font-size: var(--font-size-sm, 0.875rem);
559
+ line-height: 1.2;
560
+ overflow: hidden;
561
+ box-shadow: 0 1px 2px rgba(0, 0, 0, 0.15);
562
+ cursor: grab;
563
+ user-select: none;
564
+ display: flex;
565
+ align-items: center;
566
+ gap: var(--size-2xs, 0.25rem);
567
+ }
568
+ .rm-bar:active {
569
+ cursor: grabbing;
570
+ }
571
+ .rm-bar-title {
572
+ flex: 1;
573
+ overflow: hidden;
574
+ white-space: nowrap;
575
+ text-overflow: ellipsis;
576
+ }
577
+ .rm-bar-handle {
578
+ position: absolute;
579
+ inset-block: 0;
580
+ inset-inline-end: 0;
581
+ inline-size: var(--size-xs, 0.5rem);
582
+ background: rgba(255, 255, 255, 0.25);
583
+ cursor: ew-resize;
584
+ border-start-end-radius: var(--radius-s, 0.25rem);
585
+ border-end-end-radius: var(--radius-s, 0.25rem);
586
+ }
587
+ .rm-bar[data-status=planned] {
588
+ background: var(--color-info, oklch(60% 0.12 240));
589
+ }
590
+ .rm-bar[data-status=in-progress] {
591
+ background: var(--color-accent, oklch(50% 0.16 260));
592
+ }
593
+ .rm-bar[data-status=at-risk] {
594
+ background: var(--color-warning, oklch(65% 0.16 60));
595
+ color: var(--color-text, #1a1a1a);
596
+ }
597
+ .rm-bar[data-status=shipped] {
598
+ background: var(--color-success, oklch(55% 0.14 145));
599
+ }
600
+ .rm-bar[data-status=blocked] {
601
+ background: var(--color-danger, oklch(55% 0.18 25));
602
+ }
603
+ .rm-today {
604
+ position: absolute;
605
+ inset-block: 0;
606
+ inset-inline-start: calc(var(--rm-x) * 100%);
607
+ inline-size: 0;
608
+ border-inline-start: var(--border-width-medium, 2px) solid var(--color-warning, oklch(60% 0.18 60));
609
+ pointer-events: none;
610
+ z-index: 2;
611
+ transform: translateX(0);
612
+ }
613
+ }
614
+ product-roadmap:not([editable]) .rm-bar {
615
+ cursor: default;
616
+ }
617
+ product-roadmap:not([editable]) .rm-bar-handle {
618
+ display: none;
619
+ }
620
+ @media (prefers-reduced-motion: reduce) {
621
+ product-roadmap .rm-bar {
622
+ transition: none;
623
+ }
624
+ }
625
+
626
+ /* src/web-components/kanban-board/styles.css */
627
+ kanban-board {
628
+ display: block;
629
+ container-type: inline-size;
630
+ }
631
+ kanban-board:not(:defined) {
632
+ display: block;
633
+ }
634
+ .kb-columns {
635
+ display: flex;
636
+ gap: 1px;
637
+ background: var(--color-border, #e0e0e0);
638
+ border: 1px solid var(--color-border, #e0e0e0);
639
+ border-radius: var(--radius-l, 0.75rem);
640
+ overflow: hidden;
641
+ flex-wrap: wrap;
642
+ }
643
+ .kb-column {
644
+ min-inline-size: 14rem;
645
+ flex: 1 1 14rem;
646
+ display: flex;
647
+ flex-direction: column;
648
+ background: var(--color-surface, #fff);
649
+ margin-block: 0 !important;
650
+ padding-block-start: 0 !important;
651
+ border-block-start: 0 !important;
652
+ }
653
+ .kb-column-header {
654
+ position: sticky;
655
+ inset-block-start: 0;
656
+ z-index: 2;
657
+ padding: var(--size-s, 12px) var(--size-m, 16px);
658
+ background: var(--color-surface-raised, #f8f9fa);
659
+ border-block-end: 2px solid var(--color-border, #e0e0e0);
660
+ }
661
+ .kb-column-header h3 {
662
+ margin: 0;
663
+ font-size: 0.875rem;
664
+ font-weight: 700;
665
+ text-transform: uppercase;
666
+ letter-spacing: 0.04em;
667
+ color: var(--color-text, #1a1a1a);
668
+ display: flex;
669
+ align-items: center;
670
+ gap: 0.25em;
671
+ }
672
+ .kb-count {
673
+ font-size: 0.7rem;
674
+ font-weight: 600;
675
+ color: var(--color-text-muted, #666);
676
+ background: var(--color-border, #e0e0e0);
677
+ border-radius: var(--radius-full, 9999px);
678
+ padding: 1px 8px;
679
+ margin-inline-start: 4px;
680
+ }
681
+ .kb-wip {
682
+ font-size: 0.65rem;
683
+ font-weight: 400;
684
+ color: var(--color-text-muted, #999);
685
+ }
686
+ [data-wip-exceeded] .kb-column-header {
687
+ border-block-end-color: var(--color-error, #ef4444);
688
+ }
689
+ [data-wip-exceeded] .kb-count {
690
+ background: color-mix(in oklch, var(--color-error, #ef4444) 15%, var(--color-surface, #fff));
691
+ color: var(--color-error, #ef4444);
692
+ }
693
+ [data-column-tint=success] {
694
+ background: color-mix(in oklch, var(--color-success, #22c55e) 6%, var(--color-surface, #fff));
695
+ }
696
+ [data-column-tint=warning] {
697
+ background: color-mix(in oklch, var(--color-warning, #f59e0b) 6%, var(--color-surface, #fff));
698
+ }
699
+ [data-column-tint=error] {
700
+ background: color-mix(in oklch, var(--color-error, #ef4444) 6%, var(--color-surface, #fff));
701
+ }
702
+ [data-column-tint=info] {
703
+ background: color-mix(in oklch, var(--color-info, #3b82f6) 6%, var(--color-surface, #fff));
704
+ }
705
+ [data-column-tint=interactive] {
706
+ background: color-mix(in oklch, var(--color-interactive, #3b82f6) 6%, var(--color-surface, #fff));
707
+ }
708
+ kanban-board drag-surface {
709
+ padding: var(--size-s, 12px);
710
+ min-block-size: 6rem;
711
+ flex: 1;
712
+ }
713
+ kanban-board .kb-card {
714
+ background: var(--color-surface, #fff);
715
+ border: var(--border-width-thin, 1px) solid var(--color-border, #e0e0e0);
716
+ border-radius: var(--radius-s, 0.375rem);
717
+ padding: var(--size-xs, 8px) var(--size-s, 12px);
718
+ cursor: grab;
719
+ font-size: var(--font-size-s, 0.875rem);
720
+ line-height: 1.4;
721
+ }
722
+ kanban-board .kb-card:active {
723
+ cursor: grabbing;
724
+ }
725
+ .kb-empty {
726
+ color: var(--color-text-muted, #888);
727
+ font-size: 0.8rem;
728
+ font-style: italic;
729
+ padding: var(--size-s, 12px);
730
+ margin: 0;
731
+ }
732
+ .kb-title {
733
+ margin-block-end: var(--size-s, 12px);
734
+ }
735
+ .kb-live-region {
736
+ position: absolute;
737
+ width: 1px;
738
+ height: 1px;
739
+ overflow: hidden;
740
+ clip: rect(0, 0, 0, 0);
741
+ white-space: nowrap;
742
+ border: 0;
743
+ padding: 0;
744
+ margin: -1px;
745
+ }
746
+ kanban-board[compact] .kb-column {
747
+ min-inline-size: 11rem;
748
+ flex: 1 1 11rem;
749
+ }
750
+ kanban-board[compact] .kb-column-header {
751
+ padding: var(--size-xs, 8px) var(--size-s, 12px);
752
+ }
753
+ kanban-board[compact] .kb-column-header h3 {
754
+ font-size: 0.75rem;
755
+ }
756
+ kanban-board[compact] drag-surface {
757
+ padding: var(--size-xs, 8px);
758
+ min-block-size: 4rem;
759
+ }
760
+ kanban-board[compact] .kb-count {
761
+ font-size: 0.6rem;
762
+ }
763
+ @container (max-width: 30rem) {
764
+ .kb-columns {
765
+ flex-direction: column;
766
+ }
767
+ .kb-column {
768
+ min-inline-size: unset;
769
+ }
770
+ }
771
+ @media (prefers-reduced-motion: reduce) {
772
+ kanban-board,
773
+ kanban-board * {
774
+ transition: none;
775
+ }
776
+ }
777
+ @media print {
778
+ .kb-columns {
779
+ flex-wrap: wrap;
780
+ border: 0.5pt solid #ccc;
781
+ gap: 0;
782
+ }
783
+ .kb-column {
784
+ border: 0.5pt solid #ccc;
785
+ break-inside: avoid;
786
+ }
787
+ .kb-column-header {
788
+ position: static;
789
+ }
790
+ kanban-board drag-surface {
791
+ min-block-size: auto;
792
+ }
793
+ kanban-board [draggable] {
794
+ cursor: default;
795
+ }
796
+ }
797
+
798
+ /* src/web-components/story-map/styles.css */
799
+ story-map {
800
+ display: block;
801
+ container-type: inline-size;
802
+ }
803
+ story-map:not(:defined) {
804
+ display: block;
805
+ }
806
+ .sm-scroll {
807
+ overflow-x: auto;
808
+ overflow-y: visible;
809
+ -webkit-overflow-scrolling: touch;
810
+ }
811
+ .sm-columns {
812
+ display: flex;
813
+ gap: 1px;
814
+ background: var(--color-border, #e0e0e0);
815
+ min-inline-size: min-content;
816
+ border: 1px solid var(--color-border, #e0e0e0);
817
+ border-radius: var(--radius-l, 0.75rem);
818
+ overflow: hidden;
819
+ }
820
+ .sm-column {
821
+ min-inline-size: 14rem;
822
+ max-inline-size: 22rem;
823
+ flex: 1 0 14rem;
824
+ display: flex;
825
+ flex-direction: column;
826
+ background: var(--color-surface, #fff);
827
+ }
828
+ .sm-activity-header {
829
+ position: sticky;
830
+ inset-block-start: 0;
831
+ z-index: 2;
832
+ padding: var(--size-s, 12px) var(--size-m, 16px);
833
+ background: var(--color-surface-raised, #f8f9fa);
834
+ border-block-end: 2px solid var(--color-border, #e0e0e0);
835
+ }
836
+ .sm-activity-header h3 {
837
+ margin: 0;
838
+ font-size: 0.875rem;
839
+ font-weight: 700;
840
+ text-transform: uppercase;
841
+ letter-spacing: 0.04em;
842
+ color: var(--color-text, #1a1a1a);
843
+ }
844
+ .sm-activity-count {
845
+ font-size: 0.7rem;
846
+ font-weight: 600;
847
+ color: var(--color-text-muted, #666);
848
+ background: var(--color-border, #e0e0e0);
849
+ border-radius: var(--radius-full, 9999px);
850
+ padding: 1px 8px;
851
+ margin-inline-start: 8px;
852
+ }
853
+ story-map drag-surface {
854
+ padding: var(--size-s, 12px);
855
+ min-block-size: 8rem;
856
+ flex: 1;
857
+ }
858
+ story-map drag-surface > * {
859
+ margin-block-end: var(--size-xs, 8px);
860
+ }
861
+ story-map drag-surface > *:last-child {
862
+ margin-block-end: 0;
863
+ }
864
+ .sm-empty {
865
+ color: var(--color-text-muted, #888);
866
+ font-size: 0.8rem;
867
+ font-style: italic;
868
+ padding: var(--size-s, 12px);
869
+ margin: 0;
870
+ }
871
+ .sm-live-region {
872
+ position: absolute;
873
+ width: 1px;
874
+ height: 1px;
875
+ overflow: hidden;
876
+ clip: rect(0, 0, 0, 0);
877
+ white-space: nowrap;
878
+ }
879
+ story-map[compact] .sm-column {
880
+ min-inline-size: 11rem;
881
+ flex: 1 0 11rem;
882
+ }
883
+ story-map[compact] .sm-activity-header {
884
+ padding: var(--size-xs, 8px) var(--size-s, 12px);
885
+ }
886
+ story-map[compact] .sm-activity-header h3 {
887
+ font-size: 0.75rem;
888
+ }
889
+ story-map[compact] drag-surface {
890
+ padding: var(--size-xs, 8px);
891
+ }
892
+ @container (max-width: 30rem) {
893
+ .sm-columns {
894
+ flex-direction: column;
895
+ }
896
+ .sm-column {
897
+ max-inline-size: none;
898
+ }
899
+ }
900
+ @media (prefers-reduced-motion: reduce) {
901
+ .sm-scroll {
902
+ scroll-behavior: auto;
903
+ }
904
+ }
905
+ @media print {
906
+ .sm-scroll {
907
+ overflow: visible;
908
+ }
909
+ .sm-activity-header {
910
+ position: static;
911
+ }
912
+ .sm-columns {
913
+ flex-wrap: wrap;
914
+ }
915
+ .sm-column {
916
+ break-inside: avoid;
917
+ }
918
+ }
919
+
920
+ /* src/web-components/gantt-chart/styles.css */
921
+ gantt-chart {
922
+ display: block;
923
+ container-type: inline-size;
924
+ font-family: var(--font-sans, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif);
925
+ line-height: 1.5;
926
+ color: var(--color-text, #1a1a1a);
927
+ }
928
+ gantt-chart:not([data-upgraded]) > table {
929
+ width: 100%;
930
+ }
931
+ .gc-title {
932
+ font-size: var(--font-size-xl, 1.25rem);
933
+ font-weight: 700;
934
+ margin-block-end: var(--size-s, 0.75rem);
935
+ }
936
+ .gc-container {
937
+ border: 1px solid var(--color-border, #e0e0e0);
938
+ border-radius: var(--radius-m, 0.5rem);
939
+ overflow: hidden;
940
+ background: var(--color-surface, #ffffff);
941
+ }
942
+ .gc-timeline-header {
943
+ display: flex;
944
+ position: relative;
945
+ border-block-end: 1px solid var(--color-border, #e0e0e0);
946
+ background: var(--color-surface-raised, #f8f9fa);
947
+ min-height: 32px;
948
+ }
949
+ .gc-timeline-spacer {
950
+ flex: 0 0 var(--gc-task-width, 180px);
951
+ border-inline-end: 1px solid var(--color-border, #e0e0e0);
952
+ }
953
+ .gc-timeline-dates {
954
+ flex: 1;
955
+ position: relative;
956
+ min-height: 32px;
957
+ }
958
+ .gc-date-label {
959
+ position: absolute;
960
+ top: 0;
961
+ bottom: 0;
962
+ display: flex;
963
+ align-items: center;
964
+ font-size: 11px;
965
+ font-weight: 600;
966
+ color: var(--color-text-muted, #666666);
967
+ padding-inline-start: 6px;
968
+ white-space: nowrap;
969
+ border-inline-start: 1px solid var(--color-border, #e0e0e0);
970
+ }
971
+ .gc-date-label:first-child {
972
+ border-inline-start: none;
973
+ }
974
+ .gc-body {
975
+ display: flex;
976
+ min-height: 0;
977
+ }
978
+ .gc-task-list {
979
+ flex: 0 0 var(--gc-task-width, 180px);
980
+ border-inline-end: 1px solid var(--color-border, #e0e0e0);
981
+ overflow: hidden;
982
+ }
983
+ .gc-task-row {
984
+ display: flex;
985
+ align-items: center;
986
+ gap: 6px;
987
+ height: var(--gc-row-height, 36px);
988
+ padding-inline: 12px;
989
+ border-block-end: 1px solid color-mix(in srgb, var(--color-border, #e0e0e0) 50%, transparent);
990
+ font-size: var(--font-size-sm, 0.875rem);
991
+ white-space: nowrap;
992
+ overflow: hidden;
993
+ text-overflow: ellipsis;
994
+ }
995
+ .gc-task-row:last-child {
996
+ border-block-end: none;
997
+ }
998
+ .gc-task-name {
999
+ overflow: hidden;
1000
+ text-overflow: ellipsis;
1001
+ }
1002
+ .gc-task-dates {
1003
+ position: absolute;
1004
+ width: 1px;
1005
+ height: 1px;
1006
+ overflow: hidden;
1007
+ clip: rect(0, 0, 0, 0);
1008
+ white-space: nowrap;
1009
+ }
1010
+ .gc-group-header {
1011
+ display: flex;
1012
+ align-items: center;
1013
+ height: 28px;
1014
+ padding-inline: 12px;
1015
+ background: var(--color-surface-raised, #f8f9fa);
1016
+ border-block-end: 1px solid var(--color-border, #e0e0e0);
1017
+ }
1018
+ .gc-group-label {
1019
+ font-size: 11px;
1020
+ font-weight: 700;
1021
+ text-transform: uppercase;
1022
+ letter-spacing: 0.05em;
1023
+ color: var(--color-text-muted, #666666);
1024
+ }
1025
+ .gc-group-spacer {
1026
+ height: 28px;
1027
+ background: var(--color-surface-raised, #f8f9fa);
1028
+ border-block-end: 1px solid var(--color-border, #e0e0e0);
1029
+ }
1030
+ .gc-bars {
1031
+ flex: 1;
1032
+ position: relative;
1033
+ min-width: 0;
1034
+ overflow-x: auto;
1035
+ }
1036
+ .gc-grid-lines {
1037
+ position: absolute;
1038
+ inset: 0;
1039
+ pointer-events: none;
1040
+ }
1041
+ .gc-grid-line {
1042
+ position: absolute;
1043
+ top: 0;
1044
+ bottom: 0;
1045
+ width: 1px;
1046
+ background: color-mix(in srgb, var(--color-border, #e0e0e0) 50%, transparent);
1047
+ }
1048
+ .gc-bar-row {
1049
+ position: relative;
1050
+ height: var(--gc-row-height, 36px);
1051
+ border-block-end: 1px solid color-mix(in srgb, var(--color-border, #e0e0e0) 50%, transparent);
1052
+ }
1053
+ .gc-bar-row:last-child {
1054
+ border-block-end: none;
1055
+ }
1056
+ .gc-bar {
1057
+ position: absolute;
1058
+ top: 6px;
1059
+ bottom: 6px;
1060
+ border-radius: var(--radius-s, 4px);
1061
+ background: var(--gc-bar-color, var(--color-interactive, #0066cc));
1062
+ cursor: pointer;
1063
+ min-width: 4px;
1064
+ display: flex;
1065
+ align-items: center;
1066
+ overflow: hidden;
1067
+ transition: filter 150ms ease;
1068
+ }
1069
+ .gc-bar:hover {
1070
+ filter: brightness(1.1);
1071
+ }
1072
+ .gc-bar:focus-visible {
1073
+ outline: 2px solid var(--color-interactive, #0066cc);
1074
+ outline-offset: 2px;
1075
+ }
1076
+ .gc-bar-fill {
1077
+ height: 100%;
1078
+ border-radius: inherit;
1079
+ background: color-mix(in srgb, var(--gc-bar-color, var(--color-interactive, #0066cc)) 65%, white);
1080
+ pointer-events: none;
1081
+ }
1082
+ .gc-bar-label {
1083
+ position: absolute;
1084
+ inset: 0;
1085
+ display: flex;
1086
+ align-items: center;
1087
+ padding-inline: 6px;
1088
+ font-size: 11px;
1089
+ font-weight: 600;
1090
+ color: #fff;
1091
+ white-space: nowrap;
1092
+ overflow: hidden;
1093
+ text-overflow: ellipsis;
1094
+ pointer-events: none;
1095
+ }
1096
+ .gc-bar[data-status=done] {
1097
+ --gc-bar-color: var(--color-success, #16a34a);
1098
+ }
1099
+ .gc-bar[data-status=blocked] {
1100
+ --gc-bar-color: var(--color-error, #dc2626);
1101
+ }
1102
+ .gc-bar[data-status=not-started] {
1103
+ --gc-bar-color: var(--color-text-muted, #666666);
1104
+ opacity: 0.6;
1105
+ }
1106
+ .gc-milestone {
1107
+ position: absolute;
1108
+ top: 50%;
1109
+ width: 14px;
1110
+ height: 14px;
1111
+ transform: translate(-50%, -50%) rotate(45deg);
1112
+ background: var(--gc-bar-color, var(--color-interactive, #0066cc));
1113
+ border: 2px solid var(--color-surface, #ffffff);
1114
+ cursor: pointer;
1115
+ }
1116
+ .gc-milestone:focus-visible {
1117
+ outline: 2px solid var(--color-interactive, #0066cc);
1118
+ outline-offset: 3px;
1119
+ }
1120
+ .gc-milestone[data-status=done] {
1121
+ --gc-bar-color: var(--color-success, #16a34a);
1122
+ }
1123
+ .gc-today-line {
1124
+ position: absolute;
1125
+ top: 0;
1126
+ bottom: 0;
1127
+ width: 2px;
1128
+ background: var(--color-error, #dc2626);
1129
+ z-index: 5;
1130
+ pointer-events: none;
1131
+ }
1132
+ .gc-today-label {
1133
+ position: absolute;
1134
+ top: -22px;
1135
+ left: 50%;
1136
+ transform: translateX(-50%);
1137
+ font-size: 10px;
1138
+ font-weight: 700;
1139
+ color: var(--color-error, #dc2626);
1140
+ white-space: nowrap;
1141
+ }
1142
+ .gc-deps {
1143
+ position: absolute;
1144
+ inset: 0;
1145
+ pointer-events: none;
1146
+ overflow: visible;
1147
+ }
1148
+ .gc-dep-line {
1149
+ fill: none;
1150
+ stroke: var(--color-text-muted, #666666);
1151
+ stroke-width: 1.5;
1152
+ marker-end: url(#gc-arrowhead);
1153
+ }
1154
+ .gc-sr-only {
1155
+ position: absolute;
1156
+ width: 1px;
1157
+ height: 1px;
1158
+ padding: 0;
1159
+ margin: -1px;
1160
+ overflow: hidden;
1161
+ clip: rect(0, 0, 0, 0);
1162
+ white-space: nowrap;
1163
+ border: 0;
1164
+ }
1165
+ gantt-chart[compact] {
1166
+ --gc-row-height: 28px;
1167
+ --gc-task-width: 140px;
1168
+ }
1169
+ gantt-chart[compact] .gc-task-row {
1170
+ font-size: 12px;
1171
+ padding-inline: 8px;
1172
+ }
1173
+ gantt-chart[compact] .gc-bar {
1174
+ top: 5px;
1175
+ bottom: 5px;
1176
+ }
1177
+ gantt-chart[compact] .gc-group-header {
1178
+ height: 24px;
1179
+ }
1180
+ gantt-chart[compact] .gc-group-spacer {
1181
+ height: 24px;
1182
+ }
1183
+ @container (max-width: 30rem) {
1184
+ .gc-body {
1185
+ flex-direction: column;
1186
+ }
1187
+ .gc-task-list {
1188
+ flex: none;
1189
+ border-inline-end: none;
1190
+ border-block-end: 1px solid var(--color-border, #e0e0e0);
1191
+ }
1192
+ .gc-task-row {
1193
+ height: auto;
1194
+ padding-block: 4px;
1195
+ }
1196
+ .gc-timeline-spacer {
1197
+ display: none;
1198
+ }
1199
+ }
1200
+ @media (prefers-reduced-motion: reduce) {
1201
+ .gc-bar {
1202
+ transition: none;
1203
+ }
1204
+ }
1205
+ @media print {
1206
+ gantt-chart[data-upgraded] .gc-container,
1207
+ gantt-chart[data-upgraded] .gc-title {
1208
+ display: none;
1209
+ }
1210
+ gantt-chart[data-upgraded] .gc-sr-only {
1211
+ position: static;
1212
+ width: auto;
1213
+ height: auto;
1214
+ margin: 0;
1215
+ overflow: visible;
1216
+ clip: auto;
1217
+ white-space: normal;
1218
+ }
1219
+ }
1220
+ ::view-transition-old(*),
1221
+ ::view-transition-new(*) {
1222
+ animation-duration: 220ms;
1223
+ animation-timing-function: ease-out;
1224
+ }
1225
+
1226
+ /* src/web-components/iron-triangle/styles.css */
1227
+ iron-triangle {
1228
+ display: block;
1229
+ inline-size: 100%;
1230
+ max-inline-size: var(--iron-triangle-max, 26rem);
1231
+ margin-inline: auto;
1232
+ container-type: inline-size;
1233
+ }
1234
+ iron-triangle > svg {
1235
+ inline-size: 100%;
1236
+ block-size: auto;
1237
+ display: block;
1238
+ }
1239
+ iron-triangle svg .triangle {
1240
+ fill: var(--iron-triangle-fill, color-mix(in oklab, var(--color-interactive) 8%, transparent));
1241
+ stroke: var(--iron-triangle-stroke, var(--color-interactive));
1242
+ stroke-width: var(--iron-triangle-stroke-width, 1.5);
1243
+ stroke-linejoin: round;
1244
+ pointer-events: none;
1245
+ }
1246
+ iron-triangle svg .vertex,
1247
+ iron-triangle svg .center {
1248
+ cursor: pointer;
1249
+ outline: none;
1250
+ }
1251
+ iron-triangle svg .vertex .hit,
1252
+ iron-triangle svg .center .hit {
1253
+ fill: transparent;
1254
+ stroke: transparent;
1255
+ transition: fill 120ms ease, stroke 120ms ease;
1256
+ }
1257
+ iron-triangle svg .vertex:hover .hit,
1258
+ iron-triangle svg .vertex:focus-visible .hit,
1259
+ iron-triangle svg .center:hover .hit,
1260
+ iron-triangle svg .center:focus-visible .hit {
1261
+ fill: color-mix(in oklab, var(--color-interactive) 8%, transparent);
1262
+ stroke: var(--color-interactive);
1263
+ stroke-width: 1.5;
1264
+ stroke-dasharray: 3 3;
1265
+ }
1266
+ iron-triangle svg .vertex-name {
1267
+ font-size: 0.85rem;
1268
+ font-weight: var(--font-weight-semibold, 600);
1269
+ fill: var(--color-text);
1270
+ pointer-events: none;
1271
+ }
1272
+ iron-triangle svg .vertex:hover .vertex-name,
1273
+ iron-triangle svg .vertex:focus-visible .vertex-name {
1274
+ fill: var(--color-interactive);
1275
+ }
1276
+ iron-triangle svg .vertex-summary {
1277
+ font-size: 0.7rem;
1278
+ fill: var(--color-text-muted);
1279
+ font-variant-numeric: tabular-nums;
1280
+ pointer-events: none;
1281
+ }
1282
+ iron-triangle svg .capacity-backdrop {
1283
+ fill: var(--color-surface);
1284
+ stroke: var(--color-border-muted, var(--color-border, #e5e7eb));
1285
+ stroke-width: 1;
1286
+ pointer-events: none;
1287
+ }
1288
+ iron-triangle svg .quality-label {
1289
+ font-size: 0.65rem;
1290
+ font-weight: var(--font-weight-semibold, 600);
1291
+ fill: var(--color-interactive);
1292
+ text-transform: uppercase;
1293
+ letter-spacing: 0.06em;
1294
+ pointer-events: none;
1295
+ }
1296
+ iron-triangle svg .capacity {
1297
+ font-size: var(--iron-triangle-capacity-size, 1.6rem);
1298
+ font-weight: var(--font-weight-bold, 700);
1299
+ fill: var(--color-text);
1300
+ font-variant-numeric: tabular-nums;
1301
+ pointer-events: none;
1302
+ }
1303
+ iron-triangle svg .capacity-unit {
1304
+ font-size: 0.6rem;
1305
+ fill: var(--color-text-muted);
1306
+ pointer-events: none;
1307
+ }
1308
+ iron-triangle svg .center .hit {
1309
+ fill: transparent;
1310
+ stroke: transparent;
1311
+ transition: fill 120ms ease, stroke 120ms ease;
1312
+ }
1313
+ iron-triangle svg .center:hover .hit,
1314
+ iron-triangle svg .center:focus-visible .hit {
1315
+ fill: color-mix(in oklab, var(--color-interactive) 8%, transparent);
1316
+ stroke: var(--color-interactive);
1317
+ stroke-width: 1.5;
1318
+ stroke-dasharray: 3 3;
1319
+ }
1320
+ iron-triangle svg .center:hover .quality-label,
1321
+ iron-triangle svg .center:focus-visible .quality-label {
1322
+ fill: var(--color-interactive);
1323
+ }
1324
+ iron-triangle:state(over-deadline) svg .triangle {
1325
+ stroke: var(--color-warning);
1326
+ }
1327
+ iron-triangle:state(unbudgeted) svg .capacity {
1328
+ fill: var(--color-warning);
1329
+ }
1330
+ iron-triangle:state(manual) svg .quality-label::after {
1331
+ content: " (manual)";
1332
+ }
1333
+ iron-triangle[disabled],
1334
+ iron-triangle[locked] {
1335
+ opacity: 0.85;
1336
+ pointer-events: none;
1337
+ }
1338
+ iron-triangle > dialog.iron-triangle-dialog {
1339
+ inline-size: min(28rem, 92vw);
1340
+ border: var(--border-width-thin, 1px) solid var(--color-border);
1341
+ border-radius: var(--radius-l, 0.75rem);
1342
+ padding: var(--size-l, 1.5rem);
1343
+ background: var(--color-surface);
1344
+ color: var(--color-text);
1345
+ }
1346
+ iron-triangle > dialog.iron-triangle-dialog::backdrop {
1347
+ background: oklch(from var(--color-surface) l c h / 0.5);
1348
+ backdrop-filter: blur(2px);
1349
+ }
1350
+ iron-triangle > dialog.iron-triangle-dialog h3 {
1351
+ margin: 0 0 var(--size-m) 0;
1352
+ font-size: var(--font-size-l, 1.125rem);
1353
+ }
1354
+
1355
+ /* src/web-components/capacity-plan/styles.css */
1356
+ capacity-plan {
1357
+ display: block;
1358
+ inline-size: 100%;
1359
+ max-inline-size: var(--capacity-plan-max, 32rem);
1360
+ margin-inline: auto;
1361
+ }
1362
+ capacity-plan .capacity-ledger {
1363
+ display: grid;
1364
+ grid-template-columns: minmax(8rem, 14rem) 1fr;
1365
+ gap: var(--size-2xs, 0.25rem) var(--size-m, 1rem);
1366
+ margin: 0;
1367
+ }
1368
+ capacity-plan .capacity-ledger > div {
1369
+ display: contents;
1370
+ }
1371
+ capacity-plan .capacity-ledger dt {
1372
+ font-weight: var(--font-weight-semibold, 600);
1373
+ color: var(--color-text);
1374
+ }
1375
+ capacity-plan .capacity-ledger .num {
1376
+ margin: 0;
1377
+ font-variant-numeric: tabular-nums;
1378
+ color: var(--color-text-muted);
1379
+ text-align: end;
1380
+ padding-inline-end: var(--size-s);
1381
+ }
1382
+ capacity-plan .capacity-ledger .bar {
1383
+ margin: 0;
1384
+ align-self: center;
1385
+ }
1386
+ capacity-plan .bar-track {
1387
+ display: block;
1388
+ inline-size: 100%;
1389
+ block-size: 0.6rem;
1390
+ background: var(--color-surface-raised, color-mix(in oklab, var(--color-surface) 92%, currentColor 8%));
1391
+ border-radius: var(--radius-pill, 999px);
1392
+ overflow: hidden;
1393
+ }
1394
+ capacity-plan .bar-fill {
1395
+ display: block;
1396
+ block-size: 100%;
1397
+ inline-size: var(--w, 0%);
1398
+ border-radius: inherit;
1399
+ transition: inline-size 200ms ease;
1400
+ }
1401
+ capacity-plan .bar-capacity {
1402
+ background: color-mix(in oklab, var(--color-text) 25%, transparent);
1403
+ }
1404
+ capacity-plan .bar-quality {
1405
+ background: var(--color-interactive);
1406
+ }
1407
+ capacity-plan .bar-features {
1408
+ background: var(--color-success);
1409
+ }
1410
+ capacity-plan .bar-slack {
1411
+ background: color-mix(in oklab, var(--color-text-muted) 35%, transparent);
1412
+ }
1413
+ capacity-plan [data-row=slack][data-state=over] .num {
1414
+ color: var(--color-error);
1415
+ font-weight: var(--font-weight-semibold, 600);
1416
+ }
1417
+ capacity-plan [data-row=slack][data-state=over] .bar-slack {
1418
+ background: var(--color-error);
1419
+ }
1420
+ capacity-plan:state(overdrawn) .capacity-ledger {
1421
+ outline: 2px solid var(--color-error);
1422
+ outline-offset: var(--size-2xs);
1423
+ border-radius: var(--radius-m);
1424
+ }
1425
+
1426
+ /* src/web-components/quality-target/styles.css */
1427
+ quality-target {
1428
+ display: block;
1429
+ inline-size: 100%;
1430
+ max-inline-size: var(--quality-target-max, 36rem);
1431
+ margin-inline: auto;
1432
+ container-type: inline-size;
1433
+ }
1434
+ quality-target > svg {
1435
+ inline-size: 100%;
1436
+ block-size: auto;
1437
+ display: block;
1438
+ }
1439
+ quality-target svg .ring {
1440
+ fill: none;
1441
+ stroke: var(--color-border-muted, var(--color-border, #e5e7eb));
1442
+ stroke-width: 1;
1443
+ stroke-dasharray: 3 3;
1444
+ pointer-events: none;
1445
+ }
1446
+ quality-target svg .ring-critical {
1447
+ stroke: color-mix(in oklab, var(--color-error) 60%, transparent);
1448
+ }
1449
+ quality-target svg .ring-important {
1450
+ stroke: color-mix(in oklab, var(--color-warning) 50%, transparent);
1451
+ }
1452
+ quality-target svg .ring-acceptable {
1453
+ stroke: color-mix(in oklab, var(--color-success) 50%, transparent);
1454
+ }
1455
+ quality-target svg .spoke {
1456
+ stroke: var(--color-border, #e5e7eb);
1457
+ stroke-width: 0.75;
1458
+ stroke-dasharray: 1 4;
1459
+ pointer-events: none;
1460
+ }
1461
+ quality-target svg .vector {
1462
+ fill: var(--quality-target-vector-fill, color-mix(in oklab, var(--color-interactive) 22%, transparent));
1463
+ stroke: var(--quality-target-vector-stroke, var(--color-interactive));
1464
+ stroke-width: 1.5;
1465
+ stroke-linejoin: round;
1466
+ pointer-events: none;
1467
+ }
1468
+ quality-target svg .vector-spoke {
1469
+ stroke: var(--quality-target-vector-stroke, var(--color-interactive));
1470
+ stroke-width: 2;
1471
+ stroke-linecap: round;
1472
+ pointer-events: none;
1473
+ }
1474
+ quality-target svg .axis {
1475
+ cursor: pointer;
1476
+ outline: none;
1477
+ }
1478
+ quality-target svg .axis .hit {
1479
+ fill: transparent;
1480
+ stroke: transparent;
1481
+ transition: fill 120ms ease, stroke 120ms ease;
1482
+ }
1483
+ quality-target svg .axis:hover .hit,
1484
+ quality-target svg .axis:focus-visible .hit {
1485
+ fill: color-mix(in oklab, var(--color-interactive) 8%, transparent);
1486
+ stroke: var(--color-interactive);
1487
+ stroke-width: 1;
1488
+ stroke-dasharray: 2 2;
1489
+ }
1490
+ quality-target svg .axis-label {
1491
+ font-size: var(--quality-target-label-size, 0.625rem);
1492
+ fill: var(--color-text-muted);
1493
+ letter-spacing: 0.02em;
1494
+ pointer-events: none;
1495
+ font-weight: var(--font-weight-regular, 400);
1496
+ }
1497
+ quality-target svg .axis[data-level] .axis-label {
1498
+ font-weight: var(--font-weight-semibold, 600);
1499
+ }
1500
+ quality-target svg .axis[data-level=critical] .axis-label {
1501
+ fill: var(--color-error, #dc2626);
1502
+ }
1503
+ quality-target svg .axis[data-level=important] .axis-label {
1504
+ fill: var(--color-warning, #b45309);
1505
+ }
1506
+ quality-target svg .axis[data-level=acceptable] .axis-label {
1507
+ fill: var(--color-success, #15803d);
1508
+ }
1509
+ quality-target svg .axis[data-level=not-relevant] .axis-label {
1510
+ fill: var(--color-text-muted, #6b7280);
1511
+ text-decoration: line-through;
1512
+ font-weight: var(--font-weight-regular, 400);
1513
+ }
1514
+ quality-target svg .axis .marker {
1515
+ fill: var(--color-interactive);
1516
+ stroke: var(--color-surface);
1517
+ stroke-width: 1;
1518
+ pointer-events: none;
1519
+ }
1520
+ quality-target svg .axis[data-level=critical] .marker {
1521
+ fill: var(--color-error, #dc2626);
1522
+ }
1523
+ quality-target svg .axis[data-level=important] .marker {
1524
+ fill: var(--color-warning, #b45309);
1525
+ }
1526
+ quality-target svg .axis[data-level=acceptable] .marker {
1527
+ fill: var(--color-success, #16a34a);
1528
+ }
1529
+ quality-target svg .axis[data-level=not-relevant] .marker {
1530
+ fill: var(--color-text-muted, #6b7280);
1531
+ opacity: 0.5;
1532
+ }
1533
+ quality-target svg .capacity-backdrop {
1534
+ fill: var(--color-surface);
1535
+ stroke: var(--color-border-muted, var(--color-border, #e5e7eb));
1536
+ stroke-width: 1;
1537
+ pointer-events: none;
1538
+ }
1539
+ quality-target svg .capacity-sum {
1540
+ font-size: var(--quality-target-capacity-size, 1.25rem);
1541
+ font-weight: var(--font-weight-bold, 700);
1542
+ fill: var(--color-text);
1543
+ font-variant-numeric: tabular-nums;
1544
+ pointer-events: none;
1545
+ }
1546
+ quality-target svg .capacity-denom {
1547
+ font-size: 0.55rem;
1548
+ fill: var(--color-text-muted);
1549
+ font-variant-numeric: tabular-nums;
1550
+ pointer-events: none;
1551
+ }
1552
+ quality-target svg .center[data-over] .capacity-sum {
1553
+ fill: var(--color-error);
1554
+ }
1555
+ quality-target:state(over-budget) svg .vector {
1556
+ stroke: var(--color-warning);
1557
+ }
1558
+ quality-target .quality-footer {
1559
+ margin-block-start: var(--size-m, 1rem);
1560
+ }
1561
+ quality-target [data-quality-overrun] {
1562
+ padding: var(--size-m, 1rem);
1563
+ border: var(--border-width-thin, 1px) solid var(--color-error);
1564
+ border-radius: var(--radius-m);
1565
+ background: var(--color-error-subtle, oklch(95% 0.05 27));
1566
+ display: grid;
1567
+ gap: var(--size-2xs, 0.25rem);
1568
+ }
1569
+ quality-target [data-quality-overrun][hidden] {
1570
+ display: none;
1571
+ }
1572
+ quality-target [data-quality-errors] {
1573
+ display: none;
1574
+ }
1575
+ quality-target:state(missing-rationale) [data-quality-errors] {
1576
+ display: block;
1577
+ }
1578
+ quality-target > dialog.quality-dialog {
1579
+ inline-size: min(28rem, 92vw);
1580
+ border: var(--border-width-thin, 1px) solid var(--color-border);
1581
+ border-radius: var(--radius-l, 0.75rem);
1582
+ padding: var(--size-l, 1.5rem);
1583
+ background: var(--color-surface);
1584
+ color: var(--color-text);
1585
+ }
1586
+ quality-target > dialog.quality-dialog::backdrop {
1587
+ background: oklch(from var(--color-surface) l c h / 0.5);
1588
+ backdrop-filter: blur(2px);
1589
+ }
1590
+ quality-target > dialog.quality-dialog h3 {
1591
+ margin: 0 0 var(--size-m) 0;
1592
+ font-size: var(--font-size-l, 1.125rem);
1593
+ }
1594
+ quality-target > dialog.quality-dialog fieldset {
1595
+ border: 1px solid var(--color-border-muted, var(--color-border));
1596
+ }
1597
+ quality-target[disabled],
1598
+ quality-target[locked] {
1599
+ opacity: 0.85;
1600
+ pointer-events: none;
1601
+ }
1602
+
1603
+ /* src/index.css */