Mycelium

I · Meaning

Design What It Is

A card is not a thing. So what is?

Imagine a dashboard with three columns. The left column lists the setup tasks still to do. The middle lists the team. The right lists what's coming up this week. Three clean lists, one well-made List component, used three times. Consistent, accessible, responsive. Nothing wrong with it.

Except that the first column holds actions: work with completion, progress, unfinished work. The second holds people: identity, faces, roles, who's responsible for what. The third holds time: days, distance from now, rhythm. Three fundamentally different kinds of content. Three natures, flattened into one kind of row.

A card is not a thing. A list is not a thing. A row is not a thing. They're ways of displaying things. The question that's missing, one level down, is the one I ask of everything:

What is this?


From structure to meaning

Consider this progression:

div → list item → contact → member

<figure style="margin:1.6rem 0;text-align:center"><svg width="400" height="228" viewBox="0 0 400 228" role="img" aria-label="the same rectangle four times: empty; one row of many; a person with a face and a name; a member with a role, a joining date and a status"><text x="8" y="32" font-family="'JetBrains Mono', ui-monospace, monospace" font-size="9.5" font-weight="400" fill="#8f887d" text-anchor="start">div</text><rect x="96" y="6" width="296" height="40" rx="6" fill="none" stroke="#d8d2c8" stroke-width="1"/><path d="M244 49 v6" stroke="#8f887d" stroke-width="1" fill="none"/><text x="8" y="88" font-family="'JetBrains Mono', ui-monospace, monospace" font-size="9.5" font-weight="400" fill="#8f887d" text-anchor="start">list item</text><rect x="96" y="56" width="296" height="4" rx="2" fill="#eeeae3"/><rect x="96" y="104" width="296" height="4" rx="2" fill="#eeeae3"/><rect x="96" y="62" width="296" height="40" rx="6" fill="none" stroke="#d8d2c8" stroke-width="1"/><rect x="110" y="79" width="120" height="6" rx="3.0" fill="#e0dad0"/><path d="M244 105 v6" stroke="#8f887d" stroke-width="1" fill="none"/><text x="8" y="144" font-family="'JetBrains Mono', ui-monospace, monospace" font-size="9.5" font-weight="400" fill="#8f887d" text-anchor="start">contact</text><rect x="96" y="118" width="296" height="40" rx="6" fill="none" stroke="#d8d2c8" stroke-width="1"/><circle cx="118" cy="138" r="11" fill="#e0dad0"/><rect x="138" y="130" width="96" height="7" rx="3.5" fill="#c9c2b6"/><rect x="138" y="142" width="64" height="5" rx="2.5" fill="#e0dad0"/><path d="M244 161 v6" stroke="#8f887d" stroke-width="1" fill="none"/><text x="8" y="200" font-family="'JetBrains Mono', ui-monospace, monospace" font-size="9.5" font-weight="400" fill="#3a3631" text-anchor="start">member</text><rect x="96" y="174" width="296" height="40" rx="6" fill="none" stroke="#d8d2c8" stroke-width="1"/><circle cx="118" cy="194" r="11" fill="#e0dad0"/><rect x="138" y="186" width="96" height="7" rx="3.5" fill="#c9c2b6"/><rect x="138" y="198" width="64" height="5" rx="2.5" fill="#e0dad0"/><rect x="260" y="186" width="44" height="16" rx="8" fill="#eeeae3"/><text x="282" y="197.5" font-family="Inter, system-ui, sans-serif" font-size="8" font-weight="400" fill="#3a3631" text-anchor="middle">Admin</text><rect x="314" y="191" width="40" height="5" rx="2.5" fill="#eeeae3"/><circle cx="372" cy="194" r="4" fill="#7a1f1f"/></svg><figcaption style="font-size:.8rem;color:#a8a298;font-style:italic;margin-top:.4rem">The same rectangle four times. Each step down, it knows more about what it is, and shows more of it.</figcaption></figure>

All four could describe the exact same rectangle on a screen. But every step tells us more about what we're designing.

A div is structure. It tells us almost nothing. A list item carries a UI contract: we know it belongs to a collection. A contact is a domain object, and now we're dealing with identity: a person or an organization, a name, perhaps a face, ways to reach them. A member tells us more again: this contact belongs to something, and membership brings status, role, permissions, a joining date, activity, belonging.

The deeper we go, the more the object starts telling us how it wants to be shown. The mistake is stopping too early. Think list item and you design a list item. Think member and you design a member. Those produce very different interfaces.


What is a phone number?

Picture a list of phone numbers, nothing else on the rows. What is each row?

The easy answer is a phone number. It's almost never the right one.

When someone you haven't saved writes to you on WhatsApp, the row shows their number, because it has nothing better to show. But the row isn't a phone number, and it isn't quite a person either. It's a conversation, with whoever is on the other side: a person, a shop, a bank. The number is only what WhatsApp calls them until it knows better, and the moment it learns a name and a face, the number steps aside. And because the row is a conversation, you already know what tapping it will do: open the chat.

