agency-web/app/page.tsx

385 lines
14 KiB
TypeScript

import Link from "next/link";
import {
SITE,
services,
cases,
testimonials,
} from "./content";
import SiteHeader from "./components/SiteHeader";
import Hero from "./components/Hero";
import VelocityMarquee from "./components/VelocityMarquee";
import Reveal, { RevealItem } from "./components/Reveal";
import Scoreboard from "./components/Scoreboard";
import CaseCard, { type CaseData } from "./components/CaseCard";
import ProcessLoop from "./components/ProcessLoop";
import Faq from "./components/Faq";
import Magnetic from "./components/Magnetic";
import SectionDivider from "./components/SectionDivider";
const TAPE = [
"Revenue, not vanity metrics",
"Paid",
"SEO",
"Content",
"Social",
"+52% ROAS",
"+217% demos",
"+128 booked/mo",
"Reported every month",
];
const INDUSTRIES = [
"E-commerce",
"B2B SaaS",
"Clinics",
"Professional services",
"DTC brands",
"Marketplaces",
];
/* Monochrome partner / certification marks, recreated as simple inline SVG
wordmark-badges (no raster, no copied brand art). Illustrative, consistent
with the footer "illustrative samples" disclaimer. ~24px tall, --c-text-dim. */
const TRUST_MARKS: { label: string; svg: React.ReactNode }[] = [
{
label: "Google Partner",
svg: (
<svg viewBox="0 0 150 24" role="img" focusable="false">
<circle cx="11" cy="12" r="9" fill="none" stroke="currentColor" strokeWidth="2.2" />
<path d="M11 12h9" stroke="currentColor" strokeWidth="2.2" />
<path d="M16 12a5 5 0 1 0-1.5 3.6" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" />
<text x="28" y="16" fontFamily="var(--font-sans)" fontSize="13" fontWeight="700" fill="currentColor">
Google Partner
</text>
</svg>
),
},
{
label: "Meta Business Partner",
svg: (
<svg viewBox="0 0 178 24" role="img" focusable="false">
<path
d="M4 16c0-5 2.5-8 5.5-8 2.6 0 4 2 5.5 5 1.5-3 2.9-5 5.5-5 3 0 5.5 3 5.5 8M4 16c0 2 1 3 2.6 3 2.2 0 3.6-2.8 4.9-5M22 16c0 2-1 3-2.6 3-2.2 0-3.6-2.8-4.9-5"
fill="none"
stroke="currentColor"
strokeWidth="2.2"
strokeLinecap="round"
/>
<text x="32" y="16" fontFamily="var(--font-sans)" fontSize="13" fontWeight="700" fill="currentColor">
Meta Business Partner
</text>
</svg>
),
},
{
label: "HubSpot Certified",
svg: (
<svg viewBox="0 0 158 24" role="img" focusable="false">
<circle cx="12" cy="14" r="6" fill="none" stroke="currentColor" strokeWidth="2.2" />
<circle cx="18.5" cy="6.5" r="2.6" fill="none" stroke="currentColor" strokeWidth="2" />
<path d="M12 8V5M15 12l2.2-3.4" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" />
<text x="30" y="16" fontFamily="var(--font-sans)" fontSize="13" fontWeight="700" fill="currentColor">
HubSpot Certified
</text>
</svg>
),
},
{
label: "Shopify Plus Partner",
svg: (
<svg viewBox="0 0 168 24" role="img" focusable="false">
<path
d="M9 4 5 5 3 20l8 1 2-16-4-1Zm0 0 1.6.4M11 6.5c-1.6 0-2.2 1.2-2.2 2.2 0 1.4 2.4 1.3 2.4 2.8 0 .7-.6 1-1.2 1"
fill="none"
stroke="currentColor"
strokeWidth="1.8"
strokeLinejoin="round"
strokeLinecap="round"
/>
<text x="22" y="16" fontFamily="var(--font-sans)" fontSize="13" fontWeight="700" fill="currentColor">
Shopify Plus Partner
</text>
</svg>
),
},
];
/* Small live-feeling figures that flank the manifesto so the section reads full,
not empty. Illustrative samples, consistent with the rest of the prototype. */
const MANIFESTO_STATS = [
{ k: "Avg. reporting cadence", v: "Monthly" },
{ k: "Channels we run", v: "6+" },
{ k: "Built around", v: "Your revenue" },
];
export default function Page() {
return (
<>
<SiteHeader />
<main id="main">
<Hero />
{/* ===== KINETIC TAPE — scroll-velocity marquee ===== */}
<section className="tape" aria-label="What we do, at a glance">
<VelocityMarquee items={TAPE} />
</section>
{/* ===== POSITIONING / MANIFESTO ===== */}
<section id="manifesto" className="manifesto frame" aria-labelledby="man-h">
<div className="wrap manifesto__wrap">
<Reveal as="p" className="kicker">
<span className="kicker__dot" />
The problem with most agencies
</Reveal>
<Reveal as="p" className="manifesto__lead display" delay={80}>
<span id="man-h">
Most budgets buy <span className="strike">activity</span>, not
outcomes. Dashboards fill with impressions while the sales number{" "}
<span className="grad">sits still.</span>
</span>
</Reveal>
<Reveal as="p" className="manifesto__body" delay={180}>
We started Feedback Studios to fix that. Every campaign we run is
built to move revenue, and we report on it the way your CFO would.
No vanity metrics. No mystery. Just the number that pays the bills.
</Reveal>
{/* stat ribbon — fills the section, adds a "live" texture */}
<Reveal as="ul" className="manifesto__stats" stagger={0.07} delay={120}>
{MANIFESTO_STATS.map((s) => (
<RevealItem as="li" className="manifesto__stat" key={s.k}>
<span className="manifesto__stat-v display">{s.v}</span>
<span className="manifesto__stat-k">{s.k}</span>
</RevealItem>
))}
</Reveal>
</div>
</section>
{/* ===== INDUSTRIES / SOCIAL PROOF ===== */}
<section className="proof" aria-label="Who we work with">
<div className="wrap">
<p className="kicker proof__label">
Trusted by teams that care about the sales number
</p>
<Reveal as="ul" className="proof__list" stagger={0.06}>
{INDUSTRIES.map((p) => (
<RevealItem as="li" className="proof__item" key={p}>
<span className="proof__item-dot" aria-hidden="true" />
{p}
</RevealItem>
))}
</Reveal>
{/* second row — monochrome partner / certification marks (inline
SVG, no raster) so the section reads substantiated, not sparse */}
<Reveal as="ul" className="proof__logos" stagger={0.06} delay={120}>
{TRUST_MARKS.map((m) => (
<RevealItem as="li" className="proof__logo" key={m.label}>
<span className="proof__logo-svg" aria-hidden="true">
{m.svg}
</span>
<span className="sr-only">{m.label}</span>
</RevealItem>
))}
</Reveal>
</div>
</section>
<SectionDivider label="What we do" />
{/* ===== SERVICES — interactive ledger ===== */}
<section id="services" className="services frame" aria-labelledby="svc-h">
<div className="wrap">
<header className="sec-head">
<p className="kicker">
<span className="kicker__dot" />
Services / 06
</p>
<Reveal as="h2" variant="clip">
<span id="svc-h" className="display sec-head__title">
How we grow your business
</span>
</Reveal>
</header>
<Reveal as="ol" className="ledger" stagger={0.07}>
{services.map((s, i) => (
<RevealItem as="li" key={s.id}>
<a href={SITE.booking} className="ledger__row" data-cursor="Scope it">
<span className="ledger__no">
{String(i + 1).padStart(2, "0")}
</span>
<h3 className="ledger__name display">{s.name}</h3>
<p className="ledger__desc">{s.desc}</p>
<span className="ledger__arrow" aria-hidden="true"></span>
</a>
</RevealItem>
))}
</Reveal>
</div>
</section>
{/* ===== METRICS scoreboard (animated SVG bars + count-ups) ===== */}
<Scoreboard />
{/* ===== CASE STUDIES — 3D tilt + coded charts ===== */}
<section id="work" className="work frame" aria-labelledby="work-h">
<div className="wrap">
<header className="sec-head">
<p className="kicker">
<span className="kicker__dot" />
Selected work sample
</p>
<Reveal as="h2" variant="clip">
<span id="work-h" className="display sec-head__title">
Proof, not promises
</span>
</Reveal>
</header>
<div className="work__grid">
{cases.map((c, i) => (
<CaseCard key={c.tag} data={c as unknown as CaseData} index={i} />
))}
</div>
<div className="work__cta">
<Magnetic strength={0.3}>
<a href={SITE.booking} className="btn btn--ghost" data-cursor="See more">
View all work <span className="arrow" aria-hidden="true"></span>
</a>
</Magnetic>
</div>
</div>
</section>
{/* ===== PROCESS — pinned scroll + morphing SVG ===== */}
<ProcessLoop />
{/* ===== TESTIMONIALS ===== */}
<section className="quotes frame" aria-label="What clients say">
<div className="wrap">
<header className="sec-head">
<p className="kicker">
<span className="kicker__dot" />
In their words sample
</p>
<Reveal as="h2" variant="clip">
<span className="display sec-head__title">
The number is the point
</span>
</Reveal>
</header>
</div>
<div className="wrap quotes__grid">
{testimonials.map((t, i) => (
<Reveal as="figure" className="quote" key={i} delay={i * 120}>
<span className="quote__mark display" aria-hidden="true">&ldquo;</span>
<blockquote className="quote__text display">{t.quote}</blockquote>
<figcaption className="quote__by">
<span className="quote__rule" aria-hidden="true" />
{t.by}
</figcaption>
</Reveal>
))}
</div>
<div className="wrap partners">
<p className="kicker">Partners</p>
<ul className="partners__list">
<li>Google Partner</li>
<li>Meta Business Partner</li>
</ul>
</div>
</section>
{/* ===== FAQ ===== */}
<section id="faq" data-invert className="faq-sec frame" aria-labelledby="faq-h">
<div className="wrap faq-sec__wrap">
<header className="sec-head">
<p className="kicker">
<span className="kicker__dot" />
FAQ
</p>
<Reveal as="h2" variant="clip">
<span id="faq-h" className="display sec-head__title">
Questions about working with a digital marketing agency
</span>
</Reveal>
</header>
<Faq />
</div>
</section>
{/* ===== FINAL CTA ===== */}
<section className="final frame" aria-labelledby="final-h">
<div className="wrap final__wrap">
<p className="kicker">
<span className="kicker__dot" />
The bottom line
</p>
<Reveal as="header">
<h2 id="final-h" className="display final__h">
Ready to <span className="grad">grow?</span>
</h2>
</Reveal>
<p className="final__sub">
No long contracts. No vanity reports. Marketing you can measure in
sales.
</p>
<div className="final__cta">
<Magnetic strength={0.4}>
<Link href={SITE.booking} className="btn btn--accent" data-cursor="Book a call">
Book a call
</Link>
</Magnetic>
<a href={`mailto:${SITE.email}`} className="btn btn--ghost">
or {SITE.email}
</a>
</div>
</div>
</section>
</main>
{/* ===== FOOTER ===== */}
<footer data-invert className="colophon frame" aria-label="Footer">
<div className="wrap">
<div className="colophon__top">
<div className="colophon__brand">
<span className="brand__mark" aria-hidden="true">
<span className="brand__dot" />
</span>
<p className="colophon__line">
{SITE.name}. {SITE.tagline}
</p>
</div>
<nav className="colophon__nav" aria-label="Footer">
<ul>
<li><a href="#services">Services</a></li>
<li><a href="#work">Work</a></li>
<li><a href="#process">About</a></li>
<li><a href="#faq">FAQ</a></li>
<li><a href={`mailto:${SITE.email}`}>Contact</a></li>
</ul>
<ul>
<li><a href="https://www.linkedin.com" rel="noopener">LinkedIn</a></li>
<li><a href={SITE.booking}>Book a call</a></li>
<li><a href="#main">Privacy</a></li>
<li><a href="#main">Terms</a></li>
</ul>
</nav>
</div>
<div className="rule" />
<div className="colophon__bottom">
<p>© 2026 {SITE.name}. All rights reserved.</p>
<p className="colophon__note">
Metrics and case studies shown are illustrative samples.
</p>
</div>
</div>
</footer>
</>
);
}