{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"hover-slice-shear","type":"registry:component","title":"Slice Shear Hover","description":"Display type cut into horizontal bands that fan apart under the pointer.","dependencies":[],"registryDependencies":[],"files":[{"path":"components/viberdy/hover-slice-shear.tsx","content":"\"use client\";\n\nimport { useState } from \"react\";\n\nexport function HoverSliceShear({\n  text = \"VIBERDY\",\n  slices = 6,\n  shear = 16,\n  accentEdges = true,\n}: {\n  text?: string;\n  slices?: number;\n  shear?: number;\n  /** Tint the top and bottom bands while sheared, so the fan reads. */\n  accentEdges?: boolean;\n}) {\n  const [hovered, setHovered] = useState(false);\n\n  return (\n    <span\n      onMouseEnter={() => setHovered(true)}\n      onMouseLeave={() => setHovered(false)}\n      className=\"relative inline-block cursor-pointer select-none\"\n    >\n      {/* The one accessible copy of the string. */}\n      <span className=\"sr-only\">{text}</span>\n\n      <span aria-hidden className=\"relative block text-6xl font-black leading-none tracking-tight\">\n        {/* Invisible copy establishes the box for the absolute slices. */}\n        <span className=\"invisible block\">{text}</span>\n\n        {Array.from({ length: slices }).map((_, i) => {\n          const top = (i / slices) * 100;\n          const bottom = 100 - ((i + 1) / slices) * 100;\n          const direction = i % 2 === 0 ? 1 : -1;\n          // Ease the offset toward the vertical centre so the bands fan out\n          // instead of shearing like a uniform comb.\n          const falloff = 1 - Math.abs(i - (slices - 1) / 2) / slices;\n          const offset = hovered ? direction * shear * falloff : 0;\n\n          return (\n            <span\n              key={i}\n              className=\"absolute inset-0 block transition-transform duration-500 ease-[cubic-bezier(0.16,1,0.3,1)]\"\n              style={{\n                clipPath: \"inset(\" + top + \"% 0% \" + bottom + \"% 0%)\",\n                transform: \"translateX(\" + offset + \"px)\",\n                transitionDelay: i * 18 + \"ms\",\n                color:\n                  accentEdges && hovered && (i === 0 || i === slices - 1)\n                    ? \"#3d7bff\"\n                    : undefined,\n              }}\n            >\n              {text}\n            </span>\n          );\n        })}\n      </span>\n    </span>\n  );\n}\n","type":"registry:component","target":"components/viberdy/hover-slice-shear.tsx"}],"meta":{"tier":"free","tags":["hover","text","clip-path","display"],"href":"https://viberdy.dev/library/hover-slice-shear","aiPrompt":"Create a React + Tailwind component named HoverSliceShear — oversized display text that cuts into horizontal bands and shears apart on hover.\n\nBehavior:\n- Render the text N times (slices prop, default 6). Clip each copy to its own horizontal band with clip-path: inset(top% 0% bottom% 0%), where top = i/slices*100 and bottom = 100 - (i+1)/slices*100.\n- On hover, translate each band horizontally. Alternate the direction per band (even bands right, odd bands left).\n- Scale each band's offset by a falloff of 1 - abs(i - (slices-1)/2) / slices so bands near the vertical centre move most and the edges move least — this makes it fan rather than comb.\n- Stagger the transition-delay by about 18ms per band.\n- Use a 500ms transition with cubic-bezier(0.16, 1, 0.3, 1).\n\nAccessibility requirement (important):\n- The visible stack is duplicated text, so wrap it in aria-hidden and render exactly ONE screen-reader copy of the string in an sr-only span. Never let N copies of the word reach the accessibility tree.\n- Include one invisible (not hidden) copy in normal flow to establish the box, so the absolutely-positioned bands size themselves and no fixed height is needed.\n\nProps: text (string), slices (number), shear (number, px).\n\nOutput a single self-contained \"use client\" component.","license":"https://viberdy.dev/license"}}