Something rare is loading.

0% · summoning #001

Back to the collection

#005 · Systems Architect · Rare · AKASHA tenure, 2021 to 2026

AKASHA UI System

The open-source design system behind the AKASHA World apps, built on shadcn/ui.

Lead Product Designer · AKASHA FoundationToken architecture, component APIs, accessibility specs and documentation, designed with the engineers who built the React library.

Evidence33 code components documented in public, each installable with the shadcn CLI

AKASHA UI System, shown live: the library's real color, radius, spacing and type tokens beside an AKASHA World Extensions Hub screen, a page of the documentation site and component samples (buttons, badges, tabs, switch, avatars, select, alert dialog, toast), all drawn from the open-source source code in its light and dark themes.

The challenge

Eight independently installed apps had to read as one product. Without a shared layer, each would rebuild the same buttons, identity rows and states.

What I led

Token architecture, accessibility specs per component and documentation, component API design with engineering, and a Figma library aligned with implementation.

What shipped

AKASHA UI: 13 customized shadcn components, 20 AKASHA components and 3 blocks, in light and dark, with a public documentation site.

01 · Why one system

Eight apps had to read as one product.

Independent apps are AKASHA World's strength. Keeping them consistent was the design challenge.

AKASHA World is assembled from composable apps that install independently: Antenna for the feed, Extensions for the app marketplace, Vibes for moderation, and more. Each one ships as its own micro-frontend. Without a shared layer, every app would answer the same interface questions on its own.

  • The same parts, rebuilt

    Every app needs buttons, avatars, inputs and error states. Built separately, each one comes back with slightly different spacing, color and behavior.

  • One person, shown three ways

    A profile with a decentralized ID appears in the feed, the marketplace and the moderation queue. Formatted per app, the same person reads differently from screen to screen.

  • The same questions in every review

    Which button, which radius, which focus style. Without shared decisions, design and code reviews reopen them for every new screen.

  • Two themes, one set of decisions

    Light and dark mode stay consistent only when both themes come from the same tokens.

Antenna, AKASHA World. The feed: post headers and the main call to action.
Antenna The feed: post headers and the main call to action.
Extensions, AKASHA World. The marketplace: the author of each extension and the install action.
Extensions The marketplace: the author of each extension and the install action.
Vibes, AKASHA World. The moderation queue: the reported author and the decision buttons.
Vibes The moderation queue: the reported author and the decision buttons.

A: the same identity row. B: the same button component. Three apps, one set of decisions.

02 · Why shadcn/ui

Build on shadcn/ui. Don't invent a framework.

The system had to be the easiest path for every app to adopt.

AKASHA UI is a set of components and blocks built on shadcn/ui and Tailwind CSS, distributed the way shadcn is: you add a component to your app with one command, and from then on the code is yours.

  1. 01Engineers already knew the base

    shadcn/ui is developer-native and unopinionated. Building on something engineers already used made shared patterns easier for teams to adopt.

  2. 02Accessible primitives, not rebuilt ones

    Accordion, Checkbox, Select, Slider, Tabs and Avatar sit on Radix primitives, which bring keyboard interaction, focus management and ARIA roles to every app that uses them.

  3. 03Tokens as CSS variables

    Theming is a set of CSS variables. AKASHA keeps the shadcn names and adds its own on top (a gradient pair, success and warning) instead of renaming everything.

  4. 04Distribution through a tool teams know

    Every documented component installs from the AKASHA registry with the shadcn CLI, so adopting one is a command plus the theme tokens, not a migration.

Trade-offThe trade-off I designed around

Copied code doesn't update itself. A change to Button is pulled into each app on purpose, so the registry and the documentation act as the shared contract.

03 · My role

Design lead for the system, working directly with its engineers.

I led the design of AKASHA UI and worked directly with the engineers who implemented it in React, so the design decisions and the code stayed in step.

What I designed

  • Token architecture: semantic color in light and dark, plus radius, type, spacing and icon scales
  • Accessibility specs per component: focus states, contrast, keyboard navigation and screen reader semantics
  • Documentation: usage guidelines, live examples and edge-case specs
  • The Figma library: components and variants, with their states, in light and dark

How I worked with engineering

  • Component API design, shared with engineering: clear props, sensible defaults and controlled flexibility
  • Weekly cross-team design reviews
  • A Figma library aligned with implementation
  • A status for each shadcn component in the library, so design and engineering shared one view of what was customized
04 · Foundations

Foundations first, as tokens.

Components reference names, never values.

Colors are semantic CSS variables with a light and a dark value. Radius, type and icon sizes are fixed scales. Because components only read token names, one change to a token reaches every component that uses it, in both themes.

  • --primary

    Links, outline button labels, active states

    Light
    #7c3aed
    Dark
    #ac7efa
    In Figma
    Violet 600
  • --primary-start / endAdded

    The gradient on default buttons

    Light
    #f571b5 / #6466f1
    Dark
    #f571b5 / #6466f1
    In Figma
    Pink 400, Gradient
  • --secondary

    Secondary buttons and badges, type icons

    Light
    #ddd6fe
    Dark
    #5b21b6
    In Figma
    Violet 200
  • --secondary-foreground

    Decentralized IDs, secondary labels

    Light
    #6d28d9
    Dark
    #fafafa
    In Figma
    Violet 700
  • --accent

    Hover fills, highlighted options

    Light
    #ede9fe
    Dark
    #ddd6fe
    In Figma
    Violet 100
  • --ring

    Focus rings on every interactive part

    Light
    #8b5cf6
    Dark
    #c4b5fd
    In Figma
    Violet 500
  • --successAdded

    Confirmations

    Light
    #10b981
    Dark
    #a7f3d0
    In Figma
    Emerald 200 (dark)
  • --warningAdded

    Warnings

    Light
    #facc15
    Dark
    #fef9c3
    In Figma
    Code token
  • --destructive

    Destructive actions, NSFW flags

    Light
    #dc2626
    Dark
    #ffb0b0
    In Figma
    Rose 300 (dark)
  • --muted-foreground

    Descriptions and secondary text

    Light
    #7d7d7d
    Dark
    #b0b0b0
    In Figma
    Code token

Added Added on top of the shadcn set. Everything else keeps its shadcn/ui name.

Color palette and type samples. Each swatch maps to a token in the table above.
Figma library Color palette and type samples. Each swatch maps to a token in the table above.
  • Radius--radius 8px at the root
    sm4md6lg8xl12

    Scoped by context: buttons, duplex buttons and badges set --radius to 1.5rem, so they render as pills; cards set 1.25rem, and parts inside a card drop back to 0.5rem.

  • TypeTypography component
    Agh1 · 48Agh3 · 30Agh5 · 20Agp · 16Agsm · 14Agxs · 12
  • IconsFigma sizing page
    XS12S16M20L24XL32
  • SpacingTailwind 4px scale
    8px12px24px

    8, 12 and 24 are the steps documented in the Figma library.

Antenna, dark, AKASHA World
Antenna, dark
Antenna, light, AKASHA World
Antenna, light
AKASHA World The same feed in both themes. Nothing in the components changes; only the token values do.
05 · Architecture

Three layers, composed upward.

The code documentation lists 33 components in two groups, separate from the components and variants in the Figma library. Blocks then compose the code components into whole product patterns. Each layer builds on the ones below it.

  1. 3

    Blocks

    Assembled patterns for the social core, built from the components below.

    • Post feed
    • Post page
    • Reply page
  2. 20

    AKASHA components

    What shadcn doesn't have: decentralized identity, the extension ecosystem, social actions and empty or error states.

    • Autocomplete
    • Circular Progress
    • Content Card
    • Copy to clipboard
    • Duplex Button
    • Error Loader
    • Extension Avatar
    • Extension Card
    • Extension Type Icon
    • Feed CTA
    • Icon Container
    • Image
    • Infinite Scroll
    • Profile Avatar
    • Profile Avatar Button
    • Stack
    • Stacked Avatar
    • Stepper
    • Tags Input
    • Typography
  3. 13

    Customized shadcn components

    shadcn primitives restyled for AKASHA, such as the gradient Button and the restyled Badge, Select and Tabs.

    • Accordion
    • Badge
    • Button
    • Card
    • Checkbox
    • Form
    • Inline Notification
    • Input
    • Select
    • Slider
    • Sonner
    • Tabs
    • Textarea
  4. Foundationshadcn/uiRadix primitivesTailwind CSSTokens as CSS variables

Composition in practice: Extension Card

Extension Card adds almost nothing new. It arranges existing parts on a three-column grid, so a change to any of them shows up here automatically.

Extension card in the Figma library.
Figma library Extension card in the Figma library.
Extensions, AKASHA World. Extension cards in the Extensions Hub, including the NSFW avatar state.
Extensions Extension cards in the Extensions Hub, including the NSFW avatar state.
  1. Extension Avatar60px image, or the type's default art, or the NSFW state
  2. Typographythe name, small and bold
  3. Extension Type Iconan app, widget or plugin icon on the secondary token
  4. Profile Avatar Buttonthe author slot, filled with the small size
  5. Badgethe Add and Added action, as a pill
<ExtensionCard>
  <ExtensionCardAvatar />
  <ExtensionCardContent>
    <ExtensionCardName>Antenna</ExtensionCardName>
    <ProfileAvatarButton size="sm" />
    <ExtensionCardDescription />
  </ExtensionCardContent>
  <ExtensionCardAction active />
</ExtensionCard>
Compound API, abbreviated from the documentation. Parts share state through context, so apps rearrange them without forking the component.
06 · States

States belong to the component, not the screen.

Every component carries its own variants and states, so no app has to invent a hover, a loading spinner, an empty avatar or a flagged state.

Button
Six variants, three sizes, plus hover, focus, disabled and loading states.
Duplex Button
Follow, then Following. On hover it previews Unfollow in the destructive style before you commit.
Extension Card action
Add as an outline pill; once installed, a check and the word Added.
NSFW content
Avatars swap the image for an eye-off icon on a muted fill; Profile Avatar Button adds a text label at medium and large sizes.
Avatar fallback
No image? The avatar picks one of seven illustrations from the person's DID, so the same person always gets the same illustration.
DID field
Ethereum and Solana IDs get their network icon and any other DID gets the did:key icon. A value that isn't a DID reads Invalid DID.
Extensions, AKASHA World. Install drawer: outline Cancel, gradient Install.
Extensions Install drawer: outline Cancel, gradient Install.
Extensions, AKASHA World. After install: the card shows Installed; the drawer offers Close and Open.
Extensions After install: the card shows Installed; the drawer offers Close and Open.
Vibes, AKASHA World. A moderation decision: a textarea, inline links, and Cancel and Delist.
Vibes A moderation decision: a textarea, inline links, and Cancel and Delist.

Responsive behavior, and where it lives

Inputs
16px text on small screens, 14px from the md breakpoint, so phones don't zoom into a field on focus.
Long text that stays put
Extension descriptions clamp to one line and DIDs truncate in the middle, so cards and rows keep their height in narrow columns.
Size by context
Profile Avatar Button has small, medium, large and vertical layouts; each app picks the one that fits the space.
Layout stays in the apps
Page breakpoints belong to each app. The library's job is components that hold up at any width they are given.
07 · Accessibility

Accessibility built into the primitives.

