claude-dev-env 1.83.0 → 1.84.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 (165) hide show
  1. package/_shared/pr-loop/audit-contract.md +24 -12
  2. package/_shared/pr-loop/scripts/_claude_permissions_common.py +16 -5
  3. package/_shared/pr-loop/scripts/code_rules_gate.py +2 -3
  4. package/_shared/pr-loop/scripts/reviews_disabled.py +2 -0
  5. package/_shared/pr-loop/scripts/tests/test__claude_permissions_common.py +212 -0
  6. package/_shared/pr-loop/scripts/tests/test_agent_config_carveout.py +18 -0
  7. package/_shared/pr-loop/scripts/tests/test_claude_permissions_common.py +18 -0
  8. package/_shared/pr-loop/scripts/tests/test_code_rules_gate.py +37 -0
  9. package/_shared/pr-loop/scripts/tests/test_reviews_disabled.py +14 -0
  10. package/agents/clean-coder.md +3 -0
  11. package/audit-rubrics/category_rubrics/category-o-docstring-vs-impl-drift.md +1 -1
  12. package/bin/install.mjs +16 -8
  13. package/bin/install.test.mjs +17 -6
  14. package/commands/CLAUDE.md +0 -1
  15. package/docs/CODE_RULES.md +1 -1
  16. package/hooks/blocking/CLAUDE.md +0 -4
  17. package/hooks/blocking/code_rules_constants_config.py +5 -0
  18. package/hooks/blocking/code_rules_docstrings.py +116 -6
  19. package/hooks/blocking/code_rules_enforcer.py +4 -0
  20. package/hooks/blocking/code_rules_magic_values.py +5 -0
  21. package/hooks/blocking/code_rules_naming_collection.py +11 -6
  22. package/hooks/blocking/code_rules_shared.py +34 -0
  23. package/hooks/blocking/duplicate_rmtree_helper_blocker.py +4 -4
  24. package/hooks/blocking/test_code_rules_enforcer_docstring_prose_wall_illustration.py +197 -0
  25. package/hooks/blocking/test_code_rules_enforcer_docstring_runon_sentence.py +27 -0
  26. package/hooks/blocking/test_code_rules_enforcer_split_constants_config.py +33 -0
  27. package/hooks/blocking/test_code_rules_enforcer_split_shared.py +23 -0
  28. package/hooks/blocking/test_code_rules_magic_values.py +54 -0
  29. package/hooks/blocking/test_duplicate_rmtree_helper_blocker.py +0 -6
  30. package/hooks/blocking/test_pr_converge_bugteam_enforcer_state_tolerance.py +184 -0
  31. package/hooks/blocking/test_shared_stdin_adoption.py +5 -30
  32. package/hooks/hooks_constants/CLAUDE.md +0 -3
  33. package/hooks/hooks_constants/blocking_check_limits.py +3 -0
  34. package/hooks/hooks_constants/code_rules_path_utils_constants.py +1 -1
  35. package/hooks/hooks_constants/duplicate_rmtree_helper_blocker_constants.py +0 -1
  36. package/hooks/hooks_constants/post_tool_use_dispatcher_constants.py +0 -5
  37. package/hooks/validation/post_tool_use_dispatcher.py +1 -1
  38. package/hooks/validation/test_post_tool_use_dispatcher.py +51 -35
  39. package/hooks/workflow/CLAUDE.md +2 -8
  40. package/package.json +1 -1
  41. package/rules/CLAUDE.md +1 -1
  42. package/rules/plain-illustrative-docstrings.md +35 -1
  43. package/skills/CLAUDE.md +6 -1
  44. package/skills/autoconverge/SKILL.md +38 -57
  45. package/skills/autoconverge/reference/closing-report.md +6 -6
  46. package/skills/autoconverge/reference/convergence.md +17 -15
  47. package/skills/autoconverge/reference/gotchas.md +6 -3
  48. package/skills/autoconverge/workflow/autoconverge_report_constants/render_report_constants.py +2 -9
  49. package/skills/autoconverge/workflow/converge.contract.test.mjs +87 -13
  50. package/skills/autoconverge/workflow/converge.copilot-gate.test.mjs +1 -1
  51. package/skills/autoconverge/workflow/converge.merge-conflict.test.mjs +16 -9
  52. package/skills/autoconverge/workflow/converge.mjs +70 -73
  53. package/skills/autoconverge/workflow/render_report.py +7 -11
  54. package/skills/bugteam/CLAUDE.md +1 -1
  55. package/skills/bugteam/PROMPTS.md +7 -6
  56. package/skills/bugteam/SKILL.md +25 -72
  57. package/skills/bugteam/reference/CLAUDE.md +1 -3
  58. package/skills/bugteam/reference/README.md +1 -1
  59. package/skills/bugteam/reference/audit-and-teammates.md +1 -1
  60. package/skills/bugteam/reference/obstacles/fix-publish-summary.md +1 -1
  61. package/skills/bugteam/reference/team-setup.md +8 -7
  62. package/skills/bugteam/scripts/CLAUDE.md +0 -6
  63. package/skills/bugteam/scripts/README.md +0 -4
  64. package/skills/bugteam/scripts/bugteam_scripts_constants/CLAUDE.md +0 -1
  65. package/skills/code/SKILL.md +2 -0
  66. package/skills/copilot-review/CLAUDE.md +1 -1
  67. package/skills/copilot-review/SKILL.md +25 -23
  68. package/skills/findbugs/CLAUDE.md +2 -2
  69. package/skills/findbugs/SKILL.md +22 -83
  70. package/skills/fixbugs/SKILL.md +2 -4
  71. package/skills/log-audit/CLAUDE.md +20 -0
  72. package/skills/log-audit/SKILL.md +68 -0
  73. package/skills/log-audit/reference/CLAUDE.md +9 -0
  74. package/skills/log-audit/reference/charter.md +52 -0
  75. package/skills/log-audit/scripts/CLAUDE.md +27 -0
  76. package/skills/log-audit/scripts/cluster_recurrences.py +261 -0
  77. package/skills/log-audit/scripts/collect_log_window.py +199 -0
  78. package/skills/log-audit/scripts/log_audit_constants/CLAUDE.md +12 -0
  79. package/skills/log-audit/scripts/log_audit_constants/cluster_recurrences_constants.py +23 -0
  80. package/skills/log-audit/scripts/log_audit_constants/collect_log_window_constants.py +24 -0
  81. package/skills/log-audit/scripts/log_audit_constants/mine_copilot_findings_constants.py +49 -0
  82. package/skills/log-audit/scripts/mine_copilot_findings.py +302 -0
  83. package/skills/log-audit/scripts/test_cluster_recurrences.py +160 -0
  84. package/skills/log-audit/scripts/test_collect_log_window.py +111 -0
  85. package/skills/log-audit/scripts/test_mine_copilot_findings.py +126 -0
  86. package/skills/monitor-open-prs/SKILL.md +2 -2
  87. package/skills/post-audit-findings/SKILL.md +84 -0
  88. package/skills/pr-converge/CLAUDE.md +2 -0
  89. package/skills/pr-converge/SKILL.md +72 -59
  90. package/skills/pr-converge/reference/CLAUDE.md +1 -1
  91. package/skills/pr-converge/reference/convergence-gates.md +16 -19
  92. package/skills/pr-converge/reference/examples.md +5 -5
  93. package/skills/pr-converge/reference/fix-protocol.md +16 -43
  94. package/skills/pr-converge/reference/obstacles/fix-publish-summary.md +1 -1
  95. package/skills/pr-converge/reference/per-tick.md +24 -45
  96. package/skills/pr-converge/reference/state-schema.md +15 -0
  97. package/skills/pr-converge/scripts/README.md +3 -5
  98. package/skills/pr-fix-protocol/SKILL.md +70 -0
  99. package/skills/pr-loop-lifecycle/SKILL.md +73 -0
  100. package/skills/{bugteam → pr-loop-lifecycle}/reference/teardown-publish-permissions.md +22 -24
  101. package/skills/pr-scope-resolve/SKILL.md +48 -0
  102. package/skills/qbug/CLAUDE.md +4 -4
  103. package/skills/qbug/SKILL.md +46 -144
  104. package/skills/qbug/test_qbug_skill_audit_schema.py +2 -2
  105. package/skills/qbug/test_qbug_skill_post_fix_audit.py +1 -1
  106. package/skills/reviewer-gates/SKILL.md +96 -0
  107. package/skills/session-log/CLAUDE.md +7 -7
  108. package/skills/session-log/SKILL.md +27 -44
  109. package/skills/test_markdown_link_integrity.py +103 -0
  110. package/commands/doc-gist.md +0 -16
  111. package/hooks/blocking/_md_to_html_blocker_test_support.py +0 -65
  112. package/hooks/blocking/conftest.py +0 -30
  113. package/hooks/blocking/md_path_exemptions.py +0 -224
  114. package/hooks/blocking/md_to_html_blocker.py +0 -155
  115. package/hooks/blocking/test_md_to_html_blocker_exemptions.py +0 -434
  116. package/hooks/blocking/test_md_to_html_blocker_extensions.py +0 -157
  117. package/hooks/blocking/test_md_to_html_blocker_path_resolution.py +0 -336
  118. package/hooks/hooks_constants/doc_gist_auto_publish_constants.py +0 -18
  119. package/hooks/hooks_constants/html_companion_constants.py +0 -20
  120. package/hooks/hooks_constants/md_to_html_blocker_constants.py +0 -76
  121. package/hooks/hooks_constants/test_md_to_html_blocker_constants.py +0 -125
  122. package/hooks/workflow/doc_gist_auto_publish.py +0 -144
  123. package/hooks/workflow/md_to_html_companion.py +0 -358
  124. package/hooks/workflow/test_doc_gist_auto_publish.py +0 -117
  125. package/hooks/workflow/test_md_to_html_companion.py +0 -613
  126. package/skills/bugteam/reference/audit-contract.md +0 -163
  127. package/skills/bugteam/scripts/_bugteam_permissions_common.py +0 -455
  128. package/skills/bugteam/scripts/bugteam_scripts_constants/claude_permissions_common_constants.py +0 -69
  129. package/skills/bugteam/scripts/grant_project_claude_permissions.py +0 -280
  130. package/skills/bugteam/scripts/revoke_project_claude_permissions.py +0 -266
  131. package/skills/bugteam/scripts/test__bugteam_permissions_common.py +0 -160
  132. package/skills/bugteam/scripts/test_agent_config_carveout.py +0 -356
  133. package/skills/bugteam/scripts/test_bugteam_permissions_common.py +0 -140
  134. package/skills/doc-gist/CLAUDE.md +0 -25
  135. package/skills/doc-gist/SKILL.md +0 -97
  136. package/skills/doc-gist/references/CLAUDE.md +0 -9
  137. package/skills/doc-gist/references/examples/01-exploration-code-approaches.html +0 -453
  138. package/skills/doc-gist/references/examples/02-exploration-visual-designs.html +0 -515
  139. package/skills/doc-gist/references/examples/03-code-review-pr.html +0 -638
  140. package/skills/doc-gist/references/examples/04-code-understanding.html +0 -491
  141. package/skills/doc-gist/references/examples/05-design-system.html +0 -629
  142. package/skills/doc-gist/references/examples/06-component-variants.html +0 -605
  143. package/skills/doc-gist/references/examples/07-prototype-animation.html +0 -455
  144. package/skills/doc-gist/references/examples/08-prototype-interaction.html +0 -396
  145. package/skills/doc-gist/references/examples/09-slide-deck.html +0 -592
  146. package/skills/doc-gist/references/examples/10-svg-illustrations.html +0 -492
  147. package/skills/doc-gist/references/examples/11-status-report.html +0 -528
  148. package/skills/doc-gist/references/examples/12-incident-report.html +0 -596
  149. package/skills/doc-gist/references/examples/13-flowchart-diagram.html +0 -395
  150. package/skills/doc-gist/references/examples/14-research-feature-explainer.html +0 -381
  151. package/skills/doc-gist/references/examples/15-research-concept-explainer.html +0 -368
  152. package/skills/doc-gist/references/examples/16-implementation-plan.html +0 -702
  153. package/skills/doc-gist/references/examples/17-pr-writeup.html +0 -595
  154. package/skills/doc-gist/references/examples/18-editor-triage-board.html +0 -573
  155. package/skills/doc-gist/references/examples/19-editor-feature-flags.html +0 -663
  156. package/skills/doc-gist/references/examples/20-editor-prompt-tuner.html +0 -722
  157. package/skills/doc-gist/references/examples/21-decision-signoff.html +0 -546
  158. package/skills/doc-gist/references/examples/CLAUDE.md +0 -25
  159. package/skills/doc-gist/references/examples/README.md +0 -5
  160. package/skills/doc-gist/scripts/CLAUDE.md +0 -27
  161. package/skills/doc-gist/scripts/doc_gist_scripts_constants/CLAUDE.md +0 -10
  162. package/skills/doc-gist/scripts/doc_gist_scripts_constants/gist_upload_constants.py +0 -16
  163. package/skills/doc-gist/scripts/gist_upload.py +0 -177
  164. package/skills/doc-gist/scripts/test_gist_upload.py +0 -51
  165. /package/skills/{doc-gist/scripts/doc_gist_scripts_constants → log-audit/scripts/log_audit_constants}/__init__.py +0 -0
