@keenmate/pure-css 1.0.0-rc06 → 1.0.0-rc08

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
@@ -1,341 +1,491 @@
1
- # Changelog
2
-
3
- All notable changes to `@keenmate/pure-css` are documented here. Format based on
4
- [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
5
-
6
- ## [1.0.0-rc06] — 2026-08-30
7
-
8
- ### Fixed
9
-
10
- - **The app shell now renders standalone component `--pc-*` tokens fall back to
11
- `--base-*`.** rc05 relocated the shell into the foundation, but its CSS
12
- hard-referenced component tokens (`--pc-navbar-bg`, `--pc-sidebar-*`,
13
- `--pc-footer-*`, `--pc-card-bg`, `--pc-input-bg`) that pure-css does **not**
14
- emit those are pure-admin's `output-pc-component-variables` contract. So a
15
- consumer linking `base.css` / `pure-css.css` alone (keen-docs hit this) got an
16
- unstyled navbar/sidebar. Every such reference now carries a `--base-*` fallback
17
- traced from the token's own derivation: `var(--pc-navbar-bg, var(--base-main-bg))`,
18
- `var(--pc-sidebar-bg, var(--base-page-bg))`, navbar/sidebar text →
19
- `--base-text-color-1/2`, borders `--base-border-color`, submenu surfaces →
20
- `--base-subtle-bg`, input → `--base-input-bg`. This makes `--pc-*` an *optional*
21
- override layer over a guaranteed `--base-*` floor link only the base vars and
22
- the shell just works; set `--pc-navbar-bg` to tune the bar independently of the
23
- page. 40 references across the eight shell partials.
24
- - **Dangling token references in `_fit-flyout.scss`.** The fit-flyout trigger
25
- referenced `--pc-accent-color` (defined nowhere the token is `--pc-accent`)
26
- with no fallback, so its focus outline was inert; and `--pc-hover-bg` (also
27
- undefined) with only an rgba literal. Repointed to
28
- `var(--pc-accent, var(--base-accent-color))` and
29
- `var(--pc-hover-bg, var(--base-hover-bg, rgba(…)))`.
30
-
31
- ### Changed
32
-
33
- - **Unified the `--pc-border-radius*` scale with the `--base-border-radius-*`
34
- contract the components already use.** pure-css shipped two disconnected radius
35
- systems: `--base-border-radius-sm/md/lg` (the unitless rem-multipliers
36
- `0.4/0.6/0.8` every web/svelte component reads e.g. web-multiselect's
37
- `calc(var(--base-border-radius-md) * --ms-rem)`), and its OWN
38
- `--pc-border-radius-sm/base/lg` as hardcoded `2px/4px/8px` literals disconnected
39
- from the base layer. On one themed page a `<keen-web-multiselect>` and a pure-css
40
- `.rounded` element rounded differently, and a runtime `--base-border-radius-*`
41
- override re-rounded the components but not pure-css's own elements. The three
42
- `--pc-border-radius*` tokens now derive from the base contract —
43
- `calc(var(--base-border-radius-{sm,md,lg}, <default>) * 1rem)` (unsuffixed
44
- `--pc-border-radius` = the `-md` mid step) — mirroring how `--pc-border-color`
45
- already tracked `--base-border-color`. **Rendered radii change** to match the
46
- ecosystem: `-sm` 2px → 4px, mid 4px 6px, `-lg` 8px (unchanged). Overriding
47
- `--base-border-radius-*` now re-rounds pure-css and the components together.
48
-
49
- ## [1.0.0-rc05] 2026-08-27 [PUBLISHED]
50
-
51
- ### Added
52
-
53
- - **The app shell moves into the foundation — navbar, sidebar, and layout
54
- container.** pure-css was variables + grid + utilities; rc05 also relocates the
55
- structural app-shell layer out of pure-admin-core, so a standalone page (docs
56
- site, portal) gets the same navbar/sidebar/layout chrome as a full pure-admin
57
- app without pulling in the component library. Seven new partials, all `@use`d
58
- into the `pure-css.css` **bundle only** (base.css / grid.css / utilities.css
59
- untouched; no new standalone artifact):
60
- - `_navbar.scss` + `_navbar-elements.scss` the fixed navbar (`.pc-navbar`
61
- with `__inner`/`__start`/`__center`/`__end` regions) and its elements (burger
62
- menu, brand wordmark `.pc-app-header`, nav menu `.pc-navmenu`, page title
63
- `.pc-page-header`, profile button, theme switcher).
64
- - `_sidebar.scss` + `_sidebar-states.scss` the sidebar nav with nested
65
- submenus (`.pc-sidebar`, `.pc-layout__sidebar`, drag-to-resize
66
- `.pc-sidebar-resize`) and its hidden / icon-collapse / expanded states.
67
- - `_layout-container.scss` the layout wrapper (`.pc-layout` with
68
- `__inner`/`__main`/`__content`/`__footer` and the `.pc-footer__*` regions),
69
- including sticky/scroll content modes. Emitting `.pc-layout__main` here also
70
- gives the grid's container-query responsive columns (`.pc-col-md-*`) their
71
- documented automatic containment context in the same bundle (the
72
- `_pa-grid.scss` note is corrected from the pre-rc04 `.pa-layout__main` to
73
- `.pc-layout__main`).
74
- - `_layout-responsive.scss` — the mobile/tablet media queries for the shell.
75
- - `_resize-handle.scss` a mixin-only partial (emits nothing on its own)
76
- providing the shared grab-knob look `@use`d by the sidebar resize handle and
77
- splitter gutters.
78
- - `_fit-flyout.scss` — the Fit engine's floating-menu sink
79
- (`.pc-fit-flyout__*`): a `•••` trigger + a `<body>`-parented panel that
80
- `fit.js` fills on demand when slots relocate out of the row.
81
-
82
- pure-admin-core keeps same-named partials that now just `@forward` these, so the
83
- shell is single-sourced in the foundation and the two can't drift.
84
-
85
- - **The shell's behaviour ships too — a dependency-free JS runtime (`src/js/`).**
86
- The shell is no longer styling-only: the foundation now carries the vanilla-JS
87
- runtime that drives it, so pure-css is no longer a CSS-only package. Shipped
88
- **as source** (no build step) via a new `./js` export (and `./js/*` for
89
- individual engines); `files` gains `src/js/`.
90
- - `pure-css.js` installs the `window.pureCss` namespace a tiny event bus,
91
- live viewport / OS-colour-scheme / capability-first device sources, overlay
92
- primitives (scroll-lock, keyboard-inset), an open-menu registry, a shared
93
- `config` baseline (single-sourced from SCSS via `--pc-*` vars), and
94
- `components.initAll(scope)`. Load-order-safe and stands alone when pure-admin
95
- is absent; `pure-admin.js` adopts the same buses by reference on top.
96
- - `fit.js` — the Fit engine (`data-pc-fit` = hide / steps / relocate). It
97
- **absorbs the former `navbar-collapse.js`** (progressive nav folding via
98
- `data-pc-fit-nav`, sinking items to the sidebar or a generated "More" menu),
99
- so that separate file no longer exists.
100
- - `navbar-dropdown.js` (tap-toggle nav dropdowns/submenus),
101
- `sidebar-resize.js` (drag-to-resize the sidebar), and
102
- `container-breakpoint.js` (container-query breakpoint driver).
103
-
104
- Shell CSS is authored no-JS-safe, so styling degrades gracefully rather than
105
- breaking when the runtime isn't loaded.
106
-
107
- ### Fixed
108
-
109
- - **Migrated the dead `data-pa-nav-collapse` hook to `data-pc-fit-nav`.** The
110
- relocated nav-collapse CSS keyed on the pre-rc04 `pa-`-branded
111
- `[data-pa-nav-collapse]` attribute driven by the old `navbar-collapse.js`;
112
- since that engine is now merged into `fit.js` (which reads `data-pc-fit-nav`),
113
- the selectors in `_navbar-elements.scss` / `_layout-responsive.scss` were stale
114
- and matched nothing. Repointed at `[data-pc-fit-nav]` and corrected the
115
- companion comments (`navbar-collapse.js` → `fit.js`). Also de-branded the fit
116
- hide-class `.pa-fit-hidden` `.pc-fit-hidden`.
117
-
118
- ### Internal
119
-
120
- - **GitHub Actions release workflow (`.github/workflows/release.yml`).** On a `v*.*.*`
121
- tag push, builds the CSS (`npm ci` + `npm run build`) and publishes a GitHub Release
122
- with a `pure-css-<version>.zip` (bundling `dist/`, `src/scss/`, `README.md`,
123
- `CHANGELOG.md`, `LICENSE` the same set as the package `files`, so the zip is a
124
- toolchain-free drop-in for consumers who don't use npm) plus a `.sha256` checksum.
125
- Auto-generated release notes; tags containing `-` (rc) publish as a pre-release.
126
- Mirrors pure-admin-core's release workflow, adapted for this single-package repo.
127
- - **Exhaustive, data-driven utilities e2e coverage.** Rewrote `e2e/utilities.spec.ts`
128
- from a handful of spot-checks into a hard value assertion for 655 of the 664 shipped
129
- utility classes (the 9 `auto` sizing classes `m-auto` + per-side, `w-auto`, `h-auto` —
130
- are layout-resolved and covered behaviourally instead). Each family measures every one
131
- of its classes' computed styles in a single in-browser pass, then diffs in Node so a
132
- failure lists exactly which classes are off; the expectations independently encode the
133
- 10px-rem contract and the documented scales rather than reading them back from the CSS,
134
- so a failure means the compiled output disagrees with the contract or the contract
135
- regressed. Renamed the fixture `test/utilities.html` `test/utilities-scale.html` with
136
- definite-size `#w-parent` / `#h-parent` containers so percentage widths/heights resolve
137
- to known px. Test-only — no change to shipped CSS.
138
-
139
- ## [1.0.0-rc04] 2026-08-26 [PUBLISHED]
140
-
141
- ### Changed (BREAKING)
142
-
143
- - **pure-css now ships only the BASE token contract component tokens moved to
144
- the consumer that owns the components.** pure-css is a *foundation*: its
145
- bundles (`pure-css.css`, `base.css`) now emit only the ~46 base `--pc-*` tokens
146
- its own CSS consumes or exposes as universal theming primitives (surfaces,
147
- text, accent, links, border, the semantic role identities + their utility text
148
- colours, the theme palette slots, the radius scale). The ~165 **component**
149
- tokens (`--pc-btn-*`, `--pc-card-*`, `--pc-table-*`, `--pc-alert-*`, badges,
150
- tooltips, panels, command palette, multiselect, sentiment scale, form spacing,
151
- the derived contextual surfaces, admin layout chrome) are no longer emitted by
152
- the foundation. They are pure-admin's contract.
153
- - `output-pc-css-variables` is now base-only. The component tokens are emitted
154
- by the new **`output-pc-component-variables`** mixin (+ the existing
155
- `output-pc-alert-variables-{light,dark}`), which pure-css still *defines*
156
- (they read the shared `$`-variable vocabulary in `variables/*`, so they must
157
- be authored where that vocabulary is in scope) but does **not** call from its
158
- own bundle. Consumers that ship the components — pure-admin core, every
159
- theme — opt in by `@include output-pc-component-variables` alongside
160
- `output-pc-css-variables`.
161
- - **Theme authors / anyone calling the emit mixins must add
162
- `@include output-pc-component-variables;`** (after `output-pc-css-variables`)
163
- or lose every component token. Consumers of the *compiled* theme/core CSS are
164
- unaffectedthe emitted token set is identical, just split across two mixins.
165
- - **Every emitted CSS variable de-branded from `--pa-*` to `--pc-*`.** pure-css is
166
- a *foundation*, but it still emitted its entire runtime custom-property surface
167
- under pure-admin's `pa` brand. The full `--pa-*` set (~210 vars: `--pa-accent`,
168
- `--pa-text-color-*`, `--pa-card-bg`, `--pa-border-*`, the contextual /alert sets,
169
- `--pa-color-1..9` + `-text`, the new `--pc-*` form-spacing family already shipped
170
- this cut, etc.) is renamed to `--pc-*`. This completes the same de-branding the
171
- grid/mode classes started abovenothing pure-admin-branded remains in the
172
- foundation's output.
173
- - **The emit mixins move too:** `output-pa-css-variables` → `output-pc-css-variables`,
174
- `output-pa-alert-variables-light` / `-dark` `output-pc-alert-variables-*`.
175
- (`output-base-css-variables` is unchanged`--base-*` is a separate, neutral
176
- web-component contract and stays.)
177
- - **Untouched:** `--base-*` (web-component bridge), `--page-loader-*` (pre-FOUC
178
- loader), and the `.pa-color-{name}` colour-variant **class** (a class, not a
179
- `--pa-` variable).
180
- - **Migration:** a boundary-aware replace of the string `--pa-` → `--pc-` across
181
- markup, stylesheets, inline `style="--pa-…"`, JS `getPropertyValue`/`setProperty`
182
- calls, and every theme's `:root` / dark-mode `--pa-*` override block. Safe
183
- because the leading `--` + trailing `-` can't match `--base-*` or `--page-loader-*`.
184
- pure-admin, its demo, all 16 themes, and the svelte/keen wrappers migrate in
185
- lockstep with this release.
186
- - **Grid classes renamed from the consumer-branded `pa-` to the foundation's own
187
- `pc-` prefix.** `.pa-row` → `.pc-row`, `.pa-col*` `.pc-col*` (all percentage /
188
- fraction / responsive / `--grow`/`--shrink`/`--no-padding` variants),
189
- `.pa-offset*` `.pc-offset*`, `.pa-cq` `.pc-cq`, `.pa-hide*` `.pc-hide*`,
190
- `.pa-show*` `.pc-show*`. The grid is a pure-css *foundation* primitive, so it
191
- should not carry pure-admin's (`pa`) brand — this de-couples it. **No dual-emit:**
192
- the old `pa-*` grid classes are gone. Consumers must migrate markup
193
- (`class="pa-col-1-2"` → `class="pc-col-1-2"`) a boundary-aware find/replace
194
- (careful: `pa-col` is a substring of `pa-color-*`, which must NOT be touched).
195
- pure-admin, its demo, and the svelte/keen wrappers are migrated in lockstep.
196
- - **Light/dark mode scope classes renamed `.pa-mode-*``.pc-mode-*`.**
197
- The light/dark scopes the foundation emits its variables against (and that apps
198
- toggle on `<body>`) are foundation-owned, so they move to the `pc-` prefix too.
199
- `output-pc-css-variables` now emits at `:root, .pc-mode-light, .pc-mode-dark`.
200
- Consumers toggling the class in JS (`classList.add('pc-mode-dark')`) and themes'
201
- dark-mode blocks migrate in lockstep. (Safe replace: the string `pa-mode-` →
202
- `pc-mode-`; `pa-modal` is untouched since `mode` ≠ `moda`.)
203
-
204
- ### Added
205
-
206
- - **Sizing utilities consolidated into the foundation.** The universal sizing/flex
207
- utilities that had been left in pure-admin now live here, so a standalone
208
- pure-css page has the full set: viewport heights `h-full` / `h-screen` /
209
- `min-h-full` / `min-h-screen` / `max-h-full` / `max-h-screen`, and the
210
- Tailwind-style flex shorthands `flex-1` / `flex-auto` / `flex-initial` /
211
- `flex-none` / `flex-grow` / `flex-shrink` (alongside the existing
212
- `flex-grow-0/1`, `flex-shrink-0/1`). pure-css already owned the width/height %
213
- + rem scales (`w-*`/`h-*`, `wr-*`/`hr-*`) and the full min/max families
214
- (`minw-*`/`maxh-*`/`minwr-*`/`maxhr-*`/…); pure-admin's duplicate rem-height
215
- `h-Nx`/`min-h-Nx`/`max-h-Nx` set (byte-identical to `hr-N`/`minhr-N`/`maxhr-N`)
216
- is retired in favour of the foundation's `hr-`/`wr-` naming (`r` = rem).
217
- - **Complete form-spacing contract as runtime CSS variables, under a pure-css-owned
218
- `--pc-` namespace.** `output-pc-css-variables` now emits the full anatomy of a
219
- form's spacing at `:root`, so every consumer (pure-admin, keen-docs,
220
- keen-pure-admin) shares one contract instead of re-declaring `var()` chains or
221
- being stuck with compile-time-only margins:
222
- - Vertical rhythm: `--pc-label-gap` (label control), `--pc-help-gap`
223
- (control → help/error), `--pc-field-gap` (field → field),
224
- `--pc-form-actions-offset` (last field actions row).
225
- - Inline gaps: `--pc-form-gap` (shared + label↔inline-icon), `--pc-choice-gap`
226
- (between options), `--pc-choice-inner-gap` (control↔label), `--pc-form-actions-gap`
227
- (between buttons), `--pc-field-horizontal-gap` (horizontal label col↔input col).
228
-
229
- The inline "gap" family chains to `--pc-form-gap` (one knob moves them all);
230
- every var is also overridable on its own scope. These are the first
231
- foundation-owned runtime vars to use `--pc-` rather than the legacy
232
- consumer-branded `--pa-` prefix new foundation tokens should follow suit.
233
-
234
- ### Changed
235
-
236
- - **Renamed the misleading `$form-scale` token to `$form-gap`.** It reads like an
237
- input-sizing multiplier but is only ever consumed as a `gap:` value — the small
238
- gap between adjacent form bits (a label and its inline icon, footer action
239
- buttons, checkbox/radio group options). `$form-scale` is kept as a `!default`
240
- alias of `$form-gap`, so existing overrides keep working; it will be retired in
241
- a major. (pure-admin reads the gap through `var(--pc-form-gap, …)`, so it is
242
- also runtime-tunable.)
243
-
244
- ## [1.0.0-rc03] 2026-08-21 [PUBLISHED]
245
-
246
- ### Changed
247
-
248
- - **BREAKING renamed the top-bar region tokens from `header` to `navbar`.** The
249
- foundation's top-region tokens named the bar as a *component block* rather than a
250
- layout region, which read as misleading once pure-admin's navbar component dropped its
251
- legacy `pa-header__*` block naming. Renamed:
252
- - SCSS variables: `$header-height` → `$navbar-height`, `$header-bg` → `$navbar-bg`,
253
- `$header-border-color` → `$navbar-border-color`, `$header-text` → `$navbar-text`,
254
- `$header-text-secondary` `$navbar-text-secondary`,
255
- `$header-profile-name-color` `$navbar-profile-name-color`,
256
- `$z-index-header` → `$z-index-navbar`.
257
- - CSS variables: `--pa-header-bg` → `--pa-navbar-bg`,
258
- `--pa-header-border-color` → `--pa-navbar-border-color`,
259
- `--pa-header-text` `--pa-navbar-text`,
260
- `--pa-header-text-secondary` → `--pa-navbar-text-secondary`,
261
- `--pa-header-profile-name-color` `--pa-navbar-profile-name-color`.
262
- - `$footer-height` still mirrors the bar height (now `$navbar-height`); component-header
263
- tokens (`$card-header-*`, `$table-header-*`) are unaffected.
264
-
265
- ### Removed
266
-
267
- - **Dead `$header-brand-padding-left` variable.** Superseded by the navbar's flex `gap`;
268
- no live rule consumed it (only a stale comment referenced it).
269
-
270
- ## [1.0.0-rc02] 2026-08-05 [PUBLISHED]
271
-
272
- ### Added
273
-
274
- - **Reboot layer (`reboot.scss`) the reset the foundation always assumed.** Emits
275
- `html { font-size: 10px }` (the 10px rem base every pure-css rem value is authored
276
- against — `$font-size-base: 1.6rem` is 16px *only* at a 10px root), a `box-sizing:
277
- border-box` reset, neutral base styling for standard elements (headings, paragraphs,
278
- links, lists, blockquotes, `hr`, `figure`), the `body` font/colour/background, and the
279
- `button/input/select/textarea/label { font: inherit }` reset. Relocated from
280
- pure-admin-core's `core-components/_base.scss` so it sits with the rem-scale variables
281
- that depend on it. Analogous to Bootstrap's Reboot.
282
- - **New `reboot.css` build artifact** + `./reboot` export, and `reboot` is now part of the
283
- `pure-css.css` bundle (emitted before grid/utilities).
284
- - **Themed scrollbars (`scrollbars.scss`).** The global `*::-webkit-scrollbar` + Firefox
285
- `scrollbar-width`/`scrollbar-color` styling (thin scrollbars coloured from the `--pa-*`
286
- cascade), relocated from pure-admin-core's `core-components/_scrollbars.scss`. Global browser
287
- chrome belongs with the foundation's consistent-appearance promise, so a standalone pure-css
288
- page gets the same themed scrollbars as a full pure-admin app instead of native ones. Part of
289
- the `pure-css.css` bundle, plus a standalone `scrollbars.css` artifact + `./scrollbars` export.
290
-
291
- ### Fixed
292
-
293
- - **Standalone consumers no longer render 1.6× too large.** Before, the 10px base lived
294
- only in pure-admin-core, so a page linking `pure-css.css` (or `base.css`) on its own
295
- inherited the browser's 16px root and every rem was 1.6× oversized. The bundle now ships
296
- the 10px base itself, so the sizing scale is correct out of the box.
297
-
298
- ## [1.0.0-rc01] 2026-08-04
299
-
300
- Initial extraction of the CSS foundation out of `@keenmate/pure-admin-core`.
301
-
302
- ### Fixed
303
-
304
- - **Border/rounded utilities now resolve (were inert).** `.border` / `.border-{top,right,bottom,left}`
305
- and `.rounded` / `.rounded-{lg,top,…}` referenced bare `--border-color` / `--border-radius`
306
- variables the framework never emits so they fell back to a `currentColor` border and no radius
307
- (a latent bug inherited from pure-admin-core). Repointed them at the emitted `--pa-border-color` /
308
- `--pa-border-radius(-lg)` (themed from `--base-*`). Now `base.css` + `utilities.css` are
309
- **self-sufficient**the border/radius utilities work standalone, no host shim.
310
- - **`--pa-border-color` is now a live reference** — emitted as `var(--base-border-color, <literal>)`
311
- instead of a baked literal (it's a pure pass-through, no derivation lost). So it — and the `.border`
312
- utilities that read it — follow a **runtime** `--base-border-color` override (a theme or dark-mode
313
- class toggling it at `:root`/`.pa-mode-dark`), not just build-time themes.
314
-
315
- ### Added
316
-
317
- - **`--base-*` theming contract** `src/scss/variables/*` (the `$base-*` source of truth plus the
318
- derived typography/spacing/colors/layout/system/components modules) and
319
- `_base-css-variables.scss` (the mixin emitting `--base-*` and derived `--pa-*` custom properties).
320
- - **Native flexbox grid** `_pa-grid.scss` (`.pa-row` / `.pa-col`: percentage columns in 5%
321
- increments, intuitive fractions, container-query responsive variants, offsets, visibility helpers),
322
- relocated from pure-admin-core's `core-components/_grid.scss`. Replaces the legacy PureCSS
323
- `.pure-g` / `.pure-u-*` grid, which pure-admin had already stopped using — so pure-css ships the
324
- grid consumers actually use, not the deprecated one.
325
- - **Utilities** — `utilities.scss` (spacing / flex / display / width-height classes) plus the generic
326
- `.font-family-system/-sans/-serif/-mono` classes from `_fonts.scss` (core keeps `_fonts.scss`
327
- standalone; here it `@use`s into utilities so all foundation utilities ship together). Adds
328
- `.gap-*` / `.gap-x-*` / `.gap-y-*` (flex/grid gap, same `$spacers` scale) — the one spacing family
329
- core lacked, needed to express flex layouts with utilities.
330
- - **Build entries & artifacts** `pure-css.scss` (full bundle), `base.scss` (variables only),
331
- `grid.scss` (grid only), and the existing `utilities.scss`, compiled to
332
- `dist/css/{pure-css,base,grid,utilities}.css`. `dist/` is committed for toolchain-free vendoring.
333
- - Package tooling: `package.json` (`@keenmate/pure-css`, `exports` for `.`/`./base`/`./grid`/
334
- `./utilities`/`./scss`), `Makefile`, `README`, this changelog.
335
-
336
- ### Notes
337
-
338
- - **pure-admin-core consumes this package** as its single source for the foundation (thin
339
- `@import`/`@forward` shims for the variables, `--base-*`/`--pa-*` emit mixins, utilities, and the
340
- grid). The two no longer carry duplicate copies, so compiled `--base-*` values and grid output
341
- match core's `dist/css/main.css` exactly.
1
+ # Changelog
2
+
3
+ All notable changes to `@keenmate/pure-css` are documented here. Format based on
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
5
+
6
+ ## [1.0.0-rc08] — 2026-09-10 [PUBLISHED]
7
+
8
+ The **foundation-only + coherent-contract** release. rc08 finishes what rc07
9
+ started: pure-css sheds pure-admin's component vocabulary to become a true
10
+ foundation, the `--base-*` contract is cleaned up into a coherent, fully-named
11
+ token API, a shared themeable icon layer lands, and the default palette is
12
+ rebased onto pure-admin **Corporate**. The canonical `--base-*` list now lives in
13
+ the parent package [`@keenmate/base-css-variables`](https://www.npmjs.com/package/@keenmate/base-css-variables);
14
+ pure-css mirrors it and a drift guard keeps the two honest.
15
+
16
+ ### Breaking
17
+
18
+ - **The `--pc-*` component layer moved to `@keenmate/pure-admin-core`.** pure-css
19
+ no longer ships `variables/_components.scss` or emits the component token
20
+ mixins (`output-pc-component-variables`, `output-pc-component-mode-variables`,
21
+ `output-pc-alert-variables-{light,dark}`) the whole buttons / cards / tables /
22
+ modals / tabs / alerts / badges / panels / command-palette / multiselect /
23
+ sentiment / form-spacing vocabulary. pure-css is now **foundation-only**: the
24
+ `--base-*` bridge plus the base `--pc-*` tokens (surfaces, text, accent, links,
25
+ border, the semantic role identities, the theme palette slots, the radius
26
+ scale). Anything that relied on pure-css emitting component `--pc-*` tokens must
27
+ now take them from **pure-admin-core ≥ 2.9.0-rc20**, which owns the mixins and
28
+ the `$`-vocabulary. Consumers of the compiled `dist/css/*` are unaffected; only
29
+ SCSS consumers that `@include`d the component mixins need the core bump.
30
+
31
+ ### Added
32
+
33
+ - **A shared, themeable icon contract 13 `--base-icon-*` tokens.** `chevron`,
34
+ `caret-down`, `caret-up`, `close`, `clear`, `remove`, `expand`, `collapse`,
35
+ `add`, `edit`, `delete`, `search` (Lucide defaults), emitted as percent-encoded
36
+ SVG data-URIs meant to be painted via `mask` + `background: currentColor`. One
37
+ `--base-icon-*` override re-skins the shell, pure-admin components, and the web
38
+ components together. The dismiss family (`close`/`clear`/`remove`) cascades off
39
+ `--base-icon-close`; the CRUD family (`add`/`edit`/`delete`) reads as distinct
40
+ verbs (delete is a trash bin, not an ✕). Two disclosure models are documented:
41
+ chevron **rotates one glyph**, expand/collapse **swaps two**.
42
+ - **A coherent `--base-*` token API (WS7).** `--base-border-width`; the
43
+ `--base-primary-*` role set as aliases of accent; `--base-secondary-color(-hover)`
44
+ + `--base-text-on-secondary`; `--base-text-on-{primary,danger,success,warning,info}`
45
+ (the `text-on-<role>` convention); `--base-info-bg` (role symmetry); the brand
46
+ palette `--base-color-1..9` (+ `-text`), aliased by `--pc-color-N`; and the
47
+ non-colour scales `--base-space-*`, `--base-shadow-{sm,md,lg}`,
48
+ `--base-duration-*` + `--base-ease-*`, and `--base-z-*`.
49
+ - **`--pc-hover-bg` / `--pc-active-bg`** base tokens, so component hover/active
50
+ states read a dedicated interaction-state axis instead of borrowing the
51
+ recessed `--base-subtle-bg` surface.
52
+ - **`component-reset` — a Shadow-DOM reset entry** (`./component-reset`,
53
+ `dist/css/component-reset.css`). The counterpart to `reboot` for web components:
54
+ a `:host` box-sizing + inherited-typography reset pinned to `--base-*` so a host
55
+ page can't bleed into a component's shadow root. Sets no `rem` base; pair with
56
+ `base`. This brings the build to **7 artifacts**.
57
+
58
+ ### Changed
59
+
60
+ - **Default theme rebased onto pure-admin Corporate.** `$base-*` defaults now
61
+ track Corporate accent `#0ea5e9`, slate text/surfaces, role hues emerald /
62
+ red / amber / cyan and the palette is sourced from `$base-color-1..9`. This
63
+ changes pure-css's **un-themed default look**; themed apps are unaffected since
64
+ every theme sets its own `--base-*`. (Verified: of the reconciled defaults, only
65
+ `--base-input-border-color` — the one un-owned token — shifts themed output.)
66
+ - **`--base-disabled-bg`** given its own distinct value (`#f1f3f5`) instead of
67
+ colliding with the hover/subtle surface.
68
+ - **The shell chevrons are now SVG masks, not a `›` text glyph.** The sidebar
69
+ collapse chevron and the navbar "more" chevron render `--base-icon-chevron` via
70
+ a mask box (rotated on open); the `fit.js` injectors emit empty spans painted by
71
+ CSS.
72
+
73
+ ### Removed
74
+
75
+ - Dead `--pc-multiselect-*` and the simple `--pc-badge-*` tokens (web-multiselect
76
+ themes off its own `--ms-*` namespace; badges read `--pc-btn-*` / `--pc-color-*`).
77
+
78
+ ### Internal
79
+
80
+ - **`@keenmate/base-css-variables` is the canonical `--base-*` parent.** pure-css
81
+ mirrors its token list into `$base-*` SCSS; `scripts/check-base-parity.mjs`
82
+ fails the build if the emitted `--base-*` names drift from the contract (4 dead
83
+ tokens allow-listed). Going-forward rule: author a new `--base-*` token in
84
+ base-css-variables first, then mirror it here.
85
+
86
+ ## [1.0.0-rc07] 2026-09-08 [PUBLISHED]
87
+
88
+ The **shared theming knob** release. Before rc07 the same visual token (a tooltip
89
+ background, an input border, a dropdown surface) was produced *twice and
90
+ independently* pure-admin's `--pc-*` component tokens were baked compile-time
91
+ literals, while the KeenMate web components read `--base-*` live — so they agreed
92
+ only by coincidence and diverged the instant a theme retuned `--base-*` at
93
+ runtime (every dual-mode theme does exactly this at `.pc-mode-dark`). rc07 makes
94
+ `--base-*` the single runtime knob: override one namespace and pure-admin
95
+ components + the web components re-theme together, in light and dark.
96
+
97
+ ### Added
98
+
99
+ - **Gap `--base-*` tokens the web components already read but pure-css never
100
+ emitted** so they stop falling through to hardcoded component defaults and
101
+ actually theme: `--base-text-inverted`, `--base-checkbox-border-color`,
102
+ `--base-input-border-color` (+ the `--base-input-border` shorthand),
103
+ `--base-input-clear-color` / `--base-input-clear-bg-hover`, the solid role
104
+ fills `--base-success-bg` / `--base-danger-bg` / `--base-warning-bg`, and
105
+ `--base-rem`.
106
+
107
+ ### Changed
108
+
109
+ - **`--pc-*` component tokens now derive from `--base-*` at runtime.** ~40 themed
110
+ `--pc-*` tokens (buttons, cards, inputs, checkbox, input groups, tables, modal,
111
+ tooltip/popover, command palette, multiselect) were rewritten from baked
112
+ `#{$…}` literals to the guiding-rule form `var(--base-x, #{$fallback})`. The
113
+ `#{$fallback}` preserves today's compiled value, so **light-mode output is
114
+ unchanged** but the token now follows any runtime `--base-*` override, shared
115
+ with the web components.
116
+ - **The app shell surfaces stay compile-time deliberately not `--base-*`-derived.**
117
+ The navbar/sidebar/footer surface + text tokens (`--pc-navbar-*`,
118
+ `--pc-sidebar-*`, `--pc-footer-*`) are emitted as plain `#{$…}` literals, *not*
119
+ `var(--base-main-bg, …)`. The shell is a distinct brand surface a theme sets on
120
+ its own (e.g. a yellow navbar) independent of the `--base-*` card/page palette;
121
+ since `--base-main-bg` is always emitted, deriving the navbar from it would let
122
+ the base palette win and erase the brand colour. Standalone (`base.css`-only)
123
+ rendering is still covered the shell CSS itself resolves
124
+ `var(--pc-navbar-bg, var(--base-main-bg))`, so the `--base-*` floor applies only
125
+ when no `--pc-*` is emitted (the rc06 contract), not as a runtime override of it.
126
+ - **Surface-token naming realigned with the `--base-*` model (B5).**
127
+ `--pc-main-bg` is now the **white surface** (`--base-main-bg`), `--pc-subtle-bg`
128
+ the **muted grey** (`--base-subtle-bg`), and `--pc-page-bg` remains the **grey
129
+ canvas**. Previously `--pc-main-bg` *was* the grey canvas and `--pc-subtle-bg`
130
+ *was* white an inversion vs the `--base-*` vocabulary. pure-css's own shell
131
+ canvas usages (reboot `body`, `.pc-layout`, scrollbars) were repointed
132
+ `--pc-main-bg` `--pc-page-bg` so the canvas stays grey. **Downstream code
133
+ reading `--pc-main-bg` / `--pc-subtle-bg` must re-check intent** see
134
+ pure-admin-core rc19, which repoints its component surfaces accordingly.
135
+ - `$base-elevated-bg` default changed from the stray `#f5f5f5` to `$base-page-bg`.
136
+
137
+ ### Fixed
138
+
139
+ - **Broken `$`-link:** `$input-border` was a hardcoded `#ced4da` (the comment even
140
+ claimed it came from base) — reconnected to `$base-input-border-color`, so input
141
+ borders finally track the theme.
142
+ - **Semantic surface reconciliation** so pure-admin and the web components resolve
143
+ the *same* base token per surface: card/table headers + striped rows
144
+ `--base-elevated-bg`, dropdown/popover `--base-dropdown-bg`, table/multiselect
145
+ hover → `--base-hover-bg`, checkbox border `--base-checkbox-border-color`.
146
+ - **Sidebar search box alignment + collapsed-rail gating (`_sidebar.scss`).** The
147
+ search input's inline padding was rebalanced to `0 $spacing-base 0 $spacing-sm`
148
+ so its magnifier lines up with the nav-row icons below it (margin `$spacing-sm` +
149
+ padding-left `$spacing-sm` = the `$spacing-base` nav inset) instead of sitting one
150
+ box-margin too far in. The collapsed-rail rules that shed the search frame/field
151
+ down to the submit icon were re-scoped from `.pc-layout__sidebar--icon-collapse`
152
+ to `.sidebar-hidden .pc-layout__sidebar--icon-collapse` the mode class stays on
153
+ the element while the rail is expanded, so the unscoped rules were stripping the
154
+ search frame in the expanded state too.
155
+
156
+ ## [1.0.0-rc06] 2026-08-30
157
+
158
+ ### Fixed
159
+
160
+ - **The app shell now renders standalone — component `--pc-*` tokens fall back to
161
+ `--base-*`.** rc05 relocated the shell into the foundation, but its CSS
162
+ hard-referenced component tokens (`--pc-navbar-bg`, `--pc-sidebar-*`,
163
+ `--pc-footer-*`, `--pc-card-bg`, `--pc-input-bg`) that pure-css does **not**
164
+ emitthose are pure-admin's `output-pc-component-variables` contract. So a
165
+ consumer linking `base.css` / `pure-css.css` alone (keen-docs hit this) got an
166
+ unstyled navbar/sidebar. Every such reference now carries a `--base-*` fallback
167
+ traced from the token's own derivation: `var(--pc-navbar-bg, var(--base-main-bg))`,
168
+ `var(--pc-sidebar-bg, var(--base-page-bg))`, navbar/sidebar text
169
+ `--base-text-color-1/2`, borders `--base-border-color`, submenu surfaces
170
+ `--base-subtle-bg`, input `--base-input-bg`. This makes `--pc-*` an *optional*
171
+ override layer over a guaranteed `--base-*` floor link only the base vars and
172
+ the shell just works; set `--pc-navbar-bg` to tune the bar independently of the
173
+ page. 40 references across the eight shell partials.
174
+ - **Dangling token references in `_fit-flyout.scss`.** The fit-flyout trigger
175
+ referenced `--pc-accent-color` (defined nowherethe token is `--pc-accent`)
176
+ with no fallback, so its focus outline was inert; and `--pc-hover-bg` (also
177
+ undefined) with only an rgba literal. Repointed to
178
+ `var(--pc-accent, var(--base-accent-color))` and
179
+ `var(--pc-hover-bg, var(--base-hover-bg, rgba(…)))`.
180
+
181
+ ### Changed
182
+
183
+ - **Unified the `--pc-border-radius*` scale with the `--base-border-radius-*`
184
+ contract the components already use.** pure-css shipped two disconnected radius
185
+ systems: `--base-border-radius-sm/md/lg` (the unitless rem-multipliers
186
+ `0.4/0.6/0.8` every web/svelte component reads e.g. web-multiselect's
187
+ `calc(var(--base-border-radius-md) * --ms-rem)`), and its OWN
188
+ `--pc-border-radius-sm/base/lg` as hardcoded `2px/4px/8px` literals disconnected
189
+ from the base layer. On one themed page a `<keen-web-multiselect>` and a pure-css
190
+ `.rounded` element rounded differently, and a runtime `--base-border-radius-*`
191
+ override re-rounded the components but not pure-css's own elements. The three
192
+ `--pc-border-radius*` tokens now derive from the base contract
193
+ `calc(var(--base-border-radius-{sm,md,lg}, <default>) * 1rem)` (unsuffixed
194
+ `--pc-border-radius` = the `-md` mid step) mirroring how `--pc-border-color`
195
+ already tracked `--base-border-color`. **Rendered radii change** to match the
196
+ ecosystem: `-sm` 2px 4px, mid 4px6px, `-lg` 8px (unchanged). Overriding
197
+ `--base-border-radius-*` now re-rounds pure-css and the components together.
198
+
199
+ ## [1.0.0-rc05] 2026-08-27 [PUBLISHED]
200
+
201
+ ### Added
202
+
203
+ - **The app shell moves into the foundation — navbar, sidebar, and layout
204
+ container.** pure-css was variables + grid + utilities; rc05 also relocates the
205
+ structural app-shell layer out of pure-admin-core, so a standalone page (docs
206
+ site, portal) gets the same navbar/sidebar/layout chrome as a full pure-admin
207
+ app without pulling in the component library. Seven new partials, all `@use`d
208
+ into the `pure-css.css` **bundle only** (base.css / grid.css / utilities.css
209
+ untouched; no new standalone artifact):
210
+ - `_navbar.scss` + `_navbar-elements.scss` the fixed navbar (`.pc-navbar`
211
+ with `__inner`/`__start`/`__center`/`__end` regions) and its elements (burger
212
+ menu, brand wordmark `.pc-app-header`, nav menu `.pc-navmenu`, page title
213
+ `.pc-page-header`, profile button, theme switcher).
214
+ - `_sidebar.scss` + `_sidebar-states.scss` the sidebar nav with nested
215
+ submenus (`.pc-sidebar`, `.pc-layout__sidebar`, drag-to-resize
216
+ `.pc-sidebar-resize`) and its hidden / icon-collapse / expanded states.
217
+ - `_layout-container.scss` the layout wrapper (`.pc-layout` with
218
+ `__inner`/`__main`/`__content`/`__footer` and the `.pc-footer__*` regions),
219
+ including sticky/scroll content modes. Emitting `.pc-layout__main` here also
220
+ gives the grid's container-query responsive columns (`.pc-col-md-*`) their
221
+ documented automatic containment context in the same bundle (the
222
+ `_pa-grid.scss` note is corrected from the pre-rc04 `.pa-layout__main` to
223
+ `.pc-layout__main`).
224
+ - `_layout-responsive.scss` the mobile/tablet media queries for the shell.
225
+ - `_resize-handle.scss` a mixin-only partial (emits nothing on its own)
226
+ providing the shared grab-knob look `@use`d by the sidebar resize handle and
227
+ splitter gutters.
228
+ - `_fit-flyout.scss` — the Fit engine's floating-menu sink
229
+ (`.pc-fit-flyout__*`): a `•••` trigger + a `<body>`-parented panel that
230
+ `fit.js` fills on demand when slots relocate out of the row.
231
+
232
+ pure-admin-core keeps same-named partials that now just `@forward` these, so the
233
+ shell is single-sourced in the foundation and the two can't drift.
234
+
235
+ - **The shell's behaviour ships too — a dependency-free JS runtime (`src/js/`).**
236
+ The shell is no longer styling-only: the foundation now carries the vanilla-JS
237
+ runtime that drives it, so pure-css is no longer a CSS-only package. Shipped
238
+ **as source** (no build step) via a new `./js` export (and `./js/*` for
239
+ individual engines); `files` gains `src/js/`.
240
+ - `pure-css.js` installs the `window.pureCss` namespace a tiny event bus,
241
+ live viewport / OS-colour-scheme / capability-first device sources, overlay
242
+ primitives (scroll-lock, keyboard-inset), an open-menu registry, a shared
243
+ `config` baseline (single-sourced from SCSS via `--pc-*` vars), and
244
+ `components.initAll(scope)`. Load-order-safe and stands alone when pure-admin
245
+ is absent; `pure-admin.js` adopts the same buses by reference on top.
246
+ - `fit.js` — the Fit engine (`data-pc-fit` = hide / steps / relocate). It
247
+ **absorbs the former `navbar-collapse.js`** (progressive nav folding via
248
+ `data-pc-fit-nav`, sinking items to the sidebar or a generated "More" menu),
249
+ so that separate file no longer exists.
250
+ - `navbar-dropdown.js` (tap-toggle nav dropdowns/submenus),
251
+ `sidebar-resize.js` (drag-to-resize the sidebar), and
252
+ `container-breakpoint.js` (container-query breakpoint driver).
253
+
254
+ Shell CSS is authored no-JS-safe, so styling degrades gracefully rather than
255
+ breaking when the runtime isn't loaded.
256
+
257
+ ### Fixed
258
+
259
+ - **Migrated the dead `data-pa-nav-collapse` hook to `data-pc-fit-nav`.** The
260
+ relocated nav-collapse CSS keyed on the pre-rc04 `pa-`-branded
261
+ `[data-pa-nav-collapse]` attribute driven by the old `navbar-collapse.js`;
262
+ since that engine is now merged into `fit.js` (which reads `data-pc-fit-nav`),
263
+ the selectors in `_navbar-elements.scss` / `_layout-responsive.scss` were stale
264
+ and matched nothing. Repointed at `[data-pc-fit-nav]` and corrected the
265
+ companion comments (`navbar-collapse.js` → `fit.js`). Also de-branded the fit
266
+ hide-class `.pa-fit-hidden` → `.pc-fit-hidden`.
267
+
268
+ ### Internal
269
+
270
+ - **GitHub Actions release workflow (`.github/workflows/release.yml`).** On a `v*.*.*`
271
+ tag push, builds the CSS (`npm ci` + `npm run build`) and publishes a GitHub Release
272
+ with a `pure-css-<version>.zip` (bundling `dist/`, `src/scss/`, `README.md`,
273
+ `CHANGELOG.md`, `LICENSE` — the same set as the package `files`, so the zip is a
274
+ toolchain-free drop-in for consumers who don't use npm) plus a `.sha256` checksum.
275
+ Auto-generated release notes; tags containing `-` (rc) publish as a pre-release.
276
+ Mirrors pure-admin-core's release workflow, adapted for this single-package repo.
277
+ - **Exhaustive, data-driven utilities e2e coverage.** Rewrote `e2e/utilities.spec.ts`
278
+ from a handful of spot-checks into a hard value assertion for 655 of the 664 shipped
279
+ utility classes (the 9 `auto` sizing classes `m-auto` + per-side, `w-auto`, `h-auto` —
280
+ are layout-resolved and covered behaviourally instead). Each family measures every one
281
+ of its classes' computed styles in a single in-browser pass, then diffs in Node so a
282
+ failure lists exactly which classes are off; the expectations independently encode the
283
+ 10px-rem contract and the documented scales rather than reading them back from the CSS,
284
+ so a failure means the compiled output disagrees with the contract or the contract
285
+ regressed. Renamed the fixture `test/utilities.html` `test/utilities-scale.html` with
286
+ definite-size `#w-parent` / `#h-parent` containers so percentage widths/heights resolve
287
+ to known px. Test-only no change to shipped CSS.
288
+
289
+ ## [1.0.0-rc04] 2026-08-26 [PUBLISHED]
290
+
291
+ ### Changed (BREAKING)
292
+
293
+ - **pure-css now ships only the BASE token contract component tokens moved to
294
+ the consumer that owns the components.** pure-css is a *foundation*: its
295
+ bundles (`pure-css.css`, `base.css`) now emit only the ~46 base `--pc-*` tokens
296
+ its own CSS consumes or exposes as universal theming primitives (surfaces,
297
+ text, accent, links, border, the semantic role identities + their utility text
298
+ colours, the theme palette slots, the radius scale). The ~165 **component**
299
+ tokens (`--pc-btn-*`, `--pc-card-*`, `--pc-table-*`, `--pc-alert-*`, badges,
300
+ tooltips, panels, command palette, multiselect, sentiment scale, form spacing,
301
+ the derived contextual surfaces, admin layout chrome) are no longer emitted by
302
+ the foundation. They are pure-admin's contract.
303
+ - `output-pc-css-variables` is now base-only. The component tokens are emitted
304
+ by the new **`output-pc-component-variables`** mixin (+ the existing
305
+ `output-pc-alert-variables-{light,dark}`), which pure-css still *defines*
306
+ (they read the shared `$`-variable vocabulary in `variables/*`, so they must
307
+ be authored where that vocabulary is in scope) but does **not** call from its
308
+ own bundle. Consumers that ship the components pure-admin core, every
309
+ themeopt in by `@include output-pc-component-variables` alongside
310
+ `output-pc-css-variables`.
311
+ - **Theme authors / anyone calling the emit mixins must add
312
+ `@include output-pc-component-variables;`** (after `output-pc-css-variables`)
313
+ or lose every component token. Consumers of the *compiled* theme/core CSS are
314
+ unaffected — the emitted token set is identical, just split across two mixins.
315
+ - **Every emitted CSS variable de-branded from `--pa-*` to `--pc-*`.** pure-css is
316
+ a *foundation*, but it still emitted its entire runtime custom-property surface
317
+ under pure-admin's `pa` brand. The full `--pa-*` set (~210 vars: `--pa-accent`,
318
+ `--pa-text-color-*`, `--pa-card-bg`, `--pa-border-*`, the contextual /alert sets,
319
+ `--pa-color-1..9` + `-text`, the new `--pc-*` form-spacing family already shipped
320
+ this cut, etc.) is renamed to `--pc-*`. This completes the same de-branding the
321
+ grid/mode classes started above nothing pure-admin-branded remains in the
322
+ foundation's output.
323
+ - **The emit mixins move too:** `output-pa-css-variables` `output-pc-css-variables`,
324
+ `output-pa-alert-variables-light` / `-dark` `output-pc-alert-variables-*`.
325
+ (`output-base-css-variables` is unchanged `--base-*` is a separate, neutral
326
+ web-component contract and stays.)
327
+ - **Untouched:** `--base-*` (web-component bridge), `--page-loader-*` (pre-FOUC
328
+ loader), and the `.pa-color-{name}` colour-variant **class** (a class, not a
329
+ `--pa-` variable).
330
+ - **Migration:** a boundary-aware replace of the string `--pa-` `--pc-` across
331
+ markup, stylesheets, inline `style="--pa-…"`, JS `getPropertyValue`/`setProperty`
332
+ calls, and every theme's `:root` / dark-mode `--pa-*` override block. Safe
333
+ because the leading `--` + trailing `-` can't match `--base-*` or `--page-loader-*`.
334
+ pure-admin, its demo, all 16 themes, and the svelte/keen wrappers migrate in
335
+ lockstep with this release.
336
+ - **Grid classes renamed from the consumer-branded `pa-` to the foundation's own
337
+ `pc-` prefix.** `.pa-row` → `.pc-row`, `.pa-col*` → `.pc-col*` (all percentage /
338
+ fraction / responsive / `--grow`/`--shrink`/`--no-padding` variants),
339
+ `.pa-offset*` `.pc-offset*`, `.pa-cq` `.pc-cq`, `.pa-hide*` `.pc-hide*`,
340
+ `.pa-show*` → `.pc-show*`. The grid is a pure-css *foundation* primitive, so it
341
+ should not carry pure-admin's (`pa`) brand — this de-couples it. **No dual-emit:**
342
+ the old `pa-*` grid classes are gone. Consumers must migrate markup
343
+ (`class="pa-col-1-2"` → `class="pc-col-1-2"`) — a boundary-aware find/replace
344
+ (careful: `pa-col` is a substring of `pa-color-*`, which must NOT be touched).
345
+ pure-admin, its demo, and the svelte/keen wrappers are migrated in lockstep.
346
+ - **Light/dark mode scope classes renamed `.pa-mode-*` → `.pc-mode-*`.**
347
+ The light/dark scopes the foundation emits its variables against (and that apps
348
+ toggle on `<body>`) are foundation-owned, so they move to the `pc-` prefix too.
349
+ `output-pc-css-variables` now emits at `:root, .pc-mode-light, .pc-mode-dark`.
350
+ Consumers toggling the class in JS (`classList.add('pc-mode-dark')`) and themes'
351
+ dark-mode blocks migrate in lockstep. (Safe replace: the string `pa-mode-` →
352
+ `pc-mode-`; `pa-modal` is untouched since `mode` ≠ `moda`.)
353
+
354
+ ### Added
355
+
356
+ - **Sizing utilities consolidated into the foundation.** The universal sizing/flex
357
+ utilities that had been left in pure-admin now live here, so a standalone
358
+ pure-css page has the full set: viewport heights `h-full` / `h-screen` /
359
+ `min-h-full` / `min-h-screen` / `max-h-full` / `max-h-screen`, and the
360
+ Tailwind-style flex shorthands `flex-1` / `flex-auto` / `flex-initial` /
361
+ `flex-none` / `flex-grow` / `flex-shrink` (alongside the existing
362
+ `flex-grow-0/1`, `flex-shrink-0/1`). pure-css already owned the width/height %
363
+ + rem scales (`w-*`/`h-*`, `wr-*`/`hr-*`) and the full min/max families
364
+ (`minw-*`/`maxh-*`/`minwr-*`/`maxhr-*`/…); pure-admin's duplicate rem-height
365
+ `h-Nx`/`min-h-Nx`/`max-h-Nx` set (byte-identical to `hr-N`/`minhr-N`/`maxhr-N`)
366
+ is retired in favour of the foundation's `hr-`/`wr-` naming (`r` = rem).
367
+ - **Complete form-spacing contract as runtime CSS variables, under a pure-css-owned
368
+ `--pc-` namespace.** `output-pc-css-variables` now emits the full anatomy of a
369
+ form's spacing at `:root`, so every consumer (pure-admin, keen-docs,
370
+ keen-pure-admin) shares one contract instead of re-declaring `var()` chains or
371
+ being stuck with compile-time-only margins:
372
+ - Vertical rhythm: `--pc-label-gap` (label → control), `--pc-help-gap`
373
+ (control → help/error), `--pc-field-gap` (field → field),
374
+ `--pc-form-actions-offset` (last field → actions row).
375
+ - Inline gaps: `--pc-form-gap` (shared + label↔inline-icon), `--pc-choice-gap`
376
+ (between options), `--pc-choice-inner-gap` (control↔label), `--pc-form-actions-gap`
377
+ (between buttons), `--pc-field-horizontal-gap` (horizontal label col↔input col).
378
+
379
+ The inline "gap" family chains to `--pc-form-gap` (one knob moves them all);
380
+ every var is also overridable on its own scope. These are the first
381
+ foundation-owned runtime vars to use `--pc-` rather than the legacy
382
+ consumer-branded `--pa-` prefix — new foundation tokens should follow suit.
383
+
384
+ ### Changed
385
+
386
+ - **Renamed the misleading `$form-scale` token to `$form-gap`.** It reads like an
387
+ input-sizing multiplier but is only ever consumed as a `gap:` value — the small
388
+ gap between adjacent form bits (a label and its inline icon, footer action
389
+ buttons, checkbox/radio group options). `$form-scale` is kept as a `!default`
390
+ alias of `$form-gap`, so existing overrides keep working; it will be retired in
391
+ a major. (pure-admin reads the gap through `var(--pc-form-gap, …)`, so it is
392
+ also runtime-tunable.)
393
+
394
+ ## [1.0.0-rc03] — 2026-08-21 [PUBLISHED]
395
+
396
+ ### Changed
397
+
398
+ - **BREAKING — renamed the top-bar region tokens from `header` to `navbar`.** The
399
+ foundation's top-region tokens named the bar as a *component block* rather than a
400
+ layout region, which read as misleading once pure-admin's navbar component dropped its
401
+ legacy `pa-header__*` block naming. Renamed:
402
+ - SCSS variables: `$header-height` → `$navbar-height`, `$header-bg` → `$navbar-bg`,
403
+ `$header-border-color` → `$navbar-border-color`, `$header-text` → `$navbar-text`,
404
+ `$header-text-secondary` → `$navbar-text-secondary`,
405
+ `$header-profile-name-color` → `$navbar-profile-name-color`,
406
+ `$z-index-header` → `$z-index-navbar`.
407
+ - CSS variables: `--pa-header-bg` → `--pa-navbar-bg`,
408
+ `--pa-header-border-color` → `--pa-navbar-border-color`,
409
+ `--pa-header-text` → `--pa-navbar-text`,
410
+ `--pa-header-text-secondary` → `--pa-navbar-text-secondary`,
411
+ `--pa-header-profile-name-color` → `--pa-navbar-profile-name-color`.
412
+ - `$footer-height` still mirrors the bar height (now `$navbar-height`); component-header
413
+ tokens (`$card-header-*`, `$table-header-*`) are unaffected.
414
+
415
+ ### Removed
416
+
417
+ - **Dead `$header-brand-padding-left` variable.** Superseded by the navbar's flex `gap`;
418
+ no live rule consumed it (only a stale comment referenced it).
419
+
420
+ ## [1.0.0-rc02] — 2026-08-05 [PUBLISHED]
421
+
422
+ ### Added
423
+
424
+ - **Reboot layer (`reboot.scss`) — the reset the foundation always assumed.** Emits
425
+ `html { font-size: 10px }` (the 10px rem base every pure-css rem value is authored
426
+ against — `$font-size-base: 1.6rem` is 16px *only* at a 10px root), a `box-sizing:
427
+ border-box` reset, neutral base styling for standard elements (headings, paragraphs,
428
+ links, lists, blockquotes, `hr`, `figure`), the `body` font/colour/background, and the
429
+ `button/input/select/textarea/label { font: inherit }` reset. Relocated from
430
+ pure-admin-core's `core-components/_base.scss` so it sits with the rem-scale variables
431
+ that depend on it. Analogous to Bootstrap's Reboot.
432
+ - **New `reboot.css` build artifact** + `./reboot` export, and `reboot` is now part of the
433
+ `pure-css.css` bundle (emitted before grid/utilities).
434
+ - **Themed scrollbars (`scrollbars.scss`).** The global `*::-webkit-scrollbar` + Firefox
435
+ `scrollbar-width`/`scrollbar-color` styling (thin scrollbars coloured from the `--pa-*`
436
+ cascade), relocated from pure-admin-core's `core-components/_scrollbars.scss`. Global browser
437
+ chrome belongs with the foundation's consistent-appearance promise, so a standalone pure-css
438
+ page gets the same themed scrollbars as a full pure-admin app instead of native ones. Part of
439
+ the `pure-css.css` bundle, plus a standalone `scrollbars.css` artifact + `./scrollbars` export.
440
+
441
+ ### Fixed
442
+
443
+ - **Standalone consumers no longer render 1.6× too large.** Before, the 10px base lived
444
+ only in pure-admin-core, so a page linking `pure-css.css` (or `base.css`) on its own
445
+ inherited the browser's 16px root and every rem was 1.6× oversized. The bundle now ships
446
+ the 10px base itself, so the sizing scale is correct out of the box.
447
+
448
+ ## [1.0.0-rc01] — 2026-08-04
449
+
450
+ Initial extraction of the CSS foundation out of `@keenmate/pure-admin-core`.
451
+
452
+ ### Fixed
453
+
454
+ - **Border/rounded utilities now resolve (were inert).** `.border` / `.border-{top,right,bottom,left}`
455
+ and `.rounded` / `.rounded-{lg,top,…}` referenced bare `--border-color` / `--border-radius`
456
+ variables the framework never emits — so they fell back to a `currentColor` border and no radius
457
+ (a latent bug inherited from pure-admin-core). Repointed them at the emitted `--pa-border-color` /
458
+ `--pa-border-radius(-lg)` (themed from `--base-*`). Now `base.css` + `utilities.css` are
459
+ **self-sufficient** — the border/radius utilities work standalone, no host shim.
460
+ - **`--pa-border-color` is now a live reference** — emitted as `var(--base-border-color, <literal>)`
461
+ instead of a baked literal (it's a pure pass-through, no derivation lost). So it — and the `.border`
462
+ utilities that read it — follow a **runtime** `--base-border-color` override (a theme or dark-mode
463
+ class toggling it at `:root`/`.pa-mode-dark`), not just build-time themes.
464
+
465
+ ### Added
466
+
467
+ - **`--base-*` theming contract** — `src/scss/variables/*` (the `$base-*` source of truth plus the
468
+ derived typography/spacing/colors/layout/system/components modules) and
469
+ `_base-css-variables.scss` (the mixin emitting `--base-*` and derived `--pa-*` custom properties).
470
+ - **Native flexbox grid** — `_pa-grid.scss` (`.pa-row` / `.pa-col`: percentage columns in 5%
471
+ increments, intuitive fractions, container-query responsive variants, offsets, visibility helpers),
472
+ relocated from pure-admin-core's `core-components/_grid.scss`. Replaces the legacy PureCSS
473
+ `.pure-g` / `.pure-u-*` grid, which pure-admin had already stopped using — so pure-css ships the
474
+ grid consumers actually use, not the deprecated one.
475
+ - **Utilities** — `utilities.scss` (spacing / flex / display / width-height classes) plus the generic
476
+ `.font-family-system/-sans/-serif/-mono` classes from `_fonts.scss` (core keeps `_fonts.scss`
477
+ standalone; here it `@use`s into utilities so all foundation utilities ship together). Adds
478
+ `.gap-*` / `.gap-x-*` / `.gap-y-*` (flex/grid gap, same `$spacers` scale) — the one spacing family
479
+ core lacked, needed to express flex layouts with utilities.
480
+ - **Build entries & artifacts** — `pure-css.scss` (full bundle), `base.scss` (variables only),
481
+ `grid.scss` (grid only), and the existing `utilities.scss`, compiled to
482
+ `dist/css/{pure-css,base,grid,utilities}.css`. `dist/` is committed for toolchain-free vendoring.
483
+ - Package tooling: `package.json` (`@keenmate/pure-css`, `exports` for `.`/`./base`/`./grid`/
484
+ `./utilities`/`./scss`), `Makefile`, `README`, this changelog.
485
+
486
+ ### Notes
487
+
488
+ - **pure-admin-core consumes this package** as its single source for the foundation (thin
489
+ `@import`/`@forward` shims for the variables, `--base-*`/`--pa-*` emit mixins, utilities, and the
490
+ grid). The two no longer carry duplicate copies, so compiled `--base-*` values and grid output
491
+ match core's `dist/css/main.css` exactly.