Files
novalon-website/src/components/sections/service-card.tsx
T

63 lines
2.0 KiB
TypeScript

'use client';
import { motion } from 'framer-motion';
import { useReducedMotion } from '@/hooks/use-reduced-motion';
import Link from 'next/link';
import { ArrowRight } from 'lucide-react';
export type ServiceColor = 'brand' | 'blue' | 'teal' | 'amber' | 'purple';
interface ServiceCardProps {
number?: string;
title: string;
description: string;
color?: ServiceColor;
href: string;
className?: string;
delay?: number;
}
export function ServiceCard({
number: _number,
title,
description,
color: _color = 'brand',
href,
className = '',
delay = 0,
}: ServiceCardProps) {
const shouldReduceMotion = useReducedMotion();
return (
<motion.div
className={`group relative bg-[var(--color-bg-primary)] border border-[var(--color-border-primary)] rounded-[var(--radius-lg)] overflow-hidden transition-all duration-normal ease-ink hover:-translate-y-1 hover:shadow-[var(--shadow-lg)] hover:border-[var(--color-brand)]/20 ${className}`}
initial={shouldReduceMotion ? {} : { opacity: 0, y: 24 }}
whileInView={{ opacity: 1, y: 0 }}
viewport={{ once: true, margin: '-40px' }}
transition={{ duration: 0.6, delay, ease: [0.22, 1, 0.36, 1] }}
>
<div className="p-6 md:p-8">
{/* Title */}
<h3 className="text-xl md:text-2xl font-bold mb-3 leading-tight text-[var(--color-text-primary)]">
{title}
</h3>
{/* Description */}
<p className="text-sm md:text-base leading-relaxed mb-6 text-[var(--color-text-secondary)]">
{description}
</p>
{/* Link */}
<Link
href={href}
className="inline-flex items-center text-sm font-medium transition-all duration-fast group-hover:gap-2.5 text-[var(--color-brand)]"
style={{ minHeight: '44px', minWidth: '44px' }}
>
<span>了解详情</span>
<ArrowRight className="w-4 h-4 transform transition-transform duration-fast group-hover:translate-x-1" />
</Link>
</div>
</motion.div>
);
}