Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/apursley2012/aurora-borealis/llms.txt

Use this file to discover all available pages before exploring further.

The Contact page uses the Signal Transmitter theme — sending a message is framed as broadcasting a signal into the cosmos. A decorative animated beam pulses outward when the form is submitted, and the form transitions into a SIGNAL RECEIVED confirmation state once the submission is handled. Three social links (GitHub, LinkedIn, email) sit beneath the form as secondary contact options.
All page components for this portfolio are inlined inside assets/main.js, which is the compiled Vite production bundle. Do not edit main.js directly. Instead, make changes to the source files before running the Vite build. Editing the pre-built bundle will be overwritten on the next build.

What the Page Displays

The /contact route contains three parts:
  1. Contact form — three fields (name, email, message) with a submit button.
  2. Animated signal beam — a radial burst animation that plays on form submission.
  3. SIGNAL RECEIVED state — the form is replaced by a confirmation message after a successful submit.

Contact Form Fields

// main.js — contact form structure
<form onSubmit={handleSubmit} className="signal-form">
  <label htmlFor="name">Name</label>
  <input id="name" name="name" type="text" required placeholder="Your name" />

  <label htmlFor="email">Email</label>
  <input id="email" name="email" type="email" required placeholder="your@email.com" />

  <label htmlFor="message">Message</label>
  <textarea id="message" name="message" required placeholder="Your transmission..." rows={5} />

  <button type="submit" className="signal-submit">
    Send Signal
  </button>
</form>
All three fields are required. Attempting to submit with an empty field triggers the browser’s native validation. The type="email" attribute on the email field also provides basic format validation without JavaScript.

Animated Signal Beam

When the form is submitted, a signalFired state variable is set to true, triggering a Framer Motion AnimatePresence animation:
// main.js — signal beam animation
<AnimatePresence>
  {signalFired && (
    <motion.div
      className="signal-beam"
      initial={{ scale: 0, opacity: 1 }}
      animate={{ scale: 4, opacity: 0 }}
      exit={{}}
      transition={{ duration: 1.4, ease: "easeOut" }}
      onAnimationComplete={() => setShowConfirmation(true)}
    />
  )}
</AnimatePresence>
  • The beam starts at scale: 0 (a point at the center of the submit button) and expands to scale: 4 while fading to transparent over 1.4 seconds.
  • onAnimationComplete fires after the beam fades, setting showConfirmation to true and revealing the confirmation message.
  • To adjust the beam’s spread speed, change duration. To change the color of the beam, edit the background property on .signal-beam in the CSS (default is a radial gradient of #60a5fa → transparent).

SIGNAL RECEIVED Confirmation State

After the beam animation completes, the form is replaced by a confirmation panel:
// main.js — confirmation state
{showConfirmation ? (
  <motion.div
    className="signal-received"
    initial={{ opacity: 0, y: 20 }}
    animate={{ opacity: 1, y: 0 }}
    transition={{ duration: 0.6 }}
  >
    <h2>SIGNAL RECEIVED</h2>
    <p>Transmission logged. I'll respond within 48 hours.</p>
    <button onClick={resetForm}>Send another signal</button>
  </motion.div>
) : (
  <form>{/* ... */}</form>
)}
To change the confirmation copy, edit the <h2> text and <p> text inside the signal-received block. The “Send another signal” button calls resetForm, which sets both signalFired and showConfirmation back to false and clears the form fields.

Form Submission Handling

The contact form is front-end only by default. The handleSubmit function in main.js prevents the default browser submit and triggers the signal animation, but it does not send data to any server or email address. To make the form functional, you must integrate a backend or third-party form service before deploying.

Integration Options

ServiceApproach
FormspreeReplace handleSubmit with a fetch POST to your Formspree endpoint. Free tier available.
EmailJSCall emailjs.send() inside handleSubmit using your service, template, and public key.
Netlify FormsAdd netlify attribute to the <form> tag if deploying on Netlify — no code changes needed.
Custom APIPOST the form data to your own Express/Next.js/Edge Function route and send via Nodemailer or Resend.
Example using Formspree:
// main.js — handleSubmit with Formspree
async function handleSubmit(e) {
  e.preventDefault();
  const data = new FormData(e.target);

  const response = await fetch("https://formspree.io/f/YOUR_FORM_ID", {
    method: "POST",
    body: data,
    headers: { Accept: "application/json" },
  });

  if (response.ok) {
    setSignalFired(true);
  }
}

Below the form, three social links are rendered from a CONTACT_LINKS array:
// main.js
const CONTACT_LINKS = [
  {
    platform: "GitHub",
    href: "https://github.com/your-handle",
    icon: Github,
    label: "View source on GitHub",
  },
  {
    platform: "LinkedIn",
    href: "https://linkedin.com/in/your-profile",
    icon: Linkedin,
    label: "Connect on LinkedIn",
  },
  {
    platform: "Email",
    href: "mailto:you@yourdomain.com",
    icon: Mail,
    label: "Send a direct email",
  },
];
Update the href values for each platform. For the email link, change you@yourdomain.com to your actual address. The icon values are Lucide React components (Github, Linkedin, and Mail from lucide-react) imported at the top of main.js — swap them for any other Lucide icon to add or change platforms (e.g., Twitter/X, Dribbble).

Customization Checklist

1

Connect a form backend

Integrate Formspree, EmailJS, Netlify Forms, or a custom API endpoint into the handleSubmit function before going live.
2

Update social links

Replace all three href values in CONTACT_LINKS with your real profile URLs and email address.
3

Customize confirmation copy

Edit the SIGNAL RECEIVED heading and follow-up paragraph to match your preferred tone and response-time commitment.
4

Adjust beam animation timing

Change duration on the signal beam’s transition to speed up or slow down the visual feedback on submit.
5

Add ARIA labels

Ensure each social link has a descriptive aria-label attribute if you replace the text labels with icon-only buttons.

Home

The hero page where social links are also surfaced as secondary CTAs.

About

The Flight Log career narrative — context visitors often read before reaching out.

Build docs developers (and LLMs) love