ng-hub-ui-ds 22.9.0 → 22.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,48 @@ All notable changes to `ng-hub-ui-ds` are documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [22.9.1] - 2026-09-06
9
+
10
+ ### Fixed
11
+
12
+ - **The README stopped promising a token that resolves to nothing.** Its colour table still listed
13
+ `--hub-sys-color-{variant}-dark` as the fifth member of the family — retired in 22.4.0 — and never
14
+ mentioned `-on`, the member that replaced it and that forms, buttons and badges consume today. The
15
+ "SCSS functions" section described a closed `$hub-variants` list and a `-dark` back-compat alias,
16
+ a mechanism the package left behind in that same release: it now shows the open `$hub-accents` map,
17
+ `$hub-accents-extra` and the real derivation loop, so a reader who copies it gets working code.
18
+ Also restores the seven libraries missing from the family list and drops the two that are not in it:
19
+ `ng-hub-ui-accordion`, retired in favour of panels, and `ng-hub-ui-dropdown`, which is a directive
20
+ inside `ng-hub-ui-buttons` and never a package. `focus-ring-color()` joins the mixin catalogue.
21
+ Both languages.
22
+ - **`BREAKING_CHANGES.md` records the 22.4.0 removal of `--hub-sys-color-{variant}-dark`.** It shipped
23
+ with a changelog line and no entry here; in this repository the major tracks Angular and can never
24
+ signal a break, so this file is the only warning a consumer gets — and a CSS variable that resolves
25
+ to nothing fails silently, at paint time, with no build error.
26
+ - **The terminal-theme comment no longer points at a file the package does not ship.** It sent the
27
+ reader to `styles/themes/terminal.scss`, which lives in the documentation app, not here. The
28
+ compiled `hub-tokens.css` carries the same correction.
29
+ - **Docs site** — the family gallery on the design-system page claimed `avatar`, `milestones` and
30
+ `utils` were still pending after they had been wired to `--hub-sys-*`, and listed none of
31
+ `action-sheet`, `badges`, `buttons`, `icons`, `loading`, `metrics` or `signature`. Its cards also
32
+ linked to unprefixed URLs, which only resolve through a legacy redirect table `action-sheet` is
33
+ absent from, and which drop a reader of the Spanish page into the English docs; they are relative
34
+ now. Nothing in the published package changes.
35
+
36
+ ### Added
37
+
38
+ - **`FUNCTIONALITIES.md`**, the coverage table the rest of the family carries: which tokens, mixins
39
+ and utilities exist and which of them the documentation actually demonstrates. Every mixin is
40
+ marked uncovered on purpose — the page's demos consume the utility classes, as it says itself.
41
+
42
+ ### Removed
43
+
44
+ - **Docs site** — the orphan `app-topbar` component. The site's top navigation moved into the app
45
+ shell's sidebar slots and nothing mounts the component any more, but its stylesheet stayed behind
46
+ as the last place in the repository still reading `--hub-sys-color-primary-dark`, the alias this
47
+ package retired in 22.4.0. A component nobody renders is still a component somebody copies styles
48
+ from, which is the only reason this was worth a line. Nothing in the published package changes.
49
+
8
50
  ## [22.9.0] - 2026-09-03
9
51
 
10
52
  ### Removed
@@ -14,7 +56,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
14
56
  selector covered `:root` and every theme. With Bootstrap present it silently handed that
15
57
  package control of this one's semantic tokens; without it, every declaration resolved to its
16
58
  fallback and the block did nothing. It is gone, and with it the package's last dependency on
17
- another framework's variables: **0** `--bs-*` references remain.
59
+ another framework's variables: the emitted tokens carry **0** `--bs-*` references. The
60
+ only ones left in the package are inside `bridge-bootstrap()`, which emits nothing unless
61
+ you call it.
18
62
 
19
63
  ### Changed
20
64
 
package/README.es.md CHANGED
@@ -27,25 +27,30 @@ librerías de componentes Angular para aplicaciones standalone.
27
27
  Este paquete es la base de design tokens de la que lee el resto del ecosistema
28
28
  **ng-hub-ui**:
29
29
 
