<!DOCTYPE html><html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Mark Soper - Product leader and software engineer - Data, cloud, AI infrastructure</title><meta name="description" content="Mark Soper — Product leader, engineer, and entrepreneur building at the intersection of data infrastructure and AI."><link rel="canonical" href="https://marksoper.me/"><!-- OpenGraph --><meta property="og:type" content="website"><meta property="og:title" content="Mark Soper - Product leader and software engineer - Data, cloud, AI infrastructure"><meta property="og:description" content="Mark Soper — Product leader, engineer, and entrepreneur building at the intersection of data infrastructure and AI."><meta property="og:url" content="https://marksoper.me/"><!-- Twitter --><meta name="twitter:card" content="summary_large_image"><meta name="twitter:site" content="@marksoper"><meta name="twitter:title" content="Mark Soper - Product leader and software engineer - Data, cloud, AI infrastructure"><meta name="twitter:description" content="Mark Soper — Product leader, engineer, and entrepreneur building at the intersection of data infrastructure and AI."><!-- Fonts (self-hosted, declared in global.css) --><link rel="preload" href="/fonts/inter-latin.woff2" as="font" type="font/woff2" crossorigin><!-- RSS --><link rel="alternate" type="application/rss+xml" title="Mark Soper's Blog" href="/rss.xml"><link rel="stylesheet" href="/_astro/_slug_.CY5a_eub.css"></head> <body class="min-h-screen flex flex-col"> <!-- Static background treatment --> <div class="bg-gradient" aria-hidden="true"></div> <main class="flex-1"> <section class="hero-section max-w-[var(--container-wide)] mx-auto px-[var(--spacing-page)] pt-[82px] w-full pb-8 sm:pb-12"> <div class="flex flex-col sm:flex-row gap-8 items-start"> <a href="/"> <img src="/img/mark_soper.png" alt="Mark Soper" class="photo-ring w-28 h-28 sm:w-36 sm:h-36 rounded-full object-cover shrink-0 ring-2 transition-all duration-300 hover:scale-105"> </a> <div class="flex-1">  <a href="/" class="no-underline"> <h1 class="text-2xl sm:text-3xl font-semibold mb-1">Mark Soper</h1> </a> <p class="text-lg text-[var(--color-text-secondary)] mb-2">
Builder of data, cloud, and AI infrastructure products
</p> <div class="mt-5"> <button id="contact-toggle" class="btn-contact inline-flex items-center gap-2 px-4 py-2 text-sm font-medium rounded-lg active:scale-95 transition-all duration-150 cursor-pointer"> <svg class="w-4 h-4" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M21.75 6.75v10.5a2.25 2.25 0 01-2.25 2.25h-15a2.25 2.25 0 01-2.25-2.25V6.75m19.5 0A2.25 2.25 0 0019.5 4.5h-15a2.25 2.25 0 00-2.25 2.25m19.5 0l-9.75 6.093L2.25 6.75"></path></svg>
Contact me
</button> </div> </div> <div class> <div class="flex items-center gap-4"> <a href="https://linkedin.com/in/marksoper" class="hover:scale-110 transition-all duration-150" target="_blank" rel="noopener" aria-label="LinkedIn"> <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"></path></svg> </a> <a href="https://github.com/marksoper" class="hover:scale-110 transition-all duration-150" target="_blank" rel="noopener" aria-label="GitHub"> <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"></path></svg> </a> <a href="https://x.com/marksoper" class="hover:scale-110 transition-all duration-150" target="_blank" rel="noopener" aria-label="X (Twitter)"> <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"></path></svg> </a> <div class="divider-line h-5 w-px"></div> <a href="/blog" class="blog-link text-lg transition-colors duration-150 font-medium">
Blog
</a> </div> </div> </div> <!-- Inline contact form (homepage only, below hero header row) --> <div id="contact-form" class="overflow-hidden max-h-0 opacity-0 transition-all duration-300 ease-in-out"> <form id="contact-form-el" class="mt-6 space-y-3 max-w-sm pl-1"> <div> <input type="text" name="name" placeholder="Your name" required class="w-full px-3 py-2 text-sm rounded-lg border border-[var(--color-border-light)] bg-[var(--color-surface)] appearance-none focus:outline-none focus:ring-2 transition-shadow duration-150"> </div> <div> <input type="email" name="email" placeholder="Your email" required class="w-full px-3 py-2 text-sm rounded-lg border border-[var(--color-border-light)] bg-[var(--color-surface)] appearance-none focus:outline-none focus:ring-2 transition-shadow duration-150"> </div> <div> <textarea name="message" placeholder="Message" rows="4" required class="w-full px-3 py-2 text-sm rounded-lg border border-[var(--color-border-light)] bg-[var(--color-surface)] focus:outline-none focus:ring-2 transition-shadow duration-150 resize-none"></textarea> </div> <div class="cf-turnstile" data-sitekey="0x4AAAAAACo3twr36d0ibBIH" data-theme="light" data-size="normal"></div> <div class="flex items-center gap-3"> <button type="submit" id="contact-submit" class="btn-contact px-4 py-2 text-sm font-medium rounded-lg active:scale-95 transition-all duration-150 cursor-pointer">
Send
</button> <button type="button" id="contact-cancel" class="px-4 py-2 text-sm transition-colors duration-150 cursor-pointer text-[var(--color-text-muted)]">
Cancel
</button> <span id="contact-status" class="text-sm text-[var(--color-text-muted)]"></span> </div> </form> </div> </section> <script type="module">const s=document.getElementById("contact-toggle"),n=document.getElementById("contact-form"),c=document.getElementById("contact-form-el"),m=document.getElementById("contact-cancel"),t=document.getElementById("contact-status"),o=document.getElementById("contact-submit");let d=!1;function u(){if(d)return;d=!0;const e=document.createElement("script");e.src="https://challenges.cloudflare.com/turnstile/v0/api.js",e.async=!0,document.head.appendChild(e)}function y(){u(),n.style.maxHeight=n.scrollHeight+200+"px",n.style.opacity="1",s.style.display="none"}function i(){n.style.maxHeight="0",n.style.opacity="0",s.style.display="",t.textContent=""}s.addEventListener("click",y);m.addEventListener("click",i);c.addEventListener("submit",async e=>{e.preventDefault(),o.disabled=!0,o.textContent="Sending...",t.textContent="";try{const l=new FormData(c),a=await fetch("/api/contact",{method:"POST",body:l}),r=await a.json();a.ok?(t.style.color="#16a34a",t.textContent=r.message||"Sent!",c.reset(),window.turnstile&&turnstile.reset(),setTimeout(i,3e3)):(t.style.color="#dc2626",t.textContent=r.error||"Something went wrong.")}catch{t.style.color="#dc2626",t.textContent="Network error. Please try again."}finally{o.disabled=!1,o.textContent="Send"}});</script>   <div class="max-w-[var(--container-wide)] mx-auto px-[var(--spacing-page)]"> <!-- Work --> <section id="work" class="pt-0 pb-12 text-lg">  <div class="space-y-1"> <a href="/products/schema/" class="group flex items-center gap-4 py-3 px-3 -mx-3 rounded-lg no-underline transition-all duration-150 bg-[var(--color-accent)]/[0.04] hover:bg-[var(--color-accent)]/[0.07]">  <div class="w-14 h-14 shrink-0 rounded-lg overflow-hidden flex items-center justify-center"> <img src="https://schema.ai/favicon.svg" alt="Schema" class="w-10 h-10 object-contain"> </div>  <div class="flex-1 min-w-0"> <p class="leading-snug line-clamp-2"> <span class="font-medium text-[var(--color-text)] group-hover:text-[var(--color-accent)] transition-colors">Schema</span> <span class="text-sm text-[var(--color-text-muted)]"> &middot; Founder</span> <span class="font-[var(--font-mono)] text-sm text-[var(--color-text-muted)]"> 2025–present</span> <span class="text-base text-[var(--color-text-secondary)]"> — Infrastructure product intelligence for SRE agents. Schema MCP Server delivers current, source-grounded insights that drive reliability and cost improvements. Keep your operational AI well-informed on the infra software/services you depend on.</span> </p> </div>  <svg class="w-5 h-5 text-[var(--color-text-muted)] opacity-0 group-hover:opacity-100 group-hover:translate-x-0.5 transition-all shrink-0" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"></path></svg> </a> </div>  <h2 class="font-[var(--font-mono)] text-xl tracking-[0.16em] uppercase text-[var(--color-text-muted)] mt-10 mb-4">
Products
</h2> <div class="space-y-1"> <a href="/products/cockroach-labs/" class="group flex items-center gap-4 py-3 px-3 -mx-3 rounded-lg no-underline transition-all duration-150 hover:bg-[var(--color-surface-alt)]">  <div class="w-14 h-14 shrink-0 rounded-lg overflow-hidden flex items-center justify-center"> <img src="/img/icons/cockroachdb.svg" alt="CockroachDB" class="w-10 h-10 object-contain"> </div>  <div class="flex-1 min-w-0"> <p class="leading-snug line-clamp-2"> <span class="font-medium text-[var(--color-text)] group-hover:text-[var(--color-accent)] transition-colors">CockroachDB</span> <span class="text-sm text-[var(--color-text-muted)]"> &middot; Product Manager</span> <span class="font-[var(--font-mono)] text-sm text-[var(--color-text-muted)]"> 2021–2025</span> <span class="text-base text-[var(--color-text-secondary)]"> — Led product for CockroachDB Cloud operational tooling (API, Terraform Provider, CLI) and CockroachDB Cloud Serverless — an autoscaling, multi-tenant distributed SQL database.</span> </p> </div>  <svg class="w-5 h-5 text-[var(--color-text-muted)] opacity-0 group-hover:opacity-100 group-hover:translate-x-0.5 transition-all shrink-0" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"></path></svg> </a><a href="/products/microsoft-azure-ml/" class="group flex items-center gap-4 py-3 px-3 -mx-3 rounded-lg no-underline transition-all duration-150 hover:bg-[var(--color-surface-alt)]">  <div class="w-14 h-14 shrink-0 rounded-lg overflow-hidden flex items-center justify-center"> <img src="/img/icons/microsoft.svg" alt="Microsoft Azure Machine Learning" class="w-10 h-10 object-contain"> </div>  <div class="flex-1 min-w-0"> <p class="leading-snug line-clamp-2"> <span class="font-medium text-[var(--color-text)] group-hover:text-[var(--color-accent)] transition-colors">Microsoft Azure Machine Learning</span> <span class="text-sm text-[var(--color-text-muted)]"> &middot; Software Engineer</span> <span class="font-[var(--font-mono)] text-sm text-[var(--color-text-muted)]"> 2018–2021</span> <span class="text-base text-[var(--color-text-secondary)]"> — Built cloud platform software at Microsoft&#39;s NERD Center in Cambridge, MA, improving how data scientists develop and operationalize machine learning models.</span> </p> </div>  <svg class="w-5 h-5 text-[var(--color-text-muted)] opacity-0 group-hover:opacity-100 group-hover:translate-x-0.5 transition-all shrink-0" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"></path></svg> </a><a href="/products/rocket-insights-brightcove/" class="group flex items-center gap-4 py-3 px-3 -mx-3 rounded-lg no-underline transition-all duration-150 hover:bg-[var(--color-surface-alt)]">  <div class="w-14 h-14 shrink-0 rounded-lg overflow-hidden flex items-center justify-center"> <img src="/img/icons/brightcove.svg" alt="Brightcove" class="w-10 h-10 object-contain"> </div>  <div class="flex-1 min-w-0"> <p class="leading-snug line-clamp-2"> <span class="font-medium text-[var(--color-text)] group-hover:text-[var(--color-accent)] transition-colors">Brightcove</span> <span class="text-sm text-[var(--color-text-muted)]"> &middot; Tech Lead</span> <span class="font-[var(--font-mono)] text-sm text-[var(--color-text-muted)]"> 2017–2018</span> <span class="text-base text-[var(--color-text-secondary)]"> — Led a team of 5 engineers developing the backend API for a Fortune 500 media company&#39;s web/mobile application, scaled for millions of users globally.</span> </p> </div>  <svg class="w-5 h-5 text-[var(--color-text-muted)] opacity-0 group-hover:opacity-100 group-hover:translate-x-0.5 transition-all shrink-0" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"></path></svg> </a><a href="/products/vmware/" class="group flex items-center gap-4 py-3 px-3 -mx-3 rounded-lg no-underline transition-all duration-150 hover:bg-[var(--color-surface-alt)]">  <div class="w-14 h-14 shrink-0 rounded-lg overflow-hidden flex items-center justify-center"> <img src="/img/icons/vmware.png" alt="VMware" class="w-10 h-10 object-contain"> </div>  <div class="flex-1 min-w-0"> <p class="leading-snug line-clamp-2"> <span class="font-medium text-[var(--color-text)] group-hover:text-[var(--color-accent)] transition-colors">VMware</span> <span class="text-sm text-[var(--color-text-muted)]"> &middot; Software Engineer</span> <span class="font-[var(--font-mono)] text-sm text-[var(--color-text-muted)]"> 2016</span> <span class="text-base text-[var(--color-text-secondary)]"> — Built the Angular web application for the vSphere Docker Volume Driver, enabling Docker container administrators to manage vSphere Storage access.</span> </p> </div>  <svg class="w-5 h-5 text-[var(--color-text-muted)] opacity-0 group-hover:opacity-100 group-hover:translate-x-0.5 transition-all shrink-0" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"></path></svg> </a><a href="/products/invite-education/" class="group flex items-center gap-4 py-3 px-3 -mx-3 rounded-lg no-underline transition-all duration-150 hover:bg-[var(--color-surface-alt)]">  <div class="w-14 h-14 shrink-0 rounded-lg overflow-hidden flex items-center justify-center"> <img src="/img/icons/invite-education.png" alt="Invite Education" class="w-10 h-10 object-contain"> </div>  <div class="flex-1 min-w-0"> <p class="leading-snug line-clamp-2"> <span class="font-medium text-[var(--color-text)] group-hover:text-[var(--color-accent)] transition-colors">Invite Education</span> <span class="text-sm text-[var(--color-text-muted)]"> &middot; Product Lead</span> <span class="font-[var(--font-mono)] text-sm text-[var(--color-text-muted)]"> 2013–2014</span> <span class="text-base text-[var(--color-text-secondary)]"> — Translated the founders&#39; vision for a better college planning experience into a successful product. Led a team of three to design and build the initial version with Rails, Angular, and D3.</span> </p> </div>  <svg class="w-5 h-5 text-[var(--color-text-muted)] opacity-0 group-hover:opacity-100 group-hover:translate-x-0.5 transition-all shrink-0" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"></path></svg> </a><a href="/products/rally/" class="group flex items-center gap-4 py-3 px-3 -mx-3 rounded-lg no-underline transition-all duration-150 hover:bg-[var(--color-surface-alt)]">  <div class="w-14 h-14 shrink-0 rounded-lg overflow-hidden flex items-center justify-center"> <img src="/img/rally.jpg" alt="Rally" class="w-full h-full object-cover"> </div>  <div class="flex-1 min-w-0"> <p class="leading-snug line-clamp-2"> <span class="font-medium text-[var(--color-text)] group-hover:text-[var(--color-accent)] transition-colors">Rally</span> <span class="text-sm text-[var(--color-text-muted)]"> &middot; Founder</span> <span class="font-[var(--font-mono)] text-sm text-[var(--color-text-muted)]"> 2009–2010</span> <span class="text-base text-[var(--color-text-secondary)]"> — Founded and built a service that mined Twitter for local events data using NLP and machine learning to help people make casual plans. Designed and developed all aspects — Python, Django, Twitter Streaming API, MongoDB, Redis, AWS.</span> </p> </div>  <svg class="w-5 h-5 text-[var(--color-text-muted)] opacity-0 group-hover:opacity-100 group-hover:translate-x-0.5 transition-all shrink-0" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"></path></svg> </a><a href="/products/likematter/" class="group flex items-center gap-4 py-3 px-3 -mx-3 rounded-lg no-underline transition-all duration-150 hover:bg-[var(--color-surface-alt)]">  <div class="w-14 h-14 shrink-0 rounded-lg overflow-hidden flex items-center justify-center"> <img src="/img/likematter.jpg" alt="Likematter" class="w-full h-full object-cover"> </div>  <div class="flex-1 min-w-0"> <p class="leading-snug line-clamp-2"> <span class="font-medium text-[var(--color-text)] group-hover:text-[var(--color-accent)] transition-colors">Likematter</span> <span class="text-sm text-[var(--color-text-muted)]"> &middot; Founder</span> <span class="font-[var(--font-mono)] text-sm text-[var(--color-text-muted)]"> 2008–2009</span> <span class="text-base text-[var(--color-text-secondary)]"> — Founded and led a team building a personalized news and job discovery engine using NLP and machine learning on the OpenCalais platform.</span> </p> </div>  <svg class="w-5 h-5 text-[var(--color-text-muted)] opacity-0 group-hover:opacity-100 group-hover:translate-x-0.5 transition-all shrink-0" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M8.25 4.5l7.5 7.5-7.5 7.5"></path></svg> </a> </div> <div class="mt-6 text-right"> <a href="/products" class="inline-block text-lg font-semibold text-[var(--color-accent)] no-underline hover:underline">
All products &rarr;
</a> </div> </section> <!-- Writing --> <section class="pt-0 pb-12 text-lg"> <h2 class="font-[var(--font-mono)] text-xl tracking-[0.16em] uppercase text-[var(--color-text-muted)] mb-6">
Writing
</h2> <div class="divide-y divide-[var(--color-border-light)]"> <a href="/blog/phone-verification-aws-lambda/" class="flex justify-between items-baseline py-4 no-underline group"> <span class="text-[var(--color-text)] group-hover:text-[var(--color-accent)] transition-colors font-medium"> Phone Number Verification with Event-Driven Microservices Using AWS Lambda, Kinesis Streams, React.js </span> <span class="font-[var(--font-mono)] text-sm text-[var(--color-text-muted)] ml-4 shrink-0"> Sep 2017 </span> </a><a href="/blog/conways-game-of-life-react-redux/" class="flex justify-between items-baseline py-4 no-underline group"> <span class="text-[var(--color-text)] group-hover:text-[var(--color-accent)] transition-colors font-medium"> Javascript Developer Interview: Conway&#39;s Game of Life with React.js and Redux </span> <span class="font-[var(--font-mono)] text-sm text-[var(--color-text-muted)] ml-4 shrink-0"> Aug 2017 </span> </a><a href="/blog/graphql-data-fluency/" class="flex justify-between items-baseline py-4 no-underline group"> <span class="text-[var(--color-text)] group-hover:text-[var(--color-accent)] transition-colors font-medium"> &quot;Easier to Reason About&quot; for the Entire Product Team with GraphQL </span> <span class="font-[var(--font-mono)] text-sm text-[var(--color-text-muted)] ml-4 shrink-0"> Jan 2016 </span> </a><a href="/blog/react-data-management-flux-redux-relay/" class="flex justify-between items-baseline py-4 no-underline group"> <span class="text-[var(--color-text)] group-hover:text-[var(--color-accent)] transition-colors font-medium"> Clearing up React Data Management Confusion with Flux, Redux, and Relay </span> <span class="font-[var(--font-mono)] text-sm text-[var(--color-text-muted)] ml-4 shrink-0"> Dec 2015 </span> </a><a href="/blog/data-focused-ui-design/" class="flex justify-between items-baseline py-4 no-underline group"> <span class="text-[var(--color-text)] group-hover:text-[var(--color-accent)] transition-colors font-medium"> Data-Focused UI Design </span> <span class="font-[var(--font-mono)] text-sm text-[var(--color-text-muted)] ml-4 shrink-0"> Jul 2015 </span> </a> </div> <div class="mt-6 text-right"> <a href="/blog" class="inline-block text-lg font-semibold text-[var(--color-accent)] no-underline hover:underline">
All writing &rarr;
</a> </div> </section> </div>  </main> <footer class="mt-16"> <div class="max-w-[var(--container-wide)] mx-auto px-[var(--spacing-page)]"> <hr class="border-t border-[var(--color-border-light)]"> </div> <div class="max-w-[var(--container-wide)] mx-auto px-[var(--spacing-page)] pt-10 pb-16 flex flex-col sm:flex-row items-center justify-between gap-4"> <div class="flex items-center gap-3 text-sm text-[var(--color-text-muted)]"> <p>&copy; 2026 Mark Soper</p> <div class="divider-line h-4 w-px bg-[var(--color-border)]"></div> <p class="flex items-center gap-1.5"> <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" stroke-width="2" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" d="M15 10.5a3 3 0 11-6 0 3 3 0 016 0z"></path><path stroke-linecap="round" stroke-linejoin="round" d="M19.5 10.5c0 7.142-7.5 11.25-7.5 11.25S4.5 17.642 4.5 10.5a7.5 7.5 0 1115 0z"></path></svg>
Cambridge, MA
</p> </div> <div class="flex items-center gap-4"> <a href="https://linkedin.com/in/marksoper" class="text-[var(--color-text-muted)] hover:text-[var(--color-text)] transition-colors" target="_blank" rel="noopener" aria-label="LinkedIn"> <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433a2.062 2.062 0 01-2.063-2.065 2.064 2.064 0 112.063 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"></path></svg> </a> <a href="https://github.com/marksoper" class="text-[var(--color-text-muted)] hover:text-[var(--color-text)] transition-colors" target="_blank" rel="noopener" aria-label="GitHub"> <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"></path></svg> </a> <a href="https://x.com/marksoper" class="text-[var(--color-text-muted)] hover:text-[var(--color-text)] transition-colors" target="_blank" rel="noopener" aria-label="X"> <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"><path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"></path></svg> </a> <div class="divider-line h-4 w-px bg-[var(--color-border)]"></div> <a href="/blog" class="text-sm text-[var(--color-text-muted)] no-underline hover:text-[var(--color-text)] transition-colors font-medium">Blog</a> </div> </div> </footer> <!-- GA4 — loaded after page render --> <script>
    window.addEventListener('load', function () {
      var s = document.createElement('script');
      s.src = 'https://www.googletagmanager.com/gtag/js?id=G-2SB46X7HFE';
      s.async = true;
      document.head.appendChild(s);
      s.onload = function () {
        window.dataLayer = window.dataLayer || [];
        function gtag(){dataLayer.push(arguments);}
        gtag('js', new Date());
        gtag('config', 'G-2SB46X7HFE');
      };
    });
  </script> </body> </html>