Files
datatools-dev/landing
Michael db5ec084da docs+code: rename tool labels everywhere
Sweep follow-up to 93e43fc. Display labels now consistent across docs,
landing pages, CLI output, code comments, docstrings, and test prose.
Five parallel surfaces touched:

- docs (EN + ES): README, USER-GUIDE, CLI-REFERENCE, and 11 internal
  design/planning docs
- landing pages: index + bookkeeper/revops/shopify-pet
- src: CLI module docstrings, _TOOL_DISPLAY dicts in cli_analyze.py
  and gui/components/_legacy.py, core module headers, every tool
  page's module docstring
- tests: class/method/module docstrings and section-header comments
- test-cases READMEs

Page slugs (1_Deduplicator etc.), tool_id strings (01_deduplicator
etc.), Python class names (TestDeduplicatorWorkflow, FeatureFlag.*),
URL paths, anchor IDs, CSS classes, and asset filenames were left
intact since they're code identifiers / structural references.

All 2033 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-16 19:50:09 +00:00
..

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)
├── shopify-pet/index.html  Shopify operator (priority: pet supplies)
├── bookkeeper/index.html   bookkeeper / freelance accountant
├── revops/index.html       marketing / RevOps agency
└── 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 (Shopify = mint green, Bookkeeper = steel blue, RevOps = vivid violet)
  • 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 /shopify-pet/, /bookkeeper/, /revops/ 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 (shopify.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 shopify-pet/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.