ng-hub-ui-ds
The shared design token foundation of the ng-hub-ui family: the CSS variables --hub-ref-* (primitives) and --hub-sys-* (semantic), with light/dark and 8 themes. Import it once and the whole family reads the same palette.
What it is and what it is for
Its job is to unify and wire up the style variables across every library in the family. Each library is themed with --hub-* variables but does not define them: it consumes them. This package is the single source of truth that connects them, so that:
- One palette feeds panels, forms, calendar, board… at the same time.
- You re-theme once (one token) and the change reaches the whole family.
- Dark mode and 8 themes are ready, switchable with one attribute.
- You use it in your own CSS too, so your UI matches the components.
The wiring is rolling out library by library: further down, under the family, is the integration status of each one. Looking for the full token catalogue? It is in the token reference.
Getting started
The whole route: what to install, what to import and where, and which mechanism to use for each kind of change. ds has no dependencies (plain CSS/SCSS) and emits nothing unless you import it.
1 · Install
ds is the base; add the family libraries you use. None of them defines the palette — they all consume the ds tokens.
npm install ng-hub-ui-ds
npm install ng-hub-ui-panels ng-hub-ui-forms … # the ones you use2 · Import — once, at the root, and in this order
/* styles.scss (application root) */
/* 1 · Tokens — ALWAYS, exactly once: the base the whole family consumes */
@use 'ng-hub-ui-ds/styles/tokens/hub-tokens';
/* 2 · Native-element reset — only if your app does not ship one already (Bootstrap Reboot…) */
@use 'ng-hub-ui-ds/styles/base/reset';
/* 3 · Utilities — opt-in: import only the sheets you use
(Bootstrap-exact names: do NOT load them next to a global Bootstrap) */
@use 'ng-hub-ui-ds/styles/utilities/layout';
@use 'ng-hub-ui-ds/styles/utilities/text';
@use 'ng-hub-ui-ds/styles/utilities/surfaces';
/* 4 · Sheets of their own shipped by some libraries — once, path documented by each README */
@use 'ng-hub-ui-forms/styles' as hub-forms; // shared forms chrome
@use 'ng-hub-ui-utils/styles/tooltip'; // utils tooltip
/* 5 · Mixins — when you build your own components with the same system */
@use 'ng-hub-ui-ds' as hub;
.page { @include hub.center($max: xl); }It works without Sass too: every sheet has a compiled .css twin — @import 'ng-hub-ui-ds/styles/tokens/hub-tokens.css'; — or through angular.json:
"styles": [
"node_modules/ng-hub-ui-ds/styles/tokens/hub-tokens.css",
"src/styles.scss"
]3 · Modify — which mechanism for what you are changing
| I want to… | Mechanism | Where it is explained |
|---|---|---|
| Change a global colour (the primary, say) | :root { --hub-sys-color-primary: … } — re-themes the whole family | How to modify it |
| Add a new accent (brand, tertiary…) | CSS: --hub-sys-color-brand · Sass: $hub-accents-extra | How to modify it |
| Drop variants I do not use | Sass: replace the map — with ($hub-accents: (primary: …, danger: …)) — and only those families are emitted | SCSS functions |
| Adjust spacing / radii / grid | Override the structural tokens --hub-ref-space-* / --hub-sys-radius-* / --hub-sys-grid-* | Structural layer |
| A whole theme (dark, corporate…) | [data-theme='…'] { the tokens that differ } + the attribute on <html> | Build your theme |
| Build MY components with the same system | Mixins: @include hub.stack() · hub.text-bg(brand) · hub.radius(lg)… — or the utility classes | Mixins and styles |
| Live alongside Bootstrap / Material / Tailwind | Bridge mixins: @include hub.bridge-bootstrap($mode: adopt | project) | Bridges |
| Fine-tune ONE component of ONE library | Its own --hub-<component>-* hooks (scoped or global) | Token reference and each library's own page |
4 · And the rest of the libraries
With the tokens loaded there is nothing else to configure: every ng-hub-ui-* reads --hub-sys-* and re-themes itself with your overrides. Each component also exposes --hub-<component>-* hooks for fine tuning, and some libraries ship sheets of their own, imported once next to the tokens — the exact path is documented by each README (the shared forms chrome, say, or the utils tooltip/overlay, as in the step 2 block). The integration status of every library is under the family.
Architecture: the two layers
--hub-ref-*
Raw values with no context: colour ramps, spacing, radii, typography.
--hub-ref-color-blue-500--hub-sys-*
Meaningful assignments, the ones components consume.
--hub-sys-color-primaryGolden rule: components reference sys tokens only; sys points at ref. Changing a sys re-themes; changing a ref adjusts the base palette.
Semantic colours · live themes
The set is open: 9 variants by default (5 chromatic + 4 neutral) plus the ones you add. Every accent exposes a uniform family of roles — subtle, border-subtle, emphasis and the contrast pair on. Switch the theme and watch the whole palette recolour.
Build your theme · change the base colours only
Define only the base colour of each semantic family. The rest (subtle, border-subtle, emphasis, on) is derived automatically with color-mix / relative color — and the components below re-theme live, which is the shared wiring in action.
Live components
.my-theme {
/* define ONLY the base colour of each family */
--hub-sys-color-primary: #6d28d9;
/* the rest derives at runtime with color-mix / relative color — nothing to maintain */
--hub-sys-color-primary-subtle: color-mix(in oklch, var(--hub-sys-color-primary) 12%, var(--hub-sys-surface-page));
--hub-sys-color-primary-border-subtle: color-mix(in oklch, var(--hub-sys-color-primary) 35%, var(--hub-sys-surface-page));
--hub-sys-color-primary-emphasis: color-mix(in oklch, var(--hub-sys-color-primary) 80%, var(--hub-sys-color-ink));
--hub-sys-color-primary-on: oklch(from var(--hub-sys-color-primary) clamp(0, (0.62 - l) * 1000, 1) 0 h);
}The family · integration status
The whole family reads these tokens. The badge says whether a library is already wired to --hub-sys-* (it re-themes with the design system) or is still pending (we get to it later). Click any of them to see its examples.
How to modify it
1. Override a token (CSS) — the main road
Every value is a CSS variable, so re-theming is one line and cascades to the whole family:
:root {
--hub-sys-color-primary: #7c3aed;
--hub-sys-color-primary-subtle: #ede9fe;
--hub-sys-color-primary-emphasis: #5b21b6;
}2. Add an accent of your own
Define a --hub-sys-color-<name> family and the components that accept a semantic variant pick it up unchanged. Try it live here:
color-mix.:root {
--hub-sys-color-brand: #9333ea;
--hub-sys-color-brand-subtle: #f3e8ff;
--hub-sys-color-brand-border-subtle: #d8b4fe;
--hub-sys-color-brand-emphasis: #6b21a8;
}
<!-- in any component that accepts a semantic variant -->
<hub-panel appearance="alert" variant="brand">Brand alert</hub-panel>--hub-sys-color-brand on its own already works (the components derive the rest with color-mix). Define the full family when you want exact tints.
… or predefine it in the open map (Sass)
If you use Sass, extend the open accent map before including the package, with $hub-accents-extra. Only ds is recompiled — never the libraries — and every new variant gets its full family (subtle · border-subtle · emphasis · on):
// Add your own variants — this recompiles the ds only, never the libraries.
@use 'ng-hub-ui-ds/styles/tokens/hub-tokens' with (
$hub-accents-extra: (
brand: #ff6b00,
accent: #00b8d9,
tertiary: #9c36b5
)
);
// brand · accent · tertiary get subtle · border-subtle · emphasis · on automatically.3. Create a theme of your own
[data-theme='corporate'] {
--hub-sys-color-primary: #0033a0;
--hub-sys-surface-page: #fbfcff;
--hub-sys-text-primary: #0a1f44;
/* …the rest of the tokens that differ from the base */
}4. …or all of it at once with hub.theme() (Sass)
A single partial theming mixin: hand it only the changes as maps and it emits the variables under their canonical names. Everything hanging off each token — sys aliases, role families, utilities, components — re-derives on its own along the var() chain:
@use 'ng-hub-ui-ds' as hub;
/* change ONLY spacing step 3 — gap-3, .p-3, sys-gap-3, components… all move with it */
:root { @include hub.theme($space: (3: 1.25rem)); }
/* or a whole theme, scopeable to [data-theme] or to a subtree */
[data-theme='compact'] {
@include hub.theme(
$space: (3: 0.75rem, 4: 1rem),
$radius: (md: 0.25rem),
$accents: (primary: #0f766e, brand: #ff6b00)
);
}SCSS functions: how it is generated inside
The semantic colour families are not written by hand: the accent set is an open map with !default and the family is derived with an @each over map.keys($hub-accents). That is why adding one colour (or nine) is uniform and free of boilerplate: every key in the map gets its family automatically.
// The accent set is an OPEN map with !default — add as many as you want.
$hub-accents: (
primary: …, secondary: …, success: …, danger: …, warning: …,
info: …, neutral: …, light: …, dark: …
) !default;
// The family is derived ONCE in :root, iterating EVERY key of the map,
// so any accent you add gets its family for free.
@mixin hub-color-derive() {
@each $name in map.keys($hub-accents) {
--hub-sys-color-#{$name}-subtle: color-mix(in oklch, var(--hub-sys-color-#{$name}) 12%, var(--hub-sys-surface-page));
--hub-sys-color-#{$name}-emphasis: color-mix(in oklch, var(--hub-sys-color-#{$name}) 80%, var(--hub-sys-color-ink));
--hub-sys-color-#{$name}-on: oklch(from var(--hub-sys-color-#{$name}) clamp(0, (0.62 - l) * 1000, 1) 0 h);
}
}For most cases you do not need to touch the SCSS: overriding CSS variables covers re-theming and adding accents. The map plus mixin is the internal machinery, useful if you contribute to the package.
Structural layer · live tokens
Beyond colour, ds defines a canonical structural layer: the spacing scale (--hub-ref-space-*), sizing and fractions (--hub-sys-size-*), grid (--hub-sys-grid-columns, gutters) and a semantic gap scale (--hub-sys-gap-*). Everything below is painted by consuming those variables.
Spacing scale · --hub-ref-space-0…7
Gap scale · --hub-sys-gap-0…5
Width fractions · --hub-sys-size-*
Grid auto-fit + container widths
/* Canonical structural tokens (ref → sys) */
gap: var(--hub-sys-gap-3); /* spacing scale */
padding-inline: var(--hub-ref-space-4);
max-width: var(--hub-sys-container-max-width-lg);
grid-template-columns: repeat(var(--hub-sys-grid-columns), minmax(0, 1fr));
/* Layout mixins */
@use 'ng-hub-ui-ds' as hub;
.page { @include hub.center($max: xl); }
.toolbar { @include hub.cluster($gap: 2); }
.cards { @include hub.grid($min: 16rem, $gap: 3); }
/* Opt-in utilities (Bootstrap naming, 3 sheets) */
@use 'ng-hub-ui-ds/styles/utilities/layout'; // .d-flex .gap-3 .ms-auto .position-* .ratio-*
@use 'ng-hub-ui-ds/styles/utilities/text'; // .fs-3 .fw-bold .text-truncate .text-muted
@use 'ng-hub-ui-ds/styles/utilities/surfaces'; // .bg-* .border .rounded .shadow .opacity-*Mixins and styles
The ds Sass API: helpers that consume the canonical tokens — with no spacing or colour baked in. They are imported namespaced, with @use 'ng-hub-ui-ds' as hub. The utility sheets are built from these same mixins, so changing or extending a behaviour means minting your own class with the mixin. Every demo below is built from the real mixin; the full catalogue is at the end.
Every mixin has an equivalent utility; the demos below consume the real ds class (.cluster, .stack…) — this page re-applies no mixin.
hub.cluster() · .cluster — a row that wraps
hub.stack() · .stack — a column
hub.grid() · .grid-auto — auto-fit grid
hub.center() · .center — centred wrapper
@use 'ng-hub-ui-ds' as hub;
.toolbar { @include hub.cluster($gap: 2); } // a row that wraps
.feed { @include hub.stack($gap: 3); } // a column
.cards { @include hub.grid($min: 8rem, $gap: 2); } // auto-fit grid
.page { @include hub.center($max: sm); } // centred wrapperFull catalogue
| Mixin | Parameters | Description |
|---|---|---|
| Theme | ||
hub.theme() | $accents, $space, $gap, $radius, $shadow, $font-*, $line-height, $tokens | Partial theming in one call: hand it only the changes as maps and it emits the canonical variables; whatever derives from them re-derives itself. |
| Breakpoints | ||
hub.media-breakpoint-up() | $name, $breakpoints: $hub-breakpoints | Mobile-first media query from the breakpoint up (sm 576 · md 768 · lg 992 · xl 1200 · xxl 1400). |
hub.media-breakpoint-down() | $name, $breakpoints: $hub-breakpoints | Media query below the breakpoint. |
| Layout | ||
hub.stack() | $gap: 3, $align: stretch | Flex column with a token gap. |
hub.cluster() | $gap: 2, $align: center, $justify: flex-start | Flex row that wraps. |
hub.grid() | $min: 16rem, $gap: 4 | Auto-fit grid with a minimum width per cell. |
hub.grid-fixed() | $cols: 12, $gap: 4 | Grid of N fixed columns. |
hub.row() | $gap: 3 | Row of 12 tracks (--hub-sys-grid-columns). |
hub.col() | $span: 12 | Cell spanning $span tracks of a row(). |
hub.offset() | $n: 0 | Starts a col() on track $n + 1 (Bootstrap's offset); 0 resets it. |
hub.center() | $max: xl, $pad: 3 | Wrapper centred to a container max-width. |
| Typography | ||
hub.font-family() | $family: base | base | display | mono. |
hub.font-size() | $size: base | 1–6 (heading scale) or xs | sm | base | lg. |
hub.font-weight() | $weight: base | light | base | medium | semibold | bold. |
hub.line-height() | $height: base | 1 | sm | base | lg. |
hub.text-color() | $variant: body | An accent from the open map, body or muted; dimmed with --hub-text-opacity. |
hub.link-color() | $variant: primary | Accent link with an -emphasis hover and an underline with opacity (--hub-link-underline-opacity). |
hub.text-truncate() | — | Single-line truncation with an ellipsis. |
hub.text-break() | — | Breaks long words and URLs instead of overflowing. |
| Surfaces | ||
hub.bg() | $variant: body, $subtle: false | Accent background (or its subtle tint), body or transparent; dimmed with --hub-bg-opacity. |
hub.text-bg() | $variant: primary | Accent background + the -on colour with guaranteed contrast. |
hub.border() | $width: 1px, $color: … | Solid border with the default border token. |
hub.border-color() | $variant: primary | Border colour from an accent of the open map. |
hub.radius() | $size: md | none | sm | md | lg | xl | xxl | pill | circle. |
hub.shadow() | $size: md | none | sm | md | lg | inset. |
| Helpers | ||
hub.focus-ring() | — | Focus ring using the --hub-sys-focus-ring-* tokens. |
hub.visually-hidden() | — | Hides it visually while keeping it available to screen readers. |
hub.stretched-link() | — | Extends the link's clickable area to its positioned ancestor. |
hub.ratio() | $x: 16, $y: 9 | Fixed proportion with native aspect-ratio. |
hub.clearfix() | — | Clears floats (::after). |
| Bridges | ||
hub.bridge-bootstrap() | $mode: adopt | project | Adopts the --bs-* theme or projects onto it. |
hub.bridge-material() | $mode: adopt | project | The same with --mat-sys-* (Angular Material 3). |
hub.bridge-tailwind() | $mode: adopt | project | The same with --color-* (Tailwind v4 @theme). |
hub.bridge-open-props() | $mode: adopt | Aliases of the Open Props ramps. |
Utilities
Opt-in classes wrapping the same layer, under names exactly matching Bootstrap's — a drop-in replacement, but do not load these sheets AND Bootstrap globally in the same document. Three sheets: layout (display/flex, grid, spacing, sizing, position, helpers — these sections), text (the “Text” section) and surfaces (the “Surfaces” section). The demo uses the real classes:
.cluster .gap-2
.grid-auto .gap-2
Sizing · .w-50 · .w-25 · .w-auto
// three opt-in sheets — import only the ones you use
@use 'ng-hub-ui-ds/styles/utilities/layout'; // layout, spacing, position, helpers
@use 'ng-hub-ui-ds/styles/utilities/text'; // typography and text
@use 'ng-hub-ui-ds/styles/utilities/surfaces'; // backgrounds, borders, radii, shadows
<div class="cluster gap-2"> … </div>
<div class="grid-auto gap-2"> … </div>
<div class="w-50">half</div>
<div class="vh-100 min-vh-100">viewport height</div>Flexbox
A complete set of display and flexbox utilities, under Bootstrap's exact naming. The demos use the real ds classes.
justify-content · .justify-content-* — main axis
.justify-content-startalign-items · .align-items-* — cross axis
.align-items-startflex-direction · .flex-column
flex-fill / flex-grow-0 — grow and pin
Responsive · .flex-md-row · .align-items-md-center
The whole flex family has per-breakpoint variants. A column on mobile, a centred row from md up — resize the window:
Vertical divider · .vr
<!-- display + direction / wrap -->
<div class="d-flex flex-wrap gap-2"> … </div>
<div class="d-flex flex-column"> … </div>
<!-- main axis (justify) and cross axis (align) -->
<div class="d-flex justify-content-between align-items-center"> … </div>
<!-- grow / pin -->
<div class="d-flex gap-2">
<span class="flex-fill">grows</span>
<span class="flex-grow-0">fixed</span>
</div>
<!-- responsive: a column on mobile, a top-aligned row from md up -->
<div class="d-flex flex-column flex-md-row align-items-md-start"> … </div>
<!-- vertical divider -->
<div class="d-flex gap-3">left <span class="vr"></span> right</div>Columns, widths and spacing
A 12-column grid (.row + .col-1…12 + .offset-1…11, driven by --hub-sys-grid-columns), widths and directional padding/margin. Every demo uses the real utilities.
Columns · .row + .col-N
Offsets · .offset-N
The cell starts on track n + 1 of the same grid (grid-column-start); with a breakpoint, .offset-md-8, and .offset-md-0 resets it to automatic placement.
Widths · .w-25 / 50 / 75 / 100 / auto
Padding · .p-1…5 (all four sides)
Padding per axis · .px-* / .py-*
Margin · .m-1…5 (inside a reference frame)
Margin per axis · .mx-* / .my-*
Responsive · .col-md-6 · .d-lg-none · .p-sm-3
Mobile-first variants (sm 576 · md 768 · lg 992 · xl 1200 · xxl 1400) for display, columns and offsets, spacing, gap and the whole flex family (.flex-md-row, .justify-content-md-center, .align-items-md-start, .order-lg-*…). Resize the window — these cells are .col-12 .col-md-6 .col-xl-3:
<!-- mobile-first: 1 column → 2 at ≥768px → 4 at ≥1200px -->
<div class="row">
<div class="col-12 col-md-6 col-xl-3">…</div>
</div>
<div class="d-none d-lg-flex">desktop only</div>
<section class="p-2 p-md-4">padding that grows with the viewport</section>
// breakpoints as a mixin — for any other utility or your own CSS
@use 'ng-hub-ui-ds' as hub;
@include hub.media-breakpoint-up(md) { .sidebar { width: 18rem; } }<!-- 12-column grid: every row adds up to 12 -->
<div class="row">
<div class="col-6">col-6</div>
<div class="col-6">col-6</div>
</div>
<div class="row">
<div class="col-4">col-4</div>
<div class="col-4">col-4</div>
<div class="col-4">col-4</div>
</div>
<!-- offset: .col-4.offset-8 starts on track 9 (offset-{bp}-0 resets it) -->
<div class="row">
<div class="col-4 offset-md-8">col-4 offset-md-8</div>
</div>
<!-- widths · directional padding and margin -->
<div class="w-50">w-50</div>
<div class="p-3">1rem of padding on all four sides</div>
<div class="px-4 py-2">padding-inline 1.5rem · padding-block .5rem</div>
<div class="mx-3">margin-inline 1rem</div>Text
Typography and text utilities under Bootstrap's exact naming, built on the typography mixins (hub.font-size(), hub.font-weight(), hub.text-color()…): every value resolves to tokens, so overriding the token re-themes the utilities — and with the mixins you can mint variants of your own.
Size · .fs-1…6 · headings · .h1…6
.fs-* changes the size only; .h1…6 applies a heading's full typography (size + bold + tight leading + margin) without the semantics — a <div class="h5"> reads like an <h5>:
Weight · .fw-* · style · .fst-italic
Alignment · .text-start / .text-center / .text-end
Transform · decoration · family
Tabular figures · .font-tabular-nums
Proportional figures give every digit its own width, so a 1 is narrower than a 0 and the units of two amounts land in different places. A column of money is read by comparing downwards: look at where the decimal separator falls on each side.
Truncation · .text-truncate
Leading · .lh-1 / .lh-sm / .lh-base / .lh-lg
Colours · .text-primary … .text-muted
Text opacity · .text-opacity-* · links · .link-*
// import the sheet once
@use 'ng-hub-ui-ds/styles/utilities/text';
<h2 class="fs-3 fw-semibold">Headline</h2>
<p class="text-muted lh-lg">Secondary copy with generous leading</p>
<span class="text-uppercase fw-medium">label</span>
<td class="text-end font-monospace">1.234,56 €</td>
<p class="text-truncate" style="max-width: 16rem">Truncated with an ellipsis…</p>
// …or mint variants of your own with the mixins
@use 'ng-hub-ui-ds' as hub;
.card__title { @include hub.font-size(4); @include hub.font-weight(semibold); }
.card__meta { @include hub.text-color(muted); @include hub.text-truncate(); }Surfaces
Backgrounds, borders, radii, shadows and opacity under Bootstrap's exact naming, built on the surface mixins (hub.bg(), hub.text-bg(), hub.radius(), hub.shadow()…) and the --hub-sys-color-* / --hub-sys-radius-* / --hub-sys-shadow-* tokens.
Backgrounds · .bg-* and .bg-*-subtle
Background + guaranteed contrast · .text-bg-*
Borders · .border · .border-{variant} · .border-1…5
Radii · .rounded-0…3 · .rounded-pill · .rounded-circle
Shadows · .shadow-sm / .shadow / .shadow-lg
Opacity · .opacity-* (element) · .bg-opacity-* (background only)
// import the sheet once
@use 'ng-hub-ui-ds/styles/utilities/surfaces';
<hub-badge color="success">active</hub-badge>
<div class="bg-warning-subtle border border-warning rounded-3 p-3">notice</div>
<div class="bg-body rounded shadow-lg p-4">raised card</div>
// …or mint variants of your own with the mixins
@use 'ng-hub-ui-ds' as hub;
.card { @include hub.bg(body); @include hub.radius(lg); @include hub.shadow(sm); }
.card--brand { @include hub.text-bg(brand); } // any accent of the open mapPosition and helpers
Position/inset, overflow, order, float, visibility, z-index, object-fit and interactions — plus the behavioural helpers (.visually-hidden, .stretched-link, .ratio-*, .clearfix). All under Bootstrap's exact naming.
Position · .position-* + .top/.start/.translate-middle
Ratio · .ratio .ratio-16x9
Overflow · interaction · lateral spacing
Focus ring · .focus-ring
A focus ring driven by the --hub-sys-focus-ring-* tokens — click it or press Tab:
Accessibility · .visually-hidden
This paragraph holds a text hidden visually but announced by screen readers: for assistive technology only (inspect the DOM to see it).
<!-- badge positioned over the corner of its container -->
<div class="position-relative">
…
<span class="position-absolute top-0 start-100 translate-middle text-bg-danger rounded-pill px-2">9+</span>
</div>
<!-- media at a fixed ratio -->
<div class="ratio ratio-16x9"><iframe src="…"></iframe></div>
<!-- whole card clickable + screen-reader-only text -->
<div class="position-relative">
<a href="…" class="stretched-link">See more<span class="visually-hidden"> about surfaces</span></a>
</div>
<!-- push with auto margins inside a flex row -->
<nav class="d-flex gap-2"><span>logo</span><a class="ms-auto">login</a></nav>Bridges to other systems
Opt-in mixins that connect hub with whichever framework is present. Zero cost if you never call them. Two directions through $mode: adopt (hub takes the host's theme) and project (hub projects its theme onto the host).
@use 'ng-hub-ui-ds' as hub;
/* "I have Bootstrap and I want hub to adopt its palette" */
:root { @include hub.bridge-bootstrap($mode: adopt); }
/* "I want to tint Material and Tailwind with MY hub theme" */
:root { @include hub.bridge-material($mode: project); }
:root { @include hub.bridge-tailwind($mode: project); }| Mixin | System | adopt | project |
|---|---|---|---|
hub.bridge-bootstrap | Bootstrap 5.3+ | reads --bs-* | tints --bs-* + gutters/radius |
hub.bridge-material | Angular Material 3 | reads --mat-sys-* | tints --mat-sys-* (colour/on pair) |
hub.bridge-tailwind | Tailwind v4 | reads --color-* | emits --color-* for @theme |
hub.bridge-open-props | Open Props | ramp aliases | — |
Quick reference
| I want to… | How |
|---|---|
| Use the palette | @use '…/hub-tokens' |
| Change a global colour | :root { --hub-sys-color-primary: … } |
| Add variants of my own | with ($hub-accents-extra: (brand: …)) |
| Text with contrast | color: var(--hub-sys-color-primary-on) |
| Layout (mixin / utility) | @include hub.center() · .stack |
| Text (mixin / utility) | @include hub.font-size(3) · .fs-3 .fw-bold .text-muted |
| Surfaces (mixin / utility) | @include hub.text-bg(brand) · .bg-primary-subtle .rounded .shadow |
| Position / helpers | .position-absolute .top-0 · .ratio-16x9 · .visually-hidden |
| Responsive | .col-md-6 · .flex-md-row · .offset-md-8 · @include hub.media-breakpoint-up(md) |
| Bridge to Bootstrap/Material | @include hub.bridge-bootstrap($mode: adopt) |
| Create a theme | [data-theme='<name>'] { … } |
| Partial theming (Sass) | @include hub.theme($space: (3: 1.25rem), $accents: (primary: …)) |