How to Capture All Component States (Hover, Active, Scroll-Dependent) During Extraction

To capture all component states during extraction, systematically trigger hover, click, and scroll interactions while recording computed styles before and after each state change, then document these findings in the repository's Markdown specification files.

The JCodesMore/ai-website-cloner-template repository provides a structured inspection workflow designed to clone websites with pixel-perfect accuracy. Capturing every visual state—including default, hover, active, focus, disabled, loading, error, empty, and scroll-driven styles—is essential for generating components that faithfully reproduce the original site's interactive behavior.

Set Up the Inspection Environment

Begin by opening the target page in Chrome or any Chromium-based browser. Install and enable the Chrome MCP (Multi-Component Profiler) extension included with the repository, which allows you to query computed styles and trigger interaction states programmatically.

Perform a Systematic Hover-Sweep

Iterate over every DOM node that could have a hover state, including buttons, cards, links, and menus. For each element, record the default computed styles, trigger the hover state via MCP, then capture the modified styles.

// Helper functions like this leverage the `cn` utility (see src/lib/utils.ts)
async function captureHoverState(el: Element) {
  // Record default values
  const before = getComputedStyle(el);
  // Trigger hover via MCP
  await triggerHover(el);               // ← defined in the MCP docs
  const after = getComputedStyle(el);
  return { selector: el.tagName, before, after };
}

Save the before/after values together with the exact trigger description, such as "hover on .card-cta", to ensure precise reconstruction later.

Capture Active and Click-Driven States

Use the same MCP script to click elements and read the resulting computed styles. Pay special attention to transition timing properties like transition-duration and transition-delay, as these define how the component animates between states.

Record Scroll-Dependent Styles

Identify elements whose appearance changes based on scroll position, such as sticky headers or reveal-on-scroll cards. For each relevant scroll offset, execute:

await window.scrollTo(0, scrollY);
await waitForIdle();                  // ensure Layout/PAINT are done
const styles = getComputedStyle(targetEl);

Document the scroll offset and any IntersectionObserver thresholds used, such as rootMargin "-30% 0px", to replicate scroll-driven animations accurately.

Export the Component Specification

Assemble all captured data into Markdown spec files within docs/research/. The repository expects structured documentation in files like COMPONENT_INVENTORY.md and INTERACTION_PATTERNS.md, as outlined in the Inspection Guide.

Each component entry must specify:

  • Name – a sensible React component name
  • Structure – HTML hierarchy
  • Variants – size and color differences
  • States – default, hover, active, disabled, loading, error, empty
  • Responsive breakpoints – adaptation behavior
  • Triggers – exact mechanisms (click, hover, scroll offset, time)

Validate Captured States

Run the visual diff step in the /clone-website pipeline to compare the generated UI against original screenshots. If any state is missing, repeat the sweep for that specific element until the visual output matches the source.

Automate State Capture for Large Sites

The repository provides a ready-to-run Hover sweep script defined in .windsurf/workflows/clone-website.md and .github/skills/clone-website/SKILL.md. Hook this automation into scripts/sync-skills.mjs to generate per-section builder agents that each receive the full multi-state specification.

Reusable State Capture Implementation

For programmatic extraction, implement a helper like this in src/lib/stateCapture.ts:

// src/lib/stateCapture.ts – minimal helper used by the MCP scripts
export async function captureMultiState(
  el: Element,
  triggers: { type: 'hover' | 'click' | 'scroll'; value?: number }[]
) {
  const result: Record<string, CSSStyleDeclaration> = {};

  // default
  result['default'] = getComputedStyle(el);

  for (const t of triggers) {
    switch (t.type) {
      case 'hover':
        await triggerHover(el);
        result['hover'] = getComputedStyle(el);
        break;
      case 'click':
        await triggerClick(el);
        result['active'] = getComputedStyle(el);
        break;
      case 'scroll':
        await window.scrollTo(0, t.value ?? 0);
        await waitForIdle();
        result[`scroll_${t.value}`] = getComputedStyle(el);
        break;
    }
  }
  return result;
}

Usage within a builder agent (as documented in docs/research/INTERACTION_PATTERNS.md):

import { captureMultiState } from '@/lib/stateCapture';

const btn = document.querySelector('.primary-button')!;
const styles = await captureMultiState(btn, [
  { type: 'hover' },
  { type: 'click' },
  { type: 'scroll', value: 100 },
]);

// Export to Markdown
await writeFile(
  'docs/research/COMPONENT_INVENTORY.md',
  `### Button – Primary\n\`\`\`json\n${JSON.stringify(styles, null, 2)}\n\`\`\``

);

Essential Files for State Extraction

Reference these key files when implementing your capture workflow:

Summary

  • Capture nine distinct states for each component: default, hover, active, focus, disabled, loading, error, empty, and scroll-driven
  • Use the Chrome MCP extension to programmatically trigger hover and click states while recording computed styles
  • Document scroll positions and IntersectionObserver thresholds for elements with scroll-dependent appearance
  • Store specifications in docs/research/COMPONENT_INVENTORY.md and INTERACTION_PATTERNS.md using the prescribed Markdown format
  • Validate extraction by running the /clone-website visual diff pipeline against original screenshots
  • Automate large sites using the Hover sweep script integrated with scripts/sync-skills.mjs

Frequently Asked Questions

What specific component states must I capture during extraction?

You must record default, hover, active, focus, disabled, loading, error, empty, and scroll-dependent styles for each element. According to the repository's docs/research/INSPECTION_GUIDE.md, capturing this complete set ensures the cloned components behave identically to the original across all user interactions.

How do I programmatically trigger hover states when the MCP extension isn't available?

While the repository recommends the Chrome MCP extension for triggerHover() functionality, you can simulate hover states by dispatching native JavaScript events or using browser DevTools Protocol (CDP) commands. The captureHoverState helper in your extraction scripts should compare getComputedStyle() results before and after triggering these events to capture the computed CSS differences.

Where should I store the captured state data?

Export all captured state data to Markdown files under docs/research/, specifically COMPONENT_INVENTORY.md for structural hierarchies and INTERACTION_PATTERNS.md for behavioral specifications. Each entry must include the component name, variants, all nine possible states, responsive breakpoints, and precise trigger mechanisms.

How do I handle scroll-dependent states that use Intersection Observer?

For scroll-dependent elements, record the exact scroll offsets where visual changes occur using window.scrollTo() followed by waitForIdle() to ensure layout completion. Document any IntersectionObserver configurations, such as rootMargin values like "-30% 0px", alongside the computed styles at each threshold so builder agents can replicate the scroll-triggered animations accurately.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →