chore: deep semantic HTML audit and improvements across all pages
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 13s
Build & Deploy / 🧪 QA (push) Successful in 2m56s
Build & Deploy / 🏗️ Build (push) Successful in 4m14s
Build & Deploy / 🚀 Deploy (push) Successful in 29s
Build & Deploy / 🧪 Smoke Test (push) Successful in 1m3s
Build & Deploy / ⚡ Lighthouse (push) Successful in 3m7s
Build & Deploy / 🔔 Notify (push) Successful in 2s
All checks were successful
Build & Deploy / 🔍 Prepare (push) Successful in 13s
Build & Deploy / 🧪 QA (push) Successful in 2m56s
Build & Deploy / 🏗️ Build (push) Successful in 4m14s
Build & Deploy / 🚀 Deploy (push) Successful in 29s
Build & Deploy / 🧪 Smoke Test (push) Successful in 1m3s
Build & Deploy / ⚡ Lighthouse (push) Successful in 3m7s
Build & Deploy / 🔔 Notify (push) Successful in 2s
This commit is contained in:
@@ -58,7 +58,7 @@ export default async function BlogIndex({ params }: BlogIndexProps) {
|
|||||||
<div className="bg-neutral-light min-h-screen">
|
<div className="bg-neutral-light min-h-screen">
|
||||||
{/* Hero Section - Immersive Magazine Feel */}
|
{/* Hero Section - Immersive Magazine Feel */}
|
||||||
<Reveal>
|
<Reveal>
|
||||||
<section className="relative h-[50vh] md:h-[70vh] min-h-[400px] md:min-h-[600px] flex items-center overflow-hidden bg-primary-dark">
|
<article className="relative h-[50vh] md:h-[70vh] min-h-[400px] md:min-h-[600px] flex items-center overflow-hidden bg-primary-dark">
|
||||||
{featuredPost && featuredPost.frontmatter.featuredImage && (
|
{featuredPost && featuredPost.frontmatter.featuredImage && (
|
||||||
<>
|
<>
|
||||||
<Image
|
<Image
|
||||||
@@ -101,7 +101,7 @@ export default async function BlogIndex({ params }: BlogIndexProps) {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
</section>
|
</article>
|
||||||
</Reveal>
|
</Reveal>
|
||||||
|
|
||||||
<Section className="bg-neutral-light py-12 md:py-28">
|
<Section className="bg-neutral-light py-12 md:py-28">
|
||||||
@@ -146,7 +146,10 @@ export default async function BlogIndex({ params }: BlogIndexProps) {
|
|||||||
{remainingPosts.map((post, idx) => (
|
{remainingPosts.map((post, idx) => (
|
||||||
<Reveal key={post.slug} delay={idx * 100}>
|
<Reveal key={post.slug} delay={idx * 100}>
|
||||||
<Link href={`/${locale}/blog/${post.slug}`} className="group block">
|
<Link href={`/${locale}/blog/${post.slug}`} className="group block">
|
||||||
<Card className="h-full flex flex-col border-none shadow-lg hover:shadow-2xl transition-all duration-500 rounded-2xl md:rounded-3xl overflow-hidden">
|
<Card
|
||||||
|
tag="article"
|
||||||
|
className="h-full flex flex-col border-none shadow-lg hover:shadow-2xl transition-all duration-500 rounded-2xl md:rounded-3xl overflow-hidden"
|
||||||
|
>
|
||||||
{post.frontmatter.featuredImage && (
|
{post.frontmatter.featuredImage && (
|
||||||
<div className="relative h-48 md:h-72 overflow-hidden">
|
<div className="relative h-48 md:h-72 overflow-hidden">
|
||||||
<Image
|
<Image
|
||||||
|
|||||||
@@ -136,7 +136,7 @@ export default async function ContactPage({ params }: ContactPageProps) {
|
|||||||
<Heading level={3} subtitle={t('info.subtitle')} className="mb-6 md:mb-8">
|
<Heading level={3} subtitle={t('info.subtitle')} className="mb-6 md:mb-8">
|
||||||
{t('info.howToReachUs')}
|
{t('info.howToReachUs')}
|
||||||
</Heading>
|
</Heading>
|
||||||
<div className="space-y-4 md:space-y-8">
|
<address className="space-y-4 md:space-y-8 not-italic">
|
||||||
<div className="flex items-start gap-4 md:gap-6 group">
|
<div className="flex items-start gap-4 md:gap-6 group">
|
||||||
<div className="w-10 h-10 md:w-14 md:h-14 rounded-xl md:rounded-2xl bg-saturated/10 flex items-center justify-center text-saturated group-hover:bg-accent group-hover:text-primary-dark transition-all duration-300 shadow-sm flex-shrink-0">
|
<div className="w-10 h-10 md:w-14 md:h-14 rounded-xl md:rounded-2xl bg-saturated/10 flex items-center justify-center text-saturated group-hover:bg-accent group-hover:text-primary-dark transition-all duration-300 shadow-sm flex-shrink-0">
|
||||||
<svg
|
<svg
|
||||||
@@ -197,7 +197,7 @@ export default async function ContactPage({ params }: ContactPageProps) {
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</address>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="p-6 md:p-10 bg-white rounded-2xl md:rounded-3xl border border-neutral-medium shadow-sm animate-fade-in">
|
<div className="p-6 md:p-10 bg-white rounded-2xl md:rounded-3xl border border-neutral-medium shadow-sm animate-fade-in">
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import ProductTabs from '@/components/ProductTabs';
|
|||||||
import ProductTechnicalData from '@/components/ProductTechnicalData';
|
import ProductTechnicalData from '@/components/ProductTechnicalData';
|
||||||
import RelatedProducts from '@/components/RelatedProducts';
|
import RelatedProducts from '@/components/RelatedProducts';
|
||||||
import DatasheetDownload from '@/components/DatasheetDownload';
|
import DatasheetDownload from '@/components/DatasheetDownload';
|
||||||
import { Badge, Container, Heading, Section } from '@/components/ui';
|
import { Badge, Card, Container, Heading, Section } from '@/components/ui';
|
||||||
import { getDatasheetPath } from '@/lib/datasheets';
|
import { getDatasheetPath } from '@/lib/datasheets';
|
||||||
import { getAllProducts, getProductBySlug } from '@/lib/mdx';
|
import { getAllProducts, getProductBySlug } from '@/lib/mdx';
|
||||||
import { mapFileSlugToTranslated, mapSlugToFileSlug } from '@/lib/slugs';
|
import { mapFileSlugToTranslated, mapSlugToFileSlug } from '@/lib/slugs';
|
||||||
@@ -239,57 +239,59 @@ export default async function ProductPage({ params }: ProductPageProps) {
|
|||||||
href={`/${locale}/products/${productSlug}/${product.translatedSlug}`}
|
href={`/${locale}/products/${productSlug}/${product.translatedSlug}`}
|
||||||
className="group block bg-white rounded-[32px] overflow-hidden shadow-sm hover:shadow-2xl transition-all duration-500 border border-neutral-dark/5"
|
className="group block bg-white rounded-[32px] overflow-hidden shadow-sm hover:shadow-2xl transition-all duration-500 border border-neutral-dark/5"
|
||||||
>
|
>
|
||||||
<div className="aspect-[4/3] relative bg-neutral-light/30 p-12 overflow-hidden">
|
<Card tag="article" className="premium-card-reset">
|
||||||
{product.frontmatter.images?.[0] && (
|
<div className="aspect-[4/3] relative bg-neutral-light/30 p-12 overflow-hidden">
|
||||||
<>
|
{product.frontmatter.images?.[0] && (
|
||||||
<Image
|
<>
|
||||||
src={product.frontmatter.images[0]}
|
<Image
|
||||||
alt={product.frontmatter.title}
|
src={product.frontmatter.images[0]}
|
||||||
fill
|
alt={product.frontmatter.title}
|
||||||
className="object-contain p-8 transition-transform duration-700 group-hover:scale-110 z-10"
|
fill
|
||||||
sizes="(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw"
|
className="object-contain p-8 transition-transform duration-700 group-hover:scale-110 z-10"
|
||||||
/>
|
sizes="(max-width: 768px) 100vw, (max-width: 1024px) 50vw, 33vw"
|
||||||
{/* Subtle reflection/shadow effect */}
|
/>
|
||||||
<div className="absolute bottom-4 left-1/2 -translate-x-1/2 w-2/3 h-4 bg-black/5 blur-xl rounded-full" />
|
{/* Subtle reflection/shadow effect */}
|
||||||
</>
|
<div className="absolute bottom-4 left-1/2 -translate-x-1/2 w-2/3 h-4 bg-black/5 blur-xl rounded-full" />
|
||||||
)}
|
</>
|
||||||
</div>
|
)}
|
||||||
<div className="p-8 md:p-10">
|
</div>
|
||||||
<div className="flex flex-wrap gap-2 mb-4">
|
<div className="p-8 md:p-10">
|
||||||
{product.frontmatter.categories.map((cat, i) => (
|
<div className="flex flex-wrap gap-2 mb-4">
|
||||||
<span
|
{product.frontmatter.categories.map((cat, i) => (
|
||||||
key={i}
|
<span
|
||||||
className="text-[10px] font-bold uppercase tracking-widest text-primary/40"
|
key={i}
|
||||||
>
|
className="text-[10px] font-bold uppercase tracking-widest text-primary/40"
|
||||||
{cat}
|
>
|
||||||
|
{cat}
|
||||||
|
</span>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
<h2 className="text-2xl md:text-3xl font-bold text-text-primary group-hover:text-primary transition-colors mb-4 leading-tight">
|
||||||
|
{product.frontmatter.title}
|
||||||
|
</h2>
|
||||||
|
<p className="text-text-secondary line-clamp-2 text-base leading-relaxed mb-8">
|
||||||
|
{product.frontmatter.description}
|
||||||
|
</p>
|
||||||
|
<div className="flex items-center text-primary font-bold group-hover:text-accent-dark transition-colors">
|
||||||
|
<span className="border-b-2 border-primary/10 group-hover:border-accent-dark transition-colors pb-1">
|
||||||
|
{t('details')}
|
||||||
</span>
|
</span>
|
||||||
))}
|
<svg
|
||||||
|
className="w-5 h-5 ml-3 transition-transform group-hover:translate-x-1"
|
||||||
|
fill="none"
|
||||||
|
stroke="currentColor"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
strokeLinecap="round"
|
||||||
|
strokeLinejoin="round"
|
||||||
|
strokeWidth={2}
|
||||||
|
d="M17 8l4 4m0 0l-4 4m4-4H3"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<h2 className="text-2xl md:text-3xl font-bold text-text-primary group-hover:text-primary transition-colors mb-4 leading-tight">
|
</Card>
|
||||||
{product.frontmatter.title}
|
|
||||||
</h2>
|
|
||||||
<p className="text-text-secondary line-clamp-2 text-base leading-relaxed mb-8">
|
|
||||||
{product.frontmatter.description}
|
|
||||||
</p>
|
|
||||||
<div className="flex items-center text-primary font-bold group-hover:text-accent-dark transition-colors">
|
|
||||||
<span className="border-b-2 border-primary/10 group-hover:border-accent-dark transition-colors pb-1">
|
|
||||||
{t('details')}
|
|
||||||
</span>
|
|
||||||
<svg
|
|
||||||
className="w-5 h-5 ml-3 transition-transform group-hover:translate-x-1"
|
|
||||||
fill="none"
|
|
||||||
stroke="currentColor"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<path
|
|
||||||
strokeLinecap="round"
|
|
||||||
strokeLinejoin="round"
|
|
||||||
strokeWidth={2}
|
|
||||||
d="M17 8l4 4m0 0l-4 4m4-4H3"
|
|
||||||
/>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Link>
|
</Link>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ export default async function TeamPage({ params }: TeamPageProps) {
|
|||||||
</Reveal>
|
</Reveal>
|
||||||
|
|
||||||
{/* Michael Bodemer Section - Sticky Narrative Split Layout */}
|
{/* Michael Bodemer Section - Sticky Narrative Split Layout */}
|
||||||
<section className="relative bg-white overflow-hidden">
|
<article className="relative bg-white overflow-hidden">
|
||||||
<div className="flex flex-col lg:flex-row">
|
<div className="flex flex-col lg:flex-row">
|
||||||
<Reveal className="w-full lg:w-1/2 p-6 md:p-24 lg:p-32 flex flex-col justify-center bg-primary-dark text-white relative order-2 lg:order-1">
|
<Reveal className="w-full lg:w-1/2 p-6 md:p-24 lg:p-32 flex flex-col justify-center bg-primary-dark text-white relative order-2 lg:order-1">
|
||||||
<div className="absolute top-0 right-0 w-32 h-full bg-accent/5 -skew-x-12 translate-x-1/2" />
|
<div className="absolute top-0 right-0 w-32 h-full bg-accent/5 -skew-x-12 translate-x-1/2" />
|
||||||
@@ -161,7 +161,7 @@ export default async function TeamPage({ params }: TeamPageProps) {
|
|||||||
<div className="absolute inset-0 bg-gradient-to-t from-primary-dark/60 lg:bg-gradient-to-r lg:from-primary-dark/20 to-transparent" />
|
<div className="absolute inset-0 bg-gradient-to-t from-primary-dark/60 lg:bg-gradient-to-r lg:from-primary-dark/20 to-transparent" />
|
||||||
</Reveal>
|
</Reveal>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</article>
|
||||||
|
|
||||||
{/* Legacy Section - Immersive Background */}
|
{/* Legacy Section - Immersive Background */}
|
||||||
<Reveal>
|
<Reveal>
|
||||||
@@ -217,7 +217,7 @@ export default async function TeamPage({ params }: TeamPageProps) {
|
|||||||
</Reveal>
|
</Reveal>
|
||||||
|
|
||||||
{/* Klaus Mintel Section - Reversed Split Layout */}
|
{/* Klaus Mintel Section - Reversed Split Layout */}
|
||||||
<section className="relative bg-white overflow-hidden">
|
<article className="relative bg-white overflow-hidden">
|
||||||
<div className="flex flex-col lg:flex-row">
|
<div className="flex flex-col lg:flex-row">
|
||||||
<Reveal className="w-full lg:w-1/2 relative min-h-[400px] md:min-h-[600px] lg:min-h-screen overflow-hidden order-1">
|
<Reveal className="w-full lg:w-1/2 relative min-h-[400px] md:min-h-[600px] lg:min-h-screen overflow-hidden order-1">
|
||||||
<Image
|
<Image
|
||||||
@@ -264,7 +264,7 @@ export default async function TeamPage({ params }: TeamPageProps) {
|
|||||||
</div>
|
</div>
|
||||||
</Reveal>
|
</Reveal>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</article>
|
||||||
|
|
||||||
{/* Manifesto Section - Modern Grid */}
|
{/* Manifesto Section - Modern Grid */}
|
||||||
<Section className="bg-white text-primary py-16 md:py-28">
|
<Section className="bg-white text-primary py-16 md:py-28">
|
||||||
@@ -292,9 +292,9 @@ export default async function TeamPage({ params }: TeamPageProps) {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="sticky-narrative-content grid grid-cols-1 md:grid-cols-2 gap-4 md:gap-10">
|
<ul className="sticky-narrative-content grid grid-cols-1 md:grid-cols-2 gap-4 md:gap-10 list-none p-0 m-0">
|
||||||
{[0, 1, 2, 3, 4, 5].map((idx) => (
|
{[0, 1, 2, 3, 4, 5].map((idx) => (
|
||||||
<div
|
<li
|
||||||
key={idx}
|
key={idx}
|
||||||
className="p-6 md:p-10 bg-neutral-light rounded-2xl md:rounded-[40px] border border-transparent hover:border-accent hover:bg-white hover:shadow-2xl transition-all duration-500 group active:scale-[0.98] touch-target-none"
|
className="p-6 md:p-10 bg-neutral-light rounded-2xl md:rounded-[40px] border border-transparent hover:border-accent hover:bg-white hover:shadow-2xl transition-all duration-500 group active:scale-[0.98] touch-target-none"
|
||||||
>
|
>
|
||||||
@@ -309,9 +309,9 @@ export default async function TeamPage({ params }: TeamPageProps) {
|
|||||||
<p className="text-sm md:text-lg text-text-secondary leading-relaxed">
|
<p className="text-sm md:text-lg text-text-secondary leading-relaxed">
|
||||||
{t(`manifesto.items.${idx}.description`)}
|
{t(`manifesto.items.${idx}.description`)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</li>
|
||||||
))}
|
))}
|
||||||
</div>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
</Section>
|
</Section>
|
||||||
|
|||||||
@@ -67,9 +67,9 @@ export default function Footer() {
|
|||||||
|
|
||||||
{/* Links Columns */}
|
{/* Links Columns */}
|
||||||
<div className="lg:col-span-2">
|
<div className="lg:col-span-2">
|
||||||
<h2 className="text-accent font-bold uppercase tracking-widest text-xs md:text-sm mb-8">
|
<h3 className="text-accent font-bold uppercase tracking-widest text-xs md:text-sm mb-8">
|
||||||
{t('legal')}
|
{t('legal')}
|
||||||
</h2>
|
</h3>
|
||||||
<ul className="space-y-4 text-white/70 list-none m-0 p-0">
|
<ul className="space-y-4 text-white/70 list-none m-0 p-0">
|
||||||
<li>
|
<li>
|
||||||
<Link
|
<Link
|
||||||
@@ -120,9 +120,9 @@ export default function Footer() {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="lg:col-span-2">
|
<div className="lg:col-span-2">
|
||||||
<h2 className="text-accent font-bold uppercase tracking-widest text-xs md:text-sm mb-8">
|
<h3 className="text-accent font-bold uppercase tracking-widest text-xs md:text-sm mb-8">
|
||||||
{t('company')}
|
{t('company')}
|
||||||
</h2>
|
</h3>
|
||||||
<ul className="space-y-4 text-white/70 list-none m-0 p-0">
|
<ul className="space-y-4 text-white/70 list-none m-0 p-0">
|
||||||
<li>
|
<li>
|
||||||
<Link
|
<Link
|
||||||
@@ -189,9 +189,9 @@ export default function Footer() {
|
|||||||
|
|
||||||
{/* Recent Posts Column */}
|
{/* Recent Posts Column */}
|
||||||
<div className="lg:col-span-4">
|
<div className="lg:col-span-4">
|
||||||
<h2 className="text-accent font-bold uppercase tracking-widest text-xs md:text-sm mb-8">
|
<h3 className="text-accent font-bold uppercase tracking-widest text-xs md:text-sm mb-8">
|
||||||
{t('recentPosts')}
|
{t('recentPosts')}
|
||||||
</h2>
|
</h3>
|
||||||
<ul className="space-y-6 list-none m-0 p-0">
|
<ul className="space-y-6 list-none m-0 p-0">
|
||||||
{[
|
{[
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -341,7 +341,7 @@ export default function Header() {
|
|||||||
aria-label={t('menu')}
|
aria-label={t('menu')}
|
||||||
ref={mobileMenuRef}
|
ref={mobileMenuRef}
|
||||||
>
|
>
|
||||||
<motion.div
|
<motion.nav
|
||||||
className="flex-grow flex flex-col justify-center items-center p-8 space-y-8"
|
className="flex-grow flex flex-col justify-center items-center p-8 space-y-8"
|
||||||
initial="closed"
|
initial="closed"
|
||||||
animate={isMobileMenuOpen ? 'open' : 'closed'}
|
animate={isMobileMenuOpen ? 'open' : 'closed'}
|
||||||
@@ -463,7 +463,7 @@ export default function Header() {
|
|||||||
<Image src="/logo-white.svg" alt={t('home')} width={80} height={80} unoptimized />
|
<Image src="/logo-white.svg" alt={t('home')} width={80} height={80} unoptimized />
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
</motion.div>
|
</motion.nav>
|
||||||
</div>
|
</div>
|
||||||
</motion.header>
|
</motion.header>
|
||||||
</>
|
</>
|
||||||
|
|||||||
@@ -14,11 +14,16 @@ interface ProductSidebarProps {
|
|||||||
className?: string;
|
className?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ProductSidebar({ productName, productImage, datasheetPath, className }: ProductSidebarProps) {
|
export default function ProductSidebar({
|
||||||
|
productName,
|
||||||
|
productImage,
|
||||||
|
datasheetPath,
|
||||||
|
className,
|
||||||
|
}: ProductSidebarProps) {
|
||||||
const t = useTranslations('Products');
|
const t = useTranslations('Products');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn("flex flex-col gap-4 animate-slight-fade-in-from-bottom", className)}>
|
<aside className={cn('flex flex-col gap-4 animate-slight-fade-in-from-bottom', className)}>
|
||||||
{/* Request Quote Form Card */}
|
{/* Request Quote Form Card */}
|
||||||
<div className="bg-white rounded-3xl border border-neutral-medium shadow-sm transition-all duration-500 hover:shadow-2xl hover:-translate-y-1 overflow-hidden group/card">
|
<div className="bg-white rounded-3xl border border-neutral-medium shadow-sm transition-all duration-500 hover:shadow-2xl hover:-translate-y-1 overflow-hidden group/card">
|
||||||
<div className="bg-primary p-6 text-white relative overflow-hidden">
|
<div className="bg-primary p-6 text-white relative overflow-hidden">
|
||||||
@@ -64,9 +69,7 @@ export default function ProductSidebar({ productName, productImage, datasheetPat
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Datasheet Download */}
|
{/* Datasheet Download */}
|
||||||
{datasheetPath && (
|
{datasheetPath && <DatasheetDownload datasheetPath={datasheetPath} className="mt-0" />}
|
||||||
<DatasheetDownload datasheetPath={datasheetPath} className="mt-0" />
|
</aside>
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,24 +32,24 @@ export default function Experience() {
|
|||||||
<p className="pl-9">{t('p2')}</p>
|
<p className="pl-9">{t('p2')}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className="mt-16 grid grid-cols-1 md:grid-cols-2 gap-12">
|
<dl className="mt-16 grid grid-cols-1 md:grid-cols-2 gap-12">
|
||||||
<div className="animate-fade-in">
|
<div className="animate-fade-in">
|
||||||
<div className="text-2xl md:text-3xl font-extrabold text-accent mb-4">
|
<dt className="text-2xl md:text-3xl font-extrabold text-accent mb-4">
|
||||||
{t('certifiedQuality')}
|
{t('certifiedQuality')}
|
||||||
</div>
|
</dt>
|
||||||
<div className="text-base md:text-lg font-bold uppercase tracking-widest text-white/60">
|
<dd className="text-base md:text-lg font-bold uppercase tracking-widest text-white/60">
|
||||||
{t('vdeApproved')}
|
{t('vdeApproved')}
|
||||||
</div>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
<div className="animate-fade-in" style={{ animationDelay: '100ms' }}>
|
<div className="animate-fade-in" style={{ animationDelay: '100ms' }}>
|
||||||
<div className="text-2xl md:text-3xl font-extrabold text-accent mb-4">
|
<dt className="text-2xl md:text-3xl font-extrabold text-accent mb-4">
|
||||||
{t('fullSpectrum')}
|
{t('fullSpectrum')}
|
||||||
</div>
|
</dt>
|
||||||
<div className="text-base md:text-lg font-bold uppercase tracking-widest text-white/60">
|
<dd className="text-base md:text-lg font-bold uppercase tracking-widest text-white/60">
|
||||||
{t('solutionsRange')}
|
{t('solutionsRange')}
|
||||||
</div>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</dl>
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
</Section>
|
</Section>
|
||||||
|
|||||||
@@ -35,7 +35,10 @@ export default async function RecentPosts({ locale }: RecentPostsProps) {
|
|||||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 md:gap-10">
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 md:gap-10">
|
||||||
{recentPosts.map((post) => (
|
{recentPosts.map((post) => (
|
||||||
<Link key={post.slug} href={`/${locale}/blog/${post.slug}`} className="group block">
|
<Link key={post.slug} href={`/${locale}/blog/${post.slug}`} className="group block">
|
||||||
<Card className="h-full flex flex-col border-none shadow-lg hover:shadow-2xl transition-all duration-500 rounded-3xl">
|
<Card
|
||||||
|
tag="article"
|
||||||
|
className="h-full flex flex-col border-none shadow-lg hover:shadow-2xl transition-all duration-500 rounded-3xl"
|
||||||
|
>
|
||||||
{post.frontmatter.featuredImage && (
|
{post.frontmatter.featuredImage && (
|
||||||
<div className="relative h-64 overflow-hidden">
|
<div className="relative h-64 overflow-hidden">
|
||||||
<Image
|
<Image
|
||||||
@@ -57,11 +60,13 @@ export default async function RecentPosts({ locale }: RecentPostsProps) {
|
|||||||
<div className="p-6 md:p-8 flex flex-col flex-grow">
|
<div className="p-6 md:p-8 flex flex-col flex-grow">
|
||||||
<div className="text-xs md:text-sm font-medium text-text-light mb-3 md:mb-4 flex items-center gap-2">
|
<div className="text-xs md:text-sm font-medium text-text-light mb-3 md:mb-4 flex items-center gap-2">
|
||||||
<span className="w-6 md:w-8 h-px bg-neutral-medium" />
|
<span className="w-6 md:w-8 h-px bg-neutral-medium" />
|
||||||
{new Date(post.frontmatter.date).toLocaleDateString(locale, {
|
<time dateTime={post.frontmatter.date}>
|
||||||
year: 'numeric',
|
{new Date(post.frontmatter.date).toLocaleDateString(locale, {
|
||||||
month: 'long',
|
year: 'numeric',
|
||||||
day: 'numeric',
|
month: 'long',
|
||||||
})}
|
day: 'numeric',
|
||||||
|
})}
|
||||||
|
</time>
|
||||||
</div>
|
</div>
|
||||||
<h3 className="text-lg md:text-xl font-bold text-primary group-hover:text-accent-dark transition-colors line-clamp-2 mb-4 md:mb-6 leading-tight">
|
<h3 className="text-lg md:text-xl font-bold text-primary group-hover:text-accent-dark transition-colors line-clamp-2 mb-4 md:mb-6 leading-tight">
|
||||||
{post.frontmatter.title}
|
{post.frontmatter.title}
|
||||||
|
|||||||
@@ -45,9 +45,9 @@ export default function WhyChooseUs() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="lg:col-span-8 grid grid-cols-1 md:grid-cols-2 gap-8 order-2 lg:order-1">
|
<ul className="lg:col-span-8 grid grid-cols-1 md:grid-cols-2 gap-8 order-2 lg:order-1 list-none p-0 m-0">
|
||||||
{[0, 1, 2, 3].map((idx) => (
|
{[0, 1, 2, 3].map((idx) => (
|
||||||
<div
|
<li
|
||||||
key={idx}
|
key={idx}
|
||||||
className="p-10 bg-white rounded-3xl border border-neutral-medium hover:border-accent transition-all duration-500 hover:shadow-xl group"
|
className="p-10 bg-white rounded-3xl border border-neutral-medium hover:border-accent transition-all duration-500 hover:shadow-xl group"
|
||||||
>
|
>
|
||||||
@@ -62,9 +62,9 @@ export default function WhyChooseUs() {
|
|||||||
<p className="text-text-secondary text-base md:text-base leading-relaxed">
|
<p className="text-text-secondary text-base md:text-base leading-relaxed">
|
||||||
{t(`items.${idx}.description`)}
|
{t(`items.${idx}.description`)}
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</li>
|
||||||
))}
|
))}
|
||||||
</div>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
</Section>
|
</Section>
|
||||||
|
|||||||
@@ -1,10 +1,14 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { cn } from './utils';
|
import { cn } from './utils';
|
||||||
|
|
||||||
export function Card({ className, children, ...props }: React.HTMLAttributes<HTMLDivElement>) {
|
interface CardProps extends React.HTMLAttributes<HTMLElement> {
|
||||||
|
tag?: 'div' | 'article' | 'section' | 'aside' | 'header' | 'footer' | 'nav' | 'main';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function Card({ className, children, tag: Tag = 'div', ...props }: CardProps) {
|
||||||
return (
|
return (
|
||||||
<div className={cn('premium-card overflow-hidden', className)} {...props}>
|
<Tag className={cn('premium-card overflow-hidden', className)} {...props}>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</Tag>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user