@keenmate/pure-css 1.1.1 → 1.2.0

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
@@ -3,6 +3,71 @@
3
3
  All notable changes to `@keenmate/pure-css` are documented here. Format based on
4
4
  [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
5
5
 
6
+ ## [1.2.0] — 2026-10-07 [PUBLISHED]
7
+
8
+ ### Added
9
+
10
+ - **Palette + neutral-text utilities graduated from `@keenmate/pure-admin-core`.**
11
+ The flat colour-apply helpers that consume pure-css's palette (`--pc-color-N` /
12
+ `--pc-color-N-text`) and text (`--pc-text-color-N`) tokens now live here beside
13
+ `.text-color-N` and the role colours, completing the foundation utility surface:
14
+ - **Palette property-forms (slots 1–9):** `.bg-color-N` (background),
15
+ `.border-color-N` (border), `.text-on-color-N` (contrast text only), and the
16
+ composite `.surface-color-N` (slot background + guaranteed-readable text). They
17
+ join the existing `.text-color-N`; all emit `!important` for cascade parity with
18
+ the role colours.
19
+ - **Neutral text hierarchy:** `.text-body` (explicit default body colour) and
20
+ `.text-secondary` (muted / subdued) → `--pc-text-color-1/2`, plus the compound
21
+ `.text-caption` and `.text-lead` shorthands.
22
+
23
+ These were temporarily homed in `pure-admin-core` so they were demo-able over the
24
+ `file:` link without a pure-css release; this is their permanent home. The
25
+ numbered `-color-N` helpers were also unprefixed from `pa-*-color-N` in that
26
+ cycle (see pure-admin Initiative 2). pure-admin-core drops its copies and
27
+ single-sources them from here — bump its `@keenmate/pure-css` dep to `^1.2.0`.
28
+
29
+ - **`--base-checkbox-scale` web-component bridge token** (`$base-checkbox-scale`,
30
+ default `1`). Multiplies a checkbox's own box width/height — NOT a CSS
31
+ `transform`, which pixel-snaps the fractionally-positioned mask glyph off-centre.
32
+ The box sizes as `calc(<base-size> * var(--base-checkbox-scale))` and the glyph
33
+ via `--base-icon-check-size`, so one knob resizes every checkbox in lockstep.
34
+
35
+ - **Role surface utilities — `.bg-{role}` / `.text-on-{role}` / `.surface-{role}`**
36
+ (`utilities.scss`). The role parallel of the numeric
37
+ `.{bg,text-on,surface}-color-N` family: fill from `--pc-{role}` (primary →
38
+ `--pc-accent`), on-fill contrast text from `--base-text-on-{role}` (the only
39
+ on-role contrast token — the foreground `.text-{role}` is a different colour).
40
+ `.bg-{role}` sets the role colour as background only, `.text-on-{role}` the
41
+ contrast text to pair with it, and `.surface-{role}` combines both in one class.
42
+ Emitted for primary / success / warning / danger / info, all `!important` for
43
+ cascade parity with the role text utilities.
44
+
45
+ - **Opt-in desktop overlay sidebar — `.sidebar-overlay`** (`_layout-responsive.scss`).
46
+ The mobile off-canvas drawer (fixed sheet that slides in/out with a fading
47
+ backdrop scrim) was refactored into a shared `sidebar-drawer-overlay` mixin
48
+ parameterised by a body qualifier and drawer width. The mobile
49
+ `@media (max-width: $mobile-breakpoint)` path calls it unqualified at a 90vw
50
+ sheet; the new `body.sidebar-overlay` caller applies the same drawer behaviour at
51
+ any width (normal `$sidebar-width`, 288px) so a burger can open a temporary
52
+ floating sidebar on desktop with the content usable behind it. The qualifier
53
+ composes onto `body` so the `body.loaded` transition gate and `.sidebar-visible`
54
+ open state stay same-element compounds, and RTL still slides the drawer off the
55
+ inline-start edge.
56
+
57
+ - **Foundation component catalog — `COMPONENTS.md` + `components.json`**
58
+ (`scripts/build-catalog.mjs`, `npm run catalog`). A generated manifest of the
59
+ foundation surface pure-admin's catalog deliberately doesn't track: the `pc-*`
60
+ components (grid, app-shell, fit engine, responsive / mode state hooks,
61
+ icon-hover) plus the unprefixed utility classes. Extraction is from the COMPILED
62
+ bundles on purpose — the grid / visibility / offset families and the utilities
63
+ are loop-generated, so only the compiled CSS is the complete list; a source-only
64
+ parse would miss every interpolated class. Each `pc-*` class is assigned to a
65
+ component by longest-prefix match against a hand-authored taxonomy, and the build
66
+ FAILS on any unclassified class (drift) or unused prefix (stale) so coverage
67
+ can't silently rot. Wired into `prepublishOnly` (build → catalog) and both files
68
+ ship in the package `files[]`, giving the svelte / phoenix wrappers a source of
69
+ truth to validate their non-`pa-*` emitted DOM against.
70
+
6
71
  ## [1.1.1] — 2026-09-26 [PUBLISHED]
