@sienklogic/plan-build-run 2.0.0 → 2.0.2

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 (233) hide show
  1. package/CHANGELOG.md +56 -56
  2. package/CLAUDE.md +149 -149
  3. package/LICENSE +21 -21
  4. package/README.md +247 -247
  5. package/dashboard/bin/cli.js +25 -25
  6. package/dashboard/package.json +34 -34
  7. package/dashboard/public/css/layout.css +406 -406
  8. package/dashboard/public/css/status-colors.css +98 -98
  9. package/dashboard/public/js/htmx-title.js +5 -5
  10. package/dashboard/public/js/sidebar-toggle.js +20 -20
  11. package/dashboard/src/app.js +78 -78
  12. package/dashboard/src/middleware/errorHandler.js +52 -52
  13. package/dashboard/src/middleware/notFoundHandler.js +9 -9
  14. package/dashboard/src/repositories/planning.repository.js +128 -128
  15. package/dashboard/src/routes/events.routes.js +40 -40
  16. package/dashboard/src/routes/index.routes.js +31 -31
  17. package/dashboard/src/routes/pages.routes.js +245 -195
  18. package/dashboard/src/server.js +42 -42
  19. package/dashboard/src/services/dashboard.service.js +222 -222
  20. package/dashboard/src/services/phase.service.js +220 -167
  21. package/dashboard/src/services/project.service.js +57 -57
  22. package/dashboard/src/services/roadmap.service.js +171 -171
  23. package/dashboard/src/services/sse.service.js +58 -58
  24. package/dashboard/src/services/todo.service.js +254 -254
  25. package/dashboard/src/services/watcher.service.js +48 -48
  26. package/dashboard/src/views/coming-soon.ejs +11 -11
  27. package/dashboard/src/views/error.ejs +13 -13
  28. package/dashboard/src/views/index.ejs +5 -5
  29. package/dashboard/src/views/layout.ejs +1 -1
  30. package/dashboard/src/views/partials/dashboard-content.ejs +77 -77
  31. package/dashboard/src/views/partials/footer.ejs +3 -3
  32. package/dashboard/src/views/partials/head.ejs +21 -21
  33. package/dashboard/src/views/partials/header.ejs +12 -12
  34. package/dashboard/src/views/partials/layout-bottom.ejs +15 -15
  35. package/dashboard/src/views/partials/layout-top.ejs +8 -8
  36. package/dashboard/src/views/partials/phase-content.ejs +188 -181
  37. package/dashboard/src/views/partials/phase-doc-content.ejs +38 -0
  38. package/dashboard/src/views/partials/phases-content.ejs +117 -117
  39. package/dashboard/src/views/partials/roadmap-content.ejs +142 -142
  40. package/dashboard/src/views/partials/sidebar.ejs +38 -38
  41. package/dashboard/src/views/partials/todo-create-content.ejs +53 -53
  42. package/dashboard/src/views/partials/todo-detail-content.ejs +38 -38
  43. package/dashboard/src/views/partials/todos-content.ejs +53 -53
  44. package/dashboard/src/views/phase-detail.ejs +5 -5
  45. package/dashboard/src/views/phase-doc.ejs +5 -0
  46. package/dashboard/src/views/phases.ejs +5 -5
  47. package/dashboard/src/views/roadmap.ejs +5 -5
  48. package/dashboard/src/views/todo-create.ejs +5 -5
  49. package/dashboard/src/views/todo-detail.ejs +5 -5
  50. package/dashboard/src/views/todos.ejs +5 -5
  51. package/package.json +57 -57
  52. package/plugins/cursor-pbr/.cursor-plugin/plugin.json +22 -0
  53. package/plugins/cursor-pbr/agents/.gitkeep +0 -0
  54. package/plugins/cursor-pbr/assets/.gitkeep +0 -0
  55. package/plugins/cursor-pbr/hooks/hooks.json +11 -0
  56. package/plugins/cursor-pbr/references/.gitkeep +0 -0
  57. package/plugins/cursor-pbr/rules/.gitkeep +0 -0
  58. package/plugins/cursor-pbr/skills/.gitkeep +0 -0
  59. package/plugins/cursor-pbr/templates/.gitkeep +0 -0
  60. package/plugins/pbr/.claude-plugin/plugin.json +13 -13
  61. package/plugins/pbr/UI-CONSISTENCY-GAPS.md +61 -61
  62. package/plugins/pbr/agents/codebase-mapper.md +279 -271
  63. package/plugins/pbr/agents/debugger.md +281 -281
  64. package/plugins/pbr/agents/executor.md +428 -407
  65. package/plugins/pbr/agents/general.md +164 -164
  66. package/plugins/pbr/agents/integration-checker.md +169 -141
  67. package/plugins/pbr/agents/plan-checker.md +296 -280
  68. package/plugins/pbr/agents/planner.md +358 -358
  69. package/plugins/pbr/agents/researcher.md +363 -363
  70. package/plugins/pbr/agents/synthesizer.md +230 -230
  71. package/plugins/pbr/agents/verifier.md +489 -454
  72. package/plugins/pbr/commands/begin.md +5 -5
  73. package/plugins/pbr/commands/build.md +5 -5
  74. package/plugins/pbr/commands/config.md +5 -5
  75. package/plugins/pbr/commands/continue.md +5 -5
  76. package/plugins/pbr/commands/debug.md +5 -5
  77. package/plugins/pbr/commands/discuss.md +5 -5
  78. package/plugins/pbr/commands/explore.md +5 -5
  79. package/plugins/pbr/commands/health.md +5 -5
  80. package/plugins/pbr/commands/help.md +5 -5
  81. package/plugins/pbr/commands/import.md +5 -5
  82. package/plugins/pbr/commands/milestone.md +5 -5
  83. package/plugins/pbr/commands/note.md +5 -5
  84. package/plugins/pbr/commands/pause.md +5 -5
  85. package/plugins/pbr/commands/plan.md +5 -5
  86. package/plugins/pbr/commands/quick.md +5 -5
  87. package/plugins/pbr/commands/resume.md +5 -5
  88. package/plugins/pbr/commands/review.md +5 -5
  89. package/plugins/pbr/commands/scan.md +5 -5
  90. package/plugins/pbr/commands/setup.md +5 -5
  91. package/plugins/pbr/commands/status.md +5 -5
  92. package/plugins/pbr/commands/todo.md +5 -5
  93. package/plugins/pbr/contexts/dev.md +27 -27
  94. package/plugins/pbr/contexts/research.md +28 -28
  95. package/plugins/pbr/contexts/review.md +36 -36
  96. package/plugins/pbr/hooks/hooks.json +183 -183
  97. package/plugins/pbr/references/agent-anti-patterns.md +24 -24
  98. package/plugins/pbr/references/agent-interactions.md +134 -134
  99. package/plugins/pbr/references/agent-teams.md +54 -54
  100. package/plugins/pbr/references/checkpoints.md +157 -157
  101. package/plugins/pbr/references/common-bug-patterns.md +13 -13
  102. package/plugins/pbr/references/config-reference.md +441 -0
  103. package/plugins/pbr/references/continuation-format.md +212 -212
  104. package/plugins/pbr/references/deviation-rules.md +112 -112
  105. package/plugins/pbr/references/git-integration.md +226 -226
  106. package/plugins/pbr/references/integration-patterns.md +117 -117
  107. package/plugins/pbr/references/model-profiles.md +99 -99
  108. package/plugins/pbr/references/model-selection.md +31 -31
  109. package/plugins/pbr/references/pbr-rules.md +193 -193
  110. package/plugins/pbr/references/plan-authoring.md +181 -181
  111. package/plugins/pbr/references/plan-format.md +287 -283
  112. package/plugins/pbr/references/planning-config.md +213 -213
  113. package/plugins/pbr/references/questioning.md +214 -214
  114. package/plugins/pbr/references/reading-verification.md +127 -127
  115. package/plugins/pbr/references/stub-patterns.md +160 -160
  116. package/plugins/pbr/references/subagent-coordination.md +119 -119
  117. package/plugins/pbr/references/ui-formatting.md +461 -399
  118. package/plugins/pbr/references/verification-patterns.md +198 -198
  119. package/plugins/pbr/references/wave-execution.md +95 -95
  120. package/plugins/pbr/scripts/auto-continue.js +80 -80
  121. package/plugins/pbr/scripts/check-dangerous-commands.js +136 -136
  122. package/plugins/pbr/scripts/check-doc-sprawl.js +102 -102
  123. package/plugins/pbr/scripts/check-phase-boundary.js +196 -196
  124. package/plugins/pbr/scripts/check-plan-format.js +270 -270
  125. package/plugins/pbr/scripts/check-roadmap-sync.js +322 -252
  126. package/plugins/pbr/scripts/check-skill-workflow.js +262 -262
  127. package/plugins/pbr/scripts/check-state-sync.js +476 -476
  128. package/plugins/pbr/scripts/check-subagent-output.js +144 -144
  129. package/plugins/pbr/scripts/config-schema.json +251 -251
  130. package/plugins/pbr/scripts/context-budget-check.js +287 -287
  131. package/plugins/pbr/scripts/event-handler.js +151 -151
  132. package/plugins/pbr/scripts/event-logger.js +92 -92
  133. package/plugins/pbr/scripts/hook-logger.js +80 -76
  134. package/plugins/pbr/scripts/hooks-schema.json +79 -79
  135. package/plugins/pbr/scripts/log-subagent.js +164 -152
  136. package/plugins/pbr/scripts/log-tool-failure.js +88 -88
  137. package/plugins/pbr/scripts/pbr-tools.js +1378 -1301
  138. package/plugins/pbr/scripts/post-write-dispatch.js +66 -66
  139. package/plugins/pbr/scripts/post-write-quality.js +207 -207
  140. package/plugins/pbr/scripts/pre-bash-dispatch.js +86 -56
  141. package/plugins/pbr/scripts/pre-write-dispatch.js +97 -62
  142. package/plugins/pbr/scripts/progress-tracker.js +281 -228
  143. package/plugins/pbr/scripts/run-hook.js +92 -0
  144. package/plugins/pbr/scripts/session-cleanup.js +254 -254
  145. package/plugins/pbr/scripts/status-line.js +288 -285
  146. package/plugins/pbr/scripts/suggest-compact.js +119 -119
  147. package/plugins/pbr/scripts/task-completed.js +45 -45
  148. package/plugins/pbr/scripts/track-context-budget.js +149 -119
  149. package/plugins/pbr/scripts/validate-commit.js +200 -200
  150. package/plugins/pbr/scripts/validate-plugin-structure.js +183 -172
  151. package/plugins/pbr/scripts/validate-task.js +106 -0
  152. package/plugins/pbr/skills/begin/SKILL.md +594 -545
  153. package/plugins/pbr/skills/begin/templates/PROJECT.md.tmpl +33 -33
  154. package/plugins/pbr/skills/begin/templates/REQUIREMENTS.md.tmpl +18 -18
  155. package/plugins/pbr/skills/begin/templates/STATE.md.tmpl +49 -49
  156. package/plugins/pbr/skills/begin/templates/config.json.tmpl +64 -63
  157. package/plugins/pbr/skills/begin/templates/researcher-prompt.md.tmpl +19 -19
  158. package/plugins/pbr/skills/begin/templates/roadmap-prompt.md.tmpl +30 -30
  159. package/plugins/pbr/skills/begin/templates/synthesis-prompt.md.tmpl +16 -16
  160. package/plugins/pbr/skills/build/SKILL.md +943 -962
  161. package/plugins/pbr/skills/config/SKILL.md +256 -241
  162. package/plugins/pbr/skills/continue/SKILL.md +164 -127
  163. package/plugins/pbr/skills/debug/SKILL.md +515 -489
  164. package/plugins/pbr/skills/debug/templates/continuation-prompt.md.tmpl +16 -16
  165. package/plugins/pbr/skills/debug/templates/initial-investigation-prompt.md.tmpl +27 -27
  166. package/plugins/pbr/skills/discuss/SKILL.md +347 -338
  167. package/plugins/pbr/skills/discuss/templates/CONTEXT.md.tmpl +61 -61
  168. package/plugins/pbr/skills/discuss/templates/decision-categories.md +9 -9
  169. package/plugins/pbr/skills/explore/SKILL.md +378 -362
  170. package/plugins/pbr/skills/health/SKILL.md +221 -186
  171. package/plugins/pbr/skills/health/templates/check-pattern.md.tmpl +30 -30
  172. package/plugins/pbr/skills/health/templates/output-format.md.tmpl +63 -63
  173. package/plugins/pbr/skills/help/SKILL.md +155 -140
  174. package/plugins/pbr/skills/import/SKILL.md +504 -490
  175. package/plugins/pbr/skills/milestone/SKILL.md +704 -673
  176. package/plugins/pbr/skills/milestone/templates/audit-report.md.tmpl +48 -48
  177. package/plugins/pbr/skills/milestone/templates/stats-file.md.tmpl +30 -30
  178. package/plugins/pbr/skills/note/SKILL.md +231 -212
  179. package/plugins/pbr/skills/pause/SKILL.md +249 -235
  180. package/plugins/pbr/skills/pause/templates/continue-here.md.tmpl +71 -71
  181. package/plugins/pbr/skills/plan/SKILL.md +685 -628
  182. package/plugins/pbr/skills/plan/decimal-phase-calc.md +98 -98
  183. package/plugins/pbr/skills/plan/templates/checker-prompt.md.tmpl +21 -21
  184. package/plugins/pbr/skills/plan/templates/gap-closure-prompt.md.tmpl +32 -32
  185. package/plugins/pbr/skills/plan/templates/planner-prompt.md.tmpl +38 -38
  186. package/plugins/pbr/skills/plan/templates/researcher-prompt.md.tmpl +19 -19
  187. package/plugins/pbr/skills/plan/templates/revision-prompt.md.tmpl +23 -23
  188. package/plugins/pbr/skills/quick/SKILL.md +354 -335
  189. package/plugins/pbr/skills/resume/SKILL.md +402 -388
  190. package/plugins/pbr/skills/review/SKILL.md +686 -652
  191. package/plugins/pbr/skills/review/templates/debugger-prompt.md.tmpl +60 -60
  192. package/plugins/pbr/skills/review/templates/gap-planner-prompt.md.tmpl +40 -40
  193. package/plugins/pbr/skills/review/templates/verifier-prompt.md.tmpl +115 -115
  194. package/plugins/pbr/skills/scan/SKILL.md +304 -269
  195. package/plugins/pbr/skills/scan/templates/mapper-prompt.md.tmpl +201 -201
  196. package/plugins/pbr/skills/setup/SKILL.md +253 -227
  197. package/plugins/pbr/skills/shared/commit-planning-docs.md +35 -35
  198. package/plugins/pbr/skills/shared/config-loading.md +102 -102
  199. package/plugins/pbr/skills/shared/context-budget.md +40 -40
  200. package/plugins/pbr/skills/shared/context-loader-task.md +86 -86
  201. package/plugins/pbr/skills/shared/digest-select.md +79 -79
  202. package/plugins/pbr/skills/shared/domain-probes.md +125 -125
  203. package/plugins/pbr/skills/shared/error-reporting.md +79 -79
  204. package/plugins/pbr/skills/shared/gate-prompts.md +388 -388
  205. package/plugins/pbr/skills/shared/phase-argument-parsing.md +45 -45
  206. package/plugins/pbr/skills/shared/progress-display.md +53 -53
  207. package/plugins/pbr/skills/shared/revision-loop.md +81 -81
  208. package/plugins/pbr/skills/shared/state-loading.md +62 -62
  209. package/plugins/pbr/skills/shared/state-update.md +161 -161
  210. package/plugins/pbr/skills/shared/universal-anti-patterns.md +33 -33
  211. package/plugins/pbr/skills/status/SKILL.md +367 -353
  212. package/plugins/pbr/skills/todo/SKILL.md +198 -181
  213. package/plugins/pbr/templates/CONTEXT.md.tmpl +52 -52
  214. package/plugins/pbr/templates/INTEGRATION-REPORT.md.tmpl +151 -151
  215. package/plugins/pbr/templates/RESEARCH-SUMMARY.md.tmpl +97 -97
  216. package/plugins/pbr/templates/ROADMAP.md.tmpl +40 -40
  217. package/plugins/pbr/templates/SUMMARY.md.tmpl +81 -81
  218. package/plugins/pbr/templates/VERIFICATION-DETAIL.md.tmpl +116 -116
  219. package/plugins/pbr/templates/codebase/ARCHITECTURE.md.tmpl +98 -98
  220. package/plugins/pbr/templates/codebase/CONCERNS.md.tmpl +93 -93
  221. package/plugins/pbr/templates/codebase/CONVENTIONS.md.tmpl +104 -104
  222. package/plugins/pbr/templates/codebase/INTEGRATIONS.md.tmpl +78 -78
  223. package/plugins/pbr/templates/codebase/STACK.md.tmpl +78 -78
  224. package/plugins/pbr/templates/codebase/STRUCTURE.md.tmpl +80 -80
  225. package/plugins/pbr/templates/codebase/TESTING.md.tmpl +107 -107
  226. package/plugins/pbr/templates/continue-here.md.tmpl +73 -73
  227. package/plugins/pbr/templates/prompt-partials/phase-project-context.md.tmpl +37 -37
  228. package/plugins/pbr/templates/research/ARCHITECTURE.md.tmpl +124 -124
  229. package/plugins/pbr/templates/research/STACK.md.tmpl +71 -71
  230. package/plugins/pbr/templates/research/SUMMARY.md.tmpl +112 -112
  231. package/plugins/pbr/templates/research-outputs/phase-research.md.tmpl +81 -81
  232. package/plugins/pbr/templates/research-outputs/project-research.md.tmpl +99 -99
  233. package/plugins/pbr/templates/research-outputs/synthesis.md.tmpl +36 -36
