Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.refactkit.com/llms.txt

Use this file to discover all available pages before exploring further.

RefactKit’s design system is built on three layers: Base UI primitives for accessible component behavior, Tailwind CSS v4 for utility-class styling, and a Shadcn theme layer that maps semantic CSS custom properties to Tailwind color tokens. Because all color and typography values flow through CSS variables, you can change the entire visual identity of your app by swapping a single theme preset — without touching any component code.

How the theme layer works

src/styles/globals.css defines two sets of CSS custom properties: one on :root for the light theme and one on .dark for the dark theme. Tailwind’s @theme block then maps those variables to utility classes:
src/styles/globals.css
@theme {
  --color-primary:            var(--primary);
  --color-primary-foreground: var(--primary-foreground);
  --color-muted:              var(--muted);
  --color-muted-foreground:   var(--muted-foreground);
  --color-background:         var(--background);
  --color-foreground:         var(--foreground);
  /* ...and so on for every token */
}

:root {
  --primary: oklch(0.205 0 0);
  --primary-foreground: oklch(0.985 0 0);
  /* light-mode values */
}

.dark {
  --primary: oklch(0.922 0 0);
  --primary-foreground: oklch(0.205 0 0);
  /* dark-mode values */
}
Changing a --primary value in :root and .dark automatically updates every component that uses bg-primary, text-primary, or border-primary across the entire app.

Semantic color tokens

Semantic tokens are theme-safe by design. A component using bg-primary looks correct in every theme preset and in both light and dark mode, because the token resolves to the right value automatically. A hardcoded class like bg-blue-500 does not.
Always use semantic tokens instead of hardcoded palette values. The full set of tokens available in RefactKit:
TokenUtility classesPurpose
--background / --foregroundbg-background, text-foregroundPage canvas and body text
--card / --card-foregroundbg-card, text-card-foregroundCard surfaces
--primary / --primary-foregroundbg-primary, text-primary-foregroundBrand actions, active states
--secondary / --secondary-foregroundbg-secondary, text-secondary-foregroundSecondary actions
--muted / --muted-foregroundbg-muted, text-muted-foregroundSubdued surfaces and helper text
--accent / --accent-foregroundbg-accent, text-accent-foregroundHover states and highlights
--destructivebg-destructive, text-destructiveDanger and error states
--borderborder-borderAll borders
--ringring-ringFocus rings
--sidebar-*bg-sidebar, text-sidebar-foreground, etc.Sidebar-specific tokens

Applying a new Shadcn theme preset

The fastest way to restyle RefactKit is to apply one of the theme presets from ui.shadcn.com/themes. Each preset replaces the :root and .dark variable blocks in your CSS.
1

Choose a preset

Visit ui.shadcn.com/themes, pick a theme, and copy the generated preset code.
2

Apply the preset

Run the Shadcn CLI in the project root, substituting your copied code for <preset-code>:
npx shadcn@latest apply --preset <preset-code>
The CLI rewrites the :root and .dark blocks in src/styles/globals.css and leaves all component code untouched.
3

Verify the result

Start the dev server and check both light and dark mode:
pnpm dev

Customizing fonts

RefactKit ships with five fontsource fonts pre-installed and a useFont hook that applies the user’s selection via a data-font attribute on <html>.

Built-in fonts

Font keyPackageDisplay name
default(auto)System default — Google Sans Flex (LTR) or Zain (RTL)
google-sans@fontsource-variable/google-sans-flexGoogle Sans Flex
zain@fontsource/zainZain
geist@fontsource-variable/geistGeist
baloo@fontsource/baloo-bhaijaan-2Baloo Bhaijaan 2

Adding a new font

1

Install the fontsource package

pnpm add @fontsource/inter
2

Import the font in globals.css

Add the import at the top of src/styles/globals.css, alongside the existing imports:
src/styles/globals.css
@import "@fontsource/inter";
3

Register the CSS variable

Add a data-font selector block to src/styles/globals.css:
src/styles/globals.css
[data-font="inter"] {
  --font-family: "Inter", sans-serif;
}
4

Add the key to the Font type

Open src/hooks/use-font.ts and add "inter" to the Font union type:
src/hooks/use-font.ts
export type Font = 'default' | 'google-sans' | 'zain' | 'geist' | 'baloo' | 'inter'
5

Add the option to the settings UI

Open src/components/settings/account/appearance.tsx and add a <SelectItem> inside the font <SelectContent>:
src/components/settings/account/appearance.tsx
<SelectItem value="inter">Inter</SelectItem>

How the font hook works

useFont (src/hooks/use-font.ts) stores the user’s selection in localStorage under the key RefactKit-font and applies it by setting a data-font attribute on document.documentElement. The CSS [data-font="..."] selectors in globals.css pick up this attribute and set --font-family accordingly. When data-font is absent (the default key), a direction-aware fallback activates automatically:
src/styles/globals.css
html:not([data-font]) {
  &[dir="ltr"] {
    --font-family: "Google Sans Flex Variable", "Geist Variable", sans-serif;
  }
  &[dir="rtl"] {
    --font-family: "Zain", sans-serif;
  }
}

Light, dark, and system mode

Theme switching is handled by next-themes, which adds or removes the dark class on <html>. The Appearance component in src/components/settings/account/appearance.tsx exposes three options to users — System, Light, and Dark — using the useTheme hook from next-themes.
src/components/settings/account/appearance.tsx
const THEMES = [
  { value: 'system', label: 'System', Icon: Monitor },
  { value: 'light',  label: 'Light',  Icon: Sun    },
  { value: 'dark',   label: 'Dark',   Icon: Moon   },
] as const
You do not need to write any dark: variant classes in your own components. Because both :root and .dark define the same set of semantic tokens, every bg-primary or text-muted-foreground class automatically reflects the active mode.

Spacing and layout conventions

Follow these rules when building new UI in RefactKit to stay consistent with the component library:
  • Use flex + gap-* for spacing between elements. Do not use space-y-* or space-x-*.
  • Use size-* for equal-dimension elements. For example, size-10 instead of w-10 h-10.
  • Use data-icon="inline-start" when placing icons inside buttons. This is a Base UI convention for correct icon alignment.
{/* Correct */}
<div className="flex flex-col gap-4">
  <button type="button" className="flex items-center gap-2 size-10">
    <Icon data-icon="inline-start" />
    Label
  </button>
</div>

{/* Avoid */}
<div className="space-y-4">
  <button type="button" className="w-10 h-10"></button>
</div>