Hello, fellow assistant.

An opening.
A clear contract.

Aperture reveals existing HTML with animated SVG geometry. Here is the context to integrate it into someone’s project, and the evidence to know when you’re done.

Read the full context Start with the manifest

Looking for the feeling? The moving parts are for humans.

Read what you need.

Everything is reachable by an ordinary HTTP fetch. No account, browser automation, skill installation or MCP connection is needed.

Use the real package.

This name is not on npm yet. Download the archive into your project, then install its local path using the project’s package manager.

# Save the archive in your project’s vendor directory.
npm install ./vendor/bolted-aperture-0.1.0.tgz
Download 0.1.0

Vanilla, Vue, Svelte

@bolted/aperture

Mount after the DOM exists. Destroy the controller in the app’s teardown lifecycle.

Core guideWorking starter

React

@bolted/aperture/react

Use the hook and both refs. The controller is nullable before mount; the hook owns cleanup.

React guideWorking starter

Next.js App Router

@bolted/aperture/react

Keep the hook in a client component. The project’s router owns navigation.

Next.js guideWorking starter

The boundary matters.

Aperture owns the reveal. Your app owns the interaction. Preserve the user’s content, framework and intent.

Layout
Give the host explicit dimensions, relative positioning, zero padding and hidden overflow. Content must be its direct child. Keep persistent controls outside the clipped child.
Completion
open(), close() and toggle() resolve with { status, progress }. Follow-up focus or navigation requires status === 'completed'. A newer request interrupts the previous one.
Ownership
Your app supplies dialog semantics, focus, Escape, scroll locking, captions and routing. A reveal primitive is not a complete modal or navigation system.
Cleanup
Call destroy() on teardown outside React. The React hook does this for you. Interrupted or destroyed requests must not trigger stale work.
Fallback
Automatic transitions respect Reduce Motion. Missing animation capabilities use instant mode. Keep meaningful content and navigation usable without JavaScript.
Evidence
Capability detection is not rendering certification. Check the actual target browser. Physical Safari/iPhone verification and device benchmarks remain pending.

Keep the recipe exact.

A recipe is portable data. Use a supplied recipe unchanged. If none was supplied, choose a catalog default that fits the requested interaction.

{
  "version": 1,
  "preset": "folded-iris",
  "duration": 1.1,
  "spread": 1,
  "rotation": 0,
  "easing": "smooth",
  "origin": {
    "x": 0.5,
    "y": 0.5
  },
  "colors": [
    "#2546f0",
    "#e4ecac"
  ]
}

Validate with parseRecipe(json, { strict: true }). Pass recipeToOptions(recipe) to the controller or hook. Recipe version: 1 is the data format, not a controller setting.

Share links encode JSON after #recipe=. HTTP fetches omit the fragment. Decode a supplied URL’s fragment or request its exported JSON; do not infer values from a screenshot.

Rotation is visually inactive for circular presets. Don’t change the tuned value to make a circular shape rotate.

Finish with evidence.

Build the interaction, then exercise it. Report what you checked and what remains unverified.

Full verification checklist