Oat ui
Build lightweight web UIs with OAT (~8KB), a zero-dependency semantic HTML component library. Use this skill when building dashboards, landing pages, admin panels, forms, or any web UI. Triggers on mentions of OAT, oat.ink, lightweight UI, semantic HTML components, zero-dependency UI, or requests for minimal CSS frameworks. Also use when user wants fast-loading web interfaces without React/Vue/framework overhead.From its SKILL.md
npx -y skills add SirPangolin/sirpangolin-claude-skills --skill oat-uiAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
10.6 KB, ~3.0k tokens by cl100k_base, as published. Nobody here has run it
OAT UI Development
OAT is an ultra-lightweight (~8KB CSS + JS) semantic HTML component library with zero dependencies. It styles native HTML elements directly, reducing class pollution and forcing accessibility best practices.
Quick Start
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>My App</title>
<!-- OAT Core -->
<link rel="stylesheet" href="https://unpkg.com/@knadh/oat/oat.min.css">
<script src="https://unpkg.com/@knadh/oat/oat.min.js" defer></script>
<!-- Optional: oat-chips (~1KB) -->
<link rel="stylesheet" href="https://unpkg.com/oat-chips/dist/chip.min.css">
<!-- Optional: oat-animate (~1KB) -->
<link rel="stylesheet" href="https://unpkg.com/oat-animate/oat-animate.css">
<script src="https://unpkg.com/oat-animate/oat-animate.js" defer></script>
</head>
<body>
<h1>Hello World</h1>
<p>Styled automatically - no classes needed.</p>
<button>Click me</button>
</body>
</html>
Core Philosophy
OAT differs from other UI libraries in key ways:
-
Semantic HTML First: Native elements (
<button>,<dialog>,<details>) are styled directly. Useroleattributes anddata-variantfor variations rather than classes. -
Minimal Classes: Most components need zero classes. Only use classes for:
- Layout utilities:
hstack,vstack,container,row,col-* - Component variations:
outline,ghost,small,large - Specific components:
badge,card,chip,skeleton
- Layout utilities:
-
CSS Custom Properties: Theme via
--varoverrides, not utility classes. -
WebComponents for Interactivity:
<ot-dropdown>and<ot-tabs>provide JS behavior.
Component Quick Reference
Buttons
<button>Primary</button>
<button data-variant="secondary">Secondary</button>
<button data-variant="danger">Danger</button>
<button class="outline">Outline</button>
<button class="ghost">Ghost</button>
<button class="small">Small</button>
<button class="large">Large</button>
<button disabled>Disabled</button>
<!-- Button group -->
<menu class="buttons">
<li><button class="outline">Left</button></li>
<li><button class="outline">Center</button></li>
<li><button class="outline">Right</button></li>
</menu>
Cards
<article class="card">
<header>
<h3>Title</h3>
<p>Description</p>
</header>
<p>Content goes here.</p>
<footer class="hstack">
<button class="outline">Cancel</button>
<button>Save</button>
</footer>
</article>
Forms
<form>
<label data-field>
Name
<input type="text" placeholder="Enter name">
</label>
<label data-field>
Email
<input type="email" placeholder="[email protected]">
<small data-hint>We'll never share your email</small>
</label>
<div data-field="error">
<label>Password</label>
<input type="password" aria-invalid="true">
<div class="error" role="status">Password too short</div>
</div>
<label data-field>
<input type="checkbox"> I agree to terms
</label>
<button type="submit">Submit</button>
</form>
<!-- Input group -->
<fieldset class="group">
<input type="text" placeholder="Search">
<button>Go</button>
</fieldset>
Alerts
<div role="alert">Default info alert</div>
<div role="alert" data-variant="success">Success!</div>
<div role="alert" data-variant="warning">Warning!</div>
<div role="alert" data-variant="error">Error!</div>
Badges
<span class="badge">Default</span>
<span class="badge secondary">Secondary</span>
<span class="badge outline">Outline</span>
<span class="badge success">Success</span>
<span class="badge warning">Warning</span>
<span class="badge danger">Danger</span>
Dialog (Modal)
<button commandfor="my-dialog" command="show-modal">Open</button>
<dialog id="my-dialog" closedby="any">
<form method="dialog">
<header>
<h3>Title</h3>
<p>Description</p>
</header>
<div>Content here</div>
<footer>
<button type="button" commandfor="my-dialog" command="close" class="outline">Cancel</button>
<button value="confirm">Confirm</button>
</footer>
</form>
</dialog>
Dropdown
<ot-dropdown>
<button popovertarget="menu" class="outline">
Options
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="m6 9 6 6 6-6"/>
</svg>
</button>
<menu popover id="menu">
<button role="menuitem">Profile</button>
<button role="menuitem">Settings</button>
<hr>
<button role="menuitem">Logout</button>
</menu>
</ot-dropdown>
Tabs
<ot-tabs>
<div role="tablist">
<button role="tab">Tab 1</button>
<button role="tab">Tab 2</button>
</div>
<div role="tabpanel">Content 1</div>
<div role="tabpanel">Content 2</div>
</ot-tabs>
Accordion
<details>
<summary>Question 1</summary>
<p>Answer 1</p>
</details>
<details>
<summary>Question 2</summary>
<p>Answer 2</p>
</details>
<!-- Grouped (only one open at a time) -->
<details name="faq">
<summary>Q1</summary>
<p>A1</p>
</details>
<details name="faq">
<summary>Q2</summary>
<p>A2</p>
</details>
Table
<div class="table">
<table>
<thead>
<tr><th>Name</th><th>Status</th></tr>
</thead>
<tbody>
<tr><td>Alice</td><td><span class="badge success">Active</span></td></tr>
<tr><td>Bob</td><td><span class="badge secondary">Pending</span></td></tr>
</tbody>
</table>
</div>
Switch
<label>
<input type="checkbox" role="switch"> Notifications
</label>
Progress & Meter
<progress value="60" max="100"></progress>
<meter value="0.7" min="0" max="1" low="0.3" high="0.7" optimum="1"></meter>
Spinner
<div aria-busy="true"></div>
<div aria-busy="true" data-spinner="small"></div>
<div aria-busy="true" data-spinner="large"></div>
<button aria-busy="true" data-spinner="small" disabled>Loading</button>
<!-- Overlay spinner on card -->
<article class="card" aria-busy="true" data-spinner="large overlay">...</article>
Skeleton
<div role="status" class="skeleton line"></div>
<div role="status" class="skeleton box"></div>
Toast
ot.toast('Message', 'Title', { variant: 'success' });
ot.toast('Error', 'Oops', { variant: 'danger', placement: 'top-left' });
// Placements: top-left, top-center, top-right, bottom-left, bottom-center, bottom-right
ot.toast.clear(); // Clear all
Layout
Grid System
<div class="container">
<div class="row">
<div class="col-4">4 cols</div>
<div class="col-4">4 cols</div>
<div class="col-4">4 cols</div>
</div>
<div class="row">
<div class="col-6">6 cols</div>
<div class="col-6">6 cols</div>
</div>
<div class="row">
<div class="col-4 offset-2">offset-2</div>
<div class="col-4">4 cols</div>
</div>
</div>
Flex Utilities
<div class="hstack">Horizontal stack</div>
<div class="vstack">Vertical stack</div>
Sidebar Layout
<body data-sidebar-layout>
<nav data-topnav>
<button data-sidebar-toggle class="outline">☰</button>
<span>App Name</span>
</nav>
<aside data-sidebar>
<header>Logo</header>
<nav>
<ul>
<li><a href="#" aria-current="page">Home</a></li>
<li><a href="#">Users</a></li>
<li>
<details open>
<summary>Settings</summary>
<ul>
<li><a href="#">General</a></li>
<li><a href="#">Security</a></li>
</ul>
</details>
</li>
</ul>
</nav>
<footer>
<button class="outline">Logout</button>
</footer>
</aside>
<main>Content</main>
</body>
Extensions
oat-chips (~1KB)
For tag/filter UI patterns. See references/chips.md for details.
<button class="chip">Tag</button>
<button class="chip" aria-pressed="true">Selected</button>
<button class="chip success">Success</button>
<button class="chip">
Filter
<button class="chip-close">×</button>
</button>
oat-animate (~1KB)
Declarative animations. See references/animate.md for details.
<!-- On-load animations -->
<div ot-animate="fade-up">Fades up on load</div>
<div ot-animate="zoom-in">Zooms in</div>
<!-- Hover animations -->
<button ot-animate="hover:pop">Pops on hover</button>
<!-- Viewport animations (animate when scrolled into view) -->
<div ot-animate="view:slide-left">Slides in when visible</div>
<!-- Custom timing -->
<div ot-animate="fade-up" style="--ot-duration: 0.8s; --ot-delay: 0.2s;">Slower</div>
Available animations: fade-up, fade-down, zoom-in, slide-left, slide-right, pop, bounce, flip-in, pulse, shake
Reference Files
For detailed documentation, read these reference files:
references/components.md- Full component HTML examplesreferences/theme.md- CSS custom properties for themingreferences/chips.md- oat-chips component detailsreferences/animate.md- oat-animate animation details
Key Patterns
- Use semantic HTML:
<button>not<div class="button">,<dialog>not custom modal divs - Use data-variant:
data-variant="danger"rather than.btn-danger - Use role attributes:
role="alert",role="switch",role="menuitem" - Wrap tables:
<div class="table"><table>...</table></div>for overflow handling - Use data-field for forms:
<label data-field>wraps label + input + hint - Cards use article:
<article class="card">with<header>,<footer> - Button groups use menu:
<menu class="buttons"><li><button>...</li></menu>
Installation Options
# npm
npm install @knadh/oat
# CDN
<link rel="stylesheet" href="https://unpkg.com/@knadh/oat/oat.min.css">
<script src="https://unpkg.com/@knadh/oat/oat.min.js" defer></script>
# Extensions
npm install oat-chips
npm install oat-animate
Note: OAT is pre-v1 and may have breaking changes. Always check https://oat.ink for latest docs.
Credits
What ships with it: 4 files
32.6 KB alongside SKILL.md
references/
- animate.md7.8 KB
- chips.md5.2 KB
- components.md15.4 KB
- theme.md4.2 KB