@@ -1,406 +1,406 @@
1
- /* ============================================
2
- Towline Dashboard — Layout & Typography
3
- ============================================ */
4
-
5
- /* --- Custom Properties --- */
6
- :root {
7
- --sidebar-width: 220px;
8
- --header-height: 3.5rem;
9
- --content-max-width: 960px;
10
- --font-sans: 'Inter', system-ui, -apple-system, sans-serif;
11
- --font-mono: 'JetBrains Mono', ui-monospace, 'Cascadia Code', 'Fira Code', monospace;
12
- --space-xs: 0.25rem;
13
- --space-sm: 0.5rem;
14
- --space-md: 1rem;
15
- --space-lg: 1.5rem;
16
- --space-xl: 2rem;
17
- --space-2xl: 3rem;
18
- --radius-sm: 0.375rem;
19
- --radius-md: 0.5rem;
20
- --border-subtle: rgba(255, 255, 255, 0.08);
21
- --bg-surface: rgba(255, 255, 255, 0.03);
22
- --bg-surface-hover: rgba(255, 255, 255, 0.06);
23
- --text-dim: rgba(255, 255, 255, 0.5);
24
- }
25
-
26
- /* --- Typography Override --- */
27
- html {
28
- font-family: var(--font-sans);
29
- font-size: 15px;
30
- letter-spacing: -0.01em;
31
- }
32
-
33
- code, pre, kbd, samp {
34
- font-family: var(--font-mono);
35
- font-size: 0.875em;
36
- }
37
-
38
- h1 { font-size: 1.75rem; font-weight: 700; letter-spacing: -0.025em; margin-bottom: var(--space-sm); }
39
- h2 { font-size: 1.35rem; font-weight: 600; letter-spacing: -0.02em; margin-top: var(--space-2xl); margin-bottom: var(--space-md); }
40
- h3 { font-size: 1.1rem; font-weight: 600; }
41
-
42
- p { line-height: 1.65; }
43
-
44
- small { font-size: 0.8125rem; color: var(--text-dim); }
45
-
46
- /* --- Page Grid Layout --- */
47
- .page-wrapper {
48
- display: grid;
49
- gap: 0;
50
- grid-template-columns: var(--sidebar-width) 1fr;
51
- grid-template-rows: var(--header-height) 1fr auto;
52
- grid-template-areas:
53
- "header header"
54
- "sidebar content"
55
- "footer footer";
56
- min-height: 100vh;
57
- }
58
-
59
- /* --- Header --- */
60
- .page-wrapper > header {
61
- grid-area: header;
62
- display: flex;
63
- align-items: center;
64
- padding: 0 var(--space-xl);
65
- border-bottom: 1px solid var(--border-subtle);
66
- background: var(--bg-surface);
67
- backdrop-filter: blur(8px);
68
- position: sticky;
69
- top: 0;
70
- z-index: 10;
71
- }
72
-
73
- .page-wrapper > header nav {
74
- display: flex;
75
- justify-content: space-between;
76
- align-items: center;
77
- width: 100%;
78
- margin: 0;
79
- padding: 0;
80
- }
81
-
82
- .page-wrapper > header nav strong {
83
- font-size: 1rem;
84
- font-weight: 600;
85
- letter-spacing: -0.02em;
86
- white-space: nowrap;
87
- }
88
-
89
- .page-wrapper > header nav ul {
90
- list-style: none;
91
- margin: 0;
92
- padding: 0;
93
- }
94
-
95
- /* --- Sidebar --- */
96
- .page-wrapper > aside.sidebar {
97
- grid-area: sidebar;
98
- padding: var(--space-lg) 0;
99
- border-right: 1px solid var(--border-subtle);
100
- background: var(--bg-surface);
101
- position: sticky;
102
- top: var(--header-height);
103
- height: calc(100vh - var(--header-height));
104
- overflow-y: auto;
105
- }
106
-
107
- aside.sidebar nav ul {
108
- list-style: none;
109
- padding: 0;
110
- margin: 0;
111
- }
112
-
113
- aside.sidebar nav li {
114
- margin: 0;
115
- padding: 0;
116
- }
117
-
118
- aside.sidebar nav a {
119
- display: flex;
120
- align-items: center;
121
- padding: 0.6rem var(--space-lg);
122
- text-decoration: none;
123
- border-left: 3px solid transparent;
124
- font-size: 0.9rem;
125
- font-weight: 500;
126
- color: var(--text-dim);
127
- transition: all 0.15s ease;
128
- }
129
-
130
- aside.sidebar nav a:hover {
131
- color: var(--pico-color);
132
- background: var(--bg-surface-hover);
133
- border-left-color: rgba(255, 255, 255, 0.15);
134
- }
135
-
136
- aside.sidebar nav a[aria-current="page"] {
137
- font-weight: 600;
138
- color: var(--pico-primary);
139
- border-left-color: var(--pico-primary);
140
- background: var(--bg-surface-hover);
141
- }
142
-
143
- /* --- Main Content --- */
144
- .page-wrapper > main {
145
- grid-area: content;
146
- padding: var(--space-xl) var(--space-2xl);
147
- overflow-y: auto;
148
- max-width: calc(var(--content-max-width) + var(--space-2xl) * 2);
149
- }
150
-
151
- /* --- Footer --- */
152
- .page-wrapper > footer {
153
- grid-area: footer;
154
- padding: var(--space-md) var(--space-xl);
155
- border-top: 1px solid var(--border-subtle);
156
- text-align: center;
157
- }
158
-
159
- .page-wrapper > footer small {
160
- font-size: 0.75rem;
161
- color: var(--text-dim);
162
- }
163
-
164
- /* --- Article Cards --- */
165
- article {
166
- border: 1px solid var(--border-subtle);
167
- border-radius: var(--radius-md);
168
- background: var(--bg-surface);
169
- margin-bottom: var(--space-lg);
170
- }
171
-
172
- article > header {
173
- border-bottom: 1px solid var(--border-subtle);
174
- padding: var(--space-md) var(--space-lg);
175
- background: rgba(255, 255, 255, 0.02);
176
- border-radius: var(--radius-md) var(--radius-md) 0 0;
177
- }
178
-
179
- article > header strong {
180
- font-size: 0.95rem;
181
- font-weight: 600;
182
- }
183
-
184
- /* --- Tables --- */
185
- .table-wrap {
186
- overflow-x: auto;
187
- -webkit-overflow-scrolling: touch;
188
- margin: 0 calc(-1 * var(--space-lg));
189
- padding: 0 var(--space-lg);
190
- }
191
-
192
- table {
193
- font-size: 0.875rem;
194
- border-collapse: collapse;
195
- width: 100%;
196
- }
197
-
198
- th {
199
- font-weight: 600;
200
- font-size: 0.8125rem;
201
- text-transform: uppercase;
202
- letter-spacing: 0.04em;
203
- color: var(--text-dim);
204
- white-space: nowrap;
205
- }
206
-
207
- td {
208
- vertical-align: top;
209
- line-height: 1.5;
210
- }
211
-
212
- /* --- Progress Bar --- */
213
- progress {
214
- height: 0.5rem;
215
- border-radius: 999px;
216
- }
217
-
218
- progress::-webkit-progress-bar {
219
- background: rgba(255, 255, 255, 0.08);
220
- border-radius: 999px;
221
- }
222
-
223
- progress::-webkit-progress-value {
224
- background: var(--pico-primary);
225
- border-radius: 999px;
226
- transition: width 0.4s ease;
227
- }
228
-
229
- progress::-moz-progress-bar {
230
- background: var(--pico-primary);
231
- border-radius: 999px;
232
- }
233
-
234
- /* --- Details/Summary --- */
235
- details {
236
- margin: var(--space-sm) 0;
237
- border: none;
238
- }
239
-
240
- details summary {
241
- font-size: 0.875rem;
242
- font-weight: 500;
243
- cursor: pointer;
244
- padding: var(--space-xs) 0;
245
- color: var(--pico-primary);
246
- }
247
-
248
- details summary:hover {
249
- text-decoration: underline;
250
- }
251
-
252
- details ul {
253
- margin-top: var(--space-xs);
254
- padding-left: var(--space-lg);
255
- }
256
-
257
- details li {
258
- font-size: 0.875rem;
259
- line-height: 1.6;
260
- }
261
-
262
- /* --- Inline Code --- */
263
- :not(pre) > code {
264
- font-size: 0.8125em;
265
- padding: 0.15em 0.4em;
266
- border-radius: var(--radius-sm);
267
- background: rgba(255, 255, 255, 0.06);
268
- }
269
-
270
- /* --- Back Link --- */
271
- main > p:first-of-type > a[href="/"] {
272
- font-size: 0.875rem;
273
- color: var(--text-dim);
274
- text-decoration: none;
275
- }
276
-
277
- main > p:first-of-type > a[href="/"]:hover {
278
- color: var(--pico-primary);
279
- }
280
-
281
- /* --- SSE Connection Status --- */
282
- #sse-status {
283
- display: inline-block;
284
- width: 8px;
285
- height: 8px;
286
- border-radius: 50%;
287
- margin-left: var(--space-sm);
288
- vertical-align: middle;
289
- transition: background-color 0.3s ease;
290
- }
291
-
292
- #sse-status[data-connected="true"] {
293
- background-color: var(--status-complete);
294
- }
295
-
296
- #sse-status[data-connected="false"] {
297
- background-color: var(--status-not-started);
298
- }
299
-
300
- /* --- Mobile hamburger toggle --- */
301
- .sidebar-toggle {
302
- display: none;
303
- background: none;
304
- border: 1px solid var(--border-subtle);
305
- border-radius: var(--radius-sm);
306
- color: var(--pico-color);
307
- font-size: 1.25rem;
308
- padding: 0.25rem 0.5rem;
309
- cursor: pointer;
310
- line-height: 1;
311
- }
312
-
313
- /* ============================================
314
- Responsive Breakpoints
315
- ============================================ */
316
-
317
- /* Tablet: narrower sidebar */
318
- @media (max-width: 1024px) {
319
- :root {
320
- --sidebar-width: 180px;
321
- }
322
-
323
- .page-wrapper > main {
324
- padding: var(--space-lg) var(--space-xl);
325
- }
326
- }
327
-
328
- /* Mobile: sidebar collapses to top nav */
329
- @media (max-width: 768px) {
330
- .page-wrapper {
331
- grid-template-columns: 1fr;
332
- grid-template-rows: var(--header-height) auto 1fr auto;
333
- grid-template-areas:
334
- "header"
335
- "sidebar"
336
- "content"
337
- "footer";
338
- }
339
-
340
- .sidebar-toggle {
341
- display: block;
342
- }
343
-
344
- .page-wrapper > aside.sidebar {
345
- position: static;
346
- height: auto;
347
- border-right: none;
348
- border-bottom: 1px solid var(--border-subtle);
349
- padding: 0;
350
- overflow: visible;
351
- display: none;
352
- }
353
-
354
- .page-wrapper > aside.sidebar.open {
355
- display: block;
356
- }
357
-
358
- aside.sidebar nav ul {
359
- display: flex;
360
- flex-wrap: wrap;
361
- gap: 0;
362
- padding: var(--space-sm) var(--space-md);
363
- }
364
-
365
- aside.sidebar nav a {
366
- border-left: none;
367
- border-bottom: 2px solid transparent;
368
- padding: var(--space-sm) var(--space-md);
369
- font-size: 0.85rem;
370
- }
371
-
372
- aside.sidebar nav a[aria-current="page"] {
373
- border-left: none;
374
- border-bottom-color: var(--pico-primary);
375
- }
376
-
377
- aside.sidebar nav a:hover {
378
- border-left: none;
379
- }
380
-
381
- .page-wrapper > main {
382
- padding: var(--space-lg) var(--space-md);
383
- }
384
-
385
- h1 { font-size: 1.4rem; }
386
- h2 { font-size: 1.15rem; }
387
-
388
- table {
389
- font-size: 0.8125rem;
390
- }
391
- }
392
-
393
- /* Small mobile */
394
- @media (max-width: 480px) {
395
- html {
396
- font-size: 14px;
397
- }
398
-
399
- .page-wrapper > main {
400
- padding: var(--space-md);
401
- }
402
-
403
- article > header {
404
- padding: var(--space-sm) var(--space-md);
405
- }
406
- }
1
+ /* ============================================
2
+ Towline Dashboard — Layout & Typography
3
+ ============================================ */
4
+
5
+ /* --- Custom Properties --- */
6
+ :root {
7
+ --sidebar-width: 220px;
8
+ --header-height: 3.5rem;
9
+ --content-max-width: 960px;
10
+ --font-sans: 'Inter', system-ui, -apple-system, sans-serif;
11
+ --font-mono: 'JetBrains Mono', ui-monospace, 'Cascadia Code', 'Fira Code', monospace;
12
+ --space-xs: 0.25rem;
13
+ --space-sm: 0.5rem;
14
+ --space-md: 1rem;
15
+ --space-lg: 1.5rem;
16
+ --space-xl: 2rem;
17
+ --space-2xl: 3rem;
18
+ --radius-sm: 0.375rem;
19
+ --radius-md: 0.5rem;
20
+ --border-subtle: rgba(255, 255, 255, 0.08);
21
+ --bg-surface: rgba(255, 255, 255, 0.03);
22
+ --bg-surface-hover: rgba(255, 255, 255, 0.06);
23
+ --text-dim: rgba(255, 255, 255, 0.5);
24
+ }
25
+
26
+ /* --- Typography Override --- */
27
+ html {
28
+ font-family: var(--font-sans);
29
+ font-size: 15px;
30
+ letter-spacing: -0.01em;
31
+ }
32
+
33
+ code, pre, kbd, samp {
34
+ font-family: var(--font-mono);
35
+ font-size: 0.875em;
36
+ }
37
+
38
+ h1 { font-size: 1.75rem; font-weight: 700; letter-spacing: -0.025em; margin-bottom: var(--space-sm); }
39
+ h2 { font-size: 1.35rem; font-weight: 600; letter-spacing: -0.02em; margin-top: var(--space-2xl); margin-bottom: var(--space-md); }
40
+ h3 { font-size: 1.1rem; font-weight: 600; }
41
+
42
+ p { line-height: 1.65; }
43
+
44
+ small { font-size: 0.8125rem; color: var(--text-dim); }
45
+
46
+ /* --- Page Grid Layout --- */
47
+ .page-wrapper {
48
+ display: grid;
49
+ gap: 0;
50
+ grid-template-columns: var(--sidebar-width) 1fr;
51
+ grid-template-rows: var(--header-height) 1fr auto;
52
+ grid-template-areas:
53
+ "header header"
54
+ "sidebar content"
55
+ "footer footer";
56
+ min-height: 100vh;
57
+ }
58
+
59
+ /* --- Header --- */
60
+ .page-wrapper > header {
61
+ grid-area: header;
62
+ display: flex;
63
+ align-items: center;
64
+ padding: 0 var(--space-xl);
65
+ border-bottom: 1px solid var(--border-subtle);
66
+ background: var(--bg-surface);
67
+ backdrop-filter: blur(8px);
68
+ position: sticky;
69
+ top: 0;
70
+ z-index: 10;
71
+ }
72
+
73
+ .page-wrapper > header nav {
74
+ display: flex;
75
+ justify-content: space-between;
76
+ align-items: center;
77
+ width: 100%;
78
+ margin: 0;
79
+ padding: 0;
80
+ }
81
+
82
+ .page-wrapper > header nav strong {
83
+ font-size: 1rem;
84
+ font-weight: 600;
85
+ letter-spacing: -0.02em;
86
+ white-space: nowrap;
87
+ }
88
+
89
+ .page-wrapper > header nav ul {
90
+ list-style: none;
91
+ margin: 0;
92
+ padding: 0;
93
+ }
94
+
95
+ /* --- Sidebar --- */
96
+ .page-wrapper > aside.sidebar {
97
+ grid-area: sidebar;
98
+ padding: var(--space-lg) 0;
99
+ border-right: 1px solid var(--border-subtle);
100
+ background: var(--bg-surface);
101
+ position: sticky;
102
+ top: var(--header-height);
103
+ height: calc(100vh - var(--header-height));
104
+ overflow-y: auto;
105
+ }
106
+
107
+ aside.sidebar nav ul {
108
+ list-style: none;
109
+ padding: 0;
110
+ margin: 0;
111
+ }
112
+
113
+ aside.sidebar nav li {
114
+ margin: 0;
115
+ padding: 0;
116
+ }
117
+
118
+ aside.sidebar nav a {
119
+ display: flex;
120
+ align-items: center;
121
+ padding: 0.6rem var(--space-lg);
122
+ text-decoration: none;
123
+ border-left: 3px solid transparent;
124
+ font-size: 0.9rem;
125
+ font-weight: 500;
126
+ color: var(--text-dim);
127
+ transition: all 0.15s ease;
128
+ }
129
+
130
+ aside.sidebar nav a:hover {
131
+ color: var(--pico-color);
132
+ background: var(--bg-surface-hover);
133
+ border-left-color: rgba(255, 255, 255, 0.15);
134
+ }
135
+
136
+ aside.sidebar nav a[aria-current="page"] {
137
+ font-weight: 600;
138
+ color: var(--pico-primary);
139
+ border-left-color: var(--pico-primary);
140
+ background: var(--bg-surface-hover);
141
+ }
142
+
143
+ /* --- Main Content --- */
144
+ .page-wrapper > main {
145
+ grid-area: content;
146
+ padding: var(--space-xl) var(--space-2xl);
147
+ overflow-y: auto;
148
+ max-width: calc(var(--content-max-width) + var(--space-2xl) * 2);
149
+ }
150
+
151
+ /* --- Footer --- */
152
+ .page-wrapper > footer {
153
+ grid-area: footer;
154
+ padding: var(--space-md) var(--space-xl);
155
+ border-top: 1px solid var(--border-subtle);
156
+ text-align: center;
157
+ }
158
+
159
+ .page-wrapper > footer small {
160
+ font-size: 0.75rem;
161
+ color: var(--text-dim);
162
+ }
163
+
164
+ /* --- Article Cards --- */
165
+ article {
166
+ border: 1px solid var(--border-subtle);
167
+ border-radius: var(--radius-md);
168
+ background: var(--bg-surface);
169
+ margin-bottom: var(--space-lg);
170
+ }
171
+
172
+ article > header {
173
+ border-bottom: 1px solid var(--border-subtle);
174
+ padding: var(--space-md) var(--space-lg);
175
+ background: rgba(255, 255, 255, 0.02);
176
+ border-radius: var(--radius-md) var(--radius-md) 0 0;
177
+ }
178
+
179
+ article > header strong {
180
+ font-size: 0.95rem;
181
+ font-weight: 600;
182
+ }
183
+
184
+ /* --- Tables --- */
185
+ .table-wrap {
186
+ overflow-x: auto;
187
+ -webkit-overflow-scrolling: touch;
188
+ margin: 0 calc(-1 * var(--space-lg));
189
+ padding: 0 var(--space-lg);
190
+ }
191
+
192
+ table {
193
+ font-size: 0.875rem;
194
+ border-collapse: collapse;
195
+ width: 100%;
196
+ }
197
+
198
+ th {
199
+ font-weight: 600;
200
+ font-size: 0.8125rem;
201
+ text-transform: uppercase;
202
+ letter-spacing: 0.04em;
203
+ color: var(--text-dim);
204
+ white-space: nowrap;
205
+ }
206
+
207
+ td {
208
+ vertical-align: top;
209
+ line-height: 1.5;
210
+ }
211
+
212
+ /* --- Progress Bar --- */
213
+ progress {
214
+ height: 0.5rem;
215
+ border-radius: 999px;
216
+ }
217
+
218
+ progress::-webkit-progress-bar {
219
+ background: rgba(255, 255, 255, 0.08);
220
+ border-radius: 999px;
221
+ }
222
+
223
+ progress::-webkit-progress-value {
224
+ background: var(--pico-primary);
225
+ border-radius: 999px;
226
+ transition: width 0.4s ease;
227
+ }
228
+
229
+ progress::-moz-progress-bar {
230
+ background: var(--pico-primary);
231
+ border-radius: 999px;
232
+ }
233
+
234
+ /* --- Details/Summary --- */
235
+ details {
236
+ margin: var(--space-sm) 0;
237
+ border: none;
238
+ }
239
+
240
+ details summary {
241
+ font-size: 0.875rem;
242
+ font-weight: 500;
243
+ cursor: pointer;
244
+ padding: var(--space-xs) 0;
245
+ color: var(--pico-primary);
246
+ }
247
+
248
+ details summary:hover {
249
+ text-decoration: underline;
250
+ }
251
+
252
+ details ul {
253
+ margin-top: var(--space-xs);
254
+ padding-left: var(--space-lg);
255
+ }
256
+
257
+ details li {
258
+ font-size: 0.875rem;
259
+ line-height: 1.6;
260
+ }
261
+
262
+ /* --- Inline Code --- */
263
+ :not(pre) > code {
264
+ font-size: 0.8125em;
265
+ padding: 0.15em 0.4em;
266
+ border-radius: var(--radius-sm);
267
+ background: rgba(255, 255, 255, 0.06);
268
+ }
269
+
270
+ /* --- Back Link --- */
271
+ main > p:first-of-type > a[href="/"] {
272
+ font-size: 0.875rem;
273
+ color: var(--text-dim);
274
+ text-decoration: none;
275
+ }
276
+
277
+ main > p:first-of-type > a[href="/"]:hover {
278
+ color: var(--pico-primary);
279
+ }
280
+
281
+ /* --- SSE Connection Status --- */
282
+ #sse-status {
283
+ display: inline-block;
284
+ width: 8px;
285
+ height: 8px;
286
+ border-radius: 50%;
287
+ margin-left: var(--space-sm);
288
+ vertical-align: middle;
289
+ transition: background-color 0.3s ease;
290
+ }
291
+
292
+ #sse-status[data-connected="true"] {
293
+ background-color: var(--status-complete);
294
+ }
295
+
296
+ #sse-status[data-connected="false"] {
297
+ background-color: var(--status-not-started);
298
+ }
299
+
300
+ /* --- Mobile hamburger toggle --- */
301
+ .sidebar-toggle {
302
+ display: none;
303
+ background: none;
304
+ border: 1px solid var(--border-subtle);
305
+ border-radius: var(--radius-sm);
306
+ color: var(--pico-color);
307
+ font-size: 1.25rem;
308
+ padding: 0.25rem 0.5rem;
309
+ cursor: pointer;
310
+ line-height: 1;
311
+ }
312
+
313
+ /* ============================================
314
+ Responsive Breakpoints
315
+ ============================================ */
316
+
317
+ /* Tablet: narrower sidebar */
318
+ @media (max-width: 1024px) {
319
+ :root {
320
+ --sidebar-width: 180px;
321
+ }
322
+
323
+ .page-wrapper > main {
324
+ padding: var(--space-lg) var(--space-xl);
325
+ }
326
+ }
327
+
328
+ /* Mobile: sidebar collapses to top nav */
329
+ @media (max-width: 768px) {
330
+ .page-wrapper {
331
+ grid-template-columns: 1fr;
332
+ grid-template-rows: var(--header-height) auto 1fr auto;
333
+ grid-template-areas:
334
+ "header"
335
+ "sidebar"
336
+ "content"
337
+ "footer";
338
+ }
339
+
340
+ .sidebar-toggle {
341
+ display: block;
342
+ }
343
+
344
+ .page-wrapper > aside.sidebar {
345
+ position: static;
346
+ height: auto;
347
+ border-right: none;
348
+ border-bottom: 1px solid var(--border-subtle);
349
+ padding: 0;
350
+ overflow: visible;
351
+ display: none;
352
+ }
353
+
354
+ .page-wrapper > aside.sidebar.open {
355
+ display: block;
356
+ }
357
+
358
+ aside.sidebar nav ul {
359
+ display: flex;
360
+ flex-wrap: wrap;
361
+ gap: 0;
362
+ padding: var(--space-sm) var(--space-md);
363
+ }
364
+
365
+ aside.sidebar nav a {
366
+ border-left: none;
367
+ border-bottom: 2px solid transparent;
368
+ padding: var(--space-sm) var(--space-md);
369
+ font-size: 0.85rem;
370
+ }
371
+
372
+ aside.sidebar nav a[aria-current="page"] {
373
+ border-left: none;
374
+ border-bottom-color: var(--pico-primary);
375
+ }
376
+
377
+ aside.sidebar nav a:hover {
378
+ border-left: none;
379
+ }
380
+
381
+ .page-wrapper > main {
382
+ padding: var(--space-lg) var(--space-md);
383
+ }
384
+
385
+ h1 { font-size: 1.4rem; }
386
+ h2 { font-size: 1.15rem; }
387
+
388
+ table {
389
+ font-size: 0.8125rem;
390
+ }
391
+ }
392
+
393
+ /* Small mobile */
394
+ @media (max-width: 480px) {
395
+ html {
396
+ font-size: 14px;
397
+ }
398
+
399
+ .page-wrapper > main {
400
+ padding: var(--space-md);
401
+ }
402
+
403
+ article > header {
404
+ padding: var(--space-sm) var(--space-md);
405
+ }
406
+ }