How Hover States Are Captured Including Transition Values in the AI Website Cloner Template
The AI Website Cloner Template captures hover states by combining Tailwind CSS utility classes for static definitions with runtime extraction via window.getComputedStyle() to record exact transition durations, easing functions, and property changes.
The AI Website Cloner Template provides a systematic approach to how hover states are captured including transition values from existing websites. This open-source repository employs a dual-layer strategy that merges static Tailwind configurations with dynamic browser introspection to preserve interactive animations in cloned components.
Static CSS Definitions with Tailwind and CVA
The template uses class-variance-authority (cva) to generate variant-specific class strings that encode hover behavior directly in the component source. This approach establishes the foundational styling that determines which properties change during hover interactions.
Implementing Hover Variants in Button Components
In src/components/ui/button.tsx, the buttonVariants function defines multiple interaction states using Tailwind's hover: prefix combined with the transition-all utility:
const buttonVariants = cva(
"group/button inline-flex shrink-0 items-center justify-center rounded-lg border border-transparent bg-clip-padding text-sm font-medium whitespace-nowrap transition-all …",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground [a]:hover:bg-primary/80",
outline:
"border-border bg-background hover:bg-muted hover:text-foreground …",
secondary:
"bg-secondary text-secondary-foreground hover:bg-secondary/80 …",
ghost:
"hover:bg-muted hover:text-foreground …",
destructive:
"bg-destructive/10 text-destructive hover:bg-destructive/20 …",
link: "text-primary underline-offset-4 hover:underline",
},
},
}
);
The transition-all class ensures that any property change defined in the hover: utilities animates according to the default duration and easing configured in Tailwind. Each variant leverages different hover utilities—such as hover:bg-muted or hover:underline—to specify the specific visual feedback for that interaction state.
Runtime Extraction of Hover Styles
While static classes provide the foundation, the cloning process requires precise capture of computed values to replicate the original website's exact timing and easing curves. According to .windsurf/workflows/clone-website.md, the workflow explicitly requires capturing "hover states that animate (not just change — the transition duration and easing matter)."
Forcing Hover States in the Browser
The extraction script temporarily triggers hover states by dispatching mouse events before reading computed styles. The implementation forces elements into their hover state using dispatchEvent:
// Force hover state
el.dispatchEvent(new MouseEvent("mouseover"));
const hover = getComputedStyle(el);
// Revert hover state
el.dispatchEvent(new MouseEvent("mouseout"));
This technique allows the script to access the computed styles that only apply when the :hover pseudo-class is active, without requiring actual user interaction.
Recording Transition Properties
After establishing the hover state, the script calls window.getComputedStyle() to extract the exact values. The implementation compares normal and hover states to identify changed properties and captures the raw transition property:
function captureHoverStyles(el) {
const normal = getComputedStyle(el);
el.dispatchEvent(new MouseEvent("mouseover"));
const hover = getComputedStyle(el);
el.dispatchEvent(new MouseEvent("mouseout"));
const changed = {};
for (const prop of hover) {
if (normal.getPropertyValue(prop) !== hover.getPropertyValue(prop)) {
changed[prop] = hover.getPropertyValue(prop);
}
}
return {
hoverStyles: changed,
transition: hover.transition, // e.g., "all .2s ease-out"
};
}
This approach records not only which CSS properties change during hover—such as background-color, color, or opacity—but also the specific transition timing functions and durations required to reproduce the animation faithfully.
Key Implementation Files
Several files work together to implement this dual capture strategy:
src/components/ui/button.tsx– Demonstrates howcvaencodes hover states andtransition-allutilities for static variant definitions..windsurf/workflows/clone-website.md– Documents the runtime extraction process, emphasizing that transition duration and easing must be captured via computed styles.docs/research/INSPECTION_GUIDE.md– Lists "Animations" and "Hover states" as explicit research items requiring inspection during the cloning pipeline.src/lib/utils.ts– Provides thecnutility function used to merge Tailwind class strings, ensuring hover and transition classes combine correctly without conflicts.
Summary
- Static capture uses Tailwind's
hover:prefixes andtransition-allclasses defined incvavariants within component files likesrc/components/ui/button.tsx. - Dynamic extraction employs
window.getComputedStyle()after dispatchingMouseEventhover states to capture exact transition values including duration and easing functions. - Workflow documentation in
.windsurf/workflows/clone-website.mdspecifies that transition timing and easing are critical values that must be preserved, not just final visual states. - The
captureHoverStylesfunction compares normal and computed hover states to identify which properties change and records the completetransitionproperty string.
Frequently Asked Questions
How does the template capture transition timing values?
The template captures transition timing by reading the transition property from getComputedStyle() after forcing elements into hover states via dispatchEvent(new MouseEvent('mouseover')). This extracts the exact duration, timing function, and property list as defined in the source website's CSS, ensuring the cloned component reproduces identical animation characteristics.
What is the role of class-variance-authority in hover states?
Class-variance-authority (cva) generates conditional class strings that combine Tailwind's hover: utilities with transition-all in src/components/ui/button.tsx. This creates type-safe variant definitions where each button style includes its specific hover background, text color, and opacity changes alongside the global transition configuration.
Why does the cloning agent use both static and dynamic capture methods?
Static Tailwind classes provide maintainable, readable component code, while dynamic extraction ensures pixel-perfect replication of the original website's specific timing values. The static definitions serve as the implementation target, while the runtime computed values from window.getComputedStyle() provide the precise specifications needed to match the original interaction design.
Where is the hover extraction logic documented?
The hover extraction requirements are documented in .windsurf/workflows/clone-website.md, which explicitly states that hover states must capture animation details including transition duration and easing. Additionally, docs/research/INSPECTION_GUIDE.md identifies hover states and animations as mandatory research items for the cloning pipeline.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →