Skip to main content

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.

The writing.js file is the single source of truth for the Writing page. It exports a named array (a) of five writing post objects, each displayed as a TomeCard component with a title, excerpt, publication date, channel badge, and article link. Editing this file is the only step required to add, remove, or update an article entry — no component changes are needed. The complete SVG path registry for all named sigils in the theme lives in the companion file data/sigils.js, not here. See the Sigil SVG Path Registry section below for its full documentation. Location: data/writing.js

Export 1 — Writing Posts Array

The writing posts array is exported as a. Each element is consumed by the TomeCard component to render an article preview card with title, excerpt, date, and a channel badge.

Data Shape

interface WritingPost {
  id: string;      // Unique identifier
  title: string;   // Article title
  excerpt: string; // Short summary shown in TomeCard
  date: string;    // ISO date string, e.g. "2025-10-31"
  channel: string; // Category — one of five defined channels (see below)
  url: string;     // Link to the full article (use "#" for placeholder)
}

Field Reference

id
string
required
A unique identifier for the post used as a React list key. The current convention uses sequential numeric strings ("1", "2", etc.), but any unique string is valid. Consider switching to a slug-based convention (e.g. "banishing-memory-leaks") if the archive grows large.
title
string
required
The article title rendered as the TomeCard heading. Casing is preserved as written — no automatic transformation is applied by the component.
excerpt
string
required
A short summary of the article shown beneath the title in the card body. Keep it to one or two sentences — the card layout does not accommodate long excerpts gracefully.
date
string
required
The publication date as an ISO 8601 date string, e.g. "2025-10-31". The TomeCard component formats and displays this value. Always use the full YYYY-MM-DD format.
channel
string
required
The content category rendered as a badge on the card. Must be one of the five defined channel values:
ValueIntended Use
TechnicalIn-depth engineering articles aimed at developers
ReflectionsPersonal essays on career, learning, and process
Bug ReportsPost-mortems and debugging war stories
Project WriteupsNarrative overviews of completed projects
General AudienceExplainers written for non-technical readers
url
string
required
The fully-qualified URL linking to the full article. Use "#" as a placeholder for articles that are not yet published externally. Replace with the real URL when the article goes live.

Current Writing Entries

All five articles currently defined in data/writing.js:
export const a = [
  {
    id: "1",
    title: "Banishing Memory Leaks in React Applications",
    excerpt:
      "A deep dive into common useEffect pitfalls that lead to memory leaks, and how to properly cleanse your component lifecycle.",
    date: "2025-10-31",
    channel: "Technical",
    url: "#",
  },
  {
    id: "2",
    title: "From Retail to React: A Non-Linear Path",
    excerpt:
      "How dealing with unpredictable customers prepared me for dealing with unpredictable state mutations.",
    date: "2025-09-15",
    channel: "Reflections",
    url: "#",
  },
  {
    id: "3",
    title: "The Great Z-Index War of 2025",
    excerpt:
      "A post-mortem on a bug where a modal was trapped beneath a seemingly innocent sticky header. Lessons learned in stacking contexts.",
    date: "2025-08-22",
    channel: "Bug Reports",
    url: "#",
  },
  {
    id: "4",
    title: "Building the Void Tracker",
    excerpt:
      "Architectural decisions and trade-offs made while building a local-first task management system using Zustand and IndexedDB.",
    date: "2025-07-10",
    channel: "Project Writeups",
    url: "#",
  },
  {
    id: "5",
    title: "Demystifying the Event Loop",
    excerpt:
      "An explanation of the JavaScript event loop designed for those who find the official documentation too arcane.",
    date: "2025-06-05",
    channel: "General Audience",
    url: "#",
  },
];

Adding a New Article

Append a new object to the end of the a array. Provide all six fields. Use the real publication date, choose exactly one of the five channel values, and link to the published article URL (or "#" until it is live).
Articles are rendered in array order on the Writing page — newest first is the expected reading convention. Append new entries at the top of the array (index 0) or re-sort after appending to keep the list chronologically descending.

Export 2 — Sigil SVG Path Registry

The sigil path registry is the internal constant L, exported from sigils.js as s. It is a plain JavaScript object whose keys are sigil names and whose values are SVG d attribute strings — the raw path geometry drawn into each <path> element by Sigil.js and other icon consumers across the theme. Location: data/sigils.js

Registry Structure

type SigilRegistry = {
  [key: string]: string; // key → SVG path "d" attribute string
};

Key Groups

The registry contains four logical groups of keys:

Navigation Sigils

One sigil per page, used in the navigation bar and as section markers.home, about, projects, skills, writing, case-studies, contact

Trait Sigils

