@keenmate/pure-css 1.0.0-rc09 → 1.0.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
@@ -3,6 +3,49 @@
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.0.1] — 2026-09-13 [PUBLISHED]
7
+
8
+ ### Fixed
9
+
10
+ - **Sidebar type-and-go search text was invisible on themes with a
11
+ mode-independent sidebar (e.g. express light).** The framed search box
12
+ (`.pc-sidebar__search`) sits on the **input** surface (`--base-input-bg`), but
13
+ its field text and its `:hover` colour used `--pc-sidebar-text` — a token tuned
14
+ for the **sidebar** surface. When a theme keeps the sidebar one colour across
15
+ modes (express: always-black sidebar → `--pc-sidebar-text: #fff`), that white
16
+ text landed on the light input background and vanished (white-on-white). Both
17
+ now use `--base-input-color`, which is emitted per-mode alongside
18
+ `--base-input-bg`, so the text/background pair is always legible. Affects
19
+ `.pc-sidebar__search-field` and `.pc-sidebar__search:hover`.
20
+
21
+ ## [1.0.0] — 2026-09-12 [PUBLISHED]
22
+
23
+ The **first stable release** — the 1.0.0-rc series culminates here. Two additive
24
+ changes since rc09: the shared `--base-*` icon contract gains a `filter` glyph and
25
+ a `check` / `indeterminate` selection pair, and the mode/variant class-placement
26
+ rule is now documented.
27
+
28
+ ### Added
29
+
30
+ - **Three `--base-icon-*` tokens: `filter`, `check`, `indeterminate`.** All
31
+ mask-friendly Lucide glyphs, authored in the canonical
32
+ `@keenmate/base-css-variables` contract first and mirrored into
33
+ `variables/_base.scss` + `output-base-css-variables` (parity drift-guard stays green).
34
+ - `filter` (funnel) — "refine / narrow a list", deliberately distinct from
35
+ `search` (find-by-text).
36
+ - `check` (✓) + `indeterminate` (−) — the checkbox / tree-node selection pair
37
+ shared by web-multiselect, web-treeview and plain checkboxes: `check` =
38
+ selected, `indeterminate` = a tri-state parent whose children are a mix.
39
+ `indeterminate` shares the minus shape with `collapse` but is its own
40
+ independently-overridable knob (selection ≠ disclosure, mirroring add vs expand).
41
+ - **"Mode & variant class placement" documentation.** A new README section, plus a
42
+ matching `NOTE` in `_base-css-variables.scss`, explaining that `.pc-mode-*` /
43
+ `.pa-color-*` classes must sit on `<html>` (`:root`), not `<body>`: derived
44
+ component tokens emitted once at `:root` (e.g. `--pa-btn-info-bg: var(--pc-info)`)
45
+ freeze at the default-mode value if the mode class lands on a descendant, so role
46
+ buttons/surfaces fail to recolour on switch. Includes the one-frame
47
+ `transition: none` trick to avoid a colour flash.
48
+
6
49
  ## [1.0.0-rc09] — 2026-09-10 [PUBLISHED]
7
50
 
8
51
  The **shell/namespace decoupling** release. Part of the ecosystem-wide
@@ -110,7 +153,7 @@ pure-css mirrors it and a drift guard keeps the two honest.
110
153
  The **shared theming knob** release. Before rc07 the same visual token (a tooltip
111
154
  background, an input border, a dropdown surface) was produced *twice and
112
155
  independently* — pure-admin's `--pc-*` component tokens were baked compile-time
113
- literals, while the KeenMate web components read `--base-*` live — so they agreed
156
+ literals, while the Keenmate web components read `--base-*` live — so they agreed
114
157
  only by coincidence and diverged the instant a theme retuned `--base-*` at
115
158
  runtime (every dual-mode theme does exactly this at `.pc-mode-dark`). rc07 makes
116
159
  `--base-*` the single runtime knob: override one namespace and pure-admin
package/README.md CHANGED
@@ -1,38 +1,47 @@
1
1
  # @keenmate/pure-css
2
2
 
