Styling
Tailwind and SCSS in a theme, the colour and font tokens the engine sets, and dark mode.
Read this when you want to change colours, fonts or spacing, or support dark mode.
A theme styles itself with Tailwind CSS (small utility classes like flex and px-4) and SCSS (CSS with nesting and variables).
Both are set up for you in the starter theme.
How the files fit together
app/styles/
app.css Tailwind layers, then imports app.scss
app.scss imports the folders below, in order
01-settings/ variables, fonts, breakpoints
02-generic/ reset, RTL and LTR rules, animations
03-elements/ buttons, forms
04-components/ header, footer, product, cart …
05-utilities/ small fixesThe root route links it once, by URL, with ThemeStylesheet:
import { ThemeStylesheet } from '@salla.sa/twilight-theme-engine/tanstack';
import appCssUrl from '../styles/app.css?url';
// inside <head>:
<ThemeStylesheet href={appCssUrl} />The starter also passes critical, so the home and product pages inline a smaller critical stylesheet instead and app/client.tsx adds app.css once the first screen has painted. See Performance.
The numbered folders follow the ITCSS idea: general rules first, specific ones last, so later rules win without !important.
Put new styles in the folder that matches what you style.
Components in the starter theme often keep their markup clean and write the Tailwind classes in SCSS with @apply.
You can also use utility classes directly in your markup.
Tailwind setup
Tailwind must scan every file that contains class names, including the engine's, or those classes are dropped from the build:
module.exports = {
content: [
'./app/**/*.{js,ts,jsx,tsx,scss,css}',
'./node_modules/@salla.sa/twilight-theme-engine/dist/**/*.js',
'./node_modules/@salla.sa/twilight-components-react/dist/**/*.js',
],
darkMode: 'class',
theme: { extend: { colors: { primary: 'var(--color-primary)' } } },
plugins: [require('@salla.sa/twilight-tailwind-theme'), require('@tailwindcss/forms')],
};The primary colour points at a CSS variable, so it follows the merchant's choice.
Colour and font tokens
The merchant picks a main colour and a font in the dashboard. In the browser the engine turns them into CSS variables on <html>.
Use these instead of hard-coding values:
| Variable | Meaning |
|---|---|
--color-primary | The merchant's main colour |
--color-primary-dark, --color-primary-light | Darker and lighter shades of it |
--color-primary-reverse | Readable text colour on top of the primary colour |
--font-main | The chosen font |
The starter theme applies the font to the whole page:
body {
font-family: var(--font-main);
}Add your own tokens in 01-settings/global.scss under :root, as the starter does with --s-radius.
Dark mode is your choice
The engine does not give you a dark theme by itself. What it does:
- It adds
color-mode-darkorcolor-mode-lightto<body>, based on the merchant's colour settings. - It adds
footer-is-darkorfooter-is-lightfrom thefooter_is_darksetting.
Tailwind is configured with darkMode: 'class', so dark: utilities only apply under a .dark class that your theme must add.
The simplest path is to style the body classes directly:
body.color-mode-dark {
--color-text: #e5e7eb;
background: #111;
}Decide per theme whether you want this at all. Many themes only offer a dark footer, using the footer_is_dark setting
(see Settings).
Make styles work in both directions
Prefer logical classes so one stylesheet works in Arabic and English: ms-4 instead of ml-4, text-start instead of text-left.
The full list is in Languages and RTL.
Next: Languages and RTL, to translate your theme.