@keenmate/pure-css 1.0.6 → 1.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +55 -0
- package/README.md +5 -4
- package/dist/css/pure-css.css +25 -9
- package/package.json +83 -83
- package/src/scss/_base-css-variables.scss +12 -5
- package/src/scss/_icon-hover.scss +64 -0
- package/src/scss/_sidebar.scss +447 -459
- package/src/scss/pure-css.scss +48 -47
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,61 @@
|
|
|
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.1.1] — 2026-09-26 [PUBLISHED]
|
|
7
|
+
|
|
8
|
+
### Fixed
|
|
9
|
+
|
|
10
|
+
- **Themes could not override `$base-*` — `_base-css-variables.scss` now `@import`s
|
|
11
|
+
the variable vocabulary instead of `@use`ing it.** The file pulled its
|
|
12
|
+
`$`-vocabulary in with `@use 'variables/index' as *`, but Sass refuses to expose
|
|
13
|
+
a member whose name already exists in the importing global scope — so any consumer
|
|
14
|
+
that set a `$base-*` value **before** importing (exactly what a theme does, relying
|
|
15
|
+
on the `!default` flags) failed with *"This module and the new module both define a
|
|
16
|
+
variable named $base-accent-color"*. The workflow documented at the top of that
|
|
17
|
+
file therefore worked only for a theme that overrode nothing, and the first real
|
|
18
|
+
downstream theme (`keen-docs-themes/cobalt2`) could not build. Switched to
|
|
19
|
+
`@import 'variables/index'`, which shares the one global scope the `!default`
|
|
20
|
+
mechanism needs (the same reason `variables/_index.scss` uses `@import`). pure-css's
|
|
21
|
+
own `@use 'base-css-variables' as bcv` entry points are unaffected. Behaviour-
|
|
22
|
+
preserving for the prebuilt CSS: all 7 artifacts rebuilt, every emitted `--base-*`
|
|
23
|
+
token name and value identical. Committed as `40b5b88`; it reached `prod` just after
|
|
24
|
+
the 1.1.0 tarball was cut, so 1.1.1 is its first published release.
|
|
25
|
+
|
|
26
|
+
## [1.1.0] — 2026-09-26 [PUBLISHED]
|
|
27
|
+
|
|
28
|
+
### Changed
|
|
29
|
+
|
|
30
|
+
- **Sidebar link / submenu-toggle hover is now instant (removed `transition: all`).**
|
|
31
|
+
`.pc-sidebar__link`, the submenu toggle, and the sidebar search trigger animated
|
|
32
|
+
their hover with `transition: all $transition-fast`, which swept in `color` /
|
|
33
|
+
`background-color` — so the hover tint *faded in* and felt sluggish. Their hover
|
|
34
|
+
only changes colours (no motion), so the transition was pure colour animation,
|
|
35
|
+
against the "colours snap; transitions are motion-only" rule. Removed it; hover
|
|
36
|
+
colours now snap. The genuine motion transitions are kept — the submenu chevron
|
|
37
|
+
rotation (`transform`) and the icon-collapse label fade (`opacity` / `width`).
|
|
38
|
+
|
|
39
|
+
### Added
|
|
40
|
+
|
|
41
|
+
- **Icon hover affordance (foundation) — `_icon-hover.scss`.** Inside an enabled
|
|
42
|
+
interactive control on `:hover`, icons react with no JS and no SVG computation,
|
|
43
|
+
driven by convention + marker classes a wrapper stamps:
|
|
44
|
+
- masked `.pa-icon` glyphs that declared `--pa-icon-src-hover` swap to the
|
|
45
|
+
filled source (automatic; no-op for outline-only sets like Lucide);
|
|
46
|
+
- Font Awesome `<i>` marked `.pc-icon-hover-fill` flips regular → solid via the
|
|
47
|
+
`font-weight` axis (needs the `far` face, i.e. FA Pro);
|
|
48
|
+
- outline icons marked `.pc-icon-hover-highlight` recolour to
|
|
49
|
+
`--pc-icon-hover-color` (default: `--pc-accent`) — the hover cue for sets with
|
|
50
|
+
no solid form.
|
|
51
|
+
|
|
52
|
+
Applied to the shell contexts the foundation owns (`.pc-sidebar__link:hover` and
|
|
53
|
+
the submenu `.pc-sidebar__toggle:hover`, so submenu parents match plain/child
|
|
54
|
+
items) and a generic opt-in wrapper `.pc-icon-hover` for any enabled control. The behaviour
|
|
55
|
+
is exposed as the `pc-icon-hover-effects` mixin so component layers (pure-admin
|
|
56
|
+
core on `.pa-btn` / `.pa-tabs__item`, etc.) can apply the same effects to their
|
|
57
|
+
own selectors without redefining them. Additive; no change to existing output.
|
|
58
|
+
(Two-asset outline↔solid toggle for Heroicons / Fluent is a follow-up, wired
|
|
59
|
+
when a wrapper renders both layers.) See `pure-admin/docs/icon-hover-fill-design.md`.
|
|
60
|
+
|
|
6
61
|
## [1.0.6] — 2026-09-20 [PUBLISHED]
|
|
7
62
|
|
|
8
63
|
### Added
|
package/README.md
CHANGED
|
@@ -12,13 +12,14 @@ 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.
|
|
15
|
+
## What's New in 1.1.1
|
|
16
16
|
|
|
17
|
-
- **
|
|
17
|
+
- **Theming — downstream themes can finally override `$base-*` at compile time** — `_base-css-variables.scss` loaded its `$`-vocabulary with `@use 'variables/index' as *`, but Sass won't re-expose a member that already exists in the importing global scope, so any theme that set `$base-*` values *before* importing (the whole point of the `!default` contract) crashed with *"both define a variable named $base-accent-color"* — the workflow documented in that file compiled only when the theme overrode nothing, and the first real theme (`keen-docs-themes/cobalt2`) couldn't build. Switching to `@import 'variables/index'` shares the single global scope the `!default` mechanism relies on (the same reason `variables/_index.scss` uses `@import`), so `$base-*` overrides now land. It's behaviour-preserving for the prebuilt CSS — all seven artifacts rebuilt with every emitted `--base-*` name and value identical — and pure-css's own `@use … as bcv` entry points are unchanged. This landed just after the 1.1.0 tarball was cut, so 1.1.1 is the first release to actually ship it.
|
|
18
18
|
|
|
19
|
-
## What's New in 1.0
|
|
19
|
+
## What's New in 1.1.0
|
|
20
20
|
|
|
21
|
-
- **
|
|
21
|
+
- **Icons — hover affordance for interactive controls, no JS (`_icon-hover.scss`)** — icons inside an enabled control now react on `:hover` through pure CSS, driven by convention plus marker classes a wrapper stamps: masked `.pa-icon` glyphs that declared `--pa-icon-src-hover` swap to their filled source (automatic; a no-op for outline-only sets like Lucide), Font Awesome `<i>` marked `.pc-icon-hover-fill` flips regular → solid on the `font-weight` axis (needs the FA Pro `far` face), and outline icons marked `.pc-icon-hover-highlight` recolour to `--pc-icon-hover-color` (default `--pc-accent`) for sets with no solid form. The foundation applies it to the shell context it owns (`.pc-sidebar__link:hover`) and ships a generic opt-in wrapper `.pc-icon-hover` for any enabled control. Crucially the behaviour is exposed as the `pc-icon-hover-effects` SCSS mixin, so component layers (pure-admin core on `.pa-btn` / `.pa-tabs__item`, etc.) apply the exact same effects to their own selectors from one shared definition rather than redefining them. Additive — no change to existing output.
|
|
22
|
+
- **Sidebar — hover colours snap instead of fading** — `.pc-sidebar__link`, the submenu toggle, and the sidebar search trigger animated their hover with `transition: all $transition-fast`, which swept `color` / `background-color` so the hover tint faded in and felt sluggish. Their hover changes colours only (no motion), so per the "colours snap; transitions are motion-only" rule the transition was pure colour animation and has been removed — hover colours now snap. The genuine motion transitions are untouched: the submenu chevron rotation (`transform`) and the icon-collapse label fade (`opacity` / `width`).
|
|
22
23
|
|
|
23
24
|
## Why
|
|
24
25
|
|
package/dist/css/pure-css.css
CHANGED
|
@@ -2413,9 +2413,6 @@ body.pc-layout--sticky .pc-layout__sidebar {
|
|
|
2413
2413
|
font-weight: 500;
|
|
2414
2414
|
border-inline-end: 3px solid transparent;
|
|
2415
2415
|
}
|
|
2416
|
-
body.loaded .pc-sidebar__link {
|
|
2417
|
-
transition: all 0.1s ease-out;
|
|
2418
|
-
}
|
|
2419
2416
|
.pc-sidebar__link:hover {
|
|
2420
2417
|
color: var(--pc-sidebar-text, var(--base-text-color-1));
|
|
2421
2418
|
background-color: var(--pc-accent-light);
|
|
@@ -2445,9 +2442,6 @@ body.loaded .pc-sidebar__link {
|
|
|
2445
2442
|
.pc-sidebar__search[hidden] {
|
|
2446
2443
|
display: none;
|
|
2447
2444
|
}
|
|
2448
|
-
body.loaded .pc-sidebar__search {
|
|
2449
|
-
transition: all 0.1s ease-out;
|
|
2450
|
-
}
|
|
2451
2445
|
.pc-sidebar__search:hover {
|
|
2452
2446
|
border-color: #0ea5e9;
|
|
2453
2447
|
color: var(--base-input-color);
|
|
@@ -2513,9 +2507,6 @@ body.loaded .pc-sidebar__search {
|
|
|
2513
2507
|
font-weight: 500;
|
|
2514
2508
|
cursor: pointer;
|
|
2515
2509
|
}
|
|
2516
|
-
body.loaded .pc-sidebar__toggle {
|
|
2517
|
-
transition: all 0.1s ease-out;
|
|
2518
|
-
}
|
|
2519
2510
|
.pc-sidebar__toggle:hover {
|
|
2520
2511
|
color: var(--pc-sidebar-text, var(--base-text-color-1));
|
|
2521
2512
|
background-color: var(--pc-accent-light);
|
|
@@ -3133,6 +3124,31 @@ body.pc-layout--sticky .pc-layout__inner {
|
|
|
3133
3124
|
border-top: 1px solid var(--pc-border-color);
|
|
3134
3125
|
}
|
|
3135
3126
|
|
|
3127
|
+
.pc-sidebar__link:not([aria-disabled=true]):not(.is-disabled):hover .pa-icon,
|
|
3128
|
+
.pc-sidebar__toggle:not([aria-disabled=true]):not(.is-disabled):hover .pa-icon {
|
|
3129
|
+
-webkit-mask-image: var(--pa-icon-src-hover, var(--pa-icon-src));
|
|
3130
|
+
mask-image: var(--pa-icon-src-hover, var(--pa-icon-src));
|
|
3131
|
+
}
|
|
3132
|
+
.pc-sidebar__link:not([aria-disabled=true]):not(.is-disabled):hover .pc-icon-hover-fill,
|
|
3133
|
+
.pc-sidebar__toggle:not([aria-disabled=true]):not(.is-disabled):hover .pc-icon-hover-fill {
|
|
3134
|
+
font-weight: 900;
|
|
3135
|
+
}
|
|
3136
|
+
.pc-sidebar__link:not([aria-disabled=true]):not(.is-disabled):hover .pc-icon-hover-highlight,
|
|
3137
|
+
.pc-sidebar__toggle:not([aria-disabled=true]):not(.is-disabled):hover .pc-icon-hover-highlight {
|
|
3138
|
+
color: var(--pc-icon-hover-color, var(--pc-accent));
|
|
3139
|
+
}
|
|
3140
|
+
|
|
3141
|
+
.pc-icon-hover:not([disabled]):not([aria-disabled=true]):not(.is-disabled):hover .pa-icon {
|
|
3142
|
+
-webkit-mask-image: var(--pa-icon-src-hover, var(--pa-icon-src));
|
|
3143
|
+
mask-image: var(--pa-icon-src-hover, var(--pa-icon-src));
|
|
3144
|
+
}
|
|
3145
|
+
.pc-icon-hover:not([disabled]):not([aria-disabled=true]):not(.is-disabled):hover .pc-icon-hover-fill {
|
|
3146
|
+
font-weight: 900;
|
|
3147
|
+
}
|
|
3148
|
+
.pc-icon-hover:not([disabled]):not([aria-disabled=true]):not(.is-disabled):hover .pc-icon-hover-highlight {
|
|
3149
|
+
color: var(--pc-icon-hover-color, var(--pc-accent));
|
|
3150
|
+
}
|
|
3151
|
+
|
|
3136
3152
|
.font-family-system {
|
|
3137
3153
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
3138
3154
|
}
|
package/package.json
CHANGED
|
@@ -1,83 +1,83 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@keenmate/pure-css",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "The Keenmate CSS foundation — --base-* theming contract, PureCSS grid and utility classes. Extracted from pure-admin-core so docs sites, standalone pages and every web/svelte component share one theming layer.",
|
|
5
|
-
"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.1.1",
|
|
4
|
+
"description": "The Keenmate CSS foundation — --base-* theming contract, PureCSS grid and utility classes. Extracted from pure-admin-core so docs sites, standalone pages and every web/svelte component share one theming layer.",
|
|
5
|
+
"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
|
+
}
|
|
@@ -14,11 +14,18 @@
|
|
|
14
14
|
// --ms-accent-color: var(--base-accent-color, #3b82f6);
|
|
15
15
|
// ============================================================================
|
|
16
16
|
|
|
17
|
-
// Make
|
|
18
|
-
//
|
|
19
|
-
//
|
|
20
|
-
//
|
|
21
|
-
|
|
17
|
+
// Make the $-vocabulary resolvable here.
|
|
18
|
+
//
|
|
19
|
+
// MUST be @import, not `@use 'variables/index' as *`. A theme's whole job is to set
|
|
20
|
+
// $base-* BEFORE pulling this file in (the !default flags then keep those values) --
|
|
21
|
+
// but `@use ... as *` REFUSES to expose a member whose name already exists in the
|
|
22
|
+
// importing global scope, so every theme died on
|
|
23
|
+
// "This module and the new module both define a variable named $base-accent-color".
|
|
24
|
+
// That made the usage documented at the top of this file impossible: it worked only
|
|
25
|
+
// for a theme that overrode nothing. @import shares one global scope and is what the
|
|
26
|
+
// !default mechanism needs. pure-css's own `@use 'base-css-variables' as bcv` entries
|
|
27
|
+
// are unaffected -- a module that @imports still exports its members normally.
|
|
28
|
+
@import 'variables/index';
|
|
22
29
|
|
|
23
30
|
@mixin output-base-css-variables {
|
|
24
31
|
// === Accent Colors ===
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// ── Icon hover affordance (foundation) ────────────────────────────────────────
|
|
2
|
+
// See pure-admin/docs/icon-hover-fill-design.md.
|
|
3
|
+
//
|
|
4
|
+
// Inside an ENABLED interactive control on :hover, icons react — no JS, no SVG
|
|
5
|
+
// computation, driven by convention + marker classes the wrapper stamps:
|
|
6
|
+
//
|
|
7
|
+
// • Masked `.pa-icon` glyphs that declared a filled source on
|
|
8
|
+
// `--pa-icon-src-hover` swap their mask to it. NO-OP for outline-only glyphs
|
|
9
|
+
// (e.g. Lucide ships no solid), and no marker needed — it's automatic.
|
|
10
|
+
// • Font Awesome `<i>` marked `.pc-icon-hover-fill` flips regular → solid via the
|
|
11
|
+
// font-weight axis (same codepoint). Needs the `far` regular face present
|
|
12
|
+
// (largely FA Pro), else there's nothing lighter to flip from.
|
|
13
|
+
// • Outline icons marked `.pc-icon-hover-highlight` recolour to
|
|
14
|
+
// `--pc-icon-hover-color` (default: the accent). This is the answer for sets
|
|
15
|
+
// with no solid form (Lucide): a real hover cue without a fill.
|
|
16
|
+
//
|
|
17
|
+
// The behaviour lives here (foundation) so every consumer — pure-admin core,
|
|
18
|
+
// keen, svelte, the web components — shares ONE definition. Wrappers only stamp
|
|
19
|
+
// the marker classes. `pc-icon-hover-effects` is a mixin so component layers can
|
|
20
|
+
// apply the same effects to their own enabled-control selectors (e.g. core on
|
|
21
|
+
// `.pa-btn` / `.pa-tabs__item`) without redefining them.
|
|
22
|
+
//
|
|
23
|
+
// Deliberately NOT here yet: the two-asset outline↔solid toggle for Heroicons /
|
|
24
|
+
// Fluent (render both layers, swap visibility) — that needs a wrapper markup
|
|
25
|
+
// contract, so it's wired when a wrapper renders both layers.
|
|
26
|
+
|
|
27
|
+
@mixin pc-icon-hover-effects {
|
|
28
|
+
// Masked icons: swap to the filled mask source if one was declared. Set the
|
|
29
|
+
// longhand directly (not --pa-icon-src) so the var(--pa-icon-src) fallback
|
|
30
|
+
// stays non-cyclic — reassigning --pa-icon-src to reference itself would
|
|
31
|
+
// compute to invalid and wipe the mask to a solid box.
|
|
32
|
+
.pa-icon {
|
|
33
|
+
-webkit-mask-image: var(--pa-icon-src-hover, var(--pa-icon-src));
|
|
34
|
+
mask-image: var(--pa-icon-src-hover, var(--pa-icon-src));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Font Awesome regular → solid (weight axis). No transition — a font-weight
|
|
38
|
+
// swap is instant, matching the mask swap.
|
|
39
|
+
.pc-icon-hover-fill {
|
|
40
|
+
font-weight: 900;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Outline-only sets (Lucide): recolour the stroke instead of filling. Works
|
|
44
|
+
// because Lucide SVGs are stroke="currentColor".
|
|
45
|
+
.pc-icon-hover-highlight {
|
|
46
|
+
color: var(--pc-icon-hover-color, var(--pc-accent));
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Shell contexts owned by the foundation: sidebar nav links AND submenu toggles,
|
|
51
|
+
// so a submenu parent's icon reacts identically to a plain/child link (not just
|
|
52
|
+
// to the toggle's own hover colour).
|
|
53
|
+
.pc-sidebar__link:not([aria-disabled='true']):not(.is-disabled):hover,
|
|
54
|
+
.pc-sidebar__toggle:not([aria-disabled='true']):not(.is-disabled):hover {
|
|
55
|
+
@include pc-icon-hover-effects;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Generic opt-in: put `.pc-icon-hover` on any enabled control/element to get the
|
|
59
|
+
// behaviour without depending on a component class (a bare link, a custom
|
|
60
|
+
// button, a list row, …). Disabled opt-outs are excluded so only actionable
|
|
61
|
+
// controls react.
|
|
62
|
+
.pc-icon-hover:not([disabled]):not([aria-disabled='true']):not(.is-disabled):hover {
|
|
63
|
+
@include pc-icon-hover-effects;
|
|
64
|
+
}
|