7
72
 
8
73
  ### Fixed
package/COMPONENTS.md ADDED
@@ -0,0 +1,149 @@
1
+ # Pure CSS — Foundation Catalog
2
+
3
+ > **Auto-generated** by `scripts/build-catalog.mjs` from the compiled bundles.
4
+ > Do not edit by hand — re-run `npm run catalog` (after `npm run build`) when any `pc-*` class or utility changes.
5
+ > Machine-readable form: [`components.json`](./components.json).
6
+
7
+ Package version **1.2.0** · **11** pc-* components · **381** pc-* selectors · **718** utility classes.
8
+
9
+ This is the pure-css half of the wrapper-fidelity contract: the foundation (`pc-*` grid + app-shell + engines, and the unprefixed utility classes) that the pure-admin catalog intentionally does **not** track. The svelte / phoenix wrappers validate the non-`pa-*` classes they emit against this catalog.
10
+
11
+ ## pc-* components
12
+
13
+ | Component | Block | Category | Selectors |
14
+ |---|---|---|--:|
15
+ | Grid | `pc-row` | Grid | 290 |
16
+ | Layout scaffold | `pc-layout` | Layout & shell | 9 |
17
+ | Navbar & headers | `pc-navbar` | Layout & shell | 21 |
18
+ | Sidebar | `pc-sidebar` | Layout & shell | 22 |
19
+ | Footer | `pc-footer` | Layout & shell | 4 |
20
+ | Width containers | `pc-container` | Layout & shell | 5 |
21
+ | Fit (overflow engine) | `pc-fit` | Engines & state hooks | 6 |
22
+ | Responsive visibility | `pc-hide` | Engines & state hooks | 18 |
23
+ | Colour mode | `pc-mode` | Engines & state hooks | 2 |
24
+ | Container query context | `pc-cq` | Engines & state hooks | 1 |
25
+ | Icon hover | `pc-icon-hover` | Icon | 3 |
26
+
27
+ ## Grid
28
+
29
+ ### Grid — `pc-row`
30
+
31
+ Flexbox grid: pc-row container with pc-col auto / pc-col-auto content-width / pc-col-{5..100} percentage / fraction columns, responsive pc-col-{sm,md,lg,xl}-*, and pc-offset-* spacers. Wrappers emit these from <Column size md…> props.
32
+
33
+ - **Blocks & variants:** `pc-col`, `pc-col-1-12`, `pc-col-1-2`, `pc-col-1-3`, `pc-col-1-4`, `pc-col-1-5`, `pc-col-1-6`, `pc-col-10`, `pc-col-100`, `pc-col-11-12`, `pc-col-15`, `pc-col-2-3`, `pc-col-2-5`, `pc-col-20`, `pc-col-25`, `pc-col-3-4`, `pc-col-3-5`, `pc-col-30`, `pc-col-35`, `pc-col-4-5`, `pc-col-40`, `pc-col-45`, `pc-col-5`, `pc-col-5-12`, `pc-col-5-6`, `pc-col-50`, `pc-col-55`, `pc-col-60`, `pc-col-65`, `pc-col-7-12`, `pc-col-70`, `pc-col-75`, `pc-col-80`, `pc-col-85`, `pc-col-90`, `pc-col-95`, `pc-col-auto`, `pc-col-lg-1-12`, `pc-col-lg-1-2`, `pc-col-lg-1-3`, `pc-col-lg-1-4`, `pc-col-lg-1-5`, `pc-col-lg-1-6`, `pc-col-lg-10`, `pc-col-lg-100`, `pc-col-lg-11-12`, `pc-col-lg-15`, `pc-col-lg-2-3`, `pc-col-lg-2-5`, `pc-col-lg-20`, `pc-col-lg-25`, `pc-col-lg-3-4`, `pc-col-lg-3-5`, `pc-col-lg-30`, `pc-col-lg-35`, `pc-col-lg-4-5`, `pc-col-lg-40`, `pc-col-lg-45`, `pc-col-lg-5`, `pc-col-lg-5-12`, `pc-col-lg-5-6`, `pc-col-lg-50`, `pc-col-lg-55`, `pc-col-lg-60`, `pc-col-lg-65`, `pc-col-lg-7-12`, `pc-col-lg-70`, `pc-col-lg-75`, `pc-col-lg-80`, `pc-col-lg-85`, `pc-col-lg-90`, `pc-col-lg-95`, `pc-col-lg-auto`, `pc-col-md-1-12`, `pc-col-md-1-2`, `pc-col-md-1-3`, `pc-col-md-1-4`, `pc-col-md-1-5`, `pc-col-md-1-6`, `pc-col-md-10`, `pc-col-md-100`, `pc-col-md-11-12`, `pc-col-md-15`, `pc-col-md-2-3`, `pc-col-md-2-5`, `pc-col-md-20`, `pc-col-md-25`, `pc-col-md-3-4`, `pc-col-md-3-5`, `pc-col-md-30`, `pc-col-md-35`, `pc-col-md-4-5`, `pc-col-md-40`, `pc-col-md-45`, `pc-col-md-5`, `pc-col-md-5-12`, `pc-col-md-5-6`, `pc-col-md-50`, `pc-col-md-55`, `pc-col-md-60`, `pc-col-md-65`, `pc-col-md-7-12`, `pc-col-md-70`, `pc-col-md-75`, `pc-col-md-80`, `pc-col-md-85`, `pc-col-md-90`, `pc-col-md-95`, `pc-col-md-auto`, `pc-col-sm-1-12`, `pc-col-sm-1-2`, `pc-col-sm-1-3`, `pc-col-sm-1-4`, `pc-col-sm-1-5`, `pc-col-sm-1-6`, `pc-col-sm-10`, `pc-col-sm-100`, `pc-col-sm-11-12`, `pc-col-sm-15`, `pc-col-sm-2-3`, `pc-col-sm-2-5`, `pc-col-sm-20`, `pc-col-sm-25`, `pc-col-sm-3-4`, `pc-col-sm-3-5`, `pc-col-sm-30`, `pc-col-sm-35`, `pc-col-sm-4-5`, `pc-col-sm-40`, `pc-col-sm-45`, `pc-col-sm-5`, `pc-col-sm-5-12`, `pc-col-sm-5-6`, `pc-col-sm-50`, `pc-col-sm-55`, `pc-col-sm-60`, `pc-col-sm-65`, `pc-col-sm-7-12`, `pc-col-sm-70`, `pc-col-sm-75`, `pc-col-sm-80`, `pc-col-sm-85`, `pc-col-sm-90`, `pc-col-sm-95`, `pc-col-sm-auto`, `pc-col-xl-1-12`, `pc-col-xl-1-2`, `pc-col-xl-1-3`, `pc-col-xl-1-4`, `pc-col-xl-1-5`, `pc-col-xl-1-6`, `pc-col-xl-10`, `pc-col-xl-100`, `pc-col-xl-11-12`, `pc-col-xl-15`, `pc-col-xl-2-3`, `pc-col-xl-2-5`, `pc-col-xl-20`, `pc-col-xl-25`, `pc-col-xl-3-4`, `pc-col-xl-3-5`, `pc-col-xl-30`, `pc-col-xl-35`, `pc-col-xl-4-5`, `pc-col-xl-40`, `pc-col-xl-45`, `pc-col-xl-5`, `pc-col-xl-5-12`, `pc-col-xl-5-6`, `pc-col-xl-50`, `pc-col-xl-55`, `pc-col-xl-60`, `pc-col-xl-65`, `pc-col-xl-7-12`, `pc-col-xl-70`, `pc-col-xl-75`, `pc-col-xl-80`, `pc-col-xl-85`, `pc-col-xl-90`, `pc-col-xl-95`, `pc-col-xl-auto`, `pc-offset-10`, `pc-offset-15`, `pc-offset-20`, `pc-offset-25`, `pc-offset-30`, `pc-offset-35`, `pc-offset-40`, `pc-offset-45`, `pc-offset-5`, `pc-offset-50`, `pc-offset-55`, `pc-offset-60`, `pc-offset-65`, `pc-offset-70`, `pc-offset-75`, `pc-offset-80`, `pc-offset-85`, `pc-offset-90`, `pc-offset-95`, `pc-offset-lg-10`, `pc-offset-lg-15`, `pc-offset-lg-20`, `pc-offset-lg-25`, `pc-offset-lg-30`, `pc-offset-lg-35`, `pc-offset-lg-40`, `pc-offset-lg-45`, `pc-offset-lg-5`, `pc-offset-lg-50`, `pc-offset-lg-55`, `pc-offset-lg-60`, `pc-offset-lg-65`, `pc-offset-lg-70`, `pc-offset-lg-75`, `pc-offset-lg-80`, `pc-offset-lg-85`, `pc-offset-lg-90`, `pc-offset-lg-95`, `pc-offset-md-10`, `pc-offset-md-15`, `pc-offset-md-20`, `pc-offset-md-25`, `pc-offset-md-30`, `pc-offset-md-35`, `pc-offset-md-40`, `pc-offset-md-45`, `pc-offset-md-5`, `pc-offset-md-50`, `pc-offset-md-55`, `pc-offset-md-60`, `pc-offset-md-65`, `pc-offset-md-70`, `pc-offset-md-75`, `pc-offset-md-80`, `pc-offset-md-85`, `pc-offset-md-90`, `pc-offset-md-95`, `pc-offset-sm-10`, `pc-offset-sm-15`, `pc-offset-sm-20`, `pc-offset-sm-25`, `pc-offset-sm-30`, `pc-offset-sm-35`, `pc-offset-sm-40`, `pc-offset-sm-45`, `pc-offset-sm-5`, `pc-offset-sm-50`, `pc-offset-sm-55`, `pc-offset-sm-60`, `pc-offset-sm-65`, `pc-offset-sm-70`, `pc-offset-sm-75`, `pc-offset-sm-80`, `pc-offset-sm-85`, `pc-offset-sm-90`, `pc-offset-sm-95`, `pc-offset-xl-10`, `pc-offset-xl-15`, `pc-offset-xl-20`, `pc-offset-xl-25`, `pc-offset-xl-30`, `pc-offset-xl-35`, `pc-offset-xl-40`, `pc-offset-xl-45`, `pc-offset-xl-5`, `pc-offset-xl-50`, `pc-offset-xl-55`, `pc-offset-xl-60`, `pc-offset-xl-65`, `pc-offset-xl-70`, `pc-offset-xl-75`, `pc-offset-xl-80`, `pc-offset-xl-85`, `pc-offset-xl-90`, `pc-offset-xl-95`, `pc-row`
34
+ - **Modifiers / states:** `pc-col--grow`, `pc-col--no-padding`, `pc-col--shrink`, `pc-row--around`, `pc-row--between`, `pc-row--bottom`, `pc-row--center`, `pc-row--end`, `pc-row--middle`, `pc-row--no-gutter`, `pc-row--same-height`, `pc-row--stretch`, `pc-row--top`
35
+ - **SCSS:** `_pa-grid.scss`
36
+
37
+ ## Layout & shell
38
+
39
+ ### Layout scaffold — `pc-layout`
40
+
41
+ App shell scaffold: the pc-layout grid (inner / main / content / sidebar / footer regions) with sticky + icon-collapse modifiers.
42
+
43
+ - **Blocks & variants:** `pc-layout`
44
+ - **Elements:** `pc-layout__content`, `pc-layout__footer`, `pc-layout__inner`, `pc-layout__main`, `pc-layout__sidebar`, `pc-layout__sidebar__nav`
45
+ - **Modifiers / states:** `pc-layout--sticky`, `pc-layout__sidebar--icon-collapse`
46
+ - **SCSS:** `_layout-container.scss`, `_layout-responsive.scss`, `_sidebar-states.scss`, `_sidebar.scss`
47
+
48
+ ### Navbar & headers — `pc-navbar`
49
+
50
+ Top navbar (start / center / end, burger, inner, profile button), the navbar search pill, the nav menu, and the app-header / page-header regions.
51
+
52
+ - **Blocks & variants:** `pc-app-header`, `pc-navbar`, `pc-navbar-search`, `pc-navmenu`, `pc-page-header`
53
+ - **Elements:** `pc-app-header__version`, `pc-navbar__burger`, `pc-navbar__center`, `pc-navbar__end`, `pc-navbar__inner`, `pc-navbar__profile-btn`, `pc-navbar__start`, `pc-navmenu__dropdown`, `pc-navmenu__link`, `pc-navmenu__more-chevron`, `pc-navmenu__more-menu`
54
+ - **Modifiers / states:** `pc-navmenu__dropdown--level2`, `pc-navmenu__item--active`, `pc-navmenu__item--has-dropdown`, `pc-navmenu__item--more`, `pc-navmenu__more-menu--open`
55
+ - **SCSS:** `_layout-responsive.scss`, `_navbar-elements.scss`, `_navbar.scss`
56
+
57
+ ### Sidebar — `pc-sidebar`
58
+
59
+ Collapsible sidebar (item / link / label / icon / chevron / submenu / toggle / search) with the resize handle and resized / resizing state hooks.
60
+
61
+ - **Blocks & variants:** `pc-sidebar-resize`, `pc-sidebar-resized`, `pc-sidebar-resizing`
62
+ - **Elements:** `pc-sidebar__chevron`, `pc-sidebar__divider`, `pc-sidebar__icon`, `pc-sidebar__item`, `pc-sidebar__label`, `pc-sidebar__link`, `pc-sidebar__nav`, `pc-sidebar__search`, `pc-sidebar__search-field`, `pc-sidebar__search-icon`, `pc-sidebar__section`, `pc-sidebar__submenu`, `pc-sidebar__toggle`
63
+ - **Modifiers / states:** `pc-sidebar-resize--active`, `pc-sidebar__item--open`, `pc-sidebar__link--active`, `pc-sidebar__search--input`, `pc-sidebar__submenu--open`, `pc-sidebar__toggle--active`
64
+ - **SCSS:** `_icon-hover.scss`, `_layout-responsive.scss`, `_sidebar-states.scss`, `_sidebar.scss`
65
+
66
+ ### Footer — `pc-footer`
67
+
68
+ App footer with start / center / end regions.
69
+
70
+ - **Blocks & variants:** —
71
+ - **Elements:** `pc-footer__center`, `pc-footer__end`, `pc-footer__start`
72
+ - **Modifiers / states:** `pc-footer__end--vertical`
73
+ - **SCSS:** `_layout-container.scss`
74
+
75
+ ### Width containers — `pc-container`
76
+
77
+ Max-width content containers at each breakpoint (sm / md / lg / xl / 2xl).
78
+
79
+ - **Blocks & variants:** `pc-container-2xl`, `pc-container-lg`, `pc-container-md`, `pc-container-sm`, `pc-container-xl`
80
+ - **SCSS:** —
81
+
82
+ ## Engines & state hooks
83
+
84
+ ### Fit (overflow engine) — `pc-fit`
85
+
86
+ The fit degradation engine's self-contained "•••" overflow flyout (relocation target for data-pc-fit-target="floating-menu") plus the pc-fit-hidden state class the engine toggles.
87
+
88
+ - **Blocks & variants:** `pc-fit-hidden`
89
+ - **Elements:** `pc-fit-flyout__dots`, `pc-fit-flyout__item`, `pc-fit-flyout__panel`, `pc-fit-flyout__trigger`
90
+ - **Modifiers / states:** `pc-fit-flyout__panel--open`
91
+ - **SCSS:** `_fit-flyout.scss`, `_navbar-elements.scss`
92
+
93
+ ### Responsive visibility — `pc-hide`
94
+
95
+ Breakpoint show / hide hooks: pc-hide / pc-show, their per-breakpoint and -below variants.
96
+
97
+ - **Blocks & variants:** `pc-hide`, `pc-hide-below-lg`, `pc-hide-below-md`, `pc-hide-below-sm`, `pc-hide-below-xl`, `pc-hide-lg`, `pc-hide-md`, `pc-hide-sm`, `pc-hide-xl`, `pc-show`, `pc-show-below-lg`, `pc-show-below-md`, `pc-show-below-sm`, `pc-show-below-xl`, `pc-show-lg`, `pc-show-md`, `pc-show-sm`, `pc-show-xl`
98
+ - **SCSS:** `_pa-grid.scss`
99
+
100
+ ### Colour mode — `pc-mode`
101
+
102
+ Light / dark mode root hooks (pc-mode-light / pc-mode-dark) that select which --pc-* / --base-* value set applies.
103
+
104
+ - **Blocks & variants:** `pc-mode-dark`, `pc-mode-light`
105
+ - **SCSS:** `_base-css-variables.scss`
106
+
107
+ ### Container query context — `pc-cq`
108
+
109
+ Marks an element as a container-query context so descendant components can respond to the element's width rather than the viewport.
110
+
111
+ - **Blocks & variants:** `pc-cq`
112
+ - **SCSS:** `utilities.scss`
113
+
114
+ ## Icon
115
+
116
+ ### Icon hover — `pc-icon-hover`
117
+
118
+ Per-set icon hover strategy hooks: pc-icon-hover with -fill / -highlight variants (FA weight-flip / recolour / two-asset swap configured per icon set).
119
+
120
+ - **Blocks & variants:** `pc-icon-hover`, `pc-icon-hover-fill`, `pc-icon-hover-highlight`
121
+ - **SCSS:** `_icon-hover.scss`
122
+
123
+ ## Utilities
124
+
125
+ **718** unprefixed utility classes across **21** families (harvested from compiled `dist/css/utilities.css`). Full per-class list in [`components.json`](./components.json) → `utilities.classes`.
126
+
127
+ | Family | Count | Examples |
128
+ |---|--:|---|
129
+ | background (palette) | 9 | `bg-color-1`, `bg-color-2`, `bg-color-3`, `bg-color-4`, `bg-color-5`, `bg-color-6` … |
130
+ | background (role / named) | 5 | `bg-danger`, `bg-info`, `bg-primary`, `bg-success`, `bg-warning` |
131
+ | border (width / side / style / colour) | 14 | `border`, `border-0`, `border-bottom`, `border-bottom-0`, `border-dashed`, `border-dotted` … |
132
+ | border colour (palette) | 9 | `border-color-1`, `border-color-2`, `border-color-3`, `border-color-4`, `border-color-5`, `border-color-6` … |
133
+ | border radius | 8 | `rounded`, `rounded-0`, `rounded-bottom`, `rounded-circle`, `rounded-left`, `rounded-lg` … |
134
+ | box shadow | 4 | `shadow`, `shadow-lg`, `shadow-none`, `shadow-sm` |
135
+ | display | 6 | `d-block`, `d-flex`, `d-inline`, `d-inline-block`, `d-inline-flex`, `d-none` |
136
+ | flexbox | 25 | `align-items-baseline`, `align-items-center`, `align-items-end`, `align-items-start`, `align-items-stretch`, `flex-1` … |
137
+ | font family | 4 | `font-family-mono`, `font-family-sans`, `font-family-serif`, `font-family-system` |
138
+ | gap | 36 | `gap-0`, `gap-1`, `gap-10`, `gap-12`, `gap-16`, `gap-2` … |
139
+ | height (incl. min / max, rem + viewport) | 125 | `h-1-2`, `h-1-3`, `h-1-4`, `h-100`, `h-2-3`, `h-25` … |
140
+ | margin | 140 | `m-0`, `m-1`, `m-10`, `m-12`, `m-16`, `m-2` … |
141
+ | padding | 133 | `p-0`, `p-1`, `p-10`, `p-12`, `p-16`, `p-2` … |
142
+ | position | 5 | `position-absolute`, `position-fixed`, `position-relative`, `position-static`, `position-sticky` |
143
+ | surface (palette) | 9 | `surface-color-1`, `surface-color-2`, `surface-color-3`, `surface-color-4`, `surface-color-5`, `surface-color-6` … |
144
+ | surface (role / named) | 5 | `surface-danger`, `surface-info`, `surface-primary`, `surface-success`, `surface-warning` |
145
+ | text (colour / alignment / wrap) | 12 | `text-body`, `text-caption`, `text-center`, `text-danger`, `text-info`, `text-lead` … |
146
+ | text colour (palette) | 9 | `text-color-1`, `text-color-2`, `text-color-3`, `text-color-4`, `text-color-5`, `text-color-6` … |
147
+ | text-on (palette contrast) | 9 | `text-on-color-1`, `text-on-color-2`, `text-on-color-3`, `text-on-color-4`, `text-on-color-5`, `text-on-color-6` … |
148
+ | text-on (role contrast) | 5 | `text-on-danger`, `text-on-info`, `text-on-primary`, `text-on-success`, `text-on-warning` |
149
+ | width (incl. min / max, rem variants) | 146 | `maxw-1-2`, `maxw-1-3`, `maxw-1-4`, `maxw-10`, `maxw-100`, `maxw-15` … |
package/README.md CHANGED
@@ -12,15 +12,27 @@ It's the shared layer the whole Keenmate stack agrees on:
12
12
  top of it, and every Keenmate web/Svelte component reads its colours from the same `--base-*`
