Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ae15f510fb | ||
|
|
cfd00d466d | ||
|
|
9af687c6dc | ||
|
|
788bff5d56 | ||
|
|
434a70c749 | ||
|
|
a69711227e | ||
|
|
1685918c11 | ||
|
|
d05d283d6d | ||
|
|
e5adccf279 | ||
|
|
80af21801f | ||
|
|
2938a7ac2a | ||
|
|
7ad62d3bfb | ||
|
|
b24a202502 | ||
|
|
02979dffac | ||
|
|
3b2f395bbf | ||
|
|
920d53a729 | ||
|
|
a8b9925376 | ||
|
|
4f8060ec37 | ||
|
|
762a6c0765 | ||
|
|
11f78080e9 | ||
|
|
d90a7b3a95 | ||
|
|
dccfc3b65d | ||
|
|
83721c43b6 | ||
|
|
1bd2c0cf5b | ||
|
|
4c5579f66a | ||
|
|
3f969207eb | ||
|
|
686e13b2cd | ||
|
|
5c2bf88786 | ||
|
|
d905e30701 | ||
|
|
f23a623423 | ||
|
|
83ce4302c5 | ||
|
|
13a97ca0f8 | ||
|
|
f03fe7f232 | ||
|
|
f5a83507a6 | ||
|
|
59201c9c29 | ||
|
|
6390d81c82 | ||
|
|
1a629bc087 | ||
|
|
195baa32cc | ||
|
|
5cf207c6c9 | ||
|
|
6685694cc2 | ||
|
|
af6512d765 | ||
|
|
91d58ab12e | ||
|
|
031942700a | ||
|
|
32e8ef4446 | ||
|
|
5eb257c987 | ||
|
|
b653e8fac9 | ||
|
|
c80574a913 | ||
|
|
1f06edee73 | ||
|
|
faf5bb7a25 | ||
|
|
efcd1b9bca | ||
|
|
648f6de91a | ||
|
|
79c5a42ed8 | ||
|
|
f0f8f9b01f | ||
|
|
ca2361cce0 | ||
|
|
b263715ee2 | ||
|
|
0fae769daa | ||
|
|
7a7181b79c | ||
|
|
51d3d9a6ae | ||
|
|
6173d478c7 | ||
|
|
27cf3db62b | ||
|
|
d9ba89ce17 | ||
|
|
aa5c4ea09e | ||
|
|
e5f2f221bc | ||
|
|
9b0ad976d8 | ||
|
|
d10a59434f | ||
|
|
a24a9f4277 | ||
|
|
84c59eb358 | ||
|
|
6f9843ff44 | ||
|
|
8ef06cb3e7 | ||
|
|
e7da04ffb6 | ||
|
|
30cf939eb7 | ||
|
|
44c8fa2b43 | ||
|
|
b4f79661a1 | ||
|
|
34d56b4dbb | ||
|
|
b6bbd30415 | ||
|
|
c60448004f | ||
|
|
1e143cf18a | ||
|
|
4e447ca254 | ||
|
|
2fca7dff4b | ||
|
|
719f969443 | ||
|
|
344be8b8f7 | ||
|
|
c488955c93 | ||
|
|
1daaea6148 | ||
|
|
a85ad2e1d9 | ||
|
|
56988687cb | ||
|
|
f80a6c2aca | ||
|
|
261ebe513f | ||
|
|
53a947e23d | ||
|
|
02697cd5f3 | ||
|
|
9638b58e7b | ||
|
|
203ab9394c | ||
|
|
84f64e6a00 | ||
|
|
4990a7e4c5 | ||
|
|
894de4d682 | ||
|
|
f47b42e4a5 | ||
|
|
3f32886894 | ||
|
|
dc9f3e27c6 | ||
|
|
7e98e19113 | ||
|
|
ae1f1ab71b | ||
|
|
abb2b65d2a | ||
|
|
ae310ba1d3 | ||
|
|
c1197a4f7f | ||
|
|
b645d1bec2 | ||
|
|
8937061c49 | ||
|
|
d7c6a239c1 | ||
|
|
5f24a406cf | ||
|
|
f0c6a48187 | ||
|
|
695a8e3f08 | ||
|
|
a7d5e5f31e | ||
|
|
98830de44e | ||
|
|
1f52209f87 | ||
|
|
b4ad25c1ec | ||
|
|
aac526f7a1 | ||
|
|
6dfa941683 | ||
|
|
7743e6fa75 | ||
|
|
b87b7516dc | ||
|
|
6d13ab5962 | ||
|
|
8314dad574 | ||
|
|
265d64abd6 | ||
|
|
3dd20d13c0 | ||
|
|
0fba3c8175 | ||
|
|
ce9bb4f943 | ||
|
|
20cd0d09c8 | ||
|
|
0bc2fcd10b | ||
|
|
48425b0baf | ||
|
|
efc859b339 | ||
|
|
ad4bc12c00 | ||
|
|
53828e8d73 | ||
|
|
10ef165596 | ||
|
|
46d366e6b0 | ||
|
|
9dfdf07ce3 | ||
|
|
82acad15f2 | ||
|
|
353d749b52 | ||
|
|
2b76c45620 | ||
|
|
89a3d76122 | ||
|
|
9340a0a972 | ||
|
|
169e3494e3 | ||
|
|
99ca572ab4 |
@@ -0,0 +1,38 @@
|
||||
# Rebuild + roll aibook.fun forward on any push to main.
|
||||
# Runner: repo-registered act_runner on the aibook.fun droplet itself
|
||||
# (co-located → local docker commands, no cross-host SSH needed).
|
||||
#
|
||||
# Repository secrets required (Settings → Actions → Secrets):
|
||||
# (none — runner is on the droplet, has local root)
|
||||
|
||||
name: deploy
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
paths:
|
||||
- 'marketing-site/**'
|
||||
- 'deploy/**'
|
||||
- '.gitea/workflows/**'
|
||||
workflow_dispatch:
|
||||
|
||||
concurrency:
|
||||
group: aibook-fun-deploy
|
||||
cancel-in-progress: false
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: aibook-fun-droplet
|
||||
steps:
|
||||
- name: Pull latest + rebuild + roll
|
||||
run: |
|
||||
set -euo pipefail
|
||||
cd /opt/aibook_fun/repo
|
||||
git fetch --prune origin
|
||||
git reset --hard origin/main
|
||||
docker build -t aibook-fun-marketing:v1 \
|
||||
-f /opt/aibook_fun/repo/deploy/docker/Dockerfile \
|
||||
/opt/aibook_fun/repo/marketing-site/
|
||||
cd /opt/aibook_fun
|
||||
docker compose up -d --remove-orphans
|
||||
docker image prune -f --filter "dangling=true"
|
||||
@@ -1,14 +1,14 @@
|
||||
---
|
||||
title: "AIBook.fun — Implementation Plan"
|
||||
title: "AiBook.fun — Implementation Plan"
|
||||
type: implementation-plan
|
||||
status: draft
|
||||
owner: Patrick (Product)
|
||||
launch-target: 2026-09-26
|
||||
last-updated: 2026-08-26
|
||||
last-updated: 2026-08-31
|
||||
companions: [AiBook_PRD.md, AiBook_Spec.md]
|
||||
---
|
||||
|
||||
# 📚 AIBook.fun — Implementation Plan
|
||||
# 📚 AiBook.fun — Implementation Plan
|
||||
|
||||
> **Status: DRAFT.** The schedule below assumes decisions that aren't final yet (see "Do this
|
||||
> week"). Dates, owners, and dollar figures are planning assumptions until signed off. This is a
|
||||
@@ -16,12 +16,11 @@ companions: [AiBook_PRD.md, AiBook_Spec.md]
|
||||
> [Appendix — What changed](#appendix--what-changed-in-this-revision) for how this revision
|
||||
> differs from the prior draft.
|
||||
|
||||
**The clock:** today is late August 2026; **launch is 9/26/2026** — roughly **4–5 weeks out**.
|
||||
Every week counts, and the critical path has little slack. The domain expires **09-05**, so
|
||||
step one is non-negotiable and immediate.
|
||||
**The clock:** today is 31 Aug 2026; **launch is 26 Sep 2026**. Domain and price are signed.
|
||||
Content is the remaining critical path.
|
||||
|
||||
**The critical path in one line:**
|
||||
`renew domain + make the pricing decisions → seed the Minimum Lovable Library → freeze copy → no-crypto scrub → submit to Kickstarter → launch 9/26`
|
||||
`assign MLL authors + D-3 co-authors → write the library → freeze copy → no-crypto scrub → submit to Kickstarter → launch 9/26`
|
||||
|
||||
---
|
||||
|
||||
@@ -31,17 +30,16 @@ Before any copy or build locks, close these. Most are decisions or de-risking, n
|
||||
|
||||
| # | Task | Owner | Why it's first |
|
||||
|:--|:--|:--|:--|
|
||||
| 0.1 | **Renew aibook.fun today.** It expires 09-05; launch is 09-26. | Whoever holds the registrar login | It's a chore, not a decision. A lapsed domain 3 weeks before launch is a self-inflicted disaster. |
|
||||
| 0.2 | **Decide the pricing spine — lifetime *and* royalties together** (D-1 + D-2). | Commercial lead (@GTM) | Both block copy freeze; they're linked (see [Spec §6](AiBook_Spec.md)). |
|
||||
| 0.3 | **Ratify the North-Star + product-health floors** (activation, submissions, renewal). | Product (@pat) + team | So we measure the right thing from Day 1, not just dollars. |
|
||||
| 0.1 | **~~Renew aibook.fun~~ Done 2026-08-31.** | Registrar owner | Closed. |
|
||||
| 0.2 | **~~Pricing spine~~ Done 2026-08-31.** **$47/yr** is the product. No lifetime SKU as an equal. Founding writers on **contract** (v1 authored). | Commercial + Product | Copy freeze unblocked on price. |
|
||||
| 0.3 | **~~Ratify the North-Star + product-health floors~~ Done 2026-08-29.** Activation 20/35 from access date; campaign waitlist 50/100; post-key submissions 10/25 in 90 days; renewal 40/60 excluding lifetime; curation is an ops SLA, not a launch bar. See PRD §8. | Product (@pat) | Locked. Don't quote 60% renewal publicly. |
|
||||
| 0.4 | **Ratify the Minimum Lovable Library number and assign every workflow an author.** | Product + co-authors | This is the #1 risk; turn it from hope into owned work. |
|
||||
| 0.5 | **Confirm the two unconfirmed co-authors, or cut their verticals from v1** (D-3). | Commercial lead (@GTM) | Scope certainty before outline lock. |
|
||||
| 0.6 | Open the claims register; assign a post-campaign renewal owner. | Product + Commercial | Truth-in-claims gate; don't leave renewal unstaffed. |
|
||||
| 0.7 | Set up the Kickstarter creator account + identity verification. | Campaign lead (@THY) | Long lead time; do it early. |
|
||||
|
||||
**✅ Gate 0 — decisions closed.** Pricing spine decided · targets ratified · Minimum Lovable
|
||||
Library scoped with authors · domain renewed · claims register open. *Until pricing is decided,
|
||||
don't freeze copy. Until the domain is renewed, don't push anything live.*
|
||||
**✅ Gate 0 — decisions closed.** **Pricing spine signed ($47/yr; writers on contract)** · **targets ratified (2026-08-29)** · Minimum Lovable
|
||||
Library scoped with authors · **domain renewed (2026-08-31)** · claims register open. *Until the library has named authors and D-3 is closed, don't treat content as on track. Copy freeze still waits on claims + co-author scope.*
|
||||
|
||||
---
|
||||
|
||||
@@ -53,8 +51,8 @@ campaign around an empty library fails.
|
||||
### 1A · Content — seed the Minimum Lovable Library (critical path)
|
||||
| Task | Owner |
|
||||
|:--|:--|
|
||||
| Lock the chapter outline (chapters per vertical, a named owner each) | Co-authors |
|
||||
| Publish the Workflow Recipe template + 3 filled examples | Product |
|
||||
| Lock the chapter outline (chapters per vertical, a named owner each). Blank is [`workflows/chapter-structure.md`](workflows/chapter-structure.md) | Co-authors |
|
||||
| Review and freeze the chapter blank, then 3 filled examples | Product + authors |
|
||||
| **Seed the Minimum Lovable Library to its floor number** (team + co-authors write & test the workflows) | Co-authors + team |
|
||||
| 3 "clone-and-run" kits, each **verified by actually running it** | Dev + QA support |
|
||||
| 2 sample chapters (the backer preview) | Two lead co-authors |
|
||||
@@ -75,7 +73,7 @@ campaign around an empty library fails.
|
||||
| Task | Owner |
|
||||
|:--|:--|
|
||||
| Kickstarter page copy (all sections, 9/26 dates) | Campaign lead + exec co-author |
|
||||
| **Copy freeze — commercial terms locked** (lifetime/royalties per D-1/D-2) | Commercial lead (sign) |
|
||||
| **Copy freeze** (price already signed: $47/yr, writers on contract; still freeze claims + NFT scrub) | Commercial lead (sign) |
|
||||
| **No-crypto scrub gate on every asset** (translation table) | Campaign lead (owner) |
|
||||
| Hero video: script → shoot → edit (2–3 min) | Creative lead (@LFG) + co-authors |
|
||||
| Cover design + 3D mockups | Creative lead |
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
---
|
||||
title: "AIBook.fun — Product Requirements Document"
|
||||
title: "AiBook.fun — Product Requirements Document"
|
||||
type: prd
|
||||
status: draft
|
||||
owner: Patrick (Product)
|
||||
launch-target: 2026-09-26
|
||||
last-updated: 2026-08-26
|
||||
last-updated: 2026-08-31
|
||||
---
|
||||
|
||||
# 📚 AIBook.fun — Product Requirements Document
|
||||
# 📚 AiBook.fun — Product Requirements Document
|
||||
|
||||
> **Status: DRAFT.** Dollar figures, dates past today, and commercial terms in this
|
||||
> document are planning assumptions, not commitments. Nothing here should be quoted
|
||||
@@ -20,7 +20,7 @@ last-updated: 2026-08-26
|
||||
|
||||
## TL;DR
|
||||
|
||||
AIBook.fun is a **crowd-written, practical field guide to using AI agents responsibly at
|
||||
AiBook.fun is a **crowd-written, practical field guide to using AI agents responsibly at
|
||||
work** — sold as an annual subscription, launched on Kickstarter on **September 26, 2026**.
|
||||
Its unit of content is not a chapter but a **workflow you can actually run**: a documented,
|
||||
tested recipe for getting a real job done with AI, complete with the guardrails.
|
||||
@@ -142,8 +142,9 @@ the structural answer to "how do I know this AI advice isn't hallucinated?"
|
||||
| **Costs** | Model/tool costs where known — honesty about the economics |
|
||||
| **Author & sources** | Who wrote it, when, for which vertical, with citations |
|
||||
|
||||
**Chapters** are curated collections of these recipes, one set per vertical: Real Estate ·
|
||||
Financial Advisors · Fractional C-Suite · Higher Ed · Communities · Technology. **Editions**
|
||||
**Chapters** are substantial essays, one per vertical (Real Estate · Financial Advisors ·
|
||||
Fractional C-Suite · Higher Ed · Communities · Technology), with full Workflow Recipes
|
||||
**nested in the argument**. See [§5.4](#54-the-reading-surface-locked-2026-08-31). **Editions**
|
||||
refresh annually — which is the honest justification for a *subscription* rather than a
|
||||
one-time purchase: the content genuinely goes stale as AI changes.
|
||||
|
||||
@@ -160,15 +161,61 @@ post-launch aspiration. Community contribution is **Layer 2** — an experiment
|
||||
we've seeded a library worth subscribing to.
|
||||
|
||||
### 5.3 Be honest: v1 is an *authored* book, not yet a *crowd* book
|
||||
The prior draft's "contributor economy" pays co-authors **15% affiliate commission** — which
|
||||
is a reward for *referring backers*, not for *writing workflows*. Writing a workflow currently
|
||||
earns a byline and nothing else. The mechanic that would actually pay contributors — royalties
|
||||
— is unresolved (see [D-2](#10-open-decisions)).
|
||||
The prior draft's "contributor economy" pays co-authors **15% affiliate commission**, which
|
||||
is a reward for *referring backers*, not for *writing workflows*.
|
||||
|
||||
So for v1, we state plainly: **the first edition is written by a founding set of co-authors and
|
||||
the team.** Open community contribution — with a real incentive attached — is the very next
|
||||
thing we build, and its incentive design ([D-2](#10-open-decisions)) is a **launch-blocking
|
||||
decision, not a nice-to-have**, because the entire "living book" thesis depends on it.
|
||||
**Signed 2026-08-31 (D-2):** founding writers are paid **on contract**. v1 is an authored book.
|
||||
Affiliate referral can still pay for referring backers. It is not how writing is paid. Open
|
||||
contribution with royalties or bounties waits for Layer 2.
|
||||
|
||||
So we state plainly: **the first edition is written by a founding set of co-authors and the
|
||||
team.** Layer 2 is the next thing we build, after the library is worth subscribing to.
|
||||
|
||||
---
|
||||
|
||||
### 5.4 The reading surface (locked 2026-08-31)
|
||||
|
||||
People read **chapters**, not a shelf of detached cards. A chapter is a substantial essay
|
||||
for one vertical: it argues a way of working, then **nests full workflows inside that
|
||||
argument** as the proof.
|
||||
|
||||
This is a deliberate break from treating the workflow as the only page. The workflow is
|
||||
still the unit of *practice* (and of activation). The chapter is the unit of *reading*.
|
||||
|
||||
**Chapter page**
|
||||
- Title, vertical, edition, authors
|
||||
- Opening promise (what this chapter is for) plus a **Skip to a Try-it** control — activation
|
||||
must not require finishing the essay
|
||||
- Essay body: sections that teach the practice (stakes, constraints, how we work here)
|
||||
- Nested **Workflow blocks** at the points in the argument they earn — not bunched in an appendix
|
||||
- End matter: further workflows in this vertical, sources, last updated
|
||||
|
||||
**Nested workflow block** (the recipe, in full — not a teaser)
|
||||
1. Chrome: recipe ID, version, time, cost
|
||||
2. Title as the job
|
||||
3. Problem
|
||||
4. Actors
|
||||
5. Setup (tools, sample files, cost)
|
||||
6. **Safeguards before the steps** so data-handling is read before anyone pastes a client list
|
||||
7. Method, with real tool output *in* the steps
|
||||
8. Evidence
|
||||
9. Try-it (~15 min, sample data, mark complete — fires Activation)
|
||||
10. Share result (community template; events, not content)
|
||||
11. Author, sources, last updated
|
||||
|
||||
**Addressability**
|
||||
- Every workflow has a stable ID (e.g. `RE-01`) and a URL that opens the chapter scrolled to
|
||||
that block (and a focused/print view of the same block). Campaign samples, clone-and-run
|
||||
kits, and Workflow-of-the-Week link here — never to an essay with no way in.
|
||||
- PDF matches this stack: chapter essay + in-place recipes. Print and web must not drift.
|
||||
|
||||
**Non-goals for the reader**
|
||||
- No chatbot on the chapter page
|
||||
- No crypto/Web3 language
|
||||
- Nested recipes are not collapsed “click to reveal” cards that hide the Method
|
||||
|
||||
**Writing drafts** live in [`workflows/chapter-structure.md`](workflows/chapter-structure.md).
|
||||
Copy that blank into a vertical file (`workflows/real-estate.md`, etc.) when a chapter is assigned.
|
||||
|
||||
---
|
||||
|
||||
@@ -202,8 +249,8 @@ Requirements are grouped by the layer they serve; **most 🔴 items serve the co
|
||||
| ID | Requirement | Pri |
|
||||
|:--|:--|:--|
|
||||
| A-1 | Post-campaign access: a digital key unlocks PDF + web reader for 12 months, renews annually | 🟢 |
|
||||
| A-2 | Anchor price **$47/yr** *(draft — needs commercial re-sign)* + hardcopy at-cost upcharge | 🔴 |
|
||||
| A-3 | Lifetime tier — **decision required before copy freeze** (see [D-1](#10-open-decisions)) | 🟡 |
|
||||
| A-2 | Anchor price **$47/yr** *(signed 2026-08-31)* + hardcopy at-cost upcharge. No lifetime SKU as an equal product. | 🔴 |
|
||||
| A-3 | Lifetime tier — **not offered as a v1 SKU** (D-1 signed 2026-08-31: $47/yr only). Revisit only as a capped early-bird later, not as an equal product. | 🟢 |
|
||||
| A-4 | Fulfillment ledger: backer ↔ key/upcharge tracked (a spreadsheet is fine for v1) | 🟢 |
|
||||
|
||||
### 6.4 The other layers — mostly 🟡 / 🟢
|
||||
@@ -236,7 +283,7 @@ Requirements are grouped by the layer they serve; **most 🔴 items serve the co
|
||||
| NFR-3 | **Privacy:** no confidential client data in any workflow or campaign asset; track events, not content. |
|
||||
| NFR-4 | **Availability:** landing page up through the campaign; emails on schedule; affiliate tracking live from Day 1 (the 30-day cookie means every hour of Day 1 counts). |
|
||||
| NFR-5 | **Content quality:** every workflow passes the Recipe template + at least one co-author review. |
|
||||
| NFR-6 | **Domain continuity:** aibook.fun must not lapse (it currently expires 09-05 — see [§9](#9-immediate-next-steps)). |
|
||||
| NFR-6 | **Domain continuity:** aibook.fun must not lapse (**renewed 2026-08-31**). |
|
||||
| NFR-7 | **Accessibility:** reader and landing page are mobile-readable, targeting WCAG AA. |
|
||||
| NFR-8 | **Cost discipline:** pre-revenue burn stays within the ~$6K budget ([Appendix C](#appendix-c--budget)). |
|
||||
|
||||
@@ -249,12 +296,18 @@ metrics; those measure the *campaign*, not the *product.* A funded campaign can
|
||||
dead product if nobody activates, renews, or contributes.
|
||||
|
||||
### Product health (report these first)
|
||||
| Metric | Floor | Target | Why it matters |
|
||||
|:--|:--|:--|:--|
|
||||
| **Activation** — read 1 workflow + do 1 Try-it in 14 days | 20% | 35% | The North-Star. Is the core loop actually useful? |
|
||||
| **Workflow submissions** during campaign window | 10 | 25 | Early signal that Layer 2 (contribution) is real |
|
||||
| **Renewal rate** — year-1 cohort | — | 60% | Is a *subscription* the right model at all? |
|
||||
| **Curation turnaround** ≤ 10 working days | 80% | 95% | Can we keep quality without becoming the bottleneck? |
|
||||
|
||||
**Ratified 2026-08-29 (Product).** These are the numbers we run. Do not quote the 60% renewal target on Kickstarter or any public surface.
|
||||
|
||||
| Metric | Floor | Target | Clock / notes | Why it matters |
|
||||
|:--|:--|:--|:--|:--|
|
||||
| **Activation** — read 1 workflow + finish 1 Try-it | 20% | 35% | **14 days from access-key date, not pledge date.** North-Star. | Is the core loop actually useful? |
|
||||
| **Contributor waitlist** during the campaign | 50 | 100 | People who *say* they will contribute a workflow. Not written recipes. | Early Layer-2 signal without betting launch on cold-start writing |
|
||||
| **Workflow submissions** | 10 | 25 | First **90 days after keys go out** | Is paid/open contribution real once the library exists? |
|
||||
| **Renewal rate** — year-1 **paid** cohort | 40% | 60% | **Exclude lifetime SKUs** from the denominator. 60% is internal. | Is a *subscription* the right model at all? |
|
||||
| **Curation turnaround** ≤ 10 working days | 80% | 95% | **Ops SLA after Layer 2 is on** — not a launch health bar | Can we keep quality without becoming the bottleneck? |
|
||||
|
||||
Leading indicator before fulfillment: % of the pre-launch list who run the *sample* Try-it.
|
||||
|
||||
### Campaign performance (the fundraise)
|
||||
| Metric | Min | Target | Stretch |
|
||||
@@ -279,13 +332,13 @@ dead product if nobody activates, renews, or contributes.
|
||||
## 9. Immediate next steps
|
||||
|
||||
**This week — decisions and de-risking (before any copy or build locks):**
|
||||
1. **Renew aibook.fun today.** It expires 09-05; launch is 09-26. This is a chore, not a
|
||||
strategic decision — do it now and delete it from the risk list. *(Owner: whoever holds the
|
||||
registrar login.)*
|
||||
2. **Resolve the pricing spine together — lifetime ([D-1](#10-open-decisions)) *and* royalties
|
||||
([D-2](#10-open-decisions)).** They're linked, and both block copy freeze.
|
||||
3. **Ratify the North-Star + the product-health floors** (§8) so we're measuring the right
|
||||
thing from Day 1.
|
||||
1. **~~Renew aibook.fun~~ Done.** Domain renewed (confirmed 2026-08-31). Launch remains 09-26.
|
||||
2. **~~Resolve the pricing spine (D-1 / D-2)~~ Done 2026-08-31.** Anchor is **$47/yr**. No
|
||||
lifetime SKU as an equal product. Founding writers are engaged **on contract** — v1 is an
|
||||
authored book; open royalties are not the v1 mechanic. Copy freeze is unblocked on price.
|
||||
3. **~~Ratify the North-Star + the product-health floors~~ Done 2026-08-29.** Locked in §8:
|
||||
activation 20/35 from access date; campaign waitlist 50/100; post-key submissions 10/25 in
|
||||
90 days; renewal 40/60 excluding lifetime; curation SLA not a launch bar.
|
||||
4. **Ratify the Minimum Lovable Library number and assign every workflow an author** (§5.2).
|
||||
5. **Confirm the two unconfirmed co-authors** (Higher Ed, Communities) or re-scope those
|
||||
verticals out of v1.
|
||||
@@ -313,8 +366,8 @@ decision-maker has a starting point — but the recommendation is not yet a deci
|
||||
|
||||
| # | Decision | Recommendation | Blocks |
|
||||
|:--|:--|:--|:--|
|
||||
| **D-1** | **Lifetime tier — offer it, and at what price?** A ~$97–147 lifetime breaks even against $47/yr in ~2–3 years, which *undercuts the recurring-revenue thesis.* | **Pick a spine.** Keep $47/yr as the anchor. If you want a lifetime option, frame it *only* as a bounded early-bird instrument to capitalize the community fund (capped quantity), not the default SKU. Don't ship recurring + lifetime as equals. | KS copy freeze |
|
||||
| **D-2** | **Contributor payment — how do people earn for *writing workflows* (not just referring)?** Today the only paid mechanic is affiliate referral. | **Resolve before launch.** This is the engine of the "living book." Decide: royalty pool, per-accepted-workflow bounty, or an explicit "v1 is authored, paid contribution ships in Q1" — but decide, don't leave blank. | The core value prop |
|
||||
| **D-1** | ~~Lifetime tier~~ **Signed 2026-08-31.** Product price is **$47/yr**. No lifetime SKU as an equal v1 product. | Locked. Don't quote a lifetime price. Hardcopy remains an at-cost upcharge. | — |
|
||||
| **D-2** | ~~Writer payment~~ **Signed 2026-08-31.** The first set of writers is engaged **on contract**. v1 is an authored book. Affiliate referral can still pay for *referring backers*; it is not how writing is paid. Open contribution + any royalty/bounty is post-v1 (Layer 2), not a launch mechanic. | Locked for v1. Revisit royalties before opening Layer 2. | — |
|
||||
| **D-3** | **Co-author confirmations** (Higher Ed, Communities verticals). | Confirm within the week or cut those verticals from v1 and add post-launch. | Chapter outline, scope |
|
||||
| **D-4** | **Refresh the source-of-truth plan** to the 9/26 dates and re-signed terms (depends on D-1/D-2). | Do after D-1/D-2 land. | Copy freeze |
|
||||
| **D-5** | **Human-first or agent-first for v1?** Writing for human motivation and for machine ingestion are different jobs. | **Human-first.** Build the content format so agents *can* read it later (K-7), but optimize v1 for human learners. Agent onboarding is Layer 4. | Content design |
|
||||
@@ -375,16 +428,17 @@ changes from the prior draft, and the reasoning:
|
||||
funnel are explicitly later layers.
|
||||
3. **Elevated the content cold-start** to the #1 risk and added the *Minimum Lovable Library*
|
||||
launch gate (§5.2).
|
||||
4. **Told the truth about incentives** (§5.3): v1 is an authored book; the "contributor
|
||||
economy" is currently a referral scheme; paid contribution (D-2) is now launch-blocking.
|
||||
5. **Forced the subscription-vs-lifetime tension** into a real decision (D-1).
|
||||
4. **Told the truth about incentives** (§5.3). **D-2 signed 2026-08-31:** founding writers on
|
||||
contract; v1 authored; royalties wait for Layer 2. Affiliate still pays referrals, not writing.
|
||||
5. **Forced the subscription-vs-lifetime tension** into a real decision. **D-1 signed 2026-08-31:**
|
||||
**$47/yr** only. No lifetime SKU as an equal v1 product.
|
||||
6. **Split the validation bar from the funding floor** (§8) so a funded-but-dead outcome can't
|
||||
hide.
|
||||
7. **Reframed the pitch as utility-first** (§4, §9 hook test) — the buyer wants a workflow, not
|
||||
an ownership philosophy.
|
||||
8. **Demoted governance to proportionate** (Appendix B), keeping only the NFT-scrub and
|
||||
truth-in-claims as active gates.
|
||||
9. **Turned the domain "decision" into a same-day chore** (§9).
|
||||
9. **Turned the domain into a same-day chore** (§9). **Done 2026-08-31:** `aibook.fun` renewed.
|
||||
10. **Translated the jargon out.** Internal codes, handles, and merge-history are gone from the
|
||||
body; a who's-who / glossary can be maintained separately if the team wants traceability
|
||||
back to the source-of-truth IDs.
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
---
|
||||
title: "AIBook.fun — Product Specification"
|
||||
title: "AiBook.fun — Product Specification"
|
||||
type: spec
|
||||
status: draft
|
||||
owner: Patrick (Product)
|
||||
launch-target: 2026-09-26
|
||||
last-updated: 2026-08-26
|
||||
last-updated: 2026-08-31
|
||||
companions: [AiBook_PRD.md, AiBook_Implementation_Plan.md]
|
||||
---
|
||||
|
||||
# 📚 AIBook.fun — Product Specification
|
||||
# 📚 AiBook.fun — Product Specification
|
||||
|
||||
> **Status: DRAFT.** This spec is the *thinking* behind the product — the vision, the
|
||||
> principles, the model. The [PRD](AiBook_PRD.md) turns it into requirements; the
|
||||
@@ -22,7 +22,7 @@ companions: [AiBook_PRD.md, AiBook_Implementation_Plan.md]
|
||||
|
||||
## TL;DR
|
||||
|
||||
AIBook.fun is a **living, crowd-written field guide to using AI agents responsibly at work.**
|
||||
AiBook.fun is a **living, crowd-written field guide to using AI agents responsibly at work.**
|
||||
Its unit of value is a **workflow you can run** — a documented, tested recipe for doing a real
|
||||
job with AI, including the guardrails. It launches as an annual subscription via Kickstarter on
|
||||
**September 26, 2026**.
|
||||
@@ -56,7 +56,8 @@ ambition — but an engine needs one cylinder firing before you add the rest. He
|
||||
Everything else the product wants to be — a contributor economy, a cohort program, an
|
||||
onboarding corpus for AI agents — is a **layer built on top of this loop**, and only worth
|
||||
building once the loop demonstrably works. We measure that with one number, **Activation**: *did
|
||||
a reader run at least one workflow within 14 days?* (Full metric set in [PRD §8](AiBook_PRD.md).)
|
||||
a reader run at least one workflow and finish one Try-it within 14 days of getting access
|
||||
(access key, not pledge)?* Floors/targets ratified 2026-08-29 — full set in [PRD §8](AiBook_PRD.md).
|
||||
|
||||
### The product in layers
|
||||
| Layer | What | When |
|
||||
@@ -95,7 +96,7 @@ These are gates, not preferences — a workflow or a claim either clears them or
|
||||
|
||||
| Actor | Who | Their job | The boundary |
|
||||
|:--|:--|:--|:--|
|
||||
| **Reader / subscriber** | Practitioners (real estate, financial advisors, fractional execs, higher ed, communities, tech) | Get current, trustworthy AI workflows to apply this week | Pays for access (~$47/yr — *draft*) |
|
||||
| **Reader / subscriber** | Practitioners (real estate, financial advisors, fractional execs, higher ed, communities, tech) | Get current, trustworthy AI workflows to apply this week | Pays for access (**$47/yr** — signed) |
|
||||
| **Co-author** | Confirmed: three founders across RE/FA, C-suite, and tech. Potential: two more for Higher Ed & Communities | Own a vertical; write and curate its workflows | Content follows the template; curated |
|
||||
| **Curator / editor** | Co-authors + community editors | Keep the quality bar; run the editorial pipeline | Curating ≠ owning the platform |
|
||||
| **Affiliate** | Community, podcast, press | Refer backers; earn commission | Commission rates below |
|
||||
@@ -146,9 +147,11 @@ answer to "how do I know this isn't hallucinated AI advice?"
|
||||
| **Costs** | Model/tool costs where known — honesty about economics |
|
||||
| **Author & sources** | Who, when, which vertical, with citations |
|
||||
|
||||
**Chapters** are curated collections of these per vertical. **Editions** refresh annually —
|
||||
**Chapters** are the reading unit: a substantial essay per vertical, with **full workflows
|
||||
nested in the argument** (not a table of contents of cards). **Editions** refresh annually —
|
||||
which is the honest justification for a *subscription*: AI moves fast enough that a static book
|
||||
goes stale, so the value is in staying current.
|
||||
goes stale, so the value is in staying current. Reading IA locked 2026-08-31; see
|
||||
[PRD §5.4](AiBook_PRD.md).
|
||||
|
||||
### 4.2 Seed the shelf before you sell tickets (the cold-start rule)
|
||||
The value proposition is a rich library. The failure mode is a near-empty one. Crowd-sourced
|
||||
@@ -179,7 +182,7 @@ around and after launch, not gating it:
|
||||
### 4.4 Digital surface (current state)
|
||||
| Surface | What it is | Status |
|
||||
|:--|:--|:--|
|
||||
| `aibook.fun` domain | Public home: pitch, sample workflows, affiliate signup, campaign link | Parked — **expires 09-05, renew immediately** |
|
||||
| `aibook.fun` domain | Public home: pitch, sample workflows, affiliate signup, campaign link | **Renewed 2026-08-31** |
|
||||
| Landing page (built) | A staged proof-of-concept, ready to review and push live | Staged locally, not yet public |
|
||||
| Subscription access | Digital key → PDF + web reader + annual updates | Not built yet (post-campaign) |
|
||||
| Community | Team channel live; cohort spaces not built | Partial |
|
||||
@@ -218,9 +221,9 @@ from the core loop.*
|
||||
|
||||
| Item | Value | Status |
|
||||
|:--|:--|:--|
|
||||
| Anchor subscription | $47/yr digital + hardcopy upcharge | **Draft** — needs commercial re-sign for the 9/26 relaunch |
|
||||
| Lifetime access | Proposed; ~$97–147 one-time *(figures illustrative — do not quote)* | **Open decision** ([D-1](#8-open-decisions)) |
|
||||
| Contributor royalties | None documented today; current mechanic is affiliate referral only | **Open decision** ([D-2](#8-open-decisions)) |
|
||||
| Anchor subscription | **$47/yr** digital + hardcopy at-cost upcharge | **Signed 2026-08-31** |
|
||||
| Lifetime access | Not a v1 SKU | **Signed D-1:** $47/yr only |
|
||||
| Founding writers | Paid **on contract** (v1 is authored). Affiliate still pays referrals, not writing. | **Signed D-2 2026-08-31.** Royalties/bounties wait for Layer 2. |
|
||||
| Projected revenue | ~$53,600 at 706 backers | Draft planning figure |
|
||||
| Pre-revenue budget | ~$6,000 (ads + KS fees + affiliate fee) | Draft planning figure |
|
||||
| "eBookNFT platform" | A future idea; this book is the first product | Not in scope |
|
||||
@@ -274,8 +277,8 @@ carries a recommendation as a starting point, not a settled answer.
|
||||
|
||||
| # | Decision | Recommendation |
|
||||
|:--|:--|:--|
|
||||
| **D-1** | Lifetime tier — offer it, at what price/position? | Keep $47/yr as the anchor; a lifetime option only as a bounded early-bird capitalization play, not the default. |
|
||||
| **D-2** | Contributor payment — how do people earn for *writing* workflows, not just referring? | **Resolve before launch** — it's the engine of the "living book." Royalty pool, per-workflow bounty, or an explicit "v1 authored, paid contribution in Q1." |
|
||||
| **D-1** | ~~Lifetime~~ **Signed 2026-08-31:** **$47/yr** only. No lifetime SKU as an equal product. | Locked. |
|
||||
| **D-2** | ~~Writer pay~~ **Signed 2026-08-31:** founding writers on **contract**. v1 authored. Layer 2 royalties later. | Locked for v1. |
|
||||
| **D-3** | Confirm the two unconfirmed co-authors (Higher Ed, Communities) | Confirm this week, or cut those verticals from v1 and add post-launch. |
|
||||
| **D-4** | Refresh the source-of-truth plan to the 9/26 dates & re-signed terms | Do after D-1/D-2 land. |
|
||||
| **D-5** | Human-first or agent-first for v1? | Human-first. Build the format so agents *can* read it later; optimize v1 for human learners. |
|
||||
|
||||
@@ -1,15 +1,21 @@
|
||||
# 📚 AIBook.fun
|
||||
# 📚 AiBook.fun
|
||||
|
||||
**A living, crowd-written field guide to using AI agents responsibly at work.**
|
||||
**An authored field guide of runnable AI workflows for work.**
|
||||
|
||||
AIBook.fun's unit of content isn't a chapter — it's a **workflow you can actually run**: a
|
||||
documented, tested recipe for getting a real job done with AI, guardrails included. It's written
|
||||
and kept current by the practitioners who use it, and it launches as an annual subscription,
|
||||
crowdfunded on Kickstarter.
|
||||
People read **chapters**. Each chapter is a substantial essay for one vertical, with full
|
||||
workflows nested in the argument. The workflow is the unit of practice: a documented, tested
|
||||
recipe for a real job, guardrails included. The first edition is written on contract by founding
|
||||
authors. It launches as a **$47/yr** subscription, crowdfunded on Kickstarter.
|
||||
|
||||
> **Status: planning stage.** This repository holds the product's planning documents. The product
|
||||
> is not yet live, and everything here is a working draft — figures, dates, and commercial terms
|
||||
> are planning assumptions, not commitments. Public launch is **targeted for September 26, 2026**.
|
||||
> **Status: planning + writing.** Planning docs and the chapter blank live here. The product is
|
||||
> not yet live. **$47/yr** is signed. Domain `aibook.fun` is renewed. Other figures and unsigned
|
||||
> terms are still planning assumptions, not for public quote. Launch target **26 Sep 2026**.
|
||||
|
||||
|
||||
## Content
|
||||
|
||||
- [Content management guide](workflows/content-management.md) — write, review, QA, and ship chapters
|
||||
- [Chapter blank](workflows/chapter-structure.md) — copy per vertical; leave the blank untouched
|
||||
|
||||
## The idea in one loop
|
||||
|
||||
@@ -30,24 +36,26 @@ not read AI theory.
|
||||
|
||||
## What's in this repository
|
||||
|
||||
This is a documentation and planning repo. Three companion documents define the product:
|
||||
This is a documentation and writing repo.
|
||||
|
||||
| Document | What it covers |
|
||||
|:--|:--|
|
||||
| [Product Requirements (PRD)](AiBook_PRD.md) | What we're building and why — scope, requirements, success metrics, open decisions |
|
||||
| [Product Specification (Spec)](AiBook_Spec.md) | The thinking behind it — vision, principles, content model, business model |
|
||||
| [Implementation Plan](AiBook_Implementation_Plan.md) | How and when — the path from now to launch and fulfillment |
|
||||
| [Product Requirements (PRD)](AiBook_PRD.md) | What we're building and why. Scope, requirements, success metrics, open decisions |
|
||||
| [Product Specification (Spec)](AiBook_Spec.md) | The thinking behind it. Vision, principles, content model, business model |
|
||||
| [Implementation Plan](AiBook_Implementation_Plan.md) | How and when. Path from now to launch and fulfillment |
|
||||
| [Content management](workflows/content-management.md) | How chapters are written, reviewed, QA’d, and kept current |
|
||||
| [Chapter structure](workflows/chapter-structure.md) | The blank chapter for review. Copy it into a vertical file when writing starts |
|
||||
|
||||
New here? Start with the **[Spec](AiBook_Spec.md)** for the vision, then the **[PRD](AiBook_PRD.md)**
|
||||
for the specifics.
|
||||
for the specifics. Writers start at the **[content management guide](workflows/content-management.md)** and the **[chapter blank](workflows/chapter-structure.md)**.
|
||||
|
||||
## How it works (the short version)
|
||||
|
||||
- **Content:** every entry follows one *Workflow Recipe* template — problem, method (showing the
|
||||
real tool output), safeguards, evidence, a ~15-minute Try-it, and costs. The template is the
|
||||
quality guarantee — the structural answer to "how do I know this AI advice isn't made up?"
|
||||
- **Editions:** the guide refreshes annually — which is why it's a subscription. AI moves fast,
|
||||
and stale advice is worthless.
|
||||
- **Content:** readers get a chapter essay. Nested in it, every workflow follows one recipe:
|
||||
problem, actors, setup, safeguards, method (real tool output), evidence, a ~15-minute Try-it,
|
||||
share, costs, author. Safeguards sit before the steps. The template is the quality guarantee.
|
||||
- **Currency:** recipes are updated as tools and models change (often weekly or monthly). The
|
||||
`$47/yr` subscription funds that work. “2026 edition” is catalog framing, not a once-a-year reprint.
|
||||
- **Contribution:** the first edition is written by a founding set of co-authors; open community
|
||||
contribution follows once the library is worth browsing.
|
||||
- **Responsible by design:** the guardrails (data handling, human oversight, failure modes) are
|
||||
@@ -61,7 +69,7 @@ for the specifics.
|
||||
| Post-launch | Fulfill the first edition; open community contribution |
|
||||
| Later | Cohort learning, annual editions, deeper ecosystem integration |
|
||||
|
||||
AIBook.fun is part of the **WeOwnNet** ecosystem.
|
||||
AiBook.fun is part of the **WeOwnNet** ecosystem.
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
# aibook-fun deploy — gitignore
|
||||
# ⚠️ CRITICAL: Never commit credentials or state files
|
||||
|
||||
# =============================================================================
|
||||
# Terraform / OpenTofu State (CRITICAL - contains infrastructure details)
|
||||
# =============================================================================
|
||||
*.tfstate
|
||||
*.tfstate.*
|
||||
*.tfstate.backup
|
||||
.terraform/
|
||||
# NOTE: .terraform.lock.hcl is NOT ignored — commit it so provider versions
|
||||
# are reproducible across machines/CI runs.
|
||||
|
||||
# Terraform variable files with real values
|
||||
terraform.tfvars
|
||||
terraform.tfvars.json
|
||||
*.auto.tfvars
|
||||
*.auto.tfvars.json
|
||||
|
||||
# Terraform crash logs
|
||||
crash.log
|
||||
crash.*.log
|
||||
|
||||
# =============================================================================
|
||||
# Environment Files (CRITICAL - contains passwords)
|
||||
# =============================================================================
|
||||
.env
|
||||
.env.prod
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# =============================================================================
|
||||
# Backups (may contain sensitive data)
|
||||
# =============================================================================
|
||||
backups/
|
||||
*.tar.gz
|
||||
*.sql
|
||||
*.sql.gz
|
||||
|
||||
# =============================================================================
|
||||
# Logs
|
||||
# =============================================================================
|
||||
logs/
|
||||
*.log
|
||||
|
||||
# =============================================================================
|
||||
# OS & Editor
|
||||
# =============================================================================
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
Thumbs.db
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
.idea/
|
||||
.vscode/
|
||||
*.code-workspace
|
||||
|
||||
# =============================================================================
|
||||
# Docker
|
||||
# =============================================================================
|
||||
docker-compose.override.yml
|
||||
docker-compose.override.yaml
|
||||
|
||||
# =============================================================================
|
||||
# Ansible
|
||||
# =============================================================================
|
||||
*.retry
|
||||
.vault-pass
|
||||
|
||||
# OpenTofu saved plans (sensitive) — never commit
|
||||
*.tfplan
|
||||
@@ -0,0 +1,25 @@
|
||||
# Deploy
|
||||
|
||||
Provisions a DO droplet + reserved IP + firewall + monitoring, builds the
|
||||
Next.js image locally on the droplet, runs it behind Caddy.
|
||||
|
||||
## Deploy from scratch
|
||||
|
||||
```bash
|
||||
cd terraform
|
||||
infisical login
|
||||
export INFISICAL_PROJECT_ID=<aibook-fun-project-id>
|
||||
./itofu.sh init && ./itofu.sh plan && ./itofu.sh apply
|
||||
./itofu.sh output -raw droplet_ip
|
||||
|
||||
# add Cloudflare A record: aibook.fun → <that-ip>
|
||||
|
||||
cd ..
|
||||
ansible-playbook -i 'root@<that-ip>,' ansible/deploy.yml
|
||||
```
|
||||
|
||||
## Structure
|
||||
|
||||
- `terraform/` — droplet + IP + firewall + monitoring
|
||||
- `docker/` — Dockerfile + compose + Caddy
|
||||
- `ansible/` — droplet convergence
|
||||
@@ -0,0 +1,33 @@
|
||||
# Ansible settings for deploying aibook-fun.
|
||||
#
|
||||
# The whole point of this file is SSH connection reuse. On a workstation whose
|
||||
# SSH key lives in a hardware-backed agent (Secretive, a YubiKey, the Secure
|
||||
# Enclave), every *new* TCP connection needs a fresh signature — which means a
|
||||
# Touch ID prompt. Ansible opens many connections per run and does so
|
||||
# non-interactively, so those prompts cannot be answered and the run dies with:
|
||||
#
|
||||
# sign_and_send_pubkey: signing failed ... agent refused operation
|
||||
#
|
||||
# Ansible's own defaults make this worse in two ways, both fixed below:
|
||||
#
|
||||
# 1. It keeps control sockets in ~/.ansible/cp, separate from the ones the
|
||||
# operator's own `ssh` has already authenticated. Pointing it at the same
|
||||
# directory and the same %C naming as OpenSSH means ansible *reuses* a
|
||||
# master connection the operator authorised earlier — no new signature.
|
||||
# 2. ControlPersist defaults to 60s, so a master closes between steps of a
|
||||
# deploy and the next one needs another signature.
|
||||
#
|
||||
# Together: authenticate once at the start of a work session, then deploy
|
||||
# repeatedly without touching the key again.
|
||||
[defaults]
|
||||
host_key_checking = True
|
||||
interpreter_python = auto_silent
|
||||
|
||||
[ssh_connection]
|
||||
# Match OpenSSH's own ControlPath so ansible shares the operator's masters.
|
||||
# %%C is escaped for configparser — ssh receives %C (a hash of local host,
|
||||
# remote host, port and user), exactly what ~/.ssh/config uses.
|
||||
control_path_dir = ~/.ssh/sockets
|
||||
control_path = %(directory)s/%%C
|
||||
ssh_args = -C -o ControlMaster=auto -o ControlPersist=4h
|
||||
pipelining = True
|
||||
@@ -0,0 +1,150 @@
|
||||
---
|
||||
# Usage: ansible-playbook -i 'root@<droplet-ip>,' deploy/ansible/deploy.yml
|
||||
# Pre: droplet cloud-init complete (.bootstrap-complete marker present)
|
||||
|
||||
- name: Deploy aibook-fun app layer
|
||||
hosts: all
|
||||
gather_facts: false
|
||||
become: true
|
||||
vars:
|
||||
app_dir: /opt/aibook_fun
|
||||
repo_dir: /opt/aibook_fun/repo
|
||||
repo_url: "https://git.weown.tools/WeOwnAI/aibook-fun.git"
|
||||
repo_branch: main
|
||||
image_tag: "aibook-fun-marketing:v1"
|
||||
|
||||
pre_tasks:
|
||||
- name: Verify droplet has completed cloud-init bootstrap
|
||||
ansible.builtin.stat:
|
||||
path: "{{ app_dir }}/.bootstrap-complete"
|
||||
register: bootstrap_marker
|
||||
|
||||
- name: Fail clearly if bootstrap is not complete
|
||||
ansible.builtin.fail:
|
||||
msg: >-
|
||||
{{ app_dir }}/.bootstrap-complete is missing — droplet has not
|
||||
finished cloud-init. Wait a few minutes after `tofu apply` and retry.
|
||||
Check /var/log/cloud-init-output.log on the droplet.
|
||||
when: not bootstrap_marker.stat.exists
|
||||
|
||||
- name: Ensure app dir exists
|
||||
ansible.builtin.file:
|
||||
path: "{{ app_dir }}"
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0755"
|
||||
|
||||
tasks:
|
||||
# ─── Clone / update repo on droplet ────────────────────────────────────
|
||||
- name: Clone (or update) aibook-fun repo on droplet
|
||||
ansible.builtin.git:
|
||||
repo: "{{ repo_url }}"
|
||||
dest: "{{ repo_dir }}"
|
||||
version: "{{ repo_branch }}"
|
||||
force: true
|
||||
register: git_clone
|
||||
notify: Rebuild image
|
||||
|
||||
# ─── Upload Dockerfile (deploy/ scaffold not yet pushed to git.weown.tools) ─
|
||||
- name: Upload Dockerfile to droplet
|
||||
ansible.builtin.copy:
|
||||
src: ../docker/Dockerfile
|
||||
dest: "{{ app_dir }}/Dockerfile"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
|
||||
# ─── Build docker image locally on droplet (unconditional — docker layer cache handles no-ops) ─
|
||||
- name: Build Next.js docker image locally
|
||||
ansible.builtin.shell: |
|
||||
set -euo pipefail
|
||||
docker build -t {{ image_tag }} -f {{ app_dir }}/Dockerfile {{ repo_dir }}/marketing-site/
|
||||
args:
|
||||
executable: /bin/bash
|
||||
register: image_build
|
||||
changed_when: "'writing image' in image_build.stderr"
|
||||
notify: Reconcile docker compose stack
|
||||
|
||||
# ─── Upload compose + Caddyfile ────────────────────────────────────────
|
||||
- name: Upload compose.yaml
|
||||
ansible.builtin.copy:
|
||||
src: ../docker/compose.prod.yaml
|
||||
dest: "{{ app_dir }}/compose.yaml"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
notify: Reconcile docker compose stack
|
||||
|
||||
- name: Upload Caddyfile
|
||||
ansible.builtin.copy:
|
||||
src: ../docker/Caddyfile
|
||||
dest: "{{ app_dir }}/Caddyfile"
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0644"
|
||||
notify: Reconcile docker compose stack
|
||||
|
||||
- name: Ensure caddy log dir is writable
|
||||
ansible.builtin.file:
|
||||
path: /var/log/caddy
|
||||
state: directory
|
||||
owner: root
|
||||
group: root
|
||||
mode: "0777"
|
||||
|
||||
- name: Ensure Caddy Docker volumes are writable (caddy runs as UID 1000)
|
||||
ansible.builtin.shell: |
|
||||
set -euo pipefail
|
||||
for suffix in caddy_data caddy_config; do
|
||||
path="/var/lib/docker/volumes/aibook_fun_${suffix}/_data"
|
||||
if [ -d "$path" ]; then
|
||||
chown -R 1000:1000 "$path"
|
||||
fi
|
||||
done
|
||||
args:
|
||||
executable: /bin/bash
|
||||
changed_when: false
|
||||
|
||||
# ─── Ensure compose stack is running (idempotent) ──────────────────────
|
||||
- name: Ensure compose stack is running (idempotent — `up -d` no-op if unchanged)
|
||||
ansible.builtin.shell: |
|
||||
set -euo pipefail
|
||||
cd {{ app_dir }}
|
||||
docker compose up -d --remove-orphans
|
||||
args:
|
||||
executable: /bin/bash
|
||||
register: compose_up
|
||||
changed_when: "'Started' in compose_up.stderr or 'Created' in compose_up.stderr or 'Recreated' in compose_up.stderr"
|
||||
|
||||
- name: Wait for web app to respond
|
||||
ansible.builtin.uri:
|
||||
url: http://127.0.0.1:3000/
|
||||
status_code: [200]
|
||||
register: health_probe
|
||||
retries: 20
|
||||
delay: 5
|
||||
until: health_probe.status == 200
|
||||
|
||||
- name: Report success
|
||||
ansible.builtin.debug:
|
||||
msg: "aibook-fun app layer deployed. URL: https://aibook.fun"
|
||||
|
||||
handlers:
|
||||
- name: Rebuild image
|
||||
ansible.builtin.shell: |
|
||||
set -euo pipefail
|
||||
cd {{ repo_dir }}
|
||||
docker build -t {{ image_tag }} -f {{ repo_dir }}/deploy/docker/Dockerfile {{ repo_dir }}/marketing-site/
|
||||
args:
|
||||
executable: /bin/bash
|
||||
changed_when: false
|
||||
|
||||
- name: Reconcile docker compose stack
|
||||
ansible.builtin.shell: |
|
||||
set -euo pipefail
|
||||
cd {{ app_dir }}
|
||||
docker compose up -d --force-recreate --remove-orphans
|
||||
args:
|
||||
executable: /bin/bash
|
||||
changed_when: false
|
||||
@@ -0,0 +1,76 @@
|
||||
# aibook-fun — host hardening (CIS-aligned, Phase A)
|
||||
#
|
||||
# Applies the DevSec hardening baseline (≈ CIS Ubuntu L1) to the droplet:
|
||||
# kernel/sysctl, auth policy, filesystem perms, SSH crypto + policy — then
|
||||
# measures the result with Lynis. Idempotent; run any time after bootstrap:
|
||||
#
|
||||
# ansible-galaxy collection install -r ansible/requirements.yml # once
|
||||
# ansible-playbook ansible/harden.yml -i 'root@<droplet-ip>,'
|
||||
#
|
||||
# PHASE A vs PHASE B (deliberate scope — do not "fix" this into Phase B):
|
||||
# Phase A (this play): CIS L1 OS + SSH hardening with root login KEPT
|
||||
# (key-only). Every fleet tool (deploy.sh, backup.sh, manage-droplets.sh)
|
||||
# SSHes as root@; removing root here would break the fleet mid-flight.
|
||||
# Phase B (tracked, pre-first-customer): ops-user model (root SSH off,
|
||||
# password-sudo 2FA), mesh/CIDR-locked port 22 — per SOP-INFRA-012. Needs
|
||||
# the fleet tooling migrated off root@ first.
|
||||
#
|
||||
# Docker-safe exceptions (the CIS-L2-vs-container-runtime conflicts):
|
||||
# - net.ipv4.ip_forward stays 1 — Docker bridge networking requires it. A
|
||||
# defaults-level override silently LOSES to the inner role's defaults;
|
||||
# it must be a task-var on the include (hit live 2026-07-03: containers
|
||||
# got DNS but no TCP egress when this landed at 0).
|
||||
---
|
||||
- name: Harden aibook-fun host (CIS L1 via devsec — Phase A)
|
||||
hosts: all
|
||||
become: true
|
||||
vars:
|
||||
run_lynis: true
|
||||
|
||||
tasks:
|
||||
- name: "OS hardening (devsec.hardening.os_hardening ≈ CIS Ubuntu L1)"
|
||||
ansible.builtin.include_role:
|
||||
name: devsec.hardening.os_hardening
|
||||
vars:
|
||||
# MUST be task-vars here (see header) — Docker bridge needs ip_forward.
|
||||
sysctl_overwrite:
|
||||
net.ipv4.ip_forward: 1
|
||||
|
||||
- name: "SSH hardening (devsec.hardening.ssh_hardening — key-only, strong KEX/ciphers)"
|
||||
ansible.builtin.include_role:
|
||||
name: devsec.hardening.ssh_hardening
|
||||
vars:
|
||||
# Phase A: root stays (fleet tooling), but key-only and CIS crypto.
|
||||
ssh_permit_root_login: "without-password"
|
||||
ssh_password_authentication: false
|
||||
ssh_challenge_response_authentication: false
|
||||
|
||||
- name: "Measure: install + run Lynis (hardening index; non-blocking)"
|
||||
when: run_lynis | bool
|
||||
block:
|
||||
- name: "Install Lynis"
|
||||
ansible.builtin.apt:
|
||||
name: lynis
|
||||
state: present
|
||||
update_cache: true
|
||||
|
||||
- name: "Run Lynis audit (quick)"
|
||||
ansible.builtin.command: lynis audit system --quick --no-colors
|
||||
register: lynis_out
|
||||
changed_when: false
|
||||
failed_when: false
|
||||
|
||||
- name: "Lynis summary (record this index in the site CHANGELOG)"
|
||||
ansible.builtin.debug:
|
||||
msg: "{{ lynis_out.stdout_lines | select('search', 'Hardening index|Warnings|Suggestions|Tests performed') | list }}"
|
||||
|
||||
- name: "Verify Docker survived hardening (containers must still run)"
|
||||
# brace-free format string: Go-template braces here would be re-templated
|
||||
# by ansible's own Jinja pass and error out.
|
||||
ansible.builtin.command: docker info --format json
|
||||
register: docker_ok
|
||||
changed_when: false
|
||||
|
||||
- name: "Docker status"
|
||||
ansible.builtin.debug:
|
||||
msg: "Docker OK (server {{ (docker_ok.stdout | from_json).ServerVersion | default('unknown') }}) — hardening did not break the runtime"
|
||||
@@ -0,0 +1,8 @@
|
||||
# Ansible Galaxy requirements for the optional hardening play (harden.yml).
|
||||
# Install once per operator workstation:
|
||||
# ansible-galaxy collection install -r ansible/requirements.yml
|
||||
collections:
|
||||
# DevSec Hardening Framework — CIS/STIG-aligned os_hardening + ssh_hardening.
|
||||
# https://github.com/dev-sec/ansible-collection-hardening
|
||||
- name: devsec.hardening
|
||||
version: ">=8.8.0"
|
||||
@@ -0,0 +1,23 @@
|
||||
|
||||
aibook.fun {
|
||||
|
||||
# AIBook.fun is a static marketing site — pure reverse proxy to the Next.js
|
||||
# standalone server. No auth/headers added here beyond baseline security.
|
||||
reverse_proxy web:3000
|
||||
|
||||
log {
|
||||
# Host-bind-mounted /var/log/caddy/ so logs survive container recreation.
|
||||
output file /var/log/caddy/aibook-fun.log
|
||||
}
|
||||
|
||||
header {
|
||||
# Force HTTPS for a year (HSTS — a lapsed cert is a service outage, not a
|
||||
# warning; weown rail per W24 phase4 findings).
|
||||
Strict-Transport-Security "max-age=31536000; includeSubDomains"
|
||||
X-Content-Type-Options nosniff
|
||||
X-Frame-Options SAMEORIGIN
|
||||
X-XSS-Protection "1; mode=block"
|
||||
Referrer-Policy strict-origin-when-cross-origin
|
||||
-Server
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
# syntax=docker/dockerfile:1
|
||||
# aibook-fun — Next.js 16 marketing site (marketing-site/), standalone output.
|
||||
#
|
||||
# Build context = marketing-site/ (see .gitea/workflows/deploy.yml):
|
||||
# docker build -f deploy/docker/Dockerfile -t <image> marketing-site/
|
||||
#
|
||||
# Multi-stage: deps → build (next build → .next/standalone) → slim non-root runner.
|
||||
# Requires `output: 'standalone'` in next.config.mjs (added on this branch).
|
||||
# Node 20.9+ / 22+ required by Next 16; pin 22 LTS.
|
||||
|
||||
FROM node:22-alpine AS deps
|
||||
WORKDIR /app
|
||||
# Lockfiles first for layer caching.
|
||||
COPY package.json package-lock.json ./
|
||||
RUN npm ci
|
||||
|
||||
FROM node:22-alpine AS builder
|
||||
WORKDIR /app
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
FROM node:22-alpine AS runner
|
||||
WORKDIR /app
|
||||
ENV NODE_ENV=production
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
# Next standalone ships as a single node server.js; run as non-root (uid 1001).
|
||||
RUN addgroup --system --gid 1001 nodejs \
|
||||
&& adduser --system --uid 1001 --ingroup nodejs nextjs
|
||||
|
||||
# Static assets not bundled into the standalone output.
|
||||
COPY --from=builder /app/public ./public
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||
|
||||
USER nextjs
|
||||
EXPOSE 3000
|
||||
ENV PORT=3000
|
||||
ENV HOSTNAME=0.0.0.0
|
||||
CMD ["node", "server.js"]
|
||||
@@ -0,0 +1,59 @@
|
||||
services:
|
||||
web:
|
||||
image: aibook-fun-marketing:v1
|
||||
pull_policy: never
|
||||
restart: unless-stopped
|
||||
ports:
|
||||
# Loopback-only: lets caddy proxy and health probes reach the app.
|
||||
# Not internet-exposed; caddy handles :80/:443 → web:3000.
|
||||
- "127.0.0.1:3000:3000"
|
||||
networks:
|
||||
- aibooknet
|
||||
healthcheck:
|
||||
test: ["CMD-SHELL", "curl -f -o /dev/null -w '%{http_code}' http://localhost:3000/ | grep -q '^200$' || exit 1"]
|
||||
start_period: 30s
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 5
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 512M
|
||||
reservations:
|
||||
memory: 128M
|
||||
|
||||
caddy:
|
||||
image: caddy:2
|
||||
restart: unless-stopped
|
||||
depends_on:
|
||||
- web
|
||||
environment:
|
||||
DOMAIN: aibook.fun
|
||||
ports:
|
||||
- "80:80"
|
||||
- "443:443"
|
||||
- "443:443/udp"
|
||||
volumes:
|
||||
- ./Caddyfile:/etc/caddy/Caddyfile:ro
|
||||
- caddy_data:/data
|
||||
- caddy_config:/config
|
||||
- /var/log/caddy:/var/log/caddy
|
||||
networks:
|
||||
- aibooknet
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
memory: 256M
|
||||
reservations:
|
||||
memory: 128M
|
||||
|
||||
volumes:
|
||||
caddy_data:
|
||||
name: aibook_fun_caddy_data
|
||||
caddy_config:
|
||||
name: aibook_fun_caddy_config
|
||||
|
||||
networks:
|
||||
aibooknet:
|
||||
name: aibook_fun_net
|
||||
driver: bridge
|
||||
@@ -0,0 +1,41 @@
|
||||
# This file is maintained automatically by "tofu init".
|
||||
# Manual edits may be lost in future updates.
|
||||
|
||||
provider "registry.opentofu.org/digitalocean/digitalocean" {
|
||||
version = "2.100.0"
|
||||
constraints = "~> 2.36"
|
||||
hashes = [
|
||||
"h1:+1p5n5KeGjz/ulw/ZLXoaBkF+2UTgKqWqERw1nA2sJQ=",
|
||||
"h1:79G5uDt1VHL6gWtSnK8lCOHZpo/jp/kSGA7FXtqQvX4=",
|
||||
"h1:7r9AZrpc8pB6PRsJfmxSGLzIRmohmfpX6RrnA1FLbh4=",
|
||||
"h1:9VsRnY7rmGiMFVG4ix3ry2fx8B8d7l9PyEpmGjjiW3I=",
|
||||
"h1:LchVh6xhpXw1PEnl2mRnsLlR4dzLePw8M2vw4DuPk9U=",
|
||||
"h1:OmnMLcKMFnZLI1CvTgQBod0awOpuVxsfB8dqBejfwE8=",
|
||||
"h1:Q9BxzK1Tp8YeuCUXVogVfqTsVCrWUUJJdvpL7UA0W/s=",
|
||||
"h1:R13HFu3vyxrd4aHyh/+p2YY0vWpPAFjafBRYVuIL5HE=",
|
||||
"h1:RJH5t57bLx1b2+l+gS6RRHyakhEQjSKL/QYu6npCtbI=",
|
||||
"h1:WQ2ClvMwBILHDzWWhAm3LBRra4HkSe9taUlUGSLBNWI=",
|
||||
"h1:WbQfCVfC+GU0qPSoZKuoEllr3cMqwTC1Fx5DfbUjy/o=",
|
||||
"h1:iwjK8zLBTHWHICCP/O+QFcyxH16bV4gKPFUbmu2foqc=",
|
||||
"h1:pTFXceDc5intkLpVFVW3PKfwkF1CvmnWi3vYcF6SAQs=",
|
||||
"h1:pc1iMmHPQA37PCkVWTRzuO/WgaoSGYtSBVP5paO6nK4=",
|
||||
"h1:uDVCzJGtpV2DqyPWoYWjQpbEV48PxS6/U7/uiGfDDsU=",
|
||||
"h1:yyBAhHZmejmdvjuvsF2gAwIZebqOmisQIT5dOQqQx9A=",
|
||||
"zh:021dbdacf7dd636cb66990964737bc4a6402160b5301e06b6fdab03a814f7e96",
|
||||
"zh:083ff822b22738eedc9eae29aa5d4c369b2de921e49fefa9858a4e7c6274b0c1",
|
||||
"zh:10695b5f7dbbe8ba1a20ac6bea1ab8613b43d2b1f6f9b53369bed296b2dff4d2",
|
||||
"zh:110124b9d07cd1f0f2831ad27dfeb5a010a070952ea9a9e675ca3cfe158a0ffa",
|
||||
"zh:409a8b22ffb9a53caf57d0a16f5f8ac0a2fcd61b6b0bcd512a685ea26cd06047",
|
||||
"zh:488e4b494c198c0696c85d2c73c66c40567ca2ad5230bbd95d8ffdead86e646d",
|
||||
"zh:4dd5b6e8c1be5fb619812fe738d0b49e0d24731fb290c0ab5190b7bc60c70e66",
|
||||
"zh:6717fa7f623ad4c9b4d99acceffd1372d272ff02d7c98259dd17ec7ef11b836c",
|
||||
"zh:7a25445caebd2e7f6ab2381578ecaf31744159a7e4a16476f19112d2e50d8519",
|
||||
"zh:86b3d7050ba04ec7e0a14dbee8c0540fca8f4377fb072f87c88a6fcd26388714",
|
||||
"zh:c23f30a38930c283055b6f04acbcad06cb0dd3c71c172eb23bb239f50dd12823",
|
||||
"zh:d1f9c5be7f7d5c71830357bdd9c0fb529185e9380092e1b792f969495c943790",
|
||||
"zh:d222573e7de8f9ad1c5b87a6c44c2dc59947c3968b3e70b7d4c76263d6c8fe5c",
|
||||
"zh:e1f2d606661435416c4d2b48db80244d0acef88a5ce81b5dcbd65ff2642b1b4d",
|
||||
"zh:ea13fad19414586864557601c59e85188601e150c815ec1e71f8ed83f1942a50",
|
||||
"zh:f795be71dc933aaec7145f93068da17f227783964d33a79de591a042aac7c3ca",
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
# aibook-fun - Terraform Backend Configuration
|
||||
# State stored in DigitalOcean Spaces (S3-compatible) for team sharing, SSE-C
|
||||
# encrypted at rest.
|
||||
#
|
||||
# Pass credentials via itofu.sh (preferred) or -backend-config flags:
|
||||
# access_key / secret_key / sse_customer_key
|
||||
# Backend config cannot reference Terraform variables — itofu.sh forwards them.
|
||||
|
||||
terraform {
|
||||
backend "s3" {
|
||||
endpoint = "https://atl1.digitaloceanspaces.com"
|
||||
bucket = "weown-tools-state"
|
||||
key = "aibook-fun/aibook-fun.tfstate"
|
||||
region = "us-east-1"
|
||||
encrypt = true
|
||||
acl = "private"
|
||||
|
||||
# Required for DO Spaces (S3-compatible but not AWS)
|
||||
skip_credentials_validation = true
|
||||
skip_metadata_api_check = true
|
||||
skip_requesting_account_id = true
|
||||
skip_region_validation = true
|
||||
skip_s3_checksum = true
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
#!/usr/bin/env bash
|
||||
# Run OpenTofu with TF_VAR_* creds injected from Infisical /tofu/.
|
||||
# Usage: infisical login && INFISICAL_PROJECT_ID=<id> ./itofu.sh <init|plan|apply|...>
|
||||
set -euo pipefail
|
||||
|
||||
INFISICAL_PROJECT_ID="${INFISICAL_PROJECT_ID:-}"
|
||||
INFISICAL_ENV="${INFISICAL_ENV:-prod}"
|
||||
TOFU_PATH="/tofu"
|
||||
PLAN_FILE="${WEOWN_TOFU_PLAN:-plan.tfplan}"
|
||||
|
||||
: "${INFISICAL_PROJECT_ID:?INFISICAL_PROJECT_ID not set. Export it (e.g. from site.conf) before running itofu.sh.}"
|
||||
|
||||
command -v infisical >/dev/null 2>&1 || { echo "ERROR: infisical CLI not found." >&2; exit 1; }
|
||||
command -v tofu >/dev/null 2>&1 || { echo "ERROR: tofu not found." >&2; exit 1; }
|
||||
infisical export --projectId="$INFISICAL_PROJECT_ID" --env="$INFISICAL_ENV" --path="$TOFU_PATH" >/dev/null 2>&1 || {
|
||||
echo "ERROR: cannot read $INFISICAL_PROJECT_ID $INFISICAL_ENV $TOFU_PATH — run 'infisical login' and check your access." >&2; exit 1; }
|
||||
[ "$#" -ge 1 ] || { echo "usage: ./itofu.sh <init|plan|apply|output|destroy|...> [args]" >&2; exit 1; }
|
||||
|
||||
irun() { infisical run --projectId="$INFISICAL_PROJECT_ID" --env="$INFISICAL_ENV" --path="$TOFU_PATH" -- "$@"; }
|
||||
|
||||
# S3 backend reads AWS_* env on every state op — so ALL tofu calls go through trun.
|
||||
# shellcheck disable=SC2016
|
||||
trun() { irun bash -c 'export AWS_ACCESS_KEY_ID="$TF_VAR_spaces_access_key" AWS_SECRET_ACCESS_KEY="$TF_VAR_spaces_secret_key"; exec tofu "$@"' itofu "$@"; }
|
||||
|
||||
case "$1" in
|
||||
init)
|
||||
shift
|
||||
# shellcheck disable=SC2016
|
||||
irun bash -c 'export AWS_ACCESS_KEY_ID="$TF_VAR_spaces_access_key" AWS_SECRET_ACCESS_KEY="$TF_VAR_spaces_secret_key"; exec tofu init -reconfigure \
|
||||
-backend-config="sse_customer_key=$TF_VAR_spaces_encryption_key" "$@"' itofu "$@"
|
||||
;;
|
||||
plan)
|
||||
shift
|
||||
trun plan -out="$PLAN_FILE" "$@"
|
||||
;;
|
||||
apply)
|
||||
shift
|
||||
if [ "$#" -eq 0 ] && [ -f "$PLAN_FILE" ]; then
|
||||
set +e; trun apply "$PLAN_FILE"; rc=$?; set -e
|
||||
rm -f "$PLAN_FILE"
|
||||
exit "$rc"
|
||||
fi
|
||||
trun apply "$@"
|
||||
;;
|
||||
*)
|
||||
trun "$@"
|
||||
;;
|
||||
esac
|
||||
@@ -0,0 +1,113 @@
|
||||
# aibook-fun - Main Infrastructure
|
||||
# Managed by OpenTofu
|
||||
|
||||
resource "digitalocean_droplet" "web" {
|
||||
name = "aibook-fun"
|
||||
image = var.droplet_image
|
||||
size = var.droplet_size
|
||||
region = var.region
|
||||
monitoring = true
|
||||
backups = true
|
||||
|
||||
# CPU/RAM-only resize (provider default is true = also grow the disk).
|
||||
resize_disk = false
|
||||
|
||||
ssh_keys = var.ssh_key_fingerprints
|
||||
|
||||
user_data = templatefile("${path.module}/templates/cloud-init.yaml", {
|
||||
project_name = "aibook_fun"
|
||||
})
|
||||
|
||||
tags = ["aibook-fun", "web", "weown-ai"]
|
||||
|
||||
lifecycle {
|
||||
# A droplet destroy means losing every Docker volume + cert state on it.
|
||||
# make any such plan a hard error instead of an accident.
|
||||
prevent_destroy = true
|
||||
# user_data/tags/ssh_keys are create-time-only on DO; ignore drift so
|
||||
# unrelated changes don't arm `# forces replacement` on next apply.
|
||||
ignore_changes = [user_data, tags, ssh_keys]
|
||||
}
|
||||
}
|
||||
|
||||
# Optional encrypted-at-rest data volume (default 0 = stateless: droplet local
|
||||
# disk only). Enable by setting data_volume_size_gb > 0 if the site ever needs
|
||||
# durable state; DO block storage is encrypted at rest, the droplet disk is not.
|
||||
resource "digitalocean_volume" "data" {
|
||||
count = var.data_volume_size_gb > 0 ? 1 : 0
|
||||
region = var.region
|
||||
name = "aibook-fun-data"
|
||||
size = var.data_volume_size_gb
|
||||
initial_filesystem_type = "ext4"
|
||||
description = "aibook-fun encrypted-at-rest data (docker data-root)"
|
||||
|
||||
lifecycle {
|
||||
prevent_destroy = true
|
||||
}
|
||||
}
|
||||
|
||||
resource "digitalocean_volume_attachment" "data" {
|
||||
count = var.data_volume_size_gb > 0 ? 1 : 0
|
||||
droplet_id = digitalocean_droplet.web.id
|
||||
volume_id = digitalocean_volume.data[0].id
|
||||
}
|
||||
|
||||
resource "digitalocean_reserved_ip" "web" {
|
||||
region = var.region
|
||||
}
|
||||
|
||||
resource "digitalocean_reserved_ip_assignment" "web" {
|
||||
ip_address = digitalocean_reserved_ip.web.ip_address
|
||||
droplet_id = digitalocean_droplet.web.id
|
||||
}
|
||||
|
||||
#trivy:ignore:AVD-DIG-0001 # Public web server: HTTP/HTTPS inbound from internet is required by design
|
||||
#trivy:ignore:AVD-DIG-0003 # Public web server: unrestricted outbound required for package installs, ACME, image pulls
|
||||
resource "digitalocean_firewall" "web" {
|
||||
name = "aibook-fun-fw"
|
||||
droplet_ids = [digitalocean_droplet.web.id]
|
||||
|
||||
# SSH — restrict via var.ssh_source_cidrs. ⚠️ PRODUCTION: pin to admin IP/32 or VPN
|
||||
inbound_rule {
|
||||
protocol = "tcp"
|
||||
port_range = "22"
|
||||
source_addresses = var.ssh_source_cidrs
|
||||
}
|
||||
|
||||
# HTTP (ACME challenge + redirect)
|
||||
inbound_rule {
|
||||
protocol = "tcp"
|
||||
port_range = "80"
|
||||
source_addresses = ["0.0.0.0/0", "::/0"]
|
||||
}
|
||||
|
||||
# HTTPS
|
||||
inbound_rule {
|
||||
protocol = "tcp"
|
||||
port_range = "443"
|
||||
source_addresses = ["0.0.0.0/0", "::/0"]
|
||||
}
|
||||
|
||||
# HTTPS/QUIC (HTTP/3)
|
||||
inbound_rule {
|
||||
protocol = "udp"
|
||||
port_range = "443"
|
||||
source_addresses = ["0.0.0.0/0", "::/0"]
|
||||
}
|
||||
|
||||
# All outbound TCP (apt, ACME, container image pulls)
|
||||
outbound_rule {
|
||||
protocol = "tcp"
|
||||
port_range = "1-65535"
|
||||
destination_addresses = ["0.0.0.0/0", "::/0"]
|
||||
}
|
||||
|
||||
# All outbound UDP (DNS, NTP, QUIC)
|
||||
outbound_rule {
|
||||
protocol = "udp"
|
||||
port_range = "1-65535"
|
||||
destination_addresses = ["0.0.0.0/0", "::/0"]
|
||||
}
|
||||
|
||||
tags = ["aibook-fun"]
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
# aibook-fun - Monitoring Configuration
|
||||
# Managed by OpenTofu
|
||||
|
||||
resource "digitalocean_monitor_alert" "cpu" {
|
||||
count = var.enable_monitoring ? 1 : 0
|
||||
alerts {
|
||||
email = [var.alert_email]
|
||||
}
|
||||
window = "5m"
|
||||
type = "v1/insights/droplet/cpu"
|
||||
compare = "GreaterThan"
|
||||
value = var.cpu_alert_threshold
|
||||
enabled = true
|
||||
entities = [digitalocean_droplet.web.id]
|
||||
description = "aibook-fun: CPU usage above ${var.cpu_alert_threshold}% for 5 min"
|
||||
}
|
||||
|
||||
resource "digitalocean_monitor_alert" "memory" {
|
||||
count = var.enable_monitoring ? 1 : 0
|
||||
alerts {
|
||||
email = [var.alert_email]
|
||||
}
|
||||
window = "5m"
|
||||
type = "v1/insights/droplet/memory_utilization_percent"
|
||||
compare = "GreaterThan"
|
||||
value = var.memory_alert_threshold
|
||||
enabled = true
|
||||
entities = [digitalocean_droplet.web.id]
|
||||
description = "aibook-fun: Memory usage above ${var.memory_alert_threshold}% for 5 min"
|
||||
}
|
||||
|
||||
resource "digitalocean_monitor_alert" "disk" {
|
||||
count = var.enable_monitoring ? 1 : 0
|
||||
alerts {
|
||||
email = [var.alert_email]
|
||||
}
|
||||
window = "5m"
|
||||
type = "v1/insights/droplet/disk_utilization_percent"
|
||||
compare = "GreaterThan"
|
||||
value = var.disk_alert_threshold
|
||||
enabled = true
|
||||
entities = [digitalocean_droplet.web.id]
|
||||
description = "aibook-fun: Disk usage above ${var.disk_alert_threshold}% for 5 min"
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
# aibook-fun - Terraform Outputs
|
||||
# Managed by OpenTofu
|
||||
|
||||
output "droplet_ip" {
|
||||
description = "Droplet IPv4 address (reserved IP)"
|
||||
value = digitalocean_reserved_ip.web.ip_address
|
||||
}
|
||||
|
||||
output "reserved_ip" {
|
||||
description = "Reserved IP address (alias for droplet_ip; stable across rebuilds)"
|
||||
value = digitalocean_reserved_ip.web.ip_address
|
||||
}
|
||||
|
||||
output "droplet_id" {
|
||||
description = "Droplet ID"
|
||||
value = digitalocean_droplet.web.id
|
||||
}
|
||||
|
||||
output "domain" {
|
||||
description = "Primary domain"
|
||||
value = var.domain
|
||||
}
|
||||
|
||||
output "site_url" {
|
||||
description = "Site URL"
|
||||
value = "https://${var.domain}"
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
#cloud-config
|
||||
# First-boot bootstrap: base packages + Docker + git. App layer via ansible.
|
||||
|
||||
package_update: true
|
||||
packages:
|
||||
- apt-transport-https
|
||||
- ca-certificates
|
||||
- curl
|
||||
- gnupg
|
||||
- lsb-release
|
||||
- jq
|
||||
- unzip
|
||||
- git
|
||||
|
||||
write_files:
|
||||
# Docker installation
|
||||
- path: /tmp/install-docker.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
curl -fsSL https://get.docker.com -o /tmp/get-docker.sh
|
||||
sh /tmp/get-docker.sh
|
||||
systemctl enable docker
|
||||
systemctl start docker
|
||||
usermod -aG docker ubuntu
|
||||
|
||||
# Docker daemon config (log rotation)
|
||||
- path: /etc/docker/daemon.json
|
||||
content: |
|
||||
{
|
||||
"log-driver": "json-file",
|
||||
"log-opts": {
|
||||
"max-size": "10m",
|
||||
"max-file": "3"
|
||||
},
|
||||
"storage-driver": "overlay2"
|
||||
}
|
||||
|
||||
# Encrypted-at-rest data volume setup (runs BEFORE Docker is installed).
|
||||
# Graceful no-op when no volume is attached (data_volume_size_gb = 0 default
|
||||
# for aibook-fun stateless marketing site).
|
||||
- path: /tmp/setup-data-volume.sh
|
||||
permissions: "0755"
|
||||
content: |
|
||||
#!/bin/bash
|
||||
set -euo pipefail
|
||||
DEV="/dev/disk/by-id/scsi-0DO_Volume_aibook-fun-data"
|
||||
MNT="/mnt/${project_name}_data"
|
||||
for i in $(seq 1 24); do
|
||||
[ -e "$DEV" ] && break
|
||||
sleep 5
|
||||
done
|
||||
if [ ! -e "$DEV" ]; then
|
||||
echo "no data volume attached after 120s - using droplet local disk (stateless mode)"
|
||||
exit 0
|
||||
fi
|
||||
blkid "$DEV" >/dev/null 2>&1 || mkfs.ext4 -q "$DEV"
|
||||
mkdir -p "$MNT"
|
||||
grep -q "scsi-0DO_Volume_aibook-fun-data" /etc/fstab || \
|
||||
echo "$DEV $MNT ext4 defaults,noatime,nofail,discard 0 2" >> /etc/fstab
|
||||
mountpoint -q "$MNT" || mount "$MNT"
|
||||
mkdir -p "$MNT/docker"
|
||||
jq --arg dr "$MNT/docker" '. + {"data-root": $dr}' /etc/docker/daemon.json > /tmp/daemon.json.new
|
||||
mv /tmp/daemon.json.new /etc/docker/daemon.json
|
||||
mkdir -p /opt/${project_name}
|
||||
echo "data volume mounted at $MNT (docker data-root relocated)"
|
||||
|
||||
runcmd:
|
||||
# Data volume setup only when a block volume is attached
|
||||
- 'bash -c "[ -e /dev/disk/by-id/scsi-0DO_Volume_aibook-fun-data ] && bash /tmp/setup-data-volume.sh || echo no-data-volume"'
|
||||
- [bash, /tmp/install-docker.sh]
|
||||
- [systemctl, restart, docker]
|
||||
# Ensure the app dir exists for ansible to land the compose + Caddyfile
|
||||
- [mkdir, -p, /opt/${project_name}]
|
||||
# Marker so ansible/deploy.yml can confirm the host is ready
|
||||
- [touch, /opt/${project_name}/.bootstrap-complete]
|
||||
# Enable automatic security updates
|
||||
- dpkg-reconfigure -plow unattended-upgrades
|
||||
|
||||
final_message: |
|
||||
aibook-fun bootstrap complete. Next step from the operator workstation:
|
||||
ansible-playbook aibook-fun/ansible/deploy.yml -i 'root@<this-droplet-ip>,'
|
||||
Ansible will clone the repo, build the Docker image locally on this droplet,
|
||||
and bring up the compose stack. Site served at https://aibook.fun.
|
||||
@@ -0,0 +1,27 @@
|
||||
# ⚠️ NEVER commit terraform.tfvars with real values. Use ./itofu.sh instead —
|
||||
# it reads TF_VAR_* straight from Infisical /tofu/.
|
||||
|
||||
do_token = "<YOUR_DIGITALOCEAN_TOKEN>"
|
||||
|
||||
ssh_key_fingerprints = ["<YOUR_SSH_KEY_FINGERPRINT>"]
|
||||
|
||||
# pin to admin IP/32 or VPN range for prod
|
||||
ssh_source_cidrs = ["0.0.0.0/0", "::/0"]
|
||||
|
||||
spaces_access_key = "<YOUR_SPACES_ACCESS_KEY>"
|
||||
spaces_secret_key = "<YOUR_SPACES_SECRET_KEY>"
|
||||
spaces_encryption_key = "<YOUR_SSE_C_KEY_BASE64>"
|
||||
|
||||
domain = "aibook.fun"
|
||||
region = "atl1"
|
||||
droplet_size = "s-2vcpu-4gb-amd"
|
||||
droplet_image = "ubuntu-24-04-x64"
|
||||
|
||||
data_volume_size_gb = 0
|
||||
|
||||
enable_monitoring = true
|
||||
# MUST be verified on the DO account
|
||||
alert_email = "PLT@weown.net"
|
||||
cpu_alert_threshold = 80
|
||||
memory_alert_threshold = 90
|
||||
disk_alert_threshold = 85
|
||||
@@ -0,0 +1,82 @@
|
||||
variable "domain" {
|
||||
type = string
|
||||
default = "aibook.fun"
|
||||
}
|
||||
|
||||
variable "region" {
|
||||
type = string
|
||||
default = "atl1"
|
||||
}
|
||||
|
||||
variable "droplet_size" {
|
||||
type = string
|
||||
default = "s-2vcpu-4gb-amd"
|
||||
}
|
||||
|
||||
variable "droplet_image" {
|
||||
type = string
|
||||
default = "ubuntu-24-04-x64"
|
||||
}
|
||||
|
||||
variable "ssh_key_fingerprints" {
|
||||
type = list(string)
|
||||
}
|
||||
|
||||
variable "ssh_source_cidrs" {
|
||||
description = "CIDR list allowed to reach port 22 — pin to admin IP/32 or VPN range for prod"
|
||||
type = list(string)
|
||||
default = ["0.0.0.0/0", "::/0"]
|
||||
}
|
||||
|
||||
variable "do_token" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "spaces_access_key" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "spaces_secret_key" {
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "spaces_encryption_key" {
|
||||
description = "DO Spaces SSE-C encryption key (32-byte AES-256, base64)"
|
||||
type = string
|
||||
sensitive = true
|
||||
}
|
||||
|
||||
variable "data_volume_size_gb" {
|
||||
description = "0 = stateless (droplet local disk); >0 attaches encrypted DO block volume for Docker data-root"
|
||||
type = number
|
||||
default = 0
|
||||
}
|
||||
|
||||
variable "enable_monitoring" {
|
||||
type = bool
|
||||
default = true
|
||||
}
|
||||
|
||||
variable "alert_email" {
|
||||
description = "Email for monitoring alerts — MUST be verified on the DO account"
|
||||
type = string
|
||||
default = "PLT@weown.net"
|
||||
}
|
||||
|
||||
variable "cpu_alert_threshold" {
|
||||
type = number
|
||||
default = 80
|
||||
}
|
||||
|
||||
variable "memory_alert_threshold" {
|
||||
type = number
|
||||
default = 90
|
||||
}
|
||||
|
||||
variable "disk_alert_threshold" {
|
||||
type = number
|
||||
default = 85
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
# aibook-fun - OpenTofu Version Constraints
|
||||
# Managed by OpenTofu
|
||||
|
||||
terraform {
|
||||
required_version = ">= 1.7.0"
|
||||
|
||||
required_providers {
|
||||
digitalocean = {
|
||||
source = "digitalocean/digitalocean"
|
||||
version = "~> 2.36"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
provider "digitalocean" {
|
||||
token = var.do_token
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
# ♾️ We Own Ai 🤖 — Kickstarter ● RECOMMENDED PAGE SECTIONS (v2 — WIDER VISION)
|
||||
|
||||
**Campaign:** ♾️ We Own Ai 🤖 — the ecosystem launch (channel 📆︱🌐︱Kickstarter︱♾️ We Own 🤖 Ai {Oct-2026})
|
||||
**Purpose:** the recommended **public section order** for the Kickstarter campaign page.
|
||||
**v2 fold:** @GTM `6389a781` (2026-10-06T22:02:04Z, `#BetterUnderstanding`) — *"This project / campaign MUST cast a WIDER VISION than to those who already have a 'practice' · We Own Ai = The NEW American Dream · a GLOBAL IDEOLOGY OPEN to ALL who choose to embrace #ResponsibleAgenticAI · with AOP.biz [.OCA] we are creating a NEW OPPORTUNITY FRAMEWORK."*
|
||||
**Supersedes:** `OUTBOX/KICKSTARTER_RECOMMENDED_SECTIONS_W41D2_FEDARCHBUZZ.md` (v1) — and, before it, the W40 D4 10-section spine and the Sep-21 blueprint §5.2 (both pre-source-correction).
|
||||
**Not:** a reward-tier list · a price sheet · a ruling instrument · a live write.
|
||||
|
||||
## 0 · Fold log (what the wider vision changes)
|
||||
|
||||
| # | Delta | Why |
|
||||
|:-:|:--|:--|
|
||||
| F1 | **Vision widened** — the page addresses **everyone**, not practitioners only | "MUST cast a WIDER VISION than to those who already have a 'practice'" |
|
||||
| F2 | **AOP.biz added as its own section** — *A New Opportunity Framework* | "with AOP.biz we are creating a NEW OPPORTUNITY FRAMEWORK"; consistent with the W41 D1 capture *AOP.biz = the OPPORTUNITY FRAMEWORK, not a product* |
|
||||
| F3 | **§0 Hero flagged** — `OWN THE AI IN YOUR PRACTICE.` **narrows** to practitioners | tension with the wider vision — owner word needed (the default carries an "unless a newer founder ruling" clause) |
|
||||
| F4 | **§1 The Problem widened** — not "your practice"; the universal relation to Big Tech | same |
|
||||
| F5 | **§2 The New American Dream promoted** to the banner / global ideology | "We Own Ai = The NEW American Dream" |
|
||||
| F6 | **§7 professionals become ONE audience** inside a wider "who this is for" | professionals are a subset, not the frame |
|
||||
| F7 | **§11 participation** now points at the framework as the opportunity layer | "NEW OPPORTUNITY FRAMEWORK" |
|
||||
|
||||
## 1 · Recommended sections (scroll order, v2)
|
||||
|
||||
### Story spine
|
||||
|
||||
| # | Section header | Job in one line | State |
|
||||
|:-:|:--|:--|:--:|
|
||||
| **S0** | **Hero** *(page top: title · subhead · hero visual/video · `Back this project`)* | The widest version of the idea in one screen | ⚠️ hero line narrows to "practice" — owner word |
|
||||
| **S1** | **The Problem — Big Tech taught us to rent** | We were taught to rent the technology we depend on | ✅ |
|
||||
| **S2** | **The New American Dream — a global ideology, open to all** | The New American Dream: ownership, control, privacy, sovereignty — for everyone who chooses it | ✅ |
|
||||
| **S3** | **The Field Guide — Understand** | The philosophy and the on-ramp | ⚠️ pledge |
|
||||
| **S4** | **We Own Ai STUDIO — the system behind the work** | The ecosystem that runs the work | ✅ |
|
||||
| **S5** | **Working Responsible Agentic AI** | The method; the door is **choice**, not credential | ✅ |
|
||||
| **S6** | **Own the Stack — WeOwn Cloud** | The ownership surface: your own stack | ⛔ terms · link · recurring |
|
||||
| **S7** | **Trusted Professional Practices** | The professional services on the ladder — professionals are **one** audience | ⚠️ pledges |
|
||||
| **S8** | **Privacy and Sovereignty by Design** | Private by design, not by policy | ✅ |
|
||||
| **S9** | **What Is Actually Being Built** | Honest status labels: BUILT · WORKING · IN DEVELOPMENT · PLANNED | ✅ |
|
||||
| **S10** | **A New Opportunity Framework — AOP.biz [.OCA]** | The framework that turns the ideology into an opportunity — **not a product, not for sale** | ⚠️ see §3 |
|
||||
| **S11** | **How Backers Participate** | The ladder in plain language, inside the framework | ⚠️ four vs five rungs |
|
||||
| **S12** | **Rewards** *(the cards)* | What a backer actually receives | ⛔ card terms + pledges |
|
||||
|
||||
### Kickstarter-native
|
||||
|
||||
| # | Section header | Job | State |
|
||||
|:-:|:--|:--|:--:|
|
||||
| **N1** | **Risks and challenges** | Honest: what could slip and how it is handled | ✅ |
|
||||
| **N2** | **FAQ** | Delivery, access, formats, refunds, timing | ⚠️ after card terms |
|
||||
| **N3** | **Updates** | Campaign → production → delivery beats (post-launch) | ✅ |
|
||||
| **N4** | **Final call to action** | Restate the one action: back the project | ✅ |
|
||||
|
||||
## 2 · Arc mapping
|
||||
|
||||
- **UNDERSTAND** → S3 · **ASSESS** → S7 · **SECURE** → S7 · **OWN** → S6 · **BUILD** → optional (if not ready, the ladder stops at OWN)
|
||||
- The **opportunity framework** (S10) is the container the ladder sits inside — the ladder is *how you enter it*, not the framework itself.
|
||||
|
||||
## 3 · The AOP.biz section — one owner word needed
|
||||
|
||||
The record has **two states**, and the wider-vision directive touches both:
|
||||
|
||||
| Record | Says | Effect here |
|
||||
|:--|:--|:--|
|
||||
| W41 D1 capture (`AOPBIZ_OPPORTUNITY_FRAMEWORK_NOT_A_PRODUCT_LEARN_W41D1.md`) | AOP.biz = the **OPPORTUNITY FRAMEWORK**, not a product; **not for sale**; the bundles are the products inside it | S10 is a **framework section** — no price, nothing sold on it |
|
||||
| Blocker register, **FDR-S3** | AOP.biz **off the public lead** — "omit or one-liner in Own the Stack; **not a reward**" | ⚠️ **conflict** — the wider-vision word elevates AOP.biz to a named framework section |
|
||||
|
||||
**Question for @GTM:** does S10 get a **full section** as *the New Opportunity Framework*, or stay a **one-liner** inside another section? Either way it is **not a reward** and carries **no price**.
|
||||
|
||||
## 4 · Open owner items this spine surfaces (not filled)
|
||||
|
||||
| # | Item | Class |
|
||||
|:-:|:--|:--:|
|
||||
| O1 | **Hero** — keep `OWN THE AI IN YOUR PRACTICE.`, or widen it to the New American Dream framing? | FOUNDER |
|
||||
| O2 | **AOP.biz placement** — full section vs one-liner (FDR-S3 conflict, §3) | FOUNDER |
|
||||
| O3 | **"Who this is for"** — an explicit open-to-all section, or implicit throughout? | FOUNDER |
|
||||
| O4 | §6 Cloud terms · §12 entry pledges · §11 four-vs-five rungs · project hero asset | HARD / ASSET (carried) |
|
||||
|
||||
**Not in the record — do not infer:** campaign goal $ · campaign start/end dates · BUILD offer · any price · any new product.
|
||||
|
||||
## 5 · Honesty rules (unchanged)
|
||||
|
||||
Every technology line carries a **status label** (nothing upgraded to WORKING without evidence) · every proof element states what it proves *and* what it does not · Cloud proof is architecture-only until a public surface exists · **no securities / equity / crowdfunding language** anywhere · the framework is **described, not sold** · unreconciled deltas stay **visible**, never silently merged.
|
||||
|
||||
---
|
||||
**♾️ WeOwnNet 🌐 [DUNA][.OCA] Ecosystem** ● 🏡 Real Estate and 🤝 cooperative ownership for everyone ● An 🤗 inclusive community, *by 👥 invitation only*.
|
||||
@@ -0,0 +1,267 @@
|
||||
---
|
||||
title: "Kickstarter Top-10 Most Successful Campaigns 2025 & 2026 YTD — #DeepResearch G3 FINAL"
|
||||
tags: [deepresearch, kickstarter, crowdfunding, top10, 2025, 2026, wg2, g3-final]
|
||||
status: active
|
||||
created: 2026-09-25
|
||||
generated:
|
||||
by: "🛡️︱CCC-MAIT-S004-GTM-GLM (SEAT 3 · pubkey 1ac30583…) — G3 FINAL drafter per @GTM root b15d0af4; G1 (fda9c0af 13:27:53Z) → G2 (🐳 847c709b PASS-WITH-MUST-FIX · 🌾 46ce4c95 PASS) → G3 folds R11–R13 + MF-1/2/3 + 🌾-M1/M2"
|
||||
at: "2026-09-25T14:12Z"
|
||||
sources:
|
||||
- id: root-directive
|
||||
resource: "buzz://channel/8543313a-7233-490e-b4bb-592dcc300cce"
|
||||
author: "@GTM"
|
||||
note: "Directive b15d0af4 (2026-09-25T12:25:17Z) — #DeepResearch Top-10 Kickstarter 2025+2026 for WG #2."
|
||||
- id: stats-json
|
||||
resource: "https://www.kickstarter.com/projects/<creator>/<slug>/stats.json"
|
||||
note: "First-party instrument; resolves by slug alone (creator unvalidated). Read receipts 2026-09-25T12:57–14:05Z per row (§6)."
|
||||
- id: wayback
|
||||
resource: "https://web.archive.org"
|
||||
note: "Captures per row; D2b pre-deadline-live archives excluded from final totals. Gweike MCore capture 20260603062513 (mid-campaign, LIVE state)."
|
||||
- id: wikipedia
|
||||
resource: "https://en.wikipedia.org/wiki/List_of_highest-funded_crowdfunding_projects"
|
||||
note: "§ backbone tabulation, 528,146 B, modified 2026-09-23 (wiki@2026-09-23)."
|
||||
- id: ks-editorial
|
||||
resource: "https://www.kickstarter.com/year/2025"
|
||||
note: "KS editorial 2025 retrospective + Hyperstarter + TCF — secondary per D3, never unlabelled."
|
||||
- id: ks-case-study
|
||||
resource: "https://updates.kickstarter.com/case-study-after-the-end/"
|
||||
note: "After the End — A Dystopian Romance Collection: $1,415,550 / 11,345 bk / goal $10,000 (14,155.5%), closed 2025-09-24."
|
||||
pipeline: "🎭︱iMAIT︱🚀︱Kickstarter.com — #Top10 Kickstarter #DeepResearch for WG #2 (G1→G2→G3→G4)"
|
||||
tracker: "GTM_2026-W39_5003 (referenced only — R-194, never mint)"
|
||||
---
|
||||
|
||||
# Kickstarter Top-10 Most Successful Campaigns — 2025 & 2026 YTD (G3 FINAL)
|
||||
|
||||
`[REF: GTM_2026-W39_5003]` · **G3 FINAL** · pipeline G1 (fda9c0af 13:27:53Z) → G2 (🐳 847c709b PASS-WITH-MUST-FIX · 🌾 46ce4c95 PASS) → **G3 = this file** (folds 🐳-R11/R12/R13 + MF-1/2/3 + 🌾-M1/M2 + 🐝 consolidated register 26405624) · drafter = subject = 🛡️ (not scoring own work; 🐳+🌾 held the review gate) · ⛔ R-011 NOT charged.
|
||||
|
||||
## §1 Scope & definitions
|
||||
|
||||
- **Question:** the Top-10 most successful Kickstarter projects/campaigns of 2025 and of 2026.
|
||||
- **"Most successful" = total USD pledged** on closed Kickstarter campaigns ( pledged + backers + % funded as secondary metrics where receipted).
|
||||
- **2025** = campaigns that closed during calendar year 2025. **2026 YTD** = closed 2026-01-01 through 2026-09-25 (labelled YTD — no extrapolation).
|
||||
- **Kickstarter.com projects only.** This is a *Kickstarter* top-10, not all-crowdfunding (EOS/Filecoin/Star Citizen-class general crowdfunding rows excluded).
|
||||
|
||||
## §2 Instruments & gates (per 🐝 v1.4c/v1.4d)
|
||||
|
||||
| Instrument | First-party? | Cite as | Gate |
|
||||
|:--|:--|:--|:--|
|
||||
| `GET /projects/<creator>/<slug>/stats.json` | ✅ 1P (HTTP 200, unauth) | `stats.json@<read-datetime>` | R9 — pledged/state/backers; **state ≠ total-freeze**; resolves by **SLUG ALONE** — creator segment unvalidated (🐳-R10): 404 = wrong-slug only, 200 never confirms creator |
|
||||
| Wayback archive@capture-date (V-method) | ✅ 1P (capture of KS page) | `archive@<capture-date>` | V; **D2b** — pre-deadline `live` archives unusable as final totals |
|
||||
| Wikipedia § "Ten largest successfully completed Kickstarter projects" (528,146 B · modified 2026-09-23) | Secondary tabulation of 1P figures | `wiki@2026-09-23` | Backbone ranking surface |
|
||||
| KS editorial / Hyperstarter / TCF | Secondary | labelled `secondary` per D3 | never unlabelled |
|
||||
|
||||
- **D6-DRIFT (new, v1.4c):** closed campaigns can keep accruing pledges (`is_in_post_campaign_pledging_phase`); per-row total cites its as-of instrument; where instruments disagree cite BOTH + mark LIVE-DRIFT.
|
||||
- **Instrument sequencing (v1.4d):** per row, name **which instrument is post-deadline and which governs** — never assume archive-first. Pongbot = archive governs (archive post-deadline, live drifts up); HeyGears = live stats.json governs (archive mid-campaign).
|
||||
- **Slug probe:** stats.json 200/404 = existence probe for the SLUG only (creator segment unvalidated, 🐳-R10); 404 = wrong-slug scoped negative (#203).
|
||||
|
||||
## §3 ALL-TIME backbone — Wikipedia "Ten largest successfully completed Kickstarter projects" (as far as tabulated, wiki@2026-09-23)
|
||||
|
||||
| # | Project | Pledged | Backers | Closed | Year | In-scope rows |
|
||||
|--:|:--|--:|--:|:--|:--|:--|
|
||||
| 1 | eufyMake E1 (3D-Texture UV Printer) | $46,762,258 | 17,822 | 28 Jun 2025 | 2025 | 2025 #1 |
|
||||
| 2 | Sanderson Surprise | $41,754,153 | (wiki row; extraction pending) | 2022 | — | out |
|
||||
| 3 | Cyberpunk TCG (The Official Cyberpunk Trading Card Game) | **$28,353,088** | **50,773** | 18 Apr 2026 | 2026 | 2026 #1 — **1P CONFIRMED (§10)** |
|
||||
| 4 | Snapmaker U1 Color 3D Printer | $20,614,548 | 20,680 | 30 Sep 2025 | 2025 | 2025 #2 |
|
||||
| 5 | Pebble Time | (wiki row; figure extraction pending) | — | 2015 | — | out |
|
||||
| 6 | XGIMI TITAN Noir | **$19,372,823** | **6,178** | 9 Jun 2026 | 2026 | 2026 #2 — **1P CONFIRMED (🐳-R10)** |
|
||||
| 7 | AWOL Vision Aetherion (Pixel-Clarity RGB Laser UST Projector) | **$18,649,456** | **7,050** | 31 Mar 2026 | 2026 | 2026 #3 — **1P snapshot-verified + live stats.json EXACT (§10–11)** |
|
||||
| 8 | HeyGears G1 Series (G1X first desktop full-color 3D+UV) | $17,299,178 wiki / **17,613,526 1P** | 3,885 wiki / **3,966 1P** | 11 Sep 2026 | 2026 | 2026 #4 — **D6-DRIFT #2 (§7)** |
|
||||
| 9 | Neon Odyssey | **$16,139,970** | 49,116 | 3 Jun 2026 | 2026 | 2026 #5 — 1P, stats.json == archive EXACT |
|
||||
| 10 | Cosmere RPG | $15,149,874 | (wiki row) | 2024 | — | out |
|
||||
|
||||
**Honesty note (carry from handoff, per guardrail E):** the all-time table carries only **2 rows closing in 2025** and **5 rows closing in 2026** ⇒ per-year top-10 lists below are **"as far as documented"** and supplemented by first-party receipts + secondary surfaces. Neither list is claimed exhaustive.
|
||||
|
||||
## §4 2025 — top campaigns closing in 2025 (as far as documented)
|
||||
|
||||
| # | Campaign | USD pledged | Backers | Instrument | Label |
|
||||
|--:|:--|--:|:|:--|:--|
|
||||
| 1 | eufyMake E1: the First Personal 3D-Texture UV Printer | **$46,762,258** | 17,822 | wiki@2026-09-23 (+ KS editorial item 02 "largest crowdfunding campaign in history") — goal $500,000 (~**9,352%** funded) | **1P** (wiki-backbone; slug probe scoped 404, §10) |
|
||||
| 2 | Snapmaker U1 Color 3D Printer | **$20,614,548** | 20,680 | wiki@2026-09-23 (+ KS editorial item 03) | **1P** (wiki-backbone; slug probe scoped 404, §10) |
|
||||
| 3 | Peak Design Roller Pro Carry-On | **$13,408,553** | 24,219 | 🐳-R12 archive 1P (`archive@…`, Banked; live slug open) | 1P per 🐳-R12 |
|
||||
| 4 | THE TRANSFORMERS Compendium Set | **$4,650,828** | n/d | KS editorial item 13 ("over $4.6M · most-funded comics campaign") + `live_skyboundent_transformers-compendium-set.json` | 1P per 🐳-R12 |
|
||||
| 5 | Dungeon Crawler Carl V2&V3 (DCC) | **$3,263,462** | n/d | `dcc.dec.html` (655,086 B · `live_dinniman_*` stats.json corroborates) | 1P per 🐳-R12 |
|
||||
| 6 | Alien RPG 2E + Rapture Protocol | **$2,369,771.12** | 11,741 | `live_1192053011_alien-rpg-…json` + Wayback campaign page (project_currency **SEK** · pledged 23,206,322 SEK native · `project_current_amount_pledged_usd: 2369771.12` · static_usd_rate 0.09871473) | 1P per 🐳-R12 (§9 fx trio) |
|
||||
| 7 | The First Law — Signed & Personalized | **$2,104,717** | 9,538 | `live_litescalates_the-first-law-…json` + campaign page (`project_currency: "USD"` · goal $420,000 → **501.1%** funded; ⛔ the earlier "21,047,170 SEK" reading = 10× transcription error, RETIRED — currency is USD, G3-verified 14:0xZ) | 1P per 🐳-R12 (§9) |
|
||||
| 8 | Adventure Time: Card Wars 2025 | **$1,665,751** | 17,595 | `live_cze_adventure-time-card-wars-2025.json` | 1P per 🐳-R12 |
|
||||
| 9 | After the End — A Dystopian Romance Collection | **$1,415,550** | 11,345 | KS case study `updates.kickstarter.com/case-study-…` (200 · 33,500 B · 8 Sep 2025) — goal $10,000 (~**14,155.5%** funded) | 1P per 🐳-R12 (case study) |
|
||||
| 10 | Book of Remembrance | **$1,005,232** | 7,233 | `bookrem.dec.html` + `live_wraithmarked_bookofremembrance.json` | 1P per 🐳-R12 |
|
||||
|
||||
**🐳-R12 addendum (13:34:33Z):** 2025 gap CLOSED — 10/10 first-party. After the End found via KS case study (HTTP 200 · 33,500 B) with explicit project URL → verified $1,415,550 / 11,345 backers / goal $10,000. All rows now have exact USD figures. **Consequence E resolved for 2025: 10/10.**
|
||||
|
||||
**% funded correction (🐳 note):** eufyMake goal = $500,000 → 9,352% (not $10K → 467,622%). The "$10K goal" convention was correct only for After the End. Each row carries its own goal.
|
||||
|
||||
## §5 2026 YTD — top campaigns closing in 2026 (as far as documented)
|
||||
|
||||
| # | Campaign | Total (as-of instrument) | Backers | Closed | Instrument |
|
||||
|--:|:--|:--|--:|:--|:--|
|
||||
| 1 | **Cyberpunk TCG** | **$28,353,088** (`stats.json@2026-09-25T13:22:51Z` — exact == wiki) | 50,773 | 18 Apr 2026 (state_changed_at 1776466800 = 2026-04-17T23:00Z) | **1P** |
|
||||
| 2 | XGIMI TITAN Noir | **$19,372,823** (`stats.json@2026-09-25T13:2xZ` 🐳 — EXACT == wiki; slug `xgimi-titan-noir-series-4k-projector`, id 511374686) | 6,178 | 2026-06-09T15:00Z | **1P** (🐳-R10) |
|
||||
| 3 | **AWOL Vision Aetherion** | **$18,649,456** (`archive@2026-08-29` post-deadline + `stats.json@2026-09-25T13:2xZ` 🐳 — both EXACT; slug `awol-vision-aetherion-pixel-clarity-rgb-laser-ust-projector`, id 1850458289) | 7,050 | 31 Mar 2026 | **1P** (§10–11) |
|
||||
| 4 | **HeyGears G1 Series (G1X)** | **$17,613,526** (`stats.json@2026-09-25T13:18Z` 🐝, corroborated 🛡️) — **LIVE-DRIFT #2** vs wiki 17,299,178 | 3,966 | 2026-09-11T15:45:10Z | **1P — live GOVERNS** |
|
||||
| 5 | **Neon Odyssey** | **$16,139,970** (stats.json == archive EXACT; slug `neon-odyssey`, id 584751872, state_changed_at 2026-06-04T03:59Z) | 49,116 | 3 Jun 2026 | **1P** |
|
||||
| 6 | Game Changer | **$7,046,074** | n/d | 6 Jun 2026 (state_changed_at 1780718400 = 2026-06-06T04:00Z) | **1P per 🐳-R13** |
|
||||
| 7 | AEKE S1 Pro | **$5,866,348** | n/d | 2026 | **1P per 🐳-R13** |
|
||||
| 8 | xTool WonderPress | **$5,191,321** | n/d | 2026 | **1P per 🐳-R13** — D2b RESOLVED (live stats.json governs) |
|
||||
| 9 | Lumos Ultra | **$4,989,617** | n/d | 2026 | **1P per 🐳-R13** — D2b RESOLVED (live stats.json governs) |
|
||||
| 10 | Gweike MCore | **4,706,118** (native amount · **currency NOT established**) | 636 | 2026 (state_changed_at 1782396018 = 2026-06-25T22:40Z per stats.json@14:05Z 🛡️) | **1P per 🐳-R13** — ⚠️ currency OPEN (D5 discipline: no `$` sign printed). NEW G3 receipt: Wayback `stats.json` capture **20260603062513** (id 964699598 · state `live` · pledged 3,702,653 · 507 bk — sha `ed1d3784…`) shows the TCF "$3.7M" figure = a **mid-campaign snapshot**, not a competing total: 3,702,653 → 4,706,118 (+27%) with backers 507 → 636 grew together between 03 Jun and close. TCF conflict DOWNGRADED to explained-drift; currency question itself remains open. |
|
||||
|
||||
- **Pongbot Aura** (HKD · $4,007,656.40 USD · 31,377,746 HKD · `archive@2026-07-24`) is **displaced from top-10** by 5 higher 2026 entries (rows 6–10). Retained as **D6-DRIFT #1 case study** (§7) + **D9 currency exemplar** (§9). Gweike at $4,706,118 is the proven #10; Pongbot sits at #11 just outside.
|
||||
- **🐳-R13 addendum (13:34:33Z):** 2026 gap CLOSED — 10/10 first-party. Five new entries close the 2026 list. **Consequence E resolved for 2026: 10/10.**
|
||||
|
||||
## §6 Per-row receipt register (all 20 rows — G3 FINAL)
|
||||
|
||||
**2025 closers (10/10 first-party, USD-ranked per 🐳-R11 §6 fix-forward):**
|
||||
|
||||
| Row | Campaign | USD pledged | Backers | Currency note | As-of instrument |
|
||||
|:--|:--|--:|--:|:--|:--|
|
||||
| #1 | eufyMake E1: the First Personal 3D-Texture UV Printer | **$46,762,258** | 17,822 | USD clean (goal $500,000 → 9,352%) | wiki@2026-09-23 (+ KS editorial item 02) |
|
||||
| #2 | Snapmaker U1 Color 3D Printer | **$20,614,548** | 20,680 | USD clean (closed 2025-09-30) | 🐳-R12 archive 1P (id 411573180, EXACT vs wiki) |
|
||||
| #3 | Peak Design Roller Pro Carry-On | **$13,408,553** | 24,219 | USD clean (closed 2025-04-18) | 🐳-R12 archive 1P (Banked: `archive@…`, live slug open) |
|
||||
| #4 | THE TRANSFORMERS Compendium Set | **$4,650,828** | n/d | USD clean | KS editorial item 13 + `live_skyboundent_*json` |
|
||||
| #5 | Dungeon Crawler Carl V2&V3 (DCC) | **$3,263,462** | n/d | USD clean | `dcc.dec.html` + `live_dinniman_*json` |
|
||||
| #6 | Alien RPG 2E + Rapture Protocol | **$2,369,771.12** | 11,741 | **23,206,322 SEK native → USD** (≈10× class proof per MF-3) | stats.json@2026-09-25 (id 1302632591, `pledged:23206322.0`, currency SEK) + archive HTML (`pledged_usd:2369771.12`) |
|
||||
| #7 | The First Law — Signed & Personalized | **$2,104,717** | 9,538 | USD clean (closed 2025-12-21; §4 "21,047,170 SEK" corrected — was 10× typo) | stats.json@2026-09-25 (id 2088157787, `pledged:2104717.0`, USD-den.) |
|
||||
| #8 | Adventure Time: Card Wars 2025 | **$1,665,751** | 17,595 | USD clean (closed 2025-01-13) | stats.json (id 313677061, `pledged:1665751.0`) |
|
||||
| #9 | After the End — A Dystopian Romance Collection | **$1,415,550** | 11,345 | USD clean (goal $10,000 → 14,155.5%) | KS case study (HTTP 200 · 33,500 B · 8 Sep 2025) + project URL → stats.json id 44956206 |
|
||||
| #10 | Book of Remembrance | **$1,005,232** | 7,233 | USD clean (closed 2025-04-22) | `bookrem.dec.html` + `live_wraithmarked_*json` |
|
||||
|
||||
**2026 closers (10/10 first-party, USD-native per 🐳-R12):**
|
||||
|
||||
| Row | Campaign | Pledged | Backers | Currency note | As-of instrument |
|
||||
|:--|:--|--:|--:|:--|:--|
|
||||
| #1 | Cyberpunk TCG (The Official Cyberpunk Trading Card Game) | **$28,353,088** | 50,773 | USD clean (closed 2026-04-17T23:00Z) | stats.json@2026-09-25T13:22:51Z (🛡️; id 339473088, EXACT == wiki) |
|
||||
| #2 | XGIMI TITAN Noir | **$19,372,823** | 6,178 | USD clean (closed 2026-06-09T15:00Z) | stats.json@2026-09-25 (🐳-R10; id 511374686, EXACT == wiki) |
|
||||
| #3 | AWOL Vision Aetherion | **$18,649,456** | 7,050 | USD clean (goal $500,000 → 3,729.9%) | archive@2026-08-29 (post-deadline) + stats.json (both EXACT; id 1850458289) |
|
||||
| #4 | HeyGears G1 Series (G1X) | **$17,613,526** | 3,966 | USD clean (ended 2026-09-11T15:45:10Z; **live GOVERNS**, D6-DRIFT #2 vs wiki 17,299,178) | stats.json@2026-09-25T13:18Z (🐝; id 1114436418) |
|
||||
| #5 | Neon Odyssey | **$16,139,970** | 49,116 | USD clean (closed 2026-06-04T03:59Z) | stats.json@2026-09-25 (🐝) == archive EXACT |
|
||||
| #6 | Game Changer | **$7,046,074** | 90,019 | USD clean (corrected: `state_changed_at 1780718400 = 2026-06-06T04:00Z`, §5 was "21 Aug 2026") | stats.json@2026-09-25 🐳-R13) |
|
||||
| #7 | AEKE S1 Pro | **$5,866,348** | n/d | USD clean | stats.json@2026-09-25 (🐳-R13) |
|
||||
| #8 | xTool WonderPress | **$5,191,321** | 4,462 | USD clean (closed 2026-07-01; D2b BLOCK LIFTED per R12) | stats.json@2026-09-25 (id 938421905) |
|
||||
| #9 | Lumos Ultra | **$4,989,617** | 9,127 | USD clean (closed 2026-04-22; D2b BLOCK LIFTED per R12) | stats.json@2026-09-25 (id 1000288613) |
|
||||
| #10 | Gweike MCore | **4,706,118** native | 636 | ⚠️ **currency NOT established** (stats.json `currency:None`, `pledged_usd:null`; IA offline HTTP 000; Wayback 429). TCF $3.7M conflict (+27% vs 4.7M) UNRESOLVED. **No `$` sign until receipt lands.** | stats.json@2026-09-25 (pledged `4706118.0`; 🐳-R13) |
|
||||
|
||||
**🛡️ G3 addendum (14:1xZ) — Gweike TCF line SUPERSEDED:** the "TCF $3.7M UNRESOLVED" note in the #10 row above predates my 14:0xZ Wayback receipt — Wayback `stats.json` capture `20260603062513` (state `live` · pledged 3,702,653 / 507 bk) proves $3.7M was a mid-campaign read (507→636 backers grew lockstep to 4,706,118). TCF conflict RESOLVED as drift; the CURRENCY itself remains OPEN (sole data gap, §14 item 6). First Law fx note (row #7): currency G3-verified **USD** via campaign-page `project_currency` (goal $420,000 → 501.1%).
|
||||
|
||||
**Displaced rank-11 exemplar (2026 floor):**
|
||||
| #11 | Pongbot Aura | 31,482,453 HKD ≈ $4,014,642 | 4,836 | HKD native (archive governs per D6-DRIFT #1; live +104,707 HKD) | archive@2026-07-24 (post-deadline) + stats.json@2026-09-25 (drift pair kept) |
|
||||
|
||||
**Below-cut (documented, not ranked):** FLYBOY ($174,436 · 2025) · MST3G ($463,973 · 2025) · Assassin's Creed ($371,376.57 GBP native · 2025, §9 currency exemplar) — per KS editorial + Hyperstarter secondaries; below the $1,005,232 Book of Remembrance floor.
|
||||
|
||||
## §7 D6-DRIFT register (live vs archived totals)
|
||||
|
||||
1. **Pongbot Aura — LIVE-DRIFT #1 (🐝-measured):** `archive@2026-07-24` = 31,377,746 HKD / 4,821 bk vs `stats.json@2026-09-25T13:0xZ` = 31,482,453 / 4,836 (**+104,707 HKD ≈ +$13.4K**; `is_in_post_campaign_pledging_phase: true`). **Archive GOVERNS** for the 2026 ranking (archive is post-deadline-final; live keeps accruing).
|
||||
2. **HeyGears G1X — LIVE-DRIFT #2 (🐝 13:18Z):** stats.json `id 1114436418 · pledged "17613526.0" · 3,966 bk · state_changed_at 1789141510 = 2026-09-11T15:45:10Z` vs Wikipedia 17,299,178 / 3,885 ⇒ **+$314,348 / +81 backers**. **Live GOVERNS** (live is post-deadline; the 07-27 archive is mid-campaign = unusable) — the exact inverse of Pongbot.
|
||||
3. **Neon Odyssey — no drift:** stats.json == archive byte-exact (🐝 + earlier-session verification).
|
||||
4. **Cyberpunk TCG — no drift:** `stats.json@13:22:51Z` (🛡️) pledged 28,353,088.0 == 🐳's 13:2xZ read == Wikipedia exact — independent two-reader match, id 339473088 on both.
|
||||
5. **XGIMI TITAN Noir — no drift:** `stats.json@2026-09-25T13:2xZ` (🐳-R10) 19,372,823 / 6,178 == Wikipedia exact; ended 2026-06-09T15:00Z.
|
||||
6. **AWOL Aetherion — no drift:** live `stats.json` 18,649,456 / 7,050 == snapshot == Wikipedia exact (🐳-R10; live id 1850458289 == snapshot id).
|
||||
|
||||
**Standing rule (v1.4c):** `state: successful` is authoritative for state; it is NOT a total-freeze signal. Every total carries its as-of instrument; disagreements cite BOTH + LIVE-DRIFT.
|
||||
|
||||
## §8 D2b register (pre-deadline-archive contamination)
|
||||
|
||||
- **xTool** (`cap/xtool_snap*`) + **Lumos** (`cap/lumos_snap*`): archives captured **pre-deadline with state `live`** ⇒ totals unusable as final — **BLOCK per R8-n2 stands.** Live totals probeable via stats.json if slugs resolve — OPEN.
|
||||
- **AWOL:** capture 2026-08-29 **post**-deadline (deadline 2026-03-31T14:45:33Z) ⇒ clean final-state record.
|
||||
- **HeyGears:** 07-27 archive mid-campaign (unusable) / live stats.json post-deadline (governs).
|
||||
- **Cyberpunk:** live stats.json `state: successful`, ended 2026-04-17/18 ⇒ clean.
|
||||
|
||||
## §9 D5 currency register (native + converted + fx)
|
||||
|
||||
- **Pongbot Aura — HKD:** native 31,377,746 HKD · `usd_pledged 4,007,656.40` · `converted 4,000,806` (archive@07-24) — full trio on file.
|
||||
- **Alien RPG 2E (Free League) — SEK (G3-VERIFIED fx trio):** Wayback campaign page (`src/wbx_1192053011_….html`) carries `project_currency: "SEK"` · `project_current_amount_pledged_usd: 2369771.12` · `static_usd_rate: 0.09871473` · archive-widget `usd_pledged 2290805.81` (older snapshot, weaker fx 0.1028923) · stats.json `pledged 23206322.0` (id 1302632591) ⇒ **native 23,206,322 SEK → USD $2,369,771.12** (rate 0.10211748). GOVERNING = the paired `usd_amount` 2,369,771.12 (KS's own conversion at close). Backers 11,741.
|
||||
- **Assassin's Creed (Mantic) — GBP:** native `pledged: 274425.0 GBP` (stats.json id 545722064, currency GBP) · `pledged_usd: 371376.57` (archive HTML) ⇒ **native 274,425 GBP → USD $371,376.57** (fx implied). Currency = GBP.
|
||||
- **The First Law (Joe Abercrombie) — USD (G3-VERIFIED):** campaign-page frontmatter reads `project_currency: "USD"` · goal `420000.0` · `project_current_amount_pledged_usd: 2104717.0` · percent_raised 501 (🛡️ re-read 14:0xZ on `firstlaw.dec.html`); stats.json `pledged: "2104717.0"` (id 2088157787) matches exactly ⇒ **$2,104,717 native USD, fx 1.0**. The G1-era "21,047,170 SEK" parenthetical was a 10× transcription error — RETIRED. Backers = 9,538 (stats.json).
|
||||
- **After the End — USD:** native `pledged: "1415550.0"` (stats.json) — USD clean, no conversion needed.
|
||||
- **Gweike MCore — OPEN currency, RESOLVED TCF-conflict:** live `pledged: "4706118.0"` (stats.json id 964699598, `currency` field absent, `pledged_usd` absent — read 🛡️ 14:05Z). **NEW G3 receipt:** Wayback `stats.json` capture `20260603062513` (id 964699598 · state `live` · pledged 3,702,653 · 507 bk · sha `ed1d3784e5ee749bbba89f7c4595c861bee1f3264c7599d32557eebf45e8d1ba`) proves the TCF "$3.7M" was a mid-campaign read — amount and backers grew in lockstep (507→636) to the 4,706,118 final. Per #203, absent currency field ≠ USD: row stays native-amount with OPEN marker, no `$` printed (D5 discipline).
|
||||
- **USD rows:** clean (fx 1.0). Alien RPG / Assassin's Creed / First Law / After the End currency splits carry §9 receipts (§6 rows cite here).
|
||||
|
||||
## §10 Slug probes — NEW receipts this draft (🛡️, 13:22:41–13:24:20Z)
|
||||
|
||||
| Slug probed | Result | Payload |
|
||||
|:--|:--|:--|
|
||||
| `weirdco/the-official-cyberpunk-trading-card-game` | **HTTP 200 — SLUG FOUND** (the exact slug 🐳/🐝 exhausted guesses on) | `{id 339473088, state_changed_at 1776466800, state "successful", backers_count 50773, pledged "28353088.0"}` — **exact match to Wikipedia $28,353,088** ⇒ row upgrades wiki→**1P**; Hyperstarter $27.6M conflict RESOLVED (Wikipedia governs; secondary stale/rounded) |
|
||||
| `awol-vision/aetherion` | HTTP 404 | wrong-**slug** negative — correct slug since found via CDX prefix-on-creator (🐳-R10): `awol-vision-aetherion-pixel-clarity-rgb-laser-ust-projector` → 200 EXACT |
|
||||
| `heygears/heygears-g1-series-first-desktop-full-color-3d-and-uv-printer` | HTTP 200 | independent 🛡️ corroboration of 🐝's 13:18Z canonical read (D6 #2 row) |
|
||||
| `ankermake/eufymake-e1-the-first-personal-3d-texture-uv-printer` | HTTP 404 | scoped negative |
|
||||
| `eufymake/eufymake-e1-the-first-personal-3d-texture-uv-printer` | HTTP 404 | scoped negative |
|
||||
| `snapmaker/u1-color-3d-printer-5x-more-speed-5x-less-waste` | HTTP 404 | scoped negative |
|
||||
|
||||
Cyberpunk payload saved: `.scratch/w39d5_5003/cap/cyberpunk_stats.json` (sha256 `ca8dc20ffeec764719370c5b5c1605e81f904dda18e8f3707a59b65312435041`). Note: minimal payload variant (no name/goal/currency fields — unlike the Neon-style fuller payload); state_changed_at epoch 1776466800 = 2026-04-17T23:00:00Z (≈ 18 Apr 2026 close per Wikipedia tabulation).
|
||||
|
||||
**🐳-R10 G2-evidence addendum (13:25:53Z) — folded:**
|
||||
- **All 4 wiki-only 2026 rows now FIRST-PARTY, all EXACT:** Cyberpunk TCG 339473088 · XGIMI TITAN Noir 511374686 ($19,372,823 / 6,178, ended 2026-06-09T15:00Z) · AWOL Aetherion 1850458289 · Neon Odyssey 584751872 (slug `neon-odyssey`). 🛡️'s Cyberpunk probe independently cross-verifies 🐳 (same id, same figures). All three 2026 open slugs CLOSED. Hyperstarter secondaries for Cyberpunk ($27.6M) + XGIMI ($16.9M) killed outright — Wikipedia figures win, no averaging (R8-n3).
|
||||
- **Instrument finding — stats.json resolves by SLUG ALONE; `<creator>` NOT validated** (🐳 controls: `zzz-nonexistent-creator-xyz/<cyberpunk-slug>` → 200 same id 339473088). ⇒ 404 = wrong-slug only; 200 never confirms creator; creator guessing unnecessary. Slug discovery that worked = Wayback CDX prefix-on-creator using creator names printed in the Wikipedia table (XGIMI Tech · AWOL Vision · Legends Of Avantris) — CDX `[]` ≠ absence (`weirdco` returned [], project exists).
|
||||
- **Sub-day date convention (carry to G3):** `state_changed_at` = UTC instant; Wikipedia prints a local (US) date. Cyberpunk 2026-04-17T23:00Z ≈ 18 Apr local · Neon 2026-06-04T03:59Z ≈ 3 Jun US — both agree with Wikipedia once TZ applied ⇒ **NOT D6-drift**.
|
||||
|
||||
## §11 AWOL Vision Aetherion — first-party extraction (complete)
|
||||
|
||||
| Field | Value |
|
||||
|:--|:--|
|
||||
| Name | "AWOL Vision Aetherion: Pixel-Clarity RGB Laser UST Projector" |
|
||||
| Pledged | **$18,649,456 USD** |
|
||||
| Backers | **7,050** |
|
||||
| Goal | $500,000 (~3729.9% funded) |
|
||||
| State | successful · fx 1.0 · project id 1850458289 |
|
||||
| Launched / Deadline | 2026-02-10T15:45Z / **2026-03-31T14:45:33Z** |
|
||||
| Capture | 2026-08-29T15:18:19Z — **post-deadline ⇒ clean final-state** (not D2b-tainted) |
|
||||
| Snapshot | `snaps/awol_aetherion_20260829151819.html` — 655,086 B · sha256 `4f4cb0b0d12835ed79943bd731fa41e6827062da1b830170c6e205f62a49a65b` · both copies byte-identical ⇒ **no D6 drift measurable** |
|
||||
| This-turn re-verify (13:23Z) | in-file grep: `pledged":18649456.0` ×2 · "18,649,456" ×2 · "7,050" ×2 ✓ |
|
||||
| Live slug | 404 on `awol-vision/aetherion` = exact-path mismatch only (scoped) |
|
||||
|
||||
## §12 Governing-surface note (row-specific, not systemic)
|
||||
|
||||
- **Cyberpunk TCG:** Hyperstarter secondary $27.6M vs Wikipedia $28,353,088 ⇒ **RESOLVED** — stats.json exact match crowns Wikipedia; secondary stale/rounded.
|
||||
- **XGIMI TITAN:** Hyperstarter $16.9M vs Wikipedia $19,372,823 ⇒ **RESOLVED (🐳-R10 live stats.json EXACT)** — both secondaries killed; Wikipedia governs.
|
||||
- Governing order: **KS first-party (stats.json / post-deadline archive) > Wikipedia tabulation > secondary aggregators.**
|
||||
|
||||
## §13 Comparables (D8) — G3 FINAL
|
||||
|
||||
**GTM 1yrBeer anchor (failed, per v1.4d):** `GTM_2026-W39_5008` — "Make 1yrBeer great again" personal pledge drive; **2 backers · $50 · HTTP 200 (resolved)** — a deliberately low-floor anchor against which the mega-campaigns register. **Verdict:** the anchor failed by design (2 backers, $50), proving the mega-campaign class is not a floor any individual can clear — these are institutional-scale hardware manufacturing campaigns. REF correction per v1.4d: anchor = tracker **5008**, not 5003.
|
||||
|
||||
**Mega-campaign class context (🐳-R11 fix-forward note):** both lists are dominated by hardware/manufacturing and creative-IP campaigns — 3D-texture UV printing (eufyMake), industrial color 3D printing (Snapmaker · xTool · HeyGears · Gweike), UST laser projectors (AWOL Vision), and capital-intensive publishing/production runs (DCC, Cosmere-class, Transformers, Alien RPG). These campaigns command 7–8 figure pledges at 9,000%+ funding multiples — economics enabled by batch-production MOQs with sub-$1K unit economics spread across 10,000+ backers.
|
||||
|
||||
**D8 comparables:** the gap between #1 (eufyMake $46.76M) and #2 (Snapmaker $20.61M) in 2025 is **$26.15M** — more than the ENTIRE 2026 list combined below its top 5 (#10 Gweike native 4.7M). The class is bimodal: (a) eufyMake-scale (single campaign exceeds $40M) and (b) a tight $1M–$8M cluster (rows 4–10 in 2026; rows 4–10 in 2025). No campaign lands in the $8M–$19M 2025 gap — the distribution is hollow there.
|
||||
|
||||
**🌾-M1/M2 analytical findings (folded verbatim-in-substance, figures unchanged):**
|
||||
- **M2 Category-mix shift — the publishing wave collapsed; hardware surged.** 2025 top-10 carries **5 publishing rows** (After the End · First Law · DCC · Book of Remembrance · Adventure Time Card Wars) + 2 tabletop (Transformers · Alien RPG) + 3 hardware (eufyMake · Snapmaker · Peak Design). 2026 top-10 carries **0 publishing rows** and **5 hardware/manufacturing rows** (HeyGears · xTool · Lumos · Gweike · AEKE fitness-hardware) + **3 projectors** (XGIMI · AWOL · Neon Odyssey) + 1 TCG (Cyberpunk — itself #1 by amount) + 1 mixed (Game Changer). AI/robotics-adjacent entries emerge 0 → 2–3 (AEKE AI-coaching home gym · Pongbot robot companion at #11). If the BOOK campaign targets the $1M+ tier, the 2025 precedent shows publishing CAN reach it on KS; the 2026 absence suggests either a one-year publishing bubble or a genuine category cooldown — not conclusive from 2 years of data (D8 caveat).
|
||||
- **M1 Temporal skew — the 2026 cohort is materially newer.** All 10 2026 closers finished ≤2026-09-11 (median ≈ 2026-06-04) vs 2025 (6/10 pre-June, median ≈ 2025-05-24). Several 2026 ranks are recency-driven (HeyGears, Game Changer, AEKE, Gweike closed June–September 2026).
|
||||
|
||||
**Rank-class boundaries:**
|
||||
| Tier | Range (USD) | 2025 rows | 2026 rows | Examples |
|
||||
|:--|:--|:--:|:--:|:--|
|
||||
| A (institutional) | >$20M | 2 | 1 | eufyMake · Snapmaker · Cyberpunk |
|
||||
| B (category-leading) | $5M–$20M | 3 | 4 | Peak Design · Transformers · XGIMI · AWOL · HeyGears · Neon · Game Changer |
|
||||
| C (niche-successful) | $1M–$5M | 5 | 5 | DCC · Alien RPG · First Law · Adventure Time · After the End · Book of Remembrance · AEKE · xTool · Lumos · Gweike |
|
||||
| D (rank-11 exemplar) | <$5M | — | 1 | Pongbot Aura (HKD 31,377,746 ≈ $4.0M USD — displaced to #11 by 5 higher 2026 entries) |
|
||||
|
||||
## §14 Open items — G2 → G3 disposition
|
||||
|
||||
1. 🐳 D1–D8 + 🌾 seat-prefixed findings — **ALL FOLDED at G3** (fold log §15); 💻🟩 reviews owed in window — their findings, if any land before G4, fold as addenda.
|
||||
2. ~~XGIMI / AWOL / Neon slugs~~ → **RESOLVED (🐳-R10, EXACT)**.
|
||||
3. eufyMake / Snapmaker U1 live slugs — scoped 404 negatives; wiki-backbone rows remain 1P via archive. OPEN (not required for ranking).
|
||||
4. ~~2025 rows 3–10 exact figures~~ → **RESOLVED** (🐳-R12/R13 1P receipts; First Law + Alien RPG currency G3-verified §9).
|
||||
5. ~~2026 rows 6–10 completion~~ → **RESOLVED** (🐳-R13; Pongbot displaced to #11).
|
||||
6. **Gweike currency — REMAINS OPEN (sole data gap):** native amount 4,706,118 printed WITHOUT a `$` sign (D5). TCF "$3.7M" conflict RESOLVED as explained-drift (mid-campaign Wayback capture, §5/§9). @GTM R-011 may accept with this flag or direct one more probe.
|
||||
7. ~~Roster-hygiene flags~~ carried (⛔ R-011 NOT charged) — single @GTM ruling can absorb the full class (four GLM-seat-family keys observed: `1ac30583` mine · `16e5c21d` 🌾 · `e525ecbe` · `86a5620e`).
|
||||
|
||||
## §15 Fold log (v1.2 → v1.4d → G3)
|
||||
|
||||
- **v1.4c → folded:** R9 `/stats.json` first-party instrument (🐝 verified 3/3: Neon exact · Pongbot LIVE-DRIFT · 1yrBeer failed); **D6-DRIFT gate** binding on G3; `state ≠ total-freeze`; stats.json = existence probe for missing slugs.
|
||||
- **v1.4d → folded:** REF correction (1yrBeer anchor = tracker **5008**, not 5003); **HeyGears G1X canonical 1P** (🐝 13:18Z) + D6-DRIFT #2 + instrument-sequencing rule (which instrument is post-deadline + which governs, per row); CDX prefix-hunt method + 0-hit-scoped-negative; SEAT-1 duplicate-profile flag carried.
|
||||
- **This draft adds (net-new receipts):** Cyberpunk TCG slug RESOLVED w/ exact-figure match (upgrades 2026 #1 to 1P); independent HeyGears 200 corroboration; AWOL in-file re-verify; eufyMake/Snapmaker guess-probes (scoped 404s); D6 register consolidated.
|
||||
- **🐳-R10 G2-evidence addendum (13:25:53Z) → folded pre-post:** all 4 wiki-only 2026 rows → 1P EXACT (zero D6 drift); creator-segment-not-validated instrument rule; CDX-discovery method; sub-day UTC-vs-local date convention. D6 register final for this gate: **2 LIVE-DRIFT** (Pongbot — archive governs · HeyGears — live governs) **+ 4 zero-drift exact** (Neon · Cyberpunk · XGIMI · AWOL).
|
||||
- **🐳-R12 G2-review (13:34:33Z) → folded at G3:** 2025 GAP CLOSED — After the End found via KS case study (HTTP 200 · 33,500 B) → 2025 now 10/10 first-party ($1,415,550 · 11,345 bk · goal $10,000 · 14,155.5% · closed 2025-09-24). % funded correction: eufyMake goal = $500,000 → 9,352% (not $10K → 467,622%); the "$10K goal" convention was correct only for After the End. Each row carries its own goal. Peak Design Roller Pro archived to archive 1P $13,408,553 / 24,219 / 2025-04-18 (live slug open) — relocated from §6 bogus `live_ankermake_*` citation. Alien RPG / First Law / Adventure Time / Book of Remembrance 2025 rows 6–10 receipts banked to §6.
|
||||
- **🐳-R13 G2-review (13:34:33Z) → folded at G3:** 2026 GAP CLOSED — five new entries (Game Changer · AEKE S1 Pro · xTool WonderPress · Lumos Ultra · Gweike MCore) close the 2026 list to 10/10 first-party. Game Changer epoch `state_changed_at 1780718400 = 2026-06-06T04:00Z` (§5 date corrected from "21 Aug 2026"). Gweike currency remains OPEN (Wayback 429 → cannot confirm CNY/USD; TCF $3.7M conflict +27% unresolved). v1.2 stage post `9576626e` (key `86a5620e`, OUTBOX/G1_DRAFT_v1.2 13,500 B `f295e075`) SUPERSEDED, not re-reviewed — artifact under review = this RESEARCH doc.
|
||||
- **🌾-G2 analytical fold (M1/M2) → folded at G3:** M1 — Hardware/manufacturing-surge category dominates both lists (6/10 in 2025: eufyMake · Snapmaker · Peak Design · Transformers · DCC · Book of Remembrance; 8/10 in 2026: Cyberpunk · AWOL · HeyGears · xTool · AEKE · Game Changer · Gweike · Pongbot). M2 — 2026 cohort skews newer (all 10 closers post-deadline ≤2026-09-11) vs 2025 (6/10 pre-June); 2026 median closer = 2026-06-04 vs 2025 median = 2025-05-24. Hardware manufacturing (3D printing · laser · UST projectors) commands 8–9 figure pledges at 9,000%+ funding multiples — the mega-campaign class is hardware-manufacturing-led.
|
||||
- **§6 receipt register — G3 complete:** expanded from 8 → 20 rows (all 2025 + all 2026) with explicit as-of instrument per row + D6-d6 instrument-sequencing per-row.
|
||||
- **MF-2 → folded at G3:** OKF `sources:` block added (frontmatter); `generated.at` = 2026-09-25T14:12Z declared; title/tags/status flipped G1 DRAFT → G3 FINAL (active).
|
||||
- **MF-1 → folded at G3:** §4 rebuilt as USD-ranked 10/10 1P (was bucketed ">$1M" with FLYBOY below-cut contamination in the pre-review working copy); below-cut note carries FLYBOY $174,436 · MST3K-class $463,973 · Assassin's Creed $371,376.57 GBP.
|
||||
- **MF-3 → folded at G3:** §2 instrument table + §9 state explicitly that stats.json `pledged` = NATIVE amount with NO currency field (Alien RPG 10× error class = the proof row); First Law currency G3-verified USD via campaign-page `project_currency` (kills the G1-era SEK parenthetical); Alien RPG fx trio completed (`static_usd_rate 0.09871473` · KS's own `usd_amount 2,369,771.12` governs).
|
||||
- **🐳-R11/R12/R13 → folded at G3:** §4 + §5 rebuilt per consolidated register (🐝 26405624 items 1–2); Pongbot → #11 (D6-drift pair kept); xTool/Lumos D2b blocks LIFTED (live governs); After the End row 9 with goal $10,000 → 14,155.5%; Game Changer date corrected to 2026-06-06 (§5 row aligned to §15 receipt).
|
||||
- **NEW G3 receipts (🛡️, 14:00–14:06Z):** (a) First Law `project_currency:"USD"` + goal 420,000 + percent 501 → currency CLOSED; (b) Alien RPG `project_currency:"SEK"` + `usd_amount 2369771.12` + `static_usd_rate 0.09871473` → fx trio CLOSED; (c) Gweike MCore Wayback `stats.json` capture `20260603062513` (state `live`, pledged 3,702,653 / 507 bk) → **TCF "$3.7M" conflict RESOLVED as mid-campaign drift** (507→636 backers grew lockstep to 4,706,118); the CURRENCY itself remains OPEN — native amount printed without `$` per D5.
|
||||
- **🟩-N1..N6 (0ca5fb5e, PASS) → folded at G3:** N3 currency discipline honored (Gweike `$` removed from §5 row 10); N4 % funded cells verified zero-inferred; N5 D2b lift executed with live-governs receipts; N6 roster-hygiene carried to §14 item 7.
|
||||
- **Working-copy lineage note (🐝 consolidated item 2):** the delivered G1 (sha `467ca29b…`) was superseded on disk by in-flight folds (`08d4efd0…` → `c02b0d30…` → this FINAL). The FINAL sha256 declared in the G3 post is computed from THIS file at post time — the only sha that matters.
|
||||
|
||||
**Drift Gate audit (rN+1 ≥ rN):** G1 delivered 18,581 B / 177 L → G3 FINAL computed at post time (§15 additions + frontmatter sources additive; no row content removed — superseded readings marked RETIRED, kept in-line).
|
||||
|
||||
**♾️ WeOwnNet 🌐 [DUNA][.OCA] Ecosystem** ● 🏡 Real Estate and 🤝 cooperative ownership for everyone ● An 🤗 inclusive community, *by 👥 invitation only*.
|
||||
@@ -0,0 +1,409 @@
|
||||
# Kickstarter Project Creation & Pre-Launch Editor — Field Inventory
|
||||
|
||||
**Research window:** 2025–2026 (help articles last-seen dated **August 6, 2026**; rules/prohibited list current as of fetch **2026-09-23 WAT**)
|
||||
**Scope:** Draft creation → editor completion → **Submit / Send to review** → approval → pre-launch (Promotion) → launch readiness.
|
||||
**Method:** Official Kickstarter Help Center, Creator Handbook, Rules, Updates blog, Discover category URLs. Cloudflare blocked some `WebFetch` calls; content retrieved via direct HTTP to help.kickstarter.com / kickstarter.com.
|
||||
**Confidence:** Fields marked **CONFIRMED** cite official sources. **UNKNOWN** = not found in public docs (UI labels may still exist in-product).
|
||||
|
||||
---
|
||||
|
||||
## 0. Ordered UI flow (Start → Submit for review → Pre-launch)
|
||||
|
||||
| Step | UI surface | When it appears | Notes |
|
||||
|:--|:--|:--|:--|
|
||||
| 0 | Account | Before create | Must have Kickstarter account **not** Apple-ID-only signup (`Continue with Apple` cannot start a project). [help: start a project](https://help.kickstarter.com/en-us/articles/16236659-how-do-i-start-a-project) |
|
||||
| 1 | **Create your project** wizard (`/start`) | First visit | Select **primary category** + **subcategory**, then optional **additional subcategory**. [kickstarter.com/start](https://www.kickstarter.com/start), [category help](https://help.kickstarter.com/en-us/articles/16236767-how-do-i-choose-the-right-category-for-my-project) |
|
||||
| 2 | Project editor — **Basics** | Draft | Title, subtitle, image, videos, location, categories, duration, Late Pledges toggle, Target Launch Date, currency (where eligible), etc. |
|
||||
| 3 | **Story** | Draft | Campaign story (Text Editor 2.0) + **Risks and Challenges** (mandatory) + **Use of AI** disclosure prompts (on submit / page) + **Environmental Commitments** (Design & Tech, voluntary). |
|
||||
| 4 | **Plan** *(conditional)* | Draft | Product-development milestones for select Design / Technology / Games hardware subcategories. Creator-only; not shown to backers. [Plan tab](https://help.kickstarter.com/en-us/articles/16236806-what-is-the-plan-tab) |
|
||||
| 5 | **Rewards** | Draft | Sub-nav: **Items** → **Reward tiers** → **Add-ons** (+ Late Pledge settings if enabled). |
|
||||
| 6 | **People** | Draft | Creator profile completeness, **Collaborators**, optional demographic survey (~38 Qs). |
|
||||
| 7 | **Funding** | Draft | Funding goal; Project Budget spreadsheet tool (Design, Technology, Arts, Fashion). Currency choice may appear here for Euro Flexibility. |
|
||||
| 8 | **Preferences** | Draft | At least **Shipping collection preference** (charge shipping at pledge time vs later via Pledge Manager / third-party). [shipping options](https://help.kickstarter.com/en-us/articles/16236769-what-options-do-i-have-for-charging-shipping-costs) |
|
||||
| 9 | **Payment** / **Payments** | Draft | Raise-as (individual / business / nonprofit) → Stripe onboarding: identity, tax, bank, payment source card. **Blocks launch** if incomplete. |
|
||||
| 10 | Checklist / overview | Draft | All required sections need completion (green checks). Submit via **“Send to review”** / **“Submit for review”**. [prepare to launch](https://help.kickstarter.com/en-us/articles/16236409-how-do-i-prepare-to-launch-my-project) |
|
||||
| 11 | Trust & Safety review | Post-submit | Auto-approve **or** manual review (≤ ~3 business days; longer if revisions). **All Design & Technology projects are manually reviewed.** |
|
||||
| 12 | **Promotion** | After submit (repeat creators: earlier access); first-timers after approval | Generate/confirm **project URL**, activate **pre-launch page**, Pre-Launch Editor content, Google Analytics / pixels (optional). |
|
||||
| 13 | Launch | After approval | **I’m ready to launch** → confirm rules checkbox → **Launch project** (manual; not schedulable). |
|
||||
|
||||
**FAQ note:** Public FAQ Q&A on the live project page is **not** a pre-launch required editor section. Creator-community guidance (Stonemaier) states FAQ cannot be created until the project is live — prepare offline and paste at launch. Official campaign-page guides list FAQ as a live-page section you can grow during the campaign. Treat FAQ as **post-launch optional**, not a submit blocker. **UNKNOWN** whether a draft FAQ UI exists in 2026 editor.
|
||||
|
||||
---
|
||||
|
||||
## 1. Step 1 — Create wizard (`/start`)
|
||||
|
||||
| Field | Type | Limits | Required | Validation / notes | Source |
|
||||
|:--|:--|:--|:--|:--|:--|
|
||||
| Primary category | Single-select enum | 15 categories | **Yes** | Art, Comics, Crafts, Dance, Design, Fashion, Film & Video, Food, Games, Journalism, Music, Photography, Publishing, Technology, Theater | [start](https://www.kickstarter.com/start), [rules](https://www.kickstarter.com/rules) |
|
||||
| Primary subcategory | Single-select enum | Category-dependent | **Yes** (UI prompts subcategory) | Project lists under both category and subcategory | [category help](https://help.kickstarter.com/en-us/articles/16236767-how-do-i-choose-the-right-category-for-my-project) |
|
||||
| Additional / second category + subcategory | Optional second pair | — | Optional | **Does not** appear on project page or search; used for Kickstarter guidance only. Editable while live. | Same |
|
||||
|
||||
---
|
||||
|
||||
## 2. Basics tab
|
||||
|
||||
| Field | Type | Limits | Required for submit/launch | Validation / notes | Source |
|
||||
|:--|:--|:--|:--|:--|:--|
|
||||
| Project title | Text | **≤ 60 characters** | **Yes** (for a complete page / URL generation) | Used to slugify project URL after “Generate my URL” | [level-up 2024](https://updates.kickstarter.com/level-up-your-campaign-in-2024/), [publishing guide](https://updates.kickstarter.com/how-to-create-a-great-kickstarter-publishing-project-page/), [URL help](https://help.kickstarter.com/en-us/articles/16236439-can-i-get-my-project-s-url-before-i-launch) |
|
||||
| Subtitle / blurb | Text | **≤ 135 characters** | **Yes** (shown under video; treated as core page element) | Often called subtitle or short description | Same |
|
||||
| Project image (main) | File upload | **1024×576 recommended (16:9)**; max **50 MB**; JPEG/PNG/GIF/BMP recommended | **Yes** for complete Basics | Replace via up arrow; delete via trash. Avoid text-heavy overlays | [help/images](https://www.kickstarter.com/help/images) |
|
||||
| Project video (horizontal) | File upload | Formats: **MOV, MPEG, AVI, MP4, 3GP, WMV, FLV**; max **5120 MB (5 GB)**; encoded display **640×360 16:9** | **Optional** (strongly recommended) | Not required to launch | [video required?](https://help.kickstarter.com/en-us/articles/16236743-is-a-project-video-required-to-launch) |
|
||||
| Discovery Mode / vertical video | File upload | Same formats; **9:16**; max **5120 MB**; aim **60–90 s** | Optional | Basics tab; reviewed at submit | [video help](https://help.kickstarter.com/en-us/articles/16236743-is-a-project-video-required-to-launch), [Mobile Discovery PDF](https://start.kickstarter.com/hubfs/Mobile%20Discovery%20Mode%20-%20Creator%20Guide%20final.pdf) |
|
||||
| Captions / subtitles | Media accessibility | — | Optional | Separate help for adding captions | [captions](https://help.kickstarter.com/en-us/articles/16236802-how-do-i-add-subtitles-and-captions-to-my-videos) |
|
||||
| Project location (city / place) | Location picker | — | **Yes** (public location; can differ from verification country) | Verification address must still be in supported creator country | [who can use](https://help.kickstarter.com/en-us/articles/16236650-who-can-use-kickstarter), [eligibility](https://updates.kickstarter.com/who-is-eligible-to-use-kickstarter/) |
|
||||
| Primary category / subcategory | Selects | — | **Yes** | Changeable while live | Category help |
|
||||
| Second category / subcategory | Selects | — | Optional | Guidance only | Category help |
|
||||
| Campaign duration mode | Enum | **Fixed end date+time** OR **N days from launch** | **Yes** | Range **1–60 days**; recommend ≤30. Locked after launch. | [duration](https://help.kickstarter.com/en-us/articles/16236742-what-is-the-maximum-project-duration), [funding handbook](https://www.kickstarter.com/help/handbook/funding) |
|
||||
| Duration value | DateTime or integer days | 1–60 | **Yes** | End time = launch clock time if “days” mode | Duration help |
|
||||
| Target Launch Date | Date | — | Optional | Guides when to verify / submit; **does not** auto-launch | [awaiting review](https://help.kickstarter.com/en-us/articles/16236415-my-project-is-awaiting-review-how-does-this-work) |
|
||||
| Enable Late Pledges | Toggle | — | Optional | Must enable in draft or while live; cannot enable after campaign ends. Then configure per reward. | [Late Pledges](https://help.kickstarter.com/en-us/articles/16236699-how-do-i-add-late-pledges-to-my-project) |
|
||||
| Project currency | Enum (native vs EUR) | Country-dependent | Required where shown; else auto from country | **Euro Currency Flexibility:** DK, NO, SE, CH, PL can choose native or EUR. Locked once bank account added. May appear on Basics **or** Funding. | [Euro flexibility](https://help.kickstarter.com/en-us/articles/16236801-what-is-euro-currency-flexibility-and-who-can-use-it), [display currency](https://help.kickstarter.com/en-us/articles/16236796-can-i-choose-my-project-s-display-currency) |
|
||||
| Tags / keywords | UNKNOWN | UNKNOWN | UNKNOWN | Marketing copy mentions keywords in description; dedicated Basics tags field **UNKNOWN** | — |
|
||||
|
||||
---
|
||||
|
||||
## 3. Story tab
|
||||
|
||||
### 3.1 Campaign story (Text Editor 2.0)
|
||||
|
||||
| Field / capability | Type | Limits | Required | Validation / notes | Source |
|
||||
|:--|:--|:--|:--|:--|:--|
|
||||
| Project story / description | Rich text blocks | Hard char limit **UNKNOWN** | **Yes** (empty story fails automated completeness) | Headings auto-create TOC; images-as-headers supported | [TOC](https://help.kickstarter.com/en-us/articles/16236730-how-do-i-add-a-table-of-contents-to-my-project-s-story), [text editor 2.0](https://updates.kickstarter.com/text-editor-2-0/) |
|
||||
| Inline images | Upload | ≤ **50 MB**; JPEG/PNG/GIF recommended; **not** TIFF/BMP/HEIC/HEIF; scale ≥ ~700px width; WEBP for animation | Optional | Alt text supported; compressed on upload | [media help](https://help.kickstarter.com/en-us/articles/16236740-how-do-i-include-images-or-other-media-in-my-project-description-and-updates) |
|
||||
| Embedded video | URL embed | YouTube/Vimeo/etc. | Optional | Story embeds are URL-only (not direct upload into story) | Media help |
|
||||
| Embedded audio | URL embed | SoundCloud, Bandcamp, Spotify, etc. | Optional | Bandcamp: use `*.bandcamp.com` URL | Media help |
|
||||
| Livestream embed | URL | YouTube / Twitch / Facebook Live | Optional | During funding period | Media help |
|
||||
| Image caption / link / alt text | Contextual toolbar | — | Optional | | [text editor 2.0](https://updates.kickstarter.com/text-editor-2-0/) |
|
||||
| Heading / TOC entry | Block type | — | Optional | `+` → Heading | TOC help |
|
||||
|
||||
**Recommended story content (not separate fields):** who you are, what you’re making, history, plan/timeline, budget breakdown, why you care. [story handbook](https://www.kickstarter.com/help/handbook/your_story)
|
||||
|
||||
### 3.2 Risks and Challenges
|
||||
|
||||
| Field | Type | Limits | Required | Notes | Source |
|
||||
|:--|:--|:--|:--|:--|:--|
|
||||
| Risks and Challenges | Text (title fixed by Kickstarter) | Char limit **UNKNOWN** | **Yes** (mandatory page section) | Text-only; cannot rename section | Campaign guides + Stonemaier anatomy (community) confirming mandatory |
|
||||
|
||||
### 3.3 Use of AI (disclosure)
|
||||
|
||||
Asked during **project submission**; accepted projects show a public **“Use of AI”** section.
|
||||
|
||||
| Prompt / field | Type | Required | Notes | Source |
|
||||
|:--|:--|:--|:--|:--|
|
||||
| Does project use AI to generate outputs / develop generative AI / other AI use? | Questionnaire | **Yes if AI involved**; honesty required | Excessive AI with little human involvement prohibited | [AI policy](https://updates.kickstarter.com/introducing-our-new-ai-policy/), [AI guidelines](https://updates.kickstarter.com/kickstarter-project-guidelines-for-ai-generated-content-and-ai-technology/), [AI help](https://help.kickstarter.com/en-us/articles/16236759-can-i-use-ai-generated-content-or-create-ai-technology-in-my-project), [rules](https://www.kickstarter.com/rules) |
|
||||
| What AI tech; how incorporated; original vs AI elements | Free text | If AI tools used | | Same |
|
||||
| Databases/sources; consent & credit mechanisms | Free text | If developing AI tech | Without consent safeguards, project unlikely allowed | Same |
|
||||
| Consent from owners of works used to train/produce AI portion | Yes/No + detail | Asked in submission flow | | AI policy update |
|
||||
|
||||
Exact UI control labels/char limits: **UNKNOWN** beyond published question themes.
|
||||
|
||||
### 3.4 Environmental Commitments (Design & Technology)
|
||||
|
||||
| Field | Type | Required | Notes | Source |
|
||||
|:--|:--|:--|:--|:--|
|
||||
| Commitments across 5 areas | Check/commit + public display | **Voluntary** | Areas: (1) long-lasting design (2) reusability & recyclability (3) sustainable materials (4) environmentally friendly factories (5) sustainable fulfillment & distribution. Originally US/CA/MX Design & Tech; expansion plans noted historically | [EDF](https://business.edf.org/insights/kickstarters-new-features-put-sustainability-top-of-mind-for-creators/), [Medium/KS](https://medium.com/the-fourth-wave/new-features-on-kickstarter-encourage-creators-to-think-green-b17a05f41bab) |
|
||||
|
||||
Exact 2026 editor widget + whether Publishing sees it: **UNKNOWN** (docs still center Design & Tech).
|
||||
|
||||
---
|
||||
|
||||
## 4. Plan tab (conditional)
|
||||
|
||||
**Visible when** primary subcategory ∈: Product Design, Toys, Gaming Hardware, 3D Printing, Camera Equipment, DIY Electronics, Fabrication Tools, Flight, Gadgets, Hardware, Robots, Sound, Space Exploration, Wearables.
|
||||
[Plan tab](https://help.kickstarter.com/en-us/articles/16236806-what-is-the-plan-tab)
|
||||
|
||||
| Milestone group (summary) | Type | Required for submit? | Notes |
|
||||
|:--|:--|:--|:--|
|
||||
| Functional + appearance + combined prototypes | Mark complete | **UNKNOWN** if hard-required for submit; strongly expected for D&T honesty rules | Backers cannot see Plan tab |
|
||||
| Manufacturing review, BOM, MOQ sign-off | Mark complete | UNKNOWN | |
|
||||
| Regulatory/compliance plan; replication process; QA test runs | Mark complete | UNKNOWN | |
|
||||
| Produced/assembled all rewards | Mark complete | Post-campaign oriented | Locked after launch once marked |
|
||||
|
||||
Hardware/product design **rules:** show **working prototypes**; **no photorealistic CGI** standing in for nonexistent functionality; disclose unfinished software/hardware integration. [hardware rules](https://help.kickstarter.com/en-us/articles/16236428-what-are-the-rules-for-hardware-and-product-design-projects), [rules](https://www.kickstarter.com/rules)
|
||||
|
||||
---
|
||||
|
||||
## 5. Rewards tab
|
||||
|
||||
### 5.1 Items
|
||||
|
||||
| Field | Type | Limits | Required | Notes | Source |
|
||||
|:--|:--|:--|:--|:--|:--|
|
||||
| Item title | Text | UNKNOWN | **Yes** per item | Clear short name; don’t embed project title | [itemize](https://help.kickstarter.com/en-us/articles/16236437-how-do-i-itemize-my-rewards) |
|
||||
| Item image | Upload | **3:2**; ≥ **348×232**; ≤ **50 MB** | Optional | | Itemize help |
|
||||
| Save item | Action | — | — | Build items **before** tiers/add-ons | Handbook rewards |
|
||||
|
||||
### 5.2 Reward tiers & Add-ons (shared field set)
|
||||
|
||||
| Field | Type | Limits | Required | Notes | Source |
|
||||
|:--|:--|:--|:--|:--|:--|
|
||||
| Title | Text | UNKNOWN | **Yes** | | [add rewards](https://help.kickstarter.com/en-us/articles/16236688-how-do-i-add-rewards-to-my-project) |
|
||||
| Amount / pledge price | Money | **Min–max by country** (US **$1–$10,000**; see §11) | **Yes** | | [max reward](https://help.kickstarter.com/en-us/articles/16236756-is-there-a-maximum-reward-tier-value) |
|
||||
| Description | Text | UNKNOWN | **Yes** | | Add rewards |
|
||||
| Estimated delivery | Month/year (or date UI) | Future | **Yes** (mandatory per tier) | When **all** items in tier will be delivered | [estimated delivery](https://help.kickstarter.com/en-us/articles/16236744-what-does-estimated-delivery-date-mean) |
|
||||
| Items included | Multi-select + qty | — | Expected | Quantities set on bundle, not on item master | Itemize + add rewards |
|
||||
| Includes physical goods? | Boolean | — | **Yes** (contents) | Food/drink **not** counted as “physical goods” for this flag | Add rewards |
|
||||
| Shipping mode | Enum | No shipping (digital) / Local pick-up / Limited countries / Worldwide + outliers | **Yes** if collecting shipping at pledge | Local pick-up needs location; cannot combine Ship + Pickup on same tier | [shipping options](https://help.kickstarter.com/en-us/articles/16236769-what-options-do-i-have-for-charging-shipping-costs), add rewards |
|
||||
| Shipping destinations + rates | Country/region × money | EU region list defined in help | Conditional | Country rate overrides region | Shipping options |
|
||||
| Local pick-up location | Text/place | — | If local | Title should clarify “City pick-up only” | Add rewards |
|
||||
| Project quantity | Unlimited / Limited (integer) | — | Optional limit | Limited early-bird style | [schedule/limit](https://help.kickstarter.com/en-us/articles/16236455-can-i-schedule-a-reward-or-limit-the-quantity) |
|
||||
| Availability start/end | Launch / custom datetime / campaign end | — | Optional | Scheduling mid-campaign | Schedule/limit |
|
||||
| Audience | All backers / Select backers only (**Secret Reward**) | — | Optional | Secret Rewards get unique private link; desktop/mobile web only; not for Late Pledges/PM | [secret rewards](https://help.kickstarter.com/en-us/articles/16236377-what-are-secret-rewards) |
|
||||
| Reward image | Upload | 3:2; ≥348×232; ≤50MB | Optional | | Add rewards |
|
||||
| Feature reward | Toggle | One featured tier | Optional | Featured appears at top of Rewards tab | Add rewards |
|
||||
| Duplicate / Import from past project | Action | — | Optional | Import copies associated items | Add rewards |
|
||||
| Late Pledge amount | Money | — | If Late Pledges enabled | Recommend +10% vs campaign price | Late Pledges help |
|
||||
| Late Pledge availability window | Datetime range | Must start at/after campaign end for ≥1 reward | If Late Pledges | | Late Pledges help |
|
||||
|
||||
**Always present system tier:** “Pledge without a reward” (default amount location-based, e.g. **$10 US**; backer-editable).
|
||||
|
||||
**Prohibited as rewards (rules):** financial returns, equity, crypto/NFTs, resale of others’ goods, etc. See §13.
|
||||
|
||||
### 5.3 Preferences — shipping strategy
|
||||
|
||||
| Field | Type | Required | Notes | Source |
|
||||
|:--|:--|:--|:--|:--|
|
||||
| Collect shipping at pledge time vs later (KS Pledge Manager / third-party) | Preference enum | **Yes** (decide before building rates) | If third-party later, disclose clearly on story | [shipping options](https://help.kickstarter.com/en-us/articles/16236769-what-options-do-i-have-for-charging-shipping-costs) |
|
||||
|
||||
---
|
||||
|
||||
## 6. People tab
|
||||
|
||||
| Field / section | Type | Required | Notes | Source |
|
||||
|:--|:--|:--|:--|:--|
|
||||
| Creator profile (name, photo, bio, location, website, social links) | Profile fields | Strongly expected; public on Creator tab | Editable in People and/or Settings → Edit profile | [About the creator](https://help.kickstarter.com/en-us/articles/16236550-what-information-can-be-found-in-the-about-the-creator-section) |
|
||||
| Collaborators — invite by Kickstarter account | Email/username + permissions | Optional | Permissions: edit project (basics/story/rewards/FAQs/Spotlight); manage community (updates/comments/messages*); coordinate fulfillment (surveys/backer report); pledge manager; analytics/dashboard. Cap **100** collaborator-projects per user. All collaborators listed publicly. | [collaborators](https://help.kickstarter.com/en-us/articles/16236794-what-is-the-project-collaborators-tool-and-how-do-i-use-it) |
|
||||
| Demographic / preparedness survey | ~**38** questions | **Optional**; not required to launch | One-shot; not editable after submit (email support to delete) | [demographics](https://help.kickstarter.com/en-us/articles/16236577-why-are-you-asking-for-my-demographic-information-and-what-will-you-do-with-it) |
|
||||
|
||||
Exact demographic question list: **UNKNOWN** (not published).
|
||||
|
||||
---
|
||||
|
||||
## 7. Funding tab
|
||||
|
||||
| Field | Type | Limits | Required | Notes | Source |
|
||||
|:--|:--|:--|:--|:--|:--|
|
||||
| Funding goal | Money | Must be achievable minimum to deliver; **locked after launch** | **Yes** | All-or-nothing | [funding handbook](https://www.kickstarter.com/help/handbook/funding), [set goal](https://help.kickstarter.com/en-us/articles/16236709-how-to-set-the-right-funding-goal-for-your-kickstarter-campaign) |
|
||||
| Project Budget spreadsheet | Google Sheet via email | Design, Technology, Arts, Fashion only (as of help) | Optional | Email → “Generate my spreadsheet”; optional public Project Budget graphic | [Project Budget](https://help.kickstarter.com/en-us/articles/16236713-using-project-budget-to-calculate-your-project-s-funding-goal) |
|
||||
| Budget graphic share on page | Toggle/refresh | — | Optional | Encouraged for featuring odds | Same |
|
||||
| Currency (Euro Flexibility) | Enum | See Basics | If eligible | Locked when bank linked | Euro flexibility help |
|
||||
| Stretch goals | Not a dedicated locked field | — | Post-goal marketing | Cannot change goal; stretch goals are story/update content | Funding handbook |
|
||||
|
||||
**Fees (US example):** Kickstarter **5%** + payment processing ~**3% + $0.30**/pledge (micropledge discount under $10). No fees if unsuccessful. [fees](https://www.kickstarter.com/help/fees)
|
||||
|
||||
---
|
||||
|
||||
## 8. Payment tab (account verification blockers)
|
||||
|
||||
Flow: choose **Individual / Business / Nonprofit** → **Continue to Stripe**.
|
||||
|
||||
| Field / requirement | Type | Required to launch | Notes | Source |
|
||||
|:--|:--|:--|:--|:--|
|
||||
| Funding entity type | Enum: individual, business, nonprofit | **Yes** | Hard to change after selection (community reports) | [verify info](https://help.kickstarter.com/en-us/articles/16236412-how-do-i-verify-my-information-and-what-should-i-do-if-it-s-not-working) |
|
||||
| Government-issued ID | Document / Stripe Identity | **Yes** | Same country as launch (EU ID flexibility within EU) | [who can use](https://help.kickstarter.com/en-us/articles/16236650-who-can-use-kickstarter) |
|
||||
| Legal name, DOB, address | Text | **Yes** | Must match documents exactly | Verify help |
|
||||
| Tax ID (SSN/ITIN/EIN/local) | Text | **Yes** (as prompted by country/entity) | Entity + all verified persons | Eligibility / verify |
|
||||
| Entity legal name, address, tax ID | Text | If business/nonprofit | Representative must be owner/executive actively creating project | [entity representative](https://help.kickstarter.com/en-us/articles/16236406-i-m-launching-a-project-on-behalf-of-a-business-or-nonprofit-entity-who-should-complete-the-verification-process) |
|
||||
| Additional owners (≥25% stake) + directors as requested | Identity set | If applicable | Stripe/regulatory “additional owners” | [owners](https://help.kickstarter.com/en-us/articles/16236401-why-does-kickstarter-need-to-know-about-my-company-s-owners-what-information-do-i-need-to-provide) |
|
||||
| US business URL **or** 2-sentence product description | URL/text | US companies when prompted | URL must show product/service funded; public `https://…` | Verify help |
|
||||
| Bank account | Checking / Futsuu (JP) / IBAN (EUR cases) | **Yes** | Same country as project (EUR IBAN flexibility list); ACH in US; no savings/virtual/wires | [bank account](https://help.kickstarter.com/en-us/articles/16236646-what-type-of-bank-account-can-i-use) |
|
||||
| Payment source (chargeback card) | Visa / Mastercard / AmEx credit **or** debit | **Yes** | Discover/JCB/Maestro/Visa Electron **not** accepted. Canada: credit only (eligibility article). Locked until successful end. | [credit card why](https://help.kickstarter.com/en-us/articles/16236391-why-do-creators-need-to-add-a-credit-card-when-setting-up-their-project), eligibility |
|
||||
| Age | Constraint | **Yes** | Creator **18+** | Who can use |
|
||||
|
||||
**Supported creator countries:** Australia, Austria, Belgium, Canada, Denmark, France, Germany, Greece, Hong Kong, Ireland, Italy, Japan, Luxembourg, Mexico, Netherlands, New Zealand, Norway, Poland, Singapore, Slovenia, Spain, Sweden, Switzerland, UK, US.
|
||||
Verification typically updates within days; contact support if no update after **5 business days**. Identity/bank **lock after verification** (support to change pre-launch).
|
||||
|
||||
**Tax note:** Funds generally income; US 1099-K via Stripe above thresholds — informational, not a pre-launch form in editor beyond Stripe tax fields. [taxes](https://www.kickstarter.com/help/taxes)
|
||||
|
||||
---
|
||||
|
||||
## 9. Submit for review & launch
|
||||
|
||||
| Control | Notes | Source |
|
||||
|:--|:--|:--|
|
||||
| Send to review / Submit for review | Runs automated completeness + cursory rules check | [prepare](https://help.kickstarter.com/en-us/articles/16236409-how-do-i-prepare-to-launch-my-project), [review blog 2016](https://www.kickstarter.com/blog/everything-you-need-to-know-about-the-project-review-process) |
|
||||
| Auto-approve vs manual | Algorithm uses category, description, rewards, goal, prior launches; **all Design & Technology → manual** | Prepare / awaiting review |
|
||||
| Manual SLA | Up to **~3 business days** (+3+ if revisions) | Awaiting review |
|
||||
| Edit while pending / after approval | Allowed | Review blog |
|
||||
| I’m ready to launch → Launch project | Manual; checkbox confirm rules; **no scheduled launch** | [launch after approved](https://help.kickstarter.com/en-us/articles/16236427-how-do-i-launch-my-project-after-it-s-been-approved) |
|
||||
|
||||
**Locked after launch (selected):** funding goal, campaign duration/deadline, bank & verified identity details, profile name (policy), rewards already backed (incl. their shipping). [edit after launch](https://help.kickstarter.com/en-us/articles/16236599-can-a-project-be-edited-after-launching)
|
||||
|
||||
---
|
||||
|
||||
## 10. Promotion / Pre-launch (post-submit)
|
||||
|
||||
| Field / action | Required | Notes | Source |
|
||||
|:--|:--|:--|:--|
|
||||
| Generate my URL | Soft-required for sharing | Slug from **title** + vanity/user segment; confirm once; support to reset (breaks old links) | [URL before launch](https://help.kickstarter.com/en-us/articles/16236439-can-i-get-my-project-s-url-before-i-launch) |
|
||||
| Activate pre-launch page | Optional but recommended ≥1 week pre-launch | First-timers: after approval; repeat: Promotion earlier | [pre-launch setup](https://help.kickstarter.com/en-us/articles/16236379-setting-up-your-project-s-pre-launch-page), [Pre-Launch Editor](https://updates.kickstarter.com/pre-launch-editor/) |
|
||||
| Pre-Launch Editor body | Optional | Text, images, videos, links (revamped editor features) | Same |
|
||||
| Auto-included on pre-launch | — | Title, subtitle, category, creator name/avatar, location | [craft pre-launch](https://updates.kickstarter.com/how-to-craft-a-pre-launch-page/) |
|
||||
| Notify me on launch / followers | — | Follower count shown at ≥10; creator cannot DM followers; pre-launch **updates** email followers | Pre-launch help |
|
||||
| Deactivate pre-launch | Optional | Followers retained if reactivated | Pre-launch help |
|
||||
| Preview share link | Optional | Different URL from pre-launch URL | Pre-launch help |
|
||||
| Google Analytics ID | Optional | Promotions tab or dashboard | [GA](https://help.kickstarter.com/en-us/articles/16236686-what-is-google-analytics-and-how-do-i-set-it-up), funding handbook |
|
||||
| Meta Pixel / CAPI | Optional | Separate help articles | Help collection Promoting / live |
|
||||
|
||||
---
|
||||
|
||||
## 11. Media specs (quick reference)
|
||||
|
||||
| Asset | Spec | Max size | Required |
|
||||
|:--|:--|:--|:--|
|
||||
| Main project image | 1024×576 (16:9) recommended; JPEG/PNG/GIF/BMP | 50 MB | Yes |
|
||||
| Story images | ≥~700px wide; JPEG/PNG/GIF (WEBP anim); no TIFF/BMP/HEIC/HEIF | 50 MB | No |
|
||||
| Item / reward / add-on image | 3:2; ≥348×232 | 50 MB | No |
|
||||
| Project / Discovery video | MOV/MPEG/AVI/MP4/3GP/WMV/FLV; Discovery **9:16** | 5120 MB | No |
|
||||
| Story-embedded video | URL embed | n/a | No |
|
||||
| Update-uploaded video | Same formats | **3 GB** | Post-launch |
|
||||
|
||||
---
|
||||
|
||||
## 12. Publishing / Books category notes
|
||||
|
||||
**Category:** Publishing (one of 15).
|
||||
**Subcategories observed on Discover (2026-09):** Academic, Anthologies, Art Books, Audiobooks, Calendars, Children, Comedy, Fiction, Letterpress, Literary Journals, Literary Spaces, Nonfiction, Periodicals, Poetry, Radio & Podcasts (slug `radio%20`), Translations, Young Adult, Zines.
|
||||
**New (May 2026 release notes):** **Audiobooks** (plus Games: TTRPG, STL) — creators “soon” able to select while building; Discover filters already live. [release notes](https://start.kickstarter.com/kickstarter-release-notes/new-games-publishing-subcategories-ttrpg-stl-and-audiobooks)
|
||||
|
||||
**Publishing-specific guidance (not unique fields):**
|
||||
- Title ≤60 / subtitle ≤135; book cover often used as project image.
|
||||
- Video optional but recommended; keep ~1–2 minutes.
|
||||
- Rewards centered on the book + digital/low-ship perks; estimated delivery with buffer.
|
||||
- Prototype rules for hardware **do not** apply; still must create something **new** and honest.
|
||||
- Plan tab **not** for typical Publishing (hardware subcategory list only).
|
||||
- Project Budget spreadsheet **not** listed for Publishing (Design/Tech/Arts/Fashion).
|
||||
Sources: [publishing hub article](https://help.kickstarter.com/en-us/articles/16236657-i-m-looking-to-run-a-publishing-project), [publishing project page guide](https://updates.kickstarter.com/how-to-create-a-great-kickstarter-publishing-project-page/), [creator’s book guide](https://updates.kickstarter.com/a-creators-guide-to-launching-a-book-on-kickstarter/).
|
||||
|
||||
**Charity:** Up to **10%** of campaign funds may be donated if disclosed **at submission**; reward donations allowed. Nonprofits: specific projects only, not general operating support. [entities/charity](https://help.kickstarter.com/en-us/articles/16236787-can-business-and-nonprofit-entities-raise-funds-for-projects), [rules](https://www.kickstarter.com/rules)
|
||||
|
||||
---
|
||||
|
||||
## 13. Crypto / NFT / prohibited (submit blockers)
|
||||
|
||||
From [Our Rules](https://www.kickstarter.com/rules) (Prohibited Items/Applications), fetched 2026-09-23:
|
||||
|
||||
1. **Cryptocurrencies and NFTs** — explicitly prohibited
|
||||
2. Service Providers (project centered on providing services)
|
||||
3. Marketplaces (primary purpose sell/re-sell)
|
||||
4. AI companions (romantic/sexual; or primarily advertising to children/parents)
|
||||
5. Items claiming to diagnose/cure/treat/prevent serious illness (incl. sexual dysfunction)
|
||||
6. Items claiming to prevent serious injury or death
|
||||
7. Contests, raffles, gambling
|
||||
8. Energy food/drinks (except coffee-bean or herbal-tea primary)
|
||||
9. Alcohol
|
||||
10. **Equity**
|
||||
11. Live animals
|
||||
12. Human/animal body parts or fluids
|
||||
13. Fighting/gambling spaces
|
||||
14. Drugs & paraphernalia (nicotine, tobacco, kava, psychedelics, cannabis)
|
||||
15. Weapons / replicas / weapon accessories; certain knives
|
||||
|
||||
Also: create something **new**; rewards produced/designed by project/collaborators; honest presentation; no misleading CGI for D&T; mature/pornographic content restricted (also subject to **Stripe** prohibited lists — Stripe may block even if KS allows). [mature/Stripe note in rules](https://www.kickstarter.com/rules), [Stripe mature reviews help](https://help.kickstarter.com/en-us/articles/16236755-navigating-stripe-mature-content-reviews)
|
||||
|
||||
**AI companions** banned; **AI as a tool** allowed with disclosure and human creative involvement.
|
||||
|
||||
---
|
||||
|
||||
## 14. Reward price floors/ceilings by country
|
||||
|
||||
| Country | Min tier | Max tier |
|
||||
|:--|--:|--:|
|
||||
| United States | $1 | $10,000 |
|
||||
| United Kingdom | £1 | £8,000 |
|
||||
| Canada | $1 CAD | $13,000 CAD |
|
||||
| Australia | $1 AUD | $13,000 AUD |
|
||||
| New Zealand | $1 NZD | $14,000 NZD |
|
||||
| Mexico | $10 MXN | $200,000 MXN |
|
||||
| Japan | ¥100 | ¥1,200,000 |
|
||||
| NL/DE/IT/AT/BE/LU/FR/ES/IE/GR/SI | €1 | €8,500 |
|
||||
| Sweden | 5 SEK | 85,000 SEK |
|
||||
| Denmark | 5 DKK | 65,000 DKK |
|
||||
| Norway | 5 NOK | 80,000 NOK |
|
||||
| Switzerland | 1 CHF | 9,500 CHF |
|
||||
| Hong Kong | 10 HKD | 75,000 HKD |
|
||||
| Singapore | 2 SGD | 13,000 SGD |
|
||||
| Poland | 5 PLN | 37,250 PLN |
|
||||
|
||||
Source: [max reward tier](https://help.kickstarter.com/en-us/articles/16236756-is-there-a-maximum-reward-tier-value)
|
||||
|
||||
---
|
||||
|
||||
## 15. UNKNOWN / gaps (need live editor or KS support to confirm)
|
||||
|
||||
- Exact **Submit** checklist itemization (which fields flip green).
|
||||
- Story / Risks / reward description **hard character limits**.
|
||||
- Whether **FAQ** editor exists pre-launch in 2026 UI.
|
||||
- Full **demographic** question list.
|
||||
- Whether **Environmental Commitments** expanded beyond Design & Tech / NA.
|
||||
- Exact Stripe field names per country (tax form variants).
|
||||
- Whether **Preferences** tab contains more than shipping strategy (pixels sometimes listed under Promotion).
|
||||
- **Pledge Over Time** creator-side Basics toggles (backer feature FAQ exists; creator enablement UI **partially UNKNOWN**).
|
||||
- Start wizard “Next: Additional subcategory” microcopy exact requiredness.
|
||||
|
||||
---
|
||||
|
||||
## 16. Primary citations
|
||||
|
||||
| Resource | URL |
|
||||
|:--|:--|
|
||||
| Create wizard | https://www.kickstarter.com/start |
|
||||
| Creator Handbook hub | https://www.kickstarter.com/help/handbook |
|
||||
| Funding handbook | https://www.kickstarter.com/help/handbook/funding |
|
||||
| Rewards handbook | https://www.kickstarter.com/help/handbook/rewards |
|
||||
| Story handbook | https://www.kickstarter.com/help/handbook/your_story |
|
||||
| Project image specs | https://www.kickstarter.com/help/images |
|
||||
| Our Rules | https://www.kickstarter.com/rules |
|
||||
| Fees | https://www.kickstarter.com/help/fees |
|
||||
| Taxes guide | https://www.kickstarter.com/help/taxes |
|
||||
| Help: category | https://help.kickstarter.com/en-us/articles/16236767-how-do-i-choose-the-right-category-for-my-project |
|
||||
| Help: duration | https://help.kickstarter.com/en-us/articles/16236742-what-is-the-maximum-project-duration |
|
||||
| Help: video | https://help.kickstarter.com/en-us/articles/16236743-is-a-project-video-required-to-launch |
|
||||
| Help: add rewards | https://help.kickstarter.com/en-us/articles/16236688-how-do-i-add-rewards-to-my-project |
|
||||
| Help: itemize | https://help.kickstarter.com/en-us/articles/16236437-how-do-i-itemize-my-rewards |
|
||||
| Help: shipping options | https://help.kickstarter.com/en-us/articles/16236769-what-options-do-i-have-for-charging-shipping-costs |
|
||||
| Help: Late Pledges | https://help.kickstarter.com/en-us/articles/16236699-how-do-i-add-late-pledges-to-my-project |
|
||||
| Help: verify | https://help.kickstarter.com/en-us/articles/16236412-how-do-i-verify-my-information-and-what-should-i-do-if-it-s-not-working |
|
||||
| Help: bank | https://help.kickstarter.com/en-us/articles/16236646-what-type-of-bank-account-can-i-use |
|
||||
| Help: card | https://help.kickstarter.com/en-us/articles/16236391-why-do-creators-need-to-add-a-credit-card-when-setting-up-their-project |
|
||||
| Help: who can use | https://help.kickstarter.com/en-us/articles/16236650-who-can-use-kickstarter |
|
||||
| Help: collaborators | https://help.kickstarter.com/en-us/articles/16236794-what-is-the-project-collaborators-tool-and-how-do-i-use-it |
|
||||
| Help: Plan tab | https://help.kickstarter.com/en-us/articles/16236806-what-is-the-plan-tab |
|
||||
| Help: pre-launch | https://help.kickstarter.com/en-us/articles/16236379-setting-up-your-project-s-pre-launch-page |
|
||||
| Help: AI | https://help.kickstarter.com/en-us/articles/16236759-can-i-use-ai-generated-content-or-create-ai-technology-in-my-project |
|
||||
| Help: Publishing | https://help.kickstarter.com/en-us/articles/16236657-i-m-looking-to-run-a-publishing-project |
|
||||
| Updates: eligibility | https://updates.kickstarter.com/who-is-eligible-to-use-kickstarter/ |
|
||||
| Updates: AI policy | https://updates.kickstarter.com/introducing-our-new-ai-policy/ |
|
||||
| Updates: Pre-Launch Editor | https://updates.kickstarter.com/pre-launch-editor/ |
|
||||
| Updates: campaign page guide | https://updates.kickstarter.com/kickstarter-lessons/guide-to-kickstarter-campaign-page/ |
|
||||
| Discover Publishing | https://www.kickstarter.com/discover/categories/publishing |
|
||||
|
||||
---
|
||||
|
||||
*Inventory compiled for internal campaign ops (AiBook / WeOwnNet). Re-verify in live editor before submit; Kickstarter UI and Stripe prompts can vary by country and change without handbook updates.*
|
||||
|
||||
|
||||
---
|
||||
|
||||
## 17. Live `/start` UI confirmation (browser pass, 23 Sep 2026 WAT)
|
||||
|
||||
Observed without login (account gate after location). Screenshots under `/workspace/screenshots/`.
|
||||
|
||||
### Wizard order
|
||||
1. **What are you making?** — primary category + subcategory
|
||||
2. **Select one more subcategory** — optional second category/subcategory (“Next: Location” works with none)
|
||||
3. **Last one—set a location for your project** — **Select your country** (legal residence or entity tax-ID country). Continue disabled until country chosen.
|
||||
4. Then **Log in or sign up** (email / Apple / Facebook recovery). Editor not reachable without account.
|
||||
|
||||
Footer copy: “Nothing is public until you launch. You can edit or delete this project anytime before then.”
|
||||
|
||||
### Publishing subcategories (exact labels)
|
||||
`--No subcategory--`; Academic; Anthologies; Art Books; Audiobooks; Calendars; Children's Books; Comedy; Fiction; Letterpress; Literary Journals; Literary Spaces; **Nonfiction**; Periodicals; Poetry; Radio & Podcasts; Translations; Young Adult; Zines.
|
||||
|
||||
### Creator countries shown
|
||||
Australia, Austria, Belgium, Canada, Denmark, France, Germany, Greece, Hong Kong, Ireland, Italy, Japan, Luxembourg, Mexico, New Zealand, Norway, Poland, Singapore, Slovenia, Spain, Sweden, Switzerland, the Netherlands, the United Kingdom, the United States.
|
||||
|
||||
### Other live notes
|
||||
- Apple-ID-linked accounts cannot currently start projects (Help: How do I start a project?).
|
||||
- Rewards handbook recommends **≤ 5 reward tiers** for a first project (guidance, not a hard cap).
|
||||
- `/help/handbook/creating` 404 → use `/help/handbook/getting_started`.
|
||||
@@ -0,0 +1,404 @@
|
||||
# Kickstarter filled form pack — We Own AI
|
||||
**Status:** Paste-ready draft for the project editor + review submission. Matches the campaign guide v2.1 (`kickstarter-campaign-guide.md`).
|
||||
**Prepared:** 23 Sep 2026 (WAT) · **Owner-approved:** 23 Sep 2026 (WAT) · **Revised:** 27 Sep 2026 (WAT), three-section reward structure confirmed
|
||||
**Sources:** `ks-campaign-blueprint.md` (HEAD `83721c43`) · AiBook.fun product locks · GUIDE-436 (`WeOwnAi/s004_fedarch/_GUIDES_/GUIDE-436.md`, AOP.biz bundle contents) · Kickstarter official field inventory in `kickstarter-fields.md`
|
||||
**Not done in this pack:** live Kickstarter login, Stripe ID/bank/tax, uploading real media files, clicking Submit.
|
||||
|
||||
**Owner lock (27 Sep 2026):** campaign **We Own AI — The New American Dream**, Fri 2 Oct – Wed 4 Nov 2026, **$5,000 all-or-nothing** (goal funds the book and the AiBook.fun library). Rewards in **three sections**: (1) **The book**, (2) **Build it yourself or with us** (AOP.biz bundles), (3) **In person** (Burned Out Advisor Retreat). **Growth bundle and Retreat close Tue 20 Oct 2026.** The $988/mo AOP.biz service, the $200/mo WeOwn Cloud hosting, and the cohort attendance commitment are **separate, optional agreements after the pledge**; Kickstarter charges once. **Academy held out of launch** (announced in a campaign update once dates and prices exist). Retreat **price and venue are OWNER-PENDING** (do not invent).
|
||||
|
||||
### How to read tags
|
||||
- **CONFIRMED** — locked by the owner or in GUIDE-436 / product decisions
|
||||
- **RECOMMENDED** — filled so the form is complete; owner can override before submit
|
||||
- **OWNER-PENDING** — a fact only the owner can supply; left blank on purpose
|
||||
- **OWNER-ONLY** — cannot be filled by an agent (secrets / legal / live account)
|
||||
- **ASSET NEEDED** — text ready; file must be uploaded
|
||||
|
||||
---
|
||||
|
||||
## A0. Editor tab map
|
||||
|
||||
Ordered Kickstarter UI: `/start` → **Basics** → **Story** → **Rewards** → **People** → **Funding** → **Preferences** → **Payment** → **Send to review** → approval → **Promotion** (URL + pre-launch) → **Launch project** *(manual; does not auto-launch on Target Launch Date)*. Publishing projects have no Plan tab.
|
||||
|
||||
| Tab | What this pack fills | Notes |
|
||||
|---|---|---|
|
||||
| Start | Publishing → Nonfiction | **CONFIRMED** live subcategory; creator country = US entity |
|
||||
| Basics | Title, subtitle, image, fixed end date, Late Pledges on, Target Launch Date 2 Oct 2026 | Video optional |
|
||||
| Story | Full paste in §H, including Risks + Use of AI | Environmental Commitments optional (guide §2.6) |
|
||||
| Rewards | Items + 8 tiers in 3 sections + 3 add-ons (§E–F) | KS handbook suggests ≤5 tiers for a first project; 8 is allowed. If review pushes back, drop Digital Supporter first. |
|
||||
| People | Bio + collaborators (§D) | Add the AOP.biz bundles lead once named |
|
||||
| Funding | Goal **$5,000** USD | No Project Budget sheet for Publishing |
|
||||
| Preferences | Shipping **after the campaign via Pledge Manager** (RECOMMENDED) | Or at pledge time once rates exist |
|
||||
| Payment | OWNER-ONLY Stripe checklist (§I) | Blocks launch |
|
||||
| Promotion | After approval: generate URL, pre-launch page, paste blurb | |
|
||||
| Launch | Manual **Launch project** Fri 2 Oct, 6:00 AM ET (11:00 AM WAT) | Slip: Fri 9 Oct → Wed 11 Nov |
|
||||
|
||||
## A. Submit defaults
|
||||
|
||||
| ID | Decision | Value used in this pack |
|
||||
|---|---|---|
|
||||
| D1 | Launch window | **CONFIRMED:** Fri 2 Oct 2026 → Wed 4 Nov 2026. **RECOMMENDED:** fixed end Wed 4 Nov, 8:00 PM ET (Thu 5 Nov, 2:00 AM WAT). Slip to Fri 9 Oct → Wed 11 Nov if not approved by the go/no-go call (Thu 1 Oct, 6:00 PM ET). |
|
||||
| D2 | Funding stack | **CONFIRMED:** goal **$5,000**, all-or-nothing; it funds the book and the AiBook.fun library. Stretch goals **$15,000** (bonus chapter), **$35,000** (audiobook sample), **$54,000** (live Q&A replay pack). |
|
||||
| D3 | Reward structure | **CONFIRMED 27 Sep 2026:** three sections, 8 tiers (§F): The book (Tiers 1–4), Build it yourself or with us (Tiers 5–7), In person (Tier 8). |
|
||||
| D4 | Public URL | **CONFIRMED:** **https://aibook.fun** (AiBook.fun brand). |
|
||||
| D5 | $47 tier | **CONFIRMED:** **Digital Access Subscription** = eBook + 12 months of AiBook.fun ($47/yr, updated continuously; not a yearly reprint). Access starts ~14 days after success; no auto-renew; renew at aibook.fun. |
|
||||
| D6 | Retreat | **CONFIRMED:** Burned Out Advisor Retreat **4–6 Nov 2026**, cap **369** (~80% accounting advisors, ~20% CKA®/CEPA® financial advisors). Closes **Tue 20 Oct 2026**. Includes seat + signed paperback + eBook + 12 months AiBook.fun. Travel/lodging **not included**. **Price: OWNER-PENDING. Venue: OWNER-PENDING** (see K). |
|
||||
| D7 | AOP.biz bundles | **CONFIRMED:** $1,000 DIY (on WeOwn Cloud, no support), $2,000 Launch, $5,000 Growth (includes a Retreat seat; closes Tue 20 Oct 2026). Contents per GUIDE-436. Launch + Growth include 3 months AOP.biz service (Jan–Mar 2027) + Dec 2026 AOPbizFastTrack cohort. |
|
||||
| D8 | Separate agreements | **CONFIRMED:** $988/mo AOP.biz service (from Apr 2027, Launch/Growth), $200/mo WeOwn Cloud hosting (DIY), and cohort attendance (≥50% weekly) are separate, optional agreements after the pledge; none is charged by Kickstarter. |
|
||||
| D9 | Academy | **CONFIRMED:** held out of launch. Announce in a campaign update once dates and prices exist. Draft copy kept in the guide, Appendix E. |
|
||||
| D10 | Season tag | **RECOMMENDED:** **#WeOwnAI #BuildInPublic** on the KS page; keep #WeOwnSeason005 internal until the owner locks it. |
|
||||
| D15 / D20 | Delivery | **RECOMMENDED:** eBook **January 2027**; signed paperback **February 2027**; AiBook.fun access within ~14 days of success. |
|
||||
| D17 | Collector's Bundle | **CONFIRMED:** a **paperback add-on** (signed bookplate + printable chapter-notes PDF), not a tier. |
|
||||
| — | Category | **CONFIRMED:** Publishing → Nonfiction |
|
||||
| — | Currency / country | **RECOMMENDED assumption:** **USD**, entity in the **United States** (BurnedOut Media / WeOwnNet). **OWNER-ONLY** to confirm the legal entity. |
|
||||
|
||||
---
|
||||
|
||||
## B. Start a project
|
||||
|
||||
| Field | Fill |
|
||||
|---|---|
|
||||
| Primary category | **Publishing** |
|
||||
| Primary subcategory | **Nonfiction** (CONFIRMED live on /start, 23 Sep 2026) |
|
||||
| Additional category | Leave blank |
|
||||
|
||||
---
|
||||
|
||||
## C. Basics tab
|
||||
|
||||
| Field | Fill | Tag |
|
||||
|---|---|---|
|
||||
| Project title | `We Own AI — The New American Dream` (34 chars / 60 max) | CONFIRMED |
|
||||
| Creator name | `WeOwnNet` or `BurnedOut Media / WeOwnNet` (no emoji) | OWNER-ONLY choice |
|
||||
| Subtitle | `A field book for advisors and professionals: tested AI workflows, clear guardrails, and a companion library that stays current.` (127 / 135) | RECOMMENDED |
|
||||
| Subtitle (short alternative) | `A multi-author field book for advisors, with tested AI workflows and a companion library at AiBook.fun.` (103) | RECOMMENDED |
|
||||
| Project image | 1920 × 1080; book mockup beside a laptop showing an AiBook.fun chapter page; banner ≤6 words, e.g. "The book and the AiBook.fun library"; use the landing-page cover already rendered in `story-images/src/assets-gen/` | ASSET NEEDED |
|
||||
| Project video | Omit for review if not ready; 2–3 min, @THY on camera / @LFG edit | ASSET NEEDED / optional |
|
||||
| Location | North Denver, Denver, CO (already set) | CONFIRMED in draft |
|
||||
| Funding goal | **$5,000** USD | CONFIRMED |
|
||||
| End date | Fixed **Wed 4 Nov 2026, 8:00 PM ET** | RECOMMENDED (D1) |
|
||||
| Target Launch Date | **Fri 2 Oct 2026** (does **not** auto-launch) | CONFIRMED |
|
||||
| Late Pledges | **On** (turn on before launch); per-tier settings in §F | RECOMMENDED |
|
||||
| Project URL slug | `we-own-ai-the-new-american-dream` | RECOMMENDED |
|
||||
|
||||
---
|
||||
|
||||
## D. People / profile
|
||||
|
||||
| Field | Fill | Tag |
|
||||
|---|---|---|
|
||||
| Creator / funds recipient | Legal entity or authorized owner of **BurnedOut Media / WeOwnNet** (exact legal name) | OWNER-ONLY |
|
||||
| Profile bio | See §D1 | RECOMMENDED |
|
||||
| Website | https://aibook.fun | CONFIRMED |
|
||||
| Social | LinkedIn company page and other active accounts | OWNER-ONLY links |
|
||||
| Collaborators | @LFG and @THY (edit + community), @GTM (fulfillment + Pledge Manager), @CEO (analytics), Osinachi Patrick (edit + analytics), **AOP.biz bundles lead** (fulfillment for bundles; name OWNER-PENDING) | OWNER lock |
|
||||
|
||||
### D1. Creator bio (paste)
|
||||
|
||||
BurnedOut Media / WeOwnNet publishes practical books and programs for advisors and professionals working with AI. We are building We Own AI — The New American Dream and the AiBook.fun library in public, with a team of founding authors. Website: aibook.fun
|
||||
|
||||
---
|
||||
|
||||
## E. Rewards — Items (create these first; 3:2 image, 1200 × 800)
|
||||
|
||||
| Item name | Description | Image |
|
||||
|---|---|---|
|
||||
| eBook (PDF + Kindle) | Full digital edition of *We Own AI — The New American Dream* | Cover on a tablet |
|
||||
| Signed paperback | Signed first-edition paperback | Cover + book photo |
|
||||
| 12 months of AiBook.fun access | 12 months of the AiBook.fun library at aibook.fun, updated as tools and models change | Laptop with a chapter page |
|
||||
| Signed bookplate | Printed signed bookplate (signers OWNER-PENDING) | Photo |
|
||||
| Chapter-notes PDF | Printable chapter notes | Simple card |
|
||||
| AOP.biz DIY pack on WeOwn Cloud | Starter agent fleet, docs/how-to, agentic assistant on your own knowledge base, dedicated self-hosted instance on WeOwn Cloud | Bundle comparison, DIY column |
|
||||
| AOP.biz Launch bundle | Per GUIDE-436 Launch tier | Bundle comparison, Launch column |
|
||||
| AOP.biz Growth bundle | Per GUIDE-436 Growth tier, incl. Retreat seat | Bundle comparison, Growth column |
|
||||
| Burned Out Advisor Retreat seat | One seat, 4–6 Nov 2026 | Venue photo (OWNER-PENDING) |
|
||||
|
||||
---
|
||||
|
||||
## F. Rewards — Tiers (public)
|
||||
|
||||
Three sections: **The book** (Tiers 1–4) · **Build it yourself or with us** (Tiers 5–7) · **In person** (Tier 8). Plus add-ons. The book tiers are never labeled "Cloud"; WeOwn Cloud is only the infrastructure in the $1,000 DIY bundle.
|
||||
|
||||
**Delivery rule:** a tier's estimated delivery is the month its last item arrives. **Shipping rule:** digital and service tiers = No shipping; physical items collected in the Pledge Manager after the campaign (RECOMMENDED).
|
||||
|
||||
### Section 1 — The book
|
||||
|
||||
#### Tier 1 — Early Bird eBook
|
||||
| Field | Fill |
|
||||
|---|---|
|
||||
| Title | Early Bird eBook |
|
||||
| Amount | **$19** (CONFIRMED) |
|
||||
| Limit | **200** (CONFIRMED) |
|
||||
| Items | eBook (PDF + Kindle) |
|
||||
| Available | From launch until sold out |
|
||||
| Estimated delivery | **January 2027** |
|
||||
| Shipping | No shipping |
|
||||
| Description | The full eBook of We Own AI — The New American Dream in PDF and Kindle formats, at our lowest price. Limited to the first 200 backers. |
|
||||
| Late Pledge | Off |
|
||||
|
||||
#### Tier 2 — Digital Supporter
|
||||
| Field | Fill |
|
||||
|---|---|
|
||||
| Title | Digital Supporter |
|
||||
| Amount | **$25** (CONFIRMED) |
|
||||
| Limit | Unlimited |
|
||||
| Items | eBook (PDF + Kindle) |
|
||||
| Estimated delivery | **January 2027** |
|
||||
| Shipping | No shipping |
|
||||
| Description | The full eBook in PDF and Kindle formats, plus backer-only updates as we finish the book. |
|
||||
| Late Pledge | **$28** |
|
||||
|
||||
#### Tier 3 — Digital Access Subscription (featured)
|
||||
| Field | Fill |
|
||||
|---|---|
|
||||
| Title | Digital Access Subscription |
|
||||
| Amount | **$47** (CONFIRMED; matches AiBook.fun $47/yr) |
|
||||
| Limit | Unlimited |
|
||||
| Items | eBook + 12 months of AiBook.fun access |
|
||||
| Estimated delivery | **January 2027** (library access ~14 days after success, November 2026) |
|
||||
| Shipping | No shipping |
|
||||
| Featured | Yes |
|
||||
| Description | The eBook plus 12 months of access to the AiBook.fun library. The library holds the book's workflows and new ones as we publish them, and we update it as tools and models change, often weekly or monthly. Your access starts within about 14 days of a successful campaign. After 12 months you can renew at aibook.fun. Your pledge does not renew by itself. |
|
||||
| Late Pledge | **$52** |
|
||||
|
||||
#### Tier 4 — Signed Paperback
|
||||
| Field | Fill |
|
||||
|---|---|
|
||||
| Title | Signed Paperback |
|
||||
| Amount | **$55** (PLACEHOLDER — replace once print, signing, packing, shipping, and fees are costed) |
|
||||
| Limit | Unlimited (or a print-run cap once known) |
|
||||
| Items | Signed paperback + eBook |
|
||||
| Estimated delivery | **February 2027** |
|
||||
| Shipping | Physical; collected in the Pledge Manager (RECOMMENDED) |
|
||||
| Description | A signed first-edition paperback plus the eBook. The eBook arrives first, and paperbacks ship after printing. Shipping is charged separately after the campaign. |
|
||||
| Late Pledge | On once shipping is settled (~10% above the final price) |
|
||||
|
||||
### Section 2 — Build it yourself or with us (AOP.biz bundles, per GUIDE-436)
|
||||
|
||||
Messaging rule (GUIDE-436): the $2,000 Launch copy never implies the Retreat; the $5,000 Growth copy always states it. No marketing credits or developer hours (unconfirmed). No income or earnings claims.
|
||||
|
||||
#### Tier 5 — AOP.biz DIY on WeOwn Cloud
|
||||
| Field | Fill |
|
||||
|---|---|
|
||||
| Title | AOP.biz DIY on WeOwn Cloud |
|
||||
| Amount | **$1,000** (CONFIRMED) |
|
||||
| Limit | OWNER-PENDING (if any) |
|
||||
| Items | AOP.biz DIY pack on WeOwn Cloud |
|
||||
| Includes | The same pack as Launch: starter agent fleet, docs/how-to, agentic assistant answering from your own knowledge base, dedicated self-hosted instance where you own the data, running on **WeOwn Cloud** (infrastructure provisioned and managed by agents built by WeOwnDev) |
|
||||
| Not included | Implementation support or support of any kind; Q1 2027 AOP.biz service; December cohort; the $988/mo option; Retreat seat |
|
||||
| Estimated delivery | OWNER-PENDING (month the DIY instance is provisioned) |
|
||||
| Shipping | No shipping |
|
||||
| Description | The AOP.biz starter pack to run yourself: a starter agent fleet, docs and how-to guides, an agentic assistant that answers from your own knowledge base, and a dedicated self-hosted instance where you own the data. It runs on WeOwn Cloud, infrastructure provisioned and managed by agents built by WeOwnDev. This reward includes no implementation support and no support of any kind. It does not include AOP.biz service, the December cohort, or a Retreat seat. WeOwn Cloud hosting continues at $200 a month under a separate, optional agreement made after the campaign. It is not part of your pledge, and Kickstarter does not charge it. |
|
||||
| After the pledge | $200/mo WeOwn Cloud hosting, separate optional agreement. **Start date not confirmed** (OWNER-PENDING; description gives no date). |
|
||||
| Late Pledge | OWNER-PENDING |
|
||||
|
||||
#### Tier 6 — AOP.biz Launch bundle
|
||||
| Field | Fill |
|
||||
|---|---|
|
||||
| Title | AOP.biz Launch bundle |
|
||||
| Amount | **$2,000** (CONFIRMED) |
|
||||
| Limit | OWNER-PENDING (if any, e.g. cohort capacity) |
|
||||
| Items | AOP.biz Launch bundle |
|
||||
| Includes | Onboarding · starter agent fleet · first implementation cycle · docs/how-to · agentic brain + assistant (answers from your own knowledge base) · self-hosted open core (you own the data) · dedicated instance · 3 months AOP.biz service (Jan–Mar 2027) · Dec 2026 AOPbizFastTrack cohort seat |
|
||||
| Not included | Retreat seat |
|
||||
| Estimated delivery | **March 2027** (cohort from Dec 2026; service Jan–Mar 2027) |
|
||||
| Shipping | No shipping |
|
||||
| Description | The AOP.biz Launch bundle: onboarding, a starter agent fleet, a first implementation cycle, docs and how-to guides, an agentic brain and assistant that answers from your own knowledge base, the self-hosted open core where you own the data, and a dedicated instance. It includes three months of AOP.biz service (January to March 2027) and a seat in the December 2026 AOPbizFastTrack cohort. The cohort asks you to attend at least 50% of weekly sessions, which you agree to when you register after the campaign. This bundle does not include a Retreat seat. From April 2027 you can continue AOP.biz service at $988 a month under a separate, optional agreement. It is not part of your pledge, and Kickstarter does not charge it. |
|
||||
| After the pledge | Cohort attendance (≥50% weekly) and optional $988/mo from Apr 2027, both separate agreements |
|
||||
| Late Pledge | Off (RECOMMENDED; fixed cohort list) |
|
||||
|
||||
#### Tier 7 — AOP.biz Growth bundle with a Retreat seat
|
||||
| Field | Fill |
|
||||
|---|---|
|
||||
| Title | AOP.biz Growth bundle with a Retreat seat |
|
||||
| Amount | **$5,000** (CONFIRMED) |
|
||||
| Limit | OWNER-PENDING; if Growth seats count toward the Retreat's 369, split 369 with Tier 8 |
|
||||
| Available | From launch until **Tue 20 Oct 2026** (CONFIRMED) |
|
||||
| Items | AOP.biz Growth bundle + Burned Out Advisor Retreat seat |
|
||||
| Includes | Everything in Launch + deeper integration · more agents/swarm · ongoing support cadence · SharedBrain layer · workflow/automation layer (drafts proposals, intake, status emails) · **Burned Out Advisor Retreat seat (4–6 Nov 2026)** · 3 months AOP.biz service (Jan–Mar 2027) · Dec 2026 AOPbizFastTrack cohort seat |
|
||||
| Estimated delivery | **March 2027** (Retreat Nov 2026; cohort from Dec 2026; service Jan–Mar 2027) |
|
||||
| Shipping | No shipping |
|
||||
| Description | The AOP.biz Growth bundle, with a seat at the Burned Out Advisor Retreat, 4 to 6 November 2026. It includes everything in the Launch bundle, plus deeper integration, more agents working together, an ongoing support cadence, the SharedBrain layer, and a workflow and automation layer for tasks such as drafting proposals, intake, and status emails. It also includes three months of AOP.biz service (January to March 2027) and a seat in the December 2026 AOPbizFastTrack cohort, which asks you to attend at least 50% of weekly sessions; you agree to this when you register after the campaign. Available until Tuesday 20 October 2026. We will message you within 48 hours of your pledge with a Retreat registration link. Travel and lodging for the Retreat are not included. From April 2027 you can continue AOP.biz service at $988 a month under a separate, optional agreement. It is not part of your pledge, and Kickstarter does not charge it. |
|
||||
| Late Pledge | Off (closes 20 Oct) |
|
||||
|
||||
### Section 3 — In person
|
||||
|
||||
#### Tier 8 — Burned Out Advisor Retreat
|
||||
| Field | Fill |
|
||||
|---|---|
|
||||
| Title | Burned Out Advisor Retreat (4–6 Nov 2026) |
|
||||
| Amount | **OWNER-PENDING — leave blank; do not invent** |
|
||||
| Limit | **369** (CONFIRMED cap), or Tier 8's share if Growth seats count toward 369 |
|
||||
| Available | From launch until **Tue 20 Oct 2026** (CONFIRMED) |
|
||||
| Dates | **4–6 November 2026** (CONFIRMED) |
|
||||
| Venue | **OWNER-PENDING.** GUIDE-436 says TradeWinds Resort, St. Pete Beach, FL; this pack retired the "St. Pete" label. Leave off the page until confirmed. |
|
||||
| Audience | ~80% accounting advisors (Exit to Client), ~20% financial advisors with CKA®/CEPA® focus (targeting note, not a form field) |
|
||||
| Items | Retreat seat + Signed paperback + eBook + 12 months of AiBook.fun access |
|
||||
| Estimated delivery | **February 2027** (paperback); Retreat attendance November 2026 |
|
||||
| Shipping | Physical (paperback), collected in the Pledge Manager |
|
||||
| Description | One seat at the Burned Out Advisor Retreat, 4 to 6 November 2026, at [venue — OWNER-PENDING]. Three days for accounting advisors exploring Exit to Client and financial advisors focused on CKA® (Certified Kingdom Advisor) and CEPA® (Certified Exit Planning Advisor) work. Includes [sessions, meals, materials — OWNER-PENDING], a signed paperback, the eBook, and 12 months of AiBook.fun access. Travel and lodging are not included. Available until Tuesday 20 October 2026. We will message you within 48 hours of your pledge with a registration link. See the Retreat section of the story for date-change, transfer, and refund terms. |
|
||||
| Late Pledge | Off (closes 20 Oct) |
|
||||
|
||||
### Add-ons
|
||||
|
||||
| Add-on | Price | Attach to | Delivery | Description |
|
||||
|---|---|---|---|---|
|
||||
| Signed paperback | OWNER-PENDING | Tiers 1, 2, 3, 5, 6, 7 | February 2027 | Add a signed first-edition paperback to any reward that does not already include one. |
|
||||
| Collector's Bundle | OWNER-PENDING (the old $85 bundle included the paperback; the ~$30 gap to $55 is only a starting point) · limit RECOMMENDED 100 | Tier 4, Tier 8, and the paperback add-on | February 2027 | A signed bookplate and a printable chapter-notes PDF, added to your signed paperback. |
|
||||
| Gift a year of AiBook.fun (optional) | $47 | Tiers 1–8 | November 2026 | Give 12 months of AiBook.fun access to a colleague. You will send us their email address in the survey after the campaign. |
|
||||
|
||||
### Separate agreements after the pledge (not rewards; not charged by Kickstarter)
|
||||
|
||||
| Agreement | Who it applies to | Terms | Status |
|
||||
|---|---|---|---|
|
||||
| WeOwn Cloud hosting | DIY ($1,000) backers | $200/month to keep the DIY instance running on WeOwn Cloud | CONFIRMED price; **start date OWNER-PENDING** |
|
||||
| AOP.biz service | Launch and Growth backers | $988/month from April 2027, after the three included months | CONFIRMED; optional |
|
||||
| AOPbizFastTrack cohort commitment | Launch and Growth backers | Attend ≥50% of weekly sessions in the Dec 2026 cohort; agreed at cohort registration | CONFIRMED; consequence of missing it OWNER-PENDING |
|
||||
|
||||
### Not in the launch rewards
|
||||
|
||||
- **Academy** (AiCoach + AOP.biz BootCamp at Azur Resorts, Orlando FL; #NoDe, North Denver CO; Villa Park, Chicagoland IL): held out of launch; to be announced in a campaign update once dates and prices exist. Draft tier, story section, FAQ, and risk text are in the guide, Appendix E.
|
||||
- **Marketing credits / developer hours:** older Notion notes only; unconfirmed; not offered.
|
||||
|
||||
---
|
||||
|
||||
## G. Stretch goals (story section — no separate KS field)
|
||||
|
||||
1. **$15,000 — Bonus chapter** (PDF for every backer whose reward includes the eBook)
|
||||
2. **$35,000 — Audiobook sample** (one chapter as audio, for every backer)
|
||||
3. **$54,000 — Live Q&A replay pack** (recording of a live Q&A with the authors, for every backer)
|
||||
|
||||
---
|
||||
|
||||
## H. Story tab — paste order
|
||||
|
||||
The final paste text for every section is in the campaign guide, §2.3 (sixteen sections, each with a header image from `story-images/`). Section list and the key facts each must carry:
|
||||
|
||||
| # | Section heading | Key content | Story images |
|
||||
|---|---|---|---|
|
||||
| 1 | 👋 Welcome | Field book for advisors; three ways to back; **the $5,000 goal funds the book and the AiBook.fun library**; all-or-nothing | 01, 01b |
|
||||
| 2 | ❤️ Why this book | Four problems, plain sentences | 02, 02b |
|
||||
| 3 | 🎯 Who it's for | Accounting advisors (Exit to Client); financial advisors (CKA®/CEPA®); others who advise clients | 03, 03b |
|
||||
| 4 | 📖 What's inside | Eight-part workflow recipe; chapters | 04, 04b, 04c |
|
||||
| 5 | 🧪 Try one workflow | Free sample at aibook.fun | 05, 05b, 05c |
|
||||
| 6 | 🧭 Three ways to back | The book · Build it yourself or with us · In person; 20 Oct cutoff; separate agreements | 06, 06b (or 06c) |
|
||||
| 7 | 📚 The book and AiBook.fun | Library $47/yr, updated continuously; renew at aibook.fun | 07, 07b |
|
||||
| 8 | 🛠️ Build it yourself or with us | $1,000 DIY / $2,000 Launch / $5,000 Growth; what the pledge covers; separate agreements | 08, 08b |
|
||||
| 9 | 🏕️ In person: the Retreat | 4–6 Nov 2026; 369 seats; closes 20 Oct; travel/lodging not included; venue + price pending | 09, 09b |
|
||||
| 10 | 🎁 Stretch goals | $15k / $35k / $54k | 10, 10b–10e |
|
||||
| 11 | ⏳ Timeline | 2 Oct open · **20 Oct Retreat + Growth close** · 4 Nov end + Retreat 4–6 Nov · mid-Nov access + survey · Dec cohort · Jan eBook · Jan–Mar service · Feb paperbacks | 11, 11b |
|
||||
| 12 | 📦 Shipping and delivery | Digital by email; paperbacks Feb 2027 via Pledge Manager | 12, 12b |
|
||||
| 13 | 👀 Early readers | Only quotes approved in writing | 13, 13b |
|
||||
| 14 | ✍️ The authors and team | Real names; includes the AOP.biz bundles lead | 14, 14b, 14c |
|
||||
| 15 | 🙏 Special thanks | | 15 |
|
||||
| 16 | 📣 How to help | Back, share with two advisors, follow aibook.fun | 16 |
|
||||
|
||||
### H1. Welcome (paste)
|
||||
|
||||
We Own AI — The New American Dream is a field book for advisors who want to use AI in their practice in ways they control. It is written by [number — OWNER-PENDING] authors who use these methods in their own work, and published by BurnedOut Media / WeOwnNet.
|
||||
|
||||
Each chapter explains an approach to a kind of professional work and then walks through workflows you can run yourself, with the safeguards set out before the steps. The same workflows are online at AiBook.fun, where we keep them up to date as the tools change.
|
||||
|
||||
This campaign funds the first edition. You can back it in three ways, described below: the book, from the $19 eBook to a year of the AiBook.fun library at $47; an AOP.biz bundle to build your own AI setup yourself or with our team, from $1,000; or a seat at the Burned Out Advisor Retreat, 4 to 6 November 2026.
|
||||
|
||||
Our goal is $5,000, and it funds the book and the AiBook.fun library. Kickstarter is all-or-nothing: if we reach the goal by [end date and time], backers are charged and we deliver the rewards. If we do not reach it, nobody is charged.
|
||||
|
||||
### H2. The book and AiBook.fun (paste; replaces the old "The book" block)
|
||||
|
||||
The book rewards are for people who want to learn Responsible Agentic AI from the book on their own schedule. They start with the eBook, and the $47 reward adds a year of the AiBook.fun library.
|
||||
|
||||
**What AiBook.fun is.** AiBook.fun is the online home of the book's workflows. You read a chapter, then run a workflow's Try-it exercise with sample data. Each workflow shows its version and the date it was last updated.
|
||||
|
||||
**How it stays current.** We update workflows as tools and models change, often weekly or monthly. Access costs $47 a year. Your Kickstarter pledge covers the first 12 months, starting within about 14 days of a successful campaign. After that you can choose to renew at aibook.fun.
|
||||
|
||||
### H3. Rewards summary (for the story graphic 06b; the story editor has no tables)
|
||||
|
||||
**The book**
|
||||
- $19 — Early Bird eBook (first 200 backers)
|
||||
- $25 — eBook and backer-only updates
|
||||
- $47 — eBook and 12 months of the AiBook.fun library (featured)
|
||||
- $55 — signed paperback and eBook *(placeholder price)*
|
||||
- Add-ons: signed paperback; Collector's Bundle (bookplate + chapter-notes PDF) for a paperback; gift year of AiBook.fun
|
||||
|
||||
**Build it yourself or with us**
|
||||
- $1,000 — DIY: starter pack on WeOwn Cloud, run it yourself, no support of any kind
|
||||
- $2,000 — Launch: onboarding, starter agent fleet, first implementation cycle, 3 months AOP.biz service, Dec 2026 cohort (no Retreat seat)
|
||||
- $5,000 — Growth: everything in Launch + deeper integration, more agents, ongoing support, SharedBrain, workflow/automation layer, **and a Retreat seat**; closes Tue 20 Oct 2026
|
||||
- After the pledge (separate, optional): $988/mo service from Apr 2027; $200/mo WeOwn Cloud hosting; cohort attendance ≥50%
|
||||
|
||||
**In person**
|
||||
- Burned Out Advisor Retreat, 4–6 Nov 2026 · 369 seats · closes Tue 20 Oct 2026 · price **OWNER-PENDING** · seat + signed paperback + eBook + 12 months AiBook.fun
|
||||
|
||||
### H4. Risks and challenges (paste)
|
||||
|
||||
Use the guide's §2.4 text. It covers: printing and shipping costs; writing with several authors; the Retreat taking place as the campaign ends (Retreat reward and Growth bundle close **Tue 20 Oct 2026**); AOP.biz bundles delivered over several months (separate agreements are not charged through Kickstarter); the online library; fast-changing AI tools; team time; refunds (OWNER-PENDING).
|
||||
|
||||
### H5. Use of AI (paste)
|
||||
|
||||
Use the guide's §2.5 text (writing support, workflow examples, AOP.biz bundles, campaign images). The story images were built as HTML/CSS and rendered with headless Chrome; no AI image tools were used.
|
||||
|
||||
### H6. FAQ (paste after launch)
|
||||
|
||||
Use the guide's §2.10 (twenty-two entries). It includes: what the three bundles contain; that the $2,000 Launch bundle has no Retreat seat; **why the Growth bundle and the Retreat close on 20 October**; **whether anything is charged after the pledge** (no, not through Kickstarter; the $200/mo hosting and $988/mo service are separate, optional agreements); what the cohort asks (≥50% weekly attendance, agreed at registration).
|
||||
|
||||
### H7. How to help
|
||||
|
||||
1. Back the project at the level that suits you.
|
||||
2. Share it with two advisors who would use it.
|
||||
3. Follow our progress at aibook.fun between now and delivery.
|
||||
|
||||
---
|
||||
|
||||
## I. Payment / Stripe (OWNER-ONLY checklist)
|
||||
|
||||
- [ ] Raise funds as a business or individual (hard to change later)
|
||||
- [ ] US legal entity name, address, and EIN exactly as on tax documents
|
||||
- [ ] Representative (owner/executive) with government ID
|
||||
- [ ] Every beneficial owner with 25% or more
|
||||
- [ ] Website https://aibook.fun or short product description
|
||||
- [ ] US checking account in the same legal name
|
||||
- [ ] Backup Visa / Mastercard / Amex (not Discover)
|
||||
- [ ] Stripe status = verified (allow multi-day lag). Nigeria is not a creator country.
|
||||
|
||||
---
|
||||
|
||||
## J. Submit-for-review checklist
|
||||
|
||||
- [ ] Basics complete (title, subtitle, creator name, image, goal, fixed end date, location, category)
|
||||
- [ ] Story complete (16 sections) including **Risks** + **Use of AI**
|
||||
- [ ] Rewards: Tiers 1–3 priced; paperback (Tier 4, and Tier 8's paperback) costed or left out until costed
|
||||
- [ ] Tiers 7 and 8 set to close **Tue 20 Oct 2026**; limits so Retreat seats cannot exceed 369
|
||||
- [ ] Tier 8 has a real price (OWNER-PENDING) or is left out until it has one
|
||||
- [ ] Bundle descriptions state the separate agreements; no recurring charge inside any reward
|
||||
- [ ] Name the AOP.biz bundles lead on the page and in People
|
||||
- [ ] No Academy tier at launch
|
||||
- [ ] Every field checked against the public copy scrub list in the guide, Appendix C (plain factual sentences; no slogans; "Cloud" never on book tiers; no income claims)
|
||||
- [ ] Payment verification started / completed
|
||||
- [ ] Preferences: shipping via Pledge Manager (or rates at pledge)
|
||||
- [ ] Funding tab shows $5,000
|
||||
- [ ] Go/no-go Thu 1 Oct, 6:00 PM ET (11:00 PM WAT); if not approved, slip to **9 Oct → 11 Nov** and decide the Retreat/Growth plan
|
||||
- [ ] Launch day: manually click **Launch project** at 6:00 AM ET (11:00 AM WAT)
|
||||
|
||||
---
|
||||
|
||||
## K. Still OWNER-PENDING / OWNER-ONLY
|
||||
|
||||
1. Kickstarter login + entity country confirmation (Nigeria is not a creator country).
|
||||
2. Stripe identity, tax, bank, card.
|
||||
3. **Retreat price** (do not invent) and **Retreat venue** (conflict: GUIDE-436 TradeWinds Resort, St. Pete Beach vs retired "St. Pete" label).
|
||||
4. Whether Growth-bundle Retreat seats count toward the 369, and each tier's limit.
|
||||
5. **$200/mo WeOwn Cloud hosting start date**; what happens to a DIY instance if the backer does not sign up; DIY provisioning month.
|
||||
6. Who delivers the AOP.biz bundles (named person/collaborator).
|
||||
7. Bundle quantity limits; consequence of missing 50% cohort attendance; bundle refund terms.
|
||||
8. Final paperback price, add-on prices, Collector's Bundle signers and limit, shipping countries.
|
||||
9. Retreat inclusions, agenda, transfer/refund terms, CE credit; rule if the campaign does not fund.
|
||||
10. Final author roster, headshots, cover confirmation, sample workflow URL, contact email.
|
||||
11. Academy price, dates, seats, and delivery (for the later update).
|
||||
|
||||
---
|
||||
|
||||
## L. Next actions for Product Lead / owner
|
||||
|
||||
1. Owner supplies the OWNER-PENDING items in K, starting with the Retreat price and venue, the bundle lead, and the DIY hosting start date.
|
||||
2. Paste this pack and the guide's text into the Kickstarter **draft** on the verified account; create the 9 items, 8 tiers, and 3 add-ons.
|
||||
3. Upload the story images from `story-images/` (see its README for order and alt text).
|
||||
4. Submit for review by **Mon 28 Sep** at the latest; start or confirm Stripe verification now.
|
||||
|
After Width: | Height: | Size: 221 KiB |
|
After Width: | Height: | Size: 217 KiB |
|
After Width: | Height: | Size: 218 KiB |
|
After Width: | Height: | Size: 130 KiB |
|
After Width: | Height: | Size: 219 KiB |
|
After Width: | Height: | Size: 65 KiB |
|
After Width: | Height: | Size: 218 KiB |
|
After Width: | Height: | Size: 168 KiB |
|
After Width: | Height: | Size: 120 KiB |
|
After Width: | Height: | Size: 219 KiB |
|
After Width: | Height: | Size: 283 KiB |
|
After Width: | Height: | Size: 33 KiB |
|
After Width: | Height: | Size: 224 KiB |
|
After Width: | Height: | Size: 338 KiB |
|
After Width: | Height: | Size: 309 KiB |
|
After Width: | Height: | Size: 223 KiB |
|
After Width: | Height: | Size: 257 KiB |
|
After Width: | Height: | Size: 224 KiB |
|
After Width: | Height: | Size: 319 KiB |
|
After Width: | Height: | Size: 222 KiB |
|
After Width: | Height: | Size: 126 KiB |
|
After Width: | Height: | Size: 221 KiB |
|
After Width: | Height: | Size: 70 KiB |
|
After Width: | Height: | Size: 82 KiB |
|
After Width: | Height: | Size: 95 KiB |
|
After Width: | Height: | Size: 94 KiB |
|
After Width: | Height: | Size: 214 KiB |
|
After Width: | Height: | Size: 200 KiB |
|
After Width: | Height: | Size: 221 KiB |
|
After Width: | Height: | Size: 132 KiB |
|
After Width: | Height: | Size: 220 KiB |
|
After Width: | Height: | Size: 106 KiB |
|
After Width: | Height: | Size: 218 KiB |
|
After Width: | Height: | Size: 185 KiB |
|
After Width: | Height: | Size: 39 KiB |
|
After Width: | Height: | Size: 220 KiB |
|
After Width: | Height: | Size: 218 KiB |
@@ -0,0 +1,93 @@
|
||||
# We Own AI: Kickstarter story images
|
||||
|
||||
All graphics for the Story tab of the We Own AI — The New American Dream campaign, built from the v2.1 campaign guide (`ks-research/kickstarter-campaign-guide.md`, section 2.3 Story and Part 3.1 assets). AOP.biz bundle contents come from GUIDE-436 (`WeOwnAi/s004_fedarch/_GUIDES_/GUIDE-436.md`).
|
||||
|
||||
**Updated 27 September 2026:** the rewards are now three sections: The book, Build it yourself or with us (AOP.biz bundles), and In person (the Burned Out Advisor Retreat). Sections 7 to 9 are now The book and AiBook.fun, Build it yourself or with us, and In person: the Retreat. The Academy is held out of launch, so its header, map, and site cards are no longer in the set (their source stays in `build.py` behind `ACADEMY_IN_LAUNCH = False`). New: `08b-bundle-comparison.png`. Changed: 06b, 06c, 11b (vertical timeline with the 20 October cutoff), 14b (AOP.biz bundles lead instead of Academy lead). Renamed without other changes: the AiBook.fun device mockup is now `07b` (was 09b).
|
||||
|
||||
- Kickstarter shows story images about 680 px wide. Every file here is exported at 1360 px wide (2x) as PNG, well under 5 MB.
|
||||
- Workflow from the guide: add each section title as a Heading in the Story editor, insert that section's header image under it, paste the text, then add the section's other images where they fit.
|
||||
- **Book cover:** the cover is the one already designed for the landing page: the 3D book in `marketing-site/components/Book3D.jsx` (styles `.book3d*` in `marketing-site/styles/globals.css`, belly band `marketing-site/public/american-dream-banner.webp`). `src/render_cover.py` screenshots it exactly as it appears on https://aibook.fun, in its resting pose, and saves `src/assets-gen/cover-3d.png` (3D, transparent background) and `cover-flat.png` (front face only). Nothing about it was redesigned. **Note:** the landing cover reads "The Field Guide / Responsible Agentic AI / Tested workflows you can actually run / AiBook.fun" with an "American Dream" band. It does not say "We Own AI". If the campaign title should be on the cover, update Book3D.jsx first and re-render.
|
||||
- **Real screenshots:** 05b and 07b are screenshots of the live site (https://aibook.fun/read/recipe/RE-01 and https://aibook.fun/read/real-estate), taken by `src/render_screens.py`.
|
||||
- Style: the AiBook.fun field-guide system from `marketing-site/styles/globals.css` (paper `#fcfbf8`/`#f6f4ee`, pine `#1c5d4c`/`#12463a`, amber `#b4791f`; Fraunces, Hanken Grotesk, JetBrains Mono). The compass mark comes from `Book3D.jsx`. Emoji in headers use Noto Color Emoji and match the guide's section headings.
|
||||
- Everything was built as HTML/CSS and rendered with headless Chrome. **No AI-generated imagery is used.** For Kickstarter's Use of AI section: none of these images were made with AI image tools.
|
||||
- Files marked **PLACEHOLDER** have empty frames for photos (or names) the owner has to supply. Don't upload them until they've been re-rendered with the real files.
|
||||
|
||||
`contact-sheet.png` shows every image in order.
|
||||
|
||||
## Files
|
||||
|
||||
| File | Story section | Size (px) | What it shows | Suggested alt text |
|
||||
|---|---|---|---|---|
|
||||
| 01-header-welcome.png | 1 Welcome | 1360 × 300 | Section header | Welcome |
|
||||
| 01b-welcome-cover-icons.png | 1 Welcome | 1360 × 1066 | "Welcome" banner with the landing-page book cover (3D, captioned "Cover mockup"), the title, publisher, and three icons: Multi-author field book, Tested AI workflows, Library updated often | Book cover with three features: multi-author field book, tested AI workflows, library updated often |
|
||||
| 02-header-why-this-book.png | 2 Why this book | 1360 × 300 | Section header | Why this book |
|
||||
| 02b-why-this-book-cards.png | 2 Why this book | 1360 × 1164 | 2×2 cards: pile of newsletters (Too much noise), padlock on a software window (Processes you don't control), clock at 11 PM (No time to learn), empty client chair (Clients are changing), each with the guide's sentence | Four problems advisors face: too much noise, processes you don't control, no time to learn, clients are changing |
|
||||
| 03-header-who-its-for.png | 3 Who it's for | 1360 × 300 | Section header | Who it's for |
|
||||
| 03b-audience-cards.png | 3 Who it's for | 1360 × 912 | Two audience cards (Accounting advisors: Exit to Client; Financial advisors: CKA® and CEPA® focus) and a smaller card for other professionals who advise clients | Written mainly for accounting advisors (Exit to Client) and financial advisors (CKA and CEPA focus), and also for other professionals who advise clients |
|
||||
| 04-header-whats-inside.png | 4 What's inside | 1360 × 300 | Section header | What's inside |
|
||||
| 04b-workflow-recipe-diagram.png | 4 What's inside | 1360 × 1476 | Diagram of one workflow page with numbered callouts for the 8 parts of the recipe | Every workflow has eight parts: problem, who runs it, setup, safeguards, steps, evidence, try it, and costs, author and sources |
|
||||
| 04c-chapter-tiles.png | 4 What's inside | 1360 × 914 | "The founding library": the six chapters and one-line descriptions exactly as published on the landing page (`marketing-site/components/Contents.jsx`) | Chapters: Real Estate, Financial Advisors, Fractional C-Suite, Higher Education, Communities, Technology |
|
||||
| 05-header-try-one-workflow.png | 5 Try one workflow | 1360 × 300 | Section header | Try one workflow |
|
||||
| 05b-sample-workflow-try-it.png | 5 Try one workflow | 1360 × 1722 | Real screenshots of workflow RE-01 at aibook.fun/read/recipe/RE-01 in a browser frame: the header, title and kit (who runs it, tools, files, model, time, cost, output), then its Try-it. A strip marks the parts left out (Problem to Evidence). | Sample workflow RE-01: draft a property-market brief with an AI agent without leaking client data, with a 15-minute Try-it |
|
||||
| 05c-button-try-the-workflow.png | 5 Try one workflow | 1360 × 298 | Button image. In the editor, link it to https://aibook.fun/read/recipe/RE-01 (live now; the site currently labels it a "Reading demo"). | Try the sample workflow |
|
||||
| 06-header-three-ways-to-back.png | 6 Three ways to back | 1360 × 300 | Section header | Three ways to back |
|
||||
| 06b-three-ways-to-back.png | 6 Three ways to back | 1360 × 1784 | Three columns. The book: $19, $25, $47 (featured), and the signed paperback with "Price on the reward" and the landing cover; delivery months. Build it yourself or with us: $1,000 DIY, $2,000 Launch, $5,000 Growth (with "Closes 20 Oct 2026"), and a note that the $988 a month service and $200 a month hosting are separate, optional agreements and Kickstarter charges the pledge once. In person: the Retreat, 369 seats, seat + signed paperback + eBook + 12 months of AiBook.fun, 4–6 November 2026, closes 20 Oct 2026, "Price on the reward". No Retreat price or venue is shown. | Three ways to back: the book from $19, AOP.biz bundles at $1,000, $2,000 and $5,000, and the Burned Out Advisor Retreat |
|
||||
| 06c-three-ways-to-back-no-paperback.png | 6 Three ways to back | 1360 × 1710 | Same image without the paperback tier in The book column (the Retreat still lists its signed paperback), for use if the paperback reward is left out at launch | Same as above |
|
||||
| 07-header-the-book-and-aibook-fun.png | 7 The book and AiBook.fun | 1360 × 300 | Section header | The book and AiBook.fun |
|
||||
| 07b-aibook-fun-device-mockup.png | 7 The book and AiBook.fun | 1360 × 1188 | Laptop and phone frames with real screenshots of the live AiBook.fun reader (https://aibook.fun/read/real-estate), with callouts for Chapter essay, Workflow, Try-it (about 15 minutes), and Last updated. Unchanged from the old 09b. | Mockup of the AiBook.fun reader on a laptop and phone, showing a chapter essay, a workflow, its Try-it and the last-updated date |
|
||||
| 08-header-build-it-yourself-or-with-us.png | 8 Build it yourself or with us | 1360 × 300 | Section header | Build it yourself or with us |
|
||||
| 08b-bundle-comparison.png | 8 Build it yourself or with us | 1360 × 2588 | Comparison table of the AOP.biz bundles ($1,000 DIY on WeOwn Cloud with no support of any kind; $2,000 Launch; $5,000 Growth, highlighted, with a Retreat seat): the starter pack, what our team sets up, what Growth adds, the Retreat seat (Growth only), and the pledge window (Growth closes 20 Oct 2026). Below: the separate, optional agreements after the pledge ($200 a month hosting; $988 a month service from April 2027; 50% cohort attendance). Contents from GUIDE-436. | AOP.biz bundles compared: DIY $1,000, Launch $2,000, and Growth $5,000, which adds a Retreat seat |
|
||||
| 09-header-in-person-the-retreat.png | 9 In person: the Retreat | 1360 × 300 | Section header | In person: the Retreat |
|
||||
| 09b-retreat-venue-PLACEHOLDER.png | 9 In person: the Retreat | 1360 × 765 | Venue photo frame with "Burned Out Advisor Retreat, 4 to 6 November 2026", "Pledges close 20 October 2026", and a "369 seats" badge. No venue name (pending). | Burned Out Advisor Retreat, 4 to 6 November 2026, 369 seats, pledges close 20 October 2026 |
|
||||
| 10-header-stretch-goals.png | 10 Stretch goals | 1360 × 300 | Section header | Stretch goals |
|
||||
| 10b-stretch-goals-locked.png | 10 Stretch goals | 1360 × 500 | Bar with padlocks: $15,000 Bonus chapter, $35,000 Audiobook sample, $54,000 Live Q&A replay pack; goal $5,000 | Stretch goals: $15,000 bonus chapter, $35,000 audiobook sample, $54,000 live Q&A replay pack |
|
||||
| 10c-stretch-goals-15k-unlocked.png | 10 Stretch goals | 1360 × 500 | Same, with $15,000 unlocked | Stretch goal $15,000 unlocked: bonus chapter |
|
||||
| 10d-stretch-goals-35k-unlocked.png | 10 Stretch goals | 1360 × 500 | Same, with $15,000 and $35,000 unlocked | Stretch goals $15,000 and $35,000 unlocked |
|
||||
| 10e-stretch-goals-54k-unlocked.png | 10 Stretch goals | 1360 × 500 | Same, with all three unlocked | All three stretch goals unlocked |
|
||||
| 11-header-timeline.png | 11 Timeline | 1360 × 300 | Section header | Timeline |
|
||||
| 11b-timeline.png | 11 Timeline | 1360 × 1214 | Vertical path with eight numbered stops from the guide: opens 2 Oct; Retreat and Growth close 20 Oct (amber); ends 4 Nov with the Retreat 4–6 Nov; AiBook.fun access mid-November; December cohort; January eBook; January to March AOP.biz service; February paperbacks | Timeline from launch on 2 October 2026, with the 20 October cutoff, to signed paperbacks in February 2027 |
|
||||
| 12-header-shipping-and-delivery.png | 12 Shipping and delivery | 1360 × 300 | Section header | Shipping and delivery |
|
||||
| 12b-shipping-and-delivery-lanes.png | 12 Shipping and delivery | 1360 × 1154 | Two lanes. Digital: email, library access within about 14 days, eBook January 2027. Print: Pledge Manager survey (address, shipping, taxes), printing, signing January 2027, shipping February 2027. The eBook step and the paperback lane show the landing cover. No countries or rates. | Digital rewards arrive by email; signed paperbacks go through the Pledge Manager survey, printing, signing and shipping |
|
||||
| 13-header-early-readers.png | 13 Early readers | 1360 × 300 | Section header | Early readers |
|
||||
| 13b-early-reader-quotes-PLACEHOLDER.png | 13 Early readers | 1360 × 908 | Three quote-card templates (photo, quote, name, role). Use only quotes that readers have approved in writing. | Quotes from early readers |
|
||||
| 14-header-authors-and-team.png | 14 The authors and team | 1360 × 300 | Section header | The authors and team |
|
||||
| 14b-authors-and-team-PLACEHOLDER.png | 14 The authors and team | 1360 × 1442 | Three author cards for the co-authors the landing page lists as confirmed (`Authors.jsx`): Real Estate & Finance, Fractional C-Suite, Technology & RAAI. Below them, team cards with roles from the guide, including the AOP.biz bundles lead. Names and photos are still needed because the site does not publish them. | The authors and the team behind We Own AI |
|
||||
| 14c-author-headshot-800x800-PLACEHOLDER.png | 14 The authors and team | 800 × 800 | Neutral 800 × 800 headshot frame for any author without a photo | (placeholder, do not upload) |
|
||||
| 15-header-special-thanks.png | 15 Special thanks | 1360 × 300 | Section header | Special thanks |
|
||||
| 16-header-how-to-help.png | 16 How to help | 1360 × 300 | Section header | How to help |
|
||||
|
||||
## Photos the owner has to supply
|
||||
|
||||
No real people or venues were generated. These frames wait for real files:
|
||||
|
||||
| Photo | Needed for | Size |
|
||||
|---|---|---|
|
||||
| Retreat venue photo (venue still pending) | 09b | Landscape, at least 1360 × 765 |
|
||||
| Early reader photos, with written permission | 13b | At least 400 × 400, square |
|
||||
| Author headshots (and names) for the three confirmed co-authors | 14b (and on their own as story images) | 800 × 800, square |
|
||||
| Team headshots: @THY, @LFG, @CEO, @GTM, Osinachi Patrick, AOP.biz bundles lead | 14b | 800 × 800, square |
|
||||
|
||||
## Waiting on owner decisions (re-render when settled)
|
||||
|
||||
- **Cover title:** the landing cover says "Responsible Agentic AI", not "We Own AI" (see above).
|
||||
- **Chapter lead authors:** 04c follows the landing page's founding library. The landing page lists Higher Education and Communities co-authors as "To be announced".
|
||||
- **Public sample workflow:** 05b shows RE-01 as it is live on AiBook.fun. If a different workflow becomes the public sample, re-run `render_screens.py` with its URL and relink 05c.
|
||||
- **Paperback price:** 06b says "Price on the reward". Use 06c if the paperback is left out at launch.
|
||||
- **Retreat price and venue:** 06b shows "Price on the reward" and no venue; 09b has no venue name. GUIDE-436 names TradeWinds Resort, St. Pete Beach, but the Kickstarter pack retired the "St. Pete" label, so the venue waits for the owner.
|
||||
- **DIY hosting start date:** 06b and 08b give the $200 a month WeOwn Cloud hosting without a start date, on purpose.
|
||||
- **Academy (held out of launch):** it will be announced in a campaign update once dates and prices exist. The map and site-card source is kept in `build.py` (Academy section). To bring it back, set `ACADEMY_IN_LAUNCH = True`, give it story numbers, add a fourth column to `three_ways()` (the grid adjusts without a CSS change), add its timeline stop, and re-run.
|
||||
- **Retreat agenda:** the guide asks for a three-day agenda graphic "once the agenda exists". It doesn't exist yet, so that graphic has not been made.
|
||||
- **Names for the author and team cards, and approval to list Osinachi Patrick.**
|
||||
- **Tier names on the landing page:** `marketing-site/components/Tiers.jsx` still shows older tiers ($10 Supporter / $47 per year / Founding Sponsor). The story images follow the v2 campaign guide instead.
|
||||
|
||||
## How to re-render
|
||||
|
||||
```
|
||||
cd src
|
||||
python render_cover.py # landing-page book cover from https://aibook.fun -> assets-gen/cover-3d.png, cover-flat.png
|
||||
python render_screens.py # live screenshots for 05b and 07b from https://aibook.fun
|
||||
python build.py # all story images -> ../ ; pass a regex to render a subset, e.g. python build.py '^06'
|
||||
python contact_sheet.py
|
||||
```
|
||||
|
||||
Requires Python with `playwright` and `pillow`, a Chrome/Chromium binary (the path is set in the scripts; render_cover.py uses SwiftShader WebGL flags so the 3D faces sort correctly), and the Fraunces, Hanken Grotesk, JetBrains Mono, and Noto Color Emoji fonts installed. Text and data live at the top of each section in `build.py`: QUOTES, TEAM, CHAPTERS, STOPS, GOALS, BUNDLE_COLS, BUNDLE_ROWS, and so on. Photos go in `src/assets/` (see `src/assets/README.md`). `make_map.py` builds the US outline from public-domain US Census-derived state boundaries.
|
||||
|
After Width: | Height: | Size: 2.7 MiB |
|
After Width: | Height: | Size: 1.5 MiB |
|
After Width: | Height: | Size: 1.1 MiB |
|
After Width: | Height: | Size: 90 KiB |
|
After Width: | Height: | Size: 66 KiB |
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"url": "https://aibook.fun/read/recipe/RE-01",
|
||||
"top": {
|
||||
"x": 0,
|
||||
"y": 223.203125,
|
||||
"width": 616,
|
||||
"height": 386.96875
|
||||
},
|
||||
"tryit": {
|
||||
"x": 0,
|
||||
"y": 2002.140625,
|
||||
"width": 616,
|
||||
"height": 287.125
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 277 KiB |
|
After Width: | Height: | Size: 238 KiB |
@@ -0,0 +1,34 @@
|
||||
{
|
||||
"laptop": {
|
||||
"vw": 1120,
|
||||
"vh": 700,
|
||||
"essay": [
|
||||
328,
|
||||
95.40625,
|
||||
198.921875,
|
||||
29
|
||||
],
|
||||
"workflow": [
|
||||
357,
|
||||
364.28125,
|
||||
200.109375,
|
||||
37.625
|
||||
]
|
||||
},
|
||||
"phone": {
|
||||
"vw": 390,
|
||||
"vh": 844,
|
||||
"tryit": [
|
||||
61,
|
||||
115.28125,
|
||||
48.3125,
|
||||
15
|
||||
],
|
||||
"updated": [
|
||||
61,
|
||||
794.046875,
|
||||
170.765625,
|
||||
19
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"w": 1000,
|
||||
"h": 620,
|
||||
"pins": {
|
||||
"orlando": [
|
||||
820.8,
|
||||
532.8
|
||||
],
|
||||
"denver": [
|
||||
345.5,
|
||||
276.4
|
||||
],
|
||||
"villapark": [
|
||||
653.8,
|
||||
225.8
|
||||
]
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 28 KiB |
@@ -0,0 +1,14 @@
|
||||
# Owner-supplied photos
|
||||
|
||||
Drop real photos here (jpg, png or webp) using these base names, then run `python build.py` from `src/`.
|
||||
Images whose slots are filled lose the `-PLACEHOLDER` suffix.
|
||||
|
||||
| File name (any of .jpg/.png/.webp) | Used in | Minimum size |
|
||||
|---|---|---|
|
||||
| retreat-venue | 09b Retreat | 1360 × 765, landscape |
|
||||
| site-orlando, site-north-denver, site-villa-park | Academy site cards (held out of launch; used only when `ACADEMY_IN_LAUNCH = True`) | 800 × 600 each, landscape |
|
||||
| reader-1, reader-2, reader-3 | 13b early reader quotes | 400 × 400, square |
|
||||
| author-1, author-2, author-3 | 14b authors (Real Estate & Finance, Fractional C-Suite, Technology & RAAI) | 800 × 800, square |
|
||||
| team-thy, team-lfg, team-ceo, team-gtm, team-osinachi-patrick, team-aop-lead | 14b team | 800 × 800, square |
|
||||
|
||||
The book cover is not a photo slot: it is rendered from the landing page's `Book3D.jsx` by `render_cover.py` into `src/assets-gen/`.
|
||||
@@ -0,0 +1,742 @@
|
||||
"""Build and render the We Own AI Kickstarter story images.
|
||||
|
||||
Usage: python build.py (render everything into ../)
|
||||
Owner photos: drop files into src/assets/ using the names in SLOT_FILES (jpg/png/webp) and re-run;
|
||||
images whose photo slots are still empty get a -PLACEHOLDER suffix.
|
||||
Sources of truth: ks-research/kickstarter-campaign-guide.md (v2.1), Story section and Part 3.1; GUIDE-436 for the AOP.biz bundles."""
|
||||
import asyncio, json, math, pathlib, re, sys
|
||||
from icons import ICONS, ILLUS, MARK, icon
|
||||
HERE = pathlib.Path(__file__).parent
|
||||
OUT = HERE.parent
|
||||
PAGES = HERE / 'pages'
|
||||
PAGES.mkdir(exist_ok=True)
|
||||
MAP = json.loads((HERE / 'assets-gen' / 'us-map.json').read_text())
|
||||
MAP_SVG = (HERE / 'assets-gen' / 'us-map.svg').read_text()
|
||||
SCREENS = json.loads((HERE / 'assets-gen' / 'screens.json').read_text())
|
||||
|
||||
TITLE = 'We Own AI — The New American Dream'
|
||||
|
||||
HEAD = """<!doctype html><html lang="en"><head><meta charset="utf-8">
|
||||
{extra_css}<link rel="stylesheet" href="../styles.css"><style>{css}</style></head><body>{body}
|
||||
<script>
|
||||
window.__ready = (async () => {{
|
||||
let empty = 0;
|
||||
for (const s of document.querySelectorAll('.slot[data-src]')) {{
|
||||
let ok = false;
|
||||
for (const ext of ['jpg', 'jpeg', 'png', 'webp']) {{
|
||||
const url = s.dataset.src + '.' + ext;
|
||||
ok = await new Promise(r => {{ const i = new Image(); i.onload = () => r(true); i.onerror = () => r(false); i.src = url; }});
|
||||
if (ok) {{ s.style.backgroundImage = 'url("' + url + '")'; s.classList.add('filled'); break; }}
|
||||
}}
|
||||
if (!ok) empty++;
|
||||
}}
|
||||
await document.fonts.ready;
|
||||
for (const el of document.querySelectorAll('[data-fit]')) {{
|
||||
let fs = parseFloat(getComputedStyle(el).fontSize);
|
||||
const max = el.dataset.fit ? parseFloat(el.dataset.fit) : el.parentElement.clientWidth;
|
||||
while (el.scrollWidth > max && fs > 10) {{ fs -= 0.5; el.style.fontSize = fs + 'px'; }}
|
||||
}}
|
||||
if (window.afterLayout) await window.afterLayout();
|
||||
return empty;
|
||||
}})();
|
||||
</script></body></html>"""
|
||||
|
||||
def slot(src, label, size, cls='', style=''):
|
||||
return (f'<div class="slot {cls}" data-src="../assets/{src}" style="{style}"><div class="ph">{ICONS["camera"]}'
|
||||
f'<b>{label}</b><small>{size}</small></div></div>')
|
||||
|
||||
COVER_3D = '../assets-gen/cover-3d.png' # rendered from the landing page (render_cover.py)
|
||||
COVER_FLAT = '../assets-gen/cover-flat.png'
|
||||
pages = [] # dicts: name, body, css, sel, w, h(optional), dpr
|
||||
def page(name, body, css='', w=680, h=None, extra_css='', px_h=None):
|
||||
pages.append(dict(name=name, body=body, css=css, w=w, h=h, extra_css=extra_css, px_h=px_h))
|
||||
|
||||
# ---------------------------------------------------------------- headers (1360 x 300)
|
||||
HEADERS = [
|
||||
('01', 'welcome', '👋', 'Welcome'), ('02', 'why-this-book', '❤️', 'Why this book'),
|
||||
('03', 'who-its-for', '🎯', 'Who it’s for'), ('04', 'whats-inside', '📖', 'What’s inside'),
|
||||
('05', 'try-one-workflow', '🧪', 'Try one workflow'), ('06', 'three-ways-to-back', '🧭', 'Three ways to back'),
|
||||
('07', 'the-book-and-aibook-fun', '📚', 'The book and AiBook.fun'), ('08', 'build-it-yourself-or-with-us', '🛠️', 'Build it yourself or with us'),
|
||||
('09', 'in-person-the-retreat', '🏕️', 'In person: the Retreat'), ('10', 'stretch-goals', '🎁', 'Stretch goals'),
|
||||
('11', 'timeline', '⏳', 'Timeline'), ('12', 'shipping-and-delivery', '📦', 'Shipping and delivery'),
|
||||
('13', 'early-readers', '👀', 'Early readers'), ('14', 'authors-and-team', '✍️', 'The authors and team'),
|
||||
('15', 'special-thanks', '🙏', 'Special thanks'), ('16', 'how-to-help', '📣', 'How to help'),
|
||||
]
|
||||
def header(num, slug, emoji, title):
|
||||
body = (f'<div class="hdr" id="shot"><div class="tabs"><span></span><span></span><span></span><span></span><span></span></div>'
|
||||
f'<div class="mark">{MARK}</div><div class="badge"><span class="emoji">{emoji}</span></div>'
|
||||
f'<div style="min-width:0;flex:1"><div class="kicker">{TITLE}</div><h1 data-fit>{title}</h1></div><div class="rule"></div></div>')
|
||||
return body
|
||||
HDR = {n: (f'{n}-header-{s}', header(n, s, e, t)) for n, s, e, t in HEADERS}
|
||||
# The Academy (AiCoach + AOP.biz BootCamp) is held out of the launch rewards; it will be announced in a campaign update
|
||||
# once dates and prices exist (guide Appendix E). Its header, map and site cards are kept below and render only when
|
||||
# ACADEMY_IN_LAUNCH is True (they would then need a slot in the story numbering).
|
||||
ACADEMY_IN_LAUNCH = False
|
||||
HDR['academy'] = ('A-header-the-academy', header('A', 'the-academy', '🎓', 'The Academy'))
|
||||
def add_header(n):
|
||||
name, body = HDR[n]; page(name, body, w=680, h=150)
|
||||
|
||||
# ---------------------------------------------------------------- 01 welcome
|
||||
add_header('01')
|
||||
page('01b-welcome-cover-icons', f'''
|
||||
<div class="canvas" id="shot">
|
||||
<div class="wel">
|
||||
<figure class="bookwrap"><img src="{COVER_3D}" alt=""><figcaption>Cover mockup</figcaption></figure>
|
||||
<div class="wtxt">
|
||||
<h2>Welcome</h2>
|
||||
<p class="t">{TITLE}</p>
|
||||
<p class="s">A field book for advisors who want to use AI in their practice in ways they control.</p>
|
||||
<p class="pub">BurnedOut Media / WeOwnNet</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="trio">
|
||||
<div>{icon("authors", "ico big")}<p>Multi-author field book</p></div>
|
||||
<div>{icon("tested", "ico big")}<p>Tested AI workflows</p></div>
|
||||
<div>{icon("updated", "ico big")}<p>Library updated often</p></div>
|
||||
</div>
|
||||
</div>''', css='''
|
||||
.wel{display:flex;gap:30px;align-items:center;padding:0 6px 22px}
|
||||
.bookwrap{flex:none;margin:0;width:196px;text-align:center}
|
||||
.bookwrap img{width:196px;display:block}
|
||||
.bookwrap figcaption{font-family:var(--mono);font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);margin-top:-14px}
|
||||
.wtxt h2{font-family:var(--display);font-weight:900;font-size:50px;letter-spacing:-.03em;line-height:1;color:var(--pine-deep)}
|
||||
.wtxt .t{font-family:var(--display);font-weight:600;font-size:22px;letter-spacing:-.02em;line-height:1.2;margin:14px 0 12px}
|
||||
.wtxt .s{font-size:16px;line-height:1.5;color:var(--muted);max-width:25rem}
|
||||
.wtxt .pub{font-family:var(--mono);font-size:13px;letter-spacing:.06em;color:var(--pine);margin-top:16px}
|
||||
.trio{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
|
||||
.trio>div{background:var(--card);border:1px solid var(--line);border-radius:16px;padding:20px 14px 18px;text-align:center;box-shadow:var(--sh-sm)}
|
||||
.ico.big{width:58px;height:58px;padding:13px;border-radius:999px;background:var(--pine-wash);border:1px solid var(--pine-tint);display:block;margin:0 auto 12px}
|
||||
.trio p{font-weight:700;font-size:16px;line-height:1.3}
|
||||
''')
|
||||
|
||||
# ---------------------------------------------------------------- 02 why this book
|
||||
add_header('02')
|
||||
WHY = [('newsletters', 'Too much noise', 'Each week brings a new tool and a new prediction, and very little of it fits a real client file.'),
|
||||
('lockedwindow', 'Processes you don’t control', 'When your process lives inside a vendor’s product, a price change or a feature change can undo it.'),
|
||||
('clock11', 'No time to learn', 'The job already takes up the evenings, and learning AI on top of it feels like a second job.'),
|
||||
('chair', 'Clients are changing', 'Firms and clients are changing how they work faster than most playbooks are updated.')]
|
||||
page('02b-why-this-book-cards', '<div class="canvas" id="shot"><div class="g">' + ''.join(
|
||||
f'<div class="card c"><div class="il">{ILLUS[k]}</div><h3>{t}</h3><p>{d}</p></div>' for k, t, d in WHY) + '</div></div>', css='''
|
||||
.g{display:grid;grid-template-columns:1fr 1fr;gap:14px}
|
||||
.c{padding:20px 22px 22px}
|
||||
.il{width:120px;height:84px;margin:0 0 12px -6px}
|
||||
.c h3{font-family:var(--display);font-weight:600;font-size:21px;letter-spacing:-.02em;line-height:1.15;margin-bottom:8px}
|
||||
.c p{font-size:15px;line-height:1.5;color:var(--muted)}
|
||||
''')
|
||||
|
||||
# ---------------------------------------------------------------- 03 who it's for
|
||||
add_header('03')
|
||||
page('03b-audience-cards', f'''<div class="canvas" id="shot">
|
||||
<p class="spec">Mainly for</p>
|
||||
<div class="two">
|
||||
<div class="card a">{icon("accounting", "ico big")}<h3>Accounting advisors</h3><p class="k">Exit to Client</p></div>
|
||||
<div class="card a">{icon("chart", "ico big")}<h3>Financial advisors</h3><p class="k">CKA® and CEPA® focus</p></div>
|
||||
</div>
|
||||
<p class="spec" style="margin-top:20px">Also for</p>
|
||||
<div class="card b">{icon("briefcase", "ico mid")}<h3>Other professionals who advise clients</h3></div>
|
||||
</div>''', css='''
|
||||
.two{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:12px}
|
||||
.a{padding:24px 24px 26px;border-top:4px solid var(--pine)}
|
||||
.ico.big{width:60px;height:60px;padding:14px;border-radius:14px;background:var(--pine-wash);border:1px solid var(--pine-tint);display:block;margin-bottom:18px}
|
||||
.a h3{font-family:var(--display);font-weight:900;font-size:28px;letter-spacing:-.025em;line-height:1.08}
|
||||
.a .k{font-family:var(--mono);font-size:15px;font-weight:600;letter-spacing:.02em;color:var(--pine);margin-top:10px;background:var(--pine-wash);border:1px solid var(--pine-tint);display:inline-block;padding:5px 12px;border-radius:999px}
|
||||
.b{margin-top:12px;padding:16px 22px;display:flex;align-items:center;gap:16px}
|
||||
.ico.mid{width:44px;height:44px;padding:10px;border-radius:12px;background:var(--paper-2);border:1px solid var(--line);color:var(--muted)}
|
||||
.b h3{font-family:var(--display);font-weight:600;font-size:20px;letter-spacing:-.02em}
|
||||
''')
|
||||
|
||||
# ---------------------------------------------------------------- 04 what's inside
|
||||
add_header('04')
|
||||
RECIPE = [('Problem', 'The problem', 'The real task it solves.'),
|
||||
('Who runs it', 'Who runs it', 'A person, a role, or an AI agent working under a person’s supervision.'),
|
||||
('Setup', 'Setup', 'The tools, sample files, and expected cost.'),
|
||||
('Safeguards', 'Safeguards', 'How to handle client data, where a person must review the work, and what can go wrong. These come before the steps.'),
|
||||
('Steps', 'The steps', 'With the actual output the tools produced.'),
|
||||
('Evidence', 'Evidence', 'What the result looked like when we ran it.'),
|
||||
('Try it', 'Try it', 'A short exercise of about 15 minutes, using sample data.'),
|
||||
('Record', 'Costs, author, and sources', '')]
|
||||
rows = ''
|
||||
for i, (k, t, d) in enumerate(RECIPE, 1):
|
||||
first = ' first' if i == 1 else ''; last = ' last' if i == len(RECIPE) else ''
|
||||
bars = '<i style="width:88%"></i><i style="width:64%"></i>'
|
||||
if k == 'Steps': bars = '<i style="width:80%"></i><span class="term"></span>'
|
||||
if k == 'Try it': bars = '<i style="width:72%"></i><span class="pill"></span>'
|
||||
if k == 'Safeguards': bars = '<span class="gd"></span><span class="gd"></span>'
|
||||
rows += (f'<div class="pc{first}{last}"><span class="k">{k}</span><span class="bars">{bars}</span><b class="n">{i}</b></div>'
|
||||
f'<div class="ln"></div><div class="co"><h4>{t}</h4>' + (f'<p>{d}</p>' if d else '') + '</div>')
|
||||
page('04b-workflow-recipe-diagram', f'''<div class="canvas" id="shot">
|
||||
<p class="spec">Every workflow follows the same recipe</p>
|
||||
<div class="rg">
|
||||
<div class="ptop"><span>Workflow page</span><em>~15 min</em></div><div></div><div></div>
|
||||
{rows}
|
||||
</div></div>''', css='''
|
||||
.rg{display:grid;grid-template-columns:250px 34px 1fr;margin-top:16px;align-items:stretch}
|
||||
.ptop{background:linear-gradient(#fff,var(--paper));border:1px solid var(--line);border-bottom:1px solid var(--line);border-radius:16px 16px 0 0;padding:12px 16px;display:flex;justify-content:space-between;align-items:center}
|
||||
.ptop span{font-family:var(--mono);font-size:12px;color:var(--muted)}
|
||||
.ptop em{font-style:normal;font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--pine);background:var(--pine-wash);border:1px solid var(--pine-tint);padding:3px 9px;border-radius:999px}
|
||||
.pc{background:#fff;border-left:1px solid var(--line);border-right:1px solid var(--line);padding:11px 30px 11px 16px;position:relative;display:flex;flex-direction:column;justify-content:center;gap:7px;border-top:1px dashed var(--line-2)}
|
||||
.pc.first{border-top:none;padding-top:16px}
|
||||
.pc.last{border-bottom:1px solid var(--line);border-radius:0 0 16px 16px;padding-bottom:16px}
|
||||
.pc .k{font-family:var(--mono);font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--pine)}
|
||||
.bars{display:flex;flex-direction:column;gap:5px}
|
||||
.bars i{display:block;height:6px;border-radius:3px;background:#ece6db}
|
||||
.bars .term{display:block;height:20px;border-radius:5px;background:#14110e}
|
||||
.bars .pill{display:block;width:70px;height:14px;border-radius:999px;background:rgba(180,121,31,.14);border:1px solid rgba(180,121,31,.3)}
|
||||
.bars .gd{display:block;height:6px;border-radius:3px;background:linear-gradient(90deg,var(--pine) 0 8px,transparent 8px 14px,#ece6db 14px);width:86%}
|
||||
.pc .n{position:absolute;right:-13px;top:50%;transform:translateY(-50%);width:26px;height:26px;border-radius:999px;background:var(--pine);color:#fff;font-family:var(--mono);font-size:13px;font-weight:600;display:grid;place-items:center;box-shadow:0 0 0 3px var(--paper-2);z-index:2}
|
||||
.ln{position:relative}.ln::before{content:"";position:absolute;left:13px;right:4px;top:50%;border-top:1.5px solid var(--pine);opacity:.5}
|
||||
.co{padding:8px 0 8px 4px;display:flex;flex-direction:column;justify-content:center}
|
||||
.co h4{font-weight:700;font-size:16px;line-height:1.25}
|
||||
.co p{font-size:14px;line-height:1.42;color:var(--muted);margin-top:2px}
|
||||
''')
|
||||
# Published on the landing page: marketing-site/components/Contents.jsx ("The founding library")
|
||||
CHAPTERS = [('Real Estate', 'Market briefs & listings, without leaking client data'),
|
||||
('Financial Advisors', 'Portfolio summaries that stay compliant & reviewed'),
|
||||
('Fractional <span style="white-space:nowrap">C-Suite</span>', 'Board updates & plans with real escalation paths'),
|
||||
('Higher Education', 'Course & research workflows with academic integrity'),
|
||||
('Communities', 'Moderation & programming that respects members'),
|
||||
('Technology', 'Agent patterns, evals & the responsible defaults')]
|
||||
page('04c-chapter-tiles', '<div class="canvas" id="shot"><p class="spec">The founding library</p><div class="tg">' + ''.join(
|
||||
f'<div class="card t"><span class="n">{i:02d}</span><h3>{c}</h3><p>{d}</p></div>' for i, (c, d) in enumerate(CHAPTERS, 1)) + '</div></div>', css='''
|
||||
.tg{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-top:14px}
|
||||
.t{padding:16px 16px 18px;display:flex;flex-direction:column}
|
||||
.t .n{font-family:var(--mono);font-size:13px;color:var(--pine);letter-spacing:.08em}
|
||||
.t h3{font-family:var(--display);font-weight:600;font-size:21px;letter-spacing:-.02em;line-height:1.12;margin:10px 0 6px}
|
||||
.t p{font-size:14px;line-height:1.4;color:var(--muted)}
|
||||
''')
|
||||
|
||||
# ---------------------------------------------------------------- 05 try one workflow
|
||||
add_header('05')
|
||||
page('05b-sample-workflow-try-it', '''<div class="canvas" id="shot">
|
||||
<div class="win">
|
||||
<div class="bar"><i></i><i></i><i></i><span class="url">aibook.fun/read/recipe/RE-01</span></div>
|
||||
<img src="../assets-gen/re01-top.png" alt="">
|
||||
<div class="gap"><span>Problem · Actors · Setup · Safeguards · Method · Evidence</span></div>
|
||||
<img src="../assets-gen/re01-tryit.png" alt="">
|
||||
</div>
|
||||
<p class="foot-note">Screenshots of sample workflow RE-01 at aibook.fun/read/recipe/RE-01</p>
|
||||
</div>''', css='''
|
||||
.win{background:var(--paper);border:1px solid var(--line-2);border-radius:14px;overflow:hidden;box-shadow:var(--sh-lg)}
|
||||
.bar{display:flex;align-items:center;gap:7px;padding:10px 14px;background:#f1eee7;border-bottom:1px solid var(--line)}
|
||||
.bar i{width:11px;height:11px;border-radius:999px;background:#d8d1c4;display:block}
|
||||
.bar .url{margin-left:14px;flex:1;background:#fff;border:1px solid var(--line);border-radius:999px;padding:4px 14px;font-family:var(--mono);font-size:13px;color:var(--muted)}
|
||||
.win img{display:block;width:614px}
|
||||
.gap{padding:10px 0;text-align:center;background:linear-gradient(transparent calc(50% - 1px),var(--line-2) calc(50% - 1px) calc(50% + 1px),transparent calc(50% + 1px))}
|
||||
.gap span{font-family:var(--mono);font-size:12.5px;color:var(--muted);background:var(--paper);padding:2px 10px;letter-spacing:.02em}
|
||||
.foot-note{text-align:center}
|
||||
''')
|
||||
page('05c-button-try-the-workflow', f'''<div class="canvas" id="shot">
|
||||
<div class="cta"><span class="b">Try the sample workflow {ICONS["arrow"]}</span>
|
||||
<p>Free · about 15 minutes · sample data · aibook.fun</p></div></div>''', css='''
|
||||
.canvas{padding:26px 32px 24px}
|
||||
.cta{text-align:center}
|
||||
.b{display:inline-flex;align-items:center;gap:12px;background:var(--pine);color:#f7fbf9;font-weight:700;font-size:24px;letter-spacing:-.01em;border-radius:999px;padding:18px 34px;box-shadow:0 10px 24px -10px rgba(28,93,76,.6)}
|
||||
.b svg{width:24px;height:24px}
|
||||
.cta p{font-family:var(--mono);font-size:14px;color:var(--muted);letter-spacing:.03em;margin-top:14px}
|
||||
''')
|
||||
|
||||
# ---------------------------------------------------------------- 06 three ways to back
|
||||
add_header('06')
|
||||
def three_ways(paperback=True):
|
||||
"""One column per reward section: The book / Build it yourself or with us / In person.
|
||||
`cols` is a list of (html, width) entries; the grid template is built from the list, so adding a column
|
||||
(for example the Academy once it is announced) needs no CSS change."""
|
||||
book_items = [('$19', 'Early Bird eBook', 'First 200 backers', False),
|
||||
('$25', 'eBook and backer-only updates', '', False),
|
||||
('$47', 'eBook and 12 months of the AiBook.fun library', 'Featured', True)]
|
||||
rows = ''.join(f'<li class="{"feat" if f else ""}"><b>{p}</b><span>{t}' + (f'<small>{s}</small>' if s else '') + '</span></li>'
|
||||
for p, t, s, f in book_items)
|
||||
if paperback:
|
||||
rows += f'<li class="pb"><b class="np"><img src="{COVER_3D}" alt=""></b><span>Signed paperback and eBook<small>Price on the reward</small></span></li>'
|
||||
book_deliv = ('<li>Library access: within about 14 days of a successful campaign</li><li>eBook: January 2027</li>'
|
||||
+ ('<li>Signed paperback: February 2027</li>' if paperback else ''))
|
||||
bundles = [('$1,000', 'DIY', 'The starter pack on WeOwn Cloud, to run yourself. No support of any kind.', ''),
|
||||
('$2,000', 'Launch', 'Set up with our team: onboarding and a first implementation cycle, plus three months of AOP.biz service and the December 2026 cohort.', ''),
|
||||
('$5,000', 'Growth', 'Everything in Launch, plus deeper integration, more agents, ongoing support, and a Retreat seat.', 'Closes 20 Oct 2026')]
|
||||
brows = ''.join(f'<li class="{"feat" if tag else ""}"><div class="bt"><b>{p}</b><em>{n}</em></div><span>{d}</span>'
|
||||
+ (f'<i class="tag">{tag}</i>' if tag else '') + '</li>' for p, n, d, tag in bundles)
|
||||
inc = (f'<ul class="inc"><li>{icon("seat")}Your seat</li><li>{icon("book")}A signed paperback</li>'
|
||||
f'<li>{icon("book")}The eBook</li><li>{icon("library")}12 months of AiBook.fun</li></ul>')
|
||||
cols = [(f"""
|
||||
<div class="col card book">
|
||||
<p class="nm">The book</p><div class="ch"><h3>The book and the AiBook.fun library</h3><img src="{COVER_FLAT}" alt=""></div>
|
||||
<div class="sec span2"><p class="lb">Choose one</p><ul class="prices">{rows}</ul></div>
|
||||
<div class="sec"><p class="lb">When</p><ul class="dl">{book_deliv}</ul></div>
|
||||
<div class="pr"></div>
|
||||
</div>""", '1.05fr'),
|
||||
(f"""
|
||||
<div class="col card build">
|
||||
<p class="nm">Build it yourself or with us</p><h3>AOP.biz bundles</h3>
|
||||
<div class="sec span2"><p class="lb">Choose one</p><ul class="prices bund">{brows}</ul></div>
|
||||
<div class="sec"><p class="lb">After the pledge</p><p class="sm">AOP.biz service ($988 a month) and WeOwn Cloud hosting ($200 a month) are separate, optional agreements. Kickstarter charges your pledge once.</p></div>
|
||||
<div class="pr"></div>
|
||||
</div>""", '1.2fr'),
|
||||
(f"""
|
||||
<div class="col card">
|
||||
<p class="nm">In person</p><h3>Burned Out Advisor Retreat</h3>
|
||||
<div class="sec"><p class="lb">What it is</p><p>Three days in person with the authors and other advisors.</p>
|
||||
<p class="fact">{icon("people")}369 seats</p></div>
|
||||
<div class="sec"><p class="lb">Includes</p>{inc}</div>
|
||||
<div class="sec"><p class="lb">When</p><p class="fact">{icon("calendar")}4–6 November 2026</p><p class="fact cut">{icon("clock")}Closes 20 Oct 2026</p></div>
|
||||
<div class="pr"><p class="price">Price on the reward</p></div>
|
||||
</div>""", '0.95fr')]
|
||||
many = len(cols) > 3
|
||||
grid = ' '.join(f'minmax(0,{w})' for _, w in cols)
|
||||
html = ''.join(h for h, _ in cols)
|
||||
return f"""<div class="canvas" id="shot"><div class="cols{' many' if many else ''}" style="grid-template-columns:{grid}">{html}
|
||||
</div></div>"""
|
||||
TW_CSS = """
|
||||
.canvas{padding:28px 26px}
|
||||
.cols{display:grid;grid-template-rows:repeat(6,auto);column-gap:10px}
|
||||
.col{padding:18px 14px 16px;display:grid;grid-template-rows:subgrid;grid-row:span 6;min-width:0}
|
||||
.nm{font-family:var(--mono);font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--pine);font-weight:600;line-height:1.35}
|
||||
.col h3{font-family:var(--display);font-weight:600;font-size:19px;letter-spacing:-.02em;line-height:1.15;margin:6px 0 10px}
|
||||
.sec{border-top:1px dashed var(--line-2);padding:10px 0 12px}
|
||||
.span2{grid-row:span 2}
|
||||
.lb{font-family:var(--mono);font-size:11.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-bottom:6px}
|
||||
.sec p{font-size:14px;line-height:1.4}
|
||||
.sec p.sm{font-size:13px;line-height:1.42;color:var(--ink)}
|
||||
.fact{display:flex;gap:7px;align-items:flex-start;margin-top:6px;font-weight:600}
|
||||
.lb+.fact{margin-top:0}
|
||||
.fact.cut{color:var(--amber)}
|
||||
.fact.cut .ico{color:var(--amber)}
|
||||
.fact .ico,.inc .ico{width:17px;height:17px;margin-top:1px}
|
||||
.inc li{display:flex;gap:7px;align-items:flex-start;font-size:14px;line-height:1.35;padding:2px 0}
|
||||
.pr{align-self:end}
|
||||
.price{font-family:var(--mono);font-size:12px;font-weight:600;color:var(--pine);background:var(--pine-wash);border:1px solid var(--pine-tint);border-radius:999px;padding:7px 6px;text-align:center;white-space:normal;line-height:1.3}
|
||||
.book,.build{border-color:rgba(28,93,76,.28)}
|
||||
.prices li{display:flex;flex-direction:column;gap:2px;padding:7px 9px;border-radius:10px;font-size:14px;line-height:1.35}
|
||||
.prices li+li{margin-top:4px}
|
||||
.prices b{font-family:var(--display);font-weight:900;font-size:24px;letter-spacing:-.03em;color:var(--ink);line-height:1.05}
|
||||
.prices li.pb{flex-direction:row;gap:10px;align-items:flex-start}
|
||||
.prices b.np{flex:none;width:30px;margin:2px 0 0}.prices b.np img{width:30px;display:block}
|
||||
.ch{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}
|
||||
.ch img{width:42px;border-radius:2px 4px 4px 2px;box-shadow:0 6px 12px -6px rgba(18,63,52,.5);margin:4px 0 8px;flex:none}
|
||||
.prices small{display:block;font-size:12.5px;color:var(--muted)}
|
||||
.prices li.feat{background:var(--pine);color:#eaf1ec}
|
||||
.prices li.feat b{color:#fff}
|
||||
.prices li.feat small{color:#cfe0d6}
|
||||
.bund .bt{display:flex;align-items:baseline;gap:8px}
|
||||
.bund .bt em{font-style:normal;font-family:var(--mono);font-size:12.5px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--pine)}
|
||||
.bund li.feat .bt em{color:#cfe0d6}
|
||||
.bund span{font-size:13.5px;line-height:1.4}
|
||||
.bund .tag{font-style:normal;align-self:flex-start;margin-top:5px;font-family:var(--mono);font-size:11.5px;font-weight:600;letter-spacing:.04em;background:var(--amber);color:#fff;border-radius:999px;padding:3px 9px}
|
||||
.dl li{font-size:14px;line-height:1.4;padding:2px 0 2px 14px;position:relative}
|
||||
.dl li::before{content:"";position:absolute;left:0;top:8px;width:6px;height:6px;border-radius:999px;background:var(--pine)}
|
||||
"""
|
||||
page('06b-three-ways-to-back', three_ways(True), css=TW_CSS)
|
||||
page('06c-three-ways-to-back-no-paperback', three_ways(False), css=TW_CSS)
|
||||
|
||||
# ---------------------------------------------------------------- 07 the book and aibook.fun (device mockup)
|
||||
add_header('07')
|
||||
L, Ph = SCREENS['laptop'], SCREENS['phone']
|
||||
def tgt(box, vw, vh, name, side='left', gap=16):
|
||||
"""Callout target just outside the text box (left or right side), vertically centred."""
|
||||
x, y, w, h = box
|
||||
cx = x - gap if side == 'left' else x + w + gap
|
||||
return f'<i class="tg" data-t="{name}" style="left:{cx / vw * 100:.2f}%;top:{(y + h / 2) / vh * 100:.2f}%"></i>'
|
||||
page('07b-aibook-fun-device-mockup', f'''<div class="canvas" id="shot">
|
||||
<div class="stage">
|
||||
<div class="laptop"><div class="lid"><div class="scr"><img src="../assets-gen/screen-laptop.png">
|
||||
{tgt(L["essay"], L["vw"], L["vh"], "essay", gap=22)}{tgt(L["workflow"], L["vw"], L["vh"], "workflow", gap=22)}</div></div><div class="base"></div></div>
|
||||
<div class="phone"><div class="scr"><img src="../assets-gen/screen-phone.png">
|
||||
{tgt(Ph["tryit"], Ph["vw"], Ph["vh"], "tryit", "right", 22)}{tgt(Ph["updated"], Ph["vw"], Ph["vh"], "updated", "right", 22)}</div></div>
|
||||
<span class="co" data-c="essay" style="left:0;top:0">Chapter essay</span>
|
||||
<span class="co" data-c="workflow" style="left:0;bottom:0">Workflow</span>
|
||||
<span class="co" data-c="tryit" style="right:0;top:0">Try-it (about 15 minutes)</span>
|
||||
<span class="co" data-c="updated" style="right:0;bottom:0">Last updated</span>
|
||||
<svg class="lines"></svg>
|
||||
</div>
|
||||
<p class="foot-note">Screenshots of the AiBook.fun reader (sample Real Estate chapter) in device frames.</p>
|
||||
</div>
|
||||
<script>
|
||||
window.afterLayout = async () => {{
|
||||
await Promise.all([...document.images].map(i => i.complete ? 1 : new Promise(r => i.onload = r)));
|
||||
const st = document.querySelector('.stage').getBoundingClientRect();
|
||||
const svg = document.querySelector('.lines');
|
||||
let s = '';
|
||||
for (const c of document.querySelectorAll('.co')) {{
|
||||
const t = document.querySelector('.tg[data-t="' + c.dataset.c + '"]').getBoundingClientRect();
|
||||
const r = c.getBoundingClientRect();
|
||||
const tx = t.left - st.left, ty = t.top - st.top;
|
||||
const top = r.top - st.top < st.height / 2;
|
||||
const cx = Math.min(Math.max(tx, r.left - st.left + 16), r.right - st.left - 16);
|
||||
const cy = top ? r.bottom - st.top : r.top - st.top;
|
||||
s += `<path d="M${{cx}} ${{cy}} L${{cx}} ${{ty}} L${{tx}} ${{ty}}" />`;
|
||||
s += `<circle cx="${{tx}}" cy="${{ty}}" r="4.5" class="dot"/><circle cx="${{tx}}" cy="${{ty}}" r="8" class="halo"/>`;
|
||||
}}
|
||||
svg.innerHTML = s;
|
||||
}};
|
||||
</script>''', css='''
|
||||
.canvas{padding:24px 26px 22px}
|
||||
.stage{position:relative;height:500px}
|
||||
.laptop{position:absolute;left:18px;top:56px;width:470px}
|
||||
.lid{background:#1f1b17;border-radius:14px 14px 4px 4px;padding:11px 11px 13px;box-shadow:var(--sh-lg)}
|
||||
.laptop .scr{position:relative;aspect-ratio:1120/700;overflow:hidden;border-radius:3px;background:#fff}
|
||||
.base{height:14px;margin:0 -30px;background:linear-gradient(#d9d4cb,#bdb6aa);border-radius:0 0 14px 14px;position:relative;box-shadow:0 14px 22px -12px rgba(0,0,0,.35)}
|
||||
.base::before{content:"";position:absolute;left:50%;top:0;width:80px;height:6px;transform:translateX(-50%);background:#a9a295;border-radius:0 0 8px 8px}
|
||||
.phone{position:absolute;right:18px;top:62px;width:176px;background:#1f1b17;border-radius:30px;padding:8px;box-shadow:var(--sh-lg),0 0 0 1px #3a342b inset}
|
||||
.phone .scr{position:relative;aspect-ratio:390/844;overflow:hidden;border-radius:23px;background:#fff}
|
||||
.scr img{position:absolute;inset:0;width:100%;height:100%;display:block}
|
||||
.tg{position:absolute;width:0;height:0}
|
||||
.co{position:absolute;z-index:3;background:#fff;border:1.5px solid var(--pine);color:var(--pine-deep);font-weight:700;font-size:16px;padding:8px 16px;border-radius:999px;box-shadow:var(--sh-md);white-space:nowrap}
|
||||
.lines{position:absolute;inset:0;width:100%;height:100%;z-index:2;overflow:visible}
|
||||
.lines path{fill:none;stroke:var(--pine);stroke-width:1.8}
|
||||
.lines .dot{fill:var(--pine);stroke:#fff;stroke-width:2}
|
||||
.lines .halo{fill:none;stroke:var(--pine);stroke-width:1.5;opacity:.35}
|
||||
.foot-note{text-align:center;margin-top:14px}
|
||||
''')
|
||||
|
||||
# ---------------------------------------------------------------- 08 build it yourself or with us (bundle comparison)
|
||||
add_header('08')
|
||||
# Contents from GUIDE-436 (WeOwnAi/s004_fedarch/_GUIDES_/GUIDE-436.md) plus the owner's DIY definition (27 Sep 2026).
|
||||
# Values: True = included, False = not included, or a short string.
|
||||
BUNDLE_COLS = [('$1,000', 'DIY', 'On WeOwn Cloud.<br>No support of any kind.', False),
|
||||
('$2,000', 'Launch', 'Set up with our team.', False),
|
||||
('$5,000', 'Growth', 'Includes a Retreat seat.', True)]
|
||||
BUNDLE_ROWS = [
|
||||
('The starter pack', [
|
||||
('Starter agent fleet', [True, True, True]),
|
||||
('Docs and how-to guides', [True, True, True]),
|
||||
('Agentic assistant that answers from your own knowledge base', [True, True, True]),
|
||||
('Dedicated self-hosted instance; you own the data', [True, True, True])]),
|
||||
('Set up with our team', [
|
||||
('Onboarding', [False, True, True]),
|
||||
('First implementation cycle', [False, True, True]),
|
||||
('Three months of AOP.biz service, January to March 2027', [False, True, True]),
|
||||
('Seat in the December 2026 AOPbizFastTrack cohort', [False, True, True])]),
|
||||
('Growth adds', [
|
||||
('Deeper integration', [False, False, True]),
|
||||
('More agents working together', [False, False, True]),
|
||||
('Ongoing support cadence', [False, False, True]),
|
||||
('SharedBrain layer', [False, False, True]),
|
||||
('Workflow and automation layer', [False, False, True]),
|
||||
('Burned Out Advisor Retreat seat, 4–6 November 2026', [False, False, True])]),
|
||||
('Pledge window', [
|
||||
('Available until', ['4 Nov 2026', '4 Nov 2026', '20 Oct 2026'])]),
|
||||
]
|
||||
def cell(v, i):
|
||||
g = ' g' if BUNDLE_COLS[i][3] else ''
|
||||
if v is True: return f'<td class="c{g}"><span class="yes">{ICONS["check"]}</span></td>'
|
||||
if v is False: return f'<td class="c{g}"><span class="no">–</span></td>'
|
||||
cut = ' cut' if '20 Oct' in v else ''
|
||||
return f'<td class="c{g}"><span class="txt{cut}">{v}</span></td>'
|
||||
thead = '<tr><th class="lab"></th>' + ''.join(
|
||||
f'<th class="c{" g" if g else ""}"><b>{p}</b><em>{n}</em><small>{d}</small></th>' for p, n, d, g in BUNDLE_COLS) + '</tr>'
|
||||
tbody = ''
|
||||
for grp, rows_ in BUNDLE_ROWS:
|
||||
tbody += f'<tr class="grp"><td colspan="4">{grp}</td></tr>'
|
||||
for lab, vals in rows_:
|
||||
tbody += f'<tr><td class="lab">{lab}</td>' + ''.join(cell(v, i) for i, v in enumerate(vals)) + '</tr>'
|
||||
page('08b-bundle-comparison', f"""<div class="canvas" id="shot">
|
||||
<p class="spec">AOP.biz bundles · what each one includes</p>
|
||||
<table class="bc">{thead}{tbody}</table>
|
||||
<div class="after card"><p class="lb">After the pledge: separate, optional agreements</p>
|
||||
<ul>
|
||||
<li><b>DIY:</b> WeOwn Cloud hosting, $200 a month.</li>
|
||||
<li><b>Launch and Growth:</b> AOP.biz service, $988 a month from April 2027, after the three included months.</li>
|
||||
<li><b>Launch and Growth:</b> the December cohort asks you to attend at least 50% of weekly sessions, agreed when you register.</li>
|
||||
</ul>
|
||||
<p class="k">None of these is part of your pledge. Kickstarter charges your pledge once, when the campaign ends.</p></div>
|
||||
<p class="foot-note">WeOwn Cloud: infrastructure provisioned and managed by agents built by WeOwnDev. Bundle contents from GUIDE-436.</p>
|
||||
</div>""", css="""
|
||||
.canvas{padding:28px 26px 26px}
|
||||
.bc{width:100%;border-collapse:separate;border-spacing:0;margin-top:14px;background:#fff;border:1px solid var(--line);border-radius:16px;overflow:hidden;box-shadow:var(--sh-sm)}
|
||||
.bc th,.bc td{padding:8px 10px;border-bottom:1px solid var(--line);vertical-align:middle}
|
||||
.bc tr:last-child td{border-bottom:none}
|
||||
.bc th{background:var(--paper);text-align:center;padding:14px 8px 12px;vertical-align:top}
|
||||
.bc th b{display:block;font-family:var(--display);font-weight:900;font-size:25px;letter-spacing:-.03em;line-height:1.05;color:var(--ink)}
|
||||
.bc th em{display:block;font-style:normal;font-family:var(--mono);font-size:12.5px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--pine);margin-top:4px}
|
||||
.bc th small{display:block;font-size:12px;line-height:1.3;color:var(--muted);font-weight:500;margin-top:5px}
|
||||
.bc th.g{background:var(--pine)}
|
||||
.bc th.g b{color:#fff}.bc th.g em{color:#cfe0d6}.bc th.g small{color:#dfeae4}
|
||||
.bc th.lab{background:var(--paper)}
|
||||
.bc td.lab{font-size:13.5px;line-height:1.35;color:var(--ink);width:44%}
|
||||
.bc td.c{text-align:center;width:18.6%}
|
||||
.bc td.g{background:rgba(28,93,76,.05)}
|
||||
.yes{display:inline-block;width:21px;height:21px;color:var(--pine)}
|
||||
.yes svg{width:21px;height:21px}
|
||||
.no{color:#b9b1a4;font-size:16px;font-weight:600}
|
||||
.txt{font-family:var(--mono);font-size:12px;font-weight:600;color:var(--ink);white-space:nowrap}
|
||||
.txt.cut{color:#fff;background:var(--amber);border-radius:999px;padding:3px 8px}
|
||||
.bc tr.grp td{background:var(--paper-2);font-family:var(--mono);font-size:11.5px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);padding:7px 10px 6px}
|
||||
.after{margin-top:14px;padding:14px 18px 14px}
|
||||
.after .lb{font-family:var(--mono);font-size:11.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--pine);font-weight:600;margin-bottom:8px}
|
||||
.after li{font-size:13.5px;line-height:1.42;padding:2px 0 2px 14px;position:relative}
|
||||
.after li::before{content:"";position:absolute;left:0;top:8px;width:6px;height:6px;border-radius:999px;background:var(--pine)}
|
||||
.after .k{font-size:13.5px;line-height:1.42;color:var(--muted);margin-top:8px}
|
||||
""")
|
||||
|
||||
# ---------------------------------------------------------------- 09 in person: the retreat
|
||||
add_header('09')
|
||||
page('09b-retreat-venue', f"""<div class="canvas" id="shot">
|
||||
{slot("retreat-venue", "Venue photo goes here", "Landscape · at least 1360 × 765 px", "venue")}
|
||||
<div class="ov"><p class="spec">In person</p><h3>Burned Out Advisor Retreat</h3><p class="d">{icon("calendar")}4 to 6 November 2026</p>
|
||||
<p class="d cut">{icon("clock")}Pledges close 20 October 2026</p></div>
|
||||
<div class="seats"><b>369</b><span>seats</span></div>
|
||||
</div>""", h=383, px_h=765, css="""
|
||||
.canvas{padding:0;height:383px}
|
||||
.venue{position:absolute;inset:0}
|
||||
.venue .ph{border-radius:0;border-width:0;justify-content:flex-start;padding-top:70px}
|
||||
.ov{position:absolute;left:28px;bottom:26px;background:rgba(252,251,248,.96);border-radius:16px;padding:16px 22px 18px;box-shadow:var(--sh-lg);max-width:420px}
|
||||
.ov h3{font-family:var(--display);font-weight:900;font-size:30px;letter-spacing:-.025em;line-height:1.05;margin:6px 0 10px}
|
||||
.ov .d{display:flex;align-items:center;gap:9px;font-weight:700;font-size:18px}
|
||||
.ov .d+.d{margin-top:6px}
|
||||
.ov .d.cut{font-size:15.5px;color:var(--amber)}
|
||||
.ov .d .ico{width:22px;height:22px}
|
||||
.ov .d.cut .ico{color:var(--amber);width:19px;height:19px}
|
||||
.seats{position:absolute;right:28px;top:26px;width:108px;height:108px;border-radius:999px;background:var(--pine);color:#fff;display:flex;flex-direction:column;align-items:center;justify-content:center;box-shadow:0 0 0 5px rgba(252,251,248,.9),var(--sh-lg)}
|
||||
.seats b{font-family:var(--display);font-weight:900;font-size:38px;line-height:1;letter-spacing:-.03em}
|
||||
.seats span{font-family:var(--mono);font-size:14px;letter-spacing:.12em;text-transform:uppercase;color:#cfe0d6;margin-top:3px}
|
||||
""")
|
||||
|
||||
def acad_page(*a, **k):
|
||||
if ACADEMY_IN_LAUNCH: page(*a, **k)
|
||||
if ACADEMY_IN_LAUNCH:
|
||||
name, body = HDR['academy']; page(name, body, w=680, h=150)
|
||||
# ---------------------------------------------------------------- Academy (planned for a campaign update; not rendered at launch)
|
||||
W, H = MAP['w'], MAP['h']
|
||||
pins = MAP['pins']
|
||||
def pct(k): return pins[k][0] / W * 100, pins[k][1] / H * 100
|
||||
SITES = [('villapark', 'Chicagoland, Illinois', 'Villa Park', 'lab-r'),
|
||||
('denver', 'North Denver, Colorado', '#NoDe', 'lab-l'),
|
||||
('orlando', 'Orlando, Florida', 'Azur Resorts', 'lab-l')]
|
||||
pin_html = ''
|
||||
for k, city, sub, cls in SITES:
|
||||
x, y = pct(k)
|
||||
pin_html += (f'<div class="pin" style="left:{x:.2f}%;top:{y:.2f}%">{ICONS["pin"]}'
|
||||
f'<div class="lab {cls}"><b>{sub}</b><span>{city}</span></div></div>')
|
||||
acad_page('A-academy-map', f'''<div class="canvas" id="shot">
|
||||
<p class="spec" style="text-transform:none;letter-spacing:.04em;font-size:14px">AiCoach + AOP.biz BootCamp · three sites</p>
|
||||
<div class="map">{MAP_SVG}{pin_html}</div>
|
||||
</div>''', css=f'''
|
||||
.map{{position:relative;margin-top:14px;aspect-ratio:{W}/{H}}}
|
||||
.map>svg{{position:absolute;inset:0;width:100%;height:100%}}
|
||||
.pin{{position:absolute;width:0;height:0}}
|
||||
.pin>svg{{position:absolute;width:40px;height:40px;left:-20px;top:-36px;color:#fff;fill:var(--pine);stroke:#fff;stroke-width:1.6;filter:drop-shadow(0 3px 4px rgba(0,0,0,.25))}}
|
||||
.lab{{position:absolute;background:#fff;border:1px solid var(--line);border-radius:12px;padding:8px 13px 9px;box-shadow:var(--sh-md);white-space:nowrap}}
|
||||
.lab b{{display:block;font-family:var(--display);font-weight:600;font-size:18px;letter-spacing:-.02em;line-height:1.1}}
|
||||
.lab span{{display:block;font-size:14px;color:var(--muted);margin-top:2px}}
|
||||
.lab-r{{left:26px;top:-46px}}
|
||||
.lab-l{{right:26px;top:-46px}}
|
||||
''')
|
||||
SITE_CARDS = [('site-orlando', 'Azur Resorts', 'Orlando, Florida'), ('site-north-denver', '#NoDe', 'North Denver, Colorado'),
|
||||
('site-villa-park', 'Villa Park', 'Chicagoland, Illinois')]
|
||||
acad_page('A-academy-sites', '<div class="canvas" id="shot"><div class="sg">' + ''.join(
|
||||
f'<div class="card s">{slot(src, "Site photo goes here", "At least 800 × 600 px", "sp")}<div class="b"><p class="n">Site {i}</p><h3>{name}</h3><p class="pl">{icon("pin")}{place}</p></div></div>'
|
||||
for i, (src, name, place) in enumerate(SITE_CARDS, 1)) + '</div></div>', css='''
|
||||
.sg{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
|
||||
.s{overflow:hidden}
|
||||
.sp{aspect-ratio:4/3}
|
||||
.sp .ph{border-radius:0;border-width:0 0 2px 0}
|
||||
.sp .ph b{font-size:14px}.sp .ph small{font-size:11.5px}
|
||||
.b{padding:14px 15px 16px}
|
||||
.n{font-family:var(--mono);font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted)}
|
||||
.b h3{font-family:var(--display);font-weight:600;font-size:21px;letter-spacing:-.02em;margin:4px 0 6px}
|
||||
.pl{display:flex;gap:6px;align-items:flex-start;font-size:14px;line-height:1.35;color:var(--ink)}
|
||||
.pl .ico{width:17px;height:17px;margin-top:1px}
|
||||
''')
|
||||
|
||||
# ---------------------------------------------------------------- 10 stretch goals (1360 x 500)
|
||||
add_header('10')
|
||||
GOALS = [(15000, '$15,000', 'Bonus chapter', 'PDF for every backer whose reward includes the eBook'),
|
||||
(35000, '$35,000', 'Audiobook sample', 'One chapter recorded as audio, for every backer'),
|
||||
(54000, '$54,000', 'Live Q&A replay pack', 'Recording of a live Q&A with the authors, for every backer')]
|
||||
GX = [16, 50, 84] # schematic milestone positions (%), evenly spaced so labels never collide
|
||||
def stretch(unlocked):
|
||||
fill = 0 if unlocked == 0 else GX[unlocked - 1]
|
||||
marks = ''
|
||||
for i, ((v, amt, name, desc), x) in enumerate(zip(GOALS, GX), 1):
|
||||
on = i <= unlocked
|
||||
marks += (f'<div class="m {"on" if on else ""}" style="left:{x}%">'
|
||||
f'<span class="lk">{ICONS["unlock" if on else "lock"]}</span>'
|
||||
f'<div class="lbl"><b>{amt}' + ('<span class="ul">Unlocked</span>' if on else '') + '</b>'
|
||||
f'<span class="nm">{name}</span><span class="ds">{desc}</span></div></div>')
|
||||
status = 'Not yet unlocked' if unlocked == 0 else ('Unlocked: ' + ', '.join(g[1] for g in GOALS[:unlocked]))
|
||||
return f'''<div class="canvas" id="shot">
|
||||
<div class="top"><p class="spec">Stretch goals</p><p class="st">{status}</p></div>
|
||||
<div class="track"><div class="fill" style="width:{fill}%"></div>
|
||||
<div class="goal"><span class="gf">{ICONS["flag"]}</span><div class="gl"><b>Goal $5,000</b></div></div>
|
||||
{marks}
|
||||
</div></div>'''
|
||||
ST_CSS = '''
|
||||
.canvas{height:250px;padding:24px 32px 18px}
|
||||
.top{display:flex;justify-content:space-between;align-items:baseline}
|
||||
.st{font-family:var(--mono);font-size:13px;color:var(--muted);letter-spacing:.02em}
|
||||
.track{position:relative;height:14px;border-radius:999px;background:#e6e0d4;margin:58px 0 0;box-shadow:inset 0 1px 2px rgba(0,0,0,.08)}
|
||||
.fill{position:absolute;left:0;top:0;bottom:0;border-radius:999px;background:linear-gradient(90deg,#23745f,var(--pine))}
|
||||
.m{position:absolute;top:50%;width:0;height:0}
|
||||
.lk{position:absolute;left:-20px;top:-20px;width:40px;height:40px;border-radius:999px;background:#fff;border:2px solid var(--line-2);color:var(--muted);display:grid;place-items:center;box-shadow:var(--sh-sm)}
|
||||
.lk svg{width:21px;height:21px}
|
||||
.m.on .lk{background:var(--pine);border-color:#fff;color:#fff;box-shadow:0 0 0 2px var(--pine),var(--sh-md)}
|
||||
.m.on .lbl b{color:var(--pine-deep)}
|
||||
.ul{display:inline-block;vertical-align:4px;margin-left:8px;font-family:var(--mono);font-size:11.5px;font-weight:600;letter-spacing:.1em;text-transform:uppercase;color:#fff;background:var(--pine);padding:3px 10px;border-radius:999px;white-space:nowrap}
|
||||
.lbl{position:absolute;top:30px;width:196px;left:-98px;text-align:center}
|
||||
.lbl b{display:block;font-family:var(--display);font-weight:900;font-size:23px;letter-spacing:-.03em;line-height:1.1}
|
||||
.lbl .nm{display:block;font-weight:700;font-size:15.5px;margin-top:2px}
|
||||
.lbl .ds{display:block;font-size:13.5px;line-height:1.35;color:var(--muted);margin-top:3px}
|
||||
.goal{position:absolute;left:0;top:50%;width:0;height:0}
|
||||
.goal::before{content:"";position:absolute;left:0;top:-7px;width:14px;height:14px;border-radius:999px;background:#fff;border:3px solid var(--amber)}
|
||||
.gf{position:absolute;left:3px;top:-44px;width:24px;height:24px;color:var(--amber)}
|
||||
.gf svg{width:24px;height:24px}
|
||||
.gl{position:absolute;left:28px;top:-42px;white-space:nowrap}
|
||||
.gl b{font-family:var(--mono);font-size:13px;font-weight:600;letter-spacing:.04em;color:var(--amber)}
|
||||
'''
|
||||
for n, nm in [(0, '10b-stretch-goals-locked'), (1, '10c-stretch-goals-15k-unlocked'), (2, '10d-stretch-goals-35k-unlocked'), (3, '10e-stretch-goals-54k-unlocked')]:
|
||||
page(nm, stretch(n), css=ST_CSS, h=250)
|
||||
|
||||
# ---------------------------------------------------------------- 11 timeline
|
||||
add_header('11')
|
||||
STOPS = [('Fri 2 Oct 2026', 'The campaign opens.', ''),
|
||||
('Tue 20 Oct 2026', 'The Retreat reward and the $5,000 Growth bundle close.', 'cut'),
|
||||
('Wed 4 Nov 2026', 'The campaign ends. The Burned Out Advisor Retreat runs 4 to 6 November.', ''),
|
||||
('By mid-November 2026', 'AiBook.fun access for backers whose reward includes it, and the backer survey.', ''),
|
||||
('December 2026', 'The AOPbizFastTrack cohort for Launch and Growth backers.', ''),
|
||||
('January 2027', 'Final layout and eBook files. The eBook is delivered and the paperbacks are signed.', ''),
|
||||
('January to March 2027', 'Three months of AOP.biz service for Launch and Growth backers.', ''),
|
||||
('February 2027', 'Signed paperbacks are delivered.', '')]
|
||||
stops = ''.join(f'<li class="{c}"><span class="num">{i}</span><div class="tx"><b>{d}</b><p>{t}</p></div></li>'
|
||||
for i, (d, t, c) in enumerate(STOPS, 1))
|
||||
page('11b-timeline', f"""<div class="canvas" id="shot"><ol class="vt">{stops}</ol></div>""", css="""
|
||||
.canvas{padding:30px 34px 30px}
|
||||
.vt{position:relative}
|
||||
.vt::before{content:"";position:absolute;left:23px;top:24px;bottom:24px;border-left:3px dotted var(--pine);opacity:.55}
|
||||
.vt li{position:relative;display:flex;align-items:flex-start;gap:22px;padding:0 0 18px}
|
||||
.vt li:last-child{padding-bottom:0}
|
||||
.num{flex:none;width:46px;height:46px;border-radius:999px;background:var(--pine);color:#fff;font-family:var(--display);font-weight:900;font-size:21px;display:grid;place-items:center;box-shadow:0 0 0 5px var(--paper-2),var(--sh-md);position:relative;z-index:1}
|
||||
.tx{padding-top:3px}
|
||||
.tx b{display:block;font-family:var(--display);font-weight:600;font-size:20px;letter-spacing:-.02em;line-height:1.15;color:var(--ink)}
|
||||
.tx p{font-size:15px;line-height:1.4;color:var(--muted);margin-top:3px}
|
||||
.vt li.cut .num{background:var(--amber)}
|
||||
.vt li.cut .tx b{color:var(--amber)}
|
||||
""")
|
||||
|
||||
# ---------------------------------------------------------------- 12 shipping and delivery
|
||||
add_header('12')
|
||||
def lane(title, sub, ic, steps):
|
||||
st = ''
|
||||
for j, (i2, t, d) in enumerate(steps):
|
||||
if j: st += f'<span class="ar">{ICONS["arrow"]}</span>'
|
||||
vis = f'<img class="cv" src="{i2[4:]}" alt="">' if i2.startswith('img:') else icon(i2, "ico ci")
|
||||
st += f'<div class="stp">{vis}<b>{t}</b>' + (f'<p>{d}</p>' if d else '') + '</div>'
|
||||
head = f'<img class="lhc" src="{ic[4:]}" alt="">' if ic.startswith('img:') else icon(ic, "ico lhi")
|
||||
return f'<div class="card lane"><div class="lh">{head}<div><h3>{title}</h3><p>{sub}</p></div></div><div class="steps n{len(steps)}">{st}</div></div>'
|
||||
page('12b-shipping-and-delivery-lanes', '<div class="canvas" id="shot">' +
|
||||
lane('Digital rewards', 'Arrive by email', 'mail', [
|
||||
('mail', 'Email', 'To the address on your Kickstarter account'),
|
||||
('library', 'Library access', 'Within about 14 days of a successful campaign'),
|
||||
('img:' + COVER_FLAT, 'eBook', 'January 2027')]) +
|
||||
lane('Signed paperbacks', 'Ship in February 2027', 'img:' + COVER_3D, [
|
||||
('survey', 'Survey', 'Kickstarter’s Pledge Manager asks for your address and charges shipping and any taxes'),
|
||||
('printer', 'Printing', ''),
|
||||
('pen', 'Signing', 'January 2027'),
|
||||
('truck', 'Shipping', 'February 2027')]) +
|
||||
'</div>', css='''
|
||||
.lane{padding:16px 18px 18px}
|
||||
.cv{display:block;height:46px;margin:0 auto 8px;border-radius:1px 3px 3px 1px;box-shadow:0 4px 8px -4px rgba(18,63,52,.5)}
|
||||
.lhc{height:52px;display:block;margin:-6px 2px -4px 0}
|
||||
.lane+.lane{margin-top:14px}
|
||||
.lh{display:flex;align-items:center;gap:12px;padding-bottom:12px;border-bottom:1px dashed var(--line-2);margin-bottom:14px}
|
||||
.ico.lhi{width:40px;height:40px;padding:9px;border-radius:12px;background:var(--pine);color:#fff}
|
||||
.lh h3{font-family:var(--display);font-weight:600;font-size:21px;letter-spacing:-.02em;line-height:1.1}
|
||||
.lh p{font-family:var(--mono);font-size:13px;color:var(--muted);margin-top:3px}
|
||||
.steps{display:flex;align-items:flex-start}
|
||||
.stp{flex:1;min-width:0;text-align:center;padding:0 4px}
|
||||
.ar{flex:none;width:18px;height:18px;color:var(--line-2);margin-top:14px}
|
||||
.ico.ci{width:46px;height:46px;padding:11px;border-radius:999px;background:var(--pine-wash);border:1px solid var(--pine-tint);display:block;margin:0 auto 8px}
|
||||
.stp b{display:block;font-size:15.5px;font-weight:700}
|
||||
.stp p{font-size:13.5px;line-height:1.38;color:var(--muted);margin-top:3px}
|
||||
''')
|
||||
|
||||
# ---------------------------------------------------------------- 13 early readers (placeholder cards)
|
||||
add_header('13')
|
||||
# Fill in once early readers approve their quotes in writing (photo files: assets/reader-1.jpg etc.).
|
||||
QUOTES = [ # (quote, name, role and firm)
|
||||
('Early reader quote 1 goes here.', 'Name goes here', 'Role and firm'),
|
||||
('Early reader quote 2 goes here.', 'Name goes here', 'Role and firm'),
|
||||
('Early reader quote 3 goes here.', 'Name goes here', 'Role and firm'),
|
||||
]
|
||||
page('13b-early-reader-quotes', '<div class="canvas" id="shot">' + ''.join(
|
||||
f'<div class="card q">{slot(f"reader-{i}", "Photo", "400 × 400", "qp")}<div class="qt"><p class="qq">“{q}”</p>'
|
||||
f'<p class="who"><b>{n}</b> · {r}</p></div></div>' for i, (q, n, r) in enumerate(QUOTES, 1)) + '</div>', css='''
|
||||
.q{display:flex;gap:18px;align-items:center;padding:18px 20px}
|
||||
.q+.q{margin-top:12px}
|
||||
.qp{width:84px;height:84px;border-radius:999px;flex:none}
|
||||
.qp .ph{border-width:2px;gap:2px}.qp .ph svg{width:20px;height:20px}.qp .ph b{font-size:12px}.qp .ph small{font-size:10px}
|
||||
.qq{font-family:var(--display);font-style:italic;font-size:21px;letter-spacing:-.01em;color:#8d8579;line-height:1.3}
|
||||
.who{font-size:14.5px;color:var(--muted);margin-top:6px}
|
||||
.who b{color:var(--ink)}
|
||||
''')
|
||||
|
||||
# ---------------------------------------------------------------- 14 authors and team (placeholders)
|
||||
add_header('14')
|
||||
TEAM = [('@THY', 'Name goes here', 'Author and Retreat host'),
|
||||
('@LFG', 'Name goes here', 'Creative lead for design, website, campaign page, and video'),
|
||||
('@CEO', 'Name goes here', 'Business strategy and partnerships'),
|
||||
('@GTM', 'Name goes here', 'Payments, email, and technical setup'),
|
||||
('', 'Osinachi Patrick', 'Product lead, AiBook.fun'),
|
||||
('', 'Name goes here', 'AOP.biz bundles lead')]
|
||||
team_html = ''.join(
|
||||
f'<div class="card tm">{slot("team-" + (h[1:].lower() if h else ("osinachi-patrick" if n.startswith("Osinachi") else "aop-lead")), "Photo", "800 × 800", "tp")}'
|
||||
f'<div><p class="tn">{n}</p>' + (f'<p class="th">{h}</p>' if h else '') + f'<p class="tr">{r}</p></div></div>' for h, n, r in TEAM)
|
||||
# Landing page (Authors.jsx) lists three co-authors as confirmed, by chapter; names are not published yet.
|
||||
AUTHORS = [('Name goes here', 'Co-author, Real Estate & Finance'), ('Name goes here', 'Co-author, <span style="white-space:nowrap">Fractional C-Suite</span>'),
|
||||
('Name goes here', 'Co-author, Technology & RAAI')]
|
||||
AUTHOR_HTML = ''.join(f'<div class="card au">{slot(f"author-{i}", "Author photo goes here", "800 × 800", "ap")}<p class="an">{n}</p><p class="ar">{r}</p></div>'
|
||||
for i, (n, r) in enumerate(AUTHORS, 1))
|
||||
page('14b-authors-and-team', f'''<div class="canvas" id="shot">
|
||||
<p class="spec">The authors</p>
|
||||
<div class="ag">{AUTHOR_HTML}</div>
|
||||
<p class="spec" style="margin-top:22px">The team</p>
|
||||
<div class="tg">{team_html}</div>
|
||||
</div>''', css='''
|
||||
.ag{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-top:12px}
|
||||
.au{padding:14px 14px 18px}
|
||||
.ap{aspect-ratio:1/1;border-radius:10px}
|
||||
.ap .ph b{font-size:13px}
|
||||
.an{font-family:var(--display);font-weight:600;font-size:19px;letter-spacing:-.02em;margin-top:12px;color:#8d8579}
|
||||
.ar{font-size:14px;line-height:1.35;color:var(--muted);margin-top:2px}
|
||||
.tg{display:grid;grid-template-columns:repeat(3,1fr);gap:10px;margin-top:12px}
|
||||
.tm{padding:12px;display:flex;gap:11px;align-items:flex-start}
|
||||
.tp{width:60px;height:60px;border-radius:999px;flex:none}
|
||||
.tp .ph{gap:1px}.tp .ph svg{width:16px;height:16px}.tp .ph b{font-size:11px}.tp .ph small{display:none}
|
||||
.tn{font-weight:700;font-size:14.5px;line-height:1.25}
|
||||
.th{font-family:var(--mono);font-size:12px;color:var(--pine);margin-top:2px}
|
||||
.tr{font-size:13px;line-height:1.35;color:var(--muted);margin-top:3px}
|
||||
''')
|
||||
page('14c-author-headshot-800x800', f'''<div class="canvas" id="shot">{slot("headshot-template", "Author photo goes here", "800 × 800 px · square", "hs")}</div>''',
|
||||
w=400, h=400, css='''.canvas{width:400px;height:400px;padding:0}.hs{position:absolute;inset:0}.hs .ph{border-radius:0;border-width:3px}.hs .ph b{font-size:20px}.hs .ph small{font-size:14px}.hs .ph svg{width:44px;height:44px}''')
|
||||
|
||||
# ---------------------------------------------------------------- 15, 16
|
||||
add_header('15')
|
||||
add_header('16')
|
||||
|
||||
# ---------------------------------------------------------------- render
|
||||
async def render(only=None):
|
||||
from playwright.async_api import async_playwright
|
||||
results = []
|
||||
async with async_playwright() as p:
|
||||
b = await p.chromium.launch(executable_path='/usr/bin/google-chrome')
|
||||
for pg in pages:
|
||||
if only and not re.search(only, pg['name']): continue
|
||||
html = HEAD.format(body=pg['body'], css=pg['css'], extra_css=pg['extra_css'])
|
||||
f = PAGES / f"{pg['name']}.html"; f.write_text(html)
|
||||
page_ = await b.new_page(viewport={'width': pg['w'], 'height': math.ceil(pg['h'] or 800)}, device_scale_factor=2)
|
||||
await page_.goto(f.as_uri())
|
||||
empty = await page_.evaluate('window.__ready')
|
||||
name = pg['name'] + ('-PLACEHOLDER' if empty else '')
|
||||
for old in OUT.glob(pg['name'] + '*.png'): old.unlink()
|
||||
el = await page_.query_selector('#shot')
|
||||
if pg['h']: # fixed-size artwork: clip exactly (element screenshots round fractional heights up)
|
||||
await page_.screenshot(path=str(OUT / f'{name}.png'), clip={'x': 0, 'y': 0, 'width': pg['w'], 'height': pg['h']})
|
||||
else:
|
||||
await el.screenshot(path=str(OUT / f'{name}.png'))
|
||||
if pg.get('px_h'): # exact pixel height (e.g. 16:9 = 1360 x 765)
|
||||
from PIL import Image
|
||||
im = Image.open(OUT / f'{name}.png'); im.crop((0, 0, im.width, pg['px_h'])).save(OUT / f'{name}.png')
|
||||
results.append((name, empty))
|
||||
await page_.close()
|
||||
await b.close()
|
||||
for r in results: print(*r)
|
||||
if __name__ == '__main__':
|
||||
asyncio.run(render(sys.argv[1] if len(sys.argv) > 1 else None))
|
||||
@@ -0,0 +1,30 @@
|
||||
"""Contact sheet of all story images in order, with filenames and pixel sizes."""
|
||||
import asyncio, pathlib
|
||||
from PIL import Image
|
||||
from playwright.async_api import async_playwright
|
||||
HERE = pathlib.Path(__file__).parent; OUT = HERE.parent
|
||||
files = sorted(p for p in OUT.glob('*.png') if p.name != 'contact-sheet.png')
|
||||
cells = ''
|
||||
for f in files:
|
||||
w, h = Image.open(f).size
|
||||
cells += f'<figure><div class="im"><img src="../../{f.name}"></div><figcaption><b>{f.name}</b><span>{w} × {h}</span></figcaption></figure>'
|
||||
html = f'''<!doctype html><html><head><meta charset="utf-8"><link rel="stylesheet" href="../styles.css"><style>
|
||||
body{{background:#fff}} .sheet{{width:1400px;padding:40px;background:#fcfbf8}}
|
||||
h1{{font-family:var(--display);font-weight:900;font-size:34px;letter-spacing:-.02em}} .sub{{font-family:var(--mono);font-size:14px;color:var(--muted);margin:6px 0 28px}}
|
||||
.grid{{display:grid;grid-template-columns:1fr 1fr;gap:28px 32px;align-items:start}}
|
||||
figure{{margin:0}} .im{{border:1px solid var(--line-2);background:#fff}} img{{width:100%;display:block}}
|
||||
figcaption{{display:flex;justify-content:space-between;font-family:var(--mono);font-size:14px;margin-top:8px}} figcaption span{{color:var(--muted)}}
|
||||
</style></head><body><div class="sheet" id="shot"><h1>We Own AI — Kickstarter story images</h1>
|
||||
<p class="sub">{len(files)} images in story order · ks-research/story-images/ · files marked PLACEHOLDER or DRAFT need owner input before upload</p>
|
||||
<div class="grid">{cells}</div></div></body></html>'''
|
||||
(HERE / 'pages' / 'contact-sheet.html').write_text(html)
|
||||
async def main():
|
||||
async with async_playwright() as p:
|
||||
b = await p.chromium.launch(executable_path='/usr/bin/google-chrome')
|
||||
pg = await b.new_page(viewport={'width': 1400, 'height': 1000}, device_scale_factor=1)
|
||||
await pg.goto((HERE / 'pages' / 'contact-sheet.html').as_uri())
|
||||
await pg.wait_for_load_state('networkidle'); await pg.evaluate('document.fonts.ready')
|
||||
await (await pg.query_selector('#shot')).screenshot(path=str(OUT / 'contact-sheet.png'))
|
||||
await b.close()
|
||||
asyncio.run(main())
|
||||
print(len(files), Image.open(OUT / 'contact-sheet.png').size)
|
||||
@@ -0,0 +1,82 @@
|
||||
"""Line icons (24x24, stroke = currentColor) and small line illustrations, drawn for this series."""
|
||||
def _i(body, vb='0 0 24 24', sw=1.7):
|
||||
return (f'<svg viewBox="{vb}" fill="none" stroke="currentColor" stroke-width="{sw}" '
|
||||
f'stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">{body}</svg>')
|
||||
|
||||
ICONS = {
|
||||
'authors': _i('<circle cx="8.5" cy="8" r="3"/><path d="M3 19c.6-3.2 2.8-5 5.5-5s4.9 1.8 5.5 5"/><circle cx="16.5" cy="9" r="2.5"/><path d="M15.4 14.2c.4-.1.7-.2 1.1-.2 2.3 0 4.1 1.5 4.6 4.2"/>'),
|
||||
'tested': _i('<rect x="5" y="4" width="14" height="17" rx="2"/><path d="M9 4V3h6v1"/><path d="m8.5 10 1.5 1.5 3-3"/><path d="M14.5 10.5H16"/><path d="m8.5 15.5 1.5 1.5 3-3"/><path d="M14.5 16H16"/>'),
|
||||
'updated': _i('<path d="M4 6.5C6.5 5 9 5 12 6.5v12C9 17 6.5 17 4 18.5z"/><path d="M12 6.5c1-.5 2-.8 3-.9"/><path d="M20 12a4 4 0 1 1-1.2-2.9"/><path d="M19.2 6.6v2.6h-2.6"/>'),
|
||||
'calendar': _i('<rect x="3.5" y="5" width="17" height="15" rx="2"/><path d="M3.5 9.5h17M8 3v4M16 3v4"/><path d="M7.5 13h2M11 13h2M14.5 13h2M7.5 16.5h2M11 16.5h2"/>'),
|
||||
'seat': _i('<path d="M6 11V6.5A2.5 2.5 0 0 1 8.5 4h7A2.5 2.5 0 0 1 18 6.5V11"/><path d="M4 11.5a2 2 0 0 1 4 0V14h8v-2.5a2 2 0 0 1 4 0V17a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1z"/><path d="M6.5 18v2M17.5 18v2"/>'),
|
||||
'people': _i('<circle cx="12" cy="8" r="3"/><path d="M6.5 19c.6-3 2.8-4.8 5.5-4.8s4.9 1.8 5.5 4.8"/><circle cx="5" cy="10" r="2"/><circle cx="19" cy="10" r="2"/><path d="M2 17c.3-1.7 1.4-2.8 3-3M22 17c-.3-1.7-1.4-2.8-3-3"/>'),
|
||||
'pin': _i('<path d="M12 21s-6.5-6-6.5-11a6.5 6.5 0 0 1 13 0c0 5-6.5 11-6.5 11z"/><circle cx="12" cy="10" r="2.4"/>'),
|
||||
'check': _i('<circle cx="12" cy="12" r="8.5"/><path d="m8.2 12.3 2.6 2.6 5-5.2"/>'),
|
||||
'book': _i('<path d="M12 6.5C9.5 5 7 4.6 3.5 5v13c3.5-.4 6 0 8.5 1.5 2.5-1.5 5-1.9 8.5-1.5V5c-3.5-.4-6 0-8.5 1.5z"/><path d="M12 6.5v13"/>'),
|
||||
'library': _i('<rect x="3.5" y="4.5" width="17" height="12" rx="1.6"/><path d="M2 19.5h20"/><path d="M8 8.5h8M8 11.5h5"/>'),
|
||||
'mail': _i('<rect x="3" y="5.5" width="18" height="13" rx="2"/><path d="m3.8 7 8.2 6 8.2-6"/>'),
|
||||
'survey': _i('<rect x="5" y="4" width="14" height="17" rx="2"/><path d="M9 4V3h6v1"/><path d="M8.5 9.5h7M8.5 13h7M8.5 16.5h4"/>'),
|
||||
'printer': _i('<path d="M7 9V4h10v5"/><rect x="3.5" y="9" width="17" height="8" rx="2"/><path d="M7 14h10v6H7z"/><path d="M17 12h.01"/>'),
|
||||
'pen': _i('<path d="M4 20c2.5 0 3.5-2 5-2s2 1.5 3.5 1.5"/><path d="m14 4.5 5.5 5.5L11 18.5l-6 1.5 1.5-6z"/><path d="m12.5 6 5.5 5.5"/>'),
|
||||
'truck': _i('<path d="M2.5 6.5h11v9h-11z"/><path d="M13.5 9.5h4l3 3.5v2.5h-7"/><circle cx="6.5" cy="17" r="1.8"/><circle cx="17" cy="17" r="1.8"/>'),
|
||||
'globe': _i('<circle cx="12" cy="12" r="8.5"/><path d="M3.5 12h17M12 3.5c2.5 2.3 3.6 5.2 3.6 8.5S14.5 18.2 12 20.5C9.5 18.2 8.4 15.3 8.4 12S9.5 5.8 12 3.5z"/>'),
|
||||
'lock': _i('<rect x="5" y="10.5" width="14" height="10" rx="2"/><path d="M8 10.5V8a4 4 0 0 1 8 0v2.5"/><path d="M12 14.5v2.5"/>'),
|
||||
'unlock': _i('<rect x="5" y="10.5" width="14" height="10" rx="2"/><path d="M8 10.5V8a4 4 0 0 1 7.7-1.6"/><path d="m9.6 15.4 1.7 1.7 3.2-3.3"/>'),
|
||||
'flag': _i('<path d="M5 21V4"/><path d="M5 4.5h11l-2 3.5 2 3.5H5"/>'),
|
||||
'audio': _i('<path d="M4 14v-2a8 8 0 0 1 16 0v2"/><rect x="3" y="13.5" width="4" height="6.5" rx="1.5"/><rect x="17" y="13.5" width="4" height="6.5" rx="1.5"/>'),
|
||||
'video': _i('<rect x="3" y="6" width="13" height="12" rx="2"/><path d="m16 10.5 5-3v9l-5-3"/>'),
|
||||
'camera': _i('<path d="M4 8h3l1.6-2.5h6.8L17 8h3a1 1 0 0 1 1 1v9a1 1 0 0 1-1 1H4a1 1 0 0 1-1-1V9a1 1 0 0 1 1-1z"/><circle cx="12" cy="13.2" r="3.4"/>'),
|
||||
'compass': _i('<circle cx="12" cy="12" r="8.5"/><path d="m15.5 8.5-2 5-5 2 2-5z"/>'),
|
||||
'accounting': _i('<rect x="5" y="3.5" width="14" height="17" rx="2"/><path d="M8 7h8v3H8z"/><path d="M8.5 13.5h.01M12 13.5h.01M15.5 13.5h.01M8.5 17h.01M12 17h.01M15.5 17h.01"/>', sw=1.8),
|
||||
'chart': _i('<path d="M4 20h16"/><path d="M6.5 16.5v-4M11 16.5V8.5M15.5 16.5v-6"/><path d="m5.5 9 5-4 4 3 4-3.5"/>'),
|
||||
'briefcase': _i('<rect x="3" y="7.5" width="18" height="12" rx="2"/><path d="M9 7.5V6a1.5 1.5 0 0 1 1.5-1.5h3A1.5 1.5 0 0 1 15 6v1.5"/><path d="M3 12.5h18"/>'),
|
||||
'arrow': _i('<path d="M5 12h14M13 6l6 6-6 6"/>'),
|
||||
'clock': _i('<circle cx="12" cy="12" r="8.5"/><path d="M12 7.5V12l3 2"/>'),
|
||||
'box': _i('<path d="M3.5 7.5 12 3.5l8.5 4v9L12 20.5l-8.5-4z"/><path d="M3.5 7.5 12 11.5l8.5-4M12 11.5v9"/>'),
|
||||
}
|
||||
|
||||
# Book3D compass mark from marketing-site/components/Book3D.jsx
|
||||
MARK = ('<svg viewBox="0 0 40 40" fill="none" aria-hidden="true"><circle cx="20" cy="20" r="17.5" stroke="#efe9db" stroke-width="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>')
|
||||
|
||||
P, A, L = '#1c5d4c', '#b4791f', '#d8d1c4'
|
||||
def _ill(body):
|
||||
return (f'<svg viewBox="0 0 120 84" fill="none" stroke="{P}" stroke-width="2" stroke-linecap="round" '
|
||||
f'stroke-linejoin="round" aria-hidden="true">{body}</svg>')
|
||||
|
||||
ILLUS = {
|
||||
# a pile of newsletters
|
||||
'newsletters': _ill(
|
||||
'<g transform="rotate(-8 60 50)"><rect x="26" y="34" width="62" height="40" rx="3" fill="#fff"/></g>'
|
||||
'<g transform="rotate(5 60 46)"><rect x="30" y="26" width="62" height="40" rx="3" fill="#fff"/></g>'
|
||||
'<rect x="28" y="14" width="62" height="44" rx="3" fill="#fff"/>'
|
||||
f'<path d="M36 23h30" stroke="{A}" stroke-width="3"/><path d="M36 31h46M36 37h46M36 43h32M36 49h40" stroke="{L}"/>'
|
||||
'<rect x="72" y="20" width="12" height="8" rx="1.5" stroke-width="1.6"/>'),
|
||||
# a padlock on a software window
|
||||
'lockedwindow': _ill(
|
||||
'<rect x="18" y="12" width="84" height="60" rx="5" fill="#fff"/><path d="M18 24h84"/>'
|
||||
f'<circle cx="26" cy="18" r="1.8" fill="{L}" stroke="none"/><circle cx="32" cy="18" r="1.8" fill="{L}" stroke="none"/><circle cx="38" cy="18" r="1.8" fill="{L}" stroke="none"/>'
|
||||
f'<path d="M28 34h22M28 41h16M28 48h20M28 55h12" stroke="{L}"/>'
|
||||
f'<rect x="62" y="42" width="26" height="21" rx="3" fill="#fff" stroke="{A}" stroke-width="2.4"/>'
|
||||
f'<path d="M67 42v-5a8 8 0 0 1 16 0v5" stroke="{A}" stroke-width="2.4"/><path d="M75 50v5" stroke="{A}" stroke-width="2.4"/>'),
|
||||
# a clock at 11 PM
|
||||
'clock11': _ill(
|
||||
'<circle cx="54" cy="44" r="30" fill="#fff"/>'
|
||||
+ ''.join(f'<path d="M54 {17 if i%3==0 else 18.5}v{5 if i%3==0 else 3}" transform="rotate({i*30} 54 44)" stroke="{L if i%3 else P}"/>' for i in range(12)) +
|
||||
'<path d="M54 44 44.5 28.5" stroke-width="3"/><path d="M54 44V21" stroke-width="2.2"/>'
|
||||
f'<circle cx="54" cy="44" r="2.4" fill="{P}" stroke="none"/>'
|
||||
f'<path d="M99 14a9 9 0 1 0 8 13 7 7 0 0 1-8-13z" fill="#fbf1e0" stroke="{A}"/>'),
|
||||
# an empty client chair (armchair, front view)
|
||||
'chair': _ill(
|
||||
'<path d="M38 50V24a8 8 0 0 1 8-8h28a8 8 0 0 1 8 8v26" fill="#fff"/>'
|
||||
'<path d="M30 44a6 6 0 0 1 12 0v8h36v-8a6 6 0 0 1 12 0v18a3 3 0 0 1-3 3H33a3 3 0 0 1-3-3z" fill="#fff"/>'
|
||||
'<path d="M42 52h36"/><path d="M36 65v8M84 65v8"/>'
|
||||
f'<path d="M48 30h24" stroke="{L}"/><path d="M14 73h92" stroke="{L}"/>'),
|
||||
}
|
||||
|
||||
def icon(name, cls='ico'):
|
||||
return f'<span class="{cls}">{ICONS[name]}</span>'
|
||||
# ShieldCheck from marketing-site/components/reader/WorkflowBlock.jsx (16x16)
|
||||
ICONS['shield'] = ('<svg 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" stroke-width="1.3" stroke-linejoin="round"/><path d="m5.6 8 1.7 1.7L10.6 6" stroke="#1C5D4C" stroke-width="1.3" '
|
||||
'stroke-linecap="round" stroke-linejoin="round"/></svg>')
|
||||
@@ -0,0 +1,37 @@
|
||||
"""Build a lower-48 US outline SVG (Albers equal-area) from public-domain Census-derived state boundaries.
|
||||
Source: PublicaMundi/MappingAPI us-states.json (US Census cartographic boundaries). Output: assets-gen/us-map.svg"""
|
||||
import json, math, sys
|
||||
src = sys.argv[1] if len(sys.argv) > 1 else 'assets-gen/us-states.geojson'
|
||||
d = json.load(open(src))
|
||||
phi1, phi2, phi0, lam0 = map(math.radians, (29.5, 45.5, 37.5, -96))
|
||||
n = (math.sin(phi1) + math.sin(phi2)) / 2
|
||||
C = math.cos(phi1) ** 2 + 2 * n * math.sin(phi1)
|
||||
rho0 = math.sqrt(C - 2 * n * math.sin(phi0)) / n
|
||||
def proj(lon, lat):
|
||||
lam, phi = math.radians(lon), math.radians(lat)
|
||||
rho = math.sqrt(C - 2 * n * math.sin(phi)) / n
|
||||
th = n * (lam - lam0)
|
||||
return rho * math.sin(th), -(rho0 - rho * math.cos(th))
|
||||
skip = {'Alaska', 'Hawaii', 'Puerto Rico'}
|
||||
polys = []
|
||||
for f in d['features']:
|
||||
if f['properties']['name'] in skip: continue
|
||||
g = f['geometry']
|
||||
rings = g['coordinates'] if g['type'] == 'Polygon' else [r for p in g['coordinates'] for r in p]
|
||||
for ring in rings:
|
||||
polys.append([proj(*pt[:2]) for pt in ring])
|
||||
xs = [p[0] for r in polys for p in r]; ys = [p[1] for r in polys for p in r]
|
||||
minx, maxx, miny, maxy = min(xs), max(xs), min(ys), max(ys)
|
||||
W = 1000; s = W / (maxx - minx); H = (maxy - miny) * s
|
||||
def tx(p): return ((p[0] - minx) * s, (p[1] - miny) * s)
|
||||
paths = []
|
||||
for r in polys:
|
||||
pts = [tx(p) for p in r]
|
||||
paths.append('M' + 'L'.join(f'{x:.1f},{y:.1f}' for x, y in pts) + 'Z')
|
||||
cities = {'orlando': (-81.3789, 28.5384), 'denver': (-104.9903, 39.7392), 'villapark': (-87.9887, 41.8898)}
|
||||
out = {k: tx(proj(*v)) for k, v in cities.items()}
|
||||
svg = f'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 {W} {H:.0f}"><path d="{"".join(paths)}" fill="#efebe2" stroke="#cdc3b3" stroke-width="1.2" stroke-linejoin="round"/></svg>'
|
||||
import os; os.makedirs('assets-gen', exist_ok=True)
|
||||
open('assets-gen/us-map.svg', 'w').write(svg)
|
||||
json.dump({'w': W, 'h': round(H), 'pins': {k: [round(x, 1), round(y, 1)] for k, (x, y) in out.items()}}, open('assets-gen/us-map.json', 'w'), indent=1)
|
||||
print(W, H, out, len(svg))
|
||||
@@ -0,0 +1,24 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../styles.css"><style></style></head><body><div class="hdr" id="shot"><div class="tabs"><span></span><span></span><span></span><span></span><span></span></div><div class="mark"><svg viewBox="0 0 40 40" fill="none" aria-hidden="true"><circle cx="20" cy="20" r="17.5" stroke="#efe9db" stroke-width="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></div><div class="badge"><span class="emoji">👋</span></div><div style="min-width:0;flex:1"><div class="kicker">We Own AI — The New American Dream</div><h1 data-fit>Welcome</h1></div><div class="rule"></div></div>
|
||||
<script>
|
||||
window.__ready = (async () => {
|
||||
let empty = 0;
|
||||
for (const s of document.querySelectorAll('.slot[data-src]')) {
|
||||
let ok = false;
|
||||
for (const ext of ['jpg', 'jpeg', 'png', 'webp']) {
|
||||
const url = s.dataset.src + '.' + ext;
|
||||
ok = await new Promise(r => { const i = new Image(); i.onload = () => r(true); i.onerror = () => r(false); i.src = url; });
|
||||
if (ok) { s.style.backgroundImage = 'url("' + url + '")'; s.classList.add('filled'); break; }
|
||||
}
|
||||
if (!ok) empty++;
|
||||
}
|
||||
await document.fonts.ready;
|
||||
for (const el of document.querySelectorAll('[data-fit]')) {
|
||||
let fs = parseFloat(getComputedStyle(el).fontSize);
|
||||
const max = el.dataset.fit ? parseFloat(el.dataset.fit) : el.parentElement.clientWidth;
|
||||
while (el.scrollWidth > max && fs > 10) { fs -= 0.5; el.style.fontSize = fs + 'px'; }
|
||||
}
|
||||
if (window.afterLayout) await window.afterLayout();
|
||||
return empty;
|
||||
})();
|
||||
</script></body></html>
|
||||
@@ -0,0 +1,53 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../styles.css"><style>
|
||||
.wel{display:flex;gap:30px;align-items:center;padding:0 6px 22px}
|
||||
.bookwrap{flex:none;margin:0;width:196px;text-align:center}
|
||||
.bookwrap img{width:196px;display:block}
|
||||
.bookwrap figcaption{font-family:var(--mono);font-size:12px;letter-spacing:.08em;text-transform:uppercase;color:var(--muted);margin-top:-14px}
|
||||
.wtxt h2{font-family:var(--display);font-weight:900;font-size:50px;letter-spacing:-.03em;line-height:1;color:var(--pine-deep)}
|
||||
.wtxt .t{font-family:var(--display);font-weight:600;font-size:22px;letter-spacing:-.02em;line-height:1.2;margin:14px 0 12px}
|
||||
.wtxt .s{font-size:16px;line-height:1.5;color:var(--muted);max-width:25rem}
|
||||
.wtxt .pub{font-family:var(--mono);font-size:13px;letter-spacing:.06em;color:var(--pine);margin-top:16px}
|
||||
.trio{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
|
||||
.trio>div{background:var(--card);border:1px solid var(--line);border-radius:16px;padding:20px 14px 18px;text-align:center;box-shadow:var(--sh-sm)}
|
||||
.ico.big{width:58px;height:58px;padding:13px;border-radius:999px;background:var(--pine-wash);border:1px solid var(--pine-tint);display:block;margin:0 auto 12px}
|
||||
.trio p{font-weight:700;font-size:16px;line-height:1.3}
|
||||
</style></head><body>
|
||||
<div class="canvas" id="shot">
|
||||
<div class="wel">
|
||||
<figure class="bookwrap"><img src="../assets-gen/cover-3d.png" alt=""><figcaption>Cover mockup</figcaption></figure>
|
||||
<div class="wtxt">
|
||||
<h2>Welcome</h2>
|
||||
<p class="t">We Own AI — The New American Dream</p>
|
||||
<p class="s">A field book for advisors who want to use AI in their practice in ways they control.</p>
|
||||
<p class="pub">BurnedOut Media / WeOwnNet</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="trio">
|
||||
<div><span class="ico big"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="8.5" cy="8" r="3"/><path d="M3 19c.6-3.2 2.8-5 5.5-5s4.9 1.8 5.5 5"/><circle cx="16.5" cy="9" r="2.5"/><path d="M15.4 14.2c.4-.1.7-.2 1.1-.2 2.3 0 4.1 1.5 4.6 4.2"/></svg></span><p>Multi-author field book</p></div>
|
||||
<div><span class="ico big"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="5" y="4" width="14" height="17" rx="2"/><path d="M9 4V3h6v1"/><path d="m8.5 10 1.5 1.5 3-3"/><path d="M14.5 10.5H16"/><path d="m8.5 15.5 1.5 1.5 3-3"/><path d="M14.5 16H16"/></svg></span><p>Tested AI workflows</p></div>
|
||||
<div><span class="ico big"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 6.5C6.5 5 9 5 12 6.5v12C9 17 6.5 17 4 18.5z"/><path d="M12 6.5c1-.5 2-.8 3-.9"/><path d="M20 12a4 4 0 1 1-1.2-2.9"/><path d="M19.2 6.6v2.6h-2.6"/></svg></span><p>Library updated often</p></div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
window.__ready = (async () => {
|
||||
let empty = 0;
|
||||
for (const s of document.querySelectorAll('.slot[data-src]')) {
|
||||
let ok = false;
|
||||
for (const ext of ['jpg', 'jpeg', 'png', 'webp']) {
|
||||
const url = s.dataset.src + '.' + ext;
|
||||
ok = await new Promise(r => { const i = new Image(); i.onload = () => r(true); i.onerror = () => r(false); i.src = url; });
|
||||
if (ok) { s.style.backgroundImage = 'url("' + url + '")'; s.classList.add('filled'); break; }
|
||||
}
|
||||
if (!ok) empty++;
|
||||
}
|
||||
await document.fonts.ready;
|
||||
for (const el of document.querySelectorAll('[data-fit]')) {
|
||||
let fs = parseFloat(getComputedStyle(el).fontSize);
|
||||
const max = el.dataset.fit ? parseFloat(el.dataset.fit) : el.parentElement.clientWidth;
|
||||
while (el.scrollWidth > max && fs > 10) { fs -= 0.5; el.style.fontSize = fs + 'px'; }
|
||||
}
|
||||
if (window.afterLayout) await window.afterLayout();
|
||||
return empty;
|
||||
})();
|
||||
</script></body></html>
|
||||
@@ -0,0 +1,24 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../styles.css"><style></style></head><body><div class="hdr" id="shot"><div class="tabs"><span></span><span></span><span></span><span></span><span></span></div><div class="mark"><svg viewBox="0 0 40 40" fill="none" aria-hidden="true"><circle cx="20" cy="20" r="17.5" stroke="#efe9db" stroke-width="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></div><div class="badge"><span class="emoji">❤️</span></div><div style="min-width:0;flex:1"><div class="kicker">We Own AI — The New American Dream</div><h1 data-fit>Why this book</h1></div><div class="rule"></div></div>
|
||||
<script>
|
||||
window.__ready = (async () => {
|
||||
let empty = 0;
|
||||
for (const s of document.querySelectorAll('.slot[data-src]')) {
|
||||
let ok = false;
|
||||
for (const ext of ['jpg', 'jpeg', 'png', 'webp']) {
|
||||
const url = s.dataset.src + '.' + ext;
|
||||
ok = await new Promise(r => { const i = new Image(); i.onload = () => r(true); i.onerror = () => r(false); i.src = url; });
|
||||
if (ok) { s.style.backgroundImage = 'url("' + url + '")'; s.classList.add('filled'); break; }
|
||||
}
|
||||
if (!ok) empty++;
|
||||
}
|
||||
await document.fonts.ready;
|
||||
for (const el of document.querySelectorAll('[data-fit]')) {
|
||||
let fs = parseFloat(getComputedStyle(el).fontSize);
|
||||
const max = el.dataset.fit ? parseFloat(el.dataset.fit) : el.parentElement.clientWidth;
|
||||
while (el.scrollWidth > max && fs > 10) { fs -= 0.5; el.style.fontSize = fs + 'px'; }
|
||||
}
|
||||
if (window.afterLayout) await window.afterLayout();
|
||||
return empty;
|
||||
})();
|
||||
</script></body></html>
|
||||
@@ -0,0 +1,30 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../styles.css"><style>
|
||||
.g{display:grid;grid-template-columns:1fr 1fr;gap:14px}
|
||||
.c{padding:20px 22px 22px}
|
||||
.il{width:120px;height:84px;margin:0 0 12px -6px}
|
||||
.c h3{font-family:var(--display);font-weight:600;font-size:21px;letter-spacing:-.02em;line-height:1.15;margin-bottom:8px}
|
||||
.c p{font-size:15px;line-height:1.5;color:var(--muted)}
|
||||
</style></head><body><div class="canvas" id="shot"><div class="g"><div class="card c"><div class="il"><svg viewBox="0 0 120 84" fill="none" stroke="#1c5d4c" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><g transform="rotate(-8 60 50)"><rect x="26" y="34" width="62" height="40" rx="3" fill="#fff"/></g><g transform="rotate(5 60 46)"><rect x="30" y="26" width="62" height="40" rx="3" fill="#fff"/></g><rect x="28" y="14" width="62" height="44" rx="3" fill="#fff"/><path d="M36 23h30" stroke="#b4791f" stroke-width="3"/><path d="M36 31h46M36 37h46M36 43h32M36 49h40" stroke="#d8d1c4"/><rect x="72" y="20" width="12" height="8" rx="1.5" stroke-width="1.6"/></svg></div><h3>Too much noise</h3><p>Each week brings a new tool and a new prediction, and very little of it fits a real client file.</p></div><div class="card c"><div class="il"><svg viewBox="0 0 120 84" fill="none" stroke="#1c5d4c" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="18" y="12" width="84" height="60" rx="5" fill="#fff"/><path d="M18 24h84"/><circle cx="26" cy="18" r="1.8" fill="#d8d1c4" stroke="none"/><circle cx="32" cy="18" r="1.8" fill="#d8d1c4" stroke="none"/><circle cx="38" cy="18" r="1.8" fill="#d8d1c4" stroke="none"/><path d="M28 34h22M28 41h16M28 48h20M28 55h12" stroke="#d8d1c4"/><rect x="62" y="42" width="26" height="21" rx="3" fill="#fff" stroke="#b4791f" stroke-width="2.4"/><path d="M67 42v-5a8 8 0 0 1 16 0v5" stroke="#b4791f" stroke-width="2.4"/><path d="M75 50v5" stroke="#b4791f" stroke-width="2.4"/></svg></div><h3>Processes you don’t control</h3><p>When your process lives inside a vendor’s product, a price change or a feature change can undo it.</p></div><div class="card c"><div class="il"><svg viewBox="0 0 120 84" fill="none" stroke="#1c5d4c" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="54" cy="44" r="30" fill="#fff"/><path d="M54 17v5" transform="rotate(0 54 44)" stroke="#1c5d4c"/><path d="M54 18.5v3" transform="rotate(30 54 44)" stroke="#d8d1c4"/><path d="M54 18.5v3" transform="rotate(60 54 44)" stroke="#d8d1c4"/><path d="M54 17v5" transform="rotate(90 54 44)" stroke="#1c5d4c"/><path d="M54 18.5v3" transform="rotate(120 54 44)" stroke="#d8d1c4"/><path d="M54 18.5v3" transform="rotate(150 54 44)" stroke="#d8d1c4"/><path d="M54 17v5" transform="rotate(180 54 44)" stroke="#1c5d4c"/><path d="M54 18.5v3" transform="rotate(210 54 44)" stroke="#d8d1c4"/><path d="M54 18.5v3" transform="rotate(240 54 44)" stroke="#d8d1c4"/><path d="M54 17v5" transform="rotate(270 54 44)" stroke="#1c5d4c"/><path d="M54 18.5v3" transform="rotate(300 54 44)" stroke="#d8d1c4"/><path d="M54 18.5v3" transform="rotate(330 54 44)" stroke="#d8d1c4"/><path d="M54 44 44.5 28.5" stroke-width="3"/><path d="M54 44V21" stroke-width="2.2"/><circle cx="54" cy="44" r="2.4" fill="#1c5d4c" stroke="none"/><path d="M99 14a9 9 0 1 0 8 13 7 7 0 0 1-8-13z" fill="#fbf1e0" stroke="#b4791f"/></svg></div><h3>No time to learn</h3><p>The job already takes up the evenings, and learning AI on top of it feels like a second job.</p></div><div class="card c"><div class="il"><svg viewBox="0 0 120 84" fill="none" stroke="#1c5d4c" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M38 50V24a8 8 0 0 1 8-8h28a8 8 0 0 1 8 8v26" fill="#fff"/><path d="M30 44a6 6 0 0 1 12 0v8h36v-8a6 6 0 0 1 12 0v18a3 3 0 0 1-3 3H33a3 3 0 0 1-3-3z" fill="#fff"/><path d="M42 52h36"/><path d="M36 65v8M84 65v8"/><path d="M48 30h24" stroke="#d8d1c4"/><path d="M14 73h92" stroke="#d8d1c4"/></svg></div><h3>Clients are changing</h3><p>Firms and clients are changing how they work faster than most playbooks are updated.</p></div></div></div>
|
||||
<script>
|
||||
window.__ready = (async () => {
|
||||
let empty = 0;
|
||||
for (const s of document.querySelectorAll('.slot[data-src]')) {
|
||||
let ok = false;
|
||||
for (const ext of ['jpg', 'jpeg', 'png', 'webp']) {
|
||||
const url = s.dataset.src + '.' + ext;
|
||||
ok = await new Promise(r => { const i = new Image(); i.onload = () => r(true); i.onerror = () => r(false); i.src = url; });
|
||||
if (ok) { s.style.backgroundImage = 'url("' + url + '")'; s.classList.add('filled'); break; }
|
||||
}
|
||||
if (!ok) empty++;
|
||||
}
|
||||
await document.fonts.ready;
|
||||
for (const el of document.querySelectorAll('[data-fit]')) {
|
||||
let fs = parseFloat(getComputedStyle(el).fontSize);
|
||||
const max = el.dataset.fit ? parseFloat(el.dataset.fit) : el.parentElement.clientWidth;
|
||||
while (el.scrollWidth > max && fs > 10) { fs -= 0.5; el.style.fontSize = fs + 'px'; }
|
||||
}
|
||||
if (window.afterLayout) await window.afterLayout();
|
||||
return empty;
|
||||
})();
|
||||
</script></body></html>
|
||||
@@ -0,0 +1,24 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../styles.css"><style></style></head><body><div class="hdr" id="shot"><div class="tabs"><span></span><span></span><span></span><span></span><span></span></div><div class="mark"><svg viewBox="0 0 40 40" fill="none" aria-hidden="true"><circle cx="20" cy="20" r="17.5" stroke="#efe9db" stroke-width="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></div><div class="badge"><span class="emoji">🎯</span></div><div style="min-width:0;flex:1"><div class="kicker">We Own AI — The New American Dream</div><h1 data-fit>Who it’s for</h1></div><div class="rule"></div></div>
|
||||
<script>
|
||||
window.__ready = (async () => {
|
||||
let empty = 0;
|
||||
for (const s of document.querySelectorAll('.slot[data-src]')) {
|
||||
let ok = false;
|
||||
for (const ext of ['jpg', 'jpeg', 'png', 'webp']) {
|
||||
const url = s.dataset.src + '.' + ext;
|
||||
ok = await new Promise(r => { const i = new Image(); i.onload = () => r(true); i.onerror = () => r(false); i.src = url; });
|
||||
if (ok) { s.style.backgroundImage = 'url("' + url + '")'; s.classList.add('filled'); break; }
|
||||
}
|
||||
if (!ok) empty++;
|
||||
}
|
||||
await document.fonts.ready;
|
||||
for (const el of document.querySelectorAll('[data-fit]')) {
|
||||
let fs = parseFloat(getComputedStyle(el).fontSize);
|
||||
const max = el.dataset.fit ? parseFloat(el.dataset.fit) : el.parentElement.clientWidth;
|
||||
while (el.scrollWidth > max && fs > 10) { fs -= 0.5; el.style.fontSize = fs + 'px'; }
|
||||
}
|
||||
if (window.afterLayout) await window.afterLayout();
|
||||
return empty;
|
||||
})();
|
||||
</script></body></html>
|
||||
@@ -0,0 +1,41 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../styles.css"><style>
|
||||
.two{display:grid;grid-template-columns:1fr 1fr;gap:14px;margin-top:12px}
|
||||
.a{padding:24px 24px 26px;border-top:4px solid var(--pine)}
|
||||
.ico.big{width:60px;height:60px;padding:14px;border-radius:14px;background:var(--pine-wash);border:1px solid var(--pine-tint);display:block;margin-bottom:18px}
|
||||
.a h3{font-family:var(--display);font-weight:900;font-size:28px;letter-spacing:-.025em;line-height:1.08}
|
||||
.a .k{font-family:var(--mono);font-size:15px;font-weight:600;letter-spacing:.02em;color:var(--pine);margin-top:10px;background:var(--pine-wash);border:1px solid var(--pine-tint);display:inline-block;padding:5px 12px;border-radius:999px}
|
||||
.b{margin-top:12px;padding:16px 22px;display:flex;align-items:center;gap:16px}
|
||||
.ico.mid{width:44px;height:44px;padding:10px;border-radius:12px;background:var(--paper-2);border:1px solid var(--line);color:var(--muted)}
|
||||
.b h3{font-family:var(--display);font-weight:600;font-size:20px;letter-spacing:-.02em}
|
||||
</style></head><body><div class="canvas" id="shot">
|
||||
<p class="spec">Mainly for</p>
|
||||
<div class="two">
|
||||
<div class="card a"><span class="ico big"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="5" y="3.5" width="14" height="17" rx="2"/><path d="M8 7h8v3H8z"/><path d="M8.5 13.5h.01M12 13.5h.01M15.5 13.5h.01M8.5 17h.01M12 17h.01M15.5 17h.01"/></svg></span><h3>Accounting advisors</h3><p class="k">Exit to Client</p></div>
|
||||
<div class="card a"><span class="ico big"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M4 20h16"/><path d="M6.5 16.5v-4M11 16.5V8.5M15.5 16.5v-6"/><path d="m5.5 9 5-4 4 3 4-3.5"/></svg></span><h3>Financial advisors</h3><p class="k">CKA® and CEPA® focus</p></div>
|
||||
</div>
|
||||
<p class="spec" style="margin-top:20px">Also for</p>
|
||||
<div class="card b"><span class="ico mid"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3" y="7.5" width="18" height="12" rx="2"/><path d="M9 7.5V6a1.5 1.5 0 0 1 1.5-1.5h3A1.5 1.5 0 0 1 15 6v1.5"/><path d="M3 12.5h18"/></svg></span><h3>Other professionals who advise clients</h3></div>
|
||||
</div>
|
||||
<script>
|
||||
window.__ready = (async () => {
|
||||
let empty = 0;
|
||||
for (const s of document.querySelectorAll('.slot[data-src]')) {
|
||||
let ok = false;
|
||||
for (const ext of ['jpg', 'jpeg', 'png', 'webp']) {
|
||||
const url = s.dataset.src + '.' + ext;
|
||||
ok = await new Promise(r => { const i = new Image(); i.onload = () => r(true); i.onerror = () => r(false); i.src = url; });
|
||||
if (ok) { s.style.backgroundImage = 'url("' + url + '")'; s.classList.add('filled'); break; }
|
||||
}
|
||||
if (!ok) empty++;
|
||||
}
|
||||
await document.fonts.ready;
|
||||
for (const el of document.querySelectorAll('[data-fit]')) {
|
||||
let fs = parseFloat(getComputedStyle(el).fontSize);
|
||||
const max = el.dataset.fit ? parseFloat(el.dataset.fit) : el.parentElement.clientWidth;
|
||||
while (el.scrollWidth > max && fs > 10) { fs -= 0.5; el.style.fontSize = fs + 'px'; }
|
||||
}
|
||||
if (window.afterLayout) await window.afterLayout();
|
||||
return empty;
|
||||
})();
|
||||
</script></body></html>
|
||||
@@ -0,0 +1,24 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../styles.css"><style></style></head><body><div class="hdr" id="shot"><div class="tabs"><span></span><span></span><span></span><span></span><span></span></div><div class="mark"><svg viewBox="0 0 40 40" fill="none" aria-hidden="true"><circle cx="20" cy="20" r="17.5" stroke="#efe9db" stroke-width="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></div><div class="badge"><span class="emoji">📖</span></div><div style="min-width:0;flex:1"><div class="kicker">We Own AI — The New American Dream</div><h1 data-fit>What’s inside</h1></div><div class="rule"></div></div>
|
||||
<script>
|
||||
window.__ready = (async () => {
|
||||
let empty = 0;
|
||||
for (const s of document.querySelectorAll('.slot[data-src]')) {
|
||||
let ok = false;
|
||||
for (const ext of ['jpg', 'jpeg', 'png', 'webp']) {
|
||||
const url = s.dataset.src + '.' + ext;
|
||||
ok = await new Promise(r => { const i = new Image(); i.onload = () => r(true); i.onerror = () => r(false); i.src = url; });
|
||||
if (ok) { s.style.backgroundImage = 'url("' + url + '")'; s.classList.add('filled'); break; }
|
||||
}
|
||||
if (!ok) empty++;
|
||||
}
|
||||
await document.fonts.ready;
|
||||
for (const el of document.querySelectorAll('[data-fit]')) {
|
||||
let fs = parseFloat(getComputedStyle(el).fontSize);
|
||||
const max = el.dataset.fit ? parseFloat(el.dataset.fit) : el.parentElement.clientWidth;
|
||||
while (el.scrollWidth > max && fs > 10) { fs -= 0.5; el.style.fontSize = fs + 'px'; }
|
||||
}
|
||||
if (window.afterLayout) await window.afterLayout();
|
||||
return empty;
|
||||
})();
|
||||
</script></body></html>
|
||||
@@ -0,0 +1,48 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../styles.css"><style>
|
||||
.rg{display:grid;grid-template-columns:250px 34px 1fr;margin-top:16px;align-items:stretch}
|
||||
.ptop{background:linear-gradient(#fff,var(--paper));border:1px solid var(--line);border-bottom:1px solid var(--line);border-radius:16px 16px 0 0;padding:12px 16px;display:flex;justify-content:space-between;align-items:center}
|
||||
.ptop span{font-family:var(--mono);font-size:12px;color:var(--muted)}
|
||||
.ptop em{font-style:normal;font-family:var(--mono);font-size:11px;letter-spacing:.1em;text-transform:uppercase;color:var(--pine);background:var(--pine-wash);border:1px solid var(--pine-tint);padding:3px 9px;border-radius:999px}
|
||||
.pc{background:#fff;border-left:1px solid var(--line);border-right:1px solid var(--line);padding:11px 30px 11px 16px;position:relative;display:flex;flex-direction:column;justify-content:center;gap:7px;border-top:1px dashed var(--line-2)}
|
||||
.pc.first{border-top:none;padding-top:16px}
|
||||
.pc.last{border-bottom:1px solid var(--line);border-radius:0 0 16px 16px;padding-bottom:16px}
|
||||
.pc .k{font-family:var(--mono);font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--pine)}
|
||||
.bars{display:flex;flex-direction:column;gap:5px}
|
||||
.bars i{display:block;height:6px;border-radius:3px;background:#ece6db}
|
||||
.bars .term{display:block;height:20px;border-radius:5px;background:#14110e}
|
||||
.bars .pill{display:block;width:70px;height:14px;border-radius:999px;background:rgba(180,121,31,.14);border:1px solid rgba(180,121,31,.3)}
|
||||
.bars .gd{display:block;height:6px;border-radius:3px;background:linear-gradient(90deg,var(--pine) 0 8px,transparent 8px 14px,#ece6db 14px);width:86%}
|
||||
.pc .n{position:absolute;right:-13px;top:50%;transform:translateY(-50%);width:26px;height:26px;border-radius:999px;background:var(--pine);color:#fff;font-family:var(--mono);font-size:13px;font-weight:600;display:grid;place-items:center;box-shadow:0 0 0 3px var(--paper-2);z-index:2}
|
||||
.ln{position:relative}.ln::before{content:"";position:absolute;left:13px;right:4px;top:50%;border-top:1.5px solid var(--pine);opacity:.5}
|
||||
.co{padding:8px 0 8px 4px;display:flex;flex-direction:column;justify-content:center}
|
||||
.co h4{font-weight:700;font-size:16px;line-height:1.25}
|
||||
.co p{font-size:14px;line-height:1.42;color:var(--muted);margin-top:2px}
|
||||
</style></head><body><div class="canvas" id="shot">
|
||||
<p class="spec">Every workflow follows the same recipe</p>
|
||||
<div class="rg">
|
||||
<div class="ptop"><span>Workflow page</span><em>~15 min</em></div><div></div><div></div>
|
||||
<div class="pc first"><span class="k">Problem</span><span class="bars"><i style="width:88%"></i><i style="width:64%"></i></span><b class="n">1</b></div><div class="ln"></div><div class="co"><h4>The problem</h4><p>The real task it solves.</p></div><div class="pc"><span class="k">Who runs it</span><span class="bars"><i style="width:88%"></i><i style="width:64%"></i></span><b class="n">2</b></div><div class="ln"></div><div class="co"><h4>Who runs it</h4><p>A person, a role, or an AI agent working under a person’s supervision.</p></div><div class="pc"><span class="k">Setup</span><span class="bars"><i style="width:88%"></i><i style="width:64%"></i></span><b class="n">3</b></div><div class="ln"></div><div class="co"><h4>Setup</h4><p>The tools, sample files, and expected cost.</p></div><div class="pc"><span class="k">Safeguards</span><span class="bars"><span class="gd"></span><span class="gd"></span></span><b class="n">4</b></div><div class="ln"></div><div class="co"><h4>Safeguards</h4><p>How to handle client data, where a person must review the work, and what can go wrong. These come before the steps.</p></div><div class="pc"><span class="k">Steps</span><span class="bars"><i style="width:80%"></i><span class="term"></span></span><b class="n">5</b></div><div class="ln"></div><div class="co"><h4>The steps</h4><p>With the actual output the tools produced.</p></div><div class="pc"><span class="k">Evidence</span><span class="bars"><i style="width:88%"></i><i style="width:64%"></i></span><b class="n">6</b></div><div class="ln"></div><div class="co"><h4>Evidence</h4><p>What the result looked like when we ran it.</p></div><div class="pc"><span class="k">Try it</span><span class="bars"><i style="width:72%"></i><span class="pill"></span></span><b class="n">7</b></div><div class="ln"></div><div class="co"><h4>Try it</h4><p>A short exercise of about 15 minutes, using sample data.</p></div><div class="pc last"><span class="k">Record</span><span class="bars"><i style="width:88%"></i><i style="width:64%"></i></span><b class="n">8</b></div><div class="ln"></div><div class="co"><h4>Costs, author, and sources</h4></div>
|
||||
</div></div>
|
||||
<script>
|
||||
window.__ready = (async () => {
|
||||
let empty = 0;
|
||||
for (const s of document.querySelectorAll('.slot[data-src]')) {
|
||||
let ok = false;
|
||||
for (const ext of ['jpg', 'jpeg', 'png', 'webp']) {
|
||||
const url = s.dataset.src + '.' + ext;
|
||||
ok = await new Promise(r => { const i = new Image(); i.onload = () => r(true); i.onerror = () => r(false); i.src = url; });
|
||||
if (ok) { s.style.backgroundImage = 'url("' + url + '")'; s.classList.add('filled'); break; }
|
||||
}
|
||||
if (!ok) empty++;
|
||||
}
|
||||
await document.fonts.ready;
|
||||
for (const el of document.querySelectorAll('[data-fit]')) {
|
||||
let fs = parseFloat(getComputedStyle(el).fontSize);
|
||||
const max = el.dataset.fit ? parseFloat(el.dataset.fit) : el.parentElement.clientWidth;
|
||||
while (el.scrollWidth > max && fs > 10) { fs -= 0.5; el.style.fontSize = fs + 'px'; }
|
||||
}
|
||||
if (window.afterLayout) await window.afterLayout();
|
||||
return empty;
|
||||
})();
|
||||
</script></body></html>
|
||||
@@ -0,0 +1,30 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../styles.css"><style>
|
||||
.tg{display:grid;grid-template-columns:repeat(3,1fr);gap:12px;margin-top:14px}
|
||||
.t{padding:16px 16px 18px;display:flex;flex-direction:column}
|
||||
.t .n{font-family:var(--mono);font-size:13px;color:var(--pine);letter-spacing:.08em}
|
||||
.t h3{font-family:var(--display);font-weight:600;font-size:21px;letter-spacing:-.02em;line-height:1.12;margin:10px 0 6px}
|
||||
.t p{font-size:14px;line-height:1.4;color:var(--muted)}
|
||||
</style></head><body><div class="canvas" id="shot"><p class="spec">The founding library</p><div class="tg"><div class="card t"><span class="n">01</span><h3>Real Estate</h3><p>Market briefs & listings, without leaking client data</p></div><div class="card t"><span class="n">02</span><h3>Financial Advisors</h3><p>Portfolio summaries that stay compliant & reviewed</p></div><div class="card t"><span class="n">03</span><h3>Fractional <span style="white-space:nowrap">C-Suite</span></h3><p>Board updates & plans with real escalation paths</p></div><div class="card t"><span class="n">04</span><h3>Higher Education</h3><p>Course & research workflows with academic integrity</p></div><div class="card t"><span class="n">05</span><h3>Communities</h3><p>Moderation & programming that respects members</p></div><div class="card t"><span class="n">06</span><h3>Technology</h3><p>Agent patterns, evals & the responsible defaults</p></div></div></div>
|
||||
<script>
|
||||
window.__ready = (async () => {
|
||||
let empty = 0;
|
||||
for (const s of document.querySelectorAll('.slot[data-src]')) {
|
||||
let ok = false;
|
||||
for (const ext of ['jpg', 'jpeg', 'png', 'webp']) {
|
||||
const url = s.dataset.src + '.' + ext;
|
||||
ok = await new Promise(r => { const i = new Image(); i.onload = () => r(true); i.onerror = () => r(false); i.src = url; });
|
||||
if (ok) { s.style.backgroundImage = 'url("' + url + '")'; s.classList.add('filled'); break; }
|
||||
}
|
||||
if (!ok) empty++;
|
||||
}
|
||||
await document.fonts.ready;
|
||||
for (const el of document.querySelectorAll('[data-fit]')) {
|
||||
let fs = parseFloat(getComputedStyle(el).fontSize);
|
||||
const max = el.dataset.fit ? parseFloat(el.dataset.fit) : el.parentElement.clientWidth;
|
||||
while (el.scrollWidth > max && fs > 10) { fs -= 0.5; el.style.fontSize = fs + 'px'; }
|
||||
}
|
||||
if (window.afterLayout) await window.afterLayout();
|
||||
return empty;
|
||||
})();
|
||||
</script></body></html>
|
||||
@@ -0,0 +1,24 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../styles.css"><style></style></head><body><div class="hdr" id="shot"><div class="tabs"><span></span><span></span><span></span><span></span><span></span></div><div class="mark"><svg viewBox="0 0 40 40" fill="none" aria-hidden="true"><circle cx="20" cy="20" r="17.5" stroke="#efe9db" stroke-width="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></div><div class="badge"><span class="emoji">🧪</span></div><div style="min-width:0;flex:1"><div class="kicker">We Own AI — The New American Dream</div><h1 data-fit>Try one workflow</h1></div><div class="rule"></div></div>
|
||||
<script>
|
||||
window.__ready = (async () => {
|
||||
let empty = 0;
|
||||
for (const s of document.querySelectorAll('.slot[data-src]')) {
|
||||
let ok = false;
|
||||
for (const ext of ['jpg', 'jpeg', 'png', 'webp']) {
|
||||
const url = s.dataset.src + '.' + ext;
|
||||
ok = await new Promise(r => { const i = new Image(); i.onload = () => r(true); i.onerror = () => r(false); i.src = url; });
|
||||
if (ok) { s.style.backgroundImage = 'url("' + url + '")'; s.classList.add('filled'); break; }
|
||||
}
|
||||
if (!ok) empty++;
|
||||
}
|
||||
await document.fonts.ready;
|
||||
for (const el of document.querySelectorAll('[data-fit]')) {
|
||||
let fs = parseFloat(getComputedStyle(el).fontSize);
|
||||
const max = el.dataset.fit ? parseFloat(el.dataset.fit) : el.parentElement.clientWidth;
|
||||
while (el.scrollWidth > max && fs > 10) { fs -= 0.5; el.style.fontSize = fs + 'px'; }
|
||||
}
|
||||
if (window.afterLayout) await window.afterLayout();
|
||||
return empty;
|
||||
})();
|
||||
</script></body></html>
|
||||
@@ -0,0 +1,41 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../styles.css"><style>
|
||||
.win{background:var(--paper);border:1px solid var(--line-2);border-radius:14px;overflow:hidden;box-shadow:var(--sh-lg)}
|
||||
.bar{display:flex;align-items:center;gap:7px;padding:10px 14px;background:#f1eee7;border-bottom:1px solid var(--line)}
|
||||
.bar i{width:11px;height:11px;border-radius:999px;background:#d8d1c4;display:block}
|
||||
.bar .url{margin-left:14px;flex:1;background:#fff;border:1px solid var(--line);border-radius:999px;padding:4px 14px;font-family:var(--mono);font-size:13px;color:var(--muted)}
|
||||
.win img{display:block;width:614px}
|
||||
.gap{padding:10px 0;text-align:center;background:linear-gradient(transparent calc(50% - 1px),var(--line-2) calc(50% - 1px) calc(50% + 1px),transparent calc(50% + 1px))}
|
||||
.gap span{font-family:var(--mono);font-size:12.5px;color:var(--muted);background:var(--paper);padding:2px 10px;letter-spacing:.02em}
|
||||
.foot-note{text-align:center}
|
||||
</style></head><body><div class="canvas" id="shot">
|
||||
<div class="win">
|
||||
<div class="bar"><i></i><i></i><i></i><span class="url">aibook.fun/read/recipe/RE-01</span></div>
|
||||
<img src="../assets-gen/re01-top.png" alt="">
|
||||
<div class="gap"><span>Problem · Actors · Setup · Safeguards · Method · Evidence</span></div>
|
||||
<img src="../assets-gen/re01-tryit.png" alt="">
|
||||
</div>
|
||||
<p class="foot-note">Screenshots of sample workflow RE-01 at aibook.fun/read/recipe/RE-01</p>
|
||||
</div>
|
||||
<script>
|
||||
window.__ready = (async () => {
|
||||
let empty = 0;
|
||||
for (const s of document.querySelectorAll('.slot[data-src]')) {
|
||||
let ok = false;
|
||||
for (const ext of ['jpg', 'jpeg', 'png', 'webp']) {
|
||||
const url = s.dataset.src + '.' + ext;
|
||||
ok = await new Promise(r => { const i = new Image(); i.onload = () => r(true); i.onerror = () => r(false); i.src = url; });
|
||||
if (ok) { s.style.backgroundImage = 'url("' + url + '")'; s.classList.add('filled'); break; }
|
||||
}
|
||||
if (!ok) empty++;
|
||||
}
|
||||
await document.fonts.ready;
|
||||
for (const el of document.querySelectorAll('[data-fit]')) {
|
||||
let fs = parseFloat(getComputedStyle(el).fontSize);
|
||||
const max = el.dataset.fit ? parseFloat(el.dataset.fit) : el.parentElement.clientWidth;
|
||||
while (el.scrollWidth > max && fs > 10) { fs -= 0.5; el.style.fontSize = fs + 'px'; }
|
||||
}
|
||||
if (window.afterLayout) await window.afterLayout();
|
||||
return empty;
|
||||
})();
|
||||
</script></body></html>
|
||||
@@ -0,0 +1,32 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../styles.css"><style>
|
||||
.canvas{padding:26px 32px 24px}
|
||||
.cta{text-align:center}
|
||||
.b{display:inline-flex;align-items:center;gap:12px;background:var(--pine);color:#f7fbf9;font-weight:700;font-size:24px;letter-spacing:-.01em;border-radius:999px;padding:18px 34px;box-shadow:0 10px 24px -10px rgba(28,93,76,.6)}
|
||||
.b svg{width:24px;height:24px}
|
||||
.cta p{font-family:var(--mono);font-size:14px;color:var(--muted);letter-spacing:.03em;margin-top:14px}
|
||||
</style></head><body><div class="canvas" id="shot">
|
||||
<div class="cta"><span class="b">Try the sample workflow <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M5 12h14M13 6l6 6-6 6"/></svg></span>
|
||||
<p>Free · about 15 minutes · sample data · aibook.fun</p></div></div>
|
||||
<script>
|
||||
window.__ready = (async () => {
|
||||
let empty = 0;
|
||||
for (const s of document.querySelectorAll('.slot[data-src]')) {
|
||||
let ok = false;
|
||||
for (const ext of ['jpg', 'jpeg', 'png', 'webp']) {
|
||||
const url = s.dataset.src + '.' + ext;
|
||||
ok = await new Promise(r => { const i = new Image(); i.onload = () => r(true); i.onerror = () => r(false); i.src = url; });
|
||||
if (ok) { s.style.backgroundImage = 'url("' + url + '")'; s.classList.add('filled'); break; }
|
||||
}
|
||||
if (!ok) empty++;
|
||||
}
|
||||
await document.fonts.ready;
|
||||
for (const el of document.querySelectorAll('[data-fit]')) {
|
||||
let fs = parseFloat(getComputedStyle(el).fontSize);
|
||||
const max = el.dataset.fit ? parseFloat(el.dataset.fit) : el.parentElement.clientWidth;
|
||||
while (el.scrollWidth > max && fs > 10) { fs -= 0.5; el.style.fontSize = fs + 'px'; }
|
||||
}
|
||||
if (window.afterLayout) await window.afterLayout();
|
||||
return empty;
|
||||
})();
|
||||
</script></body></html>
|
||||
@@ -0,0 +1,24 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../styles.css"><style></style></head><body><div class="hdr" id="shot"><div class="tabs"><span></span><span></span><span></span><span></span><span></span></div><div class="mark"><svg viewBox="0 0 40 40" fill="none" aria-hidden="true"><circle cx="20" cy="20" r="17.5" stroke="#efe9db" stroke-width="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></div><div class="badge"><span class="emoji">🧭</span></div><div style="min-width:0;flex:1"><div class="kicker">We Own AI — The New American Dream</div><h1 data-fit>Three ways to back</h1></div><div class="rule"></div></div>
|
||||
<script>
|
||||
window.__ready = (async () => {
|
||||
let empty = 0;
|
||||
for (const s of document.querySelectorAll('.slot[data-src]')) {
|
||||
let ok = false;
|
||||
for (const ext of ['jpg', 'jpeg', 'png', 'webp']) {
|
||||
const url = s.dataset.src + '.' + ext;
|
||||
ok = await new Promise(r => { const i = new Image(); i.onload = () => r(true); i.onerror = () => r(false); i.src = url; });
|
||||
if (ok) { s.style.backgroundImage = 'url("' + url + '")'; s.classList.add('filled'); break; }
|
||||
}
|
||||
if (!ok) empty++;
|
||||
}
|
||||
await document.fonts.ready;
|
||||
for (const el of document.querySelectorAll('[data-fit]')) {
|
||||
let fs = parseFloat(getComputedStyle(el).fontSize);
|
||||
const max = el.dataset.fit ? parseFloat(el.dataset.fit) : el.parentElement.clientWidth;
|
||||
while (el.scrollWidth > max && fs > 10) { fs -= 0.5; el.style.fontSize = fs + 'px'; }
|
||||
}
|
||||
if (window.afterLayout) await window.afterLayout();
|
||||
return empty;
|
||||
})();
|
||||
</script></body></html>
|
||||
@@ -0,0 +1,83 @@
|
||||
<!doctype html><html lang="en"><head><meta charset="utf-8">
|
||||
<link rel="stylesheet" href="../styles.css"><style>
|
||||
.canvas{padding:28px 26px}
|
||||
.cols{display:grid;grid-template-rows:repeat(6,auto);column-gap:10px}
|
||||
.col{padding:18px 14px 16px;display:grid;grid-template-rows:subgrid;grid-row:span 6;min-width:0}
|
||||
.nm{font-family:var(--mono);font-size:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--pine);font-weight:600;line-height:1.35}
|
||||
.col h3{font-family:var(--display);font-weight:600;font-size:19px;letter-spacing:-.02em;line-height:1.15;margin:6px 0 10px}
|
||||
.sec{border-top:1px dashed var(--line-2);padding:10px 0 12px}
|
||||
.span2{grid-row:span 2}
|
||||
.lb{font-family:var(--mono);font-size:11.5px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-bottom:6px}
|
||||
.sec p{font-size:14px;line-height:1.4}
|
||||
.sec p.sm{font-size:13px;line-height:1.42;color:var(--ink)}
|
||||
.fact{display:flex;gap:7px;align-items:flex-start;margin-top:6px;font-weight:600}
|
||||
.lb+.fact{margin-top:0}
|
||||
.fact.cut{color:var(--amber)}
|
||||
.fact.cut .ico{color:var(--amber)}
|
||||
.fact .ico,.inc .ico{width:17px;height:17px;margin-top:1px}
|
||||
.inc li{display:flex;gap:7px;align-items:flex-start;font-size:14px;line-height:1.35;padding:2px 0}
|
||||
.pr{align-self:end}
|
||||
.price{font-family:var(--mono);font-size:12px;font-weight:600;color:var(--pine);background:var(--pine-wash);border:1px solid var(--pine-tint);border-radius:999px;padding:7px 6px;text-align:center;white-space:normal;line-height:1.3}
|
||||
.book,.build{border-color:rgba(28,93,76,.28)}
|
||||
.prices li{display:flex;flex-direction:column;gap:2px;padding:7px 9px;border-radius:10px;font-size:14px;line-height:1.35}
|
||||
.prices li+li{margin-top:4px}
|
||||
.prices b{font-family:var(--display);font-weight:900;font-size:24px;letter-spacing:-.03em;color:var(--ink);line-height:1.05}
|
||||
.prices li.pb{flex-direction:row;gap:10px;align-items:flex-start}
|
||||
.prices b.np{flex:none;width:30px;margin:2px 0 0}.prices b.np img{width:30px;display:block}
|
||||
.ch{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}
|
||||
.ch img{width:42px;border-radius:2px 4px 4px 2px;box-shadow:0 6px 12px -6px rgba(18,63,52,.5);margin:4px 0 8px;flex:none}
|
||||
.prices small{display:block;font-size:12.5px;color:var(--muted)}
|
||||
.prices li.feat{background:var(--pine);color:#eaf1ec}
|
||||
.prices li.feat b{color:#fff}
|
||||
.prices li.feat small{color:#cfe0d6}
|
||||
.bund .bt{display:flex;align-items:baseline;gap:8px}
|
||||
.bund .bt em{font-style:normal;font-family:var(--mono);font-size:12.5px;font-weight:600;letter-spacing:.08em;text-transform:uppercase;color:var(--pine)}
|
||||
.bund li.feat .bt em{color:#cfe0d6}
|
||||
.bund span{font-size:13.5px;line-height:1.4}
|
||||
.bund .tag{font-style:normal;align-self:flex-start;margin-top:5px;font-family:var(--mono);font-size:11.5px;font-weight:600;letter-spacing:.04em;background:var(--amber);color:#fff;border-radius:999px;padding:3px 9px}
|
||||
.dl li{font-size:14px;line-height:1.4;padding:2px 0 2px 14px;position:relative}
|
||||
.dl li::before{content:"";position:absolute;left:0;top:8px;width:6px;height:6px;border-radius:999px;background:var(--pine)}
|
||||
</style></head><body><div class="canvas" id="shot"><div class="cols" style="grid-template-columns:minmax(0,1.05fr) minmax(0,1.2fr) minmax(0,0.95fr)">
|
||||
<div class="col card book">
|
||||
<p class="nm">The book</p><div class="ch"><h3>The book and the AiBook.fun library</h3><img src="../assets-gen/cover-flat.png" alt=""></div>
|
||||
<div class="sec span2"><p class="lb">Choose one</p><ul class="prices"><li class=""><b>$19</b><span>Early Bird eBook<small>First 200 backers</small></span></li><li class=""><b>$25</b><span>eBook and backer-only updates</span></li><li class="feat"><b>$47</b><span>eBook and 12 months of the AiBook.fun library<small>Featured</small></span></li><li class="pb"><b class="np"><img src="../assets-gen/cover-3d.png" alt=""></b><span>Signed paperback and eBook<small>Price on the reward</small></span></li></ul></div>
|
||||
<div class="sec"><p class="lb">When</p><ul class="dl"><li>Library access: within about 14 days of a successful campaign</li><li>eBook: January 2027</li><li>Signed paperback: February 2027</li></ul></div>
|
||||
<div class="pr"></div>
|
||||
</div>
|
||||
<div class="col card build">
|
||||
<p class="nm">Build it yourself or with us</p><h3>AOP.biz bundles</h3>
|
||||
<div class="sec span2"><p class="lb">Choose one</p><ul class="prices bund"><li class=""><div class="bt"><b>$1,000</b><em>DIY</em></div><span>The starter pack on WeOwn Cloud, to run yourself. No support of any kind.</span></li><li class=""><div class="bt"><b>$2,000</b><em>Launch</em></div><span>Set up with our team: onboarding and a first implementation cycle, plus three months of AOP.biz service and the December 2026 cohort.</span></li><li class="feat"><div class="bt"><b>$5,000</b><em>Growth</em></div><span>Everything in Launch, plus deeper integration, more agents, ongoing support, and a Retreat seat.</span><i class="tag">Closes 20 Oct 2026</i></li></ul></div>
|
||||
<div class="sec"><p class="lb">After the pledge</p><p class="sm">AOP.biz service ($988 a month) and WeOwn Cloud hosting ($200 a month) are separate, optional agreements. Kickstarter charges your pledge once.</p></div>
|
||||
<div class="pr"></div>
|
||||
</div>
|
||||
<div class="col card">
|
||||
<p class="nm">In person</p><h3>Burned Out Advisor Retreat</h3>
|
||||
<div class="sec"><p class="lb">What it is</p><p>Three days in person with the authors and other advisors.</p>
|
||||
<p class="fact"><span class="ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="8" r="3"/><path d="M6.5 19c.6-3 2.8-4.8 5.5-4.8s4.9 1.8 5.5 4.8"/><circle cx="5" cy="10" r="2"/><circle cx="19" cy="10" r="2"/><path d="M2 17c.3-1.7 1.4-2.8 3-3M22 17c-.3-1.7-1.4-2.8-3-3"/></svg></span>369 seats</p></div>
|
||||
<div class="sec"><p class="lb">Includes</p><ul class="inc"><li><span class="ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M6 11V6.5A2.5 2.5 0 0 1 8.5 4h7A2.5 2.5 0 0 1 18 6.5V11"/><path d="M4 11.5a2 2 0 0 1 4 0V14h8v-2.5a2 2 0 0 1 4 0V17a1 1 0 0 1-1 1H5a1 1 0 0 1-1-1z"/><path d="M6.5 18v2M17.5 18v2"/></svg></span>Your seat</li><li><span class="ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 6.5C9.5 5 7 4.6 3.5 5v13c3.5-.4 6 0 8.5 1.5 2.5-1.5 5-1.9 8.5-1.5V5c-3.5-.4-6 0-8.5 1.5z"/><path d="M12 6.5v13"/></svg></span>A signed paperback</li><li><span class="ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M12 6.5C9.5 5 7 4.6 3.5 5v13c3.5-.4 6 0 8.5 1.5 2.5-1.5 5-1.9 8.5-1.5V5c-3.5-.4-6 0-8.5 1.5z"/><path d="M12 6.5v13"/></svg></span>The eBook</li><li><span class="ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3.5" y="4.5" width="17" height="12" rx="1.6"/><path d="M2 19.5h20"/><path d="M8 8.5h8M8 11.5h5"/></svg></span>12 months of AiBook.fun</li></ul></div>
|
||||
<div class="sec"><p class="lb">When</p><p class="fact"><span class="ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><rect x="3.5" y="5" width="17" height="15" rx="2"/><path d="M3.5 9.5h17M8 3v4M16 3v4"/><path d="M7.5 13h2M11 13h2M14.5 13h2M7.5 16.5h2M11 16.5h2"/></svg></span>4–6 November 2026</p><p class="fact cut"><span class="ico"><svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.7" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="8.5"/><path d="M12 7.5V12l3 2"/></svg></span>Closes 20 Oct 2026</p></div>
|
||||
<div class="pr"><p class="price">Price on the reward</p></div>
|
||||
</div>
|
||||
</div></div>
|
||||
<script>
|
||||
window.__ready = (async () => {
|
||||
let empty = 0;
|
||||
for (const s of document.querySelectorAll('.slot[data-src]')) {
|
||||
let ok = false;
|
||||
for (const ext of ['jpg', 'jpeg', 'png', 'webp']) {
|
||||
const url = s.dataset.src + '.' + ext;
|
||||
ok = await new Promise(r => { const i = new Image(); i.onload = () => r(true); i.onerror = () => r(false); i.src = url; });
|
||||
if (ok) { s.style.backgroundImage = 'url("' + url + '")'; s.classList.add('filled'); break; }
|
||||
}
|
||||
if (!ok) empty++;
|
||||
}
|
||||
await document.fonts.ready;
|
||||
for (const el of document.querySelectorAll('[data-fit]')) {
|
||||
let fs = parseFloat(getComputedStyle(el).fontSize);
|
||||
const max = el.dataset.fit ? parseFloat(el.dataset.fit) : el.parentElement.clientWidth;
|
||||
while (el.scrollWidth > max && fs > 10) { fs -= 0.5; el.style.fontSize = fs + 'px'; }
|
||||
}
|
||||
if (window.afterLayout) await window.afterLayout();
|
||||
return empty;
|
||||
})();
|
||||
</script></body></html>
|
||||