@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
@@ -3,9 +3,7 @@
3
3
  Pure Admin Visual Framework
4
4
  ================================ -->
5
5
 
6
- <!-- BASIC TABLE -->
7
-
8
- <!-- Simple Table -->
6
+ <!-- BASIC TABLE (hover is built-in; no modifier needed) -->
9
7
  <table class="pa-table">
10
8
  <thead>
11
9
  <tr>
@@ -30,8 +28,6 @@
30
28
 
31
29
 
32
30
  <!-- STRIPED TABLE -->
33
-
34
- <!-- Table with Alternating Row Colors -->
35
31
  <table class="pa-table pa-table--striped">
36
32
  <thead>
37
33
  <tr>
@@ -40,24 +36,28 @@
40
36
  </tr>
41
37
  </thead>
42
38
  <tbody>
43
- <tr>
44
- <td>John Doe</td>
45
- <td>Active</td>
46
- </tr>
47
- <tr>
48
- <td>Jane Smith</td>
49
- <td>Inactive</td>
50
- </tr>
39
+ <tr><td>John Doe</td><td>Active</td></tr>
40
+ <tr><td>Jane Smith</td><td>Inactive</td></tr>
51
41
  </tbody>
52
42
  </table>
53
43
 
54
44
 
55
- <!-- NOTE: All tables have hover effect by default (no modifier needed) -->
56
-
45
+ <!-- BORDERED TABLE (full cell borders on every side) -->
46
+ <table class="pa-table pa-table--bordered">
47
+ <thead>
48
+ <tr>
49
+ <th>Column A</th>
50
+ <th>Column B</th>
51
+ </tr>
52
+ </thead>
53
+ <tbody>
54
+ <tr><td>A1</td><td>B1</td></tr>
55
+ <tr><td>A2</td><td>B2</td></tr>
56
+ </tbody>
57
+ </table>
57
58
 
58
- <!-- TABLE WITH ACTIONS -->
59
59
 
60
- <!-- Table with Icon Buttons -->
60
+ <!-- TABLE WITH ACTIONS (col-auto keeps actions column narrow) -->
61
61
  <table class="pa-table pa-table--striped">
62
62
  <thead>
63
63
  <tr>
@@ -82,140 +82,232 @@
82
82
  </table>
83
83
 
84
84
 
85
- <!-- TABLE SPACING VARIANTS -->
85
+ <!-- TABLE SIZE VARIANTS -->
86
86
 
87
- <!-- Default Spacing (base padding) -->
87
+ <!-- XS (pairs with pa-btn--xs) -->
88
+ <table class="pa-table pa-table--xs">
89
+ <thead><tr><th>Name</th><th>Email</th></tr></thead>
90
+ <tbody><tr><td>John Doe</td><td>john@example.com</td></tr></tbody>
91
+ </table>
92
+
93
+ <!-- SM -->
94
+ <table class="pa-table pa-table--sm">
95
+ <thead><tr><th>Name</th><th>Email</th></tr></thead>
96
+ <tbody><tr><td>John Doe</td><td>john@example.com</td></tr></tbody>
97
+ </table>
98
+
99
+ <!-- Default (pairs with pa-btn default size) -->
88
100
  <table class="pa-table">
89
- <thead>
90
- <tr>
91
- <th>Name</th>
92
- <th>Email</th>
93
- </tr>
94
- </thead>
95
- <tbody>
96
- <tr>
97
- <td>John Doe</td>
98
- <td>john@example.com</td>
99
- </tr>
100
- </tbody>
101
+ <thead><tr><th>Name</th><th>Email</th></tr></thead>
102
+ <tbody><tr><td>John Doe</td><td>john@example.com</td></tr></tbody>
101
103
  </table>
102
104
 
103
- <!-- XS Size (compact, fits button-xs) -->
104
- <table class="pa-table pa-table--xs">
105
+ <!-- LG (pairs with pa-btn--lg) -->
106
+ <table class="pa-table pa-table--lg">
107
+ <thead><tr><th>Name</th><th>Email</th></tr></thead>
108
+ <tbody><tr><td>John Doe</td><td>john@example.com</td></tr></tbody>
109
+ </table>
110
+
111
+ <!-- XL (pairs with pa-btn--xl) -->
112
+ <table class="pa-table pa-table--xl">
113
+ <thead><tr><th>Name</th><th>Email</th></tr></thead>
114
+ <tbody><tr><td>John Doe</td><td>john@example.com</td></tr></tbody>
115
+ </table>
116
+
117
+
118
+ <!-- TABLE WITH BADGES — common data-display pattern -->
119
+ <table class="pa-table pa-table--striped">
105
120
  <thead>
