{
  "version": 1,
  "repo": "https://github.com/gitcamy/design-database",
  "raw_base": "https://raw.githubusercontent.com/gitcamy/design-database/main/",
  "local_path": "/Users/Cam/dev/design-database",
  "components": [
    {
      "name": "ascii-footer",
      "path": "components/ascii-footer",
      "aliases": [
        "ascii wordmark",
        "ascii grid footer",
        "cursor light footer",
        "megamind footer"
      ],
      "summary": "Footer that renders a phrase as a fixed grid of monospaced glyphs on a canvas. Letterforms read only through character density; the cursor acts as a soft point light that darkens glyphs within a radius and dissolves them far away. Nothing moves, only the character in each cell changes.",
      "tags": [
        "footer",
        "canvas",
        "typography",
        "ascii",
        "cursor-reactive",
        "pointer-light",
        "wordmark",
        "texture",
        "no-build"
      ],
      "stack": [
        "react",
        "canvas"
      ],
      "language": "jsx",
      "dependencies": [],
      "setup": [],
      "files": [
        {
          "path": "AsciiFooter.jsx",
          "role": "component",
          "dest": "components/AsciiFooter.jsx"
        },
        {
          "path": "demo.html",
          "role": "demo"
        },
        {
          "path": "README.md",
          "role": "docs"
        }
      ],
      "demo": {
        "file": "demo.html",
        "serve": "python3 -m http.server 8766",
        "build_required": false
      },
      "ports": [],
      "techniques": [
        "luminance-per-cell sampling from an offscreen 2x canvas, cached until resize",
        "glyph atlas indexed by density plus a radial light term",
        "redraws coalesced to one rAF per pointer event"
      ],
      "notes": "Self-contained, no dependencies. Legibility scales with width; below ~900px the wordmark reads as texture."
    },
    {
      "name": "marquee-along-svg-path",
      "path": "components/marquee-along-svg-path",
      "aliases": [
        "marquee on a path",
        "offset-path marquee",
        "images along a curve",
        "path marquee"
      ],
      "summary": "Marquee that moves its children along an arbitrary SVG path using CSS offset-path. Hover slowdown, drag with inertia, scroll-velocity coupling, direction flipping, rolling z-index, and responsive scaling.",
      "tags": [
        "marquee",
        "svg",
        "offset-path",
        "scroll",
        "drag",
        "hover",
        "motion",
        "hero",
        "carousel",
        "responsive"
      ],
      "stack": [
        "react",
        "typescript",
        "tailwind",
        "motion",
        "shadcn"
      ],
      "language": "tsx",
      "dependencies": [
        "motion",
        "clsx",
        "tailwind-merge"
      ],
      "setup": [
        "shadcn-style project: TypeScript, Tailwind, the @/ alias, and cn exported from @/lib/utils",
        "Next.js App Router: add \"use client\" as the first line of the component and the demo"
      ],
      "files": [
        {
          "path": "marquee-along-svg-path.tsx",
          "role": "component",
          "dest": "components/ui/marquee-along-svg-path.tsx"
        },
        {
          "path": "demo.tsx",
          "role": "demo"
        },
        {
          "path": "utils.ts",
          "role": "helper",
          "dest": "lib/utils.ts",
          "skip_if_exists": true
        },
        {
          "path": "demo.html",
          "role": "demo"
        },
        {
          "path": "README.md",
          "role": "docs"
        }
      ],
      "demo": {
        "file": "demo.html",
        "serve": "python3 -m http.server 8767",
        "build_required": false
      },
      "ports": [
        {
          "target": "framer",
          "path": "framer/MarqueeAlongPath.tsx",
          "notes": "Self-contained, inline styles, framer-motion, property controls for images/layers/size/radius/rotation/clip."
        }
      ],
      "techniques": [
        "CSS offset-path: path() driven by a motion value per item",
        "spring-smoothed scroll velocity added to base velocity",
        "drag delta mapped to path percentage with decay-based inertia"
      ],
      "notes": "Hooks are called inside items.map, so children length and repeat must be stable at runtime or the component needs remounting with a key. offset-path needs Safari 16+."
    },
    {
      "name": "mosaic-hero-open",
      "path": "components/mosaic-hero-open",
      "aliases": [
        "pill to full bleed hero",
        "hero that opens from a pill",
        "expanding hero",
        "mosaic reveal hero",
        "tile resolve hero"
      ],
      "summary": "Hero that opens by expanding a small pill into a full bleed card, with the background rendered as a tile mosaic on a grid fixed in screen space, so the image appears to resolve as the card grows. The mosaic is permanent. Wordmark, headline, paragraph and CTA enter on a stagger, then the image runs a slow continuous zoom.",
      "tags": [
        "hero",
        "canvas",
        "mosaic",
        "pixelation",
        "reveal",
        "page-load",
        "expansion",
        "line-reveal",
        "landing",
        "no-build"
      ],
      "stack": [
        "react",
        "canvas"
      ],
      "language": "jsx",
      "dependencies": [],
      "setup": [],
      "files": [
        {
          "path": "MosaicHeroOpen.jsx",
          "role": "component",
          "dest": "components/MosaicHeroOpen.jsx"
        },
        {
          "path": "demo.html",
          "role": "demo"
        },
        {
          "path": "README.md",
          "role": "docs"
        }
      ],
      "demo": {
        "file": "demo.html",
        "serve": "python3 -m http.server 8768",
        "build_required": false
      },
      "ports": [],
      "techniques": [
        "tile grid sized in screen space, not image space, so growing the container adds cells and the picture resolves as it opens",
        "downsample the source to one pixel per cell and let the browser average, then paint squares with a 1px seam",
        "open curve fitted to the reference as progress^0.6, driving width, height and corner radius from a full pill",
        "per-line headline reveal from an overflow-hidden box, so letters are cut along a horizontal edge mid reveal",
        "post-settle zoom applied to the source rectangle so the tile grid stays locked while the image moves"
      ],
      "notes": "Derived from a screen recording via the visual-to-prompt skill; brand, copy and imagery are not from the reference. Paints a procedural stand-in when no image is given. getImageData taints on a cross-origin image without CORS. The README carries the reusable prompt template."
    },
    {
      "name": "before-after-drag-reveal",
      "path": "components/before-after-drag-reveal",
      "aliases": [
        "before after slider",
        "comparison slider",
        "drag to compare",
        "with vs without",
        "image compare slider",
        "split reveal"
      ],
      "summary": "Before/after comparison section: one mockup rendered twice in identical layout, stacked, with a draggable vertical divider. Left of the line shows AFTER, right shows BEFORE. The divider only moves a clip boundary, so cards, charts and numbers switch state exactly where the line crosses them. No easing, no fades.",
      "tags": [
        "comparison",
        "before-after",
        "slider",
        "drag",
        "clip-path",
        "pointer",
        "dashboard",
        "landing",
        "accessible",
        "no-build"
      ],
      "stack": [
        "react"
      ],
      "language": "jsx",
      "dependencies": [],
      "setup": [
        "Next.js App Router: add \"use client\" as the first line of the component"
      ],
      "files": [
        {
          "path": "BeforeAfterReveal.jsx",
          "role": "component",
          "dest": "components/BeforeAfterReveal.jsx"
        },
        {
          "path": "demo.html",
          "role": "demo"
        },
        {
          "path": "README.md",
          "role": "docs"
        }
      ],
      "demo": {
        "file": "demo.html",
        "serve": "python3 -m http.server 8769",
        "build_required": false
      },
      "ports": [],
      "techniques": [
        "two identical layouts stacked, the top one clipped with clip-path: inset(0 calc(100% - var(--x)) 0 0) so the cut runs mid-card",
        "top layer opaque and isolated so transparent frames and z-indexed children underneath cannot bleed through",
        "pointer capture on the whole frame, rAF-coalesced 1:1 tracking, no easing",
        "handle doubles as a role=slider with arrow, Home and End keys"
      ],
      "notes": "Derived from a screen recording via the visual-to-prompt skill; brand, copy and icons are not from the reference. Ships a placeholder DashboardMockup (named export) used when before/after are omitted. Both layers must be the same size. The README carries the reusable prompt template."
    },
    {
      "name": "transparent-to-solid-nav",
      "path": "components/transparent-to-solid-nav",
      "aliases": [
        "scroll nav",
        "sticky header that turns white",
        "transparent header on scroll",
        "nav background on scroll",
        "solid nav on scroll"
      ],
      "summary": "Fixed top nav that is transparent with light ink over the hero, and switches to a solid (white or colored) bar with dark ink once the page scrolls past a few pixels. A two-state switch with a 250ms crossfade, not scroll-linked progress. Height, layout, logo and CTA never change.",
      "tags": [
        "navigation",
        "header",
        "nav",
        "scroll",
        "sticky",
        "fixed",
        "transparent",
        "landing",
        "no-build"
      ],
      "stack": [
        "react"
      ],
      "language": "jsx",
      "dependencies": [],
      "setup": [
        "Next.js App Router: add \"use client\" as the first line of the component"
      ],
      "files": [
        {
          "path": "ScrollNav.jsx",
          "role": "component",
          "dest": "components/ScrollNav.jsx"
        },
        {
          "path": "demo.html",
          "role": "demo"
        },
        {
          "path": "README.md",
          "role": "docs"
        }
      ],
      "demo": {
        "file": "demo.html",
        "serve": "python3 -m http.server 8770",
        "build_required": false
      },
      "ports": [],
      "techniques": [
        "boolean data-scrolled at a small threshold, not scroll-linked progress",
        "background on its own absolutely positioned layer so only opacity animates and nothing reflows",
        "ink via one CSS variable with a shorter transition than the background",
        "transitions disabled on the first check so a page loaded mid-scroll starts solid"
      ],
      "notes": "Derived from a screen recording via the visual-to-prompt skill; brand, copy and hero image are not from the reference. The menu icon only calls onMenu, no drawer included. The README carries the reusable prompt template."
    },
    {
      "name": "watermark-cta-form",
      "path": "components/watermark-cta-form",
      "aliases": [
        "cta form",
        "email capture card",
        "request info form",
        "newsletter card",
        "contact cta with logo watermark",
        "demo request section"
      ],
      "summary": "Closing CTA card with an inline email form: one base color lifted by two color-mix corner glows, an oversized brand mark as a faint watermark cropped by the bottom edge, centered headline, paragraph, and input plus button. Background color and watermark mark are both props.",
      "tags": [
        "cta",
        "form",
        "email",
        "lead-capture",
        "card",
        "watermark",
        "gradient",
        "landing",
        "no-build"
      ],
      "stack": [
        "react"
      ],
      "language": "jsx",
      "dependencies": [],
      "setup": [
        "Next.js App Router: add \"use client\" as the first line of the component"
      ],
      "files": [
        {
          "path": "WatermarkCtaForm.jsx",
          "role": "component",
          "dest": "components/WatermarkCtaForm.jsx"
        },
        {
          "path": "demo.html",
          "role": "demo"
        },
        {
          "path": "README.md",
          "role": "docs"
        }
      ],
      "demo": {
        "file": "demo.html",
        "serve": "python3 -m http.server 8771",
        "build_required": false
      },
      "ports": [],
      "techniques": [
        "two radial glows mixed from one base color with color-mix(in oklab), so any bg keeps the same lighting",
        "watermark as an absolutely positioned currentColor layer behind content in an isolated, overflow-hidden section, sized to card height and cropped at the bottom",
        "async onSubmit with idle, sending, done and error states"
      ],
      "notes": "Derived from a screenshot via the visual-to-prompt skill; brand, copy and mark are not from the reference. watermark accepts a node or an image URL. The bottom-right bloom is tuned for cool colors; use glow={false} on warm ones. The README carries the reusable prompt template."
    },
    {
      "name": "iridescent-cobalt-3d",
      "path": "components/iridescent-cobalt-3d",
      "aliases": [
        "iridescent 3d material",
        "thin film plastic",
        "holographic 3d object",
        "chrome blue 3d shapes",
        "oil slick material",
        "dichroic 3d"
      ],
      "summary": "Material for any 3D object: glossy opaque cobalt plastic under a banded thin-film iridescent coat. Deep solid blue facing the camera; cyan, violet, magenta and yellow bands on bevels and rims; lavender-white highlights. Ships as a Three.js module (material, studio environment, film thickness map, star and spring helpers) plus image-model and Blender prompts.",
      "tags": [
        "3d",
        "material",
        "three.js",
        "webgl",
        "iridescence",
        "thin-film",
        "shader",
        "product-render",
        "hero",
        "prompt",
        "no-build"
      ],
      "stack": [
        "three.js"
      ],
      "language": "js",
      "dependencies": [
        "three@>=0.163"
      ],
      "setup": [
        "Import map or bundler that resolves 'three' and 'three/addons/'"
      ],
      "files": [
        {
          "path": "iridescentCobalt.js",
          "role": "component",
          "dest": "lib/iridescentCobalt.js"
        },
        {
          "path": "demo.html",
          "role": "demo"
        },
        {
          "path": "README.md",
          "role": "docs"
        }
      ],
      "demo": {
        "file": "demo.html",
        "serve": "python3 -m http.server 8772",
        "build_required": false
      },
      "ports": [],
      "techniques": [
        "MeshPhysicalMaterial with high ior, light clearcoat and iridescence driven by a banded thickness map",
        "procedural PMREM studio: mid-dark surround plus very bright white softboxes and rim panels, so the body stays saturated and the film lights up at grazing angles",
        "NeutralToneMapping to keep saturated blues from shifting purple",
        "dished extruded face via tessellation plus analytic normals from a smooth-min distance field"
      ],
      "notes": "Derived from a screenshot via the visual-to-prompt skill; objects rebuilt from scratch. A material, not a UI component. The README carries the reusable prompt template with image-model, Blender and Three.js variants. WebGL shows the film more faintly than Cycles."
    },
    {
      "name": "lens-part-cta-reveal",
      "path": "components/lens-part-cta-reveal",
      "aliases": [
        "lens reveal",
        "parting lobes",
        "eyelid reveal",
        "scroll reveal cta",
        "ellipses part on scroll",
        "closing cta reveal",
        "purple cta reveal"
      ],
      "summary": "Closing CTA section revealed on scroll by two oversized soft-lit ellipses (one hanging from above, one rising from below) that part like an opening lens. The lobes sit in front of the content and clip it; the headline, paragraph and CTA brighten from 10% to full as the gap opens. Scroll-scrubbed, single hue family, depth only from rim highlights and a cast shade.",
      "tags": [
        "cta",
        "section",
        "scroll",
        "scroll-linked",
        "reveal",
        "parallax",
        "ellipse",
        "gradient",
        "landing",
        "no-build"
      ],
      "stack": [
        "react"
      ],
      "language": "jsx",
      "dependencies": [],
      "setup": [
        "Next.js App Router: add \"use client\" as the first line of the component",
        "Load a serif with italics (default Newsreader) or pass the serif prop"
      ],
      "files": [
        {
          "path": "LensPartReveal.jsx",
          "role": "component",
          "dest": "components/LensPartReveal.jsx"
        },
        {
          "path": "demo.html",
          "role": "demo"
        },
        {
          "path": "README.md",
          "role": "docs"
        }
      ],
      "demo": {
        "file": "demo.html",
        "serve": "python3 -m http.server 8773",
        "build_required": false
      },
      "ports": [],
      "techniques": [
        "oversized border-radius:50% ellipses whose height is solved from a target edge sag, so curvature holds at any width",
        "scroll progress from the section's bounding rect written straight to transform/opacity in one rAF, no re-render",
        "ease-in gap fitted to the reference as restGap * p^1.5",
        "rim highlight and gap shade from inset plus outer box-shadows that follow the elliptical radius",
        "rest gap floored at measured content height so wrapped copy on phones is never covered"
      ],
      "notes": "Derived from a screen recording via the visual-to-prompt skill; brand and copy are not from the reference. Progress 1 needs the section top to reach the viewport top, so a last-on-page section should stay 100vh. The README carries the reusable prompt template."
    },
    {
      "name": "cast-iron-medallion-tilt",
      "path": "components/cast-iron-medallion-tilt",
      "aliases": [
        "cast iron 3d logo",
        "sandblasted metal medallion",
        "dark metal coin logo",
        "3d ring with logo",
        "cursor tilt 3d object",
        "gunmetal emblem"
      ],
      "summary": "3D medallion in dark sandblasted cast iron: an open ring with an extruded mark floating inside, in a three-quarter pose on near black. Tilts toward the pointer on a critically damped spring with idle drift; fixed lights make highlights slide across the grain. Faces stay near black, grain shows only in raking light. Three.js module plus image, video and code prompts.",
      "tags": [
        "3d",
        "three.js",
        "webgl",
        "material",
        "metal",
        "cast-iron",
        "logo",
        "hero",
        "cursor-reactive",
        "tilt",
        "prompt",
        "no-build"
      ],
      "stack": [
        "three.js"
      ],
      "language": "js",
      "dependencies": [
        "three@>=0.163"
      ],
      "setup": [
        "Import map or bundler that resolves 'three' and 'three/addons/'",
        "renderer.toneMapping = THREE.NeutralToneMapping"
      ],
      "files": [
        {
          "path": "castIronMedallion.js",
          "role": "component",
          "dest": "lib/castIronMedallion.js"
        },
        {
          "path": "demo.html",
          "role": "demo"
        },
        {
          "path": "README.md",
          "role": "docs"
        }
      ],
      "demo": {
        "file": "demo.html",
        "serve": "python3 -m http.server 8774",
        "build_required": false
      },
      "ports": [],
      "techniques": [
        "normal map and roughness map baked from one tileable value-noise height field so bumps and sparkle agree",
        "glint pass injected via onBeforeCompile: hashed per-cell facet normals with a tight specular lobe against the first directional light, weighted toward grazing angles",
        "mark UVs scaled by the same factor as its geometry so grain and glints match the ring",
        "near-black faces from a very dim RoomEnvironment, not dark albedo; a raking key light lights side walls and grain",
        "yaw plus pitch about a diagonal gives a leaning ellipse with the mark upright (roll would tilt the mark)",
        "SmoothDamp-style critically damped spring toward rest + pointer*maxTilt + idle sine, no overshoot",
        "lights fixed while the object rotates so highlights travel across the grain"
      ],
      "notes": "Derived from a screen recording via the visual-to-prompt skill; the mark and all branding are not from the reference. Rest pose and cursor trigger are inferred. Glints follow the first DirectionalLight in the scene; the README template also has a path-traced route. Pass any THREE.Shape[] (e.g. from SVGLoader) as the mark."
    },
    {
      "name": "negative-space-mark-footer",
      "path": "components/negative-space-mark-footer",
      "aliases": [
        "bold footer",
        "two colour footer band",
        "negative space logo footer",
        "giant monogram footer",
        "cut-out mark footer"
      ],
      "summary": "Full-bleed footer band in two flat colours with an oversized monogram built from separate tiles, whose gutters open into a four pointed star in negative space. Wordmark, mark and tagline share one optical centreline; a utility row runs along the bottom. Stacks to a centred column on narrow screens.",
      "tags": [
        "footer",
        "svg",
        "logo",
        "negative-space",
        "monogram",
        "two-colour",
        "flat",
        "brand",
        "layout",
        "responsive",
        "no-build"
      ],
      "stack": [
        "react",
        "svg"
      ],
      "language": "jsx",
      "dependencies": [],
      "setup": [],
      "files": [
        {
          "path": "NegativeSpaceMarkFooter.jsx",
          "role": "component",
          "dest": "components/NegativeSpaceMarkFooter.jsx"
        },
        {
          "path": "demo.html",
          "role": "demo"
        },
        {
          "path": "README.md",
          "role": "docs"
        }
      ],
      "demo": {
        "file": "demo.html",
        "serve": "python3 -m http.server 8768",
        "build_required": false
      },
      "ports": [],
      "techniques": [
        "the negative shape is never drawn: tiles turn large radii toward the middle and the leftover ground becomes the mark",
        "gutters at roughly a tenth of the mark width, the band where tiles neither fuse into a blob nor scatter as separate shapes",
        "one shared optical centreline at a fixed percentage down the band, with flanking elements at a symmetric offset, so three items read as one lockup",
        "strict two colour rule extended to every element including icon discs, which are ink fill with the glyph knocked out in the ground colour",
        "all sizes derived from a measured container width rather than viewport units, with floors, so the band holds proportion at any size"
      ],
      "notes": "Derived from a screenshot via the visual-to-prompt skill; the monogram geometry is authored fresh and the brand and copy are not from the source. No motion: the reference was static. tile() and dome() helpers inside the file build the paths. The README carries the reusable prompt template."
    }
  ]
}