91 lines
3.1 KiB
TypeScript
91 lines
3.1 KiB
TypeScript
'use client';
|
|
|
|
import { type ReactNode } from 'react';
|
|
import { ArrowUpRight } from 'lucide-react';
|
|
|
|
interface InsightCardProps {
|
|
/** Category tag (e.g. "白皮书", "观点") */
|
|
tag: string;
|
|
/** Title */
|
|
title: string;
|
|
/** Description */
|
|
desc: string;
|
|
/** Optional date string */
|
|
date?: string;
|
|
/** Whether this is a featured (large) card with image */
|
|
featured?: boolean;
|
|
/** Image URL for featured card */
|
|
image?: string;
|
|
/** Optional link element (avoid nesting <a> in <a>) */
|
|
link?: ReactNode;
|
|
className?: string;
|
|
}
|
|
|
|
export function InsightCard({
|
|
tag,
|
|
title,
|
|
desc,
|
|
date,
|
|
featured = false,
|
|
image,
|
|
link,
|
|
className = '',
|
|
}: InsightCardProps) {
|
|
if (featured) {
|
|
return (
|
|
<div
|
|
className={`group relative overflow-hidden flex flex-col justify-end min-h-[260px] sm:min-h-[300px] md:min-h-[360px] p-8 sm:p-10 md:p-12 lg:p-14 rounded-sm cursor-pointer bg-[var(--color-bg-secondary)] border border-[var(--color-border-primary)] hover:bg-[var(--color-bg-tertiary)] ${className}`}
|
|
>
|
|
{/* Background image */}
|
|
{image && (
|
|
<div
|
|
aria-hidden="true"
|
|
style={{ backgroundImage: `url(${image})` }}
|
|
className="absolute inset-0 bg-cover bg-center transition-transform duration-700 group-hover:scale-105 opacity-10"
|
|
/>
|
|
)}
|
|
|
|
<div className="relative z-10">
|
|
<div className="text-[10px] tracking-[3px] uppercase font-medium mb-4 md:mb-5"
|
|
style={{ color: 'var(--color-brand)' }}>
|
|
{tag}
|
|
</div>
|
|
<h3 className="font-sans text-[20px] sm:text-[24px] md:text-[26px] font-bold leading-[1.3] text-[var(--color-text-primary)] mb-2 md:mb-3">
|
|
{title}
|
|
</h3>
|
|
<p className="text-[13px] sm:text-[14px] leading-relaxed max-w-[400px] mb-5 md:mb-6 text-[var(--color-text-secondary)]">
|
|
{desc}
|
|
</p>
|
|
<span className="text-[12px] inline-flex items-center gap-1.5 transition-colors duration-300 text-[var(--color-text-muted)] group-hover:text-[var(--color-brand)]">
|
|
阅读全文
|
|
<ArrowUpRight className="w-3 h-3" />
|
|
</span>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div
|
|
className={`group p-6 sm:p-8 md:p-10 transition-all duration-400 cursor-pointer flex flex-col bg-[var(--color-bg-primary)] hover:bg-[var(--color-bg-secondary)] ${className}`}
|
|
>
|
|
<div className="text-[10px] tracking-[2px] uppercase font-medium mb-3 md:mb-4"
|
|
style={{ color: 'var(--color-brand)' }}>
|
|
{tag}
|
|
</div>
|
|
<h4 className="font-sans text-[16px] sm:text-[17px] font-semibold leading-[1.5] mb-2 text-[var(--color-text-primary)]">
|
|
{title}
|
|
</h4>
|
|
<p className="text-[13px] leading-relaxed flex-1 mb-4 md:mb-5 text-[var(--color-text-muted)]">
|
|
{desc}
|
|
</p>
|
|
<div className="flex items-center justify-between">
|
|
{date && (
|
|
<span className="text-[11px] text-[var(--color-text-subtle)]">{date}</span>
|
|
)}
|
|
{link && <span className="text-[12px] text-[var(--color-text-subtle)]">{link}</span>}
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|