<button
class="inline-flex items-center gap-2
rounded-full bg-indigo-600 px-6 py-3
text-sm font-semibold text-white
shadow-lg hover:bg-indigo-500
focus-visible:outline-2
md:px-8 md:text-base
dark:bg-white dark:text-gray-950
dark:hover:bg-gray-200">
Get started
</button>
Build interfaces
with
attributes
Every spacing, color and layout decision lives on the element it styles. Your markup keeps reading like the thing it renders, not like an index of class names.
Customers
18,246
+6.5% since last week
128.7K
24
Clients
Samantha Bloom
Calling...
Markup that actually reads like the interface.
Styling is a property of an element, so it belongs on the element. No sprawling class strings, and no stylesheet to cross-reference.
<button bg="primary"
hover-bg="primary/80"
text="white"
px="6" py="3"
rounded="full">
Get started
</button>
Attribute-first
One attribute for every decision.
There is exactly one place a style decision lives: the attribute. Not a class, not a modifier, not a wrapper component. Just bg=, px= and rounded=, spelled the way you would say them out loud.
ATOMATTR VS TAILWIND
Same decisions. A different shape.
Tailwind is a great utility system, and Atomattr borrows its vocabulary. The difference is where the decisions live: one long class string, or one attribute per decision.
<button
display="inline-flex" items="center" gap="2"
rounded="full"
bg="primary" hover-bg="primary/80"
dark-bg="#fff" dark-text="gray-950"
text="white"
px="6" md-px="8" py="3"
font-size="sm" md-font-size="md"
font-weight="600" shadow="lg">
Get started
</button>
Scannable
Each decision is its own name and value, so you can read down a column instead of parsing a string.
Variants stay beside values
px and md-px sit next to each other, rather than px-6 and md:px-8 scattered through the string.
Semantic tokens
Say primary, muted or border and let the theme decide the actual color.
React Native, same words
The vocabulary carries over to <View>, so web and mobile share one way of styling.
class string
One attribute per decision
md:px-8
md-px="8"
dark:bg-white
dark-bg="#fff"
hover:bg-indigo-500
hover-bg="primary/80"
bg-indigo-600/80
bg="primary/80"
Different tools, different trade-offs. Pick the one whose markup you would rather read six months from now.
RESPONSIVE
Breakpoints, right where you read.
A breakpoint is just a prefix. md-grid-cols="2" sits beside grid-cols="1", so the whole layout story is in one spot. Resize your window and watch these tiles reflow.
display="grid" gap="3"
grid-cols="1"
md-grid-cols="2"
Family Therapy
Johnson Family
Family Therapy
Johnson Family
DARK MODE
Dark mode without a rewrite.
Add dark-bg or dark-text to the element and light and dark intent live together. Flip the theme in the header and this whole page follows.
CROSS-PLATFORM
Same language, platform-aware output.
HTML and React Native render differently. Atomattr gives you one styling vocabulary without pretending the two platforms are the same thing.
Read the docs<div display="grid" grid-cols="3" gap="4">
...
</div>
<View display="grid" grid-cols="3" gap="4" />
COMPONENTS, READY TO COPY
Real interfaces, built the same way.
PRO
$19/month
Active users
12.4k
+8.2%
Revenue
$48.9k
+3.1%
Churn
1.2%
-0.4%
COLOR SYSTEM
Design systems that stay yours.
The primary color on this page is not a screenshot. It is read straight from --aa-color-primary at render time, in whichever mode you are viewing.
Primary
Success
Warning
Danger
Semantic tokens
Tokens stay stable. Palettes can change.
PRIMARY SHADES
LIVE GRADIENT
--aa-color-primary
COMMUNITY
Build with people nearby.
Follow progress, ask questions, share experiments, and help shape the attribute API as it grows.
Try one component, then decide.
Open the docs, copy a pattern, and see how the markup feels before changing anything big in your project.