feat: rebuild marketing site with full component suite and preview
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
const AUTHORS = [
|
||||
{ tile: "RE", name: "Real Estate & Finance", role: "Market briefs, compliant summaries", status: "confirmed", label: "Co-author confirmed" },
|
||||
{ tile: "CS", name: "Fractional C-Suite", role: "Strategy & board workflows", status: "confirmed", label: "Co-author confirmed" },
|
||||
{ tile: "TE", name: "Technology & RAAI", role: "Agent patterns & safe defaults", status: "confirmed", label: "Co-author confirmed" },
|
||||
{ tile: "HE", name: "Higher Education", role: "Teaching & research integrity", status: "tba", label: "To be announced" },
|
||||
{ tile: "CO", name: "Communities", role: "Moderation & member programs", status: "tba", label: "To be announced" },
|
||||
];
|
||||
|
||||
export default function Authors() {
|
||||
return (
|
||||
<section className="section authors" id="authors">
|
||||
<div className="wrap">
|
||||
<span className="spec reveal">Who’s writing this</span>
|
||||
<h2 className="reveal">Practitioners, one per vertical.</h2>
|
||||
<p className="lede reveal">
|
||||
Each chapter is owned by someone who does the work — not a generalist writing about
|
||||
it. Names are announced as co-authors confirm.
|
||||
</p>
|
||||
<div className="auth-grid">
|
||||
{AUTHORS.map((a) => (
|
||||
<div className="auth reveal" key={a.tile}>
|
||||
<div className="mono-tile">{a.tile}</div>
|
||||
<h3>{a.name}</h3>
|
||||
<div className="role">{a.role}</div>
|
||||
<div className={`status ${a.status}`}>
|
||||
<i></i>
|
||||
{a.label}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
<div className="auth auth-join reveal">
|
||||
<div>
|
||||
<div className="spec" style={{ marginBottom: "8px" }}>Your name?</div>
|
||||
<p>Contribute a workflow after launch and earn a byline in the guide.</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
/**
|
||||
* Pure-CSS 3D book styled as the field guide. Decorative, so aria-hidden.
|
||||
* Faces (cover / spine / fore-edge / top / back) are assembled with
|
||||
* transform-style: preserve-3d; see `.book3d` in globals.css.
|
||||
*/
|
||||
export default function Book3D() {
|
||||
return (
|
||||
<div className="book3d" aria-hidden="true">
|
||||
<div className="book3d__inner">
|
||||
<div className="book3d__face book3d__back" />
|
||||
<div className="book3d__face book3d__pages" />
|
||||
<div className="book3d__face book3d__top" />
|
||||
<div className="book3d__face book3d__spine">
|
||||
<span>AIBook.fun · Responsible Agentic AI</span>
|
||||
</div>
|
||||
<div className="book3d__face book3d__cover">
|
||||
<span className="book3d__kicker">The Field Guide</span>
|
||||
<h3 className="book3d__title">
|
||||
Responsible
|
||||
<br />
|
||||
Agentic AI
|
||||
</h3>
|
||||
<span className="book3d__line" />
|
||||
<span className="book3d__sub">Tested workflows you can actually run</span>
|
||||
<svg className="book3d__mark" viewBox="0 0 40 40" fill="none">
|
||||
<circle cx="20" cy="20" r="17.5" stroke="#efe9db" strokeWidth="1" opacity="0.7" />
|
||||
<path d="M20 5 L22.6 20 L20 35 L17.4 20 Z" fill="#efe9db" />
|
||||
<path d="M5 20 L20 17.4 L35 20 L20 22.6 Z" fill="#efe9db" opacity="0.55" />
|
||||
</svg>
|
||||
<span className="book3d__brand">AIBook.fun</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
import EmailForm from "./EmailForm";
|
||||
|
||||
export default function Capture() {
|
||||
return (
|
||||
<section className="section capture" id="get">
|
||||
<div className="capture-in">
|
||||
<span className="spec reveal">Be first</span>
|
||||
<h2 className="reveal">Get the preview chapter free.</h2>
|
||||
<p className="reveal">
|
||||
Join the pre-launch list. You’ll get one full workflow to keep, a heads-up the morning
|
||||
we launch on Kickstarter, and early-backer pricing. Three emails. No spam, ever.
|
||||
</p>
|
||||
<div className="reveal">
|
||||
<EmailForm cta="Send it to me" />
|
||||
</div>
|
||||
<p className="fine reveal">
|
||||
Launching Sept 26, 2026 · unsubscribe anytime · we track sign-ups, never your work
|
||||
</p>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
const ITEMS = [
|
||||
{ num: "01", name: "Real Estate", desc: "Market briefs & listings, without leaking client data" },
|
||||
{ num: "02", name: "Financial Advisors", desc: "Portfolio summaries that stay compliant & reviewed" },
|
||||
{ num: "03", name: "Fractional C-Suite", desc: "Board updates & plans with real escalation paths" },
|
||||
{ num: "04", name: "Higher Education", desc: "Course & research workflows with academic integrity" },
|
||||
{ num: "05", name: "Communities", desc: "Moderation & programming that respects members" },
|
||||
{ num: "06", name: "Technology", desc: "Agent patterns, evals & the responsible defaults" },
|
||||
];
|
||||
|
||||
export default function Contents() {
|
||||
return (
|
||||
<section className="section contents" id="contents">
|
||||
<div className="wrap">
|
||||
<span className="spec reveal">The founding library</span>
|
||||
<h2 className="reveal">Six practices. Written by people who do the work.</h2>
|
||||
<div className="toc reveal">
|
||||
{ITEMS.map((x) => (
|
||||
<a href="#get" key={x.num}>
|
||||
<span className="num">{x.num}</span>
|
||||
<span className="name">{x.name}</span>
|
||||
<span className="desc">{x.desc}</span>
|
||||
<span className="arrow" aria-hidden="true">→</span>
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import { useState } from "react";
|
||||
|
||||
/**
|
||||
* Pre-launch email capture. Front-end demo only: on submit it shows a success
|
||||
* state. Wire `postEmail` to the real CRM endpoint (FluentCRM tag `prelaunch`)
|
||||
* when the backend is ready.
|
||||
*/
|
||||
export default function EmailForm({ className = "", cta = "Send it to me" }) {
|
||||
const [email, setEmail] = useState("");
|
||||
const [done, setDone] = useState(false);
|
||||
|
||||
async function onSubmit(e) {
|
||||
e.preventDefault();
|
||||
if (!email) return;
|
||||
// TODO: await postEmail(email) — POST to CRM, then setDone(true)
|
||||
setDone(true);
|
||||
}
|
||||
|
||||
if (done) {
|
||||
return (
|
||||
<p className="ok-msg" role="status">
|
||||
✓ You’re on the list — check your inbox for the preview chapter.
|
||||
</p>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<form className={className} onSubmit={onSubmit} noValidate>
|
||||
<input
|
||||
className="field"
|
||||
type="email"
|
||||
required
|
||||
placeholder="you@work.com"
|
||||
aria-label="Email address"
|
||||
value={email}
|
||||
onChange={(e) => setEmail(e.target.value)}
|
||||
/>
|
||||
<button className="btn btn-primary" type="submit">
|
||||
{cta}
|
||||
</button>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
const QA = [
|
||||
{
|
||||
q: "Is this AI theory, or something I can actually run?",
|
||||
a: "Something you run. Every workflow shows the real tool output, lists the real steps, and ends in a ~15-minute Try-it on non-confidential sample data. If you can’t run it, it doesn’t ship.",
|
||||
open: true,
|
||||
},
|
||||
{
|
||||
q: "How is this different from a course?",
|
||||
a: "A course teaches concepts; this is a field guide of tested recipes you apply to your real job this week. It refreshes annually because AI moves fast — stale advice is worthless.",
|
||||
},
|
||||
{
|
||||
q: "What does “responsible by design” actually mean?",
|
||||
a: "Every recipe includes data-handling rules, human-oversight steps, failure modes, and escalation paths. They’re part of the template — not an appendix, not an afterthought.",
|
||||
},
|
||||
{
|
||||
q: "Can I contribute a workflow after backing?",
|
||||
a: "Yes — open contribution opens once the founding library is live. We’re finalizing how contributors get paid (not just a byline) before launch.",
|
||||
},
|
||||
{
|
||||
q: "Why subscribe instead of buy once?",
|
||||
a: "Because a static AI book is out of date in months. The subscription is what keeps every workflow current — and it’s what funds the practitioners keeping them that way.",
|
||||
},
|
||||
];
|
||||
|
||||
export default function FAQ() {
|
||||
return (
|
||||
<section className="section faq" id="faq">
|
||||
<div className="wrap" style={{ maxWidth: "760px" }}>
|
||||
<h2 className="reveal">Frequently asked.</h2>
|
||||
<div className="qa reveal">
|
||||
{QA.map((x, i) => (
|
||||
<details key={i} open={x.open || undefined}>
|
||||
<summary>
|
||||
{x.q}
|
||||
<span className="pl" aria-hidden="true">+</span>
|
||||
</summary>
|
||||
<div className="ans">{x.a}</div>
|
||||
</details>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
const NOTES = [
|
||||
{
|
||||
n: "01 / Stays current",
|
||||
h: "A subscription, not a static book",
|
||||
p: "AI moves too fast for a book you buy once. Each annual edition is refreshed so the workflows still work when you open them.",
|
||||
},
|
||||
{
|
||||
n: "02 / Authored, then open",
|
||||
h: "Written by practitioners first",
|
||||
p: "The first edition is seeded by co-authors — a real founding library, not an empty shelf. Open, paid contribution opens once it’s worth browsing.",
|
||||
},
|
||||
{
|
||||
n: "03 / Responsible by design",
|
||||
h: "Guardrails in every recipe",
|
||||
p: "Data handling, human oversight, failure modes, escalation — part of the template on every workflow, never an appendix.",
|
||||
},
|
||||
];
|
||||
|
||||
export default function FieldNotes() {
|
||||
return (
|
||||
<section className="notes">
|
||||
<div className="wrap">
|
||||
<div className="notes-grid">
|
||||
{NOTES.map((x) => (
|
||||
<div className="note reveal" key={x.n}>
|
||||
<div className="n">{x.n}</div>
|
||||
<h3>{x.h}</h3>
|
||||
<p>{x.p}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
export default function Footer() {
|
||||
return (
|
||||
<footer className="footer">
|
||||
<div className="foot-in">
|
||||
<div className="foot-top">
|
||||
<div>
|
||||
<div className="logo">
|
||||
AIBook<b>.</b>
|
||||
<span className="dot">fun</span>
|
||||
</div>
|
||||
<p className="foot-blurb">
|
||||
A living, crowd-written field guide to using AI agents responsibly at work. Part
|
||||
of the WeOwnNet ecosystem.
|
||||
</p>
|
||||
</div>
|
||||
<div className="foot-links">
|
||||
<a href="#recipe">A recipe</a>
|
||||
<a href="#contents">Contents</a>
|
||||
<a href="#get">Preview</a>
|
||||
<a href="#faq">FAQ</a>
|
||||
</div>
|
||||
</div>
|
||||
<div className="colophon">
|
||||
© 2026 WeOwnAI · MIT-licensed docs · Launching on Kickstarter, Sept 26, 2026
|
||||
<br />
|
||||
Set in Fraunces, Hanken Grotesk & JetBrains Mono. This is a pre-launch page — pledge
|
||||
tiers and pricing are finalized at launch.
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import EmailForm from "./EmailForm";
|
||||
import Book3D from "./Book3D";
|
||||
|
||||
export default function Hero() {
|
||||
return (
|
||||
<section className="hero" id="top">
|
||||
<div className="hero-tabs" aria-hidden="true">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</div>
|
||||
<div className="wrap hero-grid">
|
||||
<div className="hero-visual">
|
||||
<Book3D />
|
||||
</div>
|
||||
<div className="hero-copy">
|
||||
<div className="eyebrow">
|
||||
<span className="tick"></span>
|
||||
<span className="spec">
|
||||
Field guide · Edition 001 · Kickstarter Sept 26, 2026
|
||||
</span>
|
||||
</div>
|
||||
<h1>
|
||||
The field guide to using AI agents{" "}
|
||||
<span className="serif-it">responsibly</span> at work.
|
||||
</h1>
|
||||
<p className="hero-sub">
|
||||
Not theory. Not hype. A subscription guide of{" "}
|
||||
<span className="hl">tested workflows you can actually run</span> — each with the
|
||||
real tool output, the guardrails, and a 15-minute exercise so you learn by doing.
|
||||
</p>
|
||||
<EmailForm className="hero-form" cta="Send me the preview chapter" />
|
||||
<p className="hero-note">
|
||||
Free preview + first access at launch · <b>3 emails, no spam</b>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
export default function Letter() {
|
||||
return (
|
||||
<section className="section letter" id="letter">
|
||||
<div className="letter-in">
|
||||
<span className="spec reveal">A note on why</span>
|
||||
<p className="letter-body reveal">
|
||||
Most AI advice is either hype or theory — and neither survives contact with real
|
||||
work. We’re writing the guide we wish we’d had: workflows that <em>actually run</em>,
|
||||
with the <span className="mark">guardrails built in</span>, kept honest by the people
|
||||
who use them every day. Fund the first edition, and you don’t just get the book — you
|
||||
help decide what goes in it.
|
||||
</p>
|
||||
<div className="sign reveal">
|
||||
<span className="scrawl">The co-authors</span>
|
||||
<span className="who">
|
||||
AIBook.fun founding team
|
||||
<br />
|
||||
Real estate · finance · leadership · tech
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
import { useEffect, useRef, useState } from "react";
|
||||
|
||||
const LINKS = [
|
||||
{ href: "#recipe", label: "A recipe" },
|
||||
{ href: "#contents", label: "Contents" },
|
||||
{ href: "#letter", label: "Why" },
|
||||
{ href: "#faq", label: "FAQ" },
|
||||
];
|
||||
|
||||
export default function Nav() {
|
||||
const [scrolled, setScrolled] = useState(false);
|
||||
const [open, setOpen] = useState(false);
|
||||
const navRef = useRef(null);
|
||||
|
||||
useEffect(() => {
|
||||
const onScroll = () => setScrolled(window.scrollY > 12);
|
||||
onScroll();
|
||||
window.addEventListener("scroll", onScroll, { passive: true });
|
||||
return () => window.removeEventListener("scroll", onScroll);
|
||||
}, []);
|
||||
|
||||
// While the mobile menu is open: close on Escape or an outside tap.
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
const onKey = (e) => e.key === "Escape" && setOpen(false);
|
||||
const onDown = (e) => {
|
||||
if (navRef.current && !navRef.current.contains(e.target)) setOpen(false);
|
||||
};
|
||||
document.addEventListener("keydown", onKey);
|
||||
document.addEventListener("pointerdown", onDown);
|
||||
return () => {
|
||||
document.removeEventListener("keydown", onKey);
|
||||
document.removeEventListener("pointerdown", onDown);
|
||||
};
|
||||
}, [open]);
|
||||
|
||||
const close = () => setOpen(false);
|
||||
|
||||
return (
|
||||
<nav ref={navRef} className={`nav${scrolled ? " scrolled" : ""}${open ? " open" : ""}`}>
|
||||
<div className="nav-in">
|
||||
<a className="logo" href="#top" onClick={close}>
|
||||
AIBook<b>.</b>
|
||||
<span className="dot">fun</span>
|
||||
</a>
|
||||
|
||||
<div className="nav-links">
|
||||
{LINKS.map((l) => (
|
||||
<a key={l.href} href={l.href}>
|
||||
{l.label}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<a href="#get" className="btn btn-primary nav-cta">
|
||||
Get the preview
|
||||
</a>
|
||||
|
||||
<button
|
||||
type="button"
|
||||
className="nav-toggle"
|
||||
aria-label={open ? "Close menu" : "Open menu"}
|
||||
aria-expanded={open}
|
||||
aria-controls="mobile-menu"
|
||||
onClick={() => setOpen((v) => !v)}
|
||||
>
|
||||
<span className="bars" aria-hidden="true"></span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div className="nav-menu" id="mobile-menu">
|
||||
{LINKS.map((l) => (
|
||||
<a key={l.href} href={l.href} onClick={close}>
|
||||
{l.label}
|
||||
</a>
|
||||
))}
|
||||
<a href="#get" className="btn btn-primary" onClick={close}>
|
||||
Get the preview
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,120 @@
|
||||
function ShieldCheck() {
|
||||
return (
|
||||
<svg width="16" height="16" viewBox="0 0 16 16" fill="none" aria-hidden="true">
|
||||
<path
|
||||
d="M8 1.5 2.5 4v3.5c0 3 2.3 5.4 5.5 7 3.2-1.6 5.5-4 5.5-7V4L8 1.5Z"
|
||||
stroke="#1C5D4C"
|
||||
strokeWidth="1.3"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
<path
|
||||
d="m5.6 8 1.7 1.7L10.6 6"
|
||||
stroke="#1C5D4C"
|
||||
strokeWidth="1.3"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
/>
|
||||
</svg>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Recipe() {
|
||||
return (
|
||||
<section className="section" id="recipe">
|
||||
<div className="wrap">
|
||||
<div className="recipe-head reveal">
|
||||
<span className="spec">Read an actual recipe</span>
|
||||
<h2>Every entry is a workflow you can run.</h2>
|
||||
<p>
|
||||
Here’s a real one from the founding library — the whole thing, exactly as it
|
||||
appears in the guide. This is the format behind every workflow.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="recipe reveal">
|
||||
<div className="recipe-top">
|
||||
<span className="recipe-id">
|
||||
recipe <b>RE-04</b> · v1.2 · ~15 min
|
||||
</span>
|
||||
<span className="recipe-vert">Real Estate</span>
|
||||
</div>
|
||||
<div className="recipe-body">
|
||||
<h3 className="recipe-title">
|
||||
Draft a property-market brief with an AI agent — without leaking client data.
|
||||
</h3>
|
||||
|
||||
<div className="row">
|
||||
<div className="k">Problem</div>
|
||||
<div className="v">
|
||||
You need a sharp neighborhood market brief for a client meeting, fast — but
|
||||
the listing sheet and client notes can’t go into a public model.{" "}
|
||||
<span className="sub">
|
||||
Job: turn messy local data into a credible one-pager in minutes, safely.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="k">Method</div>
|
||||
<div className="v">
|
||||
<ol className="steps">
|
||||
<li>Strip identifiers from the source data locally (a provided script does this).</li>
|
||||
<li>Prompt the agent with the anonymized sample and a fixed brief template.</li>
|
||||
<li>Review the draft against the checklist before anything leaves your machine.</li>
|
||||
</ol>
|
||||
<div className="term" role="img" aria-label="Sample terminal output from the workflow">
|
||||
<div className="term-bar">
|
||||
<i></i>
|
||||
<i></i>
|
||||
<i></i>
|
||||
<span>agent — property-brief · sample dataset (non-confidential)</span>
|
||||
</div>
|
||||
<pre>
|
||||
<span className="c-dim">{"$ "}</span>
|
||||
<span className="c-user">{"brief"}</span>
|
||||
{" --input "}
|
||||
<span className="c-key">{"sample_listings.csv"}</span>
|
||||
{" --template market-1pager\n\n"}
|
||||
<span className="c-dim">{"✓ redacted 3 fields (owner_name, phone, exact_address)\n✓ 41 comps in radius · median $/sqft computed\n\n"}</span>
|
||||
<span className="c-ok">{"MARKET BRIEF — Maple Heights (sample)\n"}</span>
|
||||
{" · Median list: $420/sqft (▲ 4.1% QoQ)\n · Days on market: 22 (was 31)\n · Inventory: 1.8 mo — seller-leaning\n · Read: price to comp, expect <2 wks at ask\n\n"}
|
||||
<span className="c-dim">{"# cost this run: $0.03 · model: claude · 2,140 tokens"}</span>
|
||||
</pre>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="k">Safeguards</div>
|
||||
<div className="v">
|
||||
<div className="guard">
|
||||
<ShieldCheck />
|
||||
<span>
|
||||
Redaction runs <b style={{ color: "var(--color-ink)" }}>on your machine</b> —
|
||||
raw client data never reaches the model.
|
||||
</span>
|
||||
</div>
|
||||
<div className="guard">
|
||||
<ShieldCheck />
|
||||
<span>
|
||||
A human review step is required before the brief is shared. The checklist
|
||||
is part of the recipe.
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="row">
|
||||
<div className="k">Try it</div>
|
||||
<div className="v">
|
||||
Run the same brief on the included sample dataset (no real client data) in
|
||||
about 15 minutes — then swap in your own, safely.{" "}
|
||||
<span className="chip">◷ cost to try ≈ $0.03</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
export default function Tiers() {
|
||||
return (
|
||||
<section className="section" id="back">
|
||||
<div className="wrap">
|
||||
<div className="tiers-head">
|
||||
<div className="reveal">
|
||||
<span className="spec">When we launch</span>
|
||||
<h2>What backing will look like.</h2>
|
||||
</div>
|
||||
<p className="tiers-note reveal">
|
||||
Preview of planned pledge tiers. Final pricing is confirmed at the Kickstarter
|
||||
launch — nothing here is a live checkout yet.
|
||||
</p>
|
||||
</div>
|
||||
<div className="tier-grid">
|
||||
<div className="tier reveal">
|
||||
<div className="t-name">Supporter</div>
|
||||
<div className="t-price">$10</div>
|
||||
<div className="t-unit">one-time</div>
|
||||
<div className="t-desc">
|
||||
The preview chapter, community updates, and an early look at the founding library
|
||||
as it’s written.
|
||||
</div>
|
||||
</div>
|
||||
<div className="tier feature reveal">
|
||||
<div className="t-tag">The one to get</div>
|
||||
<div className="t-name">The Book</div>
|
||||
<div className="t-price">
|
||||
$47 <small>/yr</small>
|
||||
</div>
|
||||
<div className="t-unit">annual subscription</div>
|
||||
<div className="t-desc">
|
||||
The full guide — PDF + web reader — and every annual update while you’re
|
||||
subscribed. Recurring value, no lifetime gimmick.
|
||||
</div>
|
||||
</div>
|
||||
<div className="tier reveal">
|
||||
<div className="t-name">Founding Sponsor</div>
|
||||
<div className="t-price">Founding</div>
|
||||
<div className="t-unit">limited · final terms at launch</div>
|
||||
<div className="t-desc">
|
||||
A named acknowledgment in the guide, a private cohort seat, and a hand in shaping
|
||||
the first edition.
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user