feat: initial next.js boilerplate, set up .env, add outline documents

This commit is contained in:
2026-05-27 15:21:10 -07:00
parent 946cf28141
commit dd8cbe1c45
8 changed files with 810 additions and 0 deletions
+142
View File
@@ -0,0 +1,142 @@
# Portfolio — Angel Mankel
Personal site at a reserved domain (TBD — see `config.md` once created). This is a hiring-funnel artifact, not a blog or playground.
## Who this is for
The reader is a hiring manager or recruiter at one of these companies:
- **Bullseye:** Vercel, Anthropic, Cursor, Cognition, Replit, Sourcegraph, Continue, Linear, Figma
- **Adjacent:** Stripe, Ramp, Notion, Retool, any AI-native product company shipping React-heavy surfaces
They land here from a CV, LinkedIn DM, or referral. They will spend **60-120 seconds** before deciding to reply or move on. Optimize ruthlessly for that window.
## Who Angel is (positioning)
**Headline:** Frontend engineer with deep AI-tooling fluency — ships production React and builds custom Claude Code workflows.
**The wedge:** Most React devs treat Claude Code as a toy. Most AI tinkerers can't ship a real component library. Angel does both.
**Background arc:** Healthcare IT → Salesforce admin → Software Engineer at Village Medical (current). Leads React + TypeScript redesigns of patient-facing apps and the internal component library. In parallel, heavy day-to-day Claude Code user — custom slash commands, MCP integrations, agent workflows.
**Target roles:** Frontend / Product / AI-Native engineer, remote US, mid-level (1-3 yr SWE, broader IT background). Comp target $90-130K USD, floor $100K.
Full profile lives in `~/Projects/career-ops/config/profile.yml` and `~/Projects/career-ops/cv.md`. Read those before writing any copy.
## Design direction
**Aesthetic reference:** Vercel.com, Linear.app, Anthropic.com, Rauno.me, Paco.me, Brittany Chiang's v4.
**Principles:**
- Minimalist, content-first. Typography does the heavy lifting.
- Dark only. No light theme, no theme toggle. See `palette.html` for the full spec.
- Generous whitespace. Wide line-height. Long-form readable.
- **One** signature interaction detail (subtle cursor effect, scroll-driven element, command palette) — not a museum of effects.
- No hero video, no parallax stacks, no animated SVG mascots, no "Hi I'm Angel 👋" with a waving emoji.
- Monospace accents for technical content (kbd, inline code, metadata) — sparingly.
**What we are NOT building:**
- A WebGL/Three.js showcase. Reads as "junior trying hard" to senior frontend HMs. Angel's graphics range gets one line in About, not a hero.
- A flashy gradient/blob landing page.
- A blog-first site. (Writing is welcome but not the entry point.)
- A "projects" grid of unfinished side projects. Quality over quantity — 3-4 deep case studies beats 12 thumbnails.
## Information architecture
Five routes max. Keep it skimmable.
```
/ → Landing. Name + one-line positioning + 3 case study cards + contact.
/projects → Case study index (same 3-4 cards, expandable).
/projects/[slug] → Individual case study (postmortem format).
/about → Background arc, current role, what Angel is looking for.
/uses → Optional. Tools, editor setup, Claude Code workflow. High signal for AI-native hiring.
```
Skip `/blog`, `/work` (use `/projects`), `/contact` (inline on `/`), and `/resume` (a chrono strip + Download CV link on `/about` covers it without duplicating content).
### What `/about` must include
Beyond the narrative paragraphs:
- **Chronological strip** — 3-4 rows, plain text, format: `year-range · company · role`. No bullets, no descriptions. Source from `~/Projects/career-ops/cv.md`.
- **Download CV (PDF)** — single plain-text link pointing at the PDF generated by career-ops (`generate-pdf.mjs` output). Don't style it as a button or hero CTA — one line, in flow.
## Case study format (CRITICAL)
Each case study reads like an engineering postmortem, not a marketing page. Structure:
1. **One-line summary** — what shipped, who it served, the measurable outcome.
2. **Context** — the constraint or problem. 2-3 sentences.
3. **Decisions** — 3-5 specific technical/design calls and why. Name the alternatives rejected.
4. **Outcome** — measurable result. Numbers when possible. Honest when not.
5. **What I'd do differently** — one paragraph. Signals seniority.
**Do not** include: tech stack badges, "challenges faced" sections, generic "I learned a lot" closers.
### The 3-4 case studies to write
Source material in `~/Projects/career-ops/cv.md` and `~/Projects/career-ops/modes/_profile.md` under "proof_points":
1. **Village Medical patient scheduling redesign** — React + TS rebuild of a patient-facing scheduling app. Lead with scope and UX decisions, not framework name-drops.
2. **Village Medical internal component library** — design-system ownership. This is the bullseye proof point for product/design-engineer roles. Show the API of one component, the migration story, governance model.
3. **Claude Code custom tooling** — slash commands, MCP integrations, agent workflows used day-to-day. This is the AI-native wedge. Show one concrete workflow with before/after time-on-task.
4. **(Optional) Gila River internal Electron apps** — older but quantified (100-150% productivity gains, 70% AD-script speedup). Frame as "how I got into engineering." Skip if it dilutes the frontend narrative; keep if it adds blue-collar engineering credibility.
## Tech stack recommendation
**Default:** Next.js 15 (App Router) + TypeScript + Tailwind v4 + MDX for case studies.
Why: it's the stack the bullseye companies ship. Using it is itself a signal.
**Deployment:** Self-hosted by Angel. Traefik is already configured and pointing at the domain. Do not propose Vercel, Netlify, Cloudflare Pages, or any managed host — the infra is in-house and stays that way. Build target should produce a standard Node server or static export that drops into the existing Traefik setup; ask Angel for specifics (container? bare Node? static `out/`?) before wiring CI.
**Alternatives considered:**
- Astro — better for static-heavy content sites, but Next.js signals stack alignment with target employers. Use Astro only if Angel wants to demonstrate range.
- Plain HTML/CSS — would actually be impressive ("I don't need a framework for this") but reads as contrarian unless the design carries it. Skip.
**Other choices:**
- `next/font` for self-hosted typography. Suggested pairing: Inter (UI) + JetBrains Mono / Geist Mono (code). Or splurge on a paid display face for the name only.
- `next-mdx-remote` or built-in MDX for case studies.
- `shiki` for code blocks (matches Vercel/Anthropic aesthetic better than Prism).
- View Transitions API for `/projects``/projects/[slug]` navigation. One signature detail.
- No CMS. Content lives in MDX files in-repo. Version-controlled, no DB.
## Tone and copy
Read `~/Projects/career-ops/modes/_profile.md` under "Writing Style" if it exists; otherwise extract style from `~/Projects/career-ops/writing-samples/` before drafting any user-facing copy.
Defaults if no samples found:
- First person, active voice. "I led", "I shipped", not "responsible for".
- Short sentences. Mix in a longer one for rhythm.
- Specific over abstract. "Cut p95 from 2.1s to 380ms" beats "improved performance."
- Zero corporate clichés: no "passionate", "results-oriented", "proven track record", "leveraged", "synergies", "cutting-edge."
- No emoji in copy. (Emoji on the page = wrong audience signal for these companies.)
## What "done" looks like for v1
- [ ] Site reachable at the domain through Angel's Traefik (deployment infra is his — agent does not touch it)
- [ ] `/` renders Name + positioning line + 3 case study cards + email contact
- [ ] 3 case studies fully written (not lorem ipsum)
- [ ] `/about` written, including chrono strip and Download CV link
- [ ] CV PDF generated via career-ops and served at a stable path (e.g. `/cv.pdf`)
- [ ] Open Graph image + favicon
- [ ] Lighthouse: 100/100/100/100 (this is table stakes for the audience)
- [ ] Site is responsive but designed desktop-first (hiring managers are on laptops)
- [ ] No analytics that block (Plausible or none — definitely not GA)
## What NOT to do
- Do not scaffold a Next.js project until Angel says go on the design direction.
- Do not write case study copy without first reading `~/Projects/career-ops/cv.md` and `~/Projects/career-ops/modes/_profile.md`.
- Do not invent metrics or experience. Pull only from CV + article-digest.md (if present).
- Do not add a "currently learning" or "tech stack" badge wall.
- Do not commit Angel's phone number, address, or any PII beyond name + email + LinkedIn + GitHub.
- Do not generate AI art for the OG image. A clean typographic OG card is the right move.
## Cross-references
- CV (source of truth): `~/Projects/career-ops/cv.md`
- Profile & narrative: `~/Projects/career-ops/config/profile.yml`, `~/Projects/career-ops/modes/_profile.md`
- Proof point details (if exists): `~/Projects/career-ops/article-digest.md`
- Writing samples (if exists): `~/Projects/career-ops/writing-samples/`
+191
View File
@@ -0,0 +1,191 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Portfolio Palette — Angel Mankel</title>
<style>
html, body { margin: 0; padding: 0; font-family: ui-sans-serif, system-ui, sans-serif; background: #fff; color: #000; }
body { padding: 40px 20px 120px; }
.wrap { max-width: 1100px; margin: 0 auto; }
h1 { font-size: 22px; margin: 0 0 32px; }
h2 { font-size: 14px; text-transform: uppercase; letter-spacing: 0.08em; margin: 48px 0 12px; color: #555; }
.row { display: grid; grid-template-columns: repeat(5, 1fr); gap: 12px; }
.swatch { border: 1px solid #000; overflow: hidden; font-family: ui-monospace, monospace; font-size: 11px; }
.swatch .chip { height: 100px; border-bottom: 1px solid #000; }
.swatch .meta { padding: 8px 10px; line-height: 1.4; }
.swatch .role { display: block; font-weight: 600; margin-bottom: 2px; }
.swatch .hex { display: block; color: #555; }
.stage { background: #0a0a0a; padding: 20px; margin-top: 16px; }
.stage + .stage { margin-top: 16px; }
.preview { background: #1c1c1c; color: #ededed; border: 1px solid #2e2e2e; padding: 28px; font-family: ui-sans-serif, system-ui, sans-serif; }
.preview + .preview { margin-top: 16px; }
.preview h3 { font-size: 22px; margin: 0 0 6px; font-weight: 600; }
.preview p { margin: 0 0 10px; font-size: 13px; line-height: 1.6; }
.preview a { color: #d4a24a; text-decoration: underline; text-underline-offset: 3px; }
.preview .muted { color: #6b6b6b; }
.preview .nav { display: flex; justify-content: space-between; align-items: center; font-family: ui-monospace, monospace; font-size: 12px; }
.preview .nav .links { display: flex; gap: 18px; color: #6b6b6b; }
.preview .nav .links a { color: inherit; text-decoration: none; }
.preview hr { border: 0; border-top: 1px solid #2e2e2e; margin: 20px 0; }
.preview .chrono { font-family: ui-monospace, monospace; font-size: 13px; line-height: 1.8; color: #ededed; }
.preview .chrono .y { color: #6b6b6b; margin-right: 14px; }
.preview .code { background: #0f0f0f; border: 1px solid #2e2e2e; padding: 14px 16px; font-family: ui-monospace, monospace; font-size: 12px; line-height: 1.6; }
.preview .code .k { color: #d4a24a; }
.preview .code .c { color: #6b6b6b; }
.preview .case-meta { font-family: ui-monospace, monospace; font-size: 12px; color: #6b6b6b; margin-bottom: 18px; }
.preview .case-meta span + span::before { content: " · "; }
</style>
</head>
<body>
<div class="wrap">
<h1>Palette — Angel Mankel portfolio</h1>
<!-- ============================================================ -->
<h2>Neutrals</h2>
<div class="row">
<div class="swatch">
<div class="chip" style="background: #0a0a0a;"></div>
<div class="meta">
<span class="role">bg</span>
<span class="hex">#0a0a0a</span>
</div>
</div>
<div class="swatch">
<div class="chip" style="background: #1c1c1c;"></div>
<div class="meta">
<span class="role">bg-elevated</span>
<span class="hex">#1c1c1c</span>
</div>
</div>
<div class="swatch">
<div class="chip" style="background: #2e2e2e;"></div>
<div class="meta">
<span class="role">border</span>
<span class="hex">#2e2e2e</span>
</div>
</div>
<div class="swatch">
<div class="chip" style="background: #6b6b6b;"></div>
<div class="meta">
<span class="role">text-muted</span>
<span class="hex">#6b6b6b</span>
</div>
</div>
<div class="swatch">
<div class="chip" style="background: #ededed;"></div>
<div class="meta">
<span class="role">text</span>
<span class="hex">#ededed</span>
</div>
</div>
</div>
<!-- ============================================================ -->
<h2>Accent</h2>
<div class="row">
<div class="swatch">
<div class="chip" style="background: #d4a24a;"></div>
<div class="meta">
<span class="role">accent</span>
<span class="hex">#d4a24a</span>
</div>
</div>
</div>
<!-- ============================================================ -->
<h2>Hover states</h2>
<div class="row">
<div class="swatch">
<div class="chip" style="background: #262626;"></div>
<div class="meta">
<span class="role">bg-elevated · hover</span>
<span class="hex">#262626</span>
</div>
</div>
<div class="swatch">
<div class="chip" style="background: #3d3d3d;"></div>
<div class="meta">
<span class="role">border · hover</span>
<span class="hex">#3d3d3d</span>
</div>
</div>
<div class="swatch">
<div class="chip" style="background: #9a9a9a;"></div>
<div class="meta">
<span class="role">text-muted · hover</span>
<span class="hex">#9a9a9a</span>
</div>
</div>
<div class="swatch">
<div class="chip" style="background: #ffffff;"></div>
<div class="meta">
<span class="role">text · hover</span>
<span class="hex">#ffffff</span>
</div>
</div>
<div class="swatch">
<div class="chip" style="background: #e6b966;"></div>
<div class="meta">
<span class="role">accent · hover</span>
<span class="hex">#e6b966</span>
</div>
</div>
</div>
<!-- ============================================================ -->
<h2>Previews</h2>
<div class="stage"><div class="preview">
<div class="nav">
<div><strong>Angel Mankel</strong></div>
<div class="links"><a href="#">projects</a><a href="#">about</a><a href="#">uses</a><a href="#">email</a></div>
</div>
</div></div>
<div class="stage"><div class="preview">
<h3>Frontend engineer with deep AI-tooling fluency.</h3>
<p>I ship production React at Village Medical and build custom Claude Code workflows that make the day-to-day faster.</p>
<p><a href="#">See selected projects →</a></p>
</div></div>
<div class="stage"><div class="preview">
<h3>Village Medical — patient scheduling redesign</h3>
<div class="case-meta">
<span>Software Engineer</span><span>2024</span><span>React · TypeScript</span>
</div>
<p>Rebuilt the patient appointment scheduling app from a legacy Salesforce flow into a self-contained React surface used across clinics.</p>
<p><a href="#">Read the case study →</a></p>
</div></div>
<div class="stage"><div class="preview">
<div class="muted" style="font-family: ui-monospace, monospace; font-size: 11px; letter-spacing: 0.08em; text-transform: uppercase; margin-bottom: 12px;">timeline</div>
<div class="chrono">
<div><span class="y">2024 now</span>Village Medical · Software Engineer</div>
<div><span class="y">2022 2024</span>Village Medical · Salesforce Admin</div>
<div><span class="y">2019 2022</span>Gila River · Help Desk / IT</div>
</div>
<hr>
<p><a href="#">Download CV (PDF)</a></p>
</div></div>
<div class="stage"><div class="preview">
<div class="code">
<span class="c">// custom Claude Code slash command</span>
<span class="k">export default</span> {
name: <span class="k">'review'</span>,
run: <span class="k">async</span> (ctx) =&gt; {
<span class="k">await</span> ctx.runDiffReview()
}
}
</div>
</div></div>
</div>
</body>
</html>
+295
View File
@@ -0,0 +1,295 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Portfolio Wireframe — Angel Mankel</title>
<style>
html, body { margin: 0; padding: 0; background: #fff; color: #000; font-family: ui-sans-serif, system-ui, sans-serif; }
body { padding: 40px 20px 120px; }
.page-meta { max-width: 1100px; margin: 0 auto 24px; font-size: 13px; color: #555; }
.page-meta h1 { font-size: 18px; margin: 0 0 4px; color: #000; }
.frame { max-width: 1100px; margin: 0 auto 80px; border: 2px solid #000; }
.frame-label { font-family: ui-monospace, monospace; font-size: 12px; background: #000; color: #fff; padding: 6px 10px; }
.frame-body { padding: 16px; display: flex; flex-direction: column; gap: 12px; }
.box { border: 1px dashed #333; padding: 14px; font-size: 13px; line-height: 1.4; }
.box .tag { font-family: ui-monospace, monospace; font-size: 11px; color: #555; display: block; margin-bottom: 4px; text-transform: uppercase; letter-spacing: 0.04em; }
.row { display: flex; gap: 12px; }
.row > .box { flex: 1; }
.row.three > .box { flex: 1 1 0; }
.nav { display: flex; justify-content: space-between; align-items: center; }
.nav .links { display: flex; gap: 18px; font-family: ui-monospace, monospace; font-size: 12px; }
.tall { min-height: 140px; }
.taller { min-height: 220px; }
.small { font-size: 12px; color: #555; }
hr.divider { border: 0; border-top: 1px solid #ccc; margin: 60px 0; }
.legend { max-width: 1100px; margin: 0 auto 40px; font-size: 12px; color: #555; padding: 12px; border: 1px dashed #999; }
.legend code { background: #eee; padding: 1px 4px; }
</style>
</head>
<body>
<div class="legend">
<strong>Wireframe legend.</strong> Solid black border = page viewport. Dashed border = a content region with a label.
No colors, no images, no real type. Purpose: agree on layout structure and flow before touching CSS.
Routes shown: <code>/</code>, <code>/projects</code>, <code>/projects/[slug]</code>, <code>/about</code>, <code>/uses</code>.
</div>
<!-- ============================================================ -->
<div class="page-meta">
<h1>Route: /</h1>
<div>Landing. Goal: in 60-120s, communicate who Angel is, what he ships, how to contact.</div>
</div>
<div class="frame">
<div class="frame-label">VIEWPORT — /</div>
<div class="frame-body">
<div class="box nav">
<div><span class="tag">brand</span>Angel Mankel</div>
<div class="links">
<span>projects</span><span>about</span><span>uses</span><span>email</span>
</div>
</div>
<div class="box taller">
<span class="tag">hero — text only, no image</span>
Large name or wordmark. One-line positioning underneath: "Frontend engineer with deep AI-tooling fluency — ships production React and builds custom Claude Code workflows."
Below that, a secondary line linking to most recent case study or "Currently at Village Medical." No CTA buttons.
</div>
<div class="box">
<span class="tag">section heading</span>
"Selected projects" — small caps or monospace label. Single line.
</div>
<div class="row three">
<div class="box tall">
<span class="tag">case study card 1</span>
Title · one-line summary · year · outcome metric.
Whole card is clickable → /projects/[slug].
</div>
<div class="box tall">
<span class="tag">case study card 2</span>
Same shape as card 1. Three cards total, sometimes four.
</div>
<div class="box tall">
<span class="tag">case study card 3</span>
Same shape.
</div>
</div>
<div class="box">
<span class="tag">contact strip</span>
Email · LinkedIn · GitHub. Plain text links, no icons-only treatment. Maybe a one-line "Open to remote-US roles."
</div>
<div class="box small nav">
<div><span class="tag">footer</span>© 2026 Angel Mankel</div>
<div>Self-hosted · Traefik · Next.js</div>
</div>
</div>
</div>
<!-- ============================================================ -->
<div class="page-meta">
<h1>Route: /projects</h1>
<div>Case study index. Same cards as the landing, but full list. Optional filter (year or tag).</div>
</div>
<div class="frame">
<div class="frame-label">VIEWPORT — /projects</div>
<div class="frame-body">
<div class="box nav">
<div><span class="tag">brand</span>Angel Mankel</div>
<div class="links"><span>projects</span><span>about</span><span>uses</span><span>email</span></div>
</div>
<div class="box">
<span class="tag">page heading</span>
"Projects" — single word. Optional one-line intro: "Selected projects, written as postmortems."
</div>
<div class="box">
<span class="tag">case study row 1</span>
Title · year · one-line summary · key metric. Full-width row, not a card grid (denser, more readable).
</div>
<div class="box">
<span class="tag">case study row 2</span>
Same shape.
</div>
<div class="box">
<span class="tag">case study row 3</span>
Same shape.
</div>
<div class="box">
<span class="tag">case study row 4 (optional)</span>
Same shape. Skip if it dilutes.
</div>
<div class="box small nav">
<div><span class="tag">footer</span>© 2026 Angel Mankel</div>
<div>Self-hosted · Traefik · Next.js</div>
</div>
</div>
</div>
<!-- ============================================================ -->
<div class="page-meta">
<h1>Route: /projects/[slug]</h1>
<div>Individual case study. Postmortem format: context · decisions · outcome · what I'd do differently.</div>
</div>
<div class="frame">
<div class="frame-label">VIEWPORT — /projects/[slug]</div>
<div class="frame-body">
<div class="box nav">
<div><span class="tag">brand</span>Angel Mankel</div>
<div class="links"><span>projects</span><span>about</span><span>uses</span><span>email</span></div>
</div>
<div class="box">
<span class="tag">case study header</span>
Project name (large). Below: role · year · stack · one-line outcome. No hero image.
</div>
<div class="row">
<div class="box" style="flex: 0 0 200px;">
<span class="tag">sidebar (desktop only)</span>
Sticky table of contents: Context · Decisions · Outcome · Retrospective. Collapses above the body on mobile.
</div>
<div class="box taller" style="flex: 1;">
<span class="tag">long-form body (MDX)</span>
Section: <em>Context</em> — the constraint, 2-3 sentences.<br>
Section: <em>Decisions</em> — 3-5 specific calls with rejected alternatives.<br>
Section: <em>Outcome</em> — measurable result, honest when not.<br>
Section: <em>What I'd do differently</em> — one paragraph.<br>
Inline: code blocks (shiki), occasional pull-quote, optional simple diagram. No carousels.
</div>
</div>
<div class="box">
<span class="tag">next/prev case study</span>
Two links: ← previous case study · next case study →. Keeps the reader in the work funnel.
</div>
<div class="box small nav">
<div><span class="tag">footer</span>© 2026 Angel Mankel</div>
<div>Self-hosted · Traefik · Next.js</div>
</div>
</div>
</div>
<!-- ============================================================ -->
<div class="page-meta">
<h1>Route: /about</h1>
<div>Background arc. Who Angel is, what he's looking for. Long-form, first person.</div>
</div>
<div class="frame">
<div class="frame-label">VIEWPORT — /about</div>
<div class="frame-body">
<div class="box nav">
<div><span class="tag">brand</span>Angel Mankel</div>
<div class="links"><span>projects</span><span>about</span><span>uses</span><span>email</span></div>
</div>
<div class="box">
<span class="tag">page heading</span>
"About" — single word.
</div>
<div class="box tall">
<span class="tag">narrative paragraph 1 — arc</span>
Healthcare IT → Salesforce admin → SWE at Village Medical. 3-5 sentences, first person, active voice.
</div>
<div class="box tall">
<span class="tag">narrative paragraph 2 — current work + AI wedge</span>
What Angel does day-to-day. React + TS leadership. Heavy Claude Code use. The "frontend engineer who actually uses AI to ship" framing.
</div>
<div class="box">
<span class="tag">narrative paragraph 3 — what I'm looking for</span>
One paragraph. Remote US, mid-level, AI-native or product-engineering. Names of companies he'd love to work with (optional but bold).
</div>
<div class="box">
<span class="tag">chronological strip</span>
Three or four rows, plain text. Each row: year-range · company · role. No bullets, no descriptions — the case studies and narrative carry the detail. Example:<br>
2024present · Village Medical · Software Engineer<br>
20222024 · Village Medical · Salesforce Admin<br>
20192022 · Gila River · Help Desk / IT
</div>
<div class="box">
<span class="tag">download CV</span>
Single line: "Download CV (PDF)" link. Points at the PDF generated by career-ops. No fancy treatment.
</div>
<div class="box">
<span class="tag">contact strip</span>
Email · LinkedIn · GitHub. Same as landing.
</div>
<div class="box small nav">
<div><span class="tag">footer</span>© 2026 Angel Mankel</div>
<div>Self-hosted · Traefik · Next.js</div>
</div>
</div>
</div>
<!-- ============================================================ -->
<div class="page-meta">
<h1>Route: /uses (optional)</h1>
<div>Tools, editor setup, Claude Code workflow. High-signal page for AI-native hiring managers.</div>
</div>
<div class="frame">
<div class="frame-label">VIEWPORT — /uses</div>
<div class="frame-body">
<div class="box nav">
<div><span class="tag">brand</span>Angel Mankel</div>
<div class="links"><span>projects</span><span>about</span><span>uses</span><span>email</span></div>
</div>
<div class="box">
<span class="tag">page heading</span>
"Uses" — single word. One-line intro: "What I reach for daily."
</div>
<div class="row">
<div class="box tall">
<span class="tag">section: hardware</span>
Plain list. Machine, monitors, keyboard. One line each.
</div>
<div class="box tall">
<span class="tag">section: editor &amp; shell</span>
VS Code config highlights, terminal, font, theme.
</div>
</div>
<div class="row">
<div class="box tall">
<span class="tag">section: AI workflow</span>
Claude Code setup. Custom slash commands. MCP servers. One paragraph per workflow with the time saved.
This is the signal-dense section — give it the most space.
</div>
<div class="box tall">
<span class="tag">section: self-hosting</span>
Traefik, the box, whatever else runs on it. One-liners. This is where "self-hosted" lives without becoming the lede.
</div>
</div>
<div class="box small nav">
<div><span class="tag">footer</span>© 2026 Angel Mankel</div>
<div>Self-hosted · Traefik · Next.js</div>
</div>
</div>
</div>
</body>
</html>