@forwardimpact/pathway 0.3.0 → 0.5.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 (90) hide show
  1. package/app/commands/agent.js +1 -1
  2. package/app/commands/behaviour.js +1 -1
  3. package/app/commands/command-factory.js +2 -2
  4. package/app/commands/discipline.js +1 -1
  5. package/app/commands/driver.js +1 -1
  6. package/app/commands/grade.js +1 -1
  7. package/app/commands/index.js +4 -3
  8. package/app/commands/serve.js +2 -2
  9. package/app/commands/site.js +22 -2
  10. package/app/commands/skill.js +57 -3
  11. package/app/commands/stage.js +1 -1
  12. package/app/commands/tool.js +112 -0
  13. package/app/commands/track.js +1 -1
  14. package/app/components/card.js +11 -1
  15. package/app/components/checklist.js +6 -4
  16. package/app/components/code-display.js +153 -0
  17. package/app/components/markdown-textarea.js +153 -0
  18. package/app/css/bundles/app.css +14 -0
  19. package/app/css/components/badges.css +15 -8
  20. package/app/css/components/forms.css +55 -0
  21. package/app/css/components/layout.css +12 -0
  22. package/app/css/components/surfaces.css +71 -3
  23. package/app/css/components/typography.css +1 -2
  24. package/app/css/pages/agent-builder.css +11 -102
  25. package/app/css/pages/detail.css +60 -0
  26. package/app/css/pages/job-builder.css +0 -42
  27. package/app/css/tokens.css +3 -0
  28. package/app/formatters/agent/dom.js +26 -71
  29. package/app/formatters/agent/profile.js +67 -10
  30. package/app/formatters/agent/skill.js +48 -6
  31. package/app/formatters/grade/dom.js +6 -6
  32. package/app/formatters/job/description.js +21 -16
  33. package/app/formatters/job/dom.js +9 -70
  34. package/app/formatters/json-ld.js +1 -1
  35. package/app/formatters/shared.js +58 -0
  36. package/app/formatters/skill/dom.js +70 -3
  37. package/app/formatters/skill/markdown.js +18 -0
  38. package/app/formatters/skill/shared.js +14 -4
  39. package/app/formatters/stage/microdata.js +2 -2
  40. package/app/formatters/stage/shared.js +3 -3
  41. package/app/formatters/tool/shared.js +78 -0
  42. package/app/handout-main.js +19 -18
  43. package/app/index.html +16 -3
  44. package/app/lib/card-mappers.js +91 -17
  45. package/app/lib/render.js +4 -0
  46. package/app/lib/yaml-loader.js +12 -1
  47. package/app/main.js +4 -0
  48. package/app/model/agent.js +47 -23
  49. package/app/model/checklist.js +2 -2
  50. package/app/model/derivation.js +5 -5
  51. package/app/model/levels.js +4 -2
  52. package/app/model/loader.js +12 -1
  53. package/app/model/validation.js +77 -11
  54. package/app/pages/agent-builder.js +121 -77
  55. package/app/pages/landing.js +35 -15
  56. package/app/pages/self-assessment.js +7 -5
  57. package/app/pages/skill.js +5 -17
  58. package/app/pages/stage.js +12 -8
  59. package/app/pages/tool.js +50 -0
  60. package/app/slide-main.js +1 -1
  61. package/app/slides/chapter.js +8 -8
  62. package/app/slides/index.js +26 -26
  63. package/app/slides/overview.js +8 -8
  64. package/app/slides/skill.js +1 -0
  65. package/bin/pathway.js +31 -16
  66. package/examples/capabilities/business.yaml +18 -18
  67. package/examples/capabilities/delivery.yaml +54 -37
  68. package/examples/capabilities/people.yaml +1 -1
  69. package/examples/capabilities/reliability.yaml +130 -115
  70. package/examples/capabilities/scale.yaml +39 -37
  71. package/examples/disciplines/engineering_management.yaml +1 -1
  72. package/examples/framework.yaml +21 -9
  73. package/examples/grades.yaml +5 -7
  74. package/examples/self-assessments.yaml +1 -1
  75. package/examples/stages.yaml +18 -10
  76. package/package.json +2 -1
  77. package/templates/agent.template.md +47 -17
  78. package/templates/job.template.md +8 -8
  79. package/templates/skill.template.md +33 -11
  80. package/examples/agents/.claude/skills/architecture-design/SKILL.md +0 -130
  81. package/examples/agents/.claude/skills/cloud-platforms/SKILL.md +0 -131
  82. package/examples/agents/.claude/skills/code-quality-review/SKILL.md +0 -108
  83. package/examples/agents/.claude/skills/devops-cicd/SKILL.md +0 -142
  84. package/examples/agents/.claude/skills/full-stack-development/SKILL.md +0 -134
  85. package/examples/agents/.claude/skills/sre-practices/SKILL.md +0 -163
  86. package/examples/agents/.claude/skills/technical-debt-management/SKILL.md +0 -164
  87. package/examples/agents/.github/agents/se-platform-code.agent.md +0 -132
  88. package/examples/agents/.github/agents/se-platform-plan.agent.md +0 -131
  89. package/examples/agents/.github/agents/se-platform-review.agent.md +0 -136
  90. package/examples/agents/.vscode/settings.json +0 -8
