@forwardimpact/pathway 0.21.0 → 0.23.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 (123) hide show
  1. package/README.md +3 -3
  2. package/bin/fit-pathway.js +22 -22
  3. package/package.json +4 -3
  4. package/src/commands/agent.js +14 -10
  5. package/src/commands/behaviour.js +11 -1
  6. package/src/commands/build.js +11 -2
  7. package/src/commands/command-factory.js +4 -2
  8. package/src/commands/dev.js +9 -2
  9. package/src/commands/discipline.js +19 -2
  10. package/src/commands/driver.js +11 -1
  11. package/src/commands/index.js +1 -1
  12. package/src/commands/init.js +1 -1
  13. package/src/commands/interview.js +8 -8
  14. package/src/commands/job.js +41 -28
  15. package/src/commands/level.js +76 -0
  16. package/src/commands/progress.js +20 -20
  17. package/src/commands/questions.js +3 -3
  18. package/src/commands/skill.js +11 -1
  19. package/src/commands/stage.js +11 -1
  20. package/src/commands/tool.js +4 -3
  21. package/src/commands/track.js +11 -1
  22. package/src/components/action-buttons.js +3 -3
  23. package/src/components/builder.js +25 -25
  24. package/src/components/card.js +8 -104
  25. package/src/components/comparison-radar.js +4 -4
  26. package/src/components/detail.js +18 -120
  27. package/src/components/error-page.js +8 -68
  28. package/src/components/grid.js +12 -106
  29. package/src/components/list.js +7 -116
  30. package/src/components/nav.js +7 -60
  31. package/src/components/radar-chart.js +3 -3
  32. package/src/components/skill-matrix.js +7 -7
  33. package/src/css/bundles/app.css +25 -21
  34. package/src/css/bundles/handout.css +33 -33
  35. package/src/css/bundles/slides.css +25 -25
  36. package/src/css/pages/landing.css +5 -5
  37. package/src/formatters/index.js +5 -5
  38. package/src/formatters/interview/shared.js +23 -23
  39. package/src/formatters/job/description.js +18 -18
  40. package/src/formatters/job/dom.js +12 -12
  41. package/src/formatters/job/markdown.js +7 -7
  42. package/src/formatters/json-ld.js +24 -24
  43. package/src/formatters/{grade → level}/dom.js +31 -27
  44. package/src/formatters/{grade → level}/markdown.js +19 -28
  45. package/src/formatters/{grade → level}/microdata.js +28 -38
  46. package/src/formatters/level/shared.js +86 -0
  47. package/src/formatters/progress/markdown.js +2 -2
  48. package/src/formatters/progress/shared.js +51 -51
  49. package/src/formatters/questions/markdown.js +8 -6
  50. package/src/formatters/questions/shared.js +7 -7
  51. package/src/formatters/skill/dom.js +4 -4
  52. package/src/formatters/skill/markdown.js +1 -1
  53. package/src/formatters/skill/microdata.js +3 -3
  54. package/src/formatters/skill/shared.js +3 -3
  55. package/src/formatters/track/shared.js +1 -1
  56. package/src/handout-main.js +12 -12
  57. package/src/handout.html +32 -13
  58. package/src/index.html +33 -14
  59. package/src/lib/card-mappers.js +16 -16
  60. package/src/lib/cli-command.js +3 -3
  61. package/src/lib/cli-output.js +2 -2
  62. package/src/lib/error-boundary.js +3 -66
  63. package/src/lib/errors.js +7 -45
  64. package/src/lib/job-cache.js +12 -12
  65. package/src/lib/markdown.js +2 -109
  66. package/src/lib/reactive.js +7 -73
  67. package/src/lib/render.js +53 -201
  68. package/src/lib/router-core.js +2 -156
  69. package/src/lib/router-pages.js +2 -11
  70. package/src/lib/router-slides.js +2 -197
  71. package/src/lib/state.js +16 -65
  72. package/src/lib/utils.js +3 -10
  73. package/src/lib/yaml-loader.js +22 -80
  74. package/src/main.js +10 -10
  75. package/src/pages/agent-builder.js +12 -12
  76. package/src/pages/assessment-results.js +28 -24
  77. package/src/pages/interview-builder.js +6 -6
  78. package/src/pages/interview.js +8 -8
  79. package/src/pages/job-builder.js +7 -7
  80. package/src/pages/job.js +8 -8
  81. package/src/pages/landing.js +8 -8
  82. package/src/pages/level.js +122 -0
  83. package/src/pages/progress-builder.js +8 -8
  84. package/src/pages/progress.js +74 -74
  85. package/src/pages/self-assessment.js +7 -7
  86. package/src/pages/skill.js +1 -1
  87. package/src/slide-main.js +23 -23
  88. package/src/slides/chapter.js +4 -4
  89. package/src/slides/index.js +11 -11
  90. package/src/slides/interview.js +2 -2
  91. package/src/slides/job.js +4 -4
  92. package/src/slides/level.js +32 -0
  93. package/src/slides/overview.js +10 -10
  94. package/src/slides/progress.js +13 -13
  95. package/src/slides.html +32 -13
  96. package/src/types.js +1 -1
  97. package/templates/job.template.md +2 -2
  98. package/src/commands/grade.js +0 -60
  99. package/src/css/base.css +0 -56
  100. package/src/css/components/badges.css +0 -232
  101. package/src/css/components/buttons.css +0 -101
  102. package/src/css/components/forms.css +0 -191
  103. package/src/css/components/layout.css +0 -218
  104. package/src/css/components/nav.css +0 -206
  105. package/src/css/components/progress.css +0 -166
  106. package/src/css/components/states.css +0 -82
  107. package/src/css/components/surfaces.css +0 -347
  108. package/src/css/components/tables.css +0 -362
  109. package/src/css/components/top-bar.css +0 -180
  110. package/src/css/components/typography.css +0 -121
  111. package/src/css/components/utilities.css +0 -41
  112. package/src/css/pages/detail.css +0 -119
  113. package/src/css/reset.css +0 -50
  114. package/src/css/tokens.css +0 -162
  115. package/src/css/views/handout.css +0 -30
  116. package/src/css/views/print.css +0 -634
  117. package/src/css/views/slide-animations.css +0 -113
  118. package/src/css/views/slide-base.css +0 -331
  119. package/src/css/views/slide-sections.css +0 -597
  120. package/src/css/views/slide-tables.css +0 -275
  121. package/src/formatters/grade/shared.js +0 -86
  122. package/src/pages/grade.js +0 -122
  123. package/src/slides/grade.js +0 -32
