Kettlebells, Shakespeare, and Stews

A bowl of North African bean stew with visible peppers, yogurt, and fennel fronds visible.

I had such a hard time working out from home in 2020. I bought a pull up bar, a pair of dumbbells, and a set of resistance bands, but I couldn’t get the habit of exercising to stick. I’ve been attending classes for so long that I didn’t really know how to work out on my own. But now that I’m vaccinated, I’ve started attending kettlebell classes at a nearby Muay Thai gym, and I’m feeling much stronger than I used to and I’m really enjoying it. I never really used kettlebells in the past, and it blows my mind how versatile this cannonball is.

I’ve been going out more often these days, too. Recently, I went out to see a live Shakespeare play for the first time called Pericles, Prince of Tyre. It was really fun to watch. The actors were so talented and animated. And it was free! It’s also impressive that they also did aerial gymnastics at the same time.

Clark Park before the show starts.
Clark Park before the show started.

Other than that, I got to make my favorite stew this week: North African bean stew. It’s pretty simple, but it does take a bit of time and requires a bit of mise en place. It’s definitely worth making, though.

A bowl of north african bean stew with visible peppers, yogurt, and fennel fronds visible.
A bowl of North African bean stew with visible peppers, yogurt, and fennel fronds visible.

Blocking Facebook Embeds

Screenshot showing the warning message design.

A few months ago, I got to work on the designs for blocking embedded content from Facebook. This can be embedded videos, comments, posts, pages, groups, and login buttons on the websites that you visit.

This is greatly limits what Facebook can learn from you as you browse the web, and it’s also convenient to unblock if you’d like to view the content. Here’s what it looks like:

The design showing a blocked Facebook content with text saying, "DuckDuckGo blocked this Facebook video"

There's a button that says "Unblock video" as well.
The design showing a blocked Facebook video.

The login flow is a little different. We prominently show you that the login button is blocked, and we also tell you about our limitations when you do log in with Facebook.

A login button that shows a warning that says, "Facebook tracks your activity on a site when you use them to log in."

A prompt that says, "Once you're logged in, DuckDuckGo can't block Facebook content from tracking you on this site."
A Facebook login button that shows a warning on hover and a prompt that tells you about our blocking limitations once you log in.

It took a lot of user testing and even more design variations, but we ultimately landed on simple, unobtrusive messages so that it gets out of the way of what people are doing. Super happy about this—I hope you can try it out yourself using the extension!

Some love from users:

Hello, @DuckDuckGoUX

A screenshot of the Twitter post with text that says: "I like to think about my design work as making the invisible visible, making tools that help empower people."

I recently recorded a clip about why I love working as a product designer at DuckDuckGo, and it was just posted on the design team’s Twitter account. I just used an iPhone to record it, so I’m glad that it turned out well!

A lot of websites and apps track your behavior across the web, so I’m really grateful that I’m able to help build tools that fight pervasive tracking and surveillance capitalism online.

The post can be found on

Digital Spring Cleaning

A screenshot of this website.

I did some reorganizing on this website, and I think I’m pretty happy about it! The biggest thing I did was merging both and I’ve been maintaining separate WordPress sites for my professional and private blogs, but it was a pain because I had to make sure that I copy any plugin or theme changes from one server to the other.

I figured that it would be much easier to merge the two and simply label my personal updates as #personal. I think I like this more because the site is now a better representation of me now that it has both personal and professional content. It’s also easier to share with other people: just go to to see what I’m up to.

Simplifying my website felt great and it gave me the energy to cut down on some of the hosting software and services that I no longer need:

  • I was able to downgrade Cloudron (a tool for self-hosting websites) to the free tier now that I got to remove an extra WordPress site. This will save me $180 per year.
  • I also cancelled my second Akismet subscription (a service that blocks spammy comments) since I’m only running one WordPress site. This saves me $18 per year.
  • I downgraded to a smaller server on Hetzner (a hosting company) as well and this saves me €132 or $160 per year.

That’s $358 of savings a year! It looks like reorganizing pays off.

