Auras

Auras

A headless CSS framework built on semantic HTML and data-* attributes. No classes, no build step, no JavaScript required.

Get started Components

Headless by default

Structure without opinion. Readable typography, sensible spacing, and semantic surfaces that do not force a visual language.

Attribute-driven

No class names to memorize. Use data-layout, data-surface, data-variant and other semantic attributes.

Three layers

Elements for base styles. Composites for CSS-only patterns. Components for optional interactive custom elements.

Pluggable brands

Layer a brand pack on top for a full design system. Switch brands at runtime with a single attribute change.

Quick start

Get started

Add the base stylesheet and optionally layer composites, components, and a brand pack.

<!-- Required: base elements -->
<link rel="stylesheet" href="auras.css">

<!-- Optional: composites for higher-level CSS patterns -->
<link rel="stylesheet" href="auras-composites.css">

<!-- Optional: interactive custom elements -->
<script type="module" src="@auras/components/browser.js"></script>
<script type="module" src="@auras/diagram/browser.js"></script>

<!-- Optional: brand pack -->
<link rel="stylesheet" href="auras-brand.css">
<body data-brand="auras">

Layer architecture

CSS layers ensure predictable specificity regardless of load order.

reset > tokens > brands > defaults
  > layouts > components > utilities > print

Design tokens

OKLCH-based color system with fluid typography and consistent spacing scale.

--space-1 through --space-16
--text-xs through --text-3xl
--primary, --secondary, --accent

Base layer

Elements

Typography, surfaces, buttons, notices, forms, and utilities - all styled without requiring any classes.

Typography

Heading 1

Heading 2

Heading 3

Body text inherits system fonts and scales fluidly using clamp() functions. Inline elements like strong, emphasis, code, and links are styled automatically.

Blockquotes get a subtle left border and muted styling from the base layer.

<h1>Heading 1</h1>
<p>Body text with <strong>strong</strong> and <code>code</code>.</p>
<blockquote><p>A quotation.</p></blockquote>

Buttons

<button type="button">Default</button>
<button type="button" data-variant="solid">Solid</button>
<button type="button" data-variant="soft">Soft</button>
<button type="button" data-variant="ghost">Ghost</button>
<button type="button" aria-busy="true">Loading</button>

Notices

<aside data-surface="notice" data-status="info">
  <strong>Info</strong>
  <p>Neutral informational message.</p>
</aside>

Accordion

What is Auras?

A headless CSS framework that provides structure through semantic HTML and data attributes, not class names.

Does it require JavaScript?

The base Elements and Composites layers are pure CSS. The Components layer adds optional interactive custom elements.

How do I theme it?

Override design tokens in a brand pack CSS file and apply it with data-brand on the body element.

<section data-ui="accordion">
  <details name="faq" open>
    <summary>Question</summary>
    <p>Answer.</p>
  </details>
</section>

Dialog

Dialog

Native dialogs inherit active tokens, lock page scroll, and use a motion-safe entry transition.

<dialog id="my-dialog">
  <h3>Title</h3>
  <p>Content.</p>
  <button onclick="this.closest('dialog').close()">Close</button>
</dialog>

Spatial primitives

Layout

Directional layouts, responsive grids, alignment, gaps, and stacking - all through data attributes.

Row, cluster, and stack

Row start Row center Row end
Stack item 1
Stack item 2
Stack item 3
<div data-layout="row" data-align="center" data-justify="between">...</div>
<div data-layout="cluster" data-gap="2">...</div>
<div data-layout="stack" data-gap="2">...</div>

Grid

Auto columns

Columns size themselves using auto-fit.

Responsive

Set a minimum with data-grid-min.

No breakpoints

The grid adapts to available space automatically.

Consistent gaps

Gaps use the design token spacing scale.

<div data-layout="grid" data-gap="3" data-grid-min="sm">
  <div data-surface="card">...</div>
  <div data-surface="card">...</div>
</div>

Container and responsive stacking

Left

Stacks vertically on mobile.

Right

Use data-stack="mobile" for this behavior.

<body data-layout="container">...</body>
<div data-layout="row" data-stack="mobile">...</div>

Inputs

Forms

Text fields, selects, checkboxes, switches, ranges, progress bars, and validation - all styled through the base layer.

Contact
72%
<label for="name">Name</label>
<input id="name" type="text" required />

<label><input type="checkbox" role="switch" /> Toggle</label>
<progress value="72" max="100">72%</progress>

Interactive widgets

Components

Optional light-DOM custom elements that add keyboard navigation, selection state, and panel coordination. No shadow DOM - your authored HTML stays visible and styleable.

