Source Code
src/pages/projects/mod.rs
pub mod data;
pub mod ecosim;
pub mod gpu_shaders;
pub mod home_lab;
pub mod keybind_plugin;
pub mod orbit_camera;
pub mod proc_gen;
pub mod this_website;
pub mod trading_bot;
use leptos::*;
use leptos_meta::{Meta, Title};
use leptos_router::A;
use data::{aggregated_skills, SHOW_SKILL_COUNT};
#[component]
pub fn Projects() -> impl IntoView {
let skills_view = aggregated_skills()
.into_iter()
.map(|(skill, projects)| {
let count = projects.len();
let popup_items = projects
.iter()
.map(|p| {
let name: &'static str = p.name;
let tagline: &'static str = p.tagline;
let href = format!("/projects/{}", p.slug);
view! {
<A href=href class="skill-popup-project">
<span class="skill-popup-name">{name}</span>
<span class="skill-popup-sep">" - "</span>
<span class="skill-popup-desc">{tagline}</span>
</A>
}
})
.collect::<Vec<_>>();
view! {
<li class="skill-tag-wrapper">
{skill}
{SHOW_SKILL_COUNT.then(|| view! { <span class="skill-count">"("{count}")"</span> })}
<div class="skill-popup">
<div class="skill-popup-box">{popup_items}</div>
</div>
</li>
}
})
.collect::<Vec<_>>();
view! {
<Title text="Projects – Peter Pinto"/>
<Meta name="description" content="A collection of personal projects and open work by Peter Pinto."/>
<div class="page">
<span class="eyebrow">"Projects"</span>
<h1>"Things I've " <em style="font-style:italic; color: var(--accent)">"Built"</em></h1>
<p class="lead">
"A selection of personal projects — tools, systems, and open work."
</p>
<ul class="skills-list" style="margin-top: 1.5rem; margin-bottom: 0.5rem;">
{skills_view}
</ul>
<hr class="divider"/>
<div class="project-grid">
// ── This Website ──────────────────────────────────
<div class="project-card">
<span class="eyebrow">"Full-stack Rust"</span>
<h3>"This Website"</h3>
<p>
"A full-stack Rust web application with server-side rendering,
WASM hydration, and a live view-source mode. Built with Leptos,
Axum, and cargo-leptos."
</p>
<A href="/projects/this-website" class="btn btn-outline">"Details →"</A>
</div>
// ── Home Lab ───────────────────────────────────────
<div class="project-card">
<span class="eyebrow">"Infrastructure"</span>
<h3>"Home Lab"</h3>
<p>
"A three-node bare-metal Kubernetes cluster on repurposed hardware,
running RKE2, Istio, and Longhorn with real workloads — Gitea runner,
RabbitMQ, Matrix, InfluxDB, and more."
</p>
<A href="/projects/home-lab" class="btn btn-outline">"Details →"</A>
</div>
// ── Trading Bot ────────────────────────────────────
<div class="project-card">
<span class="eyebrow">"Rust · Kubernetes Operator"</span>
<h3>"Trading Bot"</h3>
<p>
"A Kubernetes-native operator that manages the full lifecycle of automated
trading bot deployments via Custom Resource Definitions — configuration,
scheduling, and declarative risk limits all in one spec."
</p>
<A href="/projects/trading-bot" class="btn btn-outline">"Details →"</A>
</div>
// ── Ecosim ─────────────────────────────────────────
<div class="project-card">
<span class="eyebrow">"Game · Bevy"</span>
<h3>"Ecosim"</h3>
<p>
"A planet-scale ecosystem simulator built on Bevy. Players seed a world,
guide species populations, and intervene in emergent food webs — from
global climate patterns down to individual organisms."
</p>
<A href="/projects/ecosim" class="btn btn-outline">"Details →"</A>
</div>
// ── Procedural Generation ──────────────────────────
<div class="project-card">
<span class="eyebrow">"Rust · Bevy · H3"</span>
<h3>"Procedural Generation"</h3>
<p>
"A planet-scale hexagonal grid engine using Uber's H3 library.
Cells refine and coarsen dynamically based on camera distance,
with Perlin noise terrain and a trait-based simulation system."
</p>
<A href="/projects/proc-gen" class="btn btn-outline">"Details →"</A>
</div>
// ── Orbit Camera ───────────────────────────────────
<div class="project-card">
<span class="eyebrow">"Bevy Plugin"</span>
<h3>"Orbit Camera"</h3>
<p>
"A reusable Bevy orbital camera plugin. Input is fully decoupled
via a trait — swap keyboard, mouse, or gamepad without touching
the camera code. Quaternion rotation, two modes, speed falloff."
</p>
<A href="/projects/orbit-camera" class="btn btn-outline">"Details →"</A>
</div>
// ── Keybind Plugin ─────────────────────────────────
<div class="project-card">
<span class="eyebrow">"Bevy Plugin"</span>
<h3>"Keybind Plugin"</h3>
<p>
"A Bevy input binding plugin that maps keyboard, mouse, gamepad,
and touch inputs to named actions. Game logic responds to actions,
not hardware — rebinding is a runtime change."
</p>
<A href="/projects/keybind-plugin" class="btn btn-outline">"Details →"</A>
</div>
// ── GPU Shaders ────────────────────────────────────
<div class="project-card">
<span class="eyebrow">"Rust-GPU · SPIR-V"</span>
<h3>"GPU Shaders"</h3>
<p>
"SPIR-V shaders written in Rust via Rust-GPU. The vertex shader
generates H3 hexagonal cell boundaries entirely on the GPU from
a list of cell indices — no mesh data from the CPU."
</p>
<A href="/projects/gpu-shaders" class="btn btn-outline">"Details →"</A>
</div>
</div>
</div>
}
}