@keenmate/pure-admin-core 2.4.0 → 2.5.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.
Files changed (44) hide show
  1. package/README.md +11 -6
  2. package/dist/css/main.css +47 -130
  3. package/package.json +1 -1
  4. package/snippets/AUDIT.md +94 -0
  5. package/snippets/alerts.html +264 -89
  6. package/snippets/badges.html +193 -61
  7. package/snippets/buttons.html +178 -0
  8. package/snippets/callouts.html +210 -129
  9. package/snippets/cards.html +383 -200
  10. package/snippets/checkbox-lists.html +199 -65
  11. package/snippets/code.html +55 -11
  12. package/snippets/command-palette.html +401 -111
  13. package/snippets/comparison.html +144 -93
  14. package/snippets/customization.html +311 -104
  15. package/snippets/data-display.html +584 -0
  16. package/snippets/detail-panel.html +470 -138
  17. package/snippets/filter-card.html +246 -0
  18. package/snippets/forms.html +408 -308
  19. package/snippets/grid.html +253 -141
  20. package/snippets/layout.html +379 -480
  21. package/snippets/lists.html +144 -47
  22. package/snippets/loaders.html +64 -39
  23. package/snippets/manifest.json +330 -280
  24. package/snippets/modal-dialogs.html +137 -64
  25. package/snippets/modals.html +221 -151
  26. package/snippets/notifications.html +285 -0
  27. package/snippets/popconfirm.html +213 -19
  28. package/snippets/profile.html +290 -330
  29. package/snippets/statistics.html +247 -0
  30. package/snippets/tables.html +359 -150
  31. package/snippets/tabs.html +129 -45
  32. package/snippets/timeline.html +123 -56
  33. package/snippets/toasts.html +179 -31
  34. package/snippets/tooltips.html +199 -81
  35. package/snippets/typography.html +183 -58
  36. package/snippets/utilities.html +511 -415
  37. package/snippets/virtual-scroll.html +201 -75
  38. package/snippets/web-daterangepicker.html +369 -189
  39. package/snippets/web-multiselect.html +360 -124
  40. package/src/scss/core-components/_alerts.scss +51 -12
  41. package/src/scss/core-components/_pagers.scss +1 -1
  42. package/src/scss/core-components/_popconfirm.scss +35 -13
  43. package/src/scss/core-components/_tables.scss +2 -134
  44. package/src/scss/variables/_components.scss +17 -2
package/README.md CHANGED
@@ -2,15 +2,20 @@
2
2
 
3
3
  Lightweight, data-focused CSS/SCSS admin framework with Corporate theme as default.
4
4
 
5
- ## What's New in 2.3.6
5
+ ## What's New in 2.5.0
6
6
 
7
- - **Responsive font sizing** — `pa-font-responsive` class on `<html>` for automatic mobile scaling (10px desktop, 12px mobile). Granular `pa-font-base-*` / `pa-font-mobile-*` classes for full control. No JS, no FOUC.
8
- - **Getting Started page** — New demo page covering installation, theme management via CLI, responsive sizing, RTL, and BEM reference
7
+ - **Form Demo showcase page** (`/showcases/form-demo`) Vanilla-JS CRUD form mirroring the LiveView form demo from `keen-pure-admin`: inline validation slots, edit/update flow, optimistic delete with toast-undo, and a `simulateServerSave()` failure path so error states are exercisable without any tooling.
8
+ - **Alert system overhaul** — `pa-alert__heading` is now the single heading element (compact default + new `--lg` modifier for punchy presentation), default alignment flipped to `align-items: center` so icons sit nicely with single-line content (new `pa-alert--multiline` opt-out for icon + multi-line stacks), real size scale on `--sm` / `--lg` (both padding *and* font now step in 0.25rem / 0.2rem increments), and `__actions` renders with a toast-style separator. Multi-element layouts (heading + list + actions) stack reliably now via `flex-basis: 100%` on structural children.
9
+ - **Snippets audit + gap pass** — Every snippet under `snippets/` cross-checked against its SCSS source (27 audit commits, tracked in `snippets/AUDIT.md`). Wrong attribute names, dead classes, and structural omissions corrected across the board. Four new gap-pass snippets: `filter-card`, `statistics`, `notifications`, `data-display`.
10
+ - **Popconfirm position classes renamed (Breaking)** — `pa-popconfirm--right` / `--left` → `pa-popconfirm--end` / `--start`. SCSS uses logical properties so the popconfirm and its arrow mirror in `dir="rtl"`. No backwards-compatibility aliases — update markup directly.
11
+ - **`pa-alert__heading` size now opt-in (Breaking)** — Was hardcoded `font-size-lg`; defaults to the alert's body font-size now. Add `pa-alert__heading--lg` on existing alerts to keep the previous bigger treatment.
9
12
 