<script type="module" src="@auras/components/browser.js"></script>
<script type="module" src="@auras/diagram/browser.js"></script>

Tabs

auras-tabs coordinates tab selection with roving focus and panel visibility. The component only manages behavior - the Composites layer handles visual treatment.

Selected: overview

Overview

Tabs switch content inline with Left/Right arrow key navigation, Home, End, and click activation.

<auras-tabs data-ui="tabs" value="overview">
  <nav data-part="tablist">
    <button data-part="trigger" data-value="overview">Overview</button>
    <button data-part="trigger" data-value="tokens">Tokens</button>
  </nav>
  <section data-part="panels">
    <article data-part="panel" data-value="overview">...</article>
    <article data-part="panel" data-value="tokens" hidden>...</article>
  </section>
</auras-tabs>

Master-detail

auras-master-detail coordinates a sidebar list with a detail panel. The Composites layer provides a responsive grid shell.

Selected: elements

Elements

The foundation layer provides reset, design tokens, element defaults, layout primitives, and utilities in a single CSS file.

<auras-master-detail data-ui="master-detail" value="elements">
  <nav data-part="master" aria-label="Auras layers">
    <button data-part="trigger" data-value="elements">
      <strong>Elements</strong>
      <p>Base styles and tokens</p>
    </button>
  </nav>
  <section data-part="detail">
    <article data-part="panel" data-value="elements">...</article>
  </section>
</auras-master-detail>

Combobox

auras-combobox adds filtering, active option state, keyboard selection, and optional linked panels to a native input and list.

Selected: tabs

  • Tabs
  • Master-detail
  • Tree
  • Combobox
  • Splitter
  • Diagram
<auras-combobox data-ui="combobox" value="tabs">
  <label for="search">Search</label>
  <div data-part="control">
    <input data-part="input" type="text" placeholder="Filter..." />
    <button data-part="toggle" aria-label="Toggle"></button>
    <input type="hidden" data-part="value" name="search" />
  </div>
  <ul data-part="listbox">
    <li data-part="option" data-value="tabs">Tabs</li>
  </ul>
  <p data-part="empty" hidden>No matches.</p>
</auras-combobox>

Splitter

auras-splitter adds keyboard resizing, pointer drag, and percent-based layout state to a two-pane layout.

Split at: 40%

Primary

Drag the separator or use arrow keys to resize.

Secondary

The split value is exposed through the value attribute and the auras-change event.

<auras-splitter data-ui="splitter" value="40" min="25" max="75" step="5">
  <section data-part="pane" data-pane="primary">...</section>
  <button data-part="separator" aria-label="Resize"></button>
  <section data-part="pane" data-pane="secondary">...</section>
</auras-splitter>

Tree

auras-tree adds hierarchical selection, branch expansion, and spatial keyboard navigation to a nested list.

Selected: auras.css

<auras-tree data-ui="tree" value="root">
  <ul data-part="tree">
    <li data-part="item" data-branch data-expanded>
      <button data-part="toggle"></button>
      <button data-part="node" data-value="parent">Parent</button>
      <ul data-part="group">
        <li data-part="item">
          <button data-part="node" data-value="child">Child</button>
        </li>
      </ul>
    </li>
  </ul>
</auras-tree>

Diagram

auras-diagram turns semantic content with CSS Grid placement into interactive flow diagrams with spatial keyboard navigation and linked detail panels.

Selected: input

A simple three-step data pipeline.

Ingest

Raw data arrives from external sources via API or file upload.

<auras-diagram value="input" style="--diagram-columns: 7">
  <div data-part="canvas">
    <button data-part="node" data-kind="input" data-value="input"
      style="--diagram-column: 1 / span 2; --diagram-row: 1">
      <strong>Ingest</strong>
    </button>
    <div data-part="connector" aria-hidden="true"
      style="--diagram-column: 3; --diagram-row: 1">
      <svg viewBox="0 0 120 40"><path d="M4 20 H108" /></svg>
    </div>
    <!-- more nodes... -->
  </div>
  <section data-part="panels">
    <article data-part="panel" data-value="input">...</article>
  </section>
</auras-diagram>

Sections

auras-sections presents content as either tabs or an accordion from a single markup structure. In auto mode, it morphs between the two based on container width.

Tabs mode

Selected: design

Semantic HTML first, token-driven styling, and attribute-based APIs keep your markup readable and your design system consistent.

No build step required. Load one stylesheet and optional components. Works with any framework or none at all.

Ship a static directory or deploy to any edge runtime. Progressive enhancement means content works before JavaScript loads.

