@keenmate/pure-css 1.0.3 → 1.0.4

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,35 @@
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.4] — 2026-09-18 [PUBLISHED]
7
+
8
+ ### Added
9
+
10
+ - **`--pc-list-bullet-type` — runtime list-marker knob on the `ul, ol` reboot,
11
+ backed by the `--base-list-bullet-type` contract.** Switch a list's marker
12
+ (`disc` / `circle` / `square` / `none` / `decimal` / …) without a recompile: set
13
+ `--pc-list-bullet-type` at `:root`, on an ancestor, or per-instance
14
+ (`style="--pc-list-bullet-type: square"`). Applies to every list since it sits on
15
+ the base `ul, ol` reboot. It resolves as
16
+ `var(--pc-list-bullet-type, var(--base-list-bullet-type, disc))` — the per-instance
17
+ `--pc-` knob wins when set, else the themeable `--base-list-bullet-type` default
18
+ (newly added to `@keenmate/base-css-variables`, mirrored as `$base-list-bullet-type`
19
+ and emitted from `output-base-css-variables` in both `base.css` and the bundle),
20
+ else the inline browser-default `disc`. The `--pc-` knob itself is **not** emitted by
21
+ `output-*` mixins — set it only where a per-instance marker is wanted. Lists that
22
+ reset the marker (`list-style: none` on nav/sidebar menus, `.unstyled`, downstream
23
+ `--unstyled` / `--bordered` / … modifiers) still win on source order.
24
+ - **Three action / navigation icon tokens: `--base-icon-download`,
25
+ `--base-icon-link`, `--base-icon-external-link`.** Mask-friendly Lucide glyphs
26
+ (`download` = tray + down arrow for save-to-disk / export; `link` = chain for
27
+ hyperlink / attach-URL; `external-link` = diagonal arrow-out-of-box for links
28
+ that open in a new tab / leave the app), added to `variables/_base.scss` and
29
+ emitted from `output-base-css-variables` (both `base.css` and the `pure-css.css`
30
+ bundle carry them). Consumed by pure-admin's `--pa-icon-download` /
31
+ `--pa-icon-link` / `--pa-icon-external-link` (which fell back to inline glyphs
32
+ until these landed). Mirrors the canonical `@keenmate/base-css-variables`
33
+ contract (parity guard green).
34
+
6
35
  ## [1.0.3] — 2026-09-16 [PUBLISHED]
7
36
 
8
37
  ### Added
package/README.md CHANGED
@@ -12,16 +12,17 @@ It's the shared layer the whole Keenmate stack agrees on:
12
12
  top of it, and every Keenmate web/Svelte component reads its colours from the same `--base-*`
13
13
  variables.
14
14
 
15
+ ## What's New in 1.0.4
16
+
17
+ - **Reboot — `--pc-list-bullet-type` turns the list marker into a runtime knob, backed by the `--base-*` contract** — every `ul` / `ol` styled by `reboot.scss` now reads its `list-style-type` from `var(--pc-list-bullet-type, var(--base-list-bullet-type, disc))`, so you can switch a list's marker (`disc` / `circle` / `square` / `none` / `decimal` / …) without a recompile: set `--pc-list-bullet-type` at `:root`, on an ancestor, or per-instance via `style="--pc-list-bullet-type: square"`. The per-instance `--pc-` knob wins when set, else the themeable `--base-list-bullet-type` default (new in `@keenmate/base-css-variables`, emitted at `:root` by `base.css` and the bundle), else the inline browser-default `disc`. The `--pc-` knob itself is deliberately **not** emitted by the `output-*` variable mixins — you opt in only where a per-instance marker is wanted. Lists that intentionally drop the marker (`list-style: none` on nav/sidebar menus, `.unstyled`, pure-admin's `--unstyled` / `--bordered` / … list modifiers) still win on source order, so this only affects lists that already show a marker.
18
+ - **Icons — `download`, `link` and `external-link` glyphs join the `--base-*` contract** — three more mask-friendly Lucide glyphs so every consumer paints the same actions from one theme knob. `--base-icon-download` (a tray + down arrow) is save-to-disk / export, `--base-icon-link` (a chain) is the hyperlink / attach-URL mark, and `--base-icon-external-link` (a diagonal arrow-out-of-box) is its companion for links that open in a new tab / leave the app. All are authored in `variables/_base.scss` and emitted from `output-base-css-variables`, so both the standalone `base.css` and the `pure-css.css` bundle carry them; they mirror the canonical `@keenmate/base-css-variables` contract (parity guard green) and back pure-admin's `--pa-icon-download` / `-link` / `-external-link`, which routed through these names with inline fallbacks until now. Consume via `mask: var(--base-icon-link); background: currentColor`.
19
+
15
20
  ## What's New in 1.0.3
