@forwardimpact/pathway 0.22.0 → 0.23.1

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 (78) hide show
  1. package/bin/fit-pathway.js +8 -4
  2. package/package.json +6 -2
  3. package/src/commands/agent.js +6 -3
  4. package/src/commands/behaviour.js +11 -1
  5. package/src/commands/build.js +11 -2
  6. package/src/commands/command-factory.js +4 -2
  7. package/src/commands/dev.js +9 -2
  8. package/src/commands/discipline.js +25 -10
  9. package/src/commands/driver.js +11 -1
  10. package/src/commands/job.js +127 -28
  11. package/src/commands/level.js +25 -3
  12. package/src/commands/skill.js +11 -1
  13. package/src/commands/stage.js +11 -1
  14. package/src/commands/tool.js +6 -3
  15. package/src/commands/track.js +20 -4
  16. package/src/components/card.js +8 -104
  17. package/src/components/comparison-radar.js +1 -1
  18. package/src/components/detail.js +16 -118
  19. package/src/components/error-page.js +8 -68
  20. package/src/components/grid.js +12 -106
  21. package/src/components/list.js +7 -116
  22. package/src/components/nav.js +7 -60
  23. package/src/css/bundles/app.css +25 -21
  24. package/src/css/bundles/handout.css +33 -33
  25. package/src/css/bundles/slides.css +25 -25
  26. package/src/formatters/discipline/markdown.js +16 -1
  27. package/src/formatters/interview/shared.js +3 -3
  28. package/src/formatters/job/description.js +2 -2
  29. package/src/formatters/progress/shared.js +3 -3
  30. package/src/formatters/skill/shared.js +1 -1
  31. package/src/formatters/track/markdown.js +14 -0
  32. package/src/formatters/track/shared.js +1 -1
  33. package/src/handout.html +32 -13
  34. package/src/index.html +32 -13
  35. package/src/lib/error-boundary.js +3 -66
  36. package/src/lib/errors.js +7 -45
  37. package/src/lib/job-cache.js +1 -1
  38. package/src/lib/markdown.js +2 -109
  39. package/src/lib/reactive.js +7 -73
  40. package/src/lib/render.js +49 -197
  41. package/src/lib/router-core.js +2 -156
  42. package/src/lib/router-pages.js +2 -11
  43. package/src/lib/router-slides.js +2 -197
  44. package/src/lib/state.js +14 -63
  45. package/src/lib/utils.js +3 -10
  46. package/src/lib/yaml-loader.js +13 -71
  47. package/src/pages/agent-builder.js +1 -1
  48. package/src/pages/assessment-results.js +1 -1
  49. package/src/pages/job-builder.js +1 -1
  50. package/src/pages/job.js +1 -1
  51. package/src/pages/skill.js +1 -1
  52. package/src/slide-main.js +1 -1
  53. package/src/slides/index.js +1 -1
  54. package/src/slides/job.js +1 -1
  55. package/src/slides/overview.js +1 -1
  56. package/src/slides.html +32 -13
  57. package/src/css/base.css +0 -56
  58. package/src/css/components/badges.css +0 -232
  59. package/src/css/components/buttons.css +0 -101
  60. package/src/css/components/forms.css +0 -191
  61. package/src/css/components/layout.css +0 -218
  62. package/src/css/components/nav.css +0 -206
  63. package/src/css/components/progress.css +0 -166
  64. package/src/css/components/states.css +0 -82
  65. package/src/css/components/surfaces.css +0 -347
  66. package/src/css/components/tables.css +0 -362
  67. package/src/css/components/top-bar.css +0 -180
  68. package/src/css/components/typography.css +0 -121
  69. package/src/css/components/utilities.css +0 -41
  70. package/src/css/pages/detail.css +0 -119
  71. package/src/css/reset.css +0 -50
  72. package/src/css/tokens.css +0 -162
  73. package/src/css/views/handout.css +0 -30
  74. package/src/css/views/print.css +0 -634
  75. package/src/css/views/slide-animations.css +0 -113
  76. package/src/css/views/slide-base.css +0 -331
  77. package/src/css/views/slide-sections.css +0 -597
  78. package/src/css/views/slide-tables.css +0 -275
