GitHub

Styles

Tailwind-first design tokens and theming for Trophy's Gamification UI Kit—semantic colors, typography, and spacing so gamification components stay on-brand. Part of a Tailwind + shadcn gamification stack.

Components in Trophy's Gamification UI Kit are themeable and unopinionated by default. Component styles are built on semantic tokens, not fixed palette classes, so they remain portable across customer design systems.

Core Standards

  • Components use semantic Tailwind aliases like bg-primary, text-muted-foreground, and border-border.
  • Semantic aliases are backed by CSS custom properties so users can theme globally.
  • Component defaults do not hardcode color palette classes (for example purple-500, orange-500, black/80).
  • Specific gamification color treatments stay behind tokens (rank-1, rank-2, rank-3) rather than fixed color values.
  • Every foreground token is paired with a matching -foreground token for accessibility and contrast control.

Token Groups We Use

  • Core surface tokens: background, foreground, card, popover, border, input, ring
  • Action tokens: primary, secondary, accent, destructive
  • Feedback tokens: success, warning, info
  • Gamification tokens: achievement, rank-1, rank-2, rank-3

Minimal Default Theme

This repository includes a copyable minimal theme starter at apps/www/content/themes/trophy-minimal-theme.css.

CSS
:root {
  --radius: 0.625rem;

  --background: oklch(1 0 0);
  --foreground: oklch(0.145 0 0);
  --card: oklch(1 0 0);
  --card-foreground: oklch(0.145 0 0);
  --popover: oklch(1 0 0);
  --popover-foreground: oklch(0.145 0 0);

  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  --secondary: oklch(0.97 0 0);
  --secondary-foreground: oklch(0.205 0 0);
  --muted: oklch(0.97 0 0);
  --muted-foreground: oklch(0.556 0 0);
  --accent: oklch(0.97 0 0);
  --accent-foreground: oklch(0.205 0 0);
  --destructive: oklch(0.577 0.245 27.325);
  --destructive-foreground: oklch(0.985 0 0);

  --border: oklch(0.922 0 0);
  --input: oklch(0.922 0 0);
  --ring: oklch(0.708 0 0);

  --success: oklch(0.64 0.18 145);
  --success-foreground: oklch(0.985 0 0);
  --warning: oklch(0.73 0.17 65);
  --warning-foreground: oklch(0.2 0.02 65);
  --info: oklch(0.63 0.16 250);
  --info-foreground: oklch(0.985 0 0);

  --rank-1: oklch(0.83 0.17 92);
  --rank-2: oklch(0.71 0.02 250);
  --rank-3: oklch(0.64 0.14 66);
}

.dark {
  --background: oklch(0.145 0 0);
  --foreground: oklch(0.985 0 0);
  --card: oklch(0.205 0 0);
  --card-foreground: oklch(0.985 0 0);
  --popover: oklch(0.269 0 0);
  --popover-foreground: oklch(0.985 0 0);

  --primary: oklch(0.922 0 0);
  --primary-foreground: oklch(0.205 0 0);
  --secondary: oklch(0.269 0 0);
  --secondary-foreground: oklch(0.985 0 0);
  --muted: oklch(0.269 0 0);
  --muted-foreground: oklch(0.708 0 0);
  --accent: oklch(0.371 0 0);
  --accent-foreground: oklch(0.985 0 0);
  --destructive: oklch(0.704 0.191 22.216);
  --destructive-foreground: oklch(0.205 0 0);

  --border: oklch(1 0 0 / 10%);
  --input: oklch(1 0 0 / 15%);
  --ring: oklch(0.556 0 0);

  --success: oklch(0.72 0.16 145);
  --success-foreground: oklch(0.2 0.02 145);
  --warning: oklch(0.8 0.16 75);
  --warning-foreground: oklch(0.22 0.02 75);
  --info: oklch(0.75 0.14 250);
  --info-foreground: oklch(0.2 0.03 250);

  --rank-1: oklch(0.86 0.16 92);
  --rank-2: oklch(0.78 0.02 250);
  --rank-3: oklch(0.75 0.12 66);
}