Skip to main content
vibld

Template

Riverbend Food Collective

a site for a volunteer-run food bank that shows what each dollar and each shift does, fills its volunteer shifts, and sends donors to its giving page in two clicks.

Food bank nonprofit site with impact numbers and volunteer shifts · Website · Small business site · 6 pages

A mock-up of the homepage, drawn from this design’s layout, palette and typefaces. A build follows the full prompt below.

Add app screens

Pick up to 6 screens, such as a dashboard, settings or an empty state. Each is built in this design’s own palette and typefaces, with its states and guardrails.

Account setup
Add edit
Analytics
Appearance
Calendar
Chat
Checklist
Checkout
Confirmation
Dashboard
Delete account
Details
Discovery questions
Empty state
Flowchart
Import export
Inbox
Integrations
Invite team
Loading
Login
Onboarding
Plans
Playground
Product tour
Referral
Search
Settings
Share
Sign up
Success
Table
Team members
Text editor
Upgrade
Usage
Verification
Welcome

Start from this templateRead the build prompt

Typefaces

Anek Latin in its heaviest weight makes numbers read like a headline; Radio Canada, drawn for a public broadcaster, reads plainly at any size.

  • Anek LatinHeadings: headlines and impact numbers
  • Radio CanadaBody: body, shift lists and forms

Who it is for

  • Neighbors who want to give money, food or time
  • Families looking for food this week
  • Local businesses considering a food drive or sponsorship

Layout

  1. Top bar: wordmark, Get food, Volunteer, Stories, About, and a Give now button
  2. Hero: big headline on paper, one cropped photo in a tomato block, and three impact stats (meals this year, families each week, volunteers)
  3. Three ways to help: give, volunteer, run a food drive, as large color cards
  4. Get food strip: today’s pantry hours and the nearest site, in plain words
  5. Open shifts list: the next six shifts with places left
  6. Stories grid: three latest stories
  7. Partners: a text list of partner names, no logo wall
  8. Footer with address, EIN, hours, and contact form link

Palette

Bold, civic and hopeful, like a community poster on a market wall: big numbers, short sentences, color with purpose.

  • paper#fbfaf5
  • river ink#10221b
  • tomato#c8371c
  • leaf#c7e36b

Every checked pair, measured again

SampleWhereRatioNeeds
Aabody text on the page15.86:14.5:1
Aatext on cards14.12:14.5:1
Aasecondary text on muted surfaces6.11:14.5:1
Aasecondary text on the page7.13:14.5:1
Aalabel on the primary action5.00:14.5:1
Aalabel on secondary surfaces14.12:14.5:1
Aalabel on the accent11.55:14.5:1
Aaerror label5.46:14.5:1
primary action against the page5.00:13:1

As vibld’s tokens

The palette on the 15+ color tokens vibld styles a project with, each text color on the fill it is read on. Marked tokens are solved from the palette, because no swatch held that role at 4.5:1.

  • background
  • card *
  • muted *
  • primary
  • secondary *
  • accent
  • destructive *

Type scale

Display
Anek Latin, headlines and impact numbers
Body
Radio Canada, body, shift lists and forms

Spacing and imagery

Punchy: 72 to 96px between sections, oversized numerals with tight leading.

Real work in progress: crates of produce, volunteers sorting, a pickup line on a bright morning. Cropped tight and set in thick color blocks.

Components

  • Impact stat: oversized numeral, a short label and an "as of" date from impact.json
  • Shift row: day, time, task, places left from the slots endpoint, and a full state
  • Three-ways card in tomato, leaf and ink

Interactions

  • Shift list reads places left on load and disables full shifts with "Full, thank you"
  • Suggested amount buttons open the giving page in a new tab

Data

  • stories: a story: title, date, photo, summary, body in Markdown
  • sites: a pantry site: name, address, days and hours, languages, notes
  • impact: an impact number: label, value, as of (date)
  • form volunteer-shift: name, email, phone, shift (radio), first time (yes or no), group size
  • form contact: name, email, topic (select), message

Build prompt

The baseline every prompt in the catalog assumes, then this design’s own ten sections, from goal to guardrails.

