<?xml version="1.0" encoding="UTF-8"?><rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>x129 · Sundeep</title><description>Sundeep&apos;s writing.</description><link>https://x129.in/</link><item><title>LLM benchmarks, and writing one</title><link>https://x129.in/writing/trope-benchmark/</link><guid isPermaLink="true">https://x129.in/writing/trope-benchmark/</guid><description>I want to know what it takes to build a benchmark for language models, so I&apos;m writing one about storytelling tropes.</description><pubDate>Sat, 04 Jul 2026 21:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I’ve been curious about what it takes to build a benchmark for language models: a fixed set of tasks with known answers that models get scored on. So I’m writing one.&lt;/p&gt;
&lt;p&gt;I picked a domain I enjoy: storytelling tropes. The task is for a model to read a passage of fiction and name the tropes in it. New models keep coming, and this gives me my own way of measuring them.&lt;/p&gt;
&lt;p&gt;The rough plan is below. Nothing is built yet.&lt;/p&gt;
&lt;h2 id=&quot;the-plan&quot;&gt;The plan&lt;/h2&gt;
&lt;h3 id=&quot;step-1-create-a-vocabulary&quot;&gt;Step 1: create a vocabulary&lt;/h3&gt;
&lt;p&gt;The trope names come from TVTropes. The site is a folksonomy, meaning a community built it with no enforced structure, so entries vary a lot in how broad or narrow they are. I’ll curate 100 to 300 tropes by hand into a fixed vocabulary, with clear rules for when each one counts as present. I already have a few favorites in mind. The test of a good rule is that two people reading the same passage agree. Tropes too vague to grade get dropped. Foreshadowing, e.g., is present in almost any story, so a model earns credit by naming it everywhere. The vocabulary could be swapped for a folklore index like Aarne-Thompson-Uther and the benchmark would test the same skill.&lt;/p&gt;
&lt;p&gt;Here is what one item could look like. The passage, which I made up: “The old fisherman teaches the girl to read the tides. On the night of the storm he does not come back from the water, and in the morning she takes his boat out alone.” The right label is Mentor Occupational Hazard, the trope where the teacher dies and the student steps up. Revenge is a plausible wrong answer, because the story turns on a death but nothing in the passage seeks payback. The Mentor is a near miss, true but broader than what the passage supports.&lt;/p&gt;
&lt;h3 id=&quot;step-2-find-the-text&quot;&gt;Step 2: find the text&lt;/h3&gt;
&lt;p&gt;The hard part is finding passages the models can’t cheat on. The benchmark fails when a passage and its trope labels appear together in training data, because then a model can recall the answer instead of reasoning. That rules out anything with a TVTropes page, and popular stories in general, because people discuss popular stories and the discussion names the tropes.&lt;/p&gt;
&lt;p&gt;The safer sources are synopses I write, obscure works nobody has discussed, and recent posts from writing subreddits like r/WritingPrompts, taken from the middle of the upvote range. Two details on the Reddit option. The prompt often names the trope outright, so the model never sees the prompt, though the annotators can use it as a hint. And the stories belong to their authors, so nothing gets republished without asking. At a few hundred passages, asking is feasible.&lt;/p&gt;
&lt;h3 id=&quot;step-3-label-the-text&quot;&gt;Step 3: label the text&lt;/h3&gt;
&lt;p&gt;Two people label each passage independently, and I measure how often they agree. Cohen’s kappa is the standard number for this. Only labels with decent agreement survive. Where the two disagree, the trope gets cut or its rule gets sharpened. Each passage also gets a few tropes that sound plausible but are absent, to check that wrong guesses get punished.&lt;/p&gt;
&lt;p&gt;If I label everything myself, the benchmark is a quiz about my own opinions. I don’t know yet who the second person is. That is the first real problem to solve.&lt;/p&gt;
&lt;h3 id=&quot;step-4-grade-the-answers&quot;&gt;Step 4: grade the answers&lt;/h3&gt;
&lt;p&gt;The grading is simple on purpose. The model returns a list of trope names from the vocabulary, and the grader checks that list against the labels. No language model judges anything, so there is no judge for a model to persuade.&lt;/p&gt;
&lt;p&gt;The score is F1, which balances precision (what share of the guesses were right) against recall (what share of the true tropes were found). Plain accuracy fails here, because most tropes are absent from any passage, so a model that answers nothing looks near perfect. Precision punishes the cheapest trick, which is guessing everything plausible. A near miss scores zero. Answering The Mentor when Mentor Occupational Hazard is correct earns nothing, and the miss goes into a separate analysis instead. Every partial credit rule gives a model a way to raise its score without getting better at the task.&lt;/p&gt;
&lt;p&gt;Two checks before trusting a score. First, read about 50 transcripts sorted by score, because some high scores will be garbage the grader missed and some low scores will be right answers it mishandled. Fix the grader or the labels, run again, and expect several rounds. Second, probe each model for contamination. Give it the first half of a passage and see whether it can complete the text or name the source. A model that recognizes a passage can’t be credited with reasoning about it, so the probe results get reported next to the scores.&lt;/p&gt;
&lt;h3 id=&quot;step-5-publish&quot;&gt;Step 5: publish&lt;/h3&gt;
&lt;p&gt;The harness, a small labeled demo set, and results for five to ten current models go in a public repo. The labels for the scored set stay private, because anything published gets trained on within a cycle or two. Public passages still pick up discussion over time, so the plan is to replace them on a schedule. The only passages that stay clean are the ones I write and never publish.&lt;/p&gt;
&lt;p&gt;One caveat. A competent annotator can derive the labels from any public passage, so private labels protect against accidental scraping, not against someone labeling the public set on purpose. At this scale it is unlikely anyone would bother, but the writeup should say so.&lt;/p&gt;
&lt;h2 id=&quot;later&quot;&gt;Later&lt;/h2&gt;
&lt;p&gt;If the basic version works, the harder question is whether a story plays a trope straight, subverts it, or inverts it. That asks the model to work out what expectation the story sets up and then violates.&lt;/p&gt;
&lt;p&gt;The vocabulary is step 1.&lt;/p&gt;</content:encoded></item><item><title>Owning my data</title><link>https://x129.in/writing/context-sovereignty/</link><guid isPermaLink="true">https://x129.in/writing/context-sovereignty/</guid><description>I want to be able to move, inspect, and delete anything my software knows about me.</description><pubDate>Fri, 12 Jun 2026 15:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I’m trying to keep ownership of the data of my life: my notes, my conversations, my location history. The test I use is whether I can move the data, inspect it, and delete it. If I can’t do all three, I don’t own it.&lt;/p&gt;
&lt;p&gt;There seem to be two separate choices here. The first is what gets recorded: how much, in what detail, and when. The second is what gets shown: to whom, and in how much detail. They’re independent. I can record everything and show nothing.&lt;/p&gt;
&lt;p&gt;I’m trying this out in Tukur, my location-sharing app. Turning on sharing is one choice. What other people see is a separate choice. The same day of GPS points can show up as a live dot for the few people in my circle, or as a short summary that only I can read.&lt;/p&gt;
&lt;p&gt;I don’t think this means self-hosting everything. A third-party service seems fine when I pay it for servers, it doesn’t sell my data, and I can leave with everything. If I want out of Supabase, I can take my Postgres dump and go.&lt;/p&gt;
&lt;p&gt;The oldest version of this in my life is a folder of plain text notes that every tool I use reads and writes. Tools come and go, and the files stay.&lt;/p&gt;
&lt;p&gt;These days, before I build something new, I ask whether it leaves me owning more of my data or less.&lt;/p&gt;</content:encoded></item><item><title>Open web first</title><link>https://x129.in/writing/open-web-first/</link><guid isPermaLink="true">https://x129.in/writing/open-web-first/</guid><description>Why I&apos;ve been shipping websites instead of native apps, and where that&apos;s starting to break.</description><pubDate>Fri, 12 Jun 2026 14:00:00 GMT</pubDate><content:encoded>&lt;p&gt;So far, everything I’ve shipped is a URL. Send the link, tap it, and you’re in. There’s no install step and no review queue between me and the people I built the thing for.&lt;/p&gt;
&lt;p&gt;Half of the reason is arithmetic. I’m one person, and I can’t build and maintain native apps for iOS and Android alone. One web build works on every phone in the family group chat.&lt;/p&gt;
&lt;p&gt;The other half is control. Apple and Google decide what goes in their stores and what it costs to be there. On the web, I put the thing up and it’s live.&lt;/p&gt;
&lt;p&gt;An installed app can send notifications at any time. A URL waits until I want it. I like that better.&lt;/p&gt;
&lt;p&gt;Sometimes the browser can’t do the job. Tukur is at that limit now. iOS won’t let a browser tab read the phone’s location in the background, so Tukur will probably have to become a native app. The plan is to keep the web version as the main one and let the native app cover what the browser can’t. I haven’t tried this yet, so we’ll see.&lt;/p&gt;
&lt;p&gt;The cost of web first is discoverability and reach. People look for apps in the store, and a website is easier to miss. So far, with every user in my contacts, that hasn’t mattered.&lt;/p&gt;</content:encoded></item><item><title>Home cooking</title><link>https://x129.in/writing/home-cooking/</link><guid isPermaLink="true">https://x129.in/writing/home-cooking/</guid><description>What I&apos;m learning by building software only for people I know.</description><pubDate>Fri, 12 Jun 2026 13:00:00 GMT</pubDate><content:encoded>&lt;p&gt;I’m trying to build software just for myself and the people close to me. Every user is in my contacts. That lets me skip most of the usual product work. There’s nothing to market and nothing to A/B test, and I don’t have to guess whether anyone uses the thing. I can ask them at dinner.&lt;/p&gt;
&lt;p&gt;The software still has to be easy. The bar I’m aiming for: someone in my family can figure it out in ten seconds without texting me. I polish things so they’re easy to use, not so they hold attention.&lt;/p&gt;
&lt;p&gt;Decisions get smaller too. I hardcode settings that a commercial product would make configurable. I skip the explanations that exist for strangers. I’m building for ten or twenty people, and I know all of them.&lt;/p&gt;
&lt;p&gt;The circle stays loose. Someone will share a Tukur link with a person I’ve never met, and that’s fine. I cook for my family, and sometimes a friend brings a friend to dinner. The name comes from Robin Sloan’s essay &lt;a href=&quot;https://www.robinsloan.com/notes/home-cooked-app/&quot;&gt;“An app can be a home-cooked meal”&lt;/a&gt;, and I’m more or less following his recipe.&lt;/p&gt;
&lt;p&gt;There’s no business model, and I’m not looking for one. Nothing here needs to collect anything from the people using it, so their data stays theirs.&lt;/p&gt;</content:encoded></item><item><title>UX principles for engineers</title><link>https://x129.in/writing/ux-principles-for-engineers/</link><guid isPermaLink="true">https://x129.in/writing/ux-principles-for-engineers/</guid><description>Notes on making software feel good to use, for backend developers new to design.</description><pubDate>Fri, 24 Apr 2026 20:00:00 GMT</pubDate><content:encoded>&lt;details open&gt;
&lt;summary&gt;Contents&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;#the-three-layers&quot;&gt;The three layers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#orthogonalize-the-axes-find-the-independent-dimensions&quot;&gt;Orthogonalize the axes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#core-principles&quot;&gt;Core principles&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#reusable-patterns&quot;&gt;Reusable patterns&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#design-process&quot;&gt;Design process&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#vocabulary&quot;&gt;Vocabulary&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#bridges-from-backend-to-design&quot;&gt;Bridges from backend to design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;#common-traps&quot;&gt;Common traps&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;hr&gt;
&lt;h2 id=&quot;the-three-layers&quot;&gt;The three layers&lt;/h2&gt;
&lt;p&gt;Most design problems fall into one of three layers. Knowing which layer a problem lives on tells you which tool to reach for.&lt;/p&gt;





























