Commit graph

4 commits

Author SHA1 Message Date
1ec01a2257 feat(roadmap): 'In motion right now' strip + subtitle copy + admin helper
New <RoadmapInMotion> component renders between the dispatch banner
and the route's section header. Pulls the most-recent shipping item
(same selection rule the .rr-current marker uses) and prints the
first sentence of its description as a 18px serif italic line
preceded by an 'IN MOTION RIGHT NOW' tracked eyebrow.

A member who only spends 5 seconds on /roadmap now still walks away
with a sentence about what just shipped — no scroll, no hover.

firstSentenceOf() is the obvious regex against the first
[.!?](?=\s|$). Bails to the 200-char slice if no sentence boundary
fits (covers 'Dr.' / 'e.g.' confusables). Returns '' on null. The
strip hides itself entirely when there's no shipping item, or when
the shipping item has no description text.

Page subtitle: 'Hover any milestone for the full story.' →
'Tap or hover any milestone for the full story.' — touch devices
don't have hover, and the kind of detail that says we're paying
attention.

Admin description-field gains a helper note: 'For shipping items:
the first sentence appears on /roadmap as the "In motion right now"
line. Make it count.' Nudges good first-sentence writing without
adding a new field to maintain.

Banner margin under the dispatch banner reduces 56 → 40px because
the in-motion strip carries its own 36px bottom margin to the route.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 12:00:14 +02:00
d17d9b93a7 feat(db): roadmap_items.metadata_text + admin field
Migration 0007 (spec said 0006 but 0006 was already roadmap_considering)
adds a single nullable metadata_text column to roadmap_items — a short
admin-set narrative cue shown on hover in the route cards. ~60 chars
suggested in admin helper text. Hidden in the UI when NULL.

db.ts: RoadmapItem type gains the field. createRoadmapItem + updateRoadmapItem
accept an optional metadata_text parameter. moveRoadmapItem passes it through
when swapping display_order between siblings so the helper preserves it.

Admin: /admin?tab=roadmap edit form gets a new 'Hover note' input under
the description, with the helper text and a 120-char hard cap. Empty
string saves as NULL.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 11:39:18 +02:00
9ae8422527 feat(db): roadmap_items gains 'considering' + 'in_beta' rename, --on-ink tokens
Migration 0006 (the spec said 0005 but that number was already taken by
polls_on_dispatches from the previous session): rebuilds the
roadmap_items CHECK to ('shipping','in_beta','exploring','considering')
and renames any existing 'beta' rows to 'in_beta' in-place. FKs from
roadmap_attributions are preserved across the DROP/RENAME by toggling
PRAGMA foreign_keys off around the rebuild — attribution count unchanged
after migrate (verified 4 rows survive on the demo DB).

Tokens (src/styles/tokens.css): adds --on-ink, --on-ink-body,
--on-ink-muted, --ink-divider. The bleached #fffcf7 cream replaces the
warm #e8e0d0 --ink-text wherever it sits on indigo. Legacy --ink-text /
--ink-muted stay in tokens.css for now — if any later commit references
them they remain defined; the migration of existing call sites is
covered here.

Migrated to the new tokens in this pass:
  - src/components/MembershipCard.astro (members/:slug card)
  - src/pages/events.astro (hero invitation card)
  Both render with cleaner whites on indigo as a side effect.

Code updates for the new status enum:
  - db.ts: RoadmapStatus = shipping | in_beta | exploring | considering
  - admin/RoadmapTab.astro: Status select gains Considering + In beta;
    grouped section iteration covers all four
  - admin/index.astro: validation list updated
  - scripts/seed-roadmap.js: 'In progress' markdown bucket → 'in_beta'
  - pulse.astro: roadmapStatusDot + roadmapStatusBlurb temporarily widened
    (full rewrite of that section lands in step 7)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 10:46:39 +02:00
f6e7337c5e feat(admin): pulses, roadmap, events, activity tabs
Four new tabs added to /admin, matching the existing pattern exactly: ?tab=
querystring, plain HTML POST with hidden action field, redirect-with-?msg=
success path, existing .tabs / .section / .data-table / .form-grid / .input
/ .select / .btn-primary / .danger-btn classes — no new form library, no JS
beyond `confirm()`.

Pulses tab — create / edit / publish / close / delete + a results view
(?view=ID) with per-option vote counts and bar charts. Publish writes the
'pulse_opened' activity row and calls notifyPulseOpened() so members can
be notified the same way once the integration lands.

Roadmap tab — full CRUD + multi-select attribution (checkbox grid of
council + pilot users) + up/down arrow reorder within each status column
(JS-free, swaps display_order with neighbour). Status transition to
'shipping' stamps shipped_at exactly once and writes 'roadmap_shipped'
activity.

Events tab — full CRUD + an RSVP summary view (?view=ID) showing going /
interested / declined counts. Slug is required on create and readonly on
edit (it's the URL handle).

Activity tab — read-only debug table of the last 200 activity rows. Per
your call: shipping with the rest, not optional. Saves hours of "why
isn't the ticker showing X" later.

Tab views extracted to src/components/admin/{Pulses,Roadmap,Events,Activity}Tab.astro
to keep admin/index.astro navigable; the POST handlers and data loading
stay in index.astro as the single dispatch point.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 14:57:44 +02:00