The baseline
### How to use these prompts
Each niche site prompt describes a whole small site for one kind of owner: its pages, the records it keeps, the forms it collects and the tools it links to. The rules below apply to every one of them.

### Niche site principles
- The site does the one job its owner needs most (a sign-up, an RSVP, a request, a visit) on the first screen, and every page leads back to it.
- Records the owner adds often (sermons, events, listings, galleries, menus, tour dates) are content collections in `src/content/`, each record with a slug, so a new record gets its page with no code change.
- Tools the owner already pays for or uses (giving, tickets, booking, listing search, ordering) are linked, or framed in an `<iframe>` whose address is in `content.ts`, never rebuilt. With no address, a plain button links out instead, and nothing pretends to work.
- Copy is written for the owner's visitors, specific and plain. Dates, times and places are real fields, never baked into prose.
- The design is this site's own. Its layout, type and motion follow the brief, not a shared template.

### Forms
Every form is a plain HTML form, `<form method="post" action="/__vibld/forms/<name>">`, named as the brief names it (lowercase letters, digits and hyphens). Fields are ordinary named inputs; checkboxes repeat their name; no file uploads. Add a hidden `_next` input with the path to land on, and show a thank-you there when the address has `?submitted=<name>`. Add an empty hidden `_gotcha` input. A script may post it instead with `fetch(form.action, { method: 'POST', body: new FormData(form), headers: { accept: 'application/json' } })`, which answers `{ ok: true }` or `{ ok: false, error }`. A form with limited places lists them in `public/vibld.forms.json` (`{"forms":{"<name>":{"slots":{"field":"<field>","options":{"<value>":<places>}}}}}`), the field a select or radio whose values match those keys exactly; `GET /__vibld/forms/<name>/slots` returns `{ field, options: [{ value, capacity, taken, left }] }`, which the page reads to show what is left and disable full options. vibld adds bot protection when the page is served.

### Engineering baseline
- TypeScript strict mode, small typed components, and one source of truth for design tokens (CSS variables consumed by Tailwind).
- All copy lives in typed content files, so the owner can edit words without touching layout.
- Every form validates on the client, says what went wrong in plain words beside the field, and never claims success it has not had.
- No secrets in the bundle and no third-party scripts beyond Google Fonts; an owner's tool comes in only as a link or a framed page.
### Goal
Build **Riverbend Food Collective**: a site for a volunteer-run food bank that shows what each dollar and each shift does, fills its volunteer shifts, and sends donors to its giving page in two clicks.

### Stack
React + TypeScript + Vite, Tailwind CSS and React Router, one route per page. Content collections in `src/content/`, forms posting to vibld (see Forms in the baseline). No backend of its own.

### Pages & layout
- `/` Home: hero with impact numbers, three ways to help, get food, open shifts, stories, partners
- `/get-food` Get food: pantry hours and locations, what to bring (nothing), languages spoken, a map link per site
- `/volunteer` Volunteer: what each shift does, the shift sign-up form with places left
- `/give` Give: what a gift buys, the giving tool framed or linked, food drive kit, employer matching
- `/stories` Stories: news and stories, each with its page
- `/about` About: mission, board, annual report download, contact form

Home, top to bottom:
1. Top bar: wordmark, Get food, Volunteer, Stories, About, and a Give now button.
2. Hero: big headline on paper, one cropped photo in a tomato block, and three impact stats (meals this year, families each week, volunteers).
3. Three ways to help: give, volunteer, run a food drive, as large color cards.
4. Get food strip: today’s pantry hours and the nearest site, in plain words.
5. Open shifts list: the next six shifts with places left.
6. Stories grid: three latest stories.
7. Partners: a text list of partner names, no logo wall.
8. Footer with address, EIN, hours, and contact form link.

Copy to start from, in `content.ts`: headline "No one in Riverbend goes hungry", subcopy "We rescue surplus food and hand it out four days a week. Every shift and every dollar goes straight to the pantry shelves.", primary action "Give now".

### Design system
Mood: Bold, civic and hopeful, like a community poster on a market wall: big numbers, short sentences, color with purpose.

