feat: update app pages and layout

This commit is contained in:
2026-05-28 11:33:01 -07:00
parent 5c9891ecc5
commit 0448b00079
5 changed files with 211 additions and 49 deletions
+93 -2
View File
@@ -1,5 +1,11 @@
import Hero from "@/components/content/Hero";
import type { Metadata } from "next";
import { IconBrandLinkedinFilled, IconMailFilled } from "@tabler/icons-react";
import Hero from "@/components/content/Hero";
import SectionLabel from "@/components/layout/SectionLabel";
import AccentLink from "@/components/navigation/AccentLink";
import GiteaIcon from "@/components/icons/GiteaIcon";
import Tooltip from "@/components/ui/Tooltip";
import { colors, education, timeline } from "@/constants";
export const metadata: Metadata = {
title: "About — Angel Mankel",
@@ -7,6 +13,91 @@ export const metadata: Metadata = {
export default function AboutPage() {
return (
<Hero label="About"/>
<div className="space-y-14">
<Hero label="About">
<div className="space-y-5 text-[19px] leading-[1.65]">
<p>
I came up through healthcare IT help desk, then Salesforce
administration, then software engineering. A path that taught me
to translate between operations, design, and engineering without
losing the thread.
</p>
<p>
These days I write React and TypeScript for production, lead
component-library work, and spend a lot of time in Claude Code
custom slash commands, MCP integrations, agent workflows. The
AI-tooling layer is reshaping how I work across the stack.
</p>
<p>
Based in Arizona, looking for remote-US roles where shipping
frontend product and building AI tooling around it are both
first-class. Bonus points for teams that take design seriously
and don&apos;t hand things off at every layer.
</p>
</div>
</Hero>
<section className="space-y-4">
<SectionLabel label="Education" />
<ul className="space-y-2">
{education.map((row) => (
<li key={row.span} className="flex gap-2 text-sm">
<span className="w-36 shrink-0 text-neutral-500">
{row.span}
</span>
<span className="text-neutral-200">{row.degree} · {row.location}</span>
</li>
))}
</ul>
</section>
<section className="space-y-4">
<SectionLabel label="Timeline" />
<ul className="space-y-2">
{timeline.map((row) => (
<li key={row.span} className="flex gap-2 text-sm">
<span className="w-36 shrink-0 text-neutral-500">
{row.span}
</span>
<span className="text-neutral-200">{row.role}</span>
</li>
))}
</ul>
</section>
<AccentLink link="/cv.pdf" label="Download CV (PDF)" />
<nav aria-label="Contact" className="flex gap-5 text-neutral-300">
<Tooltip text="Email">
<a
href="mailto:angelmankel@gmail.com"
aria-label="Email"
className={`hover:text-neutral-200 rounded-md hover:bg-[${colors.accent}] p-1 transition-colors duration-200`}
>
<IconMailFilled size={32} />
</a>
</Tooltip>
<Tooltip text="LinkedIn">
<a
href="https://www.linkedin.com/in/angel-mankel-0616aa132/"
target="_blank"
rel="noreferrer"
aria-label="LinkedIn"
className={`hover:text-neutral-200 rounded-md hover:bg-[${colors.accent}] p-1 transition-colors duration-200`}
>
<IconBrandLinkedinFilled size={32} />
</a>
</Tooltip>
<Tooltip text="Gitea">
<a
href="#"
aria-label="Gitea"
className={`hover:text-neutral-200 rounded-md hover:bg-[${colors.accent}] p-1 transition-colors duration-200`}
>
<GiteaIcon size={32} />
</a>
</Tooltip>
</nav>
</div>
);
}
+3 -1
View File
@@ -4,6 +4,7 @@ import "./globals.css";
import Header from "@/components/layout/Header";
import Footer from "@/components/layout/Footer";
import Container from "@/components/layout/Container";
import Cursor from "@/components/ui/Cursor";
const inter = Inter({
variable: "--font-inter",
@@ -29,9 +30,10 @@ export default function RootLayout({
return (
<html
lang="en"
className={`${inter.variable} ${instrumentSerif.variable} h-full antialiased`}
className={`${inter.variable} ${instrumentSerif.variable} h-full antialiased scrollbar-track-transparent scrollbar-thumb-neutral-700`}
>
<body className="min-h-full flex flex-col font-sans">
{/* <Cursor /> */}
<Header />
<Container>{children}</Container>
<Footer />
+37 -43
View File
@@ -1,49 +1,22 @@
import Hero from "@/components/content/Hero";
import Testimonials from "@/components/content/Testimonials";
import RotatingWord from "@/components/content/RotatingWord";
import SectionLabel from "@/components/layout/SectionLabel";
import AccentLink from "@/components/navigation/AccentLink";
type Testimonial = {
name: string;
title: string;
avatar?: string;
quote: string;
};
const testimonialsData: Testimonial[] = [
{
name: "Sarah Chen",
title: "Senior Software Engineer · Patient Platforms",
quote:
"Working with Angel was the first time I saw someone treat Claude Code as a real engineering tool instead of a toy. Hed built half a workflow before the rest of us figured out it was possible.",
},
{
name: "Marcus Whitfield",
title: "Staff Frontend Engineer",
quote:
"He owned the component library end-to-end and ran the migration without breaking a single screen. Quiet shipper — you only notice his work when you go looking for it.",
},
{
name: "Priya Anand",
title: "Product Designer",
quote:
"Angel is the rare engineer who actually reads designs and asks questions when something feels off. Half my polish budget got returned to me on the projects he was on.",
},
{
name: "Daniel Okafor",
title: "Engineering Manager",
quote:
"Hes at his best when the problem doesnt fit cleanly into one stack. Id hand him an ambiguous brief and a week later hed come back with a working prototype and a plan.",
},
];
import ProjectCard from "@/components/content/ProjectCard";
import { testimonials, projects } from "@/constants";
export default function HomePage() {
return (
<div>
<Hero label="Angel Mankel">
<div className="space-y-5">
<div className="space-y-5 mb-4">
<p className="font-serif italic text-3xl leading-[1.3]">
Im a creator at heart.
I&apos;m{" "}
<RotatingWord
items={["a developer", "a creative", "a tinkerer"]}
/>
.
</p>
<p className="text-[19px] leading-[1.65]">
@@ -52,16 +25,37 @@ export default function HomePage() {
</p>
<p className="text-[19px] leading-[1.65]">
Im the kind of engineer who picks up whatever the problem needs and
keeps digging into the code, and into the people its meant for.
The throughline isnt a stack, its the curiosity.
I&apos;m the kind of engineer who picks up whatever the problem needs and
keeps digging into the code, and into the people it&apos;s meant for.
The throughline isn&apos;t a stack, it&apos;s the curiosity.
</p>
</div>
<div>
<AccentLink label="About Me" link="/about" />
</div>
</Hero>
<SectionLabel label="Selected Projects" />
<AccentLink label="See all projects" link="/projects" />
<SectionLabel label="What people say" />
<Testimonials items={testimonialsData} />
{/* Projects */}
<div className="mt-20">
<SectionLabel label="Selected Projects" />
{projects.slice(0,3).map((project, index) => (
<ProjectCard key={index} {...project} />
))}
<div className="mt-5">
<AccentLink label="See all projects" link="/projects" />
</div>
</div>
{/* Testimonials */}
<div className="mt-20">
<SectionLabel label="What people say" />
<div className="mt-5">
<Testimonials items={testimonials} />
</div>
</div>
</div>
);
}
+11 -1
View File
@@ -1,5 +1,7 @@
import Hero from "@/components/content/Hero";
import type { Metadata } from "next";
import ProjectCard from "@/components/content/ProjectCard";
import { projects } from "@/constants";
export const metadata: Metadata = {
title: "Work — Angel Mankel",
@@ -7,6 +9,14 @@ export const metadata: Metadata = {
export default function ProjectsPage() {
return (
<Hero label="Projects" subtitle="Selected work, written as postmortems." />
<>
<div className="mb-15">
<Hero label="Projects" subtitle="Selected work, written as postmortems." />
</div>
{projects.map((project, index) => (
<ProjectCard key={index} {...project} />
))}
</>
);
}
+67 -2
View File
@@ -1,12 +1,77 @@
import Hero from "@/components/content/Hero";
import type { Metadata } from "next";
import Hero from "@/components/content/Hero";
import SectionLabel from "@/components/layout/SectionLabel";
export const metadata: Metadata = {
title: "Uses — Angel Mankel",
};
type Section =
| { label: string; kind: "list"; items: string[] }
| { label: string; kind: "prose"; paragraphs: string[] };
const sections: Section[] = [
{
label: "Hardware",
kind: "list",
items: [
"Custom desktop — i9-12900H, 32GB RAM, Intel Iris Xe",
"Nobara Linux 43 · KDE Plasma 6 · Wayland",
"Headphones / keyboard / monitor — placeholder",
],
},
{
label: "Editor & Shell",
kind: "list",
items: [
"VS Code with a personal extension pack — placeholder",
"Bash / zsh — placeholder for shell",
"JetBrains Mono as the editor font",
"Theme — placeholder",
],
},
{
label: "AI Workflow",
kind: "prose",
paragraphs: [
"Claude Code is the daily driver — custom slash commands, MCP servers wired into my editor, and agent workflows that handle the repeat work so I can stay in the design problem.",
"Placeholder paragraph two — name a specific workflow and the time it saves.",
],
},
{
label: "Self-hosting",
kind: "list",
items: [
"Bare-metal home server, exposed to the internet through Traefik",
"This site lives on it — Next.js standalone build, no managed host",
"Other services — placeholder",
],
},
];
export default function UsesPage() {
return (
<Hero label="Uses" subtitle="Tools and technologies I use in my work."/>
<div className="space-y-14">
<Hero label="Uses" subtitle="What I reach for daily." />
{sections.map((section) => (
<section key={section.label} className="space-y-4">
<SectionLabel label={section.label} />
{section.kind === "list" ? (
<ul className="space-y-2 text-[15px] leading-[1.65] text-neutral-200">
{section.items.map((item) => (
<li key={item}>{item}</li>
))}
</ul>
) : (
<div className="space-y-4 text-[15px] leading-[1.65] text-neutral-200">
{section.paragraphs.map((p) => (
<p key={p}>{p}</p>
))}
</div>
)}
</section>
))}
</div>
);
}