3
- The KeenMate CSS **foundation** — the `--base-*` theming contract, the flexbox grid (`.pc-row` / `.pc-col`), and the
4
- utility classes extracted from [`@keenmate/pure-admin-core`](https://github.com/KeenMate/pure-admin)
5
- so it can be consumed on its own.
3
+ Keenmate's CSS **foundation** — descended from [Yahoo's Pure CSS](https://purecss.io/) and extended into a
4
+ more robust, themeable layer for real apps. One small, dependency-free package gives you the
5
+ **`--base-*` theming contract** (one block of custom properties re-themes everything at once), a
6
+ modern **flexbox grid** (`.pc-row` / `.pc-col`, container-query responsive — replacing Pure's float
7
+ grid), a set of **utility classes**, and an optional **app shell + JS runtime** (in the
8
+ `pure-css.css` bundle).
6
9
 
7
- ## What's New in 1.0.0-rc09
10
+ It's the shared layer the whole Keenmate stack agrees on:
11
+ [`@keenmate/pure-admin-core`](https://github.com/Keenmate/pure-admin) builds its component library on
12
+ top of it, and every Keenmate web/Svelte component reads its colours from the same `--base-*`
13
+ variables.
8
14
 
9
- - **Namespace hygiene — the app shell no longer reaches into pure-admin's token namespace** — the KeenMate ecosystem is aligning its custom-property prefixes with its class prefixes: `--pc-*` / `.pc-*` belong to the pure-css foundation + app shell, `--pa-*` / `.pa-*` belong to pure-admin components. As part of that rename, pure-css's shell had a handful of incidental references to *component* tokens — `var(--pc-card-bg, …)` in the fit-flyout / navbar dropdown / resize-handle, `var(--pc-input-bg, …)` in the sidebar search, and `var(--pc-icon-chevron, …)` on the sidebar/navbar chevrons. Since those tokens are moving to `--pa-*` (pure-admin's namespace) and the foundation must not depend on pure-admin, each now reads its `--base-*` foundation value directly. Rendered output is byte-for-byte unchanged — every dropped tier already resolved to the same `--base-*` fallback.
15
+ ## What's New in 1.0.1
10
16
 
11
- ## What's New in 1.0.0-rc08
17
+ - **Sidebar search — type-and-go text is legible again on mode-independent sidebars** — the framed sidebar search box (`.pc-sidebar__search`) sits on the *input* surface (`--base-input-bg`), but its field text and `:hover` colour were painted with `--pc-sidebar-text`, a token tuned for the *sidebar* surface. On themes that keep the sidebar one colour across light and dark (e.g. express, whose sidebar is always black → `--pc-sidebar-text: #fff`), that white text landed on the light input background and vanished — white-on-white, so you couldn't read what you were typing. Both `.pc-sidebar__search-field` and `.pc-sidebar__search:hover` now read `--base-input-color`, which is emitted per-mode alongside `--base-input-bg`, so the field text always pairs with its own surface and stays readable in every theme.
12
18
 
13
- - **Foundation-only the `--pc-*` component layer moved to `@keenmate/pure-admin-core` (breaking)** — pure-css no longer ships `variables/_components.scss` or the component emit mixins (`output-pc-component-variables`, `output-pc-component-mode-variables`, `output-pc-alert-variables-{light,dark}`) — the whole buttons / cards / tables / modals / alerts / badges / command-palette / multiselect vocabulary. pure-css is now a true foundation: the `--base-*` bridge plus the base `--pc-*` tokens (surfaces, text, accent, links, border, role identities, palette slots, radius). SCSS consumers that `@include`d the component mixins must take them from pure-admin-core ≥ 2.9.0-rc20; consumers of the compiled `dist/css/*` are unaffected.
14
- - **Icons — a shared, themeable `--base-icon-*` contract (13 tokens)** — `chevron`, `caret-down`/`-up`, `close`, `clear`, `remove`, `expand`, `collapse`, `add`, `edit`, `delete`, `search` (Lucide defaults), emitted as percent-encoded SVG data-URIs painted via `mask` + `background: currentColor`. One override re-skins the shell, pure-admin components, and the web components together; the shell's sidebar/navbar chevrons are now SVG masks instead of a `›` text glyph. Two disclosure models are documented — chevron *rotates one glyph*, expand/collapse *swaps two*.
15
- - **Contract — a coherent, fully-named `--base-*` token API (WS7)** added `--base-border-width`, the `--base-primary-*` accent aliases, `--base-secondary-*`, the `--base-text-on-<role>` set, `--base-info-bg` for role symmetry, the `--base-color-1..9` (+`-text`) brand palette aliased by `--pc-color-N`, and the non-colour scales `--base-space-*`, `--base-shadow-{sm,md,lg}`, `--base-duration-*` + `--base-ease-*`, and `--base-z-*`. `--base-disabled-bg` got its own value (`#f1f3f5`) instead of colliding with the hover surface.
16
- - **Surfaces — hover/active split off the recessed surface** — new `--pc-hover-bg` / `--pc-active-bg` base tokens let component hover/active states read a dedicated interaction-state axis rather than borrowing the recessed `--base-subtle-bg`, which read as *raised* in several dark themes.
17
- - **Themedefault palette rebased onto pure-admin Corporate**`$base-*` defaults now track Corporate (accent `#0ea5e9`, slate text/surfaces, emerald/red/amber/cyan roles), with the palette sourced from `$base-color-1..9`. This changes pure-css's *un-themed* default look; themed apps are unaffected since every theme sets its own `--base-*`.
18
- - **Shadow DOM — a new `component-reset` entry** — `./component-reset` (`dist/css/component-reset.css`) is the counterpart to `reboot` for web components: a `:host` box-sizing + inherited-typography reset pinned to `--base-*` so a host page can't bleed into a component's shadow root. No `rem` base — pair it with `base`. Brings the build to 7 artifacts.
19
- - **Internal — `@keenmate/base-css-variables` is now the canonical `--base-*` parent** — pure-css mirrors its token list into `$base-*` SCSS, and `scripts/check-base-parity.mjs` fails the build if the emitted names drift from the contract. New tokens are authored in base-css-variables first, then mirrored here.
19
+ ## What's New in 1.0.0
20
+
21
+ - **Icons — a `filter` glyph and a `check` / `indeterminate` selection pair join the shared `--base-*` contract** three more mask-friendly Lucide glyphs so every consumer paints the same affordances from one theme knob. `--base-icon-filter` (a funnel) is the "refine / narrow a list" mark, deliberately separate from `--base-icon-search` (find-by-text) so a component can show both at once. `--base-icon-check` (✓) and `--base-icon-indeterminate` (−) are the checkbox / tree-node selection pair used by web-multiselect, web-treeview and plain checkboxes — `check` means selected, `indeterminate` means a tri-state parent whose children are a mix. `indeterminate` reuses the minus shape of `collapse` by default but is its own independently-overridable token, so selection never gets entangled with disclosure (the same discipline as `add` vs `expand`). All three are authored in the canonical `@keenmate/base-css-variables` package first and mirrored into `variables/_base.scss` + the emit mixin, keeping the parity drift-guard green; consume them via `mask: var(--base-icon-check); background: currentColor`.
22
+
23
+ - **Docsmode & variant classes belong on `<html>`, not `<body>`** a new "Mode & variant class placement" section in the README (mirrored by a `NOTE` in `_base-css-variables.scss`) documents a subtle theming pitfall. CSS resolves a custom property's `var()` at the element that *declares* it, so derived component tokens that pure-admin-core emits once at `:root` — e.g. `--pa-btn-info-bg: var(--pc-info)` — bake in `:root`'s input value. Put a `.pc-mode-dark` / `.pa-color-*` class on a descendant like `<body>` and the override arrives too late: the derived token stays frozen at its default-mode value and role buttons or surfaces don't recolour when you switch. Applying the class to `:root` (the element that declares the tokens) makes the overrides win and everything re-resolves. The section also documents the one-frame `transition: none !important` trick to suppress a colour flash during the swap.
20
24
 
21
25
  ## Why
22
26
 
23
- Any surface that isn't a full admin app — a docs site, a marketing page, a standalone widget host —
24
- wants the *foundation* (variables + grid + utilities) without pure-admin-core's 40+ components. And
25
- every KeenMate web component (`<web-multiselect>`, …) and Svelte component already reads its colors
26
- from the `--base-*` custom properties. Shipping those from one small package means one theming layer
27
- that the components, the admin framework, and everything else all agree on.
27
+ pure-css is a **standalone foundation** you drop onto any surface — a docs site, a marketing page, a
28
+ widget host, or a full application. One small, dependency-free package gives you theming, layout and
29
+ utilities without buying into a component framework.
30
+
31
+ Its heart is a single **`--base-*` theming contract**: override one block of custom properties and
32
+ everything re-themes at once — the grid, the utilities, the optional app shell, and any component
33
+ that reads the same variables. Light and dark are built in via `light-dark()`, there's no build step
34
+ to consume it (just link the prebuilt CSS), and it pulls in no runtime dependencies.
28
35
 
29
36
  ```
30
- @keenmate/pure-css @keenmate/pure-admin-core
31
- ├─ --base-* variables ◀──── imports pure-css, adds
32
- ├─ .pc-row / .pc-col grid the component library
33
- └─ utility classes
34
-
35
- └── docs sites, portals, component hosts consume the built CSS directly
37
+ @keenmate/pure-css (this package)
38
+ ├─ --base-* theming contract
39
+ ├─ .pc-row / .pc-col grid
40
+ ├─ utility classes
41
+ └─ optional app shell + JS runtime
42
+ ▲ consumed directly, as built CSS, by…
43
+ ├── docs sites · portals · marketing pages · widget & component hosts
44
+ └── @keenmate/pure-admin-core — adds a full component library on top (just one consumer)
36
45
  ```
37
46
 
38
47
  ## Installation
@@ -124,15 +133,19 @@ swap the icon set.
124
133
  | `--base-icon-remove` | `✕` | take an **item** out of a collection (chip / tag / row) — non-destructive; follows `--base-icon-close` |
125
134
  | `--base-icon-expand` / `--base-icon-collapse` | `+` / `−` | **swap-two-glyphs** disclosure (tree nodes, accordions): show `+` when collapsed, `−` when open |
126
135
  | `--base-icon-add` / `--base-icon-edit` / `--base-icon-delete` | `+` / pencil / trash | **CRUD action** verbs — create / modify / **destroy** (delete is a trash can, *not* an ✕, so it reads as destructive) |
127
- | `--base-icon-search` | magnifying glass | search inputs, filter fields, command palette |
136
+ | `--base-icon-search` | magnifying glass | search inputs, command palette — find **by text** |
137
+ | `--base-icon-filter` | funnel | refine / **narrow a list** by criteria (filter toggles, faceted search) — distinct from `search` |
138
+ | `--base-icon-check` / `--base-icon-indeterminate` | `✓` / `−` | **selection** pair (checkboxes, multiselect, tree nodes): `check` = selected, `indeterminate` = a tri-state parent whose children are a mix |
128
139
 
129
- Two intentional distinctions:
140
+ Three intentional distinctions:
130
141
 
131
142
  - **Disclosure models:** **chevron rotates one glyph** (sidebar, multiselect), while **expand/collapse swaps
132
143
  two glyphs** (trees, accordions) — a component never rotates a `+` into a `−`.
133
144
  - **✕ vs trash:** `close` / `clear` / `remove` are three *dismiss* purposes that share the ✕ glyph (and
134
145
  cascade off `--base-icon-close`), while `delete` is a separate *destructive* action drawn as a trash can.
135
146
  `add` shares the `+` shape with `expand` but is an independent knob (create ≠ disclosure).
147
+ - **Selection ≠ disclosure:** `indeterminate` shares the `−` shape with `collapse` but is its own knob —
148
+ a partially-selected checkbox is not a collapsed node.
136
149
 
137
150
  ## Theming
138
151
 
@@ -149,9 +162,30 @@ that redeclares them, loaded *after* `base.css`:
149
162
 
150
163
  Because pure-admin-core, the components and any consumer all read the same variables, that one block
151
164
  re-themes all of them at once. This is the same model as
152
- [`@keenmate/pure-admin-themes`](https://github.com/KeenMate/pure-admin-themes), so the same CLI and
165
+ [`@keenmate/pure-admin-themes`](https://github.com/Keenmate/pure-admin-themes), so the same CLI and
153
166
  publishing infrastructure applies.
154
167
 
168
+ ### Mode & variant class placement
169
+
170
+ Light/dark and colour-variant switching is done by toggling a class — `.pc-mode-light` /
171
+ `.pc-mode-dark` and `.pa-color-*`. **Apply these to the `:root` element (`<html>`), not `<body>`.**
172
+
173
+ The mode/variant blocks override input tokens (`--pc-*` / `--base-*`). Many themed tokens are
174
+ *derived* from those inputs and emitted once at `:root` — e.g. core emits
175
+ `--pa-btn-info-bg: var(--pc-info)`. CSS resolves a custom property's `var()` **at the element that
176
+ declares it**, so a derived token declared on `:root` bakes in `:root`'s input value. If the mode
177
+ class sits on a *descendant* (`<body>`), the override comes too late and the derived token stays
178
+ frozen at the default-mode value — the classic symptom is a role button or surface that doesn't
179
+ change colour when you switch modes. Putting the class on `:root` (the same element that declares
180
+ the tokens) makes the overrides win and the derived tokens re-resolve.
181
+
182
+ pure-css re-emits its own base text-tier tokens at `:root, .pc-mode-light, .pc-mode-dark` to tolerate
183
+ either placement, but that does not extend to the pure-admin component layer, hence the `:root` rule.
184
+
185
+ To avoid a colour "flash" on switch, disable transitions for one frame during the swap (add a
186
+ `transition: none !important` class to `:root`, change the mode/variant class, force a reflow, then
187
+ remove it).
188
+
155
189
  ## Build
156
190
 
157
191
  ```bash
@@ -176,4 +210,4 @@ One intentional difference: `utilities.scss` here `@use`s `_fonts.scss` so the g
176
210
 
177
211
  ## License
178
212
 
179
- MIT © KeenMate. The grid is derived from [Pure](https://purecss.io/) (Yahoo!, BSD).
213
+ MIT © Keenmate. The grid is derived from [Pure](https://purecss.io/) (Yahoo!, BSD).
package/dist/css/base.css CHANGED
@@ -136,6 +136,9 @@
136
136
  --base-icon-edit: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z%22/%3E%3C/svg%3E");
137
137
  --base-icon-delete: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M3 6h18%22/%3E%3Cpath d=%22M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2%22/%3E%3Cpath d=%22M10 11v6%22/%3E%3Cpath d=%22M14 11v6%22/%3E%3C/svg%3E");
138
138
  --base-icon-search: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Ccircle cx=%2211%22 cy=%2211%22 r=%228%22/%3E%3Cpath d=%22m21 21-4.3-4.3%22/%3E%3C/svg%3E");
139
+ --base-icon-filter: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpolygon points=%2222 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3%22/%3E%3C/svg%3E");
140
+ --base-icon-check: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M20 6 9 17l-5-5%22/%3E%3C/svg%3E");
141
+ --base-icon-indeterminate: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M5 12h14%22/%3E%3C/svg%3E");
139
142
  --base-color-1: #f59e0b;
140
143
  --base-color-2: #ec4899;
141
144
  --base-color-3: #10b981;
@@ -2446,7 +2446,7 @@ body.loaded .pc-sidebar__search {
2446
2446
  }
2447
2447
  .pc-sidebar__search:hover {
2448
2448
  border-color: #0ea5e9;
2449
- color: var(--pc-sidebar-text, var(--base-text-color-1));
2449
+ color: var(--base-input-color);
2450
2450
  }
2451
2451
  .sidebar-hidden .pc-layout__sidebar--icon-collapse .pc-sidebar__search {
2452
2452
  width: auto;
@@ -2481,7 +2481,7 @@ body.loaded .pc-sidebar__search {
2481
2481
  border: none;
2482
2482
  outline: none;
2483
2483
  background: transparent;
2484
- color: var(--pc-sidebar-text, var(--base-text-color-1));
2484
+ color: var(--base-input-color);
2485
2485
  font: inherit;
2486
2486
  padding: 0;
2487
2487
  }
@@ -6081,6 +6081,9 @@ body.pc-layout--sticky .pc-layout__inner {
6081
6081
  --base-icon-edit: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z%22/%3E%3C/svg%3E");
6082
6082
  --base-icon-delete: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M3 6h18%22/%3E%3Cpath d=%22M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2%22/%3E%3Cpath d=%22M10 11v6%22/%3E%3Cpath d=%22M14 11v6%22/%3E%3C/svg%3E");
6083
6083
  --base-icon-search: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Ccircle cx=%2211%22 cy=%2211%22 r=%228%22/%3E%3Cpath d=%22m21 21-4.3-4.3%22/%3E%3C/svg%3E");
6084
+ --base-icon-filter: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpolygon points=%2222 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3%22/%3E%3C/svg%3E");
6085
+ --base-icon-check: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M20 6 9 17l-5-5%22/%3E%3C/svg%3E");
6086
+ --base-icon-indeterminate: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M5 12h14%22/%3E%3C/svg%3E");
6084
6087
  --base-color-1: #f59e0b;
6085
6088
  --base-color-2: #ec4899;
6086
6089
  --base-color-3: #10b981;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@keenmate/pure-css",
3
- "version": "1.0.0-rc09",
4
- "description": "The KeenMate CSS foundation — --base-* theming contract, PureCSS grid and utility classes. Extracted from pure-admin-core so docs sites, standalone pages and every web/svelte component share one theming layer.",
3
+ "version": "1.0.1",
4
+ "description": "The Keenmate CSS foundation — --base-* theming contract, PureCSS grid and utility classes. Extracted from pure-admin-core so docs sites, standalone pages and every web/svelte component share one theming layer.",
5
5
  "style": "dist/css/pure-css.css",
6
6
  "exports": {
7
7
  ".": "./dist/css/pure-css.css",
@@ -55,7 +55,7 @@
55
55
  "keenmate",
56
56
  "pure-admin"
57
57
  ],
58
- "author": "KeenMate",
58
+ "author": "Keenmate",
59
59
  "license": "MIT",
60
60
  "peerDependencies": {
61
61
  "sass": "^1.0.0"
@@ -67,12 +67,12 @@
67
67
  },
68
68
  "repository": {
69
69
  "type": "git",
70
- "url": "git+https://github.com/KeenMate/pure-css.git"
70
+ "url": "git+https://github.com/Keenmate/pure-css.git"
71
71
  },
72
72
  "bugs": {
73
- "url": "https://github.com/KeenMate/pure-css/issues"
73
+ "url": "https://github.com/Keenmate/pure-css/issues"
74
74
  },
75
- "homepage": "https://github.com/KeenMate/pure-css#readme",
75
+ "homepage": "https://github.com/Keenmate/pure-css#readme",
76
76
  "publishConfig": {
77
77
  "access": "public"
78
78
  },
@@ -215,7 +215,17 @@
215
215
  --base-icon-delete: #{$base-icon-delete};
216
216
 
217
217
  // === Utility icons ===
218
+ // search = magnifying glass (find by text); filter = funnel (refine/narrow a
219
+ // list — distinct affordance from search, its own knob).
218
220
  --base-icon-search: #{$base-icon-search};
221
+ --base-icon-filter: #{$base-icon-filter};
222
+
223
+ // === Selection icons — checkbox / tree-node state pair ===
224
+ // check = ✓ (selected), indeterminate = − (tri-state parent, partially selected).
225
+ // Shared by web-multiselect / web-treeview / checkboxes. indeterminate shares the
226
+ // minus shape with collapse but is its OWN knob (selection ≠ disclosure).
227
+ --base-icon-check: #{$base-icon-check};
228
+ --base-icon-indeterminate: #{$base-icon-indeterminate};
219
229
 
220
230
  // === Theme palette slots (1–9) + paired contrast text (WS7.6) ===
221
231
  // Promoted into the --base-* contract so the branded/data-viz palette is
@@ -295,6 +305,13 @@
295
305
  // .pc-mode-dark` covers html, body in light mode, and body in dark mode —
296
306
  // regardless of which class layout each theme uses for mode switching.
297
307
  //
308
+ // NOTE: this placement-agnosticism only covers the base tokens pure-css emits
309
+ // here. The pure-admin COMPONENT tokens (e.g. `--pa-btn-info-bg: var(--pc-info)`)
310
+ // are emitted once at `:root` by core and are NOT re-emitted per mode, so they
311
+ // only re-resolve when the mode/variant class sits on the :root element itself.
312
+ // Consumers MUST therefore apply `.pc-mode-*` / `.pa-color-*` to `<html>`, not
313
+ // `<body>` — see README "Mode & variant class placement".
314
+ //
298
315
  // This is a TOP-LEVEL rule (not inside the mixin) because themes only call
299
316
  // the mixin from their light-mode block; they don't call it again in the
300
317
  // dark-mode block. Emitting at framework level means themes get correct
@@ -221,7 +221,12 @@ body.pc-layout--sticky .pc-layout__sidebar {
221
221
  // alias; inlined so the shell no longer depends on the component layer
222
222
  // (variables/_components.scss now lives in pure-admin-core).
223
223
  border-color: $accent-color;
224
- color: var(--pc-sidebar-text, var(--base-text-color-1));
224
+ // This framed box sits on the INPUT surface (--base-input-bg above), NOT
225
+ // the sidebar surface — so emphasise with the input text colour, not
226
+ // --pc-sidebar-text. In themes with a mode-independent sidebar (e.g.
227
+ // express: always-black sidebar → --pc-sidebar-text is white) the old
228
+ // sidebar-text hover went white-on-white on the light input bg.
229
+ color: var(--base-input-color);
225
230
  }
226
231
 
227
232
  // Collapsed rail ONLY (icon-collapse mode AND actually collapsed, i.e.
@@ -276,7 +281,14 @@ body.pc-layout--sticky .pc-layout__sidebar {
276
281
  border: none;
277
282
  outline: none;
278
283
  background: transparent;
279
- color: var(--pc-sidebar-text, var(--base-text-color-1));
284
+ // The field shows through to the framed box's --base-input-bg surface,
285
+ // so its text must use the input text colour (--base-input-color), not
286
+ // the sidebar text colour. --pc-sidebar-text is tuned for the sidebar
287
+ // surface, which can be mode-independent (express: always-black sidebar
288
+ // → white sidebar text) and then renders white-on-white on a light
289
+ // input bg. --base-input-color is emitted per-mode alongside
290
+ // --base-input-bg, so the pair is always legible.
291
+ color: var(--base-input-color);
280
292
  font: inherit;
281
293
  padding: 0;
282
294
 
@@ -1,6 +1,6 @@
1
1
  // @keenmate/pure-css — full foundation bundle
2
2
  // ============================================================================
3
- // The KeenMate CSS foundation, extracted from @keenmate/pure-admin-core so it
3
+ // The Keenmate CSS foundation, extracted from @keenmate/pure-admin-core so it
4
4
  // can be consumed on its own (docs sites, standalone pages, non-admin portals)
5
5
  // and so pure-admin-core, themes and any web/svelte component share ONE
6
6
  // theming contract: the `--base-*` (and derived `--pc-*`) custom properties.
@@ -338,6 +338,15 @@ $base-rem: 1rem !default;
338
338
  //
339
339
  // Utility:
340
340
  // - search: magnifying glass — search inputs, filter fields, command palette.
341
+ // - filter: funnel — narrow a list/table by criteria (filter toggles, faceted
342
+ // search). Distinct from `search` (find by text) — read as "refine".
343
+ //
344
+ // Selection — the checkbox / tree-node state pair (shared by web-multiselect,
345
+ // web-treeview, checkboxes — one tick everywhere):
346
+ // - check: the ✓ — SELECTED. Checkbox checked, selected option/row/node.
347
+ // - indeterminate: the − — PARTIALLY selected (tri-state: a parent whose children
348
+ // are a mix). Shares the minus shape with `collapse` but is an
349
+ // INDEPENDENT knob — selection ≠ disclosure (cf. add vs expand).
341
350
  // =============================================================================
342
351
 
343
352
  $base-icon-chevron: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22m9 18 6-6-6-6%22/%3E%3C/svg%3E") !default;
@@ -351,8 +360,13 @@ $base-icon-collapse: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2
351
360
  $base-icon-add: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M5 12h14%22/%3E%3Cpath d=%22M12 5v14%22/%3E%3C/svg%3E") !default;
352
361
  $base-icon-edit: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z%22/%3E%3C/svg%3E") !default;
353
362
  $base-icon-delete: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M3 6h18%22/%3E%3Cpath d=%22M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2%22/%3E%3Cpath d=%22M10 11v6%22/%3E%3Cpath d=%22M14 11v6%22/%3E%3C/svg%3E") !default;
354
- // Utility: magnifying glass (Lucide search).
363
+ // Utility: magnifying glass (Lucide search) + funnel (Lucide filter).
355
364
  $base-icon-search: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Ccircle cx=%2211%22 cy=%2211%22 r=%228%22/%3E%3Cpath d=%22m21 21-4.3-4.3%22/%3E%3C/svg%3E") !default;
365
+ $base-icon-filter: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpolygon points=%2222 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3%22/%3E%3C/svg%3E") !default;
366
+ // Selection: check = ✓ (Lucide check), indeterminate = − (Lucide minus). indeterminate
367
+ // shares the minus shape with `collapse` but is its own knob (selection ≠ disclosure).
368
+ $base-icon-check: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M20 6 9 17l-5-5%22/%3E%3C/svg%3E") !default;
369
+ $base-icon-indeterminate: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M5 12h14%22/%3E%3C/svg%3E") !default;
356
370
 
357
371
  // =============================================================================
358
372
  // ALERT COLOR DERIVATION PARAMETERS