feat(marketing): editorial fonts (Fraunces/Newsreader/JetBrains Mono) site-wide
Loading:
- Fraunces, Newsreader, JetBrains_Mono added to (marketing)/layout.tsx
as CSS variables -- one load point, cached for all marketing pages
- 3 utility classes added to globals.css: .font-fraunces, .font-newsreader,
.font-jetbrains
- about/page.tsx: removed duplicate font loading (now from layout)
Font roles applied:
Fraunces → all h1/h2/h3 headings + blog card titles + hero h1 (italic)
Newsreader → long prose blocks: TheProblem, FounderStory card, Privacy
intro, HeirloomVision description, blog article paragraphs,
blog post excerpt
JetBrains → all small uppercase eyebrow labels across every section
Geist → nav, buttons, feature card body, short UI text (unchanged)
Pages updated: homepage, blog listing, blog articles, pricing, partners
About page: fonts resolve identically via layout variables, no visual change
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2a450c7644
commit
c523533531
8 changed files with 72 additions and 66 deletions
|
|
@ -1,29 +1,9 @@
|
||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { Fraunces, Newsreader, JetBrains_Mono } from "next/font/google";
|
|
||||||
import { AboutScrollReveal } from "@/components/marketing/AboutScrollReveal";
|
import { AboutScrollReveal } from "@/components/marketing/AboutScrollReveal";
|
||||||
|
|
||||||
// ── Fonts loaded only for this page ──────────────────────────────
|
// Fonts (Fraunces, Newsreader, JetBrains Mono) are now loaded globally
|
||||||
const fraunces = Fraunces({
|
// in (marketing)/layout.tsx and available via CSS variables.
|
||||||
subsets: ["latin"],
|
|
||||||
variable: "--font-fraunces",
|
|
||||||
weight: ["300", "400", "500", "600"],
|
|
||||||
style: ["normal", "italic"],
|
|
||||||
display: "swap",
|
|
||||||
});
|
|
||||||
const newsreader = Newsreader({
|
|
||||||
subsets: ["latin"],
|
|
||||||
variable: "--font-newsreader",
|
|
||||||
weight: ["300", "400", "500", "600"],
|
|
||||||
style: ["normal", "italic"],
|
|
||||||
display: "swap",
|
|
||||||
});
|
|
||||||
const jetbrainsMono = JetBrains_Mono({
|
|
||||||
subsets: ["latin"],
|
|
||||||
variable: "--font-jetbrains",
|
|
||||||
weight: ["400", "500"],
|
|
||||||
display: "swap",
|
|
||||||
});
|
|
||||||
|
|
||||||
// ── Page-level styles (design tokens + letter layout) ─────────────
|
// ── Page-level styles (design tokens + letter layout) ─────────────
|
||||||
const CSS = `
|
const CSS = `
|
||||||
|
|
@ -318,7 +298,7 @@ const CREED = [
|
||||||
|
|
||||||
export default function AboutPage() {
|
export default function AboutPage() {
|
||||||
return (
|
return (
|
||||||
<div className={`${fraunces.variable} ${newsreader.variable} ${jetbrainsMono.variable}`}>
|
<div>
|
||||||
{/* Page-specific design system — inline so it's scoped and SSR-safe */}
|
{/* Page-specific design system — inline so it's scoped and SSR-safe */}
|
||||||
{/* eslint-disable-next-line react/no-danger */}
|
{/* eslint-disable-next-line react/no-danger */}
|
||||||
<style dangerouslySetInnerHTML={{ __html: CSS }} />
|
<style dangerouslySetInnerHTML={{ __html: CSS }} />
|
||||||
|
|
|
||||||
|
|
@ -102,10 +102,10 @@ export default async function BlogPostPage({
|
||||||
<span className="text-xs text-gray-400">{post.readTime}</span>
|
<span className="text-xs text-gray-400">{post.readTime}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h1 className="text-3xl sm:text-4xl font-bold text-gray-900 leading-tight mb-4">
|
<h1 className="font-fraunces italic text-3xl sm:text-4xl font-bold text-gray-900 leading-tight mb-4">
|
||||||
{post.emoji} {post.title}
|
{post.emoji} {post.title}
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-lg text-gray-500 leading-relaxed">{post.excerpt}</p>
|
<p className="font-newsreader text-lg text-gray-500 leading-relaxed">{post.excerpt}</p>
|
||||||
|
|
||||||
<div className="mt-5 text-sm text-gray-400">
|
<div className="mt-5 text-sm text-gray-400">
|
||||||
By <span className="text-gray-600 font-medium">{post.author}</span>
|
By <span className="text-gray-600 font-medium">{post.author}</span>
|
||||||
|
|
@ -132,7 +132,7 @@ export default async function BlogPostPage({
|
||||||
{/* ── LEFT SIDEBAR: Table of Contents ── */}
|
{/* ── LEFT SIDEBAR: Table of Contents ── */}
|
||||||
<aside className="hidden lg:block">
|
<aside className="hidden lg:block">
|
||||||
<div className="sticky top-24">
|
<div className="sticky top-24">
|
||||||
<p className="text-xs font-bold text-gray-400 uppercase tracking-widest mb-4">In this article</p>
|
<p className="font-jetbrains text-xs font-bold text-gray-400 uppercase tracking-widest mb-4">In this article</p>
|
||||||
{headings.length > 0 ? (
|
{headings.length > 0 ? (
|
||||||
<ol className="flex flex-col gap-2">
|
<ol className="flex flex-col gap-2">
|
||||||
{headings.map((h, i) => (
|
{headings.map((h, i) => (
|
||||||
|
|
@ -172,14 +172,14 @@ export default async function BlogPostPage({
|
||||||
{section.heading && (
|
{section.heading && (
|
||||||
<h2
|
<h2
|
||||||
id={slugifyHeading(section.heading)}
|
id={slugifyHeading(section.heading)}
|
||||||
className="text-xl font-bold text-gray-900 mb-4 mt-2 scroll-mt-28"
|
className="font-fraunces text-xl font-bold text-gray-900 mb-4 mt-2 scroll-mt-28"
|
||||||
>
|
>
|
||||||
{section.heading}
|
{section.heading}
|
||||||
</h2>
|
</h2>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{section.paragraphs?.map((p, j) => (
|
{section.paragraphs?.map((p, j) => (
|
||||||
<p key={j} className="text-gray-600 leading-relaxed mb-4">
|
<p key={j} className="font-newsreader text-gray-600 leading-relaxed mb-4">
|
||||||
{p}
|
{p}
|
||||||
</p>
|
</p>
|
||||||
))}
|
))}
|
||||||
|
|
@ -244,7 +244,7 @@ export default async function BlogPostPage({
|
||||||
<div className="mt-14 pt-10 border-t border-gray-100">
|
<div className="mt-14 pt-10 border-t border-gray-100">
|
||||||
<div className="bg-gradient-to-br from-rose-50 to-pink-50 rounded-2xl p-8 text-center border border-rose-100">
|
<div className="bg-gradient-to-br from-rose-50 to-pink-50 rounded-2xl p-8 text-center border border-rose-100">
|
||||||
<div className="text-3xl mb-3">🌸</div>
|
<div className="text-3xl mb-3">🌸</div>
|
||||||
<h3 className="text-xl font-bold text-gray-900 mb-2">Try Tia — free during early access</h3>
|
<h3 className="font-fraunces text-xl font-bold text-gray-900 mb-2">Try Tia — free during early access</h3>
|
||||||
<p className="text-gray-500 text-sm mb-6 max-w-sm mx-auto">
|
<p className="text-gray-500 text-sm mb-6 max-w-sm mx-auto">
|
||||||
Log feeds, track vaccinations, and build a digital heirloom for your child. Built for Indian families.
|
Log feeds, track vaccinations, and build a digital heirloom for your child. Built for Indian families.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -277,7 +277,7 @@ export default async function BlogPostPage({
|
||||||
|
|
||||||
{/* More articles */}
|
{/* More articles */}
|
||||||
<div>
|
<div>
|
||||||
<p className="text-xs font-bold text-gray-400 uppercase tracking-widest mb-4">More articles</p>
|
<p className="font-jetbrains text-xs font-bold text-gray-400 uppercase tracking-widest mb-4">More articles</p>
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
{otherPosts.map((p) => (
|
{otherPosts.map((p) => (
|
||||||
<Link
|
<Link
|
||||||
|
|
@ -301,7 +301,7 @@ export default async function BlogPostPage({
|
||||||
|
|
||||||
{/* Category badge */}
|
{/* Category badge */}
|
||||||
<div>
|
<div>
|
||||||
<p className="text-xs font-bold text-gray-400 uppercase tracking-widest mb-3">Filed under</p>
|
<p className="font-jetbrains text-xs font-bold text-gray-400 uppercase tracking-widest mb-3">Filed under</p>
|
||||||
<span className={`text-xs font-semibold px-2.5 py-1 rounded-full ${post.categoryColor}`}>
|
<span className={`text-xs font-semibold px-2.5 py-1 rounded-full ${post.categoryColor}`}>
|
||||||
{post.category}
|
{post.category}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
||||||
|
|
@ -63,8 +63,8 @@ export default function BlogPage() {
|
||||||
{/* Page header */}
|
{/* Page header */}
|
||||||
<div className="bg-gradient-to-br from-rose-50 to-pink-50 border-b border-rose-100">
|
<div className="bg-gradient-to-br from-rose-50 to-pink-50 border-b border-rose-100">
|
||||||
<div className="max-w-6xl mx-auto px-5 py-12 text-center">
|
<div className="max-w-6xl mx-auto px-5 py-12 text-center">
|
||||||
<div className="mb-2 text-sm font-medium text-rose-500 uppercase tracking-widest">Journal</div>
|
<div className="font-jetbrains mb-2 text-sm font-medium text-rose-500 uppercase tracking-widest">Journal</div>
|
||||||
<h1 className="text-4xl font-bold text-gray-900 mb-3 leading-tight">The Tia Blog</h1>
|
<h1 className="font-fraunces italic text-4xl font-bold text-gray-900 mb-3 leading-tight">The Tia Blog</h1>
|
||||||
<p className="text-base text-gray-500 leading-relaxed max-w-xl mx-auto">
|
<p className="text-base text-gray-500 leading-relaxed max-w-xl mx-auto">
|
||||||
Practical guides on baby feeding, health, vaccination schedules, and getting the most out of Tia — for Indian families.
|
Practical guides on baby feeding, health, vaccination schedules, and getting the most out of Tia — for Indian families.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -83,7 +83,7 @@ export default function BlogPage() {
|
||||||
{/* ── LEFT SIDEBAR: timeline ── */}
|
{/* ── LEFT SIDEBAR: timeline ── */}
|
||||||
<aside className="hidden lg:block">
|
<aside className="hidden lg:block">
|
||||||
<div className="sticky top-24">
|
<div className="sticky top-24">
|
||||||
<p className="text-xs font-bold text-gray-400 uppercase tracking-widest mb-5">All posts</p>
|
<p className="font-jetbrains text-xs font-bold text-gray-400 uppercase tracking-widest mb-5">All posts</p>
|
||||||
<ol className="relative border-l-2 border-rose-100 pl-4 space-y-5">
|
<ol className="relative border-l-2 border-rose-100 pl-4 space-y-5">
|
||||||
{POSTS.map((p) => (
|
{POSTS.map((p) => (
|
||||||
<li key={p.slug} className="group relative">
|
<li key={p.slug} className="group relative">
|
||||||
|
|
@ -134,7 +134,7 @@ export default function BlogPage() {
|
||||||
<span className="text-xs text-gray-400">{post.readTime}</span>
|
<span className="text-xs text-gray-400">{post.readTime}</span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h2 className="text-lg font-bold text-gray-900 leading-snug mb-2 group-hover:text-rose-700 transition-colors duration-150">
|
<h2 className="font-fraunces text-lg font-bold text-gray-900 leading-snug mb-2 group-hover:text-rose-700 transition-colors duration-150">
|
||||||
{post.title}
|
{post.title}
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-gray-500 text-sm leading-relaxed line-clamp-2">
|
<p className="text-gray-500 text-sm leading-relaxed line-clamp-2">
|
||||||
|
|
@ -158,7 +158,7 @@ export default function BlogPage() {
|
||||||
|
|
||||||
{/* Categories */}
|
{/* Categories */}
|
||||||
<div>
|
<div>
|
||||||
<p className="text-xs font-bold text-gray-400 uppercase tracking-widest mb-4">Browse by topic</p>
|
<p className="font-jetbrains text-xs font-bold text-gray-400 uppercase tracking-widest mb-4">Browse by topic</p>
|
||||||
<div className="flex flex-col gap-2.5">
|
<div className="flex flex-col gap-2.5">
|
||||||
{CATEGORIES.map((cat) => (
|
{CATEGORIES.map((cat) => (
|
||||||
<div key={cat.name} className="flex items-center justify-between">
|
<div key={cat.name} className="flex items-center justify-between">
|
||||||
|
|
@ -176,7 +176,7 @@ export default function BlogPage() {
|
||||||
|
|
||||||
{/* Quick links */}
|
{/* Quick links */}
|
||||||
<div>
|
<div>
|
||||||
<p className="text-xs font-bold text-gray-400 uppercase tracking-widest mb-4">Quick reads</p>
|
<p className="font-jetbrains text-xs font-bold text-gray-400 uppercase tracking-widest mb-4">Quick reads</p>
|
||||||
<div className="flex flex-col gap-3">
|
<div className="flex flex-col gap-3">
|
||||||
{POSTS.slice(0, 3).map((p) => (
|
{POSTS.slice(0, 3).map((p) => (
|
||||||
<Link
|
<Link
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,30 @@
|
||||||
import type { Metadata } from "next";
|
import type { Metadata } from "next";
|
||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
|
import { Fraunces, Newsreader, JetBrains_Mono } from "next/font/google";
|
||||||
import { MarketingNav } from "@/components/marketing/MarketingNav";
|
import { MarketingNav } from "@/components/marketing/MarketingNav";
|
||||||
|
|
||||||
|
// ── Editorial fonts — loaded once for all marketing pages ─────────
|
||||||
|
const fraunces = Fraunces({
|
||||||
|
subsets: ["latin"],
|
||||||
|
variable: "--font-fraunces",
|
||||||
|
weight: ["300", "400", "500", "600"],
|
||||||
|
style: ["normal", "italic"],
|
||||||
|
display: "swap",
|
||||||
|
});
|
||||||
|
const newsreader = Newsreader({
|
||||||
|
subsets: ["latin"],
|
||||||
|
variable: "--font-newsreader",
|
||||||
|
weight: ["300", "400", "500", "600"],
|
||||||
|
style: ["normal", "italic"],
|
||||||
|
display: "swap",
|
||||||
|
});
|
||||||
|
const jetbrainsMono = JetBrains_Mono({
|
||||||
|
subsets: ["latin"],
|
||||||
|
variable: "--font-jetbrains",
|
||||||
|
weight: ["400", "500"],
|
||||||
|
display: "swap",
|
||||||
|
});
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: {
|
title: {
|
||||||
default: "Tia — Your baby's digital heirloom",
|
default: "Tia — Your baby's digital heirloom",
|
||||||
|
|
@ -30,9 +53,7 @@ export default function MarketingLayout({
|
||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<>
|
<div className={`${fraunces.variable} ${newsreader.variable} ${jetbrainsMono.variable}`}>
|
||||||
{/* Scroll-reveal nav — appears after scrolling past hero */}
|
|
||||||
{/* Analytics now provided globally by Umami in root layout.tsx */}
|
|
||||||
<MarketingNav />
|
<MarketingNav />
|
||||||
|
|
||||||
<main>{children}</main>
|
<main>{children}</main>
|
||||||
|
|
@ -104,6 +125,6 @@ export default function MarketingLayout({
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</footer>
|
</footer>
|
||||||
</>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@ function Hero() {
|
||||||
<span>✨</span> Free during early access
|
<span>✨</span> Free during early access
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<h1 className="text-4xl sm:text-5xl font-bold text-gray-900 leading-tight mb-5">
|
<h1 className="font-fraunces italic text-4xl sm:text-5xl font-bold text-gray-900 leading-tight mb-5">
|
||||||
Your baby's story,{" "}
|
Your baby's story,{" "}
|
||||||
<span className="text-rose-500" style={{ fontFamily: "var(--font-caveat)", fontSize: "1.1em" }}>
|
<span className="text-rose-500" style={{ fontFamily: "var(--font-caveat)", fontSize: "1.1em" }}>
|
||||||
preserved for a lifetime.
|
preserved for a lifetime.
|
||||||
|
|
@ -102,14 +102,14 @@ function TheProblem() {
|
||||||
return (
|
return (
|
||||||
<section className="py-20 px-5 bg-white">
|
<section className="py-20 px-5 bg-white">
|
||||||
<div className="max-w-2xl mx-auto">
|
<div className="max-w-2xl mx-auto">
|
||||||
<p className="text-xs font-semibold text-rose-500 uppercase tracking-widest mb-4">The 3am reality</p>
|
<p className="font-jetbrains text-xs font-semibold text-rose-500 uppercase tracking-widest mb-4">The 3am reality</p>
|
||||||
|
|
||||||
<h2 className="text-3xl font-bold text-gray-900 mb-6 leading-tight">
|
<h2 className="font-fraunces text-3xl font-bold text-gray-900 mb-6 leading-tight">
|
||||||
You're awake at 3am.<br />
|
You're awake at 3am.<br />
|
||||||
When did she last feed?
|
When did she last feed?
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div className="space-y-4 text-gray-600 leading-relaxed">
|
<div className="font-newsreader space-y-4 text-gray-600 leading-relaxed">
|
||||||
<p>
|
<p>
|
||||||
You scroll back through WhatsApp messages to your mother-in-law. You check a
|
You scroll back through WhatsApp messages to your mother-in-law. You check a
|
||||||
sticky note on the refrigerator. You open a notes app you downloaded last week
|
sticky note on the refrigerator. You open a notes app you downloaded last week
|
||||||
|
|
@ -186,8 +186,8 @@ function Features() {
|
||||||
return (
|
return (
|
||||||
<section className="py-20 px-5 bg-gray-50">
|
<section className="py-20 px-5 bg-gray-50">
|
||||||
<div className="max-w-5xl mx-auto">
|
<div className="max-w-5xl mx-auto">
|
||||||
<p className="text-xs font-semibold text-rose-500 uppercase tracking-widest mb-4 text-center">What Tia does</p>
|
<p className="font-jetbrains text-xs font-semibold text-rose-500 uppercase tracking-widest mb-4 text-center">What Tia does</p>
|
||||||
<h2 className="text-3xl font-bold text-gray-900 text-center mb-12">
|
<h2 className="font-fraunces text-3xl font-bold text-gray-900 text-center mb-12">
|
||||||
Everything in one private place.
|
Everything in one private place.
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
|
|
@ -200,7 +200,7 @@ function Features() {
|
||||||
<span className="text-3xl mb-4 transition-transform duration-200 group-hover:scale-110 block">
|
<span className="text-3xl mb-4 transition-transform duration-200 group-hover:scale-110 block">
|
||||||
{f.icon}
|
{f.icon}
|
||||||
</span>
|
</span>
|
||||||
<h3 className="font-bold text-gray-900 text-lg mb-2">{f.title}</h3>
|
<h3 className="font-fraunces font-bold text-gray-900 text-lg mb-2">{f.title}</h3>
|
||||||
<p
|
<p
|
||||||
className="text-gray-600 text-sm leading-relaxed mb-4 flex-1"
|
className="text-gray-600 text-sm leading-relaxed mb-4 flex-1"
|
||||||
dangerouslySetInnerHTML={{ __html: f.body }}
|
dangerouslySetInnerHTML={{ __html: f.body }}
|
||||||
|
|
@ -221,14 +221,14 @@ function FounderStory() {
|
||||||
return (
|
return (
|
||||||
<section className="py-20 px-5 bg-white">
|
<section className="py-20 px-5 bg-white">
|
||||||
<div className="max-w-2xl mx-auto">
|
<div className="max-w-2xl mx-auto">
|
||||||
<p className="text-xs font-semibold text-rose-500 uppercase tracking-widest mb-4">Why Tia exists</p>
|
<p className="font-jetbrains text-xs font-semibold text-rose-500 uppercase tracking-widest mb-4">Why Tia exists</p>
|
||||||
|
|
||||||
<h2 className="text-3xl font-bold text-gray-900 mb-3 leading-tight">
|
<h2 className="font-fraunces text-3xl font-bold text-gray-900 mb-3 leading-tight">
|
||||||
TIA began with a promise.
|
TIA began with a promise.
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<div className="bg-amber-50 border border-amber-200 rounded-2xl p-6 sm:p-8 mt-6">
|
<div className="bg-amber-50 border border-amber-200 rounded-2xl p-6 sm:p-8 mt-6">
|
||||||
<div className="text-gray-700 leading-relaxed space-y-4 text-sm sm:text-base">
|
<div className="font-newsreader text-gray-700 leading-relaxed space-y-4 text-sm sm:text-base">
|
||||||
<p>
|
<p>
|
||||||
When our daughter, Tia, was born, we wanted to remember everything — the tiny
|
When our daughter, Tia, was born, we wanted to remember everything — the tiny
|
||||||
stretches, the sleepy smiles, the moments that felt too precious to forget. But we
|
stretches, the sleepy smiles, the moments that felt too precious to forget. But we
|
||||||
|
|
@ -280,16 +280,16 @@ function HeirloomVision() {
|
||||||
return (
|
return (
|
||||||
<section className="py-20 px-5 bg-gradient-to-br from-rose-50 to-amber-50">
|
<section className="py-20 px-5 bg-gradient-to-br from-rose-50 to-amber-50">
|
||||||
<div className="max-w-2xl mx-auto text-center">
|
<div className="max-w-2xl mx-auto text-center">
|
||||||
<p className="text-xs font-semibold text-rose-500 uppercase tracking-widest mb-4">The heirloom vision</p>
|
<p className="font-jetbrains text-xs font-semibold text-rose-500 uppercase tracking-widest mb-4">The heirloom vision</p>
|
||||||
|
|
||||||
<h2 className="text-3xl font-bold text-gray-900 mb-6 leading-tight">
|
<h2 className="font-fraunces text-3xl font-bold text-gray-900 mb-6 leading-tight">
|
||||||
One day, your child will be able to{" "}
|
One day, your child will be able to{" "}
|
||||||
<span className="text-rose-500" style={{ fontFamily: "var(--font-caveat)", fontSize: "1.1em" }}>
|
<span className="text-rose-500" style={{ fontFamily: "var(--font-caveat)", fontSize: "1.1em" }}>
|
||||||
read their own story.
|
read their own story.
|
||||||
</span>
|
</span>
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<p className="text-gray-600 leading-relaxed mb-8 max-w-xl mx-auto">
|
<p className="font-newsreader text-gray-600 leading-relaxed mb-8 max-w-xl mx-auto">
|
||||||
Everything you log today is a letter to your future child. The 2:47am feed.
|
Everything you log today is a letter to your future child. The 2:47am feed.
|
||||||
The first solid. The doctor visit you worried about for a week. The photo from
|
The first solid. The doctor visit you worried about for a week. The photo from
|
||||||
the moment you realised she could recognise your voice.
|
the moment you realised she could recognise your voice.
|
||||||
|
|
@ -303,7 +303,7 @@ function HeirloomVision() {
|
||||||
].map(item => (
|
].map(item => (
|
||||||
<div key={item.title} className="bg-white/80 rounded-2xl p-5 border border-rose-100 hover:border-rose-300 hover:shadow-sm transition-all duration-200">
|
<div key={item.title} className="bg-white/80 rounded-2xl p-5 border border-rose-100 hover:border-rose-300 hover:shadow-sm transition-all duration-200">
|
||||||
<span className="text-2xl mb-3 block">{item.icon}</span>
|
<span className="text-2xl mb-3 block">{item.icon}</span>
|
||||||
<h3 className="font-bold text-gray-900 mb-1">{item.title}</h3>
|
<h3 className="font-fraunces font-bold text-gray-900 mb-1">{item.title}</h3>
|
||||||
<p className="text-sm text-gray-600 leading-relaxed">{item.desc}</p>
|
<p className="text-sm text-gray-600 leading-relaxed">{item.desc}</p>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
@ -318,14 +318,14 @@ function Privacy() {
|
||||||
return (
|
return (
|
||||||
<section className="py-20 px-5 bg-white">
|
<section className="py-20 px-5 bg-white">
|
||||||
<div className="max-w-2xl mx-auto">
|
<div className="max-w-2xl mx-auto">
|
||||||
<p className="text-xs font-semibold text-rose-500 uppercase tracking-widest mb-4">Privacy & trust</p>
|
<p className="font-jetbrains text-xs font-semibold text-rose-500 uppercase tracking-widest mb-4">Privacy & trust</p>
|
||||||
|
|
||||||
<h2 className="text-3xl font-bold text-gray-900 mb-4">
|
<h2 className="font-fraunces text-3xl font-bold text-gray-900 mb-4">
|
||||||
We don't sell your data —<br />
|
We don't sell your data —<br />
|
||||||
<span className="text-rose-500">we preserve it.</span>
|
<span className="text-rose-500">we preserve it.</span>
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
<p className="text-gray-600 leading-relaxed mb-8">
|
<p className="font-newsreader text-gray-600 leading-relaxed mb-8">
|
||||||
Tia is a baby-tracking app. Your child's records are not the product.
|
Tia is a baby-tracking app. Your child's records are not the product.
|
||||||
They are the point.
|
They are the point.
|
||||||
</p>
|
</p>
|
||||||
|
|
@ -356,8 +356,8 @@ function EarlyAccess() {
|
||||||
return (
|
return (
|
||||||
<section className="py-16 px-5 bg-gray-50 border-y border-gray-100">
|
<section className="py-16 px-5 bg-gray-50 border-y border-gray-100">
|
||||||
<div className="max-w-2xl mx-auto">
|
<div className="max-w-2xl mx-auto">
|
||||||
<p className="text-xs font-semibold text-rose-500 uppercase tracking-widest mb-4 text-center">Private early access</p>
|
<p className="font-jetbrains text-xs font-semibold text-rose-500 uppercase tracking-widest mb-4 text-center">Private early access</p>
|
||||||
<h2 className="text-2xl font-bold text-gray-900 text-center mb-6">
|
<h2 className="font-fraunces text-2xl font-bold text-gray-900 text-center mb-6">
|
||||||
Built by a parent, being tested by parents.
|
Built by a parent, being tested by parents.
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
|
|
@ -368,7 +368,7 @@ function EarlyAccess() {
|
||||||
].map(item => (
|
].map(item => (
|
||||||
<div key={item.title} className="bg-white rounded-2xl p-5 border border-gray-100 shadow-sm">
|
<div key={item.title} className="bg-white rounded-2xl p-5 border border-gray-100 shadow-sm">
|
||||||
<span className="text-2xl mb-3 block">{item.icon}</span>
|
<span className="text-2xl mb-3 block">{item.icon}</span>
|
||||||
<h3 className="font-bold text-gray-900 mb-2">{item.title}</h3>
|
<h3 className="font-fraunces font-bold text-gray-900 mb-2">{item.title}</h3>
|
||||||
<p className="text-sm text-gray-600 leading-relaxed">{item.desc}</p>
|
<p className="text-sm text-gray-600 leading-relaxed">{item.desc}</p>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
@ -383,7 +383,7 @@ function FinalCTA() {
|
||||||
return (
|
return (
|
||||||
<section className="py-24 px-5 bg-gradient-to-br from-rose-500 to-rose-600 text-white text-center">
|
<section className="py-24 px-5 bg-gradient-to-br from-rose-500 to-rose-600 text-white text-center">
|
||||||
<div className="max-w-xl mx-auto">
|
<div className="max-w-xl mx-auto">
|
||||||
<h2 className="text-3xl sm:text-4xl font-bold mb-4 leading-tight">
|
<h2 className="font-fraunces text-3xl sm:text-4xl font-bold mb-4 leading-tight">
|
||||||
Start preserving your<br />child's story today.
|
Start preserving your<br />child's story today.
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,8 @@ export default function PartnersPage() {
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-white">
|
<div className="min-h-screen bg-white">
|
||||||
<div className="max-w-2xl mx-auto px-5 py-20">
|
<div className="max-w-2xl mx-auto px-5 py-20">
|
||||||
<div className="mb-3 text-sm font-medium text-rose-500 uppercase tracking-widest">Work with us</div>
|
<div className="font-jetbrains mb-3 text-sm font-medium text-rose-500 uppercase tracking-widest">Work with us</div>
|
||||||
<h1 className="text-4xl font-bold text-gray-900 mb-6 leading-tight">Partners</h1>
|
<h1 className="font-fraunces text-4xl font-bold text-gray-900 mb-6 leading-tight">Partners</h1>
|
||||||
|
|
||||||
<div className="text-gray-600 leading-relaxed space-y-5 mb-10">
|
<div className="text-gray-600 leading-relaxed space-y-5 mb-10">
|
||||||
<p>
|
<p>
|
||||||
|
|
|
||||||
|
|
@ -16,9 +16,9 @@ export const metadata: Metadata = {
|
||||||
export default function PricingPage() {
|
export default function PricingPage() {
|
||||||
return (
|
return (
|
||||||
<div className="max-w-2xl mx-auto px-4 py-20">
|
<div className="max-w-2xl mx-auto px-4 py-20">
|
||||||
<p className="text-xs font-semibold text-rose-500 uppercase tracking-widest mb-4 text-center">Pricing</p>
|
<p className="font-jetbrains text-xs font-semibold text-rose-500 uppercase tracking-widest mb-4 text-center">Pricing</p>
|
||||||
|
|
||||||
<h1 className="text-3xl sm:text-4xl font-bold text-gray-900 text-center mb-4">
|
<h1 className="font-fraunces text-3xl sm:text-4xl font-bold text-gray-900 text-center mb-4">
|
||||||
Founder pricing.
|
Founder pricing.
|
||||||
</h1>
|
</h1>
|
||||||
<p className="text-gray-500 text-center mb-12 max-w-md mx-auto">
|
<p className="text-gray-500 text-center mb-12 max-w-md mx-auto">
|
||||||
|
|
|
||||||
|
|
@ -56,6 +56,11 @@
|
||||||
animation: cta-pulse 2.6s ease-out infinite;
|
animation: cta-pulse 2.6s ease-out infinite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ── Editorial font utilities (marketing pages) ── */
|
||||||
|
.font-fraunces { font-family: var(--font-fraunces, Georgia, serif); }
|
||||||
|
.font-newsreader { font-family: var(--font-newsreader, Georgia, serif); }
|
||||||
|
.font-jetbrains { font-family: var(--font-jetbrains, ui-monospace, monospace); }
|
||||||
|
|
||||||
/* hide scrollbar but keep scroll */
|
/* hide scrollbar but keep scroll */
|
||||||
.scrollbar-hide {
|
.scrollbar-hide {
|
||||||
scrollbar-width: none;
|
scrollbar-width: none;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue