Hi, I'm Kyle.
I design consumer software for 18M+ people, web to native, and prototype it in code with AI. Currently SVP Product Designer at Sovren Technologies, the parent company behind Parler, Play, Pay and Shop.
Kyle McCarthy · Dallas
The products I'm proudest of are the ones I'd hand to the people I love. I sweat the details until they feel right, because a decision I make once gets repeated every time somebody opens the app.
Sovren Technologies is the parent company behind Parler, Play, Pay and Shop, and it runs its own data and infrastructure underneath them. I set design direction across the organization and designed the surfaces people touch. One visual language runs across five platforms, carried by my direction and shared brand foundations. The bottom two layers are engineering's, not mine: I stepped in on scope when it was unclear and handled the design requests that came out of them. The markers below say who did what.
Five platforms read as one family, carried by my direction and shared brand foundations, with Pay's system the mature reference. Design-system case →
Parler ID carries a single record for each person across every surface.
Memberships, shop orders, tips and ad spend settle on Pay's one ledger.
I designed the core surface of a creator network: feed, Stories, Bursts, live Lounges, messaging and Studio.
Read the case study →A non-custodial wallet that doubles as a social network, and the checkout that powers Shop.
View case →Short-form, long-form and livestream creation, plus the path to getting paid and a storefront on every profile.
View case →A self-serve ad platform designed from a blank canvas, prototyped in code with AI, live on real spend data.
View case →Pay's working design system as it exists in Figma: Variables, component variants, and the states in between.
View case →A short essay on taste as kept decisions, drawn from the Sovren work, with one open doubt.
Read the essay →I design for the moment a product earns a place in someone's day, and the trust that keeps them coming back.
Most recently I designed four flagship consumer products, research through production: a social network, a payments wallet, a video platform and a creator marketplace, on web, iOS and Android. I run design as a player-coach: I lead the team and still ship the highest-stakes screens myself. Years inside feeds, identity and trust & safety taught me where the weight really sits.
I also prototype. With AI (Claude, Cursor, Figma AI) I turn an idea into a working prototype in days: real enough to user-test, real enough that engineering starts from running code.
How I make these calls, including one the AI couldn't fix for me: a short essay on taste.
One product in this portfolio is entirely mine. CrushSuite is a suite of Shopify apps that lets wineries sell wine online, compliantly: the state-by-state rules, age checks and shipping fees that make direct-to-consumer wine hard, handled inside Shopify's checkout. I own all of its design and product: the brand, every screen, the compliance UX that turns liquor law into settings a tasting-room manager can read, and the roadmap. I built every screen and every line of it myself with AI, from first prototype to a 5.0-rated app on the Shopify App Store with paying wineries on it today. Wine clubs (releases, subscriptions, member management) are in private beta; a conversational-AI wine assistant is next.
Visit CrushSuite ↗Hi, I'm Kyle.
I'm a product designer who ships communication and collaboration software, and prototypes it in code with AI (Claude Code, Cursor). Currently SVP Product Designer at Sovren Technologies, the parent company behind Parler, Play, Pay and Shop.
Kyle McCarthy · Dallas
ClickUp is merging design and AI-native building into a single craft: designers who prototype the flows, interactions and logic with their own hands. I've worked that way for years; this portfolio site is one of the prototypes.
A real-time communication product whose core surface I designed and prototyped in code with AI: feed, Stories, short-form video, live audio, messaging.
Read the case study →A non-custodial wallet and social-payments product, plus the checkout that powers Shop, prototyped in code.
View case →Short-form, long-form and livestream creation in a single surface, with the path to getting paid built in.
View case →A self-serve B2B ad platform designed from a blank canvas and prototyped in code with AI, on live non-deterministic data.
View case →I care about the moment a product earns a place in someone's work, and the craft in every interaction that keeps them there.
For 13 years I've designed the products people work and talk together in: four flagship consumer products across web, iOS and Android, plus enterprise SaaS deployed 200+ times. I work as a player-coach, leading the design team while keeping the hardest flows on my own desk, and I run the research and the critiques.
And I build. With Claude Code, Cursor and Figma AI I turn a rough flow into a working, high-fidelity prototype in days, then hand engineering a reference they can pull straight from.
This is what my AI-assisted way of building produces when I'm the whole team. CrushSuite is a suite of Shopify apps that lets wineries sell wine online, compliantly: the state-by-state rules, age checks and shipping fees that make direct-to-consumer wine hard, handled inside Shopify's checkout. I own all of its design and product: the brand, every screen, the compliance UX that turns liquor law into settings a tasting-room manager can read, and the roadmap. I built every screen and every line of it myself with AI, from first prototype to a 5.0-rated app on the Shopify App Store with paying wineries on it today. Wine clubs (releases, subscriptions, member management) are in private beta; a conversational-AI wine assistant is next.
Visit CrushSuite ↗I led the design org behind five consumer products, plus the design system a 100-engineer team builds from. The hardest files stayed on my desk the whole time: I draw them by hand and prototype them in code, with AI working inside a loop I set. SVP Product Design at Sovren Technologies, the parent company behind Parler, Play, Pay, Shop and a handful of sibling brands.
Kyle McCarthy · Dallas
Figma is the tool I've run a design org inside for years, and the one I reach for first because I love working in it. Pay's whole design system already lives in Figma Variables, the same primitive Figma is building its platform around. At Sovren the riskiest flows stayed on my own desk while I set the direction and standards the rest of the team built from. That player-coach seat, leading the work and still in the file after the crit ends, is where I do my best work. I want to do it at Figma: for the craft bar, the culture and community around the product, and the chance to grow around the best design talent in the field.
I set direction across the organization. Almost every screen crossed my desk before it shipped, and I designed the risky flows myself. The bottom two rows are Sovren's data and infrastructure side, sibling brands and internal systems I didn't own: I stepped in on scope when it was unclear and handled the design requests that came out of them.
There was no category playbook, so I invented the logic for each screen myself. I designed the ad platform: campaign editor, placements, and reporting across three surfaces, and prototyped the riskiest flows in working React with AI before engineering picked them up.
Read the case study →Five platforms had to read as one product family, with no shared file to enforce it. So I built Pay's design system as the reference: a small set of primitives, aliased into semantic Light and Dark modes, and composed into every component. It's rendered live on this page, in its own real values.
Addresses on the send screen, gas fees up front. It made someone learn a new alphabet before they'd trust it with a dollar. I reversed the wallet's whole logic, and the send screen now opens on a name and a photo.
We prototyped in code, so an idea got tried in an afternoon. Engineering came in while the flow was still moving, which meant the first review argued about behavior rather than intent. The states nobody had drawn showed up there: a half-finished form, a publish button that should have been greyed out, a report with nothing in it yet. Those are cheap to fix in a prototype and expensive to fix in a ticket.
Read how I work with engineers →Engineering works from a running app and the written spec, and I QA both before anything ships.
A flow goes from Figma to working code the same day. Iteration doesn't wait on a spec.
The reference lands next to the spec, so the first sprint spends its time on the flow itself.
One AI variant would nail the layout and completely miss why the screen existed. I cut it and started over.
The whole creator loop, clickable: the library, the composer, scheduling across channels, a publish that fails and retries, then what the post earned.
Open it → Written argumentThe memo behind Studio's AI direction, arguing against bolting a model on and for opening Studio to the assistant a creator already pays for.
Read it → Vision documentEight screens for a creator storefront, hung off the profile that already exists instead of a new destination.
Read it →I'd have defended both of these in a review. The ads architecture came apart in a crit, and the wallet direction I reversed once it was clear what it was asking of an audience with no crypto background at all. No screenshots survive for either one, so this is the short version.
Campaign, ad set and ad each lived on a screen of their own. In crit we pulled up the consoles ad buyers already use. Every one of them let a buyer edit across the hierarchy in one pass and save the whole session at once. The console runs as one session across the hierarchy now.
The first version of sending money opened on a wallet address field and a gas figure. We had a reason. A non-custodial wallet hands someone real control and real risk, and softening that felt like a dodge, so we put the mechanics where nobody could miss them. Most of the people it was built for had never touched a crypto key in their life. You pick a person now, and the address and the fee sit one tap behind them, which means a sender sees less of the chain before committing.
I built this team. At the peak it was twelve people: four designers, plus eight across customer success, marketing and moderation.
Multiple executives doubted one of my hires. That designer became my lead. I made five design hires in total, out of hundreds of applications and more than forty interviews, and there was no scorecard or leveling doc behind any of the calls.
The structure came later. There was no territory model and no crit calendar on day one, and I added both when the platforms multiplied past what one reviewer could hold.
Read how I ran the team →I judge my work on a phone, in one hand, walking. Not on a big monitor in a quiet room. If someone needs the screen explained, I lost.
Most of what I'm proudest of doesn't show up in a screenshot. The animation we cut 80ms from because it felt smug. The sign-up screen I kept asking AI to improve, four steps that all reviewed fine, until I deleted it instead.
And I don't demo alone. When I'm stuck between two directions I build both and put them in people's hands. With Claude Code that happens the same day now, which is usually faster than booking the meeting to argue about it.
A four-step sign-up flow that quietly created duplicate accounts.
View case →Live, uploads and a 24/7 channel, from one Create action.
View case →A few hard calls, and the one place I might be wrong.
View essay →Shopify compliance apps for wineries. I built it alone.
See CrushSuite →Everything else on this site I did with a team. This one I did alone. CrushSuite is a set of Shopify apps that let wineries sell wine online without breaking the law, which sounds narrow until you look at it: fifty states with different rules, age checks at the door, shipping fees that change by destination, and a tasting-room manager who has to configure all of it between pours. I own the design and the product, brand through roadmap, and I built it with AI from the first prototype to a paid app with wineries running on it today. Wine clubs are in private beta. A conversational wine assistant is what I'm building next.
Visit CrushSuite ↗Hi, I'm Kyle.
I've shipped the wallet people trust with their money, and run the support and moderation operation behind it. SVP Product Designer at Sovren Technologies, the parent company behind Parler, Play, Pay and Shop. Applying to be an IC on purpose.
Kyle McCarthy · Dallas
Support is the moment someone's stuck, and whatever meets them there (a bot, a policy, a person) has to get them moving again without making them feel small. I've designed that moment from the product side, and run the operation that has to make good on it from the other.
I designed the core social surface and owned what made it safe to use: the moderation policy, the AI-assisted review queue, and the reporting flows.
Read the case study →A non-custodial wallet where you send to a name and a face, and irreversible transfers stay calm and clear.
View case →Tokens, components and states defined once in Figma and read straight into code, the systems muscle AI-driven support runs on.
View case →A self-serve platform built around the person running the campaign, designed, specced and prototyped in code with AI.
View case →Every product above shipped to real people. I was also the one who answered for it afterwards, from where the policy line sat down to what came back through the queue.
The operating loop I ran at Parler, drawn as a process diagram.
Where the policy line sat was my call, and I wrote the requirements that encoded it. AI did the sorting and the summarizing; a person decided anything it escalated.
There was no support function when I got there. I wrote the SLA, then worked the queue against it myself, which is the only reason I trusted the number.
App-store mentions and in-product signal fed an automated loop that alerted the team and summarized with AI, then landed as structured insight in front of product and design. Complaints came out the other end as shipped fixes.
Building that loop was the tractable part of the job. The daily work was making sure the person on the other end of the queue never disappeared into the throughput.
I care about the moment someone's stuck, and whether what catches them is fast, honest, and still feels like a person is behind it.
For over a decade I've designed and led the teams behind consumer software: four flagship products on web, iOS and Android. I work as a player-coach, leading design while running moderation, customer support, and the listening operation that turned customer signal into shipped fixes.
And I'm AI-native. I've designed AI-assisted review workflows that keep a human on the calls that get escalated, and I prototype my own designs in code with Claude Code, Cursor and Figma AI.
This is the product where I run the operation too, support inbox included. CrushSuite is a suite of Shopify apps that lets wineries sell wine online, compliantly: the state-by-state rules, age checks and shipping fees that make direct-to-consumer wine hard, handled inside Shopify's checkout. I own all of its design and product: the brand, every screen, the compliance UX that turns liquor law into settings a tasting-room manager can read, and the roadmap. I built every screen and every line of it myself with AI, from first prototype to a 5.0-rated app on the Shopify App Store with paying wineries on it today. Wine clubs (releases, subscriptions, member management) are in private beta; a conversational-AI wine assistant is next.
Visit CrushSuite ↗Pay's design system: colour, type, spacing, radius and elevation defined once as tokens, aliased into a semantic layer with Light and Dark modes, then composed into components and the icon set. Rendered below in the system's own values: every swatch, type row and component on this page is live HTML bound to the real numbers, read out of the working file.
Open the working Figma file ↗This case exists because of arithmetic: five products, Parler, Play, Pay, Shop and Studio, plus the ad platform built on top of them, being built at once, on web, iOS and Android, by a 100+ engineer org, with one design lead setting direction.
The structure was honest about that scale: a design system per platform, on shared brand foundations. Parler, Play, Pay, Shop, Studio and the ad tools each carried its own library; the colour family, the type and the logo system were common stock. I reviewed the work before it shipped, ran the crits, wrote the specs, and drew the risky flows myself, which is how separate libraries kept reading as one product family.
Pay's system, the one rendered on this page, was the most mature of those libraries: full primitives, a semantic layer with Light and Dark modes, a component library and the icon set. It became the reference the other libraries were measured against, and the model for the unification we had underway.
The trade is real. Coherence held in one person rather than a shared file is fast until it isn't: the same decision can get remade twice, and crit is what catches the drift. That is exactly why convergence into a single system was in progress when I left, with this file's architecture as the target.
The base layer is a Primitives collection covering a small ramp for the brand mint, a longer neutral ramp, a handful of system colours, and the spacing and radius scales. These are the real names and values, read out of the working file and rendered here in the system's own numbers. The palette stays small on purpose. Mint is the only colour that appears on anything you tap to move money, so it never competes with decoration.
One type family. Inter throughout, at the sizes above. Display and heading run at 1.2 so numbers stay tight; body runs at 1.5 so it stays readable. This page renders them in Inter, so what you're reading is the scale itself.
Primitives are raw values. Nothing in the product points at them directly. Every screen consumes a second collection, Semantic, where each token is an alias with a Light and a Dark value, named for the role it plays rather than its raw colour: bg/surface, for instance, aliases to neutral/white in Light mode. That indirection is what makes the modes work. Flip the mode and the wallet re-themes, because no screen ever hard-coded a colour to begin with.
A scoped set of semantic tokens, each restricted to where it's allowed to be used: text tokens only reach text, stroke tokens only reach borders. The mint holds still across both modes on purpose. It's the one thing that should never change meaning.
The tightest decision in the palette is between two colours most people would call the same. Pay's brand is green; in a wallet, green already means a number went up. If one value did both jobs, a gain would read as a button and a button would read as good news, so the mint #59C890 is scoped to brand and action, the signal #31C859 to outcomes, and the token scoping makes the separation structural: feedback/positive can never reach a button fill, and action/primary can never colour a delta. They sit close enough to feel like one family, far enough apart that a glance at a screen tells you which kind of green you are looking at.
The icon library is built the same way as the colour: one source, many expressions. Every glyph carries a Style property (Stroke, Twotone, Duotone, Solid, Bulk) and a Type property (Rounded, Sharp, Standard), so a designer swaps a property rather than hunting for a different file. Every path is bound to system/ink, which is why these recolour with the page you are reading.
Naming is the unglamorous half: every layer is named for what it is, which keeps the library searchable even as it grows.
Tokens compose into components, so an engineer never guesses. A set of component sets, plus composed pieces like the balance card and the bottom nav, all built from the same primitives. Every fill, stroke, radius and padding in them is bound to a Semantic token, which is what makes the mode switch above possible: nothing in the library holds a colour of its own.
Change one variable and the change lands everywhere it should, because nothing on a screen was ever typed in by hand.
Every token carries a semantic name and a value, so Dev Mode hands engineering the exact variable a design used. Design and build reference one source, and a spec argument becomes a lookup.
I take the same tokens and components into a working React prototype with Claude Code and Cursor, so the system has survived contact with real code before engineering commits to the production build. This page is a smaller version of the same habit.
These are the real tokens behind Pay, rebuilt here in the system's own values. The link at the top opens the working file.
Every case study on this site was built to the same visual language, each on its own library with this file as the bar. The social platform carries the language across feed, Stories, Bursts and the moderation tooling; the wallet is where this system itself ships, and where the scoping rules earn their keep; Play stretches the language across a player, an uploader and live-broadcast tooling; and the ad platform pushes it into dense, data-heavy advertiser screens. If a case study sent you here, this is the standard it was pointing at.
The thing I'd finish first is the convergence. Each platform ran on its own library over shared foundations, and unifying them into one system, on this file's architecture, was still in progress when I left; as long as that stayed unfinished, coherence still depended on my review. The icon library carries a flaw I flagged and still haven't merged: two variant sets, Icon/Token (Alt) and Icon/Brand (Alt), collide, and that Alt naming is a trap for the next designer who searches the library. And elevation was designed for the light surface and merely survives the dark one: at 5–10% black the shadows vanish on neutral/900, so the dark theme leans on borders the system never formally named.
The core social surface for a creator-first network: the daily habit every other product in the ecosystem plugs into.
Visit the live product ↗I led design for Parler's core surface (feed, Stories, Bursts, profiles and messaging), plus Sovren's Lounges and Studio built into the same experience, all on one design system. The onboarding we launched first didn't hold up in use, so I deleted it. I also ran the trust-and-safety operation behind the product: the policy line, the support queue, and the listening loop that fed what we learned back into the design.