Accessibility requirements were defined at component level, with WCAG AA as the design target. Shared patterns provided a consistent foundation that individual applications could adopt and maintain.

  • Consistent focus foundations

    Focusable components build on the shared focus patterns of shadcn/ui and Radix primitives. Most use a 4px ring plus a 1px outline drawn from --ring, which AKASHA retunes per theme; some components, such as Slider, use their own variation.

  • Semantics from Radix

    Accordion, Checkbox, Select, Slider and Tabs get their roles, keyboard support and focus management from Radix primitives. Autocomplete uses cmdk for its keyboard-navigable list.

  • Errors tied to state

    Form sets aria-invalid from validation, and Input, Textarea and Select style their visible error state from the same attribute, so validation semantics and the visual error come from one source.

  • Never color alone

    NSFW uses an icon and a label, an installed extension shows a check and text, and inline notifications use role="alert".

  • Labels where there is no text

    Stepper announces Progress and each step number; Copy to clipboard explains itself in a tooltip.

08 · Figma to code

One set of values in Figma and in code.

Figma names swatches the way designers think (Violet 600); the code names them by role (--primary). Every swatch maps to a semantic token with the same value, and icon sizes, network icons and component status line up one to one.

Icon sizing, the scale the components use in code.
Figma library Icon sizing, the scale the components use in code.
The icon set, following Lucide, with custom network and brand icons.
Figma library The icon set, following Lucide, with custom network and brand icons.
In the Figma libraryIn the code
Swatches Violet 600, 200, 100, 700 and 500--primary, --secondary, --accent, --secondary-foreground and --ring in the light theme, with identical values
Swatches Pink 400, Rose 300, Emerald 200 and Zinc 300--primary-start; --destructive and --success in the dark theme; --input in the light theme
Icon sizes XS 12, S 16, M 20, L 24, XL 32The size-3 to size-8 icon sizes used inside components
Network icons: Eth, Solana and Non Eth (custom), Key-round (Lucide)custom-icons: ethereum, solana, no-eth and did-key, chosen by the DID field
Status: Customized shadcn componentThe docs group Custom ShadCN Components; Button's page describes a shadcn Button customized with a gradient and adjusted hover states
Profile card, post card, extension cardProfile Avatar Button, the post card in the social-content blocks, and Extension Card
09 · Governance

Easy to adopt, governed in the open.

With independently developed apps, the system had to be easy to adopt and easy to follow, so every decision was visible to design and engineering alike.

The status legend at the top of the library.
Figma library The status legend at the top of the library.
  1. 01A status on shadcn components

    The Figma library labels each shadcn component as customized for AKASHA, set aside, or awaiting a team decision, so design and engineering share one view of the library.

  2. 02Weekly cross-team design reviews

    Shared patterns were reviewed across apps every week, so each new screen started from the library.

  3. 03Documentation as the contract

    All 33 documented code components have a live preview and a one-line install; 26 include usage code and 17 a props table.

  4. 04Open source

    The library is public on GitHub under Apache 2.0, so anyone building on AKASHA can use the same components.

10 · Deep dives

Two components, end to end.

Two real components, from the Figma library to the code to the apps that use them.

Deep dive 01 · Customized shadcn component

Button

A shadcn Button, customized: the default variant became the AKASHA gradient, hover dims it, and the shape became a pill.

Button documentation (opens in a new tab)
Button styles in the Figma library, including the gradient default and icon-only buttons.
Figma library Button styles in the Figma library, including the gradient default and icon-only buttons.
Anatomy
  1. Container40px high (32px small), pill-shaped through the button's scoped --radius, 8px gap
  2. Label14px bold (12px at small)
  3. Iconoptional, 16px, either side
  4. Spinnerreplaces the content while loading
Variants and sizes
  • Default (gradient)
  • Secondary
  • Outline
  • Ghost
  • Destructive
  • Link
  • Default 40
  • Small 32
  • Icon 40
States
HoverDefault dims to 70% opacity; outline and ghost take the accent fill; secondary and destructive drop to 80% and 90% of their fill
Focus4px ring at 10% of --ring (20% in dark) plus a 1px outline
Disabled50% opacity, no pointer events
LoadingDisabled, with a spinner in place of the label
Tokens, light theme
  • --primary-start
  • --primary-end
  • --primary-foreground
  • --secondary
  • --input
  • --ring
  • --destructive
