Lakeside Cabin Weekend
Two nights for four, donated by Maya Okafor.
Every Kestrel Gives component in every state, built only from the tokens in tokens.css. Documented in DESIGN-SYSTEM.md. Follows your light or dark setting.
Stage A
Initials on a token-colored circle. The current high bidder wears the crown everywhere their avatar appears in that item's bid history. Avatars sit next to the person's name, so they're hidden from screen readers; the name carries "(top bidder)" as hidden text.
Light
Dark
Stage A
Fourteen original line icons on a 24-unit grid, stroke 2, round caps and joins, in the surrounding text color. Decorative icons are hidden from screen readers; an icon that stands alone gets a label.
Stage A
One button per action. Primary for the main action on a screen (one per view), secondary for alternatives, quiet for low-emphasis actions, danger for destructive ones. Disabled uses aria-disabled so the button stays focusable; loading adds aria-busy and a spinner that stops under reduced motion. Hover, pressed and focus are forced here with documentation-only classes.
Light
primary
secondary
quiet
danger
danger outline
sizes and layouts
Dark
primary
secondary
quiet
danger
danger outline
sizes and layouts
Stage A
Links go somewhere; buttons do something. Links are always underlined, so they don't rely on color. External links open in a new tab, show the external icon and say so to screen readers.
Light
Dark
Stage A
A short, non-interactive status label (also called a badge). The word carries the meaning; color and icon only support it.
Light
Dark
Stage A
A message about the whole page or event that stays until the situation changes. Phase (butter) says where the event is and is a status region; info gives neutral context; success, warning and danger report outcomes. Errors put focus or a link at the field that needs fixing.
Light
Dark
Stage A
A brief confirmation that something just happened, announced politely. It leaves after six seconds, waits while hovered or focused, and can be dismissed. Anything the person must act on goes in a banner or dialog instead.
Light
Dark
Stage A
A contained group of content. Media, header and footer are optional. Flat drops the shadow for cards inside other surfaces. Linked cards open the title's link from anywhere on the card, but the title stays the only tab stop.
Light
Two nights for four, donated by Maya Okafor.
Two nights for four, donated by Maya Okafor.
Two nights for four, donated by Maya Okafor.
Two nights for four, donated by Maya Okafor.
Two nights for four, donated by Maya Okafor.
Dark
Two nights for four, donated by Maya Okafor.
Two nights for four, donated by Maya Okafor.
Two nights for four, donated by Maya Okafor.
Two nights for four, donated by Maya Okafor.
Two nights for four, donated by Maya Okafor.
Stage A
What a list or page shows when there's nothing in it yet: what's missing, why, and the next step.
Light
Items you add show up here. Add one to start building the catalog.
Dark
Items you add show up here. Add one to start building the catalog.
Stage 6F
Shown at once where a page waits on the server, then its content. A read that fails or takes over 10 seconds ends in the error with Try again (DECISIONS entry 119).
Light
Loading items…
Check your connection and try again.
Dark
Loading items…
Check your connection and try again.
Stage B
A label, optional help, the control, then a message. Only optional fields are marked, with “(optional)”. Errors appear after a submit, under the field, and re-check as you fix them. Read-only shows a value that can't change, such as a locked sale type.
Light
default, with help
What people will see in the catalog.
optional, empty
hover
focus
error
disabled
read-only
Locked once an item has a bid.
textarea
textarea, error
Dark
default, with help
What people will see in the catalog.
optional, empty
hover
focus
error
disabled
read-only
Locked once an item has a bid.
textarea
textarea, error
Stage B
Whole dollars only, everywhere (SPEC §7.9): a text field with a numeric keyboard and a digits-only pattern, never type=number. Cents or symbols get “Whole dollars only.” Minimums in help and errors come from the event settings. A warning still lets you submit.
Light
default
At least $10, the event minimum. Whole dollars.
error: cents typed
error: below the minimum
warning: you can still submit
disabled (locked)
Dark
default
At least $10, the event minimum. Whole dollars.
error: cents typed
error: below the minimum
warning: you can still submit
disabled (locked)
Stage B
Native controls, styled to match. The date-time input shows the event's time zone beside it; times are stored in UTC and shown in each viewer's zone.
Light
default
focus
error
disabled
date-time
In the event's time zone, Eastern Time. Everyone sees it in their own time zone.
date-time, error
In the event's time zone, Eastern Time. Everyone sees it in their own time zone.
date-time, disabled
In the event's time zone, Eastern Time. Everyone sees it in their own time zone.
Dark
default
focus
error
disabled
date-time
In the event's time zone, Eastern Time. Everyone sees it in their own time zone.
date-time, error
In the event's time zone, Eastern Time. Everyone sees it in their own time zone.
date-time, disabled
In the event's time zone, Eastern Time. Everyone sees it in their own time zone.
Stage B
A choice between a few big options, each saying when to choose it. Native radios, so arrow keys move between options. Side by side when there's room, stacked when not.
Light
none chosen
checked
hover
focus
error
disabled
Dark
none chosen
checked
hover
focus
error
disabled
Stage B
One to five photos; the first is the cover. Arrow buttons reorder and a button removes, so nothing needs dragging, and each change is announced. Problems name the file. Uploading is shown per photo.
Light
empty
JPEG, PNG or WebP, up to 4 MB each. The first photo is the cover.
three photos
JPEG, PNG or WebP, up to 4 MB each. The first photo is the cover.
uploading
JPEG, PNG or WebP, up to 4 MB each. The first photo is the cover.
error: nothing added
JPEG, PNG or WebP, up to 4 MB each. The first photo is the cover.
error: file problems
JPEG, PNG or WebP, up to 4 MB each. The first photo is the cover.
full: five photos
JPEG, PNG or WebP, up to 4 MB each. The first photo is the cover.
Dark
empty
JPEG, PNG or WebP, up to 4 MB each. The first photo is the cover.
three photos
JPEG, PNG or WebP, up to 4 MB each. The first photo is the cover.
uploading
JPEG, PNG or WebP, up to 4 MB each. The first photo is the cover.
error: nothing added
JPEG, PNG or WebP, up to 4 MB each. The first photo is the cover.
error: file problems
JPEG, PNG or WebP, up to 4 MB each. The first photo is the cover.
full: five photos
JPEG, PNG or WebP, up to 4 MB each. The first photo is the cover.
Stage B
After a submit with problems, a danger banner at the top of the form takes focus and links to each field.
Light
Dark
Stage B
A working form built from these components. Nothing is sent anywhere. Choose a sale type to unlock the rest, then submit with mistakes to see the error summary.
Stage C1
The first thing Tab reaches on every page: it jumps past the header to the main content. Hidden until focused. Press Tab on this page to see the real one.
Stage C1
Mark and name, the main nav, then the person. Admins get a profile menu (a disclosure with a list of links: Escape or a click outside closes it and returns focus to the button); employees see their avatar only. The nav collapses to a Menu button when the header itself is narrower than the large breakpoint (--breakpoint-lg); that's where the full nav stops fitting. Submit an Item shows only during the submission window.
Light
narrow: collapsed (live)
narrow: menu open
profile menu open
employee: avatar only
Dark
narrow: collapsed (live)
narrow: menu open
profile menu open
employee: avatar only
Light
Dark
Stage C1
The top of each page: an optional back link, the page's h1 (shown here as h3 so the gallery's outline stays intact), an optional description, and actions that wrap under the title on small screens.
Light
back link, description, actions
Two nights for four, donated by Maya Okafor.
title only
Dark
back link, description, actions
Two nights for four, donated by Maya Okafor.
title only
Stage C1
The demo's own controls, first on every page and in the normal flow, so it never covers content. Dark in both modes with butter hazard stripes, so it stands apart from the app. It collapses to a strip (remembered), announces who you're viewing as, and hides with ?demo=off. Restore demo data, a danger-outline button, opens its red confirmation dialog. “Shared demo · resets daily” is in the open bar only, so the strip stays one line. About this demo (open bar only) reopens the welcome dialog; try it in the open specimens.
Light
open (live)
collapsed
Dark
open (live)
collapsed
Stage C1
The event mark, then “Kestrel” over “gives” in the heading font: one image to screen readers, named “Kestrel Gives”. On Home it sits inside the page's h1. The mark's file is white, so the card is light in both modes.
Light
KestrelgivesDark
KestrelgivesMilestone 3C
Home's numbered How to participate list (an ordered list; the circles repeat its numbers) and a charity's logo, name and description stacked on a flat card, the logo on the art's own white in both modes. The hero itself is the lockup above beside the event's name and description.
Light
Offer something you make or do.
Bid in the silent auction or claim instant-sale items.

