Skip to content
sign in

==> read the decisions

ADR-0017: One look: the Tailwind theme and the components are shared

Status: Accepted (2026-10-14). Amends ADR-0004: a project's shadow root carries the shared theme and components. Implemented 2026-10-15. Amended by ADR-0025: the bar has one arrangement, no inline/stacked.

The app styles its controls with Tailwind and shadcn; a project styles its own, by hand, inside a shadow root the page's CSS cannot reach. They have drifted: buttons with different font weights, inputs of different heights. The fix is not new class names for what Tailwind already names -- it is that both sides render the same components from the same theme.

  • The theme lives once, in the shared library: a Tailwind v4 @theme block with standard Tailwind names -- font families and weights, the type scale, control heights, radii, spacing, borders, the focus ring -- whose colours point at the CDN theme variables, so a hemospectrum theme still changes everything.
  • The components live once: shadcn's Button, Input, Card, Label and their siblings move from the app into the shared library (@cs/ui), still our own .tsx, still standard Tailwind classes.
  • The app and every project import the same components. The app's build and the user build both run Tailwind over their sources against the shared theme; a project's compiled CSS -- only the classes it uses -- is adopted into its shadow root by defineProjectElement.
  • User code does not style controls. Hand-styled buttons and inputs are replaced by @cs/ui components when the repos are ported, and a lint rule flags new ones.
  • A change to a control's look is one edit, seen by the platform and every project.
  • Each project bundle carries its own small compiled CSS; Tailwind emits only what is used.
  • shared/lib/ui.tsx's hand-written BASE_CSS is replaced by the theme.