@keenmate/pure-css 1.0.5 → 1.1.0

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,59 @@
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.0] — 2026-09-26 [PUBLISHED]
7
+
8
+ ### Changed
9
+
10
+ - **Sidebar link / submenu-toggle hover is now instant (removed `transition: all`).**
11
+ `.pc-sidebar__link`, the submenu toggle, and the sidebar search trigger animated
12
+ their hover with `transition: all $transition-fast`, which swept in `color` /
13
+ `background-color` — so the hover tint *faded in* and felt sluggish. Their hover
14
+ only changes colours (no motion), so the transition was pure colour animation,
15
+ against the "colours snap; transitions are motion-only" rule. Removed it; hover
16
+ colours now snap. The genuine motion transitions are kept — the submenu chevron
17
+ rotation (`transform`) and the icon-collapse label fade (`opacity` / `width`).
18
+
19
+ ### Added
20
+
21
+ - **Icon hover affordance (foundation) — `_icon-hover.scss`.** Inside an enabled
22
+ interactive control on `:hover`, icons react with no JS and no SVG computation,
23
+ driven by convention + marker classes a wrapper stamps:
24
+ - masked `.pa-icon` glyphs that declared `--pa-icon-src-hover` swap to the
25
+ filled source (automatic; no-op for outline-only sets like Lucide);
26
+ - Font Awesome `<i>` marked `.pc-icon-hover-fill` flips regular → solid via the
27
+ `font-weight` axis (needs the `far` face, i.e. FA Pro);
28
+ - outline icons marked `.pc-icon-hover-highlight` recolour to
29
+ `--pc-icon-hover-color` (default: `--pc-accent`) — the hover cue for sets with
30
+ no solid form.
31
+
32
+ Applied to the shell contexts the foundation owns (`.pc-sidebar__link:hover` and
33
+ the submenu `.pc-sidebar__toggle:hover`, so submenu parents match plain/child
34
+ items) and a generic opt-in wrapper `.pc-icon-hover` for any enabled control. The behaviour
35
+ is exposed as the `pc-icon-hover-effects` mixin so component layers (pure-admin
36
+ core on `.pa-btn` / `.pa-tabs__item`, etc.) can apply the same effects to their
37
+ own selectors without redefining them. Additive; no change to existing output.
38
+ (Two-asset outline↔solid toggle for Heroicons / Fluent is a follow-up, wired
39
+ when a wrapper renders both layers.) See `pure-admin/docs/icon-hover-fill-design.md`.
40
+
41
+ ## [1.0.6] — 2026-09-20 [PUBLISHED]
42
+
43
+ ### Added
44
+
45
+ - **`--base-icon-check-size` — a runtime mask-size knob for the selection glyph,
46
+ so the glyph and its scale re-theme in lockstep.** The check mark
47
+ (`--base-icon-check`) and the indeterminate dash (`--base-icon-indeterminate`)
48
+ share one mask box, but the size that box was painted at was hard-coded
49
+ downstream per consumer. This adds a single `$base-icon-check-size` (`68%`
50
+ default, emitted as `--base-icon-check-size`) that both pure-admin and the
51
+ Keenmate web components read, so overriding the check glyph **and** its scale
52
+ re-sizes the mark everywhere at once — e.g. swap in an edge-to-edge glyph like a
53
+ star and shrink it from this one knob. `68%` leaves breathing room inside the
54
+ box; it also sizes the indeterminate mark since that shares the mask box.
55
+ Authored in `variables/_base.scss` and emitted from `output-base-css-variables`,
56
+ so both `base.css` and the `pure-css.css` bundle carry it. Mirrors the canonical
57
+ `@keenmate/base-css-variables` contract (parity guard green).
58
+
6
59
  ## [1.0.5] — 2026-09-18 [PUBLISHED]
7
60
 
8
61
  ### Fixed
package/README.md CHANGED
@@ -12,14 +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.0.5
15
+ ## What's New in 1.1.0
16
16
 