The home feed: the surface a creator returns to every day, and the front door to Stories, Bursts, Sovren's Lounges, Pay and Shop.
A creator network lives or dies on whether people come back tomorrow. The feed is where that habit is won or lost.
The same screen had to welcome someone's first post and give a working creator room to run a business: short-form video, live audio, stories, messaging, payments, a storefront. Pile it all on and the surface collapses into noise; hide it and creators leave. And because the platform operated under real public scrutiny, every safety decision was part of its reputation. My job was to make the whole thing read as one calm daily habit, with the safety layer designed into the same flows.
I led design across the whole social surface on web, iOS and Android. One designer owned Parler day to day, working from the direction I set, and I sat with the VPs of Engineering daily. A 100+ engineer org was building against the designs, so the deliverable that mattered most was a design system precise enough that dozens of engineers could ship the feed, the creation tools and the safety affordances consistently while I was heads-down in the next surface.
A single component grammar ran underneath the native apps, so Feed, Stories, Bursts, profiles and messaging added up to a single daily loop a person could hold in their head.
Moderation, reporting and identity were in the first sketches; retrofitting them later would have meant redesigning every flow they touch.
The first version looked like every social app's: email or phone, verify, set up your profile, pick your interest tags. Four steps, each one defensible in review. I designed it.
In use it failed three ways. The step count put a wall between a new user and the feed, the one thing that might convince them to stay. The combined sign-up/log-in screen was worse than long: returning users couldn't tell which mode they were in and created new accounts on top of their old ones, a failure mode that quietly polluted identity across the platform. And the interest tags, the step we imagined powering personalization, got tapped through to get to the app, so the data they produced wasn't worth the screen they cost.
Sign-up and log-in became separate paths from the first screen, so an existing user was never one ambiguous button away from a duplicate account.
The onboarding sequence between account and feed was removed outright.
Profile setup arrived already filled in. Proceeding was one tap; editing was optional.
Interest tags left the flow entirely. The system infers them now from what people actually watched and followed.
Duplicate-account complaints in the support queue dropped once we split the sign-up and log-in paths. The onboarding sequence came out, and install to feed got shorter. Each step had been fine on its own.
The shipped product keeps the read calm and the tools close.
The feed as home base. One legible stream carries posts, Stories, Bursts and Sovren's live Lounges; creation is always a single tap away.
Lightweight creation. Stories and Bursts cover the in-between moments; the same tools serve a casual poster and a working creator at different intensities.
Safety woven in. Reporting, controls and identity cues live inside the flows people already use: findable the moment something goes wrong, quiet the rest of the time.