Trip to Mehoopany, PA

Finn the Dog in the Forest

Last week, we booked a yurt in Mehoopany, PA, and we stayed there for a couple of days. It felt really good to spend some time in the woods and be out of the city. We also made sure to pick a spot that didn’t have any electricity so that we’re forced to disconnect and unhook ourselves from the screen.

There was nothing to do but to sleep, lounge around in a hammock, and read a book (I started reading Dune on this trip.) It was bliss.

I felt relaxed and present.

File Sharing Setup

A drawing of a puffer fish floating in the sky.

When Firefox Send shutdown, I started running my own instance of NextCloud to send files to people. It worked as expected, but it also felt slow. It felt like I was using a website that just groggily woke up from a nap whenever I logged into it.

I figured that maybe I could replace it with something leanerespecially since I felt like I didn’t need a lot of the features that NextCloud offered. I’ve recently been learning how to set up static sites on OpenBSD and it occurred to me that I could use OpenBSD’s built-in HTTP server to send files to people.

Setting up the Server

I went through the same process that I listed in my notes on setting up an OpenBSD server using httpd. You can use any other web server, but I love how simple it is to setup httpd.

Changing Write Permissions

I wanted to be able to write in the /var/www/htdocs/ as a normal user, so I changed the permissions to be owned by my user instead of root:

$ doas chown -R jag:jag /var/www/htdocs/

Easily Uploading Files

I don’t want to copy files manually to the remote server using the command line every time I wanted to send a file, so I set up Cyberduck to connect to my server using SFTP. I bet Transmit would work well too if you’re on macOS!

A screenshot of Cyberduck showing some of my remote files.

It was relatively easy to set up, but a bit intimidating. I needed my private SSH key, SSH password, my username, and the server’s IP address. Now I can drag and drop files into the server without touching the terminal.

I also added a few conveniences:

  • I set Cyberduck to go into /var/www/htdocs/ every time I connected to my server.
  • I added the URL of my server so that I could right click and copy the URL of any file.
A screenshot of my settings on Cyberduck showing the preferred path and web URL options.

And we’re done! Now I can send files and even host little “pens” for demos. Here are some examples:

Visiting Family

Snow-covered ground and trees just outside my parent's place.

I’m grateful that I got to visit my family this weekend. I haven’t seen them in over a year, so I’m glad that I was able to spend some time with them. Even though they’re only a two-hour drive away, I wanted to wait until we’ve gotten our vaccinations.

So now that both my girlfriend and my family have received their shots, I’m not that anxious about visiting anymore. Plus, I’m also pretty lucky to have a car. Even though I’m a fan of public transit, I don’t think I would’ve visited if I had to take the bus or the train.

A view from outside my parent’s place.

Tiny Generative Art Template

A screenshot of Windows Terminal that shows the directory structure of the project.

I’ve been using canvas-sketch ever since I started learning generative art back in November. It’s an incredibly useful tool for creating a new project, setting up a local server, and saving my artwork to disk. The only issue that I have with it is that it comes with a lot of dependencies that I don’t think are necessary for the kind of art that I do.

So I thought that I could take a stab at creating a minimal generative art template that only includes the things that I need. This is is how it works:

Screencast showing a demo of the project. You can try it out yourself here: ~jagtalon/generative-art-template

It’s not a zero-dependency template, but as long as you have CoffeeScript and Browsersync installed, you should be good to go. To start a new project, all you need to do is:

  1. Download or clone the template.
  2. Run ./ (runs the CoffeeScript compiler)
  3. Run ./ (runs the Browsersync server)