<auras-sections mode="tabs" value="design">
  <section data-part="section" data-value="design">
    <button data-part="trigger">Design</button>
    <div data-part="panel">...</div>
  </section>
  <section data-part="section" data-value="develop">
    <button data-part="trigger">Develop</button>
    <div data-part="panel">...</div>
  </section>
</auras-sections>
Accordion mode

Every visual value flows through CSS custom properties. Override a handful of tokens to create a completely new look without touching selectors.

CSS @layer ordering gives you predictable specificity. Elements, composites, and utilities each live in their own layer.

A brand pack is a single CSS file that overrides tokens in @layer brands. Swap brands at runtime with one attribute change.

<auras-sections mode="accordion" value="tokens">
  <section data-part="section" data-value="tokens" data-expanded>
    <button data-part="trigger">Tokens</button>
    <div data-part="panel">...</div>
  </section>
  <!-- more sections... -->
</auras-sections>
Auto mode (resize to see morph)

Semantic markup with data attributes. No classes to memorize, no build step required.

OKLCH colors, cascade layers, fluid typography, and container-aware layouts.

Optional light-DOM components that enhance authored HTML with keyboard behavior and ARIA.

<!-- Morphs between tabs and accordion at 500px -->
<auras-sections mode="auto" morph-at="500" value="html">
  <section data-part="section" data-value="html">
    <button data-part="trigger">HTML</button>
    <div data-part="panel">...</div>
  </section>
  <!-- more sections... -->
</auras-sections>

Brand packs

Theming

Switch between brands, toggle dark mode, and adjust contrast and motion preferences - all through data attributes on the root elements.

Brand packs

A brand pack is a standalone CSS file that overrides tokens via @layer brands. Apply it by setting data-brand on the body.

<body data-brand="auras">
<body data-brand="editorial">
<body> <!-- headless, no brand -->

Dark mode and preferences

Toggle dark mode, high contrast, and reduced motion through attributes on the root element.

<html data-theme="dark">
<html data-contrast="more">
<html data-motion="reduce">

Want to create your own brand pack visually? Open Theme Studio

Color palette

OKLCH-based colors adapt automatically between light and dark modes.

Primary
Surface
Status

Accessibility

Built In, Not Bolted On

Auras bakes accessibility into every layer rather than treating it as an afterthought.

Focus management

:focus-visible outlines on all interactive elements. Components use roving focus for keyboard navigation.

Motion preferences

prefers-reduced-motion is respected by default. Override with data-motion="reduce".

Contrast modes

prefers-contrast: more/less and forced-colors: active (Windows High Contrast) are supported.

ARIA integration

Components manage aria-selected, aria-expanded, and aria-current automatically.

Progressive Enhancement

Content First, Behavior Second

Semantic HTML and CSS carry the page. Components upgrade in place when JavaScript loads.

The hydrated attribute

Every auras-* element sets hydrated on its host after successful initialization. CSS can target :not([hydrated]) to hide controls that need JavaScript.

Pre-hydration CSS

This page hides combobox toggles and dims splitter handles until JavaScript runs. When the component upgrades, the hydrated attribute appears and CSS shows the controls.

Shared base class

All components extend AurasElement, which handles property/attribute sync, auto-binding, lifecycle hooks, and the hydration signal.

Safe imperative access

Call customElements.whenDefined() before using methods like show(). The element is ready when the promise resolves.

Pre-hydration CSS Used on this page

Before JavaScript loads, toggle buttons and drag handles are hidden or dimmed. After hydration, they appear automatically.

/* Hide toggle buttons that need JS */
auras-combobox:not([hydrated]) [data-part="toggle"] {
  visibility: hidden;
}

/* Dim separator until interactive */
auras-splitter:not([hydrated]) [data-part="separator"] {
  pointer-events: none;
  opacity: 0.4;
}

/* Wait for registration before calling methods */
await customElements.whenDefined("auras-tabs");
document.querySelector("auras-tabs").show("tokens");

Component API

A Consistent Host Contract

All components share a uniform interface for attributes, methods, and events.

API Type Description
value Attribute Current selection value. Reflected as a host attribute.
activation Attribute "auto" (default) or "manual". Controls whether focus movement triggers selection.
show(value) Method Programmatically select a value and show its panel.
focusCurrent() Method Move focus to the currently active trigger or node.
hydrated Attribute Set by the base class after successful initialization. Removed on disconnect. Use in CSS for pre-hydration states.
auras-change Event Dispatched on selection change. detail: { value, trigger, panel }.