The Contact page transforms a standard enquiry form into a casting ritual. Three minimalist fields — each with only a gold bottom border — collect the visitor’s name, email, and message. Pressing “Cast the Spell” blurs the form and summons an animated SVG sigil: a five-pointed star traces itself over three seconds inside a closing circle. When the sigil completes, the form is replaced by a “Sigil Received” success state with an animated checkmark. A “Cast Another” button resets the entire ritual.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/apursley2012/fortune-seeker/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The Contact page lives at route/contact and is titled “Send a Sigil”. Its opening quote — “Inscribe your message. I shall divine a response.” — frames the act of sending a message as an act of inscription. Two booleans manage the UI: isCasting (true while the sigil animation plays) and isSuccess (true after the animation completes). The onSubmit handler prevents the default form action, sets isCasting to true, then after 3000 ms sets isCasting to false and isSuccess to true. AnimatePresence mode="wait" orchestrates the transitions between form, sigil overlay, and success state.
The form does not include a real form submission — the
onSubmit handler only manages UI state. To wire up a real backend, call your API (e.g., Formspree, EmailJS, or a custom endpoint) inside onSubmit before starting the animation timer, and handle error states by resetting isCasting if the request fails.Layout & Components
Form fields (×3)
Three
div wrappers each hold a label and an input or textarea. All inputs have background: transparent, border-bottom: 1px solid gold/30, and focus:border-gold for a minimalist look. All are disabled when isCasting is true, preventing re-submission during the animation.Submit button
A full-width
button with a gold border and serif uppercase text. It shows “Cast the Spell” with a Send icon in its idle state, and “Casting…” (no icon) during isCasting. The button is disabled during casting.Sigil SVG overlay
When
isCasting is true, an absolutely-positioned motion.div renders over the blurred form. It contains a motion.svg with two motion.path / motion.circle children: a five-pointed star and a surrounding circle. Both paths animate pathLength from 0 to 1. The circle uses a delay: 0.5 so it begins drawing after the star.Success state
The success state renders a
64×64 gold circle with an animated motion.svg checkmark path inside. The circle scales in from scale: 0 via a spring. The checkmark’s pathLength animates from 0 to 1 with a delay: 0.5. Below it, “Sigil Received” and a flavour text paragraph complete the confirmation.Data Structure
The form fields are hardcoded in JSX rather than driven by a data array. Here is their effective structure for reference:Animations
Form blur on submit
Form blur on submit
The
motion.form uses animate: { filter: isCasting ? "blur(4px)" : "blur(0px)" }. This is a CSS filter applied by Framer Motion as an inline style, so the blur transition runs through the Framer Motion animation pipeline and can be interrupted cleanly if the component re-renders.Sigil star path draw (3 s)
Sigil star path draw (3 s)
The
motion.path for the star uses initial: { pathLength: 0 } and animate: { pathLength: 1 } with transition: { duration: 2, ease: "easeInOut" }. A drop-shadow filter on the SVG container (drop-shadow-[0_0_20px_rgba(201,169,110,0.8)]) gives the drawing stroke a strong gold radiance.Outer circle draw (delay 0.5 s)
Outer circle draw (delay 0.5 s)
The
motion.circle animates pathLength from 0 to 1 with initial: { pathLength: 0, opacity: 0 } and animate: { pathLength: 1, opacity: 0.5 }. The delay: 0.5 means the circle begins closing around the already-drawing star, framing it.Flash overlay at completion
Flash overlay at completion
At
delay: 2.5 (just as the sigil finishes drawing), a motion.div with mix-blend-mode: overlay and a gold background flashes opacity: [0, 0.8, 0] over duration: 0.5. This creates a brief “seal” flash before the success state transitions in, punctuating the ritual completion.Success checkmark (spring)
Success checkmark (spring)
The success circle scales in via
initial: { scale: 0, opacity: 0 } → animate: { scale: 1, opacity: 1 } with a spring transition. The checkmark motion.svg path draws from pathLength: 0 to pathLength: 1 over 1 s with a delay: 0.5. Both animations are orchestrated by AnimatePresence mode="wait".Customization
Wire up a real email service
Inside the
onSubmit handler, collect form values from event.target elements (or use useRef / controlled inputs), then await a fetch call to Formspree, EmailJS, or your own API endpoint. Start the sigil animation only after the request resolves successfully. On failure, reset isCasting to false and display an error message.Change the sigil geometry
Replace the star path
"M50 10 L90 90 L10 40 L90 40 L10 90 Z" with any SVG d attribute. Pentacles, hexagrams, and spirals all work well in a 100×100 viewBox. Keep the path relatively simple — highly complex paths with many points can look jittery during the pathLength draw animation.Adjust animation timing
The sigil animation takes 2 s (star) + 0.5 s delay for circle start = effectively 2.5 s before the flash. The
setTimeout that triggers the success state is set to 3000 ms. If you lengthen the star duration, increase the timeout accordingly to avoid the success state appearing before the animation completes.Add field validation feedback
The current form relies on native HTML5
required validation. For custom error messages that match the gold aesthetic, add controlled state for each field and render a small motion.p below each input that fades in when the field is empty on submit. Use initial: { height: 0, opacity: 0 } and animate: { height: "auto", opacity: 1 } for the error reveal.