The Component Vocabulary
Every surface ships in styles.css; the interactive ones are wired by primitives.js — auto-enhanced, or driven through the window.AcrossUI API. Copy any block straight into an Across app.
One primary per surface. The wing-wipe rides the leading edge on hover; the border rests unchanged. Verbs, never "Get started".
<button class="across-btn across-btn--primary"><i class="ph-light ph-check"></i> Primary</button>
<button class="across-btn">Default</button>
<button class="across-btn across-btn--ghost">Ghost</button>
<button class="across-btn across-btn--danger">Danger</button>
Toggle, segmented, tabs, and the searchable combobox — single or multi-select. All keyboard-navigable, wired by primitives.js.
AcrossUI.combobox(el, {
options: ["London", "Tokyo", "Berlin"],
multiple: false,
placeholder: "Select a city…"
});
Cards are flat hairline panels — .across-card--interactive adds the wing-wipe and a 2.5% lift, never a shadow. Sortable rows drag to reorder.
<div class="across-sortable" data-sortable>
<div class="across-sortable__row">
<span class="across-sortable__handle"><i class="ph-light ph-dots-six-vertical"></i></span>
<span class="across-sortable__main">…</span>
</div>
</div>
Transient surfaces — modal, toast, tooltip, popover. Shadows lift only what genuinely floats. Toasts and modals run through window.AcrossUI.
AcrossUI.across-toast({ kind: "success", title: "Pinned", desc: "USD → EUR added." });
AcrossUI.across-modal("my-modal").open(); // also: .close()
Status badges, inline alerts, and empty / error placeholders — semantic colors, never the rebindable accent.
No pinned cities yet
Add a city to keep it close at hand.

