Design principles
These principles guide every decision in the Inntrig interface. They exist to make the product trustworthy, clear, and accessible — qualities that matter especially for a tool used to evaluate accessibility.
Accessible by default
Every component is built to WCAG 2.2 AA as a baseline. This means correct colour contrast, keyboard navigability, focus indicators, and proper use of HTML semantics. The product audits accessibility — it must embody it.
The first rule of ARIA: don't use ARIA when native HTML does the job. Use <h1>–<h6> for headings, <button> for actions, <a> for navigation. Reach for aria-* attributes only when HTML falls short.
Semantic HTML over styling hacks
HTML elements carry meaning. An <a> navigates; a <button>
triggers an action. These are not interchangeable. If something navigates, it must be an anchor — even
if it looks like a button. If it triggers an in-page action (form submission, toggle), it must be
a button.
The Button component supports an asChild prop precisely for this: it lets
a Link (which renders as <a>) carry button styles without wrapping
it in a <button>, which would be invalid HTML. Think of it as "apply button
styling to this element, whatever element it is."
Rule: Never nest a <button> inside an <a> or vice versa. Use Button asChild when a navigation link needs button styling.
Links are always underlined
Text links must always be underlined. Underlines are the universally understood visual cue for a hyperlink. Relying on colour alone to distinguish links from surrounding text fails WCAG SC 1.4.1 (Use of Colour) for users who cannot distinguish colours.
The only exception: navigational links in discrete UI regions (top bar, breadcrumb nav, footer)
where context makes the interactive nature unambiguous. These suppress the underline via the
nav a rule but restore it on hover.
Primary actions
The most important action on a page gets the primary button style (white text on blue). If two actions have equal value — like "Sign in" and "Create account" on the home page — both can be primary. Avoid more than two primary buttons in a single viewport unless they genuinely compete for equal attention.
Secondary actions use an outlined style. Destructive or low-emphasis actions use ghost/text.
Colour communicates meaning, not decoration
The token system defines semantic roles: --color-pass, --color-fail,
--color-na, --color-todo. These are used consistently across the
results UI. New colour usage should map to a semantic token — not a raw hex value — so theming
works correctly.
Layout lives in the app
Design system components handle their own internal layout (padding, alignment). Page-level layout — grids, gaps between components, hero sections — belongs in the consuming app's CSS. Don't pass layout-specific inline styles to components; add a class to the containing element instead.