jig-ui 0.21.0 → 0.23.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +134 -0
- package/README.md +158 -7
- package/dist/index.js +659 -184
- package/examples/G-161.html +7 -0
- package/examples/G-162.html +18 -0
- package/examples/G-163.html +7 -0
- package/examples/I-148.html +7 -0
- package/examples/I-149.html +7 -0
- package/examples/I-150.html +7 -0
- package/examples/I-151.html +7 -0
- package/examples/I-152.html +7 -0
- package/examples/I-153.html +7 -0
- package/examples/I-154.html +7 -0
- package/examples/I-155.html +7 -0
- package/examples/I-156.html +7 -0
- package/examples/I-157.html +7 -0
- package/examples/I-158.html +7 -0
- package/examples/I-159.html +7 -0
- package/examples/I-160.html +7 -0
- package/package.json +2 -2
- package/rules/00-anti-patterns.md +19 -0
- package/rules/01-modes.md +1 -1
- package/rules/02-tokens.md +3 -0
- package/rules/03-patterns.md +2 -1
- package/rules/05-copy.md +88 -2
- package/rules.index.json +114 -0
- package/templates/COMMAND.md.tmpl +286 -22
- package/templates/SKILL.md.tmpl +6 -1
- package/templates/command-metadata.json +5 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<!-- G-161 · A layout change that jumps -->
|
|
2
|
+
<figure data-example="dont">
|
|
3
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:6px;"><p style="margin:0;font-size:12px;color:#57534e;">Row 2 deleted. In the next frame:</p><div style="background:#fff;border:1px solid #d6d3d1;border-radius:4px;padding:6px 10px;font-size:13px;">Pay the invoice</div><div style="background:#fff;border:1px solid #d6d3d1;border-radius:4px;padding:6px 10px;font-size:13px;">Book the venue</div><div style="background:#fff;border:1px solid #d6d3d1;border-radius:4px;padding:6px 10px;font-size:13px;">Send the agenda</div><p style="margin:0;font-size:12px;color:#57534e;">The rows below snapped up. Nothing shows what went where.</p></div></div>
|
|
4
|
+
</figure>
|
|
5
|
+
<figure data-example="do">
|
|
6
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:6px;"><p style="margin:0;font-size:12px;color:#57534e;">Row 2 deleted. Over the next 150ms:</p><div style="background:#fff;border:1px solid #d6d3d1;border-radius:4px;padding:6px 10px;font-size:13px;">Pay the invoice</div><div style="background:#fff;border:1px solid #d6d3d1;border-radius:4px;padding:6px 10px;font-size:13px;box-shadow:0 0 0 2px #a8a29e;">Book the venue ↑</div><div style="background:#fff;border:1px solid #d6d3d1;border-radius:4px;padding:6px 10px;font-size:13px;box-shadow:0 0 0 2px #a8a29e;">Send the agenda ↑</div><p style="margin:0;font-size:12px;color:#57534e;">The rows below slide up into the gap, so the eye follows them.</p></div></div>
|
|
7
|
+
</figure>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<!-- G-162 · Animating layout, or everything -->
|
|
2
|
+
<figure data-example="dont">
|
|
3
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:6px;"><pre style="margin:0;font-family:ui-monospace,Menlo,monospace;font-size:12px;background:#fff;border:1px solid #d6d3d1;border-radius:4px;padding:8px;white-space:pre-wrap;">.panel {
|
|
4
|
+
transition: all 200ms;
|
|
5
|
+
}
|
|
6
|
+
.row {
|
|
7
|
+
transition: height 200ms;
|
|
8
|
+
}</pre></div></div>
|
|
9
|
+
</figure>
|
|
10
|
+
<figure data-example="do">
|
|
11
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:6px;"><pre style="margin:0;font-family:ui-monospace,Menlo,monospace;font-size:12px;background:#fff;border:1px solid #d6d3d1;border-radius:4px;padding:8px;white-space:pre-wrap;">.panel {
|
|
12
|
+
transition: opacity 150ms var(--ease-out),
|
|
13
|
+
transform 150ms var(--ease-out);
|
|
14
|
+
}
|
|
15
|
+
.row {
|
|
16
|
+
transition: transform 150ms var(--ease-in-out);
|
|
17
|
+
}</pre></div></div>
|
|
18
|
+
</figure>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<!-- G-163 · Several things moving at once -->
|
|
2
|
+
<figure data-example="dont">
|
|
3
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:6px;"><div style="background:#fff;border:1px solid #d6d3d1;border-radius:4px;padding:6px 10px;font-size:13px;">Gradient drifting behind the hero</div><div style="background:#fff;border:1px solid #d6d3d1;border-radius:4px;padding:6px 10px;font-size:13px;">Scroll arrow bouncing</div><div style="background:#fff;border:1px solid #d6d3d1;border-radius:4px;padding:6px 10px;font-size:13px;">Logo ticker scrolling</div><div style="background:#fff;border:1px solid #d6d3d1;border-radius:4px;padding:6px 10px;font-size:13px;">"New" badge pulsing</div><p style="margin:0;font-size:12px;color:#57534e;">Four loops at once. The saved message arrives and nobody sees it.</p></div></div>
|
|
4
|
+
</figure>
|
|
5
|
+
<figure data-example="do">
|
|
6
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:6px;"><div style="background:#fff;border:1px solid #d6d3d1;border-radius:4px;padding:6px 10px;font-size:13px;">Hero, still</div><div style="background:#fff;border:1px solid #d6d3d1;border-radius:4px;padding:6px 10px;font-size:13px;">Scroll arrow, still</div><div style="background:#fff;border:1px solid #d6d3d1;border-radius:4px;padding:6px 10px;font-size:13px;">Logo row, still</div><div style="background:#fff;border:1px solid #d6d3d1;border-radius:4px;padding:6px 10px;font-size:13px;box-shadow:0 0 0 2px #a8a29e;">Saved ✓</div><p style="margin:0;font-size:12px;color:#57534e;">One thing moves: the message the user caused.</p></div></div>
|
|
7
|
+
</figure>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<!-- I-148 · A claim with no source -->
|
|
2
|
+
<figure data-example="dont">
|
|
3
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">Teams using Acme ship 37% faster.</p><p style="margin:0;font-size:14px;">A 2024 study found developers save 11 hours a week.</p></div></div>
|
|
4
|
+
</figure>
|
|
5
|
+
<figure data-example="do">
|
|
6
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">In our own use, releases went from weekly to twice a week.</p><p style="margin:0;font-size:12px;color:#57534e;">Source: our release log, January to June 2026</p></div></div>
|
|
7
|
+
</figure>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<!-- I-149 · Specific in sound, empty in fact -->
|
|
2
|
+
<figure data-example="dont">
|
|
3
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">Organisations that adopt these practices often see significant gains in efficiency.</p></div></div>
|
|
4
|
+
</figure>
|
|
5
|
+
<figure data-example="do">
|
|
6
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">The billing team closed March in two days instead of five.</p></div></div>
|
|
7
|
+
</figure>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<!-- I-150 · Formula openers, closers and signposts -->
|
|
2
|
+
<figure data-example="dont">
|
|
3
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">In today's rapidly changing world, it is important to note that backups matter.</p><p style="margin:0;font-size:14px;">In conclusion, only time will tell.</p></div></div>
|
|
4
|
+
</figure>
|
|
5
|
+
<figure data-example="do">
|
|
6
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">Back up before you migrate.</p><p style="margin:0;font-size:14px;">A failed migration cannot be undone.</p></div></div>
|
|
7
|
+
</figure>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<!-- I-151 · Saying it twice -->
|
|
2
|
+
<figure data-example="dont">
|
|
3
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">Jig checks a page before it ships.</p><p style="margin:0;font-size:14px;">It reads the rules and applies them.</p><p style="margin:0;font-size:14px;">In short, Jig makes sure every page is checked before shipping.</p></div></div>
|
|
4
|
+
</figure>
|
|
5
|
+
<figure data-example="do">
|
|
6
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">Jig checks a page before it ships.</p><p style="margin:0;font-size:14px;">It reads the rules and applies them.</p><p style="margin:0;font-size:14px;">A machine decides 39 of them; a reviewer judges the rest.</p></div></div>
|
|
7
|
+
</figure>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<!-- I-152 · A rhetorical shape on repeat -->
|
|
2
|
+
<figure data-example="dont">
|
|
3
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">It's not a tool, it's a workflow.</p><p style="margin:0;font-size:14px;">It's not a checklist, it's a habit.</p><p style="margin:0;font-size:14px;">It's not a rule, it's a promise.</p></div></div>
|
|
4
|
+
</figure>
|
|
5
|
+
<figure data-example="do">
|
|
6
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">It runs in your editor.</p><p style="margin:0;font-size:14px;">Before you ship, it checks each page and names the rule a line breaks.</p></div></div>
|
|
7
|
+
</figure>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<!-- I-153 · Enthusiasm the content has not earned -->
|
|
2
|
+
<figure data-example="dont">
|
|
3
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">An incredibly exciting, truly transformative update. The possibilities are endless.</p></div></div>
|
|
4
|
+
</figure>
|
|
5
|
+
<figure data-example="do">
|
|
6
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">Exports now include every column, so the monthly report takes one download instead of four.</p></div></div>
|
|
7
|
+
</figure>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<!-- I-154 · Stacked hedges -->
|
|
2
|
+
<figure data-example="dont">
|
|
3
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">It may potentially suggest that this could, in some cases, help.</p></div></div>
|
|
4
|
+
</figure>
|
|
5
|
+
<figure data-example="do">
|
|
6
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">The evidence suggests it helps on pages over 2,000 words.</p></div></div>
|
|
7
|
+
</figure>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<!-- I-155 · Emoji in headings -->
|
|
2
|
+
<figure data-example="dont">
|
|
3
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><div style="font-size:16px;font-weight:700;line-height:1.2;">🚀 Getting started</div><p style="margin:0;font-size:14px;">Install it with one command.</p><div style="font-size:16px;font-weight:700;line-height:1.2;">✨ Key features</div><p style="margin:0;font-size:14px;">It checks each page before you ship.</p></div></div>
|
|
4
|
+
</figure>
|
|
5
|
+
<figure data-example="do">
|
|
6
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><div style="font-size:16px;font-weight:700;line-height:1.2;">Install Jig in one command</div><p style="margin:0;font-size:14px;">Install it with one command.</p><div style="font-size:16px;font-weight:700;line-height:1.2;">What each check reports</div><p style="margin:0;font-size:14px;">It checks each page before you ship.</p></div></div>
|
|
7
|
+
</figure>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<!-- I-156 · Structure imposed rather than earned -->
|
|
2
|
+
<figure data-example="dont">
|
|
3
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><div style="font-size:14px;font-weight:700;line-height:1.2;">Overview</div><p style="margin:0;font-size:14px;">Jig checks pages.</p><div style="font-size:14px;font-weight:700;line-height:1.2;">Key benefits</div><p style="margin:0;font-size:14px;">It is fast.</p><div style="font-size:14px;font-weight:700;line-height:1.2;">Conclusion</div><p style="margin:0;font-size:14px;">Jig checks pages.</p></div></div>
|
|
4
|
+
</figure>
|
|
5
|
+
<figure data-example="do">
|
|
6
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><div style="font-size:14px;font-weight:700;line-height:1.2;">Install Jig in one command</div><p style="margin:0;font-size:14px;">Run npx jig-ui init in your project.</p><div style="font-size:14px;font-weight:700;line-height:1.2;">Run your first check</div><p style="margin:0;font-size:14px;">Run npx jig-ui check. Each finding names its rule.</p></div></div>
|
|
7
|
+
</figure>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<!-- I-157 · Nothing only the author could say -->
|
|
2
|
+
<figure data-example="dont">
|
|
3
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">The migration was challenging, but the team learned valuable lessons.</p></div></div>
|
|
4
|
+
</figure>
|
|
5
|
+
<figure data-example="do">
|
|
6
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">The migration looked like a weekend's work. It took three weeks, because two services wrote the same table and nobody had written that down.</p></div></div>
|
|
7
|
+
</figure>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<!-- I-158 · No point of view -->
|
|
2
|
+
<figure data-example="dont">
|
|
3
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">There are several factors to consider, each with its own trade-offs.</p></div></div>
|
|
4
|
+
</figure>
|
|
5
|
+
<figure data-example="do">
|
|
6
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">The technology was not the hard part. Changing how procurement worked was.</p></div></div>
|
|
7
|
+
</figure>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<!-- I-159 · An even rhythm -->
|
|
2
|
+
<figure data-example="dont">
|
|
3
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">We started the project in May. We chose a small team for it. We wrote the plan in one week. We shipped the first page in June. We learned a lot along the way.</p></div></div>
|
|
4
|
+
</figure>
|
|
5
|
+
<figure data-example="do">
|
|
6
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">We started in May with three people. The plan took a week. The first page took six, because nobody had asked support what customers searched for.</p></div></div>
|
|
7
|
+
</figure>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
<!-- I-160 · Feeling named, not shown -->
|
|
2
|
+
<figure data-example="dont">
|
|
3
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">I was fascinated by the results, which provided valuable insights.</p></div></div>
|
|
4
|
+
</figure>
|
|
5
|
+
<figure data-example="do">
|
|
6
|
+
<div style="font-family:system-ui,-apple-system,'Segoe UI',sans-serif;font-size:13px;line-height:1.45;color:#1f1f1f;background:#f5f5f4;padding:16px;min-height:176px;box-sizing:border-box;"><div style="display:flex;flex-direction:column;gap:8px;"><p style="margin:0;font-size:14px;">I did not expect the result. We had tested it three times, and it failed in exactly the same place.</p></div></div>
|
|
7
|
+
</figure>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jig-ui",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "A design system for coding agents.
|
|
3
|
+
"version": "0.23.0",
|
|
4
|
+
"description": "A design system for coding agents. 159 numbered UI rules, brand x mode design tokens, and an installer for Claude Code, Codex, Cursor and opencode.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"bin": {
|
|
@@ -590,6 +590,25 @@ A pulse says "look here, something is happening". On a status that has not chang
|
|
|
590
590
|
|
|
591
591
|
**Scope: this is about motion that answers an input or carries a state change.** It is not a ceiling on every animation on the page. Slow decorative looping motion — see `P-13` — runs for seconds by design, and is not covered here. The reason the two differ is the reason the numbers differ: interaction motion sits between the user and their task, so it must get out of the way; ambient motion is never in the way, so speed would only make it noticeable.
|
|
592
592
|
|
|
593
|
+
### G-161 A layout change that jumps
|
|
594
|
+
❌ A row deleted, and the rows below snap up into the gap in one frame. A filter applied, and the grid reshuffles with nothing to follow. A card opened into its detail view, with nothing connecting the two.
|
|
595
|
+
✅ When the user's own action moves things, show where they went. The rows below slide up into the gap. Items that stay keep their identity and move to their new place; items that go fade out where they stood. A card grows into its detail view (`view-transition-name` on both, where the browser has View Transitions). Moves within the screen take `--ease-in-out` and `--duration-base`; a whole view changing, `--duration-slow`.
|
|
596
|
+
A jump makes the user find their place again, and they cannot tell a row that moved from a row that changed. The move answers "where did it go?" before they have to ask.
|
|
597
|
+
**Keep it instant** when the user did not cause the change: a live table updating under someone's pointer must not slide the row they were about to click. Also when most of the view changes at once, since a cut is clearer than twenty moves. Under reduced motion the change is instant, and focus or a live region says where things went (`G-43`).
|
|
598
|
+
Technique, for a layout change CSS cannot transition: record each item's position before the change, apply it, then animate each item's `transform` from the old position to zero (first, last, invert, play). Never animate the layout properties themselves (`G-162`).
|
|
599
|
+
|
|
600
|
+
### G-162 Animating layout, or everything
|
|
601
|
+
❌ `transition: height 200ms`, `transition: all 150ms`, a keyframe that moves `top` or `margin-left`, Tailwind's `transition-all`
|
|
602
|
+
✅ Animate `transform` and `opacity`. To move, `translate`; to grow, `scale` or a clip; to appear, `opacity`. Name the properties a transition covers: `transition: opacity var(--duration-fast) var(--ease-out), transform var(--duration-fast) var(--ease-out)`.
|
|
603
|
+
`width`, `height`, `margin`, `padding`, `top`, `left` and their kin change layout, so the browser works out the position of everything around the element again on every frame, and on a slow phone the motion stutters. `transform` and `opacity` do not move anything else. `all` animates every property that changes, including a layout one someone adds next month, and nobody reading the rule can tell which.
|
|
604
|
+
**One accepted case:** a disclosure opening to its content's height (`P-11`). Animate `grid-template-rows` from `0fr` to `1fr` on a wrapper, which the detector does not flag, or write the `height` transition with `<!-- jig-allow G-162: a disclosure grows to its content -->`.
|
|
605
|
+
The detector warns on `transition` or `transition-property` naming `all` or a layout property; a keyframe step setting one; Tailwind's `transition-all` and `transition-[<layout property>]`. `P-13`'s "Animate `transform` and `opacity`" becomes a pointer here.
|
|
606
|
+
|
|
607
|
+
### G-163 Several things moving at once
|
|
608
|
+
❌ A hero with a drifting gradient, a bouncing scroll arrow, a logo ticker and a pulsing "New" badge, all running together.
|
|
609
|
+
✅ At a time, one thing moves: the one the user caused, or the one they need to notice now. Things that move as one count as one: a list reordering, `P-13`'s ambient layers on one surface.
|
|
610
|
+
Motion is the strongest pull on the eye a page has. Two things moving split it; four make the page restless, and the one that matters (a saved state, an error arriving) competes with decoration and loses. `G-145` is the one-dot case of this rule.
|
|
611
|
+
|
|
593
612
|
---
|
|
594
613
|
|
|
595
614
|
## H. Code-level
|
package/rules/01-modes.md
CHANGED
|
@@ -190,7 +190,7 @@ Attempting to vary these by mode is a category error:
|
|
|
190
190
|
- **Accessibility floors.** Contrast, focus indication, target size, semantic markup. Identical in all three. `operator` being dense does not license a 24px tap target or a 3:1 body contrast.
|
|
191
191
|
- **Brand identity.** Palette, typeface, logo, voice.
|
|
192
192
|
- **State completeness.** Every mode renders loading, empty, error and disabled.
|
|
193
|
-
- **The anti-pattern file.** All
|
|
193
|
+
- **The anti-pattern file.** All 128 rules in it apply everywhere.
|
|
194
194
|
|
|
195
195
|
---
|
|
196
196
|
|
package/rules/02-tokens.md
CHANGED
|
@@ -243,6 +243,9 @@ away. That maps onto the tokens:
|
|
|
243
243
|
the closer analogue, and we do not ship one: exits in this system fade or
|
|
244
244
|
collapse in place rather than fly off screen, and a third easing token bought
|
|
245
245
|
only that one case.
|
|
246
|
+
- **Moving within the screen**, from one place to another: `--ease-in-out`. The
|
|
247
|
+
element is on screen at the start and the end, so it speeds up leaving its
|
|
248
|
+
place and slows into the new one (`G-161`).
|
|
246
249
|
- **Never linear** for anything that moves. Linear reads as mechanical because
|
|
247
250
|
nothing physical moves that way. Colour and opacity are the exception — a
|
|
248
251
|
simple curve is enough there, and often linear is fine.
|
package/rules/03-patterns.md
CHANGED
|
@@ -429,7 +429,8 @@ it that they did not cause. Motion in those modes always means something changed
|
|
|
429
429
|
- **Animate `transform` and `opacity`.** These run on the compositor. A loop that
|
|
430
430
|
runs forever on every frame the page is open cannot afford animated `blur`,
|
|
431
431
|
`box-shadow`, or anything that triggers layout — the cost is not paid once, it is
|
|
432
|
-
paid continuously, on whatever device the reader has.
|
|
432
|
+
paid continuously, on whatever device the reader has. `G-162` holds this for all motion;
|
|
433
|
+
here the cost is simply paid forever.
|
|
433
434
|
|
|
434
435
|
**Anti-pattern:** ambient motion used to direct attention. It is atmosphere, not a
|
|
435
436
|
signal. The moment it points at something it has become interaction motion badly
|
package/rules/05-copy.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# 05 · Copy
|
|
2
2
|
|
|
3
3
|
**Status:** draft v0.1
|
|
4
|
-
**Scope:** universal. Interface text in every mode.
|
|
5
|
-
**Load when:** writing or reviewing any user-facing string — labels, buttons, headings, errors, empty states, help text.
|
|
4
|
+
**Scope:** universal. Interface text in every mode, and the prose a page ships: docs, guides, marketing pages, blog posts.
|
|
5
|
+
**Load when:** writing or reviewing any user-facing string — labels, buttons, headings, errors, empty states, help text — or any prose longer than a paragraph.
|
|
6
6
|
|
|
7
7
|
Interface text is interface design. A screen with perfect spacing and a vague button label is a broken screen. Most of what follows costs nothing to apply and is invisible when done well.
|
|
8
8
|
|
|
@@ -142,6 +142,89 @@ See `P-01` for *where* the message goes and `F-37` for field-level validation te
|
|
|
142
142
|
|
|
143
143
|
---
|
|
144
144
|
|
|
145
|
+
## Prose
|
|
146
|
+
|
|
147
|
+
**Scope:** prose longer than a paragraph that a page ships: docs, guides,
|
|
148
|
+
marketing pages, and everything under *Long-form* below. Interface strings stay
|
|
149
|
+
under the rules above; `I-79`'s 20-word sentence limit is for them, not for
|
|
150
|
+
prose. A page with no prose longer than a paragraph judges these `n/a`.
|
|
151
|
+
|
|
152
|
+
These rules judge whether prose is specific, sourced and authored. They never
|
|
153
|
+
judge who wrote it: a finding says the copy reads as generic, never that a
|
|
154
|
+
model wrote it.
|
|
155
|
+
|
|
156
|
+
### I-148 A claim with no source
|
|
157
|
+
❌ "Teams using Acme ship 37% faster." "A 2024 Stanford study found…" A feature described that the product does not have.
|
|
158
|
+
✅ Every figure, study, quotation, date and feature a page states traces to something in the project: its data, its docs, a link to the source, the product itself. Otherwise it is cut, or written as what it is: "in our own use", "we expect".
|
|
159
|
+
A made-up figure reads exactly like a real one, and it is the claim a reader is most likely to repeat. Of everything here, it costs the most when it is wrong.
|
|
160
|
+
|
|
161
|
+
### I-149 Specific in sound, empty in fact
|
|
162
|
+
❌ "Organisations that adopt these practices often see significant gains in efficiency."
|
|
163
|
+
✅ Name who, how many, how much, compared with what. "The billing team closed the month in two days instead of five."
|
|
164
|
+
The test, as `I-81` has it for headlines: if the sentence would still be true after swapping in any other product, team or year, it says nothing.
|
|
165
|
+
|
|
166
|
+
### I-150 Formula openers, closers and signposts
|
|
167
|
+
❌ "In today's rapidly changing world…" "It is important to note that…" "Let's dive in." "Here's the thing:" "In conclusion…" "Only time will tell."
|
|
168
|
+
✅ Start with the point; end when it has been made. Signpost only where a reader would otherwise be lost.
|
|
169
|
+
`check` warns on a short, fixed list of phrases that are almost never needed; the judgment half covers the same habit in other words. A quotation keeps its own words, as with `I-118`.
|
|
170
|
+
|
|
171
|
+
### I-151 Saying it twice
|
|
172
|
+
❌ A conclusion that restates the introduction. A lead sentence repeated as the next section's opening. The same point made again in new words two paragraphs later.
|
|
173
|
+
✅ Each paragraph adds something. Where a reader needs a reminder, point back to where it was said.
|
|
174
|
+
|
|
175
|
+
### I-152 A rhetorical shape on repeat
|
|
176
|
+
❌ "It's not X, it's Y" in every section; three adjectives, three verbs, three clauses, sentence after sentence; every paragraph built claim, example, takeaway.
|
|
177
|
+
✅ Any one of these is fine. The finding is density: the same shape often enough that a reader starts to hear it.
|
|
178
|
+
|
|
179
|
+
### I-153 Enthusiasm the content has not earned
|
|
180
|
+
❌ "An incredibly exciting, truly transformative opportunity." "The possibilities are endless."
|
|
181
|
+
✅ Let the thing described make the case. If it is impressive, the specifics show it; if they do not, the adjectives will not.
|
|
182
|
+
|
|
183
|
+
### I-154 Stacked hedges
|
|
184
|
+
❌ "It may potentially suggest that this could, in some cases, help."
|
|
185
|
+
✅ One qualifier, where the uncertainty is real: "The evidence suggests…"
|
|
186
|
+
Exception: legal, medical and scientific text, and any claim that is genuinely uncertain, may need more.
|
|
187
|
+
|
|
188
|
+
### I-155 Emoji in headings
|
|
189
|
+
❌ "🚀 Getting started", "✨ Key features"
|
|
190
|
+
✅ The words carry the heading. An emoji is read aloud by a screen reader as its name, and at the head of every section it reads as a template.
|
|
191
|
+
In markup, `A-05` already reports every emoji, a heading's included; `check` reports this rule for a Markdown page's headings, which `A-05` does not read.
|
|
192
|
+
|
|
193
|
+
### I-156 Structure imposed rather than earned
|
|
194
|
+
❌ Overview, Key benefits, Challenges, Best practices, Conclusion, whatever the subject. A heading every two paragraphs. Every bullet opening with a bold phrase. A numbered list for things with no order.
|
|
195
|
+
✅ Let the content decide the structure: a heading where a reader would look for one, a numbered list for a sequence, bold only where a reader scanning must stop.
|
|
196
|
+
|
|
197
|
+
---
|
|
198
|
+
|
|
199
|
+
## Long-form
|
|
200
|
+
|
|
201
|
+
**Scope:** authored writing a person puts their name to: blog posts, essays,
|
|
202
|
+
case studies, release notes written as a story. Everything under *Prose* applies
|
|
203
|
+
as well. Judged by a reader, never measured: rhythm and voice have no number a
|
|
204
|
+
check could hold, and a score would reward prose that games it.
|
|
205
|
+
|
|
206
|
+
### I-157 Nothing only the author could say
|
|
207
|
+
❌ "The migration was challenging, but the team learned valuable lessons."
|
|
208
|
+
✅ "The migration looked like a weekend's work. It took three weeks, because two services wrote the same table and nobody had written that down."
|
|
209
|
+
A post worth reading holds something the reader could not have written themselves: a case, a number, a mistake, a decision and its reason.
|
|
210
|
+
|
|
211
|
+
### I-158 No point of view
|
|
212
|
+
❌ "There are several factors to consider, each with its own trade-offs."
|
|
213
|
+
✅ Say which factor mattered, and why: "The technology was not the hard part. Changing how procurement worked was."
|
|
214
|
+
Balance is fine when the question is open. A post that never commits to anything has not said what its author thinks.
|
|
215
|
+
|
|
216
|
+
### I-159 An even rhythm
|
|
217
|
+
❌ Sentence after sentence of the same length and build; paragraphs of identical size down the page.
|
|
218
|
+
✅ Short sentences where something lands, longer ones where an idea needs room. Read it aloud: an even rhythm is audible long before it is visible.
|
|
219
|
+
Not a length rule, and not a count: `I-79`'s limit is for interface strings.
|
|
220
|
+
|
|
221
|
+
### I-160 Feeling named, not shown
|
|
222
|
+
❌ "I was fascinated by the results, which provided valuable insights."
|
|
223
|
+
✅ "I did not expect the result. We had tested it three times, and it failed in exactly the same place."
|
|
224
|
+
Where a post reports a reaction, the specifics carry it; a named emotion with nothing behind it reads as flat.
|
|
225
|
+
|
|
226
|
+
---
|
|
227
|
+
|
|
145
228
|
## L-06 · Copy checklist
|
|
146
229
|
|
|
147
230
|
1. Sentence case throughout? (`I-53`)
|
|
@@ -152,3 +235,6 @@ See `P-01` for *where* the message goes and `F-37` for field-level validation te
|
|
|
152
235
|
6. Numerals as figures, formatted consistently? (`I-83`)
|
|
153
236
|
7. One word per concept across the whole product? (`I-87`)
|
|
154
237
|
8. Every error saying what happened and what to do next? (`I-90`)
|
|
238
|
+
9. Every figure, study, quotation and feature traceable to a source? (`I-148`)
|
|
239
|
+
10. Prose saying something specific, once, without formula? (`I-149`, `I-150`, `I-151`)
|
|
240
|
+
11. For long-form: something only the author could say, and a view? (`I-157`, `I-158`)
|
package/rules.index.json
CHANGED
|
@@ -1013,5 +1013,119 @@
|
|
|
1013
1013
|
"severity": "warning",
|
|
1014
1014
|
"since": "0.17.0",
|
|
1015
1015
|
"pass": "screen"
|
|
1016
|
+
},
|
|
1017
|
+
{
|
|
1018
|
+
"id": "I-148",
|
|
1019
|
+
"bucket": "judgment",
|
|
1020
|
+
"severity": "warning",
|
|
1021
|
+
"since": "0.23.0",
|
|
1022
|
+
"pass": "code"
|
|
1023
|
+
},
|
|
1024
|
+
{
|
|
1025
|
+
"id": "I-149",
|
|
1026
|
+
"bucket": "judgment",
|
|
1027
|
+
"severity": "note",
|
|
1028
|
+
"since": "0.23.0",
|
|
1029
|
+
"pass": "code"
|
|
1030
|
+
},
|
|
1031
|
+
{
|
|
1032
|
+
"id": "I-150",
|
|
1033
|
+
"bucket": "hybrid",
|
|
1034
|
+
"severity": "warning",
|
|
1035
|
+
"since": "0.23.0",
|
|
1036
|
+
"detector": "formula-phrase",
|
|
1037
|
+
"pass": "code"
|
|
1038
|
+
},
|
|
1039
|
+
{
|
|
1040
|
+
"id": "I-151",
|
|
1041
|
+
"bucket": "judgment",
|
|
1042
|
+
"severity": "note",
|
|
1043
|
+
"since": "0.23.0",
|
|
1044
|
+
"pass": "code"
|
|
1045
|
+
},
|
|
1046
|
+
{
|
|
1047
|
+
"id": "I-152",
|
|
1048
|
+
"bucket": "judgment",
|
|
1049
|
+
"severity": "note",
|
|
1050
|
+
"since": "0.23.0",
|
|
1051
|
+
"pass": "code"
|
|
1052
|
+
},
|
|
1053
|
+
{
|
|
1054
|
+
"id": "I-153",
|
|
1055
|
+
"bucket": "judgment",
|
|
1056
|
+
"severity": "note",
|
|
1057
|
+
"since": "0.23.0",
|
|
1058
|
+
"pass": "code"
|
|
1059
|
+
},
|
|
1060
|
+
{
|
|
1061
|
+
"id": "I-154",
|
|
1062
|
+
"bucket": "judgment",
|
|
1063
|
+
"severity": "note",
|
|
1064
|
+
"since": "0.23.0",
|
|
1065
|
+
"pass": "code"
|
|
1066
|
+
},
|
|
1067
|
+
{
|
|
1068
|
+
"id": "I-155",
|
|
1069
|
+
"bucket": "mechanical",
|
|
1070
|
+
"severity": "warning",
|
|
1071
|
+
"since": "0.23.0",
|
|
1072
|
+
"detector": "heading-emoji"
|
|
1073
|
+
},
|
|
1074
|
+
{
|
|
1075
|
+
"id": "I-156",
|
|
1076
|
+
"bucket": "judgment",
|
|
1077
|
+
"severity": "note",
|
|
1078
|
+
"since": "0.23.0",
|
|
1079
|
+
"pass": "code"
|
|
1080
|
+
},
|
|
1081
|
+
{
|
|
1082
|
+
"id": "I-157",
|
|
1083
|
+
"bucket": "judgment",
|
|
1084
|
+
"severity": "warning",
|
|
1085
|
+
"since": "0.23.0",
|
|
1086
|
+
"pass": "code"
|
|
1087
|
+
},
|
|
1088
|
+
{
|
|
1089
|
+
"id": "I-158",
|
|
1090
|
+
"bucket": "judgment",
|
|
1091
|
+
"severity": "note",
|
|
1092
|
+
"since": "0.23.0",
|
|
1093
|
+
"pass": "code"
|
|
1094
|
+
},
|
|
1095
|
+
{
|
|
1096
|
+
"id": "I-159",
|
|
1097
|
+
"bucket": "judgment",
|
|
1098
|
+
"severity": "note",
|
|
1099
|
+
"since": "0.23.0",
|
|
1100
|
+
"pass": "code"
|
|
1101
|
+
},
|
|
1102
|
+
{
|
|
1103
|
+
"id": "I-160",
|
|
1104
|
+
"bucket": "judgment",
|
|
1105
|
+
"severity": "note",
|
|
1106
|
+
"since": "0.23.0",
|
|
1107
|
+
"pass": "code"
|
|
1108
|
+
},
|
|
1109
|
+
{
|
|
1110
|
+
"id": "G-161",
|
|
1111
|
+
"bucket": "judgment",
|
|
1112
|
+
"severity": "note",
|
|
1113
|
+
"since": "0.23.0",
|
|
1114
|
+
"pass": "code"
|
|
1115
|
+
},
|
|
1116
|
+
{
|
|
1117
|
+
"id": "G-162",
|
|
1118
|
+
"bucket": "hybrid",
|
|
1119
|
+
"severity": "warning",
|
|
1120
|
+
"since": "0.23.0",
|
|
1121
|
+
"detector": "layout-motion",
|
|
1122
|
+
"pass": "code"
|
|
1123
|
+
},
|
|
1124
|
+
{
|
|
1125
|
+
"id": "G-163",
|
|
1126
|
+
"bucket": "judgment",
|
|
1127
|
+
"severity": "note",
|
|
1128
|
+
"since": "0.23.0",
|
|
1129
|
+
"pass": "code"
|
|
1016
1130
|
}
|
|
1017
1131
|
]
|