And you’re good to go! The two most important files in it are index.html and

  • 💻 index.html is a barebones HTML file that lets me view and save the artwork. It has a little bit of CSS that makes the Canvas responsive (I often work with large 3600×5400 images!) and a little bit of JavaScript that lets me download the art.
  • 🎨 is where I draw. It’s written in CoffeeScript, and it’s compiled to JS. I’m using it as a JavaScript module so that I can easily import libraries that are both local (like my little Canvas API wrapper called and remote (like NPM modules on Skypack).
Screencast showing how short the index.html and files are.

And that’s it! and are set up to watch the files for any changes, so there’s no reloading involved once these two are running.

Of course, I could get really lean by removing the dependency on CoffeeScript, but I personally enjoy working with this language so I decided to include it. If you’re interested in tweaking the setup, feel free to fork the project and modify the template to your needs! You can find the repository on Sourcehut.

Long-Exposure Art

A photo of my night sky art on my table. There's also a toy dog beside it for scale.

I’ve been fascinated with long-exposure shots of the night sky recently (like this one), so I thought it would be fun to emulate that effect on <canvas>. I assumed that it would take me a while to figure it out, but the algorithm turned out to be surprisingly simple!

The first thing I noticed was that each “star trail” is basically a small segment of a circle, so I figured that I’d be using the arc() method a lot. After staring at different long-exposure photos, I also noticed that the star trails grow in length as it moves farther away from the center of the spiral. This told me that the angle that I’ll use for the arc will probably be constant throughout the artwork. The only thing that needed to change was the radius of that arc.

But how do I draw multiple arcs across the canvas? My first solution was to generate random x-y coordinates all over the page and then get the distance between (0, 0) and (x, y) using Math.hypot(). I then created an arc for each point using the distance as its radius and then spun it around to a random angle using rotate(). It looked something like this in CoffeeScript:

# For each point:
# 1. Find the distance between (0,0) and (x,y)
# 2. Create an arc with constant theta
# 3. Rotate it to a random angle (Math.random() * 2π)
drawStarTrails = (x, y) ->
    context.arc 0, 0, Math.hypot(x, y), 0, theta
    context.rotate Math.random() * 2 * Math.PI

# Draw random x-y coordinates
drawStarTrails(Math.random() * width, Math.random() * height) for n in [1..1000]

But then I realized that I didn’t need to find the distance between (0, 0) and a random point at all. I could just plug in a random radius and I’d get the same effect:

# For each iteration:
# 1. Find a random radius.
# 2. Create an arc with constant theta
# 2. Rotate it to a random angle (Math.random() * 2π)
drawStarTrails = () ->
    context.arc 0, 0, Math.random() * width, 0, theta
    context.rotate Math.random() * 2 * Math.PI

# Create the star trails
drawStarTrails() for n in [1..1000]

And that was it! Now it took me a couple of hours fiddling with different colors, gradients, angles, stroke widths, and the number of arcs to get it to look right (the final version has 9000 arcs!), but this project reminded me how simple rules could generate something that looks complex. It’s honestly one of my favorite things about generative art.

You can find the complete source code on Sourcehut. You can also get prints in digital and physical formats (if it’s in stock) here 🖼.

This is the final version of the artwork. You can find the source code here if you’d like to read the whole program or make modifications yourself.

Filipino Food We’ve Been Making

A bowl of pancit with squid in it.

Adobong Pusit Pancit

Andrea found this adobong pusit pancit recipe from Bon Appétit over the holidays, so we thought it would be fun to try making it ourselves. Pancit is a rice noodle dish, but I’ve never had it with squid and cuttlefish ink. It was delicious.

A bowl of pancit with fried squid and green onions.

Arroz Caldo

Arroz caldo is what our family would eat during Christmas and New Year. It’s easy to make, it’s cheap, and it’s great when it’s cold out. Arroz caldo is rice porridge with chicken and ginger. You can find the recipe that we used here.

A bowl of arroz caldo. Don’t forget to top it off with fried garlic.


My favorite Filipino candy is probably yema. I love the hard exterior and the custard-y insides of this candy. It was easy to buy yema in the Philippines because it’s a common street food, but I’m definitely not running into it in Philadelphia. So we tried making it ourselves. It was tasty, but it unfortunately didn’t have the texture that I was looking for. I’ll have to try making it again next time.

Yema is a custard candy made with egg yolks and condensed milk. You can find the recipe that I used here.