refactor(home): unify section headings, differentiate capabilities and process
Reduce the "interchangeable cards" monotony flagged in Phase 0 and apply the warm-premium type scale. - SectionHeading: use the type scale (eyebrow via .eyebrow with brand tint, text-h2 title, body-lg description). Propagates to every home section. - CapabilitiesSection: cleaner cards with a brand-tinted icon tile, type-scale title/body, soft elevation (drops the AppCard wrapper). - ProcessSection: reworked into an editorial numbered timeline (large translucent brand numerals, top rule, no boxes) so it no longer looks identical to Capabilities. Verified: eslint clean, no new type errors, tailwind generates the utilities.
This commit is contained in:
@@ -1,6 +1,5 @@
|
||||
import { Bot, Database, Globe, ServerCog } from "lucide-react";
|
||||
|
||||
import { AppCard } from "@/components/ui/app-card";
|
||||
import { SectionHeading } from "./section-heading";
|
||||
import type { CapabilitiesSectionCopy } from "./types";
|
||||
|
||||
@@ -19,29 +18,25 @@ export function CapabilitiesSection({ copy }: CapabilitiesSectionProps) {
|
||||
description={copy.description}
|
||||
/>
|
||||
|
||||
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-4 xl:gap-6">
|
||||
<div className="grid grid-cols-1 gap-5 md:grid-cols-2 xl:grid-cols-4">
|
||||
{copy.items.map((item, index) => {
|
||||
const Icon = capabilityIcons[index] ?? Globe;
|
||||
|
||||
return (
|
||||
<AppCard
|
||||
<div
|
||||
key={item.title}
|
||||
layer="single"
|
||||
interactive
|
||||
className="group border-border/80 bg-surface-2 transition-all duration-300 hover:-translate-y-1 hover:border-border-strong hover:shadow-panel"
|
||||
className="group flex h-full flex-col gap-5 rounded-surface border border-border bg-surface-1 p-6 shadow-card transition duration-300 ease-out hover:-translate-y-1 hover:shadow-panel"
|
||||
>
|
||||
<div className="flex h-full flex-col gap-5 p-6">
|
||||
<div className="flex h-11 w-11 items-center justify-center rounded-nested border border-border/70 bg-background text-foreground transition-transform duration-300 group-hover:-translate-y-0.5">
|
||||
<div className="flex h-12 w-12 items-center justify-center rounded-nested bg-brand-primary/10 text-brand-primary transition-transform duration-300 group-hover:-translate-y-0.5">
|
||||
<Icon className="h-5 w-5" />
|
||||
</div>
|
||||
<div className="space-y-3">
|
||||
<h3 className="text-xl font-semibold tracking-[-0.04em] text-foreground">
|
||||
<div className="space-y-2">
|
||||
<h3 className="text-title font-semibold text-foreground">
|
||||
{item.title}
|
||||
</h3>
|
||||
<p className="text-sm leading-7 text-muted-foreground">{item.description}</p>
|
||||
<p className="text-small leading-relaxed text-muted-foreground">{item.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
</AppCard>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import { AppCard } from "@/components/ui/app-card";
|
||||
import { SectionHeading } from "./section-heading";
|
||||
import type { ProcessSectionCopy } from "./types";
|
||||
|
||||
@@ -8,35 +7,28 @@ type ProcessSectionProps = {
|
||||
|
||||
export function ProcessSection({ copy }: ProcessSectionProps) {
|
||||
return (
|
||||
<section className="space-y-8">
|
||||
<section className="space-y-10">
|
||||
<SectionHeading
|
||||
eyebrow={copy.eyebrow}
|
||||
title={copy.title}
|
||||
description={copy.description}
|
||||
/>
|
||||
|
||||
<div className="grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-4 xl:gap-6">
|
||||
<ol className="grid grid-cols-1 gap-x-8 gap-y-10 sm:grid-cols-2 lg:grid-cols-4">
|
||||
{copy.steps.map((step, index) => (
|
||||
<AppCard
|
||||
key={step.title}
|
||||
layer="single"
|
||||
interactive
|
||||
className="group border-border/80 bg-surface-2 transition-all duration-300 hover:-translate-y-1 hover:border-border-strong hover:shadow-panel"
|
||||
>
|
||||
<div className="flex h-full flex-col gap-5 p-6">
|
||||
<p className="text-sm font-semibold tracking-[0.18em] text-muted-foreground">
|
||||
<li key={step.title} className="border-t border-border pt-5">
|
||||
<span className="block text-[2.75rem] font-semibold leading-none tracking-tight text-brand-primary/25">
|
||||
{String(index + 1).padStart(2, "0")}
|
||||
</p>
|
||||
<div className="space-y-3">
|
||||
<h3 className="text-2xl font-semibold tracking-[-0.05em] text-foreground">
|
||||
</span>
|
||||
<h3 className="mt-5 text-title font-semibold text-foreground">
|
||||
{step.title}
|
||||
</h3>
|
||||
<p className="text-sm leading-7 text-muted-foreground">{step.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
</AppCard>
|
||||
<p className="mt-2 text-small leading-relaxed text-muted-foreground">
|
||||
{step.description}
|
||||
</p>
|
||||
</li>
|
||||
))}
|
||||
</div>
|
||||
</ol>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -23,13 +23,13 @@ export function SectionHeading({
|
||||
className,
|
||||
)}
|
||||
>
|
||||
<p className="text-xs font-semibold uppercase tracking-[0.16em] text-muted-foreground">
|
||||
<p className="eyebrow text-caption font-medium text-brand-primary">
|
||||
{eyebrow}
|
||||
</p>
|
||||
<h2 className="max-w-4xl text-balance text-3xl font-semibold tracking-[-0.05em] text-foreground sm:text-4xl lg:text-5xl">
|
||||
<h2 className="max-w-4xl text-balance text-h2 text-foreground">
|
||||
{title}
|
||||
</h2>
|
||||
<p className="max-w-3xl text-sm leading-7 text-muted-foreground sm:text-[1.02rem]">
|
||||
<p className={cn("text-body-lg text-muted-foreground", align === "center" ? "mx-auto" : "max-w-2xl")}>
|
||||
{description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user