Menu

Preview

Live interactive preview.

Installation

Add this component to your project using the CLI:

terminal
npx -y vui-registry-cli-v1@latest add minimal-rich-footer

Source Code

minimal-rich-footer.tsx
"use client";

import React, { useState } from "react";
import { ArrowUpRight } from "lucide-react";

export default function MinimalRichFooter() {
  const [hoveredLink, setHoveredLink] = useState<string | null>(null);

  const links = [
    { label: "Components", group: "Platform" },
    { label: "Templates", group: "Platform" },
    { label: "Pricing", group: "Platform" },
    { label: "Showcase", group: "Platform" },
    { label: "Documentation", group: "Developers" },
    { label: "API Reference", group: "Developers" },
    { label: "Changelog", group: "Developers" },
    { label: "GitHub", group: "Developers" },
    { label: "Privacy Policy", group: "Legal" },
    { label: "Terms of Service", group: "Legal" },
    { label: "Cookie Policy", group: "Legal" },
  ];

  return (
    <footer className="w-full bg-[#050505] text-white overflow-hidden relative selection:bg-white/20 selection:text-white">
      {/* Absolute top thin border */}
      <div className="absolute top-0 left-0 w-full h-[1px] bg-gradient-to-r from-transparent via-white/20 to-transparent" />

      {/* Grainy Noise Overlay - Essential for premium Vercel/Linear feel */}
      <div className="absolute inset-0 bg-[url('https://grainy-gradients.vercel.app/noise.svg')] opacity-20 mix-blend-overlay pointer-events-none" />
      
      {/* Subtle Glows */}
      <div className="absolute top-0 left-1/2 -translate-x-1/2 w-[800px] h-[400px] bg-white/[0.03] rounded-full blur-[120px] pointer-events-none" />

      <div className="max-w-7xl mx-auto px-6 pt-32 pb-12 flex flex-col gap-16 relative z-10">
        
        {/* Links Grid */}
        <div className="grid grid-cols-2 md:grid-cols-4 gap-12 md:gap-4">
          <div className="col-span-2 md:col-span-1 flex flex-col justify-between">
            <div className="flex flex-col gap-4">
              <h3 className="text-sm font-bold text-white tracking-tight">Stay updated</h3>
              <p className="text-sm text-white/50 leading-relaxed max-w-[240px]">
                Subscribe to our newsletter for the latest component releases.
              </p>
              <div className="relative mt-2 max-w-[240px]">
                <input 
                  type="email" 
                  placeholder="Email address" 
                  className="w-full bg-white/5 border border-white/10 rounded-lg px-4 py-2.5 text-sm text-white placeholder:text-white/30 focus:outline-none focus:ring-1 focus:ring-white/30 transition-all"
                />
                <button className="absolute right-1 top-1 bottom-1 px-3 bg-white text-black rounded-md text-xs font-semibold hover:bg-white/90 transition-colors">
                  Join
                </button>
              </div>
            </div>
          </div>
          
          {["Platform", "Developers", "Legal"].map((group) => (
            <div key={group} className="flex flex-col gap-6">
              <h4 className="text-xs font-bold text-white/40 uppercase tracking-[0.2em]">{group}</h4>
              <div className="flex flex-col gap-3">
                {links.filter(l => l.group === group).map(link => (
                  <a 
                    key={link.label} 
                    href="#" 
                    onMouseEnter={() => setHoveredLink(link.label)}
                    onMouseLeave={() => setHoveredLink(null)}
                    className="group flex items-center gap-2 text-sm font-medium text-white/70 hover:text-white transition-colors w-fit"
                  >
                    <span className="relative">
                      {link.label}
                      <span className="absolute left-0 bottom-0 w-full h-[1px] bg-white origin-left scale-x-0 group-hover:scale-x-100 transition-transform duration-300 ease-out" />
                    </span>
                    <ArrowUpRight className={`w-3 h-3 text-white/40 transition-all duration-300 ${hoveredLink === link.label ? "opacity-100 translate-x-0.5 -translate-y-0.5" : "opacity-0 -translate-x-2 translate-y-2"}`} />
                  </a>
                ))}
              </div>
            </div>
          ))}
        </div>

        {/* Bottom */}
        <div className="flex flex-col md:flex-row justify-between items-center gap-4 text-xs font-medium text-white/40 pt-8 border-t border-white/10">
          <p>© {new Date().getFullYear()} Velocity UI. All rights reserved.</p>
          <div className="flex gap-8">
            {["Twitter", "LinkedIn", "GitHub"].map((social) => (
              <a key={social} href="#" className="hover:text-white transition-colors">
                {social}
              </a>
            ))}
          </div>
        </div>

      </div>
    </footer>
  );
}

Dependencies

  • framer-motion: latest