feat: add robotics components and data structures
- Introduced RobotProductCard component for displaying robot details. - Added WhyUs component highlighting key reasons for choosing our robotics solutions. - Implemented CursorSpotlight for enhanced user interaction. - Created GlassPanel for a stylish UI element. - Developed MotionSection for animated section visibility. - Added PremiumButton for versatile button options. - Established data structures for industries and robots, including detailed specifications and use cases. - Included utility functions for retrieving robots by slug and category.
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
"use client";
|
||||
|
||||
import { cn } from "@/lib/cn";
|
||||
import { motion, useReducedMotion, type Variants } from "framer-motion";
|
||||
import type { ReactNode } from "react";
|
||||
|
||||
type Props = {
|
||||
eyebrow?: string;
|
||||
index?: string;
|
||||
title: ReactNode;
|
||||
/** The gold-accent phrase rendered inside the title — pass as JSX or separate prop. */
|
||||
accent?: ReactNode;
|
||||
subtitle?: ReactNode;
|
||||
align?: "left" | "center";
|
||||
className?: string;
|
||||
};
|
||||
|
||||
export function SectionHeading({
|
||||
eyebrow,
|
||||
index,
|
||||
title,
|
||||
accent,
|
||||
subtitle,
|
||||
align = "left",
|
||||
className,
|
||||
}: Props) {
|
||||
const reduce = useReducedMotion();
|
||||
const v: Variants = {
|
||||
hidden: { opacity: 0, y: reduce ? 0 : 24, filter: reduce ? "blur(0px)" : "blur(6px)" },
|
||||
visible: {
|
||||
opacity: 1,
|
||||
y: 0,
|
||||
filter: "blur(0px)",
|
||||
transition: { duration: 0.9, ease: [0.16, 1, 0.3, 1] },
|
||||
},
|
||||
};
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"flex flex-col gap-6",
|
||||
align === "center" ? "items-center text-center" : "items-start",
|
||||
className
|
||||
)}
|
||||
>
|
||||
{eyebrow ? (
|
||||
<div className="flex items-center gap-3 text-[11px] font-medium uppercase tracking-[0.22em] text-mist">
|
||||
{index ? <span className="text-gold/85">{index}</span> : null}
|
||||
<span className="h-px w-8 bg-gold/40" />
|
||||
<span className="text-mist/85">{eyebrow}</span>
|
||||
</div>
|
||||
) : null}
|
||||
<motion.h2
|
||||
variants={v}
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={{ once: true, amount: 0.3 }}
|
||||
className="font-display text-[clamp(2.4rem,5vw,4.6rem)] leading-[1.02] tracking-[-0.02em] text-bone text-balance"
|
||||
>
|
||||
{title}
|
||||
{accent ? <> <span className="gold-text">{accent}</span></> : null}
|
||||
</motion.h2>
|
||||
{subtitle ? (
|
||||
<motion.p
|
||||
variants={v}
|
||||
initial="hidden"
|
||||
whileInView="visible"
|
||||
viewport={{ once: true, amount: 0.3 }}
|
||||
transition={{ delay: 0.1 }}
|
||||
className="max-w-2xl text-pretty text-mist md:text-lg"
|
||||
>
|
||||
{subtitle}
|
||||
</motion.p>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user