{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "navbar-pill-glide",
  "type": "registry:block",
  "title": "Navbar Pill Glide",
  "description": "A navbar with its links in a frosted pill, where a soft highlight glides to whichever link you point at and a lime line along the pill tracks how far down the page you are. The logo dot circles its ring as you scroll, the bar slips away going down, and on narrow screens a round toggle wipes the full menu open from where it sits, with large rolling links and a poster that swaps as you hover them.",
  "dependencies": [
    "gsap",
    "@gsap/react"
  ],
  "registryDependencies": [],
  "cssVars": {
    "theme": {}
  },
  "files": [
    {
      "path": "components/tweenui/navbar-pill-glide.tsx",
      "type": "registry:component",
      "target": "components/tweenui/navbar-pill-glide.tsx",
      "content": "'use client';\n\nimport {\n  useCallback,\n  useEffect,\n  useId,\n  useRef,\n  useState,\n  type ComponentPropsWithoutRef,\n  type ReactNode,\n} from 'react';\nimport { useGSAP } from '@gsap/react';\nimport gsap from 'gsap';\nimport { cn } from '@/lib/utils';\n\ngsap.registerPlugin(useGSAP);\n\nconst prefersReducedMotion = () =>\n  typeof window !== 'undefined' && window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n\nexport interface NavbarPillGlideLink {\n  label: string;\n  href: string;\n  image?: string;\n}\n\nexport interface NavbarPillGlideAction {\n  label: string;\n  href: string;\n}\n\nexport type NavbarPillGlideSocialIcon = 'github' | 'x' | 'linkedin' | 'dribbble';\n\nexport interface NavbarPillGlideSocial {\n  label: string;\n  href: string;\n  icon: NavbarPillGlideSocialIcon;\n}\n\nexport interface NavbarPillGlideProps extends Omit<\n  ComponentPropsWithoutRef<'section'>,\n  'children'\n> {\n  brand?: string;\n  logo?: ReactNode;\n  homeHref?: string;\n  links?: NavbarPillGlideLink[];\n  currentHref?: string;\n  primaryAction?: NavbarPillGlideAction;\n  secondaryAction?: NavbarPillGlideAction;\n  socials?: NavbarPillGlideSocial[];\n  email?: string;\n  children?: ReactNode;\n}\n\nconst SITE = 'https://tween-ui.vercel.app';\nconst REPO = 'https://github.com/StaticMania/tween-ui';\n\nconst poster = (kind: 'block' | 'component', name: string) =>\n  `${SITE}/media/${kind}s/${name}-poster.webp`;\n\nconst DEFAULT_LINKS: NavbarPillGlideLink[] = [\n  { label: 'Home', href: '/', image: poster('block', 'gyro-gallery') },\n  { label: 'Components', href: '/components', image: poster('component', 'sliding-tabs') },\n  { label: 'Blocks', href: '/components#blocks', image: poster('block', 'shutter-slider') },\n  { label: 'Setup', href: '/installation/setup-guide', image: poster('block', 'integration-hub') },\n  { label: 'MCP', href: '/installation/mcp', image: poster('block', 'kinetic-type-ring') },\n];\n\nconst DEFAULT_PRIMARY: NavbarPillGlideAction = {\n  label: 'Get started',\n  href: '/installation/setup-guide',\n};\n\nconst DEFAULT_SECONDARY: NavbarPillGlideAction = { label: 'GitHub', href: REPO };\n\nconst DEFAULT_SOCIALS: NavbarPillGlideSocial[] = [{ label: 'GitHub', href: REPO, icon: 'github' }];\n\nconst TWEEN_MARK = (\n  <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" className=\"size-7 shrink-0\">\n    <rect width=\"24\" height=\"24\" rx=\"6\" fill=\"#045f64\" />\n    <path\n      d=\"M5 19 C 9.5 8.9, 5 5, 19 5\"\n      fill=\"none\"\n      stroke=\"#c6f56f\"\n      strokeWidth=\"2\"\n      strokeLinecap=\"round\"\n    />\n    <circle cx=\"19\" cy=\"5\" r=\"1.8\" fill=\"#c6f56f\" />\n  </svg>\n);\n\nconst CONTAINER = 'mx-auto w-full max-w-7xl px-4 sm:px-6 lg:px-8';\n\nconst HIDE_AFTER = 240;\nconst SCROLL_TOLERANCE = 6;\nconst DESKTOP_QUERY = '(min-width: 1024px)';\n\nconst EASE_OUT_EXPO = 'ease-[cubic-bezier(0.16,1,0.3,1)]';\n\nconst focusRing =\n  'focus-visible:outline-2 focus-visible:outline-offset-4 focus-visible:outline-[#c6f56f]';\n\nconst SOCIAL_PATHS: Record<NavbarPillGlideSocialIcon, ReactNode> = {\n  github: (\n    <>\n      <path d=\"M15 22v-4a4.8 4.8 0 0 0-1-3.5c3 0 6-2 6-5.5.08-1.25-.27-2.48-1-3.5.28-1.15.28-2.35 0-3.5 0 0-1 0-3 1.5-2.64-.5-5.36-.5-8 0C6 2 5 2 5 2c-.3 1.15-.3 2.35 0 3.5A5.403 5.403 0 0 0 4 9c0 3.5 3 5.5 6 5.5-.39.49-.68 1.05-.85 1.65-.17.6-.22 1.23-.15 1.85v4\" />\n      <path d=\"M9 18c-4.51 2-5-2-7-2\" />\n    </>\n  ),\n  x: (\n    <path d=\"M22 4s-.7 2.1-2 3.4c1.6 10-9.4 17.3-18 11.6 2.2.1 4.4-.6 6-2C3 15.5.5 9.6 3 5c2.2 2.6 5.6 4.1 9 4-.9-4.2 4-6.6 7-3.8 1.1 0 3-1.2 3-1.2z\" />\n  ),\n  linkedin: (\n    <>\n      <path d=\"M16 8a6 6 0 0 1 6 6v7h-4v-7a2 2 0 0 0-2-2 2 2 0 0 0-2 2v7h-4v-7a6 6 0 0 1 6-6z\" />\n      <rect width=\"4\" height=\"12\" x=\"2\" y=\"9\" />\n      <circle cx=\"4\" cy=\"4\" r=\"2\" />\n    </>\n  ),\n  dribbble: (\n    <>\n      <circle cx=\"12\" cy=\"12\" r=\"10\" />\n      <path d=\"M19.13 5.09C15.22 9.14 10 10.44 2.25 10.94\" />\n      <path d=\"M21.75 12.84c-6.62-1.41-12.14 1-16.38 6.32\" />\n      <path d=\"M8.56 2.75c4.37 6 6 9.42 8 17.72\" />\n    </>\n  ),\n};\n\nconst cleanHref = (href: string) => href.split(/[?#]/)[0]?.replace(/\\/+$/, '') || '/';\n\nconst isCurrentHref = (href: string, currentHref: string) => {\n  const target = cleanHref(href);\n  const current = cleanHref(currentHref);\n  if (target === '/') return current === '/';\n  return current === target || current.startsWith(`${target}/`);\n};\n\nconst isExternal = (href: string) => /^https?:/.test(href);\n\nconst externalProps = (href: string) =>\n  isExternal(href) ? { target: '_blank', rel: 'noopener noreferrer' } : {};\n\nconst RollText = ({ text, className }: { text: string; className?: string }) => {\n  return (\n    <>\n      <span\n        aria-hidden=\"true\"\n        className={cn('inline-flex h-[1.2em] overflow-hidden leading-[1.2em]', className)}\n      >\n        {Array.from(text).map((char, index) => (\n          <span\n            key={`${char}-${index}`}\n            className={cn(\n              'inline-block whitespace-pre [text-shadow:0_1.2em_currentColor]',\n              'transition-transform duration-[550ms] group-hover/roll:-translate-y-full group-focus-visible/roll:-translate-y-full',\n              EASE_OUT_EXPO,\n              'motion-reduce:transition-none motion-reduce:group-hover/roll:translate-y-0 motion-reduce:group-focus-visible/roll:translate-y-0'\n            )}\n            style={{ transitionDelay: `${index * 16}ms` }}\n          >\n            {char}\n          </span>\n        ))}\n      </span>\n      <span className=\"sr-only\">{text}</span>\n    </>\n  );\n};\n\nconst ArrowSwap = () => {\n  const arrowClass = cn(\n    'col-start-1 row-start-1 size-4 transition-transform duration-[550ms] motion-reduce:transition-none',\n    EASE_OUT_EXPO\n  );\n  const arrowPath = <path d=\"M7 17 17 7M7 7h10v10\" />;\n\n  return (\n    <span aria-hidden=\"true\" className=\"grid size-4 overflow-hidden\">\n      {[\n        'group-hover/roll:translate-x-[110%] group-hover/roll:-translate-y-[110%]',\n        '-translate-x-[110%] translate-y-[110%] group-hover/roll:translate-0',\n      ].map((motion) => (\n        <svg\n          key={motion}\n          viewBox=\"0 0 24 24\"\n          fill=\"none\"\n          stroke=\"currentColor\"\n          strokeWidth=\"2\"\n          strokeLinecap=\"round\"\n          strokeLinejoin=\"round\"\n          className={cn(arrowClass, motion)}\n        >\n          {arrowPath}\n        </svg>\n      ))}\n    </span>\n  );\n};\n\nconst ActionLink = ({\n  action,\n  variant,\n  className,\n}: {\n  action: NavbarPillGlideAction;\n  variant: 'primary' | 'outline';\n  className?: string;\n}) => {\n  return (\n    <a\n      href={action.href}\n      {...externalProps(action.href)}\n      className={cn(\n        'group/roll relative isolate inline-flex h-11 items-center justify-center gap-3 overflow-hidden rounded-full px-5 text-[15px] font-medium whitespace-nowrap',\n        'transition-[scale,color,border-color] duration-500 active:scale-[0.96] motion-reduce:transition-none',\n        EASE_OUT_EXPO,\n        focusRing,\n        variant === 'primary'\n          ? 'bg-[#c6f56f] text-[#03110f]'\n          : 'border border-[#9fd4d6]/25 text-[#e8f3f2] hover:border-[#e8f3f2] hover:text-[#03110f]',\n        className\n      )}\n    >\n      <span\n        aria-hidden=\"true\"\n        className={cn(\n          'pointer-events-none absolute top-1/2 left-1/2 -z-10 aspect-square w-[260%] -translate-1/2 scale-0 rounded-full bg-[#e8f3f2] transition-transform duration-[650ms] group-hover/roll:scale-100 motion-reduce:transition-none',\n          EASE_OUT_EXPO\n        )}\n      />\n      <RollText text={action.label} />\n      {variant === 'primary' ? <ArrowSwap /> : null}\n    </a>\n  );\n};\n\nconst SamplePage = ({ linkCount }: { linkCount: number }) => {\n  const headingId = useId();\n\n  return (\n    <section\n      aria-labelledby={headingId}\n      className=\"relative isolate flex h-full min-h-full flex-col overflow-hidden pt-24 pb-10 sm:pt-28 sm:pb-14\"\n    >\n      <span\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute inset-0 -z-10 bg-[repeating-linear-gradient(90deg,rgb(159_212_214/0.06)_0_1px,transparent_1px_48px),repeating-linear-gradient(0deg,rgb(159_212_214/0.045)_0_1px,transparent_1px_48px)] [mask-image:radial-gradient(ellipse_75%_65%_at_50%_40%,black,transparent)]\"\n      />\n      <span\n        aria-hidden=\"true\"\n        className=\"pointer-events-none absolute inset-0 -z-10 bg-[radial-gradient(38%_46%_at_50%_0%,rgb(198_245_111/0.12),transparent_70%),radial-gradient(55%_60%_at_92%_100%,rgb(4_95_100/0.6),transparent_72%),radial-gradient(45%_50%_at_6%_90%,rgb(4_95_100/0.35),transparent_70%)]\"\n      />\n      <div className={cn(CONTAINER, 'flex flex-1 items-center')}>\n        <div className=\"mx-auto max-w-4xl text-center\">\n          <p className=\"inline-flex items-center gap-2.5 rounded-full bg-white/[0.04] py-2 pr-4 pl-2.5 text-[10px] leading-none font-medium tracking-[0.2em] text-[#9fd4d6] uppercase ring-1 ring-white/10\">\n            <span\n              aria-hidden=\"true\"\n              className=\"size-2 shrink-0 rounded-full bg-[#c6f56f] shadow-[0_0_5px_#c6f56f,0_0_12px_#c6f56f]\"\n            />\n            {linkCount} links in one pill\n          </p>\n          <h2\n            id={headingId}\n            className=\"mt-8 text-[40px] leading-[0.98] font-medium tracking-[-0.045em] text-balance text-[#e8f3f2] sm:text-6xl md:text-7xl lg:text-[80px]\"\n          >\n            Point at a link.\n            <br />\n            The pill <span className=\"text-[#c6f56f]\">follows.</span>\n          </h2>\n          <p className=\"mx-auto mt-6 max-w-[34rem] text-[15px] leading-relaxed text-pretty text-[#e8f3f2]/60 sm:mt-8 sm:text-base md:text-lg\">\n            Sweep across the links above and the highlight glides between them. On a narrower screen\n            the round button opens the full menu from where it sits.\n          </p>\n        </div>\n      </div>\n    </section>\n  );\n};\n\nconst NavbarPillGlide = ({\n  brand = 'Tween UI',\n  logo = TWEEN_MARK,\n  homeHref = '/',\n  links = DEFAULT_LINKS,\n  currentHref = '/',\n  primaryAction = DEFAULT_PRIMARY,\n  secondaryAction = DEFAULT_SECONDARY,\n  socials = DEFAULT_SOCIALS,\n  email,\n  children,\n  className,\n  ...props\n}: NavbarPillGlideProps) => {\n  const [isOpen, setIsOpen] = useState(false);\n  const [previewHref, setPreviewHref] = useState(links[0]?.href ?? '');\n  const menuId = useId();\n\n  const rootRef = useRef<HTMLElement>(null);\n  const barRef = useRef<HTMLDivElement>(null);\n  const pillRef = useRef<HTMLDivElement>(null);\n  const highlightRef = useRef<HTMLSpanElement>(null);\n  const progressRef = useRef<HTMLSpanElement>(null);\n  const toggleRef = useRef<HTMLButtonElement>(null);\n  const menuRef = useRef<HTMLDivElement>(null);\n  const scrollerRef = useRef<HTMLDivElement>(null);\n  const timelineRef = useRef<gsap.core.Timeline | null>(null);\n  const isOpenRef = useRef(false);\n\n  const pillLinks = links.filter((link) => cleanHref(link.href) !== cleanHref(homeHref));\n  const previews = links.filter((link): link is Required<NavbarPillGlideLink> =>\n    Boolean(link.image)\n  );\n\n  const { contextSafe } = useGSAP(\n    () => {\n      const bar = barRef.current;\n      if (!bar || prefersReducedMotion()) return;\n      gsap.fromTo(\n        bar.querySelectorAll('[data-nav-item]'),\n        { autoAlpha: 0, y: -24 },\n        { autoAlpha: 1, y: 0, duration: 1, ease: 'expo.out', stagger: 0.08, clearProps: 'all' }\n      );\n    },\n    { scope: rootRef }\n  );\n\n  const glideTo = contextSafe((link: HTMLElement) => {\n    const pill = pillRef.current;\n    const highlight = highlightRef.current;\n    if (!pill || !highlight) return;\n    const box = link.getBoundingClientRect();\n    const base = pill.getBoundingClientRect();\n    const isHidden = Number(gsap.getProperty(highlight, 'opacity')) === 0;\n    gsap.to(highlight, {\n      x: box.left - base.left,\n      width: box.width,\n      opacity: 1,\n      duration: isHidden || prefersReducedMotion() ? 0 : 0.55,\n      ease: 'expo.out',\n    });\n  });\n\n  const fadeHighlight = contextSafe(() => {\n    gsap.to(highlightRef.current, { opacity: 0, duration: 0.35, ease: 'power2.out' });\n  });\n\n  const animateMenu = contextSafe((open: boolean) => {\n    const root = rootRef.current;\n    const menu = menuRef.current;\n    const toggle = toggleRef.current;\n    if (!root || !menu || !toggle) return;\n    const rootBox = root.getBoundingClientRect();\n    const toggleBox = toggle.getBoundingClientRect();\n    const at = `${toggleBox.left - rootBox.left + toggleBox.width / 2}px ${toggleBox.top - rootBox.top + toggleBox.height / 2}px`;\n    const items = menu.querySelectorAll('[data-menu-link]');\n    const meta = menu.querySelector('[data-menu-meta]');\n    timelineRef.current?.kill();\n\n    if (prefersReducedMotion()) {\n      gsap.set(menu, {\n        visibility: open ? 'visible' : 'hidden',\n        clipPath: open ? 'none' : `circle(0% at ${at})`,\n      });\n      gsap.set(items, { yPercent: 0 });\n      gsap.set(meta, { opacity: 1, y: 0 });\n      return;\n    }\n\n    timelineRef.current = open\n      ? gsap\n          .timeline()\n          .set(menu, { visibility: 'visible' })\n          .fromTo(\n            menu,\n            { clipPath: `circle(0% at ${at})` },\n            { clipPath: `circle(150% at ${at})`, duration: 1, ease: 'expo.inOut' }\n          )\n          .fromTo(\n            items,\n            { yPercent: 110 },\n            { yPercent: 0, duration: 0.9, ease: 'expo.out', stagger: 0.06 },\n            0.35\n          )\n          .fromTo(\n            meta,\n            { opacity: 0, y: 20 },\n            { opacity: 1, y: 0, duration: 0.6, ease: 'power3.out' },\n            0.6\n          )\n      : gsap\n          .timeline()\n          .to(items, { yPercent: -110, duration: 0.45, ease: 'power3.in', stagger: 0.03 })\n          .to(menu, { clipPath: `circle(0% at ${at})`, duration: 0.8, ease: 'expo.inOut' }, 0.15)\n          .set(menu, { visibility: 'hidden' });\n  });\n\n  const setOpen = useCallback(\n    (open: boolean) => {\n      if (open === isOpenRef.current) return;\n      isOpenRef.current = open;\n      setIsOpen(open);\n      animateMenu(open);\n      if (open) gsap.to(barRef.current, { yPercent: 0, duration: 0.8, ease: 'expo.out' });\n    },\n    [animateMenu]\n  );\n\n  useEffect(() => {\n    const scroller = scrollerRef.current;\n    const bar = barRef.current;\n    const progress = progressRef.current;\n    if (!scroller || !bar || !progress) return;\n    let lastY = scroller.scrollTop;\n    let isHidden = false;\n\n    const handleScroll = () => {\n      const y = scroller.scrollTop;\n      const room = scroller.scrollHeight - scroller.clientHeight;\n      const ratio = room > 0 ? y / room : 0;\n      const isQuiet = prefersReducedMotion();\n      gsap.to(progress, { scaleX: ratio, duration: isQuiet ? 0 : 0.4, ease: 'power2.out' });\n\n      const delta = y - lastY;\n      if (Math.abs(delta) < SCROLL_TOLERANCE) return;\n      lastY = y;\n      const shouldHide = delta > 0 && y > HIDE_AFTER && !isOpenRef.current;\n      if (shouldHide === isHidden) return;\n      isHidden = shouldHide;\n      gsap.to(bar, {\n        yPercent: isHidden ? -130 : 0,\n        duration: isQuiet ? 0 : isHidden ? 0.5 : 0.8,\n        ease: isHidden ? 'power3.in' : 'expo.out',\n      });\n    };\n\n    scroller.addEventListener('scroll', handleScroll, { passive: true });\n    return () => scroller.removeEventListener('scroll', handleScroll);\n  }, []);\n\n  useEffect(() => {\n    if (!isOpen) return;\n    const desktop = window.matchMedia(DESKTOP_QUERY);\n    const handleKeyDown = (event: KeyboardEvent) => {\n      if (event.key !== 'Escape') return;\n      setOpen(false);\n      toggleRef.current?.focus();\n    };\n    const handleDesktop = (event: MediaQueryListEvent) => {\n      if (event.matches) setOpen(false);\n    };\n    document.addEventListener('keydown', handleKeyDown);\n    desktop.addEventListener('change', handleDesktop);\n    return () => {\n      document.removeEventListener('keydown', handleKeyDown);\n      desktop.removeEventListener('change', handleDesktop);\n    };\n  }, [isOpen, setOpen]);\n\n  return (\n    <section\n      ref={rootRef}\n      aria-label={`${brand} site`}\n      className={cn(\n        'relative isolate h-svh min-h-[560px] w-full overflow-hidden bg-[#03110f] text-[#e8f3f2]',\n        className\n      )}\n      {...props}\n    >\n      <header className=\"pointer-events-none absolute inset-x-0 top-0 z-30\">\n        <div ref={barRef} className={cn(CONTAINER, 'flex h-20 items-center justify-between gap-6')}>\n          <a\n            href={homeHref}\n            data-nav-item=\"\"\n            aria-label={`${brand} home`}\n            className={cn(\n              'group/roll pointer-events-auto inline-flex items-center gap-2.5 rounded-full text-[#e8f3f2]',\n              focusRing\n            )}\n          >\n            {logo}\n            <RollText text={brand} className=\"text-lg font-semibold tracking-tight\" />\n          </a>\n\n          {pillLinks.length > 0 ? (\n            <nav\n              aria-label=\"Primary\"\n              data-nav-item=\"\"\n              className=\"pointer-events-auto hidden lg:block\"\n            >\n              <div\n                ref={pillRef}\n                onMouseLeave={fadeHighlight}\n                className=\"relative rounded-full border border-[#9fd4d6]/15 bg-[#071d1b]/70 p-1 backdrop-blur-xl\"\n              >\n                <span\n                  ref={highlightRef}\n                  aria-hidden=\"true\"\n                  className=\"absolute inset-y-1 left-0 rounded-full bg-[#e8f3f2]/10 opacity-0\"\n                />\n                <ul className=\"relative flex items-center\">\n                  {pillLinks.map((link) => {\n                    const isCurrent = isCurrentHref(link.href, currentHref);\n                    return (\n                      <li key={`${link.label}-${link.href}`}>\n                        <a\n                          href={link.href}\n                          {...externalProps(link.href)}\n                          aria-current={isCurrent ? 'page' : undefined}\n                          onMouseEnter={(event) => glideTo(event.currentTarget)}\n                          onFocus={(event) => glideTo(event.currentTarget)}\n                          onBlur={fadeHighlight}\n                          className={cn(\n                            'group/roll flex h-10 items-center rounded-full px-4 text-sm font-medium transition-colors duration-300 hover:text-[#e8f3f2] focus-visible:outline-2 focus-visible:outline-[#c6f56f]',\n                            isCurrent ? 'text-[#e8f3f2]' : 'text-[#9fd4d6]/70'\n                          )}\n                        >\n                          <RollText text={link.label} />\n                        </a>\n                      </li>\n                    );\n                  })}\n                </ul>\n                <span\n                  ref={progressRef}\n                  aria-hidden=\"true\"\n                  className=\"absolute inset-x-6 -bottom-px h-px origin-left scale-x-0 bg-[#c6f56f]\"\n                />\n              </div>\n            </nav>\n          ) : null}\n\n          <div data-nav-item=\"\" className=\"pointer-events-auto flex items-center gap-2\">\n            <ActionLink\n              action={secondaryAction}\n              variant=\"outline\"\n              className=\"hidden xl:inline-flex\"\n            />\n            <ActionLink action={primaryAction} variant=\"primary\" className=\"max-[400px]:px-4\" />\n            <button\n              ref={toggleRef}\n              type=\"button\"\n              aria-label={isOpen ? 'Close menu' : 'Open menu'}\n              aria-expanded={isOpen}\n              aria-controls={menuId}\n              onClick={() => setOpen(!isOpenRef.current)}\n              className={cn(\n                'grid size-11 cursor-pointer place-items-center rounded-full border border-[#9fd4d6]/15 bg-[#071d1b]/70 backdrop-blur-xl lg:hidden',\n                focusRing\n              )}\n            >\n              <span aria-hidden=\"true\" className=\"relative block h-3 w-5\">\n                <span\n                  className={cn(\n                    'absolute inset-x-0 top-0 h-px bg-[#e8f3f2] transition-transform duration-500 motion-reduce:transition-none',\n                    EASE_OUT_EXPO,\n                    isOpen && 'translate-y-[5.5px] rotate-45'\n                  )}\n                />\n                <span\n                  className={cn(\n                    'absolute inset-x-0 bottom-0 h-px bg-[#e8f3f2] transition-transform duration-500 motion-reduce:transition-none',\n                    EASE_OUT_EXPO,\n                    isOpen && '-translate-y-[5.5px] -rotate-45'\n                  )}\n                />\n              </span>\n            </button>\n          </div>\n        </div>\n      </header>\n\n      <div\n        ref={menuRef}\n        id={menuId}\n        inert={!isOpen}\n        className=\"invisible absolute inset-0 z-20 bg-[#03110f] [clip-path:circle(0%_at_100%_0%)]\"\n      >\n        <div className={cn(CONTAINER, 'grid h-full grid-cols-1 gap-10 pt-28 pb-8 md:grid-cols-12')}>\n          <nav aria-label=\"Menu\" className=\"flex min-h-0 flex-col justify-between md:col-span-7\">\n            <ul className=\"flex flex-col\">\n              {links.map((link) => (\n                <li key={`${link.label}-${link.href}`} className=\"overflow-hidden\">\n                  <a\n                    href={link.href}\n                    {...externalProps(link.href)}\n                    data-menu-link=\"\"\n                    aria-current={isCurrentHref(link.href, currentHref) ? 'page' : undefined}\n                    onMouseEnter={() => setPreviewHref(link.href)}\n                    onFocus={() => setPreviewHref(link.href)}\n                    className={cn(\n                      'group/roll flex items-baseline py-1 text-[clamp(2.5rem,11vw,5.5rem)] leading-none font-bold tracking-[-0.04em] text-[#e8f3f2] aria-[current=page]:text-[#c6f56f]',\n                      focusRing\n                    )}\n                  >\n                    <RollText text={link.label} />\n                  </a>\n                </li>\n              ))}\n            </ul>\n            <div data-menu-meta=\"\" className=\"flex flex-wrap items-center gap-3\">\n              {socials.map((social) => (\n                <a\n                  key={social.href}\n                  href={social.href}\n                  target=\"_blank\"\n                  rel=\"noopener noreferrer\"\n                  aria-label={`${brand} on ${social.label}`}\n                  className={cn(\n                    'grid size-11 place-items-center rounded-full border border-[#9fd4d6]/15 text-[#9fd4d6]/70 transition-colors duration-300 hover:border-[#e8f3f2] hover:text-[#e8f3f2]',\n                    focusRing\n                  )}\n                >\n                  <svg\n                    aria-hidden=\"true\"\n                    viewBox=\"0 0 24 24\"\n                    fill=\"none\"\n                    stroke=\"currentColor\"\n                    strokeWidth=\"2\"\n                    strokeLinecap=\"round\"\n                    strokeLinejoin=\"round\"\n                    className=\"size-5\"\n                  >\n                    {SOCIAL_PATHS[social.icon]}\n                  </svg>\n                </a>\n              ))}\n              {email ? (\n                <a\n                  href={`mailto:${email}`}\n                  className={cn(\n                    'group/roll ml-auto rounded-xs text-sm text-[#9fd4d6]/70 transition-colors duration-300 hover:text-[#e8f3f2]',\n                    focusRing\n                  )}\n                >\n                  <RollText text={email} />\n                </a>\n              ) : null}\n            </div>\n          </nav>\n          {previews.length > 0 ? (\n            <div\n              aria-hidden=\"true\"\n              className=\"relative hidden overflow-hidden rounded-2xl border border-[#9fd4d6]/12 bg-[#071d1b] md:col-span-5 md:block\"\n            >\n              {previews.map((link) => (\n                <img\n                  key={link.href}\n                  src={link.image}\n                  alt=\"\"\n                  draggable={false}\n                  loading=\"lazy\"\n                  className={cn(\n                    'absolute inset-0 size-full object-cover transition-[opacity,scale] duration-700 motion-reduce:transition-none',\n                    EASE_OUT_EXPO,\n                    link.href === previewHref ? 'scale-100 opacity-100' : 'scale-[1.06] opacity-0'\n                  )}\n                />\n              ))}\n            </div>\n          ) : null}\n        </div>\n      </div>\n\n      <div\n        ref={scrollerRef}\n        inert={isOpen}\n        data-lenis-prevent=\"\"\n        className=\"absolute inset-0 z-10 [scrollbar-width:none] overflow-y-auto [&::-webkit-scrollbar]:hidden\"\n      >\n        {children ?? <SamplePage linkCount={pillLinks.length} />}\n      </div>\n    </section>\n  );\n};\n\nexport default NavbarPillGlide;\n"
    }
  ],
  "docs": "Docs, props and examples: https://tween-ui.vercel.app/block/navbar-pill-glide\nPass your own `links` and put your page inside as `children`; every link but home goes in the pill, and all of them fill the mobile menu."
}