@@ -0,0 +1,153 @@
1
+ /**
2
+ * Code Display Component
3
+ *
4
+ * Reusable read-only code block with copy buttons and syntax highlighting.
5
+ * Used for markdown content, agent profiles, skills, and code snippets.
6
+ */
7
+
8
+ /* global Prism */
9
+ import { div, p, span, button } from "../lib/render.js";
10
+
11
+ const COPY_LABEL = "📋 Copy";
12
+ const COPY_HTML_LABEL = "Copy as HTML";
13
+
14
+ /**
15
+ * Create a copy button that copies content to clipboard
16
+ * @param {string} content - The text content to copy
17
+ * @returns {HTMLElement}
18
+ */
19
+ export function createCopyButton(content) {
20
+ const btn = button(
21
+ {
22
+ className: "btn btn-sm copy-btn",
23
+ onClick: async () => {
24
+ try {
25
+ await navigator.clipboard.writeText(content);
26
+ btn.textContent = "✓ Copied!";
27
+ btn.classList.add("copied");
28
+ setTimeout(() => {
29
+ btn.textContent = COPY_LABEL;
30
+ btn.classList.remove("copied");
31
+ }, 2000);
32
+ } catch (err) {
33
+ console.error("Failed to copy:", err);
34
+ btn.textContent = "Copy failed";
35
+ setTimeout(() => {
36
+ btn.textContent = COPY_LABEL;
37
+ }, 2000);
38
+ }
39
+ },
40
+ },
41
+ COPY_LABEL,
42
+ );
43
+ return btn;
44
+ }
45
+
46
+ /**
47
+ * Create a copy button that copies HTML to clipboard (for rich text pasting)
48
+ * @param {string} html - The HTML content to copy
49
+ * @returns {HTMLElement}
50
+ */
51
+ function createCopyHtmlButton(html) {
52
+ const btn = button(
53
+ {
54
+ className: "btn btn-sm btn-secondary copy-btn",
55
+ onClick: async () => {
56
+ try {
57
+ const blob = new Blob([html], { type: "text/html" });
58
+ const clipboardItem = new ClipboardItem({ "text/html": blob });
59
+ await navigator.clipboard.write([clipboardItem]);
60
+ btn.textContent = "✓ Copied!";
61
+ btn.classList.add("copied");
62
+ setTimeout(() => {
63
+ btn.textContent = COPY_HTML_LABEL;
64
+ btn.classList.remove("copied");
65
+ }, 2000);
66
+ } catch (err) {
67
+ console.error("Failed to copy:", err);
68
+ btn.textContent = "Copy failed";
69
+ setTimeout(() => {
70
+ btn.textContent = COPY_HTML_LABEL;
71
+ }, 2000);
72
+ }
73
+ },
74
+ },
75
+ COPY_HTML_LABEL,
76
+ );
77
+ return btn;
78
+ }
79
+
80
+ /**
81
+ * Create a code display component with syntax highlighting and copy button
82
+ * @param {Object} options
83
+ * @param {string} options.content - The code content to display
84
+ * @param {string} [options.language="markdown"] - Language for syntax highlighting
85
+ * @param {string} [options.filename] - Optional filename to display in header
86
+ * @param {string} [options.description] - Optional description text
87
+ * @param {Function} [options.toHtml] - Function to convert content to HTML (enables "Copy as HTML" button)
88
+ * @param {number} [options.minHeight] - Optional minimum height in pixels
89
+ * @param {number} [options.maxHeight] - Optional maximum height in pixels
90
+ * @returns {HTMLElement}
91
+ */
92
+ export function createCodeDisplay({
93
+ content,
94
+ language = "markdown",
95
+ filename,
96
+ description,
97
+ toHtml,
98
+ minHeight,
99
+ maxHeight,
100
+ }) {
101
+ // Create highlighted code block
102
+ const pre = document.createElement("pre");
103
+ pre.className = "code-display";
104
+ if (minHeight) pre.style.minHeight = `${minHeight}px`;
105
+ if (maxHeight) {
106
+ pre.style.maxHeight = `${maxHeight}px`;
107
+ pre.style.overflowY = "auto";
108
+ }
109
+
110
+ const code = document.createElement("code");
111
+ if (language) {
112
+ code.className = `language-${language}`;
113
+ }
114
+ code.textContent = content;
115
+ pre.appendChild(code);
116
+
117
+ // Apply Prism highlighting if available and language specified
118
+ if (language && typeof Prism !== "undefined") {
119
+ Prism.highlightElement(code);
120
+ }
121
+
122
+ // Build header content
123
+ const headerLeft = [];
124
+ if (filename) {
125
+ headerLeft.push(span({ className: "code-display-filename" }, filename));
126
+ }
127
+ if (description) {
128
+ headerLeft.push(p({ className: "text-muted" }, description));
129
+ }
130
+
131
+ // Build buttons
132
+ const buttons = [createCopyButton(content)];
133
+ if (toHtml) {
134
+ buttons.push(createCopyHtmlButton(toHtml(content)));
135
+ }
136
+
137
+ // Only show header if there's content for it
138
+ const hasHeader = headerLeft.length > 0 || buttons.length > 0;
139
+
140
+ return div(
141
+ { className: "code-display-container" },
142
+ hasHeader
143
+ ? div(
144
+ { className: "code-display-header" },
145
+ headerLeft.length > 0
146
+ ? div({ className: "code-display-info" }, ...headerLeft)
147
+ : null,
148
+ div({ className: "button-group" }, ...buttons),
149
+ )
150
+ : null,
151
+ pre,
152
+ );
153
+ }
@@ -38,3 +38,17 @@
38
38
  @import "../pages/self-assessment.css" layer(pages);
