fix(blog): optimize component share logic, typography, and modal layouts
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 5s
Build & Deploy / 🏗️ Build (push) Failing after 14s
Build & Deploy / 🧪 QA (push) Failing after 1m48s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s
Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 5s
Build & Deploy / 🏗️ Build (push) Failing after 14s
Build & Deploy / 🧪 QA (push) Failing after 1m48s
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 2s
This commit is contained in:
@@ -1,12 +1,12 @@
|
||||
'use client';
|
||||
"use client";
|
||||
|
||||
import React from 'react';
|
||||
import { ComponentShareButton } from './ComponentShareButton';
|
||||
import { Reveal } from './Reveal';
|
||||
|
||||
interface WebVitalsScoreProps {
|
||||
values: {
|
||||
/** Largest Contentful Paint in seconds (e.g. 2.5) */
|
||||
lcp: number;
|
||||
/** Interaction to Next Paint in milliseconds (e.g. 200) */
|
||||
inp: number;
|
||||
/** Cumulative Layout Shift (e.g. 0.1) */
|
||||
cls: number;
|
||||
@@ -30,46 +30,61 @@ export const WebVitalsScore: React.FC<WebVitalsScoreProps> = ({ values, descript
|
||||
];
|
||||
|
||||
const getColors = (status: string) => {
|
||||
if (status === 'good') return 'text-emerald-600 border-emerald-500';
|
||||
if (status === 'needs-improvement') return 'text-amber-500 border-amber-400';
|
||||
return 'text-red-500 border-red-500';
|
||||
if (status === 'good') return { text: 'text-slate-900', bg: 'bg-emerald-50/50', border: 'border-emerald-200/50', glow: '' };
|
||||
if (status === 'needs-improvement') return { text: 'text-slate-900', bg: 'bg-amber-50/50', border: 'border-amber-200/50', glow: '' };
|
||||
return { text: 'text-slate-900', bg: 'bg-red-50/50', border: 'border-red-200/50', glow: '' };
|
||||
};
|
||||
|
||||
// Generate stable hash for share button
|
||||
const shareId = `vitals-${React.useId().replace(/:/g, "")}`;
|
||||
|
||||
return (
|
||||
<section className="my-16 not-prose border-[2px] border-slate-900 p-8 md:p-12 relative bg-white">
|
||||
<div className="absolute -top-[14px] left-8 bg-white px-4">
|
||||
<h3 className="text-xl font-bold text-slate-900 tracking-tight m-0 uppercase flex items-center gap-3">
|
||||
<div className="w-3 h-3 bg-slate-900 rotate-45" />
|
||||
Core Web Vitals
|
||||
</h3>
|
||||
</div>
|
||||
<Reveal direction="up" delay={0.1}>
|
||||
<figure id={shareId} className="not-prose my-16 group relative transition-all duration-500 ease-out z-10">
|
||||
{/* Ambient Background Glow matching the homepage feel */}
|
||||
<div className="absolute -inset-1 bg-gradient-to-r from-slate-100/50 to-slate-200/30 rounded-[2rem] blur opacity-20 group-hover:opacity-40 transition duration-1000 -z-10" />
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 md:gap-12 mt-4">
|
||||
{metrics.map((m) => {
|
||||
const colors = getColors(m.stat);
|
||||
return (
|
||||
<div key={m.id} className="flex flex-col">
|
||||
<span className="text-[10px] font-mono text-slate-500 uppercase tracking-widest mb-1">{m.label}</span>
|
||||
<div className={`text-4xl md:text-5xl font-black tracking-tighter tabular-nums ${colors.split(' ')[0]} border-b-[3px] ${colors.split(' ')[1]} pb-2 mb-2`}>
|
||||
{m.value}<span className="text-lg ml-1 font-bold">{m.unit}</span>
|
||||
</div>
|
||||
<div className="flex justify-between items-start gap-2">
|
||||
<span className={`text-[10px] font-mono font-bold uppercase ${colors.split(' ')[0]}`}>{m.stat.replace('-', ' ')}</span>
|
||||
<span className="text-[10px] text-slate-500 leading-snug text-right max-w-[120px]">{m.desc}</span>
|
||||
</div>
|
||||
<div className="glass bg-white/80 backdrop-blur-xl border border-slate-100 rounded-2xl shadow-sm group-hover:shadow-md group-hover:border-slate-200 transition-all duration-500 overflow-hidden relative">
|
||||
|
||||
{/* Subtle top shine */}
|
||||
<div className="absolute inset-x-0 top-0 h-px bg-gradient-to-r from-transparent via-white to-transparent opacity-80" />
|
||||
|
||||
<div className="p-8 md:p-10 relative z-10">
|
||||
{/* Share Button top right */}
|
||||
<div className="absolute top-6 right-6 md:opacity-0 group-hover:opacity-100 transition-opacity duration-500 z-50">
|
||||
<ComponentShareButton targetId={shareId} title="Core Web Vitals Scores" />
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{description && (
|
||||
<div className="mt-10 p-5 bg-slate-50 border-l-2 border-slate-900">
|
||||
<p className="text-sm text-slate-800 m-0 leading-relaxed font-serif">
|
||||
<span className="font-mono text-[10px] font-bold uppercase text-slate-900 tracking-widest block mb-2">Analyse</span>
|
||||
{description}
|
||||
</p>
|
||||
<header className="mb-10 flex flex-col gap-2 border-b border-slate-100 pb-4 pr-16 md:pr-0">
|
||||
<div>
|
||||
<h3 className="text-xl md:text-2xl font-bold text-slate-900 tracking-tight m-0 flex items-center gap-3">
|
||||
<span className="w-2 h-2 rounded-full bg-slate-800" />
|
||||
Core Web Vitals
|
||||
</h3>
|
||||
{description && <p className="text-sm text-slate-500 mt-1 leading-snug m-0">{description}</p>}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 md:gap-8">
|
||||
{metrics.map((metric, i) => {
|
||||
const colors = getColors(metric.stat);
|
||||
return (
|
||||
<div key={i} className={`flex flex-col gap-2 p-6 rounded-2xl border border-transparent hover:border-slate-200 hover:bg-slate-50 transition-all duration-300 group/metric`}>
|
||||
<span className="text-[10px] font-bold text-slate-400 uppercase tracking-widest">{metric.label}</span>
|
||||
<div className="flex items-baseline gap-1">
|
||||
<span className={`text-4xl md:text-5xl font-bold tracking-tighter transition-transform duration-500 group-hover/metric:scale-110 origin-left ${colors.text}`}>
|
||||
{metric.value}
|
||||
</span>
|
||||
{metric.unit && <span className="text-sm font-mono text-slate-400">{metric.unit}</span>}
|
||||
</div>
|
||||
<span className="text-xs leading-relaxed text-slate-600 font-medium mt-1">{metric.desc}</span>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
</figure>
|
||||
</Reveal>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user