@@ -1,166 +0,0 @@
1
- /**
2
- * Progress Indicators
3
- *
4
- * Level dots, bars, and progress indicators - consolidated definition.
5
- */
6
-
7
- @layer components {
8
- /* Level bar */
9
- .level-bar {
10
- display: flex;
11
- gap: 6px;
12
- align-items: center;
13
- }
14
-
15
- /* Level dot base */
16
- .level-dot {
17
- width: 14px;
18
- height: 14px;
19
- border-radius: 50%;
20
- background: rgba(226, 232, 240, 0.5);
21
- border: 2px solid rgba(203, 213, 225, 0.8);
22
- transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
23
- position: relative;
24
- }
25
-
26
- .level-dot:hover {
27
- transform: scale(1.2);
28
- }
29
-
30
- .level-dot.filled {
31
- background: var(--color-primary);
32
- }
33
-
34
- /* Level dot colors by level */
35
- .level-dot.filled.level-1 {
36
- background: linear-gradient(135deg, #fecaca, #fca5a5);
37
- border-color: #f87171;
38
- box-shadow:
39
- 0 2px 8px rgba(239, 68, 68, 0.4),
40
- inset 0 1px 2px rgba(255, 255, 255, 0.5);
41
- }
42
-
43
- .level-dot.filled.level-2 {
44
- background: linear-gradient(135deg, #fde68a, #fcd34d);
45
- border-color: #fbbf24;
46
- box-shadow:
47
- 0 2px 8px rgba(245, 158, 11, 0.4),
48
- inset 0 1px 2px rgba(255, 255, 255, 0.5);
49
- }
50
-
51
- .level-dot.filled.level-3 {
52
- background: linear-gradient(135deg, #bbf7d0, #86efac);
53
- border-color: #34d399;
54
- box-shadow:
55
- 0 2px 8px rgba(16, 185, 129, 0.4),
56
- inset 0 1px 2px rgba(255, 255, 255, 0.5);
57
- }
58
-
59
- .level-dot.filled.level-4 {
60
- background: linear-gradient(135deg, #a5f3fc, #67e8f9);
61
- border-color: #22d3ee;
62
- box-shadow:
63
- 0 2px 8px rgba(6, 182, 212, 0.4),
64
- inset 0 1px 2px rgba(255, 255, 255, 0.5);
65
- }
66
-
67
- .level-dot.filled.level-5 {
68
- background: linear-gradient(135deg, #c4b5fd, #a78bfa);
69
- border-color: #a78bfa;
70
- box-shadow:
71
- 0 2px 8px rgba(139, 92, 246, 0.4),
72
- inset 0 1px 2px rgba(255, 255, 255, 0.5);
73
- }
74
-
75
- /* Level dots for compact display (no animation) */
76
- .level-dots {
77
- display: inline-flex;
78
- gap: var(--space-xs);
79
- }
80
-
81
- .level-dots .level-dot {
82
- width: 14px;
83
- height: 14px;
84
- border-radius: 50%;
85
- background: var(--color-border);
86
- }
87
-
88
- .level-dots .level-dot.filled {
89
- background: var(--color-primary);
90
- }
91
-
92
- /* Level cell */
93
- .level-cell {
94
- position: relative;
95
- }
96
-
97
- .level-label {
98
- display: block;
99
- margin-top: 4px;
100
- font-size: var(--font-size-xs);
101
- font-weight: 500;
102
- color: var(--color-text-muted);
103
- transition: color 0.3s;
104
- }
105
-
106
- .level-cell:hover .level-label {
107
- background: linear-gradient(135deg, #3b82f6, #9333ea);
108
- -webkit-background-clip: text;
109
- -webkit-text-fill-color: transparent;
110
- background-clip: text;
111
- }
112
-
113
- /* Progress bar */
114
- .progress-bar {
115
- height: 8px;
116
- background: var(--color-border);
117
- border-radius: var(--radius-sm);
118
- overflow: hidden;
119
- }
120
-
121
- .progress-bar-fill {
122
- height: 100%;
123
- background: var(--color-primary);
124
- border-radius: var(--radius-sm);
125
- transition: width 0.3s;
126
- }
127
-
128
- /* Stats */
129
- .stat-grid {
130
- display: grid;
131
- grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
132
- gap: var(--space-md);
133
- }
134
-
135
- .stat-item {
136
- background: var(--color-bg);
137
- padding: var(--space-md);
138
- border-radius: var(--radius-md);
139
- text-align: center;
140
- }
141
-
142
- .stats {
143
- display: flex;
144
- gap: var(--space-lg);
145
- margin-bottom: var(--space-xl);
146
- flex-wrap: wrap;
147
- }
148
-
149
- .stat {
150
- flex: 1;
151
- min-width: 120px;
152
- text-align: center;
153
- padding: var(--space-md);
154
- background: var(--color-surface);
155
- border-radius: var(--radius-md);
156
- border: 1px solid var(--color-border);
157
- }
158
-
159
- .stat-value {
160
- font-size: var(--font-size-3xl);
161
- font-weight: 700;
162
- color: var(--color-primary);
163
- display: block;
164
- margin-bottom: var(--space-xs);
165
- }
166
- }
@@ -1,82 +0,0 @@
1
- /**
2
- * State Components
3
- *
4
- * Loading, error, and empty states.
5
- */
6
-
7
- @layer components {
8
- /* Loading state */
9
- .loading {
10
- display: flex;
11
- flex-direction: column;
12
- align-items: center;
13
- justify-content: center;
14
- padding: var(--space-2xl);
15
- color: var(--color-text-muted);
16
- }
17
-
18
- .loading-spinner {
19
- width: 40px;
20
- height: 40px;
21
- border: 3px solid var(--color-border);
22
- border-top-color: var(--color-primary);
23
- border-radius: 50%;
24
- animation: spin 0.8s linear infinite;
25
- margin-bottom: var(--space-md);
26
- }
27
-
28
- @keyframes spin {
29
- to {
30
- transform: rotate(360deg);
31
- }
32
- }
33
-
34
- /* Error state */
35
- .error-message {
36
- background: #fef2f2;
37
- border: 1px solid #fecaca;
38
- border-radius: var(--radius-lg);
39
- padding: var(--space-xl);
40
- text-align: center;
41
- color: var(--color-error);
42
- }
43
-
44
- /* Empty state */
45
- .empty-state {
46
- text-align: center;
47
- padding: var(--space-2xl);
48
- color: var(--color-text-muted);
49
- }
50
-
51
- .empty-state-icon {
52
- font-size: 3rem;
53
- margin-bottom: var(--space-md);
54
- opacity: 0.5;
55
- }
56
-
57
- .empty-state-title {
58
- font-size: var(--font-size-lg);
59
- font-weight: 600;
60
- margin-bottom: var(--space-sm);
61
- color: var(--color-text);
62
- }
63
-
64
- .empty-state-message {
65
- margin: 0;
66
- }
67
-
68
- /* Not found state */
69
- .not-found {
70
- text-align: center;
71
- padding: var(--space-2xl);
72
- }
73
-
74
- .not-found h1 {
75
- font-size: var(--font-size-3xl);
76
- color: var(--color-text-muted);
77
- }
78
-
79
- .not-found-actions {
80
- margin-top: var(--space-xl);
81
- }
82
- }
@@ -1,347 +0,0 @@
1
- /**
2
- * Surface Components
3
- *
4
- * Cards, sections, and surface styles.
5
- */
6
-
7
- @layer components {
8
- /* Cards */
9
- .card {
10
- background: var(--color-surface);
11
- border-radius: var(--radius-lg);
12
- box-shadow: var(--shadow-md);
13
- padding: var(--space-lg);
14
- transition:
15
- box-shadow 0.2s,
16
- transform 0.2s;
17
- }
18
-
19
- .card:hover {
20
- box-shadow: var(--shadow-lg);
21
- }
22
-
23
- .card-clickable {
24
- cursor: pointer;
25
- }
26
-
27
- .card-clickable:hover {
28
- transform: translateY(-2px);
29
- }
30
-
31
- .card-header {
32
- display: flex;
33
- justify-content: space-between;
34
- align-items: flex-start;
35
- margin-bottom: var(--space-md);
36
- }
37
-
38
- .card-title {
39
- margin: 0;
40
- font-size: var(--font-size-lg);
41
- }
42
-
43
- .card-title-with-icon {
44
- display: flex;
45
- align-items: center;
46
- gap: var(--space-sm);
47
- }
48
-
49
- .card-title-with-icon .card-title {
50
- margin: 0;
51
- }
52
-
53
- /* Tool icons */
54
- .tool-icon {
55
- width: 28px;
56
- height: 28px;
57
- flex-shrink: 0;
58
- }
59
-
60
- /* Tool name cell with icon */
61
- .tool-name-cell {
62
- display: flex;
63
- align-items: center;
64
- gap: var(--space-sm);
65
- }
66
-
67
- .card-description {
68
- color: var(--color-text-muted);
69
- margin: 0;
70
- font-size: var(--font-size-sm);
71
- }
72
-
73
- .card-meta {
74
- display: flex;
75
- gap: var(--space-sm);
76
- flex-wrap: wrap;
77
- margin-top: var(--space-md);
78
- }
79
-
80
- /* Tool skills list (inside cards) */
81
- .tool-skills-list {
82
- list-style: none;
83
- padding: 0;
84
- margin: var(--space-sm) 0 0 0;
85
- font-size: var(--font-size-sm);
86
- }
87
-
88
- .tool-skills-list li {
89
- padding: var(--space-xs) 0;
90
- }
91
-
92
- .tool-skills-list a {
93
- color: var(--color-text-secondary);
94
- text-decoration: none;
95
- }
96
-
97
- .tool-skills-list a:hover {
98
- color: var(--color-primary);
99
- text-decoration: underline;
100
- }
101
-
102
- /* Stat cards */
103
- .stat-card {
104
- background: var(--color-surface);
105
- border-radius: var(--radius-lg);
106
- padding: var(--space-lg);
107
- text-align: center;
108
- box-shadow: var(--shadow-md);
109
- transition:
110
- transform 0.2s,
111
- box-shadow 0.2s;
112
- }
113
-
114
- .stat-card:hover {
115
- transform: translateY(-2px);
116
- box-shadow: var(--shadow-lg);
117
- }
118
-
119
- /* Surface utilities */
120
- .surface {
121
- background: var(--color-surface);
122
- border-radius: var(--radius-lg);
123
- }
124
-
125
- .surface-elevated {
126
- box-shadow: var(--shadow-md);
127
- }
128
-
129
- .surface-bordered {
130
- border: 1px solid var(--color-border);
131
- }
132
-
133
- .surface-padded {
134
- padding: var(--space-lg);
135
- }
136
-
137
- .surface-padded-sm {
138
- padding: var(--space-md);
139
- }
140
-
141
- /* Section headers */
142
- .section-header {
143
- margin-bottom: var(--space-lg);
144
- }
145
-
146
- .section-title {
147
- font-size: var(--font-size-xl);
148
- font-weight: 600;
149
- margin: 0 0 var(--space-md);
150
- color: var(--color-text);
151
- }
152
-
153
- .section-title-bordered {
154
- padding-bottom: var(--space-sm);
155
- border-bottom: 2px solid var(--color-border);
156
- }
157
-
158
- .section-description {
159
- color: var(--color-text-muted);
160
- margin: 0;
161
- }
162
-
163
- /* Page headers */
164
- .page-header {
165
- margin-bottom: var(--space-xl);
166
- }
167
-
168
- .page-title {
169
- font-size: var(--font-size-3xl);
170
- font-weight: 700;
171
- margin: 0 0 var(--space-md);
172
- }
173
-
174
- .page-description {
175
- font-size: var(--font-size-lg);
176
- color: var(--color-text-muted);
177
- margin: 0;
178
- max-width: 80ch;
179
- }
180
-
181
- .page-meta {
182
- display: flex;
183
- gap: var(--space-sm);
184
- flex-wrap: wrap;
185
- margin-top: var(--space-sm);
186
- }
187
-
188
- .page-actions {
189
- display: flex;
190
- gap: var(--space-md);
191
- margin-top: var(--space-md);
192
- flex-wrap: wrap;
193
- }
194
-
195
- @media (max-width: 640px) {
196
- .page-actions {
197
- flex-direction: column;
198
- align-items: stretch;
199
- }
200
-
201
- .page-actions .btn {
202
- text-align: center;
203
- }
204
- }
205
-
206
- /* Sections */
207
- .section {
208
- margin-top: var(--space-xl);
209
- margin-bottom: var(--space-xl);
210
- }
211
-
212
- /* Detail pages */
213
- .detail-page {
214
- max-width: var(--max-width);
215
- margin: 0 auto;
216
- }
217
-
218
- .detail-section {
219
- margin-bottom: var(--space-2xl);
220
- }
221
-
222
- .detail-section:last-child {
223
- margin-bottom: 0;
224
- }
225
-
226
- .detail-item {
227
- background: var(--color-bg);
228
- padding: var(--space-md);
229
- border-radius: var(--radius-md);
230
- }
231
-
232
- .detail-item-value {
233
- font-weight: 500;
234
- }
235
-
236
- /*
237
- * List items: 60px row height = 16px padding-top + 28px content + 16px padding-bottom
238
- * Uses bottom-border only for 1px gaps between items (like table rows)
239
- * Left/right borders and rounded corners on first/last items match table styling
240
- */
241
- .list-item {
242
- display: flex;
243
- align-items: center;
244
- gap: var(--space-sm);
245
- min-height: 60px;
246
- padding: var(--space-md) var(--space-lg);
247
- background: var(--color-surface);
248
- border: 1px solid var(--color-border);
249
- border-top: none;
250
- }
251
-
252
- /* First list-item in a sequence (handles heading before list items) */
253
- .list-item:first-child,
254
- :not(.list-item) + .list-item {
255
- border-top: 1px solid var(--color-border);
256
- border-top-left-radius: var(--radius-lg);
257
- border-top-right-radius: var(--radius-lg);
258
- }
259
-
260
- .list-item:last-child {
261
- border-bottom-left-radius: var(--radius-lg);
262
- border-bottom-right-radius: var(--radius-lg);
263
- }
264
-
265
- /* Accent borders */
266
- .accent-left {
267
- border-left: 4px solid var(--color-border);
268
- }
269
-
270
- .accent-primary {
271
- border-left-color: var(--color-primary);
272
- }
273
-
274
- .accent-success {
275
- border-left-color: var(--color-success);
276
- }
277
-
278
- .accent-warning {
279
- border-left-color: var(--color-warning);
280
- }
281
-
282
- .accent-error {
283
- border-left-color: var(--color-error);
284
- }
285
-
286
- .accent-skill-primary {
287
- border-left-color: var(--color-primary-skill);
288
- }
289
-
290
- .accent-skill-secondary {
291
- border-left-color: var(--color-secondary);
292
- }
293
-
294
- .accent-skill-broad {
295
- border-left-color: var(--color-broad);
296
- }
297
-
298
- /* Footer */
299
- #app-footer {
300
- background: var(--color-surface);
301
- border-top: 1px solid var(--color-border);
302
- padding: var(--space-lg);
303
- text-align: center;
304
- color: var(--color-text-muted);
305
- font-size: var(--font-size-sm);
306
- }
307
-
308
- #app-footer p {
309
- margin: 0 0 var(--space-sm) 0;
310
- }
311
-
312
- .footer-links {
313
- display: flex;
314
- gap: var(--space-md);
315
- justify-content: center;
316
- }
317
-
318
- .footer-links a {
319
- color: var(--color-text-muted);
320
- text-decoration: none;
321
- }
322
-
323
- .footer-links a:hover {
324
- color: var(--color-primary);
325
- text-decoration: underline;
326
- }
327
-
328
- .footer-quote {
329
- margin: var(--space-lg) auto 0;
330
- max-width: 50em;
331
- font-style: italic;
332
- color: var(--color-text-muted);
333
- border: none;
334
- padding: 0;
335
- }
336
-
337
- .footer-quote p {
338
- margin: 0 0 var(--space-xs) 0;
339
- font-size: var(--font-size-sm);
340
- line-height: 1.5;
341
- }
342
-
343
- .footer-quote cite {
344
- font-size: var(--font-size-xs);
345
- font-style: normal;
346
- }
347
- }