Skip to main content

Documentation Index

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

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

All content in Systems Witch is stored as plain JavaScript data arrays and strings at the top of their respective page components in assets/main.js. There is no CMS, no external database, and no config file to manage — just find the array, edit the entries, and rebuild. The components are purely presentational: they read the data and render it; the shape of the data determines what appears on screen.

Projects

The projects array, defined just before the ProjectsView component, drives the /projects grid. Each object in the array becomes one project card:
{
  id: "01",               // Two-digit string shown as a large ghost number on card hover
  title: "PROJECT_NAME",  // All-caps monospace title displayed in the card header
  description: "...",     // One-sentence description shown in IBM Plex Sans below the title
  tags: ["--frontend", "--webgl"], // Must match values in the filters array (see below)
  link: "https://..."     // URL opened by the [ run.exe ] button in the card footer
}
The current project entries are:
idtitletags
"01"NEURAL_WEAVE--frontend, --webgl
"02"VOID_PROTOCOL--backend, --crypto
"03"GRIMOIRE.UI--frontend, --design
"04"ECHO_CHAMBER--creative, --hardware
The filter buttons above the grid are generated from a separate filters array:
const filters = ["--all", "--frontend", "--backend", "--design", "--creative"];
"--all" is a special value that bypasses tag filtering and shows every project. All other values are matched against each project’s tags array. If you add a new tag to a project entry, add the same value to the filters array — otherwise no filter button will exist for it.

Skills

The skills array, defined just before SkillsView, populates the portrait-orientation skill cards on /skills. Cards are rendered in array order:
{
  name: "React / Next.js",  // Displayed in Cinzel serif italic at the card center
  level: 90,                // Integer 0–100; drives the animated progress bar width
  category: "Frontend"      // Shown in the top-right corner of the card in small monospace
}
The current six entries are React / Next.js (90), TypeScript (85), Node.js (75), WebGL / Three.js (60), Tailwind CSS (95), and System Architecture (80). The progress bar width animates from 0 to ${level}% on scroll-into-view using a Framer Motion whileInView transition.

Articles

The articles array, defined just before ArticlesView, populates the ls-style file listing on /articles. Each entry represents one row in the table:
{
  name: "article-slug.md",  // Shown in the NAME column; also used by the grep filter
  size: "14K",              // Shown in the SIZE column
  date: "May 20",           // Shown in the DATE column
  perms: "-rw-r--r--"       // Shown in the PERMS column
}
The grep input at the top of the page filters rows in real time by matching against name. The current five entries are:
namesizedate
architecting-the-void.md14KMay 20
css-as-incantation.md8.2KMay 15
state-management-rituals.md21KApr 30
the-death-of-clean-code.md12KApr 12
webgl-sigils-tutorial.md45KMar 28
Article names currently link nowhere — the NAME cell renders plain text. To add links, extend each entry with a link field and update the <td> for the name column to render an <a> tag:
<td className="py-2 px-4 text-bone group-hover:text-acid ...">
  <a href={article.link} target="_blank" rel="noopener noreferrer">
    {article.name}
  </a>
</td>

Testimonials

The testimonials array, defined just before TestimonialsView, populates the encrypted-message feed on /testimonials. Each entry is one transmission card:
{
  id: "TRX-001",
  sender: "CTO @ Nexus Corp",
  timestamp: "2026-05-26T14:32:01Z",  // ISO 8601; displayed verbatim in the card header
  message: "...",                      // The testimonial body, rendered in quotation marks
  status: "DECRYPTED"                  // Status label shown bottom-right; any string works
}
The three current entries carry IDs TRX-001, TRX-002, and TRX-003. Each card animates in from the left on scroll using whileInView. The pulsing > Awaiting incoming transmission... line below the cards is hardcoded in the component.

About bio

The bio text lives as inline JSX inside AboutView, rendered inside a terminal-style bg-graphite/30 block. There are five text nodes to update:
  1. Intro line# I am a full-stack developer and digital occultist. — the <span className="text-acid"> prefix renders as #.
  2. Work philosophy sentence — the paragraph describing the intersection of “hard logic” and “creative chaos”.
  3. Philosophy body — the Code is incantation... paragraph explaining the approach to interfaces.
  4. Background section header## Background.
  5. Background paragraph — replace the two placeholder tokens with real values:
    • [REDACTED_AGENCY] → your previous employer or agency name
    • [STARTUP_NAME] → the startup you scaled infrastructure for
Also update the four ENVIRONMENT_VARIABLES entries in the sidebar info block:
KeyDefault valueNotes
LOCATION"Cyberia"Your actual location or preferred alias
FOCUS"Design_Engineering"Your current primary focus area
AVAILABILITYtrueSet to false when not taking contracts — the value renders in text-acid green
CAFFEINE_LEVEL0.89A float between 0 and 1.0

Hero status line

In HomeView, after the hero tagline, there is a one-line status indicator rendered in monospace:
<div className="pt-8 flex gap-4 justify-center font-mono text-sm">
  <span className="text-graphite">//</span>
  <span className="text-acid">STATUS:</span>
  <span className="text-bone">ACCEPTING_CONTRACTS</span>
</div>
Change ACCEPTING_CONTRACTS to any status string that reflects your current availability, for example:
StringMeaning
ACCEPTING_CONTRACTSOpen for new client work
HEADS_DOWNFocused on an ongoing project
OPEN_TO_HIRELooking for a full-time role
ON_SABBATICALTemporarily unavailable

Profile image

The About page sidebar contains a placeholder where a profile photo should go. The current markup renders a dot-grid background and the text [ IMAGE_DATA_MISSING ]:
<div className="w-full h-full bg-graphite flex items-center justify-center overflow-hidden relative">
  {/* dot grid overlay */}
  <span className="font-mono text-acid text-xs opacity-50">
    [ IMAGE_DATA_MISSING ]
  </span>
</div>
Replace the inner contents with a real <img> tag to display your photo:
<div className="w-full h-full bg-graphite flex items-center justify-center overflow-hidden relative">
  <img
    src="/path/to/your-photo.jpg"
    alt="Profile"
    className="w-full h-full object-cover"
  />
</div>
The outer wrapper already handles the aspect-square ratio, border border-acid frame, and the four corner accent squares — those remain unchanged.
All data arrays are defined at module scope immediately before their page component in assets/main.js. The quickest way to locate them is to search for the array name: const projects, const skills, const articles, const testimonials.

Build docs developers (and LLMs) love