Each surface launches from the feed and returns to it, so the product gained range without gaining weight.


Discovery and identity: how people find new creators, and how creators show up, with the signals that build trust legible at a glance.
Full-screen video is the easiest surface to ruin: every control you add sits on top of someone's work.
The player opens from a tap on any Burst in the feed and takes the whole screen. The HUD ships as one overlay: a legibility gradient pinned to the top and bottom edges so white type holds against any frame while the middle of the video stays untouched; the action rail set low on the right, inside one-handed thumb reach; counts in the mono face so they survive small sizes; and the top tabs persistent, so you always know which lane of the app you're in.
The frame below is the shipped overlay itself: the Figma UI export laid over a real clip, so what you're judging is the actual gradient and rail against live footage.
The overlay against moving footage: the test that matters for a HUD, since a static mock always flatters the gradient.
A creator network is only as strong as the tools that show creators what's working and pay them for it.
Studio, a Sovren product built into the Parler experience, gives creators their balance, payouts and a clear read on performance. I designed it, then prototyped it myself in code with AI, idea to working prototype in days, so engineering started from something they could click. That prototype is on this site, still clickable.
Studio's publisher: schedule once, publish everywhere. A post starts in the content library, picks the destinations it should go out to, gets a time, and lands as a scheduled item. This is prototype work rather than shipped product, and the clickable version is on this site.

