@keenmate/pure-css 1.0.2 → 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,69 @@
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
+
35
+ ## [1.0.3] — 2026-09-16 [PUBLISHED]
36
+
37
+ ### Added
38
+
39
+ - **Three affordance icon tokens: `--base-icon-settings`, `--base-icon-bell`,
40
+ `--base-icon-user`.** Mask-friendly Lucide glyphs (`settings` = cog / gear;
41
+ `bell` = notification bell; `user` = person / profile), added to
42
+ `variables/_base.scss` and emitted from `output-base-css-variables` (both
43
+ `base.css` and the `pure-css.css` bundle carry them). For preferences/config,
44
+ notification, and profile affordances; consumed by pure-admin's
45
+ `--pa-icon-settings` / `--pa-icon-bell` / `--pa-icon-user`. Mirrors the
46
+ canonical `@keenmate/base-css-variables` contract (parity guard green).
47
+ - **Four status / severity icon tokens: `--base-icon-info`,
48
+ `--base-icon-success`, `--base-icon-warning`, `--base-icon-danger`.**
49
+ Mask-friendly Lucide glyphs (info = circle-i, success = circle-check,
50
+ warning = triangle-alert, danger = circle-x), added to `variables/_base.scss`
51
+ and emitted from `output-base-css-variables` (both `base.css` and the
52
+ `pure-css.css` bundle carry them). One shared family so every severity surface
53
+ shows the same mark; consumed by pure-admin's `--pa-icon-info` / `-success` /
54
+ `-warning` / `-danger`. Mirrors the canonical `@keenmate/base-css-variables`
55
+ contract (parity guard green).
56
+
57
+ ### Changed
58
+
59
+ - **The sidebar search icon (`.pc-sidebar__search-icon`) is now a masked
60
+ `--base-icon-search` glyph instead of a `🔍` text emoji.** Painted in
61
+ `currentColor` via `mask` (same technique as `.pc-sidebar__chevron`), so it
62
+ renders identically across platforms/fonts and re-skins from the shared
63
+ `--base-icon-search` knob — matching pure-admin's `.pa-icon--search` and the
64
+ navbar search. `font-size: 0` collapses any legacy `🔍` still in markup so it
65
+ never double-renders; consumers can drop the emoji from the button
66
+ (`<button class="pc-sidebar__search-icon">`). The literal Lucide glyph remains
67
+ the standalone fallback when `base.css` is absent.
68
+
6
69
  ## [1.0.2] — 2026-09-15 [PUBLISHED]
7
70
 
8
71
  ### Added
package/README.md CHANGED
@@ -12,13 +12,16 @@ 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.2
15
+ ## What's New in 1.0.4
16
16
 
17
- - **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`.
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`.
18
19
 
19
- ## What's New in 1.0.1
20
+ ## What's New in 1.0.3
20
21
 
