Royal Court — a shadcn/ui theme for Tailwind v4
Deep purple and gold — a luxury theme for premium services.
Royal Court pairs a regal purple primary with a restrained gold accent, on neutrals warmed toward the purple so the whole page feels upholstered rather than corporate. It belongs to concierge services, boutique hotels, and premium subscription products.
The Luxury Brand pairing sets a high-contrast display serif over a quiet sans body, and the type scale is a golden ratio so headlines command the page. Deeper shadows give cards a sense of weight that a lighter theme would not want.
The eight color roles
Every shadcn/ui variable in the export derives from these eight. The dark values are not a second theme: they are the light roles with lightness moved, hue and saturation held, and each pair repaired until it meets its WCAG threshold.
| Role | Light | Dark |
|---|---|---|
| primary | #1a1829 | #817bb2 |
| secondary | #3b205e | #986fce |
| accent | #6a2a82 | #af61cc |
| background | #fdfbf7 | #211808 |
| surface | #f9f3e7 | #35280d |
| text | #221c11 | #f8f6f1 |
| muted | #8e7c57 | #3c3425 |
| border | #e8e3d9 | #736445 |
Typography
DM Serif Display for headings, DM Sans for body copy and ui-monospace for code, on a 16px base with a 1.618 modular ratio.
Shape and elevation
A 0.25rem base radius derives the --radius-sm/md/lg/xl steps; the base shadow derives the four-step elevation scale.
Extended tokens
Foregrounds, destructive, a five-step chart ramp and the sidebar set are derived from the roles — exactly the variables a Tailwind v4 shadcn/ui project reads.
The exported globals.css
This is the stylesheet the generator downloads for this preset — a Tailwind v4 @theme block that any shadcn/ui project can replace its own app/globals.css with. Open the preset in the generator to change anything, preview it on a full landing page, and add the derived .dark block or the W3C design-tokens export.
/* Royal Court — Tailwind v4 theme (generated from the styling step) */
@import "tailwindcss";
@theme {
--color-primary: #1a1829;
--color-secondary: #3b205e;
--color-accent: #6a2a82;
--color-background: #fdfbf7;
--color-surface: #f9f3e7;
--color-text: #221c11;
--color-muted: #8e7c57;
--color-border: #e8e3d9;
--color-primary-foreground: #fdfbf7;
--color-secondary-foreground: #221c11;
--color-accent-foreground: #221c11;
--color-destructive: oklch(0.577 0.245 27.325);
--color-chart-1: #1a1829;
--color-chart-2: #3b205e;
--color-chart-3: #6a2a82;
--color-chart-4: #8e7c57;
--color-chart-5: #e8e3d9;
--color-sidebar: #f9f3e7;
--color-sidebar-foreground: #221c11;
--color-sidebar-primary: #1a1829;
--color-sidebar-primary-foreground: #fdfbf7;
--color-sidebar-accent: #6a2a82;
--color-sidebar-accent-foreground: #221c11;
--color-sidebar-border: #e8e3d9;
--color-sidebar-ring: #1a1829;
--font-heading: 'DM Serif Display', Georgia, serif;
--font-body: 'DM Sans', 'Segoe UI', sans-serif;
--font-mono: ui-monospace, SFMono-Regular, monospace;
--radius-sm: calc(0.25rem * 0.5);
--radius-md: 0.25rem;
--radius-lg: calc(0.25rem * 1.5);
--radius-xl: calc(0.25rem * 2);
--text-xs: 0.375rem;
--text-sm: 0.625rem;
--text-base: 1rem;
--text-lg: 1.625rem;
--text-xl: 2.625rem;
--text-2xl: 4.25rem;
--text-3xl: 6.84375rem;
--text-4xl: 11.09375rem;
--shadow-sm: 0 6.667px 10px -2px rgba(0, 0, 0, 0.1), 0 2.667px 4px -1.333px rgba(0, 0, 0, 0.05);
--shadow-md: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
--shadow-lg: 0 15px 22.5px -4.5px rgba(0, 0, 0, 0.1), 0 6px 9px -3px rgba(0, 0, 0, 0.05);
--shadow-xl: 0 22.5px 33.75px -6.75px rgba(0, 0, 0, 0.1), 0 9px 13.5px -4.5px rgba(0, 0, 0, 0.05);
--scrollbar-size: 10px;
--scrollbar-radius: 999px;
--scrollbar-track: transparent;
--scrollbar-thumb: #e8e3d9;
--scrollbar-thumb-hover: #1a1829;
--scrollbar-thumb-border: #fdfbf7;
--animate-marquee: marquee 25s linear infinite;
}
@keyframes marquee { from { transform: translateX(0); } to { transform: translateX(-50%); } }
@layer base {
:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.dark { color-scheme: dark; }
html {
scrollbar-width: thin;
scrollbar-color: var(--scrollbar-thumb) var(--scrollbar-track);
}
*::-webkit-scrollbar { width: var(--scrollbar-size); height: var(--scrollbar-size); }
*::-webkit-scrollbar-track { background: var(--scrollbar-track); }
*::-webkit-scrollbar-thumb {
background-color: var(--scrollbar-thumb);
border-radius: var(--scrollbar-radius);
border: 2px solid var(--scrollbar-thumb-border);
}
*::-webkit-scrollbar-thumb:hover { background-color: var(--scrollbar-thumb-hover); }
*::-webkit-scrollbar-corner { background: var(--scrollbar-track); }
@media (prefers-reduced-motion: reduce) {
*, *::before, *::after {
animation-duration: 0.01ms !important;
animation-iteration-count: 1 !important;
transition-duration: 0.01ms !important;
}
}
}
/* Generated with Nodlume — https://nodlume.dev/theme-generator/royal-court */
Make it yours
A preset is a starting point, not a decision. The shadcn/ui theme generator opens this one with every control live — swap the palette, try another of the 67 font pairings, tune the radius — and exports the result. For the thinking behind the roles, read how to build a semantic UI color palette; for how the whole system is generated, read generating custom themes.
Open in the theme generator