The Commune page (Documentation Index
Fetch the complete documentation index at: https://mintlify.com/apursley2012/nightshade/llms.txt
Use this file to discover all available pages before exploring further.
/contact) renders the ContactPage component (Je) — a minimalist dark-parchment form where visitors can send a message. When the form is submitted, it dissolves away and a wax-seal confirmation panel rises in its place. A “Cast another?” link resets the view back to the blank form.
Route
/contact → ContactPage (Je)
Page Structure
The page is wrapped inmax-w-2xl mx-auto py-12. The header block renders “Commune” in font-heading text-5xl and the subtitle “Cast a message into the dark.” in font-code text-witch-turquoise/70. Below the header, the entire interactive area sits inside a single parchment-bg p-8 md:p-12 border border-witch-plum/30 rounded-sm container. AnimatePresence mode="wait" governs the crossfade between the form view and the success view.
Form Fields
The form contains three fields and a footer action bar.Name
Message
bg-transparent), no outline (outline-none), font-body text-witch-moonlight, and a bottom-border that transitions on focus:
bg-witch-dark/30, all-sides border border-witch-plum/50, p-4 rounded-sm, and resize-none.
Footer Action Bar
Below the fields, aflex justify-between items-center row holds two groups:
Left — quick links:
[ Send a Raven ]— amailto:anchor infont-code text-xs text-witch-turquoise, hovering totext-witch-amber.[ Astral Plane (GitHub) ]— an external link infont-code text-xs text-witch-plum, hovering totext-witch-amber.
relative overflow-hidden border border-witch-plum/50 rounded-sm button labelled “Seal & Send”. A div inside it acts as a sliding plum overlay (bg-witch-plum/20), scaling from scaleX: 0 to scaleX: 1 on group-hover using transform origin-left. While the submission delay is running, the label changes to "Sealing..." and the button is disabled with opacity-50.
Submission Flow
The form’sonSubmit handler manages a two-stage state transition without sending data to any server:
User clicks Seal & Send
isSending becomes true. The button label switches to "Sealing..." and disables.Form exits
AnimatePresence unmounts the form with exit={{ opacity: 0, y: -20, filter: "blur(10px)" }}.Confirmation Panel
The success state is a centered column rendered underAnimatePresence key "success":
- Wax seal — a
w-24 h-24 bg-red-900 rounded-fullcircle that enters with a spring bounce (initial: scale: 3 → scale: 1). Inside it,"Sealed"is rendered infont-heading text-red-200/80 text-2xl. - Heading —
"Message Cast"infont-heading text-3xl text-witch-turquoise. - Message —
"Your missive has entered the ether. I shall respond before the next new moon."infont-body text-witch-moonlight/70. - Reset link — a
"Cast another?"button that callssetIsSuccess(false), returning the view to the blank form.
Wiring Up a Real Backend
Formspree Example
Replace thesetTimeout block with a fetch call to your Formspree endpoint:
name attributes to each input (name="name", name="email", name="message") so FormData picks them up correctly.
Resend Example
Route the submission through a serverless function (e.g. a Vercel API route) that calls the Resend SDK:fetch("/api/contact", { method: "POST", body: JSON.stringify(formData) }) from the form handler.