17
- - **Reboot — ordered lists (`<ol>`) render numbers again** — a 1.0.4 regression applied the new `--pc-list-bullet-type` knob to the shared `ul, ol` rule with a `disc` default, so every ordered list showed filled bullets instead of `decimal` numbers. The marker knob is an unordered concern, so it now sits on a `ul`-only rule; `<ol>` keeps the browser-default `decimal` (roman/alpha ordered variants stay a per-component override). The shared list margin/padding is unchanged, and `--pc-list-bullet-type` / `--base-list-bullet-type` continue to drive `ul` markers exactly as before.
17
+ - **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.
18
+ - **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`).
18
19
 
19
- ## What's New in 1.0.4
20
+ ## What's New in 1.0.6
20
21
 
21
- - **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.
22
- - **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`.
22
+ - **Icons — `--base-icon-check-size` turns the selection glyph's scale into a theme knob** — the check mark (`--base-icon-check`) and the indeterminate dash (`--base-icon-indeterminate`) share one mask box, but the size that box was painted at used to be hard-coded downstream. This adds a single `--base-icon-check-size` token (`68%` default, authored as `$base-icon-check-size` in `variables/_base.scss` and emitted from `output-base-css-variables`) that both pure-admin and every Keenmate web component read, so overriding the check glyph **and** its scale now re-sizes the mark in lockstep across the whole stack — drop in an edge-to-edge glyph such as a star and shrink it from this one knob. `68%` leaves breathing room inside the box, and because indeterminate shares the mask box it re-sizes too. Both `base.css` and the `pure-css.css` bundle emit it, and it mirrors the canonical `@keenmate/base-css-variables` contract (parity guard green).
23
23
 
24
24
  ## Why
25
25
 
package/dist/css/base.css CHANGED
@@ -140,6 +140,7 @@
140
140
  --base-icon-filter: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpolygon points=%2222 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3%22/%3E%3C/svg%3E");
141
141
  --base-icon-refresh: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8%22/%3E%3Cpath d=%22M21 3v5h-5%22/%3E%3Cpath d=%22M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16%22/%3E%3Cpath d=%22M3 21v-5h5%22/%3E%3C/svg%3E");
142
142
  --base-icon-check: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M20 6 9 17l-5-5%22/%3E%3C/svg%3E");
143
+ --base-icon-check-size: 68%;
143
144
  --base-icon-indeterminate: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M5 12h14%22/%3E%3C/svg%3E");
144
145
  --base-icon-copy: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Crect width=%2214%22 height=%2214%22 x=%228%22 y=%228%22 rx=%222%22 ry=%222%22/%3E%3Cpath d=%22M4 16c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h10c1.1 0 2 .9 2 2%22/%3E%3C/svg%3E");
145
146
  --base-icon-ellipsis: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Ccircle cx=%2212%22 cy=%2212%22 r=%221%22/%3E%3Ccircle cx=%2219%22 cy=%2212%22 r=%221%22/%3E%3Ccircle cx=%225%22 cy=%2212%22 r=%221%22/%3E%3C/svg%3E");
@@ -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
  }
