Styling
Vetty's UI is styled with Tailwind CSS 3.4. There is no separate design system or component library — Tailwind utility classes are applied directly to JSX.
Configuration
ui/tailwind.config.js:
module.exports = {
content: [
'./src/**/*.{js,jsx,ts,tsx}',
'./public/index.html',
],
theme: {
extend: {
colors: {
primary: {
50: '#ecfdf5',
100: '#d1fae5',
200: '#a7f3d0',
300: '#6ee7b7',
400: '#34d399',
500: '#10b981',
600: '#059669',
700: '#047857',
800: '#065f46',
900: '#064e3b',
},
},
fontFamily: {
sans: ['Inter', 'system-ui', '-apple-system', 'sans-serif'],
},
animation: {
'fade-in': 'fadeIn 0.3s ease-in-out',
'slide-up': 'slideUp 0.3s ease-out',
},
keyframes: {
fadeIn: {
'0%': { opacity: '0' },
'100%': { opacity: '1' },
},
slideUp: {
'0%': { transform: 'translateY(10px)', opacity: '0' },
'100%': { transform: 'translateY(0)', opacity: '1' },
},
},
},
},
plugins: [],
};
ui/postcss.config.js:
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
};
ui/src/index.css injects the Tailwind layers:
@tailwind base;
@tailwind components;
@tailwind utilities;
Design tokens
| Token | Hex | Typical use |
|---|---|---|
primary-50 | #ecfdf5 | Backgrounds, subtle hover |
primary-500 | #10b981 | Default primary (emerald) |
primary-600 | #059669 | Buttons, active states |
primary-700 | #047857 | Hover on primary-600 |
The same palette is replicated in the Docusaurus site (src/css/custom.css) so the docs and the product feel consistent.
Conventions
- Use Tailwind utilities directly in JSX. No inline
style={{…}}unless it's truly dynamic. - Keep class strings readable; wrap long combinations onto multiple lines using a template literal when needed.
- Prefer Tailwind's semantic classes (
text-gray-800,bg-white) over raw hex so dark mode becomes trivial later.
Animations
Two custom animations are used:
animate-fade-in— 300ms opacity transition, great for modals.animate-slide-up— 300ms translate + opacity, used for toasts and side panels.
Status badges
components/common/Badge.js maps domain status strings to colour utilities:
| Status | Classes |
|---|---|
paid, completed, active, captured | bg-primary-100 text-primary-800 |
partial, pending, scheduled | bg-amber-100 text-amber-800 |
failed, void, cancelled, no_show | bg-red-100 text-red-800 |
draft, inactive, dismissed | bg-gray-100 text-gray-600 |
Dark mode
Not enabled today. Adding it is a few-line change:
// tailwind.config.js
module.exports = {
darkMode: 'class',
// …
};
Components would then pair light utilities with dark: variants (bg-white dark:bg-slate-900).
Fonts
Inter is declared as the primary font in tailwind.config.js. For production, serve Inter from a CDN or self-host via @fontsource/inter (add to package.json when needed). Today the SPA falls back to the system font stack if Inter isn't loaded.
Icons
No icon library is wired in yet. Candidates: lucide-react (matches the Tailwind aesthetic) or @heroicons/react. Today icons are plain emoji or inline SVGs in feature components.