16
21
 
17
22
  - **Icons — seven more glyphs join the `--base-*` contract: config/notification/profile plus the full status family** — three affordance marks and a shared severity family, so every consumer paints them from one theme knob. `--base-icon-settings` (a cog), `--base-icon-bell` (a notification bell) and `--base-icon-user` (a person) cover the preferences / notifications / profile trio, while `--base-icon-info` (circle-i), `--base-icon-success` (circle-check), `--base-icon-warning` (triangle-alert) and `--base-icon-danger` (circle-x) form one severity family so every alert, toast and badge shows the same mark. All are mask-friendly Lucide glyphs authored in `variables/_base.scss` and emitted from `output-base-css-variables`, so both the standalone `base.css` and the `pure-css.css` bundle carry them; they mirror the canonical `@keenmate/base-css-variables` contract (parity guard green) and back pure-admin's `--pa-icon-settings` / `-bell` / `-user` / `-info` / `-success` / `-warning` / `-danger`. Consume via `mask: var(--base-icon-info); background: currentColor`.
18
23
 
19
24
  - **Sidebar search — the magnifier is now a themeable masked glyph, not a 🔍 emoji** — `.pc-sidebar__search-icon` previously rendered a literal 🔍 text emoji, which varied by platform and font and couldn't be re-skinned. It's now painted in `currentColor` via `mask: var(--base-icon-search)` — the same technique as `.pc-sidebar__chevron` — so it renders identically everywhere and re-skins from the shared `--base-icon-search` knob, matching the navbar search and pure-admin's `.pa-icon--search`. `font-size: 0` collapses any legacy 🔍 still in markup so it never double-renders, letting consumers drop the emoji from `<button class="pc-sidebar__search-icon">`; the literal Lucide glyph stays the standalone fallback when `base.css` is absent.
20
25
 
21
- ## What's New in 1.0.2
22
-
23
- - **Icons — `copy`, `ellipsis`, `save` and `refresh` glyphs join the shared `--base-*` contract** — four more mask-friendly Lucide glyphs so every consumer paints the same actions from one theme knob. `--base-icon-copy` (two overlapping sheets) is copy-to-clipboard, `--base-icon-ellipsis` (three dots) is the "more / overflow" mark — its vertical `⋮` variant is the *same glyph rotated 90°* (the rotate-one-glyph discipline already used for `chevron`), so there's no separate token to maintain — `--base-icon-save` (a floppy disk) is persist / commit, and `--base-icon-refresh` (two curved arrows, Lucide `refresh-cw`) is reload / re-fetch, sitting alongside `search` and `filter` in the utility-icon row (consumers typically spin it with a CSS animation while a fetch is in flight). The action trio completes the affordance set pure-admin migrated off Font Awesome: its `--pa-icon-copy` / `-ellipsis` / `-save` already routed through these `--base-icon-*` names with inline fallbacks, so they become fully theme-overridable with zero pure-admin change. All are authored in `variables/_base.scss` and emitted from `output-base-css-variables`, so both the standalone `base.css` and the `pure-css.css` bundle carry them; consume via `mask: var(--base-icon-copy); background: currentColor`.
24
-
25
26
  ## Why
26
27
 
27
28
  pure-css is a **standalone foundation** you drop onto any surface — a docs site, a marketing page, a
package/dist/css/base.css CHANGED
@@ -120,6 +120,7 @@
120
120
  --base-line-height-tight: 1.25;
121
121
  --base-line-height-normal: 1.5;
122
122
  --base-line-height-relaxed: 1.75;
123
+ --base-list-bullet-type: disc;
123
124
  --base-border-radius-sm: 0.4;
124
125
  --base-border-radius-md: 0.6;
125
126
  --base-border-radius-lg: 0.8;