Personality glyphs rendered on the About page to represent character traits.trait-detail, trait-creative, trait-sarcastic, trait-practical, trait-pattern

Rune Sigils

Seven abstract rune forms used as decorative icons in RuneTile (skills) and other components. Skills reference these via their sigilId field.rune-1, rune-2, rune-3, rune-4, rune-5, rune-6, rune-7

Usage in Data Files

  • skills.jssigilId references rune-1 through rune-7
  • caseStudies.jssigilId references named page sigils such as "case-studies" and "projects"

Full Registry

// data/sigils.js
export const s = {
  // — Navigation —
  home:          "M12 2 L22 12 L12 22 L2 12 Z M12 6 L18 12 L12 18 L6 12 Z M12 10 L14 12 L12 14 L10 12 Z",
  about:         "M12 2 A10 10 0 1 0 12 22 A10 10 0 1 0 12 2 M12 6 A6 6 0 1 0 12 18 A6 6 0 1 0 12 6 M12 2 L12 22 M2 12 L22 12",
  projects:      "M4 4 L20 4 L20 20 L4 20 Z M8 8 L16 8 L16 16 L8 16 Z M12 4 L12 20 M4 12 L20 12",
  skills:        "M12 2 L22 8 L22 16 L12 22 L2 16 L2 8 Z M12 6 L18 10 L18 14 L12 18 L6 14 L6 10 Z M12 2 L12 22 M2 8 L22 16 M2 16 L22 8",
  writing:       "M6 4 L18 4 L18 20 L6 20 Z M10 8 L14 8 M10 12 L14 12 M10 16 L14 16 M6 4 L12 10 L18 4",
  "case-studies":"M4 12 L12 4 L20 12 L12 20 Z M8 12 A4 4 0 1 0 16 12 A4 4 0 1 0 8 12 M12 4 L12 8 M12 16 L12 20 M4 12 L8 12 M16 12 L20 12",
  contact:       "M2 6 L22 6 L22 18 L2 18 Z M2 6 L12 14 L22 6 M12 14 L12 18",

  // — Trait glyphs (About page) —
  "trait-detail":    "M12 4 A8 8 0 1 0 12 20 A8 8 0 1 0 12 4 M12 10 A2 2 0 1 0 12 14 A2 2 0 1 0 12 10 M12 4 L12 10 M12 14 L12 20 M4 12 L10 12 M14 12 L20 12",
  "trait-creative":  "M12 2 L15 9 L22 12 L15 15 L12 22 L9 15 L2 12 L9 9 Z",
  "trait-sarcastic": "M4 20 L20 4 M4 4 L20 20 M8 12 A4 4 0 1 0 16 12 A4 4 0 1 0 8 12",
  "trait-practical": "M6 6 L18 6 L18 18 L6 18 Z M10 10 L14 10 L14 14 L10 14 Z M12 6 L12 10 M12 14 L12 18 M6 12 L10 12 M14 12 L18 12",
  "trait-pattern":   "M4 12 A8 8 0 1 0 20 12 A8 8 0 1 0 4 12 M8 12 A4 4 0 1 0 16 12 A4 4 0 1 0 8 12 M12 4 L12 20 M4 12 L20 12",

  // — Rune icons (skills, case studies) —
  "rune-1": "M8 4 L16 4 L12 12 L16 20 L8 20 L12 12 Z",
  "rune-2": "M12 4 L20 12 L12 20 L4 12 Z M12 8 L16 12 L12 16 L8 12 Z",
  "rune-3": "M6 6 L18 18 M18 6 L6 18 M12 4 L12 20",
  "rune-4": "M12 4 A8 8 0 1 0 12 20 A8 8 0 1 0 12 4 M12 4 L12 20 M4 12 L20 12",
  "rune-5": "M4 8 L20 8 M4 16 L20 16 M8 4 L8 20 M16 4 L16 20",
  "rune-6": "M12 2 L22 12 L12 22 L2 12 Z M12 8 L16 12 L12 16 L8 12 Z",
  "rune-7": "M12 4 L18 20 L6 20 Z M12 10 L15 17 L9 17 Z",
};
The sigil registry in data/sigils.js is consumed read-only by Sigil.js at render time. To add a new sigil, append a new key–value pair to the registry object in sigils.js with a valid SVG path d string drawn on a 24 × 24 viewBox. Then reference the new key via sigilId in whichever data file needs it.
Do not rename or remove existing keys in data/sigils.js without auditing all data files that reference them. The sigilId fields in skills.js and caseStudies.js will silently resolve to undefined if their referenced key is missing, which will render a blank icon with no error thrown.

Build docs developers (and LLMs) love