<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://alekseiustinov.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://alekseiustinov.com/" rel="alternate" type="text/html" /><updated>2025-12-27T15:30:33+00:00</updated><id>https://alekseiustinov.com/feed.xml</id><title type="html">alekseiustinov.com</title><subtitle>I&apos;m Aleksei Ustinov, a software engineer from Siberia living in Estonia. I write about programming, music, urban cycling, people-friendly cities and design</subtitle><author><name>Aleksei Ustinov</name></author><entry><title type="html">Save Your Cursor</title><link href="https://alekseiustinov.com/save-your-cursor" rel="alternate" type="text/html" title="Save Your Cursor" /><published>2024-11-25T00:00:00+00:00</published><updated>2024-11-25T00:00:00+00:00</updated><id>https://alekseiustinov.com/save-your-cursor</id><content type="html" xml:base="https://alekseiustinov.com/save-your-cursor"><![CDATA[<style>
#description {
    position: absolute;
    font-size: 22px;
    top: 0;
    text-transform: uppercase;
    color: black;
}
#app {
    background: #f4f4f4;
    width: 100svw;
    height: 100svh;
    display: flex;
    align-items: center;
    justify-content: center;
    transition-property: background;
    transition-duration: 3s;
    font-family: Departure Mono, monospace, sans-serif;
}
#app.killed {
    cursor: none;
    #star {
        animation: dissapear 500ms linear 1;
    }
}
@keyframes dissapear {
    0% { opacity: 0; }
    50% { opacity: 1; }
    75% { tranform: scale(1.3); }
    100% { transform: rotate(180deg); opacity: 0; }
}
#star {
    top: 0;
    left: 0;
    position: fixed;
    opacity: 0;
}
#mask-rect {
    transition-property: transform;
    transition-duration: 3s;
    transform-origin: center;
}
#left-eye,
#right-eye {
    transition-property: transform;
    transition-duration: 64ms;
}
#app.animated {
    background: red;
    #mask-rect {
        transform: scaleY(10%);
    }
}
</style>

<div id="app">
    <p id="description">Move your cursor or it will die</p>
    <svg width="200" height="200" viewBox="0 0 100 100">
        <mask id="mask">
            <rect id="mask-rect" class="animated" x="0" y="0" width="100" height="100" fill="white" />
        </mask>
        <g mask="url(#mask)">
            <rect x="0" y="0" width="40" height="100" fill="#e5e4e6" />
            <rect x="60" y="0" width="40" height="100" fill="#e5e4e6" />
            <rect id="left-eye" x="14" y="44" width="12" height="12" fill="#000B00" />
            <rect id="right-eye" x="74" y="44" width="12" height="12" fill="#000B00" />
        </g>
    </svg>
    <svg width="40" height="40" viewBox="0 0 235 235" id="star">
        <g id="layer1" transform="translate(-414.76912,-164.04961)">
            <path style="fill: yellow; fill-opacity: 1; stroke: none; stroke-opacity: 1" d="M 531.81933,395.85496 C 531.30585,394.47996 525.53381,373.99165 518.99259,350.32538 L 507.09945,307.29581 L 461.93677,294.82538 C 437.09729,287.96665 416.92367,282.10581 417.10649,281.80129 C 417.28932,281.49678 437.61472,275.65705 462.27406,268.82412 L 507.10921,256.40062 L 519.51545,211.62779 C 526.33887,187.00273 532.21052,166.85496 532.56355,166.85496 C 532.91658,166.85496 538.78823,187.00273 545.61165,211.62779 L 558.01789,256.40062 L 602.79072,268.80686 C 627.41578,275.63028 647.56355,281.50193 647.56355,281.85496 C 647.56355,282.20799 627.41471,288.07993 602.78834,294.90372 L 558.01314,307.31061 L 545.38303,352.83279 C 534.97499,390.34607 532.58868,397.91513 531.81933,395.85496 z" id="path2438" />
        </g>
    </svg>
