Skip to content

Instantly share code, notes, and snippets.

@fayimora
Created March 5, 2026 00:59
Show Gist options
  • Select an option

  • Save fayimora/dff193ef9cf4d3488d8b2c7dc825dea9 to your computer and use it in GitHub Desktop.

Select an option

Save fayimora/dff193ef9cf4d3488d8b2c7dc825dea9 to your computer and use it in GitHub Desktop.
import { createFileRoute, Link } from "@tanstack/react-router";
import {
BookOpen,
FileText,
Gavel,
Globe,
GraduationCap,
Landmark,
MessageSquare,
Scale,
Shield,
} from "lucide-react";
import { useEffect, useRef, useState } from "react";
import { Button } from "@/components/ui/button";
import { cn } from "@/lib/utils";
export const Route = createFileRoute("/")({
component: LandingV1,
});
/* ---------------------------------------------------------------------------
* Landing Page — "THE FRONT PAGE"
*
* A full-viewport broadsheet newspaper experience. Gold rules draw themselves
* across the screen, sections animate in like editorial columns, and the hero
* headline types itself letter by letter. Every detail — the dateline, the
* volume number, the column rules — is crafted to feel like holding a freshly
* printed broadsheet.
* --------------------------------------------------------------------------- */
const HEADLINE = "Know Where They Stand";
const SUBHEAD =
"Explore Restore Britain's policy positions on housing, taxes, immigration, and more. AI-powered answers sourced directly from their published work";
const TICKER_ITEMS = [
"HOUSING: Social homes reserved for British citizens",
"PUBS: Business rate relief reinstated for community locals",
"ECONOMY: IR35 to be scrapped",
"IMMIGRATION: Net negative immigration target",
"TAXATION: Inheritance tax abolished entirely",
"BENEFITS: Social benefits for British citizens only",
];
const POLICY_COLS: {
icon: typeof Landmark;
label: string;
excerpt: string;
}[] = [
{
icon: Landmark,
label: "Housing",
excerpt:
"British first for social housing. Benefits and council housing reserved for citizens. Support for family formation.",
},
{
icon: Shield,
label: "Immigration",
excerpt:
"Net negative immigration. Abolish the asylum system. Mass deportations of illegal migrants. Red list for high-risk countries.",
},
{
icon: FileText,
label: "Economy",
excerpt:
"Scrap IR35. Lowest corporation tax in Europe. Abolish inheritance tax entirely. Tax remittances to reduce economic migration.",
},
{
icon: BookOpen,
label: "Pubs & Culture",
excerpt:
"Reinstate business rate relief for community pubs. Reduce hospitality VAT to 12.5%. Support for British brewing.",
},
{
icon: Gavel,
label: "Law & Order",
excerpt:
"Restore the death penalty for heinous crimes. Free political prisoners. Abolish non-crime hate incidents. Legalise pepper spray for self-defence.",
},
{
icon: Scale,
label: "Civil Liberties",
excerpt:
"Repeal the Online Safety Act. End the lockdown legacy. Independent inquiry into COVID vaccines. Enshrine free speech in law.",
},
{
icon: GraduationCap,
label: "Education",
excerpt:
"End school holiday fines. Pro-British universities. Justice for Batley teacher. Classroom Freedom Charter for teachers.",
},
{
icon: Globe,
label: "Foreign Policy",
excerpt:
"Scrap foreign aid spending. Every aid project voted case-by-case in Parliament. British money for British people only.",
},
];
function TickerBar() {
const doubled = [...TICKER_ITEMS, ...TICKER_ITEMS];
return (
<div className="relative overflow-hidden border-rb-accent/30 border-y bg-rb-accent/5">
<div className="flex animate-[ticker_32s_linear_infinite] whitespace-nowrap">
{doubled.map((item, i) => (
<span
className="inline-flex shrink-0 items-center gap-3 px-6 py-2 font-sans text-[11px] text-rb-accent uppercase tracking-[0.15em]"
key={`ticker-${item}-${i.toString()}`}
>
<span className="inline-block h-1 w-1 bg-rb-accent opacity-50" />
{item}
</span>
))}
</div>
</div>
);
}
function LandingV1() {
const [visible, setVisible] = useState(false);
const heroRef = useRef<HTMLDivElement>(null);
useEffect(() => {
const t = setTimeout(() => setVisible(true), 50);
return () => clearTimeout(t);
}, []);
return (
<div className="relative flex min-h-dvh flex-col overflow-hidden bg-background">
{/* ---- Gold accent top rule (animated draw) ---- */}
<div
className={cn(
"h-0.75 origin-left bg-rb-accent transition-transform duration-600 ease-out",
visible ? "scale-x-100" : "scale-x-0"
)}
/>
{/* ---- Masthead ---- */}
<header className="relative mx-auto w-full max-w-6xl px-4 pt-4 pb-3 md:px-6 md:pt-6 md:pb-4">
<div
className={cn(
"text-center transition-all duration-500 ease-out",
visible ? "translate-y-0 opacity-100" : "translate-y-4 opacity-0"
)}
>
<h1 className="font-bold font-serif text-3xl text-foreground uppercase tracking-[0.12em] md:text-5xl lg:text-6xl">
Ask Restore Britain
</h1>
<p className="mt-1 font-serif text-muted-foreground text-sm italic tracking-wide">
Independent AI-Powered Policy Analysis
</p>
</div>
{/* Double rule */}
<div className="mt-4 flex flex-col gap-0.75">
<div className="h-0.5 bg-foreground/15" />
<div className="h-px bg-foreground/10" />
</div>
</header>
{/* ---- Ticker bar ---- */}
<TickerBar />
{/* ---- Hero section ---- */}
<section
className="mx-auto flex w-full max-w-6xl flex-1 flex-col items-center justify-center px-4 py-8 md:px-6"
ref={heroRef}
>
<div className="mx-auto max-w-3xl text-center">
<h2
className={cn(
"font-bold font-serif text-2xl text-foreground leading-tight transition-all delay-100 duration-400 md:text-5xl lg:text-6xl",
visible ? "translate-y-0 opacity-100" : "translate-y-4 opacity-0"
)}
>
{HEADLINE}
</h2>
<p
className={cn(
"mx-auto mt-4 max-w-xl font-serif text-muted-foreground text-sm leading-[1.75] transition-all delay-200 duration-400 md:mt-6 md:text-base md:leading-[1.85]",
visible ? "translate-y-0 opacity-100" : "translate-y-3 opacity-0"
)}
>
{SUBHEAD}
</p>
{/* CTA */}
<div
className={cn(
"mt-8 transition-all delay-300 duration-400 md:mt-10",
visible ? "translate-y-0 opacity-100" : "translate-y-3 opacity-0"
)}
>
<Link to="/chat">
<Button
className="h-11 gap-2 border-rb-accent bg-rb-accent px-6 font-serif text-white text-xs uppercase tracking-[0.15em] transition-all hover:bg-rb-accent-hover md:h-12 md:px-8 md:text-sm"
size="lg"
>
<MessageSquare className="h-4 w-4" />
Start a Conversation
</Button>
</Link>
</div>
{/* Source stats */}
<div
className={cn(
"mt-8 flex flex-wrap items-center justify-center gap-x-6 gap-y-2 transition-all delay-400 duration-400 md:mt-10 md:gap-x-8 md:gap-y-3",
visible ? "translate-y-0 opacity-100" : "translate-y-3 opacity-0"
)}
>
{[
{ value: "3", label: "Policy PDFs" },
{ value: "5", label: "Web Pages" },
{ value: "42+", label: "Sections" },
{ value: "100%", label: "Claims Cited" },
].map((stat) => (
<div className="flex items-baseline gap-1.5" key={stat.label}>
<span className="font-bold font-serif text-lg text-rb-accent">
{stat.value}
</span>
<span className="font-sans text-[10px] text-muted-foreground uppercase tracking-[0.15em]">
{stat.label}
</span>
</div>
))}
</div>
</div>
</section>
{/* ---- Editorial columns (anchored to bottom) ---- */}
<section className="mx-auto w-full max-w-6xl shrink-0 px-4 pb-2 md:px-6">
<div className="mb-3 flex items-center gap-3 md:mb-6 md:gap-4">
<div className="h-px flex-1 bg-border" />
<span className="font-sans text-[10px] text-muted-foreground uppercase tracking-[0.3em]">
Key Policy Positions
</span>
<div className="h-px flex-1 bg-border" />
</div>
<div className="grid grid-cols-2 gap-0 border-border border-t md:grid-cols-4 lg:grid-cols-4">
{POLICY_COLS.map((col) => {
const Icon = col.icon;
return (
<article
className="border-border border-r border-b p-3 last:border-r-0 md:nth-4:border-r-0 md:nth-8:border-r-0 md:border-b-0 md:p-5 lg:nth-4:border-r lg:nth-8:border-r-0"
key={col.label}
>
<div className="mb-3 flex items-center gap-2">
<Icon className="h-4 w-4 text-rb-accent" />
<h3 className="font-bold font-sans text-[10px] text-rb-accent uppercase tracking-[0.25em]">
{col.label}
</h3>
</div>
<p className="font-serif text-foreground/75 text-xs leading-[1.75] md:text-sm">
{col.excerpt}
</p>
</article>
);
})}
</div>
</section>
{/* ---- Footer ---- */}
<footer className="border-border border-t bg-card/50">
<div className="mx-auto flex max-w-6xl flex-col items-center justify-between gap-2 px-4 py-3 md:flex-row md:px-6 md:py-4">
<p className="font-sans text-[10px] text-muted-foreground uppercase tracking-[0.15em]">
&copy; {new Date().getFullYear()} Ask Restore Britain
</p>
<p className="font-serif text-muted-foreground/50 text-xs italic">
Independent &middot; AI-Powered &middot; Not affiliated with any
party
</p>
</div>
</footer>
{/* ---- Inline keyframes for ticker ---- */}
<style>
{`
@keyframes ticker {
0% { transform: translateX(0); }
100% { transform: translateX(-50%); }
}
`}
</style>
</div>
);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment