9a82a3b0e7
- New design tokens: signal red, ink and paper as RGB channels; ink and paper swap roles in dark mode so every component inverts cleanly - Fonts via next/font: Bricolage Grotesque (with wdth/opsz axes), Geist, Geist Mono; drop Inter and Playfair - Poster hero: kicker, giant DK0 wordmark that reacts to pointer distance (weight and width through a damped spring, desktop only, off for reduced motion), claim as h1, intro with thesis countdown, marquee strip - Header in poster style: transparent over the red hero, paper strip with ink rule when scrolled or on subpages; drawer menu restyled - Remove wavy SVG separators, CSS shader gradient, background blobs and unused providers that caused the pink/purple bands between sections - Drop the global p/span/div color override so colors inherit properly - New hero texts in de/en, tests and i18n key check updated Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
68 lines
2.9 KiB
TypeScript
68 lines
2.9 KiB
TypeScript
import { getTranslations } from "next-intl/server";
|
|
import KineticWordmark from "./KineticWordmark";
|
|
|
|
interface HeroProps {
|
|
locale: string;
|
|
}
|
|
|
|
// Abgabe der Masterarbeit, Grundlage für den Countdown im Intro
|
|
const THESIS_DEADLINE = new Date("2027-02-15T12:00:00+01:00");
|
|
|
|
const MARQUEE = ["Self-Hosting", "Next.js", "SwiftUI", "Flutter", "Docker", "Microsoft 365", "Godot", "Home Assistant"];
|
|
|
|
export default async function Hero({ locale }: HeroProps) {
|
|
const t = await getTranslations({ locale, namespace: "home.hero" });
|
|
const daysLeft = Math.max(0, Math.ceil((THESIS_DEADLINE.getTime() - Date.now()) / 86_400_000));
|
|
|
|
return (
|
|
<>
|
|
<section id="top" className="relative overflow-hidden bg-signal px-4 pt-24 text-ink sm:px-6 md:pt-28 lg:px-10">
|
|
<p className="font-mono text-[13px] leading-snug">{t("kicker")}</p>
|
|
|
|
<div className="mt-4 sm:mt-8">
|
|
<KineticWordmark />
|
|
</div>
|
|
|
|
<div className="mt-3 grid gap-6 border-t-2 border-ink pb-8 pt-6 md:grid-cols-[1.3fr_1fr] md:items-end md:pb-10">
|
|
<h1 className="text-balance font-display text-[clamp(2rem,4.4vw,4rem)] font-extrabold leading-[0.96] tracking-[-0.035em] [font-variation-settings:'wdth'_85]">
|
|
<span className="sr-only">Dennis Konkol: </span>
|
|
{t("claim")}
|
|
</h1>
|
|
<div>
|
|
<p className="max-w-[42ch] text-[17px] leading-relaxed">
|
|
{t("intro")} {daysLeft > 0 && t("countdown", { days: daysLeft })}
|
|
</p>
|
|
<div className="mt-5 flex flex-wrap gap-2.5">
|
|
<a
|
|
href="#projects"
|
|
className="inline-flex items-center gap-2 rounded-full bg-ink px-5 py-3.5 text-[15px] font-semibold text-paper transition-transform duration-150 ease-out active:scale-[0.97]"
|
|
>
|
|
{t("ctaWork")} <span aria-hidden="true">↓</span>
|
|
</a>
|
|
<a
|
|
href="#contact"
|
|
className="inline-flex items-center rounded-full px-5 py-3.5 text-[15px] font-semibold shadow-[inset_0_0_0_1.5px_rgb(var(--plakat-ink))] transition-[background-color,color,transform] duration-150 ease-out hover:bg-ink hover:text-signal active:scale-[0.97]"
|
|
>
|
|
{t("ctaContact")}
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
<div className="overflow-hidden bg-ink text-paper" aria-hidden="true">
|
|
<div className="flex w-max animate-marquee gap-9 py-[18px] font-display text-[clamp(1.1rem,2.4vw,1.7rem)] font-bold leading-none">
|
|
{[...MARQUEE, ...MARQUEE].map((item, i) => (
|
|
<span key={i} className="flex items-center gap-9 whitespace-nowrap">
|
|
{item}
|
|
<svg viewBox="0 0 24 24" className="h-[0.7em] w-[0.7em] fill-signal">
|
|
<path d="M12 1.5l2.6 7.9 7.9 2.6-7.9 2.6-2.6 7.9-2.6-7.9-7.9-2.6 7.9-2.6z" />
|
|
</svg>
|
|
</span>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</>
|
|
);
|
|
}
|