@@ -6086,6 +6102,7 @@ body.pc-layout--sticky .pc-layout__inner {
6086
6102
  --base-icon-filter: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpolygon points=%2222 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3%22/%3E%3C/svg%3E");
6087
6103
  --base-icon-refresh: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M3 12a9 9 0 0 1 9-9 9.75 9.75 0 0 1 6.74 2.74L21 8%22/%3E%3Cpath d=%22M21 3v5h-5%22/%3E%3Cpath d=%22M21 12a9 9 0 0 1-9 9 9.75 9.75 0 0 1-6.74-2.74L3 16%22/%3E%3Cpath d=%22M3 21v-5h5%22/%3E%3C/svg%3E");
6088
6104
  --base-icon-check: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M20 6 9 17l-5-5%22/%3E%3C/svg%3E");
6105
+ --base-icon-check-size: 68%;
6089
6106
  --base-icon-indeterminate: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M5 12h14%22/%3E%3C/svg%3E");
6090
6107
  --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");
6091
6108
  --base-icon-ellipsis: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Ccircle cx=%2212%22 cy=%2212%22 r=%221%22/%3E%3Ccircle cx=%2219%22 cy=%2212%22 r=%221%22/%3E%3Ccircle cx=%225%22 cy=%2212%22 r=%221%22/%3E%3C/svg%3E");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keenmate/pure-css",
3
- "version": "1.0.5",
3
+ "version": "1.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
5
  "style": "dist/css/pure-css.css",
6
6
  "exports": {
@@ -228,6 +228,10 @@
228
228
  // Shared by web-multiselect / web-treeview / checkboxes. indeterminate shares the
229
229
  // minus shape with collapse but is its OWN knob (selection ≠ disclosure).
230
230
  --base-icon-check: #{$base-icon-check};
231
+ // mask-size for the selection glyph inside its box — one knob every consumer
232
+ // reads, so overriding the glyph AND its scale re-sizes the mark in lockstep.
233
+ // Also sizes indeterminate (it shares the mask box).
234
+ --base-icon-check-size: #{$base-icon-check-size};
231
235
  --base-icon-indeterminate: #{$base-icon-indeterminate};
232
236
 
233
237
  // === Action / affordance icons ===
@@ -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
+ }
@@ -159,10 +159,6 @@ body.pc-layout--sticky .pc-layout__sidebar {
159
159
  font-weight: $font-weight-medium;
160
160
  border-inline-end: $border-width-thick solid transparent; // RTL: flips to border-left
161
161
 
162
- body.loaded & {
163
- transition: all $transition-fast $easing-snappy;
164
- }
165
-
166
162
  &:hover {
167
163
  color: var(--pc-sidebar-text, var(--base-text-color-1));
168
164
  background-color: var(--pc-accent-light);
@@ -212,10 +208,6 @@ body.pc-layout--sticky .pc-layout__sidebar {
212
208
  display: none;
213
209
  }
214
210
 
215
- body.loaded & {
216
- transition: all $transition-fast $easing-snappy;
217
- }
218
-
219
211
  &:hover {
220
212
  // $accent-color (foundation) — was $input-focus-border-color, an exact
221
213
  // alias; inlined so the shell no longer depends on the component layer
@@ -335,10 +327,6 @@ body.pc-layout--sticky .pc-layout__sidebar {
335
327
  font-weight: $font-weight-medium;
336
328
  cursor: pointer;
337
329
 
338
- body.loaded & {
339
- transition: all $transition-fast $easing-snappy;
340
- }
341
-
342
330
  &:hover {
343
331
  color: var(--pc-sidebar-text, var(--base-text-color-1));
344
332
  background-color: var(--pc-accent-light);
@@ -35,6 +35,7 @@
35
35
  @use 'layout-container';
36
36
  @use 'layout-responsive';
37
37
  @use 'fit-flyout';
38
+ @use 'icon-hover';
38
39
 
39
40
  @use 'utilities';
40
41
 
@@ -374,6 +374,11 @@ $base-icon-refresh: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/20
374
374
  // Selection: check = ✓ (Lucide check), indeterminate = − (Lucide minus). indeterminate
375
375
  // shares the minus shape with `collapse` but is its own knob (selection ≠ disclosure).
376
376
  $base-icon-check: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M20 6 9 17l-5-5%22/%3E%3C/svg%3E") !default;
377
+ // mask-size for the selection glyph inside its box. One knob both pure-admin and
378
+ // the web components read, so overriding the glyph AND its scale re-sizes the mark
379
+ // everywhere at once. 68% leaves breathing room; an edge-to-edge glyph (e.g. a
380
+ // star) can be shrunk from here. Also sizes indeterminate (shares the mask box).
381
+ $base-icon-check-size: 68% !default;
377
382
  $base-icon-indeterminate: url("data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 viewBox=%220 0 24 24%22 fill=%22none%22 stroke=%22%23000%22 stroke-width=%222%22 stroke-linecap=%22round%22 stroke-linejoin=%22round%22%3E%3Cpath d=%22M5 12h14%22/%3E%3C/svg%3E") !default;
378
383
  // copy = two overlapping sheets (Lucide copy); ellipsis = three dots (Lucide
379
384
  // ellipsis, the "more / overflow" affordance — the vertical variant is the same