<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Side Project</title>
        <link>https://sideproject.com</link>
        <description>Essays and experiments by Tu Pham</description>
        <lastBuildDate>Tue, 07 Apr 2026 07:20:10 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <image>
            <title>Side Project</title>
            <url>https://sideproject.com/favicon.ico</url>
            <link>https://sideproject.com</link>
        </image>
        <copyright>All rights reserved 2026</copyright>
        <item>
            <title><![CDATA[I sent my handwritten notes to AI. Here's what it saw.]]></title>
            <link>https://sideproject.com/essays/i-sent-my-notes-to-ai</link>
            <guid isPermaLink="false">https://sideproject.com/essays/i-sent-my-notes-to-ai</guid>
            <pubDate>Wed, 01 Apr 2026 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>These notes were from a morning where I was working through content organization across different platforms. Feet kicked up on my desk, staring at the page of notes I'd written down and thought: <strong>who takes notes like this?</strong> So I sent it to Claude.</p>
<div class="not-prose my-10 border-y border-zinc-200 dark:border-zinc-700"><div class="border-b border-zinc-200 last:border-b-0 dark:border-zinc-700"><div class="grid md:grid-cols-[2fr_3fr]"><div class="px-6 pt-6 pb-3 md:border-r md:border-zinc-200 md:dark:border-zinc-700"><p class="font-dm-mono text-[0.68rem] font-bold uppercase tracking-[0.2em] text-gold-500">What I saw</p></div><div class="px-6 pt-6 pb-3"><p class="font-dm-mono text-[0.68rem] font-bold uppercase tracking-[0.2em] text-gold-500">AI Observation</p></div></div><div class="grid md:grid-cols-[2fr_3fr]"><div class="not-prose flex flex-col gap-3 border-b border-zinc-200 px-6 pb-6 dark:border-zinc-700 [&amp;_*]:!m-0 md:border-b-0 md:border-r"><img alt="Handwritten generative notes — cross-shaped layout, no grid" loading="lazy" width="1080" height="1080" decoding="async" data-nimg="1" class="w-full rounded border border-zinc-200 dark:border-zinc-700" style="color:transparent" srcset="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fyour-generative-notes.9e2ac414.jpg&amp;w=1080&amp;q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fyour-generative-notes.9e2ac414.jpg&amp;w=3840&amp;q=75 2x" src="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fyour-generative-notes.9e2ac414.jpg&amp;w=3840&amp;q=75"><p class="font-dm-mono text-[0.82rem] leading-relaxed text-zinc-500"></p><p>The original page of notes. Cross-shaped layout, no grid, no headers. Things ended up where they ended up.</p><p></p></div><div class="not-prose flex flex-col gap-3 px-6 pb-6 text-sm leading-relaxed [&amp;_*]:!m-0"><img alt="AI diagram of generative notes — spatial logic mapped" loading="lazy" width="400" height="320" decoding="async" data-nimg="1" class="w-full" style="color:transparent" src="/_next/static/media/diagram-your-generative.189d2a4e.svg"><p class="font-dm-mono text-[0.82rem] leading-relaxed text-zinc-500"></p><p>The same page, read without self-criticism. The cross shape wasn't imposed. It emerged from felt proximity. The “do we care?” is the most revealing mark on the page.</p><p></p><ul class="list-none space-y-1 p-0"><li class="relative pl-4 font-dm-mono text-xs leading-relaxed text-gold-500 before:absolute before:left-0 before:content-['·']">spatial sorting by felt proximity</li><li class="relative pl-4 font-dm-mono text-xs leading-relaxed text-gold-500 before:absolute before:left-0 before:content-['·']">no imposed structure</li><li class="relative pl-4 font-dm-mono text-xs leading-relaxed text-gold-500 before:absolute before:left-0 before:content-['·']">radiates outward</li></ul></div></div></div></div>
<p>Claude's first read was that <strong>the page had internal logic.</strong> It just didn't perform tidiness for anyone else. That the spatial arrangement wasn't chaos but felt sorting: <strong>things ended up near each other because they were related</strong>, not because I consciously placed them. That the “do we care?” next to the platform list wasn't uncertainty. It was discipline.</p>
<p>Claude asked if it was my notebook. I confirmed it was. That made me ask why it was asking. If it already suspected, the read wasn't as clean as I thought. Claude admitted it: probably confirming a pattern rather than reading it fresh. I asked it to try again, this time without context. The read shifted slightly. That was enough.</p>
<div class="not-prose my-10 border-y border-t-2 border-zinc-900 py-6 text-xl font-light italic leading-relaxed text-zinc-900 dark:border-zinc-300 dark:text-zinc-100 border-b-zinc-200 dark:border-b-zinc-700"><p>“I was probably confirming a pattern I already expected rather than reading it fresh.” — Claude</p></div>
<p>Then I thought: what if I sent notes from my last meeting. Would Claude have anything different to say about this page versus the other one. The second page was meeting notes. Claude's read: <strong>this person was in someone else's world, not their own.</strong> It knew the ideas weren't mine.</p>
<div class="not-prose my-10 border-y border-zinc-200 dark:border-zinc-700"><div class="border-b border-zinc-200 last:border-b-0 dark:border-zinc-700"><div class="grid md:grid-cols-[2fr_3fr]"><div class="px-6 pt-6 pb-3 md:border-r md:border-zinc-200 md:dark:border-zinc-700"><p class="font-dm-mono text-[0.68rem] font-bold uppercase tracking-[0.2em] text-gold-500">What I saw</p></div><div class="px-6 pt-6 pb-3"><p class="font-dm-mono text-[0.68rem] font-bold uppercase tracking-[0.2em] text-gold-500">AI Observation</p></div></div><div class="grid md:grid-cols-[2fr_3fr]"><div class="not-prose flex flex-col gap-3 border-b border-zinc-200 px-6 pb-6 dark:border-zinc-700 [&amp;_*]:!m-0 md:border-b-0 md:border-r"><img alt="Handwritten meeting notes — incoming ideas, not my own" loading="lazy" width="1080" height="1080" decoding="async" data-nimg="1" class="w-full rounded border border-zinc-200 dark:border-zinc-700" style="color:transparent" srcset="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fyour-meeting-notes.7a75f833.jpg&amp;w=1080&amp;q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fyour-meeting-notes.7a75f833.jpg&amp;w=3840&amp;q=75 2x" src="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fyour-meeting-notes.7a75f833.jpg&amp;w=3840&amp;q=75"><p class="font-dm-mono text-[0.82rem] leading-relaxed text-zinc-500"></p><p>Meeting notes. Incoming ideas, not my own. A practitioner's instinct surfacing as one practical note in a sea of conceptual territory.</p><p></p></div><div class="not-prose flex flex-col gap-3 px-6 pb-6 text-sm leading-relaxed [&amp;_*]:!m-0"><img alt="AI diagram of meeting notes — incoming ideas mapped" loading="lazy" width="400" height="320" decoding="async" data-nimg="1" class="w-full" style="color:transparent" src="/_next/static/media/diagram-your-meeting-notes.30984bb4.svg"><p class="font-dm-mono text-[0.82rem] leading-relaxed text-zinc-500"></p><p>The final entry at the bottom has no connections. It arrived as a feeling, not a thought.</p><p></p><ul class="list-none space-y-1 p-0"><li class="relative pl-4 font-dm-mono text-xs leading-relaxed text-gold-500 before:absolute before:left-0 before:content-['·']">someone in someone else's world</li><li class="relative pl-4 font-dm-mono text-xs leading-relaxed text-gold-500 before:absolute before:left-0 before:content-['·']">practitioner's instinct surfaces</li><li class="relative pl-4 font-dm-mono text-xs leading-relaxed text-gold-500 before:absolute before:left-0 before:content-['·']">one idea arrived without connections</li></ul></div></div></div></div>
<div class="not-prose my-8 flex flex-col gap-3 border-l-[3px] border-zinc-900 bg-zinc-100 p-5 dark:border-zinc-300 dark:bg-zinc-800 [&amp;_*]:!m-0"><p class="font-dm-mono text-[0.68rem] font-bold uppercase tracking-[0.2em] text-gold-500">What AI saw: verbatim observations</p><div class="border-b border-zinc-200 py-2 font-dm-mono text-sm leading-relaxed text-zinc-600 last:border-b-0 dark:border-zinc-700 dark:text-zinc-400"><p><strong>On the first page:</strong> “The anchor is a date and a title. Orientation before thinking begins. What follows radiates outward without a predetermined shape.”</p></div><div class="border-b border-zinc-200 py-2 font-dm-mono text-sm leading-relaxed text-zinc-600 last:border-b-0 dark:border-zinc-700 dark:text-zinc-400"><p><strong>On the platform list:</strong> “'Do we care?' isn't uncertainty. It's discipline.”</p></div><div class="border-b border-zinc-200 py-2 font-dm-mono text-sm leading-relaxed text-zinc-600 last:border-b-0 dark:border-zinc-700 dark:text-zinc-400"><p><strong>On the meeting notes:</strong> “This person was in someone else's world, not their own, when they wrote most of this.”</p></div><div class="border-b border-zinc-200 py-2 font-dm-mono text-sm leading-relaxed text-zinc-600 last:border-b-0 dark:border-zinc-700 dark:text-zinc-400"><p><strong>On the final entry:</strong> “Unconnected, at the bottom. Arrived as feeling rather than thought.”</p></div></div>
<p>Here's the thing about handwriting: <strong>it leaves evidence your typed notes don't.</strong> You can't vary pressure on a keyboard. You can't drift toward one corner of a document because something felt peripheral. When you write by hand, you're making spatial and physical decisions you're not conscious of. Those decisions are information. Not about the content of your thinking, but about the shape of it.</p>
<p><strong>Digital notes are legible to everyone and revealing to no one</strong>, including you. They sit on a grid at the same weight, in the same font, with the same authority regardless of how certain or uncertain you actually were when you typed them. Handwriting doesn't lie that way. <strong>A lighter stroke is a lighter conviction.</strong> A circled word is a word your hand decided mattered before your brain caught up.</p>
<h2>Other people's notes</h2>
<p>Then I got curious. I wanted to see how AI would interpret other people's notes. So I asked around for handwritten pages. Same process, no context, just the image. Here's what Claude had to say.</p>
<h3>Person A</h3>
<div class="not-prose my-10 grid gap-0 border-y border-zinc-200 dark:border-zinc-700 md:grid-cols-[2fr_3fr]"><div class="not-prose flex flex-col gap-3 border-b border-zinc-200 p-6 last:border-b-0 dark:border-zinc-700 [&amp;_*]:!m-0 md:border-b-0 md:first:border-r"><p class="font-dm-mono text-[0.68rem] font-bold uppercase tracking-[0.2em] text-gold-500">What I saw</p><p class="text-lg font-bold text-zinc-900 dark:text-zinc-100">Person A</p><p class="border-b border-zinc-100 pb-3 font-dm-mono text-xs text-zinc-500 dark:border-zinc-700">Framework thinker · Handwritten</p><img alt="Person A's handwritten notebook — structured framework with feedback loops" loading="lazy" width="720" height="540" decoding="async" data-nimg="1" class="mb-4 w-full rounded border border-zinc-200 dark:border-zinc-700" style="color:transparent" srcset="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fperson-a-notebook.1223eb1b.jpg&amp;w=750&amp;q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fperson-a-notebook.1223eb1b.jpg&amp;w=1920&amp;q=75 2x" src="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fperson-a-notebook.1223eb1b.jpg&amp;w=1920&amp;q=75"><p class="font-dm-mono text-[0.82rem] leading-relaxed text-zinc-500"></p><p>Same format, different brain entirely. Everything has a container. Deadlines embedded in tasks, feedback loops built in.</p><p></p></div><div class="not-prose flex flex-col gap-3 border-b border-zinc-200 p-6 last:border-b-0 dark:border-zinc-700 [&amp;_*]:!m-0 md:border-b-0 md:first:border-r"><p class="font-dm-mono text-[0.68rem] font-bold uppercase tracking-[0.2em] text-gold-500">What AI saw</p><p class="text-lg font-bold text-zinc-900 dark:text-zinc-100">Person A · AI Observation</p><p class="border-b border-zinc-100 pb-3 font-dm-mono text-xs text-zinc-500 dark:border-zinc-700">Structure before content</p><img alt="AI diagram of Person A's notes" loading="lazy" width="400" height="320" decoding="async" data-nimg="1" class="w-full" style="color:transparent" src="/_next/static/media/diagram-person-a.02b34f3d.svg"><p class="font-dm-mono text-[0.82rem] leading-relaxed text-zinc-500"></p><p>The framework has feedback loops built in. The checklist has deadlines embedded in tasks. This person builds the container before they think inside it.</p><p></p><ul class="list-none space-y-1 p-0"><li class="relative pl-4 font-dm-mono text-xs leading-relaxed text-gold-500 before:absolute before:left-0 before:content-['·']">tasks contain tasks</li><li class="relative pl-4 font-dm-mono text-xs leading-relaxed text-gold-500 before:absolute before:left-0 before:content-['·']">shape decided in advance</li><li class="relative pl-4 font-dm-mono text-xs leading-relaxed text-gold-500 before:absolute before:left-0 before:content-['·']">two languages, one notebook</li></ul></div></div>
<h3>Person B</h3>
<p>Typed, mid-meeting. Structure attempted, not committed.</p>
<div class="not-prose my-10 grid gap-0 border-y border-zinc-200 dark:border-zinc-700 md:grid-cols-[2fr_3fr]"><div class="not-prose flex flex-col gap-3 border-b border-zinc-200 p-6 last:border-b-0 dark:border-zinc-700 [&amp;_*]:!m-0 md:border-b-0 md:first:border-r"><p class="font-dm-mono text-[0.68rem] font-bold uppercase tracking-[0.2em] text-gold-500">What I saw</p><p class="text-lg font-bold text-zinc-900 dark:text-zinc-100">Person B</p><p class="border-b border-zinc-100 pb-3 font-dm-mono text-xs text-zinc-500 dark:border-zinc-700">Mid-meeting capture · Typed</p><img alt="Person B's typed meeting notes — structure attempted, not committed" loading="lazy" width="812" height="1429" decoding="async" data-nimg="1" class="mb-4 w-full rounded border border-zinc-200 dark:border-zinc-700" style="color:transparent" srcset="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fperson-c-notes.88005ab8.jpg&amp;w=828&amp;q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fperson-c-notes.88005ab8.jpg&amp;w=1920&amp;q=75 2x" src="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fperson-c-notes.88005ab8.jpg&amp;w=1920&amp;q=75"><p class="font-dm-mono text-[0.82rem] leading-relaxed text-zinc-500"></p><p>The tool implied structure. The person tried to follow it. Neither fully won. The questions embedded mid-list are the most honest thing on the page.</p><p></p></div><div class="not-prose flex flex-col gap-3 border-b border-zinc-200 p-6 last:border-b-0 dark:border-zinc-700 [&amp;_*]:!m-0 md:border-b-0 md:first:border-r"><p class="font-dm-mono text-[0.68rem] font-bold uppercase tracking-[0.2em] text-gold-500">What AI saw</p><p class="text-lg font-bold text-zinc-900 dark:text-zinc-100">Person B · AI Observation</p><p class="border-b border-zinc-100 pb-3 font-dm-mono text-xs text-zinc-500 dark:border-zinc-700">Structure attempted, not committed</p><img alt="AI diagram of Person B's notes" loading="lazy" width="400" height="320" decoding="async" data-nimg="1" class="w-full" style="color:transparent" src="/_next/static/media/diagram-person-c.fa52e8de.svg"><p class="font-dm-mono text-[0.82rem] leading-relaxed text-zinc-500"></p><p>The tool implied structure. The person tried to follow it. Neither fully won.</p><p></p><ul class="list-none space-y-1 p-0"><li class="relative pl-4 font-dm-mono text-xs leading-relaxed text-gold-500 before:absolute before:left-0 before:content-['·']">questions land mid-list</li><li class="relative pl-4 font-dm-mono text-xs leading-relaxed text-gold-500 before:absolute before:left-0 before:content-['·']">categories don't fully hold</li><li class="relative pl-4 font-dm-mono text-xs leading-relaxed text-gold-500 before:absolute before:left-0 before:content-['·']">thinking still happening on page</li></ul></div></div>
<h3>Person C</h3>
<p>Same person, same tool. Two pages — one raw capture, one “thinking.” Typed on both.</p>
<div class="not-prose my-10 border-y border-zinc-200 dark:border-zinc-700"><div class="border-b border-zinc-200 last:border-b-0 dark:border-zinc-700"><div class="grid md:grid-cols-[2fr_3fr]"><div class="px-6 pt-6 pb-3 md:border-r md:border-zinc-200 md:dark:border-zinc-700"><p class="font-dm-mono text-[0.68rem] font-bold uppercase tracking-[0.2em] text-gold-500">Person C · Raw capture</p></div><div class="px-6 pt-6 pb-3"><p class="font-dm-mono text-[0.68rem] font-bold uppercase tracking-[0.2em] text-gold-500">AI Observation</p></div></div><div class="grid md:grid-cols-[2fr_3fr]"><div class="not-prose flex flex-col gap-3 border-b border-zinc-200 px-6 pb-6 dark:border-zinc-700 [&amp;_*]:!m-0 md:border-b-0 md:border-r"><img alt="Person C's raw typed notes — no headers, no bullets, placeholder title" loading="lazy" width="720" height="440" decoding="async" data-nimg="1" class="w-full rounded border border-zinc-200 dark:border-zinc-700" style="color:transparent" srcset="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fperson-d-raw.4116020a.png&amp;w=750&amp;q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fperson-d-raw.4116020a.png&amp;w=1920&amp;q=75 2x" src="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fperson-d-raw.4116020a.png&amp;w=1920&amp;q=75"><p class="font-dm-mono text-[0.82rem] leading-relaxed text-zinc-500"></p><p>The only typed sample closest to handwriting. No imposed structure, no ambiguity. What you're reading is the thinking, not the presentation of it.</p><p></p><ul class="list-none space-y-1 p-0"><li class="relative pl-4 font-dm-mono text-xs leading-relaxed text-gold-500 before:absolute before:left-0 before:content-['·']">no headers, no bullets</li><li class="relative pl-4 font-dm-mono text-xs leading-relaxed text-gold-500 before:absolute before:left-0 before:content-['·']">placeholder title untouched</li><li class="relative pl-4 font-dm-mono text-xs leading-relaxed text-gold-500 before:absolute before:left-0 before:content-['·']">tool built for polish — ignored</li></ul></div><div class="not-prose flex flex-col gap-3 px-6 pb-6 text-sm leading-relaxed [&amp;_*]:!m-0"><img alt="AI diagram of Person C's raw notes" loading="lazy" width="400" height="320" decoding="async" data-nimg="1" class="w-full" style="color:transparent" src="/_next/static/media/diagram-person-d-raw.6a13bd87.svg"><p class="font-dm-mono text-[0.82rem] leading-relaxed text-zinc-500"></p><p>The only typed sample closest to handwriting. No imposed structure, no ambiguity. What you're reading is the thinking, not the presentation of it.</p><p></p></div></div></div><div class="border-b border-zinc-200 last:border-b-0 dark:border-zinc-700"><div class="grid md:grid-cols-[2fr_3fr]"><div class="px-6 pt-6 pb-3 md:border-r md:border-zinc-200 md:dark:border-zinc-700"><p class="font-dm-mono text-[0.68rem] font-bold uppercase tracking-[0.2em] text-gold-500">Person C · "Thinking" mode</p></div><div class="px-6 pt-6 pb-3"><p class="font-dm-mono text-[0.68rem] font-bold uppercase tracking-[0.2em] text-gold-500">AI Observation</p></div></div><div class="grid md:grid-cols-[2fr_3fr]"><div class="not-prose flex flex-col gap-3 border-b border-zinc-200 px-6 pb-6 dark:border-zinc-700 [&amp;_*]:!m-0 md:border-b-0 md:border-r"><img alt="Person C's structured typed notes — bold headers, complete sentences" loading="lazy" width="720" height="455" decoding="async" data-nimg="1" class="w-full rounded border border-zinc-200 dark:border-zinc-700" style="color:transparent" srcset="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fperson-d-structured.69371269.png&amp;w=750&amp;q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fperson-d-structured.69371269.png&amp;w=1920&amp;q=75 2x" src="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fperson-d-structured.69371269.png&amp;w=1920&amp;q=75"><p class="font-dm-mono text-[0.82rem] leading-relaxed text-zinc-500"></p><p>This was submitted as thinking. But typed thinking isn't raw — backspace exists, autocorrect exists, the cursor waits. Every handwritten page in this study is unedited by definition. This one can't make that claim. That's not a flaw in the person. It's a property of the medium.</p><p></p></div><div class="not-prose flex flex-col gap-3 px-6 pb-6 text-sm leading-relaxed [&amp;_*]:!m-0"><img alt="AI diagram of Person C's structured notes" loading="lazy" width="400" height="320" decoding="async" data-nimg="1" class="w-full" style="color:transparent" src="/_next/static/media/diagram-person-d-structured.658e10ab.svg"><p class="font-dm-mono text-[0.82rem] leading-relaxed text-zinc-500"></p><p>Every line is complete. No questions, no abandoned directions, nothing written smaller because they weren't sure. Either this person thinks in finished thoughts — or the medium quietly cleaned it up before you got here.</p><p></p><ul class="list-none space-y-1 p-0"><li class="relative pl-4 font-dm-mono text-xs leading-relaxed text-gold-500 before:absolute before:left-0 before:content-['·']">no uncertainty visible</li><li class="relative pl-4 font-dm-mono text-xs leading-relaxed text-gold-500 before:absolute before:left-0 before:content-['·']">only conclusions survived</li><li class="relative pl-4 font-dm-mono text-xs leading-relaxed text-gold-500 before:absolute before:left-0 before:content-['·']">backspace is invisible but it was here</li></ul></div></div></div></div>
<h2>What I noticed</h2>
<p><strong>Handwritten notes don't have an audience.</strong> Nobody formats their thinking for a page nobody sees. Which means what ends up there is a direct, unfiltered translation of how a specific brain works. The arrows, the circles, the things written smaller because you weren't sure — that's all you.</p>
<p>So what happens to you when filtered through Notion, through AI suggestions, through AI dictation? Even the way we speak versus what we decide to keep for later in notes is decidedly different.</p>
<p>After thinking about all of this, I went back to my notebook. Same mess. Same arrows going nowhere obvious. But I stopped apologizing for it. Somewhere in those pages, <strong>my thinking is operating on a layer I'm not fully aware of.</strong> The notes are the evidence. I just hadn't looked at them that way before.</p>
<p>That's when I asked my 14 year old nephew if he takes handwritten notes. Not really, he said. I'm concerned <strong>there's a part of thinking that doesn't get to take shape</strong> without this alternative mode.</p>
<p>Anyone out there doing a study on this? Would love to see it.</p>]]></content:encoded>
            <author>tu@sideproject.com (Tu Pham)</author>
        </item>
        <item>
            <title><![CDATA[SaaS Co-ops? The future belongs to all of us, but only by choice]]></title>
            <link>https://sideproject.com/essays/saas-co-ops-the-future-belongs-to-all-of-us</link>
            <guid isPermaLink="false">https://sideproject.com/essays/saas-co-ops-the-future-belongs-to-all-of-us</guid>
            <pubDate>Tue, 31 Mar 2026 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>I joined Subvert.fm last night. Member #19235. <strong>It's a co-op: artists, labels, fans, workers all own a piece of it.</strong> The platform is in alpha. There's no guarantee it works. (Really hoping it does!!!)</p>
