The main navigation menu is driven by a singleDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/blairxu13/persona3-website/llms.txt
Use this file to discover all available pages before exploring further.
ITEMS array defined at the top of src/P3Menu.jsx. Each object in the array describes one menu entry — its display label, the route it navigates to, and a set of typographic offsets that produce the signature staggered, skewed Persona-style layout. Adding, removing, or reordering entries requires only editing this array (and, for new pages, registering a matching route in App.jsx).
The ITEMS Array
Below is the default configuration shipped with the portfolio. Each entry maps directly to one visible label in the menu.The
github and sideproj entries in the default ITEMS array do not have matching routes in App.jsx. Clicking them will call onNavigate("github") or onNavigate("sideproj"), which triggers navigate("/github") — a path with no registered <Route>, resulting in a blank or 404 view. See External Links below for how to handle the GitHub case, and the Adding a Menu Item section for wiring up a real route.Item Object Fields
Each object inITEMS accepts the following fields:
A unique React key for the list item. Used internally by React’s reconciler — not displayed to the user.
The text displayed in the menu. Rendered in Anton italic, uppercase. Keep labels short (1–3 words) so they fit within the staggered layout.
The route segment passed to
onNavigate. In App.jsx, the handler calls navigate(/${page}), so ”about”routes to/about. This value must match a registered Route path in App.jsx` (or be handled specially for external links).Font size of the label in pixels. Larger values create more visual prominence. The default range is 56–80 px. Adjust this to communicate hierarchy — primary items like “ABOUT ME” use larger sizes.
Applied as
marginRight in pixels. Positive values push the item inward from the right edge, creating the horizontal stagger across entries. Use values in the 0–20 px range to maintain visual cohesion.Applied as
marginTop in pixels. Adds vertical breathing room between items beyond the default flex gap. Varying this across entries breaks the rigid grid feel.CSS
skewX in degrees applied to the label wrapper. Negative values lean the label to the left (the default Persona slant). Keep values between -12 and 0 for legibility.CSS
skewY in degrees applied to the label wrapper. Combined with skew, this produces the characteristic parallelogram warp on each label. Positive and negative values alternate across items to give each entry a distinct tilt.Adding a Menu Item
Add an entry to the ITEMS array in P3Menu.jsx
Open
src/P3Menu.jsx and append a new object to ITEMS. Choose a unique id, a short uppercase label, and a page slug that will become the URL path.Register a Route in App.jsx
Open
src/App.jsx and add a <Route> for the new path inside the existing router tree.Create the page component
Create
src/ContactPage.jsx (or any filename matching your import above). At minimum, render a full-viewport container with a back-navigation trigger.Optionally add a PageTransition variant
PageTransition.jsx does not use a color-map lookup. Each transition style is its own named component function, and TransitionOverlay selects between them with explicit if checks. To add a custom wipe for your new page:1. Define a new transition component in src/PageTransition.jsx, following the same pattern as the existing ones (e.g. AboutTransition, SocialsTransition):if branch for the new variant inside TransitionOverlay:App.jsx:External Links
The defaultgithub item calls navigate("/github"), which goes nowhere useful. For items that should open an external URL rather than an internal route, intercept navigation inside the onNavigate handler in App.jsx:
ITEMS array clean — the page field still acts as a key — while routing external destinations through window.open instead of React Router.
Styling Tips
The combination offontSize, skew, skewY, offsetX, and offsetY is what produces the layered, hand-placed feel of the Persona menu. A few guidelines:
fontSizecommunicates hierarchy. Primary items (ABOUT MEat 80 px) should be noticeably larger than secondary items (SIDE PROJECTSat 56 px).- Alternate
skewYsigns (positive / negative) across adjacent items. This zigzag rhythm prevents the list from feeling like a uniform slant. offsetXcreates depth. Items pushed further inward (largeroffsetX) appear more “recessed,” while zero-offset items feel closest to the viewer.- Keep
skew(skewX) moderate. Values beyond ±15° make the Anton italic letterforms difficult to read at large sizes. - Vary
offsetYslightly rather than relying solely on the flex gap. A few pixels of difference between items removes the mechanical regularity of a traditional list.