106
- <tr>
107
- <th>Name</th>
108
- <th>Email</th>
109
- </tr>
121
+ <tr><th>Name</th><th>Status</th><th>Role</th></tr>
110
122
  </thead>
111
123
  <tbody>
112
124
  <tr>
113
125
  <td>John Doe</td>
114
- <td>john@example.com</td>
126
+ <td><span class="pa-badge pa-badge--success">Active</span></td>
127
+ <td><span class="pa-badge pa-badge--primary">Admin</span></td>
128
+ </tr>
129
+ <tr>
130
+ <td>Jane Smith</td>
131
+ <td><span class="pa-badge pa-badge--danger">Inactive</span></td>
132
+ <td><span class="pa-badge pa-badge--secondary">User</span></td>
115
133
  </tr>
116
134
  </tbody>
117
135
  </table>
118
136
 
119
- <!-- LG Size (spacious, fits button-lg) -->
120
- <table class="pa-table pa-table--lg">
137
+
138
+ <!-- ================================
139
+ RESPONSIVE TABLES (pa-table--responsive)
140
+ Modifier on the <table> itself — NOT a wrapper class.
141
+ Desktop: normal table.
142
+ Tablet (max-width: $tablet-breakpoint): horizontal scroll.
143
+ Mobile (max-width: $table-responsive-breakpoint): each row becomes
144
+ a card; each <td> becomes a label+value row inside the card. The
145
+ label comes from a data-label attribute on each <td>.
146
+ ================================ -->
147
+ <table class="pa-table pa-table--striped pa-table--responsive">
121
148
  <thead>
122
149
  <tr>
150
+ <th>ID</th>
123
151
  <th>Name</th>
124
152
  <th>Email</th>
153
+ <th>Role</th>
154
+ <th>Status</th>
125
155
  </tr>
126
156
  </thead>
127
157
  <tbody>
128
158
  <tr>
129
- <td>John Doe</td>
130
- <td>john@example.com</td>
159
+ <td data-label="ID">1</td>
160
+ <td data-label="Name">John Doe</td>
161
+ <td data-label="Email">john@example.com</td>
162
+ <td data-label="Role">Admin</td>
163
+ <td data-label="Status"><span class="pa-badge pa-badge--success">Active</span></td>
131
164
  </tr>
132
165
  </tbody>
133
166
  </table>
134
167
 
135
168
 
136
- <!-- RESPONSIVE TABLE -->
137
-
138
- <!-- Table in Card with Horizontal Scroll on Mobile -->
139
- <div class="pa-card">
140
- <div class="pa-card__body">
141
- <div class="pa-table-responsive">
142
- <table class="pa-table pa-table--striped">
143
- <thead>
144
- <tr>
145
- <th>ID</th>
146
- <th>Name</th>
147
- <th>Email</th>
148
- <th>Role</th>
149
- <th>Status</th>
150
- </tr>
151
- </thead>
152
- <tbody>
153
- <tr>
154
- <td>1</td>
155
- <td>John Doe</td>
156
- <td>john@example.com</td>
157
- <td>Admin</td>
158
- <td>Active</td>
159
- </tr>
160
- </tbody>
161
- </table>
162
- </div>
163
- </div>
164
- </div>
165
-
166
-
167
- <!-- TABLE WITH BADGES -->
168
-
169
- <!-- Table with Status Badges -->
170
- <table class="pa-table pa-table--striped">
169
+ <!-- ================================
170
+ RESPONSIVE GRID TABLES (pa-table--responsive-grid)
171
+ Same desktop appearance, but mobile layout is a CSS Grid inside
172
+ each row (set via data-grid on <tr>). Individual cells can span
173
+ columns via data-span.
174
+ ================================ -->
175
+ <table class="pa-table pa-table--striped pa-table--responsive-grid">
171
176
  <thead>
172
177
  <tr>
178
+ <th>ID</th>
173
179
  <th>Name</th>
180
+ <th>Email</th>
174
181
  <th>Status</th>
175
- <th>Role</th>
176
182
  </tr>
177
183
  </thead>
178
184
  <tbody>
179
- <tr>
180
- <td>John Doe</td>
181
- <td><span class="pa-badge pa-badge--success">Active</span></td>
182
- <td><span class="pa-badge pa-badge--primary">Admin</span></td>
183
- </tr>
184
- <tr>
185
- <td>Jane Smith</td>
186
- <td><span class="pa-badge pa-badge--danger">Inactive</span></td>
187
- <td><span class="pa-badge pa-badge--secondary">User</span></td>
185
+ <!-- 2-col grid: Name + ID on top row, Email + Status on bottom -->
186
+ <tr data-grid="2">
187
+ <td data-label="Name" data-span="2">John Doe</td>
188
+ <td data-label="ID">1</td>
189
+ <td data-label="Status"><span class="pa-badge pa-badge--success">Active</span></td>
190
+ <td data-label="Email" data-span="full">john.doe@company.example</td>
188
191
  </tr>
189
192
  </tbody>
190
193
  </table>
191
194
 
195
+ <!-- data-grid accepts "2" or "3" (preset column counts).
196
+ data-span accepts "2", "3", or "full" on individual cells. -->
192
197
 
193
- <!-- TABLE CONTAINER -->
194
198
 
195
- <!-- Table in Container with Border and Scrolling -->
199
+ <!-- ================================
200
+ TABLE CONTAINER (pa-table-container)
201
+ Simple wrapper that gives the table a border, rounded corners, and
202
+ horizontal scroll on overflow. Use when you want the table framed
203
+ but don't need a card header / footer / actions area.
204
+ ================================ -->
205
+
206
+ <!-- Base container -->
196
207
  <div class="pa-table-container">
197
208
  <table class="pa-table">
198
- <thead>
199
- <tr>
200
- <th>ID</th>
201
- <th>Name</th>
202
- <th>Email</th>
203
- </tr>
204
- </thead>
205
- <tbody>
206
- <tr>
207
- <td>1</td>
208
- <td>John Doe</td>
209
- <td>john@example.com</td>
210
- </tr>
211
- </tbody>
209
+ <thead><tr><th>ID</th><th>Name</th><th>Email</th></tr></thead>
210
+ <tbody><tr><td>1</td><td>John Doe</td><td>john@example.com</td></tr></tbody>
212
211
  </table>
213
212
  </div>
214
213
 
214
+ <!-- Panel container (adds shadow + lg radius + hover shadow lift) -->
215
+ <div class="pa-table-container pa-table-container--panel">
216
+ <div class="pa-table-container__header">
217
+ <h3 class="pa-table-container__title">Recent Users</h3>
218
+ <div class="pa-table-container__actions">
219
+ <button class="pa-btn pa-btn--sm pa-btn--secondary">Export</button>
220
+ <button class="pa-btn pa-btn--sm pa-btn--primary">Add</button>
221
+ </div>
222
+ </div>
223
+ <table class="pa-table">
224
+ <thead><tr><th>Name</th><th>Email</th></tr></thead>
225
+ <tbody><tr><td>John Doe</td><td>john@example.com</td></tr></tbody>
226
+ </table>
227
+ </div>
215
228
 
216
- <!-- PAGER COMPONENT -->
217
229
 
218
- <!-- Centered Pager (default) -->
230
+ <!-- ================================
231
+ TABLE CARD (pa-table-card)
232
+ Full card with header + body + optional footer, purpose-built to
233
+ host a table. The body has no padding (table edges meet the card
234
+ border), and the first/last column gets $card-header-padding-h of
235
+ padding-inline so data lines up with the header text above.
236
+ Add --scrollable to the body when the table is wide enough to need
237
+ horizontal scroll (the card has overflow: hidden for its radius,
238
+ so without --scrollable wide tables are silently clipped).
239
+ ================================ -->
240
+ <div class="pa-table-card">
241
+ <div class="pa-table-card__header">
242
+ <h3>Orders</h3>
243
+ <div class="pa-table-card__actions">
244
+ <span class="pa-badge pa-badge--secondary">12 total</span>
245
+ <button class="pa-btn pa-btn--sm pa-btn--primary">Add Order</button>
246
+ </div>
247
+ </div>
248
+ <div class="pa-table-card__body pa-table-card__body--scrollable">
249
+ <table class="pa-table pa-table--striped">
250
+ <thead>
251
+ <tr><th>Order ID</th><th>Customer</th><th>Amount</th><th>Status</th></tr>
252
+ </thead>
253
+ <tbody>
254
+ <tr>
255
+ <td>#1001</td>
256
+ <td>John Smith</td>
257
+ <td>$250.00</td>
258
+ <td><span class="pa-badge pa-badge--success">Completed</span></td>
259
+ </tr>
260
+ </tbody>
261
+ </table>
262
+ </div>
263
+ <div class="pa-table-card__footer">
264
+ <span>Showing 1 of 12 orders</span>
265
+ <button class="pa-btn pa-btn--sm pa-btn--secondary">View All</button>
266
+ </div>
267
+ </div>
268
+
269
+ <!-- Table card with semantic color variant (coloured header) -->
270
+ <div class="pa-table-card pa-table-card--primary">
271
+ <div class="pa-table-card__header">
272
+ <h3>Primary Table</h3>
273
+ </div>
274
+ <div class="pa-table-card__body">
275
+ <table class="pa-table">
276
+ <thead><tr><th>Key</th><th>Value</th></tr></thead>
277
+ <tbody><tr><td>Theme</td><td>corporate</td></tr></tbody>
278
+ </table>
279
+ </div>
280
+ </div>
281
+
282
+ <!-- Table card without visual styling (structure only) — useful when
283
+ the card itself is already framed by a parent layout -->
284
+ <div class="pa-table-card pa-table-card--plain">
285
+ <div class="pa-table-card__header">
286
+ <h3>Inline Section Table</h3>
287
+ </div>
288
+ <div class="pa-table-card__body">
289
+ <table class="pa-table">
290
+ <thead><tr><th>Col 1</th><th>Col 2</th></tr></thead>
291
+ <tbody><tr><td>A</td><td>B</td></tr></tbody>
292
+ </table>
293
+ </div>
294
+ </div>
295
+
296
+ <!-- Patterns:
297
+ pa-table-card--{primary|success|warning|danger} semantic header colours
298
+ pa-table-card--color-{1..9} theme slot header colours
299
+ pa-table-card--plain drop card chrome
300
+ (No --secondary / --info / --light / --dark variants for table-card.)
301
+ -->
302
+
303
+
304
+ <!-- ================================
305
+ PAGER (pa-pager)
306
+ Pagination controls. Declared in _pagers.scss — independent of
307
+ the table, so works anywhere. Centre-aligned by default.
308
+ ================================ -->
309
+
310
+ <!-- Centred pager with prev/next + page input -->
219
311
  <div class="pa-pager">
220
312
  <div class="pa-pager__container">
221
313
  <div class="pa-pager__controls">
@@ -230,7 +322,7 @@
230
322
  </div>
231
323
  </div>
232
324
 
233
- <!-- Left-Aligned Pager -->
325
+ <!-- Start-aligned pager with First/Last -->
234
326
  <div class="pa-pager pa-pager--start">
235
327
  <div class="pa-pager__container">
236
328
  <div class="pa-pager__controls">
@@ -242,7 +334,7 @@
242
334
  </div>
243
335
  </div>
244
336
 
245
- <!-- Right-Aligned Pager -->
337
+ <!-- End-aligned pager with row count -->
246
338
  <div class="pa-pager pa-pager--end">
247
339
  <div class="pa-pager__container">
248
340
  <span class="pa-pager__text">Showing 1-25 of 250</span>
@@ -254,9 +346,13 @@
254
346
  </div>
255
347
 
256
348
 
257
- <!-- LOAD MORE COMPONENT -->
349
+ <!-- ================================
350
+ LOAD MORE (pa-load-more)
351
+ Single action button as an alternative to paging. Also declared in
352
+ _pagers.scss.
353
+ ================================ -->
258
354
 
259
- <!-- Centered Load More (default) -->
355
+ <!-- Centred "Load More" with count -->
260
356
  <div class="pa-load-more">
261
357
  <button class="pa-load-more__button">
262
358
  <span class="pa-load-more__text">Load More</span>
@@ -264,7 +360,7 @@
264
360
  </button>
265
361
  </div>
266
362
 
267
- <!-- Load More with Loading State -->
363
+ <!-- Loading state spinner rotates, button becomes non-interactive -->
268
364
  <div class="pa-load-more">
269
365
  <button class="pa-load-more__button pa-load-more__button--loading">
270
366
  <span class="pa-load-more__spinner"></span>
@@ -272,48 +368,161 @@
272
368
  </button>
273
369
  </div>
274
370
 