Accessibility
  • A native button with type="button" by default, so it never submits a form by accident
  • asChild renders a link as a real link, with button styling
  • Loading disables the button, so it can't be pressed twice
In use across apps · close-ups from AKASHA World screens
  • Button in Antenna: Feed prompt: Start Beaming!, the default gradient variant
    Antenna Feed prompt: Start Beaming!, the default gradient variant
  • Button in Extensions: Install drawer: Cancel as outline, Install as default
    Extensions Install drawer: Cancel as outline, Install as default
  • Button in Extensions: After install: Close and Open keep the same pair
    Extensions After install: Close and Open keep the same pair
  • Button in Vibes: Review queue: Delist as outline, Keep as default
    Vibes Review queue: Delist as outline, Keep as default
  • Button in Vibes: Decision form: Cancel as a text button, Delist as default
    Vibes Decision form: Cancel as a text button, Delist as default
Deep dive 02 · AKASHA component

Profile Avatar Button

How AKASHA shows a person: avatar, name and decentralized ID, the same way in every app.

Profile Avatar Button documentation (opens in a new tab)
The large, vertical layout as a profile card in the Figma library.
Figma library The large, vertical layout as a profile card in the Figma library.
Anatomy
  1. Avatarthe image, or a fallback chosen from the DID; an eye-off icon when NSFW
  2. Name12px at small, 14px bold at medium and large; underlines on hover
  3. NSFW labeldestructive text, at medium and large
  4. Metadataan open slot, for example the age of a post
  5. DID fielda 16px network icon and the ID, truncated in the middle
Layouts
  • Small: 16px avatar, one row
  • Medium: 40px avatar, two rows
  • Large: 80px avatar
  • Large, vertical: profile headers
States
Valid DIDEthereum or Solana network icon; the did:key icon for other DIDs
Invalid DIDA distinct icon and the text Invalid DID
No avatarOne of seven illustrations, picked from the DID
NSFWEye-off icon on a muted fill, plus a destructive label
HoverThe name underlines
Tokens, light theme
  • --secondary-foreground
  • --destructive
  • --muted
  • --foreground
Accessibility
  • Name and ID are real text, readable by screen readers and selectable
  • NSFW is signaled by an icon and a label, not by color
  • The same person gets the same fallback in every app, so recognition doesn't depend on an upload
In use across apps · close-ups from AKASHA World screens
  • Profile Avatar Button in Antenna: Post header, medium: name, post age as metadata, Ethereum address
    Antenna Post header, medium: name, post age as metadata, Ethereum address
  • Profile Avatar Button in Antenna: Navigation menu, medium: the signed-in profile
    Antenna Navigation menu, medium: the signed-in profile
  • Profile Avatar Button in Extensions: Extension author, small: one row, 16px avatar
    Extensions Extension author, small: one row, 16px avatar
  • Profile Avatar Button in Vibes: Reported content, medium: the author under review
    Vibes Reported content, medium: the author under review
  • Profile Avatar Button in Vibes: Review queue, medium: same layout, a different case
    Vibes Review queue, medium: same layout, a different case
11 · Outcome

What the system made possible.

What the library delivered to the AKASHA World apps, and the benefits it was designed for.

Shipped

  • A public code library: 33 documented components in two groups, plus 3 blocks, each installable with the shadcn CLI
  • Light and dark themes from one set of tokens
  • Shared identity, extension and social patterns, the same across the Antenna, Extensions and Vibes designs
  • A Figma library of components and variants whose values match the code token for token

Intended benefits

  • Fewer one-off components, because the common ones already exist
  • Shorter reviews: which button and which focus style are already decided
  • A person reads the same in every app
  • Theme and brand changes made once, in tokens
The takeaway

Independently built apps read as one product when the shared path is also the easiest one. Building on shadcn/ui, matching Figma and code value for value, and documenting every component in public is how I designed AKASHA UI to be that path.

Let's talk

Let's make
it happen.

For product leadership, ambitious projects, and interesting collaborations.