{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "hacker-text-html-demo",
  "title": "Hacker Text",
  "description": "Example of text animation that scrambles letters before revealing the final text using HTML, CSS and JavaScript.",
  "dependencies": [],
  "registryDependencies": [
    "https://atlasui.dev/r/hacker-text-html.json"
  ],
  "files": [
    {
      "path": "registry/html/examples/hacker-text-html-demo/index.html",
      "content": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"UTF-8\" />\n    <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\" />\n    <title>Hacker Text Html Demo - Atlas UI</title>\n    <link rel=\"stylesheet\" href=\"style.css\" />\n  </head>\n  <body>\n    <span class=\"hacker-text\" data-value=\"Atlas UI\">Atlas UI</span>\n  </body>\n\n  <script type=\"module\" src=\"script.js\"></script>\n</html>\n",
      "type": "registry:file",
      "target": "~/hacker-text/index.html"
    },
    {
      "path": "registry/html/examples/hacker-text-html-demo/style.css",
      "content": "@import url(\"https://fonts.googleapis.com/css2?family=Bebas+Neue&display=swap\");\n\n:root {\n  --background: light-dark(\n    oklch(100% 0.00011 271.152),\n    oklch(18.22% 0.00002 271.152)\n  );\n  --foreground: light-dark(\n    oklch(18.22% 0.00002 271.152),\n    oklch(98.511% 0.00011 271.152)\n  );\n}\n\nhtml {\n  color-scheme: light dark;\n}\n\nbody {\n  margin: 0;\n  padding: 0;\n  height: 100vh;\n  width: 100%;\n  background: var(--background);\n  display: flex;\n  align-items: center;\n  justify-content: center;\n}\n\n.hacker-text {\n  font-family: \"Bebas Neue\", sans-serif;\n  text-transform: uppercase;\n  font-size: 4rem;\n  cursor: pointer;\n  color: var(--foreground);\n}\n",
      "type": "registry:file",
      "target": "~/hacker-text/style.css"
    },
    {
      "path": "registry/html/examples/hacker-text-html-demo/script.js",
      "content": "document.addEventListener(\"DOMContentLoaded\", () => {\n  const textElements = document.querySelectorAll(\".hacker-text\");\n  const letters = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\";\n  let interval = null;\n  let timeout = null;\n\n  const scrambleText = (target) => {\n    let iteration = 0;\n\n    clearInterval(interval);\n\n    interval = setInterval(() => {\n      if (!target.dataset.value) return;\n\n      target.innerText = target.innerText\n        .split(\"\")\n        .map((letter, index) => {\n          if (index < iteration) {\n            return target.dataset.value[index];\n          }\n          return letters[Math.floor(Math.random() * 26)];\n        })\n        .join(\"\");\n\n      if (iteration >= target.dataset.value.length) {\n        clearInterval(interval);\n      }\n\n      iteration += 1 / 3;\n    }, 30);\n  };\n\n  const applyEffect = () => {\n    if (window.matchMedia(\"(min-width: 768px)\").matches) {\n      textElements.forEach((textElement) => {\n        textElement.addEventListener(\"mouseover\", (event) => {\n          const target = event.target;\n          scrambleText(target);\n        });\n      });\n    }\n    // Run effect on page load after 600ms for all devices\n    timeout = setTimeout(() => {\n      textElements.forEach((textElement) => {\n        scrambleText(textElement);\n      });\n    }, 600);\n  };\n\n  applyEffect();\n\n  window.addEventListener(\"beforeunload\", () => {\n    if (interval) clearInterval(interval);\n    if (timeout) clearTimeout(timeout);\n  });\n});\n",
      "type": "registry:file",
      "target": "~/hacker-text/script.js"
    }
  ],
  "meta": {
    "framework": "html"
  },
  "type": "registry:example"
}