275
- <!-- Left-Aligned Load More -->
276
- <div class="pa-load-more pa-load-more--start">
277
- <button class="pa-load-more__button">
278
- <span class="pa-load-more__text">Show More Items</span>
279
- </button>
280
- </div>
371
+ <!-- Start / end alignment also available: pa-load-more--start / --end -->
281
372
 
282
- <!-- Right-Aligned Load More -->
283
- <div class="pa-load-more pa-load-more--end">
284
- <button class="pa-load-more__button">
285
- <span class="pa-load-more__text">Load Previous</span>
286
- </button>
287
- </div>
288
373
 
374
+ <!-- ================================
375
+ COMPONENT REFERENCE
376
+ ================================ -->
289
377
 
290
- <!-- AVAILABLE TABLE MODIFIERS -->
291
378
  <!--
292
- BASE CLASS:
293
- - pa-table (base table with hover effect built-in)
294
-
295
- MODIFIERS:
296
- - pa-table--striped (alternating row colors)
297
- - pa-table--xs (compact, fits button-xs)
298
- - pa-table--sm (slightly wider horizontal padding)
299
- - pa-table--lg (spacious, fits button-lg)
300
- - pa-table--xl (extra spacious, fits button-xl)
301
-
302
- HELPERS:
303
- - col-auto (auto-width column that shrinks to content)
304
- - pa-table-container (wrapper with border and scroll)
305
- - pa-table-responsive (horizontal scroll on mobile)
306
-
307
- PAGER:
308
- - pa-pager (center aligned by default)
309
- - pa-pager--start (start aligned)
310
- - pa-pager--end (end aligned)
311
- - pa-pager__container, __controls, __info, __input, __text
312
-
313
- LOAD MORE:
314
- - pa-load-more (center aligned by default)
315
- - pa-load-more--start (start aligned)
316
- - pa-load-more--end (end aligned)
317
- - pa-load-more__button, __spinner, __text, __count
318
- - pa-load-more__button--loading (loading state)
379
+ pa-table — THE TABLE ELEMENT:
380
+ - .pa-table Base (100% width, collapsed borders, built-in hover)
381
+
382
+ Modifiers:
383
+ - .pa-table--striped Alternating row colours on tbody tr:nth-child(even)
384
+ - .pa-table--bordered Full cell borders on every side
385
+ - .pa-table--xs Pairs with pa-btn--xs (compact)
386
+ - .pa-table--sm Slightly tighter than default
387
+ - (default size)
388
+ - .pa-table--lg Pairs with pa-btn--lg
389
+ - .pa-table--xl Pairs with pa-btn--xl
390
+ - .pa-table--responsive Mobile: each row card with data-label
391
+ per cell; tablet: horizontal scroll
392
+ - .pa-table--responsive-grid Mobile: CSS Grid inside each <tr> (use
393
+ data-grid="2"|"3" on <tr> + data-span
394
+ on <td> for custom layouts)
395
+
396
+ Row/cell helpers:
397
+ - .col-auto On a <th>/<td>: width: 1%; nowrap
398
+ (shrinks column to content)
399
+ - data-label="Label" on <td> Mobile label in --responsive /
400
+ --responsive-grid modes
401
+ - data-grid="2" | "3" On <tr>: mobile grid layout
402
+ - data-span="2" | "3" | "full" On <td> inside data-grid row: column span
403
+
404
+ Implicit behaviour:
405
+ - Hover is built in (no modifier needed). Rows also get an inline-start
406
+ accent border on hover if $table-hover-accent-width > 0.
407
+ - Buttons inside td get -0.25rem vertical margin so they don't grow the
408
+ row height.
409
+ - Last row's bottom border is removed (unless --responsive or --bordered).
410
+
411
+ pa-table-container — SIMPLE WRAPPER:
412
+ - .pa-table-container overflow-x: auto, border, rounded corners
413
+ - .pa-table-container--panel Adds shadow + lg radius + hover lift
414
+
415
+ Panel header sub-elements (optional):
416
+ - .pa-table-container__header
417
+ - .pa-table-container__title
418
+ - .pa-table-container__actions
419
+
420
+ pa-table-card — FULL CARD CONTAINER:
421
+ - .pa-table-card Card with overflow: hidden (so the
422
+ table respects rounded corners)
423
+
424
+ Structure:
425
+ .pa-table-card
426
+ .pa-table-card__header
427
+ h1..h6 (title text; styled automatically)
428
+ .pa-table-card__actions
429
+ .pa-btn / .pa-badge / etc.
430
+ .pa-table-card__body (padding: 0 — table meets card edges)
431
+ table.pa-table (first/last cells auto-inset by card padding)
432
+ .pa-table-card__footer (optional)
433
+
434
+ Body modifier:
435
+ - .pa-table-card__body--scrollable Enables overflow-x: auto.
436
+ Without this, the card's own
437
+ overflow: hidden silently clips
438
+ wide tables. Opt in when the
439
+ table can be wider than the card.
440
+
441
+ Variants (semantic colour on the header):
442
+ - .pa-table-card--primary
443
+ - .pa-table-card--success
444
+ - .pa-table-card--warning
445
+ - .pa-table-card--danger
446
+ (No --secondary / --info / --light / --dark for table-card.)
447
+
448
+ Theme color variants (1-9):
449
+ - .pa-table-card--color-{1..9}
450
+
451
+ Structural variant:
452
+ - .pa-table-card--plain Strips card chrome — no border,
453
+ bg, radius, or shadow. Useful
454
+ when the container already
455
+ provides that framing.
456
+
457
+ WHEN TO USE WHICH WRAPPER:
458
+ - pa-table alone simplest; fine inside a pa-card body
459
+ - pa-table-container border + scroll without card overhead
460
+ - pa-table-container--panel adds shadow + optional header area
461
+ - pa-table-card proper card with header/actions/footer slots;
462
+ table edges meet card border cleanly
463
+
464
+ pa-pager — PAGINATION CONTROLS:
465
+ - .pa-pager flex container, centre-aligned by default
466
+ - .pa-pager--start flex-start
467
+ - .pa-pager--end flex-end
468
+
469
+ Sub-elements:
470
+ - .pa-pager__container inner wrapper (flex row, gap: $spacing-sm)
471
+ - .pa-pager__controls button group (gap: $pager-controls-gap)
472
+ - .pa-pager__info input + text wrapper
473
+ - .pa-pager__input narrow number input ($pager-input-width)
474
+ - .pa-pager__text muted caption text
475
+
476
+ pa-load-more — SINGLE-ACTION ALTERNATIVE:
477
+ - .pa-load-more flex container, centre-aligned by default
478
+ - .pa-load-more--start / --end
479
+ - .pa-load-more__button button styling; sits independent of pa-btn
480
+ .pa-load-more__button--loading adds spinner rotation + reduced opacity
481
+ - .pa-load-more__spinner circular spinner (rotates when --loading)
482
+ - .pa-load-more__text label
483
+ - .pa-load-more__count muted counter (margin-inline-start)
484
+
485
+ pa-virtual-table — see virtual-scroll.html for full coverage.
486
+
487
+ STRUCTURE PATTERNS:
488
+
489
+ Simple data table:
490
+ <table class="pa-table pa-table--striped">
491
+ <thead><tr><th>Name</th><th>Email</th></tr></thead>
492
+ <tbody>
493
+ <tr><td>John Doe</td><td>john@example.com</td></tr>
494
+ </tbody>
495
+ </table>
496
+
497
+ Responsive table (mobile → stacked cards):
498
+ <table class="pa-table pa-table--striped pa-table--responsive">
499
+ <thead><tr><th>Name</th><th>Email</th></tr></thead>
500
+ <tbody>
501
+ <tr>
502
+ <td data-label="Name">John Doe</td>
503
+ <td data-label="Email">john@example.com</td>
504
+ </tr>
505
+ </tbody>
506
+ </table>
507
+
508
+ Table card with scrollable body:
509
+ <div class="pa-table-card">
510
+ <div class="pa-table-card__header">
511
+ <h3>Orders</h3>
512
+ <div class="pa-table-card__actions">
513
+ <button class="pa-btn pa-btn--sm pa-btn--primary">Add</button>
514
+ </div>
515
+ </div>
516
+ <div class="pa-table-card__body pa-table-card__body--scrollable">
517
+ <table class="pa-table pa-table--striped">…</table>
518
+ </div>
519
+ </div>
520
+
521
+ Actions column with icon buttons:
522
+ <td class="col-auto">
523
+ <div class="pa-btn-group">
524
+ <button class="pa-btn pa-btn--xs pa-btn--icon-only pa-btn--primary" title="View">👁️</button>
525
+ <button class="pa-btn pa-btn--xs pa-btn--icon-only pa-btn--danger" title="Delete">🗑️</button>
526
+ </div>
527
+ </td>
319
528
  -->