<figure class="not-prose my-8"><img alt="Subvert founding member #19235" loading="lazy" width="2000" height="1373" decoding="async" data-nimg="1" style="color:transparent" srcset="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fsubvert-member-19235.b5743194.png&amp;w=2048&amp;q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fsubvert-member-19235.b5743194.png&amp;w=3840&amp;q=75 2x" src="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fsubvert-member-19235.b5743194.png&amp;w=3840&amp;q=75"><figcaption class="mt-3 font-dm-mono text-[0.68rem] font-bold uppercase tracking-[0.2em] text-gold-500">Member #19235</figcaption></figure>
<p>I've loved Bandcamp for years. It's where I go for game soundtracks, for finding things that don't exist anywhere else. If you care about indie artists actually getting paid, it's still the best option: <strong>82 cents on the dollar</strong>, a real catalog, none of the algorithmic noise. But Bandcamp has been sold twice in three years, cut half its staff, and is now owned by a music licensing company most of its own users had never heard of. <strong>The people who built it with their trust didn't get a vote.</strong> It's still embedded on this site, because it still earns it.</p>
<p>I've been trying to pay more attention to the tech I use. Not just what it does for me, but what's actually going on inside it. <strong>Who owns it. Who benefits.</strong> What I'm quietly endorsing by showing up every day.</p>
<p>So when I found out about Subvert I joined. Then I went exploring.</p>
<p>First band I found was <a href="https://alpha.subvert.fm/zorz/zorz" target="_blank" rel="noopener noreferrer">ZORZ</a> — out of Zaragoza, deep underground electronic, cold and mechanical in exactly the right way. It hit like discovering industrial music on Wax Trax! in the late 80s. <strong>That feeling of stumbling onto something before it has a name.</strong> Before it's been explained to you. Jim Nash and Dannie Flesher were doing the same thing from a Chicago record shop: putting out Ministry and KMFDM and My Life With the Thrill Kill Kult before any of it was proven, because they heard something and decided that wasn't a reason to wait.</p>
<figure class="not-prose my-8"><img alt="ZORZ on Subvert.fm" loading="lazy" width="1200" height="975" decoding="async" data-nimg="1" style="color:transparent" srcset="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fzorz-subvert.a35cdabf.png&amp;w=1200&amp;q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fzorz-subvert.a35cdabf.png&amp;w=3840&amp;q=75 2x" src="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fzorz-subvert.a35cdabf.png&amp;w=3840&amp;q=75"><figcaption class="mt-3 font-dm-mono text-[0.68rem] font-bold uppercase tracking-[0.2em] text-gold-500">ZORZ — Subvert.fm</figcaption></figure>
<p>Member #19235. <strong>Already found something worth finding</strong>, and I'll be switching as soon as Subvert is public and has a great embedded player.</p>
<hr>
<p><em>Postscript: I recently opened a box retrieved from my mom's house that I hadn't touched since 1993. This was in it. A friend in Tampa writing to tell me Thrill Kill Kult is playing July 26, $10 cover. Some things don't change.</em></p>
<figure class="not-prose my-8"><img alt="Letter, June 1991" loading="lazy" width="2000" height="1499" decoding="async" data-nimg="1" style="color:transparent" srcset="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fthrill-kill-letter-1991.a45204cf.jpeg&amp;w=2048&amp;q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fthrill-kill-letter-1991.a45204cf.jpeg&amp;w=3840&amp;q=75 2x" src="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fthrill-kill-letter-1991.a45204cf.jpeg&amp;w=3840&amp;q=75"><figcaption class="mt-3 font-dm-mono text-[0.68rem] font-bold uppercase tracking-[0.2em] text-gold-500">Tampa, June 1991</figcaption></figure>]]></content:encoded>
            <author>tu@sideproject.com (Tu Pham)</author>
        </item>
        <item>
            <title><![CDATA[Spirograph, shapes, and the joy of dragging things around]]></title>
            <link>https://sideproject.com/essays/spirograph-shapes-and-drag</link>
            <guid isPermaLink="false">https://sideproject.com/essays/spirograph-shapes-and-drag</guid>
            <pubDate>Sun, 29 Mar 2026 00:00:00 GMT</pubDate>
            <content:encoded><![CDATA[<p>This started as a warm-up. I wanted to build something small that felt good to use. No product requirements, no user stories, just: <strong>I want to make a spirograph</strong></p>
<div role="region" aria-label="Interactive spirograph — click a shape and throw it to draw a pattern" class="not-prose relative my-10 overflow-hidden rounded-lg border border-zinc-200 dark:border-zinc-700" style="height:min(600px, 80vh);touch-action:none"><div class="flex h-full flex-col items-center justify-center gap-6 sm:gap-12 select-none"><div class="flex h-[120px] w-[120px] items-center justify-center rounded-full border border-dashed transition-all duration-200 border-zinc-300 dark:border-zinc-600" style="border-width:1px"><span class="pointer-events-none text-xs text-zinc-400">Drag or throw</span></div><div class="flex gap-6 sm:gap-10"><div role="button" tabindex="0" aria-label="Throw Penrose triangle to draw spirograph" class="h-16 w-16 cursor-grab transition-transform duration-150 hover:scale-110 focus-visible:scale-110 focus-visible:outline-2 focus-visible:outline-gold-500 active:cursor-grabbing dark:invert"><img src="/shape-abstruse.svg" alt="Penrose triangle" class="h-full w-full" draggable="false"></div><div role="button" tabindex="0" aria-label="Throw Isometric cube to draw spirograph" class="h-16 w-16 cursor-grab transition-transform duration-150 hover:scale-110 focus-visible:scale-110 focus-visible:outline-2 focus-visible:outline-gold-500 active:cursor-grabbing dark:invert"><img src="/shape-abstract.svg" alt="Isometric cube" class="h-full w-full" draggable="false"></div><div role="button" tabindex="0" aria-label="Throw Impossible star to draw spirograph" class="h-16 w-16 cursor-grab transition-transform duration-150 hover:scale-110 focus-visible:scale-110 focus-visible:outline-2 focus-visible:outline-gold-500 active:cursor-grabbing dark:invert"><img src="/shape-impossible.svg" alt="Impossible star" class="h-full w-full" draggable="false"></div></div></div></div>
<p class="not-prose -mt-6 mb-10 text-center font-dm-mono text-[0.68rem] font-bold uppercase tracking-[0.2em] text-gold-500">Play some music and watch — instant visualizer</p>
<h2>Where it started</h2>
<p>A single <code>index.html</code> file. Three simple shapes (circle, triangle, square), a dashed target ring, and a canvas. Drag a shape onto the ring, a spirograph starts drawing. Each shape triggers a different pattern. Click to reset. That was the whole thing. Vanilla HTML, CSS, JavaScript. <strong>No build step, no framework.</strong></p>
<p>It was the first thing I built for this site, before there was even a site. Just a standalone page to see if the idea worked.</p>
<h2>Making it physical</h2>
<p>The first version used browser drag-and-drop. You'd grab a shape and drop it on the target. It worked, but <strong>it felt mechanical</strong>. Like filling out a form. The interaction didn't match what was happening on screen.</p>
<p>So I slowed the spirograph down. Instead of the pattern appearing all at once, <strong>you watch it build line by line.</strong> The inner gear rolls visibly inside the outer ring. There's an arm, a pen point, a trail. It looks like the physical toy now. The one with the plastic gears and the ballpoint pens that always slipped.</p>
<p>Then I replaced the simple geometric shapes with something stranger. Three abstract forms from The Noun Project. A Penrose triangle, an isometric cube, an impossible star. <strong>They don't explain themselves.</strong> You pick one up and throw it.</p>
<h2>Throw, bounce, land</h2>
<p>That was the real change. Instead of dragging to a target, <strong>you click a shape and fling it.</strong> It bounces off the walls of the container. Ricochet physics, like a pinball, until it hits the outer ring. Wherever it lands, that's where the spirograph starts drawing from.</p>
<p><strong>The angle matters.</strong> Throw it to the right and the pattern starts from 3 o'clock. Throw it upward and it might bounce twice before landing at 11 o'clock. The entry point changes the visual experience even though the math underneath is identical.</p>
<p>There's almost no friction, so the shape keeps moving. If it slows down too much it nudges itself toward the center. It always finds the ring eventually.</p>
<h2>What each pattern does</h2>
<ul>
<li>The <strong>Penrose triangle</strong> draws a tight black pattern. The ratio between the outer and inner radii determines the number of petals.</li>
<li>The <strong>isometric cube</strong> produces a <strong>rainbow spirograph</strong>. The pen color cycles through the full spectrum as it draws.</li>
<li>The <strong>impossible star</strong> draws a <strong>pink trail</strong>. Its inner circle is the largest of the three, creating a wide, open pattern.</li>
</ul>
<p>The pattern stops when the pen returns to its starting point. One full cycle, then it holds.</p>
<h2>The math</h2>
<p>A hypotrochoid. Two circles, one fixed, one rolling inside it. A pen at a fixed distance from the center of the rolling circle traces the curve. The parametric equations:</p>
<p>x = (R - r) × cos(t) + d × cos((R - r)/r × t)</p>
<p>y = (R - r) × sin(t) + d × sin((R - r)/r × t)</p>
<p>Where R is the outer radius, r is the inner radius, d is the pen distance, and t is the angle. The pattern completes when t reaches 2π × lcm(R, r) / r.</p>
<p>Small changes in these three numbers produce wildly different shapes. <strong>That gap between simple inputs and complex outputs is the whole point.</strong></p>
<h2>How it was built</h2>
<p>I'm not a coder. This was built entirely through conversation with Claude Code — describing what I wanted by feel, watching what happened, and adjusting from there. No planning, no pseudocode, no architecture diagram. Just: “make it feel less mechanical” and “the shape should rotate like it's hitting the sides.”</p>
<p>There were three real versions. Here's what actually happened at each step.</p>
<h3>Version 1: The HTML page</h3>
<p>A single <code>index.html</code>. Three colored shapes — a blue circle, a black triangle, a gray square. Drag one onto a dashed ring. A spirograph draws instantly, 8 lines per frame. Click to reset. Tailwind via CDN. No build step. <strong>This was Claude's first pass — one prompt, no changes.</strong></p>
<div class="not-prose relative my-10 overflow-hidden rounded-lg border border-zinc-200 dark:border-zinc-700" style="height:min(600px, 80vh)"><div class="flex h-full flex-col items-center justify-center gap-12 select-none"><div class="flex h-[120px] w-[120px] items-center justify-center rounded-full border-[3px] border-dashed transition-all duration-200 border-zinc-300 dark:border-zinc-600"><span class="pointer-events-none text-xs text-zinc-400">Drop here</span></div><div class="flex gap-10"><div class="h-16 w-16 cursor-grab transition-transform duration-150 hover:scale-110" draggable="true"><svg class="h-full w-full" viewBox="0 0 64 64"><circle cx="32" cy="32" r="28" fill="#4A90D9"></circle></svg></div><div class="h-16 w-16 cursor-grab transition-transform duration-150 hover:scale-110" draggable="true"><svg class="h-full w-full" viewBox="0 0 64 64"><polygon points="32,4 60,60 4,60" fill="#444"></polygon></svg></div><div class="h-16 w-16 cursor-grab transition-transform duration-150 hover:scale-110" draggable="true"><svg class="h-full w-full" viewBox="0 0 64 64"><rect x="6" y="6" width="52" height="52" fill="#777"></rect></svg></div></div></div></div>
<h3>Version 2: Throw physics</h3>
<p>The site grew around it. The spirograph moved into React. Then four things changed:</p>
<ol>
<li><strong>Slowed it down.</strong> From 8 steps per frame to 1. Added the visible rolling gear, arm, and pen point. Now you watch it draw.</li>
<li><strong>Swapped the shapes.</strong> Replaced circle/triangle/square with abstract SVGs from The Noun Project. More mysterious, less literal.</li>
<li><strong>Added throw physics.</strong> Replaced drag-and-drop with click-and-throw. Mouse velocity on release determines the trajectory. Wall bouncing with reflection angles.</li>
<li><strong>Entry angle.</strong> Wherever the shape hits the outer ring becomes the starting angle. Same math, different visual depending on how you throw.</li>
</ol>
<p>Each change made it <strong>feel less like a demo and more like a toy.</strong></p>
<div class="not-prose relative my-10 overflow-hidden rounded-lg border border-zinc-200 dark:border-zinc-700" style="height:min(600px, 80vh);touch-action:none"><div class="flex h-full flex-col items-center justify-center gap-12 select-none"><div class="flex h-[120px] w-[120px] items-center justify-center rounded-full border border-dashed transition-all duration-200 border-zinc-300 dark:border-zinc-600" style="border-width:1px"><span class="pointer-events-none text-xs text-zinc-400">Drag or throw</span></div><div class="flex gap-10"><div class="h-16 w-16 cursor-grab transition-transform duration-150 hover:scale-110 active:cursor-grabbing dark:invert"><img src="/shape-abstract.svg" alt="Abstract shape" class="h-full w-full" draggable="false"></div><div class="h-16 w-16 cursor-grab transition-transform duration-150 hover:scale-110 active:cursor-grabbing dark:invert"><img src="/shape-abstruse.svg" alt="Abstruse shape" class="h-full w-full" draggable="false"></div><div class="h-16 w-16 cursor-grab transition-transform duration-150 hover:scale-110 active:cursor-grabbing dark:invert"><img src="/shape-impossible.svg" alt="Impossible shape" class="h-full w-full" draggable="false"></div></div></div></div>
<h3>Version 3: Shape-derived spirographs</h3>
<p>The version at the top. The shapes now determine the spirograph — spokes connect each shape's tips to the inner rolling circle, the shape rotates as if physically rolling against the wall, and the spirograph parameters are tuned to each shape's geometry. <strong>Three real steps: derive params from shape symmetry, detect tips at the pixel level, tune the angles by feel.</strong></p>
<h2>How long would this take without vibe coding?</h2>
<p>I asked myself: if I had to build this the traditional way — planning, writing code, debugging — how long would each version take?</p>
<table><thead><tr><th></th><th>V1 (HTML)</th><th>V1→V2 (physics)</th><th>V2→V3 (shape-derived)</th></tr></thead><tbody><tr><td><strong>Beginner</strong></td><td>2–3 days</td><td>1–2 weeks</td><td>wouldn't attempt</td></tr><tr><td><strong>Mid-level</strong></td><td>2–4 hours</td><td>1–2 days</td><td>1 day</td></tr><tr><td><strong>Expert</strong></td><td>30 min</td><td>2–4 hours</td><td>2–3 hours</td></tr></tbody></table>
<p>I did all three in one long session.</p>
<h2>Would a coder have done this differently?</h2>
<p>Probably. A coder would plan the architecture first. They'd name things properly from the start instead of renaming “circle” to “cube” halfway through after realizing the shape keys didn't match the actual shapes. They wouldn't have spent twenty minutes adjusting spoke angles by 2 degrees at a time while sending screenshots back and forth. They'd have read the SVG coordinate system once and gotten it right.</p>
<p>But they also might have over-specified the first version and never gotten to the third. <strong>The advantage of building by feel is that you skip the parts that don't matter and spend all your time on the parts that do.</strong> I never once thought about code architecture. I thought about whether the shape felt right when it hit the ring.</p>
<p>Would I have explained it better to Claude Code if I knew how to code? Here's what Claude Code said when I asked:</p>
<p><em>Claude Code's answer to this question:</em></p>
<p>Honestly, no. The best prompts I got from you were the ones that described feel: “it felt mechanical,” “the shape should rotate like it's hitting the sides,” “the star inner circle should be larger so we can see the spokes.” Those gave me clear direction without constraining the implementation. A coder might have said “increase the r parameter to 120” — which is precise but assumes they know the right value. You said “make it bigger” and we iterated until it looked right. The feel-first approach sometimes takes more rounds, but it never sends us down the wrong path for the wrong reason.</p>
<p>If anything, this exercise produced very satisfying technical screenshots at every step.</p>
<div class="not-prose my-8 grid grid-cols-2 gap-4"><div><img alt="Cube spirograph early in the drawing — rainbow trail just starting" loading="lazy" width="790" height="790" decoding="async" data-nimg="1" style="color:transparent" srcset="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fcube-screenshot-1.18607fbb.png&amp;w=828&amp;q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fcube-screenshot-1.18607fbb.png&amp;w=1920&amp;q=75 2x" src="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fcube-screenshot-1.18607fbb.png&amp;w=1920&amp;q=75"><p class="mt-3 font-dm-mono text-[0.68rem] font-bold uppercase tracking-[0.2em] text-gold-500">Cube — early rainbow test</p></div><div><img alt="Cube spirograph fully drawn — dense rainbow circles filling the ring" loading="lazy" width="800" height="800" decoding="async" data-nimg="1" style="color:transparent" srcset="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fcube-screenshot-2.b78415dc.png&amp;w=828&amp;q=75 1x, /_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fcube-screenshot-2.b78415dc.png&amp;w=1920&amp;q=75 2x" src="/_next/image?url=%2F_next%2Fstatic%2Fmedia%2Fcube-screenshot-2.b78415dc.png&amp;w=1920&amp;q=75"><p class="mt-3 font-dm-mono text-[0.68rem] font-bold uppercase tracking-[0.2em] text-gold-500">Cube — full pattern</p></div></div>]]></content:encoded>
            <author>tu@sideproject.com (Tu Pham)</author>
        </item>
    </channel>
</rss>