Skip to content
Merged
41 changes: 40 additions & 1 deletion app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -298,11 +298,50 @@ a.cta-primary:focus-visible {
outline-offset: 9px;
}

/* The status link under the hero terminal. Raw --whisper is ~3.5:1 on
paper, short of AA at body size, so the value text uses whisper mixed
68% with ink (~6.6:1). The label is ink like the stat labels; the dot
and the arrow keep the full accent. */
a.hero-status {
color: color-mix(in srgb, var(--whisper) 68%, var(--ink));
}

.hero-status-text {
padding-bottom: 1px;
border-bottom: 1px solid transparent;
transition: border-bottom-color 260ms cubic-bezier(0.2, 0.8, 0.2, 1);
}

a.hero-status:hover .hero-status-text {
border-bottom-color: currentColor;
}

a.hero-status .arrow {
margin-right: 0;
transition: transform 260ms cubic-bezier(0.16, 1, 0.3, 1);
}

a.hero-status:hover .arrow {
transform: translateX(6px);
}

.status-live {
width: 7px;
height: 7px;
border-radius: 50%;
background: var(--whisper);
animation: fleet-pulse 2.4s ease-in-out infinite;
}

@media (prefers-reduced-motion: reduce) {
a.cta-primary,
a.cta-primary .arrow {
a.cta-primary .arrow,
a.hero-status .arrow {
transition: none;
}
.status-live {
animation: none;
}
}

/* --- hero terminal -----------------------------------------------------
Expand Down
48 changes: 39 additions & 9 deletions components/site/Hero.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import { links } from "@/lib/links";
import { HERO_FIGURES, HERO_HEADLINE, HERO_LEAD } from "@/lib/copy";
import {
HERO_FIGURES,
HERO_HEADLINE,
HERO_LEAD,
HERO_STATUS,
} from "@/lib/copy";
import { highlightBrand } from "@/components/ui/brand";
import { Figure } from "@/components/ui/Figure";
import { Frame } from "@/components/ui/Frame";
Expand All @@ -25,8 +30,11 @@ export function Hero() {
</span>
</h1>

<div className="grid gap-10 @4xl:grid-cols-[minmax(0,1fr)_minmax(0,440px)] @4xl:items-start @4xl:gap-12">
<div className="flex flex-col gap-8 @4xl:gap-12">
{/* At @4xl the stats and the status link share row 2 so they
baseline-align; below it, DOM order stacks lead/CTAs, stats,
terminal, then the link. */}
<div className="grid gap-y-10 @4xl:grid-cols-[minmax(0,1fr)_minmax(0,440px)] @4xl:items-start @4xl:gap-x-12 @4xl:gap-y-14">
<div className="flex flex-col gap-10 @4xl:col-start-1 @4xl:row-start-1 @4xl:gap-16">
<p className="rise rise-3 max-w-[64ch] text-body leading-[1.65]">
{highlightBrand(HERO_LEAD)}
</p>
Expand Down Expand Up @@ -66,15 +74,37 @@ export function Hero() {
</a>
</div>
</div>
</div>

<div className="rise rise-5 grid grid-cols-2 gap-y-4 @xl:grid-cols-4">
{HERO_FIGURES.map((figure) => (
<Figure key={figure.label} {...figure} />
))}
</div>
<div className="rise rise-5 grid grid-cols-2 gap-y-4 @xl:grid-cols-4 @4xl:col-start-1 @4xl:row-start-2 @4xl:self-baseline">
{HERO_FIGURES.map((figure) => (
<Figure key={figure.label} {...figure} />
))}
</div>

<HeroTerminal className="block w-full" />
<HeroTerminal className="block w-full @4xl:col-start-2 @4xl:row-start-1" />

{/* Mirrors Figure's label/value lines so it baseline-aligns with
the stat strip beside it. */}
<a
className="hero-status rise rise-5 flex flex-col gap-1 justify-self-start @4xl:col-start-2 @4xl:row-start-2 @4xl:self-baseline"
href={links.stats}
target="_blank"
rel="noopener noreferrer"
>
<span className="meta text-ink opacity-60">
{HERO_STATUS.label}
</span>
<span className="flex items-center gap-3 text-body font-medium tracking-[-0.01em]">
<span aria-hidden className="status-live" />
<span className="hero-status-text inline-flex items-center gap-2">
{HERO_STATUS.value}
<span className="arrow" aria-hidden>
→
</span>
</span>
</span>
</a>
</div>
</div>
</Frame>
Expand Down
8 changes: 8 additions & 0 deletions lib/copy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ export const HERO_FIGURES = [
{ label: "gas overhead", value: "<1%" },
] as const satisfies readonly FigureCopy[];

/** The status link under the hero terminal. Shaped like FigureCopy so it
* shares the stat strip's label/value type (rendered inline in Hero, not
* through Figure). */
export const HERO_STATUS = {
label: "see also",
value: "Status website",
} as const satisfies FigureCopy;

export const COMPARE_HEADLINE = [
"information scaled.",
"supply didn't.",
Expand Down
1 change: 1 addition & 0 deletions lib/links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ export const links = {
litepaper: "/decdn_litepaper.pdf",
presskit: "/presskit/decdn-presskit.zip",
docs: "https://docs.decdn.org/overview/introduction",
stats: "https://stats.decdn.org/",
blog: "/blog/",
contact: `mailto:${EMAIL}`,
privacy: "/legal/privacy/",
Expand Down
Loading