Move the previous + upcoming dates out of the dark hero box into an editorial
strip beneath it (large serif day, terracotta eyebrow, "All gatherings" link
top-aligned on the right). Hero card keeps just the RSVP footer.
Admin can now upload a png/jpg event photo (SPEC §8 exception added):
- new image-upload admin field kind with live preview, uploading via
POST /api/admin/upload (fenja-only, type + 5MB validation);
- files stored under data/uploads (gitignored, BIFROST_UPLOAD_DIR
overridable) and served by GET /uploads/[file] with a traversal guard.
Reworks the /pulse event card: the greeting moved inside a taller box, the
"next gathering" label sits above the date + title, and the photo renders
as a top-right background that blends into the indigo via gradient masks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Three small tweaks:
- AppLayout wordmark: 'Project' and 'Bifrost' now share font-size 18 +
line-height 1.4 + tracking-snug via a combined selector. The previous
asymmetry (Bifrost had display: inline-block + padding 4/0/2 +
line-height: 1 to lift the gradient-clip box for the italic ascender)
was visibly making Bifrost render slightly off-height vs Project. With
parent line-height 1.4 the gradient-clip bbox is tall enough on its
own; padding hack removed.
- EventHeroCard footer status line drops the ' | CLOSES TUESDAY'
trailer. The line now reads simply '{capacity} SEATS · {n} CONFIRMED'.
closesDay variable and .hero-status-divider style both gone.
- /pulse pulse-col eyebrow: 'This week's' → 'Pulse Vote'. Matches the
more direct labelling everywhere else.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Self-contained component for the next gathering. Three-column grid:
- Left (140px): 10px tracked weekday · 88px serif day numeral (zero-
padded, line-height 0.85) · 11px tracked MONTH · HH:MM line. All on
the bleached --on-ink cream.
- Middle (1fr): 10px tracked NEXT GATHERING · KIND eyebrow · 26px serif
title · 13px description (--on-ink-body @ 85%) · 12px location line
(--on-ink-muted @ 65%).
- Right (auto, min 140px): tracked duration label right-aligned, then
up to 3 confirmed attendees as 'name + 18px avatar' rows, with a
+N overflow chip beneath if more.
Bottom strip after a 0.5px --ink-divider top border, padding-top 22px:
- Left: tracked '{capacity} SEATS · {n} CONFIRMED | CLOSES {DAY}' status
line, with a low-opacity '|' divider character between the halves.
- Right: form actions — 'Can't make it' link + cream pill 'Save your
seat →'. If already confirmed, swaps to outlined 'You're confirmed
✓' + a small 'Change' link.
Empty state collapses the action strip and renders a serif italic
'Nothing scheduled yet — when we have something, you'll be the first to
know.' (the only italic on the card, mirroring the spec).
/pulse swap: the previous inline events-card markup (hero body + bundled
coming-up grid + see-all link) is replaced by a single <EventHeroCard>
slot. The 'Also coming up' strip lives outside the indigo card now and
will be built in step 6; for this commit a temporary comment marker
holds its slot. AvatarPile import is dropped from /pulse since
EventHeroCard renders the attendees list inline.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>