DGit UI › Components
Theme
Neutral gray scale (light and dark), shadcn's color names on it, type scale, menu animation. Import after Tailwind.
Install
npx shadcn add @dgit/themeFirst time? Add the registry to components.json: see Get started.
dgit.css
/*
* DGit UI theme. Import it after Tailwind in the app's main CSS:
*
* @import "tailwindcss";
* @import "./dgit.css";
*
* Two layers of names, one source of color:
* - a neutral gray scale (gray-100…gray-1000, background-100/200, gray-alpha-100…600) in the
* Geist style: values from the Geist design language as measured on vercel.com, 2026-09-21;
* - shadcn's semantic names (background, foreground, muted, border, …) pointed at that scale,
* so stock shadcn components match.
*
* Theme: `<html data-theme="light|dark">` picks one (lib/theme.ts sets it); without the attribute
* the system setting decides. Fonts aren't loaded here: load Geist and Geist Mono (the `geist`
* npm package or Google Fonts), and Pretendard for Korean if needed.
*/
:root {
color-scheme: light dark;
--dgit-gray-100: 0, 0%, 95%;
--dgit-gray-200: 0, 0%, 92%;
--dgit-gray-300: 0, 0%, 90%;
--dgit-gray-400: 0, 0%, 92%;
--dgit-gray-500: 0, 0%, 79%;
--dgit-gray-600: 0, 0%, 66%;
--dgit-gray-700: 0, 0%, 56%;
--dgit-gray-800: 0, 0%, 49%;
--dgit-gray-900: 0, 0%, 30%;
--dgit-gray-1000: 0, 0%, 9%;
--dgit-background-100: 0, 0%, 100%;
--dgit-background-200: 0, 0%, 98%;
--dgit-gray-alpha-100: #0000000d;
--dgit-gray-alpha-200: #00000014;
--dgit-gray-alpha-300: #0000001a;
--dgit-gray-alpha-400: #00000014;
--dgit-gray-alpha-500: #00000036;
--dgit-gray-alpha-600: #00000057;
--dgit-blue: oklch(57.61% 0.2508 258.23);
--dgit-green: oklch(51.75% 0.1453 147.65);
--dgit-green-bg: oklch(96.92% 0.037 147.15);
--dgit-amber: oklch(52.79% 0.1496 54.65);
--dgit-amber-bg: oklch(96.81% 0.0495 90.2423);
--dgit-red: oklch(54.99% 0.232 25.29);
--dgit-red-bg: oklch(95.41% 0.0299 14.2526);
/* A card that sits on the page: 1px edge, a 2px drop, a ring in the page color. */
--dgit-shadow-card: 0 0 0 1px rgba(0, 0, 0, 0.08), 0 2px 2px 0 rgba(0, 0, 0, 0.04), 0 0 0 1px hsla(var(--dgit-background-200), 1);
/* A floating panel (menus, popovers). */
--dgit-shadow-menu:
0 0 0 1px rgba(0, 0, 0, 0.08), 0 1px 1px 0 rgba(0, 0, 0, 0.02), 0 8px 16px -4px rgba(0, 0, 0, 0.04),
0 24px 32px -8px rgba(0, 0, 0, 0.06), 0 0 0 1px hsla(var(--dgit-background-200), 1);
--radius: 0.875rem;
}
/* Light or dark, chosen explicitly… */
:root[data-theme="light"] {
color-scheme: light;
}
:root[data-theme="dark"] {
color-scheme: dark;
--dgit-gray-100: 0, 0%, 10%;
--dgit-gray-200: 0, 0%, 12%;
--dgit-gray-300: 0, 0%, 16%;
--dgit-gray-400: 0, 0%, 18%;
--dgit-gray-500: 0, 0%, 27%;
--dgit-gray-600: 0, 0%, 53%;
--dgit-gray-700: 0, 0%, 56%;
--dgit-gray-800: 0, 0%, 49%;
--dgit-gray-900: 0, 0%, 63%;
--dgit-gray-1000: 0, 0%, 93%;
--dgit-background-100: 0, 0%, 4%;
--dgit-background-200: 0, 0%, 0%;
--dgit-gray-alpha-100: #ffffff0f;
--dgit-gray-alpha-200: #ffffff17;
--dgit-gray-alpha-300: #ffffff21;
--dgit-gray-alpha-400: #ffffff24;
--dgit-gray-alpha-500: #ffffff3d;
--dgit-gray-alpha-600: #ffffff82;
--dgit-green: oklch(73.1% 0.19 150);
--dgit-green-bg: oklch(25% 0.05 150);
--dgit-amber: oklch(82% 0.15 80);
--dgit-amber-bg: oklch(24% 0.04 75);
--dgit-red: oklch(70% 0.19 22);
--dgit-red-bg: oklch(25% 0.05 20);
--dgit-shadow-card: 0 0 0 1px var(--dgit-gray-alpha-400), 0 2px 2px 0 rgba(0, 0, 0, 0.16);
--dgit-shadow-menu: 0 0 0 1px var(--dgit-gray-alpha-400), 0 8px 16px -4px rgba(0, 0, 0, 0.32), 0 24px 32px -8px rgba(0, 0, 0, 0.4);
}
/* …or by the system when nothing was chosen (same values as above). */
@media (prefers-color-scheme: dark) {
:root:not([data-theme]) {
--dgit-gray-100: 0, 0%, 10%;
--dgit-gray-200: 0, 0%, 12%;
--dgit-gray-300: 0, 0%, 16%;
--dgit-gray-400: 0, 0%, 18%;
--dgit-gray-500: 0, 0%, 27%;
--dgit-gray-600: 0, 0%, 53%;
--dgit-gray-700: 0, 0%, 56%;
--dgit-gray-800: 0, 0%, 49%;
--dgit-gray-900: 0, 0%, 63%;
--dgit-gray-1000: 0, 0%, 93%;
--dgit-background-100: 0, 0%, 4%;
--dgit-background-200: 0, 0%, 0%;
--dgit-gray-alpha-100: #ffffff0f;
--dgit-gray-alpha-200: #ffffff17;
--dgit-gray-alpha-300: #ffffff21;
--dgit-gray-alpha-400: #ffffff24;
--dgit-gray-alpha-500: #ffffff3d;
--dgit-gray-alpha-600: #ffffff82;
--dgit-green: oklch(73.1% 0.19 150);
--dgit-green-bg: oklch(25% 0.05 150);
--dgit-amber: oklch(82% 0.15 80);
--dgit-amber-bg: oklch(24% 0.04 75);
--dgit-red: oklch(70% 0.19 22);
--dgit-red-bg: oklch(25% 0.05 20);
--dgit-shadow-card: 0 0 0 1px var(--dgit-gray-alpha-400), 0 2px 2px 0 rgba(0, 0, 0, 0.16);
--dgit-shadow-menu: 0 0 0 1px var(--dgit-gray-alpha-400), 0 8px 16px -4px rgba(0, 0, 0, 0.32), 0 24px 32px -8px rgba(0, 0, 0, 0.4);
}
}
/* shadcn's names, on the scale above. */
:root {
--background: hsla(var(--dgit-background-100), 1);
--foreground: hsla(var(--dgit-gray-1000), 1);
--card: hsla(var(--dgit-background-100), 1);
--card-foreground: hsla(var(--dgit-gray-1000), 1);
--popover: hsla(var(--dgit-background-100), 1);
--popover-foreground: hsla(var(--dgit-gray-1000), 1);
--primary: hsla(var(--dgit-gray-1000), 1);
--primary-foreground: hsla(var(--dgit-background-100), 1);
--secondary: hsla(var(--dgit-gray-100), 1);
--secondary-foreground: hsla(var(--dgit-gray-1000), 1);
--muted: hsla(var(--dgit-gray-100), 1);
--muted-foreground: hsla(var(--dgit-gray-900), 1);
--accent: hsla(var(--dgit-gray-100), 1);
--accent-foreground: hsla(var(--dgit-gray-1000), 1);
--destructive: var(--dgit-red);
--border: hsla(var(--dgit-gray-300), 1);
--input: hsla(var(--dgit-gray-300), 1);
--ring: hsla(var(--dgit-gray-1000), 1);
--warn: var(--dgit-amber);
--warn-bg: var(--dgit-amber-bg);
--ok: var(--dgit-green);
}
@theme inline {
--font-sans: "Geist", "Geist Sans", "Pretendard", ui-sans-serif, system-ui, -apple-system, "Segoe UI", "Apple SD Gothic Neo", sans-serif;
--font-mono: "Geist Mono", ui-monospace, "SF Mono", Menlo, monospace, "Pretendard";
--radius-sm: calc(var(--radius) - 6px);
--radius-md: calc(var(--radius) - 4px);
--radius-lg: var(--radius);
--radius-xl: calc(var(--radius) + 4px);
--color-background: var(--background);
--color-foreground: var(--foreground);
--color-card: var(--card);
--color-card-foreground: var(--card-foreground);
--color-popover: var(--popover);
--color-popover-foreground: var(--popover-foreground);
--color-primary: var(--primary);
--color-primary-foreground: var(--primary-foreground);
--color-secondary: var(--secondary);
--color-secondary-foreground: var(--secondary-foreground);
--color-muted: var(--muted);
--color-muted-foreground: var(--muted-foreground);
--color-accent: var(--accent);
--color-accent-foreground: var(--accent-foreground);
--color-destructive: var(--destructive);
--color-border: var(--border);
--color-input: var(--input);
--color-ring: var(--ring);
--color-warn: var(--warn);
--color-warn-bg: var(--warn-bg);
--color-ok: var(--ok);
/* The gray scale by name: hover:bg-gray-100, text-gray-900, bg-background-200, … */
--color-gray-100: hsla(var(--dgit-gray-100), 1);
--color-gray-200: hsla(var(--dgit-gray-200), 1);
--color-gray-300: hsla(var(--dgit-gray-300), 1);
--color-gray-400: hsla(var(--dgit-gray-400), 1);
--color-gray-500: hsla(var(--dgit-gray-500), 1);
--color-gray-600: hsla(var(--dgit-gray-600), 1);
--color-gray-700: hsla(var(--dgit-gray-700), 1);
--color-gray-800: hsla(var(--dgit-gray-800), 1);
--color-gray-900: hsla(var(--dgit-gray-900), 1);
--color-gray-1000: hsla(var(--dgit-gray-1000), 1);
--color-background-100: hsla(var(--dgit-background-100), 1);
--color-background-200: hsla(var(--dgit-background-200), 1);
--color-gray-alpha-100: var(--dgit-gray-alpha-100);
--color-gray-alpha-200: var(--dgit-gray-alpha-200);
--color-gray-alpha-300: var(--dgit-gray-alpha-300);
--color-gray-alpha-400: var(--dgit-gray-alpha-400);
--color-gray-alpha-500: var(--dgit-gray-alpha-500);
--color-gray-alpha-600: var(--dgit-gray-alpha-600);
--shadow-card: var(--dgit-shadow-card);
--shadow-menu: var(--dgit-shadow-menu);
/* Type scale: heading (600, tight), label and copy (400), button (500). */
--text-heading-14: 14px;
--text-heading-14--line-height: 20px;
--text-heading-14--letter-spacing: -0.28px;
--text-heading-14--font-weight: 600;
--text-heading-16: 16px;
--text-heading-16--line-height: 24px;
--text-heading-16--letter-spacing: -0.32px;
--text-heading-16--font-weight: 600;
--text-heading-20: 20px;
--text-heading-20--line-height: 26px;
--text-heading-20--letter-spacing: -0.4px;
--text-heading-20--font-weight: 600;
--text-heading-24: 24px;
--text-heading-24--line-height: 32px;
--text-heading-24--letter-spacing: -0.96px;
--text-heading-24--font-weight: 600;
--text-heading-30: 30px;
--text-heading-30--line-height: 36px;
--text-heading-30--letter-spacing: -0.75px;
--text-heading-30--font-weight: 500;
--text-label-12: 12px;
--text-label-12--line-height: 16px;
--text-label-13: 13px;
--text-label-13--line-height: 18px;
--text-label-14: 14px;
--text-label-14--line-height: 20px;
--text-copy-13: 13px;
--text-copy-13--line-height: 18px;
--text-copy-14: 14px;
--text-copy-14--line-height: 20px;
--text-copy-15: 15px;
--text-copy-15--line-height: 22px;
--text-button-14: 14px;
--text-button-14--line-height: 20px;
--text-button-14--font-weight: 500;
}
@layer base {
* {
@apply border-border outline-ring/50;
}
html,
body {
@apply bg-background text-foreground font-sans;
}
body {
font-size: 15px;
line-height: 1.5;
-webkit-font-smoothing: antialiased;
}
}
/* Menus grow from where they were opened: 120 ms, just long enough to follow. */
@keyframes dgit-menu-in {
from {
opacity: 0;
transform: scale(0.96);
}
to {
opacity: 1;
transform: scale(1);
}
}
@utility animate-menu {
animation: dgit-menu-in 120ms ease-out;
}
@media (prefers-reduced-motion: reduce) {
.animate-menu {
animation: none;
}
}