Jekyll Hello world, I’m Jekyll
Random Use Photoshop’s checkered canvas for loading images
Jekyll An introduction to Jekyll
Adobe Letterpressed InDesign icons
Life The tech behind our wedding
Work Working on TeuxDeux
Work Today is my first day at Destroy Today LLC
Adobe Today is my last day at Adobe
Random Depth of Field drawing in Instagram
Random Double tap to unlike in Instagram
Work Back on my own
Work Building the Pencil Page with FiftyThree
A chance encounter with a former co-worker leads to a quick freelance gig that would define my style of work for years to come.
Life Brooklyn Beta is people
Random Washing the Dishes and Other Moments of Thought
A rock in my parents’ backyard, eight months of acupuncture, and a household chore share a common thread of being the catalyst for thought.
Random The perfect GIF workflow using Dropbox and Alfred
Work Joining Oak
Redesign Redesigning with rules
Work Lessons learned in a year on my own
Life 2012 – A Year in Review
Cushion Restructuring the individual project page ↗
Cushion Project blocks ↗
Cushion Redesigning the homepage ↗
Cushion Multiple timelines ↗
Cushion Archiving and estimate differences ↗
Cushion Multiple financial goals ↗
Cushion Zooming in on the timeline ↗
Cushion Currency ↗
Cushion Preferences, accounts, and typeface change ↗
Cushion Sending out the first email ↗
Cushion Currency inputs, notifications, and invoice nets ↗
Cushion Dots and lines ↗
Cushion Calculating in the database and revealing tendencies ↗
Work Lessons learned on a 3-month sabbatical
Cushion Improved form UX ↗
Cushion Cushion is online ↗
Cushion Schedule timeline patterns ↗
Cushion A slimmer schedule timeline ↗
Cushion The schedule timeline ↗
Cushion Plugging in real data for the first time ↗
Cushion Transitions and project lists ↗
Cushion Death to modals ↗
Cushion The individual project page ↗
Cushion Estimated incomes and talks with other freelancers ↗
Cushion Statuses to lists and the paid beta ↗
Cushion The timeline ↗
Cushion Invoice terminology ↗
Cushion Modal forms ↗
Cushion Wiring the backend to the frontend ↗
Cushion Balancing design and dev ↗
Cushion Timecop, Monocle, and Vagrant ↗
Cushion Going with Ruby and Sinatra ↗
Cushion Ditching local-first and trying out Node.js ↗
Cushion Switching to AngularJS ↗
Cushion Building the Table with Vue.js ↗
Cushion Clients, Projects, and Invoices ↗
Work Building the Carousel website with Dropbox
I detail my experience working with Dropbox to build an adaptive website that provides a unique experience across mobile, tablet, and desktop.
Life On sabbatical
Cushion Introduction (to the Cushion journal) ↗
Cushion Cushion ↗
Work Building the Mailbox website with Dropbox
Not one to turn down a challenge, I accept a freelance gig with an identical deadline to another job with the same client. Feel the burn-out.
Talk Book Covers, Model Airplanes, and My Dad
An extended transcription of my CreativeMornings talk about my dad, his work, and how he turned me into the maker I am today.
Cushion Retention through useful features ↗
Cushion The onboarding checklist ↗
Cushion Spreading the word ↗
Cushion From beta to launch - the subdomain ↗
Cushion From beta to launch - sign up ↗
Cushion From beta to launch - messaging ↗
Cushion Launch ↗
Cushion Authenticating with 3rd party services ↗
Cushion Intro to integrations ↗
Cushion Inspiration vs imitation ↗
Cushion The emotional rollercoaster ↗
Cushion Designing project blocks ↗
Cushion Everything in increments ↗
Cushion Deleting your account ↗
Cushion Designing the subscription page ↗
Cushion Rewriting the timeline ↗
Cushion Funding Cushion ↗
Cushion Hiring a team of freelancers ↗
Cushion Taking a real break from work ↗
Cushion Slack as a notification center ↗
Cushion Document your features ↗
Cushion 300 ↗
Cushion Vacations ↗
Cushion Offering discounts ↗
Cushion Waves of traffic ↗
Cushion Less blogging, more journaling ↗
Work Building the Casper homepage
I collaborated with Casper to build the animations for their new homepage. In this post, I share the story from initial call to launch.
Cushion My typical week as a founder ↗
Cushion Building components in a sandbox ↗
Cushion Reactive time with Vue.js ↗
Cushion Visualizing daylight saving time ↗
Cushion Recording screencast GIFs ↗
Cushion Writing a job listing ↗
Cushion Using feature flags to run betas ↗
Cushion Our first company lunch ↗
Cushion How to embed Vue.js & Vuex inside an AngularJS app... wait what? ↗
Cushion The “Update Available” alert ↗
Cushion Improving readability with bigger fonts and higher contrast ↗
Cushion My design workflow ↗
Cushion Simplifying our build process and SSL with Cloudfront ↗
Cushion Restructuring an evolving app ↗
Realizing that a redesign doesn’t mean I need to start from scratch with everything, I reclaim the logo from the previous design to use on the new site.
Eager to build more than the blog, I write about bringing a new content model to the site in the form of an intro on the homepage.
Similar to the post itself, there’s not much to this description besides indicating that I replace the default favicon with my own.
Redesign RSS feed location
In this post, I second-guess the path to the site’s RSS feed and refactor it to support multiple feeds, which will most likely be overkill in the end.
Taking a break from visible progress, I implement TypeScript on the site as a way for me to finally learn what the big deal is all about.
Redesign Sideways progress
Rather than moving the needle further, I spend a night going down a rabbit hole that does leave me without much to show, but I still consider it progress.
A dozen posts into writing for the new site, I recognize a need for pagination and write about implementing it in Contentful.
After referencing another post in the form of a link, I find myself needing to build a custom renderer in Contentful.
A friend pointed out a mistake in an earlier post I wrote, so I implemented footnotes to allow for corrections while still maintaining the original writing.
In a move to improve readability, I adjust the leading on the site to provide more breathing room between lines of text.
With the discovery of the ch unit type in CSS and guidance on the ideal character-based line width, I set out to enforce a max-width on the site’s body copy.
Redesign Syntax highlighting
With an increasing number of code snippets in my posts, I introduce Prism.js to the site for much improved syntax highlighting.
Redesign WebP fallback on Safari
After fetching WebP formatted images from Contentful’s image API, I realize that Safari doesn’t support WebP and requires a fallback PNG.
Redesign Responsive images
A forgotten CSS style prevents the images on the site from resizing for mobile, but a new discovery of Contentful’s image API leads to the perfect max-width.
In order to maintain a chronologically aware blog, I add dates to posts and the RSS feed using the date-fns library.
After realizing that Contentful’s rich text renderer doesn’t include a renderer for assets, I create my own using Contentful’s image API.
Redesign Lighthouse, Now build env vars, and Nuxt manifest
To keep myself in check, I install a Lighthouse integration to score the site’s performance and accessibility.
Redesign Title and article links
With a description as short as the post itself, I write about adding a site title and links to the article titles.
Redesign RSS feed
After being nudged by the elders of the web, I implement an RSS feed for those who are still sour about the demise of Google Reader—myself included.
Redesign Contentful preview API hiccup
Neglecting to read the manual, I hit a snag and blame Contentful’s API before inevitably realizing that the problem exists between the keyboard and chair.
Redesign Hello World
In this inaugural post, I set out on an adventure to redesign my site while documenting its process along the way.
Life Burning Out and Finding Stability
After five years of running my own startup, I experience my first panic attack, which leads me to course correct my life in favor of good health and stability.
Life Focusing on self improvement
Cushion The new invoice page is live ↗
With only days before the SCA deadline, I launch the new invoice page with to be SCA-ready while also paving the way for more improvements.
Cushion Integration testing the invoice page with Cypress ↗
Wrapping up my work on the invoice page, I set up integration testing using Cypress to make sure that everything continues to work end-to-end.
Cushion Tidying up as you go ↗
Continuing to make progress on the invoice page, I talk about some of the ways I’m improving the codebase along the way.
Cushion A subsidized plan for 2021 ↗
A chat with a user leads me to consider a subsidized plan for the New Year to help folks through the pandemic.
Cushion Redesigning the invoice page for SCA with Stripe Elements ↗
I pause work on the account page to make sure Cushion’s invoice payment integration is ready for the SCA deadline.
Cushion Rethinking the pricing page ↗
In needing to redesign the pricing page for the new account section, I decide to rethink the structure of Cushion’s existing plans.
Cushion A dev’s troubleshooting journey ↗
An innocent bug report unfolds into a roller coaster ride of a troubleshooting journey.
Cushion Scaffolding the account page ↗
As I begin building Cushion’s new account page, I start by scaffolding a static version of it and building the components it requires.
Cushion Redesigning the account section for SCA with Stripe Billing customer portal ↗
With SCA regulation going into effect at the end of the year, I prioritize migrating to the Stripe customer portal, which means redesigning the account section.
Cushion Designing a new layout system ↗
After years and years of incrementally tweaking the design of Cushion, I take a holistic look at the layout system.
Cushion Redesigning the blog ↗
After redesigning Cushion’s homepage, I take the next step in migrating to Contentful by rethinking the blog.
Cushion Animating the new homepage hero ↗
To keep my mind busy while dealing with a tough time, I distract myself with Cushion’s new homepage animation.
Cushion Responsive images for different layouts ↗
While building Cushion’s new homepage, I go the extra mile to swap out better-fitting images for different breakpoints.
Cushion A flexible way of using Nuxt.js with Contentful CMS ↗
After migrating Cushion’s changelog to Contentful, I move onto the homepage, where I narrow in on an approach to compose pages entirely in the CMS.
Cushion Migrating the changelog to the Contentful CMS ↗
In my initial step towards migrating Cushion’s marketing site to Contentful, I start with the changelog.
Cushion Promoting invoicing to the main nav ↗
I reworked the main nav to include invoicing, which was met with a wave of thanks from users.
Cushion The next big rocks ↗
After launching Cushion’s new onboarding, I detail the next few items on my to-do list, which for once are not new features.
Cushion Onboarding is live ↗
A weekend turned into a month, but Cushion’s new onboarding is finally live. Instead of focusing on the launch itself, I talk through my favorite part.
Cushion Composable onboarding ↗
To provide a more pleasant codebase for Future Jonnie to inherit, I restructure the onboarding to be composable and easily testable.
Cushion Writing my own utility methods ↗
I decide to write a few utility methods myself, rather than relying on 3rd party library, and I’m glad I do.
Cushion Using a utility library vs building my own ↗
Torn between adding a dependency for a utility method or writing it myself, I talk through the pros and cons of both approaches.
Cushion A reminder to write ↗
Determined to launch thew onboarding flow, I forgot to write for a week and it shows.
Cushion The date picker component ↗
Continuing my work on Cushion’s onboarding flow, I build a new and improved date picker component.
Life My eye
Cushion Building components for the long run ↗
With my recent work on Cushion’s new onboarding flow, I take a meandering walk through the new components I built for it that are all typed and tested.
Cushion Investigating inflection points ↗
Stepping back to look at Cushion’s growth over its entire lifetime reveals a crystal clear moment when everything went south.
Cushion Recalibrating my estimates ↗
I start working on the new onboarding flow, but quickly realize it won’t be a weekend project.
Cushion A friendly onboarding flow ↗
As a first stab at onboarding, I design a flow that includes myself asking questions, which hopefully provides a friendly intro to the app.
Cushion Bringing back onboarding ↗
In an attempt to ease people into the app rather than pushing them out of the airplane, I decide to bring back a proper onboarding flow.
Cushion Rough sketches ↗
After feeling reluctant to reveal any design progress, I decide to bite the bullet and share a few rough sketches—no matter how uncomfortable it feels.
Cushion Flattening the nav ↗
Continuing the idea of the single click, I talk through a potential path to flattening the nav from multiple layers down to one.
Cushion Well, this is embarrassing ↗
Browsing through Cushion, I realize something strange. As I troubleshoot the anomaly, I discover an embarrassing truth.
Cushion Sending newsletters again ↗
I sent my first Cushion newsletter in over a year and a half, which sounds crazy, but nonetheless, it feels great to send them again.
Cushion Validating assumptions ↗
Before diving into analytics, I decide to spend time writing database queries that could validate some of my assumptions using existing data.
Cushion Intentional analytics ↗
After building Cushion so far based purely on assumptions and intuition, I finally start to think about using analytics to help guide me.
Cushion This app has good bones ↗
A thought-provoking conversation leads me to realize that Cushion is still solid and worth iterating on, instead of restarting from scratch.
Cushion Keeping API requests simple ↗
After establishing a new guiding principle to keep API requests simple, I describe how I could refactor a complex view that relies on a heavy API request.
Redesign Continue reading / Stay in the loop
While thinking through adding the ability for people to receive posts as emails, I took a detour and reworked the footer area for posts.
Life My week off
Nearing the end of my week off after the Stripe redesign launch, I reflect on what I ended up doing. Long story short, not much, and it was great.
Cushion A single click ↗
I discuss a pain point in the current Cushion involving the number of clicks it takes to get to where you need to go. What if it only took one?
Cushion Shaping Vuex through testing ↗
Cushion Excluding a folder from VSCode’s search (and disabling Jest’s generated coverage reports) ↗
Random 100vw and the horizontal overflow you probably didn’t know about
If you use 100vw and don’t check what your website looks like with scrollbars always visible, it most likely has a horizontal overflow issue.
Redesign Prefetch and better fetching
Cushion Retaining state with the router in a single page application ↗
Cushion Custom focus rings using :focus-within ↗
Cushion Testing v-on="$listeners" in Vue.js ↗
Redesign Reply link in RSS feed posts
Cushion Vue + ESLint + Prettier conflicts ↗
Stripe The new Stripe.com
Cushion Speeding up Jest tests with --runInBand ↗
Cushion Moving the Cushion Journal to my blog ↗
Redesign Filter by category
Cushion Updating Sentry ↗
Redesign Should I email my posts, too?
Cushion Updating Skylight and dealing with ActiveSupport ↗
Cushion Reducing Heroku CI time by 35% for an extra penny ↗
Cushion The build failed, but I swear it wasn’t me ↗
Cushion A hiccup with subdomain routing ↗
Cushion Upgrading to Ruby 2.7.1 ↗
Cushion QA’ing pull requests using Heroku Review Apps ↗
Cushion Subdomain routing in Sinatra ↗
Cushion Redirecting the Heroku “Open app” button to a custom domain ↗
Cushion Reloading Ruby with Sinatra::Reloader ↗
Cushion Exploring a modern Cushion ↗
Random Learning Go
Cushion Migrating the Cushion website to S3 to avoid dealing with SSL ↗
Redesign Contentful asset URLs
Life The Ace Hotel & Swim Club date shake
Life Recurring dream
Life Learning not to speedrun
Life Produce for days
Life Chef Collective
Life A new game
Random Checkered pattern for loading images, revisited
Almost a decade after my post about using Photoshop’s checkered pattern for loading images, I revisit the code to refactor it for the modern web.
Stripe One year at Stripe
Redesign Blog index sticky nav
Redesign Contentful mishaps
Redesign Short-form vs long-form posts
Life Red Hook cat lot
Life The missed vacation
Life The virus’s ripples
Life Learning Figma with a full stomach
Life Depression, chili, and the bathroom sink
Life Half-gallon margaritas
Life Laundry in the eleventh hour
Life The mirrorless webcam
Life Cooking from memory
Life Working from home for good
Life Dystopian grocery shopping
Life A long walk through Red Hook
Life One week without Twitter and Instagram
After one week without Twitter and Instagram, I wrote about my experience so far, which has been so beneficial that I wonder if I’ll ever reinstall them.
Life Deleting Twitter and Instagram from my phone
I feel unhealthy about how I use Twitter and Instagram, scrolling through them only to feel caught up, so I’m deleting both off my phone and taking a break.
Redesign Casper homepage section
While embedding the fixed-size Casper animation on the homepage, I face the technical challenge of gracefully scaling the animation on smaller viewports.
Redesign Blog index
With the goal of improving the UX of the blog’s index, I redesign the layout for easier skimming over the entirety of the blog and better organizing of posts.
Redesign Stripe homepage section
Initially about the Stripe section of the homepage, this post quickly diverges into a tirade about frameworks and how vanilla JS is much more future-proof.
Redesign Article pagination
After realizing that my articles lead to a dead end after reading, I describe how I added pagination in the form of links to adjacent articles.
Redesign Context-aware logo
This post describes the technical workings of the anchored DT logo, which changes color based on the homepage section being scrolled through.
Redesign Homepage concept
Once I had enough time to come down after launching the homepage, I write about the concept of embedding all of my scroll-based animations onto one page.
Instead of accompanying the launch of the new homepage with a lengthy process post, I preferred to simply announce the page and enjoy it being out there.
In preparation for the launch of the new redesign, I walk through migrating blog posts from the previous site and flipping the switch to the root domain.
Redesign Centered layout
This is a quick post about giving into the centered layout after months of enjoying the classic left-aligned layout.
Redesign Contact links
After realizing the site didn’t include any way of reaching me, I add Twitter and mailto links to the header.
Cushion Quick launches after a big launch ↗
After launching the Schedule timeline beta, I’m able to easily launch a handful of smaller releases to keep progress going.
Cushion The new Schedule timeline is in beta! ↗
To get folks to start testing the new Schedule timeline early, I released the initial beta this weekend.
Cushion Zooming into the schedule timeline ↗
With the schedule timeline nearing a beta launch, I take a couple more weeks to sneak zooming into the feature set.
Cushion Flipping the schedule timeline ↗
In an unexpected moment, I decide to try vertically flipping the new schedule timeline, so projects stack from the top.
Cushion Handling timeline labels ↗
Determined to always display labels on the new schedule timeline, I detail all the edge cases I’ve gotten myself into.
Cushion Visualizing projects in the new schedule timeline ↗
Now that I have a canvas for the new schedule timeline, I need to fill it with projects.
Cushion A freeform scrolling timeline ↗
After thinking through a modern schedule timeline, I start by enlarging the timeline to full-page and adding freeform scrolling.
Cushion Exploring a modern schedule timeline ↗
Taking a break from the Clients section, I get a burst of inspiration thinking about scheduling.
Cushion Revisiting the UX for client notes ↗
Continuing work on the new Clients section, I revisit client notes, but with a few UX improvements.
Cushion Overflow shadows using the Intersection Observer API ↗
Improving a upon the overflow shadows in Cushion, I replace scroll events with the Intersection Observer API.
Cushion Addressing beta feedback for the new Clients section ↗
After rolling out the new Client section to a few dozen beta users, I start applying their feedback.
Cushion Upgrading to Vue 3 ↗
While making forward progress with the new Clients section, I take a break to upgrade the new codebase to Vue 3.
Cushion A Safari performance issue and other stresses ↗
An already stressful time is made even more stressful by a Safari performance issue with nested grids.
Cushion Time period filter and totals for the Clients section ↗
With the Clients section beta up and running, I launch my first incremental update.
Cushion A video call with a friend about marking projects as paid ↗
A video call with a friend provides some interesting insight into a potential direction for restructuring the app.
Cushion The new Clients section is now in private beta ↗
After a heads-down week, I managed to reach the first milestone in releasing the new Clients section—private beta.
Cushion Stabilizing PostgreSQL memory issues with pgbouncer ↗
In an update of the database memory saga, I discover pgbouncer, which puts a stop to the constantly climbing memory woes.
Cushion A top-level “Clients” section ↗
With the sidebar navigation ready to deploy this weekend, I get an early start on the top-level “Clients” section.
Cushion Improving the sidebar nav ↗
After regretting, but living with, the skinny sidebar nav of obscure icons, I finally set a course to improve its UX.
Cushion Sending blog posts as emails - Part 2 ↗
Following up on the initial proof of concept, I build the complete system to send journal posts as emails.
Cushion Sending blog posts as emails ↗
In an effort to grow readership, while also prototyping an idea, I start building a system to email my posts.
Cushion Sticky line item totals ↗
Putting the final touches on the invoice form, I apply a sticky behavior to the line item totals.
Cushion Little details: Overflow shadows ↗
I spend extra time getting a little detail right by tying shadows to whether the underlying content has overflow.
Cushion Redesigning the flow for importing tracked time into invoices ↗
With the last remaining to-do on my list for the new invoice form, I tackle the flow for importing tracked time.
Design Town Turning my IKEA desk into a motorized standing desk
After realizing standing desks are actually affordable now, I assemble my own using an IKEA countertop.
Cushion A week of cleanup ↗
With the inline forms behind me, I spend a week cleaning up the codebase with a focus on Cushion’s form states.
Cushion Building the inline form system ↗
After detailing how I planned to build inline forms in Cushion, I went ahead and built the first one for creating clients inline.
Cushion Inline forms and the weight of the next big task ↗
In between big tasks, I distract myself with smaller tasks until I’m ready to finally face it—inline forms.
Cushion Designing a breadcrumbs component ↗
Chopping away at the new invoice form, I designed and built a new component for breadcrumbs.
Cushion Thinking about a “test mode” ↗
Aggravated by people signing up with no real intention to use Cushion leads me to consider a “test mode” where they can try the app without signing up.
Cushion Redesigning the invoice line item footer ↗
While redesigning the invoice form, I share the decision-making behind the design of the new line item footer.
Cushion Migrating CI to GitHub Actions ↗
Frustrated with Heroku, I start migrating away from it, beginning with continuous integration.
Cushion Troubleshooting the database upgrade ↗
Upgrading Cushion’s database leads to a week of troubleshooting performance issues.
Cushion Upgrading the production database ↗
After receiving an email from Heroku to upgrade Cushion’s database, I upgrade Cushion’s database.
Cushion 7 years old ↗
With Cushion reaching the 7-year mark, I reflect on its life and plot a course for its future.
Cushion Thinking through a new invoice form ↗
At the fork in the road, I choose the invoice form as the next step in renovating Cushion, including a long-awaited list of improvements.
Cushion The calm after the sprint ↗
With a couple big launches behind me, I think about what to tackle next or whether I need to pick a direction just yet.
Cushion The new account page is live ↗
After launching Cushion’s new invoice page last week, I launch the new account page this week with a ton of other goodies.
Cushion “Software” with a capital “S” ↗
I hit a roadblock designing a UI that didn’t excite me, so I decide to take a step back and rethink a more personalized design.
Cushion Adding hotkey labels to the UI ↗
After taking a short break to collect myself, I eased back into work with a low-priority feature that I’ve been itching to add for a while.
Cushion Moving & resizing workloads in the timeline ↗
While building the drag & drop interaction for workloads, I accidentally created the coolest interaction I’ve ever made.
Cushion Editing workloads in the timeline ↗
After taking a couple weeks off to move into our new home, I’m back in the saddle with creating and editing workloads.
Cushion Vacations in the timeline ↗
To continue reaching feature parity with the existing schedule view, I added vacations to the new timeline.
Cushion Nested modal drawers with parallax ↗
Over the weekend, I ate the broccoli and built a nested drawer system, but ended up with a delightful parallax effect.
Cushion The evolution of a tooltip design ↗
The full circle journey of designing a tooltip that’s both simple and useful.
Cushion Estimated workloads in the schedule timeline ↗
After visualizing tracked time, I jumped from the past and into the future to visualize estimated workloads.
Cushion Total tracked time in the schedule timeline ↗
Now that Cushion can visualize tracked time, the next step is to combine tracked time and highlight when you overworked yourself.
Cushion Lazy loading tracked time in the schedule timeline ↗
After being close to launching tracked time in the schedule timeline beta, I decide to spend an extra week adding lazy loading.
Cushion Visualizing tracked time in the schedule timeline ↗
Straying from the plan to bring the timeline to 1:1 feature parity with the existing timeline, I visualize tracked time.
Cushion Duplicating an invoice ↗
I take a short break from the timeline beta to launch the ability to duplicate an invoice. No big deal.
Cushion Grouping and archiving projects in the schedule timeline ↗
On the new path of pursuing a list-based layout, I group the projects by list and add an archive filter.
Cushion One step back, two steps forward ↗
Foreseeing a problematic future with the stacking layout, I rethink the direction and end up down a better path.
Cushion Project actions in the Schedule timeline beta ↗
After adding the ability to add and edit projects in the Schedule timeline, I implement more detailed interactions with project actions.
Cushion Creating a project via form in the schedule timeline ↗
Back to working on the app, I take the leap into creating projects, but via form first instead of click & drag.
Cushion New year, new homepage ↗
I spend my holiday break bringing more fun to the Cushion homepage with a new design, full of illustrations and animations.