Make it feel like you.
Neutral by default, with 15 ready-made themes. Each theme is one CSS file that sets every token for light and dark. No JavaScript.
Surface
--sprout-surfaceCanvas
--sprout-canvasPrimary
--sprout-primaryText
--sprout-textThemes
Each card below is themed on its own with data-sprout-theme. Pick a theme for the whole site from the header.
- Search…
- Search…
- Search…
- Search…
- Search…
- Search…
- Search…
- Search…
- Search…
- Search…
- Search…
- Search…
- Search…
- Search…
- Search…
- Search…
Use a theme
Import the theme file after Sprõut's styles. Then set the attribute on your document root. You can import more than one theme and switch the attribute at runtime.
@import "tailwindcss";
@import "@tulipfarm/sprout/styles.css";
@import "@tulipfarm/sprout/themes/claude.css";
/* On your document root: */
/* <html data-sprout-theme="claude"> */The default follows the system color preference. Set class="light"or class="dark" on your document root to choose explicitly.
Make your own
A theme is one file. Copy any theme, change the slug in its selectors, and edit the values. The font and radius apply in both modes. The colors come in a light block and a dark block. The dark block appears twice: once forclass="dark" and once for the system preference.
/* Claude: Warm paper and clay orange.
*
* One file is the whole theme: font, radius, and every color token for light
* and dark. Import it after "@tulipfarm/sprout/styles.css", then set
* data-sprout-theme="claude" on <html>, or on any element to theme only
* that subtree.
*/
@layer base {
[data-sprout-theme="claude"] {
--sprout-font: ui-serif, Georgia, "Times New Roman", serif;
--sprout-radius-control: 0.5rem;
--sprout-radius-panel: 0.875rem;
}
[data-sprout-theme="claude"],
.light[data-sprout-theme="claude"],
.light [data-sprout-theme="claude"] {
--sprout-canvas: #f5f4ed;
--sprout-surface: #faf9f5;
--sprout-hover: #efede9;
--sprout-active: #e7e6e1;
--sprout-text: #3d3929;
--sprout-muted: #6b6a64;
--sprout-line: #dedcd1;
--sprout-border: #9c998f;
--sprout-border-strong: #858277;
--sprout-input: #dcdad4;
--sprout-primary: #b9552f;
--sprout-primary-hover: #a34b29;
--sprout-primary-active: #904225;
--sprout-on-primary: #ffffff;
--sprout-focus: #b9552f;
--sprout-danger: #b32d34;
--sprout-danger-hover: #98252b;
--sprout-on-danger: #fff8f8;
--sprout-info: #1f5fb8;
--sprout-info-subtle: #ebf1fd;
--sprout-danger-subtle: #fdeeef;
--sprout-success: #1d6a37;
--sprout-success-subtle: #e8f4eb;
--sprout-warning: #8a4b08;
--sprout-warning-subtle: #fdf1dc;
--sprout-primary-subtle: color-mix(
in oklab,
var(--sprout-primary) 10%,
var(--sprout-surface)
);
--sprout-secondary: #edece7;
--sprout-overlay: rgb(18 18 18 / 0.35);
}
.dark[data-sprout-theme="claude"],
.dark [data-sprout-theme="claude"] {
--sprout-canvas: #262624;
--sprout-surface: #30302e;
--sprout-hover: #40403d;
--sprout-active: #4a4947;
--sprout-text: #f5f4ee;
--sprout-muted: #b7b5a9;
--sprout-line: #45443f;
--sprout-border: #898884;
--sprout-border-strong: #a2a29d;
--sprout-input: #575754;
--sprout-primary: #d97757;
--sprout-primary-hover: #de876b;
--sprout-primary-active: #e1957c;
--sprout-on-primary: #1f1e1d;
--sprout-focus: #d97757;
--sprout-danger: #ff9197;
--sprout-danger-hover: #ffadb1;
--sprout-on-danger: #3c1014;
--sprout-info: #8fb8f5;
--sprout-info-subtle: #1f2c45;
--sprout-danger-subtle: #3a2124;
--sprout-success: #82d29a;
--sprout-success-subtle: #1c3223;
--sprout-warning: #eec27e;
--sprout-warning-subtle: #34291b;
--sprout-primary-subtle: color-mix(
in oklab,
var(--sprout-primary) 16%,
var(--sprout-surface)
);
--sprout-secondary: #42423f;
--sprout-overlay: rgb(8 8 8 / 0.65);
}
@media (prefers-color-scheme: dark) {
:root:not(.light):not(.dark)[data-sprout-theme="claude"],
:root:not(.light):not(.dark) [data-sprout-theme="claude"] {
--sprout-canvas: #262624;
--sprout-surface: #30302e;
--sprout-hover: #40403d;
--sprout-active: #4a4947;
--sprout-text: #f5f4ee;
--sprout-muted: #b7b5a9;
--sprout-line: #45443f;
--sprout-border: #898884;
--sprout-border-strong: #a2a29d;
--sprout-input: #575754;
--sprout-primary: #d97757;
--sprout-primary-hover: #de876b;
--sprout-primary-active: #e1957c;
--sprout-on-primary: #1f1e1d;
--sprout-focus: #d97757;
--sprout-danger: #ff9197;
--sprout-danger-hover: #ffadb1;
--sprout-on-danger: #3c1014;
--sprout-info: #8fb8f5;
--sprout-info-subtle: #1f2c45;
--sprout-danger-subtle: #3a2124;
--sprout-success: #82d29a;
--sprout-success-subtle: #1c3223;
--sprout-warning: #eec27e;
--sprout-warning-subtle: #34291b;
--sprout-primary-subtle: color-mix(
in oklab,
var(--sprout-primary) 16%,
var(--sprout-surface)
);
--sprout-secondary: #42423f;
--sprout-overlay: rgb(8 8 8 / 0.65);
}
}
}Override in your stylesheet
Place overrides after imports. Use root variables for runtime theme values or Tailwind's @theme inline for utility mappings. Sprõut does not set global fonts or page styles.
@import "tailwindcss";
@import "@tulipfarm/sprout/styles.css";
:root {
--sprout-primary: #285b78;
--sprout-primary-hover: #204860;
--sprout-on-primary: #f6fbff;
--sprout-radius-control: 0.5rem;
--sprout-sidebar-width: 16rem;
--sprout-sidebar-mobile-width: 18rem;
--sprout-sidebar-icon-width: 3.5rem;
--sprout-font: "Your font", system-ui, sans-serif;
}
.dark {
--sprout-primary: #a3d2ec;
--sprout-primary-hover: #bee1f4;
--sprout-on-primary: #142c3a;
}Mobile drawers and theme scope
The mobile drawer and tooltips render in portals under the document body. Define your theme on the document root so it reaches overlays. For a theme limited to a subtree, put data-sprout-theme on that subtree and pass a container inside it to Sidebar through portalContainer.
Overlay layers use 40 for the backdrop, 50 for the drawer, and 60 for tooltips. Keep application chrome below those layers. Theme persistence and mode controls belong to your app; Sprõut has no theme provider.
Keep contrast intact
Change foreground and background pairs together. Verify text contrast, visible focus, and control borders in both light and dark modes after changing colors.