&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Layer&lt;/th&gt;&lt;th&gt;What it decides&lt;/th&gt;&lt;th&gt;Fails as&lt;/th&gt;&lt;th&gt;Tool to fix&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Information architecture&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;What concepts exist and how they relate&lt;/td&gt;&lt;td&gt;&lt;em&gt;”I don’t know what this app is about.”&lt;/em&gt;&lt;/td&gt;&lt;td&gt;Concept map, rename things&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Interaction design&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;What happens when you do something, and how state moves between screens&lt;/td&gt;&lt;td&gt;&lt;em&gt;”I got stuck / lost / surprised.”&lt;/em&gt;&lt;/td&gt;&lt;td&gt;Flow diagrams, prototypes, state machines&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Visual design&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Type, color, hierarchy, motion (how it looks and feels)&lt;/td&gt;&lt;td&gt;&lt;em&gt;“This feels cheap / cold / generic.”&lt;/em&gt;&lt;/td&gt;&lt;td&gt;Mood boards, component libraries, a single aesthetic commitment&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;p&gt;Products with a voice (kids’ apps, coaching apps, anything with narrative) have a fourth layer above these: narrative design, how the product speaks. Work the layers in the order a user meets them: voice before pixels, pixels before behavior. A screen that passes one layer and fails another is still failing.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;orthogonalize-the-axes-find-the-independent-dimensions&quot;&gt;Orthogonalize the axes (find the independent dimensions)&lt;/h2&gt;
&lt;p&gt;Before designing anything, identify the independent dimensions of your problem. Confused designs are almost always designs where two axes were collapsed into one.&lt;/p&gt;
&lt;p&gt;A parent who wants read-aloud mode in Golpo isn’t necessarily targeting a younger child than one who picks read-independently. Reading mode and age are independent: a 6-year-old might want to read alone; a 4-year-old might want a parent along. If you can imagine a user who is high on one dimension and low on the other, they deserve separate treatment. If you can’t, they’re not separate axes.&lt;/p&gt;
&lt;p&gt;Common axes worth separating in almost any product:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Concrete attribute vs. abstract stance.&lt;/strong&gt; Age vs. skill level. Plan tier vs. feature access. Role vs. permission.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Author vs. reader.&lt;/strong&gt; Creating content vs. consuming it: different postures, different UX needs, often different screens.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Operator vs. end-user.&lt;/strong&gt; Admin / parent / manager surfaces vs. the person using the product day-to-day.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Session vs. identity vs. profile.&lt;/strong&gt; “I am here now” vs. “this is me across sessions” vs. “this is who I am managing.” Most products conflate at least two of these.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Private vs. shared.&lt;/strong&gt; Work done alone vs. work done with or for others. Different stakes, different UI.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Guided vs. free.&lt;/strong&gt; Step-by-step wizard vs. open canvas. Often toggleable within the same product.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Entry intent.&lt;/strong&gt; The same user arriving via a share link, a cold homepage visit, or a notification is three different users. Don’t force them through one funnel.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;core-principles&quot;&gt;Core principles&lt;/h2&gt;
&lt;h3 id=&quot;on-the-product-as-a-whole&quot;&gt;On the product as a whole&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Jakob’s Law.&lt;/strong&gt; Users spend most of their time on &lt;em&gt;other&lt;/em&gt; products. Novel is not better. Innovate where it creates value and conform where it doesn’t. A grid of cards is a grid of cards. Don’t reinvent it unless you have a reason.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Principle of least astonishment.&lt;/strong&gt; What happens should match what the user expected. Every surprise is a small failure, even positive ones.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;One product, one voice.&lt;/strong&gt; A feature that feels imported from a different company is a failure. Coherence beats individual screen quality.&lt;/p&gt;
&lt;h3 id=&quot;on-the-first-session&quot;&gt;On the first session&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Time-to-value.&lt;/strong&gt; The clock starts when the user lands and stops when they feel the product working for them. Every onboarding step is a tax against this clock. Spend the budget wisely.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Deferred registration.&lt;/strong&gt; Do not ask for an account before the user has felt value. Let them play anonymously first, and claim their work on sign-in.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Avoid the blank page.&lt;/strong&gt; In creative tools, the empty state is the hardest moment. Pre-fill, suggest, or seed with examples. A thoughtful zero-state is worth ten polish passes elsewhere.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Ask concrete, derive abstract.&lt;/strong&gt; Users answer “how old are you?” easily; they stumble on “what’s your reading posture?” Ask the concrete proxy, compute the abstract stance, and expose the abstract as an override.&lt;/p&gt;
&lt;h3 id=&quot;on-complexity&quot;&gt;On complexity&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Progressive disclosure.&lt;/strong&gt; Show the minimum; reveal complexity on demand. Power-user settings belong behind a toggle, not on the main surface.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Every element earns its place.&lt;/strong&gt; If a section feels empty, fix the composition: more whitespace, bigger type, bolder hierarchy.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Forgiving formats.&lt;/strong&gt; Accept more than you demand. Dates, phone numbers, IDs: strip whitespace, normalize, guess intent. The user should never be punished for a formatting mistake the computer could have fixed.&lt;/p&gt;
&lt;h3 id=&quot;on-feedback-and-state&quot;&gt;On feedback and state&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Every action has a reaction.&lt;/strong&gt; If the user does something, the product acknowledges it within ~100ms, even if the real result is async. Silence is the worst feedback.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Undo beats confirm.&lt;/strong&gt; Prefer a reversible action with an undo over a “are you sure?” modal. Modals interrupt; undo respects the user’s flow.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;State visibility.&lt;/strong&gt; The user should always be able to answer “where am I, what just happened, what can I do next?” from the screen alone. No guessing.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;reusable-patterns&quot;&gt;Reusable patterns&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Happy path, then edges.&lt;/strong&gt; Design the most common successful flow end-to-end first. Only then fan out to error states, empty states, edge cases. Designing edges first produces a product that feels defensive instead of purposeful.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Hierarchy of decisions.&lt;/strong&gt; Every screen has one primary action, zero or one secondary actions, and several tertiary ones. Make the primary action obvious (color, size, position). Demote the rest. If everything is bold, nothing is.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Forgiving first, then strict.&lt;/strong&gt; The first time a user does something, be forgiving: accept any input, offer examples, don’t punish mistakes. As they become power users, let them opt into stricter, faster, denser surfaces.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Zero state, empty state, error state, loaded state.&lt;/strong&gt; Every screen has four states. Design all four. The empty state is almost always the weakest in a real product. Invest there.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Pre-commit vs. post-commit.&lt;/strong&gt; Destructive, expensive, or irreversible actions want a pre-commit pattern: a confirmation, a preview, or a reversible delay. Everything else should be instant.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Convention over invention.&lt;/strong&gt; A hamburger menu in the top-left. A search icon that looks like a magnifying glass. A primary CTA that’s filled and on the right. These conventions are boring on purpose. Follow them for 95% of your UI; save your novelty budget for the 5% that matters.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&quot;design-process&quot;&gt;Design process&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Understand the user.&lt;/strong&gt; Who are they? What are they trying to do? What do they already know? Everything else compounds from this.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Enumerate flows.&lt;/strong&gt; List every way a user might move through the product. Draw them. Label entry points, decisions, async waits, terminals.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Orthogonalize.&lt;/strong&gt; Identify the independent axes. Pin the ones you aren’t addressing now.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Commit to a direction.&lt;/strong&gt; Decide the aesthetic, the voice, the mode. Do this &lt;em&gt;before&lt;/em&gt; pushing pixels. Half the bad designs in the world are designs made without committing.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Design the happy path.&lt;/strong&gt; End-to-end, one flow at a time.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fan out to edges.&lt;/strong&gt; Empty states, errors, re-entry, interruptions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Show variations.&lt;/strong&gt; Don’t fall in love with your first idea. Hold it next to two alternatives. Pick by comparison, not by attachment.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cut.&lt;/strong&gt; Every element that didn’t earn its place.&lt;/li&gt;
&lt;/ol&gt;
&lt;hr&gt;
&lt;h2 id=&quot;vocabulary&quot;&gt;Vocabulary&lt;/h2&gt;









































































