# How to Detect and Extract Layered Image Compositions in ai-website-cloner-template

> Learn to detect and extract layered image compositions in ai-website-cloner-template. Discover techniques to capture parent context, sibling count, and CSS positioning for advanced image analysis.

- Repository: [JCodesMore/ai-website-cloner-template](https://github.com/JCodesMore/ai-website-cloner-template)
- Tags: how-to-guide
- Published: 2026-06-24

---

**Run the browser-side discovery script from [`.windsurf/workflows/clone-website.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/.windsurf/workflows/clone-website.md) to capture every `<img>` element's parent context, sibling count, and CSS positioning data, then flag containers with `siblingCount > 1` or background-image declarations as layered compositions requiring multi-asset extraction.**

The ai-website-cloner-template treats layered images as first-class extraction targets to ensure cloned websites remain pixel-perfect. Unlike single raster files, these compositions consist of multiple stacked assets—background gradients, foreground illustrations, and overlay icons—that must be detected and reconstructed individually. This guide walks through the repository's built-in detection logic and provides the exact JavaScript implementation used to identify these complex visual stacks.

## What Are Layered Image Compositions?

Layered image compositions are UI sections that appear as single pictures but are actually constructed from **multiple raster or SVG assets** stacked via CSS positioning. A typical example combines a background watercolor texture, a foreground UI mock-up, and small icon overlays. According to the [`docs/research/INSPECTION_GUIDE.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/docs/research/INSPECTION_GUIDE.md), missing any layer during extraction results in visually incomplete clones, making detection critical for fidelity.

## Where Detection Logic Lives

The repository centralizes its layered-asset detection guidance across three key locations:

| Component | File Path | Purpose |
|-----------|-----------|---------|
| **Workflow guidance** | [`.windsurf/workflows/clone-website.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/.windsurf/workflows/clone-website.md) | Narrative explaining that sections may contain multiple layers; requires enumerating all `<img>` and background-image elements. Contains the extraction script at lines 88-124. |
| **CLI reference** | [`.opencode/commands/clone-website.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/.opencode/commands/clone-website.md) | Duplicates the layered-asset requirements for command-line agent usage. |
| **Inspection checklist** | [`docs/research/INSPECTION_GUIDE.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/docs/research/INSPECTION_GUIDE.md) | High-level audit checklist explicitly flagging "Z-index layers" and "Layered assets matter" as critical inspection points. |

## Step-by-Step Detection Process

### Running the Browser Discovery Script

Detection executes within the target page's browser context using Chrome MCP, Playwright MCP, or any supported browser tool. The script gathers comprehensive metadata for every image element to reveal stacking relationships.

The process iterates over all `<img>` elements and extracts:
- `src`, `alt`, and natural dimensions
- **`parentClasses`** – CSS classes of the direct container (`img.parentElement?.className`)
- **`siblingCount`** – Number of sibling `<img>` elements in the same parent (`[...img.parentElement.querySelectorAll('img')].length`)
- **`position`** and **`zIndex`** – Computed CSS values to identify absolutely-positioned overlays

Additionally, the script scans every DOM node for non-`none` `backgroundImage` values and records the element's tag and class.

### Identifying Stacked Layers

A container qualifies as a **layered composition** when the returned JSON shows either:
- **`siblingCount > 1`** inside the same parent element
- Presence of both a background-image declaration and child `<img>` elements within the same container

These patterns indicate stacked visual assets requiring separate extraction.

## Code Implementation

### Browser Extraction Script

Execute this script in the browser console (as implemented in [`.windsurf/workflows/clone-website.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/.windsurf/workflows/clone-website.md) lines 88-124) to generate the layer map:

```javascript
// Run via browser MCP (Chrome DevTools or Playwright)
const layers = (() => {
  // Gather <img> elements with parent context
  const imgs = [...document.querySelectorAll('img')].map(img => ({
    src: img.src || img.currentSrc,
    alt: img.alt,
    width: img.naturalWidth,
    height: img.naturalHeight,
    parentClasses: img.parentElement?.className ?? '',
    siblingCount:
      img.parentElement
        ? [...img.parentElement.querySelectorAll('img')].length
        : 0,
    position: getComputedStyle(img).position,
    zIndex: getComputedStyle(img).zIndex,
  }));

  // Gather background-image declarations
  const bgs = [...document.querySelectorAll('*')]
    .filter(el => {
      const bg = getComputedStyle(el).backgroundImage;
      return bg && bg !== 'none';
    })
    .map(el => ({
      url: getComputedStyle(el).backgroundImage,
      element: `${el.tagName.toLowerCase()}.${el.className.split(' ')[0] || ''}`,
    }));

  return JSON.stringify({ imgs, bgs }, null, 2);
})();

console.log(layers);

```

### Interpreting the Output

Save the JSON output to identify layered compositions. This example shows a detected stack:

