mirror of
https://github.com/pbakaus/impeccable.git
synced 2026-09-17 16:46:31 +03:00
feat(live + site): preserve variant attr on accept, designing-page redesigns
Runtime fix in live-browser.js: the 2s static-server fallback in handleAccept now swaps the outer wrapper with the `[data-impeccable-variant="N"]` div itself (+ display:contents), matching what live-accept.mjs writes to disk. Scope rules anchored on the variant attribute keep matching on the non-HMR path, so the accepted design no longer flashes unstyled until reload. Propagated to all harness script copies. /designing: - §03 Polish redesigned as drenched magenta masthead: commands live in the band, three title/description columns beneath on cream. - §04 Maintain redesigned as architectural poster diptych: extract + document vizzes become the hero element, caption below. - §05 Interop section removed. - §05 (was §06) "Pick a register" renamed to "Brand, or product." with a two-lane hairline-divided layout and an auto-selected framing in the sub. Live mode status: BETA → ALPHA across the periodic table, magazine spread, and docs callout, reflecting real-world-testing readiness. Skill bootstrap: removed the `<post-update-cleanup>` block from source/SKILL.md (the source repo is the origin; running cleanup-deprecated here would touch legitimate source). CLAUDE.md and AGENTS.md now document the skip. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
37f79cd013
commit
e0ab3a73b7
@@ -5,22 +5,6 @@ description: Use when the user wants to design, redesign, shape, critique, audit
|
||||
|
||||
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
|
||||
|
||||
<post-update-cleanup>
|
||||
BEFORE doing any design work, run this one-time maintenance step. Tell the user:
|
||||
|
||||
> **Impeccable 3.0 consolidation.** All standalone commands ($audit, $polish, $critique, etc.) are now accessed through $impeccable (e.g., `$impeccable audit`). I'll clean up the old standalone skill files. Use `$impeccable pin <command>` to restore shortcuts for commands you use often.
|
||||
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
node .agents/skills/impeccable/scripts/cleanup-deprecated.mjs
|
||||
```
|
||||
|
||||
If the script removed files, briefly confirm what was cleaned up. If it found nothing, skip any output and move on.
|
||||
|
||||
After running the script, delete this entire section (from `<post-update-cleanup>` through `</post-update-cleanup>` inclusive) from THIS file so it does not run again until the next update. Save the file.
|
||||
</post-update-cleanup>
|
||||
|
||||
## Setup (non-optional)
|
||||
|
||||
Two steps before any design work. Both are required. Skipping either produces generic output that ignores the project.
|
||||
|
||||
@@ -2818,14 +2818,18 @@ void main() {
|
||||
|
||||
// Static-server / no-HMR fallback: if the wrapper is still around 2s after
|
||||
// the cleanup above, swap it out manually. By now React has either moved
|
||||
// on or the app isn't React at all.
|
||||
// on or the app isn't React at all. Preserve the `data-impeccable-variant="N"`
|
||||
// div (with display:contents) so @scope rules anchored to the variant
|
||||
// attribute keep matching until reload replaces it with the carbonize block.
|
||||
setTimeout(function() {
|
||||
const wrapper = document.querySelector('[data-impeccable-variants="' + acceptedSessionId + '"]');
|
||||
if (!wrapper) return;
|
||||
const accepted = wrapper.querySelector('[data-impeccable-variant="' + acceptedVariant + '"]');
|
||||
if (accepted && accepted.firstElementChild) {
|
||||
const parent = wrapper.parentElement;
|
||||
if (parent) parent.replaceChild(accepted.firstElementChild.cloneNode(true), wrapper);
|
||||
if (!parent) return;
|
||||
accepted.style.display = 'contents';
|
||||
parent.replaceChild(accepted, wrapper);
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
@@ -11,22 +11,6 @@ allowed-tools:
|
||||
|
||||
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
|
||||
|
||||
<post-update-cleanup>
|
||||
BEFORE doing any design work, run this one-time maintenance step. Tell the user:
|
||||
|
||||
> **Impeccable 3.0 consolidation.** All standalone commands (/audit, /polish, /critique, etc.) are now accessed through /impeccable (e.g., `/impeccable audit`). I'll clean up the old standalone skill files. Use `/impeccable pin <command>` to restore shortcuts for commands you use often.
|
||||
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
node .claude/skills/impeccable/scripts/cleanup-deprecated.mjs
|
||||
```
|
||||
|
||||
If the script removed files, briefly confirm what was cleaned up. If it found nothing, skip any output and move on.
|
||||
|
||||
After running the script, delete this entire section (from `<post-update-cleanup>` through `</post-update-cleanup>` inclusive) from THIS file so it does not run again until the next update. Save the file.
|
||||
</post-update-cleanup>
|
||||
|
||||
## Setup (non-optional)
|
||||
|
||||
Two steps before any design work. Both are required. Skipping either produces generic output that ignores the project.
|
||||
|
||||
@@ -2818,14 +2818,18 @@ void main() {
|
||||
|
||||
// Static-server / no-HMR fallback: if the wrapper is still around 2s after
|
||||
// the cleanup above, swap it out manually. By now React has either moved
|
||||
// on or the app isn't React at all.
|
||||
// on or the app isn't React at all. Preserve the `data-impeccable-variant="N"`
|
||||
// div (with display:contents) so @scope rules anchored to the variant
|
||||
// attribute keep matching until reload replaces it with the carbonize block.
|
||||
setTimeout(function() {
|
||||
const wrapper = document.querySelector('[data-impeccable-variants="' + acceptedSessionId + '"]');
|
||||
if (!wrapper) return;
|
||||
const accepted = wrapper.querySelector('[data-impeccable-variant="' + acceptedVariant + '"]');
|
||||
if (accepted && accepted.firstElementChild) {
|
||||
const parent = wrapper.parentElement;
|
||||
if (parent) parent.replaceChild(accepted.firstElementChild.cloneNode(true), wrapper);
|
||||
if (!parent) return;
|
||||
accepted.style.display = 'contents';
|
||||
parent.replaceChild(accepted, wrapper);
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
@@ -7,22 +7,6 @@ license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md f
|
||||
|
||||
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
|
||||
|
||||
<post-update-cleanup>
|
||||
BEFORE doing any design work, run this one-time maintenance step. Tell the user:
|
||||
|
||||
> **Impeccable 3.0 consolidation.** All standalone commands (/audit, /polish, /critique, etc.) are now accessed through /impeccable (e.g., `/impeccable audit`). I'll clean up the old standalone skill files. Use `/impeccable pin <command>` to restore shortcuts for commands you use often.
|
||||
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
node .cursor/skills/impeccable/scripts/cleanup-deprecated.mjs
|
||||
```
|
||||
|
||||
If the script removed files, briefly confirm what was cleaned up. If it found nothing, skip any output and move on.
|
||||
|
||||
After running the script, delete this entire section (from `<post-update-cleanup>` through `</post-update-cleanup>` inclusive) from THIS file so it does not run again until the next update. Save the file.
|
||||
</post-update-cleanup>
|
||||
|
||||
## Setup (non-optional)
|
||||
|
||||
Two steps before any design work. Both are required. Skipping either produces generic output that ignores the project.
|
||||
|
||||
@@ -2818,14 +2818,18 @@ void main() {
|
||||
|
||||
// Static-server / no-HMR fallback: if the wrapper is still around 2s after
|
||||
// the cleanup above, swap it out manually. By now React has either moved
|
||||
// on or the app isn't React at all.
|
||||
// on or the app isn't React at all. Preserve the `data-impeccable-variant="N"`
|
||||
// div (with display:contents) so @scope rules anchored to the variant
|
||||
// attribute keep matching until reload replaces it with the carbonize block.
|
||||
setTimeout(function() {
|
||||
const wrapper = document.querySelector('[data-impeccable-variants="' + acceptedSessionId + '"]');
|
||||
if (!wrapper) return;
|
||||
const accepted = wrapper.querySelector('[data-impeccable-variant="' + acceptedVariant + '"]');
|
||||
if (accepted && accepted.firstElementChild) {
|
||||
const parent = wrapper.parentElement;
|
||||
if (parent) parent.replaceChild(accepted.firstElementChild.cloneNode(true), wrapper);
|
||||
if (!parent) return;
|
||||
accepted.style.display = 'contents';
|
||||
parent.replaceChild(accepted, wrapper);
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
@@ -6,22 +6,6 @@ version: 3.0.0
|
||||
|
||||
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
|
||||
|
||||
<post-update-cleanup>
|
||||
BEFORE doing any design work, run this one-time maintenance step. Tell the user:
|
||||
|
||||
> **Impeccable 3.0 consolidation.** All standalone commands (/audit, /polish, /critique, etc.) are now accessed through /impeccable (e.g., `/impeccable audit`). I'll clean up the old standalone skill files. Use `/impeccable pin <command>` to restore shortcuts for commands you use often.
|
||||
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
node .gemini/skills/impeccable/scripts/cleanup-deprecated.mjs
|
||||
```
|
||||
|
||||
If the script removed files, briefly confirm what was cleaned up. If it found nothing, skip any output and move on.
|
||||
|
||||
After running the script, delete this entire section (from `<post-update-cleanup>` through `</post-update-cleanup>` inclusive) from THIS file so it does not run again until the next update. Save the file.
|
||||
</post-update-cleanup>
|
||||
|
||||
## Setup (non-optional)
|
||||
|
||||
Two steps before any design work. Both are required. Skipping either produces generic output that ignores the project.
|
||||
|
||||
@@ -2818,14 +2818,18 @@ void main() {
|
||||
|
||||
// Static-server / no-HMR fallback: if the wrapper is still around 2s after
|
||||
// the cleanup above, swap it out manually. By now React has either moved
|
||||
// on or the app isn't React at all.
|
||||
// on or the app isn't React at all. Preserve the `data-impeccable-variant="N"`
|
||||
// div (with display:contents) so @scope rules anchored to the variant
|
||||
// attribute keep matching until reload replaces it with the carbonize block.
|
||||
setTimeout(function() {
|
||||
const wrapper = document.querySelector('[data-impeccable-variants="' + acceptedSessionId + '"]');
|
||||
if (!wrapper) return;
|
||||
const accepted = wrapper.querySelector('[data-impeccable-variant="' + acceptedVariant + '"]');
|
||||
if (accepted && accepted.firstElementChild) {
|
||||
const parent = wrapper.parentElement;
|
||||
if (parent) parent.replaceChild(accepted.firstElementChild.cloneNode(true), wrapper);
|
||||
if (!parent) return;
|
||||
accepted.style.display = 'contents';
|
||||
parent.replaceChild(accepted, wrapper);
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
@@ -9,22 +9,6 @@ license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md f
|
||||
|
||||
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
|
||||
|
||||
<post-update-cleanup>
|
||||
BEFORE doing any design work, run this one-time maintenance step. Tell the user:
|
||||
|
||||
> **Impeccable 3.0 consolidation.** All standalone commands (/audit, /polish, /critique, etc.) are now accessed through /impeccable (e.g., `/impeccable audit`). I'll clean up the old standalone skill files. Use `/impeccable pin <command>` to restore shortcuts for commands you use often.
|
||||
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
node .github/skills/impeccable/scripts/cleanup-deprecated.mjs
|
||||
```
|
||||
|
||||
If the script removed files, briefly confirm what was cleaned up. If it found nothing, skip any output and move on.
|
||||
|
||||
After running the script, delete this entire section (from `<post-update-cleanup>` through `</post-update-cleanup>` inclusive) from THIS file so it does not run again until the next update. Save the file.
|
||||
</post-update-cleanup>
|
||||
|
||||
## Setup (non-optional)
|
||||
|
||||
Two steps before any design work. Both are required. Skipping either produces generic output that ignores the project.
|
||||
|
||||
@@ -2818,14 +2818,18 @@ void main() {
|
||||
|
||||
// Static-server / no-HMR fallback: if the wrapper is still around 2s after
|
||||
// the cleanup above, swap it out manually. By now React has either moved
|
||||
// on or the app isn't React at all.
|
||||
// on or the app isn't React at all. Preserve the `data-impeccable-variant="N"`
|
||||
// div (with display:contents) so @scope rules anchored to the variant
|
||||
// attribute keep matching until reload replaces it with the carbonize block.
|
||||
setTimeout(function() {
|
||||
const wrapper = document.querySelector('[data-impeccable-variants="' + acceptedSessionId + '"]');
|
||||
if (!wrapper) return;
|
||||
const accepted = wrapper.querySelector('[data-impeccable-variant="' + acceptedVariant + '"]');
|
||||
if (accepted && accepted.firstElementChild) {
|
||||
const parent = wrapper.parentElement;
|
||||
if (parent) parent.replaceChild(accepted.firstElementChild.cloneNode(true), wrapper);
|
||||
if (!parent) return;
|
||||
accepted.style.display = 'contents';
|
||||
parent.replaceChild(accepted, wrapper);
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
@@ -7,22 +7,6 @@ license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md f
|
||||
|
||||
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
|
||||
|
||||
<post-update-cleanup>
|
||||
BEFORE doing any design work, run this one-time maintenance step. Tell the user:
|
||||
|
||||
> **Impeccable 3.0 consolidation.** All standalone commands (/audit, /polish, /critique, etc.) are now accessed through /impeccable (e.g., `/impeccable audit`). I'll clean up the old standalone skill files. Use `/impeccable pin <command>` to restore shortcuts for commands you use often.
|
||||
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
node .kiro/skills/impeccable/scripts/cleanup-deprecated.mjs
|
||||
```
|
||||
|
||||
If the script removed files, briefly confirm what was cleaned up. If it found nothing, skip any output and move on.
|
||||
|
||||
After running the script, delete this entire section (from `<post-update-cleanup>` through `</post-update-cleanup>` inclusive) from THIS file so it does not run again until the next update. Save the file.
|
||||
</post-update-cleanup>
|
||||
|
||||
## Setup (non-optional)
|
||||
|
||||
Two steps before any design work. Both are required. Skipping either produces generic output that ignores the project.
|
||||
|
||||
@@ -2818,14 +2818,18 @@ void main() {
|
||||
|
||||
// Static-server / no-HMR fallback: if the wrapper is still around 2s after
|
||||
// the cleanup above, swap it out manually. By now React has either moved
|
||||
// on or the app isn't React at all.
|
||||
// on or the app isn't React at all. Preserve the `data-impeccable-variant="N"`
|
||||
// div (with display:contents) so @scope rules anchored to the variant
|
||||
// attribute keep matching until reload replaces it with the carbonize block.
|
||||
setTimeout(function() {
|
||||
const wrapper = document.querySelector('[data-impeccable-variants="' + acceptedSessionId + '"]');
|
||||
if (!wrapper) return;
|
||||
const accepted = wrapper.querySelector('[data-impeccable-variant="' + acceptedVariant + '"]');
|
||||
if (accepted && accepted.firstElementChild) {
|
||||
const parent = wrapper.parentElement;
|
||||
if (parent) parent.replaceChild(accepted.firstElementChild.cloneNode(true), wrapper);
|
||||
if (!parent) return;
|
||||
accepted.style.display = 'contents';
|
||||
parent.replaceChild(accepted, wrapper);
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
@@ -11,22 +11,6 @@ allowed-tools:
|
||||
|
||||
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
|
||||
|
||||
<post-update-cleanup>
|
||||
BEFORE doing any design work, run this one-time maintenance step. Tell the user:
|
||||
|
||||
> **Impeccable 3.0 consolidation.** All standalone commands (/audit, /polish, /critique, etc.) are now accessed through /impeccable (e.g., `/impeccable audit`). I'll clean up the old standalone skill files. Use `/impeccable pin <command>` to restore shortcuts for commands you use often.
|
||||
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
node .opencode/skills/impeccable/scripts/cleanup-deprecated.mjs
|
||||
```
|
||||
|
||||
If the script removed files, briefly confirm what was cleaned up. If it found nothing, skip any output and move on.
|
||||
|
||||
After running the script, delete this entire section (from `<post-update-cleanup>` through `</post-update-cleanup>` inclusive) from THIS file so it does not run again until the next update. Save the file.
|
||||
</post-update-cleanup>
|
||||
|
||||
## Setup (non-optional)
|
||||
|
||||
Two steps before any design work. Both are required. Skipping either produces generic output that ignores the project.
|
||||
|
||||
@@ -2818,14 +2818,18 @@ void main() {
|
||||
|
||||
// Static-server / no-HMR fallback: if the wrapper is still around 2s after
|
||||
// the cleanup above, swap it out manually. By now React has either moved
|
||||
// on or the app isn't React at all.
|
||||
// on or the app isn't React at all. Preserve the `data-impeccable-variant="N"`
|
||||
// div (with display:contents) so @scope rules anchored to the variant
|
||||
// attribute keep matching until reload replaces it with the carbonize block.
|
||||
setTimeout(function() {
|
||||
const wrapper = document.querySelector('[data-impeccable-variants="' + acceptedSessionId + '"]');
|
||||
if (!wrapper) return;
|
||||
const accepted = wrapper.querySelector('[data-impeccable-variant="' + acceptedVariant + '"]');
|
||||
if (accepted && accepted.firstElementChild) {
|
||||
const parent = wrapper.parentElement;
|
||||
if (parent) parent.replaceChild(accepted.firstElementChild.cloneNode(true), wrapper);
|
||||
if (!parent) return;
|
||||
accepted.style.display = 'contents';
|
||||
parent.replaceChild(accepted, wrapper);
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
@@ -9,22 +9,6 @@ allowed-tools:
|
||||
|
||||
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
|
||||
|
||||
<post-update-cleanup>
|
||||
BEFORE doing any design work, run this one-time maintenance step. Tell the user:
|
||||
|
||||
> **Impeccable 3.0 consolidation.** All standalone commands (/audit, /polish, /critique, etc.) are now accessed through /impeccable (e.g., `/impeccable audit`). I'll clean up the old standalone skill files. Use `/impeccable pin <command>` to restore shortcuts for commands you use often.
|
||||
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
node .pi/skills/impeccable/scripts/cleanup-deprecated.mjs
|
||||
```
|
||||
|
||||
If the script removed files, briefly confirm what was cleaned up. If it found nothing, skip any output and move on.
|
||||
|
||||
After running the script, delete this entire section (from `<post-update-cleanup>` through `</post-update-cleanup>` inclusive) from THIS file so it does not run again until the next update. Save the file.
|
||||
</post-update-cleanup>
|
||||
|
||||
## Setup (non-optional)
|
||||
|
||||
Two steps before any design work. Both are required. Skipping either produces generic output that ignores the project.
|
||||
|
||||
@@ -2818,14 +2818,18 @@ void main() {
|
||||
|
||||
// Static-server / no-HMR fallback: if the wrapper is still around 2s after
|
||||
// the cleanup above, swap it out manually. By now React has either moved
|
||||
// on or the app isn't React at all.
|
||||
// on or the app isn't React at all. Preserve the `data-impeccable-variant="N"`
|
||||
// div (with display:contents) so @scope rules anchored to the variant
|
||||
// attribute keep matching until reload replaces it with the carbonize block.
|
||||
setTimeout(function() {
|
||||
const wrapper = document.querySelector('[data-impeccable-variants="' + acceptedSessionId + '"]');
|
||||
if (!wrapper) return;
|
||||
const accepted = wrapper.querySelector('[data-impeccable-variant="' + acceptedVariant + '"]');
|
||||
if (accepted && accepted.firstElementChild) {
|
||||
const parent = wrapper.parentElement;
|
||||
if (parent) parent.replaceChild(accepted.firstElementChild.cloneNode(true), wrapper);
|
||||
if (!parent) return;
|
||||
accepted.style.display = 'contents';
|
||||
parent.replaceChild(accepted, wrapper);
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
@@ -11,22 +11,6 @@ allowed-tools:
|
||||
|
||||
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
|
||||
|
||||
<post-update-cleanup>
|
||||
BEFORE doing any design work, run this one-time maintenance step. Tell the user:
|
||||
|
||||
> **Impeccable 3.0 consolidation.** All standalone commands (/audit, /polish, /critique, etc.) are now accessed through /impeccable (e.g., `/impeccable audit`). I'll clean up the old standalone skill files. Use `/impeccable pin <command>` to restore shortcuts for commands you use often.
|
||||
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
node .rovodev/skills/impeccable/scripts/cleanup-deprecated.mjs
|
||||
```
|
||||
|
||||
If the script removed files, briefly confirm what was cleaned up. If it found nothing, skip any output and move on.
|
||||
|
||||
After running the script, delete this entire section (from `<post-update-cleanup>` through `</post-update-cleanup>` inclusive) from THIS file so it does not run again until the next update. Save the file.
|
||||
</post-update-cleanup>
|
||||
|
||||
## Setup (non-optional)
|
||||
|
||||
Two steps before any design work. Both are required. Skipping either produces generic output that ignores the project.
|
||||
|
||||
@@ -2818,14 +2818,18 @@ void main() {
|
||||
|
||||
// Static-server / no-HMR fallback: if the wrapper is still around 2s after
|
||||
// the cleanup above, swap it out manually. By now React has either moved
|
||||
// on or the app isn't React at all.
|
||||
// on or the app isn't React at all. Preserve the `data-impeccable-variant="N"`
|
||||
// div (with display:contents) so @scope rules anchored to the variant
|
||||
// attribute keep matching until reload replaces it with the carbonize block.
|
||||
setTimeout(function() {
|
||||
const wrapper = document.querySelector('[data-impeccable-variants="' + acceptedSessionId + '"]');
|
||||
if (!wrapper) return;
|
||||
const accepted = wrapper.querySelector('[data-impeccable-variant="' + acceptedVariant + '"]');
|
||||
if (accepted && accepted.firstElementChild) {
|
||||
const parent = wrapper.parentElement;
|
||||
if (parent) parent.replaceChild(accepted.firstElementChild.cloneNode(true), wrapper);
|
||||
if (!parent) return;
|
||||
accepted.style.display = 'contents';
|
||||
parent.replaceChild(accepted, wrapper);
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
@@ -9,22 +9,6 @@ license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md f
|
||||
|
||||
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
|
||||
|
||||
<post-update-cleanup>
|
||||
BEFORE doing any design work, run this one-time maintenance step. Tell the user:
|
||||
|
||||
> **Impeccable 3.0 consolidation.** All standalone commands (/audit, /polish, /critique, etc.) are now accessed through /impeccable (e.g., `/impeccable audit`). I'll clean up the old standalone skill files. Use `/impeccable pin <command>` to restore shortcuts for commands you use often.
|
||||
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
node .trae-cn/skills/impeccable/scripts/cleanup-deprecated.mjs
|
||||
```
|
||||
|
||||
If the script removed files, briefly confirm what was cleaned up. If it found nothing, skip any output and move on.
|
||||
|
||||
After running the script, delete this entire section (from `<post-update-cleanup>` through `</post-update-cleanup>` inclusive) from THIS file so it does not run again until the next update. Save the file.
|
||||
</post-update-cleanup>
|
||||
|
||||
## Setup (non-optional)
|
||||
|
||||
Two steps before any design work. Both are required. Skipping either produces generic output that ignores the project.
|
||||
|
||||
@@ -2818,14 +2818,18 @@ void main() {
|
||||
|
||||
// Static-server / no-HMR fallback: if the wrapper is still around 2s after
|
||||
// the cleanup above, swap it out manually. By now React has either moved
|
||||
// on or the app isn't React at all.
|
||||
// on or the app isn't React at all. Preserve the `data-impeccable-variant="N"`
|
||||
// div (with display:contents) so @scope rules anchored to the variant
|
||||
// attribute keep matching until reload replaces it with the carbonize block.
|
||||
setTimeout(function() {
|
||||
const wrapper = document.querySelector('[data-impeccable-variants="' + acceptedSessionId + '"]');
|
||||
if (!wrapper) return;
|
||||
const accepted = wrapper.querySelector('[data-impeccable-variant="' + acceptedVariant + '"]');
|
||||
if (accepted && accepted.firstElementChild) {
|
||||
const parent = wrapper.parentElement;
|
||||
if (parent) parent.replaceChild(accepted.firstElementChild.cloneNode(true), wrapper);
|
||||
if (!parent) return;
|
||||
accepted.style.display = 'contents';
|
||||
parent.replaceChild(accepted, wrapper);
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
@@ -9,22 +9,6 @@ license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md f
|
||||
|
||||
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
|
||||
|
||||
<post-update-cleanup>
|
||||
BEFORE doing any design work, run this one-time maintenance step. Tell the user:
|
||||
|
||||
> **Impeccable 3.0 consolidation.** All standalone commands (/audit, /polish, /critique, etc.) are now accessed through /impeccable (e.g., `/impeccable audit`). I'll clean up the old standalone skill files. Use `/impeccable pin <command>` to restore shortcuts for commands you use often.
|
||||
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
node .trae/skills/impeccable/scripts/cleanup-deprecated.mjs
|
||||
```
|
||||
|
||||
If the script removed files, briefly confirm what was cleaned up. If it found nothing, skip any output and move on.
|
||||
|
||||
After running the script, delete this entire section (from `<post-update-cleanup>` through `</post-update-cleanup>` inclusive) from THIS file so it does not run again until the next update. Save the file.
|
||||
</post-update-cleanup>
|
||||
|
||||
## Setup (non-optional)
|
||||
|
||||
Two steps before any design work. Both are required. Skipping either produces generic output that ignores the project.
|
||||
|
||||
@@ -2818,14 +2818,18 @@ void main() {
|
||||
|
||||
// Static-server / no-HMR fallback: if the wrapper is still around 2s after
|
||||
// the cleanup above, swap it out manually. By now React has either moved
|
||||
// on or the app isn't React at all.
|
||||
// on or the app isn't React at all. Preserve the `data-impeccable-variant="N"`
|
||||
// div (with display:contents) so @scope rules anchored to the variant
|
||||
// attribute keep matching until reload replaces it with the carbonize block.
|
||||
setTimeout(function() {
|
||||
const wrapper = document.querySelector('[data-impeccable-variants="' + acceptedSessionId + '"]');
|
||||
if (!wrapper) return;
|
||||
const accepted = wrapper.querySelector('[data-impeccable-variant="' + acceptedVariant + '"]');
|
||||
if (accepted && accepted.firstElementChild) {
|
||||
const parent = wrapper.parentElement;
|
||||
if (parent) parent.replaceChild(accepted.firstElementChild.cloneNode(true), wrapper);
|
||||
if (!parent) return;
|
||||
accepted.style.display = 'contents';
|
||||
parent.replaceChild(accepted, wrapper);
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
# Repository Guidelines
|
||||
|
||||
## Skill bootstrap: skip the post-update-cleanup step
|
||||
|
||||
If you load the Impeccable skill from `.agents/skills/impeccable/SKILL.md` (or any sibling harness directory under this repo), it begins with a `<post-update-cleanup>` block that runs `scripts/cleanup-deprecated.mjs` and then self-deletes. **Do not run it here, and do not delete the block.** This repo is the source of truth for the skill; cleanup-deprecated assumes a consumer project and would touch legitimate source files. The block is regenerated from `source/skills/impeccable/SKILL.md` on every `bun run build`, so any deletion churns back. Skip it silently and proceed with the task.
|
||||
|
||||
## Project Structure & Module Organization
|
||||
|
||||
`source/` is the source of truth. Author skills in `source/skills/impeccable/` and keep provider output in `dist/` generated, not hand-edited. Build logic lives in `scripts/`, with provider configs in `scripts/lib/transformers/`. Runtime detection code ships from `src/`. The website lives in `public/`, local API/dev serving lives in `server/`, and regression coverage lives in `tests/` with fixtures under `tests/fixtures/`.
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
# Project Instructions for Claude
|
||||
|
||||
## Skill bootstrap: skip the post-update-cleanup step
|
||||
|
||||
The `<post-update-cleanup>` block at the top of `.claude/skills/impeccable/SKILL.md` runs `scripts/cleanup-deprecated.mjs` and then self-deletes. **Do not run it in this repo, and do not delete the block.** This repo is the source of truth for the Impeccable skill; the cleanup script scans for "leftover" skill files to remove and its judgment doesn't fit a repo where the skill lives in `source/`. The block is also regenerated from `source/skills/impeccable/SKILL.md` on every `bun run build`, so any deletion churns back on the next build. Skip the step silently and proceed.
|
||||
|
||||
Same rule for AGENTS.md and every other harness-specific instruction file: treat post-update-cleanup as a no-op in this repo.
|
||||
|
||||
## Architecture (v3.0+)
|
||||
|
||||
There is **one** user-invocable skill, `impeccable`, with **23 commands** underneath it. Users type `/impeccable polish`, `/impeccable audit`, etc. The skill is defined in `source/skills/impeccable/`:
|
||||
|
||||
@@ -7,6 +7,11 @@ tagline: "Iterate on UI in the browser. Pick an element, drop a comment, get thr
|
||||
<span class="docs-live-callout-text">See it in action, with the animated demo, at <a href="/live-mode">/live-mode</a>. This page is the reference for what your AI harness reads when the command runs.</span>
|
||||
</div>
|
||||
|
||||
<div class="docs-live-callout">
|
||||
<span class="docs-live-callout-icon" aria-hidden="true">▸</span>
|
||||
<span class="docs-live-callout-text"><strong>Status: alpha.</strong> Live Mode works end-to-end and is ready to try, but it still needs more testing against real-world repos and framework configs. Expect rough edges on uncommon setups, and please report what breaks.</span>
|
||||
</div>
|
||||
|
||||
<div class="docs-viz-hero docs-viz-hero--plain">
|
||||
<div class="docs-viz-live-frame">
|
||||
<div class="docs-viz-live-chrome">
|
||||
|
||||
+267
-215
@@ -1319,6 +1319,24 @@
|
||||
max-width: 56ch;
|
||||
}
|
||||
|
||||
.live-mode-page-alpha-note {
|
||||
font-family: var(--font-body);
|
||||
font-size: 0.9375rem;
|
||||
line-height: 1.55;
|
||||
color: var(--color-ash);
|
||||
margin: 0;
|
||||
max-width: 56ch;
|
||||
padding: 10px 14px;
|
||||
border-left: 2px solid var(--color-accent);
|
||||
background: color-mix(in oklab, var(--color-accent) 6%, transparent);
|
||||
border-radius: 0 4px 4px 0;
|
||||
}
|
||||
|
||||
.live-mode-page-alpha-note strong {
|
||||
color: var(--color-ink);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.live-mode-start {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
@@ -2411,47 +2429,87 @@
|
||||
PHASE 3 — Polish (3-column editorial, no cards)
|
||||
============================================ */
|
||||
|
||||
/* Polish section — drenched magenta masthead band over a three-column
|
||||
title/description grid. Commands live in the band so the grid stays
|
||||
focused on the editorial titles. */
|
||||
.designing-polish {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: clamp(1.5rem, 3vw, 2.5rem);
|
||||
display: block;
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.designing-polish {
|
||||
grid-template-columns: 1fr;
|
||||
gap: var(--spacing-lg, 32px);
|
||||
}
|
||||
.designing-polish-band {
|
||||
background: var(--color-accent);
|
||||
padding: 20px 28px;
|
||||
display: grid;
|
||||
grid-template-columns: auto 1fr auto;
|
||||
gap: 24px;
|
||||
align-items: baseline;
|
||||
color: oklch(98% 0 0);
|
||||
}
|
||||
|
||||
.designing-polish-band-label {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.6875rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.22em;
|
||||
text-transform: uppercase;
|
||||
opacity: 0.85;
|
||||
}
|
||||
|
||||
.designing-polish-band-cmds {
|
||||
display: flex;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.8125rem;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.05em;
|
||||
}
|
||||
|
||||
.designing-polish-band-cmds a {
|
||||
display: inline-block;
|
||||
padding: 4px 16px;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
border-right: 1px solid color-mix(in oklch, currentColor 32%, transparent);
|
||||
}
|
||||
|
||||
.designing-polish-band-cmds a:first-child { padding-left: 0; }
|
||||
.designing-polish-band-cmds a:last-child { border-right: 0; padding-right: 0; }
|
||||
|
||||
.designing-polish-band-cmds a:hover {
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 3px;
|
||||
}
|
||||
|
||||
.designing-polish-band-meta {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.625rem;
|
||||
letter-spacing: 0.2em;
|
||||
text-transform: uppercase;
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
.designing-polish-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
gap: 28px;
|
||||
padding: 28px;
|
||||
background: var(--color-cream);
|
||||
border-left: 1px solid var(--color-mist);
|
||||
border-right: 1px solid var(--color-mist);
|
||||
border-bottom: 1px solid var(--color-mist);
|
||||
}
|
||||
|
||||
.designing-polish-col {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-sm, 16px);
|
||||
padding-top: var(--spacing-sm, 16px);
|
||||
border-top: 1px solid var(--color-ink);
|
||||
gap: 10px;
|
||||
}
|
||||
|
||||
.designing-polish-cmd {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.75rem;
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
.designing-polish-cmd a {
|
||||
color: inherit;
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 3px;
|
||||
text-decoration-thickness: 1px;
|
||||
}
|
||||
|
||||
.designing-polish-cmd a:hover { text-decoration-thickness: 2px; }
|
||||
|
||||
.designing-polish-name {
|
||||
font-family: var(--font-display);
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-size: 1.5rem;
|
||||
line-height: 1.1;
|
||||
line-height: 1.15;
|
||||
color: var(--color-ink);
|
||||
margin: 0;
|
||||
}
|
||||
@@ -2459,51 +2517,80 @@
|
||||
.designing-polish-desc {
|
||||
font-family: var(--font-body);
|
||||
font-size: 0.9375rem;
|
||||
line-height: 1.7;
|
||||
line-height: 1.6;
|
||||
color: var(--color-charcoal);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.designing-polish-grid {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
.designing-polish-band {
|
||||
grid-template-columns: 1fr;
|
||||
gap: 10px;
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
PHASE 4 — Maintain (two editorial columns + one hero viz each)
|
||||
============================================ */
|
||||
|
||||
/* Maintain section — architectural poster diptych. Each tile presents the
|
||||
domain visualization as the hero (stage) with a quiet caption beneath
|
||||
(command link, italic title, short description). */
|
||||
.designing-maintain {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: clamp(1.5rem, 3vw, 2.5rem);
|
||||
gap: clamp(1.5rem, 3vw, 2rem);
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.designing-maintain {
|
||||
grid-template-columns: 1fr;
|
||||
gap: var(--spacing-xl, 48px);
|
||||
}
|
||||
}
|
||||
|
||||
.designing-maintain-col {
|
||||
.designing-maintain-tile {
|
||||
margin: 0;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: var(--spacing-sm, 16px);
|
||||
gap: 18px;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.designing-maintain-stage {
|
||||
aspect-ratio: 5 / 3;
|
||||
background: var(--color-cream);
|
||||
border: 1px solid var(--color-mist);
|
||||
display: grid;
|
||||
place-items: center;
|
||||
padding: 28px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.designing-maintain-caption {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
}
|
||||
|
||||
.designing-maintain-label {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.75rem;
|
||||
font-size: 0.6875rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.2em;
|
||||
text-transform: uppercase;
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
.designing-maintain-label a {
|
||||
color: var(--color-accent);
|
||||
text-decoration: underline;
|
||||
text-underline-offset: 3px;
|
||||
text-decoration-thickness: 1px;
|
||||
color: inherit;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.designing-maintain-label a:hover { text-decoration-thickness: 2px; }
|
||||
.designing-maintain-label a:hover {
|
||||
color: var(--color-accent-hover);
|
||||
}
|
||||
|
||||
.designing-maintain-name {
|
||||
font-family: var(--font-display);
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-size: 1.5rem;
|
||||
line-height: 1.15;
|
||||
color: var(--color-ink);
|
||||
@@ -2512,159 +2599,191 @@
|
||||
|
||||
.designing-maintain-desc {
|
||||
font-family: var(--font-body);
|
||||
font-size: 0.9375rem;
|
||||
line-height: 1.7;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.55;
|
||||
color: var(--color-charcoal);
|
||||
margin: 0 0 var(--spacing-md, 24px) 0;
|
||||
margin: 0;
|
||||
max-width: 42ch;
|
||||
}
|
||||
|
||||
/* Extract consolidation viz — inline, no card */
|
||||
/* Extract consolidation viz — cloud of pills converging on a single primitive */
|
||||
.designing-extract-viz {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto 1fr;
|
||||
gap: 14px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 20px;
|
||||
flex-wrap: nowrap;
|
||||
justify-content: center;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.designing-extract-before {
|
||||
display: grid;
|
||||
grid-template-columns: repeat(3, 1fr);
|
||||
gap: 4px;
|
||||
}
|
||||
|
||||
.designing-extract-btn {
|
||||
padding: 6px 4px;
|
||||
background: var(--color-paper);
|
||||
border: 1px solid var(--color-mist);
|
||||
border-radius: 3px;
|
||||
font-family: var(--font-body);
|
||||
font-size: 9px;
|
||||
text-align: center;
|
||||
color: var(--color-charcoal);
|
||||
}
|
||||
|
||||
.designing-extract-btn:nth-child(1) { background: oklch(97% 0.01 20); }
|
||||
.designing-extract-btn:nth-child(3) { background: oklch(97% 0.01 220); color: oklch(40% 0.06 220); }
|
||||
.designing-extract-btn:nth-child(4) { border-radius: 0; }
|
||||
.designing-extract-btn:nth-child(6) { border-radius: 999px; }
|
||||
|
||||
.designing-extract-arrow {
|
||||
color: var(--color-accent);
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
.designing-extract-after {
|
||||
padding: 10px;
|
||||
background: var(--color-ink);
|
||||
color: var(--color-paper);
|
||||
font-family: var(--font-body);
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.06em;
|
||||
text-transform: uppercase;
|
||||
border-radius: 4px;
|
||||
text-align: center;
|
||||
min-height: 42px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
grid-template-columns: repeat(2, auto);
|
||||
gap: 6px;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/* DESIGN.md inline preview */
|
||||
.designing-designmd-preview {
|
||||
padding: 10px 14px;
|
||||
background: var(--color-cream);
|
||||
border-radius: 6px;
|
||||
font-family: var(--font-mono);
|
||||
.designing-extract-btn {
|
||||
display: inline-block;
|
||||
padding: 5px 12px;
|
||||
background: var(--color-paper);
|
||||
border: 1px solid var(--color-mist);
|
||||
font-family: var(--font-body);
|
||||
font-size: 0.75rem;
|
||||
line-height: 1.85;
|
||||
color: var(--color-ink);
|
||||
color: var(--color-ash);
|
||||
opacity: 0.75;
|
||||
}
|
||||
|
||||
.designing-extract-arrow {
|
||||
font-family: var(--font-display);
|
||||
font-style: italic;
|
||||
font-size: 2.5rem;
|
||||
line-height: 1;
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
.designing-extract-after {
|
||||
display: inline-block;
|
||||
padding: 10px 22px;
|
||||
background: var(--color-ink);
|
||||
color: var(--color-paper);
|
||||
font-family: var(--font-body);
|
||||
font-size: 1rem;
|
||||
font-weight: 500;
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
/* DESIGN.md index — enlarged list of numbered sections */
|
||||
.designing-designmd-preview {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
width: 100%;
|
||||
max-width: 280px;
|
||||
}
|
||||
|
||||
.designing-designmd-preview-line {
|
||||
display: flex;
|
||||
gap: 10px;
|
||||
align-items: baseline;
|
||||
display: grid;
|
||||
grid-template-columns: 32px 1fr;
|
||||
gap: 14px;
|
||||
padding-bottom: 6px;
|
||||
border-bottom: 1px solid var(--color-mist);
|
||||
font-family: var(--font-body);
|
||||
font-size: 0.9375rem;
|
||||
color: var(--color-ink);
|
||||
}
|
||||
|
||||
.designing-designmd-preview-line:last-child { border-bottom: 0; }
|
||||
|
||||
.designing-designmd-preview-num {
|
||||
color: var(--color-ash);
|
||||
min-width: 18px;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.75rem;
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
@media (max-width: 720px) {
|
||||
.designing-maintain {
|
||||
grid-template-columns: 1fr;
|
||||
gap: var(--spacing-xl, 48px);
|
||||
}
|
||||
.designing-extract-viz { flex-wrap: wrap; }
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
APPENDIX: Register (cross-link, quieter aside)
|
||||
============================================ */
|
||||
|
||||
.designing-register {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1.6fr;
|
||||
gap: clamp(1.5rem, 4vw, 2.5rem);
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.designing-register {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
.designing-register-preview {
|
||||
/* Two-lane explainer — brand vs product as twin columns divided by a
|
||||
hairline, each with its own mock to make the vocabulary visible. */
|
||||
.designing-lanes {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 8px;
|
||||
gap: 0;
|
||||
margin-bottom: var(--spacing-lg, 32px);
|
||||
}
|
||||
|
||||
.designing-register-mini {
|
||||
padding: 14px 12px;
|
||||
border-radius: 6px;
|
||||
.designing-lane {
|
||||
padding: 0 clamp(18px, 3vw, 32px);
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
min-height: 88px;
|
||||
justify-content: center;
|
||||
gap: 14px;
|
||||
border-left: 1px solid var(--color-mist);
|
||||
}
|
||||
|
||||
.designing-register-mini--brand {
|
||||
.designing-lane:first-child {
|
||||
padding-left: 0;
|
||||
border-left: 0;
|
||||
}
|
||||
|
||||
.designing-lane-kind {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.6875rem;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.2em;
|
||||
text-transform: uppercase;
|
||||
color: var(--color-accent);
|
||||
}
|
||||
|
||||
.designing-lane-rule {
|
||||
margin: 0;
|
||||
font-family: var(--font-body);
|
||||
font-size: 0.9375rem;
|
||||
line-height: 1.55;
|
||||
color: var(--color-charcoal);
|
||||
max-width: 38ch;
|
||||
}
|
||||
|
||||
.designing-lane-mock {
|
||||
padding: 28px 20px;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
justify-content: center;
|
||||
min-height: 116px;
|
||||
border: 1px solid var(--color-mist);
|
||||
}
|
||||
|
||||
.designing-lane-mock--brand {
|
||||
background: oklch(96% 0.02 30);
|
||||
}
|
||||
|
||||
.designing-register-mini--brand .designing-register-mini-label {
|
||||
.designing-lane-mock--brand .designing-lane-mock-label {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 8px;
|
||||
font-size: 9px;
|
||||
letter-spacing: 0.18em;
|
||||
text-transform: uppercase;
|
||||
color: oklch(40% 0.12 30);
|
||||
}
|
||||
|
||||
.designing-register-mini--brand .designing-register-mini-title {
|
||||
.designing-lane-mock--brand .designing-lane-mock-title {
|
||||
font-family: var(--font-display);
|
||||
font-style: italic;
|
||||
font-size: 14px;
|
||||
font-size: 22px;
|
||||
color: oklch(20% 0.1 30);
|
||||
line-height: 1.1;
|
||||
}
|
||||
|
||||
.designing-register-mini--product {
|
||||
.designing-lane-mock--product {
|
||||
background: var(--color-cream);
|
||||
}
|
||||
|
||||
.designing-register-mini--product .designing-register-mini-label {
|
||||
.designing-lane-mock--product .designing-lane-mock-label {
|
||||
font-family: var(--font-body);
|
||||
font-size: 9px;
|
||||
font-size: 10px;
|
||||
font-weight: 600;
|
||||
color: var(--color-ash);
|
||||
letter-spacing: 0.04em;
|
||||
}
|
||||
|
||||
.designing-register-mini--product .designing-register-mini-title {
|
||||
.designing-lane-mock--product .designing-lane-mock-title {
|
||||
font-family: var(--font-body);
|
||||
font-weight: 600;
|
||||
font-size: 13px;
|
||||
font-size: 15px;
|
||||
color: var(--color-ink);
|
||||
line-height: 1.2;
|
||||
line-height: 1.25;
|
||||
}
|
||||
|
||||
.designing-register-link {
|
||||
.designing-lane-link {
|
||||
font-family: var(--font-body);
|
||||
font-size: 0.875rem;
|
||||
font-weight: 600;
|
||||
@@ -2673,93 +2792,26 @@
|
||||
text-underline-offset: 3px;
|
||||
text-decoration-thickness: 1px;
|
||||
display: inline-block;
|
||||
margin-top: var(--spacing-md, 24px);
|
||||
margin-bottom: var(--spacing-sm, 16px);
|
||||
}
|
||||
|
||||
.designing-register-link:hover {
|
||||
.designing-lane-link:hover {
|
||||
text-decoration-thickness: 2px;
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
APPENDIX: Interop (minimal inline diagram)
|
||||
============================================ */
|
||||
|
||||
.designing-interop {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr auto 1fr;
|
||||
gap: 16px 24px;
|
||||
align-items: center;
|
||||
justify-items: center;
|
||||
font-family: var(--font-body);
|
||||
font-size: 0.9375rem;
|
||||
color: var(--color-ink);
|
||||
padding: 32px 16px;
|
||||
border: 1px solid var(--color-mist);
|
||||
border-radius: 8px;
|
||||
background: var(--color-cream);
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.designing-interop {
|
||||
.designing-lanes {
|
||||
grid-template-columns: 1fr;
|
||||
padding: 24px 16px;
|
||||
gap: var(--spacing-md, 24px);
|
||||
}
|
||||
.designing-lane {
|
||||
padding: var(--spacing-md, 24px) 0 0 0;
|
||||
border-left: 0;
|
||||
border-top: 1px solid var(--color-mist);
|
||||
}
|
||||
.designing-lane:first-child {
|
||||
padding-top: 0;
|
||||
border-top: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.designing-interop-side {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 6px;
|
||||
align-items: center;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.designing-interop-side-label {
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.625rem;
|
||||
letter-spacing: 0.16em;
|
||||
text-transform: uppercase;
|
||||
color: var(--color-ash);
|
||||
}
|
||||
|
||||
.designing-interop-side-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 4px;
|
||||
font-family: var(--font-body);
|
||||
font-size: 0.9375rem;
|
||||
color: var(--color-ink);
|
||||
}
|
||||
|
||||
.designing-interop-node {
|
||||
padding: 8px 16px;
|
||||
background: var(--color-paper);
|
||||
border: 1px solid var(--color-mist);
|
||||
border-radius: 6px;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.designing-interop-node--center {
|
||||
background: var(--color-ink);
|
||||
color: var(--color-paper);
|
||||
border-color: transparent;
|
||||
font-family: var(--font-mono);
|
||||
font-size: 0.875rem;
|
||||
padding: 12px 20px;
|
||||
}
|
||||
|
||||
.designing-interop-arrow {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
color: var(--color-accent);
|
||||
font-size: 18px;
|
||||
line-height: 1;
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.designing-interop-arrow { transform: rotate(90deg); }
|
||||
}
|
||||
|
||||
/* ============================================
|
||||
|
||||
+76
-82
@@ -275,20 +275,28 @@
|
||||
|
||||
<div class="designing-phase-body">
|
||||
<div class="designing-polish">
|
||||
<div class="designing-polish-col">
|
||||
<span class="designing-polish-cmd"><a href="/docs/audit">/impeccable audit</a></span>
|
||||
<h3 class="designing-polish-name">Score it.</h3>
|
||||
<p class="designing-polish-desc">Five dimensions scored 0 to 4: accessibility, performance, theming, responsive, anti-patterns. Findings tagged P0 to P3.</p>
|
||||
<div class="designing-polish-band">
|
||||
<span class="designing-polish-band-label">Pre-ship</span>
|
||||
<div class="designing-polish-band-cmds">
|
||||
<a href="/docs/audit">audit</a>
|
||||
<a href="/docs/clarify">clarify</a>
|
||||
<a href="/docs/harden">harden</a>
|
||||
</div>
|
||||
<span class="designing-polish-band-meta">03 · 04</span>
|
||||
</div>
|
||||
<div class="designing-polish-col">
|
||||
<span class="designing-polish-cmd"><a href="/docs/clarify">/impeccable clarify</a></span>
|
||||
<h3 class="designing-polish-name">Rewrite the copy.</h3>
|
||||
<p class="designing-polish-desc">Labels, error messages, empty-state prose, microcopy. Tuned to the audience from PRODUCT.md.</p>
|
||||
</div>
|
||||
<div class="designing-polish-col">
|
||||
<span class="designing-polish-cmd"><a href="/docs/harden">/impeccable harden</a></span>
|
||||
<h3 class="designing-polish-name">Stress-test reality.</h3>
|
||||
<p class="designing-polish-desc">60-character names, German product titles, prices in the billions, 500s, offline. Production data is messy.</p>
|
||||
<div class="designing-polish-grid">
|
||||
<div class="designing-polish-col">
|
||||
<h3 class="designing-polish-name">Score it.</h3>
|
||||
<p class="designing-polish-desc">Five dimensions scored 0 to 4: accessibility, performance, theming, responsive, anti-patterns. Findings tagged P0 to P3.</p>
|
||||
</div>
|
||||
<div class="designing-polish-col">
|
||||
<h3 class="designing-polish-name">Rewrite the copy.</h3>
|
||||
<p class="designing-polish-desc">Labels, error messages, empty-state prose, microcopy. Tuned to the audience from PRODUCT.md.</p>
|
||||
</div>
|
||||
<div class="designing-polish-col">
|
||||
<h3 class="designing-polish-name">Stress-test reality.</h3>
|
||||
<p class="designing-polish-desc">60-character names, German product titles, prices in the billions, 500s, offline. Production data is messy.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -303,90 +311,76 @@
|
||||
|
||||
<div class="designing-phase-body">
|
||||
<div class="designing-maintain">
|
||||
<div class="designing-maintain-col">
|
||||
<span class="designing-maintain-label"><a href="/docs/extract">/impeccable extract</a></span>
|
||||
<h3 class="designing-maintain-name">Consolidate drift.</h3>
|
||||
<p class="designing-maintain-desc">Find patterns used three or more times with the same intent. Propose tokens and primitives. Migrate call sites in the same pass.</p>
|
||||
<div class="designing-extract-viz" aria-hidden="true">
|
||||
<div class="designing-extract-before">
|
||||
<span class="designing-extract-btn">Subscribe</span>
|
||||
<span class="designing-extract-btn">Submit</span>
|
||||
<span class="designing-extract-btn">Join</span>
|
||||
<span class="designing-extract-btn">Send</span>
|
||||
<span class="designing-extract-btn">Go</span>
|
||||
<span class="designing-extract-btn">OK</span>
|
||||
<figure class="designing-maintain-tile">
|
||||
<div class="designing-maintain-stage">
|
||||
<div class="designing-extract-viz" aria-hidden="true">
|
||||
<div class="designing-extract-before">
|
||||
<span class="designing-extract-btn">Subscribe</span>
|
||||
<span class="designing-extract-btn">Submit</span>
|
||||
<span class="designing-extract-btn">Join</span>
|
||||
<span class="designing-extract-btn">Send</span>
|
||||
<span class="designing-extract-btn">Go</span>
|
||||
<span class="designing-extract-btn">OK</span>
|
||||
</div>
|
||||
<span class="designing-extract-arrow">→</span>
|
||||
<span class="designing-extract-after">Button</span>
|
||||
</div>
|
||||
<span class="designing-extract-arrow">→</span>
|
||||
<span class="designing-extract-after">Button</span>
|
||||
</div>
|
||||
</div>
|
||||
<figcaption class="designing-maintain-caption">
|
||||
<span class="designing-maintain-label"><a href="/docs/extract">/impeccable extract</a></span>
|
||||
<h3 class="designing-maintain-name">Consolidate drift.</h3>
|
||||
<p class="designing-maintain-desc">Find patterns used three or more times with the same intent. Propose tokens and primitives.</p>
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
<div class="designing-maintain-col">
|
||||
<span class="designing-maintain-label"><a href="/docs/document">/impeccable document</a></span>
|
||||
<h3 class="designing-maintain-name">Re-capture the system.</h3>
|
||||
<p class="designing-maintain-desc">Scans tokens, components, and rendered output. Writes a spec-compliant DESIGN.md that every other command reads.</p>
|
||||
<div class="designing-designmd-preview" aria-hidden="true">
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">01</span><span>Overview</span></div>
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">02</span><span>Colors</span></div>
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">03</span><span>Typography</span></div>
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">04</span><span>Elevation</span></div>
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">05</span><span>Components</span></div>
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">06</span><span>Do's and Don'ts</span></div>
|
||||
<figure class="designing-maintain-tile">
|
||||
<div class="designing-maintain-stage">
|
||||
<div class="designing-designmd-preview" aria-hidden="true">
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">01</span><span>Overview</span></div>
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">02</span><span>Colors</span></div>
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">03</span><span>Typography</span></div>
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">04</span><span>Elevation</span></div>
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">05</span><span>Components</span></div>
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">06</span><span>Do's & Don'ts</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<figcaption class="designing-maintain-caption">
|
||||
<span class="designing-maintain-label"><a href="/docs/document">/impeccable document</a></span>
|
||||
<h3 class="designing-maintain-name">Re-capture the system.</h3>
|
||||
<p class="designing-maintain-desc">Scans tokens, components, and rendered output. Writes a spec-compliant DESIGN.md.</p>
|
||||
</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="designing-phase designing-phase--appendix" aria-label="Brand vs product register">
|
||||
<section class="designing-phase designing-phase--appendix" aria-label="Brand or product lane">
|
||||
<header class="designing-phase-head">
|
||||
<span class="designing-phase-num">Before any of this</span>
|
||||
<h2 class="designing-phase-title">Pick a register.</h2>
|
||||
<p class="designing-phase-sub">Brand and product surfaces have different defaults. Impeccable tracks this in <code>PRODUCT.md</code> as a single field, so commands like <code>typeset</code>, <code>animate</code>, and <code>colorize</code> adapt their vocabulary to match.</p>
|
||||
<span class="designing-phase-num">Two lanes</span>
|
||||
<h2 class="designing-phase-title">Brand, or product.</h2>
|
||||
<p class="designing-phase-sub">Two defaults with different vocabularies. Impeccable picks the lane from your task cue and <code>PRODUCT.md</code> before every command, so <code>typeset</code>, <code>animate</code>, <code>colorize</code>, and friends adjust their output to match. You rarely need to set it by hand.</p>
|
||||
</header>
|
||||
|
||||
<div class="designing-phase-body">
|
||||
<div class="designing-register">
|
||||
<div class="designing-register-preview" aria-hidden="true">
|
||||
<div class="designing-register-mini designing-register-mini--brand">
|
||||
<span class="designing-register-mini-label">No. 04 · Dispatch</span>
|
||||
<span class="designing-register-mini-title">Letters, occasionally.</span>
|
||||
<div class="designing-lanes">
|
||||
<section class="designing-lane">
|
||||
<span class="designing-lane-kind">Brand</span>
|
||||
<p class="designing-lane-rule">Design IS the product. Marketing, landing, editorial, long-form, portfolio.</p>
|
||||
<div class="designing-lane-mock designing-lane-mock--brand" aria-hidden="true">
|
||||
<span class="designing-lane-mock-label">No. 04 · Dispatch</span>
|
||||
<span class="designing-lane-mock-title">Letters, occasionally.</span>
|
||||
</div>
|
||||
<div class="designing-register-mini designing-register-mini--product">
|
||||
<span class="designing-register-mini-label">Newsletter</span>
|
||||
<span class="designing-register-mini-title">Subscribe to updates</span>
|
||||
</section>
|
||||
<section class="designing-lane">
|
||||
<span class="designing-lane-kind">Product</span>
|
||||
<p class="designing-lane-rule">Design serves the task. App UI, admin, dashboards, tools.</p>
|
||||
<div class="designing-lane-mock designing-lane-mock--product" aria-hidden="true">
|
||||
<span class="designing-lane-mock-label">Newsletter</span>
|
||||
<span class="designing-lane-mock-title">Subscribe to updates</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p style="font-family:var(--font-body);font-size:0.9375rem;line-height:1.65;color:var(--color-charcoal);margin:0;max-width:52ch">The same element, rendered in brand register (editorial masthead) and product register (utility). Register is answered once during <code>teach</code> and applies to every downstream command.</p>
|
||||
<a class="designing-register-link" href="/tutorials/brand-vs-product">Read the brand-vs-product tutorial →</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="designing-phase designing-phase--appendix" aria-label="DESIGN.md interop">
|
||||
<header class="designing-phase-head">
|
||||
<span class="designing-phase-num">Interop</span>
|
||||
<h2 class="designing-phase-title">Your system travels.</h2>
|
||||
<p class="designing-phase-sub"><code>DESIGN.md</code> follows <a href="https://stitch.withgoogle.com/docs/design-md/format/" target="_blank" rel="noopener">the format Google Stitch publishes</a>. Not a lock-in. When you outgrow Impeccable or want a second opinion from another tool, the file comes with you.</p>
|
||||
</header>
|
||||
|
||||
<div class="designing-phase-body">
|
||||
<div class="designing-interop" aria-hidden="true">
|
||||
<div class="designing-interop-side">
|
||||
<span class="designing-interop-side-label">Writes it</span>
|
||||
<span class="designing-interop-node">Impeccable</span>
|
||||
</div>
|
||||
<div class="designing-interop-node designing-interop-node--center">DESIGN.md</div>
|
||||
<div class="designing-interop-side">
|
||||
<span class="designing-interop-side-label">Reads it</span>
|
||||
<div class="designing-interop-side-list">
|
||||
<span class="designing-interop-node">Google Stitch</span>
|
||||
<span class="designing-interop-node">Other tools</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<a class="designing-lane-link" href="/tutorials/brand-vs-product">Read the brand-vs-product tutorial →</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
+1
-1
@@ -554,7 +554,7 @@
|
||||
<section class="live-section" id="live-mode">
|
||||
<div class="section-header" data-reveal>
|
||||
<span class="section-number">04</span>
|
||||
<h2 class="section-title">Live Mode <span class="beta-badge">BETA</span></h2>
|
||||
<h2 class="section-title">Live Mode <span class="beta-badge">ALPHA</span></h2>
|
||||
</div>
|
||||
<div class="live-content" data-reveal>
|
||||
<p class="section-lead">Pick any element in the browser. Drop a comment or a stroke. Hit Go. Three production-quality variants swap in via your framework's HMR. Accept the one you want and it writes back to source.</p>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
* Hover tooltips show description and relationships inline.
|
||||
*/
|
||||
|
||||
import { commandCategories, commandRelationships, betaCommands } from '../data.js';
|
||||
import { commandCategories, commandRelationships, alphaCommands } from '../data.js';
|
||||
|
||||
const categoryColors = {
|
||||
create: { bg: 'var(--cat-create-bg)', border: 'var(--cat-create-border)', text: 'var(--cat-create-text)' },
|
||||
@@ -298,8 +298,8 @@ export class PeriodicTable {
|
||||
}
|
||||
el.appendChild(name);
|
||||
|
||||
// Beta badge
|
||||
if (betaCommands.includes(cmd)) {
|
||||
// Alpha badge
|
||||
if (alphaCommands.includes(cmd)) {
|
||||
const badge = document.createElement('div');
|
||||
badge.style.cssText = `
|
||||
position: absolute;
|
||||
@@ -312,7 +312,7 @@ export class PeriodicTable {
|
||||
opacity: 0.45;
|
||||
text-transform: uppercase;
|
||||
`;
|
||||
badge.textContent = 'β';
|
||||
badge.textContent = 'α';
|
||||
el.appendChild(badge);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { renderCommandDemo, initCommandDemo } from "../demo-renderer.js";
|
||||
import { initSplitCompare } from "../effects/split-compare.js";
|
||||
import { commandProcessSteps, commandCategories, commandRelationships, betaCommands } from "../data.js";
|
||||
import { commandProcessSteps, commandCategories, commandRelationships, alphaCommands } from "../data.js";
|
||||
|
||||
// Track current split instance and command for cleanup
|
||||
let currentSplitInstance = null;
|
||||
@@ -134,14 +134,14 @@ function renderDesktopLayout(container, commands) {
|
||||
|
||||
const fisheyeHTML = filteredCommands.map((cmd, i) => {
|
||||
const cat = commandCategories[cmd.id] || 'other';
|
||||
const isBeta = betaCommands.includes(cmd.id);
|
||||
const isAlpha = alphaCommands.includes(cmd.id);
|
||||
// The root skill is shown as "/impeccable", everything else is a sub-command
|
||||
// displayed without a slash (invocation is /impeccable <name>)
|
||||
const isRoot = cmd.id === 'impeccable';
|
||||
const label = isRoot
|
||||
? `<span class="fisheye-slash">/</span>impeccable`
|
||||
: cmd.id;
|
||||
return `<button class="fisheye-item${i === startIndex ? ' is-active' : ''}" data-index="${i}" data-id="${cmd.id}" data-cat="${cat}">${label}${isBeta ? '<span class="fisheye-beta">BETA</span>' : ''}</button>`;
|
||||
return `<button class="fisheye-item${i === startIndex ? ' is-active' : ''}" data-index="${i}" data-id="${cmd.id}" data-cat="${cat}">${label}${isAlpha ? '<span class="fisheye-beta">ALPHA</span>' : ''}</button>`;
|
||||
}).join('');
|
||||
|
||||
container.innerHTML = `
|
||||
@@ -166,7 +166,7 @@ function renderDesktopLayout(container, commands) {
|
||||
|
||||
function renderSpread(cmd, index, isActive) {
|
||||
const cat = commandCategories[cmd.id] || 'other';
|
||||
const isBeta = betaCommands.includes(cmd.id);
|
||||
const isAlpha = alphaCommands.includes(cmd.id);
|
||||
const relationship = commandRelationships[cmd.id];
|
||||
// Build relationship flow
|
||||
let flowHTML = '';
|
||||
@@ -213,7 +213,7 @@ function renderSpread(cmd, index, isActive) {
|
||||
<div class="magazine-spread${isActive ? ' active' : ''}" data-index="${index}" data-category="${cat}" data-id="${cmd.id}" id="cmd-${cmd.id}">
|
||||
<div class="spread-identity">
|
||||
<span class="spread-category-label">${categoryLabels[cat] || cat}</span>
|
||||
<h3 class="spread-command-name">${nameHTML}${isBeta ? '<span class="beta-badge">BETA</span>' : ''}</h3>
|
||||
<h3 class="spread-command-name">${nameHTML}${isAlpha ? '<span class="beta-badge">ALPHA</span>' : ''}</h3>
|
||||
<p class="spread-description">${cmd.tagline || cmd.description}</p>
|
||||
${flowHTML}
|
||||
</div>
|
||||
|
||||
+2
-2
@@ -12,8 +12,8 @@ export const readyCommands = [
|
||||
'layout' // First command to be fully completed
|
||||
];
|
||||
|
||||
// Commands marked as beta — shown with a badge in the UI
|
||||
export const betaCommands = [
|
||||
// Commands marked as alpha — shown with a badge in the UI
|
||||
export const alphaCommands = [
|
||||
'live'
|
||||
];
|
||||
|
||||
|
||||
@@ -46,9 +46,10 @@
|
||||
|
||||
<div class="live-mode-page">
|
||||
<header class="live-mode-page-header">
|
||||
<p class="live-mode-page-eyebrow">New in v3.0 <span class="live-mode-page-eyebrow-badge">Beta</span></p>
|
||||
<p class="live-mode-page-eyebrow">New in v3.0 <span class="live-mode-page-eyebrow-badge">Alpha</span></p>
|
||||
<h1 class="live-mode-page-title">Live Mode</h1>
|
||||
<p class="live-mode-page-lede">Pick any element in the browser. Drop a comment or a stroke. Three production-quality variants swap in via your framework's HMR. Accept the one you want and it writes back to source.</p>
|
||||
<p class="live-mode-page-alpha-note"><strong>Why alpha:</strong> Live Mode works end-to-end and is ready to try, but it still needs more testing against real-world repos and framework configs. Expect rough edges on uncommon setups, and please report what breaks.</p>
|
||||
<div class="live-mode-start" aria-label="Start live mode command">
|
||||
<span class="live-mode-start-prompt">$</span>
|
||||
<code class="live-mode-start-cmd">/impeccable live</code>
|
||||
|
||||
+80
-85
@@ -263,7 +263,7 @@ function renderSkillsOverviewMain(skillsByCategory, allSkills) {
|
||||
const tagline = skill.editorial?.frontmatter?.tagline || skill.description;
|
||||
const shortTagline = tagline.length > 140 ? tagline.slice(0, 137) + '...' : tagline;
|
||||
const rel = COMMAND_RELATIONSHIPS[skill.id] || {};
|
||||
const isBeta = skill.id === 'live';
|
||||
const isAlpha = skill.id === 'live';
|
||||
|
||||
let metaHtml = '';
|
||||
if (rel.pairs) {
|
||||
@@ -281,7 +281,7 @@ function renderSkillsOverviewMain(skillsByCategory, allSkills) {
|
||||
return `
|
||||
<div class="command-row">
|
||||
<div class="command-row-name">
|
||||
<a href="/docs/${skill.id}"><span class="command-row-namespace">/impeccable</span> ${escapeHtml(skill.id)}</a>${isBeta ? ' <span class="command-row-beta">BETA</span>' : ''}
|
||||
<a href="/docs/${skill.id}"><span class="command-row-namespace">/impeccable</span> ${escapeHtml(skill.id)}</a>${isAlpha ? ' <span class="command-row-beta">ALPHA</span>' : ''}
|
||||
</div>
|
||||
<div class="command-row-info">
|
||||
<p class="command-row-desc">${escapeHtml(shortTagline)}</p>
|
||||
@@ -805,9 +805,10 @@ function renderLiveModeMain() {
|
||||
return `
|
||||
<div class="live-mode-page">
|
||||
<header class="live-mode-page-header">
|
||||
<p class="live-mode-page-eyebrow">New in v3.0 <span class="live-mode-page-eyebrow-badge">Beta</span></p>
|
||||
<p class="live-mode-page-eyebrow">New in v3.0 <span class="live-mode-page-eyebrow-badge">Alpha</span></p>
|
||||
<h1 class="live-mode-page-title">Live Mode</h1>
|
||||
<p class="live-mode-page-lede">Pick any element in the browser. Drop a comment or a stroke. Three production-quality variants swap in via your framework's HMR. Accept the one you want and it writes back to source.</p>
|
||||
<p class="live-mode-page-alpha-note"><strong>Why alpha:</strong> Live Mode works end-to-end and is ready to try, but it still needs more testing against real-world repos and framework configs. Expect rough edges on uncommon setups, and please report what breaks.</p>
|
||||
<div class="live-mode-start" aria-label="Start live mode command">
|
||||
<span class="live-mode-start-prompt">$</span>
|
||||
<code class="live-mode-start-cmd">/impeccable live</code>
|
||||
@@ -1143,20 +1144,28 @@ function renderDesigningMain() {
|
||||
|
||||
<div class="designing-phase-body">
|
||||
<div class="designing-polish">
|
||||
<div class="designing-polish-col">
|
||||
<span class="designing-polish-cmd"><a href="/docs/audit">/impeccable audit</a></span>
|
||||
<h3 class="designing-polish-name">Score it.</h3>
|
||||
<p class="designing-polish-desc">Five dimensions scored 0 to 4: accessibility, performance, theming, responsive, anti-patterns. Findings tagged P0 to P3.</p>
|
||||
<div class="designing-polish-band">
|
||||
<span class="designing-polish-band-label">Pre-ship</span>
|
||||
<div class="designing-polish-band-cmds">
|
||||
<a href="/docs/audit">audit</a>
|
||||
<a href="/docs/clarify">clarify</a>
|
||||
<a href="/docs/harden">harden</a>
|
||||
</div>
|
||||
<span class="designing-polish-band-meta">03 · 04</span>
|
||||
</div>
|
||||
<div class="designing-polish-col">
|
||||
<span class="designing-polish-cmd"><a href="/docs/clarify">/impeccable clarify</a></span>
|
||||
<h3 class="designing-polish-name">Rewrite the copy.</h3>
|
||||
<p class="designing-polish-desc">Labels, error messages, empty-state prose, microcopy. Tuned to the audience from PRODUCT.md.</p>
|
||||
</div>
|
||||
<div class="designing-polish-col">
|
||||
<span class="designing-polish-cmd"><a href="/docs/harden">/impeccable harden</a></span>
|
||||
<h3 class="designing-polish-name">Stress-test reality.</h3>
|
||||
<p class="designing-polish-desc">60-character names, German product titles, prices in the billions, 500s, offline. Production data is messy.</p>
|
||||
<div class="designing-polish-grid">
|
||||
<div class="designing-polish-col">
|
||||
<h3 class="designing-polish-name">Score it.</h3>
|
||||
<p class="designing-polish-desc">Five dimensions scored 0 to 4: accessibility, performance, theming, responsive, anti-patterns. Findings tagged P0 to P3.</p>
|
||||
</div>
|
||||
<div class="designing-polish-col">
|
||||
<h3 class="designing-polish-name">Rewrite the copy.</h3>
|
||||
<p class="designing-polish-desc">Labels, error messages, empty-state prose, microcopy. Tuned to the audience from PRODUCT.md.</p>
|
||||
</div>
|
||||
<div class="designing-polish-col">
|
||||
<h3 class="designing-polish-name">Stress-test reality.</h3>
|
||||
<p class="designing-polish-desc">60-character names, German product titles, prices in the billions, 500s, offline. Production data is messy.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1171,90 +1180,76 @@ function renderDesigningMain() {
|
||||
|
||||
<div class="designing-phase-body">
|
||||
<div class="designing-maintain">
|
||||
<div class="designing-maintain-col">
|
||||
<span class="designing-maintain-label"><a href="/docs/extract">/impeccable extract</a></span>
|
||||
<h3 class="designing-maintain-name">Consolidate drift.</h3>
|
||||
<p class="designing-maintain-desc">Find patterns used three or more times with the same intent. Propose tokens and primitives. Migrate call sites in the same pass.</p>
|
||||
<div class="designing-extract-viz" aria-hidden="true">
|
||||
<div class="designing-extract-before">
|
||||
<span class="designing-extract-btn">Subscribe</span>
|
||||
<span class="designing-extract-btn">Submit</span>
|
||||
<span class="designing-extract-btn">Join</span>
|
||||
<span class="designing-extract-btn">Send</span>
|
||||
<span class="designing-extract-btn">Go</span>
|
||||
<span class="designing-extract-btn">OK</span>
|
||||
<figure class="designing-maintain-tile">
|
||||
<div class="designing-maintain-stage">
|
||||
<div class="designing-extract-viz" aria-hidden="true">
|
||||
<div class="designing-extract-before">
|
||||
<span class="designing-extract-btn">Subscribe</span>
|
||||
<span class="designing-extract-btn">Submit</span>
|
||||
<span class="designing-extract-btn">Join</span>
|
||||
<span class="designing-extract-btn">Send</span>
|
||||
<span class="designing-extract-btn">Go</span>
|
||||
<span class="designing-extract-btn">OK</span>
|
||||
</div>
|
||||
<span class="designing-extract-arrow">→</span>
|
||||
<span class="designing-extract-after">Button</span>
|
||||
</div>
|
||||
<span class="designing-extract-arrow">→</span>
|
||||
<span class="designing-extract-after">Button</span>
|
||||
</div>
|
||||
</div>
|
||||
<figcaption class="designing-maintain-caption">
|
||||
<span class="designing-maintain-label"><a href="/docs/extract">/impeccable extract</a></span>
|
||||
<h3 class="designing-maintain-name">Consolidate drift.</h3>
|
||||
<p class="designing-maintain-desc">Find patterns used three or more times with the same intent. Propose tokens and primitives.</p>
|
||||
</figcaption>
|
||||
</figure>
|
||||
|
||||
<div class="designing-maintain-col">
|
||||
<span class="designing-maintain-label"><a href="/docs/document">/impeccable document</a></span>
|
||||
<h3 class="designing-maintain-name">Re-capture the system.</h3>
|
||||
<p class="designing-maintain-desc">Scans tokens, components, and rendered output. Writes a spec-compliant DESIGN.md that every other command reads.</p>
|
||||
<div class="designing-designmd-preview" aria-hidden="true">
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">01</span><span>Overview</span></div>
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">02</span><span>Colors</span></div>
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">03</span><span>Typography</span></div>
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">04</span><span>Elevation</span></div>
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">05</span><span>Components</span></div>
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">06</span><span>Do's and Don'ts</span></div>
|
||||
<figure class="designing-maintain-tile">
|
||||
<div class="designing-maintain-stage">
|
||||
<div class="designing-designmd-preview" aria-hidden="true">
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">01</span><span>Overview</span></div>
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">02</span><span>Colors</span></div>
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">03</span><span>Typography</span></div>
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">04</span><span>Elevation</span></div>
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">05</span><span>Components</span></div>
|
||||
<div class="designing-designmd-preview-line"><span class="designing-designmd-preview-num">06</span><span>Do's & Don'ts</span></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<figcaption class="designing-maintain-caption">
|
||||
<span class="designing-maintain-label"><a href="/docs/document">/impeccable document</a></span>
|
||||
<h3 class="designing-maintain-name">Re-capture the system.</h3>
|
||||
<p class="designing-maintain-desc">Scans tokens, components, and rendered output. Writes a spec-compliant DESIGN.md.</p>
|
||||
</figcaption>
|
||||
</figure>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="designing-phase designing-phase--appendix" aria-label="Brand vs product register">
|
||||
<section class="designing-phase designing-phase--appendix" aria-label="Brand or product lane">
|
||||
<header class="designing-phase-head">
|
||||
<span class="designing-phase-num">Before any of this</span>
|
||||
<h2 class="designing-phase-title">Pick a register.</h2>
|
||||
<p class="designing-phase-sub">Brand and product surfaces have different defaults. Impeccable tracks this in <code>PRODUCT.md</code> as a single field, so commands like <code>typeset</code>, <code>animate</code>, and <code>colorize</code> adapt their vocabulary to match.</p>
|
||||
<span class="designing-phase-num">Two lanes</span>
|
||||
<h2 class="designing-phase-title">Brand, or product.</h2>
|
||||
<p class="designing-phase-sub">Two defaults with different vocabularies. Impeccable picks the lane from your task cue and <code>PRODUCT.md</code> before every command, so <code>typeset</code>, <code>animate</code>, <code>colorize</code>, and friends adjust their output to match. You rarely need to set it by hand.</p>
|
||||
</header>
|
||||
|
||||
<div class="designing-phase-body">
|
||||
<div class="designing-register">
|
||||
<div class="designing-register-preview" aria-hidden="true">
|
||||
<div class="designing-register-mini designing-register-mini--brand">
|
||||
<span class="designing-register-mini-label">No. 04 · Dispatch</span>
|
||||
<span class="designing-register-mini-title">Letters, occasionally.</span>
|
||||
<div class="designing-lanes">
|
||||
<section class="designing-lane">
|
||||
<span class="designing-lane-kind">Brand</span>
|
||||
<p class="designing-lane-rule">Design IS the product. Marketing, landing, editorial, long-form, portfolio.</p>
|
||||
<div class="designing-lane-mock designing-lane-mock--brand" aria-hidden="true">
|
||||
<span class="designing-lane-mock-label">No. 04 · Dispatch</span>
|
||||
<span class="designing-lane-mock-title">Letters, occasionally.</span>
|
||||
</div>
|
||||
<div class="designing-register-mini designing-register-mini--product">
|
||||
<span class="designing-register-mini-label">Newsletter</span>
|
||||
<span class="designing-register-mini-title">Subscribe to updates</span>
|
||||
</section>
|
||||
<section class="designing-lane">
|
||||
<span class="designing-lane-kind">Product</span>
|
||||
<p class="designing-lane-rule">Design serves the task. App UI, admin, dashboards, tools.</p>
|
||||
<div class="designing-lane-mock designing-lane-mock--product" aria-hidden="true">
|
||||
<span class="designing-lane-mock-label">Newsletter</span>
|
||||
<span class="designing-lane-mock-title">Subscribe to updates</span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<p style="font-family:var(--font-body);font-size:0.9375rem;line-height:1.65;color:var(--color-charcoal);margin:0;max-width:52ch">The same element, rendered in brand register (editorial masthead) and product register (utility). Register is answered once during <code>teach</code> and applies to every downstream command.</p>
|
||||
<a class="designing-register-link" href="/tutorials/brand-vs-product">Read the brand-vs-product tutorial →</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="designing-phase designing-phase--appendix" aria-label="DESIGN.md interop">
|
||||
<header class="designing-phase-head">
|
||||
<span class="designing-phase-num">Interop</span>
|
||||
<h2 class="designing-phase-title">Your system travels.</h2>
|
||||
<p class="designing-phase-sub"><code>DESIGN.md</code> follows <a href="https://stitch.withgoogle.com/docs/design-md/format/" target="_blank" rel="noopener">the format Google Stitch publishes</a>. Not a lock-in. When you outgrow Impeccable or want a second opinion from another tool, the file comes with you.</p>
|
||||
</header>
|
||||
|
||||
<div class="designing-phase-body">
|
||||
<div class="designing-interop" aria-hidden="true">
|
||||
<div class="designing-interop-side">
|
||||
<span class="designing-interop-side-label">Writes it</span>
|
||||
<span class="designing-interop-node">Impeccable</span>
|
||||
</div>
|
||||
<div class="designing-interop-node designing-interop-node--center">DESIGN.md</div>
|
||||
<div class="designing-interop-side">
|
||||
<span class="designing-interop-side-label">Reads it</span>
|
||||
<div class="designing-interop-side-list">
|
||||
<span class="designing-interop-node">Google Stitch</span>
|
||||
<span class="designing-interop-node">Other tools</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<a class="designing-lane-link" href="/tutorials/brand-vs-product">Read the brand-vs-product tutorial →</a>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
|
||||
@@ -10,22 +10,6 @@ license: Apache 2.0. Based on Anthropic's frontend-design skill. See NOTICE.md f
|
||||
|
||||
Designs and iterates production-grade frontend interfaces. Real working code, committed design choices, exceptional craft.
|
||||
|
||||
<post-update-cleanup>
|
||||
BEFORE doing any design work, run this one-time maintenance step. Tell the user:
|
||||
|
||||
> **Impeccable 3.0 consolidation.** All standalone commands ({{command_prefix}}audit, {{command_prefix}}polish, {{command_prefix}}critique, etc.) are now accessed through {{command_prefix}}impeccable (e.g., `{{command_prefix}}impeccable audit`). I'll clean up the old standalone skill files. Use `{{command_prefix}}impeccable pin <command>` to restore shortcuts for commands you use often.
|
||||
|
||||
Then run:
|
||||
|
||||
```bash
|
||||
node {{scripts_path}}/cleanup-deprecated.mjs
|
||||
```
|
||||
|
||||
If the script removed files, briefly confirm what was cleaned up. If it found nothing, skip any output and move on.
|
||||
|
||||
After running the script, delete this entire section (from `<post-update-cleanup>` through `</post-update-cleanup>` inclusive) from THIS file so it does not run again until the next update. Save the file.
|
||||
</post-update-cleanup>
|
||||
|
||||
## Setup (non-optional)
|
||||
|
||||
Two steps before any design work. Both are required. Skipping either produces generic output that ignores the project.
|
||||
|
||||
@@ -2818,14 +2818,18 @@ void main() {
|
||||
|
||||
// Static-server / no-HMR fallback: if the wrapper is still around 2s after
|
||||
// the cleanup above, swap it out manually. By now React has either moved
|
||||
// on or the app isn't React at all.
|
||||
// on or the app isn't React at all. Preserve the `data-impeccable-variant="N"`
|
||||
// div (with display:contents) so @scope rules anchored to the variant
|
||||
// attribute keep matching until reload replaces it with the carbonize block.
|
||||
setTimeout(function() {
|
||||
const wrapper = document.querySelector('[data-impeccable-variants="' + acceptedSessionId + '"]');
|
||||
if (!wrapper) return;
|
||||
const accepted = wrapper.querySelector('[data-impeccable-variant="' + acceptedVariant + '"]');
|
||||
if (accepted && accepted.firstElementChild) {
|
||||
const parent = wrapper.parentElement;
|
||||
if (parent) parent.replaceChild(accepted.firstElementChild.cloneNode(true), wrapper);
|
||||
if (!parent) return;
|
||||
accepted.style.display = 'contents';
|
||||
parent.replaceChild(accepted, wrapper);
|
||||
}
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user