Full Width [alt+shift+f] Shortcuts [alt+shift+k]
Sign Up [alt+shift+s] Log In [alt+shift+l]
1
I was reading Manu’s post about ‘old tech’ and suddenly thought, markdown is really, really good. What is it? Markdown is a markup (get it?) language which aims to make formatting text as easy as possible, while still being easy to read. Markdown can be processed into HTML, which is what the web is made of. It was created by John Gruber and Aaron Schwartz, and released over 20 years ago. It is commonly found in blogging software, content management systems, software documentation, and many other places. This post that you’re reading right now is written in markdown. Most alternatives to markdown are what I call ‘rich text’, which vary quite a bit in how they work, they are often more complex and proprietary. Here’s why I think that markdown is really, really good. You write it Markdown is for writing, and it’s designed to be written. You don’t need to memorise an interface to use markdown, you need to remember a syntax instead, and you can use that same syntax everywhere that you write markdown. In markdown to write add a link to a webpage you type a ‘[‘ followed by the link text, if you’re really lucky whatever you’re typing into is smart enough to close that square bracket for you, then you type a ‘(‘ followed by the URL. Notice you never had to stop typing to add this link, this process is exactly the same wherever you are writing markdown, there is no keyboard shortcuts or special interface to remember. In ‘rich text’ world you would need to stop typing and do a few things. You might need to type your link text then highlight it, then find then whichever button that you need to convert it to a link, then you may need to use whichever interface this particular app uses to add the link for you, they vary wildly. It’s HTML Markdown makes HTML, perfectly standard HTML that any web browser can understand, every single thing that you write with markdown becomes HTML, just like the HTML that you are reading right now. Sadly in the ‘rich text’ world you can never really...
4th Feb 2025

Stay updated

Get a weekly newsletter with the top 5 articles worth reading every week.

More from Luke Mitchell | Product Designer

Warm email

I have an email address that you’ll find in the footer below this post, I rarely get emails to it, the ones I do get fall into two categories: very, very kind people paying compliments to me about this website; secondly some sort of cold email, usually from a SEO expert explaining that my SEO is shit. Like Eric I am often tempted to email back and see what they would do if I took them up on the offer. The other day I got a cold email that stuck out, here’s what it said: hey luke, this is an out-of-the-blue email but i’m writing on behalf of the small team behind ruks.org: we’ve been (manually!) compiling a big database of design + creative individuals and firms who we think are awesome. if you’re reading this email, that means at some point and somehow, we came across your portfolio and/or your work. (manually. no web scrapers.) for context, ruks.org is just a nice, short domain that we bought a while back, but we’ve decided it stands for the “[r]esource of [u]n[k]nown [s]pecialists.” that is to say, it’s a database of creative talent. we are not venture-backed, and the platform is currently free. it’s a side project of family office, a design studio based in new york. long story short, our spreadsheet of portfolios we had saved got a little unwieldy, and we figured it’d be nice to make the resource public. our hope that it can help route opportunities for work to the inboxes of great creative talent. you can click here to make an account and take a look at your profile. if you would like to correct your profile or would like to recommend that any other creatives be added, please let us know. you can respond directly to this email since this is a manually sent note. all the best, annie swanson at ruks.org + family office What have I just learned? I have been added to a database of other creative people The database has been hand-crafted It was hand-crafted by a small team It was built to offer a resource to the wider community It is currently free, probably not always It does not need to be profitable because it has no outside funding It is called ‘ruks’ The name has a fun back-story It was originally an internal tool used by the small team I can take a look at the entry they’ve created for me This email was sent manually, by Annie I can reply to this email because it was sent manually by Annie The small team is called Family Office Family Office is based in New York And so on… Isn’t that nice? It’s a cold email from a real person, at a real company, in a real place, who have built a real thing, that has a real use. In those four paragraphs I have learned so much, it answered every question and settled every doubt I had in real time while I was reading it. It gives me some decent, optional action items, and it gives me an easy way to ask more questions. It’s very sad that this seems so original and refreshing to me. But let’s not dwell too much on that feeling. Go check out ruks, I’m in it. Thanks Annie.

29th Dec 2025 1 votes
Chicken accessories for chickens

This post originally appeared on thoughtbot.com I was browsing an online marketplace the other day because I was a bit bored, and because I have a unique need to seek out dark patterns. Something caught my eye as I scrolled. Amongst all the other suspiciously cheap items, was a bag for a chicken. Not a bag with a chicken pattern, not a bag shaped like a chicken, no — a bag to carry a chicken. A living chicken. A bag for carrying a chicken. It made me smile as I took a screenshot. After 30 seconds, I went back to scrolling with a blank expression. It wasn’t over. I kept thinking about this thing for days afterward. All I had were questions: Why does this product exist? Why does a chicken need to be carried in a chicken-carrying bag? Where is the chicken going in the chicken-carrying bag? Who is this chicken-carrying bag for? How many chickens does this chicken toting person own? In the absence of the chicken-carrying bag, how do they carry their chicken(s)? How many chicken-carrying bags have been sold so far? How many chicken-carrying bags need to be sold to break even on the initial investment? Who came up with the idea for the chicken-carrying bag? Do they have any first-hand experience with chicken carrying? How do you get the chicken into the chicken-carrying bag? Did the chicken-carrying bag manufacturer test the usability of the chicken-carrying bag? How else did they test the chicken-carrying bag? When did the chicken-carrying bag manufacturer consider the chicken-carrying bag good enough to sell? How did they decide on the fabric to use for the chicken-carrying bag? What does the next version of the chicken-carrying bag look like? How will the chicken-carrying bag manufacturer find out the highest-priority feature to add next? How do I get to a place in my life where my singular focus is improving my chicken-carrying experience? The list is endless… What does this have to do with design? Next time you’re struggling to come up with a question to find out more about something — be it a design problem, a new product pitched by a budding founder, or even another bizarre (to you) product you’ve found online — think of this chicken-carrying bag. You will have plenty. Alternative titles for this post: Why Did the Chicken Cross the Road in a Bag? This £5.17 Item Revolutionised My EDC For Sale: Chicken Bag, Never Worn (OK, one more question, is the chicken wearing the bag?) 5 Chicken Accessory Trends for 2025

17th Jan 2025 1 votes
The time for designers to learn to code is now

I often use the analogy that when we design for print, what are we doing over and over again? Doing proof prints. Why then when designing websites (or apps) are we not getting in to the browser as quickly as possible, rather than creating interactive pictures of websites in Figma? This is where you can stand out as a designer by learning to code. I’m not talking about writing production code with developers here. Hell, maybe in the future, but I’m talking getting a good understanding of How Things Work™ and using that knowledge to blast your web and app design skills into the stratosphere. Andy’s post is an excellent guide and list of resources, it’s also one of the best summaries of why you should at least understand how the things you build for work, and some very good reasons to learn to code as a designer, it’s an ancient argument but in 2024 it might just make you stand out enough when some of our work can be spat out in 30 seconds by AI. With design tools further commoditising and sanitising expected creative output, the time for designers to be able to stand out is very much here. I think for some, learning to code is a good route for that. Please give this a try if you’re a new (or not so new) designer.

12th Jul 2024 1 votes
How I collect & create bookmarks

I have been collecting bookmarks for quite a while, as you read this there are 1052 of them, which shocks me, they really build up fast. What I haven’t done yet is explain how I collect them and how they end up on this site. Ethos Describing my ethos properly is probably another post by itself, but if I find something delightful, engaging, interesting, beautiful or useful it will probably make it into my list. One rule that I do have is that I can only add something to the list once, which can be a bit limiting if somebody does a great redesign of their website. Sources I have a few places that I find my bookmarks, the best one being the many RSS feeds that I am subscribed to. My favourites are: Things to click SC 2.4.4 Sidebar Meanwhile I often browse a few websites that I have saved as Safari bookmarks. Some of my favourites are: Typewolf Minimal Gallery Collosal Savee It’s Nice That I also find a few of my bookmarks by scrolling Mastodon, and sometimes my lovely coworkers will share something in Slack that I find interesting too. Sometimes I even just stumble upon things by myself, if you can believe it. Method I usually spend a Sunday morning browsing through all my feeds, websites and accounts to find new links to bookmark, it’s a bit like reading the Sunday newspaper. I use my trusty iPad to do this. Once I find a link to bookmark I will store it in Drafts to work on later. I will also keep note of the place I found the link, so that I can credit them. When I next find time and I’m working at my desk I will sort through my links in Drafts and begin adding them into my extra-special-custom-made CMS. The first step is to open the Raycast extension I built, it allows me to enter all the bookmark details and save them to a database as a draft, to be edited or published later. A few notes on the extension: I can grab the current Safari tab URL and title by tapping a keyboard shortcut, which saves on copy-pasting. If I check ‘url as title’ the extension will crunch the URL into a nicer format: https://www.example.com becomes example.com. It will save the form as a draft if I need to do something else in the background. Later I can open the other Raycast command which I use to manage the bookmarks, and publish them. In the screenshot below you see that it displays all the saved content with handy indicators for unpublished bookmarks. From here I can tap a keyboard shortcut to publish or delete the drafts as needed. Once published the new bookmarks will appear on the bookmarks page the next day – I publish my website every morning, automatically. Back-end The bookmarks system backend is a simple app written using Hono, which is a more modern equivalent to Express (which is how the first version was built). It makes it easy to write a CRUD style API to list, create, edit, and delete bookmarks. The API is hosted on cloudflare as a serverless worker. For a database the bookmarks system uses cloudflare D1, which is a nice wrapper around SQLite. Front-end As I’ve shown above I add, publish, and edit bookmarks using Raycast. This website is built with Eleventy, my favourite way to build a website. Eleventy makes it easy to grab the bookmarks data, adding a JavaScript file to the data folder that exports an object is all that is needed. Once the data is fetched I then display the bookmarks using a Nunjucks template for the markup. No client side JavaScript is exported, just plain HTML. That’s pretty much it. That’s my DIY approach to collecting links a putting them on this website. You can browse all the bookmarks at /bookmarks, you can also find the RSS, and JSON feed to subscribe to them on that page too.

15th Jun 2024 1 votes

More in design

The least wrong colors, version 2

Four years ago, I wrote “How to pick the least wrong colors.” The gist is: picking a categorical color palette is an optimization problem. There’s no such thing as the right colors. But if you use the right cost function, and the right kind of hill climbing, you can at least get the least wrong ones. Since the original post I’ve been slowly picking away at improvements and new approaches. Now that we’re past the singularity, I’ve put a few coding robots on the job. It’s reassuring that many of my assumptions were good ones! The robots have been able to improve the code, bridging some of the gaps in my own knowledge. Today, I’m publishing an updated version of the algorithm as an npm package, along with a fancy GUI version. While there’s still more to do, I’m proud of how far I’ve been able to take it. What’s new New evaluators More controls The public API and a CLI What’s improved The annealing algorithm Configurable color space and distance metric The results One more thing Acknowledgements What’s new New evaluators Almost as soon as I published the first version, I realized that the cost function lends itself really well to modularity. Beyond my initial evaluation functions, I could design new ones, and provide a framework for anyone to plug in their own. As a recap, my original criteria for good categorical colors, mapped to evaluation functions: Similarity — a way of measuring the similarity of one palette to another, useful for providing art direction and getting brand alignment Energy — the colors should be different from each other so they aren’t liable to be confused from one another Range — the differences between the colors should be consistent so unintended groupings don’t appear Color vision deficiency — simulating the colors under different types of color blindness (red-green, blue-yellow, partial to full tritanopia) Here’s the new evaluators: JND — strongly reject palettes that have two or more colors that are too similar Avoid — the mirror image of the similarity evaluation, push colors away from a user-defined set Contrast — compares colors, keeping them above the WCAG AA color contrast floor. Can be used with a background color to maintain contrast on a chart’s background Saliency — uses color naming study data to prefer colors that are easy to name Name difference — the mirror image of saliency, avoiding colors that share names Each of these evaluators can be weighted, indicating the kinds of tradeoffs and priorities you’d like for your color palette. Additionally, the whole evaluator system is pluggable: you can define your own evaluators and have them drive the optimizer! More controls Colors can now be fixed in place, or pinned to a particular order, making it easier to load in existing palettes and optimize all or just some of the colors. Individual channels of each color can be locked, too, meaning you can keep the saturation or hue of a color fixed while optimizing its lightness. This works in any color space. The public API and a CLI The whole package is now a proper library, with a public API. This means: 1. the whole thing is now distributable through npm, with proper versioning, 2. there’s a CLI, making it much more ergonomic for both humans and agents. The API allows for full configuration of the algorithm, as well as loading in colors to optimize. Output can be in raw color values, CSS properties, or DTCG JSON. There’s also a new reportJndIssues endpoint that allows you to evaluate palettes without optimizing them, which is useful to compare a generated palette to commonly-used ones (like Observable, d3, IBM Carbon, and more). What’s improved The annealing algorithm When I wrote the initial algorithm in 2022, I had just learned about simulated annealing. I’ll be honest: I don’t know much more today than I did then. But with AI-assisted research, I was able to solve some questions I had about the initial implementation. Now, the algorithm picks the correct starting temperature based on some random initial samples. Mutation also happens in a scaled manner, so colors change less towards the end of the optimization schedule. Iterations can be capped to prevent very long runs, and the whole thing is much, much more performant. Configurable color space and distance metric The first version of the algorithm worked in RGB space. Now, it defaults to okhsl, but even this is configurable. Individual channels can be constrained to dial in the palette’s boundaries. Also, you can choose which color distance metric you’d like to use (but the library uses CIEDE2000 by default). This flexibility is powered largely by a move from chroma.js to culori. I’ve learned a ton about color spaces since 2022, so being able to mix and match color spaces with distance metrics has been extremely useful. The results The category-colors library reliably produces better results than other palette-generating tools and industry-standard color palettes. Compared to other palette-generating tools, category-colors has more control. Palettailor, for example, optimizes for pure color difference, without accounting for color vision deficiency. QualPal brings some of the optimization parameters, but doesn’t allow for steering towards or away from arbitrary colors. Scores at 8 colors ΔEMinimum ΔEworst of CVD Name differenceMinimum Uniformitylower is better category-colors 22.6 ±1.6 13.7 ±2.0 0.35 ±0.14 best in column 0.30 ±0.02 best in column QualPal 1.1.0 24.7 21.8 best in column 0.10 0.44 Palettailor 26.6 ±2.4 best in column 4.5 ±1.7 0.34 ±0.16 0.34 ±0.04 Colorgorical 15.8 ±3.3 4.1 ±1.6 0.09 ±0.06 0.42 ±0.03 All numbers are at 8 colors. Rows with ± are mean ± standard deviation over 10 palettes; rows without are deterministic and produce one palette. category-colors and Palettailor are 10 independent runs on the same seeds; Colorgorical’s row is 10 palettes from its authors’ own sampling script at equal criterion weights. QualPal was run with CVD on, matched bounds, and takes no seed. Name difference is Heer & Stone’s 1 − cosine; Colorgorical’s own interface reports a Hellinger distance instead. Shaded cells are the best value in their column. Compared to industry-standard palettes, category-colors can produce more optimal palettes, especially at high cardinality. Scores at 8 colors ΔEMinimum ΔEworst of CVD Name differenceMinimum Uniformitylower is better category-colors 22.6 ±1.6 best in column 13.7 ±2.0 best in column 0.35 ±0.14 0.30 ±0.02 best in column Okabe–Ito 21.3 8.8 0.06 0.34 Observable 10 18.4 0.6 0.40 0.34 Tableau 10 18.1 3.2 0.24 0.32 d3 category10 16.2 1.6 0.84 best in column 0.40 ColorBrewer Set3 13.7 1.9 0.16 0.32 IBM Carbon 12.8 5.0 0.11 0.34 Same run: 8 colors, 10 trials. Reference palettes are deterministic, so they're single values. Shaded cells are the best value in their column. One more thing I’ve built a UI that consumes the package and makes it easy to generate and optimize palettes. This has been the biggest request since I published the initial essay, so it’s the thing I’m excited to share. It’s ridiculously overengineered, but hey, what else are personal projects for? Acknowledgements Many measurements come from published research: Gaurav Sharma, Wencheng Wu and Edul Dalal for CIEDE2000; Gustavo Machado, Manuel Oliveira and Leandro Fernandes for the color vision deficiency simulation; Maureen Stone, Danielle Albers Szafir and Vidya Setlur for the size-dependent just-noticeable-difference result; Jeffrey Heer and Maureen Stone, whose color naming models and the c3 data from the Stanford Visualization Group power both the saliency and name-difference evaluators. Existing palettes: Masataka Okabe and Kei Ito’s Color Universal Design set; Matthew Petroff’s sequences; and Mark Harrower and Cynthia Brewer’s ColorBrewer. Other generators laid a lot of the groundwork: Kecheng Lu and colleagues (Palettailor), Connor Gramazio, David Laidlaw and Karen Schloss (Colorgorical), Johan Larsson (QualPal), and Chin Tseng, Arran Zeyu Wang, Ghulam Jilani Quadri and Danielle Albers Szafir (CatPAW). Andrew McNutt, Maureen Stone and Jeffrey Heer’s color-buddy has also been indispensable. Finally, Dan Burzo’s culori made it easy to make this library colorspace-agnostic.

a week ago 1 votes
Mountains of work

This is part of a new experiment I started in an effort to document the process of making Niche design.

a week ago 1 votes
When the canvas starts acting, who’s really in control?

Weekly curated resources for designers — thinkers and makers.

a week ago 1 votes
Gestalt Principles for Visual UI Design

Users parse a layout before they read its labels. Whitespace, borders, alignment, color, and motion determine what belongs together. When these cues fight the content, users attach the label, price, warning, status, or action to the wrong object. Proximity, similarity, enclosure, and the other Gestalt cues guide the eye, snapping visual chaos into clarity.

a week ago 2 votes
The silks of Como: A reminder of the value of craft

I miss this. Visiting a mill is such an enjoyable, often inspiring experience, yet I don’t do it as much as I used to. Perhaps because once you’d done one worsted weaver it’s hard to justify more.  But we’ve never done silk. I did go to Vann... > Read more

a week ago 1 votes
📚 BoredReading

You seem to be enjoying this.

Join free to unlock everything.

Create free account

Already have an account? Sign in