Repository navigation
Expand file tree
/
Copy pathportfolio.html
More file actions
184 lines (175 loc) · 13.2 KB
/
Copy pathportfolio.html
File metadata and controls
184 lines (175 loc) · 13.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
---
layout: default
title: Portfolio
description: "Selected work by David Silva — a vanilla-JS roguelike, a Pokédex, dashboards, a microblog, Manuscript Forge and Cashew. Built from scratch, with the engineering behind each one."
image: /img/og-default.png
---
<div class="portfolio-container">
<nav class="portfolio-nav" role="navigation" aria-label="Portfolio projects">
<ul class="portfolio-nav-list">
<li><a href="#roguelike" class="portfolio-nav-link" data-project="roguelike" aria-label="View Vanilla Roguelike project">Vanilla Roguelike</a></li>
<li><a href="#pokedex" class="portfolio-nav-link" data-project="pokedex" aria-label="View Pokédex project">Pokédex</a></li>
<li><a href="#dashboard" class="portfolio-nav-link" data-project="dashboard" aria-label="View Dashboard project">Dashboard</a></li>
<li><a href="#microblog" class="portfolio-nav-link" data-project="microblog" aria-label="View Microblog project">Microblog</a></li>
<li><a href="#manuscript-forge" class="portfolio-nav-link" data-project="manuscript-forge" aria-label="View Manuscript Forge project">Manuscript Forge</a></li>
<li><a href="#cashew" class="portfolio-nav-link" data-project="cashew" aria-label="View Cashew project">Cashew</a></li>
</ul>
</nav>
<main class="portfolio-content" role="main">
<!-- Vanilla Roguelike Project -->
<section id="roguelike" class="portfolio-project" data-project="roguelike" aria-labelledby="roguelike-title">
<div class="project-header">
<h1 id="roguelike-title" class="project-title">Vanilla Roguelike</h1>
<div class="project-links">
<a href="https://github.com/Davidslv/vanilla-roguelike" target="_blank" rel="noopener noreferrer" class="project-link">GitHub</a>
</div>
</div>
<div class="project-content">
<div class="project-screenshot">
<img src="/img/portfolio/roguelike-game-screenshot-adaptive.webp" alt="Vanilla Roguelike game screenshot" loading="lazy" />
</div>
<div class="project-description">
<h2>About</h2>
<p>Vanilla is a terminal-based roguelike game engine written in Ruby featuring procedurally generated mazes, player navigation, monster AI, and inventory systems. It uses Entity-Component-System architecture with event-driven design for game state tracking and comprehensive debugging capabilities.</p>
<h2>Motivation</h2>
<p>After building Vanilla and learning valuable lessons about game architecture, I documented my experience in "<a href="https://www.amazon.com/Building-Your-Own-Roguelike-Hands-ebook/dp/B0G1RBWF6V" target="_blank" rel="noopener noreferrer">Building Your Own Roguelike</a>". The book distills practical insights from this real-world implementation, making complex patterns like ECS architecture, command patterns, and event-driven systems accessible to developers learning game development.</p>
<h2>Tech Stack</h2>
<p>Built with Ruby 3.4.1, using RSpec for testing, I18n for localization, and SimpleCov for coverage. Implements ECS pattern with modular systems (movement, rendering, AI), event-driven logging with visualization tools, and multiple maze generation algorithms (Binary Tree, Aldous-Broder, Recursive Backtracker, Recursive Division).</p>
</div>
</section>
<!-- Pokédex Project -->
<section id="pokedex" class="portfolio-project" data-project="pokedex" aria-labelledby="pokedex-title" style="display: none;">
<div class="project-header">
<h1 id="pokedex-title" class="project-title">Pokédex</h1>
<div class="project-links">
<a href="https://pokedex-lemon-nine.vercel.app" target="_blank" rel="noopener noreferrer" class="project-link">Live Demo</a>
</div>
</div>
<div class="project-content">
<div class="project-screenshot">
<img src="/img/portfolio/pokedex-screenshot-adaptive.webp" alt="Pokédex application screenshot" loading="lazy" />
</div>
<div class="project-description">
<h2>About</h2>
<p>A browser-based recreation of the classic red Pokédex from Pokémon Gen 1, featuring 151 Pokémons. This interactive web app provides a nostalgic, kid-friendly encyclopedia with authentic design and voice narration. Users can browse Pokémon, view detailed stats, types, evolution chains, and hear auto-narrated descriptions.</p>
<h2>Motivation</h2>
<p>Built as a labor of love for my nephew, this project combines family bonding with web development passion. It taught me user-centered design by focusing on what excites a 7-year-old: vibrant visuals, simple controls, and interactive audio.</p>
<h2>Tech Stack</h2>
<p>Vanilla HTML5, CSS3, and JavaScript for a lightweight, framework-free experience.</p>
</div>
</div>
</section>
<!-- Dashboard Project -->
<section id="dashboard" class="portfolio-project" data-project="dashboard" aria-labelledby="dashboard-title" style="display: none;">
<div class="project-header">
<h1 id="dashboard-title" class="project-title">Dashboard</h1>
<div class="project-links">
<a href="https://dashboard.davidslv.uk" target="_blank" rel="noopener noreferrer" class="project-link">Live Demo</a>
</div>
</div>
<div class="project-content">
<div class="project-screenshot">
<img src="/img/portfolio/dashboard-screenshot-adaptive.webp" alt="Dashboard application screenshot" loading="lazy" />
</div>
<div class="project-description">
<h2>About</h2>
<p>AI Dashboard is a single-page web application that helps users discover, search, and organize AI tools and services. It displays services in a smartphone-style grid layout with hover descriptions, category filtering, and search to find tools across categories like Video Generation, Automation, Research, Development, and more.</p>
<h2>Motivation</h2>
<p>It was built to keep services I use or want to use in one place, avoiding browser bookmark bloat and forgotten links. Instead of scattered bookmarks, it provides a single hub for discovering and accessing AI tools with an intuitive, app-like experience.</p>
<h2>Tech Stack</h2>
<p>Built with React 18, Vite for fast development and builds, CSS Modules for component-scoped styling, and vanilla JavaScript. Fully client-side with no backend—all data is statically defined, making it fast, simple, and easy to deploy.</p>
</div>
</div>
</section>
<!-- Microblog Project -->
<section id="microblog" class="portfolio-project" data-project="microblog" aria-labelledby="microblog-title" style="display: none;">
<div class="project-header">
<h1 id="microblog-title" class="project-title">Microblog</h1>
<div class="project-links">
<a href="https://microblog.davidslv.uk" target="_blank" rel="noopener noreferrer" class="project-link">Live Demo</a>
</div>
</div>
<div class="project-content">
<div class="project-screenshot">
<img src="/img/portfolio/microblog-screenshot-adaptive.webp" alt="Microblog application screenshot" loading="lazy" />
</div>
<div class="project-description">
<h2>About</h2>
<p>Microblog is a high-performance microblogging platform where users post short messages (200 characters), reply to create conversations, follow other users, and view personalized feeds (timeline, following, or all posts). It uses modern techniques to handle data-intensive operations such as <b>fan-out on write</b> and horizontal scaling.</p>
<h2>Motivation</h2>
<p>Built as a production-ready educational case study demonstrating scalable Rails architecture, performance optimization techniques, and modern web development practices. Shows real-world engineering from database design to horizontal scaling, serving as a practical learning resource for developers.</p>
<h2>Tech Stack</h2>
<p>Built with Ruby on Rails 8.1.1 backend (PostgreSQL, Puma, Solid Queue, JWT auth) and React 18+ frontend (Vite, Tailwind CSS, Axios). Follows a three-layer architecture (Presentation/Application/Data) enabling independent scaling. Uses RSpec, Vitest, and Playwright for testing.</p>
</div>
</div>
</section>
<!-- Manuscript Forge Project -->
<section id="manuscript-forge" class="portfolio-project" data-project="manuscript-forge" aria-labelledby="manuscript-forge-title" style="display: none;">
<div class="project-header">
<h1 id="manuscript-forge-title" class="project-title">Manuscript Forge</h1>
<span class="wip-badge" aria-label="Work in progress">WIP</span>
<div class="project-links">
<span class="project-link disabled">Coming Soon</span>
</div>
</div>
<div class="project-content">
<div class="project-screenshot">
<img src="/img/portfolio/manuscript-forge-screenshot-adaptive.webp" alt="Manuscript Forge application screenshot" loading="lazy" />
</div>
<div class="project-description">
<h2>About</h2>
<p>Manuscript Forge is a work-in-progress platform designed to help writers manage, organize, and refine their manuscripts. It provides tools for version control, collaboration, and structured writing workflows.</p>
<h2>Motivation</h2>
<p>Created after writing "<a href="https://www.amazon.com/Building-Your-Own-Roguelike-Hands-ebook/dp/B0G1RBWF6V" target="_blank" rel="noopener noreferrer">Vanilla Roguelike</a>" in Markdown and needing proper chapter and diagram formatting for PDF export and Amazon KDP. Existing tools couldn't handle structured conversion, so I built custom tooling to convert Markdown to DOCX for formatting control, enabling PDF export and KDP ebook creation.</p>
<h2>Tech Stack</h2>
<p>Built with Ruby on Rails 8.1 (API mode), PostgreSQL 16, Solid Queue for async processing (Postgres-backed, no Redis), Shrine + AWS S3 for file storage, pandoc-ruby for document conversion, React + Vite frontend, Tailwind CSS, and RSpec for testing. Architecture follows service-oriented design with background jobs for document processing.</p>
</div>
</div>
</section>
<!-- Cashew Project -->
<section id="cashew" class="portfolio-project" data-project="cashew" aria-labelledby="cashew-title" style="display: none;">
<div class="project-header">
<h1 id="cashew-title" class="project-title">Cashew</h1>
<div class="project-links">
<a href="https://cashew.davidslv.uk" target="_blank" rel="noopener noreferrer" class="project-link">Live Demo</a>
</div>
</div>
<div class="project-content">
<div class="project-screenshot">
<div class="screenshot-carousel">
<div class="carousel-container">
<div class="carousel-slide active">
<img src="/img/portfolio/cashew-screenshot-adaptive.webp" alt="Cashew application screenshot" loading="lazy" />
</div>
<div class="carousel-slide">
<img src="/img/portfolio/cashew-app-screenshot-1-adaptive.webp" alt="Cashew application screenshot" loading="lazy" />
</div>
<div class="carousel-slide">
<img src="/img/portfolio/cashew-app-screenshot-2-adaptive.webp" alt="Cashew application screenshot" loading="lazy" />
</div>
</div>
<div class="carousel-controls">
<button class="carousel-btn prev" aria-label="Previous screenshot">‹</button>
<div class="carousel-indicators">
<button class="indicator active" data-slide="0" aria-label="Go to screenshot 1"></button>
<button class="indicator" data-slide="1" aria-label="Go to screenshot 2"></button>
<button class="indicator" data-slide="2" aria-label="Go to screenshot 3"></button>
</div>
<button class="carousel-btn next" aria-label="Next screenshot">›</button>
</div>
</div>
</div>
<div class="project-description">
<h2>About</h2>
<p>Cashew is a single-page web application that helps UK users compare mortgage overpayment strategies against investment alternatives like Cash ISAs and Stocks & Shares ISAs. It calculates interest savings, term reductions, investment growth projections, and factors in UK tax implications to show which strategy is financially better.</p>
<h2>Motivation</h2>
<p>I created Cashew to address the need for a simple, privacy-focused financial decision tool. Many existing solutions are either too complex or compromise user privacy. Cashew aims to provide powerful financial insights while keeping user data secure and private—no data storage, fully GDPR-compliant, with all calculations happening in real-time.</p>
<h2>Tech Stack</h2>
<p>Built with Ruby on Rails 8.1.1, using Hotwire (Turbo + Stimulus) for SPA behavior, Importmap for JavaScript modules, RSpec for testing, and Chart.js for visualizations. The architecture follows SOLID principles with service-oriented design.</p>
</div>
</div>
</section>
</main>
</div>
<script src="/js/portfolio.js"></script>
<script src="/js/carousel.js"></script>