30
- - [**ng-hub-ui-accordion**](https://www.npmjs.com/package/ng-hub-ui-accordion) (obsoleta — usa ng-hub-ui-panels)
31
30
  - [**ng-hub-ui-action-sheet**](https://www.npmjs.com/package/ng-hub-ui-action-sheet)
32
31
  - [**ng-hub-ui-avatar**](https://www.npmjs.com/package/ng-hub-ui-avatar)
32
+ - [**ng-hub-ui-badges**](https://www.npmjs.com/package/ng-hub-ui-badges)
33
33
  - [**ng-hub-ui-board**](https://www.npmjs.com/package/ng-hub-ui-board)
34
34
  - [**ng-hub-ui-breadcrumbs**](https://www.npmjs.com/package/ng-hub-ui-breadcrumbs)
35
+ - [**ng-hub-ui-buttons**](https://www.npmjs.com/package/ng-hub-ui-buttons)
35
36
  - [**ng-hub-ui-calendar**](https://www.npmjs.com/package/ng-hub-ui-calendar)
36
- - [**ng-hub-ui-dropdown**](https://www.npmjs.com/package/ng-hub-ui-dropdown)
37
37
  - [**ng-hub-ui-ds**](https://www.npmjs.com/package/ng-hub-ui-ds) ← Estás aquí
38
38
  - [**ng-hub-ui-forms**](https://www.npmjs.com/package/ng-hub-ui-forms)
39
39
  - [**ng-hub-ui-history**](https://www.npmjs.com/package/ng-hub-ui-history)
40
+ - [**ng-hub-ui-icons**](https://www.npmjs.com/package/ng-hub-ui-icons)
41
+ - [**ng-hub-ui-loading**](https://www.npmjs.com/package/ng-hub-ui-loading)
42
+ - [**ng-hub-ui-metrics**](https://www.npmjs.com/package/ng-hub-ui-metrics)
40
43
  - [**ng-hub-ui-milestones**](https://www.npmjs.com/package/ng-hub-ui-milestones)
41
44
  - [**ng-hub-ui-modal**](https://www.npmjs.com/package/ng-hub-ui-modal)
42
45
  - [**ng-hub-ui-nav**](https://www.npmjs.com/package/ng-hub-ui-nav)
43
46
  - [**ng-hub-ui-paginable**](https://www.npmjs.com/package/ng-hub-ui-paginable)
44
47
  - [**ng-hub-ui-panels**](https://www.npmjs.com/package/ng-hub-ui-panels)
45
48
  - [**ng-hub-ui-portal**](https://www.npmjs.com/package/ng-hub-ui-portal)
49
+ - [**ng-hub-ui-signature**](https://www.npmjs.com/package/ng-hub-ui-signature)
46
50
  - [**ng-hub-ui-skeleton**](https://www.npmjs.com/package/ng-hub-ui-skeleton)
47
51
  - [**ng-hub-ui-sortable**](https://www.npmjs.com/package/ng-hub-ui-sortable)
48
52
  - [**ng-hub-ui-stepper**](https://www.npmjs.com/package/ng-hub-ui-stepper)
53
+ - [**ng-hub-ui-toast**](https://www.npmjs.com/package/ng-hub-ui-toast)
49
54
  - [**ng-hub-ui-utils**](https://www.npmjs.com/package/ng-hub-ui-utils)
50
55
 
51
56
  ---
@@ -178,8 +183,10 @@ espaciado direccional `-x` / `-y`.
178
183
 
179
184
  ## 🎨 Los colores semánticos
180
185
 
181
- Cada color semántico (`primary` · `success` · `danger` · `warning` · `info`)
182
- expone una **familia uniforme** de cinco tokens:
186
+ Cada variante semántica expone una **familia uniforme** de cinco tokens. El conjunto por
187
+ defecto es `primary` · `secondary` · `success` · `danger` · `warning` · `info` · `neutral` ·
188
+ `light` · `dark`, y es **abierto**: cada variante que añadas obtiene la misma familia (ver
189
+ [Cómo modificarlo](#️-cómo-modificarlo)).
183
190
 
184
191
  | Token | Uso típico |
185
192
  | ----------------------------------- | ---------------------------------------------- |
@@ -187,7 +194,7 @@ expone una **familia uniforme** de cinco tokens:
187
194
  | `--hub-sys-color-<v>-subtle` | Fondo tenue (banners, alertas) |
188
195
  | `--hub-sys-color-<v>-border-subtle` | Borde tenue sobre el fondo subtle |
189
196
  | `--hub-sys-color-<v>-emphasis` | Texto legible sobre el fondo subtle |
190
- | `--hub-sys-color-<v>-dark` | Variante oscura del color |
197
+ | `--hub-sys-color-<v>-on` | Color de texto/icono con contraste **sobre** el acento |
191
198
 
192
199
  Ejemplo de uso (un aviso a juego con el resto de la familia):
193
200
 
@@ -248,7 +255,7 @@ Los únicos nombres fuera de Bootstrap son los primitivos de layout que reflejan
248
255
  .sr-label { @include hub.visually-hidden(); }
249
256
  ```
250
257
 
251
- Grupos: **tema** (`theme()` — tematización parcial en una llamada: pásale solo las escalas/acentos cambiados como mapas), **breakpoints** (`media-breakpoint-up/down` sobre el mapa `$hub-breakpoints` — de él se generan las variantes responsive `.d-md-*`, `.col-lg-*`, `.p-sm-*`…), **layout** (`stack`, `cluster`, `grid`, `grid-fixed`, `row`, `col`, `offset`, `center`), **tipografía** (`font-family`, `font-size`, `font-weight`, `line-height`, `text-color`, `link-color`, `text-truncate`, `text-break`), **superficies** (`bg`, `text-bg`, `border`, `border-color`, `radius`, `shadow`), **helpers** (`focus-ring`, `visually-hidden`, `stretched-link`, `ratio`, `clearfix`) y los **puentes** (`bridge-bootstrap` / `bridge-material` / `bridge-tailwind` / `bridge-open-props`).
258
+ Grupos: **tema** (`theme()` — tematización parcial en una llamada: pásale solo las escalas/acentos cambiados como mapas), **breakpoints** (`media-breakpoint-up/down` sobre el mapa `$hub-breakpoints` — de él se generan las variantes responsive `.d-md-*`, `.col-lg-*`, `.p-sm-*`…), **layout** (`stack`, `cluster`, `grid`, `grid-fixed`, `row`, `col`, `offset`, `center`), **tipografía** (`font-family`, `font-size`, `font-weight`, `line-height`, `text-color`, `link-color`, `text-truncate`, `text-break`), **superficies** (`bg`, `text-bg`, `border`, `border-color`, `radius`, `shadow`), **helpers** (`focus-ring`, `focus-ring-color`, `visually-hidden`, `stretched-link`, `ratio`, `clearfix`) y los **puentes** (`bridge-bootstrap` / `bridge-material` / `bridge-tailwind` / `bridge-open-props`).
252
259
 
253
260
  El catálogo completo con demos en vivo está documentado en [hubui.dev/design-system](https://hubui.dev/en/design-system/).
254
261
 
@@ -311,43 +318,55 @@ Reúne tus overrides bajo un atributo de tema y actívalo cuando quieras:
311
318
  ## 🧩 Funciones SCSS (cómo se genera por dentro)
312
319
 
313
320
  Las familias de color semántico **no se escriben a mano**, y un tema solo fija el
314
- **acento** de cada variante — `-subtle`, `-border-subtle` y `-emphasis` se derivan
315
- **una sola vez** en `:root` con `color-mix()` a partir del acento, la superficie y
316
- el _ink_ vivos. Así, añadir un color o un tema es uniforme y sin _boilerplate_.
321
+ **acento** de cada variante — `-subtle`, `-border-subtle`, `-emphasis` y `-on` se
322
+ derivan **una sola vez** en `:root` a partir del acento, la superficie y el _ink_
323
+ vivos. Los nombres de las variantes viven en un único mapa Sass **abierto**, así
324
+ que añadir un color o un tema es uniforme y sin _boilerplate_.
317
325
 
318
326
  ```scss
319
- $hub-variants: primary, success, danger, warning, info;
320
-
321
- // Un acento por variante, por tema — solo el color base.
322
- $hub-accents-light: (
327
+ // El ÚNICO sitio que enumera los nombres de variante. Es `!default`, así que puedes
328
+ // reemplazarlo entero antes del import — o, mejor, fusionar con $hub-accents-extra.
329
+ $hub-accents: (
323
330
  primary: var(--hub-ref-color-blue-500, #0d6efd),
331
+ secondary: var(--hub-ref-color-gray-600, #6c757d),
324
332
  success: var(--hub-ref-color-green-500, #198754),
325
333
  danger: var(--hub-ref-color-red-500, #dc3545),
326
334
  warning: var(--hub-ref-color-yellow-500, #ffc107),
327
- info: var(--hub-ref-color-cyan-500, #0dcaf0)
328
- );
329
-
330
- // Fija SOLO --hub-sys-color-<variante> (el acento). Se llama en cada tema.
335
+ info: var(--hub-ref-color-cyan-500, #0dcaf0),
336
+ neutral: var(--hub-ref-color-gray-600, #6c757d),
337
+ light: var(--hub-ref-color-gray-100, #f8f9fa),
338
+ dark: var(--hub-ref-color-gray-900, #212529)
339
+ ) !default;
340
+
341
+ // Override aditivo — pasa SOLO las variantes que añades o retocas, conserva las demás.
342
+ $hub-accents-extra: () !default;
343
+ $hub-accents: map.merge($hub-accents, $hub-accents-extra);
344
+
345
+ // Fija SOLO --hub-sys-color-<variante> (el acento). Se llama en cada bloque de tema
346
+ // con el mapa propio del tema, así que un tema emite justo las variantes que retinta.
331
347
  @mixin hub-color-accents($accents) {
332
- @each $name in $hub-variants {
333
- --hub-sys-color-#{$name}: #{map.get($accents, $name)};
348
+ @each $name, $color in $accents {
349
+ --hub-sys-color-#{$name}: #{$color};
334
350
  }
335
351
  }
336
352
 
337
- // Deriva la familia de roles del acento + superficie + ink vivos. Se emite UNA
338
- // vez en :root; los temas solo cambian las entradas y la familia se recalcula.
353
+ // Deriva la familia de roles del acento + superficie + ink vivos. Se emite UNA vez
354
+ // en :root sobre el conjunto abierto, así que cada variante — incluidas las tuyas —
355
+ // obtiene su familia completa gratis.
339
356
  @mixin hub-color-derive() {
340
- @each $name in $hub-variants {
357
+ @each $name in map.keys($hub-accents) {
341
358
  --hub-sys-color-#{$name}-subtle: color-mix(in oklch, var(--hub-sys-color-#{$name}) 12%, var(--hub-sys-surface-page, #fff));
342
359
  --hub-sys-color-#{$name}-border-subtle: color-mix(in oklch, var(--hub-sys-color-#{$name}) 35%, var(--hub-sys-surface-page, #fff));
343
360
  --hub-sys-color-#{$name}-emphasis: color-mix(in oklch, var(--hub-sys-color-#{$name}) 80%, var(--hub-sys-color-ink, #212529));
344
- --hub-sys-color-#{$name}-dark: var(--hub-sys-color-#{$name}-emphasis); // alias retrocompatible
361
+ // Volteo de contraste en escala de grises según la luminosidad del propio acento:
362
+ // los acentos oscuros (L < .62) resuelven a texto blanco; los claros, a casi negro.
363
+ --hub-sys-color-#{$name}-on: oklch(from var(--hub-sys-color-#{$name}) clamp(0, (0.62 - l) * 1000, 1) 0 h);
345
364
  }
346
365
  }
347
366
 
348
367
  :root,
349
368
  [data-theme='light'] {
350
- @include hub-color-accents($hub-accents-light);
369
+ @include hub-color-accents($hub-accents);
351
370
  @include hub-color-derive();
352
371
  }
353
372
  ```
@@ -355,8 +374,8 @@ $hub-accents-light: (
355
374
  > Casi nunca necesitas tocar el SCSS: como la familia se deriva del **acento
356
375
  > único** en tiempo de ejecución, sobrescribir `--hub-sys-color-<variante>` en CSS
357
376
  > plano — incluso en un subárbol — recalcula `-subtle` / `-border-subtle` /
358
- > `-emphasis` automáticamente. Los mapas + mixins son solo la mecánica interna,
359
- > útil si contribuyes al paquete o compilas tu propia variante de la paleta.
377
+ > `-emphasis` / `-on` automáticamente. Los mapas + mixins son solo la mecánica
378
+ > interna, útil si contribuyes al paquete o compilas tu propia variante de la paleta.
360
379
 
361
380
  ---
362
381
 
package/README.md CHANGED
@@ -27,25 +27,30 @@ component libraries for standalone apps.
27
27
  This package is the design-token foundation the rest of the **ng-hub-ui**
28
28
  ecosystem reads from:
29
29
 
30
- - [**ng-hub-ui-accordion**](https://www.npmjs.com/package/ng-hub-ui-accordion) (deprecated — use ng-hub-ui-panels)
31
30
  - [**ng-hub-ui-action-sheet**](https://www.npmjs.com/package/ng-hub-ui-action-sheet)
32
31
  - [**ng-hub-ui-avatar**](https://www.npmjs.com/package/ng-hub-ui-avatar)
32
+ - [**ng-hub-ui-badges**](https://www.npmjs.com/package/ng-hub-ui-badges)
33
33
  - [**ng-hub-ui-board**](https://www.npmjs.com/package/ng-hub-ui-board)
34
34
  - [**ng-hub-ui-breadcrumbs**](https://www.npmjs.com/package/ng-hub-ui-breadcrumbs)
35
+ - [**ng-hub-ui-buttons**](https://www.npmjs.com/package/ng-hub-ui-buttons)
35
36
  - [**ng-hub-ui-calendar**](https://www.npmjs.com/package/ng-hub-ui-calendar)
36
- - [**ng-hub-ui-dropdown**](https://www.npmjs.com/package/ng-hub-ui-dropdown)
37
37
  - [**ng-hub-ui-ds**](https://www.npmjs.com/package/ng-hub-ui-ds) ← You are here
38
38
  - [**ng-hub-ui-forms**](https://www.npmjs.com/package/ng-hub-ui-forms)
39
39
  - [**ng-hub-ui-history**](https://www.npmjs.com/package/ng-hub-ui-history)
40
+ - [**ng-hub-ui-icons**](https://www.npmjs.com/package/ng-hub-ui-icons)
41
+ - [**ng-hub-ui-loading**](https://www.npmjs.com/package/ng-hub-ui-loading)
42
+ - [**ng-hub-ui-metrics**](https://www.npmjs.com/package/ng-hub-ui-metrics)
40
43
  - [**ng-hub-ui-milestones**](https://www.npmjs.com/package/ng-hub-ui-milestones)
41
44
  - [**ng-hub-ui-modal**](https://www.npmjs.com/package/ng-hub-ui-modal)
42
45
  - [**ng-hub-ui-nav**](https://www.npmjs.com/package/ng-hub-ui-nav)
43
46
  - [**ng-hub-ui-paginable**](https://www.npmjs.com/package/ng-hub-ui-paginable)
44
47
  - [**ng-hub-ui-panels**](https://www.npmjs.com/package/ng-hub-ui-panels)
45
48
  - [**ng-hub-ui-portal**](https://www.npmjs.com/package/ng-hub-ui-portal)
49
+ - [**ng-hub-ui-signature**](https://www.npmjs.com/package/ng-hub-ui-signature)
46
50
  - [**ng-hub-ui-skeleton**](https://www.npmjs.com/package/ng-hub-ui-skeleton)
47
51
  - [**ng-hub-ui-sortable**](https://www.npmjs.com/package/ng-hub-ui-sortable)
48
52
  - [**ng-hub-ui-stepper**](https://www.npmjs.com/package/ng-hub-ui-stepper)
53
+ - [**ng-hub-ui-toast**](https://www.npmjs.com/package/ng-hub-ui-toast)
49
54
  - [**ng-hub-ui-utils**](https://www.npmjs.com/package/ng-hub-ui-utils)
50
55
 
51
56
  ---
@@ -179,8 +184,10 @@ These are live, re-basable CSS variables too, using the same directional
179
184
 
180
185
  ## 🎨 Semantic colours
181
186
 
182
- Each semantic colour (`primary` · `success` · `danger` · `warning` · `info`)
183
- exposes a **uniform family** of five tokens:
187
+ Each semantic variant exposes a **uniform family** of five tokens. The default set is
188
+ `primary` · `secondary` · `success` · `danger` · `warning` · `info` · `neutral` · `light` ·
189
+ `dark`, and it is **open**: every variant you add gets the same family (see
190
+ [How to customise it](#️-how-to-customise-it)).
184
191
 
185
192
  | Token | Typical use |
186
193
  | ----------------------------------- | ---------------------------------------------- |
@@ -188,7 +195,7 @@ exposes a **uniform family** of five tokens:
188
195
  | `--hub-sys-color-<v>-subtle` | Faint background (banners, alerts) |
189
196
  | `--hub-sys-color-<v>-border-subtle` | Faint border over the subtle background |
190
197
  | `--hub-sys-color-<v>-emphasis` | Legible text over the subtle background |
191
- | `--hub-sys-color-<v>-dark` | Dark variant of the colour |
198
+ | `--hub-sys-color-<v>-on` | Contrast text/icon colour laid **on** the accent |
192
199
 
193
200
  Usage example (a callout that matches the rest of the family):
194
201
 
@@ -250,7 +257,7 @@ The only non-Bootstrap names are the layout primitives that mirror the mixins: `
250
257
  .sr-label { @include hub.visually-hidden(); }
251
258
  ```
252
259
 
253
- Groups: **theme** (`theme()` — partial theming in one call: pass only the changed scales/accents as maps), **breakpoints** (`media-breakpoint-up/down` over the `$hub-breakpoints` map — the responsive variants `.d-md-*`, `.col-lg-*`, `.p-sm-*`… are generated from it), **layout** (`stack`, `cluster`, `grid`, `grid-fixed`, `row`, `col`, `offset`, `center`), **typography** (`font-family`, `font-size`, `font-weight`, `line-height`, `text-color`, `link-color`, `text-truncate`, `text-break`), **surfaces** (`bg`, `text-bg`, `border`, `border-color`, `radius`, `shadow`), **helpers** (`focus-ring`, `visually-hidden`, `stretched-link`, `ratio`, `clearfix`) and the **bridges** (`bridge-bootstrap` / `bridge-material` / `bridge-tailwind` / `bridge-open-props`).
260
+ Groups: **theme** (`theme()` — partial theming in one call: pass only the changed scales/accents as maps), **breakpoints** (`media-breakpoint-up/down` over the `$hub-breakpoints` map — the responsive variants `.d-md-*`, `.col-lg-*`, `.p-sm-*`… are generated from it), **layout** (`stack`, `cluster`, `grid`, `grid-fixed`, `row`, `col`, `offset`, `center`), **typography** (`font-family`, `font-size`, `font-weight`, `line-height`, `text-color`, `link-color`, `text-truncate`, `text-break`), **surfaces** (`bg`, `text-bg`, `border`, `border-color`, `radius`, `shadow`), **helpers** (`focus-ring`, `focus-ring-color`, `visually-hidden`, `stretched-link`, `ratio`, `clearfix`) and the **bridges** (`bridge-bootstrap` / `bridge-material` / `bridge-tailwind` / `bridge-open-props`).
254
261
 
255
262
  The full catalogue with live demos is documented at [hubui.dev/design-system](https://hubui.dev/en/design-system/).
256
263
 
@@ -313,52 +320,64 @@ Group your overrides under a theme attribute and activate it whenever you want:
313
320
  ## 🧩 SCSS functions (how it is generated internally)
314
321
 
315
322
  The semantic colour families are **not written by hand**, and a theme only ever
316
- sets the **accent** of each variant — `-subtle`, `-border-subtle` and `-emphasis`
317
- are derived **once** in `:root` with `color-mix()` from the live accent, surface
318
- and ink CSS variables. Adding a colour or a theme is uniform and boilerplate-free.
323
+ sets the **accent** of each variant — `-subtle`, `-border-subtle`, `-emphasis` and
324
+ `-on` are derived **once** in `:root` from the live accent, surface and ink CSS
325
+ variables. The variant names live in a single **open** Sass map, so adding a colour
326
+ or a theme is uniform and boilerplate-free.
319
327
 
320
328
  ```scss
321
- $hub-variants: primary, success, danger, warning, info;
322
-
323
- // One accent per variant, per theme — just the base colour.
324
- $hub-accents-light: (
329
+ // The ONE place that enumerates variant names. `!default`, so you can replace it
330
+ // wholesale before the import — or, better, merge into it with $hub-accents-extra.
331
+ $hub-accents: (
325
332
  primary: var(--hub-ref-color-blue-500, #0d6efd),
333
+ secondary: var(--hub-ref-color-gray-600, #6c757d),
326
334
  success: var(--hub-ref-color-green-500, #198754),
327
335
  danger: var(--hub-ref-color-red-500, #dc3545),
328
336
  warning: var(--hub-ref-color-yellow-500, #ffc107),
329
- info: var(--hub-ref-color-cyan-500, #0dcaf0)
330
- );
331
-
332
- // Sets ONLY --hub-sys-color-<variant> (the accent). Called in every theme block.
337
+ info: var(--hub-ref-color-cyan-500, #0dcaf0),
338
+ neutral: var(--hub-ref-color-gray-600, #6c757d),
339
+ light: var(--hub-ref-color-gray-100, #f8f9fa),
340
+ dark: var(--hub-ref-color-gray-900, #212529)
341
+ ) !default;
342
+
343
+ // Additive override — pass ONLY the variants you add or retune, keep the defaults.
344
+ $hub-accents-extra: () !default;
345
+ $hub-accents: map.merge($hub-accents, $hub-accents-extra);
346
+
347
+ // Sets ONLY --hub-sys-color-<variant> (the accent). Called in every theme block
348
+ // with that theme's own map, so a theme emits exactly the variants it re-tints.
333
349
  @mixin hub-color-accents($accents) {
334
- @each $name in $hub-variants {
335
- --hub-sys-color-#{$name}: #{map.get($accents, $name)};
350
+ @each $name, $color in $accents {
351
+ --hub-sys-color-#{$name}: #{$color};
336
352
  }
337
353
  }
338
354
 
339
355
  // Derives the role family from the live accent + surface + ink. Emitted ONCE in
340
- // :root; themes only override the inputs, so the family recomputes contextually.
356
+ // :root over the open set, so every variant — including the ones you added — gets
357
+ // its full family for free.
341
358
  @mixin hub-color-derive() {
342
- @each $name in $hub-variants {
359
+ @each $name in map.keys($hub-accents) {
343
360
  --hub-sys-color-#{$name}-subtle: color-mix(in oklch, var(--hub-sys-color-#{$name}) 12%, var(--hub-sys-surface-page, #fff));
344
361
  --hub-sys-color-#{$name}-border-subtle: color-mix(in oklch, var(--hub-sys-color-#{$name}) 35%, var(--hub-sys-surface-page, #fff));
345
362
  --hub-sys-color-#{$name}-emphasis: color-mix(in oklch, var(--hub-sys-color-#{$name}) 80%, var(--hub-sys-color-ink, #212529));
346
- --hub-sys-color-#{$name}-dark: var(--hub-sys-color-#{$name}-emphasis); // back-compat alias
363
+ // Grayscale contrast flip driven by the accent's own lightness: dark accents
364
+ // (L < .62) resolve to white text, light accents to near-black.
365
+ --hub-sys-color-#{$name}-on: oklch(from var(--hub-sys-color-#{$name}) clamp(0, (0.62 - l) * 1000, 1) 0 h);
347
366
  }
348
367
  }
349
368
 
350
369
  :root,
351
370
  [data-theme='light'] {
352
- @include hub-color-accents($hub-accents-light);
371
+ @include hub-color-accents($hub-accents);
353
372
  @include hub-color-derive();
354
373
  }
355
374
  ```
356
375
 
357
376
  > You almost never need to touch the SCSS: because the family is derived from the
358
377
  > **single accent** at runtime, overriding `--hub-sys-color-<variant>` in plain CSS
359
- > — even on a subtree — recomputes `-subtle` / `-border-subtle` / `-emphasis`
360
- > automatically. The maps + mixins are just the internal mechanism, useful if you
361
- > contribute to the package or compile your own palette variant.
378
+ > — even on a subtree — recomputes `-subtle` / `-border-subtle` / `-emphasis` /
379
+ > `-on` automatically. The maps + mixins are just the internal mechanism, useful if
380
+ > you contribute to the package or compile your own palette variant.
362
381
 
363
382
  ---
364
383