diff --git a/generate.scm b/generate.scm
index 429bb24..cab16fc 100644
--- a/generate.scm
+++ b/generate.scm
@@ -18,20 +18,18 @@
;; ─── Individual cards (all become flat children of .columns) ──────────────────
-;; Project card — optionally wraps in an anchor if url is set
+;; Project card — detail bullets revealed on hover (desktop) or click (mobile)
(define (render-project proj)
- (let* ((url (field proj 'url))
- (card `(div (@ (class ,(string-append "project-card" (if url " clickable" "")))
- ,@(if url `((onclick ,(string-append "window.open('" url "','_blank')"))) '()))
- (div (@ (class "project-header"))
- (span (@ (class "project-name")) ,(field proj 'name))
- ,(date-range (field proj 'date-start) (field proj 'date-end)))
- (div (@ (class "project-summary"))
- ,(bullets (field proj 'summary-bullets)))
- (div (@ (class "project-details"))
- ,(bullets (field proj 'detail-bullets)))
- ,(tech-list (field proj 'technologies)))))
- card))
+ `(div (@ (class "project-card")
+ (onclick "this.classList.toggle('open')"))
+ (div (@ (class "project-header"))
+ (span (@ (class "project-name")) ,(field proj 'name))
+ ,(date-range (field proj 'date-start) (field proj 'date-end)))
+ (div (@ (class "project-summary"))
+ ,(bullets (field proj 'summary-bullets)))
+ (div (@ (class "project-details"))
+ ,(bullets (field proj 'detail-bullets)))
+ ,(tech-list (field proj 'technologies))))
;; Title card: blurb only, no projects nested inside.
;; Projects are emitted as siblings after the title card.
@@ -52,7 +50,8 @@
(map render-project (field tc 'projects))))
(define (render-education edu)
- `(div (@ (class "education-card"))
+ `(div (@ (class "education-card")
+ (onclick "this.classList.toggle('open')"))
(div (@ (class "edu-header"))
(span (@ (class "edu-degree")) ,(field edu 'degree))
,(date-range (field edu 'date-start) (field edu 'date-end)))
diff --git a/resume.html b/resume.html
index 33f16f8..c93a210 100644
--- a/resume.html
+++ b/resume.html
@@ -18,4 +18,4 @@ setInterval(function() {
setColHeight();
}
}, 200);
-
Education
The University of Georgia • Athens, GA
- Graduated December 2016
- ICPC Participant and Meeting Coordinator
Work Experience
Acme Corp • Remote
- Led a team of 4 engineers on the core platform.
- Drove adoption of internal developer tooling.
- Reviewed architecture proposals and mentored junior engineers.
- Built a Raft-based distributed config store used by 40+ services.
- Designed the consensus layer using a custom Raft implementation in Go.
- Added multi-region replication with conflict-free merge semantics.
- Reduced config propagation time from ~30 s to <500 ms p99.
- Go
- Raft
- gRPC
- Kubernetes
- Prometheus
- Unified internal service catalogue and runbook search into one portal.
- Indexed 300+ services via OpenAPI scraping and custom metadata YAML.
- Built a fuzzy-search backend in Go backed by Bleve.
- Reduced mean time-to-runbook from ~8 min to <30 s.
Acme Corp • Remote
- Owned the authentication service end-to-end.
- Reduced API latency by 35% through caching improvements.
- Rewrote legacy PHP auth service in Go; cut p99 latency from 800 ms to 40 ms.
- Migrated 12 M users with zero downtime using a dual-write/dark-read strategy.
- Introduced PKCE OAuth 2.0 flow replacing home-grown session tokens.
- Added comprehensive integration test suite with 92% coverage.
- Go
- PostgreSQL
- Redis
- OAuth2
- Docker
- Implemented token-bucket rate limiting across all public API endpoints.
- Built as a gRPC interceptor; config hot-reloaded from the config service.
- Reduced abusive traffic incidents by 80% in the first quarter after launch.
- Added per-tenant override rules managed via an internal admin UI.
Startup XYZ • Athens, GA
- Built product features across the React frontend and Node.js backend.
- Maintained CI/CD pipelines and AWS infrastructure.
- Collaborated directly with design and product teams.
- Delivered a live analytics dashboard processing 50k events/s.
- Replaced polling with WebSocket fan-out, cutting server load by 60%.
- Implemented client-side time-series aggregation using D3.js.
- Added user-configurable alert thresholds stored in IndexedDB.
- React
- Node.js
- WebSockets
- D3.js
- AWS
Projects
- A resume generator written in Scheme that produces HTML via SXML.
- Defined a small DSL for resume data in resume.scm.
- generate.scm walks the data and emits SXML serialised to HTML.
- CSS handles all layout including the two-column split.
- A 600-line Lisp interpreter in Python supporting tail-call optimisation.
- Implemented environments as linked frames, closures, and a macro expander.
- Added a REPL with readline history and pretty-printing.
Interests
Open-SourceRegular contributor to Guile and Chicken Scheme ecosystem libraries.
Rock ClimbingSport climber; currently projecting 5.12a outdoors.
Technical WritingBlog at janedoe.dev — compilers, distributed systems, functional programming.
Favorite Software
Guile SchemeEmacsNeovimNixGuixTailscaleWireGuardmpvzathuratmuxAlacrittySyncthingBspwmRofi