Keyboard interaction, visible focus states, labels, and reduced-motion support ship by default.
-
Configure and use it
This is the smallest useful starting point. Copy it into the indicated application file or run it from the project root, then adjust the documented values for your product.
bunx wrnexus test accessibility .
-bunx wrnexus security headers .
What changes after this
Keyboard, focus, naming, contrast, zoom, and reduced-motion behavior become explicit acceptance criteria.
-
Keyboard first
Every interactive control must be reachable in a logical order and operable without a pointer. Preserve native elements and the component's documented keyboard behavior.
Names and descriptions
Provide visible labels or accessible names for icon-only actions. Associate help and validation messages with their fields rather than relying on color alone.
Focus and overlays
Keep visible focus rings. Modal, drawer, dropdown, and popover components manage focus and dismissal; test Escape, Tab, Shift+Tab, and focus restoration.
Motion and contrast
Theme tokens preserve semantic contrast, while components honor reduced motion. Verify custom colors in light and dark modes at 200% zoom.
-
Verify the result
Type-check the application, inspect the resolved package and styles, and build the production artifact. Test the page at a narrow viewport, with keyboard navigation, and in both color modes before shipping.
The commands exit successfully, the build reports the installed UI components and active theme, and the rendered page remains usable before and after hydration.
+
Overview
Keyboard interaction, visible focus states, labels, and reduced-motion support ship by default.
Configuration
Use the design switcher in the header to test this setting live.
Component behavior
The setting is inherited by components, blocks, templates, and playground previews.
+
Label controls and explain errors
Give every control a visible label. Use helperText for instructions and error for actionable feedback. Test Tab, Shift+Tab, Enter and Escape; focus must remain visible and follow the reading order.
<Input label="Email address" type="email" name="email" required="true" helperText="Use your work email." error="Enter a valid email address." />
+<Button label="Save changes" disabled="true" />
Verify the result
Open the matching component page, change its options, and try the keyboard controls. Copy the demonstrated configuration into your page, then replace sample content with your data.
}
+}
\ No newline at end of file
diff --git a/app/pages/blocks/stats-bar.wrn b/app/pages/blocks/stats-bar.wrn
new file mode 100644
index 0000000..29a828e
--- /dev/null
+++ b/app/pages/blocks/stats-bar.wrn
@@ -0,0 +1,10 @@
+page StatsBarBlock {
+ layout = "gallery"
+
+ seo { title = "Stats Bar block" }
+ view { ← All blocks
Stats Bar
A ready-to-use section. Copy the complete example below.
}
+}
\ No newline at end of file
diff --git a/app/pages/colors.wrn b/app/pages/colors.wrn
index d39923e..7ef643d 100644
--- a/app/pages/colors.wrn
+++ b/app/pages/colors.wrn
@@ -8,13 +8,11 @@ page ColorsGuide {
Customization
Colors
Semantic primary, secondary, success, warning, danger, and info tokens remain available in every palette.
-
Configure and use it
This is the smallest useful starting point. Copy it into the indicated application file or run it from the project root, then adjust the documented values for your product.
<Button color="primary">Save</Button>
-<Alert color="danger">Unable to save</Alert>
What changes after this
Status and hierarchy use named semantic roles that remain understandable in both light and dark modes.
-
Semantic roles
Primary and secondary communicate hierarchy; success, warning, danger, and info communicate state. Use roles consistently instead of choosing colors by appearance.
Component colors
Every maintained component accepts the shared color contract. Prefer the color prop for supported variants and tokens for application-owned surfaces.
Accessible combinations
Check text, icons, borders, hover, focus, selected, and disabled states. Never make color the only carrier of meaning.
Brand overrides
Define brand values once through theme tokens. Derived surfaces and on-colors keep contrast coherent across light and dark modes.
-
Verify the result
Type-check the application, inspect the resolved package and styles, and build the production artifact. Test the page at a narrow viewport, with keyboard navigation, and in both color modes before shipping.
The commands exit successfully, the build reports the installed UI components and active theme, and the rendered page remains usable before and after hydration.
+
Brand colors
Primary and secondary tokens communicate brand hierarchy.
Status colors
Success, warning, danger, and info preserve their semantic meaning in every palette.
Component override
Pass color="success" or another semantic color to any component.
+
Choose color by meaning
Use primary for the main action, danger for destructive actions and success for completion. Always include text or an icon so color is not the only signal.
Open the matching component page, change its options, and try the keyboard controls. Copy the demonstrated configuration into your page, then replace sample content with your data.
+
}
diff --git a/app/pages/components/accordion.wrn b/app/pages/components/accordion.wrn
index e711faf..5399610 100644
--- a/app/pages/components/accordion.wrn
+++ b/app/pages/components/accordion.wrn
@@ -6,13 +6,13 @@ page AccordionDetail {
state playground_variant = ctx.url.searchParams.get("pg_variant") ?? "default"
state playground_class = ctx.url.searchParams.get("pg_class") ?? "showcase-instance showcase-instance--1"
state playground_id = ctx.url.searchParams.get("pg_id") ?? "accordion"
- state playground_items = JSON.parse(ctx.url.searchParams.get("pg_items") ?? "[{\"id\":\"accordion-0-1\",\"key\":\"accordion-0-1\",\"value\":\"primary\",\"label\":\"Primary workflow\",\"title\":\"Primary workflow\",\"description\":\"A clean default configuration for everyday product interfaces.\",\"text\":\"A configurable sample message.\",\"href\":\"#accordion-demo\",\"actionHref\":\"#accordion-demo\",\"actionLabel\":\"View details\",\"icon\":\"icon-[lucide--sparkles]\",\"iconClass\":\"icon-[lucide--sparkles]\",\"variant\":\"primary\",\"status\":\"Active\",\"time\":\"09:30\",\"current\":true,\"selected\":true,\"checked\":true,\"disabled\":false,\"outgoing\":false,\"open\":true,\"number\":1,\"count\":16,\"percentage\":72,\"color\":\"#7c3aed\",\"target\":\"_self\",\"ariaLabel\":\"Open primary workflow 1\",\"items\":[{\"label\":\"Nested option A\",\"value\":\"nested-a\"},{\"label\":\"Nested option B\",\"value\":\"nested-b\"}],\"links\":[{\"label\":\"Documentation\",\"href\":\"#documentation\"},{\"label\":\"API reference\",\"href\":\"#api-reference\"}],\"values\":[\"Included\",\"Standard\"]},{\"id\":\"accordion-0-2\",\"key\":\"accordion-0-2\",\"value\":\"secondary\",\"label\":\"Additional option\",\"title\":\"Supporting example\",\"description\":\"A clean default configuration for everyday product interfaces.\",\"text\":\"Another configurable message.\",\"href\":\"#accordion-demo\",\"actionHref\":\"#accordion-demo\",\"actionLabel\":\"View details\",\"icon\":\"icon-[lucide--sparkles]\",\"iconClass\":\"icon-[lucide--sparkles]\",\"variant\":\"primary\",\"status\":\"Active\",\"time\":\"09:30\",\"current\":false,\"selected\":false,\"checked\":false,\"disabled\":false,\"outgoing\":true,\"open\":true,\"number\":2,\"count\":32,\"percentage\":72,\"color\":\"#7c3aed\",\"target\":\"_self\",\"ariaLabel\":\"Open primary workflow 2\",\"items\":[{\"label\":\"Nested option A\",\"value\":\"nested-a\"},{\"label\":\"Nested option B\",\"value\":\"nested-b\"}],\"links\":[{\"label\":\"Documentation\",\"href\":\"#documentation\"},{\"label\":\"API reference\",\"href\":\"#api-reference\"}],\"values\":[\"Included\",\"Standard\"]}]")
- state playground_defaultOpen = JSON.parse(ctx.url.searchParams.get("pg_defaultOpen") ?? "[{\"id\":\"accordion-0-1\",\"key\":\"accordion-0-1\",\"value\":\"primary\",\"label\":\"Primary workflow\",\"title\":\"Primary workflow\",\"description\":\"A clean default configuration for everyday product interfaces.\",\"text\":\"A configurable sample message.\",\"href\":\"#accordion-demo\",\"actionHref\":\"#accordion-demo\",\"actionLabel\":\"View details\",\"icon\":\"icon-[lucide--sparkles]\",\"iconClass\":\"icon-[lucide--sparkles]\",\"variant\":\"primary\",\"status\":\"Active\",\"time\":\"09:30\",\"current\":true,\"selected\":true,\"checked\":true,\"disabled\":false,\"outgoing\":false,\"open\":true,\"number\":1,\"count\":16,\"percentage\":72,\"color\":\"#7c3aed\",\"target\":\"_self\",\"ariaLabel\":\"Open primary workflow 1\",\"items\":[{\"label\":\"Nested option A\",\"value\":\"nested-a\"},{\"label\":\"Nested option B\",\"value\":\"nested-b\"}],\"links\":[{\"label\":\"Documentation\",\"href\":\"#documentation\"},{\"label\":\"API reference\",\"href\":\"#api-reference\"}],\"values\":[\"Included\",\"Standard\"]},{\"id\":\"accordion-0-2\",\"key\":\"accordion-0-2\",\"value\":\"secondary\",\"label\":\"Additional option\",\"title\":\"Supporting example\",\"description\":\"A clean default configuration for everyday product interfaces.\",\"text\":\"Another configurable message.\",\"href\":\"#accordion-demo\",\"actionHref\":\"#accordion-demo\",\"actionLabel\":\"View details\",\"icon\":\"icon-[lucide--sparkles]\",\"iconClass\":\"icon-[lucide--sparkles]\",\"variant\":\"primary\",\"status\":\"Active\",\"time\":\"09:30\",\"current\":false,\"selected\":false,\"checked\":false,\"disabled\":false,\"outgoing\":true,\"open\":true,\"number\":2,\"count\":32,\"percentage\":72,\"color\":\"#7c3aed\",\"target\":\"_self\",\"ariaLabel\":\"Open primary workflow 2\",\"items\":[{\"label\":\"Nested option A\",\"value\":\"nested-a\"},{\"label\":\"Nested option B\",\"value\":\"nested-b\"}],\"links\":[{\"label\":\"Documentation\",\"href\":\"#documentation\"},{\"label\":\"API reference\",\"href\":\"#api-reference\"}],\"values\":[\"Included\",\"Standard\"]}]")
+ state playground_items = JSON.parse(ctx.url.searchParams.get("pg_items") ?? "[{\"value\":\"workspace\",\"label\":\"How do I create a workspace?\",\"content\":\"Choose Create workspace, add a name, and invite your team. You can update the details any time in Settings.\"},{\"value\":\"billing\",\"label\":\"Can I change my plan later?\",\"content\":\"Yes. Open Billing to compare plans and choose the one that suits your team.\"},{\"value\":\"security\",\"label\":\"How is my account protected?\",\"content\":\"Enable two-step verification and add a recovery method to keep your account secure.\"}]")
+ state playground_defaultOpen = JSON.parse(ctx.url.searchParams.get("pg_defaultOpen") ?? "[\"workspace\"]")
state playground_multiple = (ctx.url.searchParams.get("pg_multiple") ?? "false") === "true"
state playground_alwaysOpen = (ctx.url.searchParams.get("pg_alwaysOpen") ?? "false") === "true"
state playground_disabled = (ctx.url.searchParams.get("pg_disabled") ?? "false") === "true"
- state playground_indicator = ctx.url.searchParams.get("pg_indicator") ?? "plus"
- state playground_indicatorPosition = ctx.url.searchParams.get("pg_indicatorPosition") ?? "start"
+ state playground_indicator = ctx.url.searchParams.get("pg_indicator") ?? "chevron"
+ state playground_indicatorPosition = ctx.url.searchParams.get("pg_indicatorPosition") ?? "end"
state playground_showIndicator = (ctx.url.searchParams.get("pg_showIndicator") ?? "true") === "true"
state playground_bordered = (ctx.url.searchParams.get("pg_bordered") ?? "false") === "true"
state playground_separated = (ctx.url.searchParams.get("pg_separated") ?? "false") === "true"
@@ -43,224 +43,36 @@ page AccordionDetail {
page AccordionExample {
+ state items = [
+ {
+ "value": "workspace",
+ "label": "How do I create a workspace?",
+ "content": "Choose Create workspace, add a name, and invite your team. You can update the details any time in Settings."
+ },
+ {
+ "value": "billing",
+ "label": "Can I change my plan later?",
+ "content": "Yes. Open Billing to compare plans and choose the one that suits your team."
+ },
+ {
+ "value": "security",
+ "label": "How is my account protected?",
+ "content": "Enable two-step verification and add a recovery method to keep your account secure."
+ }
+]
+ state defaultOpen = [
+ "workspace"
+]
+ view {
+ <Accordion
+ items="{items}"
+ defaultOpen="{defaultOpen}"
+ indicator="chevron"
+ indicatorPosition="end"
+ />
+ }
+}
Event outputInteract with the preview to inspect the typed payload.
@@ -269,219 +81,23 @@ page AccordionDetail {
Component props17 controls
+ "workspace"
+]
@@ -490,707 +106,145 @@ page AccordionDetail {
Live examples
Designed for real product surfaces
Compare configurations and resize the browser to check responsive behavior.
-
Recommended
Production default
Balanced spacing, hierarchy, and content for the most common product workflow.
+
Recommended
Plain disclosure rows
Unframed questions with trailing chevrons and aligned answers.
page AccordionExample {
+ state items = [
+ {
+ "value": "workspace",
+ "label": "How do I create a workspace?",
+ "content": "Choose Create workspace, add a name, and invite your team. You can update the details any time in Settings."
+ },
+ {
+ "value": "billing",
+ "label": "Can I change my plan later?",
+ "content": "Yes. Open Billing to compare plans and choose the one that suits your team."
+ },
+ {
+ "value": "security",
+ "label": "How is my account protected?",
+ "content": "Enable two-step verification and add a recovery method to keep your account secure."
+ }
+]
+ state defaultOpen = [
+ "workspace"
+]
+ view {
+ <Accordion
+ items="{items}"
+ defaultOpen="{defaultOpen}"
+ indicator="chevron"
+ indicatorPosition="end"
+ />
+ }
+}
-
Dense UI
Compact application
A tighter variation for dashboards, side panels, tables, and operational interfaces.
page AccordionExample {
+ state items = [
+ {
+ "value": "workspace",
+ "label": "How do I create a workspace?",
+ "content": "Choose Create workspace, add a name, and invite your team. You can update the details any time in Settings."
+ },
+ {
+ "value": "billing",
+ "label": "Can I change my plan later?",
+ "content": "Yes. Open Billing to compare plans and choose the one that suits your team."
+ },
+ {
+ "value": "security",
+ "label": "How is my account protected?",
+ "content": "Enable two-step verification and add a recovery method to keep your account secure."
+ }
+]
+ state defaultOpen = [
+ "workspace"
+]
+ view {
+ <Accordion
+ size="sm"
+ variant="secondary"
+ items="{items}"
+ defaultOpen="{defaultOpen}"
+ bordered="true"
+ />
+ }
+}
-
Extended
Rich configuration
A more expressive variation using additional data, stronger emphasis, and optional states.
+
Advanced
Separate panels
Individually framed rows; multiple answers can stay open.
page AccordionExample {
+ state items = [
+ {
+ "value": "workspace",
+ "label": "How do I create a workspace?",
+ "content": "Choose Create workspace, add a name, and invite your team. You can update the details any time in Settings."
+ },
+ {
+ "value": "billing",
+ "label": "Can I change my plan later?",
+ "content": "Yes. Open Billing to compare plans and choose the one that suits your team."
+ },
+ {
+ "value": "security",
+ "label": "How is my account protected?",
+ "content": "Enable two-step verification and add a recovery method to keep your account secure."
+ }
+]
+ state defaultOpen = [
+ "workspace"
+]
+ view {
+ <Accordion
+ size="lg"
+ variant="success"
+ items="{items}"
+ defaultOpen="{defaultOpen}"
+ multiple="true"
+ indicator="chevron"
+ indicatorPosition="end"
+ bordered="true"
+ separated="true"
+ />
+ }
+}