@@ -146,6 +147,9 @@
146
147
  --base-icon-settings: 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.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915%22/%3E%3Ccircle cx=%2212%22 cy=%2212%22 r=%223%22/%3E%3C/svg%3E");
147
148
  --base-icon-bell: 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=%22M10.268 21a2 2 0 0 0 3.464 0%22/%3E%3Cpath d=%22M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326%22/%3E%3C/svg%3E");
148
149
  --base-icon-user: 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=%22M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2%22/%3E%3Ccircle cx=%2212%22 cy=%227%22 r=%224%22/%3E%3C/svg%3E");
150
+ --base-icon-download: 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=%22M12 15V3%22/%3E%3Cpath d=%22M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4%22/%3E%3Cpath d=%22m7 10 5 5 5-5%22/%3E%3C/svg%3E");
151
+ --base-icon-link: 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=%22M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71%22/%3E%3Cpath d=%22M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71%22/%3E%3C/svg%3E");
152
+ --base-icon-external-link: 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=%22M15 3h6v6%22/%3E%3Cpath d=%22M10 14 21 3%22/%3E%3Cpath d=%22M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6%22/%3E%3C/svg%3E");
149
153
  --base-icon-info: 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=%2210%22/%3E%3Cpath d=%22M12 16v-4%22/%3E%3Cpath d=%22M12 8h.01%22/%3E%3C/svg%3E");
150
154
  --base-icon-success: 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=%2210%22/%3E%3Cpath d=%22m16 9-5.5 5.5L8 12%22/%3E%3C/svg%3E");
151
155
  --base-icon-warning: 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=%22m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3%22/%3E%3Cpath d=%22M12 9v4%22/%3E%3Cpath d=%22M12 17h.01%22/%3E%3C/svg%3E");
@@ -44,6 +44,7 @@ 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));
47
48
  }
48
49
  ul li, ol li {
49
50
  margin-bottom: 0.4rem;
@@ -6062,6 +6063,7 @@ body.pc-layout--sticky .pc-layout__inner {
6062
6063
  --base-line-height-tight: 1.25;
6063
6064
  --base-line-height-normal: 1.5;
6064
6065
  --base-line-height-relaxed: 1.75;
6066
+ --base-list-bullet-type: disc;
6065
6067
  --base-border-radius-sm: 0.4;
6066
6068
  --base-border-radius-md: 0.6;
6067
6069
  --base-border-radius-lg: 0.8;
@@ -6088,6 +6090,9 @@ body.pc-layout--sticky .pc-layout__inner {
6088
6090
  --base-icon-settings: 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.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915%22/%3E%3Ccircle cx=%2212%22 cy=%2212%22 r=%223%22/%3E%3C/svg%3E");
6089
6091
  --base-icon-bell: 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=%22M10.268 21a2 2 0 0 0 3.464 0%22/%3E%3Cpath d=%22M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326%22/%3E%3C/svg%3E");
6090
6092
  --base-icon-user: 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=%22M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2%22/%3E%3Ccircle cx=%2212%22 cy=%227%22 r=%224%22/%3E%3C/svg%3E");
6093
+ --base-icon-download: 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=%22M12 15V3%22/%3E%3Cpath d=%22M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4%22/%3E%3Cpath d=%22m7 10 5 5 5-5%22/%3E%3C/svg%3E");
6094
+ --base-icon-link: 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=%22M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71%22/%3E%3Cpath d=%22M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71%22/%3E%3C/svg%3E");
6095
+ --base-icon-external-link: 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=%22M15 3h6v6%22/%3E%3Cpath d=%22M10 14 21 3%22/%3E%3Cpath d=%22M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6%22/%3E%3C/svg%3E");
6091
6096
  --base-icon-info: 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=%2210%22/%3E%3Cpath d=%22M12 16v-4%22/%3E%3Cpath d=%22M12 8h.01%22/%3E%3C/svg%3E");
6092
6097
  --base-icon-success: 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=%2210%22/%3E%3Cpath d=%22m16 9-5.5 5.5L8 12%22/%3E%3C/svg%3E");
6093
6098
  --base-icon-warning: 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=%22m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3%22/%3E%3Cpath d=%22M12 9v4%22/%3E%3Cpath d=%22M12 17h.01%22/%3E%3C/svg%3E");
@@ -33,6 +33,7 @@ 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));
36
37
  }
