Files
datatools-dev/landing/README.md
Michael e7ec79b9b5 demo: retarget landing pages to the accounting audience
Reorients the whole sales surface to accounting so it matches the rebuilt
demos. Replaces the Shopify and RevOps persona pages with accounts-payable
(1099) and accounts-receivable pages, refreshes the bookkeeper page, and
rewires the hub + deploy tooling:

- landing/bookkeeper/  — refreshed to the validated bank-rec demo
  (26 -> 20, six phantom duplicates), iframe ?p=bookkeeper.
- landing/ap-1099/     — NEW (replaces shopify-pet/): 1099 vendor prep,
  "24 records -> 8 vendors, 7 missing EINs recovered", iframe ?p=ap-1099,
  amber accent.
- landing/ar-aging/    — NEW (replaces revops/): AR open invoices,
  "26 -> 21, five double-entered invoices removed", iframe ?p=ar-aging,
  green accent.
- landing/index.html   — hub rewritten with the three accounting cards.
- deploy.py / deploy.config.example.json / README.md / _shared/styles.css
  — persona list, sitemap defaults, 404 links, cross-links, docs updated.

All demo iframes now point at the renamed app_demo personas; deploy.py
builds the dist bundle cleanly (verified) and the Gumroad ?from= tags match.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-22 18:59:50 +00:00

5.9 KiB
Raw Blame History

Landing pages

Three persona-tagged landing pages per docs/PLAN.md §2.3 and docs/DEMO-PLAN.md §3 / §7. Static HTML, zero build step, ship to Cloudflare Pages.

Structure

landing/
├── _shared/styles.css      shared CSS (system fonts, no externals)
├── bookkeeper/index.html   bookkeeper — bank reconciliation
├── ap-1099/index.html      accounts payable — 1099 vendor prep
├── ar-aging/index.html     accounts receivable — open invoices
└── README.md               this file

Each page:

  • Inherits landing/_shared/styles.css
  • Overrides the --accent colour variable in an inline <style> block so each persona has its own visual identity (Bookkeeper = steel blue, AP / 1099 = amber/gold, AR = receivables green)
  • Has a sticky buy bar with the Gumroad CTA tagged with ?from=<persona>
  • Embeds the live demo (Streamlit) via <iframe> with a sandbox attribute
  • Carries persona-specific H1, sub-copy, use cases, FAQ, and a ready-to-paste terminal block showing the CLI in action
  • Includes Open Graph + Schema.org SoftwareApplication JSON-LD for link-share previews and SEO

Pre-deploy URL substitutions — automated

The HTML carries placeholder URLs (the literal strings https://demo.datatools.app, https://datatools.app, https://gumroad.com/l/datatools, mailto:hello@datatools.app) that must be replaced before deployment. A small Python script does this for you — no global search-and-replace needed.

# 1) Copy the template and fill in your real URLs:
cp landing/deploy.config.example.json landing/deploy.config.json
edit landing/deploy.config.json

# 2) Build the deploy-ready bundle:
python3 landing/deploy.py
# → produces landing/dist/ with substitutions applied,
#   plus robots.txt, sitemap.xml, 404.html, favicon.svg

landing/deploy.config.json is gitignored so your real URLs never hit the repo. Re-run landing/deploy.py whenever you change a URL or edit any HTML source.

Cloudflare Pages deployment

The simplest path — one Pages project pointed at landing/dist/:

# Option A: drag-and-drop the directory in the Cloudflare dashboard
#   Pages → Create project → Direct Upload → drag landing/dist/

# Option B: Wrangler CLI (one command, scriptable)
wrangler pages deploy landing/dist

Configure the custom apex domain (datatools.app) in the Cloudflare Pages project settings; sub-paths /bookkeeper/, /ap-1099/, /ar-aging/ are served automatically because the directory layout mirrors them. Cache rule defaults are fine (HTML 1 day, CSS 7 days).

If you want separate Pages projects per persona for independent A/B testing, point three projects at the same landing/dist/ and configure each with its own sub-domain (bookkeeper.datatools.app, etc.) and a Pages rule that rewrites the root to that persona's sub-directory.

Telemetry wiring (per DEMO-PLAN §8)

The plan calls for event-only counters, no PII, no Google Analytics.

For each page, on Cloudflare Pages, attach a Worker (or use Cloudflare Web Analytics — it's privacy-friendly out of the box and zero config). Track:

  • page_view per persona (auto from CF Web Analytics)
  • cta_clicked — add a small inline <script> that fires a fetch to /api/event?event=cta_clicked&persona=<persona> when the buy button is clicked, then continues the navigation to Gumroad.
  • demo.run_completed and demo.cta_clicked are owned by the demo app, not the landing page.

Conversion (per DEMO-PLAN §8):

demo_engagement = demo.run_completed / page_view       (target ≥ 30%)
purchase_intent = demo.cta_clicked / demo.run_completed (target ≥  5%)
purchase_rate   = gumroad.purchase / demo.cta_clicked   (target ≥ 30%)

The Gumroad webhook captures ?from=<persona> so we can attribute purchases back to the landing page that produced them.

Maintenance triggers (per DEMO-PLAN §9)

Refresh the page when:

Trigger Action
cta_clicked / run_completed < 5% for 4 weeks The demo is working but the buyer isn't trusting the CTA. Add a screenshot of the network tab showing zero outbound calls. Soften the price callout.
page_view → run_completed < 30% for 4 weeks The demo iframe isn't loading or visitors aren't engaging. Check the iframe URL. Move the demo above the fold if it's currently below.
New tool ships (0609) Add it to the persona's saved pipeline only if it fits — don't bloat the demo with every tool.
Pricing change Update <meta> schema, the buybar .price-tag, the pricing card, and the FAQ. Search-and-replace $49 across the file.
New persona added (4th, 5th) Copy bookkeeper/index.html, replace persona-specific copy, add to the footer cross-link block on the existing pages.

Why static HTML

Per DECISIONS.md §5 and BUSINESS.md §7, the landing-page channel must be:

  • Async-friendly — Cloudflare Pages serves these with no operator involvement
  • Cheap — Cloudflare Pages free tier is sufficient until well past the $5k/mo MRR re-lock trigger (DECISIONS.md §8)
  • Privacy-respecting — no third-party tracker means no cookie banner, which means no friction added to the conversion funnel
  • Zero ongoing maintenance — no framework, no build, no upgrades. The CSS uses system fonts; no Google Fonts; no CDN dependency that could break the page when their TLS certificate rolls.

Anti-temptations (per DEMO-PLAN §11 + plan §5)

These pages deliberately exclude:

  • No live chat widget. Locked by no-touch.
  • No "schedule a demo with us" CTA. Same.
  • No email capture before the demo. Friction kills conversion.
  • No Google Analytics / Meta Pixel. Privacy story is a moat, not a checkbox to ignore.
  • No SaaS-style "free trial / no credit card." This is a one-time download, not a subscription.
  • No A/B-testing framework yet. Pre-PMF traffic doesn't reach statistical significance — ship the single-arm copy, iterate monthly.