39
39
  @import "../pages/assessment-results.css" layer(pages);
40
40
  @import "../pages/progress-builder.css" layer(pages);
41
+
42
+ /**
43
+ * Prism overrides (unlayered to beat Prism's unlayered CSS)
44
+ */
45
+ pre.code-display[class*="language-"] {
46
+ font-family: var(--font-family-mono);
47
+ font-size: var(--font-size-xs);
48
+ background-color: var(--color-surface);
49
+ }
50
+
51
+ pre.code-display > code[class*="language-"] {
52
+ font-family: inherit;
53
+ font-size: inherit;
54
+ }
@@ -5,10 +5,13 @@
5
5
  */
6
6
 
7
7
  @layer components {
8
- /* Base badge */
8
+ /* Base badge - 28px height matches tool icons for consistent row heights */
9
9
  .badge {
10
- display: inline-block;
11
- padding: var(--space-xs) var(--space-sm);
10
+ display: inline-flex;
11
+ align-items: center;
12
+ justify-content: center;
13
+ height: 28px;
14
+ padding: 0 var(--space-sm);
12
15
  border-radius: var(--radius-md);
13
16
  font-size: var(--font-size-xs);
14
17
  font-weight: 500;
@@ -78,10 +81,13 @@
78
81
  color: #5b21b6;
79
82
  }
80
83
 
81
- /* Level badge base style */
84
+ /* Level badge base style - 28px height matches tool icons */
82
85
  .level-badge {
83
- display: inline-block;
84
- padding: var(--space-xs) var(--space-sm);
86
+ display: inline-flex;
87
+ align-items: center;
88
+ justify-content: center;
89
+ height: 28px;
90
+ padding: 0 var(--space-sm);
85
91
  border-radius: var(--radius-md);
86
92
  font-size: var(--font-size-sm);
87
93
  font-weight: 500;
@@ -142,11 +148,12 @@
142
148
  padding: var(--space-xs) var(--space-sm);
143
149
  }
144
150
 
145
- /* Modifier tags - consolidated definition */
151
+ /* Modifier tags - 28px height matches badges and tool icons */
146
152
  .modifier {
147
153
  display: inline-flex;
148
154
  align-items: center;
149
- padding: var(--space-xs) var(--space-sm);
155
+ height: 28px;
156
+ padding: 0 var(--space-sm);
150
157
  border-radius: var(--radius-sm);
151
158
  font-size: var(--font-size-sm);
152
159
  font-weight: 600;
@@ -102,4 +102,59 @@
102
102
  background: var(--color-primary-light, rgba(37, 99, 235, 0.1));
103
103
  color: var(--color-primary);
104
104
  }
105
+
106
+ /* Code display - unified component for code/markdown with copy buttons */
107
+ .code-display-container {
108
+ display: flex;
109
+ flex-direction: column;
110
+ gap: var(--space-sm);
111
+ }
112
+
113
+ .code-display-header {
114
+ display: flex;
115
+ justify-content: space-between;
116
+ align-items: center;
117
+ flex-wrap: wrap;
118
+ gap: var(--space-md);
119
+ }
120
+
121
+ .code-display-info {
122
+ display: flex;
123
+ flex-direction: column;
124
+ gap: var(--space-xs);
125
+ flex: 1;
126
+ min-width: 200px;
127
+ }
128
+
129
+ .code-display-info .text-muted {
130
+ margin: 0;
131
+ }
132
+
133
+ .code-display-filename {
134
+ font-family: var(--font-family-mono);
135
+ font-size: var(--font-size-xs);
136
+ color: var(--color-text-muted);
137
+ }
138
+
139
+ .code-display {
140
+ width: 100%;
141
+ margin: 0;
142
+ padding: var(--space-md);
143
+ font-family: var(--font-family-mono);
144
+ font-size: var(--font-size-xs);
145
+ line-height: 1.6;
146
+ background-color: var(--color-surface);
147
+ border: 1px solid var(--color-border);
148
+ border-radius: var(--radius-md);
149
+ overflow: auto;
150
+ color: var(--color-text);
151
+ white-space: pre-wrap;
152
+ word-wrap: break-word;
153
+ }
154
+
155
+ .code-display code {
156
+ background: transparent;
157
+ padding: 0;
158
+ color: inherit;
159
+ }
105
160
  }
