LowkeyUI Living Styleguide — Design

Date: 2026-06-10 Branch: lowkey-styleguide-and-fixes (continues styleguide-lowkey; based on fix/lowkey-rollout-bugfixes + master merge). One PR carries the styleguide and any component fixes we decide to make as sections get reviewed.

Problem

An AI-generated reference doc (__drops/lowkey-components.html) attempted to catalog all lowkeyui components, but it hand-copies styles and invents class names (lkf-btn-* instead of the real kp-button-*), and several values are hallucinated (e.g. it claims primary button hover is stone-800; the real style is hover:bg-sky-950, app/src/app.css:283). Any doc that copies styles drifts and teaches AI sessions the wrong vocabulary.

Goals

  1. A benchmark that 100% represents platform components — look and behavior — by construction, not by transcription.
  2. A visual reference devs can use to check AI-generated designs against the real thing.
  3. Steer future AI sessions to the real sources (app/src/app.css .lowkey/.lowkey-forms blocks, app/src/ui/*.jsx, app/src/ui/shadcn/*, tailwind.config.js) instead of copying from any reference doc.

Deliverables

1. Live styleguide page (canonical)

  • Route: /styleguide, registered top-level in app/src/routes.jsx, lazy-loaded, dev-only (import.meta.env.DEV) so it never ships in production builds.
  • Location: app/src/pages-builder/styleguide/ (page + one small Section helper).
  • Access: https://local.kualibuild.com:<4000+index>/styleguide (e.g. :4001 for container a1). No proxy changes needed — caddy's final catch-all already forwards unmatched paths to builder-ui, and the dev server serves the SPA for unknown paths.
  • Content: numbered sections, one per component. Each section renders:
    • the real component, imported from app/src/ui/... / app/src/ui/shadcn/..., or real kp-* markup inside .lowkey / .lowkey-forms wrappers — never copied CSS;
    • every variant and state (default, hover where forceable, focus, disabled, error, checked, indeterminate, open/closed, loading…). States that normally require interaction are also rendered statically (e.g. dropdown shown open) so the HTML snapshot captures them;
    • a copyable code line: the import statement or the class names;
    • a Source of truth pointer: file path (+ line for app.css rules), e.g. app.css:282 (.lowkey .kp-button-primary), ui/checkbox.jsx.
  • Header banner addressed to AI sessions and devs: do not copy styles from this page; import these components or use these class names; per-section sources below.

2. HTML snapshot (portable)

  • Script: scripts/export-styleguide.mjs. Loads /styleguide in headless Chromium (Playwright), inlines the compiled stylesheets, and writes a self-contained lowkey-components.html to __drops/ (path configurable via CLI arg).
  • The snapshot is visually identical to the live page because it carries the real compiled CSS — hover/focus/disabled still work (they're CSS); JS interactions don't, which is why every interactive state is also rendered statically (see above).
  • Banner notes: generated date, source commit, the live route, and "regenerate with node scripts/export-styleguide.mjs". Replaces the hallucinated file.

3. Discoverability

  • Add a short pointer in builder-ui CLAUDE.md / AGENTS.md: where the styleguide route is, what it's for, and that app.css + ui/ are the source of truth for lowkey styles.

Component inventory

Seed (from the old HTML doc)

The 44 sections of the old HTML doc (buttons ×12, inputs, textarea, select, input group, checkbox, radio, label, field view, rich text view, section card, table, badges, chip, tabs, tooltip, popover/menu, modal, side panel, sticky header, action bar, compare-changes popup, spinner, skeleton, alert, toast, banner, avatar, workflow step pill, pulse badge, drag handle, datepicker, document list row).

Discovery sweep (find what the old doc missed)

Before the 1-by-1 build starts, run a systematic sweep for lowkey components that never made it into the HTML doc, and append findings to the inventory:

  • every kp-* class styled under .lowkey / .lowkey-forms in app/src/app.css;
  • every component in app/src/ui/ and app/src/ui/shadcn/ (known so far: toggle, segmented-control, lookup, info-box, config-box, pop-up, indeterminate-checkbox, shadcn sheet, sidebar, skeleton, separator, dropdown-menu, popover);
  • usages of the lowkey Tailwind variant (lowkey: prefix) and .lowkey-scoped classNames in JSX, to catch components styled inline rather than via app.css.

Layouts (atoms → pages)

The styleguide also documents the platform's page-level layout patterns — at minimum the 1-panel, 2-panel, and 3-panel layouts used across builder/runner screens — rendered as scaled-down live examples with the real layout components/classes and source pointers, so new screens start from the right skeleton.

Molecules (compositions)

Beyond single components, include common compositions assembled from the real atoms:

  • modal/dialog with a field form and footer actions (confirm, destructive confirm);
  • card/section containing labeled fields (view mode and edit mode);
  • table with mixed gadget cells;
  • search/filter bar (input group + dropdown + button);
  • others surfaced during discovery where the platform repeats a pattern.

The inventory is finalized during the build: each candidate is checked against the codebase; pure hallucinations are dropped, real components missing from the seed are added.

Build & verification process (1-by-1)

Phase 0 is the discovery sweep above, which finalizes the candidate inventory. Then, for each component, in order, starting with buttons:

  1. Locate the real definition (app.css rule / ui/*.jsx) and at least one real usage in the app.
  2. Build the styleguide section from real imports/markup.
  3. Verify in the running dev environment (a1 container) with Playwright: screenshot the styleguide section and the component on a real platform screen; compare; fix discrepancies.
  4. User eyeballs the section at https://local.kualibuild.com:4001/styleguide and approves.
  5. Next component. Commit per component or small group.

The snapshot script is built early (after the first 2–3 sections exist) so export stays verified throughout, then re-run at the end.

Error handling / edge cases

  • Dev-only gate: the route module must not be imported at all in prod builds (guard the route registration, not just the render), so no bundle bloat and no accidental exposure.
  • Auth: the route lives inside the normal app shell; viewing requires the usual local login. Acceptable — devs are logged in anyway.
  • Components requiring data/context (lookup, datepicker, workflow tracker): mount with minimal mock props inside the page; never hit real APIs. If a component can't render without heavy context, show its static states and note the limitation in the section.
  • .lowkey scoping: the page wraps content in .lowkey / .lowkey-forms (and formbot-gadget / formbot-config wrappers where the cascade requires them — several rules only match inside those, e.g. .lowkey-forms .formbot-gadget .kp-input).

Testing

  • Playwright screenshot comparison during the build (process above).
  • A unit-level render smoke test (same runner as existing __tests__ suites) asserting the styleguide page mounts without error, so refactors that break imports fail fast.

Out of scope

  • Restyling or fixing any platform component Scope change (2026-06-10): component fixes ARE in scope — when section review surfaces a real component bug or inconsistency, we fix it on this branch with the user's approval, and it rides the same PR as the styleguide. Each fix gets its own commit, separate from styleguide-section commits.
  • Production styleguide hosting, Figma sync, icon catalog (the icons guide already exists).
  • Updating the orphaned lowkeyui-redesign-guidelines.mdx beyond a pointer to the new page.