Skip to main content

WayneUI 2.0

The design system for C&IT internal applications.

One set of brand tokens, one set of components, four ways to use them, and an accessibility bar the pipeline enforces rather than a README claims. It replaces the Bootstrap 3 and jQuery package that has been in these applications since 2017.

consumer paths, one set of markup
4
components in the gallery
50
color pairings measured every build
74
brand green on white, gated in CI
8.82:1
accessibility tests, none allowed to fail
1084

This page is the demo

Every control below is the shipped component, rendered here. There is no screenshot anywhere on this site. Switch the theme in the bar and watch it hold, or narrow the window to 320 pixels.

Credits enrolled12
Credits required15
Holds1
Waitlisted2
Warning:

Advising hold

You must meet with an advisor before registering for more than 12 credits.
Available courses, Winter 2027
SeatsStatus
CSC 2110Computer Science I412 of 40Open
MAT 2010Calculus I40 of 35Closed
ENG 3050Technical Communication34 of 25Waitlist
OpenWaitlistClosed

Pick the path you are already on

WayneUI does not ask an application to change how it is built. All four paths emit the same classes, the same ARIA and the same data-wsu-* hooks, because all four are tested against the same extracted markup contract rather than against anyone's memory.

Static HTML

No build step, no framework, no package manager.

Copy three files.

<link rel="stylesheet" href="wayne-ui.css">
<script src="wayne-ui-theme.js" type="module"></script>

<button class="wsu-btn wsu-btn--primary">Add course</button>

Raw PHP

One require. No Composer, no autoloader, no container.

require the standalone helpers.

<?php require 'wayne-ui.php'; ?>

<?= wsu_app_shell_open(['title' => 'Course Registration']) ?>
  <?= wsu_button('Add course', ['variant' => 'primary']) ?>
<?= wsu_app_shell_close() ?>

Laravel and Blade

A provider, 28 Blade components, request-scoped breadcrumbs.

composer require waynestate/wayne-ui

<x-wsu::app-shell title="Course Registration">
    <x-wsu::page-header title="Select courses" />
    <x-wsu::button variant="primary">Add course</x-wsu::button>
</x-wsu::app-shell>

Laravel, Inertia and Vue

35 Vue 3 components, no CSS emitted, one plugin.

pnpm add @waynestate/wayne-ui-vue @waynestate/wayne-ui-css

<AppShell>
  <PageHeader title="Select courses" />
  <Button variant="primary">Add course</Button>
</AppShell>

Two templates, both of them applications

The difference is who can reach the page, and therefore how much university identity it carries. Not what the page is for.

Internal

Compact bar, shield only, full width. The bar collapsed from about 140 pixels of chrome to 89 by dropping the marketing masthead an internal tool has no use for.

Stylesheet
wayne-ui.css
Search
Inline in the bar

Publicly accessible

The real wayne.edu masthead and footer, from @waynestate/wsuheader and @waynestate/wsufooter, consumed as dependencies and never copied into a view.

Stylesheet
wayne-ui-official.css
Search
Expanding, because the masthead already has one

What is actually enforced

These are pipeline jobs, not intentions. Nothing in the accessibility stages is allow_failure, and no job downgrades a violation to a warning.

Contrast

74 pairings

Declared on the tokens themselves and read back by the tests, so a color added without a declaration is a color that escapes the gate. 52 of them are held to 7:1.

axe-core

Zero violations

8 pages, 2 themes, 3 viewport widths. 320, 768 and 1440, which is also 1280 at 400% zoom.

Lighthouse

100

Not 95, and not "no regressions since last time". A score below 100 stops the build.

Markup contract

202 classes

Extracted from the two static templates. Vue, Blade and the framework-free PHP helpers are all tested against that file rather than against each other.

The numbers in full

Why?

The WayneUI before this one was written in 2017, as a Laravel package. It gave an application a Wayne State look without every team building one, and it worked. It is still running in production today.

It shipped Bootstrap 3.2.0 and jQuery 1.11.1, both released in 2014, vendored as minified copies and committed. It had one consumer path, so a team not on Laravel could not use it at all. Twenty six commits across four years, and the last functional change was in 2019.

That is the problem, and it is not that the package was old. It stopped in 2019 and the applications standing on it did not. Bootstrap 3 reached end of life, the university masthead was redesigned, the accessibility guidelines moved twice, and every one of those happened to applications with no way to receive the change. The masthead is the clearest case: pasted in once and never synced, it still carried an Internet Explorer 9 filter years after Internet Explorer was gone, showing an identity the university had already replaced.

So this is a rewrite rather than an upgrade. There is no compatibility shim and migrating is real work, because carrying the old class names forward would have meant carrying the reasons they were wrong.

What changed between the 2017 package and this one
What2017 to 2019Now
Consumer pathsOne, and only if you were on LaravelFour, from one set of markup
Front end dependenciesBootstrap 3.2.0 and jQuery 1.11.1, copied in and frozen thereTailwind and daisyUI, declared and updated like anything else
The university mastheadA copy, pasted once in 2017A dependency, updated when they update it
AccessibilityAssertedMeasured every release, in both themes
Last functional change2019This release