# Eye Library Reference

## Where the library lives

```
~/.sandcode/eye/
├── awwwards/
│   └── <slug>/
│       ├── shot.png         # full-page static capture at 1440×
│       ├── motion.webm      # 8-second scripted interaction (may be absent)
│       ├── keyframes/       # extracted motion keyframes (may be absent)
│       ├── meta.json        # Awwwards metadata + filter state
│       └── motion.json      # derived motion descriptors (may be absent)
├── user/                    # user-added references outside Awwwards
│   └── <slug>/              # same layout as awwwards/
└── filter.json              # user's love/reject map (may be absent)
```

## How to query it

1. **List available slugs**: read `~/.sandcode/eye/awwwards/` directory + `~/.sandcode/eye/user/` directory.
2. **Read each `meta.json`** to get tier, tags, liveUrl.
3. **Read `filter.json`** if present to apply personal weighting.
4. **Score each reference** using:
   ```
   score = tier_weight × filter_multiplier
   tier_weight: SOTY=1.0, SOTM=0.85, SOTD=0.7
   filter_multiplier: love=1.3, keep=1.1, unseen=1.0, reject=0.0
   ```
5. **Filter by domain match**: compare the project's domain against each reference's `industryTags` and `styleTags`. Keep references whose tags overlap with the project's domain or whose register is compatible.
6. **Pick top 3–6** scored references as the matched cluster.

## Shape of meta.json

```json
{
  "site": {
    "slug": "the-agency-of-love-logic",
    "title": "The Agency of Love & Logic",
    "liveUrl": "https://loloagency.com/",
    "tier": "SOTD",
    "awardDate": "2026-03-18",
    "industryTags": ["Design Agencies", "Portfolio"],
    "techTags": ["GSAP", "Sanity", "Astro"],
    "styleTags": ["Graphic design", "Responsive", "Interaction Design"]
  },
  "capturedAt": "2026-04-19T16:49:15Z",
  "captureStatus": "ok",
  "filterState": "unseen",
  "files": { "static": "shot.png", "motion": "motion.webm", "keyframes": [...] }
}
```

## Shape of motion.json (when present)

```json
{
  "durationMs": 8000,
  "keyframeCount": 10,
  "scrollLinkedRatio": 0.12,          // DOM transform delta / scroll px
  "hoverLatencyMs": 80,
  "hoverDurationMs": 340,
  "primaryEasing": "ease-out-expo",   // nearest named from the bank
  "fpsVariance": 2.1,
  "fpsMedian": 60,
  "canvasCoverage": 0.42,             // fraction of viewport that's canvas/video
  "animationDensity": 0.58            // fraction of frames with visible change
}
```

**High `canvasCoverage`** (> 0.3) in the matched cluster → cluster wants 3D / WebGL. Don't ship a static page.

**Primary easing distribution** across the cluster → constrains your easing choices in generated output. If matched cluster averages `ease-out-expo`, don't ship `ease-in` or `linear`.

**Animation density** high → static page inappropriate for the cluster. Ship with motion or reconsider domain match.

## Using matched references without copying

**The generator never sees the pixels.** You, the model, read `meta.json` + `motion.json` to derive:
- Palette tendency (from tags like "Colorful" / "Minimal" / specific color filters if present)
- Typography register (via style tags like "Typography" + tech tags like "GSAP" / "WebGL")
- Motion signature (via `motion.json`)
- Composition register (via tags like "Parallax" / "Scrolling" / "Animation" / "Clean" / "3D")

You then generate new output constrained by these derived properties but NOT copying any reference.

## Copy-check

When generating, mentally compare to the matched cluster:
- If the layout matches any single reference too closely → it's a copy. Restart.
- If the palette is lifted from any single reference → pick different values.
- If the hero composition mirrors a specific reference → recompose.

The matched cluster provides a *register*, not a *template*.

## Empty library handling

If `~/.sandcode/eye/awwwards/` is empty or missing:
1. Tell the user once: *"Eye library is empty. Run `/eye-ingest run` to populate it from Awwwards. Proceeding with domain → identity map for now."*
2. Fall back to `references/04-domain-map.md` for the blank-slate commit.
3. Do not block on this — the page must still ship.
4. Do not silently fail or produce a worse output; the domain map is there to backstop.

## Seeded references (shipped with SANDCODE)

The `demos/eye-library-proof/` folder in the SANDCODE repo contains 6 seed captures: `the-agency-of-love-logic`, `evolve-2`, `lando-norris`, `bruno-simon-portfolio`, `igloo-inc`, `studio-x`. These are reference material, not the user's library. Use them only as examples in skill documentation, never as substitutes for the user's actual library.

## When to refresh the library

- User explicitly asks for fresh references: run `/eye-ingest run`
- Library hasn't been updated in > 30 days: suggest refresh, don't auto-run
- User's work is trending toward a specific domain missing from the library: suggest targeted ingest with `/eye-ingest run SOTD 1` for recent work