@@ -1,515 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="en">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Empty state — four visual directions</title>
7
- <style>
8
- :root {
9
- --ivory: #FAF9F5;
10
- --slate: #141413;
11
- --clay: #D97757;
12
- --oat: #E3DACC;
13
- --olive: #788C5D;
14
- --gray-150: #F0EEE6;
15
- --gray-300: #D1CFC5;
16
- --gray-500: #87867F;
17
- --gray-700: #3D3D3A;
18
- --white: #FFFFFF;
19
-
20
- --serif: ui-serif, Georgia, 'Times New Roman', serif;
21
- --sans: system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
22
- --mono: ui-monospace, 'SF Mono', Menlo, Monaco, monospace;
23
- }
24
-
25
- * { margin: 0; padding: 0; box-sizing: border-box; }
26
-
27
- body {
28
- font-family: var(--sans);
29
- background: var(--ivory);
30
- color: var(--gray-700);
31
- line-height: 1.55;
32
- -webkit-font-smoothing: antialiased;
33
- padding-bottom: 96px;
34
- }
35
-
36
- /* ---------- sticky toolbar ---------- */
37
-
38
- .toolbar {
39
- position: sticky;
40
- top: 0;
41
- z-index: 10;
42
- background: var(--ivory);
43
- border-bottom: 1.5px solid var(--gray-300);
44
- padding: 14px 32px;
45
- display: flex;
46
- align-items: center;
47
- gap: 18px;
48
- font-size: 13px;
49
- }
50
-
51
- .toolbar .title {
52
- font-family: var(--mono);
53
- font-size: 12px;
54
- letter-spacing: 0.04em;
55
- color: var(--gray-500);
56
- margin-right: auto;
57
- }
58
-
59
- .toolbar .field {
60
- display: flex;
61
- align-items: center;
62
- gap: 10px;
63
- }
64
-
65
- .toolbar .field > span {
66
- color: var(--gray-700);
67
- font-weight: 500;
68
- }
69
-
70
- .seg {
71
- display: inline-flex;
72
- border: 1.5px solid var(--gray-300);
73
- border-radius: 8px;
74
- overflow: hidden;
75
- background: var(--white);
76
- }
77
-
78
- .seg label {
79
- padding: 6px 14px;
80
- cursor: pointer;
81
- font-size: 13px;
82
- color: var(--gray-700);
83
- user-select: none;
84
- }
85
-
86
- .seg label + label {
87
- border-left: 1.5px solid var(--gray-300);
88
- }
89
-
90
- .seg input { display: none; }
91
-
92
- .seg input:checked + span {
93
- color: var(--slate);
94
- font-weight: 600;
95
- }
96
-
97
- .seg label:has(input:checked) {
98
- background: var(--oat);
99
- }
100
-
101
- /* ---------- page header ---------- */
102
-
103
- .page {
104
- max-width: 1240px;
105
- margin: 0 auto;
106
- padding: 48px 32px 0;
107
- }
108
-
109
- header.page-head {
110
- max-width: 720px;
111
- margin-bottom: 40px;
112
- }
113
-
114
- .eyebrow {
115
- font-size: 12px;
116
- letter-spacing: 0.08em;
117
- text-transform: uppercase;
118
- color: var(--gray-500);
119
- margin-bottom: 12px;
120
- }
121
-
122
- h1 {
123
- font-family: var(--serif);
124
- font-weight: 500;
125
- font-size: 38px;
126
- line-height: 1.15;
127
- color: var(--slate);
128
- margin-bottom: 18px;
129
- letter-spacing: -0.01em;
130
- }
131
-
132
- .prompt-box {
133
- background: var(--gray-150);
134
- border: 1.5px solid var(--gray-300);
135
- border-radius: 12px;
136
- padding: 16px 20px;
137
- font-size: 14.5px;
138
- }
139
-
140
- .prompt-box .label {
141
- font-family: var(--mono);
142
- font-size: 11px;
143
- text-transform: uppercase;
144
- letter-spacing: 0.06em;
145
- color: var(--gray-500);
146
- display: block;
147
- margin-bottom: 6px;
148
- }
149
-
150
- /* ---------- artboard grid ---------- */
151
-
152
- .board {
153
- display: grid;
154
- grid-template-columns: 1fr 1fr;
155
- gap: 32px;
156
- }
157
-
158
- @media (max-width: 960px) {
159
- .board { grid-template-columns: 1fr; }
160
- }
161
-
162
- .artboard {
163
- background: var(--white);
164
- border: 1.5px solid var(--gray-300);
165
- border-radius: 12px;
166
- padding: 20px;
167
- position: relative;
168
- }
169
-
170
- .tag {
171
- position: absolute;
172
- top: 14px;
173
- left: 14px;
174
- font-family: var(--mono);
175
- font-size: 11px;
176
- letter-spacing: 0.02em;
177
- background: var(--oat);
178
- color: var(--slate);
179
- padding: 4px 10px;
180
- border-radius: 8px;
181
- z-index: 2;
182
- }
183
-
184
- .stage {
185
- height: 280px;
186
- border-radius: 8px;
187
- border: 1.5px solid var(--gray-300);
188
- background: var(--ivory);
189
- display: flex;
190
- align-items: center;
191
- justify-content: center;
192
- padding: 24px;
193
- transition: background 0.15s, border-color 0.15s;
194
- overflow: hidden;
195
- }
196
-
197
- .stage.dark {
198
- background: var(--slate);
199
- border-color: var(--slate);
200
- }
201
-
202
- .rationale {
203
- margin-top: 16px;
204
- font-size: 13px;
205
- color: var(--gray-500);
206
- line-height: 1.5;
207
- }
208
-
209
- /* =========================================================
210
- Empty-state variants — each scoped under .es-*
211
- Theme tokens flip when .stage.dark is present.
212
- ========================================================= */
213
-
214
- .stage { --fg: var(--slate); --muted: var(--gray-500); --line: var(--gray-300); --panel: var(--white); }
215
- .stage.dark { --fg: #F0EEE6; --muted: #9C9A93; --line: #3D3D3A; --panel: #1F1E1B; }
216
-
217
- /* ---- A · Minimal ---- */
218
-
219
- .es-a {
220
- text-align: center;
221
- max-width: 300px;
222
- }
223
- .es-a h3 {
224
- font-family: var(--serif);
225
- font-weight: 500;
226
- font-size: 19px;
227
- color: var(--fg);
228
- margin-bottom: 6px;
229
- }
230
- .es-a p {
231
- font-size: 13px;
232
- color: var(--muted);
233
- margin-bottom: 18px;
234
- }
235
- .es-a .btn {
236
- display: inline-block;
237
- font-size: 13px;
238
- color: var(--fg);
239
- border: 1.5px solid var(--line);
240
- border-radius: 8px;
241
- padding: 8px 16px;
242
- background: transparent;
243
- }
244
-
245
- /* ---- B · Illustrated ---- */
246
-
247
- .es-b {
248
- text-align: center;
249
- max-width: 320px;
250
- }
251
- .es-b svg {
252
- display: block;
253
- margin: 0 auto 18px;
254
- }
255
- .es-b h3 {
256
- font-family: var(--serif);
257
- font-weight: 500;
258
- font-size: 19px;
259
- color: var(--fg);
260
- margin-bottom: 6px;
261
- }
262
- .es-b p {
263
- font-size: 13px;
264
- color: var(--muted);
265
- margin-bottom: 16px;
266
- }
267
- .es-b .btn {
268
- display: inline-block;
269
- font-size: 13px;
270
- font-weight: 500;
271
- color: var(--white);
272
- background: var(--clay);
273
- border-radius: 8px;
274
- padding: 8px 16px;
275
- }
276
- .stage.dark .es-b .btn { color: var(--slate); background: var(--oat); }
277
-
278
- /* ---- C · Playful ---- */
279
-
280
- .es-c {
281
- text-align: center;
282
- max-width: 300px;
283
- }
284
- .es-c .float {
285
- width: 56px;
286
- height: 56px;
287
- margin: 0 auto 20px;
288
- position: relative;
289
- animation: bob 3.2s ease-in-out infinite;
290
- }
291
- .es-c .float .card {
292
- position: absolute;
293
- inset: 0;
294
- border-radius: 10px;
295
- background: var(--panel);
296
- border: 1.5px solid var(--line);
297
- }
298
- .es-c .float .card:nth-child(1) { transform: rotate(-8deg) translate(-6px, 4px); opacity: 0.5; }
299
- .es-c .float .card:nth-child(2) { transform: rotate( 6deg) translate( 6px, 2px); opacity: 0.75; }
300
- .es-c .float .card:nth-child(3) { background: var(--oat); border-color: var(--oat); }
301
- .stage.dark .es-c .float .card:nth-child(3) { background: var(--clay); border-color: var(--clay); }
302
- .es-c .shadow {
303
- width: 44px;
304
- height: 8px;
305
- margin: -8px auto 22px;
306
- border-radius: 50%;
307
- background: rgba(0,0,0,0.12);
308
- filter: blur(2px);
309
- animation: shadow 3.2s ease-in-out infinite;
310
- }
311
- .stage.dark .es-c .shadow { background: rgba(0,0,0,0.5); }
312
- .es-c h3 {
313
- font-family: var(--serif);
314
- font-weight: 500;
315
- font-size: 19px;
316
- color: var(--fg);
317
- margin-bottom: 6px;
318
- }
319
- .es-c p {
320
- font-size: 13px;
321
- color: var(--muted);
322
- }
323
-
324
- @keyframes bob {
325
- 0%, 100% { transform: translateY(0); }
326
- 50% { transform: translateY(-10px); }
327
- }
328
- @keyframes shadow {
329
- 0%, 100% { transform: scaleX(1); opacity: 0.9; }
330
- 50% { transform: scaleX(0.8); opacity: 0.5; }
331
- }
332
-
333
- /* ---- D · Instructional ---- */
334
-
335
- .es-d {
336
- width: 100%;
337
- max-width: 360px;
338
- }
339
- .es-d h3 {
340
- font-family: var(--serif);
341
- font-weight: 500;
342
- font-size: 18px;
343
- color: var(--fg);
344
- margin-bottom: 14px;
345
- }
346
- .es-d ol {
347
- list-style: none;
348
- counter-reset: step;
349
- display: flex;
350
- flex-direction: column;
351
- gap: 10px;
352
- }
353
- .es-d li {
354
- counter-increment: step;
355
- display: flex;
356
- align-items: flex-start;
357
- gap: 12px;
358
- background: var(--panel);
359
- border: 1.5px solid var(--line);
360
- border-radius: 8px;
361
- padding: 10px 14px;
362
- font-size: 13px;
363
- color: var(--fg);
364
- }
365
- .es-d li::before {
366
- content: counter(step);
367
- font-family: var(--mono);
368
- font-size: 11px;
369
- flex: 0 0 20px;
370
- height: 20px;
371
- border-radius: 50%;
372
- background: var(--oat);
373
- color: var(--slate);
374
- display: inline-flex;
375
- align-items: center;
376
- justify-content: center;
377
- margin-top: 1px;
378
- }
379
- .es-d li span { color: var(--muted); display: block; font-size: 12px; margin-top: 2px; }
380
- </style>
381
- </head>
382
- <body>
383
-
384
- <div class="toolbar">
385
- <div class="title">Birchline · design exploration</div>
386
- <div class="field">
387
- <span>Background:</span>
388
- <div class="seg" id="bg-seg">
389
- <label><input type="radio" name="bg" value="light" checked><span>Light</span></label>
390
- <label><input type="radio" name="bg" value="dark"><span>Dark</span></label>
391
- </div>
392
- </div>
393
- </div>
394
-
395
- <div class="page">
396
-
397
- <header class="page-head">
398
- <div class="eyebrow">Exploration · Empty states</div>
399
- <h1>Four visual directions for the “no tasks yet” state</h1>
400
- <div class="prompt-box">
401
- <span class="label">Prompt</span>
402
- Explore four visual directions for our empty-state component. Render each
403
- live so we can compare tone, density, and how well they hold up on light
404
- and dark surfaces.
405
- </div>
406
- </header>
407
-
408
- <section class="board">
409
-
410
- <!-- ================= A — Minimal ================= -->
411
- <article class="artboard">
412
- <span class="tag">A — Minimal</span>
413
- <div class="stage">
414
- <div class="es-a">
415
- <h3>No tasks yet</h3>
416
- <p>When you create a task it will show up here.</p>
417
- <span class="btn">New task</span>
418
- </div>
419
- </div>
420
- <p class="rationale">
421
- Pure typography, single quiet action. Reads as calm and confident;
422
- assumes the surrounding UI already carries enough personality.
423
- </p>
424
- </article>
425
-
426
- <!-- ================= B — Illustrated ================= -->
427
- <article class="artboard">
428
- <span class="tag">B — Illustrated</span>
429
- <div class="stage">
430
- <div class="es-b">
431
- <svg width="120" height="90" viewBox="0 0 120 90" aria-hidden="true">
432
- <rect x="14" y="20" width="72" height="54" rx="8"
433
- fill="var(--panel)" stroke="var(--line)" stroke-width="1.5"/>
434
- <rect x="34" y="10" width="72" height="54" rx="8"
435
- fill="var(--oat)"/>
436
- <line x1="46" y1="26" x2="92" y2="26"
437
- stroke="var(--slate)" stroke-width="2" stroke-linecap="round"/>
438
- <line x1="46" y1="38" x2="80" y2="38"
439
- stroke="var(--slate)" stroke-width="2" stroke-linecap="round" opacity="0.5"/>
440
- <circle cx="98" cy="60" r="12" fill="var(--clay)"/>
441
- <path d="M98 55 v10 M93 60 h10"
442
- stroke="white" stroke-width="2" stroke-linecap="round"/>
443
- </svg>
444
- <h3>Start your first list</h3>
445
- <p>Group related work and watch progress roll up automatically.</p>
446
- <span class="btn">Create a task</span>
447
- </div>
448
- </div>
449
- <p class="rationale">
450
- A small geometric spot illustration anchors the eye and explains the
451
- object model (lists contain tasks) without a wall of copy.
452
- </p>
453
- </article>
454
-
455
- <!-- ================= C — Playful ================= -->
456
- <article class="artboard">
457
- <span class="tag">C — Playful</span>
458
- <div class="stage">
459
- <div class="es-c">
460
- <div class="float">
461
- <div class="card"></div>
462
- <div class="card"></div>
463
- <div class="card"></div>
464
- </div>
465
- <div class="shadow"></div>
466
- <h3>Nothing on your plate</h3>
467
- <p>Enjoy the quiet, or add something to get moving.</p>
468
- </div>
469
- </div>
470
- <p class="rationale">
471
- A gently bobbing stack adds life to an otherwise static screen. Motion
472
- is subtle enough to loop indefinitely without drawing complaints.
473
- </p>
474
- </article>
475
-
476
- <!-- ================= D — Instructional ================= -->
477
- <article class="artboard">
478
- <span class="tag">D — Instructional</span>
479
- <div class="stage">
480
- <div class="es-d">
481
- <h3>Set up this project</h3>
482
- <ol>
483
- <li>
484
- Create your first task
485
- <span>Give it a name and an owner.</span>
486
- </li>
487
- <li>
488
- Add a due date
489
- <span>Birchline will surface it on the timeline.</span>
490
- </li>
491
- <li>
492
- Invite a teammate
493
- <span>Shared projects stay in sync automatically.</span>
494
- </li>
495
- </ol>
496
- </div>
497
- </div>
498
- <p class="rationale">
499
- Treats the empty state as onboarding. Higher density, but every line is
500
- actionable — best when the user is new to the product, not just the view.
501
- </p>
502
- </article>
503
-
504
- </section>
505
- </div>
506
-
507
- <script>
508
- const stages = document.querySelectorAll('.stage');
509
- document.getElementById('bg-seg').addEventListener('change', (e) => {
510
- const dark = e.target.value === 'dark';
511
- stages.forEach((s) => s.classList.toggle('dark', dark));
512
- });
513
- </script>
514
- </body>
515
- </html>