@@ -95,6 +95,10 @@
95
95
  grid-template-columns: repeat(3, 1fr);
96
96
  }
97
97
 
98
+ .grid-4 {
99
+ grid-template-columns: repeat(4, 1fr);
100
+ }
101
+
98
102
  .grid-6 {
99
103
  grid-template-columns: repeat(6, 1fr);
100
104
  }
@@ -174,6 +178,10 @@
174
178
  grid-template-columns: repeat(2, 1fr);
175
179
  }
176
180
 
181
+ .grid-4 {
182
+ grid-template-columns: repeat(2, 1fr);
183
+ }
184
+
177
185
  .grid-6 {
178
186
  grid-template-columns: repeat(3, 1fr);
179
187
  }
@@ -198,6 +206,10 @@
198
206
  grid-template-columns: 1fr;
199
207
  }
200
208
 
209
+ .grid-4 {
210
+ grid-template-columns: repeat(2, 1fr);
211
+ }
212
+
201
213
  .grid-6 {
202
214
  grid-template-columns: repeat(2, 1fr);
203
215
  }
@@ -40,6 +40,30 @@
40
40
  font-size: var(--font-size-lg);
41
41
  }
42
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
+
43
67
  .card-description {
44
68
  color: var(--color-text-muted);
45
69
  margin: 0;
@@ -53,6 +77,28 @@
53
77
  margin-top: var(--space-md);
54
78
  }
55
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
+
56
102
  /* Stat cards */
