The contact and about pages of sys.witch share a family of self-contained, stateful components.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/apursley2012/sys-witch/llms.txt
Use this file to discover all available pages before exploring further.
SummoningForm handles all user-facing contact functionality entirely on the client — no backend required. TimelineEntry threads the work history together with an animated left-rail timeline, and TraitSigilGrid renders a five-up grid of personality sigils that define the portfolio owner’s character.
SummoningForm
SummoningForm is a fully self-contained contact form component with its own local state. It requires no props — all behaviour is internal. The form sits inside an animated GlowFrame wrapper (neon-magenta) and is centred at max-w-2xl on the contact page.
Fields
| Field label (display) | HTML id | Type | Placeholder | Required |
|---|---|---|---|---|
| Entity Identifier | name | text | Your name | Yes |
| Return Frequency | email | email | your@email.com | Yes |
| Transmission Payload | message | textarea | What knowledge do you seek? | Yes |
font-mono text-xs text-neon-magenta uppercase tracking-wider alongside a small rune sigil (rune-1, rune-2, rune-3 respectively). Inputs use a bg-base/50 fill with a border-neon-magenta/30 border that transitions to a full border-neon-magenta + ring-1 ring-neon-magenta on focus.
Submit Behaviour
SummoningForm is a static, front-end-only form. There is no backend endpoint or mailto: link wired up in the current implementation. The onSubmit handler:
- Calls
event.preventDefault()to block native submission. - Sets an
isSubmittingboolean totrue, causing the submit button (normally labelled"Send The Signal") to pulse and display"Channeling...". - After 1 500 ms simulates completion:
isSubmittingreturns tofalseandisSuccessis set totrue. - After a further 3 000 ms
isSuccessresets tofalse, returning the form to its default state.
Success State
WhenisSuccess is true the form is replaced by an animated success panel displaying:
- A large
rune-4sigil with a magenta glow. - The heading “Signal Transmitted” in
font-display. - The subtext
"The message has entered the void."infont-mono.
initial={{ opacity: 0, scale: 0.9 }} via Framer Motion.
Props
SummoningForm accepts no props — all state is managed internally with React.useState.
JSX Usage
TimelineEntry
TimelineEntry renders a single item in the vertical work-history timeline on the About page. Each entry consists of a circular node icon on the left rail and an animated content block to its right. The vertical rail itself is drawn as a gradient line from neon-cyan down to transparent — the isLast prop suppresses this line on the final entry to avoid a dangling tail.
Props
| Prop | Type | Required | Default | Description |
|---|---|---|---|---|
year | string | Yes | — | The year or date range to display (e.g. "2023 – 2025") |
title | string | Yes | — | Role or event name, rendered in font-display |
description | string | Yes | — | Body paragraph for the timeline entry |
isLast | boolean | No | false | Set to true on the final entry to hide the tail line |
Visual Structure
- The left rail node is a
w-10 h-10circle withborder-2 border-neon-cyanand ashadow-glow-cyanthat holds arune-4sigil. - The connecting gradient line is
w-[2px]running full height, fadingfrom-neon-cyan via-neon-cyan/20 to-transparent. - The content block slides in from the right (
x: 20 → 0) using awhileInViewFramer Motion animation withonce: trueand a-100pxmargin. - The
yearis rendered infont-mono text-neon-cyan text-sm; thetitleinfont-display text-xl; thedescriptioninfont-sans text-text-secondary.
JSX Usage
TraitSigilGrid
TraitSigilGrid renders a fixed five-item grid of personality trait tiles on the About page. The trait list is hardcoded inside the component — it does not accept any props.
Hardcoded Traits
| Trait name | Sigil ID | Neon colour |
|---|---|---|
| Detail-Oriented | trait-detail | cyan |
| Creative | trait-creative | magenta |
| Sarcastic | trait-sarcastic | purple |
| Practical | trait-practical | lime |
| Pattern-Spotter | trait-pattern | cyan |
Rendered Layout
The grid usesgrid-cols-2 md:grid-cols-3 lg:grid-cols-5 so all five tiles sit in a single row on wide viewports. Each tile is a flex flex-col items-center text-center column containing:
- A
w-20 h-20rounded-lg icon box with a per-traitborder-neon-{color}/30border. - The trait’s sigil icon at
size={32}, centred in the box. - The trait name in
font-mono text-sm text-text-secondarybelow.
whileInView, once: true) with a stagger delay of index * 0.1s. On hover the tile lifts with -translate-y-2, the border brightens to full neon-{color}, a matching shadow-glow-{color} appears, and the sigil icon rotates 180° via CSS group-hover:rotate-180.
Props
TraitSigilGrid accepts no props.
JSX Usage
To modify the traits, edit the hardcoded
traits array directly inside TraitSigilGrid.js. Each entry requires a name, a sigilId registered in data/sigils.js, and a color matching one of the theme tokens (cyan, magenta, purple, lime).