Files
mozimo.in/src/app/journal.$slug.tsx
T
tanshu 06f6e75b57 Keep shoppers on mozimo.in: internalize all marketing links
- gifting tab CTAs now point at our /collections pages (seed defaults +
  one-off PB migration rewriting shop.mozimo.in cta_urls, idempotent)
- Hero/Footer/our-world/journal 'shop' links -> /chocolate; bespoke
  bulk-ordering -> /gifting#corporate-bulk
- still on Shopify (deliberate, until Phase 2): PDP buy button, Header
  bag+account, footer policies
2026-09-06 14:48:41 +05:30

116 lines
4.0 KiB
TypeScript

import { createFileRoute, Link } from "@tanstack/react-router";
import Header from "@/components/Header";
import Footer from "@/components/Footer";
import Reveal from "@/components/Reveal";
import Rise from "@/components/Rise";
import { journalPosts } from "@/data/catalog";
export const Route = createFileRoute("/journal/$slug")({
component: JournalArticle,
});
function JournalArticle() {
const { slug } = Route.useParams();
const post = journalPosts.find((p) => p.slug === slug);
if (!post) {
return (
<div className="flex min-h-screen flex-col bg-ivory-50">
<Header />
<main className="wrap flex flex-1 flex-col items-center justify-center py-40 text-center">
<p className="eyebrow text-orange-500">404</p>
<h1 className="display mt-6 text-4xl text-ink-900">
This page has been{" "}
<em className="italic text-orange-500">eaten.</em>
</h1>
<Link to="/journal" className="btn btn-ghost mt-10">
Back to the Journal
</Link>
</main>
<Footer />
</div>
);
}
return (
<div className="min-h-screen bg-ivory-50">
<Header />
<main>
{/* article hero */}
<section className="relative overflow-hidden bg-ivory-50">
<div className="wrap pb-14 pt-40 md:pt-48">
<Link
to="/journal"
className="link-quiet eyebrow text-orange-600 hover:text-orange-500"
>
The Mozimo Journal
</Link>
<h1 className="display mt-7 max-w-4xl text-[clamp(2.4rem,5.5vw,4.8rem)] text-ink-900">
<Rise delay={0.25}>{post.title}</Rise>
</h1>
<Reveal delay={0.45}>
<p className="eyebrow mt-8 text-[0.62rem]! text-ink-500">
{post.date} · {post.readTime} read
</p>
</Reveal>
</div>
<Reveal delay={0.3} variant="clip">
<div className="wrap">
<img
src={post.image}
alt=""
width={1760}
height={1000}
className="aspect-[21/9] w-full rounded-2xl object-cover"
/>
</div>
</Reveal>
</section>
{/* body */}
<section className="bg-ivory-100 text-ink-900">
<div className="wrap max-w-3xl py-16 md:py-24">
{post.body.map((para, i) => (
<Reveal key={i} delay={Math.min(i * 0.05, 0.3)}>
<p className="mt-7 text-[1.08rem] leading-[1.85] text-ink-700 first:mt-0 first:text-[1.2rem] first:leading-[1.7] first:text-ink-900">
{para}
</p>
{post.pullQuote && i === 1 && (
<blockquote className="my-12 text-center">
<p className="display text-[clamp(1.6rem,3.5vw,2.6rem)] italic text-orange-500">
&ldquo;{post.pullQuote}&rdquo;
</p>
<footer className="rule mx-auto mt-8 w-40" />
</blockquote>
)}
</Reveal>
))}
<Reveal delay={0.2}>
<div className="mt-16 border-t border-ink-900/15 pt-10 text-center">
<p className="font-script text-3xl text-orange-500">
taste the story
</p>
<div className="mt-6 flex flex-wrap justify-center gap-4">
<a
href="/chocolate"
target="_blank"
rel="noopener noreferrer"
className="btn btn-dark"
>
Shop the Collection
</a>
<Link to="/journal" className="btn btn-ghost">
More from the Journal
</Link>
</div>
</div>
</Reveal>
</div>
</section>
</main>
<Footer />
</div>
);
}