2026-08-01 03:24:51 -03:00

413 lines
12 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div class="page">
<section class="card about">
<div class="left">
<div class="portrait">
<img src="@/assets/profile-avatar.jpg" alt="Brad Stein" />
</div>
<div class="contact">
<div class="name">Brad Stein</div>
<div class="role">{{ about.role }}</div>
<div class="role">{{ about.focusLine }}</div>
<div class="meta">US Citizen · Remote</div>
<div class="links">
<a href="https://www.linkedin.com/in/steinbradley/" target="_blank" rel="noopener noreferrer">LinkedIn</a>
<a href="https://scm.bstein.dev/bstein" target="_blank" rel="noopener noreferrer">Gitea</a>
<a href="https://metrics.bstein.dev" target="_blank" rel="noopener noreferrer">Metrics</a>
<a href="mailto:brad@bstein.dev">brad@bstein.dev</a>
</div>
</div>
</div>
<div class="right">
<h1>About Me</h1>
<div class="copy">
<p v-for="paragraph in about.summary.slice(0, 2)" :key="paragraph">{{ paragraph }}</p>
<p>
Public platform work is visible in the
<a href="https://scm.bstein.dev/bstein/titan-iac" target="_blank" rel="noopener noreferrer">Titan IaC repo</a>,
<a href="https://scm.bstein.dev/bstein" target="_blank" rel="noopener noreferrer">scm.bstein.dev</a> and
<a href="https://metrics.bstein.dev" target="_blank" rel="noopener noreferrer">metrics.bstein.dev</a>.
</p>
</div>
<div class="skill-groups" aria-label="Résumé skill summary">
<div v-for="group in about.skillGroups" :key="group.label" class="skill-group">
<h2>{{ group.label }}</h2>
<div class="highlights">
<div v-for="skill in group.items" :key="skill" class="pill mono">{{ skill }}</div>
</div>
</div>
</div>
</div>
</section>
<section class="card">
<div class="section-head">
<h2>Experience</h2>
<span class="pill mono">Summary</span>
</div>
<div class="timeline">
<div v-for="item in timeline" :key="item.id" class="entry">
<div class="dot"></div>
<div>
<div class="entry-title">{{ item.title }}</div>
<div class="entry-sub">
<a v-if="item.companyUrl" :href="item.companyUrl" target="_blank" rel="noopener noreferrer">
{{ item.company }}
</a>
<span v-else>{{ item.company }}</span>
<span> · {{ item.dates }}</span>
</div>
<ul>
<li v-for="point in item.points" :key="point">{{ point }}</li>
</ul>
</div>
</div>
</div>
<div class="divider"></div>
<p class="note">
Web version aligned to <span class="mono">Stein.Brad.Resume.2026.06.pdf</span>. Phone and street address are
intentionally omitted from the public site.
</p>
</section>
<section class="card">
<div class="section-head">
<h2>Titan Lab</h2>
<span class="pill mono">atlas platform</span>
</div>
<div class="copy">
<p>
Titan Lab is the live platform behind bstein.dev. The core is <span class="mono">Atlas</span>, a GitOps-managed
<span class="mono">k3s</span> cluster where services are reconciled by <span class="mono">Flux</span> and operated
with the same habits I use professionally: source of truth, quality gates, observability, identity, storage,
recovery paths, and documented handoff.
</p>
<p>
The platform runs identity, source control, CI/CD, container delivery, observability, storage, member services,
and experimental AI workloads. It is also where I build automation around bootstrap, recovery, service health,
and operator workflows instead of leaving them as manual notes.
</p>
<p>
<span class="mono">Oceanus</span> and <span class="mono">Tethys</span> are now part of Atlas capacity instead of separate public status surfaces.
The dedicated non-cluster hosts are the control-plane database node and the jumphost. <span class="mono">Cassandra</span>,
the MTG AI playtester, is deployed at
<a href="https://cassandra.bstein.dev/" target="_blank" rel="noopener noreferrer">cassandra.bstein.dev</a>.
</p>
</div>
</section>
<section class="card">
<div class="section-head">
<h2>Education</h2>
<span class="pill mono">UT Austin</span>
</div>
<div class="copy">
<p>
Studied Mechanical Engineering and Applied Math at the University of Texas at Austin, including Java, C++,
probability, statistics, complex analysis, numerical methods, number theory, and differential equations.
</p>
<p>
Participated in the Emerging Scholars honors calculus program and later served as an assistant for it.
</p>
</div>
</section>
</div>
</template>
<script setup>
import { computed } from "vue";
import { useRoute } from "vue-router";
import { homepageContentForMode, homepageModeFromRoute } from "../data/homepageContent";
const route = useRoute();
const content = computed(() => homepageContentForMode(homepageModeFromRoute(route)));
const about = computed(() => content.value.about);
const timeline = [
{
id: "titan-lab-architect",
title: "Kubernetes Cluster Development",
company: "Titan Lab",
companyUrl: "https://scm.bstein.dev/bstein/titan-iac",
dates: "Apr 2020 Present",
points: [
"Created and operate a local k3s cluster with metrics for home and self-hosted services.",
"Run personal SCM, CI/CD, password management, mail, cloud storage, movie streaming, video conferencing, AI chatbot, and cluster automation services.",
"Build automation around bootstrap, recovery, service health, operator workflows, identity, storage, and dashboards.",
],
},
{
id: "actalent-boeing-ptes",
title: "Software Development Engineer in Test",
company: "Boeing",
companyUrl: "https://www.boeing.com/",
dates: "Oct 2023 Oct 2025",
points: [
"Consulted through Actalent on a complex communications program at the intersection of test engineering, DevSecOps, and infrastructure automation.",
"Created system and end-to-end tests using Python and Selenium to validate microservice and web UI interactions.",
"Built TaskWatcher tooling for key capture/decryption and Docker Compose drift protection on dedicated hosts.",
"Created Lanterna to visualize a Flux-driven monorepo with Mermaid charts rerun after merged changes.",
"Created promotion-pipeline quality gates for a system test suite and microservice release flow.",
],
},
{
id: "tradehat-frontend",
title: "Frontend Engineer",
company: "TradeHat",
companyUrl: "https://www.tradehat.com/",
dates: "Mar 2020 Mar 2021",
points: [
"Worked as one of four engineers building the startup product from scratch.",
"Selected Vue.js and Quasar as the frontend foundation for multi-architecture support.",
"Helped build the alpha deployment infrastructure using redundant ThinkPads hosted at each engineer's home in Dallas.",
"Built reporting and dashboard pages in Vue with Tailwind CSS and FusionCharts.",
],
},
{
id: "ibm-sdet",
title: "Software Development Engineer in Test",
company: "IBM",
companyUrl: "https://www.ibm.com/cloud",
dates: "Nov 2018 May 2023",
points: [
"Authored and planned automated end-to-end and system tests for IBM Cloud systems in Python, Go, and Terraform.",
"Served as a consultant before accepting a full-time role in 2020; documented contributions and hosted feature demos and knowledge transfers.",
"Automated platform validation for a remote data center, including RHEL and SUSE functionality, licensing, repository availability, and performance.",
"Automated A100 and V100 GPU resource tests for CUDA functionality and data security in accelerated-computing environments.",
"Created a Zabbix health dashboard for Cloud APIs and planned key feature testing in Python.",
"Created Terraform and Go system tests for microservice interactions and platform scalability/autoscaling.",
],
},
{
id: "unifocus-survey-programmer",
title: "Lead Survey Programmer",
company: "UniFocus",
companyUrl: "https://www.unifocus.com/",
dates: "Aug 2014 Nov 2018",
points: [
"Transformed a configuration role into an automation role using Python and SQL for online surveys and reports.",
"Served as team lead, recruiting staff and mentoring junior engineers.",
"Converted Python automation scripts into a CLI tool and built a VBA-driven Excel workbook for business contacts.",
"Automated responsive design updates for web surveys with Python and added JavaScript/CSS mobile support.",
"Created a Python XML parser to restore survey data that could otherwise be lost.",
"Won UniFocus Excellence Award (2015) and Innovation Award (2016).",
],
},
];
</script>
<style scoped>
.page {
max-width: 1260px;
margin: 0 auto;
padding: 32px 22px 72px;
}
.about {
display: grid;
grid-template-columns: minmax(220px, 0.48fr) minmax(0, 2fr);
gap: 30px;
}
.portrait {
width: 120px;
height: 120px;
flex: 0 0 120px;
aspect-ratio: 1 / 1;
border-radius: 50%;
overflow: hidden;
border: 1px solid rgba(255, 255, 255, 0.12);
display: grid;
place-items: center;
background: linear-gradient(135deg, rgba(0, 229, 197, 0.5), rgba(127, 124, 255, 0.45));
}
.portrait img {
width: 100%;
height: 100%;
object-fit: cover;
}
.left {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 14px;
padding-top: 8px;
}
.contact .name {
font-weight: 800;
color: var(--text-strong);
}
.contact .role {
color: var(--text-muted);
max-width: 220px;
line-height: 1.35;
}
.contact .meta {
color: var(--text-muted);
font-size: 13px;
margin-top: 2px;
}
.badges {
display: flex;
gap: 8px;
flex-wrap: wrap;
margin-top: 10px;
}
.links {
display: flex;
gap: 10px;
flex-wrap: wrap;
margin-top: 8px;
}
.links a {
color: var(--accent-cyan);
text-decoration: none;
}
.links a:hover {
color: var(--accent-rose);
}
.right h1 {
margin: 0 0 8px;
}
.skill-groups {
display: grid;
gap: 0;
margin-top: 18px;
}
.skill-group {
display: grid;
grid-template-columns: minmax(130px, 160px) minmax(0, 1fr);
gap: 16px;
align-items: start;
padding: 11px 0;
border-top: 1px solid rgba(255, 255, 255, 0.08);
}
.skill-group h2 {
margin: 5px 0 0;
color: var(--text-strong);
font-size: 15px;
}
.section-head {
display: flex;
align-items: center;
justify-content: space-between;
margin-bottom: 10px;
}
.copy {
color: var(--text-muted);
}
.copy p {
margin: 0 0 10px;
line-height: 1.55;
}
.copy p:last-child {
margin-bottom: 0;
}
.highlights {
display: flex;
gap: 6px;
flex-wrap: wrap;
margin-top: 0;
}
.highlights .pill {
min-height: 30px;
padding: 5px 9px;
font-size: 12px;
}
.note {
color: var(--text-muted);
margin: 0;
}
.note a {
color: var(--text-muted);
text-decoration: none;
border-bottom: 1px dashed rgba(255, 255, 255, 0.18);
padding-bottom: 1px;
}
.note a:hover {
color: var(--accent-cyan);
border-bottom-color: rgba(0, 229, 197, 0.5);
}
.timeline {
display: grid;
gap: 12px;
margin-top: 8px;
}
.entry {
display: grid;
grid-template-columns: auto 1fr;
gap: 10px;
}
.dot {
width: 14px;
height: 14px;
border-radius: 50%;
border: 2px solid var(--accent-cyan);
margin-top: 6px;
}
.entry-title {
font-weight: 800;
}
.entry-sub {
color: var(--text-muted);
margin-bottom: 4px;
}
.entry-sub a {
color: var(--accent-cyan);
text-decoration: none;
}
.entry-sub a:hover {
color: var(--accent-rose);
}
ul {
margin: 0;
padding-left: 16px;
color: var(--text-muted);
}
@media (max-width: 820px) {
.about {
grid-template-columns: 1fr;
}
.left {
justify-content: flex-start;
}
.skill-group {
grid-template-columns: 1fr;
gap: 8px;
}
}
</style>