Portfolio — Two-column CV
A recruiter-friendly two-column resume with a dark sidebar holding avatar, contact details, animated skill bars, language proficiency dots and links, paired with a spacious right column for summary, a connected experience timeline, education cards and project tiles. A floating toolbar swaps five accent themes, toggles comfortable or compact density and prints to clean PDF, with print CSS preserving the two columns on paper.
MCP
Code
/* ============================================================
Maya Okafor — Two-column CV
Neutral white/ink base + one switchable accent.
============================================================ */
:root {
/* Accent (overridden by [data-accent] on <body>) */
--accent: #5b5bd6;
--accent-strong: #4747b8;
--accent-soft: #ececfb;
--accent-tint: #c9c9f5;
/* Neutral base */
--ink: #16181d;
--ink-2: #3b3f48;
--muted: #6b7280;
--line: #e6e8ec;
--paper: #ffffff;
--bg: #eef0f4;
/* Sidebar ink (dark column) */
--side-ink: #f5f6f8;
--side-muted: #b8bcc6;
--side-line: rgba(255, 255, 255, .14);
/* Density (overridden by [data-density]) */
--gap-block: 26px;
--gap-point: 6px;
--lh: 1.5;
--radius: 14px;
--shadow: 0 18px 50px -22px rgba(17, 20, 30, .35), 0 2px 8px -3px rgba(17, 20, 30, .15);
--font: "Inter", system-ui, -apple-system, Segoe UI, Roboto, sans-serif;
--serif: "Newsreader", Georgia, "Times New Roman", serif;
}
/* ---- Accent palettes ---- */
body[data-accent="indigo"] { --accent:#5b5bd6; --accent-strong:#4747b8; --accent-soft:#ececfb; --accent-tint:#c9c9f5; }
body[data-accent="emerald"] { --accent:#0f9d76; --accent-strong:#0b7d5e; --accent-soft:#e1f5ee; --accent-tint:#abe4d2; }
body[data-accent="rose"] { --accent:#e0427f; --accent-strong:#bf2e67; --accent-soft:#fce4ee; --accent-tint:#f6b8d2; }
body[data-accent="amber"] { --accent:#d9820a; --accent-strong:#b56807; --accent-soft:#fcefda; --accent-tint:#f3d29a; }
body[data-accent="slate"] { --accent:#475569; --accent-strong:#334155; --accent-soft:#e8ecf1; --accent-tint:#bcc6d3; }
/* ---- Density: compact ---- */
body[data-density="compact"] {
--gap-block: 16px;
--gap-point: 3px;
--lh: 1.42;
}
/* ---- Reset ---- */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; }
html { -webkit-text-size-adjust: 100%; }
body {
font-family: var(--font);
line-height: var(--lh);
color: var(--ink);
background:
radial-gradient(1100px 600px at 80% -10%, var(--accent-soft), transparent 60%),
var(--bg);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
padding: clamp(16px, 4vw, 56px) 16px 64px;
min-height: 100vh;
}
a { color: inherit; text-decoration: none; }
:focus-visible {
outline: 2.5px solid var(--accent);
outline-offset: 2px;
border-radius: 4px;
}
/* ============================================================
Toolbar
============================================================ */
.toolbar {
max-width: 880px;
margin: 0 auto 22px;
display: flex;
flex-wrap: wrap;
gap: 14px 20px;
align-items: center;
justify-content: space-between;
background: rgba(255, 255, 255, .82);
backdrop-filter: blur(10px);
border: 1px solid rgba(255, 255, 255, .7);
box-shadow: 0 10px 30px -16px rgba(17, 20, 30, .4);
border-radius: 999px;
padding: 10px 14px;
}
.toolbar__group { display: flex; align-items: center; gap: 12px; }
.toolbar__label {
font-size: 12px; font-weight: 600; letter-spacing: .04em;
text-transform: uppercase; color: var(--muted);
}
.swatches { display: flex; gap: 8px; }
.swatch {
width: 24px; height: 24px; border-radius: 50%;
background: var(--sw);
border: 2px solid #fff;
box-shadow: 0 0 0 1px var(--line);
cursor: pointer; padding: 0;
transition: transform .15s ease, box-shadow .15s ease;
}
.swatch:hover { transform: translateY(-1px) scale(1.06); }
.swatch[aria-checked="true"] {
box-shadow: 0 0 0 2px #fff, 0 0 0 4px var(--sw);
}
.btn {
display: inline-flex; align-items: center; gap: 7px;
font: inherit; font-size: 13.5px; font-weight: 600;
color: var(--ink-2);
background: #fff;
border: 1px solid var(--line);
border-radius: 999px;
padding: 8px 15px;
cursor: pointer;
transition: border-color .15s ease, color .15s ease, transform .12s ease, background .15s ease;
}
.btn:hover { border-color: var(--accent); color: var(--accent-strong); transform: translateY(-1px); }
.btn:active { transform: translateY(0); }
.btn__icon { font-size: 15px; line-height: 1; }
.btn--primary {
background: var(--accent); color: #fff; border-color: transparent;
}
.btn--primary:hover { background: var(--accent-strong); color: #fff; }
.btn[aria-pressed="true"] {
background: var(--accent-soft); color: var(--accent-strong); border-color: var(--accent-tint);
}
/* ============================================================
Page (the printable sheet)
============================================================ */
.page {
max-width: 880px;
margin: 0 auto;
background: var(--paper);
border-radius: var(--radius);
box-shadow: var(--shadow);
overflow: hidden;
display: grid;
grid-template-columns: 290px 1fr;
}
/* ============================================================
Sidebar (dark column)
============================================================ */
.sidebar {
background:
linear-gradient(180deg, var(--accent-strong) 0%, var(--ink) 78%);
color: var(--side-ink);
padding: 34px 26px 38px;
}
.avatar {
position: relative;
width: 112px; height: 112px;
margin: 0 auto 18px;
border-radius: 50%;
box-shadow: 0 0 0 4px rgba(255, 255, 255, .14), 0 14px 30px -12px rgba(0, 0, 0, .6);
}
.avatar svg { width: 100%; height: 100%; display: block; border-radius: 50%; }
.avatar__initials {
position: absolute; inset: auto 0 8px; text-align: center;
font-weight: 800; font-size: 13px; letter-spacing: .14em;
color: #fff; opacity: 0;
}
.name {
font-size: clamp(28px, 6vw, 34px);
font-weight: 800;
line-height: 1.04;
letter-spacing: -.02em;
text-align: center;
}
.role {
text-align: center;
color: var(--side-muted);
font-weight: 500;
font-size: 13.5px;
letter-spacing: .02em;
margin-top: 6px;
padding-bottom: 22px;
border-bottom: 1px solid var(--side-line);
}
.side-block { padding: 20px 0; border-bottom: 1px solid var(--side-line); }
.side-block--last { border-bottom: 0; padding-bottom: 0; }
.side-h {
font-size: 11px; font-weight: 700; letter-spacing: .16em;
text-transform: uppercase;
color: var(--accent-tint);
margin-bottom: 13px;
}
.contact-list, .links { list-style: none; display: grid; gap: 9px; }
.contact-list li, .links li {
display: flex; align-items: center; gap: 10px;
font-size: 13px; color: var(--side-ink);
word-break: break-word;
}
.ci {
flex: 0 0 22px; width: 22px; height: 22px;
display: inline-grid; place-items: center;
font-size: 11px; font-weight: 700;
border-radius: 6px;
background: rgba(255, 255, 255, .1);
color: var(--accent-tint);
}
.contact-list a:hover, .links a:hover { color: var(--accent-tint); text-decoration: underline; text-underline-offset: 2px; }
.links li a { display: flex; align-items: center; gap: 10px; width: 100%; }
/* Skills */
.skills { list-style: none; display: grid; gap: 12px; }
.skill-row {
display: flex; justify-content: space-between; align-items: baseline;
font-size: 12.5px; margin-bottom: 5px;
}
.skill-num { color: var(--side-muted); font-size: 11px; font-variant-numeric: tabular-nums; }
.bar {
height: 6px; border-radius: 99px;
background: rgba(255, 255, 255, .12);
overflow: hidden;
}
.bar span {
display: block; height: 100%;
width: var(--lvl);
border-radius: 99px;
background: linear-gradient(90deg, var(--accent-tint), #fff);
transform-origin: left;
animation: grow .9s cubic-bezier(.2, .7, .2, 1) both;
}
@keyframes grow { from { transform: scaleX(0); } to { transform: scaleX(1); } }
/* Languages */
.langs { list-style: none; display: grid; gap: 10px; }
.langs li { display: flex; justify-content: space-between; align-items: center; font-size: 13px; }
.dots { display: inline-flex; gap: 4px; }
.dots i {
width: 8px; height: 8px; border-radius: 50%;
background: rgba(255, 255, 255, .18);
display: inline-block;
}
.dots i.on { background: var(--accent-tint); }
/* ============================================================
Main column
============================================================ */
.main { padding: 38px 40px 30px; min-width: 0; }
.masthead { padding-bottom: 22px; margin-bottom: var(--gap-block); border-bottom: 2px solid var(--accent-soft); }
.kicker {
font-size: 11px; font-weight: 700; letter-spacing: .16em;
text-transform: uppercase; color: var(--accent-strong);
}
.head-name {
font-family: var(--serif);
font-size: clamp(30px, 6vw, 42px);
font-weight: 600;
letter-spacing: -.01em;
line-height: 1.05;
margin: 6px 0 10px;
}
.tagline { color: var(--ink-2); font-size: 14.5px; max-width: 46ch; }
.block { margin-bottom: var(--gap-block); }
.block:last-of-type { margin-bottom: 18px; }
.main-h {
display: flex; align-items: center; gap: 10px;
font-size: 13px; font-weight: 700;
letter-spacing: .12em; text-transform: uppercase;
color: var(--ink);
margin-bottom: 14px;
}
.main-h__bullet {
width: 18px; height: 4px; border-radius: 99px;
background: var(--accent);
flex: 0 0 auto;
}
.summary { color: var(--ink-2); font-size: 14.5px; }
/* Experience timeline */
.timeline { list-style: none; display: grid; gap: var(--gap-block); }
.t-item {
position: relative;
padding-left: 22px;
}
.t-item::before {
content: ""; position: absolute; left: 4px; top: 7px;
width: 9px; height: 9px; border-radius: 50%;
background: var(--accent);
box-shadow: 0 0 0 4px var(--accent-soft);
}
.t-item::after {
content: ""; position: absolute; left: 8px; top: 20px; bottom: -22px;
width: 1.5px; background: var(--line);
}
.timeline .t-item:last-child::after { display: none; }
.t-head {
display: flex; flex-wrap: wrap; align-items: baseline;
justify-content: space-between; gap: 4px 14px;
}
.t-role { font-size: 16px; font-weight: 700; }
.t-dates {
font-size: 11.5px; font-weight: 600; color: var(--accent-strong);
background: var(--accent-soft); border-radius: 99px; padding: 2px 9px;
white-space: nowrap; font-variant-numeric: tabular-nums;
}
.t-org { color: var(--muted); font-size: 13px; font-weight: 500; margin: 2px 0 8px; }
.t-points { list-style: none; display: grid; gap: var(--gap-point); }
.t-points li {
position: relative; padding-left: 16px;
font-size: 13.5px; color: var(--ink-2);
}
.t-points li::before {
content: ""; position: absolute; left: 0; top: 8px;
width: 6px; height: 6px; border-radius: 1px;
background: var(--accent-tint);
transform: rotate(45deg);
}
/* Education */
.edu-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.edu {
border: 1px solid var(--line); border-radius: 10px;
padding: 14px 16px;
background: linear-gradient(180deg, #fff, var(--accent-soft) 320%);
}
.edu-deg { font-size: 14.5px; font-weight: 700; }
.edu-school { font-size: 12.5px; color: var(--accent-strong); font-weight: 600; margin: 3px 0 6px; }
.edu-note { font-size: 12.5px; color: var(--muted); }
/* Projects */
.projects { display: grid; grid-template-columns: 1fr 1fr; gap: 14px; }
.proj {
border: 1px solid var(--line); border-radius: 12px;
padding: 15px 16px; background: #fff;
transition: border-color .18s ease, box-shadow .18s ease, transform .18s ease;
}
.proj:hover {
border-color: var(--accent-tint);
box-shadow: 0 12px 26px -16px rgba(17, 20, 30, .4);
transform: translateY(-2px);
}
.proj-name { font-size: 14.5px; font-weight: 700; }
.proj-name::before { content: "↗"; color: var(--accent); margin-right: 6px; font-weight: 700; }
.proj-desc { font-size: 12.8px; color: var(--ink-2); margin: 5px 0 10px; }
.proj-tags { list-style: none; display: flex; flex-wrap: wrap; gap: 6px; }
.proj-tags li {
font-size: 10.5px; font-weight: 600; letter-spacing: .02em;
color: var(--accent-strong); background: var(--accent-soft);
border-radius: 99px; padding: 3px 9px;
}
.cv-footer {
display: flex; align-items: center; gap: 8px;
margin-top: 18px; padding-top: 16px;
border-top: 1px solid var(--line);
font-size: 12px; color: var(--muted);
}
.cv-footer__sep { color: var(--accent-tint); }
/* ============================================================
Responsive
============================================================ */
@media (max-width: 720px) {
.page { grid-template-columns: 1fr; }
.sidebar { padding: 30px 24px 30px; }
.main { padding: 28px 24px 26px; }
.edu-grid, .projects { grid-template-columns: 1fr; }
}
@media (max-width: 420px) {
.toolbar { border-radius: 18px; flex-direction: column; align-items: stretch; }
.toolbar__group { justify-content: space-between; }
.t-head { flex-direction: column; }
}
@media (prefers-reduced-motion: reduce) {
.bar span { animation: none; }
* { transition: none !important; }
}
/* ============================================================
Print — keep the two-column on paper
============================================================ */
@media print {
@page { margin: 12mm; }
body {
background: #fff;
padding: 0;
color: #000;
}
.no-print { display: none !important; }
.page {
max-width: none; box-shadow: none; border-radius: 0;
margin: 0;
grid-template-columns: 270px 1fr;
}
.sidebar {
background: var(--accent-strong) !important;
-webkit-print-color-adjust: exact;
print-color-adjust: exact;
}
.proj, .edu { break-inside: avoid; }
.t-item { break-inside: avoid; }
.bar span { animation: none; }
a { color: inherit; }
}/* ============================================================
Two-column CV — accent switcher, density toggle, print, toast
Vanilla JS, no dependencies.
============================================================ */
(function () {
"use strict";
var body = document.body;
var STORE = "okafor-cv";
/* ---------- toast helper ---------- */
var toastEl = null;
var toastTimer = null;
function toast(msg) {
if (!toastEl) {
toastEl = document.createElement("div");
toastEl.className = "toast no-print";
toastEl.setAttribute("role", "status");
toastEl.setAttribute("aria-live", "polite");
Object.assign(toastEl.style, {
position: "fixed",
left: "50%",
bottom: "24px",
transform: "translateX(-50%) translateY(16px)",
background: "var(--ink)",
color: "#fff",
font: "600 13.5px/1 var(--font)",
padding: "11px 18px",
borderRadius: "999px",
boxShadow: "0 14px 34px -12px rgba(0,0,0,.5)",
opacity: "0",
pointerEvents: "none",
transition: "opacity .22s ease, transform .22s ease",
zIndex: "9999",
maxWidth: "90vw",
textAlign: "center"
});
document.body.appendChild(toastEl);
}
toastEl.textContent = msg;
requestAnimationFrame(function () {
toastEl.style.opacity = "1";
toastEl.style.transform = "translateX(-50%) translateY(0)";
});
clearTimeout(toastTimer);
toastTimer = setTimeout(function () {
toastEl.style.opacity = "0";
toastEl.style.transform = "translateX(-50%) translateY(16px)";
}, 1900);
}
/* ---------- persistence ---------- */
function load() {
try { return JSON.parse(localStorage.getItem(STORE)) || {}; }
catch (e) { return {}; }
}
function save(state) {
try { localStorage.setItem(STORE, JSON.stringify(state)); }
catch (e) { /* ignore */ }
}
var state = load();
/* ---------- accent switcher ---------- */
var swatches = Array.prototype.slice.call(document.querySelectorAll(".swatch"));
var accentNames = {
indigo: "Indigo", emerald: "Emerald", rose: "Rose",
amber: "Amber", slate: "Slate"
};
function setAccent(name, announce) {
if (!accentNames[name]) name = "indigo";
body.setAttribute("data-accent", name);
swatches.forEach(function (s) {
var on = s.getAttribute("data-accent") === name;
s.setAttribute("aria-checked", on ? "true" : "false");
});
state.accent = name;
save(state);
if (announce) toast(accentNames[name] + " accent applied");
}
swatches.forEach(function (s) {
s.addEventListener("click", function () {
setAccent(s.getAttribute("data-accent"), true);
});
});
// Roving keyboard support inside the radiogroup
var group = document.querySelector(".swatches");
if (group) {
group.addEventListener("keydown", function (e) {
var idx = swatches.indexOf(document.activeElement);
if (idx === -1) return;
var next = null;
if (e.key === "ArrowRight" || e.key === "ArrowDown") next = (idx + 1) % swatches.length;
else if (e.key === "ArrowLeft" || e.key === "ArrowUp") next = (idx - 1 + swatches.length) % swatches.length;
if (next !== null) {
e.preventDefault();
swatches[next].focus();
setAccent(swatches[next].getAttribute("data-accent"), true);
}
});
}
/* ---------- density toggle ---------- */
var densityBtn = document.getElementById("density-toggle");
var densityText = document.getElementById("density-text");
function setDensity(mode, announce) {
var compact = mode === "compact";
body.setAttribute("data-density", compact ? "compact" : "comfortable");
densityBtn.setAttribute("aria-pressed", compact ? "true" : "false");
// Button offers the OTHER mode as its action label
densityText.textContent = compact ? "Comfortable" : "Compact";
state.density = compact ? "compact" : "comfortable";
save(state);
if (announce) toast((compact ? "Compact" : "Comfortable") + " density");
}
densityBtn.addEventListener("click", function () {
var now = body.getAttribute("data-density");
setDensity(now === "compact" ? "comfortable" : "compact", true);
});
/* ---------- print ---------- */
var printBtn = document.getElementById("print-btn");
printBtn.addEventListener("click", function () {
toast("Opening print dialog…");
setTimeout(function () { window.print(); }, 120);
});
/* ---------- restore saved prefs ---------- */
setAccent(state.accent || body.getAttribute("data-accent") || "indigo", false);
setDensity(state.density || body.getAttribute("data-density") || "comfortable", false);
/* ---------- friendly: copy email on click of mailto label area ---------- */
var mailLink = document.querySelector('a[href^="mailto:"]');
if (mailLink && navigator.clipboard) {
mailLink.addEventListener("click", function (e) {
var email = mailLink.getAttribute("href").replace("mailto:", "");
// Let the mailto fire, but also copy as a convenience.
navigator.clipboard.writeText(email).then(function () {
toast("Email copied: " + email);
}).catch(function () { /* ignore */ });
});
}
})();<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>Maya Okafor — Product Designer · CV</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&family=Newsreader:ital,opsz,wght@0,6..72,500;0,6..72,600;1,6..72,500&display=swap" rel="stylesheet" />
<link rel="stylesheet" href="style.css" />
</head>
<body data-accent="indigo" data-density="comfortable">
<!-- Floating control bar (hidden in print) -->
<div class="toolbar no-print" role="region" aria-label="CV controls">
<div class="toolbar__group" role="group" aria-label="Accent theme">
<span class="toolbar__label" id="accent-label">Accent</span>
<div class="swatches" role="radiogroup" aria-labelledby="accent-label">
<button class="swatch" data-accent="indigo" role="radio" aria-checked="true" aria-label="Indigo accent" style="--sw:#5b5bd6"></button>
<button class="swatch" data-accent="emerald" role="radio" aria-checked="false" aria-label="Emerald accent" style="--sw:#0f9d76"></button>
<button class="swatch" data-accent="rose" role="radio" aria-checked="false" aria-label="Rose accent" style="--sw:#e0427f"></button>
<button class="swatch" data-accent="amber" role="radio" aria-checked="false" aria-label="Amber accent" style="--sw:#d9820a"></button>
<button class="swatch" data-accent="slate" role="radio" aria-checked="false" aria-label="Slate accent" style="--sw:#475569"></button>
</div>
</div>
<div class="toolbar__group">
<button class="btn" id="density-toggle" type="button" aria-pressed="false">
<span class="btn__icon" aria-hidden="true">↕</span>
<span id="density-text">Compact</span>
</button>
<button class="btn btn--primary" id="print-btn" type="button">
<span class="btn__icon" aria-hidden="true">⎙</span>
Print / PDF
</button>
</div>
</div>
<main class="page" id="cv">
<!-- ===================== LEFT SIDEBAR ===================== -->
<aside class="sidebar" aria-label="Contact and skills">
<div class="avatar" role="img" aria-label="Portrait of Maya Okafor">
<svg viewBox="0 0 120 120" aria-hidden="true">
<defs>
<clipPath id="circ"><circle cx="60" cy="60" r="60" /></clipPath>
</defs>
<g clip-path="url(#circ)">
<rect width="120" height="120" fill="var(--accent-soft)" />
<circle cx="60" cy="48" r="26" fill="var(--accent)" />
<path d="M14 120c4-30 24-44 46-44s42 14 46 44z" fill="var(--accent)" />
<circle cx="60" cy="46" r="20" fill="var(--accent-tint)" opacity=".55" />
</g>
</svg>
<span class="avatar__initials" aria-hidden="true">MO</span>
</div>
<h1 class="name">Maya<br />Okafor</h1>
<p class="role">Senior Product Designer</p>
<section class="side-block" aria-labelledby="sb-contact">
<h2 class="side-h" id="sb-contact">Contact</h2>
<ul class="contact-list">
<li><span class="ci" aria-hidden="true">✉</span><a href="mailto:[email protected]">[email protected]</a></li>
<li><span class="ci" aria-hidden="true">☎</span><a href="tel:+15125550148">+1 (512) 555-0148</a></li>
<li><span class="ci" aria-hidden="true">⌖</span><span>Austin, TX · Remote-first</span></li>
<li><span class="ci" aria-hidden="true">◉</span><a href="https://example.com" target="_blank" rel="noopener">okafor.design</a></li>
</ul>
</section>
<section class="side-block" aria-labelledby="sb-skills">
<h2 class="side-h" id="sb-skills">Skills</h2>
<ul class="skills">
<li>
<div class="skill-row"><span>Product Strategy</span><span class="skill-num">95%</span></div>
<div class="bar"><span style="--lvl:95%"></span></div>
</li>
<li>
<div class="skill-row"><span>Interaction Design</span><span class="skill-num">90%</span></div>
<div class="bar"><span style="--lvl:90%"></span></div>
</li>
<li>
<div class="skill-row"><span>Design Systems</span><span class="skill-num">88%</span></div>
<div class="bar"><span style="--lvl:88%"></span></div>
</li>
<li>
<div class="skill-row"><span>Prototyping</span><span class="skill-num">82%</span></div>
<div class="bar"><span style="--lvl:82%"></span></div>
</li>
<li>
<div class="skill-row"><span>User Research</span><span class="skill-num">78%</span></div>
<div class="bar"><span style="--lvl:78%"></span></div>
</li>
<li>
<div class="skill-row"><span>Front-end (HTML/CSS)</span><span class="skill-num">70%</span></div>
<div class="bar"><span style="--lvl:70%"></span></div>
</li>
</ul>
</section>
<section class="side-block" aria-labelledby="sb-lang">
<h2 class="side-h" id="sb-lang">Languages</h2>
<ul class="langs">
<li><span>English</span><span class="dots" aria-label="Native"><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i></span></li>
<li><span>Yoruba</span><span class="dots" aria-label="Native"><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i><i class="on"></i></span></li>
<li><span>Spanish</span><span class="dots" aria-label="Professional"><i class="on"></i><i class="on"></i><i class="on"></i><i></i><i></i></span></li>
<li><span>French</span><span class="dots" aria-label="Conversational"><i class="on"></i><i class="on"></i><i></i><i></i><i></i></span></li>
</ul>
</section>
<section class="side-block side-block--last" aria-labelledby="sb-links">
<h2 class="side-h" id="sb-links">Find me</h2>
<ul class="links">
<li><a href="https://example.com/dribbble" target="_blank" rel="noopener"><span class="ci" aria-hidden="true">◐</span>Dribbble</a></li>
<li><a href="https://example.com/linkedin" target="_blank" rel="noopener"><span class="ci" aria-hidden="true">in</span>LinkedIn</a></li>
<li><a href="https://example.com/github" target="_blank" rel="noopener"><span class="ci" aria-hidden="true">{ }</span>GitHub</a></li>
<li><a href="https://example.com/read" target="_blank" rel="noopener"><span class="ci" aria-hidden="true">✎</span>Writing</a></li>
</ul>
</section>
</aside>
<!-- ===================== RIGHT MAIN COLUMN ===================== -->
<div class="main">
<header class="masthead">
<p class="kicker">Senior Product Designer · 9 years</p>
<h2 class="head-name">Maya Okafor</h2>
<p class="tagline">I design calm, decisive product experiences — from messy zero-to-one
discovery to scalable design systems used by hundreds of engineers.</p>
</header>
<section class="block" aria-labelledby="m-summary">
<h3 class="main-h" id="m-summary"><span class="main-h__bullet" aria-hidden="true"></span>Summary</h3>
<p class="summary">
Product designer with nine years shipping consumer and B2B software across fintech,
health, and developer tools. I pair sharp problem framing with a craftsperson's eye,
turning ambiguous goals into measurable outcomes. I lead by building — prototypes,
systems, and the shared language that lets teams move fast without drifting.
</p>
</section>
<section class="block" aria-labelledby="m-exp">
<h3 class="main-h" id="m-exp"><span class="main-h__bullet" aria-hidden="true"></span>Experience</h3>
<ol class="timeline">
<li class="t-item">
<div class="t-head">
<h4 class="t-role">Senior Product Designer</h4>
<span class="t-dates">2022 — Present</span>
</div>
<p class="t-org">Northwind Labs · Developer Platform</p>
<ul class="t-points">
<li>Owned end-to-end design for the deploy pipeline used by 40k+ developers; cut time-to-first-deploy by 38%.</li>
<li>Founded the cross-team design system, replacing 6 divergent UI kits with one tokenized library.</li>
<li>Mentored 3 designers and ran a weekly critique that lifted the team's quality bar.</li>
</ul>
</li>
<li class="t-item">
<div class="t-head">
<h4 class="t-role">Product Designer</h4>
<span class="t-dates">2019 — 2022</span>
</div>
<p class="t-org">Cedar & Bloom · Personal Finance</p>
<ul class="t-points">
<li>Redesigned onboarding to a goal-first flow, raising activation from 41% to 63%.</li>
<li>Shipped accessible budgeting visualizations meeting WCAG AA across the app.</li>
<li>Partnered with research to run 30+ moderated sessions per quarter.</li>
</ul>
</li>
<li class="t-item">
<div class="t-head">
<h4 class="t-role">UX Designer</h4>
<span class="t-dates">2016 — 2019</span>
</div>
<p class="t-org">Meridian Health · Patient Apps</p>
<ul class="t-points">
<li>Designed a triage assistant adopted by 22 clinics, reducing call volume by 19%.</li>
<li>Built the first component library and contribution guidelines for the org.</li>
</ul>
</li>
</ol>
</section>
<section class="block" aria-labelledby="m-edu">
<h3 class="main-h" id="m-edu"><span class="main-h__bullet" aria-hidden="true"></span>Education</h3>
<div class="edu-grid">
<div class="edu">
<h4 class="edu-deg">B.F.A. Interaction Design</h4>
<p class="edu-school">Rhodes School of Design · 2012–2016</p>
<p class="edu-note">Honors. Thesis on calm interfaces for chronic-care patients.</p>
</div>
<div class="edu">
<h4 class="edu-deg">Certificate, Front-end Engineering</h4>
<p class="edu-school">Atlas Online · 2018</p>
<p class="edu-note">Semantic HTML, CSS architecture, accessibility.</p>
</div>
</div>
</section>
<section class="block block--projects" aria-labelledby="m-proj">
<h3 class="main-h" id="m-proj"><span class="main-h__bullet" aria-hidden="true"></span>Selected Projects</h3>
<div class="projects">
<article class="proj">
<h4 class="proj-name">Atlas Design System</h4>
<p class="proj-desc">Tokenized component library & docs site adopted across 6 product teams.</p>
<ul class="proj-tags"><li>Systems</li><li>Tokens</li><li>Docs</li></ul>
</article>
<article class="proj">
<h4 class="proj-name">Deploy Flow Redesign</h4>
<p class="proj-desc">Reworked the deploy pipeline UI; first-deploy time down 38%.</p>
<ul class="proj-tags"><li>0→1</li><li>Research</li><li>Proto</li></ul>
</article>
<article class="proj">
<h4 class="proj-name">Goal-first Onboarding</h4>
<p class="proj-desc">Activation-driving budgeting flow; 41% → 63% activation.</p>
<ul class="proj-tags"><li>Fintech</li><li>Activation</li></ul>
</article>
<article class="proj">
<h4 class="proj-name">Triage Assistant</h4>
<p class="proj-desc">Patient self-triage tool live in 22 clinics; call volume −19%.</p>
<ul class="proj-tags"><li>Health</li><li>A11y</li></ul>
</article>
</div>
</section>
<footer class="cv-footer">
<span>References available on request</span>
<span class="cv-footer__sep" aria-hidden="true">·</span>
<span>Updated June 2026</span>
</footer>
</div>
</main>
<script src="script.js"></script>
</body>
</html>Two-column CV
A balanced, modern resume layout split into a dark left sidebar and a light right main column. The sidebar carries the identity — a CSS-drawn avatar, contact lines, animated proficiency bars, dot-rated languages, and social links — while the main column reads top to bottom: summary, a vertical experience timeline with date pills, education cards, and a grid of selected-project tiles.
A frosted floating toolbar drives the interactions. Five accent swatches re-tint the
whole page through CSS custom properties (indigo, emerald, rose, amber, slate), a
density toggle switches between comfortable and compact spacing for fitting more on a
page, and a print button opens the browser print dialog. Accent and density choices
persist in localStorage, the swatch group is keyboard-navigable with arrow keys, and
clicking the email copies it to the clipboard.
Dedicated print CSS keeps both columns side by side on paper, preserves the accent colors, and avoids breaking project and timeline blocks across pages — so the on-screen CV and the exported PDF stay in sync.
Illustrative portfolio — fictional person and projects.