13
13
  variables.
14
14
 
15
+ ## What's New in 1.2.0
16
+
17
+ > **Upgrade note — additive for pure-css, a coordinated rename downstream.** Every
18
+ > change here is purely additive to pure-css itself (new classes and one new token;
19
+ > nothing removed), so a pure-css-only upgrade is drop-in. The breaking part is
20
+ > downstream: `pure-admin-core` must bump its `@keenmate/pure-css` dependency to
21
+ > `^1.2.0` and drop its own copies of the palette / neutral-text helpers (now
22
+ > single-sourced here), and in that same cycle the numbered colour utilities lost
23
+ > their `pa-` prefix — `.pa-bg-color-N` → `.bg-color-N`, `.pa-text-color-N` →
24
+ > `.text-color-N`, etc. Any markup still using the prefixed names must be updated.
25
+
26
+ - **Utilities — palette + neutral-text helpers graduated from pure-admin-core** — the flat colour-apply helpers that consume pure-css's palette (`--pc-color-N` / `--pc-color-N-text`) and text-hierarchy (`--pc-text-color-N`) tokens now live here beside `.text-color-N`: the property-forms `.bg-color-N` / `.border-color-N` / `.text-on-color-N` and the composite `.surface-color-N` for slots 1–9, plus neutral `.text-body` / `.text-secondary` and the `.text-caption` / `.text-lead` shorthands. They were temporarily homed in `pure-admin-core` so they were demo-able over the `file:` link without a release; this is their permanent home, and pure-admin-core now single-sources them from here (bump its dep to `^1.2.0`).
27
+ - **Utilities — role surface helpers (`.bg-{role}` / `.text-on-{role}` / `.surface-{role}`)** — the role parallel of the numeric `-color-N` family, for primary / success / warning / danger / info. `.bg-{role}` paints the role fill (`--pc-{role}`, primary → `--pc-accent`), `.text-on-{role}` supplies the on-fill contrast text (`--base-text-on-{role}`, distinct from the foreground `.text-{role}`), and `.surface-{role}` combines both in one class — all `!important` for cascade parity with the role text utilities.
28
+ - **Shell — opt-in desktop overlay sidebar (`.sidebar-overlay`)** — the mobile off-canvas drawer was refactored into a shared `sidebar-drawer-overlay` mixin, and a new `body.sidebar-overlay` caller reuses it on desktop at the normal 288px `$sidebar-width`: a burger opens a temporary floating sidebar (fixed sheet sliding in with a fading backdrop) over usable content, rather than reflowing the layout. RTL and the `body.loaded` first-paint transition gate are preserved.
29
+ - **Tooling — foundation component catalog (`COMPONENTS.md` / `components.json`)** — a new `npm run catalog` (`scripts/build-catalog.mjs`) generates a human- and machine-readable manifest of the `pc-*` components and unprefixed utilities from the compiled bundles, so the svelte / phoenix wrappers have a source of truth to validate their emitted DOM against. It assigns every `pc-*` class to a component by longest-prefix match against a hand-authored taxonomy and fails the build on any unclassified class or unused prefix, so coverage can't drift; it's wired into `prepublishOnly` and both files ship in the package.
30
+ - **Theming — `--base-checkbox-scale` bridge token** — a new `$base-checkbox-scale` (default `1`) mirrored from `@keenmate/base-css-variables`, emitted as `--base-checkbox-scale`. It multiplies a checkbox's own box width/height (`calc(<base-size> * var(--base-checkbox-scale))`) rather than a `transform: scale()` that would pixel-snap the mask glyph off-centre, so one knob resizes every checkbox in lockstep (paired with `--base-icon-check-size`).
31
+
15
32
  ## What's New in 1.1.1
