commit fd2120dd6e8324b9bd6210c7414511005f328c90
parent 70939abec880bd5133ae70e3f3491ab64bb4f9a4
Author: I Mean I'm Just Saying <imeanimjustsaying@kiwifarms.st>
Date: Mon, 29 Jun 2026 01:00:02 -0400
Merge chore/simplify-header: constant-size header on all pages
Diffstat:
4 files changed, 23 insertions(+), 89 deletions(-)
diff --git a/homepage/CHANGELOG.md b/homepage/CHANGELOG.md
@@ -32,6 +32,10 @@
to `common`). New homepage Playwright suite (`e2e/landing.spec.ts`) covers every
preset, the symlog small-site visibility, the guard rails, exclude-outlier, indexed,
and mobile. No summary-schema change — everything derives client-side.
+- **Header simplified.** The shrink-on-scroll homepage masthead is removed: the header
+ is now one compact brass-mark + wordmark bar, the same size on every page. The client
+ `SiteHeader` and the homepage headroom spacer are gone; `Header` is a plain server
+ component again.
## 2026-06-28
diff --git a/homepage/app/components/Header.tsx b/homepage/app/components/Header.tsx
@@ -1,10 +1,20 @@
+import Link from "next/link";
import { currentHomepage } from "../lib/homepage";
-import { SiteHeader } from "./SiteHeader";
-// Top nav for the hub. The hub is a single cross-site landing, so the header is
-// just the branding mark + wordmark — large as a masthead on the home page,
-// collapsing to a compact sticky bar on scroll (see SiteHeader).
+// The hub's header: a compact sticky bar with the brass mark + wordmark, the
+// same size on every page.
export default function Header() {
- const config = currentHomepage();
- return <SiteHeader title={config.headerTitle} />;
+ const { headerTitle } = currentHomepage();
+ return (
+ <header className="sticky top-0 z-20 border-b border-[var(--border)] bg-[rgba(12,10,8,0.72)] backdrop-blur-md">
+ <div className="max-w-6xl mx-auto px-5 sm:px-6 flex h-14 items-center">
+ <Link href="/" className="group flex items-center gap-2.5">
+ <span className="h-2.5 w-2.5 shrink-0 rotate-45 rounded-[3px] bg-[var(--accent)] shadow-[0_0_14px_var(--accent)] transition-colors group-hover:bg-[var(--accent-strong)]" />
+ <span className="font-display text-[1.35rem] font-semibold leading-none tracking-tight text-[var(--foreground)]">
+ {headerTitle}
+ </span>
+ </Link>
+ </div>
+ </header>
+ );
}
diff --git a/homepage/app/components/SiteHeader.tsx b/homepage/app/components/SiteHeader.tsx
@@ -1,72 +0,0 @@
-"use client";
-
-import Link from "next/link";
-import { usePathname } from "next/navigation";
-import { useEffect, useState } from "react";
-
-// The hub's single wordmark. On the home page it starts as a large masthead and
-// collapses to the compact header bar the moment you scroll; every other route
-// always shows the compact state. (Merges what used to be a separate hero
-// heading + a small sticky logo into one element.)
-//
-// The header's layout box is pinned to the compact height (h-14) and the wordmark
-// is top-anchored and allowed to overflow it, so growing/shrinking the wordmark
-// changes nothing in the page's flow — `<main>` never reflows on scroll. Only the
-// wordmark's own font-size and the bar's chrome (border/blur) animate. The home
-// page reserves matching headroom (see page.tsx) so content clears the enlarged
-// wordmark.
-export function SiteHeader({ title }: { title: string }) {
- const isHome = usePathname() === "/";
- const [scrolled, setScrolled] = useState(false);
-
- useEffect(() => {
- const onScroll = () => setScrolled(window.scrollY > 4);
- onScroll();
- window.addEventListener("scroll", onScroll, { passive: true });
- return () => window.removeEventListener("scroll", onScroll);
- }, []);
-
- const large = isHome && !scrolled;
-
- return (
- <header
- className={
- "sticky top-0 z-20 transition-[background-color,border-color] duration-300 ease-out " +
- (large
- ? "border-b border-transparent"
- : "border-b border-[var(--border)] bg-[rgba(12,10,8,0.72)] backdrop-blur-md")
- }
- >
- {/* Pinned compact height + top-anchored content. The enlarged wordmark
- overflows this box (overflow visible) without enlarging it, so the page
- layout is identical at every scroll position. The top padding centers the
- compact wordmark in the 56px bar; the large state grows downward from it. */}
- <div className="max-w-6xl mx-auto px-5 sm:px-6 h-14 pt-[18px] flex items-start overflow-visible">
- <Link href="/" className="group flex items-end gap-2.5 sm:gap-3.5">
- <span
- className={
- "shrink-0 rotate-45 rounded-[3px] bg-[var(--accent)] transition-all duration-300 ease-out group-hover:bg-[var(--accent-strong)] " +
- (large
- ? "mb-1.5 h-3.5 w-3.5 sm:h-4 sm:w-4 shadow-[0_0_18px_var(--accent)]"
- : "mb-1 h-2.5 w-2.5 shadow-[0_0_14px_var(--accent)]")
- }
- />
- {isHome ? (
- <h1
- className={
- "font-display font-semibold leading-[0.9] tracking-[-0.02em] text-[var(--foreground)] transition-[font-size] duration-300 ease-out " +
- (large ? "text-4xl sm:text-6xl" : "text-[1.35rem]")
- }
- >
- {title}
- </h1>
- ) : (
- <span className="font-display text-[1.35rem] font-semibold leading-none tracking-tight text-[var(--foreground)]">
- {title}
- </span>
- )}
- </Link>
- </div>
- </header>
- );
-}
diff --git a/homepage/app/page.tsx b/homepage/app/page.tsx
@@ -47,15 +47,7 @@ function loadSummary(): HomepageSummary {
export default function Home() {
const summary = loadSummary();
- // The wordmark masthead lives in the sticky header now (SiteHeader), large at the
- // top and shrinking on scroll. Because the header's box stays compact and the
- // large wordmark overflows it, this fixed-height spacer reserves the headroom the
- // overflowing masthead needs so the landing clears it — constant at every scroll
- // position, so nothing reflows when the wordmark collapses.
- return (
- <>
- <div aria-hidden className="h-7 sm:h-14" />
- <HomeLanding summary={summary} />
- </>
- );
+ // The compact wordmark lives in the sticky header (same on every page), so the
+ // home route starts straight into the landing.
+ return <HomeLanding summary={summary} />;
}