Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,11 @@ all data loaded at build time) · GitHub Pages deploy via `.github/workflows/dep
- Content is hand-authored TS in `lib/content/`, not markdown/JSON (`resolveJsonModule` +
`strict` infers `never[]` from an empty JSON array, which fails typecheck). Travel data is the
exception — script-generated JSON via `scripts/process-travel-data.js` /
`scripts/fetch-flights.js` (both manual, not automated).
`scripts/fetch-flights.js` (both manual, not automated). Countries come from a Notion-exported
CSV at `~/personal/travel/`; flights from the `Flighty - App Data` Notion DB. Flighty itself was
deleted in 2026, so that DB is no longer a sync target — it's the hand-maintained log of record,
and new flights get added to it before re-running the script. `generateRoutes` merges A→B with
B→A and stores the alphabetical direction, so a re-run is byte-stable apart from `generatedAt`.
- `github-actions[bot]` pushes with the default `GITHUB_TOKEN` don't trigger workflows, so a cron
that commits data can't make the site rebuild. Anything needing fresh data at deploy time must
fetch during the build, not commit-then-rebuild.
Expand Down
28 changes: 28 additions & 0 deletions app/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -945,6 +945,34 @@ input,
letter-spacing: 0.04em;
color: var(--blood-400);
}
.form-success {
display: grid;
grid-template-columns: auto 1fr;
gap: 2px var(--s-3);
align-items: center;
padding: var(--s-4);
border: 2px solid var(--accent);
background: color-mix(in srgb, var(--accent) 14%, transparent);
}
.form-success-mark {
grid-row: 1 / span 2;
font-size: 30px;
line-height: 1;
color: var(--accent-text);
}
.form-success-head {
font-family: var(--font-mono);
font-size: 12px;
font-weight: 700;
letter-spacing: 0.16em;
text-transform: uppercase;
color: var(--fg);
}
.form-success-body {
font-size: 14px;
line-height: 1.4;
color: var(--fg-muted);
}
.form-captcha { align-self: flex-start; }

/* ---- Resume ---------------------------------------------- */
Expand Down
2 changes: 1 addition & 1 deletion app/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export default function RootLayout({
url: SITE_URL,
description: "Builds software with AI.",
sameAs: [
"https://linkedin.com/in/dommangonon",
"https://www.linkedin.com/in/dominicmangonon/",
"https://x.com/collapsecontext",
"https://dommangonon.substack.com",
"https://github.com/dommango",
Expand Down
15 changes: 12 additions & 3 deletions components/landing/Contact.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ export function Contact() {
const recaptchaRef = useRef<ReCAPTCHA>(null)

const update =
(key: keyof typeof form) => (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) =>
(key: keyof typeof form) => (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
setStatus((st) => (st === 'idle' ? st : 'idle'))
setForm((s) => ({ ...s, [key]: e.target.value }))
}

const submit = async (e: React.FormEvent) => {
e.preventDefault()
Expand All @@ -45,7 +47,6 @@ export function Contact() {
setForm({ name: '', email: '', message: '' })
setCaptchaOk(false)
recaptchaRef.current?.reset()
setTimeout(() => setStatus('idle'), 4000)
} else {
setStatus('error')
setFeedback(result.message)
Expand All @@ -69,7 +70,7 @@ export function Contact() {
dom.mangonon@gmail.com →
</a>
<div className="contact-socials">
<a href="https://linkedin.com/in/dommangonon" target="_blank" rel="noreferrer">
<a href="https://www.linkedin.com/in/dominicmangonon/" target="_blank" rel="noreferrer">
LinkedIn ↗
</a>
<a href="https://x.com/collapsecontext" target="_blank" rel="noreferrer">
Expand Down Expand Up @@ -123,6 +124,14 @@ export function Contact() {

{status === 'error' && <p className="form-error">{feedback}</p>}

{status === 'success' && (
<div className="form-success" role="status">
<span className="form-success-mark" aria-hidden="true">✓</span>
<span className="form-success-head">Message sent</span>
<span className="form-success-body">{feedback}</span>
</div>
)}

<div className="form-foot">
<button
type="submit"
Expand Down
4 changes: 1 addition & 3 deletions components/landing/Footer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export function Footer({ onHome }: FooterProps) {
<span className="brand-word">Dom Mangonon</span>
</button>
<div className="footer-socials">
<a href="https://linkedin.com/in/dommangonon" target="_blank" rel="noreferrer">
<a href="https://www.linkedin.com/in/dominicmangonon/" target="_blank" rel="noreferrer">
LinkedIn ↗
</a>
<a href="https://x.com/collapsecontext" target="_blank" rel="noreferrer">
Expand All @@ -28,8 +28,6 @@ export function Footer({ onHome }: FooterProps) {
</div>
<div className="footer-legal">
<span>© 2026 · Dom Mangonon</span>
<span>·</span>
<span>Built with Claude Code</span>
</div>
</div>
</footer>
Expand Down
6 changes: 3 additions & 3 deletions components/landing/Hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ export function Hero() {
</p>
<p className="hero-about hero-about-secondary">
In 2025 I went all in on AI and started shipping actual software: a restaurant cost
tracker, a tournament bracket engine, an SEC filings pipeline. All built with Claude
Code, including this site. The projects below are real, deployed, and mostly still
running.
tracker, a tournament bracket engine, an SEC filings pipeline. All built using
coding agents, including this site. The projects below are real, deployed, and mostly
still running.
</p>
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion components/landing/Projects.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export function Projects() {
<span className="ds-eyebrow">Projects</span>
<h2 className="projects-title">Things I built.</h2>
<p className="projects-blurb">
Mostly nights and weekends, mostly with Claude Code. A couple are running in the wild;
Mostly nights and weekends, mostly with coding agents. A couple are running in the wild;
a couple are pipelines that only ever needed to run once.
</p>
</div>
Expand Down
4 changes: 2 additions & 2 deletions components/landing/Resume.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const TIMELINE = [
{
y: '2025 →',
t: 'Building with AI',
d: 'Shipping software nights and weekends with Claude Code (see above)',
d: 'Shipping software nights and weekends with coding agents (see above)',
},
{
y: '2021 →',
Expand Down Expand Up @@ -62,7 +62,7 @@ export function Resume() {
</p>
<a
className="writing-all"
href="https://linkedin.com/in/dommangonon"
href="https://www.linkedin.com/in/dominicmangonon/"
target="_blank"
rel="noreferrer"
>
Expand Down
22 changes: 17 additions & 5 deletions content/travel/countries.json
Original file line number Diff line number Diff line change
Expand Up @@ -608,7 +608,7 @@
"order": 51,
"continent": "South America",
"coordinates": [
38.4161,
-38.4161,
-63.6167
]
},
Expand All @@ -623,10 +623,22 @@
-14.235,
-51.9253
]
},
{
"id": "aruba",
"name": "Aruba",
"flag": "🇦🇼",
"firstVisited": 2026,
"order": 53,
"continent": "North America",
"coordinates": [
12.5211,
-69.9683
]
}
],
"stats": {
"totalCountries": 52,
"totalCountries": 53,
"continents": 5,
"continentNames": [
"Africa",
Expand All @@ -635,14 +647,14 @@
"North America",
"South America"
],
"yearRange": "1986-2024",
"yearRange": "1986-2026",
"firstYear": 1986,
"lastYear": 2024,
"lastYear": 2026,
"countriesByContinent": {
"Africa": 1,
"Asia": 15,
"Europe": 21,
"North America": 9,
"North America": 10,
"South America": 6
}
}
Expand Down
Loading
Loading