@@ -1,101 +0,0 @@
1
- /**
2
- * Button Components
3
- *
4
- * Button styles for all button variants.
5
- */
6
-
7
- @layer components {
8
- .btn {
9
- display: inline-block;
10
- padding: var(--space-sm) var(--space-lg);
11
- border: none;
12
- border-radius: var(--radius-md);
13
- font-size: var(--font-size-base);
14
- font-weight: 500;
15
- cursor: pointer;
16
- text-decoration: none;
17
- transition: all 0.2s;
18
- text-align: center;
19
- }
20
-
21
- .btn:hover {
22
- text-decoration: none;
23
- }
24
-
25
- .btn-primary {
26
- background: var(--color-primary);
27
- color: white;
28
- }
29
-
30
- .btn-primary:hover {
31
- background: var(--color-primary-dark);
32
- color: white;
33
- }
34
-
35
- .btn-secondary {
36
- background: var(--color-bg);
37
- color: var(--color-text);
38
- border: 1px solid var(--color-border);
39
- }
40
-
41
- .btn-secondary:hover {
42
- background: var(--color-border);
43
- }
44
-
45
- .btn-sm {
46
- padding: var(--space-xs) var(--space-md);
47
- font-size: var(--font-size-sm);
48
- }
49
-
50
- .btn-lg {
51
- padding: var(--space-md) var(--space-xl);
52
- font-size: var(--font-size-lg);
53
- }
54
-
55
- .btn:disabled {
56
- opacity: 0.5;
57
- cursor: not-allowed;
58
- }
59
-
60
- /* Button groups */
61
- .button-group {
62
- display: flex;
63
- gap: var(--space-sm);
64
- flex-wrap: wrap;
65
- }
66
-
67
- /* Copy button */
68
- .copy-btn {
69
- white-space: nowrap;
70
- display: inline-flex;
71
- align-items: center;
72
- gap: var(--space-sm);
73
- transition: all 0.2s ease;
74
- }
75
-
76
- .copy-btn.copied {
77
- background-color: var(--color-success);
78
- border-color: var(--color-success);
79
- }
80
-
81
- /* Download all button */
82
- .download-all-btn {
83
- width: 100%;
84
- padding: var(--space-md);
85
- font-size: var(--font-size-lg);
86
- }
87
-
88
- /* Back link */
89
- .back-link {
90
- display: inline-flex;
91
- align-items: center;
92
- gap: var(--space-xs);
93
- color: var(--color-text-muted);
94
- font-size: var(--font-size-sm);
95
- margin-bottom: var(--space-md);
96
- }
97
-
98
- .back-link:hover {
99
- color: var(--color-primary);
100
- }
101
- }
@@ -1,191 +0,0 @@
1
- /**
2
- * Form Components
3
- *
4
- * Form inputs, selects, and form groups.
5
- */
6
-
7
- @layer components {
8
- .form-group {
9
- margin-bottom: var(--space-md);
10
- }
11
-
12
- .form-label {
13
- display: block;
14
- margin-bottom: var(--space-xs);
15
- font-weight: 500;
16
- color: var(--color-text);
17
- }
18
-
19
- .form-input,
20
- .form-select {
21
- width: 100%;
22
- padding: var(--space-sm) var(--space-md);
23
- border: 1px solid var(--color-border);
24
- border-radius: var(--radius-md);
25
- font-size: var(--font-size-base);
26
- font-family: inherit;
27
- background: var(--color-surface);
28
- transition:
29
- border-color 0.2s,
30
- box-shadow 0.2s;
31
- }
32
-
33
- .form-input:focus,
34
- .form-select:focus {
35
- outline: none;
36
- border-color: var(--color-primary);
37
- box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
38
- }
39
-
40
- .form-select {
41
- cursor: pointer;
42
- }
43
-
44
- /* Search bar */
45
- .search-bar {
46
- display: flex;
47
- gap: var(--space-md);
48
- margin-bottom: var(--space-xl);
49
- flex-wrap: wrap;
50
- }
51
-
52
- .search-bar .form-input {
53
- flex: 1;
54
- min-width: 200px;
55
- }
56
-
57
- .search-bar .form-select {
58
- min-width: 150px;
59
- }
60
-
61
- /* Stage radio buttons */
62
- .stage-radio-group {
63
- display: flex;
64
- flex-wrap: wrap;
65
- gap: var(--space-sm);
66
- }
67
-
68
- .stage-radio-item {
69
- display: flex;
70
- align-items: center;
71
- }
72
-
73
- .stage-radio-input {
74
- position: absolute;
75
- opacity: 0;
76
- width: 0;
77
- height: 0;
78
- }
79
-
80
- .stage-radio-label {
81
- display: inline-flex;
82
- align-items: center;
83
- gap: var(--space-xs);
84
- padding: var(--space-sm) var(--space-md);
85
- background: var(--color-surface);
86
- border: 2px solid var(--color-border);
87
- border-radius: var(--radius-md);
88
- cursor: pointer;
89
- font-weight: 500;
90
- transition:
91
- border-color 0.2s ease,
92
- background-color 0.2s ease;
93
- }
94
-
95
- .stage-radio-label:hover {
96
- border-color: var(--color-primary);
97
- background: var(--color-bg);
98
- }
99
-
100
- .stage-radio-label.active {
101
- border-color: var(--color-primary);
102
- background: var(--color-primary-light, rgba(37, 99, 235, 0.1));
103
- color: var(--color-primary);
104
- }
105
-
106
- /* Code display - collapsible component for code/markdown with copy buttons */
107
- .code-display-pane {
108
- border: 1px solid var(--color-border);
109
- border-radius: var(--radius-md);
110
- background: var(--color-bg);
111
- overflow: hidden;
112
- }
113
-
114
- .code-display-summary {
115
- display: flex;
116
- align-items: center;
117
- gap: var(--space-sm);
118
- padding: var(--space-sm) var(--space-md);
119
- cursor: pointer;
120
- list-style: none;
121
- background: var(--color-surface);
122
- border-bottom: 1px solid transparent;
123
- }
124
-
125
- .code-display-summary::-webkit-details-marker {
126
- display: none;
127
- }
128
-
129
- .code-display-summary::before {
130
- content: "▸";
131
- font-size: var(--font-size-xs);
132
- color: var(--color-text-muted);
133
- flex-shrink: 0;
134
- }
135
-
136
- .code-display-pane[open] > .code-display-summary {
137
- border-bottom-color: var(--color-border);
138
- }
139
-
140
- .code-display-pane[open] > .code-display-summary::before {
141
- content: "▾";
142
- }
143
-
144
- .code-display-summary .code-display-filename {
145
- flex: 1;
146
- min-width: 0;
147
- overflow: hidden;
148
- text-overflow: ellipsis;
149
- white-space: nowrap;
150
- }
151
-
152
- .code-display-summary .button-group {
153
- flex-shrink: 0;
154
- }
155
-
156
- .code-display-body {
157
- padding: var(--space-sm) var(--space-md) var(--space-md);
158
- }
159
-
160
- .code-display-body .text-muted {
161
- margin: 0 0 var(--space-sm);
162
- }
163
-
164
- .code-display-filename {
165
- font-family: var(--font-family-mono);
166
- font-size: var(--font-size-xs);
167
- color: var(--color-text-muted);
168
- }
169
-
170
- .code-display {
171
- width: 100%;
172
- margin: 0;
173
- padding: var(--space-md);
174
- font-family: var(--font-family-mono);
175
- font-size: var(--font-size-xs);
176
- line-height: 1.6;
177
- background-color: var(--color-surface);
178
- border: 1px solid var(--color-border);
179
- border-radius: var(--radius-md);
180
- overflow: auto;
181
- color: var(--color-text);
182
- white-space: pre-wrap;
183
- word-wrap: break-word;
184
- }
185
-
186
- .code-display code {
187
- background: transparent;
188
- padding: 0;
189
- color: inherit;
190
- }
191
- }
@@ -1,218 +0,0 @@
1
- /**
2
- * Layout Utilities
3
- *
4
- * Stack, flex, and grid utilities for consistent layouts.
5
- */
6
-
7
- @layer components {
8
- /* App container */
9
- #app {
10
- min-height: 100vh;
11
- }
12
-
13
- #app-content {
14
- flex: 1;
15
- max-width: var(--max-width);
16
- width: 100%;
17
- margin: 0 auto;
18
- padding: var(--space-lg);
19
- }
20
-
21
- /* Stack - vertical flex container with gap */
22
- .stack {
23
- display: flex;
24
- flex-direction: column;
25
- }
26
-
27
- .stack-xs {
28
- gap: var(--space-xs);
29
- }
30
-
31
- .stack-sm {
32
- gap: var(--space-sm);
33
- }
34
-
35
- .stack-md {
36
- gap: var(--space-md);
37
- }
38
-
39
- .stack-lg {
40
- gap: var(--space-lg);
41
- }
42
-
43
- .stack-xl {
44
- gap: var(--space-xl);
45
- }
46
-
47
- /* Flex utilities */
48
- .flex-between {
49
- display: flex;
50
- justify-content: space-between;
51
- align-items: center;
52
- }
53
-
54
- .flex-center {
55
- display: flex;
56
- align-items: center;
57
- justify-content: center;
58
- }
59
-
60
- .flex-start {
61
- display: flex;
62
- align-items: flex-start;
63
- }
64
-
65
- .flex-wrap {
66
- flex-wrap: wrap;
67
- }
68
-
69
- .flex-gap-sm {
70
- gap: var(--space-sm);
71
- }
72
-
73
- .flex-gap-md {
74
- gap: var(--space-md);
75
- }
76
-
77
- .flex-gap-lg {
78
- gap: var(--space-lg);
79
- }
80
-
81
- /* Fixed column grids */
82
- .grid {
83
- display: grid;
84
- gap: var(--space-lg);
85
- }
86
-
87
- .grid-2 {
88
- grid-template-columns: repeat(2, 1fr);
89
- }
90
-
91
- .grid-3 {
92
- grid-template-columns: repeat(3, 1fr);
93
- }
94
-
95
- .grid-4 {
96
- grid-template-columns: repeat(4, 1fr);
97
- }
98
-
99
- .grid-6 {
100
- grid-template-columns: repeat(6, 1fr);
101
- }
102
-
103
- /* Auto-fit grids - responsive grids that automatically adjust column count */
104
- .auto-grid-xs {
105
- display: grid;
106
- grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
107
- gap: var(--space-md);
108
- }
109
-
110
- .auto-grid-sm {
111
- display: grid;
112
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
113
- gap: var(--space-md);
114
- }
115
-
116
- .auto-grid-md {
117
- display: grid;
118
- grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
119
- gap: var(--space-lg);
120
- }
121
-
122
- .auto-grid-lg {
123
- display: grid;
124
- grid-template-columns: repeat(auto-fit, minmax(400px, 1fr));
125
- gap: var(--space-xl);
126
- }
127
-
128
- /* Gap modifiers */
129
- .gap-sm {
130
- gap: var(--space-sm);
131
- }
132
-
133
- .gap-md {
134
- gap: var(--space-md);
135
- }
136
-
137
- .gap-lg {
138
- gap: var(--space-lg);
139
- }
140
-
141
- .gap-xl {
142
- gap: var(--space-xl);
143
- }
144
-
145
- /* Two-column layout */
146
- .two-columns {
147
- display: grid;
148
- grid-template-columns: 1fr 1fr;
149
- gap: var(--space-xl);
150
- }
151
-
152
- /* Content columns */
153
- .content-columns {
154
- display: grid;
155
- grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
156
- gap: var(--space-md);
157
- }
158
-
159
- /* Print-optimized two-column layout */
160
- .print-columns {
161
- display: grid;
162
- grid-template-columns: 1fr 1fr;
163
- gap: var(--space-lg);
164
- align-items: start;
165
- }
166
-
167
- .print-columns > .section-detail,
168
- .print-columns > .section {
169
- margin-top: 0;
170
- margin-bottom: 0;
171
- }
172
-
173
- @media (max-width: 1280px) {
174
- .grid-3 {
175
- grid-template-columns: repeat(2, 1fr);
176
- }
177
-
178
- .grid-4 {
179
- grid-template-columns: repeat(2, 1fr);
180
- }
181
-
182
- .grid-6 {
183
- grid-template-columns: repeat(3, 1fr);
184
- }
185
- }
186
-
187
- @media (max-width: 768px) {
188
- .two-columns {
189
- grid-template-columns: 1fr;
190
- }
191
-
192
- .print-columns {
193
- grid-template-columns: 1fr;
194
- }
195
- }
196
-
197
- @media (max-width: 640px) {
198
- .grid-2 {
199
- grid-template-columns: 1fr;
200
- }
201
-
202
- .grid-3 {
203
- grid-template-columns: 1fr;
204
- }
205
-
206
- .grid-4 {
207
- grid-template-columns: repeat(2, 1fr);
208
- }
209
-
210
- .grid-6 {
211
- grid-template-columns: repeat(2, 1fr);
212
- }
213
-
214
- .auto-grid-lg {
215
- grid-template-columns: 1fr;
216
- }
217
- }
218
- }
@@ -1,206 +0,0 @@
1
- /**
2
- * Navigation Drawer
3
- *
4
- * Left-hand drawer with vertically stacked links, toggled by top bar button.
5
- * Open by default on desktop, overlays on mobile.
6
- */
7
-
8
- @layer components {
9
- /* --------------------------------------------------------------------------
10
- Drawer Panel
11
- -------------------------------------------------------------------------- */
12
- #app-drawer {
13
- position: fixed;
14
- top: var(--top-bar-height);
15
- left: 0;
16
- bottom: 0;
17
- width: var(--drawer-width);
18
- background: var(--color-surface);
19
- border-right: 1px solid var(--color-border);
20
- z-index: 100;
21
- overflow-y: auto;
22
- display: flex;
23
- flex-direction: column;
24
- transform: translateX(calc(-1 * var(--drawer-width)));
25
- transition: transform 0.3s ease;
26
- }
27
-
28
- .drawer-open #app-drawer {
29
- transform: translateX(0);
30
- }
31
-
32
- /* --------------------------------------------------------------------------
33
- Drawer Header - brand area
34
- -------------------------------------------------------------------------- */
35
- .drawer-header {
36
- padding: var(--space-lg) var(--space-md);
37
- border-bottom: 1px solid var(--color-border);
38
- flex-shrink: 0;
39
- }
40
-
41
- .nav-brand {
42
- display: flex;
43
- flex-direction: column;
44
- align-items: center;
45
- gap: var(--space-xs);
46
- text-decoration: none;
47
- color: var(--color-text);
48
- }
49
-
50
- .brand-emoji {
51
- font-size: 2.5rem;
52
- line-height: 1;
53
- }
54
-
55
- .nav-brand:hover {
56
- text-decoration: none;
57
- }
58
-
59
- .brand-title {
60
- font-size: var(--font-size-lg);
61
- font-weight: 700;
62
- color: var(--color-text);
63
- }
64
-
65
- .nav-brand:hover .brand-title {
66
- color: var(--color-primary);
67
- }
68
-
69
- .brand-tag {
70
- display: inline-block;
71
- font-size: var(--font-size-xs);
72
- font-weight: 600;
73
- letter-spacing: 0.5px;
74
- padding: 2px 8px;
75
- border-radius: 9999px;
76
- background: linear-gradient(135deg, #f472b6 0%, #a78bfa 50%, #38bdf8 100%);
77
- background-size: 200% 200%;
78
- color: white;
79
- animation: gradient-shift 6s ease infinite;
80
- opacity: 0.9;
81
- transition:
82
- opacity 0.2s,
83
- transform 0.2s;
84
- cursor: default;
85
- }
86
-
87
- .brand-tag:hover {
88
- opacity: 1;
89
- transform: scale(1.05);
90
- }
91
-
92
- @keyframes gradient-shift {
93
- 0%,
94
- 100% {
95
- background-position: 0% 50%;
96
- }
97
- 50% {
98
- background-position: 100% 50%;
99
- }
100
- }
101
-
102
- /* --------------------------------------------------------------------------
103
- Drawer Navigation - sections and links
104
- -------------------------------------------------------------------------- */
105
- .drawer-nav {
106
- flex: 1;
107
- overflow-y: auto;
108
- padding: var(--space-sm) 0;
109
- }
110
-
111
- .drawer-section {
112
- display: flex;
113
- flex-direction: column;
114
- padding: var(--space-sm) 0;
115
- }
116
-
117
- .drawer-section + .drawer-section {
118
- border-top: 1px solid var(--color-border);
119
- }
120
-
121
- .drawer-section-label {
122
- font-size: var(--font-size-xs);
123
- font-weight: 600;
124
- text-transform: uppercase;
125
- letter-spacing: 0.05em;
126
- color: var(--color-text-light);
127
- padding: var(--space-xs) var(--space-md);
128
- margin-bottom: var(--space-xs);
129
- }
130
-
131
- .drawer-nav a {
132
- display: block;
133
- color: var(--color-text-muted);
134
- font-weight: 500;
135
- font-size: var(--font-size-sm);
136
- padding: var(--space-xs) var(--space-md);
137
- text-decoration: none;
138
- transition: all 0.15s;
139
- border-left: 3px solid transparent;
140
- }
141
-
142
- .drawer-nav a:hover {
143
- color: var(--color-primary);
144
- background: rgba(59, 130, 246, 0.06);
145
- border-left-color: var(--color-primary-light);
146
- text-decoration: none;
147
- }
148
-
149
- .drawer-nav a.active {
150
- color: var(--color-primary);
151
- background: rgba(59, 130, 246, 0.1);
152
- border-left-color: var(--color-primary);
153
- font-weight: 600;
154
- }
155
-
156
- /* CTA links in drawer */
157
- .drawer-cta {
158
- color: var(--color-primary) !important;
159
- font-weight: 600 !important;
160
- }
161
-
162
- .drawer-cta:hover {
163
- background: rgba(59, 130, 246, 0.1) !important;
164
- }
165
-
166
- /* --------------------------------------------------------------------------
167
- App Body - content area that shifts with drawer
168
- -------------------------------------------------------------------------- */
169
- .app-body {
170
- min-height: 100vh;
171
- display: flex;
172
- flex-direction: column;
173
- transition: margin-left 0.3s ease;
174
- }
175
-
176
- .drawer-open .app-body {
177
- margin-left: var(--drawer-width);
178
- }
179
-
180
- /* --------------------------------------------------------------------------
181
- Drawer Overlay - backdrop on mobile when drawer is open
182
- -------------------------------------------------------------------------- */
183
- .drawer-overlay {
184
- display: none;
185
- position: fixed;
186
- top: var(--top-bar-height);
187
- left: 0;
188
- right: 0;
189
- bottom: 0;
190
- background: rgba(0, 0, 0, 0.3);
191
- z-index: 90;
192
- }
193
-
194
- /* --------------------------------------------------------------------------
195
- Mobile - overlay instead of push
196
- -------------------------------------------------------------------------- */
197
- @media (max-width: 768px) {
198
- .drawer-open .app-body {
199
- margin-left: 0;
200
- }
201
-
202
- .drawer-open .drawer-overlay {
203
- display: block;
204
- }
205
- }
206
- }