{"$schema":"https://ui.shadcn.com/schema/registry-item.json","name":"0n-gradient-headline","type":"registry:component","title":"Gradient Headline","description":"The brand-gradient h1 pattern shipped across the 0n ecosystem. Paints text with an animated multi-stop linear gradient. Built-in presets for sxowebsite, 0nmcp, 0ncore, verifiedsxo — or pass your own stops.","dependencies":[],"registryDependencies":[],"files":[{"path":"components/0n/gradient-headline.tsx","type":"registry:component","target":"components/0n/gradient-headline.tsx","content":"'use client'\n\n/**\n * 0n Gradient Headline — the brand-gradient h1 pattern.\n *\n * A drop-in headline component that paints text with an animated multi-stop\n * linear gradient. Shipped across the 0n ecosystem (sxowebsite.com,\n * 0nmcp.com, 0ncore.com) for hero sections and post-purchase moments.\n *\n * Install:\n *   npx shadcn@latest add https://0nmcp.com/r/0n-gradient-headline.json\n *\n * Use:\n *   <GradientHeadline>Free SXO Scan.</GradientHeadline>\n *\n *   <GradientHeadline as=\"h2\" preset=\"0n\" animate>\n *     Stop building workflows. Start describing outcomes.\n *   </GradientHeadline>\n *\n *   <GradientHeadline preset=\"custom\" stops={['#10b981', '#06b6d4', '#8b5cf6']}>\n *     Your brand, your gradient.\n *   </GradientHeadline>\n */\n\nimport type { ElementType, ReactNode, CSSProperties } from 'react'\n\nconst PRESETS = {\n  /** sxowebsite.com — violet → indigo → cyan → ice */\n  sxo: ['#8B5CF6', '#6366F1', '#06B6D4', '#a5f3fc'],\n  /** 0nmcp.com — green → teal → violet */\n  '0n': ['#6EE05A', '#14b8a6', '#8b5cf6'],\n  /** 0ncore.com — green → cyan → lavender */\n  '0ncore': ['#7ed957', '#00d4ff', '#a78bfa'],\n  /** verifiedsxo.com — emerald → teal */\n  verified: ['#10b981', '#0d9488'],\n} as const\n\ntype Preset = keyof typeof PRESETS | 'custom'\n\nconst SIZE_CLASS = {\n  sm: 'text-2xl sm:text-3xl',\n  md: 'text-3xl sm:text-4xl lg:text-5xl',\n  lg: 'text-4xl sm:text-5xl lg:text-6xl',\n  xl: 'text-5xl sm:text-6xl lg:text-7xl',\n} as const\n\nexport interface GradientHeadlineProps {\n  /** Tag to render — defaults to h1. Use h2/h3 for section heads. */\n  as?: ElementType\n  /** Built-in palette, or 'custom' to supply your own stops. */\n  preset?: Preset\n  /** Custom stop colors (only used when preset='custom'). */\n  stops?: readonly string[]\n  /** Gradient angle in degrees. Default 135. */\n  angle?: number\n  /** Size preset for the type scale. */\n  size?: keyof typeof SIZE_CLASS\n  /** Animate the gradient position. Subtle, infinite, easing. */\n  animate?: boolean\n  /** Forwarded className. */\n  className?: string\n  children: ReactNode\n}\n\nexport function GradientHeadline({\n  as: Tag = 'h1',\n  preset = 'sxo',\n  stops,\n  angle = 135,\n  size = 'lg',\n  animate = false,\n  className = '',\n  children,\n}: GradientHeadlineProps) {\n  const palette =\n    preset === 'custom'\n      ? stops ?? PRESETS.sxo\n      : PRESETS[preset]\n\n  const stopList = palette\n    .map((c, i) => `${c} ${Math.round((i / Math.max(palette.length - 1, 1)) * 100)}%`)\n    .join(', ')\n\n  const style: CSSProperties = {\n    backgroundImage: `linear-gradient(${angle}deg, ${stopList})`,\n    backgroundSize: animate ? '200% 200%' : '100% 100%',\n    animation: animate ? 'on-gradient-shift 6s ease infinite' : undefined,\n  }\n\n  return (\n    <Tag\n      className={`font-extrabold tracking-tight leading-[1.05] ${SIZE_CLASS[size]} ${className}`}\n    >\n      <span className=\"bg-clip-text text-transparent\" style={style}>\n        {children}\n      </span>\n      {animate ? (\n        <style>{`\n          @keyframes on-gradient-shift {\n            0%, 100% { background-position: 0% 50%; }\n            50% { background-position: 100% 50%; }\n          }\n        `}</style>\n      ) : null}\n    </Tag>\n  )\n}\n\nGradientHeadline.PRESETS = PRESETS\n"}]}