16
33
 
17
34
  - **Theming — downstream themes can finally override `$base-*` at compile time** — `_base-css-variables.scss` loaded its `$`-vocabulary with `@use 'variables/index' as *`, but Sass won't re-expose a member that already exists in the importing global scope, so any theme that set `$base-*` values *before* importing (the whole point of the `!default` contract) crashed with *"both define a variable named $base-accent-color"* — the workflow documented in that file compiled only when the theme overrode nothing, and the first real theme (`keen-docs-themes/cobalt2`) couldn't build. Switching to `@import 'variables/index'` shares the single global scope the `!default` mechanism relies on (the same reason `variables/_index.scss` uses `@import`), so `$base-*` overrides now land. It's behaviour-preserving for the prebuilt CSS — all seven artifacts rebuilt with every emitted `--base-*` name and value identical — and pure-css's own `@use … as bcv` entry points are unchanged. This landed just after the 1.1.0 tarball was cut, so 1.1.1 is the first release to actually ship it.
18
35
 
19
- ## What's New in 1.1.0
20
-
21
- - **Icons — hover affordance for interactive controls, no JS (`_icon-hover.scss`)** — icons inside an enabled control now react on `:hover` through pure CSS, driven by convention plus marker classes a wrapper stamps: masked `.pa-icon` glyphs that declared `--pa-icon-src-hover` swap to their filled source (automatic; a no-op for outline-only sets like Lucide), Font Awesome `<i>` marked `.pc-icon-hover-fill` flips regular → solid on the `font-weight` axis (needs the FA Pro `far` face), and outline icons marked `.pc-icon-hover-highlight` recolour to `--pc-icon-hover-color` (default `--pc-accent`) for sets with no solid form. The foundation applies it to the shell context it owns (`.pc-sidebar__link:hover`) and ships a generic opt-in wrapper `.pc-icon-hover` for any enabled control. Crucially the behaviour is exposed as the `pc-icon-hover-effects` SCSS mixin, so component layers (pure-admin core on `.pa-btn` / `.pa-tabs__item`, etc.) apply the exact same effects to their own selectors from one shared definition rather than redefining them. Additive — no change to existing output.
22
- - **Sidebar — hover colours snap instead of fading** — `.pc-sidebar__link`, the submenu toggle, and the sidebar search trigger animated their hover with `transition: all $transition-fast`, which swept `color` / `background-color` so the hover tint faded in and felt sluggish. Their hover changes colours only (no motion), so per the "colours snap; transitions are motion-only" rule the transition was pure colour animation and has been removed — hover colours now snap. The genuine motion transitions are untouched: the submenu chevron rotation (`transform`) and the icon-collapse label fade (`opacity` / `width`).
23
-
24
36
  ## Why
25
37
 
26
38
  pure-css is a **standalone foundation** you drop onto any surface — a docs site, a marketing page, a