&lt;table&gt;&lt;thead&gt;&lt;tr&gt;&lt;th&gt;Term&lt;/th&gt;&lt;th&gt;Meaning&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Affordance&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;A visual cue that signals how something can be used (a button that looks pressable).&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Information scent&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;How strongly a link or label hints at what’s behind it. Weak scent = users bail.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Fitts’s Law&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Targets that are bigger and closer are faster to hit. Primary actions deserve real estate.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Hick’s Law&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;More choices = more decision time. Limit options or group them.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Progressive disclosure&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Reveal complexity only when needed.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Empty state / zero state&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;The screen a brand-new user sees before any content exists.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Dead end&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;A screen with no obvious next action. Always a bug.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Destructive action&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Something that can’t be undone or costs real money. Deserves distinct treatment.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Primary / secondary / tertiary&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;The decision hierarchy on a given screen.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Hero flow / golden path&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;The single most important flow in the product. The one you polish first.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Entry intent&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Why the user landed here (cold visit, share link, notification, etc.). Often deserves separate design.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;State machine&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;The formal set of states a UI can be in and the transitions between them.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Scaffolding&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Temporary structure that supports the user until they don’t need it. Training wheels, inline hints, example content.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Deferred registration&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Letting users do real work before asking for an account.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Happy path&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;The successful, normal-case flow. Design this first.&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;&lt;strong&gt;Dogfooding&lt;/strong&gt;&lt;/td&gt;&lt;td&gt;Using your own product daily. The single best way to find what’s broken.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;
&lt;hr&gt;
&lt;h2 id=&quot;bridges-from-backend-to-design&quot;&gt;Bridges from backend to design&lt;/h2&gt;
&lt;p&gt;You already do most of this thinking, just in a different domain.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Information architecture&lt;/strong&gt; is schema design. Getting the data model wrong makes every API awkward; getting the IA wrong makes every screen awkward. Both are expensive to migrate.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Interaction design&lt;/strong&gt; is state machines. Every screen is a state; every button is a transition. Design the graph, not the pages.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Empty states, error states, loading states, loaded states&lt;/strong&gt; are your four required branches. Handling one and not the others is like catching success but not exceptions.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Undo&lt;/strong&gt; is transaction rollback. Prefer it over confirmation dialogs wherever the work to implement is reasonable.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Orthogonalization&lt;/strong&gt; is separation of concerns: the same move as splitting authentication from authorization. The same discipline that makes clean modules makes clean UIs.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Progressive disclosure&lt;/strong&gt; is the interface analog of good defaults. Everyone gets the reasonable thing; power users opt in.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Forgiving formats&lt;/strong&gt; is Postel’s Law. “Be conservative in what you send, liberal in what you accept” applies to user input too.&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;h2 id=&quot;common-traps&quot;&gt;Common traps&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Adding filler to fill space.&lt;/strong&gt; A screen feels empty, so you invent a “stats” section or a decorative illustration. Solve it with composition: more whitespace, bigger type, bolder hierarchy. Let the page breathe.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Designing for the power user first.&lt;/strong&gt; You know the product, so you surface the advanced options prominently. Design for the first-time user instead. Hide power features behind progressive disclosure. Reveal density only once the user has signaled they want it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Asking every question your database can store.&lt;/strong&gt; Onboarding becomes a form. Ask the fewest questions that unlock real personalization. Derive the rest. Defer the optional.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Falling in love with the first idea.&lt;/strong&gt; Always hold your favorite next to two alternatives. You don’t know if an idea is good until you’ve seen it beat something.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Treating novelty as quality.&lt;/strong&gt; Spend your novelty budget on the 5% that matters. Conform on the rest. Jakob’s Law applies here too.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Confirming everything.&lt;/strong&gt; Every action gets a “Are you sure?” dialog. Reversible actions + a brief undo window respect the user’s flow better. Reserve modals for truly destructive or expensive actions.&lt;/p&gt;</content:encoded></item></channel></rss>