// app.jsx — Ken Kelly portfolio prototype // One long page. Three visual directions. const { useState, useEffect, useRef, useCallback, useMemo } = React; // ───────────────────────────────────────────────────────────── content ── const BIO = { name: "Ken Kelly", handle: "kkelly", title: "Principal Software Architect", location: "South Florida, US", yearsExp: 20, available: true, blurb: "I build production frontends and backends that don't fall over. React, TypeScript, Go — 20+ years of shipping software that real customers depend on.", links: { email: "ken@kkelly.dev", github: "https://github.com/kenhkelly", linkedin: "https://www.linkedin.com/in/kenhkelly/", resume: "/resume.pdf", }, }; const NOW = [ { k: "building", v: "Replatforming Total Wine's web checkout — React + Go services." }, { k: "available", v: "Taking on 1–2 consulting engagements for Q3. Backend, frontend, or both." }, { k: "learning", v: "Deepening DevOps chops — Kubernetes, Terraform, and CI/CD pipeline design." }, { k: "location", v: "South Florida · ET (UTC−5/−4)" }, ]; const EXPERIENCE = [ { range: "2018 — present", company: "Total Wine & More", role: "Principal Software Architect", notes: "Architect the consumer web + native apps. Lead frontend platform, drive Go service migrations, mentor a team of 12.", stack: ["React", "React Native", "TypeScript", "Go", "GraphQL", "GCP", "Restate", "Redpanda"], }, { range: "2014 — 2018", company: "Senior Engineer", role: "E-commerce & SaaS clients", notes: "Full-stack lead on commerce, fulfillment, and CMS rebuilds. Took several products from MVP through scale.", stack: ["Node.js", "React", "Postgres", "Redis", "Docker"], }, { range: "2008 — 2014", company: "Independent / agency", role: "Frontend & full-stack", notes: "Client work across hospitality, retail, media. Built and ran a small agency for four of those years.", stack: ["PHP", "MySQL", "jQuery", "Backbone", "Rails"], }, { range: "2005 — 2008", company: "First gigs", role: "Web developer", notes: "Got my hands dirty. Tables-for-layout, Flash, PSD-to-HTML, the works.", stack: ["HTML", "CSS", "JS", "PHP"], }, ]; const PROJECTS = [ { id: "tw-mobile", title: "Total Wine & More — Mobile App", year: "2019 — present", role: "Tech Lead", summary: "Native iOS & Android storefront. Catalog browse, reorder, in-store pickup, wallet. 4.9★ on iOS with millions of downloads.", stack: ["React Native", "Swift", "Kotlin", "GraphQL", "Go"], metrics: [ { v: "4.9★", l: "App Store rating" }, { v: "8M+", l: "downloads" }, { v: "60Hz", l: "scroll on a 5-year-old phone" }, ], href: "https://apps.apple.com/us/app/total-wine-more/id1277318070", }, { id: "tw-web", title: "Total Wine & More — Web", year: "2018 — present", role: "Principal Engineer", summary: "Top-50 US e-commerce site by traffic. Lead frontend architecture, performance, A/B platform, design-system rollout.", stack: ["React", "TypeScript", "Next.js", "Go", "GraphQL", "Akamai"], metrics: [ { v: "92", l: "Lighthouse perf" }, { v: "<1.2s", l: "median LCP" }, { v: "1.5B", l: "annual GMV" }, ], href: "https://www.totalwine.com", }, ]; const SKILLS = { Languages: ["TypeScript", "JavaScript", "Go", "Swift", "Kotlin", "SQL"], Frontend: ["React", "React Native", "Next.js", "Vite", "CSS Architecture"], Backend: ["Go", "Node.js", "GraphQL", "REST", "Postgres", "Redis", "Restate", "Redpanda"], Platform: ["AWS", "GCP", "Docker", "Kubernetes", "Terraform", "CI/CD"], "Practice": ["System design", "Mentoring", "Tech strategy", "Code review"], }; // ───────────────────────────────────────────────────────────── tweaks ── const TWEAK_DEFAULTS = { direction: "terminal", accent: "#7CFFB2", density: "cozy", font: "jetbrains", }; const FONT_STACKS = { jetbrains: '"JetBrains Mono", ui-monospace, "Cascadia Code", Menlo, monospace', plex: '"IBM Plex Mono", ui-monospace, Menlo, monospace', geist: '"Geist Mono", "JetBrains Mono", ui-monospace, monospace', }; const DIRECTIONS = { terminal: { label: "Terminal", bg: "#06100B", bgAlt: "#0A1812", surface: "#0E1A14", border: "rgba(124,255,178,0.14)", text: "#C8E6D3", muted: "#5E7E6A", accent: "#7CFFB2", scanlines: true, promptChar: "$", }, console: { label: "Console", bg: "#0B0E14", bgAlt: "#10141C", surface: "#141923", border: "rgba(127,215,255,0.12)", text: "#D8E0EE", muted: "#6E7A91", accent: "#7FD7FF", scanlines: false, promptChar: "›", }, brutalist: { label: "Brutalist", bg: "#000000", bgAlt: "#0A0A0A", surface: "#0F0F0F", border: "rgba(255,180,84,0.18)", text: "#F2F2F2", muted: "#7A7A7A", accent: "#FFB454", scanlines: false, promptChar: "▌", }, }; // ───────────────────────────────────────────────────────────── helpers ── function useTime() { const [t, setT] = useState(() => new Date()); useEffect(() => { const id = setInterval(() => setT(new Date()), 1000); return () => clearInterval(id); }, []); return t; } function fmtClock(d) { return d.toLocaleTimeString("en-US", { hour: "2-digit", minute: "2-digit", second: "2-digit", hour12: false, }); } // ───────────────────────────────────────────────────────── terminal hero ── function TerminalHero({ theme }) { const lines = useMemo(() => ([ { type: "cmd", text: "whoami" }, { type: "out", text: "ken kelly · principal software engineer · south florida" }, { type: "cmd", text: "cat ./about.txt" }, { type: "out", text: BIO.blurb }, { type: "cmd", text: "ls ~/work | head -3" }, { type: "out", text: "total-wine-mobile/ total-wine-web/ go-weather/" }, { type: "cmd", text: "echo $STATUS" }, { type: "out", text: "available_for_consulting=true" }, ]), []); const [visible, setVisible] = useState([]); const [typing, setTyping] = useState(""); const [idx, setIdx] = useState(0); const [skipped, setSkipped] = useState(false); useEffect(() => { if (skipped) { setVisible(lines); return; } if (idx >= lines.length) return; const cur = lines[idx]; if (cur.type === "out") { const id = setTimeout(() => { setVisible(v => [...v, cur]); setIdx(i => i + 1); }, 180); return () => clearTimeout(id); } let i = 0; setTyping(""); const id = setInterval(() => { i++; setTyping(cur.text.slice(0, i)); if (i >= cur.text.length) { clearInterval(id); setTimeout(() => { setVisible(v => [...v, cur]); setTyping(""); setIdx(p => p + 1); }, 120); } }, 28); return () => clearInterval(id); }, [idx, skipped, lines]); const skip = () => setSkipped(true); return (
{BIO.title} {BIO.yearsExp}+ years {BIO.location}
{BIO.blurb}
I'm Ken. I write production software for a living and have been doing it since the early 2000s. These days I split my time between principal-level work at Total Wine & a small consulting practice on the side.
I'm equally at home in a React codebase and a Go service, which means I tend to get pulled into the gnarly seams between the two — performance, type-safety across the wire, dev-experience, build systems, and the boring infra that decides whether a product can actually scale.
I care about shipping, leaving codebases healthier than I found them, and mentoring engineers who'll outgrow me. I'm currently picking up 1–2 consulting clients for Q3 — happy to talk if you're stuck on something hard.
{p.id}{p.summary}
{`$ cat > /var/mail/ken <
Best for: consulting engagements, technical advisory, hands-on architecture work.