Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/quarterback/dev-site. dev-site-five-kappa.vercel.app
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152<!doctype html><html lang="en"><head><meta charset="utf-8" /><meta name="viewport" content="width=device-width, initial-scale=1" /><link rel="icon" href="/favicon.svg" type="image/svg+xml" /><link rel="icon" href="/favicon.png" type="image/png" sizes="any" /><title>Mallo | Ron Bronson</title><meta name="description" content="The first advanced-analytics site for pesäpallo, Finland's national baseball variant, with league-indexed stats, DARKO-style projections, park factors, and playoff odds, built on the official results API." /><link rel="canonical" href="https://ronbronson.dev/projects/mallo.html" /><meta property="og:type" content="website" /><meta property="og:site_name" content="Ron Bronson" /><meta property="og:title" content="Mallo | Ron Bronson" /><meta property="og:description" content="The first advanced-analytics site for pesäpallo, Finland's national baseball variant, with league-indexed stats, DARKO-style projections, park factors, and playoff odds, built on the official results API." /><meta property="og:url" content="https://ronbronson.dev/projects/mallo.html" /><meta property="og:image" content="https://ronbronson.dev/assets/social-card.png" /><meta property="og:image:width" content="1200" /><meta property="og:image:height" content="630" /><meta property="og:image:alt" content="Ron Bronson beside the words Problems Are Designed, with a workshop photo and a content schema check." /><meta name="twitter:card" content="summary_large_image" /><meta name="twitter:title" content="Mallo | Ron Bronson" /><meta name="twitter:description" content="The first advanced-analytics site for pesäpallo, Finland's national baseball variant, with league-indexed stats, DARKO-style projections, park factors, and playoff odds, built on the official results API." /><meta name="twitter:image" content="https://ronbronson.dev/assets/social-card.png" /><link rel="preload" as="font" type="font/woff2" href="../assets/fonts/gallery/PPNeueMontreal-Extrabold.woff2" crossorigin /><!-- standard.site --><link rel="site.standard.document" href="at://did:plc:odgxwakrg5r2zjetnrkxuh5c/site.standard.document/3mpomspcnun2v" /><!-- /standard.site --><link rel="stylesheet" href="../assets/slabs.css" /><script src="../assets/contact.js" defer></script></head><body class="pg-blue"><div class="s-wrap">
<header class="top"> <p class="top__name"><a href="../index.html">Ron Bronson</a></p> <nav aria-label="Main navigation"><a href="../index.html#work">Work</a><a href="https://ronbronson.design">Design</a><a href="https://blog.ronbronson.dev">Blog</a><a class="nav-gh" href="https://github.com/quarterback" target="_blank" rel="me noopener" aria-label="GitHub" title="GitHub"><svg viewBox="0 0 496 512" width="22" height="22" fill="currentColor" aria-hidden="true"><path d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3zm44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 26 31.4 26 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 82 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8z"/></svg></a><a class="nav-mail" href="#contact" data-contact aria-label="Email" title="Email"><svg viewBox="0 0 24 24" width="22" height="22" fill="none" stroke="currentColor" stroke-width="2.2" stroke-linejoin="round" aria-hidden="true"><rect x="2.5" y="5" width="19" height="14"/><path d="M3 6l9 7 9-7"/></svg></a></nav> </header>
<article class="project">
<h1 class="project__title">Mallo</h1> <p class="project__lede">The first advanced-analytics site for pesäpallo, Finland’s national baseball variant. It adds the sabermetrics layer the sport never had, something I’d wanted for as long as I’ve followed it.</p> <p class="project__lede--fi" lang="fi">Ensimmäinen pesäpallon edistyneen analytiikan sivusto. Sarjaan suhteutetut tunnusluvut, DARKO-tyyliset ennusteet, lajin ensimmäiset julkaistut kenttäkertoimet ja Monte Carlo -pudotuspelitodennäköisyydet — rakennettu virallisen tulospalvelun datasta.</p> <div class="project__meta"> <span>A personal project</span> <span class="sep">·</span> <span>2026</span> <span class="sep">·</span> <a class="live-link" href="https://www.mallo.fi" target="_blank" rel="noopener">Mallo</a> </div>
<figure class="figure"> <svg class="ph" viewBox="0 0 1400 800" preserveAspectRatio="xMidYMid slice" aria-hidden="true"> <defs> <pattern id="ph-a" width="16" height="16" patternUnits="userSpaceOnUse" patternTransform="rotate(20)"> <rect width="16" height="16" fill="#a8dadc"/> <line x1="0" y1="0" x2="0" y2="16" stroke="#457b9d" stroke-width="6"/> </pattern> </defs> <rect width="1400" height="800" fill="url(#ph-a)"/> </svg> <img src="../assets/mallo/home.png" alt="Screenshot of mallo.fi" loading="lazy" style="position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:top center;" /> </figure>
<div class="project__body">
<p>I’ve followed pesäpallo, Finland’s national baseball variant, for well over a decade. Somewhere along the way the fandom turned into something bigger: I’ve talked the sport up on podcasts and other people’s shows; I <a href="../projects/finnish-baseball-game-design.html">gave a conference talk</a> on what it taught me about game design; and a couple of years ago I was on the pre- and post-game show for the <a href="https://youtu.be/U0lsmfUmrLI" target="_blank" rel="noopener">first-ever English-language Superpesis telecast</a>. I eventually made the pilgrimage to Finland to watch it in person. Superpesis, the top league, <a href="https://www.superpesis.fi/ajankohtaista/superpesis-yhdysvaltalainen-ron-bronson-toteutti-unelmansa-ja-matkusti-suomeen-katsomaan-pesapalloa" target="_blank" rel="noopener">wrote about the trip</a>. For an American, I’ve been in this a while. If you want the origin story, I wrote up <a href="https://medium.com/@ronbronson/pesapallo-9dc4d3f1ed5e" target="_blank" rel="noopener">how a guy from America starts following Finnish baseball</a>.</p>
<div class="figpair"> <figure class="figure"> <img src="../assets/mallo/telecast-booth.png" alt="Ron Bronson in the broadcast booth for the first English-language telecast of a pesäpallo game, with an on-screen name graphic and the Ruutu logo" loading="lazy" /> </figure> <figure class="figure"> <img src="../assets/mallo/post-game.png" alt="Post Game with Ron Bronson show logo" loading="lazy" /> </figure> </div>
<p>I’m also a lifelong baseball fan, and I’ve been reading sabermetrics since the ’90s, when I was buying <i>Baseball America</i> and <i>Baseball Weekly</i> off the rack years before any of this went mainstream. Pesäpallo and baseball are cousins: the same instincts in a different sport. I’d always wanted a way to hold both interests in the same hand. Mallo puts both in one place, and it comes from someone who fell for baseball reading box scores as a kid.</p>
<p>Before Mallo there was no advanced-analytics site for pesäpallo anywhere, even though the sport keeps decades of granular records. Mallo borrows openly from the analytics sites I grew up on (DARKO for projections, Baseball Savant for percentile fingerprints, FanGraphs for league-indexed rate stats, Baseball-Reference for career lines and comps) and translates each idea into the grammar of the Finnish game.</p>
<p>Mallo runs on real data from the official results service (<a href="https://www.pesistulokset.fi" target="_blank" rel="noopener">Pesistulokset</a>), which turned out to be a documented JSON API with per-player, per-match rows of roughly 82 fields each: hits split by target base, advancement as batter and as runner, turns at bat, defensive position, and match context down to the stadium, weather, temperature, and attendance. Coverage reaches back to the 1940s, with granular stats to 1990. Mallo ingests the current Superpesis season and refreshes on every deploy.</p>
<h2>Stats that fit the sport</h2>
<p>Finnish media publish counting stats and a handful of percentages. Mallo keeps the traditional line (kunnarit, lyödyt, tuodut, tehot) and adds honest denominators and league context. Rate stats are computed against the attempts that actually happened, then indexed to the league. <b>TEHO+</b> is the headline stat (100 is league average, era- and division-adjusted in the spirit of OPS+ and wRC+), with a park-adjusted <b>kTEHO+</b> alongside it. Every qualified player gets a Baseball-Savant-style percentile fingerprint: diverging red-to-blue bars that read as a skill profile at a glance.</p>
<h2>Projections and context</h2>
<p><b>PARE</b> is the projection engine. It asks DARKO’s question of pesäpallo: how much of a hot streak is real? Every game a player has ever played is weighted by exponential decay, blended toward the league mean with empirical-Bayes shrinkage that leans harder on small samples, with per-stat decay and prior strengths fitted by walk-forward scoring. A 28-to-33-game season is short, but each game comes with unusually rich recorded context, so the observed stats stay the headline, adjusted for the conditions they happened in: the first published park factors for the sport (kenttäkertoimet), weather effects, and opponent strength to come.</p>
<h2>Also on the site</h2>
<ul> <li><b>Standings & playoff odds</b>: real Superpesis points, with Monte Carlo playoff odds simulated over the remaining schedule and re-run at weekly cutoffs to draw a season-long odds chart.</li> <li><b>Similarity scores</b>: Baseball-Reference-style comps: nearest neighbors over standardized rate stats, 1000 means identical.</li> <li><b>Pesäpallo baseball</b>: a rank-preserving quantile map from Superpesis percentiles onto MLB distributions, so a player’s season reads as a shareable English-language line for people who know baseball but not pesäpallo.</li> <li><b>Every league, first-class</b>: men’s and women’s Superpesis and the lower tiers all build their own navigation; the women’s game is never buried behind a filter.</li> </ul>
<h2>How it’s built</h2>
<p>The core is Python over SQLite (a metrics layer, the projection engine, a context model, and a Monte Carlo simulator), with a small web UI on top and charts drawn in vendored D3 without a CDN. The demo league generates every stat line from known latent talent so the tests can assert the projections and park factors recover it. It’s a directed agent build, documented in after-action reports in the repo and released under the AGPL. Mostly it’s a fan project, the site I always wanted to exist.</p>
<p><a class="live-link" href="https://www.mallo.fi" target="_blank" rel="noopener">See Mallo</a></p>
</div>
</article>
<footer class="foot" id="contact"> <div class="hx-icons" aria-label="Elsewhere"><a class="hx-i" href="https://bsky.app/profile/ronbronson.com" target="_blank" rel="me noopener" aria-label="Bluesky" title="Bluesky"><svg viewBox="0 0 576 512" fill="currentColor" aria-hidden="true"><path d="M407.8 294.7c-3.3-.4-6.7-.8-10-1.3 3.4 .4 6.7 .9 10 1.3zM288 227.1C261.9 176.4 190.9 81.9 124.9 35.3 61.6-9.4 37.5-1.7 21.6 5.5 3.3 13.8 0 41.9 0 58.4S9.1 194 15 213.9c19.5 65.7 89.1 87.9 153.2 80.7 3.3-.5 6.6-.9 10-1.4-3.3 .5-6.6 1-10 1.4-93.9 14-177.3 48.2-67.9 169.9 120.3 124.6 164.8-26.7 187.7-103.4 22.9 76.7 49.2 222.5 185.6 103.4 102.4-103.4 28.1-156-65.8-169.9-3.3-.4-6.7-.8-10-1.3 3.4 .4 6.7 .9 10 1.3 64.1 7.1 133.6-15.1 153.2-80.7 5.9-19.9 15-138.9 15-155.5s-3.3-44.7-21.6-52.9c-15.8-7.1-40-14.9-103.2 29.8-66.1 46.6-137.1 141.1-163.2 191.8z"></path></svg></a><a class="hx-i" href="https://mastodon.social/@ronbronson" target="_blank" rel="me noopener" aria-label="Mastodon" title="Mastodon"><svg viewBox="0 0 448 512" fill="currentColor" aria-hidden="true"><path d="M433 179.1c0-97.2-63.7-125.7-63.7-125.7-62.5-28.7-228.6-28.4-290.5 0 0 0-63.7 28.5-63.7 125.7 0 115.7-6.6 259.4 105.6 289.1 40.5 10.7 75.3 13 103.3 11.4 50.8-2.8 79.3-18.1 79.3-18.1l-1.7-36.9s-36.3 11.4-77.1 10.1c-40.4-1.4-83-4.4-89.6-54-.6-4.6-.9-9.3-.9-13.9 85.6 20.9 158.7 9.1 178.7 6.7 56.1-6.7 105-41.3 111.2-72.9 9.8-49.8 9-121.5 9-121.5zM357.9 304.3l-46.6 0 0-114.2c0-49.7-64-51.6-64 6.9l0 62.5-46.3 0 0-62.5c0-58.5-64-56.6-64-6.9l0 114.2-46.7 0c0-122.1-5.2-147.9 18.4-175 25.9-28.9 79.8-30.8 103.8 6.1l11.6 19.5 11.6-19.5c24.1-37.1 78.1-34.8 103.8-6.1 23.7 27.3 18.4 53 18.4 175l0 0z"></path></svg></a><a class="hx-i" href="https://www.linkedin.com/in/ronbronson/" target="_blank" rel="me noopener" aria-label="LinkedIn" title="LinkedIn"><svg viewBox="0 0 448 512" fill="currentColor" aria-hidden="true"><path d="M100.3 448l-92.9 0 0-299.1 92.9 0 0 299.1zM53.8 108.1C24.1 108.1 0 83.5 0 53.8 0 39.5 5.7 25.9 15.8 15.8s23.8-15.8 38-15.8 27.9 5.7 38 15.8 15.8 23.8 15.8 38c0 29.7-24.1 54.3-53.8 54.3zM447.9 448l-92.7 0 0-145.6c0-34.7-.7-79.2-48.3-79.2-48.3 0-55.7 37.7-55.7 76.7l0 148.1-92.8 0 0-299.1 89.1 0 0 40.8 1.3 0c12.4-23.5 42.7-48.3 87.9-48.3 94 0 111.3 61.9 111.3 142.3l0 164.3-.1 0z"></path></svg></a><a class="hx-i" href="https://github.com/quarterback" target="_blank" rel="me noopener" aria-label="GitHub" title="GitHub"><svg viewBox="0 0 512 512" fill="currentColor" aria-hidden="true"><path d="M216.5 362.5c-66-8-112.5-55.5-112.5-117 0-25 9-52 24-70-6.5-16.5-5.5-51.5 2-66 20-2.5 47 8 63 22.5 19-6 39-9 63.5-9s44.5 3 62.5 8.5c15.5-14 43-24.5 63-22 7 13.5 8 48.5 1.5 65.5 16 19 24.5 44.5 24.5 70.5 0 61.5-46.5 108-113.5 116.5 17 11 28.5 35 28.5 62.5l0 52C323 491.5 335.5 500 350.5 494 441 459.5 512 369 512 257 512 115.5 397 0 255.5 0S0 115.5 0 257c0 111 70.5 203 165.5 237.5 13.5 5 26.5-4 26.5-17.5l0-40c-7 3-16 5-24 5-33 0-52.5-18-66.5-51.5-5.5-13.5-11.5-21.5-23-23-6-.5-8-3-8-6 0-6 10-10.5 20-10.5 14.5 0 27 9 40 27.5 10 14.5 20.5 21 33 21s20.5-4.5 32-16c8.5-8.5 15-16 21-21z"></path></svg></a><a class="hx-i" href="https://www.instagram.com/ronbronson/" target="_blank" rel="me noopener" aria-label="Instagram" title="Instagram"><svg viewBox="0 0 448 512" fill="currentColor" aria-hidden="true"><path d="M224.3 141a115 115 0 1 0 -.6 230 115 115 0 1 0 .6-230zm-.6 40.4a74.6 74.6 0 1 1 .6 149.2 74.6 74.6 0 1 1 -.6-149.2zm93.4-45.1a26.8 26.8 0 1 1 53.6 0 26.8 26.8 0 1 1 -53.6 0zm129.7 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM399 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"></path></svg></a><a class="hx-i" href="https://twitter.com/ronbronson" target="_blank" rel="me noopener" aria-label="Twitter" title="Twitter"><svg viewBox="0 0 448 512" fill="currentColor" aria-hidden="true"><path d="M357.2 48L427.8 48 273.6 224.2 455 464 313 464 201.7 318.6 74.5 464 3.8 464 168.7 275.5-5.2 48 140.4 48 240.9 180.9 357.2 48zM332.4 421.8l39.1 0-252.4-333.8-42 0 255.3 333.8z"></path></svg></a><a class="hx-i" href="https://letterboxd.com/ronbronson/" target="_blank" rel="me noopener" aria-label="Letterboxd" title="Letterboxd"><svg viewBox="0 0 640 512" fill="currentColor" aria-hidden="true"><path d="M521.3 128C586.9 128 640 181.1 640 246.6S586.9 365.2 521.3 365.2c-42.5 0-79.7-22.3-100.7-55.8 11.4-18.2 18-39.7 18-62.8s-6.6-44.6-18-62.8l.8-1.2c20.8-32.3 56.8-53.9 97.9-54.6l2 0zM320 128c42.5 0 79.7 22.3 100.7 55.8-11.4 18.2-18 39.7-18 62.8s6.6 44.6 18 62.8l-.8 1.2c-20.8 32.3-56.8 53.9-97.9 54.6l-2 0c-42.5 0-79.7-22.3-100.7-55.8 11.4-18.2 18-39.7 18-62.8s-6.6-44.6-18-62.8l.8-1.2c20.8-32.3 56.8-53.9 97.9-54.6l2 0zm-201.3 0c42.5 0 79.7 22.3 100.7 55.8-11.4 18.2-18 39.7-18 62.8s6.6 44.6 18 62.8l-.8 1.2c-20.8 32.3-56.8 53.9-97.9 54.6l-2 0C53.1 365.1 0 312.1 0 246.6S53.1 128 118.7 128z"></path></svg></a><a class="hx-i" href="https://bookhive.buzz/profile/ronbronson.com" target="_blank" rel="me noopener" aria-label="Bookhive" title="Bookhive"><svg viewBox="0 0 448 512" fill="currentColor" aria-hidden="true"><path d="M384 512L96 512c-53 0-96-43-96-96L0 96C0 43 43 0 96 0L400 0c26.5 0 48 21.5 48 48l0 288c0 20.9-13.4 38.7-32 45.3l0 66.7c17.7 0 32 14.3 32 32s-14.3 32-32 32l-32 0zM96 384c-17.7 0-32 14.3-32 32s14.3 32 32 32l256 0 0-64-256 0zm32-232c0 13.3 10.7 24 24 24l176 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-176 0c-13.3 0-24 10.7-24 24zm24 72c-13.3 0-24 10.7-24 24s10.7 24 24 24l176 0c13.3 0 24-10.7 24-24s-10.7-24-24-24l-176 0z"></path></svg></a><a class="hx-i" href="https://record.club/ron" target="_blank" rel="me noopener" aria-label="Record.club" title="Record.club"><svg viewBox="0 0 512 512" fill="currentColor" aria-hidden="true"><path d="M0 256a256 256 0 1 1 512 0 256 256 0 1 1 -512 0zm256-96a96 96 0 1 1 0 192 96 96 0 1 1 0-192zm0 240a144 144 0 1 0 0-288 144 144 0 1 0 0 288zm0-112a32 32 0 1 0 0-64 32 32 0 1 0 0 64z"></path></svg></a><a class="hx-i" href="https://listening.ronbronson.com" target="_blank" rel="me noopener" aria-label="Listening" title="Listening"><svg viewBox="0 0 448 512" fill="currentColor" aria-hidden="true"><path d="M64 224c0-88.4 71.6-160 160-160s160 71.6 160 160l0 37.5c-10-3.5-20.8-5.5-32-5.5l-16 0c-26.5 0-48 21.5-48 48l0 128c0 26.5 21.5 48 48 48l16 0c53 0 96-43 96-96l0-160C448 100.3 347.7 0 224 0S0 100.3 0 224L0 384c0 53 43 96 96 96l16 0c26.5 0 48-21.5 48-48l0-128c0-26.5-21.5-48-48-48l-16 0c-11.2 0-22 1.9-32 5.5L64 224z"></path></svg></a><a class="hx-i" href="https://www.last.fm/user/statechampion" target="_blank" rel="me noopener" aria-label="Last.fm" title="Last.fm"><svg viewBox="0 0 512 512" fill="currentColor" aria-hidden="true"><path d="M225.8 367.1l-18.8-51s-30.5 34-76.2 34c-40.5 0-69.2-35.2-69.2-91.5 0-72.1 36.4-97.9 72.1-97.9 66.5 0 74.8 53.3 100.9 134.9 18.8 56.9 54 102.6 155.4 102.6 72.7 0 122-22.3 122-80.9 0-72.9-62.7-80.6-115-92.1-25.8-5.9-33.4-16.4-33.4-34 0-19.9 15.8-31.7 41.6-31.7 28.2 0 43.4 10.6 45.7 35.8l58.6-7c-4.7-52.8-41.1-74.5-100.9-74.5-52.8 0-104.4 19.9-104.4 83.9 0 39.9 19.4 65.1 68 76.8 44.9 10.6 79.8 13.8 79.8 45.7 0 21.7-21.1 30.5-61 30.5-59.2 0-83.9-31.1-97.9-73.9-32-96.8-43.6-163-161.3-163-86.1 0-131.8 54.5-131.8 147.2 0 89.1 45.7 137.2 127.9 137.2 66.2 0 97.9-31.1 97.9-31.1z"/></svg></a><a class="hx-i" rel="me" href="mailto:ron@ronbronson.com" aria-label="Email" title="Email"><svg viewBox="0 0 512 512" fill="currentColor" aria-hidden="true"><path d="M48 64c-26.5 0-48 21.5-48 48 0 15.1 7.1 29.3 19.2 38.4l208 156c17.1 12.8 40.5 12.8 57.6 0l208-156c12.1-9.1 19.2-23.3 19.2-38.4 0-26.5-21.5-48-48-48L48 64zM0 196L0 384c0 35.3 28.7 64 64 64l384 0c35.3 0 64-28.7 64-64l0-188-198.4 148.8c-34.1 25.6-81.1 25.6-115.2 0L0 196z"></path></svg></a></div> <h2>Colophon, with digressions</h2> <p><b>Type</b> PP Neue Montreal, Hanken Grotesk, IBM Plex Mono</p> <p><b>Built with</b> HTML, CSS, JavaScript, SVG</p> <p><b>Images</b> static screenshots</p> <p><b>Hosting</b> GitHub, Vercel</p> <p class="digression" id="digression">Inexplicably, a Green Bay Packers shareholder.</p>
</footer>
</div> <script> /* Digressions — one aside, picked at random per load (never the same one twice in a row). Add or edit entries in DIGRESSIONS; the footer shows one at a time so the list never has to be spelled out. */ (function () { var DIGRESSIONS = [ "Inexplicably, a Green Bay Packers shareholder.", "Favorite sports teams: Toronto Blue Jays, Vimpelin Veto, New Jersey Devils, Lapuan Virkiä, <s>New York Jets</s>, Portland Timbers, New York Knicks, Portland Thorns, Brighton & Hove Albion, Sassuolo, Toluca, Toronto Tempo, Montreal Expos (RIP)", "<em>Have you seen my fragrance collection?</em> <a href='https://www.oksmelly.xyz/' target='_blank' rel='noopener'>it’s here</a>.", "I’m a longtime tea sommelier. I once curated the tea menu at <a href='https://hopscotchcoffee.com/' target='_blank' rel='noopener'>Hopscotch Coffee</a> in Bloomington. Ask me for loose-leaf recs!", "Favorite wine regions: Slovenia, Georgia or anything that aged in amphorae or an old boot. I’m not picky.", "I’ve coached high school tennis for ten years across 3 states. My career varsity record apparently is 91-33-4. 1 team state championship, 4 District/Regional titles, 5 Conference titles. 4 individual state champions. So far…", "Yes, I have a <a href='https://www.discogs.com/user/quarterback/collection?header=1' target='_blank' rel='noopener'>Discogs</a> 🙄", "I actually grew up watching golf, because my grandfather played. I still like a Par 3 because of him.", "Last time I went fishing? 1994.", "Unsurprisingly, I was once a bar trivia host in Bloomington. One step closer to my true calling: game show host." ]; var el = document.getElementById("digression"); if (!el) return; var last = -1; try { last = parseInt(sessionStorage.getItem("rb-digression"), 10); } catch (e) {} var i = Math.floor(Math.random() * DIGRESSIONS.length); while (DIGRESSIONS.length > 1 && i === last) i = Math.floor(Math.random() * DIGRESSIONS.length); try { sessionStorage.setItem("rb-digression", i); } catch (e) {} el.innerHTML = DIGRESSIONS[i]; })(); </script></body></html>