21
- - **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.
22
+ - **Iconsseven 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`.
23
+
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.
22
25
 
23
26
  ## Why
24
27
 
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;
@@ -143,6 +144,16 @@
143
144
  --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");
144
145
  --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");
145
146
  --base-icon-save: 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.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z%22/%3E%3Cpath d=%22M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7%22/%3E%3Cpath d=%22M7 3v4a1 1 0 0 0 1 1h7%22/%3E%3C/svg%3E");
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");
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");
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");
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");
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");
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");
156
+ --base-icon-danger: 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=%22m15 9-6 6%22/%3E%3Cpath d=%22m9 9 6 6%22/%3E%3C/svg%3E");
146
157
  --base-color-1: #f59e0b;
147
158
  --base-color-2: #ec4899;
148
159
  --base-color-3: #10b981;
@@ -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;
@@ -2463,17 +2464,15 @@ body.loaded .pc-sidebar__search {
2463
2464
  width: 2.4rem;
2464
2465
  min-width: 2.4rem;
2465
2466
  height: 2.4rem;
2466
- display: flex;
2467
- align-items: center;
2468
- justify-content: center;
2469
2467
  flex-shrink: 0;
2470
2468
  padding: 0;
2471
2469
  border: none;
2472
- background: transparent;
2473
- color: inherit;
2474
- font-size: 1.6rem;
2475
- line-height: 1;
2476
2470
  cursor: pointer;
2471
+ color: inherit;
2472
+ font-size: 0;
2473
+ background-color: currentColor;
2474
+ -webkit-mask: var(--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")) center/1.6rem no-repeat;
2475
+ mask: var(--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")) center/1.6rem no-repeat;
2477
2476
  }
2478
2477
  .pc-sidebar__search--input .pc-sidebar__search-field {
2479
2478
  flex: 1;
@@ -6064,6 +6063,7 @@ body.pc-layout--sticky .pc-layout__inner {
6064
6063
  --base-line-height-tight: 1.25;
6065
6064
  --base-line-height-normal: 1.5;
6066
6065
  --base-line-height-relaxed: 1.75;
6066
+ --base-list-bullet-type: disc;
6067
6067
  --base-border-radius-sm: 0.4;
6068
6068
  --base-border-radius-md: 0.6;
6069
6069
  --base-border-radius-lg: 0.8;
@@ -6087,6 +6087,16 @@ body.pc-layout--sticky .pc-layout__inner {
6087
6087
  --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
6088
  --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");
6089
6089
  --base-icon-save: 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.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z%22/%3E%3Cpath d=%22M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7%22/%3E%3Cpath d=%22M7 3v4a1 1 0 0 0 1 1h7%22/%3E%3C/svg%3E");
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");
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");
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");
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");
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");
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");
6099
+ --base-icon-danger: 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=%22m15 9-6 6%22/%3E%3Cpath d=%22m9 9 6 6%22/%3E%3C/svg%3E");
6090
6100
  --base-color-1: #f59e0b;
6091
6101
  --base-color-2: #ec4899;
6092
6102
  --base-color-3: #10b981;
@@ -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.2",
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};
@@ -237,6 +238,26 @@
237
238
  --base-icon-copy: #{$base-icon-copy};
238
239
  --base-icon-ellipsis: #{$base-icon-ellipsis};
239
240
  --base-icon-save: #{$base-icon-save};
241
+ // settings = cog / gear. Consumed by pure-admin's --pa-icon-settings.
242
+ --base-icon-settings: #{$base-icon-settings};
243
+ // bell = notification bell. Consumed by pure-admin's --pa-icon-bell.
244
+ --base-icon-bell: #{$base-icon-bell};
245
+ // user = person. Consumed by pure-admin's --pa-icon-user.
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};
252
+
253
+ // === Status / severity icons — shared toast/alert/callout/notification set ===
254
+ // info = circle-i, success = circle-check, warning = triangle-alert,
255
+ // danger = circle-x. Consumed by pure-admin's --pa-icon-info / -success /
256
+ // -warning / -danger so every severity surface shows the same mark.
257
+ --base-icon-info: #{$base-icon-info};
258
+ --base-icon-success: #{$base-icon-success};
259
+ --base-icon-warning: #{$base-icon-warning};
260
+ --base-icon-danger: #{$base-icon-danger};
240
261
 
241
262
  // === Theme palette slots (1–9) + paired contrast text (WS7.6) ===
242
263
  // Promoted into the --base-* contract so the branded/data-viz palette is
@@ -262,17 +262,21 @@ body.pc-layout--sticky .pc-layout__sidebar {
262
262
  width: $sidebar-icon-size;
263
263
  min-width: $sidebar-icon-size;
264
264
  height: $sidebar-icon-size;
265
- display: flex;
266
- align-items: center;
267
- justify-content: center;
268
265
  flex-shrink: 0;
269
266
  padding: 0;
270
267
  border: none;
271
- background: transparent;
272
- color: inherit;
273
- font-size: $font-size-base;
274
- line-height: 1; // prevent emoji baseline shift, matching __icon
275
268
  cursor: pointer;
269
+ color: inherit;
270
+ // Masked magnifier painted in currentColor — was a 🔍 text emoji, which
271
+ // rendered inconsistently across platforms/fonts (the same reason the
272
+ // sidebar chevron is masked above). Reads the shared --base-icon-search
273
+ // so it matches pure-admin's .pa-icon--search and the navbar search;
274
+ // #{$base-icon-search} is the standalone literal fallback. font-size:0
275
+ // collapses any legacy 🔍 still in markup so it never double-renders.
276
+ font-size: 0;
277
+ background-color: currentColor;
278
+ -webkit-mask: var(--base-icon-search, #{$base-icon-search}) center / #{$font-size-base} no-repeat;
279
+ mask: var(--base-icon-search, #{$base-icon-search}) center / #{$font-size-base} no-repeat;
276
280
  }
277
281
 
278
282
  .pc-sidebar__search-field {
@@ -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)
@@ -377,6 +381,24 @@ $base-icon-indeterminate: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.
377
381
  $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") !default;
378
382
  $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") !default;
379
383
  $base-icon-save: 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.2 3a2 2 0 0 1 1.4.6l3.8 3.8a2 2 0 0 1 .6 1.4V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2z%22/%3E%3Cpath d=%22M17 21v-7a1 1 0 0 0-1-1H8a1 1 0 0 0-1 1v7%22/%3E%3Cpath d=%22M7 3v4a1 1 0 0 0 1 1h7%22/%3E%3C/svg%3E") !default;
384
+ // settings = cog / gear (Lucide settings): preferences / config affordance.
385
+ $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") !default;
386
+ // bell = notification bell (Lucide bell): the navbar bell button glyph.
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;
388
+ // user = person (Lucide user): profile trigger button / avatar placeholder.
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;
396
+ // Status / severity icons (shared toast/alert/callout/notification set): info =
397
+ // circle-i, success = circle-check, warning = triangle-alert, danger = circle-x.
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;
399
+ $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") !default;
400
+ $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") !default;
401
+ $base-icon-danger: 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=%22m15 9-6 6%22/%3E%3Cpath d=%22m9 9 6 6%22/%3E%3C/svg%3E") !default;
380
402
 
381
403
  // =============================================================================
382
404
  // ALERT COLOR DERIVATION PARAMETERS