```json
{
  "imgs": [
    {
      "src": "/images/hero-bg.jpg",
      "alt": "",
      "width": 1920,
      "height": 1080,
      "parentClasses": "hero-section",
      "siblingCount": 2,
      "position": "relative",
      "zIndex": "auto"
    },
    {
      "src": "/images/hero-illustration.png",
      "alt": "",
      "width": 400,
      "height": 350,
      "parentClasses": "hero-section",
      "siblingCount": 2,
      "position": "absolute",
      "zIndex": "10"
    }
  ],
  "bgs": [
    {
      "url": "url(\"/images/hero-gradient.png\")",
      "element": "section.hero-section"
    }
  ]
}

```

Here, the `hero-section` container contains **two sibling images** (`siblingCount: 2`) plus a **background-image**, confirming a three-layer composition.

## Extracting and Storing Assets

### Downloading Identified Layers

Once detected, download each asset using `curl`, `wget`, or a Node.js script. Store them under `public/images/` with descriptive prefixes indicating their layer order:

```bash

# Example downloads for the hero composition

curl -o public/images/hero-gradient.png https://example.com/images/hero-gradient.png
curl -o public/images/hero-bg.jpg https://example.com/images/hero-bg.jpg
curl -o public/images/hero-illustration.png https://example.com/images/hero-illustration.png

```

### Recording in Component Specs

Document the extracted layers in the component specification's "Assets" block (as defined in the workflow template):

```markdown

## Assets

- Background image: `public/images/hero-gradient.png`
- Base photo: `public/images/hero-bg.jpg`
- Overlay illustration: `public/images/hero-illustration.png`

```

### Reconstructing in React Components

Assemble the layers in your React component using absolute positioning or Tailwind utilities to preserve the original stacking:

```tsx
// src/components/HeroSection.tsx
export default function HeroSection() {
  return (
    <section className="relative overflow-hidden">
      {/* Background gradient layer */}
      <div 
        className="absolute inset-0 z-0"
        style={{ backgroundImage: 'url(/images/hero-gradient.png)' }}
      />
      
      {/* Base photo layer */}
      <img
        src="/images/hero-bg.jpg"
        alt=""
        className="relative z-10 w-full h-auto object-cover"
      />
      
      {/* Overlay illustration layer */}
      <img
        src="/images/hero-illustration.png"
        alt=""
        className="absolute inset-0 z-20 m-auto w-48 h-48"
      />
    </section>
  );
}

```

## Full Pipeline Checklist

Follow this workflow derived from [`.windsurf/workflows/clone-website.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/.windsurf/workflows/clone-website.md) to ensure complete extraction:

- [ ] Run the **layer detection script** in the target page's browser context
- [ ] Verify that any container with `siblingCount > 1` or a background-image is logged
- [ ] Download every identified asset into `public/images/`
- [ ] Add the assets to the component spec under the **Assets** heading
- [ ] Build the React component using stacked `<img>` elements or background-image CSS with proper `z-index` values
- [ ] Run `npm run build` followed by `npx tsc --noEmit` to verify compilation

## Summary

- **Layered compositions** are UI sections built from multiple stacked images that appear as single visuals.
- The detection logic resides in [`.windsurf/workflows/clone-website.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/.windsurf/workflows/clone-website.md) (lines 88-124) and relies on analyzing `siblingCount`, `parentClasses`, and `zIndex` values.
- **Browser-side execution** via MCP tools captures both `<img>` elements and CSS `background-image` declarations.
- Containers with multiple sibling images or combined img/background assets require multi-file extraction.
- Store extracted assets in `public/images/` and reconstruct layers usingabsolute positioning or Tailwind `z-index` utilities in React components.

## Frequently Asked Questions

### How do I distinguish between a single image and a layered composition?

A single image exists in isolation within its parent container, showing `siblingCount: 1` and no background-image on the parent. A layered composition shows `siblingCount > 1` (multiple `<img>` elements sharing a parent) or a combination of background-image CSS and child images. The detection script in [`.windsurf/workflows/clone-website.md`](https://github.com/JCodesMore/ai-website-cloner-template/blob/main/.windsurf/workflows/clone-website.md) automatically flags these patterns based on DOM structure analysis.

### Can I automate the download process for detected layers?

Yes. Pipe the JSON output from the browser script into a Node.js utility script (such as `scripts/download-assets.mjs`) that iterates over the `src` and `url` fields. Use `fetch()` or `https.get()` to stream each asset into `public/images/` while preserving the original filenames or applying descriptive prefixes like `hero-bg` and `hero-overlay`.

### What should I do if an image uses CSS background-image instead of an `<img>` tag?

The detection script specifically queries computed styles for `backgroundImage` properties across all DOM nodes. These appear in the `bgs` array of the output JSON. When reconstructing the component, apply these as `background-image` CSS properties on `<div>` elements or section containers rather than `<img>` tags, ensuring you match the original `z-index` and positioning values captured during detection.

### Where does the ai-website-cloner-template expect me to store extracted layered assets?

The template convention places all extracted visual assets in the `public/images/` directory. Reference these files in your component specs using relative paths starting with `public/images/`, and import them in React components using absolute paths like `/images/hero-bg.jpg`. This ensures Next.js or similar frameworks correctly serve the files as static assets.