Accessibility
Native semantics first; script only where access requires it.
Mica's accessibility position is mostly a consequence of its other
choices. Styling native elements means their semantics, keyboard behavior,
and assistive-tech mapping arrive intact — a <button> is
announced as a button because it is one. The tokenized focus ring in
mica.preset is visible on every control by default rather than
something you remember to add, and dark mode is color-scheme,
so native controls follow the theme without a parallel palette.
Never fake behavior in CSS
The checkbox-hack school of CSS-only components produces things that look
like tabs and are unusable with a keyboard. Mica refuses that trade: if the
accessible version of a pattern needs script, the script is the
honest cost and ships as an opt-in Tier-2 module. That is the whole Tier 1/2
boundary — does accessibility require JS? — and it is why
m-tabs and m-combobox have modules while dialogs,
accordions, and menus do not.
Tier-2 modules enhance working markup; they never render it. With the module absent you get a degraded but usable page — all tab panels visible in order, a native autocomplete — not an empty container.
Visually hidden
Content some users must reach and others must not see: a table caption
the layout already implies, a heading that structures the document without
repeating a visible title, a description for an icon-only control.
display: none and inline-size: 0 both remove it
from the accessibility tree, which is the opposite of the goal.
There is a hidden sentence here. Off-screen, still announced. Nothing renders between the period and this word.
<caption data-visually-hidden>Standings by conference</caption>
It is an attribute, not a class. class stays the app's;
data-* is valid HTML and needs no HTMLAttributes
augmentation in React or TypeScript; and .visually-hidden /
.sr-only are the most copy-pasted names in accessibility, so a
project arriving with its own copy is the likely case rather than the edge
case. Nothing to collide with.
focusable — the skip link
A skip link must be hidden until someone tabs to it, then visible. The variant hides only while unfocused; on focus the rule stops matching and the element keeps whatever styling you gave it — there is no undo rule fighting your CSS.
<a href="#main" data-visually-hidden="focusable">Skip to content</a>
Tab into this page from the address bar to see mica's own skip link.
What mica does not do for you
A stylesheet cannot supply an accessible name, a heading order, or a sensible tab sequence. Mica keeps the platform's semantics available and declines to break them; labelling controls, structuring headings, and testing with a screen reader remain yours.