{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "morph-navbar-html",
  "title": "Morph Navbar",
  "description": "A polished navigation bar with a fluid, morphing pill that tracks the active link and hover state built with HTML, CSS, JavaScript and Motion.",
  "dependencies": [
    "motion"
  ],
  "files": [
    {
      "path": "registry/html/atlasui/morph-navbar/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>Morph Navbar - Atlas UI</title>\n    <link rel=\"stylesheet\" href=\"style.css\" />\n  </head>\n  <body>\n    <nav id=\"morph-navbar\">\n      <div id=\"morph-navbar-container\">\n        <a href=\"#\" class=\"morph-navbar-item\">Home</a>\n        <a href=\"#about\" class=\"morph-navbar-item\">About</a>\n        <a href=\"#services\" class=\"morph-navbar-item\">Services</a>\n        <a href=\"#portfolio\" class=\"morph-navbar-item\">Portfolio</a>\n        <a href=\"#contact\" class=\"morph-navbar-item\">Contact</a>\n      </div>\n    </nav>\n  </body>\n\n  <script type=\"module\" src=\"script.js\"></script>\n</html>\n",
      "type": "registry:file",
      "target": "~/morph-navbar/index.html"
    },
    {
      "path": "registry/html/atlasui/morph-navbar/style.css",
      "content": ":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\n* {\n  margin: 0;\n  padding: 0;\n  box-sizing: border-box;\n}\n\nbody {\n  background-color: var(--background);\n}\n\n#morph-navbar {\n  position: relative;\n  margin-inline: auto;\n  display: flex;\n  height: 3.5rem;\n  max-width: fit-content;\n  border-radius: 9999px;\n  background: linear-gradient(180deg, #404040, #262626);\n  padding: 0.25rem;\n  color: white;\n  box-shadow:\n    0 8px 32px rgba(0, 0, 0, 0.6),\n    0 2px 8px rgba(0, 0, 0, 0.4),\n    inset 0 1px 0 rgba(255, 255, 255, 0.1),\n    inset 0 -1px 2px rgba(0, 0, 0, 0.5);\n}\n\n#morph-navbar-container {\n  position: relative;\n  display: flex;\n  height: 100%;\n  width: 100%;\n  column-gap: 0.25rem;\n  border-radius: 9999px;\n  background: linear-gradient(180deg, #262626, #171717);\n  padding: 0.25rem;\n  box-shadow:\n    inset 0 2px 4px rgba(0, 0, 0, 0.8),\n    inset 0 -1px 2px rgba(255, 255, 255, 0.05);\n}\n\n.morph-navbar-item {\n  position: relative;\n  z-index: 20;\n  display: flex;\n  align-items: center;\n  justify-content: center;\n  border-radius: 9999px;\n  padding: 0.75rem 1rem;\n  font-size: 0.75rem;\n  line-height: 1.33;\n  font-weight: 500;\n  font-family: \"Inter\", sans-serif;\n  text-decoration: none;\n  color: white;\n  transition: color 0.2s ease;\n}\n\n.morph-navbar-item.is-active {\n  color: #171717;\n}\n\n.active-pill {\n  position: absolute;\n  top: 4px;\n  z-index: 5;\n  height: 2.5rem;\n  border-radius: 9999px;\n  background: linear-gradient(180deg, #e8e8e8, #c0c0c0, #a0a0a0);\n  box-shadow:\n    0 2px 8px rgba(0, 0, 0, 0.4),\n    0 1px 2px rgba(0, 0, 0, 0.3),\n    inset 0 2px 0 rgba(255, 255, 255, 0.5),\n    inset 0 -2px 0 rgba(255, 255, 255, 0.3),\n    inset 0 -8px 16px rgba(255, 255, 255, 0.2),\n    inset 0 0 0 1px rgba(255, 255, 255, 0.4),\n    inset 0 1px 4px rgba(0, 0, 0, 0.1);\n}\n\n.hover-pill {\n  position: absolute;\n  height: 2.5rem;\n  border-radius: 9999px;\n  background: linear-gradient(\n    to bottom,\n    rgba(255, 255, 255, 0.1),\n    rgba(255, 255, 255, 0.05)\n  );\n  box-shadow: inset 0 1px 2px rgba(255, 255, 255, 0.2);\n  backdrop-filter: blur(8px);\n}\n\n@media (min-width: 768px) {\n  #morph-navbar {\n    height: 4rem;\n  }\n\n  .morph-navbar-item {\n    padding: 0.75rem 1.75rem;\n    font-size: 1rem;\n    line-height: 1.5;\n  }\n\n  .active-pill {\n    height: 3rem;\n  }\n\n  .hover-pill {\n    height: 3rem;\n  }\n}\n",
      "type": "registry:file",
      "target": "~/morph-navbar/style.css"
    },
    {
      "path": "registry/html/atlasui/morph-navbar/script.js",
      "content": "import { animate } from \"motion\";\n\nconst navbar = document.getElementById(\"morph-navbar-container\");\nconst items = Array.from(document.querySelectorAll(\".morph-navbar-item\"));\n\nconst activePill = document.createElement(\"span\");\nactivePill.className = \"active-pill\";\n\nconst hoverPill = document.createElement(\"span\");\nhoverPill.className = \"hover-pill\";\n\nnavbar.appendChild(activePill);\nnavbar.appendChild(hoverPill);\n\nconst PADDING_OFFSET = 4;\n\nfunction getRelativeRect(el) {\n  const elRect = el.getBoundingClientRect();\n  const containerRect = navbar.getBoundingClientRect();\n\n  return {\n    left: elRect.left - containerRect.left,\n    width: elRect.width,\n  };\n}\n\nfunction normalizeHref(href) {\n  try {\n    const url = new URL(href, window.location.origin);\n    return url.pathname + url.hash;\n  } catch {\n    return href;\n  }\n}\n\nfunction getActiveItemFromURL() {\n  const current = window.location.pathname + window.location.hash;\n\n  return items.find((item) => {\n    const itemHref = normalizeHref(item.getAttribute(\"href\"));\n    return current === itemHref || window.location.hash === itemHref;\n  });\n}\n\nfunction moveActivePill(el, immediate = false) {\n  if (!el) return;\n\n  const { left, width } = getRelativeRect(el);\n\n  el.classList.add(\"is-active\");\n  items.forEach((i) => i !== el && i.classList.remove(\"is-active\"));\n\n  animate(\n    activePill,\n    { left: `${left}px`, width: `${width}px` },\n    immediate\n      ? { duration: 0 }\n      : { type: \"spring\", stiffness: 400, damping: 33 },\n  );\n}\n\nfunction moveHoverPill(el) {\n  const { left, width } = getRelativeRect(el);\n\n  animate(\n    hoverPill,\n    { left: `${left}px`, width: `${width}px` },\n    { type: \"spring\", stiffness: 400, damping: 33 },\n  );\n}\n\nfunction resetHoverPill() {\n  animate(\n    hoverPill,\n    {\n      left: `${PADDING_OFFSET}px`,\n      width: `calc(100% - ${PADDING_OFFSET * 2}px)`,\n    },\n    { type: \"spring\", stiffness: 400, damping: 33 },\n  );\n}\n\nitems.forEach((item) => {\n  item.addEventListener(\"mouseenter\", () => moveHoverPill(item));\n\n  item.addEventListener(\"mouseleave\", resetHoverPill);\n\n  item.addEventListener(\"click\", () => {\n    moveActivePill(item);\n  });\n});\n\nwindow.addEventListener(\"load\", () => {\n  const activeItem = getActiveItemFromURL();\n\n  if (activeItem) {\n    moveActivePill(activeItem, true);\n  } else if (items[0]) {\n    moveActivePill(items[0], true);\n  }\n\n  resetHoverPill();\n});\n",
      "type": "registry:file",
      "target": "~/morph-navbar/script.js"
    }
  ],
  "meta": {
    "framework": "html"
  },
  "type": "registry:file"
}