DocuGardenerDocs
DESIGN SYSTEM

Design System

Token reference, component primitives, and contribution rules for the DocuGardener UI. All values here are locked — do not hardcode colours, shadows, or radius values in components. Use only the tokens and primitives listed below.

Live preview: /ux-preview/design-system.html

Repo-level quick reference: docs/design-system.md

Colour Tokens

Defined in web/app/globals.css as CSS custom properties on :root and .dark. Never use raw hex values in components.

--backgroundPage / shell background
--foregroundPrimary text
--cardCard surface
--borderCard/input borders
--inputInput field borders
--primaryBrand accent — buttons, links
--mutedSubdued surface (headers, sidebars)
--muted-foregroundSecondary / helper text
--status-freshStatusChip: fresh (green / healthy)
--status-witheredStatusChip: withered (amber / degraded)
--status-brokenStatusChip: broken (red / critical)

Spacing & Radius Tokens

Token / classValueUse
.rounded-card0.75remAll Card components
--radius0.5remBase shadcn radius
.app-containermax-w-7xl + px-6/8Page content wrapper
.shadow-cardsubtle ring + drop-shadowDefault card shadow
.shadow-card-hoverelevated on hoverInteractive cards

StatusChip

File: web/components/ui/status-chip.tsx. Use StatusChip for all inline status indicators in card headers. Never replicate the chip with raw Tailwind classes — always use this primitive.

PRIMARYMain section header chips, active feature indicators
FRESHHealthy / live / active states
WITHEREDDegraded / warning / BYOK states
BROKENError / critical / failed states
NEUTRALInformational / passive labels

Usage

import { StatusChip } from "@/components/ui/status-chip"

// In a CardHeader:
<StatusChip variant="primary" label="REPOSITORIES" className="mb-2" />

DataTable

File: web/components/ui/data-table.tsx. Use for all data tables in dashboard pages. Provides dense padding, hover rows, and overflow scrolling. Never use raw <table> elements in dashboard code.

Usage

import {
  DataTable, DataTableHeader, DataTableBody,
  DataTableRow, DataTableHead, DataTableCell,
} from "@/components/ui/data-table"

<DataTable>
  <DataTableHeader>
    <DataTableRow>
      <DataTableHead>Name</DataTableHead>
      <DataTableHead>Status</DataTableHead>
    </DataTableRow>
  </DataTableHeader>
  <DataTableBody>
    {rows.map((row) => (
      <DataTableRow key={row.id}>
        <DataTableCell>{row.name}</DataTableCell>
        <DataTableCell>{row.status}</DataTableCell>
      </DataTableRow>
    ))}
  </DataTableBody>
</DataTable>

Override note

DataTable uses dense defaults (px-3 py-2 heads, px-3 py-2.5 cells). Pass an explicit className to override via tailwind-merge — e.g. className="px-6 py-3".

PageHeader

File: web/components/layout/PageHeader.tsx. Every dashboard page must open with PageHeader. Do not build custom page headers. Use the subtitle slot for the accent line above the title, and the children slot for stat cards.

Typography Classes

.type-section-headerSection HeaderCard titles, section labels
.type-bodyBody text for descriptions and prose.Card descriptions, paragraphs
.type-metadataMETADATALabels, overline text
.animate-entranceEntrance animationApply to cards; stagger with animationDelay

Rules (Non-Negotiable)

  • ·Use CSS custom property tokens — never raw hex or rgb values.
  • ·Use .rounded-card for all Card components — never override with arbitrary values.
  • ·Use StatusChip for all inline status labels in card headers.
  • ·Use DataTable for all data tables in dashboard pages — no raw <table>.
  • ·Use PageHeader for every dashboard page — no custom page headers.
  • ·Do not add border-l-8 for status colour coding — use StatusChip instead.
  • ·Shadows come from .shadow-card / .shadow-card-hover — no inline shadow utilities.