Now take the lines a company pays for every month. Surely those are just numbers. But why would anyone open that list? Maybe the phone bill came in at a thousand dollars and someone wants to know why: fifty lines, and here they are. Then each row is a charge. Or maybe it's to see which extensions are actually used, by whom, and whether anyone answers them. Then each row is a desk, and a desk has someone at it, or doesn't.

And each answer walks somewhere different. Two steps ahead of a conversation is a reply, saving the number, or blocking it. Two steps ahead of a charge is last month's bill, the line nobody has used since spring, and the button that cancels it. Two steps ahead of a desk is who sits there, the calls it missed, and where those calls should go when nobody does. Three journeys, three sets of actions, and each set would be wrong on the other two lists.

Same digits every time: a conversation, a charge, a desk. Nothing in the number tells you which. Only what the list is for does.


Semantic form

This isn't a new idea. It's form follows function (Sullivan, 1896); it's what Krippendorff called product semantics in the 1980s, the study of how the shape of a made object tells you what it is and what it's for; it's Norman's signifiers, the perceivable cues that tell a person what actions are possible. In this book, I'll borrow a name for it and call it semantic form: the visual form of an interface should communicate the nature of what it represents.

Go back to that dashboard: the setup tasks still to do on the left, the team in the middle, what's coming up this week on the right. Three lists, one component. Now ask what each column is, one level deeper than "a list". Not to pick a style for it. Because the answer tells you what the person will want from it next, which is where the features of a screen can honestly come from.

The first isn't a list of tasks. It's the setup steps an account can't work without until they're done. Each one is a task, and I care whether it's done, so the form shows that state and lets me change it in the same place. But stay with the question a moment longer. What do I actually want from this column? How much have I completed and how much is left. Whether I'm moving at a decent pace or stuck. Which of these matters more than the others. Whether one is blocked until another is done. Or, most mornings, just: what's the next thing I need to do? Every one of those is a feature, and none of them is visible while the column is "a list of tasks". A list has no pace and no next.

The second isn't a list of contacts. It's the team: members, with a role, a date they joined, whether they're active. People are recognized before they're read, so the row leads with what a person is recognized by, a face, or the shape where one belongs, and a name set like a name. The number the system uses to reach them shows only when there's nothing better, the way WhatsApp shows someone you haven't saved. Then the same longer question. How many of them are online right now? How should they be ordered, by name, by role, by who logged in last? Who's new this month? I don't know what fields this product has, and neither do you, but the questions don't need the fields. They need the noun. Once the column is the team instead of a list, the questions ask themselves, and the fields turn out to be answers.

The third isn't a list of dates. Say it's release due dates. Each is a date, but what I want from a due date is different from what I'd want from a birthday or a timestamp: how soon, which is first, which has slipped, which are close enough together to fight for the same week. So the day carries the weight, the ones that are near read as near, the overdue one interrupts, and the rhythm of the column shows the shape of the month. A different list of dates would answer different questions with a different form. The form came from the noun.

Three columns, three deeper nouns, one typography, one spacing scale, one palette. The differences between them come from what the rows are. Where two rows don't differ in what they are, there's nothing for their forms to differ about. And the features that make each column worth having came from the same place: not from a backlog, from asking what each column is and what a person would want from it two steps on.


Nature, then state

An interface communicates two things before any detail is read. Nature: what is it? A person, a task, a payment, a conversation, a project. And state: what does it mean right now? Good, bad, done, waiting, blocked, urgent, needs my attention, just so you know. They're separate dimensions. Payment is nature; payment failed is state. Member is nature; awaiting approval is state.

The interface communicates nature and state. Text communicates detail.


Let the object teach you

Before I design an element now, I ask three things of the object itself. What is it? What properties make it what it is? What can happen to it that matters to the person?

| Object | Its nature gives us | Its state might be | |---|---|---| | Conversation | participants, messages, sequence, who spoke, when | active, unread, waiting for them, waiting for us, escalated, resolved | | Invoice | money, payer, recipient, amount, due date | draft, upcoming, paid, overdue, failed | | Project | goals, work, ownership, milestones, progress | on track, waiting, blocked, done, at risk |

Once those are written down, the interface starts suggesting its own form. You're no longer beginning with an empty rectangle. You're beginning with an object that already knows what it is.

The alternative is what modern design systems make so easy: Card → Heading → Description → List → Row → Icon → Text → Button, repeated everywhere, until customers are rows and invoices are rows and messages are rows and the whole product is interchangeable rectangles told apart by their labels. That's why an interface can be beautifully polished and still feel generic. It isn't missing decoration. It's missing meaning. The product's actual world, its people, money, work, conversations, time, successes and problems, got flattened into components.