Getting Started

Introduction

The Smejkal Design System is a unified set of tokens, components, and conventions that keeps the admin dashboard and this documentation site visually consistent. It is built on Tailwind CSS v4, Radix UI primitives, class-variance-authority, and a token vocabulary that lives in @repo/ui.

Stack

Every layer of the system has a specific job. Tailwind v4 handles utility classes and the @theme inline bridge that turns CSS custom properties into utilities. Radix UI provides the accessible primitive behavior for interactive components. CVA manages variant logic so component APIs stay clean. Lucide React supplies all icons through a single consistent set.

LayerTechnologyPurpose
Styling engineTailwind CSS v4Utility classes, token bridge via @theme inline
PrimitivesRadix UIAccessible keyboard behavior, focus management, ARIA
Variant APIclass-variance-authority (CVA)Type-safe component variant definitions
Class mergingtailwind-merge + clsx via cn()Conflict-free class composition at runtime
Iconslucide-reactNamed icon imports, consistent stroke weight
Shared tokens@repo/ui/theme.cssSingle source of truth for all CSS custom properties
Shared components@repo/ui/src/components/Atom-level components consumed by all apps

Key principles

Token-driven

Every color, radius, and shadow is a CSS custom property. Apps import the shared @repo/ui/theme.css token file and expose each token as a Tailwind utility via @theme inline in their own globals.css. Changing a design decision in one place propagates to every app automatically.

Dark-first

Both the admin app and this docs site apply class="dark" to the HTML element. The token system defines light mode values in :root and dark overrides under the .dark selector. Dark is the default; light mode support is available whenever it is needed.

Accessible by default

All interactive components are built on Radix UI primitives, which provide keyboard navigation, focus trap management, and correct ARIA attributes out of the box. Focus rings use the brand green at 40% opacity so they are visible without being distracting.

Composable

Atom components live in @repo/ui/src/components/ and are imported through the workspace path alias @repo/ui/components/[name]. Page-level patterns — data tables, confirmation dialogs, action bars — are composed from atoms inside each app rather than being baked into the shared package.

Package structure

The monorepo is a Turborepo + pnpm workspace. Design system concerns are spread across three packages:

PackageContents
@repo/uiShared components, theme.css token file, cn() utility, CVA helpers
@repo/typesShared TypeScript interfaces (Supabase row types, component prop types)
@repo/configShared ESLint, TypeScript, and Tailwind configuration presets

Each app — apps/web, apps/admin, and apps/docs — installs the workspace packages and adds its ownglobals.css with app-specific @theme inlineoverrides where needed.

How to use this documentation

The sections in the left sidebar follow the order you would encounter each layer when building a new feature: start with accessibility constraints, then choose colors from the token vocabulary, follow writing conventions for copy, use icons consistently, understand the Tailwind utility mapping, grasp the theming architecture, and finally apply the typography system for long-form content.

This design system is intentionally opinionated. When in doubt, prefer the token over a hard-coded value, prefer an existing component over a one-off, and prefer the established naming convention over a new one.