10
- ## What's New in 2.3.5
13
+ ## What's New in 2.4.0
11
14
 
12
- - **Navbar alignment fix** — `__end` section pushed to right edge via `margin-inline-start: auto`, works without `__center` spacer
13
- - **Scroll-lock fix** — Panel/modal open no longer hides scrollbar (`overflow-y: scroll` instead of `hidden`)
15
+ - **`download-themes` bin removed** — Theme management now lives in the [`pureadmin` CLI](https://www.npmjs.com/package/@keenmate/pureadmin) (`npx pureadmin themes add/update/list`). README's Theme Setup section rewritten to match.
16
+ - **Theme-aware charts** — Demo dashboard chart rewritten to source colors and fonts from Pure Admin CSS custom properties (`--pa-accent`, `--pa-text-color-*`, `--base-font-family`). Establishes the canonical pattern for SVG charts tracking the active theme.
17
+ - **KPI square stats theme correctly** — `pa-stat--square` color variants now route through `--pa-accent` / `--pa-success-bg` / etc. instead of raw SCSS vars that resolved to Bootstrap defaults in every theme.
18
+ - **Profile panel readable on colored headers** — Name, email, role badge, and tab icons now use `--pa-header-profile-name-color` (guaranteed to contrast with header bg) instead of body text vars, with opacity/color-mix for hierarchy.
14
19
 
15
20
  ## Installation
16
21
 
package/dist/css/main.css CHANGED
@@ -8762,14 +8762,14 @@ a.pa-card p {
8762
8762
  ======================================== */
8763
8763
  .pa-alert {
8764
8764
  position: relative;
8765
- padding: 1.2rem 1rem;
8765
+ padding: 1.2rem 1.25rem;
8766
8766
  margin-bottom: 1.6rem;
8767
8767
  border: 1px solid transparent;
8768
8768
  border-radius: var(--pa-border-radius);
8769
8769
  font-size: 1.4rem;
8770
8770
  display: flex;
8771
8771
  flex-wrap: wrap;
8772
- align-items: flex-start;
8772
+ align-items: center;
8773
8773
  }
8774
8774
  .pa-card__body .pa-alert:first-child {
8775
8775
  margin-top: 0;
@@ -8937,16 +8937,19 @@ a.pa-card p {
8937
8937
  background-color: transparent;
8938
8938
  }
8939
8939
  .pa-alert--sm {
8940
- padding: 1.2rem 1rem;
8941
- font-size: 1.4rem;
8940
+ padding: 0.8rem 1.6rem;
8941
+ font-size: 1.2rem;
8942
8942
  }
8943
8943
  .pa-alert--lg {
8944
- padding: 1.2rem 1rem;
8944
+ padding: 1.6rem 2.4rem;
8945
8945
  font-size: 1.6rem;
8946
8946
  }
8947
8947
  .pa-alert--dismissible {
8948
8948
  padding-inline-end: 4.8rem;
8949
8949
  }
8950
+ .pa-alert--multiline {
8951
+ align-items: flex-start;
8952
+ }
8950
8953
  .pa-alert__icon {
8951
8954
  flex-shrink: 0;
8952
8955
  font-size: 1.6rem;
@@ -8954,28 +8957,39 @@ a.pa-card p {
8954
8957
  }
8955
8958
  .pa-alert__content {
8956
8959
  flex: 1;
8960
+ min-width: 0;
8961
+ }
8962
+ .pa-alert__heading, .pa-alert__list, .pa-alert__actions,
8963
+ .pa-alert > p,
8964
+ .pa-alert > hr {
8965
+ flex-basis: 100%;
8957
8966
  }
8958
8967
  .pa-alert__heading {
8959
- margin: 0 0 0.8rem 0;
8968
+ margin: 0;
8960
8969
  color: inherit;
8961
- font-size: 1.8rem;
8962
8970
  font-weight: 600;
8963
8971
  }
8972
+ .pa-alert__heading--lg {
8973
+ font-size: 1.8rem;
8974
+ }
8964
8975
  .pa-alert__list {
8965
- margin: 0.8rem 0;
8976
+ margin: 0;
8966
8977
  padding-inline-start: 2.4rem;
8967
8978
  }
8968
8979
  .pa-alert__actions {
8969
- margin-top: 1.2rem;
8980
+ margin-top: 0;
8981
+ padding-top: 1.6rem;
8982
+ border-top: 1px solid rgba(0, 0, 0, 0.1);
8970
8983
  display: flex;
8971
8984
  gap: 0.8rem;
8985
+ flex-wrap: wrap;
8972
8986
  }
8973
8987
  .pa-alert__close {
8974
8988
  position: absolute;
8975
8989
  top: 0;
8976
8990
  inset-inline-end: 0;
8977
8991
  z-index: 2px;
8978
- padding: 1.2rem 1rem;
8992
+ padding: 1.2rem 1.25rem;
8979
8993
  background: none;
8980
8994
  border: none;
8981
8995
  font-size: 2rem;
@@ -11469,115 +11483,6 @@ web-multiselect {
11469
11483
  white-space: nowrap;
11470
11484
  }
11471
11485
 
11472
- .pa-pager {
11473
- display: flex;
11474
- margin: 1.6rem 0;
11475
- }
11476
- .pa-card__body .pa-pager:first-child {
11477
- margin-top: 0;
11478
- }
11479
- .pa-card__body .pa-pager:last-child {
11480
- margin-bottom: 0;
11481
- }
11482
- .pa-pager {
11483
- justify-content: center;
11484
- }
11485
- .pa-pager--start {
11486
- justify-content: flex-start;
11487
- }
11488
- .pa-pager--center {
11489
- justify-content: center;
11490
- }
11491
- .pa-pager--end {
11492
- justify-content: flex-end;
11493
- }
11494
- .pa-pager__container {
11495
- display: flex;
11496
- align-items: center;
11497
- gap: 0.8rem;
11498
- white-space: nowrap;
11499
- }
11500
- .pa-pager__controls {
11501
- display: flex;
11502
- gap: 0.4rem;
11503
- }
11504
- .pa-pager__info {
11505
- display: flex;
11506
- align-items: center;
11507
- gap: 0.8rem;
11508
- }
11509
- .pa-pager__input {
11510
- width: 6.4rem !important;
11511
- text-align: center;
11512
- }
11513
- .pa-pager__text {
11514
- color: var(--pa-text-color-2);
11515
- font-size: 1.4rem;
11516
- }
11517
-
11518
- .pa-load-more {
11519
- display: flex;
11520
- margin: 1.6rem 0;
11521
- }
11522
- .pa-card__body .pa-load-more:first-child {
11523
- margin-top: 0;
11524
- }
11525
- .pa-card__body .pa-load-more:last-child {
11526
- margin-bottom: 0;
11527
- }
11528
- .pa-load-more {
11529
- justify-content: center;
11530
- }
11531
- .pa-load-more--start {
11532
- justify-content: flex-start;
11533
- }
11534
- .pa-load-more--center {
11535
- justify-content: center;
11536
- }
11537
- .pa-load-more--end {
11538
- justify-content: flex-end;
11539
- }
11540
- .pa-load-more__button {
11541
- display: flex;
11542
- align-items: center;
11543
- gap: 0.8rem;
11544
- padding: 0.8rem 1.2rem;
11545
- background-color: transparent;
11546
- border: 1px solid var(--pa-border-color);
11547
- border-radius: var(--pa-border-radius);
11548
- color: var(--pa-text-color-1);
11549
- font-size: 1.4rem;
11550
- cursor: pointer;
11551
- transition: all 0.1s ease-out;
11552
- }
11553
- .pa-load-more__button:hover {
11554
- border-color: var(--pa-accent);
11555
- color: var(--pa-accent);
11556
- background-color: var(--pa-accent-light);
11557
- }
11558
- .pa-load-more__button--loading {
11559
- pointer-events: none;
11560
- opacity: 0.7;
11561
- }
11562
- .pa-load-more__button--loading .pa-load-more__spinner {
11563
- animation: pa-spin 1s linear infinite;
11564
- }
11565
- .pa-load-more__spinner {
11566
- width: 1.6rem;
11567
- height: 1.6rem;
11568
- border: 2px solid var(--pa-border-color);
11569
- border-top: 2px solid var(--pa-accent);
11570
- border-radius: 50%;
11571
- }
11572
- .pa-load-more__text {
11573
- color: inherit;
11574
- }
11575
- .pa-load-more__count {
11576
- color: var(--pa-text-color-2);
11577
- font-size: 1.2rem;
11578
- margin-inline-start: 0.4rem;
11579
- }
11580
-
11581
11486
  .pa-virtual-table {
11582
11487
  border: 1px solid var(--pa-border-color);
11583
11488
  border-radius: var(--pa-border-radius);
@@ -12194,7 +12099,7 @@ code {
12194
12099
  width: 1.6rem;
12195
12100
  height: 1.6rem;
12196
12101
  border: 2px solid var(--pa-border-color);
12197
- border-top: 2px solid #007bff;
12102
+ border-top: 2px solid var(--pa-accent);
12198
12103
  border-radius: 50%;
12199
12104
  }
12200
12105
  .pa-load-more__text {
@@ -14809,44 +14714,56 @@ code {
14809
14714
  }
14810
14715
  .pa-popconfirm--bottom .pa-popconfirm__arrow {
14811
14716
  top: -0.64rem;
14812
- left: 50%;
14717
+ inset-inline-start: 50%;
14813
14718
  transform: translateX(-50%) rotate(45deg);
14814
14719
  border-right: none;
14815
14720
  border-bottom: none;
14816
14721
  }
14722
+ [dir=rtl] .pa-popconfirm--bottom .pa-popconfirm__arrow {
14723
+ transform: translateX(50%) rotate(45deg);
14724
+ }
14817
14725
 
14818
14726
  .pa-popconfirm--top {
14819
14727
  margin-bottom: 0.8rem;
14820
14728
  }
14821
14729
  .pa-popconfirm--top .pa-popconfirm__arrow {
14822
14730
  bottom: -0.64rem;
14823
- left: 50%;
14731
+ inset-inline-start: 50%;
14824
14732
  transform: translateX(-50%) rotate(45deg);
14825
14733
  border-left: none;
14826
14734
  border-top: none;
14827
14735
  }
14736
+ [dir=rtl] .pa-popconfirm--top .pa-popconfirm__arrow {
14737
+ transform: translateX(50%) rotate(45deg);
14738
+ }
14828
14739
 
14829
- .pa-popconfirm--right {
14830
- margin-left: 0.8rem;
14740
+ .pa-popconfirm--end {
14741
+ margin-inline-start: 0.8rem;
14831
14742
  }
14832
- .pa-popconfirm--right .pa-popconfirm__arrow {
14833
- left: -0.64rem;
14743
+ .pa-popconfirm--end .pa-popconfirm__arrow {
14744
+ inset-inline-start: -0.64rem;
14834
14745
  top: 50%;
14835
14746
  transform: translateY(-50%) rotate(45deg);
14836
14747
  border-top: none;
14837
14748
  border-right: none;
14838
14749
  }
14750
+ [dir=rtl] .pa-popconfirm--end .pa-popconfirm__arrow {
14751
+ transform: translateY(-50%) rotate(45deg) scaleX(-1);
14752
+ }
14839
14753
 
14840
- .pa-popconfirm--left {
14841
- margin-right: 0.8rem;
14754
+ .pa-popconfirm--start {
14755
+ margin-inline-end: 0.8rem;
14842
14756
  }
14843
- .pa-popconfirm--left .pa-popconfirm__arrow {
14844
- right: -0.64rem;
14757
+ .pa-popconfirm--start .pa-popconfirm__arrow {
14758
+ inset-inline-end: -0.64rem;
14845
14759
  top: 50%;
14846
14760
  transform: translateY(-50%) rotate(45deg);
14847
14761
  border-bottom: none;
14848
14762
  border-left: none;
14849
14763
  }
14764
+ [dir=rtl] .pa-popconfirm--start .pa-popconfirm__arrow {
14765
+ transform: translateY(-50%) rotate(45deg) scaleX(-1);
14766
+ }
14850
14767
 
14851
14768
  .pa-popconfirm--compact {
14852
14769
  min-width: 19.2rem;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@keenmate/pure-admin-core",
3
- "version": "2.4.0",
3
+ "version": "2.5.0",
4
4
  "description": "Lightweight, data-focused HTML/CSS admin framework built with PureCSS foundation and comprehensive component system",
5
5
  "style": "dist/css/main.css",
6
6
  "exports": {
@@ -0,0 +1,94 @@
1
+ # Snippets Audit Log
2
+
3
+ Tracks which snippets have been cross-checked against their SCSS source and when. Paired with `manifest.json` (which records file hashes for downstream framework wrappers), this file answers *has anyone verified this is still accurate*.
4
+
5
+ **Process.** An audit reads the corresponding SCSS surface, compares it against the snippet (base class, modifiers, BEM elements, child styling, sizes, variants), triangulates with usage in `demo/views/*.mustache`, and fixes drift in-place. One snippet per commit.
6
+
7
+ **Legend.**
8
+ - ✅ audited — snippet reviewed and brought in line with SCSS as of the listed commit
9
+ - ⏳ pending — not yet touched in this pass
10
+ - 🆕 missing — component exists in SCSS but has no snippet
11
+
12
+ ## Audited
13
+
14
+ | Snippet | Audited | SCSS verified against | Commit |
15
+ |---|---|---|---|
16
+ | `callouts.html` | 2026-04-24 | `core-components/_callouts.scss` | [6ea28e8](../../../commit/6ea28e8) |
17
+ | `code.html` | 2026-04-24 | `core-components/_code.scss`, `variables/_colors.scss` | [cd2e51b](../../../commit/cd2e51b) |
18
+ | `loaders.html` | 2026-04-24 | `core-components/_loaders.scss`, `core-components/_buttons.scss` (loading state), `variables/_components.scss` | [6a4682d](../../../commit/6a4682d) |
19
+ | `toasts.html` | 2026-04-24 | `core-components/_toasts.scss` | [4056fa9](../../../commit/4056fa9) |
20
+ | `popconfirm.html` | 2026-04-24 | `core-components/_popconfirm.scss` | [d8e7f7c](../../../commit/d8e7f7c) |
21
+ | `typography.html` | 2026-04-24 | `core-components/_base.scss`, `core-components/_utilities.scss` (.pa-text), `utilities.scss` (.text-*), `_fonts.scss`, `variables/_typography.scss` | [12f1281](../../../commit/12f1281) |
22
+ | `alerts.html` | 2026-04-25 | `core-components/_alerts.scss`, `variables/_components.scss` (alert padding + font-size scales) | [512ef3c](../../../commit/512ef3c), revised [dd7a096](../../../commit/dd7a096) (toast-style `__actions` separator), [f824000](../../../commit/f824000) (flex-wrap layout fix: structural children get `flex-basis: 100%`), [514d67d](../../../commit/514d67d) (heading unification: `__heading` defaults to body size, `--lg` opt-in for punchy), [f25700d](../../../commit/f25700d) (introduced `$alert-padding-{sm,lg}-{v,h}` and `$alert-font-size-{sm,lg}` so `--sm` / `--lg` actually differ from default), [d2b27ea](../../../commit/d2b27ea) (default `$alert-padding-{v,h}` decoupled from `$card-footer-padding-{v,h}`: 0.75rem / 1.25rem, so default sits inside the V 0.5 → 0.75 → 1 / H 1 → 1.25 → 1.5 scale instead of outside it), and _(this commit)_ (default `align-items: center` so icon + single-line content centres; new `pa-alert--multiline` modifier opts back to `flex-start` for icon + multi-line `__content`) |
23
+ | `badges.html` | 2026-04-24 | `core-components/badges/_badge-base.scss`, `_composite-badge.scss`, `_composite-badge-variants.scss`, `_badge-group.scss`, `_labels.scss` | [517f6bf](../../../commit/517f6bf) |
24
+ | `buttons.html` | 2026-04-24 | `core-components/_buttons.scss` | [43a9a42](../../../commit/43a9a42) |
25
+ | `tables.html` | 2026-04-24 | `core-components/_tables.scss` (covers `.pa-table`, `.pa-table-container`, `.pa-table-card`), `core-components/_pagers.scss` (covers `.pa-pager`, `.pa-load-more`) | [e34ca85](../../../commit/e34ca85) |
26
+ | `lists.html` | 2026-04-24 | `core-components/_lists.scss` | [894b0dd](../../../commit/894b0dd) |
27
+ | `tooltips.html` | 2026-04-24 | `core-components/_tooltips.scss` | [b2d196b](../../../commit/b2d196b) |
28
+ | `grid.html` | 2026-04-24 | `core-components/_grid.scss`, `utilities.scss` (.pa-cq), `variables/_spacing.scss` ($grid-breakpoints) | [0bd9f16](../../../commit/0bd9f16) |
29
+ | `utilities.html` | 2026-04-24 | `utilities.scss` (main utilities), `core-components/_utilities.scss` (components-adjacent helpers), `variables/_spacing.scss` (spacing scale) | [20df758](../../../commit/20df758) |
30
+ | `cards.html` | 2026-04-24 | `core-components/_cards.scss` | [4a67018](../../../commit/4a67018) |
31
+ | `forms.html` | 2026-04-24 | `core-components/forms/` (all 7 files: _form-layout, _form-inputs, _form-states, _input-groups, _input-wrapper, _checkboxes-radios, _query-editor) | [272f141](../../../commit/272f141) |
32
+ | `layout.html` | 2026-04-24 | `core-components/layout/` (all 6 files: _layout-container, _navbar, _navbar-elements, _sidebar, _sidebar-states, _layout-responsive), `variables/_layout.scss` (container widths) | [9762492](../../../commit/9762492) |
33
+ | `profile.html` | 2026-04-24 | `core-components/_profile.scss` | [2b70e27](../../../commit/2b70e27) |
34
+ | `tabs.html` | 2026-04-24 | `core-components/_tabs.scss` | [35f5f16](../../../commit/35f5f16) |
35
+ | `timeline.html` | 2026-04-24 | `core-components/_timeline.scss` | [eaa5ad9](../../../commit/eaa5ad9) |
36
+ | `checkbox-lists.html` | 2026-04-24 | `core-components/_checkbox-lists.scss`, `core-components/forms/_checkboxes-radios.scss` (pa-checkbox component reference) | [e2bb951](../../../commit/e2bb951) |
37
+ | `command-palette.html` | 2026-04-24 | `core-components/_command-palette.scss` (covers `.pa-command-palette`, `.pa-navbar-search`, `.pa-shortcut-help`) | [a9b4fe3](../../../commit/a9b4fe3) |
38
+ | `comparison.html` | 2026-04-24 | `core-components/_comparison.scss` | [e4f1cd6](../../../commit/e4f1cd6) |
39
+ | `modals.html` | 2026-04-24 | `core-components/_modals.scss`, `variables/_components.scss` ($modal-*-width + $modal-body-scrollable-max-height) | [795856e](../../../commit/795856e) |
40
+ | `modal-dialogs.html` | 2026-04-24 | `src/js/modal-dialogs.js` (PureAdmin.confirm / alert / prompt / custom API); DOM produced matches `_modals.scss` | [e5eba00](../../../commit/e5eba00) |
41
+ | `detail-panel.html` | 2026-04-24 | `core-components/_detail-panel.scss`, `variables/_components.scss` (panel width + z-index) | [c1dc6ff](../../../commit/c1dc6ff) |
42
+ | `customization.html` | 2026-04-25 | `_base-css-variables.scss`, `_variables.scss`, theme-system pattern (mirrors `pure-admin-themes` repo) | [0a8950e](../../../commit/0a8950e) |
43
+ | `virtual-scroll.html` | 2026-04-25 | `core-components/_tables.scss` (`.pa-virtual-table` shell, lines 477-552), `core-components/_timeline.scss` (`.pa-timeline__loader`), `src/js/virtual-scroll.js` (VirtualScroll class API) | [85db533](../../../commit/85db533) |
44
+ | `web-daterangepicker.html` | 2026-04-25 | `../../web-daterangepicker/src/web-component.ts` (observedAttributes), `../../web-daterangepicker/src/types.ts` (DatePickerOptions, DateInfo, disabledDatesHandling), `../../web-daterangepicker/API.md`, `core-components/_web-components-theme.scss` (--base-* bridge) | [7cbad56](../../../commit/7cbad56) |
45
+ | `web-multiselect.html` | 2026-04-25 | `../../web-multiselect/src/web-component.ts` (observedAttributes), `../../web-multiselect/src/types.ts` (BadgesDisplayMode, BadgesPosition, SearchMode, ValueFormat etc.), `../../web-multiselect/src/css/_variables.css` (--ms-* surface), `core-components/_web-components-theme.scss` | [95cf062](../../../commit/95cf062) |
46
+ | `filter-card.html` | 2026-04-25 | `core-components/_filter-card.scss` (whole file — only BEM elements + 2 state modifiers, no base block) | [b65ec2b](../../../commit/b65ec2b) |
47
+ | `statistics.html` | 2026-04-25 | `core-components/_statistics.scss` (whole file — `.pa-stat`, `--hero`, `--hero-compact`, `--square` + 6 colour variants, `.pa-kpi-grid`) | [5de0ce8](../../../commit/5de0ce8) |
48
+ | `notifications.html` | 2026-04-25 | `core-components/_notifications.scss` (whole file — bell + dropdown panel, item states, page-view modifier, hover-revealed actions) | [0d7bb15](../../../commit/0d7bb15) |
49
+ | `data-display.html` | 2026-04-25 | `core-components/_data-display.scss` (whole file — 7 components: `.pa-field` + `.pa-fields` (15+ layout modifiers), `.pa-field-group`, `.pa-desc-table`, `.pa-prop-card`, `.pa-banded`, `.pa-accent-grid`, `.pa-dot-leaders`; shared copy-pattern modifiers across all) | [39cc6bd](../../../commit/39cc6bd) |
50
+
51
+ ## Pending
52
+
53
+ _None — both audit and gap passes complete._
54
+
55
+ Run `npm run generate-hashes -w @keenmate/pure-admin-core` to refresh `snippets/manifest.json` whenever any of the snippet files change.
56
+
57
+ ## Gaps — SCSS without a snippet
58
+
59
+ These components exist in `src/scss/core-components/` but downstream consumers have no snippet to crib from. Decide per-entry whether to add a snippet or mark as demo-internal.
60
+
61
+ | Component | SCSS file | Notes |
62
+ |---|---|---|
63
+ | pagers | `_pagers.scss` | Covered inside `tables.html` audit (same family; pager/load-more only meaningful alongside tables). |
64
+ | ~~notifications~~ | ~~`_notifications.scss`~~ | ~~Public — snippet worth adding~~ → done in `notifications.html` |
65
+ | ~~statistics~~ | ~~`_statistics.scss`~~ | ~~Public — snippet worth adding~~ → done in `statistics.html` |
66
+ | file-selector | `_file-selector.scss` | **Deferred** — component is not yet finished. Revisit once the API stabilizes; snippet would chase a moving target. |
67
+ | ~~filter-card~~ | ~~`_filter-card.scss`~~ | ~~Public — snippet worth adding~~ → done in `filter-card.html` |
68
+ | logic-tree | `_logic-tree.scss` | **Deferred** — component is not yet finished. Revisit once the API stabilizes. |
69
+ | ~~data-display~~ | ~~`_data-display.scss`~~ | ~~Public — snippet worth adding~~ → done in `data-display.html` |
70
+ | smart-filters (aka query-editor) | `core-components/forms/_query-editor.scss` | **Deferred** — component is not yet finished. SCSS file is named `_query-editor.scss` but the demo calls it "Smart Filters" (`demo/views/smart-filters.mustache` + `demo/js/search-autocomplete*.js`, `virtual-textbox.js`). Briefly cross-referenced from forms.html; revisit once the API stabilizes. |
71
+ | data-viz | `_data-viz.scss` | D3-driven — snippet would be thin; defer |
72
+ | scrollbars | `_scrollbars.scss` | Global utility styling; no snippet needed |
73
+ | settings-panel | `_settings-panel.scss` | Demo-internal; no snippet needed |
74
+ | web-components-theme | `_web-components-theme.scss` | CSS custom properties bridge; no snippet needed |
75
+ | base | `_base.scss` | Reset/base styles; covered by `typography.html` |
76
+
77
+ ## Known issues flagged during audits (not in scope to fix here)
78
+
79
+ - **`demo/views/code.mustache`** reference block lists several accent colors that don't match `variables/_colors.scss`: JSON → "Green" (actual amber), bash → "Gray" (actual green), SQL → "Purple" (actual teal), keyword → "purple, bold" (actual blue + medium), function → "blue" (actual purple), property → "cyan" (actual pink-red). Fix in a later demo pass.
80
+ - **`.pa-spinner` ghost size modifiers.** `_loaders.scss` only defines `--xs`; the demo page (`demo/views/loaders.mustache`) and the previous snippet both showed `--sm`, `--md`, `--lg`, `--xl`, `--2xl` with fabricated size labels (1rem → 4rem). All render at the default 16px because the modifiers don't exist. Snippet fixed in loaders commit; demo page still broken — either remove the ghost sizes from the demo, or add them to SCSS. Decision to be made in a future framework pass.
81
+ - ~~**Popconfirm is physical-only; toasts are logical.**~~ Fixed in the popconfirm logical-rename commit: `--left`/`--right` → `--start`/`--end`, SCSS switched to `inset-inline-*` + `margin-inline-*`, arrow gets `scaleX(-1)` under `[dir="rtl"]`. See Unreleased section of CHANGELOG.
82
+ - **Composite badge missing `--btn-danger` variant.** All other button-section colour overrides exist (`--btn-primary`, `--btn-secondary`, `--btn-success`, `--btn-warning`, `--btn-info`, `--btn-light`, `--btn-dark`) but not `--btn-danger`. The base `.pa-composite-badge__button` defaults to danger colours, so adding `--btn-danger` would be a no-op in practice, but the gap is inconsistent with `--label-danger` (which does exist) and makes "what overrides are available" harder to predict. Snippet flags the omission; actual fix is a single block in `_composite-badge-variants.scss`.
83
+ - ~~**Pager/load-more definitions are duplicated** between `_tables.scss` (lines 475-608) and `_pagers.scss`.~~ Fixed: duplicate block removed from `_tables.scss`, and the `var(--pa-accent)` upgrade on the load-more spinner ported into `_pagers.scss` (it was using the raw SCSS `$accent-color` before). See Unreleased CHANGELOG entry.
84
+ - **Timeline `--alternating` uses physical `left`/`right` throughout.** `_timeline.scss` mixes its RTL handling: `--simple` and `--feed` use logical properties (`inset-inline-*`, `margin-inline-*`, `padding-inline-*`, `border-inline-*`) and mirror correctly in RTL. But `--alternating` and its modifiers (`--start`, `--end`, `--keep-layout`, `--single-column`) use physical `left`/`right` positions for the centre line, dots, connector arms, dates, icons, and content offsets. Result: in RTL, the alternating timeline doesn't mirror — items stay on the same physical sides, the dates don't flip to the inline-start of each item, and `--start`/`--end` are locked to physical left/right. Fix would need `inset-inline-start/end` + `border-inline-*` substitutions throughout the alternating block, plus probably a `[dir="rtl"] &` flip for the nth-child offset origin. Framework scope; snippet documents the current physical behaviour accurately.
85
+
86
+ ## Rehash
87
+
88
+ At the end of the audit (or whenever snippets settle), run:
89
+
90
+ ```bash
91
+ npm run generate-hashes -w @keenmate/pure-admin-core
92
+ ```
93
+
94
+ to refresh `snippets/manifest.json` so downstream framework wrappers see the new hashes.