Skip to main content

Documentation Index

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

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

Footer provides a consistent bottom bar on every page of the Spooky Developer portfolio. It displays a dynamic copyright notice and a ghost-icon button that lets visitors toggle haunt mode on or off. Because it sits at the end of the Layout flex column — after the flex-grow <main> element — it is naturally pushed to the bottom of the viewport on short pages and flows below the content on longer ones.

What it renders

The footer is a single <footer> element with two children arranged in a responsive flex row:
<div className="text-haunt-bone/60 text-sm font-body">
  © {new Date().getFullYear()} The Developer from Beyond.
</div>
The year is evaluated at render time using new Date().getFullYear(), so it always displays the current year without any manual updates. The text uses text-haunt-bone/60 — a muted warm-cream at 60 % opacity — to keep it readable without competing with page content.

Haunt-mode toggle button

<button onClick={toggleHaunt} className="flex items-center gap-2 px-4 py-2 rounded-full border border-haunt-moon/30 text-haunt-moon hover:bg-haunt-moon/10 transition-colors font-body text-sm">
  <GhostIcon className={`w-4 h-4 ${isHaunted ? 'animate-bounce' : 'opacity-50'}`} />
  {isHaunted ? 'Calm the haunt' : 'Awaken the spirits'}
</button>
The button calls toggleHaunt from the useHaunt() context hook. When haunt mode is active the ghost icon bounces (animate-bounce) and the label reads “Calm the haunt”; when inactive the icon is dimmed (opacity-50) and the label reads “Awaken the spirits”. The preference is persisted to localStorage by the HauntProvider, so the user’s choice survives page reloads.

Styling

The <footer> element carries the following Tailwind classes:
ClassPurpose
w-full py-8 px-6Full-width with comfortable vertical and horizontal padding
mt-20Separates the footer from the last page section
border-t border-haunt-moon/20Subtle teal top border as a visual divider
flex flex-col md:flex-row justify-between items-center gap-4Stacks on mobile, splits left/right on desktop
bg-haunt-bg/80 backdrop-blur-smSemi-transparent dark teal background with blur, matching the header treatment
z-50 relativeKeeps the footer above the fixed Background layer

Automatic inclusion

Footer is imported and rendered directly inside Layout. There is no need to add it to individual page components — it appears on every route automatically.
// Layout.js — excerpt
<div className="min-h-screen flex flex-col relative ...">
  {/* ... */}
  <main className="flex-grow ...">
    <Outlet />
  </main>
  <Footer />   {/* ← always present, always at the bottom */}
</div>
All footer content lives in components/layout/Footer.js. Common modifications: Add anchor tags before or after the copyright <div>:
<a href="https://github.com/yourhandle" target="_blank" rel="noopener noreferrer"
   className="text-haunt-moon/60 hover:text-haunt-moon transition-colors text-sm font-body">
  GitHub
</a>
Edit the string inside the copyright <div>. The {new Date().getFullYear()} expression can be kept as-is for an auto-updating year. Import NavLink from react-router-dom and add links to internal routes:
import { NavLink } from 'react-router-dom';

<NavLink to="/contact" className="text-haunt-bone/60 hover:text-haunt-moon text-sm font-body transition-colors">
  Contact
</NavLink>

Source location

components/layout/Footer.js

Build docs developers (and LLMs) love