Skip to main content

Documentation Index

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

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

The Layout component is the single root wrapper rendered for every route in Full Moon. It stacks the midnight background, two fixed atmospheric overlay layers (fog and starfield), the custom <Cursor />, the site <Navigation />, and a Framer Motion–animated <main> that fades each page in and out as the user navigates. Because it sits at the top of the React tree, any visual primitive that must persist across page transitions — the background, the cursor, the nav bar — lives here rather than inside individual page components.
import { j as jsxs, m as motion } from "../assets/proxy.js";
import { C as Cursor } from "./Cursor.js";
import { N as Navigation, O as Outlet } from "./Navigation.js";

function Layout() {
  return (
    <div className="min-h-screen bg-midnight-base text-witch-teal-glow relative overflow-hidden">
      {/* Atmospheric fog overlay */}
      <div className="fixed inset-0 bg-fog pointer-events-none z-0" />

      {/* Procedural starfield overlay */}
      <div className="fixed inset-0 starfield pointer-events-none z-0" />

      {/* Custom animated cursor */}
      <Cursor />

      {/* Site-wide navigation bar */}
      <Navigation />

      {/* Framer Motion page transition wrapper */}
      <motion.main
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        exit={{ opacity: 0 }}
        transition={{ duration: 0.5 }}
        className="relative z-10 min-h-screen flex flex-col"
      >
        {/* Matched child route renders here */}
        <Outlet />
      </motion.main>
    </div>
  );
}

export { Layout as L };

Props

Layout accepts no props. It is registered as the route element that wraps all page routes in the router definition, so React Router controls when it mounts and which child route is active — no external configuration is needed.

Composition

The component builds up the full-screen canvas by layering seven distinct children inside a single root <div>: 1. Root <div>
<div className="min-h-screen bg-midnight-base text-witch-teal-glow relative overflow-hidden">
The outermost container sets the canvas for every page. bg-midnight-base applies the deep navy-black background color (#0a0e1a). text-witch-teal-glow sets the default text color to teal (#2dd4bf) so all downstream text inherits the on-brand palette without explicit coloring. relative overflow-hidden establishes the stacking context and prevents the fixed atmospheric layers from causing a horizontal scroll bar on narrow viewports. 2. Fog layer
<div className="fixed inset-0 bg-fog pointer-events-none z-0" />
A fixed, full-viewport div rendered behind all content at z-0. The bg-fog class applies a CSS background (typically a radial gradient or low-opacity texture) that softens the hard midnight background and gives the canvas atmospheric depth. It is positioned fixed so it never scrolls away as the page grows taller. 3. Starfield layer
<div className="fixed inset-0 starfield pointer-events-none z-0" />
A second fixed full-viewport div at the same z-0 stacking level. The starfield class drives a CSS animation or background image that produces a field of faint, twinkling stars across the entire viewport. Like the fog layer, it is decorative-only and never scrolls with page content. 4. <Cursor />
<Cursor />
The custom animated cursor component, mounted at z-[100] inside its own container, renders above every other element in the layout. It replaces the default OS cursor with a glowing teal orb, a precise white dot, and stochastic trailing spark particles. See the Cursor component docs for a full breakdown. 5. <Navigation />
<Navigation />
The site-wide navigation bar component, rendered persistently across all routes. Because it lives inside Layout rather than inside individual page components, the nav never unmounts during client-side navigation. See the Navigation component docs for the full route table and bundling details. 6. <motion.main>
<motion.main
  initial={{ opacity: 0 }}
  animate={{ opacity: 1 }}
  exit={{ opacity: 0 }}
  transition={{ duration: 0.5 }}
  className="relative z-10 min-h-screen flex flex-col"
>
A Framer Motion–enhanced <main> element that wraps all page content. On every route transition, the initialanimateexit sequence produces a 500 ms cross-fade: the incoming page fades in from fully transparent, and the outgoing page (when paired with <AnimatePresence> at the router level) fades out simultaneously. z-10 ensures page content renders above the z-0 atmospheric layers.
<AnimatePresence> must wrap the router outlet at the top of the React tree for exit animations to fire. Without it, Framer Motion has no mechanism to delay unmounting the outgoing page component, so the exit: { opacity: 0 } transition is skipped entirely and pages snap out instantly instead of fading.
7. <Outlet />
<Outlet />
The React Router <Outlet /> renders whichever child route component is currently matched. This is the only part of the tree that changes between navigations — everything above it (background, cursor, nav) remains mounted and stable.

Usage

Register Layout as the parent route element in your router definition. All page routes become children of this one entry so they automatically inherit the full visual shell:
// In your router definition
{
  element: <Layout />,
  children: [
    { path: "/about",        element: <About /> },
    { path: "/skills",       element: <Skills /> },
    // ...
  ]
}
The pointer-events-none class on both the fog and starfield layers is critical. Without it, those fixed-position <div> elements would sit on top of the page content in the event-capture phase and silently absorb all mouse clicks, hover events, and scroll interactions — making the entire site appear non-interactive even though the DOM is fully rendered.

Build docs developers (and LLMs) love