diff --git a/content/projects/_index.md b/content/projects/_index.md
index 783b87c..ff3d3b5 100644
--- a/content/projects/_index.md
+++ b/content/projects/_index.md
@@ -1,75 +1,5 @@
+++
title = "Projects"
-description = "The PulseEngine ecosystem โ from core pipeline tools to build rules and developer infrastructure"
-template = "section.html"
+description = "The PulseEngine ecosystem โ from verified pipeline to safety-critical applications"
+template = "projects.html"
+++
-
-## Core Pipeline
-
-
-
-{{ project_card(name="meld", desc="Statically fuses multiple WebAssembly components into a single core module. Import resolution, index-space merging, and canonical ABI adapter generation at build time.", url="https://github.com/pulseengine/meld", icon="๐", badge="accent", label="Fusion") }}
-
-{{ project_card(name="loom", desc="Twelve-pass WebAssembly optimization pipeline built on Cranelift's ISLE pattern-matching engine. Constant folding, strength reduction, CSE, inlining, dead code elimination.", url="https://github.com/pulseengine/loom", icon="๐งต", badge="cyan", label="Optimizer", releases="https://github.com/pulseengine/loom/releases") }}
-
-{{ project_card(name="synth", desc="Transcodes WebAssembly to native ARM for embedded Cortex-M targets through program synthesis โ exploring equivalent native implementations, not just translating instructions.", url="https://github.com/pulseengine/synth", icon="โก", badge="green", label="Transcoder") }}
-
-{{ project_card(name="kiln", desc="WebAssembly Component Model interpreter and runtime. Full WASI 0.2 support with no_std architecture for embedded, automotive, medical, and aerospace environments.", url="https://github.com/pulseengine/kiln", icon="๐ฅ", badge="amber", label="Runtime", releases="https://github.com/pulseengine/kiln/releases") }}
-
-{{ project_card(name="sigil", desc="Supply chain security โ attestation, signing, and verification across every pipeline stage. Sigstore keyless signing, SLSA L4 provenance, TPM 2.0 support.", url="https://github.com/pulseengine/sigil", icon="๐", badge="purple", label="Security", releases="https://github.com/pulseengine/sigil/releases") }}
-
-
-
-## Safety-Critical Systems
-
-
-
-{{ project_card(name="gale", desc="Formally verified Rust port of Zephyr RTOS kernel primitives for ASIL-D. Dual-track verification with Verus and Rocq, 9 verified synchronization primitives.", url="https://github.com/pulseengine/gale", icon="๐ฌ๏ธ", badge="green", label="RTOS") }}
-
-{{ project_card(name="spar", desc="AADL v2.2 architecture analysis toolchain โ parser, semantic model, 30+ pluggable analyses, and LSP server for safety-critical system design.", url="https://github.com/pulseengine/spar", icon="๐๏ธ", badge="accent", label="Architecture", releases="https://github.com/pulseengine/spar/releases", vscode="https://marketplace.visualstudio.com/items?itemName=pulseengine.spar-aadl") }}
-
-{{ project_card(name="rivet", desc="Schema-driven SDLC artifact manager for requirements traceability and safety compliance. STPA, ASPICE, and cybersecurity schemas.", url="https://github.com/pulseengine/rivet", icon="๐", badge="amber", label="Traceability", releases="https://github.com/pulseengine/rivet/releases") }}
-
-
-
-## Build & Verification
-
-
-
-{{ project_card(name="rules_wasm_component", desc="Bazel rules for WebAssembly Component Model across Rust, Go, C++, and JavaScript.", url="https://github.com/pulseengine/rules_wasm_component", icon="๐ฆ", badge="accent", label="Bazel", releases="https://github.com/pulseengine/rules_wasm_component/releases") }}
-
-{{ project_card(name="rules_rocq_rust", desc="Bazel rules for Rocq theorem proving and Rust formal verification with hermetic Nix toolchains.", url="https://github.com/pulseengine/rules_rocq_rust", icon="๐", badge="green", label="Verification", releases="https://github.com/pulseengine/rules_rocq_rust/releases") }}
-
-{{ project_card(name="rules_verus", desc="Bazel rules for Verus Rust verification.", url="https://github.com/pulseengine/rules_verus", icon="โ ", badge="green", label="Verification") }}
-
-{{ project_card(name="rules_moonbit", desc="Bazel rules for MoonBit with hermetic toolchain support.", url="https://github.com/pulseengine/rules_moonbit", icon="๐", badge="cyan", label="Bazel") }}
-
-{{ project_card(name="rules_lean", desc="Bazel rules for Lean 4 with Mathlib and Aeneas integration for formal verification.", url="https://github.com/pulseengine/rules_lean", icon="๐", badge="green", label="Verification") }}
-
-
-
-## AI & MCP
-
-
-
-{{ project_card(name="mcp", desc="Rust framework for building Model Context Protocol servers and clients, published to crates.io.", url="https://github.com/pulseengine/mcp", icon="๐ค", badge="purple", label="Framework", releases="https://github.com/pulseengine/mcp/releases") }}
-
-{{ project_card(name="template-mcp-server", desc="Scaffolding template for creating MCP servers in Rust with cross-platform npm distribution.", url="https://github.com/pulseengine/template-mcp-server", icon="๐งฉ", badge="purple", label="Template") }}
-
-{{ project_card(name="timedate-mcp", desc="MCP server for time, date, and timezone operations with full IANA timezone support.", url="https://github.com/pulseengine/timedate-mcp", icon="๐", badge="purple", label="Server", releases="https://github.com/pulseengine/timedate-mcp/releases") }}
-
-
-
-## Developer Tools
-
-
-
-{{ project_card(name="temper", desc="GitHub App that hardens repositories to organizational standards.", url="https://github.com/pulseengine/temper", icon="๐ก๏ธ", badge="red", label="Governance") }}
-
-{{ project_card(name="wasm-component-examples", desc="Working examples for Component Model development in C, C++, Go, and Rust.", url="https://github.com/pulseengine/wasm-component-examples", icon="๐", badge="accent", label="Examples") }}
-
-{{ project_card(name="bazel-file-ops-component", desc="WebAssembly-based cross-platform file operations for Bazel builds. Dual TinyGo and Rust implementations.", url="https://github.com/pulseengine/bazel-file-ops-component", icon="๐", badge="cyan", label="Build") }}
-
-{{ project_card(name="moonbit_checksum_updater", desc="Native MoonBit checksum management with GitHub API integration.", url="https://github.com/pulseengine/moonbit_checksum_updater", icon="๐ข", badge="cyan", label="Build") }}
-
-
diff --git a/static/cube.js b/static/cube.js
new file mode 100644
index 0000000..1929cfe
--- /dev/null
+++ b/static/cube.js
@@ -0,0 +1,287 @@
+// Rubik's cube โ drag to rotate, auto-spin, snap + zoom + open
+(function () {
+ 'use strict';
+
+ var cube = document.querySelector('.cube');
+ if (!cube) return;
+
+ var scene = document.querySelector('.cube-scene');
+ var detailPanel = document.querySelector('.cube-detail');
+ var snaps = document.querySelectorAll('[data-face]');
+ var closeBtn = document.querySelector('.cube-detail__close');
+ var reduceMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
+
+ var rotX = -30, rotY = 35;
+ var dragging = false;
+ var lastX, lastY;
+ var autoSpin = true;
+ var idleTimer;
+ var activeFace = null;
+ var introPhase = true;
+ var introStart = performance.now();
+
+ var angles = {
+ architect: [0, 0],
+ build: [0, -90],
+ verify: [0, 90],
+ trace: [0, 180],
+ run: [-90, 0],
+ agent: [90, 0]
+ };
+
+ function apply() {
+ cube.style.transform = 'rotateX(' + rotX + 'deg) rotateY(' + rotY + 'deg)';
+ }
+
+ function stopAuto() {
+ introPhase = false;
+ scene.style.transform = 'scale(1)';
+ autoSpin = false;
+ clearTimeout(idleTimer);
+ idleTimer = setTimeout(function () {
+ if (!activeFace) autoSpin = true;
+ }, 4000);
+ }
+
+ // โโ Auto-rotation with intro animation โโโโโโโ
+ function spin() {
+ if (dragging || reduceMotion) {
+ requestAnimationFrame(spin);
+ return;
+ }
+
+ if (introPhase) {
+ var elapsed = (performance.now() - introStart) / 1000;
+ var dur = 1.8;
+
+ if (elapsed < dur) {
+ var t = elapsed / dur;
+ var scale, spinSpeed;
+
+ if (t < 0.15) {
+ // Phase 1: 1.0 โ 0.3 (snap contract)
+ var p = t / 0.15;
+ scale = 1.0 - 0.7 * p * p;
+ spinSpeed = 0.2;
+ } else if (t < 0.4) {
+ // Phase 2: 0.3 โ 10.0 (explode)
+ var p = (t - 0.15) / 0.25;
+ var ease = 1 - Math.pow(1 - p, 2);
+ scale = 0.3 + 9.7 * ease;
+ spinSpeed = 1.2 * ease + 0.2;
+ } else {
+ // Phase 3: 10.0 โ 1.0 (settle)
+ var p = (t - 0.4) / 0.6;
+ var ease = 1 - Math.pow(1 - p, 4);
+ scale = 10.0 - 9.0 * ease;
+ spinSpeed = 1.2 * (1 - ease) + 0.08;
+ }
+
+ scene.style.transform = 'scale(' + scale + ')';
+ rotY += spinSpeed;
+ apply();
+ requestAnimationFrame(spin);
+ return;
+ } else {
+ introPhase = false;
+ scene.style.transform = 'scale(1)';
+ }
+ }
+
+ if (!autoSpin) {
+ requestAnimationFrame(spin);
+ return;
+ }
+
+ rotY += 0.08;
+ apply();
+ requestAnimationFrame(spin);
+ }
+
+ // โโ Drag (mouse) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ scene.addEventListener('mousedown', function (e) {
+ dragging = true;
+ lastX = e.clientX;
+ lastY = e.clientY;
+ scene.style.cursor = 'grabbing';
+ stopAuto();
+ });
+ window.addEventListener('mousemove', function (e) {
+ if (!dragging) return;
+ rotY += (e.clientX - lastX) * 0.4;
+ rotX -= (e.clientY - lastY) * 0.4;
+ lastX = e.clientX;
+ lastY = e.clientY;
+ apply();
+ });
+ window.addEventListener('mouseup', function () {
+ dragging = false;
+ scene.style.cursor = 'grab';
+ });
+
+ // โโ Drag (touch) โโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ scene.addEventListener('touchstart', function (e) {
+ if (e.touches.length === 1) {
+ dragging = true;
+ lastX = e.touches[0].clientX;
+ lastY = e.touches[0].clientY;
+ stopAuto();
+ }
+ }, { passive: true });
+ window.addEventListener('touchmove', function (e) {
+ if (!dragging || e.touches.length !== 1) return;
+ rotY += (e.touches[0].clientX - lastX) * 0.4;
+ rotX -= (e.touches[0].clientY - lastY) * 0.4;
+ lastX = e.touches[0].clientX;
+ lastY = e.touches[0].clientY;
+ apply();
+ }, { passive: true });
+ window.addEventListener('touchend', function () { dragging = false; });
+
+ // โโ Open a face โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ function openFace(face) {
+ activeFace = face;
+ autoSpin = false;
+
+ // Set target rotation
+ var a = angles[face];
+ rotX = a[0];
+ rotY = a[1];
+
+ // Prep detail content
+ if (detailPanel) {
+ detailPanel.querySelectorAll('.cube-detail__panel').forEach(function (p) {
+ p.style.display = (p.getAttribute('data-detail') === face) ? 'block' : 'none';
+ });
+ }
+
+ // Animate: rotate the cube
+ cube.style.transition = 'transform 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94)';
+ apply();
+
+ // After rotate: zoom out
+ setTimeout(function () {
+ scene.style.transform = 'scale(0.55)';
+ }, 300);
+
+ // After zoom: show detail
+ setTimeout(function () {
+ cube.style.transition = 'none';
+ if (detailPanel) detailPanel.classList.add('cube-detail--open');
+ }, 700);
+ }
+
+ function closeFace() {
+ activeFace = null;
+
+ // Hide detail
+ if (detailPanel) detailPanel.classList.remove('cube-detail--open');
+
+ // Zoom back in
+ scene.style.transform = 'scale(1)';
+
+ // Return to isometric
+ rotX = -30;
+ rotY = 35;
+ cube.style.transition = 'transform 0.6s cubic-bezier(0.25, 0.46, 0.45, 0.94)';
+ apply();
+
+ setTimeout(function () {
+ cube.style.transition = 'none';
+ autoSpin = true;
+ }, 600);
+
+ snaps.forEach(function (b) { b.classList.remove('face-btn--active'); });
+ }
+
+ // โโ Button clicks โโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ snaps.forEach(function (btn) {
+ btn.addEventListener('click', function () {
+ var face = btn.getAttribute('data-face');
+ if (!angles[face]) return;
+
+ if (activeFace === face) {
+ closeFace();
+ return;
+ }
+
+ // If switching from another face, close first then open
+ if (activeFace) {
+ if (detailPanel) detailPanel.classList.remove('cube-detail--open');
+ }
+
+ snaps.forEach(function (b) { b.classList.remove('face-btn--active'); });
+ btn.classList.add('face-btn--active');
+ openFace(face);
+ });
+ });
+
+ if (closeBtn) {
+ closeBtn.addEventListener('click', closeFace);
+ }
+
+ // โโ Click on cube faces โโโโโโโโโโโโโโโโโโโโโโโ
+ var faceMap = {
+ 'cube__face--front': 'architect',
+ 'cube__face--right': 'build',
+ 'cube__face--left': 'verify',
+ 'cube__face--back': 'trace',
+ 'cube__face--top': 'run',
+ 'cube__face--bottom': 'agent'
+ };
+
+ var faces = cube.querySelectorAll('.cube__face');
+ faces.forEach(function (face) {
+ face.addEventListener('click', function (e) {
+ // Don't trigger on drag
+ if (dragging) return;
+
+ // Find which face this is
+ var faceName = null;
+ for (var cls in faceMap) {
+ if (face.classList.contains(cls)) {
+ faceName = faceMap[cls];
+ break;
+ }
+ }
+ if (!faceName || !angles[faceName]) return;
+
+ // Prevent the GitHub link from firing
+ e.preventDefault();
+ e.stopPropagation();
+
+ if (activeFace === faceName) {
+ closeFace();
+ return;
+ }
+
+ if (activeFace) {
+ if (detailPanel) detailPanel.classList.remove('cube-detail--open');
+ }
+
+ snaps.forEach(function (b) { b.classList.remove('face-btn--active'); });
+ // Also highlight the matching top button
+ snaps.forEach(function (b) {
+ if (b.getAttribute('data-face') === faceName) b.classList.add('face-btn--active');
+ });
+
+ openFace(faceName);
+ });
+
+ // Prevent links inside cube faces from navigating
+ face.querySelectorAll('a').forEach(function (link) {
+ link.addEventListener('click', function (e) {
+ if (!activeFace) {
+ e.preventDefault();
+ }
+ // If detail is already open, allow links (they're decoration anyway)
+ });
+ });
+ });
+
+ // โโ Init โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
+ scene.style.transform = 'scale(1)';
+ scene.style.transition = 'transform 0.5s cubic-bezier(0.25, 0.46, 0.45, 0.94)';
+ apply();
+ if (!reduceMotion) requestAnimationFrame(spin);
+})();
diff --git a/templates/projects.html b/templates/projects.html
new file mode 100644
index 0000000..6f75391
--- /dev/null
+++ b/templates/projects.html
@@ -0,0 +1,536 @@
+{% extends "base.html" %}
+
+{% block title %}{{ section.title }} โ {{ config.title }}{% endblock %}
+{% block description %}{{ section.description }}{% endblock %}
+
+{% block content %}
+
AADL v2.2 and SysML v2 architecture analysis toolchain. Pluggable analysis passes, deployment solver, code generation (WIT, Rust, Lean 4 proofs, rivet docs), SVG rendering, LSP server. Compiles to a single WebAssembly component.
+
spar is architecturally upstream โ it validates system design before any code exists, then generates the interfaces and skeletons that feed into the build pipeline.
meld fuses multiple WebAssembly components into a single module. loom runs multi-pass optimization via Cranelift ISLE. synth transcodes to native ARM and RISC-V through program synthesis. sigil signs and attests every transformation with Sigstore or Ed25519.
+
Four separate tools, one flow. Every stage is independently verifiable.
Verify โ three independent proof paths across everything
+
Verus proves Rust code via SMT/Z3 โ preconditions, postconditions, invariants on every public function. Rocq machine-checks abstract invariants that hold regardless of implementation. Lean 4 proves scheduling theory โ priority inheritance, deadline guarantees, starvation freedom.
+
These are not limited to one tool. Every component in the ecosystem โ meld, loom, synth, kiln, gale, relay, wohl โ carries formal verification. Three independent paths run in CI on every commit.
Schema-driven SDLC artifact manager. Schemas covering ISO 26262, ASPICE, DO-178C, IEC 61508, IEC 62304, EN 50128, EU AI Act, SOTIF, STPA, STPA-Sec, cybersecurity, supply chain, and more. Validates on every commit โ broken links fail the build.
+
Imports AADL models from spar, STPA analysis from meld, test results from CI. Compliance reports generate on every release. LSP server, MCP server, dashboard.
kiln is a WebAssembly Component Model runtime with full WASI 0.2 and no_std architecture for embedded targets. gale provides formally verified Zephyr RTOS kernel primitives in Rust.
+
Built on top: relay โ formally verified flight software inspired by NASA's cFS, reimagined as generic WebAssembly components. wohl โ safety-critical home supervision. Real applications proving the ecosystem works end-to-end.
rivet mcp exposes a full tool suite to AI agents โ validate, add artifacts, link, check coverage, stamp provenance. Agents write code AND maintain traceability as part of their workflow.
+
rivet stamp records AI session provenance. mcp is the Rust framework for building MCP servers. spar wasm runs architecture analysis in-browser at 1.3 MB.