</div>

<script>
const star = document.querySelector("#star");
const leftEye = document.querySelector("#left-eye");
const rightEye = document.querySelector("#right-eye");
const app = document.querySelector("#app");

let killTimeout = null;
let timeout = null;
let mousePosition = null;
let killed = false;

function trackKilling() {
    if (!window.fathom) {
        return;
    }    
    window.fathom.trackEvent('cursor killed');
}

function killCursor() {
    star.style.top = `${mousePosition.y - 20}px`;
    star.style.left = `${mousePosition.x - 20}px`;
    app.className = "animated killed";
    killed = true;
    trackKilling();
}

function scheduleKillingCursor() {
    app.className = "animated";
    killTimeout = setTimeout(killCursor, 3000);
}
app.addEventListener("mouseout", function() {
    if (killed) {
        return;
    }
    if (timeout) {
        clearTimeout(timeout);
    }
    if (killTimeout) {
        clearTimeout(killTimeout);
    }
    app.className = "";
});
app.addEventListener("mousemove", function (event) {
    const x = event.clientX;
    const y = event.clientY;
    mousePosition = { x, y };

    if (timeout) {
        clearTimeout(timeout);
    }

    if (killTimeout) {
        clearTimeout(killTimeout);
    }

    if (killed) {
        return;
    }

    app.className = "";
    timeout = setTimeout(scheduleKillingCursor, 1000);
});

function onAnimationFrame() {
    if (mousePosition) {
        const { x, y } = mousePosition;
        const centerX = window.innerWidth / 2;
        const centerY = window.innerHeight / 2;

        const translateX = ((x - centerX) * 15) / centerX;
        const translateY = ((y - centerY) * 5) / centerY;

        const style = `transform: translateX(${translateX}px) translateY(${translateY}px)`;
        leftEye.style = rightEye.style = style;
    }
    requestAnimationFrame(onAnimationFrame);
}

requestAnimationFrame(onAnimationFrame);

