@tti/tti-ux (2.0.0)
Installation
@tti:registry=npm install @tti/tti-ux@2.0.0"@tti/tti-ux": "2.0.0"About this package
tti-ux
Living style guide for the tux design system. A runnable Nuxt 4 app that IS the source of truth for components — if a visual changes, this site shows it first.
Built for Texas A&M Transportation Institute apps (Landscape, TTI AI Studio, TTI Code, the TTI docs site, marcom WordPress kit) and now shipping as a Tauri desktop layer for Windows 11 / macOS Tahoe / Ubuntu, with Tauri Mobile (iOS / Android) on the near horizon. Components and tokens are domain-agnostic. The example data in showcase pages (project titles, status badges, form fields) is illustrative — intentionally spread across transportation-research domains so no single consuming app's identity leaks into the design system.
Current release: see CHANGELOG.md — consumers pin a
git tag (never a branch) · WCAG 2.2 AA conformance · color contrast
verified at AAA across all three themes (light, dark, high-contrast) ·
platform-adaptive at the chrome layer (web + Tauri desktop + Tauri mobile).
What's in here
- 140+ Tux* components + 6 composables (the exact census lives in
app/utils/tuxCatalog.ts, enforced against the filesystem bytests/tux-catalog.test.ts) underapp/components/andapp/composables/— alerts, badges, accordions, the editorial page header, chart family (line / bar / area / scatter / donut / gauge / geographic / sunburst / sparkline), research-publishing cluster (abstract / author byline / paper meta / footnote / citation export), TTI identity cluster (researcher / lab / program / funding source / center badge), geospatial cluster (map embed / legend / marker / corridor strip), forms wrapper cluster (form field / markdown editor / file dropzone / validation summary / confirm dialog), Tauri app-shell primitives (app frame / menu bar / splash screen / tab bar / FAB / focus view), the unified institutional footer, the doc-site sidebar + TOC, the prose wrapper for long-form markdown, table, tree, treemap, the keyboard-shortcut overlay, the edge-anchored slide-over, and the rest of the catalog. All demoed at/components/<kebab-name>(tightly-coupled clusters share a single route under/components/<family-name>). - Foundations — tokens, typography, motion, icons, the three
style variants. Pages under
/tokens,/typography, etc. - Composition examples — six real-shape pages showing the system in context: a Landscape dashboard, a research-program landing, a tti-ai-studio session, a research paper, a TTI center landing, and the sidebar shell.
- Tooling —
/contrast-auditrenders every contrast-risk surface in three themed columns side-by-side;/accessibilitycarries the formal conformance statement;scripts/audit-contrast.mjsis the puppeteer-based WCAG ratio checker that gates CI. - Framework-neutral kit —
kit/ships the generatedkit/css/tux-tokens.csstoken drop and the Bootstrap 4 re-skin for non-Vue consumers (WordPress, RIMS, BIMS, Forgejo overlays), CDN-served via jsDelivr at a pinned tag. Seekit/README.md. - Design docs — under
design/:tux.md(manifesto),unification-plan.md(the suite unification doctrine — one chrome, many voices),components.md(doctrine + pattern coverage map),compositions.md(composability doctrine),palette.md(visual identity),roadmap.md,chart-foundations.md,platform-awareness.md(Tauri / multi-platform doctrine),tauri-bindings.md(Tauri API surface per component),visual-language-evolution.md, plus the canonicaltokens.jsonsource and theapps.jsonTTI Portals registry. Twelve ADRs underdocs/adr/record architectural decisions.
Run it
npm install
npm run dev
# → http://localhost:3030
Every page under /components/* is a live demo rendered by the same
component your app imports. The header carries a light/dark toggle; the
footer's preferences strip carries the WCAG AAA high-contrast toggle.
New visitors should start at /getting-started for the onboarding
tour.
npm install also installs a husky pre-commit
hook (via the prepare script) that runs eslint --fix on staged
.vue/.ts/.js/.mjs files through lint-staged.
The same eslint . runs in CI; the hook catches issues before the push.
Themes
Three themes ship: tti (default light), tti-dark (warm-charcoal dark),
and tti-hc (WCAG AAA high-contrast). Toggle via the chrome controls or
set data-theme on <html>. New institutions theme by adding a
[data-theme="<name>"] block to app/assets/css/tokens.css
overriding only the --brand-* slots.
Platform-aware
tux is one component tree, platform-adaptive at the chrome layer. Web is the default render target; Tauri shells on Windows / macOS / Linux + Tauri Mobile each get correct titlebar controls, scrollbars, swipe gestures, safe-area handling, and keyboard glyphs through a small set of platform-aware primitives. The brand layer (typography, palette, motion vocabulary) stays invariant; the chrome layer adapts.
See design/platform-awareness.md for
the two-layer model and 8 dimensions of variation, and
design/tauri-bindings.md for which
components call which Tauri APIs.
Platform detection is via useTuxPlatform() —
a module-singleton that sets [data-platform] on <html> post-hydration.
Library-agnostic Tauri detection (globalThis.__TAURI_INTERNALS__); no
static @tauri-apps/api import, so the web build doesn't carry the
runtime weight.
Accessibility
- Target: WCAG 2.2 Level AA conformance for the design system.
- Color contrast: verified at WCAG 2.2 Level AAA (7:1 normal text, 4.5:1 large text) across all three themes. CI fails if any pair regresses.
- Motion: every animation respects
prefers-reduced-motion: reduceand collapses to instant (non-negotiable). Documented indesign/motion. - Touch + gesture: every swipe action has a visible alternative (keyboard or button) — swipe-only is a screen-reader trap.
- See
/accessibilityfor the formal statement, the per-criterion automated/manual coverage table, and the link to file an issue.
# Run the audit locally:
npm run generate
AUDIT_LEVEL=AAA npm run audit:contrast
Consuming from another app
The canonical install source is the Forgejo npm registry on
code.tti.tamu.edu — every vX.Y.Z tag publishes @tti/tti-ux
automatically. (The GitHub repo is a mirror whose only job is the
GitHub Pages deploy of ux.tti.tamu.edu; don't install from it.)
One-time setup in the consuming app (or your ~/.npmrc):
# .npmrc
@tti:registry=https://code.tti.tamu.edu/api/packages/tti/npm/
(If the repo/package isn't public to you, add
//code.tti.tamu.edu/api/packages/tti/npm/:_authToken=<your token>.)
Then depend on a pinned version and extend the layer:
npm install @tti/tti-ux@2.0.0
// nuxt.config.ts of the consuming app
export default defineNuxtConfig({
extends: ["@tti/tti-ux"],
});
Bumping the pinned version is how you opt in to a new tux release —
check CHANGELOG.md for what each version contains.
For local dev with a sibling checkout, swap to a file URL:
"@tti/tti-ux": "file:../tti-ux". A direct git pin also works on
the internal network:
"@tti/tti-ux": "git+https://code.tti.tamu.edu/tti/tti-ux.git#v2.0.0".
(Legacy consumers pinned to github:ttitamu/tti-ux#v1.x keep
working, but new pins should not use the mirror.)
Deploying behind a reverse proxy? Set icon: { mode: "svg" } in
your nuxt.config.ts. @nuxt/icon's default CSS-mask mode fetches
icon CSS through /api/* routes, which proxies commonly route
elsewhere — the failure mode is invisible 0×0 icon spans (ghost
buttons). Landscape hit exactly this behind Caddy; svg mode inlines
the icons and sidesteps the route entirely.
Either path pulls in app/components/, app/composables/,
app/assets/css/, and app/app.config.ts automatically — the consuming
app gets Tux* auto-imports, all composables (useTuxApps,
useTuxPlatform, useTuxSwipe, useTuxRipple, useTuxHighlighter,
useTuxMermaid) auto-imported, tokens loaded, Nuxt UI themed to maroon,
and access to
the markdown rendering pipeline (@nuxtjs/mdc with Shiki syntax
highlighting + KaTeX math).
Guardrails for consumers
The design-system audits ship with the package. The one every consumer
should run — zero extra dependencies, one CI line — is the
undefined-token audit (it catches the var(--surface-base) bug class,
where a consumer-invented token resolves to nothing and renders
transparent):
- run: npx tux-audit tokens app
Token definitions are harvested from both the tti-ux layer and your own
CSS, so canonical tokens always resolve and your local component knobs
still count. Target dirs via args or TUX_AUDIT_DIRS; declare your own
custom-property namespaces via TUX_AUDIT_EXTERNAL_PREFIXES.
tux-audit contrast / tux-audit a11y also exist but need your own
devDeps plus a generated site — puppeteer for contrast, jsdom + axe-core
for a11y — and they tell you exactly that if you run them unprepared.
Tags are immutable; consumers pin to a version and upgrade deliberately
by bumping the #vX.Y.Z ref. See CHANGELOG.md for what
each version contains.
Naming
Components are PascalCase on disk (TuxAlert.vue) to match Nuxt UI's
UAlert convention. In templates, use either form — Vue auto-imports
resolve both:
<TuxAlert variant="compliance" title="…" />
<tux-alert variant="compliance" title="…" />
Prefer the hyphenated form in showcase code samples; PascalCase in imports.
Project context
tti-ux is one of three concurrent products at TTI Networking & Information
Services: Landscape (sensitive-data classifier),
tti-ai-studio (LLM tooling for researchers), and this style guide itself.
The system supports all three plus an emerging marcom WordPress kit and
the Tauri desktop shells the consumer apps now ship as. See
design/tux.md for the full manifesto.
License
Apache 2.0 — matches Landscape and the other TAMUS/TTI open-source projects.
Dependencies
Dependencies
| ID | Version |
|---|---|
| @iconify-json/lucide | ^1.2.102 |
| @nuxt/a11y | ^1.0.0-alpha.1 |
| @nuxt/eslint | ^1.15.2 |
| @nuxt/icon | ^2.0.0 |
| @nuxt/image | ^2.0.0 |
| @nuxt/ui | ^4.6.1 |
| @nuxtjs/color-mode | ^4.0.0 |
| @nuxtjs/mdc | ^0.21.1 |
| @tailwindcss/vite | ^4.0.0 |
| @tanstack/vue-virtual | ^3.13.0 |
| @tiptap/extension-code-block-lowlight | ^3.22.4 |
| @tiptap/extension-image | ^3.22.4 |
| @tiptap/extension-link | ^3.22.4 |
| @tiptap/extension-placeholder | ^3.22.4 |
| @tiptap/extension-table | ^3.22.4 |
| @tiptap/extension-table-cell | ^3.22.4 |
| @tiptap/extension-table-header | ^3.22.4 |
| @tiptap/extension-table-row | ^3.22.4 |
| @tiptap/extension-task-item | ^3.22.4 |
| @tiptap/extension-task-list | ^3.22.4 |
| @tiptap/extension-typography | ^3.22.4 |
| @tiptap/extension-underline | ^3.22.4 |
| @tiptap/starter-kit | ^3.22.4 |
| katex | ^0.16.47 |
| lowlight | ^3.3.0 |
| mermaid | ^11.14.0 |
| nuxt | ^4.4.2 |
| rehype-katex | ^7.0.1 |
| remark-math | ^6.0.0 |
| shiki | ^4.0.2 |
| tailwindcss | ^4.0.0 |
| vue | ^3.5.32 |
| vue-router | ^5.0.0 |
Development dependencies
| ID | Version |
|---|---|
| @fontsource/jetbrains-mono | ^5.2.8 |
| @fontsource/open-sans | ^5.2.7 |
| @fontsource/oswald | ^5.2.8 |
| @fontsource/public-sans | ^5.2.7 |
| @fontsource/work-sans | ^5.2.8 |
| @nuxt/devtools | ^2.0.0 |
| @nuxt/test-utils | ^4.1.0 |
| @vue/language-core | ^3.3.3 |
| @vue/test-utils | ^2.4.11 |
| axe-core | ^4.11.3 |
| d3-geo | ^3.1.1 |
| husky | ^9.1.7 |
| jsdom | ^29.1.1 |
| lint-staged | ^17.0.5 |
| puppeteer | ^24.42.0 |
| serve-handler | ^6.1.7 |
| topojson-client | ^3.1.0 |
| topojson-server | ^3.0.1 |
| topojson-simplify | ^3.0.3 |
| typescript | ^5.7.0 |
| us-atlas | ^3.0.1 |
| vitest | ^4.1.10 |
| vue-tsc | ^3.3.3 |