Studio on web and mobile: the same earnings, payouts and analytics on any screen.
Every other product in the ecosystem plugs into this surface.
Creation entry points multiplied as surfaces shipped: post, Story, Burst and Lounge each grew its own way in, and by the end the composer deserved a unification we never gave it: one entry that branches by format. And the internal moderation tooling got less design attention than the consumer product; the people working that queue for hours at a stretch got a functional tool when the hours they spend in it justify a considered one.
Everything on this page was built to the same visual language as Pay, Play and the ad tools. The Pay system, the most mature of our per-platform libraries, is documented in the design-system case study.
A non-custodial wallet with a social layer: you send to a name or a face, chat, follow, stake and get paid, while keys, gas and chain mechanics wait until you go looking for them. Built on crypto settlement, designed to extend to fiat.
Visit the live product ↗One wallet, the whole value-moving flow: pick a recipient, set an amount in both denominations, then land on a confirmation written in plain sentences. Send, receive and stake sit one tap from the balance, and friends live on the tab bar, next to the money.
Money is the most sensitive thing a product can ask people to trust it with. One confusing moment and they never come back.
A non-custodial wallet hands people real control (their keys, settlement that can't be undone) and that control is exactly what makes it frightening. Seed phrases, gas fees, and a 42-character address where one wrong character means the money is gone. Most wallets answer the fear with more warnings and more controls, which only makes the cliff edge feel closer. My job was to design self-custody, sending and settlement for people who had never touched a blockchain, without lying to them about what was happening underneath.
I set design direction across the Sovren ecosystem. One designer owned execution on Parler and Pay under my direction, and I kept the wallet's highest-stakes flows on my own desk: send, receive, confirmation, security and account management. A 100+ engineer org was building screens where a mislabeled button could cost someone real money, so state and edge cases were specced in Pay's design system, the most mature library in the ecosystem.
People held their own keys, and the design put dollars and tokens behind one calm way to hold and move value, without burying anyone in cryptographic detail.
A mistaken transfer can't be clawed back, so confirmation and clarity were designed into value-moving flows from the first sketch.
The first version of the send screen wanted a wallet address and a gas number before it wanted a name.
Send flows asked for wallet addresses, fees showed up as gas, and chain state sat right on the surface. The argument for it was honesty: self-custody is a serious promise, and showing that detail felt like respecting the people who understood it. To a crypto-native eye, those signals read as competence.
This wallet was being built for a social audience, most of whom had never held a crypto key. One wrong character in an address field, and there was no getting the money back. Nobody around them could answer what a gas figure actually meant.
So I changed the direction. You send to a person: a name, a face, a handle, with the dollar value carried alongside the token amount. Security setup, fees and network detail moved behind progressive disclosure, surfaced only when they matter, and the wallet now reads like a familiar finance app.
We kept the blockchain visible. The web app still offers address-level sends and full transaction history for anyone who wants it, and whoever wants the raw detail gets it with one more tap.
Left is the direction I killed. Right is what shipped. On the old send screen the recipient is a hex address and the balance reads as a raw token figure. On the new one the recipient is a face and a handle, and the amount carries a switch so you can read it in tokens or in dollars. The home screen made the same move: a dark crypto surface became a balance and the actions people actually came for. Both are the real product; the names and figures are demo data.
The send screen starts from a name and a face.
Every element on the send screen was a decision, because this is the screen where the money actually moves. Identity comes first (avatar, name, handle) because "am I sending to the right person?" is the question people actually panic over. The amount sits in display type with its dollar value directly beneath and a one-tap flip between denominations. A balance chip with Max means nobody does wallet math by hand. The keypad is the phone's own pattern, because nothing on this screen should require learning.
And when the money moves, the confirmation says so in plain words: what happened, what happens next, one primary action. The full transaction detail stays one tap away for anyone who wants proof.


The pattern every value-moving flow ends on: who, how much in both denominations, then a confirmation written in plain sentences.
Pay also shipped as a full web application, and the desktop is where the reversed decision shows its other half. On a phone, the wallet protects your attention: one flow, one question per screen. On the desktop it becomes a workspace (asset dashboard, prices, a persistent send-and-request rail), and the desktop surfaces the detail the phone keeps out of the way: address-level sends, complete transaction history, even hosted node management. The person at this screen asked for the detail, so the design gives it to them.
Both postures are built from the same token and component system. A numeric keypad and a data-dense console, one design language.
The web home: balances and prices at a glance, with sending and requesting docked on the right so moving money never leaves the page.
Asset detail on the web, where the raw detail surfaces on purpose: a price range you can scrub, available and locked balances split apart, hashed transaction history, and a send panel that takes a wallet address and a memo for the people who came for exactly that.
The deepest surface in the product: node licenses, per-chain health and the hosting plans that bill for them, all inside the wallet. Nodes offline is stated in the same breath as the count, an unstarted chain shows what starting one costs, and every plan carries its renewal date and card. Designing this next to the phone's send screen is the range the design system had to hold.
Moving value feels ordinary now, and it happens among people you already know.
Send starts from a person, safely. Balance and assets read at a glance, and sending begins with a name or a face on one legible flow, with the cryptography kept out of the way until the moment it earns its place on screen. Account security, confirmation and clear identity cues live inside that same flow, and it was drawn so fiat could sit beside crypto in the same wallet, even though crypto settlement shipped first.
A social layer around the money. Chat, a follower network, profiles and an activity feed mean the wallet is somewhere you already spend time, and a payment often starts as a message.


Staking is a two-screen decision: choose to stake or lock, then slide to compare durations. The duration slider snaps to 6, 12, 18 or 24 months, and a one-line note in plain language explains the deal: the longer you lock, the more you earn.

A payment request lands inside a chat thread, so money keeps the context of the conversation it came from. The social grammar here is the same one that runs the main social platform.
Pay is also the checkout behind Shop: when someone buys from a creator's storefront, the payment settles through the same wallet they already trust for everything else.
The send screen still leads with tokens: 15,213.22 OPT in display type, $521.90 in small grey beneath it. For the audience we reversed the whole product toward, I'd flip that default: dollars large, tokens one tap down. Staking kept more crypto vocabulary than it should have; "lock durations" is our language, and I'd redesign that flow around the person's actual questions: what do I earn, when can I get it back. And fiat beside crypto stayed a design model, because settlement shipped crypto-only. The architecture was drawn for it; real use never got to test it, and I'd want that validated before repeating the claim.
Short-form, full-length uploads, livestreams and a 24/7 linear player in a single product, with the route from publishing to getting paid designed into the same screens. Live in seconds; every replay on demand.
Visit the live product ↗Bursts to live, on the surface people actually use. A tap opens the Bursts reel, a swipe moves through it, then a creator goes live and the alert lands on top of what you were already watching. Short clips and live streams sit in the same product, so moving between them is one motion instead of a trip to another app.
A livestream on the web: the video, live chat, a tip action beside the title, and the creator's merch shelf directly under the player. Everything a viewer might do for a creator is on this one screen.
The act of making video had been split into pieces, and creators paid the tax every day.
Short-form lived in one app, long-form in another, livestreaming in a third, and the money in a dashboard off to the side. A creator who wanted to post a clip, drop a full video and go live had to manage separate worlds, each with its own rules, exports and analytics. Each handoff lost momentum, quality, or the thread of how anything made money, and it capped how much a creator could produce and earn. The brief I set myself was one path from camera to payout.
The player, the uploader and the live tooling are wildly different surfaces, and a 100+ engineer org was building all three at once. I leaned on Play's own library, held to the same visual language as the rest of the ecosystem, to keep them recognizably one product while the teams moved in parallel.
Short-form, long-form and live each have their own rhythm, so the job was a single creation flow flexible enough to hold all three. People also flip between watching and making all day on this product, and the move between the two had to feel like one continuous motion.
Earning had to be visible inside the creation flow itself: tips in the player, a payout line the creator can see fill up.
Play was shaped by a constraint present from the first sketch, and it decided everything downstream.
Live and on-demand video are different systems. We built both: a real-time pipeline that takes RTMP in from OBS, hardware encoders or a phone and delivers it live in seconds (sub-second with LL-HLS) over our own edge network, and an upload pipeline that stores, transcodes to a 4K ladder and serves a library. Two pipelines, with different failure modes, different latencies, different states. The industry's answer to that split is to ship it (a streaming product over here, a video site over there) and let creators carry their audience across the gap by hand.
The constraint I set for the design was that the architecture never gets to appear on screen. That one rule made most of the hard decisions for me. Both pipelines had to end in one player, so watching a replay feels identical to watching it live. Going live and uploading had to start from the same Create action, so the format is the last choice a creator makes, and the lightest. And because every live session is archived with DVR, a broadcast becomes a library video where it stands: no export, no re-upload.
The cost of the rule was real. Most controls in the player, buffering, seeking, error states, had to be designed twice underneath: once against live latency, once against a static file. They were specced precisely enough in the design system that engineers on two separate pipelines shipped what reads as one surface.
Go live from a studio rig, an encoder or a phone; the viewer never sees which.

The broadcaster's view from a phone: counts and controls at the top, chat arriving over the picture. The same session is simultaneously the web player's livestream, and its own replay the moment it ends.
A tip is a payment, but it's also a public act: the room sees it land in chat. The sheet is designed around that second fact.
The top of the sheet is a live preview of the chat message the tip will become: your avatar, the "Tipped $1" badge, the message you're attaching. You see exactly what the room will see before any money moves. The amount is a dollar figure with a slider underneath, so generosity is adjustable in one thumb-drag; typing an exact number uses the phone's own keypad, nothing to learn. And the sheet holds two payment routes (a primary on the button, an in-app payment on the quiet line below it) so the impulse to support someone never dies on a payment method.
Tips are priced in dollars, even though creators also earn in tokens elsewhere on the product. The person tipping mid-stream is thinking about the creator, and the sheet is built to keep it that way.

The sheet in full: the preview of how the tip renders in chat sits above the amount, and the amount sits above the payment routes. A tipper works out how the tip will look in the room before settling on what to spend, so the preview comes first.
A workflow that used to span three apps now fits inside one product.
Unified creation. Clips, full uploads and live sessions share one creation flow; the format is a choice inside it, and switching between formats needs no exports.
Watching that feeds making. The player, channels and discovery are designed so a viewer is always one step from the Create action: the same person, changing hats on the same screen.
Money in the same room. Tips land in the player, storefronts sit on the profile, and the earnings ledger lives in the product's own navigation, with the self-serve ad platform as a monetization rail beside it.
A channel on the web: a live broadcast up top, and the same page carrying the creator's videos, Bursts, live tab and playlists. Bursts here are the short-form format from the social platform, with their own tab on every channel.
An honest ledger. The earnings page shows all-time fiat and token earnings, then itemizes every row: the video, the supporter, gross, each fee, net. I put the fee math on every line; a creator deciding whether this platform deserves their work should never have to reverse-engineer their own pay.
Cash out through Pay, with a store on every profile. Payouts settle through the ecosystem's wallet, so the money a video earns arrives next to the money from everything else. A creator's Shop storefront rides on the same profile: the merch shelf under the livestream and the Store tab on the channel are the same inventory.
The earnings ledger: fiat and token totals up top, and per-video rows that itemize gross, both fees and net: the full math of a creator's pay, printed where they can check it.

The Store tab on a creator's profile: the audience a video earns can buy from the creator without leaving the page, and the sale settles through the same wallet as the tips.
The tip sheet gets the social half right and then hands you off. "Continue to payment" is a second step at the exact moment someone is feeling generous, and I'd fold the wallet's one-tap confirm directly into the sheet so tipping is a single motion. The whole watch experience is also designed for the stream that's already busy. A new creator's first broadcast, with one viewer and an empty chat rail, gets the same layout as a stream with a full chat rail, and none of the help it actually needs: a prompt, a sense that someone is there, something for that one viewer to do.
Every screen on this page holds the same visual language as the social platform and the wallet. The system discipline behind that coherence has its own case study.
Sovren needed a revenue layer, and no product like it existed in-house: a self-serve ads platform running five placements from one campaign flow (feed, banner, video pre-roll, profile, wallet) on a first-party auction that runs in real time. I designed it from a blank page and handed engineering a working prototype in code.
The advertiser home: campaigns with delivery toggles, budgets and live performance in one table. Every figure in the row is being re-derived by the auction while you look at it.
An ecosystem of creator products survives only if something underneath it makes money. That something was ads, and it didn't exist yet.
There was no reference product inside the company to build from. One ad server had to fill the same five placements, priced by an auction our own stack runs in real time. The buyer is an advertiser with no agency behind them, who has to create, target, fund and read a campaign without ever talking to a human. Because the pitch was a platform advertisers could trust with budgets, honesty was a hard requirement I put in the spec: estimates labeled as estimates, spend always legible, no defaults that quietly spend more.
The safe way to scope an ads product is one tool per format, shipped one at a time.
That was the fork at the start. Feed ads carry social mechanics, pre-roll carries video mechanics, the wallet placement has rules of its own. A console per format would have let each ship on its own schedule with its own simple flow, and it's how plenty of ad stacks grow, one bolted-on manager at a time. The cost lands on the advertiser: five placements become five tools to learn and five places to check spend.
I structured it the other way. A campaign is one object (objective, audience, budget, creative) and the placement is a property you set inside the flow. We paid for that call in design and engineering time: the wallet placement, the one with rules unlike any other format, is what came closest to breaking the shared flow, and the component library had to be strong enough to hold it anyway. See how that discipline held up in the design-system case study. What the advertiser gets back is a console learned once, where a new placement arrives as a new option in a flow they already know.
A sponsored post runs in the same feed as everything else; the video unit runs full-bleed with the platform's own overlay grammar; the wallet placement sits inside Pay. So each unit borrows its host surface's layout and type, and wears its disclosure in the unit's own metadata row: Sponsored, set in the same type as the handle, with one clear action per unit. Advertisers are real accounts here too, with profiles and storefronts, which keeps an ad one tap away from a page a person can actually inspect.
Placements · feed, vertical video & the advertiser's own page
The units in situ, from the platform's own marketing set: a sponsored feed post, a sponsored vertical video, and the advertiser's storefront profile beside them. The advertiser and creative are demo content; the UI is the shipped product.
The first architecture gave the campaign, the ad set and the ad a screen each.
It looked clean in a flow diagram. Editing a campaign put you on one screen, editing an ad set on another, editing an ad on a third, so changing two things in one sitting meant either starting the flow over or saving progress and coming back. I built it and I would have shipped it. What killed it was a crit that put competitor platforms on the table next to mine: advertisers move up and down the whole hierarchy in one session, and every product they already use lets them. I only caught it because the prototype was clickable and I had put it in front of someone who buys ads for a living.
What replaced it is one session across the whole hierarchy. The campaign tree on the left of the editor is what that decision looks like on screen.

A frame from the clickable prototype I built and would have shipped, which is why the body copy is still placeholder. Every level of the hierarchy got its own page and its own place in the sequence. Changing a budget and a creative in one sitting meant leaving this screen and starting the walk again. The step counter in the header is the whole problem in one component, and it is what the ad buyer in that crit put a finger on.
I was directing design across the whole ecosystem through this build, and this was the surface I kept making with my own hands: I wrote the spec, designed the console, then built the prototype in React with Claude Code and Cursor doing the heavy lifting and Figma AI plus media-gen models feeding the creative work. It had real components and real state: flows you could click through and break. Questions that die on a static mock (what a half-built ad set looks like, what blocks publishing, what an empty report says) got answered in the prototype before they became tickets.
The campaign object came first: objective, audience, budget, creative, with placement as a property. Every screen in the console hangs off that structure.
Functional code, with validation, empty states and error paths built in, so the system's behavior was decided where it could actually be tested.
Engineering got the prototype plus exact written specs, and I QA'd what shipped against both before it went out.
Every number in the console says what it is: an estimate, a live read, or a settled result.
Almost nothing this console displays is authored by a designer. The auction sets what each impression costs, so spend, eCPM and CTR are re-derived while you watch. Reach is a moving estimate that shifts with every targeting edit. The creative is whatever an advertiser (or, increasingly, a generative model) hands the system.
So the components are rules for content I'd never see in advance. Numbers carry their state (loading, estimated, settled) so a projection can't be mistaken for a result. Reporting modules keep their shape when data arrives thin or late. Creative slots take any aspect ratio and length, and the preview renders the actual unit per placement, so what an advertiser approves is what runs. This layer of the design is invisible in a screenshot, and it's exactly the layer I prototyped in code to get right.
The creative step treats unknown assets as the input: video, image and carousel sit in one library, each tile carrying its format and how many ads already use it, and the preview behind renders the real unit the moment one is chosen. Choosing creative never leaves the ad you are editing.
The campaign editor is where the system's opinions concentrate, so it's the screen worth zooming into. The tree on the left holds the whole campaign (ad sets, ads, drafts) with problems flagged at every level they roll up to, so a broken ad marks its parent from three levels away. Publishing is gated by a validation banner that names the exact ad and the exact missing field, and jumps you straight to it. Targeting leans on saved, reusable audiences, each carrying its reach as a labeled estimate, and exclusions are first-class: keeping existing subscribers out of an acquisition campaign is one selection. On the right, the ad previews re-render as you edit. And every edit saves as it's made, with the footer saying so in plain text, because losing a half-built campaign is how you lose the advertiser.
One screen showing everything at once: the campaign tree with roll-up flags, the one-issue banner pointing at the exact field, audiences with labeled reach estimates, an exclusion in force, live previews, and the autosave note in the footer.
This is the case I can take apart live: the architecture and the AI workflow.
What I'd change, biggest first.
eCPM, CPC and CTR lead the columns. That serves a media buyer and quietly excludes the self-serve advertiser the platform was built for. I'd make the plain-language read the default (what it cost, what it reached, what it returned) and put the acronyms one level down.
The asset step's empty state leans on an emoji where a skeleton of the actual placement would teach the spec while you wait. Smaller than the first one, but it bugs me.
Generation is now part of how creative gets made. I'd design briefing and variant review into the flow itself, and hold model output to the same labeled-honesty rules as every number in the console.
Taste, as it actually shows up in shipped work: decisions from my time at Sovren, the process I run with engineers before any of them reach a design file, and the place my own thinking is most likely to be wrong.
I once asked an AI to fix a screen that was failing, and it sent back variant after variant of the same screen. Not one of them asked whether the screen should exist. What that is an example of is the thing this essay is about: the calls that get made when nobody is checking.
Every screen is hundreds of decisions like that, and each one gets made somewhere: by you, by a default, by whoever wrote the component you reached for. I try to make more of them on purpose. Three calls from my work at Sovren follow, then the process I actually run with engineers so decisions like these survive contact with a build.
Pay's first direction was crypto-first: wallet addresses on the surface, gas fees visible, the chain's mechanics treated as the product's honest truth. It made sense in the room. This is a non-custodial wallet, and hiding how it worked felt dishonest. But that direction asked the person with real money on the line to learn our vocabulary before trusting us with a dollar, and a wall of hex characters is a reason to close an app. So I reversed it. You send to a person, with a name and a face, and the address and gas fee move off the send screen without disappearing. The wallet now reads like the finance apps people already trust. The mechanics are still there, just not on the first screen.
Before a screen existed, I sat down with the engineers building the console and we drafted the PRD together: what the auction data actually was, what a query could return, and what happened to a number between an ad running and a report settling. We built a prototype off that and reviewed it as a group, working through rate limits, caching, migration off the old reporting tool and what an empty report should say, and I asked them where I was overdesigning it. Only once that prototype held up did the design file open.
That order is the decision. Because the data layer was settled before a figure hit a screen, every number could carry its state, loading, estimated or settled, each with its own visual weight, so a projection can't pass itself off as a result. Nobody sees that layer in a screenshot.
Pay's design system carries two greens that are forbidden to mix: brand mint on anything you can act on, and a separate signal green for a value that went up. One green would have been tidier, and I wanted tidier. But a single green teaches a reflex: this color means good, tap it. In a wallet, blurring "you may act" into "you gained" is a small confusion with compounding interest. Almost nobody will ever notice the two greens, and the wallet feels trustworthy partly because of them. Both facts sit fine with me.
Decision two is not a one-off. The PRD gets drafted with the engineers, we build a prototype and review it as a group, and the questions that decide the design get answered there: what the API returns, what a screen shows when a write fails, what an empty state says, what breaks in a migration. I ask them where I'm overdesigning, which is a strange question to hear from a designer, and I ask what a flow feels like on top of whether it works. Only then do I open the design file. The Studio prototype is what one of those reviews ran against, and the AI memo is the argument that decided what went into it.
With Claude Code I take a flow from Figma to a working prototype the same day, which changed how fast I move and changed nothing about who decides. The onboarding screen from the top of this essay is the case in point: I kept asking for a better version of it, and I kept getting one. Deleting it was mine to do.
Most of the work above was made by a team I hired and built, and I stayed in the file the whole time I was running it. How that team worked, who owned what, and the ending I handled wrong for months are in the team essay.
My bias runs toward calm: hide what's technical, and make the product boring exactly where people are scared. That instinct has served the products I've shipped, which mostly held people's money or their public identity. But some of the best-loved software doesn't hide what's under the hood. It leads with it, and a designer who always reaches for calm risks sanding off the edge that would make someone love the thing. I watch for it in critique now: when I hear myself say "simplify," I try to ask whether I'm protecting the user or just my own comfort.
I hired and built the design team at Sovren. This is how the hiring actually went, how critique worked in three layers, what I handed over to the designers, and the ending I spent months getting wrong.
Twelve people reported to me at Sovren. Four were designers; the other eight ran customer success, marketing and moderation. I held the same scope from my first month there to my last, and the hires, the crits and the endings came to me. What follows is how the hiring went, how critique worked, what I handed over, and the call I got wrong for months.
I hired five designers out of hundreds of applications and more than forty interviews. No scorecard, no rubric, no leveling doc. What I was screening for showed up in the direction I set in the room, the crits I ran, and the QA sign-off I did before anything shipped.
Multiple executives in the org doubted one of those hires, a young UX designer who later became my lead. I walked the room through the deliverables and what the person could actually do, and it was clear enough that we'd found a hidden gem.
They could take very little direction and still land on exactly what was needed about eighty percent of the time, and they moved fast doing it. Communication was rough early on and got better under coaching. On the other twenty percent, they took the feedback and the criticism without defending the work.
Critique had a rhythm. Daily standups covered progress. A weekly crit was where most work got reviewed, and for anything carrying real risk I called a one-off crit on that project alone and pulled in whoever it touched: engineers, product, marketing, sometimes an executive.
That layer reversed the ad dashboard. I had a prototype on the screen you could actually click, and an advertiser in the room reacting to it, and neither one alone would have caught the problem. We hadn't seen it ourselves, and I don't think a spec review ever would have. The architecture and what replaced it are in the ad platform case study.
Parler and Pay went to one designer, all the website and email design to another, and ads, data, Studio and Shop to a third. Each of them took requests straight from engineering and from stakeholders without routing anything through me. Direction still came from me, and that limit was real: they ran execution, and the calls on scope and requirements stayed mine.
Fantastic designer, great vision. They missed deadlines, some work ran far longer than anyone expected, and when a date was slipping I heard nothing about it until it already had. They were remote, and without that communication remote didn't work.
Left to themselves they'd bend the requirements and build what they thought the thing should be. About half the time that worked, and what came back was better than what we'd asked for. The other half we missed a real deadline over it.
We tried to fix it directly, with multiple working sessions, then specific recommendations, then a formal improvement plan. They put real effort into all of it. It still ended with me letting them go.
Here's the part I got wrong. Everything I put in place went after lateness and coordination, because that's what I could see: missed dates, and silence right before one slipped. I ran that theory for months. The gap was somewhere else, and it was that they couldn't hold the user's position against their own; when the two conflicted, their own instinct won.
No design file opens on my team until the engineers who are going to build the thing have been through the requirements with me and we've all had a running prototype in front of us. The full sequence is in the craft essay, including the two questions I ask that engineers don't expect to hear from a designer. The Studio prototype is one we reviewed that way.
Five product managers built against the direction I set. All five reported to the Chief Product Officer, so I had no line to them on the org chart, only the direction. I decided scope and requirements, the engineering grey areas came to me, and QA didn't clear a release until I signed off.
I hired this team and created it. The crit layers and the territory model arrived once the platforms multiplied, and the first three things I changed as it scaled were how we communicated, how priorities got tracked, and how the team engaged with engineering.
Thirteen steps through the creator workflow: opening the content library, composing one post, fitting it to each channel, scheduling it, watching a publish fail and retrying it, then reading what it earned. Everything inside the browser frame is live.
Use the arrow keys to step through the scripted walkthrough, or ignore it and click around. Tabs, rows, drawers, editors, the composer and boost are all real.
The strategy memo behind Studio's AI direction. Every scheduler was bolting the same model onto the same generic prompt, which is why they all read the same. This argues for the opposite: open Studio to the assistant a creator already pays for, and own the data that makes it useful.
The two I would defend hardest are the guardrails and the list of things we chose not to build.
Eight screens showing how a creator opens, stocks, arranges and earns from a storefront, hung off the profile that already exists rather than sitting somewhere new. Version 0.2, revised after review.
The buyer view is included because the creator needs to preview their own storefront the way a buyer sees it. That screen was missing from v0.1 and the review caught it.
The pixels, and what happened after send.
Every safety affordance in these screens had an operation behind it, and I ran that too: the policy calls, the queue, and the signal that came back.
The operating loop as it ran, drawn from the process itself: signal in, AI triage, the policy line, a human decision, action, and the insight routed back into the roadmap.
Moderation
I owned the policy line (what the platform allowed and what it didn't), wrote the moderation requirements, and ran an AI-assisted review process with human review on the calls the system escalated.
Customer support
I stood up the support function from nothing: created the SLA and worked the queue against it, so a promise to get back to someone was a promise the operation kept.
CX listening ops
I built the listening loop: automations that caught app mentions and customer signal, summarized them with AI, and delivered structured insight to product and design, closing the line from complaint to shipped fix.
Running the queue changed how I designed the product: the reporting flows in the screens above are shaped by knowing what it's like to process the other end of them.