You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

119 lines
13 KiB
HTML

<!doctype html>
<html lang=en>
<head id="head">
<meta charset=utf-8>
<title id=title >the codeartist — programmer and engineer based in BerlinProjects</title>
<meta name=description content="The personal page and weblog of Norman Köhring">
<meta name=author content="Norman Köhring">
<meta name=DC.title content="the codeartist — programmer and engineer based in Berlin">
<meta name="twitter:card" content="summary">
<meta name="twitter:site" content="@koehr_in">
<meta name="twitter:author" content="@koehr_in">
<meta name=twitter:description content="The personal page and weblog of the codeartist Norman Köhring">
<meta name="twitter:title" content="Projects // the codeartist">
<meta name="og:title" content="Projects // the codeartist">
<meta property="og:type" content="website">
<meta http-equiv="x-ua-compatible" content="ie=edge"/>
<meta name=viewport content="width=device-width,initial-scale=1,shrink-to-fit=no"/>
<meta name=ICBM content="52.4595, 13.5335">
<meta name=geo.position content="52.4595; 13.5335">
<meta name=geo.region content=DE-BE>
<meta name=geo.placename content=Berlin>
<link rel=me href=https://koehr.in>
<link rel=me href=https://k0r.in>
<link rel=me href=https://koehr.ing>
<link rel=me href=@Koehr@mstdn.io>
<link rel=me href=https://sr.ht/~koehr/>
<link rel=me href=https://git.k0r.in>
<link rel=me href=https://threads.net/@coffee_n_code>
<link rel=me href=https://instagram.com/@coffee_n_code>
<link rel=me href=https://ko-fi.com/koehr>
<link rel=me href=https://reddit.com/user/koehr>
<link rel=icon href=/favicon.png type=image/x-icon>
<link rel=stylesheet href=/style.css>
</head>
<body>
<main id="main">
<header>
<h1 >Projects</h1>
<em >Stuff I made. This is mostly about software, but might also include some TTRPG related things, from time to time.</em>
<br/>
Last updated: <time datetime="Mon, 15 Jul 2024 00:00:00 +0000" >July 15, 2024</time>
</header>
<div ><p>I tend to host my code on multiple places, typically <a href="https://sr.ht">Sourcehut</a> and <a href="https://git.k0r.in">my Forgejo server</a>. Usually, if it involves a community, it is hosted or mirrored on Github as well, for visibility.</p><h2>250kB Club <a href="https://250kb.club">🔗</a></h2><img src="/projects/250kb.jpg" title="250kB Club Screenshot" alt="250kB Club Screenshot" />
<p>I am the creator of 250kB Club, which should actually be called 256kb.club, but that thought reached me only after I got the domain.</p><p>Already in 2016, we crossed the line, where the typical website is bigger than the game Doom. I think, we can do better! The 250kB Club is a collection of web pages that focus on performance, efficiency and accessibility. Originally inspired by <a href="https://1mb.club">1mb.club</a>, I created the 250kB Club, because I don't think 1MB is small enough. Not long ago, we would have waited 10 or more minutes to load this amount of data and not everyone in the world is a lucky high-speed internet user.</p><p>Source code: <a href="https://github.com/nkoehring/250kb-club">github</a>, <a href="https://git.sr.ht/~koehr/the-250kb-club">sourcehut</a>, <a href="https://git.k0r.in/n/250kb-Club">selfhosted</a></p><h2>Starsy <a href="https://starsy.netlify.app">🔗</a></h2><img src="/projects/starsy.jpg" title="Starsy Screenshot" alt="Starsy Screenshot" />
<p>For a hard sci-fi campaign setting, I once planned, I created this star system generator. I wanted to recreate the style of some image I found on reddit, a while ago.</p><p>Source code: <a href="https://github.com/nkoehring/starsy">github</a>, <a href="https://git.k0r.in/n/starsy">selfhosted</a></p><h2>RPG-Cards-ng <a href="https://rpg-cards-ng.netlify.app">🔗</a></h2><img src="/projects/rpgcards.jpg" title="RPG-Cards-ng Screenshot" alt="RPG-Cards-ng Screenshot" />
<p>I wanted to be able to create good looking cards for RPG sessions but didn't find a good tool that makes designing them simple and intuitive. So I created my own tool.</p><p>Source code: <a href="https://github.com/nkoehring/rpg-cards-ng">github</a>, <a href="https://git.k0r.in/n/rpg-cards-ng">selfhosted</a></p><h2>Vuejs//Berlin <a href="https://vuejs.berlin">🔗</a></h2><img src="/projects/vuejsberlin.jpg" title="Vuejs Berlin Screenshot" alt="Vuejs Berlin Screenshot" />
<p>I host the monthly Vuejs//Berlin meetup and created this homepage to publish details about the upcoming and former meetups. It also hosts a newsletter archive.</p><p>The Vuejs//Berlin meetup is Berlins community around the <a href="https://vuejs.org">Vue Framework</a> and its ecosystem. We meet monthly every second Tuesday. Doors open at 19:00, talks usually start around 19:30. Subscribe to <a href="https://lu.ma/vuejs_berlin">the event calendar</a> to never miss an update!</p><p>Source code: <a href="https://github.com/VuejsBerlin/new.vuejs.berlin">github</a></p><h2>Projects for myself</h2><p>Just for the sake of completeness and to motivate myself to keep track of it, here are some private projects around my own setup.</p><h3>Homepage Overhaul</h3><blockquote><p>With lots of work comes lots of opportunity for productive procrastination</p></blockquote><p>Not too long ago, .ing <span title="Top Level Domain">TLDs</span> became available, that allowed me to finally have my full name as a "cool" domain name: <code>koehr.ing</code>. Other domains I have are <code>nkoehring.de</code> (boring), <code>koehr.in</code> (confusing) and <code>k0r.in</code> (nerdy). <code>koehri.ng</code> wouldn't be possible due to domain registars policies or pricing (Nigeria used to have the british model, like allowing only net.ng, com.ng, and so on. Later they allowed more, but the price would be pretty high).</p><p>Why am I writing all this? Because the new domain name made me think about my homepage as a professional. I wanted to have something, that showcases my skills while not being the usual boring homepage. This is how <a href="https://cli.koehr.ing">the interactive homepage experiment</a> began; a terminal like website, written from scratch. Having this, I now also needed to change my old homepage to somehow feature my new shiny experiment. But my old homepage is white and not very responsive; two very good reasons (for me), to change it. So I also started writing a completely new homepage, using <a href="https://github.com/vssio/vss">vss</a>. Pretty soon I realised, it is by far not mature enough for my needs, so I started building workarounds to suit my needs, so I don't get stuck in the rabbit hole of choosing frameworks over finishing the page. My plan is, to finish the page and its content and then, when there is time, move it on top of something more sophisticated, like good ol' <a href="https://www.getzola.org/">Zola</a>.</p><h3>New Server</h3><p>I found a pretty cheap dedicated server with tons of space and quite some CPU power, compared to cheap virtual servers. Now I need to move everything I hosted on a VServer before. That is not a simple task, unfortunately, as I tend to overthink and want to use the change to make everything better (or just different, maybe). This move includes a switch from <a href="https://www.docker.com/">Docker</a> and <a href="https://blog.container-solutions.com/running-docker-containers-with-systemd">systemd services</a> to <a href="https://podman.io/">podman</a> and <a href="https://wiki.archlinux.org/title/Systemd/User#Automatic_start-up_of_systemd_user_instances">lingering users</a>. This way, no root enabled service is involved in running any outside-facing services. This website and everything under the koehr.ing domain runs already on the new server.</p><h3>learned.today</h3><p>Quite a while (aka way too long) ago, I bought the domain <code>learned.today</code> and thought about some idea around a Today I learned page or service, where people just share short snippets of things they just learned, similar to <a href="/til">my TIL page</a>. I never got to implementing it though. I wrote it down here as a motivation for myself, to finally work on it.</p></div>
</main>
<div id="spacer"></div>
<header id="header">
<a href="/">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 832.4 143.1">
<path id="header-underscore"
d="M832.4 131.1q0 5.5-3.1 8.6-3 3.4-8.2 3.3h-75.5q-5.2 0-8.2-3.3-1.7-1.6-2.4-3.8-.7-2.3-.7-4.8 0-5.5 3.1-8.7 1.6-1.7 3.7-2.4 2.2-.8 4.5-.8h75.5q5.2 0 8.2 3.2 3 3.1 3 8.7z" />
<path id="header-bracket"
d="M731.9 81.4q0 6.7-6.5 10.7l-1 .6-74.3 39.2q-2.5 1.3-5.2 1.2-4.8 0-8.1-3.8-3.2-3.6-3.2-8.4 0-3.3 1.7-6 1.8-2.9 4.6-4.4l55.3-29.1-55.3-29q-2.8-1.6-4.6-4.3-1.7-2.7-1.7-6.2 0-4.7 3.2-8.4 3.3-4 8-3.7 2.7 0 5.3 1.2l74.4 39.2q3.3 1.7 5.3 4.7 2 2.8 2 6.5z" />
<path id="header-r"
d="M588.7 66.5q0 5-3.5 8.5-3.5 3.4-8.1 3.5-4.4 0-8.3-4.3-10-10.7-20.9-10.6-2.2 0-4.3.3-2.1.3-4 1-1.8.6-3.7 1.6-1.7 1-3.4 2.3-1.7 1.3-3.3 2.9-7.8 8.2-7.6 19.7V131q0 5.5-3.1 8.6-3 3.4-8.3 3.3l-2.2-.2q-1-.1-2.2-.5-1-.3-2-1-1-.6-1.8-1.6-1.7-1.6-2.4-3.8-.7-2.3-.7-4.8V51.6q0-5.4 3-8.6 3-3.4 8.3-3.3 2 0 3.7.6 1.8.6 3.3 1.8 1.4 1 2.2 2.7 1 1.5 1.6 3.3 11.8-8.4 27-8.4 10.6 0 21 5 11.3 5.4 17.2 14.5 2.5 3.7 2.5 7.3z" />
<path id="header-h"
d="M483.9 131.1q0 5.5-3.1 8.6-3 3.4-8.3 3.3-5.2 0-8.2-3.3-3.2-3.1-3.1-8.6V84.8q0-4.6-1.5-8.2-1.4-3.5-4.4-6.9-2.1-2-4.3-3.4-2.2-1.4-4.7-2-2.4-.7-5.3-.7-4.3 0-7.8 1.5-3.3 1.5-6.4 4.6-5.9 6.3-5.8 15v46.4q0 5.5-3 8.6-3.1 3.4-8.4 3.3l-2.2-.2q-1-.1-2.2-.5-1-.3-2-1-1-.6-1.8-1.6-1.7-1.6-2.4-3.8-.7-2.3-.7-4.8V11.9q0-5.5 3-8.6 3-3.4 8.3-3.3 5.2 0 8.2 3.3 3.2 3.1 3.2 8.6v33q1.5-1 3-1.6l3.2-1.2 3.4-1q1.6-.5 3.3-.8l3.5-.4 3.6-.2q4.4 0 8.5 1 4.1.7 7.9 2.4 3.8 1.6 7.3 4.1 3.5 2.5 6.6 5.8Q484 66 484 84.8z" />
<path id="header-e"
d="M387.5 111.1q0 1.2-.3 2.3-.1 1-.5 2l-.9 2q-6.6 12-19.4 19-12 6.6-25.4 6.6-20.8 0-35.8-14.6-15.9-15-15.9-37 0-22.1 15.9-37.1 15-14.6 35.8-14.6 3.9 0 7.8.7 4 .7 8 2.2 9.2 3.1 18.2 10 6 4.6 9.1 9.3 3.3 4.7 3.3 10 0 1.3-.3 2.5-.2 1.3-.7 2.4-1.5 3.4-5 5.3l-56.9 32.2q7.2 4.9 16.5 4.9 7.2 0 12.6-2.5 5.5-2.5 9.7-7.4l.7-1 .8-1 .9-1.3 1-1.5q3.3-4.2 7.4-5.1l1.8-.2q4.4 0 8 3.4 3.6 3.5 3.6 8.5zm-29.9-42.7q-7.2-4.8-16.6-4.8-6 0-11 2-4.9 1.8-9.3 6-4.5 4-6.7 9-2 4.8-2 10.8l.1 2.9z" />
<path id="header-o"
d="M286.8 91.4q0 4.2-.6 8.3-.6 4-1.8 7.7-1.1 3.8-2.9 7.4-1.7 3.5-4 6.9-2.4 3.3-5.2 6.1Q258 143 237.7 143T203 128q-14.3-15.2-14.3-36.6 0-21.5 14.3-36.6 14.4-15 34.7-15 4 0 7.8.5 3.9.7 7.5 1.9t7 3q3.3 1.9 6.4 4.3 3.2 2.4 5.9 5.4 14.4 15 14.5 36.5zm-22.6 0q0-2.4-.4-4.5-.2-2.2-.9-4.2-.6-2-1.5-3.9-1-2-2.2-3.7-1.2-1.7-2.8-3.4-4-4.2-8.6-6.1-4.5-2-10-2-11 0-18.7 8.2-7.8 8-7.8 19.6 0 11.4 7.8 19.7 7.8 8 18.6 8 5.6 0 10.1-1.9 4.6-2 8.6-6.1 4-4.3 5.8-9 2-4.9 2-10.7z" />
<path id="header-k"
d="M186.3 131q0 4.7-3.3 8.3-1.5 1.8-3.7 2.7-2 1.1-4.3 1.1-3.5 0-6.6-2L119.2 105v26q0 5.5-3 8.6-3.1 3.4-8.4 3.3l-2.2-.2q-1-.1-2.2-.5-1-.3-2-1-1-.6-1.8-1.6-1.7-1.6-2.4-3.8-.7-2.3-.7-4.8V11.9q0-5.5 3-8.6 3-3.4 8.3-3.3 5.2 0 8.2 3.3 3.2 3.1 3.2 8.6v65.9l49.2-36.1q3.2-2 6.6-2 4.7 0 8 3.7t3.3 8.4q-.2 6-5 9.6l-41 30 41 29.9q2.3 1.7 3.6 4.2 1.4 2.5 1.4 5.4z" />
<path id="header-tilde"
d="M73.1 91q0 2-.6 3.9T71 98.6q-3.2 5.7-8.9 8.5-5.6 2.8-12.9 2.8-8.8 0-18-7.8-2.4-2.3-4.5-3.7-2.1-1.5-3-1.7-1.5 0-2.1.3l-.8 1.3q-.3.7-.8 1.2l-1 1-.9.8q-2.7 2-6.4 2-1.7 0-3.2-.3-1.4-.3-3-1.1-1.5-.8-2.6-2.1-2.8-3.1-2.8-8v-1.3q0-.7.2-1.2l.2-1 .4-1 .4-1q.1-.6.5-1.1l.5-1q3.2-5.7 8.8-8.5 5.7-2.9 13-2.9 3.2 0 6.2 1 3 .9 6 2.7 2.9 1.6 5.7 4.2 5.2 4.6 7.6 5.4 1 0 1.6-.2l.7-.4q.3-.1.5-.4 3.6-5.6 9.2-5.6 5.7 0 8.8 3.5 2.8 3 2.8 8z" />
</svg>
Homepage of
<div class=p-name>
<span class=first-name>Norman</span>
<span class=last-name>Köhring</span>
</div>
Code Artist
</a>
</header>
<div id="main-menu">
<menu>
<li><a title="What I do these days" href="/now">/now</a></li>
<li><a title="Today I Learned" href="/til">/til</a></li>
<li><a title="My projects" href="/projects">/projects</a></li>
<li><a title="Weblog" href="/blog">/blog</a></li>
<li><a title="CV / Resume" href="/cv">/cv</a></li>
<li><a title="Tools I use" href="/stack">/stack</a></li>
<li><a title="Hardware I use" href="/setup">/setup</a></li>
</menu>
</div>
<footer id="footer">
</footer>
<script defer>
const el = document.getElementById('header')
const threshhold = 24
let headerIsSmall = false
window.addEventListener("scroll", () => {
if (window.scrollY > threshhold && !headerIsSmall) {
el.classList.add('small')
headerIsSmall = true
} else if (window.scrollY <= threshhold && headerIsSmall) {
el.classList.remove('small')
headerIsSmall = false
}
})
</script>
<script async data-goatcounter=https://koehr.goatcounter.com/count src=//gc.zgo.at/count.js></script>
</body>
</html>