Toss · the chip button
A button is a chip that flips like a tossed coin between its faces. wow.toss(chip, { swap })
An interface standard and kit
Pick one physical world for the product and make every control an object in it. Metal that catches the light, springs instead of fades, every state designed. One CSS file, one JS module, no dependencies. Plus a linter that fails flat UI before it ships.
npx github:mthburnsbarber-web/wow-ui lint src/
The kit, live
Everything below is the real kit running in your browser: kit/wow.css and kit/wow.js. Tilt your phone, hover, tap. With Reduce Motion on, it all settles into quiet fades.
A button is a chip that flips like a tossed coin between its faces. wow.toss(chip, { swap })
Suggestions fanned in your hand. Tap one to play it. wow.deal(cards)
Chips drop in one by one, each with a click. wow.stack(chips)
Never a stock spinner. A riffle shuffle; the top card catches the light. .wow-riffle
A wrong code shakes and the gold cools to grey. The right one flips over. wow.shake() wow.flip()
Each granted permission turns face-up as a gold card. Tap to try it. .wow-flip
Never red text. The exact reason, in the world's language, with the fix one tap away. .wow-joker
Lacquer, a three-stop metal with a highlight, engraved double rules, guilloché, key light, vignette, device-resolution grain.
Success is pressed into wax, not a green tick. wow.springs.toss
Same rules, different world
A world is a set of tokens: lacquer, metal, paper, key light, type. Put data-wow-world on any element and every surface inside re-skins at once. Click one to make it the page.
Nothing simply fades in
The kit solves a damped spring exactly and returns a CSS linear() easing with its settle time. It takes the same two numbers as SwiftUI's .spring(response:dampingFraction:), so the web screen and its native twin move the same.
Banknote line work
Sums of sine rings, offset in phase, like the engraving on a banknote. Deterministic SVG you can export. The kit uses it for the slowly turning rosette, card backs and certificate borders.
The banned list, enforced
wow-lint reads CSS, HTML, JSX, Vue, Svelte and SwiftUI and fails the build on the things the standard bans: stock spinners, plain fades, linear easing, flat grey borders, flat yellow "gold", controls that do nothing, icon buttons with no label, and motion with no Reduce Motion fallback.
$ npx github:mthburnsbarber-web/wow-ui lint examples/flat examples/flat/SettingsView.swift:13:13 warn system-segmented Unstyled segmented control. Make it an object from your world. examples/flat/SettingsView.swift:15:26 error stock-spinner Stock spinner. Make loading an object from your world. examples/flat/SettingsView.swift:17:13 error silent-control Control that does nothing. Say why it can't act and offer the fix. examples/flat/SettingsView.swift:18:17 error flat-gold Flat yellow gold. Metal is a three-stop gradient: var(--wow-metal). examples/flat/SettingsView.swift:20:9 error plain-fade Plain fade. Give it a verb with a spring; fades are for Reduce Motion only. examples/flat/SettingsView.swift:20:9 error no-reduced-motion Motion with no Reduce Motion fallback in any scanned file. examples/flat/SettingsView.swift:21:9 error linear-easing Linear easing on one-shot motion. Use a spring: var(--wow-spring-*). examples/flat/styles.css:3:3 error flat-grey-border Flat grey border. Use an engraved rule: .wow-plate, var(--wow-rule). examples/flat/styles.css:9:3 error plain-fade Plain fade. Give it a verb with a spring; fades are for Reduce Motion only. examples/flat/styles.css:13:3 error linear-easing Linear easing on one-shot motion. Use a spring: var(--wow-spring-*). examples/flat/styles.css:16:1 error plain-fade Plain fade. Give it a verb with a spring; fades are for Reduce Motion only. examples/flat/styles.css:22:3 error flat-gold Flat yellow gold. Metal is a three-stop gradient: var(--wow-metal). examples/flat/Toolbar.jsx:3:10 error flat-grey-border Flat grey border. Use an engraved rule: .wow-plate, var(--wow-rule). examples/flat/Toolbar.jsx:4:24 error stock-spinner Stock spinner. Make loading an object from your world. examples/flat/Toolbar.jsx:6:15 error silent-control Control that does nothing. Say why it can't act and offer the fix. examples/flat/Toolbar.jsx:7:7 error unlabeled-control No accessible label. Every object needs a name. examples/flat/Toolbar.jsx:8:7 error silent-control Control that does nothing. Say why it can't act and offer the fix. 17 problems (16 errors, 1 warning) in 3 files $ npx github:mthburnsbarber-web/wow-ui lint kit worlds demo 6 files checked. Nothing flat.
Use it
The standard is written to be pasted at the top of any UI task, for any AI. It also ships as a Claude Code skill.
Copy kit/ and one world, or load them from a CDN. No build step.
<link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/mthburnsbarber-web/wow-ui@v1.0.0/kit/wow.css"> <link rel="stylesheet" href="https://cdn.jsdelivr.net/gh/mthburnsbarber-web/wow-ui@v1.0.0/worlds/worlds.css"> <body class="wow-scene" data-wow-world="card-table"> <div class="wow-card wow-tilt wow-foil wow-glint" data-wow-tilt>…</div> <script type="module"> import * as wow from 'https://cdn.jsdelivr.net/gh/mthburnsbarber-web/wow-ui@v1.0.0/kit/wow.js'; wow.auto(); </script>
Install it as a skill. Every UI task loads the standard, uses the kit, and runs the linter and the contact sheet before calling it done.
git clone https://github.com/mthburnsbarber-web/wow-ui ~/.claude/skills/wow-ui
Any other agent: add one line to AGENTS.md.
Before any UI work, read and follow STANDARD.md from github.com/mthburnsbarber-web/wow-ui, then run `npx github:mthburnsbarber-web/wow-ui lint` on the changed files.