All docs

Principles

Guardrails that keep the system coherent as it grows. Follow these when you extend the library or build application UIs on top of it.

  1. 01

    Stay with shadcn defaults

    The library does not invent new tokens, components, or conventions. Where SE UI differs from stock shadcn Base UI Vega, it's a deliberate override that's explicitly documented. The four existing overrides (input, select, textarea, and the outline button variant, all using bg-card) are the only approved ones in v1.

  2. 02

    Primary is for interactive UI only

    Buttons, focus rings, selected states, progress indicators. Not for body text and not for inline links. Body text uses --foreground, which always has maximum contrast against --background. This matches shadcn's default behaviour and keeps the contrast story simple.

  3. 03

    WCAG AA is the target

    UI primaries must pass 4.5:1 with white text. Brand marketing colours that fail AA are adapted into UI primaries that pass. Body text and destructive warnings hit AAA by default because they use --foreground/--background. The untouched marketing colour is preserved in --brand-primary for logos and brand-marketing surfaces where the adapted --primary would dull the identity.

  4. 04

    Sentence case for titles and headings

    "Component library", not "Component Library". Applies across the app, the docs, and every component name.

  5. 05

    Semantic colours are locked across brands

    Destructive is red, success is green, warning is amber, info is blue. These values do not change per brand.

  6. 06

    Single radius scale per app

    Pick one --radius value. --radius-sm, --radius-md, --radius-lg, and --radius-xl all derive from it.

  7. 07

    Dogfooding

    The app uses @smaller-earth/ui as its component library. Smaller Earth is the default theme; switching brands in the top bar re-themes the entire app, which is how we verify the system works end-to-end.

  8. 08

    Local vs library components

    If a component is used in more than one SE app, it belongs in @smaller-earth/ui. If it only exists in one app, it stays in that app's components/. Don't speculatively promote components.

  9. 09

    Components are primitives, Blocks are patterns

    Components are atomic, unopinionated, generic. They live in the library, updates flow to every consumer, and adding one is rare because shadcn covers most primitives. Blocks are compositions like login forms, settings panels, stats cards. They make layout and copy decisions, live as copy-paste in the docs, and each consuming app owns its copy. Resist promoting blocks into components: if two apps need the same block shaped slightly differently, that's blocks working correctly, not a signal to promote. Do promote when a sub-primitive inside multiple blocks repeats (a "status row with icon, label, timestamp"), not when the block itself does.