<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="/rss/pretty-feed-v3.xsl" type="text/xsl"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Ky Decker</title><description>Dispatches from the world wide web.</description><link>https://ky.fyi</link><item><title>Mapping where districts start and end</title><link>https://ky.fyi/posts/boundaries-map</link><guid isPermaLink="true">https://ky.fyi/posts/boundaries-map</guid><description>Helping BetaNYC map and query New York City&apos;s various civic boundaries.</description><pubDate>Tue, 13 Feb 2024 05:53:27 GMT</pubDate><content:encoded>&lt;p&gt;import ProjectInfo from &quot;../../../components/ProjectInfo.astro&quot;;
import zhi from &quot;./zhi.jpeg&quot;;&lt;/p&gt;
&lt;p&gt;&amp;lt;ProjectInfo
collaborators={[
{
name: &quot;Zhi Keng He&quot;,
url: &quot;https://github.com/zhik&quot;,
img: zhi,
},
]}
timeline={{
start: &quot;July 2022&quot;,
end: &quot;August 2022&quot;,
}}
tech={[&quot;Mapbox&quot;, &quot;Svelte&quot;, &quot;Tailwind&quot;]}
roles={[&quot;Research&quot;, &quot;Product Design&quot;, &quot;Engineering&quot;]}
repo=&quot;betanyc/nyc-boundaries&quot;
website=&quot;https://boundaries.beta.nyc&quot;
/&amp;gt;&lt;/p&gt;
&lt;h2&gt;Background&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://beta.nyc/&quot;&gt;BetaNYC&lt;/a&gt; is a non-profit civic tech organization which builds tools and hosts public events to increase access to civic data and demystify government processes. I joined BetaNYC for 8 weeks during Summer 2022 as a Civic Innovation Fellow.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure&amp;gt;
&lt;img src=&quot;./manhattan-municipal-building.jpg&quot; alt=&quot;A low-angle shot of the Manhattan Municipal
Building.&quot; /&gt;
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;BetaNYC operates out of the Manhattan Municipal Building at 1 Centre
Street.&lt;/strong&gt; Technologists work alongside urban planners and other city
professionals. Photo by Mattia Panciroli via
&lt;a href=&quot;https://flic.kr/p/bPBHUc&quot;&gt;Flickr&lt;/a&gt;, 2012.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;h2&gt;The Challenge&lt;/h2&gt;
&lt;p&gt;Every day, you cross dozens of invisible borders: city council districts, school districts, police precincts, fire battalions, senate districts, zip codes, and more. These borders, although invisible, affect your life in important ways. Who collects your trash? Who represents you? Who arrives to care for you if you&apos;re injured? To answer these questions, it helps to know exactly where boundaries begin and end—and how they overlap.&lt;/p&gt;
&lt;p&gt;BetaNYC maintains an open source web app called &lt;a href=&quot;https://boundaries.beta.nyc/&quot;&gt;NYC Boundaries Map&lt;/a&gt;. First launched in 2018, the Boundaries Map allows anyone to view and explore overlapping jurisdictional boundaries within the city. The map is commonly used by city council staff and community boards in order to direct feedback from constituents to the correct department.&lt;/p&gt;
&lt;p&gt;The Boundaries Map helps answer questions like, &quot;which school districts does this community board serve?&quot;, &quot;which sanitation district do I contact about the trash at 2nd Avenue and East 14th Street?&quot;, and &quot;what police precinct am I in right now?&quot;&lt;/p&gt;
&lt;p&gt;The map was not pleasant to use.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure&amp;gt;
&lt;img src=&quot;./boundaries-map-initial.png&quot; alt=&quot;The NYC Boundaries Map as of June 2022.&quot; /&gt;
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;The original Boundaries Map.&lt;/strong&gt; 13 separate boundaries render with 13
separate border colors and labels. A rainbow spaghetti of geographic data.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;Working together with &lt;a href=&quot;https://github.com/zhik&quot;&gt;Zhi&lt;/a&gt;, we noted several usability issues:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Toggling on more than two districts quickly made the map illegible.&lt;/li&gt;
&lt;li&gt;Boundaries on the map itself were not interactive.&lt;/li&gt;
&lt;li&gt;The map&apos;s implementation in &lt;a href=&quot;https://leafletjs.com/&quot;&gt;Leaflet&lt;/a&gt; resulted in rasterized borders and labels, which looked blurry on HiDPI screens.&lt;/li&gt;
&lt;li&gt;Viewing overlaps required a complex sequence of &quot;querying&quot; boundaries by selecting an administrative region and then selecting which district to intersect with, and the query itself was slow to execute.&lt;/li&gt;
&lt;li&gt;The map required frequent manual zooming and panning, since it did not adapt automatically to queries.&lt;/li&gt;
&lt;li&gt;Searching for an address required pre-selecting a borough.&lt;/li&gt;
&lt;li&gt;Viewing additional metadata about a district required leaving the app and searching Google.&lt;/li&gt;
&lt;li&gt;The app was desktop-only.&lt;/li&gt;
&lt;li&gt;Visual design polish was generally lacking.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Additionally, there was no frontend framework in use (!) and I felt there was an opportunity to modernize and speed up development by adding one.&lt;/p&gt;
&lt;h2&gt;Research and Build&lt;/h2&gt;
&lt;p&gt;With a solid list of usability tickets to address, I got to work sketching ideas for how we might fit things together.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure&amp;gt;
&lt;img src=&quot;./sketchbook.png&quot; alt=&quot;A sketchbook containing several small ideas for maps and
dropdowns.&quot; /&gt;
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Sketching ideas.&lt;/strong&gt; I explored how we might combine location search,
district browsing, and overlap browsing within a single interface.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;Without delay, we dove into code. After quick exploration with various frontend libraries, I installed &lt;a href=&quot;https://svelte.dev/&quot;&gt;Svelte&lt;/a&gt; and &lt;a href=&quot;https://tailwindcss.com/&quot;&gt;Tailwind&lt;/a&gt;, which would allow us to build more advanced functionality more easily. We moved from Leaflet to &lt;a href=&quot;https://www.mapbox.com/&quot;&gt;Mapbox&lt;/a&gt; since it offered us exciting opportunities to interact with the map directly.&lt;/p&gt;
&lt;p&gt;We scheduled video calls with some frequent users of the Boundaries Map in order to better understand how they were using the tool and what could be improved. We shared our work-in-progress prototype for feedback. The participants were excited to be a part of the process and helped validate assumptions we had made.&lt;/p&gt;
&lt;h2&gt;Outcomes&lt;/h2&gt;
&lt;p&gt;After a few short weeks, we announced the updated app.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure&amp;gt;
&amp;lt;div class=&quot;video-wrapper&quot;&amp;gt;
&amp;lt;video
autoplay
loop
muted
playsinline
preload=&quot;none&quot;
poster=&quot;/video/boundaries-map-poster.png&quot;
&amp;gt;
&amp;lt;source src=&quot;/video/boundaries-map.mp4&quot; type=&quot;video/mp4&quot; /&amp;gt;
&amp;lt;/video&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;The new Boundaries Map.&lt;/strong&gt; The updated app features overlaps on hover,
direct interaction with the map, a unified navigation bar, and clearer
information hierarchy.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;The new map automatically zooms and pans to the selected boundary. It displays boundary overlaps on hover, allows single-click filtering by clicking any boundary, and supports mobile viewing. It links to the relevant webpage for a district when available, so users can find things like phone numbers for city council members. And it now allows users to share URLs for filtered views, and export overlap data to JSON for analysis in other tools.&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://www.beta.nyc/2022/09/07/summer-associates-wrap-up/&quot;&gt;Read the announcement&lt;/a&gt; or &lt;a href=&quot;https://boundaries.beta.nyc/?&quot;&gt;explore boundaries&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Reflections&lt;/h2&gt;
&lt;p&gt;I had never worked with mapping technology before, so it was fun to learn about how to wield geospatial data using Mapbox. (Huge thanks to &lt;a href=&quot;https://github.com/zhik&quot;&gt;Zhi&lt;/a&gt; sharing his knowledge of GeoJSON and Shapefiles!) Svelte and Tailwind were also new frameworks for me, and this project helped me get more familiar with their capabilities.&lt;/p&gt;
&lt;p&gt;With extra time, I&apos;d explore how to improve mobile navigation, since touchscreens can&apos;t support the same hover interactions as desktop. I&apos;d also explore whether it&apos;s worth introducing color to the base map to more clearly communicate the locations of parks, water, and other regions. (Boundaries Map is &lt;a href=&quot;https://github.com/BetaNYC/nyc-boundaries&quot;&gt;open source&lt;/a&gt;, so maybe I&apos;ll get to these one day! Or maybe you, my reader, can make contributions of your own.)&lt;/p&gt;
&lt;p&gt;BetaNYC introduced me to the city&apos;s vast library of &lt;a href=&quot;https://opendata.cityofnewyork.us/&quot;&gt;open data&lt;/a&gt;, and I&apos;ve continued to think about other possibilities for design and technology to surface public data for good.&lt;/p&gt;
</content:encoded></item><item><title>Building Commonplace</title><link>https://ky.fyi/posts/commonplace</link><guid isPermaLink="true">https://ky.fyi/posts/commonplace</guid><description>What goes into building a design system for healthcare?</description><pubDate>Sat, 13 Jan 2024 05:13:17 GMT</pubDate><content:encoded>&lt;p&gt;import BeforeAfter from &quot;../../../components/BeforeAfter.astro&quot;;
import actionPlanBefore from &quot;./action-plan-before.png&quot;;
import actionPlanAfter from &quot;./action-plan-after.png&quot;;
import memberTableBefore from &quot;./member-table-before.png&quot;;
import memberTableAfter from &quot;./member-table-after.png&quot;;
import ProjectInfo from &quot;../../../components/ProjectInfo.astro&quot;;&lt;/p&gt;
&lt;p&gt;import neves from &quot;./neves.jpeg&quot;;
import minji from &quot;./minji.jpeg&quot;;
import amber from &quot;./amber.jpeg&quot;;
import taylor from &quot;./taylor.jpeg&quot;;
import liza from &quot;./liza.jpeg&quot;;
import owen from &quot;./owen.jpeg&quot;;
import brennan from &quot;./brennan.jpeg&quot;;
import craig from &quot;./craig.jpeg&quot;;
import aster from &quot;./aster.png&quot;;&lt;/p&gt;
&lt;p&gt;&amp;lt;ProjectInfo
collaborators={[
{
name: &quot;Neves Rodrigues&quot;,
url: &quot;https://www.nevesrodrigues.com/&quot;,
img: neves,
},
{
name: &quot;Minji Lee&quot;,
url: &quot;https://www.linkedin.com/in/minji-lee-ba045518/&quot;,
img: minji,
},
{
name: &quot;Amber Greene&quot;,
url: &quot;https://www.linkedin.com/in/amberhamptongreene/&quot;,
img: amber,
},
{
name: &quot;Taylor Maynard&quot;,
url: &quot;https://www.linkedin.com/in/taylorjmaynard/&quot;,
img: taylor,
},
{
name: &quot;Liza Fryberger&quot;,
url: &quot;https://www.linkedin.com/in/liza-fryberger/&quot;,
img: liza,
},
{
name: &quot;Owen Tran&quot;,
url: &quot;https://www.linkedin.com/in/owentran27/&quot;,
img: owen,
},
{
name: &quot;Brennan Moore&quot;,
url: &quot;https://www.zamiang.com/&quot;,
img: brennan,
},
{
name: &quot;Craig Spaeth&quot;,
url: &quot;http://www.craigspaeth.com/&quot;,
img: craig,
},
{
name: &quot;Aster Ryan&quot;,
url: &quot;https://aster.fyi/&quot;,
img: aster,
},
]}
timeline={{
start: &quot;March 2019&quot;,
end: &quot;July 2021&quot;,
}}
tech={[&quot;Figma&quot;, &quot;React&quot;, &quot;React Spring&quot;, &quot;Storybook&quot;, &quot;TypeScript&quot;]}
roles={[&quot;Strategy&quot;, &quot;Research&quot;, &quot;Product Design&quot;, &quot;Engineering&quot;]}
/&amp;gt;&lt;/p&gt;
&lt;h2&gt;Background&lt;/h2&gt;
&lt;p&gt;&lt;a href=&quot;https://www.cityblock.com/&quot;&gt;Cityblock&lt;/a&gt; is a health company which got its start within Google&apos;s &lt;a href=&quot;https://www.sidewalklabs.com/&quot;&gt;Sidewalk Labs&lt;/a&gt;. Teams of clinicians and other health professionals provide in-community care to people on Medicare and Medicaid to improve health for an often-neglected population.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure&amp;gt;
&amp;lt;div class=&quot;video-wrapper&quot;&amp;gt;
&amp;lt;video
controls
playsinline
preload=&quot;none&quot;
poster=&quot;/video/cityblock-member-story-poster.png&quot;
&amp;gt;
&amp;lt;source src=&quot;/video/cityblock-member-story.mp4&quot; type=&quot;video/mp4&quot; /&amp;gt;
&amp;lt;/video&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Andre, a Cityblock member, tells his story.&lt;/strong&gt; Via{&quot; &quot;}
&amp;lt;a href=&quot;https://vimeo.com/796683739&quot;&amp;gt;Cityblock on Vimeo&amp;lt;/a&amp;gt;, 2023.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;To support care teams and the members they serve, Cityblock builds and maintains a tool called &lt;strong&gt;Commons&lt;/strong&gt;. I joined Cityblock in February 2019 as a Product Designer and recognized a need for a more systematic approach to design. Over the following two years, I built and expanded a design system in Figma and React. I named it &lt;strong&gt;Commonplace&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;The Challenge&lt;/h2&gt;
&lt;p&gt;Cityblock was less than two years old, but Commons already offered a sprawling set of features, including: tracking member status, charting member acuity, coordinating member outreach, storing and editing core demographics, viewing health history, scheduling events, managing tasks for individuals and teams, creating and administering health assessments with automated scoring, texting members... all that, and more planned.&lt;/p&gt;
&lt;p&gt;All of these features converged in an interface that looked like this:&lt;/p&gt;
&lt;p&gt;&amp;lt;figure&amp;gt;
&lt;img src=&quot;./initial.png&quot; alt=&quot;The Cityblock dashboard. There are many different styles, colors, and
fonts.&quot; /&gt;(quality:100)
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;The appearance of Commons when I joined Cityblock.&lt;/strong&gt; Here, in the
right-hand drawer, a user is composing a progress note about the current
member. The varying colors, typography, and hierarchy make the interface
difficult to understand. All member data displayed in this case study is
notional.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;Although there were some underlying commonalities and shared language throughout the product, &lt;strong&gt;the design was not scaling to meet the needs of its users or developers.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;A lack of systemization was leading to longer development times, more time spent on undifferentiated work, more bugs in the product, and a user experience that was inconsistent and confusing. These problems would only worsen as Cityblock grew.&lt;/p&gt;
&lt;h2&gt;Mapping the Territory&lt;/h2&gt;
&lt;p&gt;Together with Cityblock&apos;s Director of Design, &lt;a href=&quot;https://www.nevesrodrigues.com/&quot;&gt;Neves&lt;/a&gt;, we catalogued the available views. I conducted a product audit, clicking through and taking screenshots of every view, dialog, drawer, and dropdown within Commons. The images were then organized into folders for future reference.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure&amp;gt;
&amp;lt;div class=&quot;video-wrapper&quot;&amp;gt;
&amp;lt;video
autoplay
loop
muted
playsinline
preload=&quot;none&quot;
poster=&quot;/video/product-audit-poster.png&quot;
&amp;gt;
&amp;lt;source src=&quot;/video/product-audit.mp4&quot; type=&quot;video/mp4&quot; /&amp;gt;
&amp;lt;/video&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;A product audit.&lt;/strong&gt; We captured screenshots from every corner of Commons
and organized them in folders corresponding to the app&apos;s information
architecture.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;The product audit helped us understand the current state of Commons, and it ushered in an essential archival practice for the future. Throughout my tenure at Cityblock, I would continue to catalogue product interfaces at least once a year.&lt;/p&gt;
&lt;p&gt;Following the product audit, we created an &lt;a href=&quot;https://bradfrost.com/blog/post/interface-inventory/&quot;&gt;interface inventory&lt;/a&gt;, collecting all variations and permutations of each component and displaying a collage of those permutations on a large poster board.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure&amp;gt;
&lt;img src=&quot;./inventory.png&quot; alt=&quot;A black foam board with several sheets of paper pinned to it. Each sheet of
paper displays a component name and a collection of variations on that
component observed in the product.&quot; /&gt;
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;The interface inventory.&lt;/strong&gt; The product audit screenshots were used to
create a collage of each component&apos;s variations. How many header styles can
you count?
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;This inventory allowed us to more easily spot inconsistencies and discuss how best to resolve them across the system.&lt;/p&gt;
&lt;h2&gt;Laying Foundations&lt;/h2&gt;
&lt;p&gt;Once the interface inventory was complete, we focused on design foundations—typography, color, and spacing. All components rest on top of these three primitives, and we wanted to get the essentials right.&lt;/p&gt;
&lt;h3&gt;Typography&lt;/h3&gt;
&lt;p&gt;Care teams at Cityblock are given small Chromebooks to take with them around the city. They use their Chromebooks to access Commons in many locations: the office, at community hubs, in members&apos; homes, and in their car or on the subway.&lt;/p&gt;
&lt;p&gt;As we laid out a typographic scale and compared different typefaces, we made sure to test text on the Chromebook&apos;s low-DPI display in a variety of real-world, less-than-ideal lighting conditions, in order to ensure that Commons was legible in every setting.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure&amp;gt;
&lt;img src=&quot;./low-contrast-typography.png&quot; alt=&quot;A screen within Commons&quot; /&gt;(quality:100)
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Low-contrast typography within Commons.&lt;/strong&gt; Many views contained small,
light text which was difficult to read under ideal conditions, and
practically impossible in others. All data is notional.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;With Cityblock&apos;s brand designer, &lt;a href=&quot;https://www.linkedin.com/in/minji-lee-ba045518/&quot;&gt;Minji&lt;/a&gt;, we tested various typefaces for the product before landing on &lt;a href=&quot;https://commercialtype.com/catalog/graphik&quot;&gt;Graphik&lt;/a&gt; for its legibility and understated friendliness. All text colors within the new design system would adhere to &lt;a href=&quot;https://www.w3.org/WAI/WCAG21/Understanding/contrast-minimum&quot;&gt;WCAG AA&lt;/a&gt; or &lt;a href=&quot;https://www.w3.org/WAI/WCAG21/Understanding/contrast-enhanced&quot;&gt;AAA&lt;/a&gt; contrast ratios.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure&amp;gt;
&lt;img src=&quot;./typography.png&quot; alt=&quot;The Commonplace typographic scale, using the font,
Graphik.&quot; /&gt;(quality:100)
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;The typographic scale.&lt;/strong&gt; The base unit is set to 16 pixels and most header
sizes scale up from there using
&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Values_and_units#ems_and_rems&quot;&gt;&lt;code&gt;rem&lt;/code&gt;&lt;/a&gt;.
After experimentation, we decided to break this scale for the body size (15
pixels) and small text (13 pixels) in order to maintain medium-high data
density.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;h3&gt;Color&lt;/h3&gt;
&lt;p&gt;When considering colors in Commons, we prioritized pure function, accessibility and contrast, relation to the brand, and coherence as a whole.&lt;/p&gt;
&lt;p&gt;I also examined the use of color in film to portray two separate settings—the hospital and the home.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure&amp;gt;
&amp;lt;div class=&quot;two-up&quot;&amp;gt;
&lt;img src=&quot;./hospital-palette.png&quot; alt=&quot;A collage of various hospital settings portrayed in film and
TV.&quot; /&gt;(quality:100)&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![A collage of various &quot;home&quot; settings portrayed in film and TV.](./home-palette.png)(quality:100)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/div&amp;gt;
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Colors of the hospital, and colors of home.&lt;/strong&gt; What feelings do these scenes evoke?
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;The hospital blue-greens are distinctly clinical, down to the robes worn by patients and doctors, and feel somber and sterile. “Home” tones, in contrast, emit a warm, welcoming glow. I wrote at the time, &quot;Cityblock should feel less like the hospital, and more like home.&quot;&lt;/p&gt;
&lt;p&gt;This led to guiding principles:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Guiding Principles for Color in Commons&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Color gently.&lt;/strong&gt; Opt for soft, subdued tones. Avoid highly-saturated, electric colors.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Use high contrast elements sparingly.&lt;/strong&gt; What is the one action on any given view that deserves attention?&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skew warm.&lt;/strong&gt; Do not tint neutrals blue.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;p&gt;And the resulting palette, defined as matching Figma styles and CSS variables:&lt;/p&gt;
&lt;p&gt;&amp;lt;figure&amp;gt;
&lt;img src=&quot;./colors.png&quot; alt=&quot;The Commonplace color palette with matching variables in
CSS.&quot; /&gt;(quality:100)
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;The color palette.&lt;/strong&gt; Colors are arranged along a spectrum from 100 (light)
to 900 (dark). Some colors are aliased with a semantic name, so developers
don&apos;t need to remember that icons are &lt;code&gt;--color-neutral-600&lt;/code&gt;. They can just
use &lt;code&gt;--color-icon&lt;/code&gt;.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;h3&gt;Spacing&lt;/h3&gt;
&lt;p&gt;We agreed to use an 8 pixel grid for all components, and we agreed on specific fixed widths for sidebars while leaving the rest of the app responsive to scale with the browser.&lt;/p&gt;
&lt;h2&gt;Building Components&lt;/h2&gt;
&lt;p&gt;Once foundations were in place, primitives were set up both in Figma and as CSS Variables in the codebase, and we were able to quickly and easily replace all existing hex codes with new color variables, replace existing padding, margin, widths, and heights with the new spacing scale, and swap out the typography.&lt;/p&gt;
&lt;p&gt;Then began the long and steady process of building and replacing components one-by-one. Create a new &lt;code&gt;Button&lt;/code&gt;. Test it. Swap out all existing buttons and delete all existing styles. Merge in the changes. Pick a new component, rinse and repeat.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure&amp;gt;
&lt;img src=&quot;./components.png&quot; alt=&quot;Components displayed in Figma and in code.&quot; /&gt;(quality:100)
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Commonplace components.&lt;/strong&gt; Each component in the codebase included unit
tests, a Storybook story, and &lt;a href=&quot;https://jsdoc.app/about-getting-started&quot;&gt;JSDoc
comments&lt;/a&gt; for each prop in order to
provide in-context documentation within VS Code.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;Component work took place over the course of many months, alongside other feature work I was involved in. It took place largely independently, although I continued to collaborate with &lt;a href=&quot;https://www.nevesrodrigues.com/&quot;&gt;Neves&lt;/a&gt; for visual and interaction design feedback, researchers like &lt;a href=&quot;https://www.linkedin.com/in/amberhamptongreene/&quot;&gt;Amber&lt;/a&gt; and &lt;a href=&quot;https://www.linkedin.com/in/taylorjmaynard/&quot;&gt;Taylor&lt;/a&gt; for user insights, and engineers like &lt;a href=&quot;https://www.zamiang.com/&quot;&gt;Brennan&lt;/a&gt;, &lt;a href=&quot;https://aster.fyi/&quot;&gt;Aster&lt;/a&gt;, and &lt;a href=&quot;http://www.craigspaeth.com/&quot;&gt;Craig&lt;/a&gt; for code review.&lt;/p&gt;
&lt;p&gt;We chose an incremental approach—rather than building and shipping an entirely new design system all at once—in order to maintain forward momentum, bug test along the way, and enable new features to be built with new components as quickly as possible.&lt;/p&gt;
&lt;h2&gt;Outcomes&lt;/h2&gt;
&lt;p&gt;By January 2020, most views within Commons used Commonplace components. &lt;strong&gt;Responses from engineers and care team members were overwhelmingly positive.&lt;/strong&gt; Bug reports decreased, new features became easier to build, and engineers got to spend more time on differentiated work and less time fiddling with CSS.&lt;/p&gt;
&lt;p&gt;Despite the addition of new components, several thousand lines of code had been deleted since the start of the project due to the reusability and modular nature of the design system—a meaningful reduction in complexity and technical debt.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure&amp;gt;
&amp;lt;BeforeAfter
before={{
src: actionPlanBefore,
alt: &quot;The action plan in Commons before the introduction of Commonplace.&quot;,
}}
after={{
src: actionPlanAfter,
alt: &quot;The action plan in Commons after the introduction of Commonplace.&quot;,
}}
/&amp;gt;
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Member action plan, before (early 2019) and after (early 2020).&lt;/strong&gt; More
information is available at a glance, without drilling down into cards and
accordions.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;figure&amp;gt;
&amp;lt;BeforeAfter
before={{
src: memberTableBefore,
alt: &quot;The member table in Commons before the introduction of Commonplace.&quot;,
}}
after={{
src: memberTableAfter,
alt: &quot;The member table in Commons after the introduction of Commonplace.&quot;,
}}
/&amp;gt;
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Member table, before (early 2019) and after (early 2020).&lt;/strong&gt; We aimed to
main medium-high data density, helpful for our care staff, while making the
UI feel more approachable and calm.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;Around this time, I gave a company-wide talk about design systems, a concept which was unfamiliar to many people outside of the tech team. There was palpable excitement over seeing the drastic comparisons of before and after screens.&lt;/p&gt;
&lt;p&gt;I would continue to contribute design and code toward Commonplace until my departure in July 2021.&lt;/p&gt;
&lt;h2&gt;Reflections&lt;/h2&gt;
&lt;p&gt;Care teams at Cityblock do difficult, meaningful work, and it&apos;s essential that the technology we build for them respects their time and energy. I&apos;m proud of the way I was able to help transform Cityblock&apos;s approach to design and engineering, and (hopefully) reduce stress for our hard-working care teams.&lt;/p&gt;
&lt;p&gt;Health tech is a complex space, and I still see dozens of ways that Commons could be streamlined. A design system is only as strong as the features it&apos;s used to build, but where a design system ends and product features begin isn&apos;t always clear. There is always more to do.&lt;/p&gt;
&lt;p&gt;As I write this, in February 2024, &lt;strong&gt;I&apos;ve just &lt;a href=&quot;https://www.linkedin.com/posts/evadecker_its-been-awhile-but-im-excited-to-be-back-activity-7166518870042730496-bUhd?utm_source=share&amp;amp;utm_medium=member_desktop&quot;&gt;returned to Cityblock&lt;/a&gt; to help level up design systems again.&lt;/strong&gt; After 3 years&apos; absence, the system foundations I put in place have held up well. Some areas have flourished, others have remained the same, and a few weeds have sprouted, but it&apos;s a wonderful feeling to see the work you put so much effort into continue to endure.&lt;/p&gt;
</content:encoded></item><item><title>Design outside the computer</title><link>https://ky.fyi/posts/design-outside-the-computer</link><guid isPermaLink="true">https://ky.fyi/posts/design-outside-the-computer</guid><description>Your digital UI can come from the physical world.</description><pubDate>Mon, 20 May 2024 17:30:34 GMT</pubDate><content:encoded>&lt;p&gt;This weekend, I added a new feature to my site. It&apos;s an old-school kind of webpage—something I&apos;ve always wanted to create, but never really had the tools for until now.&lt;/p&gt;
&lt;p&gt;It&apos;s a &lt;a href=&quot;/guestbook&quot;&gt;guestbook&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;In the guestbook, anyone can write and publish a short message accompanying a name and optional URL. Once submitted, the message gets published to the top of the page for everyone to see. That&apos;s it—no likes, no shares, no threads. Nothing fancy.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./guestbook.png&quot; alt=&quot;A collection of notecards with monospace text on them.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;figcaption&amp;gt;
&lt;strong&gt;The guestbook.&lt;/strong&gt; People have already written kind things and drawn snails.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://docs.astro.build/en/guides/astro-db/&quot;&gt;Astro DB&lt;/a&gt;, recently released, made it a breeze to spin up a database and implement publishing, even for a backend novice like me. But this post isn&apos;t about how to implement a guestbook. (UX developer &lt;a href=&quot;https://ryantrimble.com/&quot;&gt;Ryan Trimble&lt;/a&gt; already wrote a &lt;a href=&quot;https://ryantrimble.com/blog/creating-a-guestbook-with-astro-db/&quot;&gt;great tutorial&lt;/a&gt; for that!) It&apos;s about how invigorating it can be to design digital UI when you step away from your computer.&lt;/p&gt;
&lt;p&gt;I didn&apos;t want to build just any plain stream of messages and text—I wanted to create something that felt warm, personable, and tactile—like signing a real book. To accomplish that, I first did something important: I shut my laptop.&lt;/p&gt;
&lt;h2&gt;The death of texture&lt;/h2&gt;
&lt;p&gt;The world around us is full of texture. From the bark of an elm tree to the weave of a linen blanket... even the body of a MacBook isn&apos;t completely smooth. Most digital spaces, in contrast, are textureless. Flat expanses of nothingness, stretching into a grainless void.&lt;/p&gt;
&lt;p&gt;Our interfaces used to be more textured. During the heydey of &lt;a href=&quot;https://en.wikipedia.org/wiki/Skeuomorph#Virtual_examples&quot;&gt;skeuomorphism&lt;/a&gt; in the late 2000s, designers prided themselves on being able to craft realistic-looking wood grain, leather, glass, and other effects.&lt;/p&gt;
&lt;p&gt;In 2013, Apple released iOS 7, featuring a redesigned user interface which, under Jony Ive, fully embraced flat design, bringing a swift death to the iPhone&apos;s skeuomorphism. The vast majority of digital spaces soon followed suit.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure class=&quot;no-bleed&quot;&amp;gt;
&amp;lt;div class=&quot;two-up&quot;&amp;gt;
&lt;img src=&quot;./ios6.png&quot; alt=&quot;The home screen of iOS 6.&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![The home screen of iOS 7.](./ios7.png)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/div&amp;gt;
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;iOS 6 (left) and iOS 7 (right).&lt;/strong&gt; iOS 7&apos;s flat design effectively killed skeuomorphic design trends across the industry. Images from &lt;a href=&quot;https://arstechnica.com/gadgets/2013/09/death-to-textures-ios-6-and-ios-7-compared-in-pictures/&quot;&gt;Ars Technica&lt;/a&gt;.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;Although the usability of the digital landscape has improved greatly over the past decade, I can&apos;t help but feel like the web lost a little bit of its soul when everything got flattened. So much of the web today feels boring, samey, and soulless.&lt;/p&gt;
&lt;h2&gt;Real-life objects can live on your website&lt;/h2&gt;
&lt;p&gt;Let&apos;s push that pendulum back the other direction! A bit, at least. Let&apos;s give the web some soul. Let&apos;s give it some &lt;strong&gt;texture&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;How do you add texture? You could browse for Photoshop packs and fiddle with layers and blend modes to emulate real life. Or, you could grab some paper, scissors, and markers, and go craft in your living room on a nice Spring day.&lt;/p&gt;
&lt;p&gt;The second option is way more fun.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure class=&quot;no-bleed&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./notecard-progress.png&quot; alt=&quot;Two stamps sit beside small rectangular piece of cream-color card stock. There is a red stamp on the paper with a hand holding a match alight.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Crafting cards.&lt;/strong&gt; Stamps from &lt;a href=&quot;https://www.caseyrubberstamps.com/&quot;&gt;Casey Rubber Stamps&lt;/a&gt; in NYC.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;I spent an afternoon cutting out same-sized rectangles of card stock and doodling on them with whatever drawing tools I had around. Highlighters, pencil, crayons. Washi tape. Some ORAL stickers I stole from the queer health clinic. Every card is a little bit different.&lt;/p&gt;
&lt;p&gt;I scanned in the cards using a flatbed scanner, cleaned up the images in Photoshop, and optimized them for web. Now all these physical objects have a digital home. :)&lt;/p&gt;
&lt;h2&gt;Tips for bringing physical media into digital UI&lt;/h2&gt;
&lt;p&gt;Working with physical media is rewarding. Quirks of the medium show up in ways that would require large effort to reproduce digitally—the edges I cut are not quite straight; the lines I drew are not perfectly even. Sometimes the ink smudged. It&apos;s okay! Desirable, even.&lt;/p&gt;
&lt;p&gt;But translating media into digital space takes care to show up and perform well. Here are a few tips if you&apos;re thinking of bringing real-life objects into your digital designs.&lt;/p&gt;
&lt;h3&gt;Know how your layout will flow and reflow&lt;/h3&gt;
&lt;p&gt;Before starting, ask yourself: will text need to wrap to multiple lines? Will the element grow, or is it a static size? Does the design need to adapt to mobile? The more flexible the size of your elements, the more difficult it may be to craft physical media to support them.&lt;/p&gt;
&lt;p&gt;When designing cards for the guestbook, I decided to design around a consistent 4:3 aspect ratio. For this, you can use &lt;code&gt;aspect-ratio&lt;/code&gt; in CSS, which has coverage in &lt;a href=&quot;https://caniuse.com/?search=aspect-ratio&quot;&gt;94% of browsers used globally&lt;/a&gt;.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.notecard {
  aspect-ratio: 4 / 3;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;Enforcing a static aspect ratio means we need to be thoughtful about how much text a user can enter. How wide is each line of text? How many total characters can the content area support?&lt;/p&gt;
&lt;p&gt;We can use the &lt;code&gt;ch&lt;/code&gt; unit in CSS to define the maximum width of the text. The &lt;code&gt;ch&lt;/code&gt; unit is equal to the width of the character &lt;code&gt;0&lt;/code&gt; in the selected font, and since we&apos;re using a monospace font where all characters are the same width, we can use &lt;code&gt;ch&lt;/code&gt; to display exactly 28 characters per line.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.notecard .content {
  width: 28ch;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We want to allow users to draw ASCII art and other fun things, too. To do that, we need to preserve whitespace for entries and prevent long lines of unbroken text from overflowing the container.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;.notecard .content {
  width: 28ch;
  white-space: pre-wrap; // Preserve whitespace
  overflow-wrap: break-word; // Break long lines of text
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can enforce these limits in our HTML for form submission:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;textarea
  name=&quot;content&quot;
  placeholder=&quot;Leave a message, write a poem, draw some ASCII art...&quot;
  required
  rows=&quot;5&quot;
  cols=&quot;28&quot;
  maxlength=&quot;140&quot;
&amp;gt;&amp;lt;/textarea&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;We can also tell the form to preserve implicit newlines on submission with &lt;code&gt;wrap=&quot;hard&quot;&lt;/code&gt;, which will guarantee that even if we change our CSS in the future or decide to display guestbook entries somewhere else, handcrafted ASCII art will remain intact.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&amp;lt;textarea
  name=&quot;content&quot;
  placeholder=&quot;Leave a message, write a poem, draw some ASCII art...&quot;
  required
  rows=&quot;5&quot;
  cols=&quot;28&quot;
  maxlength=&quot;140&quot;
  wrap=&quot;hard&quot;
&amp;gt;&amp;lt;/textarea&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;There are a few other details to take care of, like showing a warning message when there&apos;s no room left for text, but the above code takes care of the basic setup for a fixed-size, fixed-length textarea.&lt;/p&gt;
&lt;h3&gt;Use a flatbed scanner&lt;/h3&gt;
&lt;p&gt;Dedicated scanners are cheap nowadays, and produce better results than photography. There are two types of scanners: CIS scanners have a very shallow focus, while CCD scanners have a &lt;a href=&quot;http://www.microscopy-uk.org.uk/mag/artjan13/dw-scanner-type.html&quot;&gt;wider depth of field&lt;/a&gt;. (I used a $60 &lt;a href=&quot;https://www.amazon.com/Canon-CanoScan-Lide-Slim-Scanner/dp/B07G5YBS1W?th=1&quot;&gt;CIS scanner&lt;/a&gt; for this project, but if I needed to buy a new scanner today it would be a CCD!)&lt;/p&gt;
&lt;p&gt;I&apos;ve found that 300 DPI is enough resolution for retina displays. Through trial and error, I also learned that putting a contrasting backdrop behind your documents will make it much easier to isolate the subject in tools like Photoshop after scanning.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure class=&quot;no-bleed&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./magic-wand.png&quot; alt=&quot;&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Use a dark backdrop.&lt;/strong&gt; A contrasting backdrop makes documents easier to isolate using tools like the magic wand.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;h3&gt;Be mindful of color contrast and file size&lt;/h3&gt;
&lt;p&gt;Image backgrounds make it more difficult to measure &lt;a href=&quot;https://contrast.tools/&quot;&gt;accessible color contrast&lt;/a&gt; ratios for text on top; don&apos;t make any backgrounds too high-contrast. If you realize a shade you used was too dark, you can adjust contrast settings after scanning your images in. If there are any busy elements in your object, try to position them in a spot where text is unlikely to overlap. For the guestbook, I put the loudest elements in the margins, away from text.&lt;/p&gt;
&lt;p&gt;The downside to working with images can be increased bandwidth. Use a command line tool like &lt;a href=&quot;https://optipng.sourceforge.net/&quot;&gt;optipng&lt;/a&gt; to losslessly compress files, or a build tool like Astro&apos;s &lt;a href=&quot;https://docs.astro.build/en/guides/images/#image--astroassets&quot;&gt;&lt;code&gt;&amp;lt;Image /&amp;gt;&lt;/code&gt;&lt;/a&gt; to handle it for you. There&apos;s no use in designing beautiful objects if a massive file size will prevent them from ever being seen!&lt;/p&gt;
&lt;h3&gt;Incorporate some randomness&lt;/h3&gt;
&lt;p&gt;The real world isn&apos;t often aligned in perfect 90 degree angles; your interface doesn&apos;t have to align to the grid, either. Consider incorporating some variation in how you position elements, for example, by using Astro&apos;s &lt;a href=&quot;https://docs.astro.build/en/reference/directives-reference/#definevars&quot;&gt;&lt;code&gt;define:vars&lt;/code&gt;&lt;/a&gt; style directive to pass variables into CSS:&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;---
// Rotate each notecard randomly between 3 and -3 degrees
const randomRotation = `${Math.random() * 6 - 3}deg`;

// Offset each notecard randomly between 12 and -12 pixels
const randomTranslateX = `${Math.random() * 24 - 12}px`;
---

&amp;lt;div class=&quot;notecard&quot;&amp;gt;
  &amp;lt;!-- Notecard contents --&amp;gt;
&amp;lt;/div&amp;gt;

&amp;lt;style define:vars={{ rotation: randomRotation, translateX: randomTranslateX }}&amp;gt;
  .notecard {
    transform: translateX(var(--translateX)) rotate(var(--rotation));
  }
&amp;lt;/style&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;Have fun!&lt;/h3&gt;
&lt;p&gt;Embrace experimentation and the freedom of designing without a screen. There are so many potential areas to bring physical objects into digital experiences. It isn&apos;t always called for or necessary, but for the right moment, a touch of real, physical texture can go a long way toward making an experience that&apos;s a joy to use.&lt;/p&gt;
&lt;p&gt;Now go off and draw your own UI. Don&apos;t forget to &lt;a href=&quot;/guestbook&quot;&gt;sign the guestbook&lt;/a&gt; before you go.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Shout out to &lt;a href=&quot;https://leanrada.com&quot;&gt;Lean Rada&lt;/a&gt;, whose &lt;a href=&quot;https://leanrada.com/guestbook/&quot;&gt;guestbook&lt;/a&gt;—discovered through the CSS JOY &lt;a href=&quot;/webrings&quot;&gt;webring&lt;/a&gt;—offered inspiration for the themable index card format. Lean&apos;s even includes customizable fonts, colors, and stickers! Check it out.&lt;/p&gt;
</content:encoded></item><item><title>Embrace friction</title><link>https://ky.fyi/posts/embrace-friction</link><guid isPermaLink="true">https://ky.fyi/posts/embrace-friction</guid><description>On letterpress, tech, and the power of going slow.</description><pubDate>Mon, 08 Dec 2025 17:26:21 GMT</pubDate><content:encoded>&lt;p&gt;This weekend, I attended a letterpress course at the &lt;a href=&quot;https://centerforbookarts.org/&quot;&gt;Center for Book Arts&lt;/a&gt; in NYC. I love working with and reading about typography, but until now, most of my interactions with type have been mediated through a digital display. I was thrilled to get physical. To touch the type!&lt;/p&gt;
&lt;p&gt;We learned about the &lt;a href=&quot;https://en.wikipedia.org/wiki/Vandercook&quot;&gt;Vandercook proof press&lt;/a&gt;, an imposing steel machine from the early 20th century. We selected typefaces from the Center’s many cases of lead type. And over the span of two days, each of us set a page of text to print.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure class=&quot;no-bleed&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./vandercook-presses.jpg&quot; alt=&quot;Three proof presses are lined up against the windows within a brick-walled studio in New York. Against cans of paint and cases of metal type are visible.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Vandercook proof presses.&lt;/strong&gt; Located at the Center for Book Arts.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;Letterpress is slow, methodical work. Instructor &lt;a href=&quot;https://www.sarahnicholls.com/&quot;&gt;Sarah Nicholls&lt;/a&gt; says it “reshapes your relation to time.” Every letter, space, and detail is placed individually, entire forms composed by hand. Nicholls uses letterpress as the final step in her editing process—it forces deep consideration of every word’s purpose.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./letterpress-workstation.jpg&quot; alt=&quot;A letterpress workstation shows a wooden case full of metal characters of type.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Letterpress workstation.&lt;/strong&gt; On the left, a case of 18pt Caslon #540 lead type. Above, a reference using the &lt;a href=&quot;https://en.wikipedia.org/wiki/California_job_case&quot;&gt;California job case&lt;/a&gt; layout. On the right, a metal galley plate and composition stick, where type is being arranged.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;Setting each character within the composition stick, you feel the shape of words. Physically, yes, but linguistically, too. There is a poetry to the shapes that form language. I felt this intimately, setting Ursula K. Le Guin&apos;s translation of the twenty-five hundred year-old &lt;a href=&quot;https://en.wikipedia.org/wiki/Tao_Te_Ching&quot;&gt;Tao Te Ching&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;As I composed my page, letter by letter, I thought about friction. Friction shapes our relation to a system. It is difficult to set type in letterpress, so I say less, with more intention. It is easy to type on a computer, so I say more. If I wanted to set this blog post in letterpress, it would take me a week or more. Would I use all of these words?&lt;/p&gt;
&lt;p&gt;&amp;lt;figure&amp;gt;
&amp;lt;div class=&quot;two-up&quot;&amp;gt;
&lt;img src=&quot;./taoing-preprint.jpg&quot; alt=&quot;Blocks of text are arranged and tied with twine. The blocks rest in the corner of a metal tray called a galley.&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![The blocks of text are arranged in the center of the metal bed on the Vandercook press, positioned securely by steel blocks.](./vandercook-press.jpg)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/div&amp;gt;
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Setting type for print.&lt;/strong&gt; Blocks are arranged individually on a composition stick, then moved to a galley before being placed and secured on the Vandercook press for printing.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;Tools like ChatGPT take friction(-lessness) to a new extreme, where even writing is not required: only a rough impulse about the result you want. What do we lose when we abandon taking time to shape language? What meaning is made from pressing buttons on a text extrusion machine?&lt;/p&gt;
&lt;p&gt;New technology often prizes itself on being &quot;frictionless&quot;. But is lack of friction always a worthwhile goal? Thoughtfulness requires time. Learning requires time. Friction, ever obstinate, forces us to slow down. When we slow down, we may discover things that are easy to miss when zooming by at quicker speeds.&lt;/p&gt;
&lt;p&gt;In a world that constantly demands we move faster and be more productive, there is joy to be found in doing less, more slowly, with greater intent.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure class=&quot;no-bleed&quot;&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;img src=&quot;./taoing.jpg&quot; alt=&quot;Taoing. The way you can go isn&apos;t the real way. The name you can say isn&apos;t the real name. Heaven and earth begin in the unnamed: name&apos;s the mother of the ten thousand things. So the unwanting soul sees what&apos;s hidden, and the ever-wanting soul sees only what it wants. Two things, one origin, but different in name, whose identity is mystery. Mystery of all mysteries! The door to the hidden.&quot; /&gt;&lt;/p&gt;
&lt;p&gt;&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Taoing, from Tao Te Ching by Lao Tzu, translated by Ursula K. Le Guin.&lt;/strong&gt; Title set in &lt;a href=&quot;https://fontsinuse.com/typefaces/6/lydian&quot;&gt;Lydian Condensed Bold&lt;/a&gt;, 48pt. Text set in &lt;a href=&quot;https://fontsinuse.com/typefaces/5488/caslon-no-471-and-540&quot;&gt;Caslon #540&lt;/a&gt;, 18pt.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;The penultimate line of &quot;Taoing&quot; ends with an exclamation point. After carefully arranging the preceding sixteen lines, letter by letter, over two days, placing that exclamation point exploded like a firework inside of me.&lt;/p&gt;
&lt;p&gt;Bang! I felt it.&lt;/p&gt;
&lt;p&gt;I felt it because I was going slow enough to notice.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;The Center for Book Arts offers many &lt;a href=&quot;https://shop.centerforbookarts.org/collections/workshops&quot;&gt;workshops&lt;/a&gt; for letterpress, risograph printing, book binding, and more. I sincerely recommend taking a class if you&apos;re in the NYC area. I will definitely be returning.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Edit, December 10: After publishing, I came across a related article by &lt;a href=&quot;https://tante.cc/about/&quot;&gt;tante&lt;/a&gt; about friction, AI, loneliness, and touch:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[...] friction is not just “things not working properly”, it can also be read as &lt;em&gt;being touched&lt;/em&gt;. Just as crowded spaces create friction by other people being in my way while moving, a process with friction makes me feel other people&apos;s work, their point of view and how it differs from mine, makes me feel their needs and wants. Friction is part of what being in, being part of society &lt;em&gt;is&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&amp;lt;cite&amp;gt;&lt;a href=&quot;https://tante.cc/2025/07/30/friction-and-not-being-touched/&quot;&gt;Friction and not being touched&lt;/a&gt;&amp;lt;/cite&amp;gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;It&apos;s worth reading in full.&lt;/p&gt;
&lt;hr /&gt;
&lt;p&gt;Edit, March 25: I&apos;ve encountered a few more articles on the topic of friction:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;https://artificialbureaucracy.substack.com/p/kill-chain&quot;&gt;Kill Chain&lt;/a&gt; by Kevin Baker examines Palantir&apos;s Project Maven and its role in the deaths of 175-180 Iranian schoolgirls during a February 2026 attack by the US.&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;https://matthiasott.com/notes/the-shape-of-friction&quot;&gt;The Shape of Friction&lt;/a&gt; by Matthias Ott muses on &quot;working with the nature, the &apos;grain&apos; of a material rather than against it.&quot; and says &quot;Professional work always has friction.&quot; The writing is a response to Dave Rupert&apos;s piece &lt;a href=&quot;https://daverupert.com/2026/03/people-are-not-friction/&quot;&gt;People are not friction&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I&apos;ve started an Are.na channel to collect other examples of &lt;a href=&quot;https://www.are.na/ky-decker/friction-in-systems-software&quot;&gt;friction in systems/software&lt;/a&gt;.&lt;/p&gt;
</content:encoded></item><item><title>Creating a catalogue of gender-swapped song covers</title><link>https://ky.fyi/posts/genderswap</link><guid isPermaLink="true">https://ky.fyi/posts/genderswap</guid><description>The making of Genderswap.fm, using SvelteKit, Supabase, and the Spotify Web API.</description><pubDate>Sat, 02 Mar 2024 05:40:50 GMT</pubDate><content:encoded>&lt;p&gt;import ProjectInfo from &quot;../../../components/ProjectInfo.astro&quot;;
import abba from &quot;./abba.jpeg&quot;;&lt;/p&gt;
&lt;p&gt;&amp;lt;ProjectInfo
collaborators={[
{
name: &quot;ABBA&quot;,
url: &quot;https://youtu.be/GHddJnNo_BQ?si=E9kbils39dAbpdky&quot;,
img: abba,
},
]}
timeline={{
start: &quot;October 2023&quot;,
end: &quot;December 2023&quot;,
}}
roles={[&quot;Strategy&quot;, &quot;Branding&quot;, &quot;Product Design&quot;, &quot;Engineering&quot;]}
tech={[
&quot;Melt UI&quot;,
&quot;Svelte&quot;,
&quot;SvelteKit&quot;,
&quot;Supabase&quot;,
&quot;Spotify Web API&quot;,
&quot;TypeScript&quot;,
]}
repo=&quot;kydecker/genderswap.fm&quot;
website=&quot;https://genderswap.fm&quot;
/&amp;gt;&lt;/p&gt;
&lt;h2&gt;Background&lt;/h2&gt;
&lt;p&gt;In 2021, I read the novel &lt;em&gt;&lt;a href=&quot;https://hardcover.app/books/paul-takes-the-form-of-a-mortal-girl&quot;&gt;Paul Takes the Form of a Mortal Girl&lt;/a&gt;&lt;/em&gt; by Andrea Lawlor. Early in the book, Paul gushes about his love of gender-swapped covers:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Some covers deliver the age-old simple pleasures of drag—knowledge, the opportunity to investigate the simulacra and make comparisons, that obscure little frisson of dissonance. Take Joan Baez singing “Virgil Kane is my name… like my father before me, I’m a working man” (which, of course, is originally from The Band’s “The Night They Drove Old Dixie Down)” or Cait O’Riordan from the Pogues crooning, “My name is Jock Stewart, I’m a canny gun man” (from the traditional “I’m a Man You Don’t Meet Every Day”). Joan Baez’s contralto can, if you squint your ears, pass as a farm-boy tenor; Cait O’Riordan’s chalky delivery might be that of a rich ponce.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I listened to each cover and original, enamored with how lyrics could completely transform under another artist&apos;s tone, tempo, and gender.&lt;/p&gt;
&lt;p&gt;I began compiling Paul&apos;s songs into a playlist, and then I added more of my own. And more. And more. For another two years.&lt;/p&gt;
&lt;h2&gt;The Challenge&lt;/h2&gt;
&lt;p&gt;As my covers playlist grew, so did the tedium of managing it in Spotify. I kept all covers alphabetized (by hand), and I maintained two separate playlists—one for both &lt;a href=&quot;https://open.spotify.com/playlist/5YQ4AyxQ6DeDxKJgSryAU2?si=68e701a76c854e5c&quot;&gt;covers and originals&lt;/a&gt;, and another for &lt;a href=&quot;https://open.spotify.com/playlist/50iUGmY3cSUETCHGfUgf6a?si=f078e27420334399&quot;&gt;covers only&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure&amp;gt;
&amp;lt;div class=&quot;video-wrapper&quot;&amp;gt;
&amp;lt;video
autoplay
loop
muted
playsinline
preload=&quot;none&quot;
poster=&quot;/video/adding-spotify-poster.png&quot;
&amp;gt;
&amp;lt;source src=&quot;/video/adding-spotify.mp4&quot; type=&quot;video/mp4&quot; /&amp;gt;
&amp;lt;/video&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Difficulties organizing in Spotify.&lt;/strong&gt; The interface makes it challenging
to organize songs within large playlists. (Sorting by title exists, but it&apos;s
unreliable here—John Denver&apos;s &quot;Take Me Home, Country Roads&quot; deserves to live
beside Judy Collins&apos;s &quot;Leaving on a Jet Plane/Take Me Home Country Roads&quot;.)
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;After managing this playlist for two years, I decided to build a custom solution to host and catalogue covers. I named it &lt;a href=&quot;https://genderswap.fm/&quot;&gt;Genderswap.fm&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Laying Foundations&lt;/h2&gt;
&lt;p&gt;This personal project was my first time working directly on the backend. Thankfully, &lt;a href=&quot;https://supabase.com/&quot;&gt;Supabase&lt;/a&gt;—an open source alternative to Google&apos;s &lt;a href=&quot;https://firebase.google.com/&quot;&gt;Firebase&lt;/a&gt;—made it easy to get started.&lt;/p&gt;
&lt;p&gt;I experimented with alternative data structures and landed on a two table model: one table for &lt;code&gt;songs&lt;/code&gt;, and one table for &lt;code&gt;covers&lt;/code&gt;, which links two &lt;code&gt;song&lt;/code&gt; rows together along with extra metadata about their relation.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure class=&quot;no-bleed&quot; style=&quot;max-width: 600px&quot;&amp;gt;
&lt;img src=&quot;./schema.png&quot; alt=&quot;A visualization of the database schema for
Genderswap.fm.&quot; /&gt;(quality:100)
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Database schema.&lt;/strong&gt; This is the shape of the data for Genderswap.fm.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;I decided to use &lt;a href=&quot;https://svelte.dev/&quot;&gt;Svelte&lt;/a&gt; and SvelteKit for my application framework. I had previously used Svelte in my build for the &lt;a href=&quot;/projects/boundaries-map&quot;&gt;NYC Boundaries Map&lt;/a&gt;, and the addition of SvelteKit made it easy to manage routing, server-side rendering, and API requests. I set up a Spotify Developer account and used the &lt;a href=&quot;https://github.com/spotify/spotify-web-api-ts-sdk&quot;&gt;Spotify Web API TypeScript SDK&lt;/a&gt; to make it easy for users to search for and enter songs. I also added &lt;a href=&quot;https://melt-ui.com/&quot;&gt;Melt UI&lt;/a&gt;, a Svelte-based component library, to help build the submission form.&lt;/p&gt;
&lt;h2&gt;Ideation&lt;/h2&gt;
&lt;p&gt;For the design, I knew I wanted to allow users to browse by pairs of songs shown together. It wouldn&apos;t be too different from browsing &quot;by album&quot; in any other music tool, but rather than displaying a single album for each result, I&apos;d display original/cover pairs.&lt;/p&gt;
&lt;p&gt;From there, users could tap in to view the details of a cover, and listen to the original and the cover side-by-side, with notes about their differences.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure&amp;gt;
&amp;lt;div class=&quot;two-up&quot;&amp;gt;
&lt;img src=&quot;./sketch-1.png&quot; alt=&quot;Detail page and form field sketches.&quot; /&gt;&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;![Search and filtering sketches.](./sketch-2.png)(quality:100)
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;&amp;lt;/div&amp;gt;
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Exploratory sketches.&lt;/strong&gt; Ideating around the display of albums, how to structure the submission form, and how to surface filters. I still hadn&apos;t figured out what I would ask users to tag manually, and what I could tag automatically using Spotify&apos;s API.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;h2&gt;Finding a Design Language&lt;/h2&gt;
&lt;p&gt;To communicate the way these covers remix sound, reinterpret lyrics, and reconfigure meaning, I established a visual motif to thread its way through the app: two objects, overlapping and askew. Sharing space, but different.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure&amp;gt;
&lt;img src=&quot;./album-grid.png&quot; alt=&quot;A grid of albums and covers displayed on
Genderswap.fm&quot; /&gt;(quality:100)
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Overlapping visual motif.&lt;/strong&gt; Intentional overlapping groups the original
and cover as a single unit. The cover album is larger and foregrounded for
emphasis.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;Typography is set in &lt;a href=&quot;https://www.kometa.xyz/typefaces/labil-grotesk/&quot;&gt;Labil Grotesk&lt;/a&gt;, a queer font which topples over itself, unable to rest upright, mirroring the off-kilter elements elsewhere in the app.&lt;/p&gt;
&lt;p&gt;&amp;lt;figure class=&quot;no-bleed&quot;&amp;gt;
&lt;img src=&quot;./typography.png&quot; alt=&quot;Header typography for a detail page within the app. The text reads: Sonata
No. 8 in C Minor, Op. 13 “Pathétique”: II. Adagio cantabile. Jun Fukamachi
covering Ludwig van Beethoven&quot; /&gt;(quality:100)
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Labil Grotesk in use.&lt;/strong&gt; I love the way the &apos;O&apos; falls over, ready to roll
off the screen.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;While the topsy-turvy contextual alternates were enabled for page-level headings, I disabled them for smaller text to prioritize legibility.&lt;/p&gt;
&lt;h2&gt;Little Big Features&lt;/h2&gt;
&lt;p&gt;As with all my work, I looked for opportunities to introduce small but meaningful details.&lt;/p&gt;
&lt;p&gt;&amp;lt;div class=&quot;two-col&quot;&amp;gt;
&amp;lt;figure class=&quot;no-bleed&quot;&amp;gt;
&amp;lt;div class=&quot;video-wrapper&quot;&amp;gt;
&amp;lt;video
autoplay
loop
muted
playsinline
preload=&quot;none&quot;
poster=&quot;/video/tag-filtering-poster.png&quot;
&amp;gt;
&amp;lt;source src=&quot;/video/tag-filtering.mp4&quot; type=&quot;video/mp4&quot; /&amp;gt;
&amp;lt;/video&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Automated tagging.&lt;/strong&gt; Covers are automatically tagged with attributes
like &quot;sadder&quot; or &quot;more danceable&quot;, and you can search and filter by tag.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;
&amp;lt;figure class=&quot;no-bleed&quot;&amp;gt;
&lt;img src=&quot;./readable-urls.png&quot; alt=&quot;A collection of three browser URL boxes with associated titles. The URLs
are nicely formatted with hyphens and human readable text. The titles are
formatted like &amp;quot;Cat Power&apos;s cover of Sea Of Love by Phil Phillips &amp;amp; The
Twilights.&amp;quot;&quot; /&gt;(quality:100)
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Readable URLs and page titles.&lt;/strong&gt; Share human-readable URLs which
accommodate diacritics and non-Latin characters.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;
&amp;lt;figure class=&quot;no-bleed&quot;&amp;gt;
&lt;img src=&quot;./covered-as.png&quot; alt=&quot;&amp;quot;Girls Just Wanna Have Fun&amp;quot; covered as &amp;quot;Girls Just Wanna Have
Some&amp;quot;&quot; /&gt;(quality:100)
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;&quot;Covered as...&quot;&lt;/strong&gt; Conditionally see when a cover&apos;s title diverges from
the original.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;
&amp;lt;figure class=&quot;no-bleed&quot;&amp;gt;
&lt;img src=&quot;./earlier-release.png&quot; alt=&quot;The user has selected ABBA&apos;s Dancing Queen from ABBA Gold. A banner says
there&apos;s an earlier release, and prompts the user to choose the album
Arrival, which was released 32 years
earlier.&quot; /&gt;(quality:100)
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Earlier release prompting.&lt;/strong&gt; Behind the scenes, the app will search for
earlier album releases for your original song. If one is found, it&apos;ll
prompt you to update your submission.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;
&amp;lt;figure class=&quot;no-bleed&quot;&amp;gt;
&lt;img src=&quot;./og-image.png&quot; alt=&quot;A text message with a preview of the album art and page
title.&quot; /&gt;(quality:100)
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Rich social previews.&lt;/strong&gt; Custom Open Graph images generated using
&lt;a href=&quot;https://github.com/vercel/satori&quot;&gt;Satori&lt;/a&gt; and
&lt;a href=&quot;https://github.com/lovell/sharp&quot;&gt;Sharp&lt;/a&gt; display a cover&apos;s title, album
art, and tags.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;
&amp;lt;figure class=&quot;no-bleed&quot;&amp;gt;
&lt;img src=&quot;./just-titles.png&quot; alt=&quot;A list of titles displaying remaster dates and other non-title info
scratched out by a red marker.&quot; /&gt;(quality:100)
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Just the titles.&lt;/strong&gt; Remaster dates, &quot;(Featured on...)&quot;, &quot;[From the
Movie...]&quot;, and other cruft is stripped out, leaving only the artistic
title.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;
&amp;lt;figure class=&quot;no-bleed&quot;&amp;gt;
&amp;lt;div class=&quot;video-wrapper&quot;&amp;gt;
&amp;lt;video
autoplay
loop
muted
playsinline
preload=&quot;none&quot;
poster=&quot;/video/confetti-poster.png&quot;
&amp;gt;
&amp;lt;source src=&quot;/video/confetti.mp4&quot; type=&quot;video/mp4&quot; /&amp;gt;
&amp;lt;/video&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Celebrate contribution.&lt;/strong&gt; Confetti erupts after each new submission. 🎉
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;
&amp;lt;figure class=&quot;no-bleed&quot;&amp;gt;
&lt;img src=&quot;./saved-name.png&quot; alt=&quot;&amp;quot;An input with the label &amp;quot;Your first name (optional)&amp;quot;. The input is
prefilled with the name &amp;quot;Eva&amp;quot;.&quot; /&gt;(quality:100)
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Pre-filled name for repeat submissions.&lt;/strong&gt; Entered names will be
pre-filled for future submissions on the same device.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;
&amp;lt;figure class=&quot;no-bleed&quot;&amp;gt;
&amp;lt;div class=&quot;video-wrapper&quot;&amp;gt;
&amp;lt;video
autoplay
loop
muted
playsinline
preload=&quot;none&quot;
poster=&quot;/video/paste-link-poster.png&quot;
&amp;gt;
&amp;lt;source src=&quot;/video/paste-link.mp4&quot; type=&quot;video/mp4&quot; /&amp;gt;
&amp;lt;/video&amp;gt;
&amp;lt;/div&amp;gt;
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;Paste links into search.&lt;/strong&gt; Title too hard to type? Just copy and paste
the Spotify link.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;
&amp;lt;/div&amp;gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&quot;https://genderswap.fm&quot;&gt;Explore covers&lt;/a&gt;, get a &lt;a href=&quot;https://genderswap.fm/random&quot;&gt;random cover&lt;/a&gt;, or &lt;a href=&quot;https://genderswap.fm/new&quot;&gt;submit your own&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Outcomes&lt;/h2&gt;
&lt;p&gt;I didn&apos;t have any massive ambitions for this app—it was mostly a way for me to learn new technology, and see if I could manage my covers library in a way that felt a little more natural. In that sense, it was a success!&lt;/p&gt;
&lt;p&gt;After finishing the first version of the app, I emailed it to Andrea Lawlor, sharing how &lt;em&gt;Paul Takes the Form&lt;/em&gt; had inspired me. A few days later, I received this reply:&lt;/p&gt;
&lt;p&gt;&amp;lt;figure class=&quot;no-bleed&quot; style=&quot;max-width: 585px&quot;&amp;gt;
&lt;img src=&quot;./andrea-lawlor-email.jpg&quot; alt=&quot;&amp;quot;Andrea Lawlor email to me, 2:45PM: Whoa this is THE COOLEST thing I have
EVER SEEN IN MY LIFE. Thank you!
Wow!&amp;quot;&quot; /&gt;(quality:100)
&amp;lt;figcaption&amp;gt;
&lt;strong&gt;&lt;a href=&quot;https://www.anderlawlor.com/&quot;&gt;Andrea Lawlor&lt;/a&gt;&apos;s reply.&lt;/strong&gt; You heard it
here, folks. The coolest thing ever.
&amp;lt;/figcaption&amp;gt;
&amp;lt;/figure&amp;gt;&lt;/p&gt;
&lt;p&gt;I was overjoyed. Thanks, Andrea. Thanks, Paul.&lt;/p&gt;
&lt;p&gt;Genderswap.fm is now showcased on &lt;a href=&quot;https://madewithsvelte.com/genderswap-fm&quot;&gt;Made with Svelte&lt;/a&gt; and the &lt;a href=&quot;https://utopia.fyi/showcase&quot;&gt;Utopia.fyi Showcase&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Reflections&lt;/h2&gt;
&lt;p&gt;There are many improvements I&apos;d still love to make to the app. At the top of the list is an &lt;a href=&quot;https://github.com/kydecker/genderswap.fm/issues/7&quot;&gt;in-app audio player&lt;/a&gt;. I&apos;d also like &lt;a href=&quot;https://github.com/kydecker/genderswap.fm/issues/133&quot;&gt;better search&lt;/a&gt;, and a way to &lt;a href=&quot;https://github.com/kydecker/genderswap.fm/issues/16&quot;&gt;automatically generate and sync the Genderswap.fm database to a Spotify playlist&lt;/a&gt;. I track &lt;a href=&quot;https://github.com/kydecker/genderswap.fm/issues&quot;&gt;all issues and ideas on GitHub&lt;/a&gt;, and contributions are welcome.&lt;/p&gt;
&lt;p&gt;I learned a lot building this out. The backend is not as scary as it seems, and I taught myself that it&apos;s possible for me to build a full-stack app from start to finish! There&apos;s still more to learn, and I hope to continue working on this project when I have time.&lt;/p&gt;
</content:encoded></item></channel></rss>