@keenmate/pure-css 1.0.4 → 1.0.6
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 +31 -0
- package/README.md +215 -218
- package/dist/css/base.css +1 -0
- package/dist/css/pure-css.css +5 -1
- package/dist/css/reboot.css +4 -1
- package/package.json +1 -1
- package/src/scss/_base-css-variables.scss +4 -0
- package/src/scss/reboot.scss +20 -12
- package/src/scss/variables/_base.scss +5 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,37 @@
|
|
|
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.6] — 2026-09-20 [PUBLISHED]
|
|
7
|
+
|
|
8
|
+
### Added
|
|
9
|
+
|
|
10
|
+
- **`--base-icon-check-size` — a runtime mask-size knob for the selection glyph,
|
|
11
|
+
so the glyph and its scale re-theme in lockstep.** The check mark
|
|
12
|
+
(`--base-icon-check`) and the indeterminate dash (`--base-icon-indeterminate`)
|
|
13
|
+
share one mask box, but the size that box was painted at was hard-coded
|
|
14
|
+
downstream per consumer. This adds a single `$base-icon-check-size` (`68%`
|
|
15
|
+
default, emitted as `--base-icon-check-size`) that both pure-admin and the
|
|
16
|
+
Keenmate web components read, so overriding the check glyph **and** its scale
|
|
17
|
+
re-sizes the mark everywhere at once — e.g. swap in an edge-to-edge glyph like a
|
|
18
|
+
star and shrink it from this one knob. `68%` leaves breathing room inside the
|
|
19
|
+
box; it also sizes the indeterminate mark since that shares the mask box.
|
|
20
|
+
Authored in `variables/_base.scss` and emitted from `output-base-css-variables`,
|
|
21
|
+
so both `base.css` and the `pure-css.css` bundle carry it. Mirrors the canonical
|
|
22
|
+
`@keenmate/base-css-variables` contract (parity guard green).
|
|
23
|
+
|
|
24
|
+
## [1.0.5] — 2026-09-18 [PUBLISHED]
|
|
25
|
+
|
|
26
|
+
### Fixed
|
|
27
|
+
|
|
28
|
+
- **Ordered lists (`<ol>`) regressed to `disc` bullets instead of numbers.** In
|
|
29
|
+
1.0.4 the `--pc-list-bullet-type` knob was applied to the shared `ul, ol`
|
|
30
|
+
reboot rule with a `disc` default, so every `<ol>` (bare, or `.pa-list-ordered`
|
|
31
|
+
and any consumer's ordered list) rendered filled bullets instead of `decimal`
|
|
32
|
+
numbers. The marker knob is an **unordered** concern, so it now lives on a
|
|
33
|
+
`ul`-only rule; `<ol>` keeps the browser-default `decimal` (ordered-marker
|
|
34
|
+
variants like roman/alpha stay a per-component override). The shared
|
|
35
|
+
margin/padding rule on `ul, ol` is unchanged.
|
|
36
|
+
|
|
6
37
|
## [1.0.4] — 2026-09-18 [PUBLISHED]
|
|
7
38
|
|
|
8
39
|
### Added
|
package/README.md
CHANGED
|
@@ -1,218 +1,215 @@
|
|
|
1
|
-
# @keenmate/pure-css
|
|
2
|
-
|
|
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).
|
|
9
|
-
|
|
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.
|
|
14
|
-
|
|
15
|
-
## What's New in 1.0.
|
|
16
|
-
|
|
17
|
-
- **
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
utilities
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
|
82
|
-
|
|
|
83
|
-
| `dist/css/
|
|
84
|
-
| `dist/css/
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
The
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
<
|
|
100
|
-
<script src="node_modules/@keenmate/pure-css/src/js/
|
|
101
|
-
<script
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
|
129
|
-
|
|
|
130
|
-
| `--base-icon-
|
|
131
|
-
| `--base-icon-
|
|
132
|
-
| `--base-icon-
|
|
133
|
-
| `--base-icon-
|
|
134
|
-
| `--base-icon-
|
|
135
|
-
| `--base-icon-
|
|
136
|
-
| `--base-icon-
|
|
137
|
-
| `--base-icon-
|
|
138
|
-
| `--base-icon-
|
|
139
|
-
| `--base-icon-
|
|
140
|
-
| `--base-icon-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
-
|
|
148
|
-
|
|
149
|
-
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
:
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
*
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
## License
|
|
217
|
-
|
|
218
|
-
MIT © Keenmate. The grid is derived from [Pure](https://purecss.io/) (Yahoo!, BSD).
|
|
1
|
+
# @keenmate/pure-css
|
|
2
|
+
|
|
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).
|
|
9
|
+
|
|
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.
|
|
14
|
+
|
|
15
|
+
## What's New in 1.0.6
|
|
16
|
+
|
|
17
|
+
- **Icons — `--base-icon-check-size` turns the selection glyph's scale into a theme knob** — the check mark (`--base-icon-check`) and the indeterminate dash (`--base-icon-indeterminate`) share one mask box, but the size that box was painted at used to be hard-coded downstream. This adds a single `--base-icon-check-size` token (`68%` default, authored as `$base-icon-check-size` in `variables/_base.scss` and emitted from `output-base-css-variables`) that both pure-admin and every Keenmate web component read, so overriding the check glyph **and** its scale now re-sizes the mark in lockstep across the whole stack — drop in an edge-to-edge glyph such as a star and shrink it from this one knob. `68%` leaves breathing room inside the box, and because indeterminate shares the mask box it re-sizes too. Both `base.css` and the `pure-css.css` bundle emit it, and it mirrors the canonical `@keenmate/base-css-variables` contract (parity guard green).
|
|
18
|
+
|
|
19
|
+
## What's New in 1.0.5
|
|
20
|
+
|
|
21
|
+
- **Reboot — ordered lists (`<ol>`) render numbers again** — a 1.0.4 regression applied the new `--pc-list-bullet-type` knob to the shared `ul, ol` rule with a `disc` default, so every ordered list showed filled bullets instead of `decimal` numbers. The marker knob is an unordered concern, so it now sits on a `ul`-only rule; `<ol>` keeps the browser-default `decimal` (roman/alpha ordered variants stay a per-component override). The shared list margin/padding is unchanged, and `--pc-list-bullet-type` / `--base-list-bullet-type` continue to drive `ul` markers exactly as before.
|
|
22
|
+
|
|
23
|
+
## Why
|
|
24
|
+
|
|
25
|
+
pure-css is a **standalone foundation** you drop onto any surface — a docs site, a marketing page, a
|
|
26
|
+
widget host, or a full application. One small, dependency-free package gives you theming, layout and
|
|
27
|
+
utilities without buying into a component framework.
|
|
28
|
+
|
|
29
|
+
Its heart is a single **`--base-*` theming contract**: override one block of custom properties and
|
|
30
|
+
everything re-themes at once — the grid, the utilities, the optional app shell, and any component
|
|
31
|
+
that reads the same variables. Light and dark are built in via `light-dark()`, there's no build step
|
|
32
|
+
to consume it (just link the prebuilt CSS), and it pulls in no runtime dependencies.
|
|
33
|
+
|
|
34
|
+
```
|
|
35
|
+
@keenmate/pure-css (this package)
|
|
36
|
+
├─ --base-* theming contract
|
|
37
|
+
├─ .pc-row / .pc-col grid
|
|
38
|
+
├─ utility classes
|
|
39
|
+
└─ optional app shell + JS runtime
|
|
40
|
+
▲ consumed directly, as built CSS, by…
|
|
41
|
+
├── docs sites · portals · marketing pages · widget & component hosts
|
|
42
|
+
└── @keenmate/pure-admin-core — adds a full component library on top (just one consumer)
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npm install @keenmate/pure-css
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Quick Start
|
|
52
|
+
|
|
53
|
+
**Prebuilt CSS (simplest):**
|
|
54
|
+
|
|
55
|
+
```html
|
|
56
|
+
<link rel="stylesheet" href="node_modules/@keenmate/pure-css/dist/css/pure-css.css">
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
or cherry-pick:
|
|
60
|
+
|
|
61
|
+
```html
|
|
62
|
+
<link rel="stylesheet" href="…/pure-css/dist/css/base.css"> <!-- variables only -->
|
|
63
|
+
<link rel="stylesheet" href="…/pure-css/dist/css/grid.css"> <!-- + grid -->
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
**SCSS (customize before compiling):**
|
|
67
|
+
|
|
68
|
+
```scss
|
|
69
|
+
// Override the source of truth; everything re-derives.
|
|
70
|
+
$base-accent-color: #4f46e5;
|
|
71
|
+
$base-page-bg: #0b1020;
|
|
72
|
+
|
|
73
|
+
@use '@keenmate/pure-css/scss/pure-css';
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## What's in it
|
|
77
|
+
|
|
78
|
+
| Artifact | Contents | When to link |
|
|
79
|
+
| --- | --- | --- |
|
|
80
|
+
| `dist/css/pure-css.css` | everything below, in one file | the common case |
|
|
81
|
+
| `dist/css/base.css` | only `:root { --base-*; --pc-*; }` | you just need the theming contract (e.g. to theme embedded web components) or a base for a theme override |
|
|
82
|
+
| `dist/css/component-reset.css` | a `:host` reset (box-sizing + inherited typography pinned to `--base-*`) — the Shadow-DOM counterpart to reboot | building a web component: adopt it into the shadow root (e.g. `import '@keenmate/pure-css/component-reset?inline'`) so the host page can't bleed styles in; pair with `base` |
|
|
83
|
+
| `dist/css/grid.css` | `.pc-row` / `.pc-col-*` (percentage + fraction columns, container-query responsive) | layout only |
|
|
84
|
+
| `dist/css/utilities.css` | spacing / flex / display / width-height utilities (`.m-4`, `.d-flex`, `.w-50`, …) | utilities only |
|
|
85
|
+
|
|
86
|
+
The `pure-css.css` bundle also includes the **app shell** (navbar, sidebar,
|
|
87
|
+
layout container) — `base.css` / `grid.css` / `utilities.css` do not.
|
|
88
|
+
|
|
89
|
+
### The app-shell runtime (`./js`)
|
|
90
|
+
|
|
91
|
+
The shell's behaviour (nav fit/collapse, dropdowns, drag-to-resize, container
|
|
92
|
+
breakpoints) ships as dependency-free source JS via the `./js` export — no
|
|
93
|
+
bundler required, drop it in with a `<script>` and call `initAll`:
|
|
94
|
+
|
|
95
|
+
```html
|
|
96
|
+
<link rel="stylesheet" href="node_modules/@keenmate/pure-css/dist/css/pure-css.css">
|
|
97
|
+
<script src="node_modules/@keenmate/pure-css/src/js/pure-css.js"></script>
|
|
98
|
+
<script src="node_modules/@keenmate/pure-css/src/js/fit.js"></script>
|
|
99
|
+
<script src="node_modules/@keenmate/pure-css/src/js/navbar-dropdown.js"></script>
|
|
100
|
+
<script src="node_modules/@keenmate/pure-css/src/js/sidebar-resize.js"></script>
|
|
101
|
+
<script>window.pureCss.components.initAll(document);</script>
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
`window.pureCss` also exposes an event bus and live `viewport` / `colorScheme` /
|
|
105
|
+
`device` sources. The runtime is optional — shell CSS is authored no-JS-safe, so
|
|
106
|
+
the styling stands on its own and the JS only adds the interactive behaviour.
|
|
107
|
+
|
|
108
|
+
### The `--base-*` contract
|
|
109
|
+
|
|
110
|
+
`--base-*` is the **single source of truth for theming**. Framework colors, component variables
|
|
111
|
+
(`--pc-*`) and web/svelte components all derive from it via fallback chains
|
|
112
|
+
(`--ms-accent-color: var(--base-accent-color, #3b82f6)`). Categories: accent, text, background,
|
|
113
|
+
border, input, dropdown, tooltip, contextual (success/danger/warning/info), interactive states,
|
|
114
|
+
typography, border-radius, spacing/shadow/motion/z-index scales, and icons. The full list is
|
|
115
|
+
`src/scss/variables/_base.scss`.
|
|
116
|
+
|
|
117
|
+
#### Icons
|
|
118
|
+
|
|
119
|
+
`--base-icon-*` are mask-friendly SVG glyphs (Lucide defaults) for the shared UI affordances, so the
|
|
120
|
+
pure-css shell, pure-admin components, and the web/svelte components render the **same** marks and a
|
|
121
|
+
theme re-skins them in one place. Each is consumed via `mask: var(--base-icon-x); background:
|
|
122
|
+
currentColor`, so the glyph inherits text colour — override a token with any mask-friendly `url()` to
|
|
123
|
+
swap the icon set.
|
|
124
|
+
|
|
125
|
+
| Token | Glyph | Use |
|
|
126
|
+
| --- | --- | --- |
|
|
127
|
+
| `--base-icon-chevron` | stroked angle `›` | expanders / nav — **rotate-one-glyph** disclosure (points right, rotate 90° when open) |
|
|
128
|
+
| `--base-icon-caret-down` / `--base-icon-caret-up` | solid triangles `▾` / `▴` | static dropdown / `<select>` affordance (down) and sort-direction / upward-dropdown counterpart (up) — a caret never rotates |
|
|
129
|
+
| `--base-icon-close` | `✕` | dismiss a transient **surface** (dialog, panel, popover, toast) |
|
|
130
|
+
| `--base-icon-clear` | `✕` | clear a **field** — distinct purpose, same glyph; **follows** `--base-icon-close`, override alone to diverge |
|
|
131
|
+
| `--base-icon-remove` | `✕` | take an **item** out of a collection (chip / tag / row) — non-destructive; follows `--base-icon-close` |
|
|
132
|
+
| `--base-icon-expand` / `--base-icon-collapse` | `+` / `−` | **swap-two-glyphs** disclosure (tree nodes, accordions): show `+` when collapsed, `−` when open |
|
|
133
|
+
| `--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) |
|
|
134
|
+
| `--base-icon-search` | magnifying glass | search inputs, command palette — find **by text** |
|
|
135
|
+
| `--base-icon-filter` | funnel | refine / **narrow a list** by criteria (filter toggles, faceted search) — distinct from `search` |
|
|
136
|
+
| `--base-icon-refresh` | two curved arrows | reload / re-fetch a view or dataset |
|
|
137
|
+
| `--base-icon-check` / `--base-icon-indeterminate` | `✓` / `−` | **selection** pair (checkboxes, multiselect, tree nodes): `check` = selected, `indeterminate` = a tri-state parent whose children are a mix |
|
|
138
|
+
| `--base-icon-copy` | two overlapping sheets | copy-to-clipboard |
|
|
139
|
+
| `--base-icon-ellipsis` | three dots `⋯` | "more / overflow" affordance — **rotate-one-glyph** for the vertical `⋮` variant (rotate 90°) |
|
|
140
|
+
| `--base-icon-save` | floppy disk | persist / commit |
|
|
141
|
+
|
|
142
|
+
Three intentional distinctions:
|
|
143
|
+
|
|
144
|
+
- **Disclosure models:** **chevron rotates one glyph** (sidebar, multiselect), while **expand/collapse swaps
|
|
145
|
+
two glyphs** (trees, accordions) — a component never rotates a `+` into a `−`.
|
|
146
|
+
- **✕ vs trash:** `close` / `clear` / `remove` are three *dismiss* purposes that share the ✕ glyph (and
|
|
147
|
+
cascade off `--base-icon-close`), while `delete` is a separate *destructive* action drawn as a trash can.
|
|
148
|
+
`add` shares the `+` shape with `expand` but is an independent knob (create ≠ disclosure).
|
|
149
|
+
- **Selection ≠ disclosure:** `indeterminate` shares the `−` shape with `collapse` but is its own knob —
|
|
150
|
+
a partially-selected checkbox is not a collapsed node.
|
|
151
|
+
|
|
152
|
+
## Theming
|
|
153
|
+
|
|
154
|
+
A **theme** is nothing but a set of `--base-*` values. The lightest possible theme is a stylesheet
|
|
155
|
+
that redeclares them, loaded *after* `base.css`:
|
|
156
|
+
|
|
157
|
+
```css
|
|
158
|
+
:root {
|
|
159
|
+
--base-accent-color: #4f46e5;
|
|
160
|
+
--base-page-bg: #f6f8fb;
|
|
161
|
+
--base-text-color-1: #1a2233;
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Because pure-admin-core, the components and any consumer all read the same variables, that one block
|
|
166
|
+
re-themes all of them at once. This is the same model as
|
|
167
|
+
[`@keenmate/pure-admin-themes`](https://github.com/Keenmate/pure-admin-themes), so the same CLI and
|
|
168
|
+
publishing infrastructure applies.
|
|
169
|
+
|
|
170
|
+
### Mode & variant class placement
|
|
171
|
+
|
|
172
|
+
Light/dark and colour-variant switching is done by toggling a class — `.pc-mode-light` /
|
|
173
|
+
`.pc-mode-dark` and `.pa-color-*`. **Apply these to the `:root` element (`<html>`), not `<body>`.**
|
|
174
|
+
|
|
175
|
+
The mode/variant blocks override input tokens (`--pc-*` / `--base-*`). Many themed tokens are
|
|
176
|
+
*derived* from those inputs and emitted once at `:root` — e.g. core emits
|
|
177
|
+
`--pa-btn-info-bg: var(--pc-info)`. CSS resolves a custom property's `var()` **at the element that
|
|
178
|
+
declares it**, so a derived token declared on `:root` bakes in `:root`'s input value. If the mode
|
|
179
|
+
class sits on a *descendant* (`<body>`), the override comes too late and the derived token stays
|
|
180
|
+
frozen at the default-mode value — the classic symptom is a role button or surface that doesn't
|
|
181
|
+
change colour when you switch modes. Putting the class on `:root` (the same element that declares
|
|
182
|
+
the tokens) makes the overrides win and the derived tokens re-resolve.
|
|
183
|
+
|
|
184
|
+
pure-css re-emits its own base text-tier tokens at `:root, .pc-mode-light, .pc-mode-dark` to tolerate
|
|
185
|
+
either placement, but that does not extend to the pure-admin component layer, hence the `:root` rule.
|
|
186
|
+
|
|
187
|
+
To avoid a colour "flash" on switch, disable transitions for one frame during the swap (add a
|
|
188
|
+
`transition: none !important` class to `:root`, change the mode/variant class, force a reflow, then
|
|
189
|
+
remove it).
|
|
190
|
+
|
|
191
|
+
## Build
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
make install # sass
|
|
195
|
+
make build # src/scss -> dist/css (bundle + base + grid + utilities)
|
|
196
|
+
make sizes # show artifact sizes
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
`dist/` is committed so consumers can vendor the built CSS without a Sass toolchain.
|
|
200
|
+
|
|
201
|
+
## Provenance
|
|
202
|
+
|
|
203
|
+
The SCSS is the foundation extracted from `pure-admin-core`'s `src/scss` — the `variables/` modules,
|
|
204
|
+
`_base-css-variables.scss`, `utilities.scss`, `_fonts.scss`, and the native grid (`_pa-grid.scss`,
|
|
205
|
+
formerly core's `core-components/_grid.scss`). **pure-admin-core now consumes this package** as its
|
|
206
|
+
single source for the foundation (thin `@import`/`@forward` shims), so the two no longer drift —
|
|
207
|
+
core's compiled `--base-*` values and grid output match pure-css exactly.
|
|
208
|
+
|
|
209
|
+
One intentional difference: `utilities.scss` here `@use`s `_fonts.scss` so the generic
|
|
210
|
+
`.font-family-*` classes ship with the other utilities, whereas core keeps `_fonts.scss` standalone.
|
|
211
|
+
`_rtl-helpers.scss` and the component layer stay in core.
|
|
212
|
+
|
|
213
|
+
## License
|
|
214
|
+
|
|
215
|
+
MIT © Keenmate. The grid is derived from [Pure](https://purecss.io/) (Yahoo!, BSD).
|
package/dist/css/base.css
CHANGED
|
@@ -140,6 +140,7 @@
|
|
|
140
140
|
--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");
|
|
141
141
|
--base-icon-refresh: 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 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8%22/%3E%3Cpath d=%22M21 3v5h-5%22/%3E%3Cpath d=%22M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16%22/%3E%3Cpath d=%22M3 21v-5h5%22/%3E%3C/svg%3E");
|
|
142
142
|
--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");
|
|
143
|
+
--base-icon-check-size: 68%;
|
|
143
144
|
--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");
|
|
144
145
|
--base-icon-copy: 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%3Crect width=%2214%22 height=%2214%22 x=%228%22 y=%228%22 rx=%222%22 ry=%222%22/%3E%3Cpath d=%22M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2%22/%3E%3C/svg%3E");
|
|
145
146
|
--base-icon-ellipsis: 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=%2212%22 cy=%2212%22 r=%221%22/%3E%3Ccircle cx=%2219%22 cy=%2212%22 r=%221%22/%3E%3Ccircle cx=%225%22 cy=%2212%22 r=%221%22/%3E%3C/svg%3E");
|
package/dist/css/pure-css.css
CHANGED
|
@@ -44,12 +44,15 @@ ul, ol {
|
|
|
44
44
|
margin: 0 0 1.6rem 0;
|
|
45
45
|
padding: 0;
|
|
46
46
|
padding-inline-start: 3.2rem;
|
|
47
|
-
list-style-type: var(--pc-list-bullet-type, var(--base-list-bullet-type, disc));
|
|
48
47
|
}
|
|
49
48
|
ul li, ol li {
|
|
50
49
|
margin-bottom: 0.4rem;
|
|
51
50
|
}
|
|
52
51
|
|
|
52
|
+
ul {
|
|
53
|
+
list-style-type: var(--pc-list-bullet-type, var(--base-list-bullet-type, disc));
|
|
54
|
+
}
|
|
55
|
+
|
|
53
56
|
ul.unstyled, ol.unstyled {
|
|
54
57
|
list-style: none;
|
|
55
58
|
padding-inline-start: 0;
|
|
@@ -6083,6 +6086,7 @@ body.pc-layout--sticky .pc-layout__inner {
|
|
|
6083
6086
|
--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");
|
|
6084
6087
|
--base-icon-refresh: 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 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8%22/%3E%3Cpath d=%22M21 3v5h-5%22/%3E%3Cpath d=%22M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16%22/%3E%3Cpath d=%22M3 21v-5h5%22/%3E%3C/svg%3E");
|
|
6085
6088
|
--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");
|
|
6089
|
+
--base-icon-check-size: 68%;
|
|
6086
6090
|
--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");
|
|
6087
6091
|
--base-icon-copy: 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%3Crect width=%2214%22 height=%2214%22 x=%228%22 y=%228%22 rx=%222%22 ry=%222%22/%3E%3Cpath d=%22M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2%22/%3E%3C/svg%3E");
|
|
6088
6092
|
--base-icon-ellipsis: 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=%2212%22 cy=%2212%22 r=%221%22/%3E%3Ccircle cx=%2219%22 cy=%2212%22 r=%221%22/%3E%3Ccircle cx=%225%22 cy=%2212%22 r=%221%22/%3E%3C/svg%3E");
|
package/dist/css/reboot.css
CHANGED
|
@@ -33,12 +33,15 @@ ul, ol {
|
|
|
33
33
|
margin: 0 0 1.6rem 0;
|
|
34
34
|
padding: 0;
|
|
35
35
|
padding-inline-start: 3.2rem;
|
|
36
|
-
list-style-type: var(--pc-list-bullet-type, var(--base-list-bullet-type, disc));
|
|
37
36
|
}
|
|
38
37
|
ul li, ol li {
|
|
39
38
|
margin-bottom: 0.4rem;
|
|
40
39
|
}
|
|
41
40
|
|
|
41
|
+
ul {
|
|
42
|
+
list-style-type: var(--pc-list-bullet-type, var(--base-list-bullet-type, disc));
|
|
43
|
+
}
|
|
44
|
+
|
|
42
45
|
ul.unstyled, ol.unstyled {
|
|
43
46
|
list-style: none;
|
|
44
47
|
padding-inline-start: 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@keenmate/pure-css",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.6",
|
|
4
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": {
|
|
@@ -228,6 +228,10 @@
|
|
|
228
228
|
// Shared by web-multiselect / web-treeview / checkboxes. indeterminate shares the
|
|
229
229
|
// minus shape with collapse but is its OWN knob (selection ≠ disclosure).
|
|
230
230
|
--base-icon-check: #{$base-icon-check};
|
|
231
|
+
// mask-size for the selection glyph inside its box — one knob every consumer
|
|
232
|
+
// reads, so overriding the glyph AND its scale re-sizes the mark in lockstep.
|
|
233
|
+
// Also sizes indeterminate (it shares the mask box).
|
|
234
|
+
--base-icon-check-size: #{$base-icon-check-size};
|
|
231
235
|
--base-icon-indeterminate: #{$base-icon-indeterminate};
|
|
232
236
|
|
|
233
237
|
// === Action / affordance icons ===
|
package/src/scss/reboot.scss
CHANGED
|
@@ -64,24 +64,32 @@ ul, ol {
|
|
|
64
64
|
margin: $list-margin-top 0 $list-margin-bottom 0;
|
|
65
65
|
padding: 0;
|
|
66
66
|
padding-inline-start: $list-padding-left; // RTL: flips to right
|
|
67
|
-
// Runtime-overridable marker. Set --pc-list-bullet-type (disc | circle |
|
|
68
|
-
// square | none | decimal | …) at :root, on an ancestor, or per-instance
|
|
69
|
-
// (style="--pc-list-bullet-type: square") to switch the marker without a
|
|
70
|
-
// recompile. It layers over the base contract: --pc-list-bullet-type wins when
|
|
71
|
-
// set, else the themeable --base-list-bullet-type default (emitted by
|
|
72
|
-
// output-base-css-variables), else the inline browser-default disc. The --pc-
|
|
73
|
-
// knob itself is not emitted by the variable mixins — set it only where a
|
|
74
|
-
// per-instance marker is wanted. Components that reset the marker
|
|
75
|
-
// (list-style: none on nav/sidebar menus, .unstyled, pure-admin's
|
|
76
|
-
// --unstyled/--bordered/… list modifiers) win on source order, so this only
|
|
77
|
-
// affects lists that still show a marker.
|
|
78
|
-
list-style-type: var(--pc-list-bullet-type, var(--base-list-bullet-type, disc));
|
|
79
67
|
|
|
80
68
|
li {
|
|
81
69
|
margin-bottom: $list-item-margin-bottom;
|
|
82
70
|
}
|
|
83
71
|
}
|
|
84
72
|
|
|
73
|
+
// Runtime-overridable UNORDERED marker — ul only, so <ol> keeps its numbers
|
|
74
|
+
// (a shared `ul, ol` rule with a `disc` default turned ordered lists into
|
|
75
|
+
// bullets). Set --pc-list-bullet-type (disc | circle | square | none | …) at
|
|
76
|
+
// :root, on an ancestor, or per-instance (style="--pc-list-bullet-type: square")
|
|
77
|
+
// to switch the marker without a recompile. It layers over the base contract:
|
|
78
|
+
// --pc-list-bullet-type wins when set, else the themeable --base-list-bullet-type
|
|
79
|
+
// default (emitted by output-base-css-variables), else the inline browser-default
|
|
80
|
+
// disc. The --pc- knob itself is not emitted by the variable mixins — set it only
|
|
81
|
+
// where a per-instance marker is wanted. Components that reset the marker
|
|
82
|
+
// (list-style: none on nav/sidebar menus, .unstyled, pure-admin's
|
|
83
|
+
// --unstyled/--bordered/… list modifiers) win on source order, so this only
|
|
84
|
+
// affects unordered lists that still show a marker. By design this applies at
|
|
85
|
+
// EVERY nesting depth (a single, controllable marker), so nested <ul>s all use
|
|
86
|
+
// the same marker rather than the browser's disc→circle→square depth cascade —
|
|
87
|
+
// intentional, not a bug: the knob trades depth-varying markers for one uniform,
|
|
88
|
+
// themeable bullet.
|
|
89
|
+
ul {
|
|
90
|
+
list-style-type: var(--pc-list-bullet-type, var(--base-list-bullet-type, disc));
|
|
91
|
+
}
|
|
92
|
+
|
|
85
93
|
// Lists - unstyled (for navigation, etc.)
|
|
86
94
|
ul.unstyled, ol.unstyled {
|
|
87
95
|
list-style: none;
|
|
@@ -374,6 +374,11 @@ $base-icon-refresh: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/20
|
|
|
374
374
|
// Selection: check = ✓ (Lucide check), indeterminate = − (Lucide minus). indeterminate
|
|
375
375
|
// shares the minus shape with `collapse` but is its own knob (selection ≠ disclosure).
|
|
376
376
|
$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;
|
|
377
|
+
// mask-size for the selection glyph inside its box. One knob both pure-admin and
|
|
378
|
+
// the web components read, so overriding the glyph AND its scale re-sizes the mark
|
|
379
|
+
// everywhere at once. 68% leaves breathing room; an edge-to-edge glyph (e.g. a
|
|
380
|
+
// star) can be shrunk from here. Also sizes indeterminate (shares the mask box).
|
|
381
|
+
$base-icon-check-size: 68% !default;
|
|
377
382
|
$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;
|
|
378
383
|
// copy = two overlapping sheets (Lucide copy); ellipsis = three dots (Lucide
|
|
379
384
|
// ellipsis, the "more / overflow" affordance — the vertical variant is the same
|