Author SHA1 Message Date
pat 788bff5d56 Story images: relabel Cloud column and section 9 header as Book & Library
- 06b/06c: third column label is now "Book & Library" with the heading
  "The book and the AiBook.fun library" (was "Cloud" / "Do it yourself,
  online"). Same size, cover image unchanged.
- 09 header renamed to 09-header-book-library-and-aibook-fun.png with the
  title "Book & Library and AiBook.fun" (was "Cloud and AiBook.fun").
- three_ways() builds the grid from a list of columns so a fourth bucket can
  be added later without a CSS change; three-column output is unchanged.
- Contact sheet and README updated.
2026-09-25 19:15:39 +01:00
pat 434a70c749 Rename the book reward bucket from Cloud to Book & Library in the guide and form pack
The book and library tiers ($19 Early Bird eBook, $25 eBook plus updates,
$47 eBook plus 12 months of AiBook.fun, $55 signed paperback, $85 Collector's
Bundle) were grouped under "Cloud". WeOwn Cloud is a separate product, so the
bucket is now "Book & Library" everywhere. Sentences that called Cloud the
do-it-yourself path now describe the Book & Library tiers plainly. Prices,
dates and other content are unchanged. The .docx is regenerated from the
fixed Markdown with v2/build_docx.py (same page map, 36 pages).
2026-09-25 19:15:39 +01:00
pat a69711227e Story images: sources for landing-page cover and live screenshots 2026-09-25 17:58:24 +00:00
pat 1685918c11 Use landing-page cover and real screenshots in story images 2026-09-25 17:58:22 +00:00
pat d05d283d6d Add Kickstarter story image HTML sources and build scripts 2026-09-25 17:36:23 +00:00
pat e5adccf279 Add Kickstarter story images README and contact sheet 2026-09-25 17:36:21 +00:00
pat 80af21801f Add Kickstarter story images 2026-09-25 17:36:18 +00:00
yonks 2938a7ac2a Add ks-research/KICKSTARTER_TOP10.md 2026-09-25 15:49:21 +00:00
pat 7ad62d3bfb Add Word version of Kickstarter campaign guide (v2) 2026-09-25 15:24:59 +00:00
pat b24a202502 Rewrite Kickstarter campaign guide (v2): clearer structure and plain copy 2026-09-25 15:24:57 +00:00
pat 02979dffac Add full Kickstarter campaign guide modeled on Onryo structure 2026-09-25 14:28:30 +00:00
pat 3b2f395bbf Add Retreat + Academy as live Kickstarter tiers (3-bucket rewards) 2026-09-23 13:58:49 +00:00
pat 920d53a729 Mark Kickstarter submit defaults owner-approved (23 Sep 2026) 2026-09-23 13:50:53 +00:00
pat a8b9925376 docs: mark Nonfiction subcategory confirmed from live Kickstarter UI 2026-09-23 13:25:58 +00:00
pat 4f8060ec37 docs: confirm live /start Publishing subcategories and country step 2026-09-23 13:25:56 +00:00
pat 762a6c0765 docs: sync filled KS pack with full editor tabs; keep recommended fills as working defaults 2026-09-23 13:25:19 +00:00
pat 11f78080e9 docs: deepen Kickstarter field inventory (full editor tab map) 2026-09-23 13:25:18 +00:00
pat d90a7b3a95 docs: complete filled Kickstarter form pack (paste-ready) 2026-09-23 13:20:41 +00:00
pat dccfc3b65d docs: Kickstarter project-creation field inventory 2026-09-23 13:20:40 +00:00
pat 83721c43b6 Update ks-campaign-blueprint.md 2026-09-22 13:33:42 +00:00
pat 1bd2c0cf5b Add ks-campaign-blueprint 2026-09-22 13:32:45 +00:00
pat 4c5579f66a docs: point writers at content guide; fix currency wording in README 2026-09-10 10:32:15 +00:00
pat 3f969207eb docs: link content management guide from README 2026-09-10 10:32:04 +00:00
pat 686e13b2cd docs: add content management and QA guide 2026-09-10 10:32:03 +00:00
pat 5c2bf88786 fix(marketing-site): keep output:'standalone' for docker deploy
deploy / deploy (push) Successful in 22s
2026-09-02 22:53:21 +00:00
pat d905e30701 chore: sync all local reading-demo changes to main
deploy / deploy (push) Failing after 2s
2026-09-02 22:52:49 +00:00
plt f23a623423 Merge pull request 'fix(marketing-site): restore output:'standalone' — required by docker deploy' (#6) from fix/restore-standalone-output into main
deploy / deploy (push) Successful in 19s
Reviewed-on: #6
2026-09-02 19:53:52 +00:00
dilonne 83ce4302c5 fix(marketing-site): restore output:'standalone' — required by docker deploy 2026-09-02 21:53:22 +02:00
plt 13a97ca0f8 Merge pull request 'ci(deploy): rewrite for build-on-droplet + local runner' (#5) from feat/ci-runner-setup into main
deploy / deploy (push) Failing after 28s
Reviewed-on: #5
2026-09-02 17:59:22 +00:00
plt f03fe7f232 Merge branch 'main' into feat/ci-runner-setup 2026-09-02 17:58:59 +00:00
dilonne f5a83507a6 ci(deploy): rewrite for build-on-droplet + local runner 2026-09-02 19:55:56 +02:00
pat 59201c9c29 chore: brand presentation is AiBook.fun
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 16:33:11 +00:00
pat 6390d81c82 chore: brand presentation is AiBook.fun
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 16:33:10 +00:00
pat 1a629bc087 chore: brand presentation is AiBook.fun
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 16:33:09 +00:00
pat 195baa32cc chore: brand presentation is AiBook.fun
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 16:33:08 +00:00
pat 5cf207c6c9 chore: brand presentation is AiBook.fun
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 16:33:07 +00:00
pat 6685694cc2 chore: brand presentation is AiBook.fun
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 16:33:05 +00:00
pat af6512d765 chore: brand presentation is AiBook.fun
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 16:33:04 +00:00
pat 91d58ab12e chore: brand presentation is AiBook.fun
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 16:33:03 +00:00
pat 031942700a chore: brand presentation is AiBook.fun
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 16:33:02 +00:00
pat 32e8ef4446 chore: brand presentation is AiBook.fun
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 16:33:01 +00:00
pat 5eb257c987 chore: brand presentation is AiBook.fun
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 16:32:59 +00:00
pat b653e8fac9 chore: brand presentation is AiBook.fun
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 16:32:58 +00:00
pat c80574a913 chore: brand presentation is AiBook.fun
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 16:32:57 +00:00
pat 1f06edee73 chore: brand presentation is AiBook.fun 2026-09-02 16:32:56 +00:00
pat faf5bb7a25 chore: brand presentation is AiBook.fun 2026-09-02 16:32:55 +00:00
pat efcd1b9bca chore: brand presentation is AiBook.fun 2026-09-02 16:32:54 +00:00
pat 648f6de91a chore: brand presentation is AiBook.fun 2026-09-02 16:32:53 +00:00
pat 79c5a42ed8 chore: brand presentation is AiBook.fun 2026-09-02 16:32:51 +00:00
pat f0f8f9b01f chore: sync marketing site and workflows with local reading demo
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 16:21:50 +00:00
pat ca2361cce0 fix(nav): center the section links in the bar
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 14:41:34 +00:00
pat b263715ee2 fix(site): drop dead Contents links from nav and footer
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 14:39:34 +00:00
pat 0fae769daa fix(site): drop dead Contents links from nav and footer
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 14:39:32 +00:00
pat 7a7181b79c feat(nav): Go to Library button on the marketing site
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 12:57:34 +00:00
pat 51d3d9a6ae feat(nav): Go to Library button on the marketing site
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 12:57:33 +00:00
pat 6173d478c7 copy(site): content updates continuously, not once a year
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 12:47:52 +00:00
pat 27cf3db62b copy(site): content updates continuously, not once a year
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 12:47:51 +00:00
pat d9ba89ce17 copy(site): content updates continuously, not once a year
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 12:47:50 +00:00
pat aa5c4ea09e copy(site): content updates continuously, not once a year
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 12:47:49 +00:00
pat e5f2f221bc copy(site): content updates continuously, not once a year
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 12:47:48 +00:00
pat 9b0ad976d8 copy(site): content updates continuously, not once a year
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 12:47:47 +00:00
pat d10a59434f copy(site): content updates continuously, not once a year
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 12:47:45 +00:00
pat a24a9f4277 copy(site): sharpen field notes into plain facts
deploy / build-and-deploy (push) Canceled after 0s
2026-09-02 12:19:47 +00:00
plt 84c59eb358 Merge pull request 'feat(deploy): aibook.fun deploy layer (terraform + ansible + docker on DO)' (#4) from feat/aibook-fun-deploy into main
deploy / build-and-deploy (push) Canceled after 0s
Reviewed-on: #4
2026-09-02 09:53:59 +00:00
plt 6f9843ff44 Merge branch 'main' into feat/aibook-fun-deploy 2026-09-02 09:51:34 +00:00
dilonne 8ef06cb3e7 feat(deploy): aibook.fun deploy layer (terraform + ansible + docker on DO) 2026-09-02 10:57:09 +02:00
pat e7da04ffb6 fix(site): give Fraunces section titles room to breathe 2026-09-02 05:58:39 +00:00
pat 30cf939eb7 copy(reader): Library page gets a title and a subtitle 2026-09-01 16:58:14 +00:00
pat 44c8fa2b43 copy(reader): write the library title like a person 2026-09-01 08:24:27 +00:00
pat b4f79661a1 fix(reader): keep library title on one line 2026-09-01 08:21:09 +00:00
pat 34d56b4dbb fix(reader): give library title room to breathe 2026-09-01 07:53:22 +00:00
pat b6bbd30415 fix(reader): Library in the nav, breadcrumbs in the chapter 2026-09-01 07:50:48 +00:00
pat c60448004f fix(reader): Library in the nav, breadcrumbs in the chapter 2026-09-01 07:50:47 +00:00
pat 1e143cf18a fix(reader): Library in the nav, breadcrumbs in the chapter 2026-09-01 07:50:46 +00:00
pat 4e447ca254 fix(reader): Library in the nav, breadcrumbs in the chapter 2026-09-01 07:50:45 +00:00
pat 2fca7dff4b fix(reader): Library in the nav, breadcrumbs in the chapter 2026-09-01 07:50:44 +00:00
pat 719f969443 fix(reader): Library in the nav, breadcrumbs in the chapter 2026-09-01 07:50:43 +00:00
pat 344be8b8f7 fix(reader): Library in the nav, breadcrumbs in the chapter 2026-09-01 07:50:42 +00:00
pat c488955c93 feat(reader): show workflow kit on chapter pages 2026-09-01 07:19:50 +00:00
pat 1daaea6148 feat(reader): show workflow kit on chapter pages 2026-09-01 07:19:49 +00:00
pat a85ad2e1d9 feat(reader): show workflow kit on chapter pages 2026-09-01 07:19:48 +00:00
pat 56988687cb feat(reader): show workflow kit on chapter pages 2026-09-01 07:19:47 +00:00
pat f80a6c2aca feat(reader): show workflow kit on chapter pages 2026-09-01 07:19:45 +00:00
pat 261ebe513f feat(reader): show workflow kit on chapter pages 2026-09-01 07:19:44 +00:00
pat 53a947e23d feat(reader): show workflow kit on chapter pages 2026-09-01 07:19:43 +00:00
pat 02697cd5f3 fix(library): start founding Real Estate sample at RE-01 2026-09-01 03:55:43 +00:00
pat 9638b58e7b fix(library): start founding Real Estate sample at RE-01 2026-09-01 03:55:42 +00:00
pat 203ab9394c fix(library): start founding Real Estate sample at RE-01 2026-09-01 03:55:41 +00:00
pat 84f64e6a00 fix(library): start founding Real Estate sample at RE-01 2026-09-01 03:55:40 +00:00
pat 4990a7e4c5 fix(library): start founding Real Estate sample at RE-01 2026-09-01 03:55:39 +00:00
pat 894de4d682 fix(library): start founding Real Estate sample at RE-01 2026-09-01 03:55:38 +00:00
pat f47b42e4a5 fix(reader): use full chapter width with workflow rail 2026-09-01 03:49:21 +00:00
pat 3f32886894 fix(reader): use full chapter width with workflow rail 2026-09-01 03:49:20 +00:00
pat dc9f3e27c6 fix(reader): use full chapter width with workflow rail 2026-09-01 03:49:19 +00:00
pat 7e98e19113 fix(reader): use full chapter width with workflow rail 2026-09-01 03:49:18 +00:00
pat ae1f1ab71b fix(reader): use full chapter width with workflow rail 2026-09-01 03:49:17 +00:00
pat abb2b65d2a Replace the chapter progress bar with an opaque outline 2026-09-01 03:44:10 +00:00
pat ae310ba1d3 Pass workflow index into the focus view 2026-09-01 03:44:09 +00:00
pat c1197a4f7f Show workflow count on ready library rows 2026-09-01 03:44:08 +00:00
pat b645d1bec2 Restructure the chapter shell around a visible outline 2026-09-01 03:44:06 +00:00
pat 8937061c49 Label nested workflows and add in-recipe jump links 2026-09-01 03:44:05 +00:00
pat d7c6a239c1 Add sticky chapter outline for the reading demo 2026-09-01 03:44:04 +00:00
pat 5f24a406cf Add chapter outline data and recipe short titles 2026-09-01 03:44:03 +00:00
pat f0c6a48187 fix(reader): do not show Library twice on the library page 2026-09-01 03:36:11 +00:00
pat 695a8e3f08 docs: note how to run the reading demo 2026-08-31 07:33:31 +00:00
pat a7d5e5f31e feat(reader): add reading-demo layout styles 2026-08-31 07:33:30 +00:00
pat 98830de44e feat(nav): send logo home and add Sample chapter link 2026-08-31 07:33:29 +00:00
pat 1f52209f87 feat(reader): add sample comps for RE-05 Try-it 2026-08-31 07:33:28 +00:00
pat b4ad25c1ec feat(reader): add sample listings for RE-04 Try-it 2026-08-31 07:33:27 +00:00
pat aac526f7a1 feat(reader): add print/focus recipe view 2026-08-31 07:33:26 +00:00
pat 6dfa941683 feat(reader): add Real Estate sample chapter 2026-08-31 07:33:25 +00:00
pat 7743e6fa75 feat(reader): add reading-demo library page 2026-08-31 07:33:24 +00:00
pat b87b7516dc feat(reader): add full nested workflow block 2026-08-31 07:33:23 +00:00
pat 6d13ab5962 feat(reader): reuse terminal chrome for nested method output 2026-08-31 07:33:22 +00:00
pat 8314dad574 feat(reader): add slim reader footer 2026-08-31 07:33:21 +00:00
pat 265d64abd6 feat(reader): add slim reader nav 2026-08-31 07:33:19 +00:00
pat 3dd20d13c0 feat(reader): persist Try-it activation in localStorage 2026-08-31 07:33:18 +00:00
pat 0fba3c8175 feat(reader): add sample Real Estate chapter and nested recipes 2026-08-31 07:33:17 +00:00
pat ce9bb4f943 docs: content is the critical path; chapter blank lives in workflows/ 2026-08-31 07:21:23 +00:00
pat 20cd0d09c8 docs: mark aibook.fun domain renewed in digital surface table 2026-08-31 07:21:21 +00:00
pat 0bc2fcd10b docs: close leftover D-2 copy; point §5.4 at workflows/chapter-structure.md 2026-08-31 07:21:20 +00:00
pat 48425b0baf docs: index the chapter blank; chapters are the reading unit; $47/yr signed 2026-08-31 07:21:19 +00:00
pat efc859b339 docs: add workflows/ chapter blank for review (PRD §5.4) 2026-08-31 07:21:18 +00:00
pat ad4bc12c00 docs: close Gate 0.1 and 0.2 (domain + pricing) 2026-08-31 07:16:38 +00:00
pat 53828e8d73 docs: commercial spine signed — $47/yr; writers on contract 2026-08-31 07:16:37 +00:00
pat 10ef165596 docs: sign D-1/D-2 — $47/yr, no v1 lifetime SKU, founding writers on contract; domain renewed 2026-08-31 07:16:36 +00:00
pat 46d366e6b0 docs: chapters are the reading unit; workflows nest in the essay 2026-08-30 23:25:57 +00:00
pat 9dfdf07ce3 docs: lock reading IA — chapters as essays with nested full workflows (2026-08-31) 2026-08-30 23:25:57 +00:00
pat 82acad15f2 docs: mark Gate 0.3 product-health ratification done (2026-08-29) 2026-08-29 20:36:17 +00:00
pat 353d749b52 docs: point Spec activation clock at access key; metrics ratified 2026-08-29 2026-08-29 20:36:16 +00:00
pat 2b76c45620 docs: ratify product-health metrics (2026-08-29)
Activation 20/35 from access-key date; campaign contributor waitlist 50/100; post-key submissions 10/25 in 90 days; renewal 40/60 excluding lifetime; curation SLA demoted from launch bar.
2026-08-29 20:36:15 +00:00
SinachPat 89a3d76122 feat(marketing-site): American Dream cover band + narrative weave
- Cover: publisher-style belly band across the lower book cover using a
  compressed banner (2.2MB screenshot -> 60KB WebP, resized to display
  needs), cropped via a width-locked <img> + percentage offset so the
  wordmark stays legible rather than getting zoomed/cropped sideways.
  Compass + wordmark compacted into a row to make room.
- Copy: the theme woven through Field Notes, Contents, the Founding
  Sponsor tier, and one direct FAQ entry -- mostly oblique, since the
  cover already states it explicitly. Hero/Recipe/Capture/Footer left
  untouched on purpose.
2026-08-28 10:49:57 +01:00
pat 9340a0a972 Merge pull request 'feat: rebuild marketing site with full component suite and preview' (#3) from feature/marketing-site into main
Reviewed-on: WeOwnAI/aibook-fun#3
2026-08-27 15:56:49 +00:00
SinachPat 3580c00fa1 feat: rebuild marketing site with full component suite and preview 2026-08-27 16:53:12 +01:00
pat 169e3494e3 Merge pull request 'docs: write README with project overview and docs index' (#2) from docs/plain-language-rewrite into main
Reviewed-on: WeOwnAI/aibook-fun#2
2026-08-26 14:10:13 +00:00
pat 99ca572ab4 Merge pull request 'docs: rewrite PRD, Spec, and Implementation Plan for clarity' (#1) from docs/plain-language-rewrite into main
Reviewed-on: WeOwnAI/aibook-fun#1
2026-08-26 13:56:32 +00:00
172 changed files with 13275 additions and 86 deletions
+38
View File
@@ -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"
+14 -16
View File
@@ -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 |
+90 -36
View File
@@ -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.
+17 -14
View File
@@ -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. |
+28 -20
View File
@@ -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
+73
View File
@@ -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
+25
View File
@@ -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
+33
View File
@@ -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
+150
View File
@@ -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
+76
View File
@@ -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"
+8
View File
@@ -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"
+23
View File
@@ -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
}
}
+41
View File
@@ -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"]
+59
View File
@@ -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
+41
View File
@@ -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",
]
}
+25
View File
@@ -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
}
}
+48
View File
@@ -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
+113
View File
@@ -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"]
}
+44
View File
@@ -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"
}
+28
View File
@@ -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.
+27
View File
@@ -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
+82
View File
@@ -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
}
+17
View File
@@ -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
}
File diff suppressed because it is too large Load Diff
+267
View File
@@ -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&quot;: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*.
Binary file not shown.
File diff suppressed because it is too large Load Diff
+409
View File
@@ -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`.
+449
View File
@@ -0,0 +1,449 @@
# Kickstarter filled form pack — We Own AI
**Status:** Paste-ready draft for the project editor + review submission
**Prepared:** 23 Sep 2026 (WAT) · **Owner-approved:** 23 Sep 2026 (WAT)
**Sources:** `ks-campaign-blueprint.md` (HEAD `83721c43`) · AiBook.fun product locks · 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:** **APPROVED 23 Sep 2026** for window/goal/URL/$47 access/physical placeholders. **Revised 23 Sep 2026:** reward model is **three buckets** — (1) Retreat, (2) Academy, (3) Book & Library — with Retreat + Academy as **live Kickstarter tiers** (not omitted). Retreat/Academy **dollar amounts still OWNER-ONLY** (do not invent).
### How to read tags
- **CONFIRMED** — locked in blueprint / product decisions
- **RECOMMENDED** — filled so the form is complete; owner can override before submit
- **OWNER-ONLY** — cannot be filled by an agent (secrets / legal / live account)
- **ASSET NEEDED** — text ready; file must be uploaded
---
## A0. Editor tab map (from deepened research, 23 Sep 2026)
Ordered Kickstarter UI: `/start` → **Basics** → **Story** → **Plan** *(skip for Publishing)* → **Rewards** → **People** → **Funding** → **Preferences** → **Payment** → **Send to review** → approval → **Promotion** (URL + pre-launch) → **Launch project** *(manual; does not auto-launch on Target Launch Date)*.
| Tab | What this pack fills | Notes |
|---|---|---|
| Start | Publishing → Nonfiction | **CONFIRMED** live subcategory; then optional 2nd subcategory; then **creator country** (US entity); then login |
| Basics | Title, subtitle, image, duration 33 days, Late Pledges on, Target Launch Date 2 Oct 2026 | Video optional; Discovery/vertical video optional |
| Story | Full paste in §H including Risks + AI disclosure | Environmental Commitments: skip (Publishing) |
| Plan | N/A | Publishing does not get Plan / prototype rules |
| Rewards | Items + Book & Library + Retreat + Academy tiers (§E–F); **3 buckets** | FAQ: prepare offline; many accounts only paste FAQ **after live**. KS handbook suggests ≤5 tiers for first projects — this pack is intentionally denser; trim if review pushes back. |
| People | Bio + collaborator list pending D10 | Demographics survey optional |
| Funding | Goal **$5,000** USD | Project Budget sheet is Design/Tech/Arts/Fashion — skip for Publishing |
| Preferences | Charge shipping **at pledge time** for physical tiers (once rates exist) | Or “later via Pledge Manager” if owner prefers |
| Payment | OWNER-ONLY Stripe checklist (§I) | Blocks launch |
| Promotion | After approval: generate URL, turn on pre-launch page, paste pre-launch blurb | First-timers often get this after approval |
| Launch | Manual **Launch project** on Fri 2 Oct (or slip Fri 9 Oct) | Target Launch Date does **not** auto-launch |
## A. Submit defaults (owner-approved 23 Sep 2026)
| ID | Decision | Value used in this pack |
|---|---|---|
| D1 | Launch window | **OWNER-APPROVED 23 Sep 2026:** Fri 2 Oct 2026 → Wed 4 Nov 2026 (33 days). Slip to Fri 9 Oct → Wed 11 Nov if review is not approved by launch morning. |
| D2 | Funding stack | **OWNER-APPROVED 23 Sep 2026:** Kickstarter goal **$5,000**. Published stretches: **$15,000** (bonus chapter), **$35,000** (audiobook sample), **$54,000** (community live Q&A replay pack). Goal stays $5K. |
| D3 / prices | Digital pricing | **OWNER-APPROVED 23 Sep 2026:** see Rewards. Physical paperback/collector prices remain **placeholders** until quotes. |
| D4 | Public URL | **OWNER-APPROVED 23 Sep 2026:** **https://aibook.fun** (domain renewed; AiBook.fun brand). |
| D5 | Tier 5 | **OWNER-APPROVED 23 Sep 2026:** keep as **Digital Access Subscription** (no NFT/crypto language). Maps to **$47/yr** AiBook.fun access. |
| D6 / D7 | Retreats / Academy | **OWNER-REVISED 23 Sep 2026:** **include** as live tiers. **Retreat:** Burned Out Advisor Retreat **4–6 Nov 2026**, cap **369**. **Academy:** AiCoach + AOP.biz BootCamp seats at **Orlando (Azur / FL)**, **North Denver (CO)**, **Villa Park / Chicagoland (IL)**. Prices **OWNER-ONLY**. Old Colorado / St. Pete labels retired. |
| D9 | Season tag | **RECOMMENDED:** use **#WeOwnAI #BuildInPublic** on KS page; keep #WeOwnSeason005 for internal/social only until owner locks. |
| D15 / D20 | Physical delivery | **RECOMMENDED:** **February 2027** |
| D17 | Collector extras | **RECOMMENDED:** signed bookplate + printable bonus PDF chapter notes (producible). No unnamed “exclusive extras.” |
| — | Category | **RECOMMENDED:** Publishing → **Nonfiction** (confirm exact subcategory label in editor) |
| — | Currency / country | **RECOMMENDED assumption:** **USD**, entity in **United States** (BurnedOut Media / WeOwnNet). **OWNER-ONLY** to confirm legal entity. |
---
## B. Start a project
| Field | Fill |
|---|---|
| Primary category | **Publishing** |
| Primary subcategory | **Nonfiction** **(CONFIRMED live on /start, 23 Sep 2026)** |
| Additional category | Optional: leave blank, or Technology only if you want internal KS guidance (not public) |
---
## C. Basics tab
| Field | Fill | Tag |
|---|---|---|
| Project title | `We Own AI — The New American Dream` (35 chars / 60 max) | CONFIRMED (blueprint headline) |
| Subtitle | `A field book for advisors who want to own the AI era — not rent it.` (68 chars / 135 max) | CONFIRMED intent; slightly shortened for limit |
| Project image | Book cover / mockup, full-bleed, **1024×576**, no NFT badges, minimal text | ASSET NEEDED |
| Project video | Omit for review if not ready; add after approval. Target 2–3 min, @THY on camera / @LFG edit | ASSET NEEDED / optional to submit |
| Location | City of the **US entity** HQ (or primary creator city in eligible country) | OWNER-ONLY |
| Funding goal | **$5,000** USD | CONFIRMED (public floor) |
| Campaign duration | **33 days from launch** (or fixed end **Wed 4 Nov 2026** if launching Fri 2 Oct) | RECOMMENDED (D1) |
| Target Launch Date | **Fri 2 Oct 2026** (guidance only — does **not** auto-launch) | RECOMMENDED |
| Preferences — shipping | Collect shipping **at pledge** for physical rewards once rates exist | RECOMMENDED |
| Funding goal (Funding tab) | **$5,000** USD | CONFIRMED |
| Late Pledges | **On** for digital tiers; Late price = pledge + ~10% | RECOMMENDED |
| Project URL slug | `we-own-ai-the-new-american-dream` (adjust if taken) | 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 (short) | See §D1 below | RECOMMENDED |
| Website | https://aibook.fun | RECOMMENDED (D4) |
| Social | LinkedIn (primary), others as live | OWNER-ONLY links |
| Collaborators to invite | Authors/operators named once D10 roster is confirmed (@THY, @LFG, @CEO, Brian, Lou, …) | OWNER lock D10 |
### D1. Creator bio (paste)
We Own AI is a multi-author field book from BurnedOut Media / WeOwnNet for financial advisors and professionals who feel AI moving under their practice. We are building the book and community in public. Backers fund the first edition, digital access, and the next chapters of the work — not a token, not equity, not a charity drive.
---
## E. Rewards — Items (create these first)
| Item name | Description | Image |
|---|---|---|
| eBook (PDF + Kindle) | Full digital edition of *We Own AI — The New American Dream* | Cover |
| Signed paperback | Signed physical paperback of the book | Cover + book photo |
| Digital access key (12 months) | 12 months of members-only digital library / workflow updates at AiBook.fun (or successor URL) | Product screenshot — no NFT language |
| Signed bookplate | Printed signed bookplate | Photo |
| Bonus PDF — chapter notes | Printable bonus notes PDF | Simple card |
| Retreat seat (Nov 4–6 2026) | One seat, Burned Out Advisor Retreat | Venue / event photo |
| Academy BootCamp seat — Orlando | AiCoach + AOP.biz BootCamp, Azur Resorts FL | Site photo |
| Academy BootCamp seat — North Denver | AiCoach + AOP.biz BootCamp, CO | Site photo |
| Academy BootCamp seat — Villa Park | AiCoach + AOP.biz BootCamp, Chicagoland IL | Site photo |
---
## F. Rewards — Tiers (public)
Organized as **Retreat · Academy · Book & Library**. Book & Library = Tiers 1–5; Retreat = Tier 6; Academy = Tiers 7–9.
**Shipping rule:** Digital tiers = No shipping. Physical = shipping rates **OWNER-ONLY** (get quotes; do not launch physical without rates).
### Tier 1 — Digital Supporter *(Book & Library)*
| Field | Fill |
|---|---|
| Title | Digital Supporter |
| Amount | **$25** **(RECOMMENDED)** |
| Limit | Unlimited |
| Items | eBook (PDF + Kindle) |
| Estimated delivery | **October 2026** (digital after funding / production of final files) **(RECOMMENDED)** |
| Description | Get the full eBook (PDF + Kindle) and backer-only campaign updates. Instant digital thank-you when files are ready after a successful campaign. |
| Late Pledge | **$28** |
### Tier 2 — Early Bird eBook *(Book & Library)*
| Field | Fill |
|---|---|
| Title | Early Bird eBook |
| Amount | **$19** **(RECOMMENDED)** |
| Limit | **200** (CONFIRMED cap) |
| Items | eBook (PDF + Kindle) |
| Estimated delivery | **October 2026** |
| Available | From launch until sold out or first 48 hours (pick one; **RECOMMENDED:** quantity-only cap of 200) |
| Description | Discounted eBook for the first 200 backers. Same digital edition as Digital Supporter. |
| Late Pledge | Off (early bird ends with campaign scarcity) |
### Tier 3 — Paperback + eBook *(Book & Library)*
| Field | Fill |
|---|---|
| Title | Signed Paperback |
| Amount | **$55** **(PLACEHOLDER — replace after print+sign+pack+ship+fees costed)** |
| Limit | Unlimited (or set a print-run cap once known) |
| Items | Signed paperback + eBook |
| Estimated delivery | **February 2027** (CONFIRMED recommendation D15) |
| Shipping | Restricted countries + rates **OWNER-ONLY** |
| Description | Signed paperback plus the eBook. Physical copies ship after printing; digital files deliver earlier when ready. |
### Tier 4 — Collector’s Bundle *(Book & Library)*
| Field | Fill |
|---|---|
| Title | Collector’s Bundle |
| Amount | **$85** **(PLACEHOLDER — must stay above Tier 3 after costs)** |
| Limit | Optional limit (e.g. 100) **RECOMMENDED:** 100 |
| Items | Signed paperback + eBook + signed bookplate + Bonus PDF — chapter notes |
| Estimated delivery | **February 2027** (physical); digital extras with eBook wave |
| Shipping | Same as paperback |
| Description | Signed paperback, eBook, signed bookplate, and a printable bonus PDF of chapter notes. No tokens. No equity. |
### Tier 5 — Digital Access Subscription *(Book & Library)*
| Field | Fill |
|---|---|
| Title | Digital Access Subscription |
| Amount | **$47** **(RECOMMENDED — aligns with AiBook.fun $47/yr)** |
| Limit | Unlimited |
| Items | eBook + Digital access key (12 months) |
| Estimated delivery | Access provisioning **within 14 days of campaign success** **(RECOMMENDED)**; eBook with digital wave |
| Description | Full eBook plus **12 months** of members-only digital library access (runnable workflows / updates as published on aibook.fun). This is a digital access subscription — not a cryptocurrency, NFT, or investment. |
| Late Pledge | **$52** |
### Reward model — three buckets (owner, 23 Sep 2026)
| Bucket | Public meaning | Kickstarter tiers in this pack |
|---|---|---|
| **1 · Retreat** | Burned Out Advisor Retreat (in-person) | Tier 6 |
| **2 · Academy** | AiCoach + AOP.biz BootCamp cohort seats | Tiers 7–9 (one per site) |
| **3 · Book & Library** | The book and AiBook.fun access (eBook, signed paperback, 12 months of AiBook.fun) | Tiers 1–5 |
**Audience note (Retreat, for copy / targeting — not a KS form field):** sell-out goal **369**; mix ~**80%** accounting advisors (exit-to-client interest) + ~**20%** financial advisors with CKA / CEPA niche focus.
**First-project guidance (KS handbook):** ≤ **5** reward tiers is a recommendation, not a hard limit. This pack uses **9** public tiers to match the three buckets. If Kickstarter review pushes back, collapse Academy sites into one tier with a location survey, or move Academy to add-ons.
### Tier 6 — Burned Out Advisor Retreat
| Field | Fill |
|---|---|
| Title | Burned Out Advisor Retreat (Nov 4–6) |
| Bucket | **1 · Retreat** |
| Amount | **OWNER-ONLY — do not invent** (price below COGS + fees) |
| Limit | **369** (CONFIRMED sell-out max) |
| Dates | **4–6 November 2026** (CONFIRMED) |
| Items | Retreat seat (Nov 4–6) + Signed paperback + eBook + Digital access key (12 months) **(RECOMMENDED bundle — owner can slim)** |
| Estimated delivery | Retreat attendance **November 2026**; book **February 2027**; digital items on the Book & Library schedule |
| Shipping | Physical book rates **OWNER-ONLY**; retreat travel/lodging **not included** unless owner says otherwise in description |
| Description | One seat at the **Burned Out Advisor Retreat**, **4–6 Nov 2026**. Built for advisors who want exit-to-client leverage and responsible AI practice — not a crypto pitch. Includes the signed paperback, eBook, and 12 months of AiBook.fun digital access. Travel and lodging not included unless stated. |
| Late Pledge | Off (or OWNER-ONLY if seats remain) |
### Tier 7 — Academy · Orlando (Azur / FL)
| Field | Fill |
|---|---|
| Title | Academy BootCamp — Orlando (Azur Resorts, FL) |
| Bucket | **2 · Academy** |
| Amount | **OWNER-ONLY — do not invent** |
| Limit | **OWNER-ONLY** (cohort cap TBD) |
| Program | **AiCoach + AOP.biz BootCamp** (CONFIRMED) |
| Site | **Azur Resorts, Orlando, Florida, USA** (CONFIRMED) |
| Items | Academy BootCamp seat (Orlando) + eBook + Digital access key (12 months) **(RECOMMENDED)** |
| Estimated delivery | Cohort dates **OWNER-ONLY** (state exact cohort window in description once locked); digital items on the Book & Library schedule |
| Shipping | No shipping for seat; digital only unless book add-on |
| Description | One seat in the upcoming **AiCoach + AOP.biz BootCamp** cohort at **Azur Resorts, Orlando, FL**. Includes the eBook and 12 months of AiBook.fun digital access. Travel and lodging not included unless stated. |
| Late Pledge | Off unless seats remain |
### Tier 8 — Academy · North Denver (CO)
| Field | Fill |
|---|---|
| Title | Academy BootCamp — North Denver (CO) |
| Bucket | **2 · Academy** |
| Amount | **OWNER-ONLY — do not invent** |
| Limit | **OWNER-ONLY** (cohort cap TBD) |
| Program | **AiCoach + AOP.biz BootCamp** |
| Site | **North Denver, Colorado, USA** (CONFIRMED) |
| Items | Academy BootCamp seat (North Denver) + eBook + Digital access key (12 months) **(RECOMMENDED)** |
| Estimated delivery | Cohort dates **OWNER-ONLY**; digital items on the Book & Library schedule |
| Description | One seat in the upcoming **AiCoach + AOP.biz BootCamp** cohort in **North Denver, CO**. Includes the eBook and 12 months of AiBook.fun digital access. Travel and lodging not included unless stated. |
| Late Pledge | Off unless seats remain |
### Tier 9 — Academy · Villa Park / Chicagoland (IL)
| Field | Fill |
|---|---|
| Title | Academy BootCamp — Villa Park (Chicagoland, IL) |
| Bucket | **2 · Academy** |
| Amount | **OWNER-ONLY — do not invent** |
| Limit | **OWNER-ONLY** (cohort cap TBD) |
| Program | **AiCoach + AOP.biz BootCamp** |
| Site | **Villa Park, Chicagoland, Illinois, USA** (CONFIRMED) |
| Items | Academy BootCamp seat (Villa Park) + eBook + Digital access key (12 months) **(RECOMMENDED)** |
| Estimated delivery | Cohort dates **OWNER-ONLY**; digital items on the Book & Library schedule |
| Description | One seat in the upcoming **AiCoach + AOP.biz BootCamp** cohort at **Villa Park (Chicagoland), IL**. Includes the eBook and 12 months of AiBook.fun digital access. Travel and lodging not included unless stated. |
| Late Pledge | Off unless seats remain |
### Book & Library bucket label (Tiers 1–5)
Tiers 1–5 above are the **Book & Library** tiers: the eBook, the optional signed paperback, and $47 AiBook.fun access. Public copy may say “Book & Library” as the bucket name; Kickstarter tier titles stay plain (Early Bird, Digital Supporter, etc.). Do not label these tiers “Cloud”: WeOwn Cloud is a separate product and will be added as its own bucket once the owner confirms what it includes and its price.
---
## G. Stretch goals (story section — not a separate KS form field)
Paste into Story under “Stretch goals.” Only list unlocks you will actually ship.
1. **$15,000 — Bonus chapter** (digital PDF for all backers at Digital Supporter+)
2. **$35,000 — Audiobook sample** (one chapter audio)
3. **$54,000 — Live Q&A replay pack** (recorded session for backers)
---
## H. Story tab — full paste draft
Use H2/H3 headings so Kickstarter builds the TOC. Replace `[PHOTO]` with uploads. **No NFT / token / Web3 / crypto / equity language anywhere.**
---
### Who this is for
If you advise clients for a living — or you run a professional practice — and AI feels less like a tool and more like something renting your future, this book is for you.
*We Own AI — The New American Dream* is a multi-author field book for advisors and professionals who want to **own** how they work with AI, not rent someone else’s stack forever.
### The problem
- Hype fatigue: every week a new “AI will replace you” thread, little that helps Monday morning.
- Rented tools: your workflows live inside vendors you do not control.
- Burnout: the job already asks too much; learning AI on top can feel like another unpaid shift.
- Displacement fear: clients and firms are changing faster than playbooks.
### The book
**Title:** We Own AI — The New American Dream
**Publisher frame:** BurnedOut Media / WeOwnNet
**Form:** Multi-author field book — essays plus practical paths you can run.
**Companion digital access (optional reward):** ongoing members-only library at [aibook.fun](https://aibook.fun), updated as tools and models change (often weekly or monthly), billed as a yearly digital access subscription — **not** an annual reprint and **not** a token.
[PHOTO: cover]
[PHOTO: interior / mockup spread]
[PHOTO: mockup on desk]
### What’s inside
A clear through-line: burnout and displacement → ownership mindset → concrete practices you can try.
We will publish a chapter excerpt on this page and in pre-launch posts before launch day.
[PHOTO: excerpt card]
### The authors
Real names and roles — no anonymous “the team.” Confirm final roster (owner Decision D10) before launch; placeholder structure:
- **@THY** — voice / on-camera
- **@LFG** — campaign operations
- **@CEO** — publishing leadership
- **Brian, Lou,** and additional founding writers as contracted
[PHOTO: 800×800 headshots]
### Rewards (summary)
| Pledge | You get |
|---|---|
**Bucket 3 · Book & Library**
| $19 Early Bird (200) | eBook |
| $25 Digital Supporter | eBook |
| $47 Digital Access Subscription | eBook + 12 months members-only digital access |
| $55 Signed Paperback *(price finalize after print quote)* | Signed paperback + eBook |
| $85 Collector’s Bundle *(finalize after costs)* | Signed paperback + eBook + bookplate + bonus PDF |
**Bucket 1 · Retreat**
| Burned Out Advisor Retreat (Nov 4–6) · **369 max** · **price OWNER-ONLY** | Retreat seat + signed paperback + eBook + 12 months AiBook.fun access *(recommended bundle)* |
**Bucket 2 · Academy**
| Academy BootCamp — Orlando (Azur / FL) · **price + cohort dates OWNER-ONLY** | AiCoach + AOP.biz BootCamp seat + eBook + AiBook.fun access |
| Academy BootCamp — North Denver (CO) · **price + cohort dates OWNER-ONLY** | same |
| Academy BootCamp — Villa Park / Chicagoland (IL) · **price + cohort dates OWNER-ONLY** | same |
### Stretch goals
- **$15K** — Bonus chapter for digital backers
- **$35K** — Audiobook sample
- **$54K** — Live Q&A replay pack
### Timeline
| When | What |
|---|---|
| Now → launch | Kickstarter review, pre-launch list, final page polish |
| Fri 2 Oct – Wed 4 Nov 2026 | Live campaign (33 days) — working calendar |
| After funding | Digital files & access provisioning |
| February 2027 | Physical book fulfillment target |
### How Kickstarter works here
This campaign is **all-or-nothing**. If we do not reach the **$5,000** goal, you are not charged. If we fund, we produce and deliver the rewards described above.
### Risks and challenges
**Compressed runway.** We are submitting with a short pre-launch window. Mitigation: submit for review immediately; if approval is not in hand on launch morning, we slip to the next Friday (9 Oct – 11 Nov) rather than launch half-ready.
**Print and shipping.** Paper cost, sign, pack, and international shipping can move. Mitigation: February 2027 delivery estimate includes buffer; digital rewards ship first; we will update backers if a printer slip appears.
**Scope creep / high-touch fulfillment.** Retreat (369) and three Academy sites raise fulfillment and date-risk. Mitigation: dates for Retreat are locked (4–6 Nov 2026); Academy cohort windows must be stated before launch; prices must clear COGS; travel/lodging excluded unless contracted into the reward. Stretch goals stay digital-first.
**AI tools in production.** Writers and operators use modern AI tools as assistants for research, drafting support, and workflow examples inside the book and digital library. **Humans author, edit, and are accountable for the final text and claims.** We do not sell AI-generated junk as a finished book without human editorial control. See AI disclosure below.
**Team bandwidth.** Multi-author coordination can slow chapters. Mitigation: founding writers on contract; Minimum Lovable Library approach for companion digital workflows; public updates on slips.
### AI disclosure (required honesty)
- **What AI we use:** mainstream large-language-model assistants and related tools for research aid, outline help, editing suggestions, and example workflows featured in the digital library.
- **What humans do:** authorship, editorial judgment, fact ownership, final prose, product decisions, and fulfillment promises.
- **What this project is:** an original multi-author book and optional digital-access subscription about owning AI in professional work — **not** an AI model product, **not** a crypto/NFT project, **not** equity crowdfunding.
- **Imagery:** campaign graphics and mockups will be labeled honestly; we will not use synthetic imagery to fake a finished printed book you have not approved.
### FAQ
**When do digital rewards arrive?**
After a successful campaign, eBook files are delivered as soon as the final edition files are ready — targeted around the end of the campaign / early production window (October–November 2026 working assumption). Digital access keys for the subscription tier are provisioned within about 14 days of funding success.
**When do physical books arrive?**
Estimated **February 2027**.
**Do you ship internationally?**
Yes to countries we list in the reward shipping settings once rates are quoted. **(OWNER: paste final country list + rates before launch.)**
**What is Digital Access Subscription?**
Twelve months of members-only digital library access (workflows and updates as published), plus the eBook. It is **not** a cryptocurrency, NFT, token, or investment.
**What if a stretch goal misses?**
Stretch goals only unlock if we cross that pledged total. Base rewards do not depend on stretches.
**Refunds?**
If the campaign does not fund, Kickstarter does not charge you. After a successful campaign, refund policy follows Kickstarter’s rules plus our update if a specific reward becomes impossible; we will communicate in backer updates.
**Is this related to AiBook.fun?**
Yes. AiBook.fun is the public home for the runnable digital library that pairs with this book’s ownership thesis. The Kickstarter funds the book campaign and optional digital access — presented in plain language, without Web3 wrapping.
### How to help besides backing
1. Back the project.
2. Share it with two advisors who feel this pain.
3. Join the email list at aibook.fun for launch reminders.
### Final ask
If you want a field book — and a community — built in public for professionals who refuse to only rent the AI era, back *We Own AI — The New American Dream* today.
---
## I. Payment / Stripe (OWNER-ONLY checklist)
Complete inside Kickstarter → Payment before Submit:
- [ ] Beneficiary = correct **US** (or other eligible) **legal entity** or individual
- [ ] Legal name matches bank + tax docs exactly
- [ ] EIN / tax ID entered in Stripe
- [ ] Beneficial owners disclosed if entity
- [ ] Government ID uploaded
- [ ] Bank account in same country / same name
- [ ] Card on file
- [ ] Stripe status = verified (allow multi-day lag)
---
## J. Submit-for-review checklist
- [ ] Basics complete (title, subtitle, image, goal, dates, location, category)
- [ ] Story complete including **Risks** + **AI disclosure**
- [ ] At least one fully priced digital reward with delivery month
- [ ] Physical rewards either costed with shipping **or** removed until costed
- [ ] No NFT / crypto / equity / charity-pass-through language
- [ ] Payment verification started / completed
- [ ] Collaborator names match D10
- [ ] Click **Submit for review**
- [ ] Preferences: shipping-at-pledge set (or explicit later-via-PM choice)
- [ ] Funding tab shows $5,000 (Publishing: no Project Budget sheet required)
- [ ] Calendar: if not approved by Thu 1 Oct evening WAT, execute D14 slip to **9 Oct**
- [ ] On launch day: manually click **Launch project** (Target Launch Date does not fire launch)
---
## K. Still OWNER-ONLY (blocks a true “typed into Kickstarter” completion)
1. Kickstarter login + entity country confirmation (Nigeria is not a creator country).
2. Stripe identity, tax, bank, card.
3. Final paperback/collector **dollar** amounts after printer quotes.
4. Shipping country list + rates.
5. Final author roster headshots (D10).
6. Project image + optional hero video files.
7. Explicit yes on D1 launch Friday if different from Oct 2.
---
## L. Next actions for Product Lead / owner
1. Owner still needs to lock **Retreat + Academy dollar amounts**, Academy **cohort dates/caps**, **D3 physical prices**, shipping rates, and **entity country**.
2. Agent (or owner) pastes this pack into a Kickstarter **draft** on the verified account.
3. Upload assets; start Stripe verification **today** (23 Sep) — review SLA needs headroom for an Oct 2 launch.
Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 217 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 283 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 240 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 211 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 216 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 156 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 225 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 95 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 94 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 143 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 221 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 132 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 185 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 218 KiB

+92
View File
@@ -0,0 +1,92 @@
# 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 campaign guide (`ks-research/kickstarter-campaign-guide.md`, section 2.3 Story and Part 3.1 assets).
- 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 09b 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 × 1634 | Three columns (Retreat, Academy, Book & Library) showing what each is, what it includes, and when. Book & Library prices are one per line ($19, $25, $47 featured). The signed paperback appears with "Price on the reward" and a small image of the landing cover. The Book & Library header shows the cover too. No Retreat or Academy price is shown. | Three ways to back: Retreat, Academy, and Book & Library, with Book & Library rewards at $19, $25 and $47 |
| 06c-three-ways-to-back-no-paperback.png | 6 Three ways to back | 1360 × 1414 | Same image without the paperback (the Book & Library header still shows the cover), for use if the paperback reward is left out at launch | Same as above |
| 07-header-the-retreat.png | 7 The Retreat | 1360 × 300 | Section header | The Retreat |
| 07b-retreat-venue-PLACEHOLDER.png | 7 The Retreat | 1360 × 765 | Venue photo frame with "Burned Out Advisor Retreat, 4 to 6 November 2026" and a "369 seats" badge | Burned Out Advisor Retreat, 4 to 6 November 2026, 369 seats |
| 08-header-the-academy.png | 8 The Academy | 1360 × 300 | Section header | The Academy |
| 08b-academy-map.png | 8 The Academy | 1360 × 956 | US map with pins on #NoDe (North Denver, CO), Villa Park (Chicagoland, IL), and Azur Resorts (Orlando, FL) | Map of the three AiCoach + AOP.biz BootCamp sites: North Denver, Villa Park near Chicago, and Orlando |
| 08c-academy-sites-PLACEHOLDER.png | 8 The Academy | 1360 × 666 | Three site cards, each with a photo frame | The three Academy sites |
| 09-header-book-library-and-aibook-fun.png | 9 Book & Library and AiBook.fun | 1360 × 300 | Section header | Book & Library and AiBook.fun |
| 09b-aibook-fun-device-mockup.png | 9 Book & Library 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 | 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 |
| 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 × 920 | Path with six numbered stops, using the guide's dates. Stop 4 (Academy cohorts) reads "Dates to be announced". | Timeline from launch on 2 October 2026 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. 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 | 07b | Landscape, at least 1360 × 765 |
| Academy site photos: Azur Resorts (Orlando), #NoDe (North Denver), Villa Park (Chicagoland) | 08c | At least 800 × 600 each, landscape |
| 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, Academy BootCamp 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.
- **A fourth reward bucket:** 06b and 06c are built from a list of columns in `three_ways()` in `build.py`. To add a fourth bucket once its contents and price are confirmed, append one more column entry there and re-run `python build.py '^06'`; the grid adjusts without a CSS change.
- **Academy cohort dates and seats:** 08c has no dates or seats, and timeline stop 4 says "Dates to be announced".
- **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 09b 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, 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.
Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

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
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 277 KiB

Binary file not shown.

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
]
}
}
File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 28 KiB

File diff suppressed because one or more lines are too long
@@ -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 | 07b Retreat | 1360 × 765, landscape |
| site-orlando, site-north-denver, site-villa-park | 08c Academy sites | 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-academy-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/`.
+637
View File
@@ -0,0 +1,637 @@
"""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), Story section and Part 3.1."""
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-retreat', '🏕️', 'The Retreat'), ('08', 'the-academy', '🎓', 'The Academy'),
('09', 'book-library-and-aibook-fun', '📚', 'Book & Library and AiBook.fun'), ('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}
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 bucket. To add a fourth bucket later, append another (html, width) entry
to `cols` below; the grid template is built from the list, so no CSS change is needed."""
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', '', 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><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 ''))
inc = f'<ul class="inc"><li>{icon("seat")}Your seat</li><li>{icon("book")}The eBook</li><li>{icon("library")}12 months of AiBook.fun</li></ul>'
cols = [(f'''
<div class="col card">
<p class="nm">Retreat</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></div>
<div class="pr"><p class="price">Price on the reward</p></div>
</div>''', '1fr'),
(f'''
<div class="col card">
<p class="nm">Academy</p><h3>AiCoach + AOP.biz BootCamp</h3>
<div class="sec"><p class="lb">What it is</p><p>A seat in the next cohort at one of three sites:</p>
<p class="fact">{icon("pin")}Orlando, Florida</p><p class="fact">{icon("pin")}North Denver, Colorado</p><p class="fact">{icon("pin")}Villa Park, Chicagoland, Illinois</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")}The next cohort at your chosen site</p></div>
<div class="pr"><p class="price">Price on the reward</p></div>
</div>''', '1fr'),
(f'''
<div class="col card book">
<p class="nm">Book &amp; Library</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.3fr')]
many = len(cols) > 3 # four or more columns: let columns shrink below their content width and wrap the price pill
grid = ' '.join(f'minmax(0,{w})' if many else 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 = '''
.cols{display:grid;grid-template-columns:1fr 1fr 1.3fr;grid-template-rows:repeat(6,auto);column-gap:10px}
.col{padding:18px 15px 16px;display:grid;grid-template-rows:subgrid;grid-row:span 6}
.nm{font-family:var(--mono);font-size:13px;letter-spacing:.12em;text-transform:uppercase;color:var(--pine);font-weight:600}
.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:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-bottom:6px}
.sec p{font-size:14px;line-height:1.4}
.fact{display:flex;gap:7px;align-items:flex-start;margin-top:6px;font-weight:600}
.lb+.fact{margin-top:0}
.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:12.5px;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:nowrap}
.many .price{white-space:normal}
.book{border-color:rgba(28,93,76,.28)}
.prices li{display:grid;grid-template-columns:58px 1fr;gap:8px;align-items:baseline;padding:7px 8px;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)}
.prices b.np{align-self:start;width:30px;margin:0 0 0 6px}.prices b.np img{width:30px;display:block}
.ch{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}
.ch img{width:46px;border-radius:2px 4px 4px 2px;box-shadow:0 6px 12px -6px rgba(18,63,52,.5);margin:4px 0 8px}
.prices small{display:block;font-size:13px;color:var(--muted)}
.prices li.feat{background:var(--pine);color:#eaf1ec}
.prices li.feat b{color:#fff}
.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 retreat
add_header('07')
page('07b-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">{TITLE.split(" — ")[0]}</p><h3>Burned Out Advisor Retreat</h3><p class="d">{icon("calendar")}4 to 6 November 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 .ico{width:22px;height:22px}
.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}
''')
# ---------------------------------------------------------------- 08 academy
add_header('08')
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>')
page('08b-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')]
page('08c-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}
''')
# ---------------------------------------------------------------- 09 book & library and aibook.fun (device mockup)
add_header('09')
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('09b-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}
''')
# ---------------------------------------------------------------- 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.'),
('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.'),
('Dates to be announced', 'Academy BootCamp cohorts in Orlando, North Denver, and Villa Park.'),
('January 2027', 'Final layout and eBook files. The eBook is delivered and the paperbacks are signed.'),
('February 2027', 'Signed paperbacks are delivered.')]
XS = [96, 290, 484]
Y1, Y2 = 30, 250
pos = [(XS[0], Y1), (XS[1], Y1), (XS[2], Y1), (XS[2], Y2), (XS[1], Y2), (XS[0], Y2)]
stops = ''.join(f'<div class="stop{" tba" if i == 4 else ""}" style="left:{x}px;top:{y}px"><span class="num">{i}</span><div class="tx"><b>{d}</b><p>{t}</p></div></div>'
for i, ((x, y), (d, t)) in enumerate(zip(pos, STOPS), 1))
page('11b-timeline', f'''<div class="canvas" id="shot"><div class="tl">
<svg class="path" viewBox="0 0 616 420"><path d="M{XS[0]} {Y1} H{XS[2]} C{XS[2]+160} {Y1} {XS[2]+160} {Y2} {XS[2]} {Y2} H{XS[0]}" /></svg>
{stops}</div></div>''', css=f'''
.tl{{position:relative;height:396px}}
.path{{position:absolute;inset:0;width:616px;height:420px}}
.path path{{fill:none;stroke:var(--pine);stroke-width:3;stroke-dasharray:2 9;stroke-linecap:round;opacity:.7}}
.stop{{position:absolute;width:0;height:0}}
.num{{position:absolute;left:-23px;top:-23px;width:46px;height:46px;border-radius:999px;background:var(--pine);color:#fff;font-family:var(--display);font-weight:900;font-size:22px;display:grid;place-items:center;box-shadow:0 0 0 5px var(--paper-2),var(--sh-md)}}
.stop.tba .num{{background:#fff;color:var(--pine);border:2.5px solid var(--pine)}}
.tx{{position:absolute;top:34px;left:-92px;width:184px;text-align:center}}
.tx b{{display:block;font-family:var(--display);font-weight:600;font-size:18px;letter-spacing:-.02em;line-height:1.15;color:var(--ink)}}
.tx p{{font-size:14px;line-height:1.4;color:var(--muted);margin-top:5px}}
.stop.tba .tx b{{color:var(--pine)}}
''')
# ---------------------------------------------------------------- 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', 'Academy BootCamp lead')]
team_html = ''.join(
f'<div class="card tm">{slot("team-" + (h[1:].lower() if h else ("osinachi-patrick" if n.startswith("Osinachi") else "academy-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)
+82
View File
@@ -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>')
+37
View File
@@ -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,75 @@
<!doctype html><html lang="en"><head><meta charset="utf-8">
<link rel="stylesheet" href="../styles.css"><style>
.cols{display:grid;grid-template-columns:1fr 1fr 1.3fr;grid-template-rows:repeat(6,auto);column-gap:10px}
.col{padding:18px 15px 16px;display:grid;grid-template-rows:subgrid;grid-row:span 6}
.nm{font-family:var(--mono);font-size:13px;letter-spacing:.12em;text-transform:uppercase;color:var(--pine);font-weight:600}
.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:12px;letter-spacing:.1em;text-transform:uppercase;color:var(--muted);margin-bottom:6px}
.sec p{font-size:14px;line-height:1.4}
.fact{display:flex;gap:7px;align-items:flex-start;margin-top:6px;font-weight:600}
.lb+.fact{margin-top:0}
.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:12.5px;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:nowrap}
.many .price{white-space:normal}
.book{border-color:rgba(28,93,76,.28)}
.prices li{display:grid;grid-template-columns:58px 1fr;gap:8px;align-items:baseline;padding:7px 8px;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)}
.prices b.np{align-self:start;width:30px;margin:0 0 0 6px}.prices b.np img{width:30px;display:block}
.ch{display:flex;align-items:flex-start;justify-content:space-between;gap:10px}
.ch img{width:46px;border-radius:2px 4px 4px 2px;box-shadow:0 6px 12px -6px rgba(18,63,52,.5);margin:4px 0 8px}
.prices small{display:block;font-size:13px;color:var(--muted)}
.prices li.feat{background:var(--pine);color:#eaf1ec}
.prices li.feat b{color:#fff}
.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:1fr 1fr 1.3fr">
<div class="col card">
<p class="nm">Retreat</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>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></div>
<div class="pr"><p class="price">Price on the reward</p></div>
</div>
<div class="col card">
<p class="nm">Academy</p><h3>AiCoach + AOP.biz BootCamp</h3>
<div class="sec"><p class="lb">What it is</p><p>A seat in the next cohort at one of three sites:</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"><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"/></svg></span>Orlando, Florida</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"><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"/></svg></span>North Denver, Colorado</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"><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"/></svg></span>Villa Park, Chicagoland, Illinois</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>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>The next cohort at your chosen site</p></div>
<div class="pr"><p class="price">Price on the reward</p></div>
</div>
<div class="col card book">
<p class="nm">Book &amp; Library</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</span></li><li><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></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>

Some files were not shown because too many files have changed in this diff Show More