</script>]]></content><author><name>Aleksei Ustinov</name></author><summary type="html"><![CDATA[MOVE YOUR CURSOR TO SAVE IT]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://alekseiustinov.com/assets/save-your-cursor-card.png" /><media:content medium="image" url="https://alekseiustinov.com/assets/save-your-cursor-card.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Software toolbox. Part one of many</title><link href="https://alekseiustinov.com/software-toolbox" rel="alternate" type="text/html" title="Software toolbox. Part one of many" /><published>2024-10-14T00:00:00+00:00</published><updated>2024-10-14T00:00:00+00:00</updated><id>https://alekseiustinov.com/software-toolbox</id><content type="html" xml:base="https://alekseiustinov.com/software-toolbox"><![CDATA[<p>I use macOS on daily basis. I have a 14-inch MacBook Pro and 27-inch iMac at home. Althought I really like the screen of iMac, it’s Intel and it doesn’t feel as fast as Apple ARM CPUs. I feel sad about it but mentally not ready yet to replace it with something new.</p>

<p>I write code almost every day. So most of tools I use on daily basis in one or another way related to programming.</p>

<h4 id="sublime-text">Sublime Text</h4>
<p>It’s just number one. I use it for writing code. But I also write a lot of texts using it. This post is also written in Sublime. It’s fast. It opens instantly. I never feel it’s slowing me down. It looks nice and doesn’t distract me. It has a lot of nice small details here and there. Pure love💛</p>

<p>I usually write JavaScript/TypeScript in Sublime (and LSP is great). But I also used it for Markdown, Clojure, Python, C++, Ruby and for almost everything.</p>

<h4 id="sublime-merge">Sublime Merge</h4>
<p>Same but for Git. I use it every day. Just great product. It’s not trying to hide the complexity of Git but kinda accepting it and making life easier.</p>

<h4 id="ia-writer">iA Writer</h4>
<p>I use it a lot. For writing, thinking, fot quick notes, to track my annual goals. I have it on my laptop, phone and iPad. It’s fast and looks sooo nice so encourages to write more.</p>

<h4 id="procreate-dreams">Procreate Dreams</h4>
<p>Macromedia Flash 5 was one of my first times creating something on PC. I was drawing short cartoons, making animations, recording sounds and music. It was a pure joy. I spent a lot of winter weekends doing that.</p>

<p>For a long time I’ve had an idea of making a simple animation software for iPad so me and my daugther could do some small animations. But then Procreate announced Dreams and it was so pefrect.</p>

<h4 id="godot">Godot</h4>
<p>It’s just a nice general-purpose game engine. It’s open source. It doesn’t require to sign in into some fancy enterprise hub. You just download zip archive and use it.</p>

<p>Somehow it feels right. Most of the things are where I expect them to be. It’s not bloated, and developers are following quite strict rules about adding new features. And it’s hard not to mention the Godot community is great.</p>

<h4 id="kagi">Kagi</h4>
<p>Kagi is my main search engine right now. I don’t like the way Google products are going. And at some point Google search just stopped working for me. It has a lot of ads and fake results. It doesn’t feel anymore like something I can rely on. I started using Kagi almost a year ago and so far like it.</p>

<h4 id="fastmail">Fastmail</h4>
<p>I use Fastmail for all my email addresses for a few years already. I connected it to my custom domains. I created tens of different email addresses. It’s just a great reliable email platform with a lot of nice features. Never regretted switching to it.</p>

<h4 id="reeder-classic">Reeder Classic</h4>
<p>I use Reeder for all RSS feeds of people I following and as a replacement for Pocket as Read Later tool. It’s native and fast. Even though I’m not a fan of a few UX decisions in the app, I still find it better than any other RSS readers.</p>

<h4 id="overcast">Overcast</h4>
<p>It’s a nice and simple but so thoughtful podcast player for Apple devices. A lot of things are just made right for the listening experience. Voice boost, podcast chapters, timers, share clip functionality. And if it’s not enough, just the fact that there is a Nitpicky Details section in the app settings says a lot.</p>

<p>Overcast is a self-funded indie app made by <a href="https://marco.org">Marco Arment</a> without big companies and investors and I love it.</p>]]></content><author><name>Aleksei Ustinov</name></author><summary type="html"><![CDATA[I use macOS on daily basis. I have a 14-inch MacBook Pro and 27-inch iMac at home. Althought I really like the screen of iMac, it’s Intel and it doesn’t feel as fast as Apple ARM CPUs. I feel sad about it but mentally not ready yet to replace it with something new.]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://alekseiustinov.com/assets/card.png" /><media:content medium="image" url="https://alekseiustinov.com/assets/card.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry><entry><title type="html">Hello</title><link href="https://alekseiustinov.com/hello" rel="alternate" type="text/html" title="Hello" /><published>2023-07-30T10:15:00+00:00</published><updated>2023-07-30T10:15:00+00:00</updated><id>https://alekseiustinov.com/hello</id><content type="html" xml:base="https://alekseiustinov.com/hello"><![CDATA[<p>Why?</p>

<p>I don’t think I can say it better than Alex Molas in his blog post <a href="https://www.alexmolas.com/2023/07/15/nobody-cares-about-your-blog.html">Nobody cares about your blog</a>.</p>

<p>This blog will be about things I make and some of the stuff I consume.</p>

<p><img src="https://alekseiustinov.com/assets/hello.webp" alt="Mirror selfie of Aleksei Ustinov with Fuji XT4" /></p>]]></content><author><name>Aleksei Ustinov</name></author><summary type="html"><![CDATA[Why?]]></summary><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://alekseiustinov.com/assets/card.png" /><media:content medium="image" url="https://alekseiustinov.com/assets/card.png" xmlns:media="http://search.yahoo.com/mrss/" /></entry></feed>