Palette: paper `#fbfaf5`, river ink `#10221b`, tomato `#c8371c`, leaf `#c7e36b`. Tokens: background `#fbfaf5`, foreground `#10221b`, primary `#c8371c` with `#fbfaf5` labels, cards `#edede8`, accent `#c7e36b`.

Type: Anek Latin for headlines and impact numbers; Radio Canada for body, shift lists and forms. Load both from https://fonts.googleapis.com/css2?family=Anek+Latin:wght@500;800&family=Radio+Canada:wght@400;600&display=swap.

Corners: 4px on controls, 8px on cards, 20px on large panels. Spacing: Punchy: 72 to 96px between sections, oversized numerals with tight leading.

Imagery: Real work in progress: crates of produce, volunteers sorting, a pickup line on a bright morning. Cropped tight and set in thick color blocks. Use the owner's photos where the project has them. Without them, use the project's stock photos, or shapes and color from the palette; never a stock photo of people at desks.

### Components & interactions
- Impact stat: oversized numeral, a short label and an "as of" date from impact.json
- Shift row: day, time, task, places left from the slots endpoint, and a full state
- Three-ways card in tomato, leaf and ink

Motion:
- Shift list reads places left on load and disables full shifts with "Full, thank you"
- Suggested amount buttons open the giving page in a new tab

The signature motion is: the impact numbers count up once, quickly, the first time they come into view, then hold. Keep it to that one; everything else is a 150 to 300ms state change. With prefers-reduced-motion, it and every reveal are still.

### Data & state
Collections:
- `src/content/stories.json`: a story: title, date, photo, summary, body in Markdown; each has its page at `/stories/<slug>`
- `src/content/sites.json`: a pantry site: name, address, days and hours, languages, notes
- `src/content/impact.json`: an impact number: label, value, as of (date)

Forms:
- `volunteer-shift`: A volunteer picks a shift. Fields: name, email, phone, shift (radio), first time (yes or no), group size. Places are limited per shift: Saturday 8-11 sort 12, Saturday 11-2 pantry 10, Tuesday 4-7 pantry 8, Thursday 9-12 delivery 6.
- `contact`: A general question or a food drive request. Fields: name, email, topic (select), message.

Linked tools:
- Giving: the collective’s donation page (Zeffy, Givebutter or Donorbox), framed on /give, with suggested amounts as buttons that open it.
- Annual report: a PDF the owner uploads.

### Accessibility
WCAG 2.2 AA. Every control has a visible focus ring and a 44px target, every form field a visible label, and errors are announced. Dates and times are written out ("Sunday, March 8, 10:30 AM"), not only shown in a grid. Images have alt text that says what is in them. Verified contrast: body text on the page #10221b on #fbfaf5 15.86:1; text on cards #10221b on #edede8 14.11:1; secondary text on muted surfaces #4b5852 on #e8e9e4 6.10:1; secondary text on the page #4b5852 on #fbfaf5 7.13:1; label on the primary action #fbfaf5 on #c8371c 4.99:1; label on secondary surfaces #10221b on #edede8 14.11:1; label on the accent #10221b on #c7e36b 11.54:1; error label #ffffff on #c62f2f 5.45:1; primary action against the page #c8371c on #fbfaf5 4.99:1.

### Security
No third-party scripts other than Google Fonts. Framed tools are `<iframe>`s from the owner's own address with a `title`, `loading="lazy"` and `referrerpolicy="strict-origin-when-cross-origin"`. Forms cap input length and carry the empty `_gotcha` field.

### Performance & SEO
Images as AVIF or WebP with width and height, the first one eager and the rest lazy. Preconnect to Google Fonts. Each page has its own title and description from content, and records' pages take theirs from the record. Structured data where it fits: Organization and Event.

### Guardrails
- Avoid: Pity imagery, a donation thermometer that is never updated, stock photos of hands holding a heart, and percentages without a source.
- One primary action per screen, one accent color, at most six top-level links.
- No carousel in the hero, no mega menu, no emoji or clip-art icons, no hard offset shadows, no purple-to-blue gradient.
- The names in it are invented. Use no real organization's or person's name, logo or trademark.

Open the builderAll templatesThis palette on its own