Fosters and rehomes cats and dogs from crowded shelters.
Dark
Offer something you make or do.
Bid in the silent auction or claim instant-sale items.

Fosters and rehomes cats and dogs from crowded shelters.
Stage C2
Native modal dialogs: focus moves in and stays in, the page behind goes inert, Escape closes (except while a request runs) and focus returns to the button that opened it. Confirm shows what you're agreeing to, with amounts computed from the data. Danger starts on the safe button. Type-to-confirm keeps its button inactive until the event name is typed exactly. Info (the welcome) offers a way on instead of asking: its dismiss is the primary and takes first focus, and the tour is a real link. When it's taller than the screen only its body scrolls, with a divider above the actions. On phones the actions fill the row, and each takes the full width when they wrap. Try the live ones below; requests take about a second.
Light
confirm: bid (amount computed from the bid)
Place a $65 bid?
Lakeside Cabin Weekend
Top bid $60 · 4 bids
Your bid: $65
Bids can't be taken back.
confirm: request running (Escape and Cancel wait)
Place a $65 bid?
Lakeside Cabin Weekend
Top bid $60 · 4 bids
Your bid: $65
Bids can't be taken back.
confirm: request failed
Place a $65 bid?
Lakeside Cabin Weekend
Top bid $60 · 4 bids
Your bid: $65
Bids can't be taken back.
danger: restore demo data
Restore demo data?
Every item, bid, purchase, proof and email template goes back to the seeded demo. Changes made since then are lost.
danger: cancel item
Cancel this item?
Lakeside Cabin Weekend comes off the listings. Its page stays up, marked as cancelled, and everyone who bid sees it on their dashboard.
with a reason: submitted empty (inline error, field invalid)
Reject Rosa Delgado's proof?
Rosa will see your reason on Your Items and can upload a new proof.
For example, "The screenshot doesn't show the amount." Up to 300 characters.
type to confirm: not matching yet (button inactive)
Reset for next year?
This deletes every item, photo, bid, purchase and proof from Kestrel Gives 2026. Users, charities, email templates and settings stay. This can't be undone.
type to confirm: matches
Reset for next year?
This deletes every item, photo, bid, purchase and proof from Kestrel Gives 2026. Users, charities, email templates and settings stay. This can't be undone.
info: the welcome (Start exploring is the primary and takes first focus; the guide is a link; the × closes, and so does a click on the backdrop)
Welcome to the Kestrel Gives demo
A demo of an auction and instant sale tool I designed and built at a previous job, rebuilt from memory with fictional people and data. Switch who you're viewing as and where the event is, and try it out.
Everyone shares this demo, and it resets daily.
Try this:
Restore demo data puts everything back.
Dark
confirm: bid (amount computed from the bid)
Place a $65 bid?
Lakeside Cabin Weekend
Top bid $60 · 4 bids
Your bid: $65
Bids can't be taken back.
confirm: request running (Escape and Cancel wait)
Place a $65 bid?
Lakeside Cabin Weekend
Top bid $60 · 4 bids
Your bid: $65
Bids can't be taken back.
confirm: request failed
Place a $65 bid?
Lakeside Cabin Weekend
Top bid $60 · 4 bids
Your bid: $65
Bids can't be taken back.
danger: restore demo data
Restore demo data?
Every item, bid, purchase, proof and email template goes back to the seeded demo. Changes made since then are lost.
danger: cancel item
Cancel this item?
Lakeside Cabin Weekend comes off the listings. Its page stays up, marked as cancelled, and everyone who bid sees it on their dashboard.
with a reason: submitted empty (inline error, field invalid)
Reject Rosa Delgado's proof?
Rosa will see your reason on Your Items and can upload a new proof.
For example, "The screenshot doesn't show the amount." Up to 300 characters.
type to confirm: not matching yet (button inactive)
Reset for next year?
This deletes every item, photo, bid, purchase and proof from Kestrel Gives 2026. Users, charities, email templates and settings stay. This can't be undone.
type to confirm: matches
Reset for next year?
This deletes every item, photo, bid, purchase and proof from Kestrel Gives 2026. Users, charities, email templates and settings stay. This can't be undone.
info: the welcome (Start exploring is the primary and takes first focus; the guide is a link; the × closes, and so does a click on the backdrop)
Welcome to the Kestrel Gives demo
A demo of an auction and instant sale tool I designed and built at a previous job, rebuilt from memory with fictional people and data. Switch who you're viewing as and where the event is, and try it out.
Everyone shares this demo, and it resets daily.
Try this:
Restore demo data puts everything back.
Stage C2
One item in a browse grid. The amount line and the single status are computed from the item, the viewer and the phase by the same code the app uses; nothing on these tiles is typed in. One status shows, most important first. Cancelled items never appear in listings, only in Your Items.
Submission window
Light
Dark
Live: silent auction
Light
Dark
Live: instant sale
Light
Dark
Ended
Light
Dark
Your Items only: cancelled
Light
Dark
Stage C2
The item page's photos: one at a time, previous and next, and thumbnails beneath. No autoplay. Thumbnails are buttons named “Photo 2 of 5”, and the current one is marked. The arrows go inactive at either end, and changes are announced. Placeholders stand in until the seed photos land (Milestone 2).
Light
five photos (live)
Photo 1 of 5
one photo: no controls
Photo 1 of 1
Dark
five photos (live)
Photo 1 of 5
one photo: no controls
Photo 1 of 1
Stage C2
Rows of records for admins. A caption names the table, numbers are right-aligned in tabular figures, and row actions (--size-target-sm, allowed in dense rows by SPEC §6) sit at the end with the row's name in their label. On narrow screens the table scrolls inside its own region, which joins the tab order only while it scrolls. No sorting until a screen needs it.
Light
people
| Name | Bids | Wins | Pledged | Proof | Actions |
|---|---|---|---|---|---|
| Maya Okafor | 12 | 2 | $410 | Approved | |
| Jules Ferreira | 7 | 1 | $85 | Proof due | |
| Dev Kapoor | 3 | 0 | $0 | None | |
| Priya Natarajan | 9 | 3 | $1,240 | Rejected |
empty
| Name | Proof amount | Donation total | Actions |
|---|---|---|---|
| No proofs to review. New ones show up here as winners upload them. | |||
Dark
people
| Name | Bids | Wins | Pledged | Proof | Actions |
|---|---|---|---|---|---|
| Maya Okafor | 12 | 2 | $410 | Approved | |
| Jules Ferreira | 7 | 1 | $85 | Proof due | |
| Dev Kapoor | 3 | 0 | $0 | None | |
| Priya Natarajan | 9 | 3 | $1,240 | Rejected |
empty
| Name | Proof amount | Donation total | Actions |
|---|---|---|---|
| No proofs to review. New ones show up here as winners upload them. | |||