57
103
  .stat-card {
58
104
  background: var(--color-surface);
@@ -100,7 +146,7 @@
100
146
  .section-title {
101
147
  font-size: var(--font-size-xl);
102
148
  font-weight: 600;
103
- margin: 0 0 var(--space-sm);
149
+ margin: 0 0 var(--space-md);
104
150
  color: var(--color-text);
105
151
  }
106
152
 
@@ -187,11 +233,33 @@
187
233
  font-weight: 500;
188
234
  }
189
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
+ */
190
241
  .list-item {
191
- padding: var(--space-sm);
242
+ display: flex;
243
+ align-items: center;
244
+ gap: var(--space-sm);
245
+ min-height: 60px;
246
+ padding: var(--space-md) var(--space-lg);
192
247
  background: var(--color-surface);
193
- border-radius: var(--radius-md);
194
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);
195
263
  }
196
264
 
197
265
  /* Accent borders */
@@ -111,8 +111,7 @@
111
111
 
112
112
  /* Code inline */
113
113
  .code-inline {
114
- font-family:
115
- ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
114
+ font-family: var(--font-family-mono);
116
115
  font-size: 0.9em;
117
116
  background: var(--color-bg);
118
117
  padding: 0.1em 0.4em;
@@ -51,32 +51,12 @@
51
51
  }
52
52
 
53
53
  .agent-section .filename {
54
- font-family:
55
- ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
56
- font-size: var(--font-size-sm);
54
+ font-family: var(--font-family-mono);
55
+ font-size: var(--font-size-xs);
57
56
  color: var(--color-text-muted);
58
57
  margin-bottom: var(--space-sm);
59
58
  }
60
59
 
61
- .agent-section .code-block {
62
- background: var(--color-bg);
63
- border: 1px solid var(--color-border);
64
- border-radius: var(--radius-md);
65
- padding: var(--space-md);
66
- overflow-x: auto;
67
- font-family:
68
- ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
69
- font-size: var(--font-size-sm);
70
- line-height: 1.5;
71
- white-space: pre-wrap;
72
- word-break: break-word;
73
- }
74
-
75
- .agent-section .code-block code {
76
- font-family: inherit;
77
- font-size: inherit;
78
- }
79
-
80
60
  /* Agent cards grid */
81
61
  .agent-cards-grid {
82
62
  display: grid;
@@ -122,24 +102,16 @@
122
102
  font-size: 1.5rem;
123
103
  }
124
104
 
125
- .agent-card-filename {
126
- font-family:
127
- ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
128
- font-size: var(--font-size-sm);
129
- color: var(--color-text-muted);
130
- margin: 0;
131
- padding: 0 var(--space-md);
132
- padding-top: var(--space-sm);
133
- }
134
-
135
105
  .agent-card-preview {
136
106
  padding: var(--space-md);
137
107
  }
138
108
 
139
- .agent-card-preview .code-preview {
109
+ .agent-card-preview .code-display-container {
140
110
  margin: 0;
111
+ }
112
+
113
+ .agent-card-preview .code-display {
141
114
  max-height: 400px;
142
- overflow-y: auto;
143
115
  }
144
116
 
145
117
  /* Skill cards grid */
@@ -170,38 +142,16 @@
170
142
  font-size: var(--font-size-sm);
171
143
  }
172
144
 
173
- .skill-card-filename {
174
- font-family:
175
- ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
176
- font-size: var(--font-size-xs);
177
- color: var(--color-text-muted);
178
- margin: 0;
179
- padding: var(--space-xs) var(--space-md);
180
- }
181
-
182
145
  .skill-card-preview {
183
146
  padding: var(--space-sm) var(--space-md) var(--space-md);
184
147
  }
185
148
 
