Single-commit clean baseline after security scrub of niche-tells, project codenames, internal jargon, and contributor-email leaks. Contents: - 100 Rust crates (_primitives/_rust/) - 37 agent manifests (_manifests/) + generated specs (_generated/) - 67 user-invocable skills (skills/) - 33 hooks (hooks/) - Composition blocks (_blocks/) - Documentation (docs/, README.md) - TS adapter packages (_ts_packages/) - Assembler (_assembler/) - Roles (_roles/) - Templates (_templates/) - Forgejo CI (.forgejo/) Author: Denis Parfionovich <info@greendragon.info> License: see LICENSE.
230 lines
8 KiB
Markdown
230 lines
8 KiB
Markdown
---
|
|
name: site-teardown
|
|
description: "Deconstruct any live website into reusable recipe — extract HTML, CSS, JS, design tokens, animations. Use when user says: teardown, deconstruct, clone site, reverse engineer, how is this site built."
|
|
arguments:
|
|
- name: url
|
|
description: URL of the website to deconstruct
|
|
required: true
|
|
- name: depth
|
|
description: "quick = tokens + screenshots only, full = complete teardown (default: full)"
|
|
required: false
|
|
---
|
|
|
|
# Site Teardown — Deconstruct Any Website into a Reusable Recipe
|
|
|
|
Extracts design tokens, layout structure, animation techniques, and library stack from a live website.
|
|
Output: structured recipe that can be fed into `/frontend-design`, `/landing-page`, `/design-system`.
|
|
|
|
## Phase 1 — Navigate & Screenshot
|
|
|
|
```
|
|
1. browser_navigate → {url}
|
|
2. browser_resize → width: 1280, height: 900
|
|
3. browser_take_screenshot → fullPage: true, filename: "teardown-desktop.png"
|
|
4. browser_resize → width: 375, height: 812
|
|
5. browser_take_screenshot → fullPage: true, filename: "teardown-mobile.png"
|
|
6. browser_resize → width: 1280, height: 900 (restore)
|
|
```
|
|
|
|
Save screenshots to `teardown/{domain}/` in the project directory (relative to `$PWD`).
|
|
|
|
## Phase 2 — Extract HTML Structure
|
|
|
|
Run `browser_evaluate` with:
|
|
|
|
```javascript
|
|
() => {
|
|
const sections = Array.from(document.querySelectorAll('section, [class*="section"], main > div'));
|
|
const nav = document.querySelector('nav, header');
|
|
const footer = document.querySelector('footer');
|
|
const headings = Array.from(document.querySelectorAll('h1, h2, h3')).map(h => ({
|
|
tag: h.tagName, text: h.textContent.trim().slice(0, 80)
|
|
}));
|
|
return {
|
|
title: document.title,
|
|
sectionCount: sections.length,
|
|
hasNav: !!nav,
|
|
navType: nav?.classList?.toString() || 'unknown',
|
|
hasFooter: !!footer,
|
|
headings,
|
|
bodyClasses: document.body.classList.toString(),
|
|
htmlLang: document.documentElement.lang
|
|
};
|
|
}
|
|
```
|
|
|
|
Also extract full HTML for deep analysis:
|
|
```javascript
|
|
() => document.documentElement.outerHTML
|
|
```
|
|
Save to `teardown/{domain}/index.html`.
|
|
|
|
## Phase 3 — Extract Design Tokens
|
|
|
|
Run `browser_evaluate` to extract computed styles from key elements:
|
|
|
|
```javascript
|
|
() => {
|
|
const get = (sel) => {
|
|
const el = document.querySelector(sel);
|
|
return el ? getComputedStyle(el) : null;
|
|
};
|
|
const body = get('body');
|
|
const h1 = get('h1');
|
|
const btn = get('a[class*="btn"], button[class*="btn"], .cta, a[class*="cta"]');
|
|
const card = get('[class*="card"], [class*="Card"]');
|
|
const props = {};
|
|
const root = getComputedStyle(document.documentElement);
|
|
for (const name of ['--primary', '--secondary', '--accent', '--background', '--foreground',
|
|
'--radius', '--font-sans', '--font-mono', '--brand']) {
|
|
const val = root.getPropertyValue(name).trim();
|
|
if (val) props[name] = val;
|
|
}
|
|
return {
|
|
colors: {
|
|
background: body?.backgroundColor,
|
|
text: body?.color,
|
|
heading: h1?.color,
|
|
button: btn ? { bg: btn.backgroundColor, text: btn.color, radius: btn.borderRadius } : null,
|
|
card: card ? { bg: card.backgroundColor, border: card.borderColor, radius: card.borderRadius, shadow: card.boxShadow } : null
|
|
},
|
|
typography: {
|
|
bodyFont: body?.fontFamily,
|
|
bodySize: body?.fontSize,
|
|
h1Font: h1?.fontFamily,
|
|
h1Size: h1?.fontSize,
|
|
h1Weight: h1?.fontWeight,
|
|
lineHeight: body?.lineHeight
|
|
},
|
|
spacing: {
|
|
bodyPadding: body?.padding,
|
|
sectionPadding: get('section')?.padding
|
|
},
|
|
customProperties: props
|
|
};
|
|
}
|
|
```
|
|
|
|
**Output:** Save as `teardown/{domain}/tokens.json`.
|
|
|
|
## Phase 4 — Fetch CSS & JS Sources
|
|
|
|
### 4a. Collect resource URLs
|
|
|
|
```javascript
|
|
() => {
|
|
const css = Array.from(document.querySelectorAll('link[rel="stylesheet"]')).map(l => l.href);
|
|
const js = Array.from(document.querySelectorAll('script[src]')).map(s => s.src);
|
|
const inlineStyles = document.querySelectorAll('style').length;
|
|
return { css, js, inlineStyleBlocks: inlineStyles };
|
|
}
|
|
```
|
|
|
|
### 4b. Fetch each CSS file via WebFetch
|
|
|
|
For each CSS URL: `WebFetch` with prompt:
|
|
> "Extract ALL design-relevant CSS from this stylesheet: custom properties (--vars), @keyframes, @font-face, color values, gradient definitions, backdrop-filter, box-shadow patterns, border-radius values, transition/animation properties. Return as structured list."
|
|
|
|
### 4c. Detect JS libraries
|
|
|
|
```javascript
|
|
() => ({
|
|
gsap: typeof gsap !== 'undefined',
|
|
ScrollTrigger: typeof ScrollTrigger !== 'undefined',
|
|
lenis: !!document.querySelector('[data-lenis-prevent]') || typeof Lenis !== 'undefined',
|
|
framerMotion: !!document.querySelector('[data-framer-component-type]'),
|
|
three: typeof THREE !== 'undefined',
|
|
curtains: typeof Curtains !== 'undefined',
|
|
particles: typeof tsParticles !== 'undefined',
|
|
aos: typeof AOS !== 'undefined',
|
|
locomotive: !!document.querySelector('[data-scroll-container]'),
|
|
swiper: typeof Swiper !== 'undefined',
|
|
tailwind: !!document.querySelector('[class*="bg-"], [class*="text-"], [class*="flex"]'),
|
|
react: typeof __NEXT_DATA__ !== 'undefined' || !!document.getElementById('__next'),
|
|
astro: !!document.querySelector('[data-astro-source-file]'),
|
|
vue: !!document.getElementById('__nuxt') || !!document.querySelector('[data-v-]')
|
|
})
|
|
```
|
|
|
|
### 4d. Network analysis (supplementary)
|
|
|
|
`browser_network_requests` with `filter: "\\.css$|\\.js$"`, `static: false` — cross-reference with DOM-extracted URLs.
|
|
|
|
## Phase 5 — Animation Catalog
|
|
|
|
```javascript
|
|
() => {
|
|
const anims = [];
|
|
const allEls = document.querySelectorAll('*');
|
|
const seen = new Set();
|
|
allEls.forEach(el => {
|
|
const s = getComputedStyle(el);
|
|
if (s.animationName && s.animationName !== 'none' && !seen.has(s.animationName)) {
|
|
seen.add(s.animationName);
|
|
anims.push({ type: 'css-animation', name: s.animationName, duration: s.animationDuration });
|
|
}
|
|
if (s.transition && s.transition !== 'all 0s ease 0s' && s.transition !== 'none') {
|
|
const key = s.transition.slice(0, 60);
|
|
if (!seen.has(key)) { seen.add(key); anims.push({ type: 'transition', value: s.transition.slice(0, 120) }); }
|
|
}
|
|
});
|
|
const canvases = document.querySelectorAll('canvas').length;
|
|
const videos = document.querySelectorAll('video').length;
|
|
const svgAnims = document.querySelectorAll('animate, animateTransform').length;
|
|
return { animations: anims, canvasCount: canvases, videoCount: videos, svgAnimations: svgAnims };
|
|
}
|
|
```
|
|
|
|
**Output:** Save analysis as `teardown/{domain}/animations.md`.
|
|
|
|
If `depth=quick` → STOP here with tokens + screenshots only.
|
|
|
|
## Phase 6 — Compile Recipe
|
|
|
|
Assemble `teardown/{domain}/recipe.md`:
|
|
|
|
```markdown
|
|
# Site Teardown: {domain}
|
|
Date: {date}
|
|
|
|
## Layout Structure
|
|
{section map from Phase 2}
|
|
|
|
## Design Tokens
|
|
{from Phase 3 — colors, typography, spacing}
|
|
|
|
## Tech Stack
|
|
- Framework: {React/Next/Astro/Vue from Phase 4c}
|
|
- CSS: {Tailwind/custom/styled-components}
|
|
- Animation: {GSAP/Framer Motion/CSS/AOS from Phase 4c}
|
|
- Scroll: {Lenis/Locomotive/native from Phase 4c}
|
|
- 3D/WebGL: {Three.js/curtains.js/none from Phase 4c}
|
|
|
|
## Animation Techniques
|
|
{catalog from Phase 5}
|
|
|
|
## Reproduction Steps
|
|
1. Set up {framework} project with {css approach}
|
|
2. Apply design tokens: {token summary}
|
|
3. Implement layout: {section sequence}
|
|
4. Add animations: {technique list with skill references}
|
|
5. Optimize: /web-assets → /a11y-audit → /perf-audit
|
|
|
|
## Recommended Skills
|
|
- /frontend-design archetype={suggested}
|
|
- /scroll-animation technique={if GSAP detected}
|
|
- /web-effects effect={if WebGL detected}
|
|
- /motion-design {if Framer Motion detected}
|
|
```
|
|
|
|
## Chaining
|
|
|
|
| Direction | Skill | How |
|
|
|-----------|-------|-----|
|
|
| FROM | `/design-inspiration` | User picks best reference → teardown |
|
|
| FROM | `/competitor-analysis` | Deep-dive competitor's site |
|
|
| TO | `/frontend-design` | Feed tokens → suggest archetype |
|
|
| TO | `/landing-page` | Use recipe as template |
|
|
| TO | `/design-system` | Generate token system from extracted tokens |
|
|
| TO | `/scroll-animation` | Reproduce detected scroll effects |
|
|
| TO | `/web-effects` | Reproduce detected WebGL/particle effects |
|