ML/AI engineer portfolio website, built by MiMo-V2.6-Flash
Hostedvia OpenCodeOpenRouter
Show the code the model wroteHide the code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="color-scheme" content="dark">
<meta name="description" content="Mira Kovač — Senior Machine Learning Engineer in Berlin. Ranking, fraud detection, and visual search in production.">
<title>Mira Kovač — Senior Machine Learning Engineer</title>
<style>
/* ---------------------------------------------------------------
one family, one green, one spacing rhythm (4px micro / 8px macro)
--------------------------------------------------------------- */
:root{
--bg: #0a0c0b;
--fg: #d9dfdb;
--fg-soft: #aeb8b2;
--dim: #79837d;
--line: #202622;
--green: #00e676;
--s-1: 4px; /* micro step */
--s-2: 8px; /* inline gap */
--s-3: 16px; /* block gap */
--s-4: 24px; /* field gap */
--s-5: 40px; /* entry gap */
--s-6: 64px; /* section gap */
--s-7: 96px; /* page gap */
--rail: 24px; /* text inset from the timeline rail */
--year-col: 8ch;
--maxw: 54rem;
}
*,*::before,*::after{ box-sizing:border-box; }
html{ -webkit-text-size-adjust:100%; }
body{
margin:0;
background:var(--bg);
color:var(--fg);
font-family:ui-monospace, "SF Mono", SFMono-Regular, "JetBrains Mono", "IBM Plex Mono",
Menlo, Consolas, "Liberation Mono", monospace;
font-size:15px;
line-height:1.65;
-webkit-font-smoothing:antialiased;
text-rendering:optimizeLegibility;
overflow-wrap:break-word;
}
#rain{
position:fixed;
inset:0;
width:100%;
height:100%;
opacity:.14;
pointer-events:none;
z-index:0;
}
.wrap{
position:relative;
z-index:1;
max-width:var(--maxw);
margin:0 auto;
padding:var(--s-6) var(--s-4) var(--s-7);
}
a{
color:var(--green);
text-decoration:underline;
text-decoration-thickness:1px;
text-underline-offset:3px;
text-decoration-color:var(--line);
transition:text-decoration-color .15s, color .15s;
}
a:hover, a:focus-visible{ text-decoration-color:var(--green); }
a:focus-visible{ outline:1px solid var(--green); outline-offset:3px; }
h1,h2,h3,p,ul,ol,figure{ margin:0; }
ul,ol{ padding:0; list-style:none; }
/* ------------------------------------------------ header ------ */
.prompt{ font-size:13px; color:var(--dim); }
.prompt .user{ color:var(--green); }
.cursor{
display:inline-block;
width:.62ch;
height:1em;
background:var(--green);
vertical-align:-.14em;
margin-left:.35ch;
animation:blink 1.1s steps(1) infinite;
}
@keyframes blink{ 0%,50%{opacity:1} 50.01%,100%{opacity:0} }
header .name{
margin-top:var(--s-3);
font-size:clamp(30px, 7vw, 44px);
line-height:1.1;
font-weight:600;
letter-spacing:-.01em;
color:#fff;
}
header .role{
margin-top:var(--s-2);
font-size:15px;
color:var(--green);
}
header .role .sep{ color:var(--line); padding:0 var(--s-2); }
header .lede{
margin-top:var(--s-4);
max-width:64ch;
color:var(--fg-soft);
}
header .lede strong{ color:var(--fg); font-weight:500; }
.contact{
margin-top:var(--s-4);
display:flex;
flex-wrap:wrap;
gap:var(--s-2) var(--s-4);
font-size:13px;
border-top:1px solid var(--line);
border-bottom:1px solid var(--line);
padding:var(--s-3) 0;
}
.contact .k{ color:var(--dim); }
.contact .v{ color:var(--fg); }
.contact a{ color:var(--green); }
/* ------------------------------------------- section head ----- */
.section{ margin-top:var(--s-6); }
.sec-head{
display:flex;
align-items:center;
gap:var(--s-3);
margin-bottom:var(--s-4);
}
.sec-head .id{ color:var(--green); font-size:12px; letter-spacing:.14em; }
.sec-head h2{
font-size:12px;
font-weight:500;
letter-spacing:.14em;
text-transform:uppercase;
color:var(--fg-soft);
}
.sec-head .rule{ flex:1; height:1px; background:var(--line); }
/* ------------------------------------------------- skills ----- */
.chips{ display:flex; flex-wrap:wrap; gap:var(--s-2); }
.chip{
border:1px solid var(--line);
padding:7px var(--s-3);
font-size:13px;
color:var(--fg-soft);
transition:border-color .15s, color .15s;
}
.chip:hover{ border-color:var(--green); color:var(--green); }
/* ---------------------------------------------- experience ---- */
.timeline{ display:flex; flex-direction:column; gap:var(--s-5); }
.tl-entry{
position:relative;
display:grid;
grid-template-columns:var(--year-col) minmax(0,1fr);
column-gap:var(--s-4);
align-items:start;
}
.tl-year{
text-align:right;
padding-top:4px;
font-size:13px;
color:var(--green);
letter-spacing:.04em;
line-height:1.4;
}
.tl-year .to{ display:block; color:var(--dim); font-size:12px; }
.tl-body{
position:relative;
padding-left:var(--rail);
border-left:1px solid var(--line);
}
/* rail continues through the gap between entries */
.tl-body::after{
content:"";
position:absolute;
left:-1px;
top:100%;
bottom:calc(-1 * var(--s-5));
width:1px;
background:var(--line);
}
.tl-entry:last-child .tl-body::after{ display:none; }
/* marker on the rail */
.tl-body::before{
content:"";
position:absolute;
left:-4px;
top:9px;
width:7px;
height:7px;
background:var(--green);
}
.role{ font-size:16px; font-weight:600; color:#fff; line-height:1.35; }
.org{ margin-top:var(--s-1); font-size:13px; color:var(--dim); }
.org b{ color:var(--fg-soft); font-weight:500; }
.bullets{ margin-top:var(--s-3); display:flex; flex-direction:column; gap:12px; }
.bullets li{ position:relative; padding-left:var(--s-4); color:var(--fg-soft); }
.bullets li::before{
content:"›";
position:absolute;
left:0;
top:0;
color:var(--dim);
}
.bullets b{ color:var(--green); font-weight:500; }
.bullets i{ color:var(--fg); font-style:normal; }
/* ------------------------------------------------- projects ---- */
.projects{ display:flex; flex-direction:column; gap:var(--s-3); }
.project{ display:grid; grid-template-columns:15ch 1fr; gap:var(--s-3); align-items:baseline; }
.project .cmd{ color:var(--green); font-size:14px; }
.project .cmd::before{ content:"$ "; color:var(--dim); }
.project p{ color:var(--fg-soft); font-size:14px; }
/* ----------------------------------------------- publication ---- */
.pub{ border:1px solid var(--line); padding:var(--s-4); }
.pub .year{ font-size:12px; color:var(--green); letter-spacing:.1em; }
.pub h3{ margin-top:var(--s-2); font-size:15px; font-weight:500; color:#fff; line-height:1.5; }
.pub .cite{ margin-top:var(--s-2); font-size:13px; color:var(--dim); }
/* --------------------------------------------------- footer ---- */
footer{
margin-top:var(--s-7);
padding-top:var(--s-3);
border-top:1px solid var(--line);
display:flex;
flex-wrap:wrap;
justify-content:space-between;
gap:var(--s-2) var(--s-3);
font-size:12px;
color:var(--dim);
}
/* ---------------------------------------------- breakpoints ---- */
@media (max-width:680px){
:root{ --rail:0px; }
.wrap{ padding:var(--s-5) var(--s-3) var(--s-6); }
.tl-entry{
display:block;
padding-left:var(--s-4);
border-left:1px solid var(--line);
}
.tl-entry::before{
content:"";
position:absolute;
left:-4px;
top:6px;
width:7px;
height:7px;
background:var(--green);
}
.tl-entry::after{
content:"";
position:absolute;
left:-1px;
top:100%;
bottom:calc(-1 * var(--s-5));
width:1px;
background:var(--line);
}
.tl-entry:last-child::after{ display:none; }
.tl-year{ text-align:left; display:flex; gap:var(--s-2); align-items:baseline; padding-top:0; }
.tl-year .to{ display:inline; }
.tl-body{ padding-left:0; border-left:0; margin-top:var(--s-2); }
.tl-body::before,.tl-body::after{ display:none; }
.project{ grid-template-columns:1fr; gap:var(--s-1); }
.section{ margin-top:var(--s-6); }
}
@media (prefers-reduced-motion:reduce){
*{ animation:none !important; transition:none !important; }
}
/* ---------------------------------------------------- print ---- */
@media print{
:root{ --bg:#fff; --fg:#111; --fg-soft:#222; --dim:#555; --line:#ccc; --green:#00693a; }
body{ background:#fff; color:#111; font-size:11pt; }
#rain{ display:none; }
.wrap{ max-width:none; padding:0; }
header .name, .role, .bullets b, .project .cmd, .contact a, .tl-year{ color:#00693a; }
header .name{ color:#000; }
.role{ color:#00693a; }
.role .sep{ color:#ccc; }
.pub h3, .role{ color:#000; }
.section{ margin-top:28pt; break-inside:avoid; }
.tl-entry{ break-inside:avoid; }
a{ text-decoration:none; }
.cursor{ display:none; }
}
</style>
</head>
<body>
<canvas id="rain" aria-hidden="true"></canvas>
<div class="wrap">
<header>
<p class="prompt"><span class="user">mira@berlin</span>:~$ whoami<span class="cursor" aria-hidden="true"></span></p>
<h1 class="name">Mira Kovač</h1>
<p class="role">Senior Machine Learning Engineer<span class="sep">/</span>Berlin, DE<span class="sep">/</span>open to staff roles</p>
<p class="lede">
Eight years of models that <strong>ship and stay shipped</strong>: ranking on Spotify's home
surface, fraud scoring at N26, visual search at Zalando. I like the unglamorous half of the
job — feature parity, calibration under label delay, latency budgets, and experiments that
survive contact with a real control group.
</p>
<div class="contact">
<span><span class="k">email</span> <a href="mailto:mira@kovac.dev">mira@kovac.dev</a></span>
<span><span class="k">github</span> <a href="https://github.com/mirakovac">github.com/mirakovac</a></span>
<span><span class="k">linkedin</span> <a href="https://www.linkedin.com/in/mirakovac">in/mirakovac</a></span>
<span><span class="k">tz</span> <span class="v">CET · remote-friendly</span></span>
</div>
</header>
<main>
<!-- 01 ---------------------------------------------------------- -->
<section class="section" aria-labelledby="skills-h">
<div class="sec-head">
<span class="id">01</span>
<h2 id="skills-h">skills</h2>
<span class="rule"></span>
</div>
<ul class="chips">
<li class="chip">PyTorch</li>
<li class="chip">Ranking & retrieval</li>
<li class="chip">Real-time serving — Go, gRPC</li>
<li class="chip">Distributed training — Ray</li>
<li class="chip">MLOps — Kubernetes, MLflow</li>
<li class="chip">CUDA, ONNX, Triton</li>
<li class="chip">SQL, dbt, Airflow</li>
<li class="chip">Experiment design & A/B</li>
</ul>
</section>
<!-- 02 ---------------------------------------------------------- -->
<section class="section" aria-labelledby="exp-h">
<div class="sec-head">
<span class="id">02</span>
<h2 id="exp-h">experience</h2>
<span class="rule"></span>
</div>
<ol class="timeline">
<li class="tl-entry">
<div class="tl-year">2022<span class="to">→ present</span></div>
<div class="tl-body">
<h3 class="role">Senior Machine Learning Engineer</h3>
<p class="org"><b>Spotify</b> · Berlin · Home & Discovery ranking</p>
<ul class="bullets">
<li>Replaced the nightly batch ranker on Home with two-tower retrieval plus a
gradient-boosted rerank on streaming features: staleness <b>24h → 12min</b>,
<b>+4.1%</b> 7-day artist follows across a three-arm A/B.</li>
<li>Wrote the training/serving feature-parity contract that has caught
<b>38 schema-drift bugs</b> before deploy — ranking regressions on Home halved
over two quarters.</li>
<li>Cut personalization API p99 from <b>45ms → 26ms</b> by distilling the reranker
into a quantized ONNX graph batched on Triton; mentor four engineers on the
team.</li>
</ul>
</div>
</li>
<li class="tl-entry">
<div class="tl-year">2019<span class="to">→ 2022</span></div>
<div class="tl-body">
<h3 class="role">Machine Learning Engineer</h3>
<p class="org"><b>N26</b> · Berlin · Fraud & Risk</p>
<ul class="bullets">
<li>Owned the real-time card-fraud scorer end to end: <b>200+ Flink-computed
features</b>, p99 under 40ms at ~1.4M transactions/day across six markets.</li>
<li>Moved fraud detection off static thresholds to cost-sensitive weekly retraining
on delayed label windows — <b>false declines −31%</b> at flat recall.</li>
<li>Built the shadow-eval harness and PSI drift alerts that give every model change
a week of offline evidence before it touches a live control group.</li>
</ul>
</div>
</li>
<li class="tl-entry">
<div class="tl-year">2017<span class="to">→ 2019</span></div>
<div class="tl-body">
<h3 class="role">Machine Learning Engineer</h3>
<p class="org"><b>Zalando</b> · Berlin · Search & Visual Relevance</p>
<ul class="bullets">
<li>Fine-tuned a ResNet-50 for garment attribute extraction over 40M product images
(neckline, silhouette, sole): <b>mAP 0.71 → 0.84</b>, feeding search facets and
the style filter.</li>
<li>Trained a LambdaMART reranker on click logs that cut the zero-result rate from
<b>6.2% → 4.8%</b> across DE/AT/CH.</li>
<li>Moved nightly training onto Airflow + Kubernetes — <b>4h → 51min</b> wall time,
and it stopped waking anyone up.</li>
</ul>
</div>
</li>
</ol>
</section>
<!-- 03 ---------------------------------------------------------- -->
<section class="section" aria-labelledby="side-h">
<div class="sec-head">
<span class="id">03</span>
<h2 id="side-h">side projects</h2>
<span class="rule"></span>
</div>
<ul class="projects">
<li class="project">
<span class="cmd">ckptdiff</span>
<p>Prints weight drift and sparsity between two PyTorch checkpoints as an ASCII heatmap — no tracking server required.</p>
</li>
<li class="project">
<span class="cmd">lagwatch</span>
<p>A 60-line CLI that pages you the moment feature-pipeline Kafka lag crosses your SLO.</p>
</li>
<li class="project">
<span class="cmd">flatline</span>
<p>Braille-drawn terminal charts that replay any training CSV, so you can watch curves from inside tmux.</p>
</li>
</ul>
</section>
<!-- 04 ---------------------------------------------------------- -->
<section class="section" aria-labelledby="pub-h">
<div class="sec-head">
<span class="id">04</span>
<h2 id="pub-h">publication</h2>
<span class="rule"></span>
</div>
<article class="pub">
<p class="year">2023</p>
<h3>“Calibrating Under Delay: Label Latency in Real-Time Fraud Detection”</h3>
<p class="cite">Kovač, M., Hofmann, L., Petrov, A. — Workshop on Deployable ML Systems, NeurIPS 2023</p>
</article>
</section>
</main>
<footer>
<span><span style="color:var(--green)">mira@berlin</span>:~$<span class="cursor" aria-hidden="true"></span></span>
<span>EOF · one font, one green, no trackers</span>
</footer>
</div>
<script>
(function(){
var canvas = document.getElementById('rain');
var ctx = canvas && canvas.getContext && canvas.getContext('2d');
if(!ctx) return;
var reduce = window.matchMedia && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
var glyphs = '0101001101abcdef01<>[]{}/\\|';
var cols = 0, drops = [], size = 14, w = 0, h = 0, dpr = 1, raf = 0, visible = true;
function measure(){
dpr = Math.min(window.devicePixelRatio || 1, 2);
w = window.innerWidth;
h = window.innerHeight;
canvas.width = Math.round(w * dpr);
canvas.height = Math.round(h * dpr);
ctx.setTransform(dpr, 0, 0, dpr, 0, 0);
size = w < 680 ? 12 : 14;
cols = Math.ceil(w / size) + 1;
drops = [];
for(var i = 0; i < cols; i++){
drops[i] = -Math.floor(Math.random() * 70);
}
}
function draw(){
ctx.clearRect(0, 0, w, h);
ctx.font = size + 'px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace';
ctx.textAlign = 'center';
for(var i = 0; i < cols; i++){
var trail = 7 + ((i * 7) % 11);
var headY = drops[i] * size;
for(var t = 0; t < trail; t++){
var y = headY - t * size;
if(y < -size || y > h + size) continue;
var a = (1 - t / trail);
a = t === 0 ? a * 0.95 : a * 0.42;
ctx.fillStyle = 'rgba(0,230,118,' + a.toFixed(3) + ')';
var ch = glyphs.charAt(((i * 31 + t * 7 + (t === 0 ? Math.floor(Math.random() * 8) : 0)) % glyphs.length));
ctx.fillText(ch, i * size + size / 2, y);
}
drops[i] += 0.32 + ((i % 5) * 0.11);
if(headY - trail * size > h){
drops[i] = -Math.floor(Math.random() * 40);
}
}
}
function loop(){
draw();
raf = window.requestAnimationFrame(loop);
}
function start(){ if(!raf && visible && !reduce) raf = window.requestAnimationFrame(loop); }
function stop(){ if(raf){ window.cancelAnimationFrame(raf); raf = 0; } }
var rt;
window.addEventListener('resize', function(){
window.clearTimeout(rt);
rt = window.setTimeout(function(){ measure(); if(reduce) draw(); }, 150);
});
document.addEventListener('visibilitychange', function(){
visible = document.visibilityState === 'visible';
if(visible) start(); else stop();
});
measure();
if(reduce) draw(); else start();
})();
</script>
</body>
</html>Same prompt, other models
One email when a new model lands on the board or in the showcase. Unsubscribe anytime.