Customize with SCSS
The Orbix design system (src/Orbix/packages/foundry-ui) ships with its SCSS sources. Every npm run build
compiles the Tailwind CSS engine from those sources with the settings of one small file,
src/Orbix/ClientApp/scss/brand.scss. With the file as shipped (every line commented out) the result is exactly
the default Orbix design.
Use it to set your brand color, radius and fonts once for the whole application, to give any design token a fixed value, or to leave out components you do not use. Node.js is needed for this (see Requirements); the .NET build itself never runs npm.
The brand file
// src/Orbix/ClientApp/scss/brand.scss
$theme: (
brand: #0f766e, // brand color: the whole palette is derived from it
radius: lg, // none | sm | md | lg | full
font: humanist, // foundry | system | humanist | geometric | serif
);
$tokens: (
font-sans: ("Poppins", system-ui, sans-serif),
radius-control: 8px,
);
$components: (
calendar: false,
datagrid: false,
);| Map | What it does |
|---|---|
$theme | Default appearance, with the keys of the theme customizer: brand (a #rrggbb color), preset, neutral, mode, radius, density, elevation, layout, motion, font (values in Theming). The theme runtime builds the full palette from brand (hover and active states, subtle tints, readable text colors, dark mode and chart colors, with AA contrast). Your visitors can still choose another preset or mode in the customizer. |
$tokens | A fixed value for any --fd-* token, written without the --fd- prefix: fonts (font-sans, font-mono), radii (radius-control, radius-surface, radius-overlay), spacing (space-4) and more. Fixed values win over the radius, density and font presets of the customizer. For colors use $theme (brand, neutral), so that light and dark mode stay consistent. |
$components | Components to leave out of the CSS, by file name in packages/foundry-ui/scss/components (for example calendar, datagrid, wizard). Only remove components that none of your pages use. An unknown name stops the build with a clear message. |
Settings in $theme take precedence over the defaults in ClientApp/js/app.ts (initTheme({ product: … }));
the choices a visitor makes in the customizer take precedence over both.
Rebuild
Run the commands in src/Orbix (or add --prefix src/Orbix from the solution folder):
| Command | What it does |
|---|---|
npm run build | Compiles the design system from SCSS into ClientApp/css/foundry/foundry.tailwind.css, then builds every asset into wwwroot/build/tailwind |
npm run build:css | Compiles the design system only (useful while you try settings with npm run dev running: the watch build picks up the new styles) |
npm run dev | Compiles the design system once, then rebuilds the assets on every change (run dotnet watch --project src/Orbix next to it) |
ClientApp/css/foundry/ is generated: do not edit it, it is replaced on every build. ClientApp/css/engines/tailwind.css
imports it, and the <ox-vite> tag helper of the document head loads the built file from
wwwroot/build/tailwind/manifest.json. A visitor who already chose a theme keeps it; clear the site data of your
browser (or use a private window) to see your new defaults. For a deployment, build the assets first, then run
dotnet publish: the published app serves wwwroot/build/tailwind.
Structure of the SCSS sources
src/Orbix/packages/foundry-ui/
├── scss/
│ ├── foundry.scss the core: tokens, base styles, components and layouts
│ ├── _config.scss the settings read from your brand file ($theme, $tokens, $components)
│ ├── _overrides.scss the CSS written from those settings (loaded last)
│ ├── _base.scss base layer: fonts, reset, typography
│ ├── _components.scss component layer: the load order of every component and layout
│ ├── abstracts/ functions, mixins and maps (token(), space(), rem(), focus-ring, up() …), no CSS
│ ├── tokens/ token values: _orbix.scss (Sass variables), _orbix-properties.scss (--fd-* properties)
│ ├── base/ @font-face, reset, typography, small utilities, keyframes
│ ├── components/ one partial per fd-* component (_button.scss, _card.scss, _modal.scss …)
│ └── layouts/ app shell, sidebar, topbar, navigation, page header, auth pages, grid
├── engines/
│ ├── bootstrap/scss/ Bootstrap 5.3 engine: foundry.scss, Bootstrap settings from the tokens, bridge, utilities
│ └── tailwind/css/ Tailwind CSS v4 engine: foundry.css (@theme from the tokens, layers, utilities)
├── tokens/ the design token sources (base.json, skins/orbix.json), for reference
├── cli/ the build command used by scripts/build.mjs (foundry-ui css …)
└── dist/ precompiled stylesheet, scripts, fonts and token filesEvery component reads design tokens at runtime (var(--fd-…)), and every partial uses logical properties
(margin-inline-start, never margin-left), so light and dark mode and right-to-left languages keep working
with your changes.
Your own SCSS
You can write your own components on the same API. Add a stylesheet to ClientApp/css/orbix/ as plain CSS
(imported from ClientApp/css/orbix/main.css), or write SCSS with the functions and mixins of the design system
and import it from ClientApp/js/app.ts (import '../scss/reports.scss';): Vite compiles it with Sass and the
<ox-vite> tag helper links the resulting stylesheet.
// src/Orbix/ClientApp/scss/reports.scss
@use "../../packages/foundry-ui/scss/abstracts" as fd;
.reports-summary {
padding: fd.space(4);
border-radius: fd.token(radius-surface);
@include fd.focus-visible;
@include fd.up(lg) { padding: fd.space(6); }
}You can also edit the partials in packages/foundry-ui/scss directly. Keep a note of those changes: an Orbix
update replaces packages/foundry-ui, while ClientApp/scss/brand.scss stays yours.
Switch the engine
This item is built on Tailwind CSS v4. The SCSS sources of both engines are included, so you can compile the
design system on Bootstrap 5 instead. The pages use the same fd-* markup with either engine. Support for
this item covers the Tailwind CSS engine.
- In
src/Orbix, install the Bootstrap SCSS sources:npm install --save-dev bootstrap(you can remove the Tailwind CSS compiler withnpm uninstall tailwindcss @tailwindcss/cli). - Rename
ClientApp/css/engines/tailwind.csstoClientApp/css/engines/bootstrap.cssand change its first line to@import "../foundry/foundry.bootstrap.css";. - In
Infrastructure/OrbixOptions.cschangeEngines = ["tailwind"]toEngines = ["bootstrap"]and the default ofEngineto"bootstrap"; inappsettings.jsonset"Engine": "bootstrap". - In
package.jsonchange thebuildscript tonode scripts/assets.mjs && node scripts/build.mjs bootstrap. - Run
npm run build: the assets are written towwwroot/build/bootstrap(you can deletewwwroot/build/tailwind).
The test suite (dotnet test after npm run build) checks that the build of the engine in ClientApp/css/engines
is complete and that the pages load it.