feat(ui): add AnimatedGlossyBorder and refine industrial interactions
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 39s
Build & Deploy / 🧪 QA (push) Successful in 1m44s
Build & Deploy / 🏗️ Build (push) Successful in 3m23s
Build & Deploy / 🚀 Deploy (push) Successful in 47s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 1m2s
Build & Deploy / 🔔 Notify (push) Successful in 2s
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 39s
Build & Deploy / 🧪 QA (push) Successful in 1m44s
Build & Deploy / 🏗️ Build (push) Successful in 3m23s
Build & Deploy / 🚀 Deploy (push) Successful in 47s
Build & Deploy / 🧪 Post-Deploy Verification (push) Successful in 1m2s
Build & Deploy / 🔔 Notify (push) Successful in 2s
This commit is contained in:
@@ -3,6 +3,7 @@
|
||||
import * as React from 'react';
|
||||
import { motion, Variants } from 'framer-motion';
|
||||
import { HoverShineOverlay } from '@/components/ui/HoverShineOverlay';
|
||||
import { LogoArcs } from '@/components/ui/LogoArcs';
|
||||
|
||||
export interface BenefitItem {
|
||||
id: string;
|
||||
@@ -100,13 +101,32 @@ export function BenefitGrid({ badge, title, description, benefits }: BenefitGrid
|
||||
whileInView="visible"
|
||||
viewport={{ once: true, margin: "-50px" }}
|
||||
>
|
||||
{benefits.map((benefit) => (
|
||||
<motion.div
|
||||
key={benefit.id}
|
||||
variants={itemVariants}
|
||||
className="group relative overflow-hidden bg-neutral-50/50 border border-neutral-200/60 rounded-3xl p-8 transition-all duration-500 hover:bg-white hover:border-primary/30 hover:shadow-[0_20px_40px_-15px_rgba(0,0,0,0.05)] hover:-translate-y-1"
|
||||
>
|
||||
<HoverShineOverlay shineColor="via-primary/5" />
|
||||
{benefits.map((benefit, index) => {
|
||||
const bgPositionClasses = [
|
||||
"-bottom-[30%] -right-[30%]",
|
||||
"-top-[30%] -left-[30%]",
|
||||
"-bottom-[30%] -left-[30%]"
|
||||
];
|
||||
const animationClasses = [
|
||||
"animate-[spin_60s_linear_infinite]",
|
||||
"animate-[spin_80s_linear_infinite]",
|
||||
"animate-[spin_100s_linear_infinite]"
|
||||
];
|
||||
const positionClass = bgPositionClasses[index % bgPositionClasses.length];
|
||||
const animationClass = animationClasses[index % animationClasses.length];
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
key={benefit.id}
|
||||
variants={itemVariants}
|
||||
className="group relative overflow-hidden bg-neutral-50/50 border border-neutral-200/60 rounded-3xl p-8 transition-all duration-500 hover:bg-white hover:border-primary/30 hover:shadow-[0_20px_40px_-15px_rgba(0,0,0,0.05)] hover:-translate-y-1"
|
||||
>
|
||||
<HoverShineOverlay shineColor="via-primary/5" />
|
||||
|
||||
{/* Subtle Background Logo Arcs */}
|
||||
<div className={`absolute ${positionClass} w-[120%] h-[120%] z-0 opacity-0 group-hover:opacity-[0.03] transition-opacity duration-1000 pointer-events-none mix-blend-multiply`}>
|
||||
<LogoArcs className={`w-full h-full text-primary ${animationClass}`} />
|
||||
</div>
|
||||
|
||||
<div className="relative z-10 flex items-start gap-4">
|
||||
<div className="relative shrink-0 w-12 h-12 flex items-center justify-center bg-primary/10 text-primary rounded-xl transition-all duration-500 group-hover:bg-primary group-hover:text-white group-hover:scale-110 group-hover:-rotate-3">
|
||||
@@ -125,7 +145,8 @@ export function BenefitGrid({ badge, title, description, benefits }: BenefitGrid
|
||||
</div>
|
||||
</div>
|
||||
</motion.div>
|
||||
))}
|
||||
);
|
||||
})}
|
||||
</motion.div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@@ -6,8 +6,9 @@ import { motion } from 'framer-motion';
|
||||
import { useState, useEffect } from 'react';
|
||||
import { Button } from '@/components/ui/Button';
|
||||
import { HoverShineOverlay } from '@/components/ui/HoverShineOverlay';
|
||||
|
||||
import { AnimatedGlossyBorder } from '@/components/ui/AnimatedGlossyBorder';
|
||||
import { Container } from '@/components/ui/Container';
|
||||
import { LogoArcs } from '@/components/ui/LogoArcs';
|
||||
|
||||
interface CompetenceBentoGridProps {
|
||||
badge?: string;
|
||||
@@ -113,7 +114,14 @@ export function CompetenceBentoGrid(props: CompetenceBentoGridProps) {
|
||||
className={gridClasses}
|
||||
>
|
||||
<div className="absolute top-0 right-0 w-32 h-32 bg-primary/30 blur-3xl rounded-full -mr-10 -mt-10 group-hover:bg-primary/50 transition-colors duration-500" />
|
||||
|
||||
{/* Subtle Background Logo Arcs */}
|
||||
<div className={`absolute -bottom-[30%] -right-[30%] w-[120%] h-[120%] z-0 opacity-10 group-hover:opacity-20 transition-opacity duration-1000 pointer-events-none mix-blend-overlay`}>
|
||||
<LogoArcs className={`w-full h-full text-white animate-[spin_60s_linear_infinite]`} />
|
||||
</div>
|
||||
|
||||
<HoverShineOverlay shineColor="via-white/30" />
|
||||
<AnimatedGlossyBorder color="white" className="opacity-0 group-hover:opacity-100 transition-opacity duration-700" borderWidth={1} />
|
||||
<h4 className="font-bold text-xl md:text-2xl relative z-10 leading-snug">{item.title}</h4>
|
||||
{item.description && <p className="text-white/60 text-sm mt-3 relative z-10">{item.description}</p>}
|
||||
</motion.div>
|
||||
@@ -148,6 +156,12 @@ export function CompetenceBentoGrid(props: CompetenceBentoGridProps) {
|
||||
)}
|
||||
|
||||
<HoverShineOverlay />
|
||||
<AnimatedGlossyBorder color="white" className="opacity-0 group-hover:opacity-100 transition-opacity duration-700" borderWidth={1} />
|
||||
|
||||
{/* Subtle Background Logo Arcs */}
|
||||
<div className="absolute -top-[30%] -left-[30%] w-[120%] h-[120%] z-0 opacity-0 group-hover:opacity-[0.05] transition-opacity duration-1000 pointer-events-none mix-blend-overlay">
|
||||
<LogoArcs className={`w-full h-full text-white animate-[spin_80s_linear_infinite]`} />
|
||||
</div>
|
||||
|
||||
<div className="relative z-10 p-8 flex flex-col justify-end h-full text-white">
|
||||
{item.tag && (
|
||||
|
||||
@@ -4,6 +4,7 @@ import * as React from 'react';
|
||||
import { motion, Variants } from 'framer-motion';
|
||||
import Image from 'next/image';
|
||||
import { HoverShineOverlay } from '@/components/ui/HoverShineOverlay';
|
||||
import { AnimatedGlossyBorder } from '@/components/ui/AnimatedGlossyBorder';
|
||||
|
||||
interface SubCompanyTilesProps {
|
||||
badge?: string;
|
||||
@@ -49,6 +50,7 @@ const itemVariants: Variants = {
|
||||
};
|
||||
|
||||
import { usePathname } from 'next/navigation';
|
||||
import { LogoArcs } from '@/components/ui/LogoArcs';
|
||||
|
||||
export function SubCompanyTiles(props: SubCompanyTilesProps) {
|
||||
const { data } = props;
|
||||
@@ -91,6 +93,19 @@ export function SubCompanyTiles(props: SubCompanyTilesProps) {
|
||||
const isEtib = company.title.includes('E-TIB');
|
||||
const isIng = company.title.includes('Ingenieur');
|
||||
const isNemo = company.title.includes('NEMO');
|
||||
|
||||
const bgPositionClasses = [
|
||||
"-bottom-[30%] -right-[30%]",
|
||||
"-top-[30%] -left-[30%]",
|
||||
"-bottom-[30%] -left-[30%]"
|
||||
];
|
||||
const animationClasses = [
|
||||
"animate-[spin_60s_linear_infinite]",
|
||||
"animate-[spin_80s_linear_infinite]",
|
||||
"animate-[spin_100s_linear_infinite]"
|
||||
];
|
||||
const positionClass = bgPositionClasses[index % bgPositionClasses.length];
|
||||
const animationClass = animationClasses[index % animationClasses.length];
|
||||
|
||||
return (
|
||||
<motion.div
|
||||
@@ -126,10 +141,22 @@ export function SubCompanyTiles(props: SubCompanyTilesProps) {
|
||||
? 'bg-gradient-to-t from-[#0a192f]/90 via-[#0a192f]/60 to-[#0a192f]/40'
|
||||
: 'bg-gradient-to-t from-[#0a192f]/90 via-[#0a192f]/60 to-[#0a192f]/40 group-hover:from-primary/90 group-hover:to-primary/20'
|
||||
}`} />
|
||||
|
||||
{/* Subtle Background Logo Arcs */}
|
||||
<div className={`absolute ${positionClass} w-[120%] h-[120%] z-10 opacity-[0.02] group-hover:opacity-[0.08] transition-opacity duration-1000 pointer-events-none mix-blend-overlay`}>
|
||||
<LogoArcs className={`w-full h-full text-white ${animationClass}`} />
|
||||
</div>
|
||||
|
||||
{/* Premium Shine Sweep Effect (Industrial Reflection) */}
|
||||
<HoverShineOverlay shineColor="via-white/30" />
|
||||
|
||||
{/* Glossy Animated Border */}
|
||||
<AnimatedGlossyBorder
|
||||
color={isCurrent ? "primary" : "white"}
|
||||
className={`transition-opacity duration-700 ${isCurrent ? 'opacity-100' : 'opacity-0 group-hover:opacity-100'}`}
|
||||
borderWidth={1}
|
||||
/>
|
||||
|
||||
{/* Current Site Indicator Badge */}
|
||||
{isCurrent && (
|
||||
<div className="absolute top-6 right-6 z-20">
|
||||
|
||||
Reference in New Issue
Block a user