Files
ar.badieiandCursor c2376b3b9e
Build & Push Docker Image / build (push) Has been cancelled
feat: redesign landing page with brand system and section blocks
Refresh the homepage around new hero/services/roadmap sections, shared design tokens, and updated brand assets.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-23 17:00:55 +03:30

117 lines
2.9 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"use client"
import { motion, useReducedMotion, type Transition } from "motion/react"
import { cn } from "@/lib/utils"
interface BorderBeamProps {
/**
* Approximate length of the visible beam. Mapped to conic spread.
*/
size?: number
/**
* The duration of one full loop (seconds).
*/
duration?: number
/**
* The delay of the border beam.
*/
delay?: number
/**
* The color of the border beam from.
*/
colorFrom?: string
/**
* The color of the border beam to.
*/
colorTo?: string
/**
* The motion transition of the border beam.
*/
transition?: Transition
/**
* The class name of the border beam.
*/
className?: string
/**
* The style of the border beam.
*/
style?: React.CSSProperties
/**
* Whether to reverse the animation direction.
*/
reverse?: boolean
/**
* The initial offset position (0-100).
*/
initialOffset?: number
/**
* The border width of the beam.
*/
borderWidth?: number
}
/**
* Soft beam riding the parent border via a masked rotating conic-gradient.
* Avoids offset-path corner breaks while staying flush with rounded frames.
*/
export const BorderBeam = ({
className,
size = 50,
delay = 0,
duration = 6,
colorFrom = "#29A19C",
colorTo = "#044343",
transition,
style,
reverse = false,
initialOffset = 0,
borderWidth = 1,
}: BorderBeamProps) => {
const reduceMotion = useReducedMotion()
// Map legacy px "size" → angular span (deg). Clamped so the beam stays a short arc.
const spread = Math.min(48, Math.max(12, size * 0.18))
const startAngle = initialOffset * 3.6
return (
<div
className="pointer-events-none absolute overflow-hidden rounded-[inherit] border-(length:--border-beam-width) border-transparent [mask-image:linear-gradient(transparent,transparent),linear-gradient(#000,#000)] [mask-composite:intersect] [mask-clip:padding-box,border-box]"
style={
{
// Overlay the parent’s border (e.g. .media-frame 1px).
inset: `-${borderWidth}px`,
"--border-beam-width": `${borderWidth}px`,
} as React.CSSProperties
}
>
<motion.div
className={cn(
"absolute top-1/2 left-1/2 aspect-square w-[max(200%,200vw)]",
className
)}
style={
{
x: "-50%",
y: "-50%",
background: `conic-gradient(from ${startAngle}deg, transparent 0deg, ${colorFrom} ${spread * 0.35}deg, ${colorTo} ${spread}deg, transparent ${spread * 1.65}deg)`,
...style,
} as React.CSSProperties
}
initial={false}
animate={
reduceMotion
? { rotate: 0 }
: { rotate: reverse ? -360 : 360 }
}
transition={{
repeat: Infinity,
ease: "linear",
duration,
delay: -delay,
...transition,
}}
/>
</div>
)
}