Skip to content
Public template

About

Monarda — the Lentago Labs campaign-site kit: an Astro template plus intake and a timed dry-run, deploying to the client's own GitHub Pages or S3/CloudFront. Bee balm: showy, fast-spreading, a pollinator magnet.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

monarda — Campaign page · site in a day, yours not ours

main License

Astro Template Client-owned

monarda — campaign-site kit

A ready-to-run fundraising campaign website: a fast, static, accessible page you set up by editing one file. Workflows deploy it to your own GitHub Pages or AWS account — no server to run, no card data to handle, and nothing hosted by anyone but you.

Authorship: The code, prompts, and documentation in this repo are co-written with Claude (Anthropic). I direct the work and review the output; Claude writes the code and prose. I'm an infrastructure operator, not a software engineer — please don't read this repo as a portfolio of coding ability.


This README has two readers. Find yours:

  • For the client — this is your campaign, and this site will be yours.
  • For the operator — you're standing the site up for someone else's campaign.

For the client — what you get, and what you own

New here? Start with ADOPTION.md — it walks through everything you need in one place: what you'll need before you start, the intake questions, the deploy drill, and how to take the site down later if you ever need to.

What you get: one page for your campaign, with four sections — a hero (your campaign name, tagline, goal, deadline, and an optional progress bar), your story, a donate button or widget hosted by your payment processor, and a contact / volunteer section. It's built as plain static HTML with system fonts, no trackers, and no JavaScript running in anyone's browser, so it loads fast and scores well on Lighthouse — Google's page-speed and accessibility checker. That one page is rung 1. The kit comes in rungs, steps you take one at a time, and rung 2 is a plain site for your whole organization; see Rung 2 below.

What you own — everything:

Thing Who owns it
This GitHub repository You
The live website + domain You
Your payment processor account + the money You
Your AWS account (only if you choose the S3 option) You

The site lives in your account and runs from there. It doesn't depend on us to keep working, and we don't host it, hold your funds, or see your donor data.

A note on payments and safety. This kit never touches card data. The donate section either links to your processor's hosted donate page or embeds their widget, so the payment itself happens on the processor's own secure, PCI-compliant pages — PCI being the card industry's security standard. That's deliberate: your money and your compliance obligations stay with the processor, not with this website.

Edit one file

Everything about your campaign lives in campaign.config.ts: name, tagline, goal, deadline, story, colors, donate widget, and contact info. Open it, fill in your details, save. The full field reference is in src/config.ts. On rung 2, the words on each page live in content/ as well; the settings stay in this one file.

npm install     # once
npm run dev     # preview locally at the printed URL
npm run build   # produce the static site in ./dist

Rung 2 — the plain organization site

Skip this if one campaign page is all you need. Rung 1 stays the default.

What you get: six pages instead of one — home, about, programs, events, donate, and contact — with the same header menu and footer on every page. The campaign page can stay as a seventh page at /campaign/. Each page is a Markdown file in content/; Markdown is plain text where a line starting with ## is a heading and - starts a list. The pages ship with placeholder text that starts with "Replace this," so you can see what's left. The donate page uses the same processor-hosted button or widget as rung 1, and the contact page the same email button or form. There's still no server, no admin screen, and nothing hosted by anyone but you.

How to switch: set rung: 2 in campaign.config.ts, fill in the organization block next to it, and edit the files in content/. To preview rung 2 before you commit to it, run SITE_RUNG=2 npm run dev. If the people who edit your pages shouldn't have to learn git, docs/editing-without-git.md sets up an optional browser editor, in your own accounts, that sends each edit to you as a pull request.

What it costs: the same as rung 1. GitHub Pages is free, and the S3 path costs what AWS charges for a handful of small files. The pull-request check builds and checks both rungs, which uses a couple of minutes of GitHub Actions time per change: free on a public repository, and counted against the monthly free allowance on a private one.

How long: not timed yet. Rung 2 has its own drill in DRY-RUN.md, timed separately so the rung-1 number stays honest, and its first receipt will go under receipts/. The setup steps are the same as rung 1; the extra time is writing the pages, and that depends on how much you already have written down.

Coming from another site? If your organization already has a WordPress or Squarespace site, the rescue import turns its export into these pages and prints what it couldn't carry over. The same runbook covers Wix, Weebly, Google Sites, and a site you've lost access to.

Choosing a processor

Pick any processor that can give you either an embed snippet (a block of HTML you paste in) or a donate link. Set the matching field — donate.embedHtml or donate.buttonUrl — in the config. A few common, no-backend options, as examples only — choose whatever fits your campaign, we don't endorse any one of them:

Processor How you wire it Notes
Givebutter Paste their widget/embed code into donate.embedHtml, or use your campaign URL as donate.buttonUrl. Popular for nonprofits/campaigns; hosted forms + embeds.
Zeffy Paste the embed <iframe> into donate.embedHtml, or link the form URL. Advertises zero platform fees.
PayPal Use a PayPal donate-button link or hosted button as donate.buttonUrl. Widely recognized; simple link-button.
Donorbox / Stripe Payment Link Paste the embed into donate.embedHtml, or link the hosted page. Both provide hosted, embeddable donation pages.

Whichever you pick, the payment itself happens on the processor's pages, not here. Confirm current fees, eligibility, and payout terms directly with them.

Contact & volunteers

This kit doesn't ship a backend — there's no server of its own to receive a form submission. In the config, set contact.email (renders a mailto: button, the kind that opens the visitor's email app) and/or paste a hosted form embed (Google Forms, Tally, Jotform) into contact.formEmbedHtml.

Deploying (your account, your choice)

  • GitHub Pages — free, the default. GitHub's own free static-site hosting. In your repo, go to Settings → Pages → Source = GitHub Actions, then push to main. deploy-pages.yml builds and publishes it for you. For a project site (you.github.io/repo/), set base: "/repo/" in the config.
  • S3 + CloudFront — the paid variant. Amazon's storage and content-delivery services, for a custom domain with a CDN — a network of servers that serve your site from somewhere close to each visitor. See deploy-s3.yml: it proves its identity to your AWS account with short-lived GitHub OIDC — a sign-in method that needs no stored password or key — so there are no long-lived AWS keys anywhere in this kit. It syncs to S3 and optionally clears the CloudFront cache. It ships switched off until you fill in four clearly-marked placeholders. This option costs money on AWS; Pages doesn't.

For the operator — running the dry-run

Two documents drive an engagement with a client:

  1. INTAKE.md — the one-page questionnaire. Every answer maps to a campaign.config.ts field or a setup step. Fill it in with the client first.
  2. DRY-RUN.md — the timed drill: from a filled intake to a live site on the client's own account, with a checklist and a table to record the elapsed time. The recorded time is the receipt. Run it once before a real engagement to surface the slow steps (DNS, the AWS OIDC role). Rung 2 has a second, separately timed drill in the same file.

The delivery rule (ADR-0007, fleet-wide): kits deploy into client-owned repos/accounts — never Lentago-hosted. That's why both deploy workflows target the client's own GitHub/AWS. See docs/adr/ for the decisions behind the donate-embed and client-ownership design.

What's here


🌱 Lentago Labs is a pro-bono operations practice for organizations that run on volunteers, donations, and one overworked tech person. Everything here is free to take, and we practice what we publish: our own estate runs this way, in the open. Start at the org profile.

About

Monarda — the Lentago Labs campaign-site kit: an Astro template plus intake and a timed dry-run, deploying to the client's own GitHub Pages or S3/CloudFront. Bee balm: showy, fast-spreading, a pollinator magnet.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages

Generated from lentago/repo-template