186
- .skill-card-preview .code-preview {
149
+ .skill-card-preview .code-display-container {
187
150
  margin: 0;
188
- max-height: 300px;
189
- overflow-y: auto;
190
151
  }
191
152
 
192
- /* Code preview */
193
- .code-preview {
194
- background: var(--color-bg);
195
- border: 1px solid var(--color-border);
196
- border-radius: var(--radius-md);
197
- padding: var(--space-sm);
198
- font-family:
199
- ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
200
- font-size: var(--font-size-xs);
201
- line-height: 1.4;
202
- white-space: pre-wrap;
203
- word-break: break-word;
204
- color: var(--color-text-muted);
153
+ .skill-card-preview .code-display {
154
+ max-height: 300px;
205
155
  }
206
156
 
207
157
  .skills-list {
@@ -210,30 +160,6 @@
210
160
  gap: var(--space-md);
211
161
  }
212
162
 
213
- .skill-header {
214
- display: flex;
215
- justify-content: space-between;
216
- align-items: center;
217
- padding: var(--space-sm) var(--space-md);
218
- background: var(--color-bg);
219
- border-bottom: 1px solid var(--color-border);
220
- }
221
-
222
- .skill-filename {
223
- font-family:
224
- ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
225
- font-size: var(--font-size-sm);
226
- color: var(--color-text-muted);
227
- }
228
-
229
- .skill-card .code-block {
230
- margin: 0;
231
- border: none;
232
- border-radius: 0;
233
- max-height: 300px;
234
- overflow-y: auto;
235
- }
236
-
237
163
  /* CLI hint */
238
164
  .cli-hint {
239
165
  background: var(--color-bg);
@@ -243,17 +169,6 @@
243
169
  margin-bottom: var(--space-sm);
244
170
  }
245
171
 
246
- .cli-command {
247
- display: flex;
248
- align-items: flex-start;
249
- gap: var(--space-md);
250
- }
251
-
252
- .cli-command .code-block {
253
- flex: 1;
254
- margin: 0;
255
- }
256
-
257
172
  /* Role agents list */
258
173
  .role-agents-list {
259
174
  display: flex;
@@ -295,9 +210,8 @@
295
210
  }
296
211
 
297
212
  .role-filename {
298
- font-family:
299
- ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace;
300
- font-size: var(--font-size-sm);
213
+ font-family: var(--font-family-mono);
214
+ font-size: var(--font-size-xs);
301
215
  color: var(--color-text-muted);
302
216
  }
303
217
 
@@ -315,11 +229,6 @@
315
229
  margin-bottom: var(--space-sm);
316
230
  }
317
231
 
318
- .role-agent-content .code-block {
319
- max-height: 400px;
320
- overflow-y: auto;
321
- }
322
-
323
232
  /* Stage agent preview */
324
233
  .stage-agent-preview .stage-header {
325
234
  display: flex;
@@ -56,4 +56,64 @@
56
56
  align-items: center;
57
57
  gap: var(--space-xs);
58
58
  }
59
+
60
+ /* Tools table (for skill detail page) */
61
+ .tools-table {
62
+ width: 100%;
63
+ border-collapse: separate;
64
+ border-spacing: 0;
65
+ margin-top: var(--space-md);
66
+ border: 1px solid var(--color-border);
67
+ border-radius: var(--radius-lg);
68
+ overflow: hidden;
69
+ background: var(--color-surface);
70
+ }
71
+
72
+ /*
73
+ * Table cells: 60px row height = 16px padding-top + 28px content + 16px padding-bottom
74
+ * Matches list-item height for visual consistency
75
+ */
76
+ .tools-table th,
77
+ .tools-table td {
78
+ padding: var(--space-md) var(--space-lg);
79
+ text-align: left;
80
+ border-bottom: 1px solid var(--color-border);
81
+ height: 60px;
82
+ }
83
+
84
+ .tools-table th {
85
+ font-weight: 600;
86
+ font-size: var(--font-size-sm);
87
+ color: var(--color-text-secondary);
88
+ background: var(--color-bg);
89
+ text-transform: uppercase;
90
+ letter-spacing: 0.025em;
91
+ }
92
+
93
+ .tools-table th:first-child {
94
+ width: 260px;
95
+ white-space: nowrap;
96
+ }
97
+
98
+ .tools-table td:first-child {
99
+ white-space: nowrap;
100
+ }
101
+
102
+ .tools-table tbody tr:last-child td {
103
+ border-bottom: none;
104
+ }
105
+
106
+ .tools-table tbody tr:hover {
107
+ background: var(--color-bg);
108
+ }
109
+
110
+ /* See all link */
111
+ .see-all-link {
112
+ margin-top: var(--space-md);
113
+ }
114
+
115
+ .see-all-link a {
116
+ color: var(--color-primary);
117
+ font-size: var(--font-size-sm);
118
+ }
59
119
  }