@keenmate/pure-admin-core 2.8.0 → 2.9.0-rc03
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/README.md +16 -15
- package/dist/css/main.css +222 -20
- package/package.json +1 -1
- package/snippets/profile.html +15 -10
- package/snippets/splitter.html +210 -0
- package/src/scss/_base-css-variables.scss +12 -8
- package/src/scss/_core.scss +3 -0
- package/src/scss/core-components/_buttons.scss +15 -0
- package/src/scss/core-components/_cards.scss +164 -2
- package/src/scss/core-components/_profile.scss +6 -14
- package/src/scss/core-components/_splitter.scss +206 -0
- package/src/scss/variables/_base.scss +3 -11
- package/src/scss/variables/_colors.scss +19 -19
- package/src/scss/variables/_components.scss +22 -1
- package/src/scss/variables/_system.scss +8 -0
- package/src/scss/.claude/settings.local.json +0 -11
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
<!-- ================================
|
|
2
|
+
SPLITTER
|
|
3
|
+
Pure Admin Visual Framework
|
|
4
|
+
|
|
5
|
+
Resizable container with two or more panes. Drag a gutter to resize,
|
|
6
|
+
double-click to collapse / restore, arrow keys nudge size when the
|
|
7
|
+
gutter is focused.
|
|
8
|
+
|
|
9
|
+
CSS + structure here; drag, keyboard, persistence behaviour is wired up
|
|
10
|
+
by packages/core/src/js/splitter.js. The script auto-initializes on
|
|
11
|
+
[data-pa-splitter] at DOMContentLoaded.
|
|
12
|
+
|
|
13
|
+
Two markup flavours:
|
|
14
|
+
* 2-pane shorthand — uses --start / --end modifiers and root-level
|
|
15
|
+
min-start / max-start / default attributes (sections 1–3 below).
|
|
16
|
+
* N-pane (N ≥ 2) — generic panes with per-pane size / min / max
|
|
17
|
+
attributes (section 4 below). Use this when you have 3+ panes
|
|
18
|
+
or want more than one minimizable pane.
|
|
19
|
+
|
|
20
|
+
Orientation modifiers (match flexbox direction of the panes):
|
|
21
|
+
--horizontal panes side-by-side, vertical gutter (default)
|
|
22
|
+
--vertical panes stacked, horizontal gutter
|
|
23
|
+
|
|
24
|
+
The splitter takes whatever width/height its parent gives it — make
|
|
25
|
+
sure the parent has a sized cross axis (height for --horizontal,
|
|
26
|
+
width for --vertical) or the panes will collapse.
|
|
27
|
+
================================ -->
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
<!-- ================================
|
|
31
|
+
HORIZONTAL SPLIT
|
|
32
|
+
Side-by-side panes; vertical gutter. Start pane has a 200px floor
|
|
33
|
+
and 60% ceiling, defaults to 280px, persists under "demo-sidebar".
|
|
34
|
+
================================ -->
|
|
35
|
+
|
|
36
|
+
<div class="pa-splitter pa-splitter--horizontal"
|
|
37
|
+
data-pa-splitter
|
|
38
|
+
data-pa-splitter-id="demo-sidebar"
|
|
39
|
+
data-pa-splitter-min-start="200px"
|
|
40
|
+
data-pa-splitter-max-start="60%"
|
|
41
|
+
data-pa-splitter-default="280px"
|
|
42
|
+
style="height: 400px;">
|
|
43
|
+
<div class="pa-splitter__pane pa-splitter__pane--start">
|
|
44
|
+
<!-- Your sidebar / list / nav content -->
|
|
45
|
+
</div>
|
|
46
|
+
<div class="pa-splitter__gutter"
|
|
47
|
+
role="separator"
|
|
48
|
+
aria-orientation="vertical"
|
|
49
|
+
tabindex="0"></div>
|
|
50
|
+
<div class="pa-splitter__pane pa-splitter__pane--end">
|
|
51
|
+
<!-- Your main / detail content -->
|
|
52
|
+
</div>
|
|
53
|
+
</div>
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
<!-- ================================
|
|
57
|
+
VERTICAL SPLIT
|
|
58
|
+
Stacked panes; horizontal gutter. Useful for editor + console / log
|
|
59
|
+
pane patterns.
|
|
60
|
+
================================ -->
|
|
61
|
+
|
|
62
|
+
<div class="pa-splitter pa-splitter--vertical"
|
|
63
|
+
data-pa-splitter
|
|
64
|
+
data-pa-splitter-id="demo-console"
|
|
65
|
+
data-pa-splitter-min-start="80px"
|
|
66
|
+
data-pa-splitter-max-start="80%"
|
|
67
|
+
data-pa-splitter-default="60%"
|
|
68
|
+
style="height: 400px;">
|
|
69
|
+
<div class="pa-splitter__pane pa-splitter__pane--start">
|
|
70
|
+
<!-- Editor / primary content -->
|
|
71
|
+
</div>
|
|
72
|
+
<div class="pa-splitter__gutter"
|
|
73
|
+
role="separator"
|
|
74
|
+
aria-orientation="horizontal"
|
|
75
|
+
tabindex="0"></div>
|
|
76
|
+
<div class="pa-splitter__pane pa-splitter__pane--end">
|
|
77
|
+
<!-- Console / log / secondary -->
|
|
78
|
+
</div>
|
|
79
|
+
</div>
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
<!-- ================================
|
|
83
|
+
SPACED CARDS
|
|
84
|
+
Set `gap` on the splitter root to put breathing room between the
|
|
85
|
+
panes and the gutter — the JS subtracts it from the available
|
|
86
|
+
space so percent constraints still resolve correctly. Override
|
|
87
|
+
gutter thickness via the --pa-splitter-gutter-size custom property.
|
|
88
|
+
================================ -->
|
|
89
|
+
|
|
90
|
+
<div class="pa-splitter pa-splitter--horizontal"
|
|
91
|
+
data-pa-splitter
|
|
92
|
+
style="height: 280px; gap: 1.6rem; --pa-splitter-gutter-size: 1rem;">
|
|
93
|
+
<div class="pa-splitter__pane pa-splitter__pane--start" style="padding: 0;">
|
|
94
|
+
<div class="pa-card" style="height: 100%; margin: 0;">…</div>
|
|
95
|
+
</div>
|
|
96
|
+
<div class="pa-splitter__gutter"
|
|
97
|
+
role="separator"
|
|
98
|
+
aria-orientation="vertical"
|
|
99
|
+
tabindex="0"></div>
|
|
100
|
+
<div class="pa-splitter__pane pa-splitter__pane--end" style="padding: 0;">
|
|
101
|
+
<div class="pa-card" style="height: 100%; margin: 0;">…</div>
|
|
102
|
+
</div>
|
|
103
|
+
</div>
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
<!-- ================================
|
|
107
|
+
N-PANE LAYOUT (3 panes — sidebar + content + inspector)
|
|
108
|
+
Per-pane attributes replace the root-level --start ones. Only the
|
|
109
|
+
first and last panes honour the minimize marker. Panes without a
|
|
110
|
+
data-pa-splitter-size share the leftover equally.
|
|
111
|
+
================================ -->
|
|
112
|
+
|
|
113
|
+
<div class="pa-splitter pa-splitter--horizontal"
|
|
114
|
+
data-pa-splitter
|
|
115
|
+
data-pa-splitter-id="demo-three-pane"
|
|
116
|
+
style="height: 400px;">
|
|
117
|
+
<div class="pa-splitter__pane"
|
|
118
|
+
data-pa-splitter-size="240px"
|
|
119
|
+
data-pa-splitter-min="180px"
|
|
120
|
+
data-pa-splitter-max="360px"
|
|
121
|
+
data-pa-splitter-minimize>
|
|
122
|
+
<!-- File tree / nav (minimizable to a left rail) -->
|
|
123
|
+
</div>
|
|
124
|
+
<div class="pa-splitter__gutter"
|
|
125
|
+
role="separator"
|
|
126
|
+
aria-orientation="vertical"
|
|
127
|
+
tabindex="0"></div>
|
|
128
|
+
<div class="pa-splitter__pane"
|
|
129
|
+
data-pa-splitter-min="240px">
|
|
130
|
+
<!-- Editor / main content (fills the rest) -->
|
|
131
|
+
</div>
|
|
132
|
+
<div class="pa-splitter__gutter"
|
|
133
|
+
role="separator"
|
|
134
|
+
aria-orientation="vertical"
|
|
135
|
+
tabindex="0"></div>
|
|
136
|
+
<div class="pa-splitter__pane"
|
|
137
|
+
data-pa-splitter-size="280px"
|
|
138
|
+
data-pa-splitter-min="220px"
|
|
139
|
+
data-pa-splitter-max="420px"
|
|
140
|
+
data-pa-splitter-minimize>
|
|
141
|
+
<!-- Inspector / detail (minimizable to a right rail) -->
|
|
142
|
+
</div>
|
|
143
|
+
</div>
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
<!-- ================================
|
|
147
|
+
DATA ATTRIBUTES — root (both modes)
|
|
148
|
+
data-pa-splitter marker; required
|
|
149
|
+
data-pa-splitter-id enables localStorage persistence
|
|
150
|
+
under "pa-splitter:<id>"
|
|
151
|
+
data-pa-splitter-step keyboard step in px (default: 10)
|
|
152
|
+
data-pa-splitter-rail-size rail width in px (default: 40)
|
|
153
|
+
data-pa-splitter-minimize-threshold drag-to-rail snap ratio (default: 0.40)
|
|
154
|
+
|
|
155
|
+
DATA ATTRIBUTES — root (legacy 2-pane only)
|
|
156
|
+
data-pa-splitter-min-start "200px" or "20%" (default: 0)
|
|
157
|
+
data-pa-splitter-max-start "60%" or "800px" (default: available)
|
|
158
|
+
data-pa-splitter-default initial size when no saved state
|
|
159
|
+
data-pa-splitter-minimize "start" or "end" — opt into rail collapse
|
|
160
|
+
|
|
161
|
+
DATA ATTRIBUTES — per pane (N-pane only)
|
|
162
|
+
data-pa-splitter-size "240px" or "30%" (default: shared leftover)
|
|
163
|
+
data-pa-splitter-min "150px" or "10%" (default: 0)
|
|
164
|
+
data-pa-splitter-max "400px" or "50%" (default: available)
|
|
165
|
+
data-pa-splitter-minimize marker — only honoured on the first
|
|
166
|
+
and last panes
|
|
167
|
+
|
|
168
|
+
CHILD ATTRIBUTES (both modes)
|
|
169
|
+
data-pa-splitter-toggle put on any element inside the splitter
|
|
170
|
+
(typically a button in the card header)
|
|
171
|
+
to trigger collapse / restore on click.
|
|
172
|
+
In N-pane mode, toggles the enclosing
|
|
173
|
+
pane (if it's minimizable).
|
|
174
|
+
|
|
175
|
+
RAIL-TITLE HOOK (non-card content)
|
|
176
|
+
Any element marked with `[data-pa-splitter-rail-title]` inside a
|
|
177
|
+
minimized pane rotates to vertical writing (sideways-rl). Use this
|
|
178
|
+
when you put plain content (not a `.pa-card`) in a minimizable pane:
|
|
179
|
+
|
|
180
|
+
<div class="pa-splitter__pane" data-pa-splitter-minimize>
|
|
181
|
+
<div data-pa-splitter-rail-title>📁 Files</div>
|
|
182
|
+
<!-- The rest of your pane content here -->
|
|
183
|
+
</div>
|
|
184
|
+
|
|
185
|
+
Cards adapt automatically — `_cards.scss` rotates the card header
|
|
186
|
+
inside any `.pa-splitter__pane--minimized` without needing the
|
|
187
|
+
attribute. No markup change needed for the card snippets above.
|
|
188
|
+
|
|
189
|
+
CSS CUSTOMIZATION
|
|
190
|
+
--pa-splitter-gutter-size gutter thickness (default: 6px)
|
|
191
|
+
--pa-splitter-rail-size rail width when a pane is minimized
|
|
192
|
+
(default: 40px / $splitter-rail-size).
|
|
193
|
+
JS picks this up via getComputedStyle, so
|
|
194
|
+
setting it on `:root` or per-instance via
|
|
195
|
+
inline style overrides the rail width
|
|
196
|
+
without also setting the data-attr.
|
|
197
|
+
gap space between panes and gutter
|
|
198
|
+
(native flexbox property)
|
|
199
|
+
|
|
200
|
+
MODIFIER CLASSES
|
|
201
|
+
pa-splitter--minimize-mirror flip the minimized title 180°
|
|
202
|
+
(transform: scale(-1,-1) on the heading
|
|
203
|
+
inside any `[data-pa-splitter-rail-title]`
|
|
204
|
+
or `.pa-card__header`)
|
|
205
|
+
|
|
206
|
+
JAVASCRIPT API (window.PaSplitter)
|
|
207
|
+
PaSplitter.init(el) initialize a single element (idempotent)
|
|
208
|
+
PaSplitter.initAll(root?) initialize all uninitialized splitters
|
|
209
|
+
under root (default: document)
|
|
210
|
+
================================ -->
|
|
@@ -47,14 +47,6 @@
|
|
|
47
47
|
--base-disabled-bg: #{$base-disabled-bg};
|
|
48
48
|
--base-elevated-bg: #{$base-elevated-bg};
|
|
49
49
|
|
|
50
|
-
// === Background Colors (legacy aliases) ===
|
|
51
|
-
--base-surface-1: #{$base-surface-1};
|
|
52
|
-
--base-surface-2: #{$base-surface-2};
|
|
53
|
-
--base-surface-3: #{$base-surface-3};
|
|
54
|
-
--base-surface-inverse: #{$base-surface-inverse};
|
|
55
|
-
--base-primary-bg: #{$base-primary-bg};
|
|
56
|
-
--base-primary-bg-hover: #{$base-primary-bg-hover};
|
|
57
|
-
|
|
58
50
|
// === Border Colors ===
|
|
59
51
|
--base-border-color: #{$base-border-color};
|
|
60
52
|
--base-border: #{$base-border};
|
|
@@ -265,6 +257,18 @@
|
|
|
265
257
|
// ============================================================================
|
|
266
258
|
|
|
267
259
|
@mixin output-pa-css-variables {
|
|
260
|
+
// =========================================================================
|
|
261
|
+
// COLOR SCHEME SIGNAL
|
|
262
|
+
// Tells the browser whether this scope is light or dark so native UA
|
|
263
|
+
// elements (scrollbars, form controls) and `light-dark()` resolve
|
|
264
|
+
// correctly. Drives web components (e.g. <web-multiselect>) that ship
|
|
265
|
+
// adaptive palettes via `light-dark()`. Override $theme-color-scheme
|
|
266
|
+
// before importing variables for always-dark themes; for dual-mode
|
|
267
|
+
// themes leave default `light` here and add `color-scheme: dark;` to
|
|
268
|
+
// the `.pa-mode-dark` block.
|
|
269
|
+
// =========================================================================
|
|
270
|
+
color-scheme: #{$theme-color-scheme};
|
|
271
|
+
|
|
268
272
|
// =========================================================================
|
|
269
273
|
// CORE COLORS
|
|
270
274
|
// =========================================================================
|
package/src/scss/_core.scss
CHANGED
|
@@ -111,6 +111,9 @@
|
|
|
111
111
|
// Settings Panel
|
|
112
112
|
@use 'core-components/settings-panel' as *;
|
|
113
113
|
|
|
114
|
+
// Splitter (resizable two-pane container)
|
|
115
|
+
@use 'core-components/splitter' as *;
|
|
116
|
+
|
|
114
117
|
// Data Display (read-only fields)
|
|
115
118
|
@use 'core-components/data-display' as *;
|
|
116
119
|
|
|
@@ -44,6 +44,21 @@
|
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
+
// Chromeless action button — no fill, no border, just the label / icon.
|
|
48
|
+
// Used for inline affordances inside dense surfaces (card-header actions,
|
|
49
|
+
// notification dismiss, toast close, splitter minimize) where a full button
|
|
50
|
+
// would compete with the content.
|
|
51
|
+
&--ghost {
|
|
52
|
+
background-color: transparent;
|
|
53
|
+
border-color: transparent;
|
|
54
|
+
color: var(--pa-text-secondary);
|
|
55
|
+
|
|
56
|
+
&:hover {
|
|
57
|
+
background-color: var(--pa-surface-hover);
|
|
58
|
+
color: var(--pa-text-color-1);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
47
62
|
&--xs {
|
|
48
63
|
height: $btn-height-xs;
|
|
49
64
|
padding: $btn-padding-xs-v $btn-padding-xs-h;
|
|
@@ -23,8 +23,13 @@
|
|
|
23
23
|
&__header {
|
|
24
24
|
padding: $card-header-padding-v $card-header-padding-h;
|
|
25
25
|
min-height: $card-header-min-height;
|
|
26
|
-
border-top-
|
|
27
|
-
border-
|
|
26
|
+
// No own border-top-radius — the card's `overflow: hidden` + outer
|
|
27
|
+
// border-radius clips the header's square top corners to match. Setting
|
|
28
|
+
// a radius here makes the header curve at 8px while the card's INNER
|
|
29
|
+
// corner is ~7px (outer 8px minus the 1px border), leaving a thin
|
|
30
|
+
// wedge of card background visible at each top corner — most obvious
|
|
31
|
+
// on coloured variants (--primary/--success/--warning/--danger/--color-*)
|
|
32
|
+
// where the wedge shows as a white sliver against the variant colour.
|
|
28
33
|
border-bottom: $border-width-base solid var(--pa-border-color);
|
|
29
34
|
background: var(--pa-card-header-bg);
|
|
30
35
|
display: flex;
|
|
@@ -95,6 +100,24 @@
|
|
|
95
100
|
flex-shrink: 0;
|
|
96
101
|
}
|
|
97
102
|
|
|
103
|
+
// …unless it's the progressive-overflow variant, which intentionally
|
|
104
|
+
// shrinks below content so the JS can read `scrollWidth > clientWidth`
|
|
105
|
+
// as the "needs overflow" signal. Nested under `&__header` so the
|
|
106
|
+
// selector matches `.pa-card__header .pa-card__actions--overflow` —
|
|
107
|
+
// the same specificity as the rule above, but later in source order
|
|
108
|
+
// and explicit on the modifier.
|
|
109
|
+
.pa-card__actions--overflow {
|
|
110
|
+
flex-shrink: 1;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// When the actions wrapper can shrink (overflow variant), give the title
|
|
114
|
+
// a floor so it can't be squeezed to 0 — icon + a few chars + ellipsis
|
|
115
|
+
// stay visible no matter how narrow. `:has()` scopes the override so
|
|
116
|
+
// ordinary cards keep `min-width: 0` and their full ellipsis range.
|
|
117
|
+
&:has(> .pa-card__actions--overflow) > .pa-card__title {
|
|
118
|
+
min-width: 6rem;
|
|
119
|
+
}
|
|
120
|
+
|
|
98
121
|
// Buttons in card headers - negative margin to prevent header height growth
|
|
99
122
|
.pa-btn {
|
|
100
123
|
margin-top: -0.25rem;
|
|
@@ -232,6 +255,61 @@
|
|
|
232
255
|
display: flex;
|
|
233
256
|
gap: $spacing-sm;
|
|
234
257
|
align-items: center;
|
|
258
|
+
|
|
259
|
+
// Responsive actions — render both the spread button list AND a
|
|
260
|
+
// collapsed split-button form; a container query on the header swaps
|
|
261
|
+
// which is visible. Stays CSS-only (no ResizeObserver / layout reads)
|
|
262
|
+
// but the markup carries both forms.
|
|
263
|
+
//
|
|
264
|
+
// <div class="pa-card__header">
|
|
265
|
+
// <div class="pa-card__title">…</div>
|
|
266
|
+
// <div class="pa-card__actions pa-card__actions--responsive">
|
|
267
|
+
// <div class="pa-card__actions-full">
|
|
268
|
+
// …spread buttons…
|
|
269
|
+
// </div>
|
|
270
|
+
// <div class="pa-card__actions-collapsed">
|
|
271
|
+
// <div class="pa-btn-split">…same actions as a menu…</div>
|
|
272
|
+
// </div>
|
|
273
|
+
// </div>
|
|
274
|
+
// </div>
|
|
275
|
+
//
|
|
276
|
+
// Container is the header; threshold is $card-actions-collapse-at.
|
|
277
|
+
// Wired up via :has() (Baseline 2023) so authors don't need a second
|
|
278
|
+
// modifier on the header.
|
|
279
|
+
&--responsive {
|
|
280
|
+
> .pa-card__actions-full {
|
|
281
|
+
display: flex;
|
|
282
|
+
gap: $spacing-sm;
|
|
283
|
+
align-items: center;
|
|
284
|
+
}
|
|
285
|
+
> .pa-card__actions-collapsed {
|
|
286
|
+
display: none;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
// Progressive overflow variant — driven by card-actions-overflow.js.
|
|
291
|
+
// `min-width: 0` lets flex shrink the wrapper below its content; with
|
|
292
|
+
// `overflow: hidden` the wrapper clips its children when narrow, which
|
|
293
|
+
// is what makes `scrollWidth > clientWidth` a reliable overflow signal
|
|
294
|
+
// for the JS. Buttons themselves get `flex-shrink: 0` so they don't
|
|
295
|
+
// squeeze to fit — they either fit fully or get moved to the menu.
|
|
296
|
+
&--overflow {
|
|
297
|
+
min-width: 0;
|
|
298
|
+
overflow: hidden;
|
|
299
|
+
|
|
300
|
+
> * {
|
|
301
|
+
flex-shrink: 0;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
// Enable the container query on any header that contains a responsive
|
|
307
|
+
// actions wrapper. Container query rule itself is emitted at the bottom
|
|
308
|
+
// of this file (outside the .pa-card block) since `@container` can't
|
|
309
|
+
// hide inside an arbitrarily-nested selector cleanly.
|
|
310
|
+
&__header:has(> .pa-card__actions--responsive) {
|
|
311
|
+
container-type: inline-size;
|
|
312
|
+
container-name: pa-card-header;
|
|
235
313
|
}
|
|
236
314
|
|
|
237
315
|
&__meta {
|
|
@@ -240,11 +318,15 @@
|
|
|
240
318
|
}
|
|
241
319
|
|
|
242
320
|
// Card variants
|
|
321
|
+
// Coloured variants override the header's border-bottom-color to match the
|
|
322
|
+
// variant — otherwise the default light-gray hairline shows as a visible
|
|
323
|
+
// strip against the coloured surroundings (header bg + card border above).
|
|
243
324
|
&--primary {
|
|
244
325
|
border-color: var(--pa-accent);
|
|
245
326
|
|
|
246
327
|
.pa-card__header {
|
|
247
328
|
background-color: var(--pa-accent);
|
|
329
|
+
border-bottom-color: var(--pa-accent);
|
|
248
330
|
color: var(--pa-btn-primary-text);
|
|
249
331
|
|
|
250
332
|
h1,
|
|
@@ -263,6 +345,7 @@
|
|
|
263
345
|
|
|
264
346
|
.pa-card__header {
|
|
265
347
|
background-color: var(--pa-success-bg);
|
|
348
|
+
border-bottom-color: var(--pa-success-bg);
|
|
266
349
|
color: var(--pa-btn-success-text);
|
|
267
350
|
|
|
268
351
|
h1,
|
|
@@ -281,6 +364,7 @@
|
|
|
281
364
|
|
|
282
365
|
.pa-card__header {
|
|
283
366
|
background-color: var(--pa-warning-bg);
|
|
367
|
+
border-bottom-color: var(--pa-warning-bg);
|
|
284
368
|
color: var(--pa-btn-warning-text);
|
|
285
369
|
|
|
286
370
|
h1,
|
|
@@ -299,6 +383,7 @@
|
|
|
299
383
|
|
|
300
384
|
.pa-card__header {
|
|
301
385
|
background-color: var(--pa-danger-bg);
|
|
386
|
+
border-bottom-color: var(--pa-danger-bg);
|
|
302
387
|
color: var(--pa-btn-danger-text);
|
|
303
388
|
|
|
304
389
|
h1,
|
|
@@ -366,6 +451,7 @@
|
|
|
366
451
|
|
|
367
452
|
.pa-card__header {
|
|
368
453
|
background-color: var(--pa-color-#{$i});
|
|
454
|
+
border-bottom-color: var(--pa-color-#{$i});
|
|
369
455
|
color: var(--pa-color-#{$i}-text);
|
|
370
456
|
|
|
371
457
|
h1,
|
|
@@ -486,3 +572,79 @@ a.pa-card {
|
|
|
486
572
|
border-bottom: $border-width-medium solid var(--pa-accent);
|
|
487
573
|
padding-bottom: $spacing-sm;
|
|
488
574
|
}
|
|
575
|
+
|
|
576
|
+
// Responsive card actions — container query for the spread/collapsed swap.
|
|
577
|
+
// Container context set by `.pa-card__header:has(> .pa-card__actions--responsive)`
|
|
578
|
+
// above. Threshold needs explicit interpolation in `@container` (the Sass
|
|
579
|
+
// auto-interpolation that works in `@media` doesn't apply here).
|
|
580
|
+
@container pa-card-header (max-width: #{$card-actions-collapse-at}) {
|
|
581
|
+
.pa-card__actions--responsive {
|
|
582
|
+
> .pa-card__actions-full {
|
|
583
|
+
display: none;
|
|
584
|
+
}
|
|
585
|
+
> .pa-card__actions-collapsed {
|
|
586
|
+
display: flex;
|
|
587
|
+
align-items: center;
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
// Card adaptation inside a minimized splitter pane.
|
|
593
|
+
// Lives here (not in `_splitter.scss`) so the splitter stays unaware of card
|
|
594
|
+
// internals — the rotation hook on the splitter side is `[data-pa-splitter-rail-title]`
|
|
595
|
+
// and this rule applies that attribute's contract to the card header.
|
|
596
|
+
//
|
|
597
|
+
// Layout: pa-card already has `height: 100%` etc., we just hide body/footer,
|
|
598
|
+
// promote the header to fill the rail, and pin the title to the top.
|
|
599
|
+
.pa-splitter__pane--minimized > .pa-card {
|
|
600
|
+
height: 100%;
|
|
601
|
+
display: flex;
|
|
602
|
+
flex-direction: column;
|
|
603
|
+
margin: 0;
|
|
604
|
+
|
|
605
|
+
> .pa-card__body,
|
|
606
|
+
> .pa-card__footer {
|
|
607
|
+
display: none;
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
> .pa-card__header {
|
|
611
|
+
flex: 1 1 auto;
|
|
612
|
+
// Pin title to the rail's top (inline-start in sideways-rl writing mode).
|
|
613
|
+
justify-content: flex-start;
|
|
614
|
+
writing-mode: sideways-rl;
|
|
615
|
+
|
|
616
|
+
// Icons reset to natural orientation (descendant combinator covers both
|
|
617
|
+
// flat markup and the BEM `pa-card__title > i` nesting).
|
|
618
|
+
i,
|
|
619
|
+
svg {
|
|
620
|
+
writing-mode: initial;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
// Vertically align the icon between expanded and minimized states.
|
|
624
|
+
// In expanded mode, `align-items: center` centers the title vertically
|
|
625
|
+
// (icon center at header-min-height / 2 from top). In minimized mode,
|
|
626
|
+
// `justify-content: flex-start` pins the title to the rail's top edge.
|
|
627
|
+
// Push the title down by the difference so the icon sits at the same
|
|
628
|
+
// visual y-position in both states — no "jump" when toggling.
|
|
629
|
+
.pa-card__title {
|
|
630
|
+
padding-top: calc((#{$card-header-min-height} - #{$font-size-base}) / 2 - #{$card-header-padding-v});
|
|
631
|
+
}
|
|
632
|
+
|
|
633
|
+
// Hide interactive controls inside the header — they'd be sideways and
|
|
634
|
+
// unreadable. The list here is intentional: cards know their own header
|
|
635
|
+
// contents better than the splitter ever could.
|
|
636
|
+
.pa-btn,
|
|
637
|
+
.pa-btn-group,
|
|
638
|
+
button,
|
|
639
|
+
input {
|
|
640
|
+
display: none;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
// Mirror modifier — when the splitter root carries `pa-splitter--minimize-mirror`,
|
|
646
|
+
// the card heading flips 180° (matches the generic mirror behaviour, scoped
|
|
647
|
+
// to the card title heading).
|
|
648
|
+
.pa-splitter--minimize-mirror .pa-splitter__pane--minimized > .pa-card > .pa-card__header :is(h1, h2, h3, h4, h5, h6) {
|
|
649
|
+
transform: scale(-1, -1);
|
|
650
|
+
}
|
|
@@ -162,20 +162,12 @@
|
|
|
162
162
|
white-space: nowrap;
|
|
163
163
|
}
|
|
164
164
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
background-color: color-mix(in srgb, var(--pa-header-profile-name-color) 15%, transparent);
|
|
172
|
-
color: var(--pa-header-profile-name-color);
|
|
173
|
-
font-size: $font-size-xs;
|
|
174
|
-
font-weight: $font-weight-medium;
|
|
175
|
-
border-radius: var(--pa-border-radius);
|
|
176
|
-
text-transform: uppercase;
|
|
177
|
-
letter-spacing: $profile-role-letter-spacing;
|
|
178
|
-
}
|
|
165
|
+
// Role badge: use the standard `.pa-badge` component in markup instead of
|
|
166
|
+
// a custom `__role` element. Previously this declared its own bg/colour/
|
|
167
|
+
// padding/uppercase styling — duplicating badge work that already existed
|
|
168
|
+
// in the framework, and coupling to `--pa-header-profile-name-color` which
|
|
169
|
+
// went invisible inside dark-mode panel bodies. Snippets and demo markup
|
|
170
|
+
// updated accordingly in 2.9.0.
|
|
179
171
|
|
|
180
172
|
&__close {
|
|
181
173
|
position: absolute;
|