37
38
  ul li, ol li {
38
39
  margin-bottom: 0.4rem;
package/package.json CHANGED
@@ -1,83 +1,83 @@
1
- {
2
- "name": "@keenmate/pure-css",
3
- "version": "1.0.3",
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
- "style": "dist/css/pure-css.css",
6
- "exports": {
7
- ".": "./dist/css/pure-css.css",
8
- "./css": "./dist/css/pure-css.css",
9
- "./css/*": "./dist/css/*",
10
- "./base": "./dist/css/base.css",
11
- "./reboot": "./dist/css/reboot.css",
12
- "./component-reset": "./dist/css/component-reset.css",
13
- "./scrollbars": "./dist/css/scrollbars.css",
14
- "./grid": "./dist/css/grid.css",
15
- "./utilities": "./dist/css/utilities.css",
16
- "./scss": "./src/scss/pure-css.scss",
17
- "./scss/*": "./src/scss/*",
18
- "./js": "./src/js/pure-css.js",
19
- "./js/*": "./src/js/*"
20
- },
21
- "files": [
22
- "dist/",
23
- "src/scss/",
24
- "src/js/",
25
- "README.md",
26
- "CHANGELOG.md",
27
- "LICENSE"
28
- ],
29
- "scripts": {
30
- "build:bundle": "sass src/scss/pure-css.scss dist/css/pure-css.css --no-source-map --silence-deprecation=import",
31
- "build:base": "sass src/scss/base.scss dist/css/base.css --no-source-map --silence-deprecation=import",
32
- "build:reboot": "sass src/scss/reboot.scss dist/css/reboot.css --no-source-map --silence-deprecation=import",
33
- "build:component-reset": "sass src/scss/component-reset.scss dist/css/component-reset.css --no-source-map --silence-deprecation=import",
34
- "build:scrollbars": "sass src/scss/scrollbars.scss dist/css/scrollbars.css --no-source-map --silence-deprecation=import",
35
- "build:grid": "sass src/scss/grid.scss dist/css/grid.css --no-source-map --silence-deprecation=import",
36
- "build:utilities": "sass src/scss/utilities.scss dist/css/utilities.css --no-source-map --silence-deprecation=import",
37
- "build": "npm run build:bundle && npm run build:base && npm run build:reboot && npm run build:component-reset && npm run build:scrollbars && npm run build:grid && npm run build:utilities",
38
- "watch": "sass --watch src/scss/pure-css.scss:dist/css/pure-css.css --silence-deprecation=import",
39
- "dev": "vite --port 12500",
40
- "test": "npm run test:e2e",
41
- "test:e2e": "playwright test",
42
- "test:e2e:ui": "playwright test --ui",
43
- "test:e2e:headed": "playwright test --headed",
44
- "test:e2e:install": "playwright install chromium",
45
- "prepublishOnly": "npm run build"
46
- },
47
- "keywords": [
48
- "css",
49
- "scss",
50
- "purecss",
51
- "grid",
52
- "utilities",
53
- "css-variables",
54
- "theming",
55
- "keenmate",
56
- "pure-admin"
57
- ],
58
- "author": "Keenmate",
59
- "license": "MIT",
60
- "peerDependencies": {
61
- "sass": "^1.0.0"
62
- },
63
- "devDependencies": {
64
- "@playwright/test": "^1.60.0",
65
- "sass": "^1.70.0",
66
- "vite": "^5.4.0"
67
- },
68
- "repository": {
69
- "type": "git",
70
- "url": "git+https://github.com/Keenmate/pure-css.git"
71
- },
72
- "bugs": {
73
- "url": "https://github.com/Keenmate/pure-css/issues"
74
- },
75
- "homepage": "https://github.com/Keenmate/pure-css#readme",
76
- "publishConfig": {
77
- "access": "public"
78
- },
79
- "allowScripts": {
80
- "esbuild@0.21.5": true,
81
- "@parcel/watcher@2.6.0": true
82
- }
83
- }
1
+ {
2
+ "name": "@keenmate/pure-css",
3
+ "version": "1.0.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
+ "style": "dist/css/pure-css.css",
6
+ "exports": {
7
+ ".": "./dist/css/pure-css.css",
8
+ "./css": "./dist/css/pure-css.css",
9
+ "./css/*": "./dist/css/*",
10
+ "./base": "./dist/css/base.css",
11
+ "./reboot": "./dist/css/reboot.css",
12
+ "./component-reset": "./dist/css/component-reset.css",
13
+ "./scrollbars": "./dist/css/scrollbars.css",
14
+ "./grid": "./dist/css/grid.css",
15
+ "./utilities": "./dist/css/utilities.css",
16
+ "./scss": "./src/scss/pure-css.scss",
17
+ "./scss/*": "./src/scss/*",
18
+ "./js": "./src/js/pure-css.js",
19
+ "./js/*": "./src/js/*"
20
+ },
21
+ "files": [
22
+ "dist/",
23
+ "src/scss/",
24
+ "src/js/",
25
+ "README.md",
26
+ "CHANGELOG.md",
27
+ "LICENSE"
28
+ ],
29
+ "scripts": {
30
+ "build:bundle": "sass src/scss/pure-css.scss dist/css/pure-css.css --no-source-map --silence-deprecation=import",
31
+ "build:base": "sass src/scss/base.scss dist/css/base.css --no-source-map --silence-deprecation=import",
32
+ "build:reboot": "sass src/scss/reboot.scss dist/css/reboot.css --no-source-map --silence-deprecation=import",
33
+ "build:component-reset": "sass src/scss/component-reset.scss dist/css/component-reset.css --no-source-map --silence-deprecation=import",
34
+ "build:scrollbars": "sass src/scss/scrollbars.scss dist/css/scrollbars.css --no-source-map --silence-deprecation=import",
35
+ "build:grid": "sass src/scss/grid.scss dist/css/grid.css --no-source-map --silence-deprecation=import",
36
+ "build:utilities": "sass src/scss/utilities.scss dist/css/utilities.css --no-source-map --silence-deprecation=import",
37
+ "build": "npm run build:bundle && npm run build:base && npm run build:reboot && npm run build:component-reset && npm run build:scrollbars && npm run build:grid && npm run build:utilities",
38
+ "watch": "sass --watch src/scss/pure-css.scss:dist/css/pure-css.css --silence-deprecation=import",
39
+ "dev": "vite --port 12500",
40
+ "test": "npm run test:e2e",
41
+ "test:e2e": "playwright test",
42
+ "test:e2e:ui": "playwright test --ui",
43
+ "test:e2e:headed": "playwright test --headed",
44
+ "test:e2e:install": "playwright install chromium",
45
+ "prepublishOnly": "npm run build"
46
+ },
47
+ "keywords": [
48
+ "css",
49
+ "scss",
50
+ "purecss",
51
+ "grid",
52
+ "utilities",
53
+ "css-variables",
54
+ "theming",
55
+ "keenmate",
56
+ "pure-admin"
57
+ ],
58
+ "author": "Keenmate",
59
+ "license": "MIT",
60
+ "peerDependencies": {
61
+ "sass": "^1.0.0"
62
+ },
63
+ "devDependencies": {
64
+ "@playwright/test": "^1.60.0",
65
+ "sass": "^1.70.0",
66
+ "vite": "^5.4.0"
67
+ },
68
+ "repository": {
69
+ "type": "git",
70
+ "url": "git+https://github.com/Keenmate/pure-css.git"
71
+ },
72
+ "bugs": {
73
+ "url": "https://github.com/Keenmate/pure-css/issues"
74
+ },
75
+ "homepage": "https://github.com/Keenmate/pure-css#readme",
76
+ "publishConfig": {
77
+ "access": "public"
78
+ },
79
+ "allowScripts": {
80
+ "esbuild@0.21.5": true,
81
+ "@parcel/watcher@2.6.0": true
82
+ }
83
+ }
@@ -175,6 +175,7 @@
175
175
  --base-line-height-tight: #{$base-line-height-tight};
176
176
  --base-line-height-normal: #{$base-line-height-normal};
177
177
  --base-line-height-relaxed: #{$base-line-height-relaxed};
178
+ --base-list-bullet-type: #{$base-list-bullet-type};
178
179
 
179
180
  // === Border Radius ===
180
181
  --base-border-radius-sm: #{$base-border-radius-sm};
@@ -243,6 +244,11 @@
243
244
  --base-icon-bell: #{$base-icon-bell};
244
245
  // user = person. Consumed by pure-admin's --pa-icon-user.
245
246
  --base-icon-user: #{$base-icon-user};
247
+ // download = tray + down arrow; link = chain; external-link = arrow-out-of-box.
248
+ // Consumed by pure-admin's --pa-icon-download / -link / -external-link.
249
+ --base-icon-download: #{$base-icon-download};
250
+ --base-icon-link: #{$base-icon-link};
251
+ --base-icon-external-link: #{$base-icon-external-link};
246
252
 
247
253
  // === Status / severity icons — shared toast/alert/callout/notification set ===
248
254
  // info = circle-i, success = circle-check, warning = triangle-alert,
@@ -1,134 +1,146 @@
1
- // @keenmate/pure-css — reset & base element styling ("reboot")
2
- // ============================================================================
3
- // The foundation's reset layer. Establishes the 10px rem base that EVERY
4
- // pure-css rem value assumes (see variables/_typography.scss — `$font-size-base:
5
- // 1.6rem` is 16px only when the root is 10px), a border-box reset, and neutral
6
- // base styling for standard HTML elements (headings, paragraphs, links, lists,
7
- // blockquotes, rules, the body font/colour). Analogous to Bootstrap's Reboot.
8
- //
9
- // This lives in pure-css — not in a consuming app — because the 10px base is
10
- // part of the foundation's sizing contract: without it, a standalone consumer
11
- // inherits the browser's 16px root and every rem renders 1.6x too large. Link
12
- // it (or the full `pure-css.css` bundle) and the scale just works.
13
- //
14
- // App-specific base rules (the admin dashboard's decorative body background,
15
- // sidebar overflow handling) intentionally stay in pure-admin-core; a generic
16
- // foundation shouldn't impose them on every consumer.
17
- // ============================================================================
18
-
19
- @use 'variables/index' as *;
20
-
21
- // 10px rem base for intuitive sizing (1rem = 10px)
22
- // This makes calculations simple: 1.5rem = 15px, 3.5rem = 35px
23
- html {
24
- font-size: 10px;
25
- }
26
-
27
- // Reset and base styles
28
- * {
29
- box-sizing: border-box;
30
- }
31
-
32
- // Standard HTML element spacing (using framework variables)
33
- // Headings
34
- h1, h2, h3, h4, h5, h6 {
35
- margin: $heading-margin-top 0 $heading-margin-bottom 0;
36
- padding: 0;
37
- }
38
-
39
- // Paragraphs
40
- p {
41
- margin: $paragraph-margin-top 0 $paragraph-margin-bottom 0;
42
- padding: 0;
43
- }
44
-
45
- // Links — global default. Wrapped in :where() so specificity is 0,
46
- // letting component scopes (alerts, navbar, sidebar) override with even a
47
- // single class without fighting the pseudo-class specificity raise that
48
- // `a:hover` / `a:visited` would otherwise add (0,1,1 vs a class's 0,1,0).
49
- :where(a) {
50
- color: var(--pc-link-color);
51
- text-decoration: underline;
52
- }
53
-
54
- :where(a:hover) {
55
- color: var(--pc-link-color-hover);
56
- }
57
-
58
- :where(a:visited) {
59
- color: var(--pc-link-color-visited);
60
- }
61
-
62
- // Lists - styled lists (default browser styling)
63
- ul, ol {
64
- margin: $list-margin-top 0 $list-margin-bottom 0;
65
- padding: 0;
66
- padding-inline-start: $list-padding-left; // RTL: flips to right
67
-
68
- li {
69
- margin-bottom: $list-item-margin-bottom;
70
- }
71
- }
72
-
73
- // Lists - unstyled (for navigation, etc.)
74
- ul.unstyled, ol.unstyled {
75
- list-style: none;
76
- padding-inline-start: 0; // RTL: flips to right
77
-
78
- li {
79
- margin-bottom: 0;
80
- }
81
- }
82
-
83
- // Definition lists
84
- dl {
85
- margin: $list-margin-top 0 $list-margin-bottom 0;
86
- padding: 0;
87
- }
88
-
89
- dd {
90
- margin: 0;
91
- padding: 0;
92
- }
93
-
94
- // Blockquote
95
- blockquote {
96
- margin: $blockquote-margin-top 0 $blockquote-margin-bottom 0;
97
- padding-inline-start: $blockquote-padding-left; // RTL: flips to right
98
- }
99
-
100
- // Pre/Code blocks
101
- pre {
102
- overflow-x: auto;
103
- }
104
-
105
- // Horizontal rule
106
- hr {
107
- margin: $hr-margin-top 0 $hr-margin-bottom 0;
108
- }
109
-
110
- // Figure
111
- figure {
112
- margin: $figure-margin-top 0 $figure-margin-bottom 0;
113
- padding: 0;
114
- }
115
-
116
- body {
117
- margin: 0;
118
- padding: 0;
119
- font-family: var(--base-font-family);
120
- font-size: 1.6rem; // 16px default text (with 10px rem base)
121
- color: var(--pc-text-color-1);
122
- background-color: var(--pc-page-bg);
123
- line-height: $line-height-base;
124
- }
125
-
126
- // Ensure form elements and labels inherit theme font and size instead of browser defaults
127
- button,
128
- input,
129
- select,
130
- textarea,
131
- label {
132
- font-family: inherit;
133
- font-size: inherit;
134
- }
1
+ // @keenmate/pure-css — reset & base element styling ("reboot")
2
+ // ============================================================================
3
+ // The foundation's reset layer. Establishes the 10px rem base that EVERY
4
+ // pure-css rem value assumes (see variables/_typography.scss — `$font-size-base:
5
+ // 1.6rem` is 16px only when the root is 10px), a border-box reset, and neutral
6
+ // base styling for standard HTML elements (headings, paragraphs, links, lists,
7
+ // blockquotes, rules, the body font/colour). Analogous to Bootstrap's Reboot.
8
+ //
9
+ // This lives in pure-css — not in a consuming app — because the 10px base is
10
+ // part of the foundation's sizing contract: without it, a standalone consumer
11
+ // inherits the browser's 16px root and every rem renders 1.6x too large. Link
12
+ // it (or the full `pure-css.css` bundle) and the scale just works.
13
+ //
14
+ // App-specific base rules (the admin dashboard's decorative body background,
15
+ // sidebar overflow handling) intentionally stay in pure-admin-core; a generic
16
+ // foundation shouldn't impose them on every consumer.
17
+ // ============================================================================
18
+
19
+ @use 'variables/index' as *;
20
+
21
+ // 10px rem base for intuitive sizing (1rem = 10px)
22
+ // This makes calculations simple: 1.5rem = 15px, 3.5rem = 35px
23
+ html {
24
+ font-size: 10px;
25
+ }
26
+
27
+ // Reset and base styles
28
+ * {
29
+ box-sizing: border-box;
30
+ }
31
+
32
+ // Standard HTML element spacing (using framework variables)
33
+ // Headings
34
+ h1, h2, h3, h4, h5, h6 {
35
+ margin: $heading-margin-top 0 $heading-margin-bottom 0;
36
+ padding: 0;
37
+ }
38
+
39
+ // Paragraphs
40
+ p {
41
+ margin: $paragraph-margin-top 0 $paragraph-margin-bottom 0;
42
+ padding: 0;
43
+ }
44
+
45
+ // Links — global default. Wrapped in :where() so specificity is 0,
46
+ // letting component scopes (alerts, navbar, sidebar) override with even a
47
+ // single class without fighting the pseudo-class specificity raise that
48
+ // `a:hover` / `a:visited` would otherwise add (0,1,1 vs a class's 0,1,0).
49
+ :where(a) {
50
+ color: var(--pc-link-color);
51
+ text-decoration: underline;
52
+ }
53
+
54
+ :where(a:hover) {
55
+ color: var(--pc-link-color-hover);
56
+ }
57
+
58
+ :where(a:visited) {
59
+ color: var(--pc-link-color-visited);
60
+ }
61
+
62
+ // Lists - styled lists (default browser styling)
63
+ ul, ol {
64
+ margin: $list-margin-top 0 $list-margin-bottom 0;
65
+ padding: 0;
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
+
80
+ li {
81
+ margin-bottom: $list-item-margin-bottom;
82
+ }
83
+ }
84
+
85
+ // Lists - unstyled (for navigation, etc.)
86
+ ul.unstyled, ol.unstyled {
87
+ list-style: none;
88
+ padding-inline-start: 0; // RTL: flips to right
89
+
90
+ li {
91
+ margin-bottom: 0;
92
+ }
93
+ }
94
+
95
+ // Definition lists
96
+ dl {
97
+ margin: $list-margin-top 0 $list-margin-bottom 0;
98
+ padding: 0;
99
+ }
100
+
101
+ dd {
102
+ margin: 0;
103
+ padding: 0;
104
+ }
105
+
106
+ // Blockquote
107
+ blockquote {
108
+ margin: $blockquote-margin-top 0 $blockquote-margin-bottom 0;
109
+ padding-inline-start: $blockquote-padding-left; // RTL: flips to right
110
+ }
111
+
112
+ // Pre/Code blocks
113
+ pre {
114
+ overflow-x: auto;
115
+ }
116
+
117
+ // Horizontal rule
118
+ hr {
119
+ margin: $hr-margin-top 0 $hr-margin-bottom 0;
120
+ }
121
+
122
+ // Figure
123
+ figure {
124
+ margin: $figure-margin-top 0 $figure-margin-bottom 0;
125
+ padding: 0;
126
+ }
127
+
128
+ body {
129
+ margin: 0;
130
+ padding: 0;
131
+ font-family: var(--base-font-family);
132
+ font-size: 1.6rem; // 16px default text (with 10px rem base)
133
+ color: var(--pc-text-color-1);
134
+ background-color: var(--pc-page-bg);
135
+ line-height: $line-height-base;
136
+ }
137
+
138
+ // Ensure form elements and labels inherit theme font and size instead of browser defaults
139
+ button,
140
+ input,
141
+ select,
142
+ textarea,
143
+ label {
144
+ font-family: inherit;
145
+ font-size: inherit;
146
+ }
@@ -283,6 +283,10 @@ $base-line-height-tight: 1.25 !default;
283
283
  $base-line-height-normal: 1.5 !default;
284
284
  $base-line-height-relaxed: 1.75 !default;
285
285
 
286
+ // List marker — default bullet/number for ul, ol (disc | circle | square | none
287
+ // | decimal | …). Consumed on the base list reboot with an inline `disc` fallback.
288
+ $base-list-bullet-type: disc !default;
289
+
286
290
  // =============================================================================
287
291
  // BORDER RADIUS
288
292
  // Border radius sizes (unitless multipliers for x10px base)
@@ -383,6 +387,12 @@ $base-icon-settings: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2
383
387
  $base-icon-bell: 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=%22M10.268 21a2 2 0 0 0 3.464 0%22/%3E%3Cpath d=%22M3.262 15.326A1 1 0 0 0 4 17h16a1 1 0 0 0 .74-1.673C19.41 13.956 18 12.499 18 8A6 6 0 0 0 6 8c0 4.499-1.411 5.956-2.738 7.326%22/%3E%3C/svg%3E") !default;
384
388
  // user = person (Lucide user): profile trigger button / avatar placeholder.
385
389
  $base-icon-user: 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=%22M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2%22/%3E%3Ccircle cx=%2212%22 cy=%227%22 r=%224%22/%3E%3C/svg%3E") !default;
390
+ // download = tray + down arrow (Lucide download): save-to-disk / export. link =
391
+ // chain (Lucide link): hyperlink / attach-URL; external-link = diagonal
392
+ // arrow-out-of-box (Lucide external-link): opens in a new tab / leaves the app.
393
+ $base-icon-download: 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=%22M12 15V3%22/%3E%3Cpath d=%22M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4%22/%3E%3Cpath d=%22m7 10 5 5 5-5%22/%3E%3C/svg%3E") !default;
394
+ $base-icon-link: 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=%22M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71%22/%3E%3Cpath d=%22M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71%22/%3E%3C/svg%3E") !default;
395
+ $base-icon-external-link: 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=%22M15 3h6v6%22/%3E%3Cpath d=%22M10 14 21 3%22/%3E%3Cpath d=%22M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6%22/%3E%3C/svg%3E") !default;
386
396
  // Status / severity icons (shared toast/alert/callout/notification set): info =
387
397
  // circle-i, success = circle-check, warning = triangle-alert, danger = circle-x.
388
398
  $base-icon-info: 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=%2210%22/%3E%3Cpath d=%22M12 16v-4%22/%3E%3Cpath d=%22M12 8h.01%22/%3E%3C/svg%3E") !default;