{
  "id": "product-3d-showcase",
  "kind": "template",
  "title": "Product showcase",
  "summary": "A product opener with layered depth cards, a flowing backdrop and a rotating ring of variants.",
  "url": "https://enrichr.dev/templates/product-3d-showcase.html",
  "section": "page",
  "techniques": [
    "parallax",
    "3d-css",
    "webgl"
  ],
  "stack": [
    "Vanilla JS",
    "WebGL",
    "CSS 3D"
  ],
  "frameworks": [
    "React",
    "Next.js",
    "Vanilla"
  ],
  "mood": [
    "modern",
    "soft"
  ],
  "intents": [
    "product page hero",
    "hardware launch page",
    "product variants gallery",
    "launch landing"
  ],
  "status": "preview",
  "params": [
    {
      "key": "headline",
      "label": "Product name",
      "type": "text",
      "value": "Aura One"
    }
  ],
  "license": "Free to use in personal and client projects during the preview. Final licence terms will be published here before any paid tier starts; ask before reselling the code as a collection.",
  "contract": "composition of elements, each mounted with mount(root, opts)",
  "exports": {
    "claude": "Add the \"Product showcase\" template (first screen) to this project.\n\nThis is the \"Product showcase\" template (first screen) from the Enrichr Library: A product opener with layered depth cards, a flowing backdrop and a rotating ring of variants.\nPage: https://enrichr.dev/templates/product-3d-showcase.html\nMachine-readable spec: https://enrichr.dev/templates/product-3d-showcase.json\n\nTemplate contract: this is a composition of Enrichr elements. Each element follows mount(root, opts):\n- root is an empty container; set root.innerHTML to the element's markup, then call mount(root, opts). It returns { update(partialOpts), destroy() }.\n- The slots below say which container gets which element. Colour tokens: --lt-bg (background), --lt-fg (text), --lt-ac (accent), set on the stage from the palette.\n- slot \"bg\": Shader gradient background (https://enrichr.dev/elements/shader-gradient-background.json)\n- slot \"hero\": Depth parallax card (https://enrichr.dev/elements/depth-parallax-card.json)\n- slot \"body\": 3D ring carousel (https://enrichr.dev/elements/ring-carousel.json)\n\nSteps:\n1. Look at the project first to see its framework and where components, styles and static files live. Follow its conventions.\n2. Fetch https://enrichr.dev/templates/product-3d-showcase.json if you can read URLs (fields: source.markup, source.css, source.js, params); otherwise use the source at the end of this message.\n3. Add the files, mount it where I tell you (default: the top of the home page), and pass the settings below as the opts.\n4. Keep the behaviour of the source unchanged. Do not add dependencies. Respect prefers-reduced-motion. Keep text as real HTML.\n5. Run the dev server and check it. with reduced motion on, nothing moves; it works at 375px wide and with touch only; there are no console errors; scrolling stays smooth; destroy() is called when it unmounts.\n\nSettings:\n{{SETTINGS}}\n\nSource:\n{{CODE}}",
    "chatgpt": "I want the \"Product showcase\" template (first screen) on my website. Below is its complete source. Please:\n1. Build one self-contained index.html that I can open locally to see it working (put the CSS in a <style> tag and the JavaScript in a <script> tag, with the markup in the body).\n2. Then explain, step by step, which parts go where in my own site, and how to mount it. My stack is: [tell me yours, or say \"plain HTML\"].\n3. Keep the behaviour of the source unchanged. Do not add dependencies. Respect prefers-reduced-motion. Keep text as real HTML.\n\nThis is the \"Product showcase\" template (first screen) from the Enrichr Library: A product opener with layered depth cards, a flowing backdrop and a rotating ring of variants.\nPage: https://enrichr.dev/templates/product-3d-showcase.html\nMachine-readable spec: https://enrichr.dev/templates/product-3d-showcase.json\n\nTemplate contract: this is a composition of Enrichr elements. Each element follows mount(root, opts):\n- root is an empty container; set root.innerHTML to the element's markup, then call mount(root, opts). It returns { update(partialOpts), destroy() }.\n- The slots below say which container gets which element. Colour tokens: --lt-bg (background), --lt-fg (text), --lt-ac (accent), set on the stage from the palette.\n- slot \"bg\": Shader gradient background (https://enrichr.dev/elements/shader-gradient-background.json)\n- slot \"hero\": Depth parallax card (https://enrichr.dev/elements/depth-parallax-card.json)\n- slot \"body\": 3D ring carousel (https://enrichr.dev/elements/ring-carousel.json)\n\nSettings:\n{{SETTINGS}}\n\nSource:\n{{CODE}}\n\nVerify: with reduced motion on, nothing moves; it works at 375px wide and with touch only; there are no console errors; scrolling stays smooth; destroy() is called when it unmounts.",
    "cursor": "Add the \"Product showcase\" template (first screen) to this codebase.\n\nThis is the \"Product showcase\" template (first screen) from the Enrichr Library: A product opener with layered depth cards, a flowing backdrop and a rotating ring of variants.\nPage: https://enrichr.dev/templates/product-3d-showcase.html\nMachine-readable spec: https://enrichr.dev/templates/product-3d-showcase.json\n\nTemplate contract: this is a composition of Enrichr elements. Each element follows mount(root, opts):\n- root is an empty container; set root.innerHTML to the element's markup, then call mount(root, opts). It returns { update(partialOpts), destroy() }.\n- The slots below say which container gets which element. Colour tokens: --lt-bg (background), --lt-fg (text), --lt-ac (accent), set on the stage from the palette.\n- slot \"bg\": Shader gradient background (https://enrichr.dev/elements/shader-gradient-background.json)\n- slot \"hero\": Depth parallax card (https://enrichr.dev/elements/depth-parallax-card.json)\n- slot \"body\": 3D ring carousel (https://enrichr.dev/elements/ring-carousel.json)\n\nUse Composer / agent mode. First search the repo for how components, styles and scripts are organised, then add the files in the matching places, mount it on the page I name, and run the app to confirm it works. Keep the behaviour of the source unchanged. Do not add dependencies. Respect prefers-reduced-motion. Keep text as real HTML.\n\nSettings:\n{{SETTINGS}}\n\nSource:\n{{CODE}}\n\nVerify: with reduced motion on, nothing moves; it works at 375px wide and with touch only; there are no console errors; scrolling stays smooth; destroy() is called when it unmounts.\n\nOptional: save this as .cursor/rules/enrichr-product-3d-showcase.mdc so the rule stays with the project:\n---\ndescription: How to use the Enrichr Product showcase template\nalwaysApply: false\n---\nEach slot is an Enrichr element: set the slot container's innerHTML to the element markup, then call mount(container, opts). Call destroy() on every instance on unmount.",
    "v0": "Create a Next.js (App Router) client component for the \"Product showcase\" template (first screen). Tailwind is available but this component needs no utility classes.\n\nThis is the \"Product showcase\" template (first screen) from the Enrichr Library: A product opener with layered depth cards, a flowing backdrop and a rotating ring of variants.\nPage: https://enrichr.dev/templates/product-3d-showcase.html\nMachine-readable spec: https://enrichr.dev/templates/product-3d-showcase.json\n\nTemplate contract: this is a composition of Enrichr elements. Each element follows mount(root, opts):\n- root is an empty container; set root.innerHTML to the element's markup, then call mount(root, opts). It returns { update(partialOpts), destroy() }.\n- The slots below say which container gets which element. Colour tokens: --lt-bg (background), --lt-fg (text), --lt-ac (accent), set on the stage from the palette.\n- slot \"bg\": Shader gradient background (https://enrichr.dev/elements/shader-gradient-background.json)\n- slot \"hero\": Depth parallax card (https://enrichr.dev/elements/depth-parallax-card.json)\n- slot \"body\": 3D ring carousel (https://enrichr.dev/elements/ring-carousel.json)\n\nFiles to create:\n- one <element-id>.js per element in the code below, each with  export { mount };  appended and  export const markup = \"<its markup string>\";  (add // @ts-nocheck on the first line under TypeScript).\n- every element's CSS goes in your global stylesheet (class names are global and start with ef-).\n\nUse this component as the wrapper (adjust the import paths):\n```tsx\n\"use client\";\nimport { useEffect, useRef } from \"react\";\nimport { markup as markup_shader_gradient_background, mount as mount_shader_gradient_background } from \"./shader-gradient-background\";\nimport { markup as markup_depth_parallax_card, mount as mount_depth_parallax_card } from \"./depth-parallax-card\";\nimport { markup as markup_ring_carousel, mount as mount_ring_carousel } from \"./ring-carousel\";\n\nconst SLOTS = [\n  { slot: \"bg\", element: \"shader-gradient-background\", opts: {\"colorA\":\"$bg\",\"colorB\":\"$ac2\",\"speed\":0.6} },\n  { slot: \"hero\", element: \"depth-parallax-card\", opts: {\"label\":\"$headline\",\"colorA\":\"$ac2\",\"colorB\":\"$ac\"} },\n  { slot: \"body\", element: \"ring-carousel\", opts: {\"count\":6,\"radius\":200,\"hue\":160} },\n];\nconst REGISTRY: Record<string, { markup: string; mount: (root: HTMLElement, o: object) => { destroy: () => void } }> = {\n  \"shader-gradient-background\": { markup: markup_shader_gradient_background, mount: mount_shader_gradient_background },\n  \"depth-parallax-card\": { markup: markup_depth_parallax_card, mount: mount_depth_parallax_card },\n  \"ring-carousel\": { markup: markup_ring_carousel, mount: mount_ring_carousel },\n};\n\n// Replace $headline, $fg, $ac and the like with your values and the palette before mounting.\nexport default function Product3dShowcase({ values }: { values: Record<string, string> }) {\n  const stage = useRef<HTMLDivElement>(null);\n  useEffect(() => {\n    const live: { destroy: () => void }[] = [];\n    stage.current?.querySelectorAll(\"[data-slot]\").forEach((host) => {\n      const s = SLOTS.find((x) => x.slot === host.getAttribute(\"data-slot\"));\n      if (!s) return;\n      const opts = Object.fromEntries(Object.entries(s.opts).map(([k, v]) => [k, typeof v === \"string\" ? v.replace(/\\$(\\w+)/g, (m, key) => values[key] ?? m) : v]));\n      host.innerHTML = REGISTRY[s.element].markup;\n      live.push(REGISTRY[s.element].mount(host as HTMLElement, opts));\n    });\n    return () => live.forEach((i) => i.destroy());\n  }, [JSON.stringify(values)]);\n  return (\n    <div ref={stage} style={{ background: values.bg, color: values.fg, position: \"relative\", overflow: \"hidden\" }}>\n      <div data-slot=\"bg\" />\n      <div data-slot=\"hero\" />\n      <div data-slot=\"body\" />\n    </div>\n  );\n}\n```\n\nRender it on the home page so I can see it. Keep the behaviour of the source unchanged. Do not add dependencies. Respect prefers-reduced-motion. Keep text as real HTML.\n\nSettings:\n{{SETTINGS}}\n\nSource:\n{{CODE}}",
    "lovable": "Add the \"Product showcase\" template (first screen) to this React + Vite + TypeScript + Tailwind project. Do not install any packages.\n\nThis is the \"Product showcase\" template (first screen) from the Enrichr Library: A product opener with layered depth cards, a flowing backdrop and a rotating ring of variants.\nPage: https://enrichr.dev/templates/product-3d-showcase.html\nMachine-readable spec: https://enrichr.dev/templates/product-3d-showcase.json\n\nTemplate contract: this is a composition of Enrichr elements. Each element follows mount(root, opts):\n- root is an empty container; set root.innerHTML to the element's markup, then call mount(root, opts). It returns { update(partialOpts), destroy() }.\n- The slots below say which container gets which element. Colour tokens: --lt-bg (background), --lt-fg (text), --lt-ac (accent), set on the stage from the palette.\n- slot \"bg\": Shader gradient background (https://enrichr.dev/elements/shader-gradient-background.json)\n- slot \"hero\": Depth parallax card (https://enrichr.dev/elements/depth-parallax-card.json)\n- slot \"body\": 3D ring carousel (https://enrichr.dev/elements/ring-carousel.json)\n\nFiles to create:\n- one <element-id>.js per element in the code below, each with  export { mount };  appended and  export const markup = \"<its markup string>\";  (add // @ts-nocheck on the first line under TypeScript).\n- every element's CSS goes in your global stylesheet (class names are global and start with ef-).\n\nWrapper component (src/components/Product3dShowcase.tsx):\n```tsx\n\"use client\";\nimport { useEffect, useRef } from \"react\";\nimport { markup as markup_shader_gradient_background, mount as mount_shader_gradient_background } from \"./shader-gradient-background\";\nimport { markup as markup_depth_parallax_card, mount as mount_depth_parallax_card } from \"./depth-parallax-card\";\nimport { markup as markup_ring_carousel, mount as mount_ring_carousel } from \"./ring-carousel\";\n\nconst SLOTS = [\n  { slot: \"bg\", element: \"shader-gradient-background\", opts: {\"colorA\":\"$bg\",\"colorB\":\"$ac2\",\"speed\":0.6} },\n  { slot: \"hero\", element: \"depth-parallax-card\", opts: {\"label\":\"$headline\",\"colorA\":\"$ac2\",\"colorB\":\"$ac\"} },\n  { slot: \"body\", element: \"ring-carousel\", opts: {\"count\":6,\"radius\":200,\"hue\":160} },\n];\nconst REGISTRY: Record<string, { markup: string; mount: (root: HTMLElement, o: object) => { destroy: () => void } }> = {\n  \"shader-gradient-background\": { markup: markup_shader_gradient_background, mount: mount_shader_gradient_background },\n  \"depth-parallax-card\": { markup: markup_depth_parallax_card, mount: mount_depth_parallax_card },\n  \"ring-carousel\": { markup: markup_ring_carousel, mount: mount_ring_carousel },\n};\n\n// Replace $headline, $fg, $ac and the like with your values and the palette before mounting.\nexport default function Product3dShowcase({ values }: { values: Record<string, string> }) {\n  const stage = useRef<HTMLDivElement>(null);\n  useEffect(() => {\n    const live: { destroy: () => void }[] = [];\n    stage.current?.querySelectorAll(\"[data-slot]\").forEach((host) => {\n      const s = SLOTS.find((x) => x.slot === host.getAttribute(\"data-slot\"));\n      if (!s) return;\n      const opts = Object.fromEntries(Object.entries(s.opts).map(([k, v]) => [k, typeof v === \"string\" ? v.replace(/\\$(\\w+)/g, (m, key) => values[key] ?? m) : v]));\n      host.innerHTML = REGISTRY[s.element].markup;\n      live.push(REGISTRY[s.element].mount(host as HTMLElement, opts));\n    });\n    return () => live.forEach((i) => i.destroy());\n  }, [JSON.stringify(values)]);\n  return (\n    <div ref={stage} style={{ background: values.bg, color: values.fg, position: \"relative\", overflow: \"hidden\" }}>\n      <div data-slot=\"bg\" />\n      <div data-slot=\"hero\" />\n      <div data-slot=\"body\" />\n    </div>\n  );\n}\n```\n\nRemove the \"use client\" line if it is not needed. Show it on the home page. Keep the behaviour of the source unchanged. Do not add dependencies. Respect prefers-reduced-motion. Keep text as real HTML.\n\nSettings:\n{{SETTINGS}}\n\nSource:\n{{CODE}}",
    "bolt": "Create a small Vite project (vanilla JavaScript, no framework unless I already have one) that shows the \"Product showcase\" template (first screen).\n\nThis is the \"Product showcase\" template (first screen) from the Enrichr Library: A product opener with layered depth cards, a flowing backdrop and a rotating ring of variants.\nPage: https://enrichr.dev/templates/product-3d-showcase.html\nMachine-readable spec: https://enrichr.dev/templates/product-3d-showcase.json\n\nTemplate contract: this is a composition of Enrichr elements. Each element follows mount(root, opts):\n- root is an empty container; set root.innerHTML to the element's markup, then call mount(root, opts). It returns { update(partialOpts), destroy() }.\n- The slots below say which container gets which element. Colour tokens: --lt-bg (background), --lt-fg (text), --lt-ac (accent), set on the stage from the palette.\n- slot \"bg\": Shader gradient background (https://enrichr.dev/elements/shader-gradient-background.json)\n- slot \"hero\": Depth parallax card (https://enrichr.dev/elements/depth-parallax-card.json)\n- slot \"body\": 3D ring carousel (https://enrichr.dev/elements/ring-carousel.json)\n\nFiles: index.html (a container element, then a script tag), style.css (the CSS below), product-3d-showcase.js (the JavaScript below) and main.js that sets the container's innerHTML to the markup and calls mount(container, opts) with the settings below. Keep the behaviour of the source unchanged. Do not add dependencies. Respect prefers-reduced-motion. Keep text as real HTML.\n\nSettings:\n{{SETTINGS}}\n\nSource:\n{{CODE}}\n\nVerify: with reduced motion on, nothing moves; it works at 375px wide and with touch only; there are no console errors; scrolling stays smooth; destroy() is called when it unmounts.",
    "replit": "Create a new HTML, CSS and JavaScript Repl that shows the \"Product showcase\" template (first screen). No packages, no server code.\n\nThis is the \"Product showcase\" template (first screen) from the Enrichr Library: A product opener with layered depth cards, a flowing backdrop and a rotating ring of variants.\nPage: https://enrichr.dev/templates/product-3d-showcase.html\nMachine-readable spec: https://enrichr.dev/templates/product-3d-showcase.json\n\nTemplate contract: this is a composition of Enrichr elements. Each element follows mount(root, opts):\n- root is an empty container; set root.innerHTML to the element's markup, then call mount(root, opts). It returns { update(partialOpts), destroy() }.\n- The slots below say which container gets which element. Colour tokens: --lt-bg (background), --lt-fg (text), --lt-ac (accent), set on the stage from the palette.\n- slot \"bg\": Shader gradient background (https://enrichr.dev/elements/shader-gradient-background.json)\n- slot \"hero\": Depth parallax card (https://enrichr.dev/elements/depth-parallax-card.json)\n- slot \"body\": 3D ring carousel (https://enrichr.dev/elements/ring-carousel.json)\n\nFiles: index.html (a container element, link style.css, load product-3d-showcase.js and then main.js), style.css (the CSS below), product-3d-showcase.js (the JavaScript below), main.js (sets the container's innerHTML to the markup, then calls mount(container, opts) with the settings below). Press Run to preview. Keep the behaviour of the source unchanged. Do not add dependencies. Respect prefers-reduced-motion. Keep text as real HTML.\n\nSettings:\n{{SETTINGS}}\n\nSource:\n{{CODE}}",
    "figma": "Designer handoff notes for the \"Product showcase\" template (first screen) (Enrichr Library). Figma cannot run this JavaScript inside a design file, so use it as a motion reference and hand the code to a developer.\n\nThis is the \"Product showcase\" template (first screen) from the Enrichr Library: A product opener with layered depth cards, a flowing backdrop and a rotating ring of variants.\nPage: https://enrichr.dev/templates/product-3d-showcase.html\nMachine-readable spec: https://enrichr.dev/templates/product-3d-showcase.json\n\nWhat it does: A product opener with layered depth cards, a flowing backdrop and a rotating ring of variants.\n\nTunable settings:\n- Product name: text, default Aura One\n\nCurrent settings:\n{{SETTINGS}}\n\nFor the developer: Template contract: this is a composition of Enrichr elements. Each element follows mount(root, opts):\n- root is an empty container; set root.innerHTML to the element's markup, then call mount(root, opts). It returns { update(partialOpts), destroy() }.\n- The slots below say which container gets which element. Colour tokens: --lt-bg (background), --lt-fg (text), --lt-ac (accent), set on the stage from the palette.\n- slot \"bg\": Shader gradient background (https://enrichr.dev/elements/shader-gradient-background.json)\n- slot \"hero\": Depth parallax card (https://enrichr.dev/elements/depth-parallax-card.json)\n- slot \"body\": 3D ring carousel (https://enrichr.dev/elements/ring-carousel.json)\n\nIn Figma:\n- Draw the resting state as a frame and the end state as a second frame; link them with Smart Animate to show the motion in a prototype.\n- Put the settings above in the frame's notes or Dev Mode annotations so the developer matches them.\n- Link https://enrichr.dev/templates/product-3d-showcase.html in the handoff: the live demo and the copy-ready code are there. Developers can paste the prompts for Claude, Cursor or v0 from the Export menu.\nNothing is copied from another designer's file; this is original code from Enrichr.",
    "framer": "Add the \"Product showcase\" template (first screen) to Framer as a code component. Framer code components are React, so wrap the vanilla code like this. Check it in the Framer editor, as Framer's component API can change.\n\nThis is the \"Product showcase\" template (first screen) from the Enrichr Library: A product opener with layered depth cards, a flowing backdrop and a rotating ring of variants.\nPage: https://enrichr.dev/templates/product-3d-showcase.html\nMachine-readable spec: https://enrichr.dev/templates/product-3d-showcase.json\n\nTemplate contract: this is a composition of Enrichr elements. Each element follows mount(root, opts):\n- root is an empty container; set root.innerHTML to the element's markup, then call mount(root, opts). It returns { update(partialOpts), destroy() }.\n- The slots below say which container gets which element. Colour tokens: --lt-bg (background), --lt-fg (text), --lt-ac (accent), set on the stage from the palette.\n- slot \"bg\": Shader gradient background (https://enrichr.dev/elements/shader-gradient-background.json)\n- slot \"hero\": Depth parallax card (https://enrichr.dev/elements/depth-parallax-card.json)\n- slot \"body\": 3D ring carousel (https://enrichr.dev/elements/ring-carousel.json)\n\n1. In Framer: Assets > Code > New component. Name it Product3dShowcase.\n2. Paste the JavaScript below into a separate code file named product-3d-showcase.js in the same project, with  export { mount };  and  export const markup = \"<the markup string>\";  added. Put the CSS into the component as a <style> tag.\n3. Component:\n```tsx\nimport { addPropertyControls, ControlType } from \"framer\"\nimport { useEffect, useRef } from \"react\";\nimport { markup as markup_shader_gradient_background, mount as mount_shader_gradient_background } from \"./shader-gradient-background\";\nimport { markup as markup_depth_parallax_card, mount as mount_depth_parallax_card } from \"./depth-parallax-card\";\nimport { markup as markup_ring_carousel, mount as mount_ring_carousel } from \"./ring-carousel\";\n\nconst SLOTS = [\n  { slot: \"bg\", element: \"shader-gradient-background\", opts: {\"colorA\":\"$bg\",\"colorB\":\"$ac2\",\"speed\":0.6} },\n  { slot: \"hero\", element: \"depth-parallax-card\", opts: {\"label\":\"$headline\",\"colorA\":\"$ac2\",\"colorB\":\"$ac\"} },\n  { slot: \"body\", element: \"ring-carousel\", opts: {\"count\":6,\"radius\":200,\"hue\":160} },\n];\nconst REGISTRY: Record<string, { markup: string; mount: (root: HTMLElement, o: object) => { destroy: () => void } }> = {\n  \"shader-gradient-background\": { markup: markup_shader_gradient_background, mount: mount_shader_gradient_background },\n  \"depth-parallax-card\": { markup: markup_depth_parallax_card, mount: mount_depth_parallax_card },\n  \"ring-carousel\": { markup: markup_ring_carousel, mount: mount_ring_carousel },\n};\n\n// Replace $headline, $fg, $ac and the like with your values and the palette before mounting.\nexport default function Product3dShowcase({ values }: { values: Record<string, string> }) {\n  const stage = useRef<HTMLDivElement>(null);\n  useEffect(() => {\n    const live: { destroy: () => void }[] = [];\n    stage.current?.querySelectorAll(\"[data-slot]\").forEach((host) => {\n      const s = SLOTS.find((x) => x.slot === host.getAttribute(\"data-slot\"));\n      if (!s) return;\n      const opts = Object.fromEntries(Object.entries(s.opts).map(([k, v]) => [k, typeof v === \"string\" ? v.replace(/\\$(\\w+)/g, (m, key) => values[key] ?? m) : v]));\n      host.innerHTML = REGISTRY[s.element].markup;\n      live.push(REGISTRY[s.element].mount(host as HTMLElement, opts));\n    });\n    return () => live.forEach((i) => i.destroy());\n  }, [JSON.stringify(values)]);\n  return (\n    <div ref={stage} style={{ background: values.bg, color: values.fg, position: \"relative\", overflow: \"hidden\" }}>\n      <div data-slot=\"bg\" />\n      <div data-slot=\"hero\" />\n      <div data-slot=\"body\" />\n    </div>\n  );\n}\n\n// Template: expose headline and palette colours as property controls the same way.\n```\n4. Keep the behaviour of the source unchanged. Do not add dependencies. Respect prefers-reduced-motion. Keep text as real HTML.\n\nSettings:\n{{SETTINGS}}\n\nSource:\n{{CODE}}",
    "webflow": "Add the \"Product showcase\" template (first screen) to a Webflow site with an Embed element. Test it on the published or preview site: scripts in embeds may not run inside the Designer canvas.\n\nThis is the \"Product showcase\" template (first screen) from the Enrichr Library: A product opener with layered depth cards, a flowing backdrop and a rotating ring of variants.\nPage: https://enrichr.dev/templates/product-3d-showcase.html\nMachine-readable spec: https://enrichr.dev/templates/product-3d-showcase.json\n\nTemplate contract: this is a composition of Enrichr elements. Each element follows mount(root, opts):\n- root is an empty container; set root.innerHTML to the element's markup, then call mount(root, opts). It returns { update(partialOpts), destroy() }.\n- The slots below say which container gets which element. Colour tokens: --lt-bg (background), --lt-fg (text), --lt-ac (accent), set on the stage from the palette.\n- slot \"bg\": Shader gradient background (https://enrichr.dev/elements/shader-gradient-background.json)\n- slot \"hero\": Depth parallax card (https://enrichr.dev/elements/depth-parallax-card.json)\n- slot \"body\": 3D ring carousel (https://enrichr.dev/elements/ring-carousel.json)\n\n1. Add an Embed element where it should appear. Paste a <style> block with the CSS, one container <div id=\"enrichr-product-3d-showcase\"></div>, and a <script> block with the JavaScript followed by:\n   mount(document.getElementById(\"enrichr-product-3d-showcase\"), { ...your settings... });\n   (set the container's innerHTML to the markup first, as in the contract).\n2. Embed elements have a size limit (check Webflow's current number). If the code is longer, host the JS and CSS as files and link them from Custom code in the page settings, then keep only the container and the mount call in the Embed.\n3. Keep the behaviour of the source unchanged. Do not add dependencies. Respect prefers-reduced-motion. Keep text as real HTML.\n\nSettings:\n{{SETTINGS}}\n\nSource:\n{{CODE}}"
  },
  "exportTools": [
    "claude",
    "chatgpt",
    "cursor",
    "v0",
    "lovable",
    "bolt",
    "replit",
    "figma",
    "framer",
    "webflow"
  ],
  "palette": "forest",
  "palettes": {
    "forest": {
      "label": "Forest",
      "bg": "#10261f",
      "fg": "#f2f6f0",
      "ac": "#c6f26b",
      "ac2": "#2f7d5b"
    },
    "ink": {
      "label": "Ink",
      "bg": "#0b0b10",
      "fg": "#f4f1ea",
      "ac": "#ff5a36",
      "ac2": "#6a5cff"
    },
    "paper": {
      "label": "Paper",
      "bg": "#f3efe6",
      "fg": "#16140f",
      "ac": "#d6361f",
      "ac2": "#1f4fd6"
    }
  },
  "slots": [
    {
      "slot": "bg",
      "element": "shader-gradient-background",
      "opts": {
        "colorA": "$bg",
        "colorB": "$ac2",
        "speed": 0.6
      },
      "spec": "https://enrichr.dev/elements/shader-gradient-background.json"
    },
    {
      "slot": "hero",
      "element": "depth-parallax-card",
      "opts": {
        "label": "$headline",
        "colorA": "$ac2",
        "colorB": "$ac"
      },
      "spec": "https://enrichr.dev/elements/depth-parallax-card.json"
    },
    {
      "slot": "body",
      "element": "ring-carousel",
      "opts": {
        "count": 6,
        "radius": 200,
        "hue": 160
      },
      "spec": "https://enrichr.dev/elements/ring-carousel.json"
    }
  ]
}