@keenmate/pure-css 1.0.0-rc03 → 1.0.0-rc05
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 +195 -0
- package/README.md +69 -23
- package/dist/css/base.css +48 -204
- package/dist/css/grid.css +364 -364
- package/dist/css/pure-css.css +1726 -612
- package/dist/css/reboot.css +5 -5
- package/dist/css/scrollbars.css +9 -9
- package/dist/css/utilities.css +78 -30
- package/package.json +18 -3
- package/src/js/container-breakpoint.js +308 -0
- package/src/js/fit.js +890 -0
- package/src/js/navbar-dropdown.js +164 -0
- package/src/js/pure-css.js +305 -0
- package/src/js/sidebar-resize.js +210 -0
- package/src/scss/_base-css-variables.scss +360 -385
- package/src/scss/_fit-flyout.scss +76 -0
- package/src/scss/_fonts.scss +36 -36
- package/src/scss/_layout-container.scss +168 -0
- package/src/scss/_layout-responsive.scss +181 -0
- package/src/scss/_navbar-elements.scss +419 -0
- package/src/scss/_navbar.scss +120 -0
- package/src/scss/_pa-grid.scss +43 -43
- package/src/scss/_resize-handle.scss +76 -0
- package/src/scss/_sidebar-states.scss +243 -0
- package/src/scss/_sidebar.scss +420 -0
- package/src/scss/base.scss +2 -3
- package/src/scss/grid.scss +1 -1
- package/src/scss/pure-css.scss +20 -5
- package/src/scss/reboot.scss +5 -5
- package/src/scss/scrollbars.scss +10 -10
- package/src/scss/utilities.scss +791 -758
- package/src/scss/variables/_base.scss +232 -232
- package/src/scss/variables/_components.scss +840 -835
- package/src/scss/variables/_layout.scss +62 -62
- package/src/scss/variables/_system.scss +1 -1
- package/src/scss/variables/_typography.scss +37 -37
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/* ========================================
|
|
2
|
+
Fit — Floating-menu sink (fit.js)
|
|
3
|
+
The self-contained relocation target for
|
|
4
|
+
data-pc-fit="relocate" data-pc-fit-target="floating-menu".
|
|
5
|
+
fit.js creates the trigger (pinned in the container) + panel (on <body>)
|
|
6
|
+
on demand and toggles --open; this styles them. No sidebar dependency.
|
|
7
|
+
Relocated from pure-admin-core: the fit engine (fit.js) + its flyout sink
|
|
8
|
+
now live in the foundation package.
|
|
9
|
+
======================================== */
|
|
10
|
+
@use 'variables/index' as *;
|
|
11
|
+
|
|
12
|
+
// Trigger — a compact "•••" button fit pins at the end of the container. Hidden
|
|
13
|
+
// (inline style) by the engine until at least one slot lives in the panel.
|
|
14
|
+
.pc-fit-flyout__trigger {
|
|
15
|
+
display: inline-flex;
|
|
16
|
+
align-items: center;
|
|
17
|
+
justify-content: center;
|
|
18
|
+
flex: 0 0 auto;
|
|
19
|
+
width: 2.8rem;
|
|
20
|
+
height: 2.8rem;
|
|
21
|
+
padding: 0;
|
|
22
|
+
border: $border-width-base solid transparent;
|
|
23
|
+
border-radius: var(--pc-border-radius);
|
|
24
|
+
background: transparent;
|
|
25
|
+
color: inherit;
|
|
26
|
+
cursor: pointer;
|
|
27
|
+
|
|
28
|
+
&:hover { background: var(--pc-hover-bg, rgba(0, 0, 0, 0.05)); }
|
|
29
|
+
&:focus-visible { outline: 2px solid var(--pc-accent-color); outline-offset: 1px; }
|
|
30
|
+
&[aria-expanded='true'] { background: var(--pc-hover-bg, rgba(0, 0, 0, 0.08)); }
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// The three dots, drawn so the sink needs no icon-font dependency.
|
|
34
|
+
.pc-fit-flyout__dots {
|
|
35
|
+
width: 0.4rem;
|
|
36
|
+
height: 0.4rem;
|
|
37
|
+
border-radius: 50%;
|
|
38
|
+
background: currentColor;
|
|
39
|
+
position: relative;
|
|
40
|
+
|
|
41
|
+
&::before,
|
|
42
|
+
&::after {
|
|
43
|
+
content: '';
|
|
44
|
+
position: absolute;
|
|
45
|
+
top: 0;
|
|
46
|
+
width: 0.4rem;
|
|
47
|
+
height: 0.4rem;
|
|
48
|
+
border-radius: 50%;
|
|
49
|
+
background: currentColor;
|
|
50
|
+
}
|
|
51
|
+
&::before { inset-inline-start: -0.7rem; }
|
|
52
|
+
&::after { inset-inline-start: 0.7rem; }
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// Panel — appended to <body>, positioned by JS (fixed, near the trigger).
|
|
56
|
+
.pc-fit-flyout__panel {
|
|
57
|
+
position: fixed;
|
|
58
|
+
z-index: $z-index-navbar + 10;
|
|
59
|
+
display: none;
|
|
60
|
+
min-width: 20rem;
|
|
61
|
+
max-width: 32rem;
|
|
62
|
+
padding: $spacing-sm;
|
|
63
|
+
background: var(--pc-card-bg);
|
|
64
|
+
border: $border-width-base solid var(--pc-border-color);
|
|
65
|
+
border-radius: var(--pc-border-radius);
|
|
66
|
+
box-shadow: $shadow-lg;
|
|
67
|
+
|
|
68
|
+
&--open { display: block; }
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Each relocated slot is wrapped in an item row inside the panel.
|
|
72
|
+
.pc-fit-flyout__item {
|
|
73
|
+
padding: $spacing-xs $spacing-sm;
|
|
74
|
+
|
|
75
|
+
& + & { border-top: $border-width-base solid var(--pc-border-color); }
|
|
76
|
+
}
|
package/src/scss/_fonts.scss
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
/* Pure Admin Visual Framework - Default Font Definitions */
|
|
2
|
-
|
|
3
|
-
// Default framework fonts - themes can override these
|
|
4
|
-
// Note: Font size classes for <html> are in _utilities.scss (use px values for correct rem scaling)
|
|
5
|
-
|
|
6
|
-
// Font family classes with system defaults
|
|
7
|
-
.font-family-system {
|
|
8
|
-
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
9
|
-
|
|
10
|
-
*, h1, h2, h3, h4, h5, h6, p, div, span, button, input, textarea, select {
|
|
11
|
-
font-family: inherit;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
.font-family-sans {
|
|
16
|
-
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
17
|
-
|
|
18
|
-
*, h1, h2, h3, h4, h5, h6, p, div, span, button, input, textarea, select {
|
|
19
|
-
font-family: inherit;
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
.font-family-serif {
|
|
24
|
-
font-family: Georgia, "Times New Roman", Times, serif;
|
|
25
|
-
|
|
26
|
-
*, h1, h2, h3, h4, h5, h6, p, div, span, button, input, textarea, select {
|
|
27
|
-
font-family: inherit;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
.font-family-mono {
|
|
32
|
-
font-family: "Courier New", Courier, monospace;
|
|
33
|
-
|
|
34
|
-
*, h1, h2, h3, h4, h5, h6, p, div, span, button, input, textarea, select {
|
|
35
|
-
font-family: inherit;
|
|
36
|
-
}
|
|
1
|
+
/* Pure Admin Visual Framework - Default Font Definitions */
|
|
2
|
+
|
|
3
|
+
// Default framework fonts - themes can override these
|
|
4
|
+
// Note: Font size classes for <html> are in _utilities.scss (use px values for correct rem scaling)
|
|
5
|
+
|
|
6
|
+
// Font family classes with system defaults
|
|
7
|
+
.font-family-system {
|
|
8
|
+
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
9
|
+
|
|
10
|
+
*, h1, h2, h3, h4, h5, h6, p, div, span, button, input, textarea, select {
|
|
11
|
+
font-family: inherit;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
.font-family-sans {
|
|
16
|
+
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
|
|
17
|
+
|
|
18
|
+
*, h1, h2, h3, h4, h5, h6, p, div, span, button, input, textarea, select {
|
|
19
|
+
font-family: inherit;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.font-family-serif {
|
|
24
|
+
font-family: Georgia, "Times New Roman", Times, serif;
|
|
25
|
+
|
|
26
|
+
*, h1, h2, h3, h4, h5, h6, p, div, span, button, input, textarea, select {
|
|
27
|
+
font-family: inherit;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.font-family-mono {
|
|
32
|
+
font-family: "Courier New", Courier, monospace;
|
|
33
|
+
|
|
34
|
+
*, h1, h2, h3, h4, h5, h6, p, div, span, button, input, textarea, select {
|
|
35
|
+
font-family: inherit;
|
|
36
|
+
}
|
|
37
37
|
}
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
@use 'variables/index' as *;
|
|
2
|
+
/* ========================================
|
|
3
|
+
Layout Container
|
|
4
|
+
Main layout wrapper, content areas, sticky/scroll modes
|
|
5
|
+
======================================== */
|
|
6
|
+
|
|
7
|
+
// Layout wrapper - applied to body for mode-specific classes
|
|
8
|
+
body.pc-layout--sticky {
|
|
9
|
+
height: 100vh;
|
|
10
|
+
overflow: hidden;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Layout Container - centered, starts below navbar
|
|
14
|
+
.pc-layout {
|
|
15
|
+
max-width: 100%;
|
|
16
|
+
margin: $navbar-height auto 0;
|
|
17
|
+
background-color: var(--pc-main-bg);
|
|
18
|
+
overflow: visible; // Allow tooltips to escape
|
|
19
|
+
display: flex;
|
|
20
|
+
flex-direction: column;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Constrained widths - controlled by body class
|
|
24
|
+
body.pc-container-sm .pc-layout {
|
|
25
|
+
max-width: $layout-container-sm;
|
|
26
|
+
box-shadow: $shadow-2xl;
|
|
27
|
+
border-left: $border-width-base solid var(--pc-border-color);
|
|
28
|
+
border-right: $border-width-base solid var(--pc-border-color);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
body.pc-container-md .pc-layout {
|
|
32
|
+
max-width: $layout-container-md;
|
|
33
|
+
box-shadow: $shadow-2xl;
|
|
34
|
+
border-left: $border-width-base solid var(--pc-border-color);
|
|
35
|
+
border-right: $border-width-base solid var(--pc-border-color);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
body.pc-container-lg .pc-layout {
|
|
39
|
+
max-width: $layout-container-lg;
|
|
40
|
+
box-shadow: $shadow-2xl;
|
|
41
|
+
border-left: $border-width-base solid var(--pc-border-color);
|
|
42
|
+
border-right: $border-width-base solid var(--pc-border-color);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
body.pc-container-xl .pc-layout {
|
|
46
|
+
max-width: $layout-container-xl;
|
|
47
|
+
box-shadow: $shadow-xl;
|
|
48
|
+
border-left: $border-width-base solid var(--pc-border-color);
|
|
49
|
+
border-right: $border-width-base solid var(--pc-border-color);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
body.pc-container-2xl .pc-layout {
|
|
53
|
+
max-width: $layout-container-2xl;
|
|
54
|
+
box-shadow: $shadow-xl;
|
|
55
|
+
border-left: $border-width-base solid var(--pc-border-color);
|
|
56
|
+
border-right: $border-width-base solid var(--pc-border-color);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Sticky mode - fixed height
|
|
60
|
+
body.pc-layout--sticky .pc-layout {
|
|
61
|
+
height: calc(100vh - #{$navbar-height}); // Full viewport minus top margin
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// Scroll mode - minimum height
|
|
65
|
+
body:not(.pc-layout--sticky) .pc-layout {
|
|
66
|
+
min-height: calc(100vh - #{$navbar-height}); // Ensure footer reaches bottom
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Layout inner container - flex wrapper for sidebar + content
|
|
70
|
+
.pc-layout__inner {
|
|
71
|
+
display: flex;
|
|
72
|
+
width: 100%;
|
|
73
|
+
flex: 1; // Take available space, pushing footer to bottom
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Sticky mode - inner container takes full height minus footer
|
|
77
|
+
body.pc-layout--sticky .pc-layout__inner {
|
|
78
|
+
flex: 1;
|
|
79
|
+
overflow: hidden; // Prevent overflow, let content wrapper scroll
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// Content wrapper - wraps main content only
|
|
83
|
+
.pc-layout__content {
|
|
84
|
+
flex: 1;
|
|
85
|
+
display: flex;
|
|
86
|
+
flex-direction: column;
|
|
87
|
+
overflow-y: auto; // Always scrollable
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Main content area
|
|
91
|
+
.pc-layout__main {
|
|
92
|
+
flex: 1;
|
|
93
|
+
padding: $spacing-base;
|
|
94
|
+
container-type: inline-size;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
// Footer - outside inner, sibling to inner
|
|
98
|
+
.pc-layout__footer {
|
|
99
|
+
min-height: $footer-height;
|
|
100
|
+
background-color: var(--pc-footer-bg);
|
|
101
|
+
border-top: $border-width-base solid var(--pc-footer-border-color);
|
|
102
|
+
display: flex;
|
|
103
|
+
align-items: center;
|
|
104
|
+
padding: $spacing-xs $spacing-base;
|
|
105
|
+
flex-shrink: 0; // Don't shrink footer
|
|
106
|
+
gap: $spacing-base;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// Footer sections - Start/Center/End layout (mirrors navbar structure)
|
|
110
|
+
.pc-footer__start {
|
|
111
|
+
display: flex;
|
|
112
|
+
align-items: center;
|
|
113
|
+
gap: $spacing-base;
|
|
114
|
+
flex-shrink: 0;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.pc-footer__center {
|
|
118
|
+
flex: 1;
|
|
119
|
+
min-width: 0; // Allow shrinking for ellipsis
|
|
120
|
+
display: flex;
|
|
121
|
+
align-items: center;
|
|
122
|
+
justify-content: center;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
.pc-footer__end {
|
|
126
|
+
display: flex;
|
|
127
|
+
align-items: center;
|
|
128
|
+
gap: $spacing-base;
|
|
129
|
+
flex-shrink: 0;
|
|
130
|
+
|
|
131
|
+
&--vertical {
|
|
132
|
+
flex-direction: column;
|
|
133
|
+
align-items: flex-end;
|
|
134
|
+
gap: $spacing-xs;
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Responsive footer - stack sections on mobile
|
|
139
|
+
@media (max-width: $mobile-breakpoint) {
|
|
140
|
+
.pc-layout__footer {
|
|
141
|
+
flex-wrap: wrap;
|
|
142
|
+
min-height: auto;
|
|
143
|
+
padding: $spacing-sm $spacing-base;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.pc-footer__start,
|
|
147
|
+
.pc-footer__center,
|
|
148
|
+
.pc-footer__end {
|
|
149
|
+
flex-shrink: 1;
|
|
150
|
+
min-width: 0;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.pc-footer__start {
|
|
154
|
+
flex: 1 1 auto;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.pc-footer__center {
|
|
158
|
+
display: none; // Hide empty center on mobile
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.pc-footer__end {
|
|
162
|
+
flex: 0 1 auto;
|
|
163
|
+
|
|
164
|
+
&--vertical {
|
|
165
|
+
align-items: flex-end;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
@use 'variables/index' as *;
|
|
2
|
+
/* ========================================
|
|
3
|
+
Layout Responsive
|
|
4
|
+
Mobile and tablet media queries
|
|
5
|
+
======================================== */
|
|
6
|
+
|
|
7
|
+
// Config CSS variables — the JS-readable single source for values that also
|
|
8
|
+
// exist as SCSS tokens (window.pureAdmin.config mirrors these; see
|
|
9
|
+
// docs/config-shared-ui-baseline.md). Non-themeable structural constants, so
|
|
10
|
+
// they're emitted here (not via a theme mixin) yet ship in both main.css and
|
|
11
|
+
// every theme. The breakpoint is a clean px value (parseFloat-friendly); the
|
|
12
|
+
// motion tokens are calc() expressions, so JS resolves them off a probe element
|
|
13
|
+
// (getComputedStyle can't resolve calc in an unregistered custom property).
|
|
14
|
+
// These also give CSS consumers named motion tokens as runtime vars.
|
|
15
|
+
:root {
|
|
16
|
+
--pc-mobile-breakpoint: #{$mobile-breakpoint};
|
|
17
|
+
--pc-transition-fast: #{$transition-fast};
|
|
18
|
+
--pc-transition-normal: #{$transition-normal};
|
|
19
|
+
--pc-transition-medium: #{$transition-medium};
|
|
20
|
+
--pc-transition-slow: #{$transition-slow};
|
|
21
|
+
--pc-easing-snappy: #{$easing-snappy};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Responsive Design - Mobile and Tablet
|
|
25
|
+
@media (max-width: $mobile-breakpoint) {
|
|
26
|
+
// Mobile: the sidebar is an off-canvas drawer that SLIDES in/out, in sync with
|
|
27
|
+
// the profile panel (same $transition-medium / $easing-snappy). It's always
|
|
28
|
+
// position:fixed at the drawer size and translated off-canvas at the
|
|
29
|
+
// inline-start edge; `.sidebar-visible` slides it to translateX(0). This
|
|
30
|
+
// replaces the old snap between width:0 and a fixed overlay, which popped in
|
|
31
|
+
// with no animation. Content takes full width in both states because the
|
|
32
|
+
// drawer is out of flow (fixed).
|
|
33
|
+
.pc-layout__sidebar,
|
|
34
|
+
.pc-layout__sidebar--icon-collapse {
|
|
35
|
+
position: fixed;
|
|
36
|
+
top: $navbar-height;
|
|
37
|
+
inset-inline-start: 0; // RTL: flips to right
|
|
38
|
+
bottom: 0;
|
|
39
|
+
width: $mobile-sidebar-width;
|
|
40
|
+
z-index: 1050;
|
|
41
|
+
background-color: var(--pc-sidebar-bg);
|
|
42
|
+
opacity: 1;
|
|
43
|
+
overflow-y: auto;
|
|
44
|
+
overscroll-behavior: contain; // drawer's own scroll doesn't chain to the page
|
|
45
|
+
border-inline-end: none; // RTL: flips to left
|
|
46
|
+
transform: translateX(-100%); // off-canvas (slid out past the inline-start edge)
|
|
47
|
+
visibility: hidden; // inert + unfocusable while closed; flips visible on open
|
|
48
|
+
|
|
49
|
+
// Gate the transition on body.loaded like the sidebar links, so the drawer
|
|
50
|
+
// doesn't animate from off-canvas on first paint.
|
|
51
|
+
body.loaded & {
|
|
52
|
+
transition: transform $transition-medium $easing-snappy,
|
|
53
|
+
visibility $transition-medium $easing-snappy;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// RTL: the drawer sits at the inline-start (right) edge, so it slides off to
|
|
58
|
+
// the right when closed.
|
|
59
|
+
[dir="rtl"] .pc-layout__sidebar,
|
|
60
|
+
[dir="rtl"] .pc-layout__sidebar--icon-collapse {
|
|
61
|
+
transform: translateX(100%);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
// icon-collapse mode is a full overlay drawer on mobile — force labels visible.
|
|
65
|
+
.pc-layout__sidebar--icon-collapse .pc-sidebar__label {
|
|
66
|
+
opacity: 1 !important;
|
|
67
|
+
width: auto !important;
|
|
68
|
+
overflow: visible !important;
|
|
69
|
+
position: static !important;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Backdrop scrim: an always-present fixed pseudo that FADES its opacity, so it
|
|
73
|
+
// eases in/out with the drawer (a pseudo that only existed while open couldn't
|
|
74
|
+
// fade out). Inert + invisible when closed. On body::before so it's positioned
|
|
75
|
+
// against the viewport (not a transformed ancestor) — the toggle class lives
|
|
76
|
+
// on body too.
|
|
77
|
+
body::before {
|
|
78
|
+
content: "";
|
|
79
|
+
position: fixed;
|
|
80
|
+
top: $navbar-height;
|
|
81
|
+
inset-inline: 0; // RTL: covers full width
|
|
82
|
+
bottom: 0;
|
|
83
|
+
background-color: $mobile-backdrop-bg;
|
|
84
|
+
z-index: 1040;
|
|
85
|
+
opacity: 0;
|
|
86
|
+
visibility: hidden;
|
|
87
|
+
pointer-events: none;
|
|
88
|
+
|
|
89
|
+
body.loaded & {
|
|
90
|
+
transition: opacity $transition-medium $easing-snappy,
|
|
91
|
+
visibility $transition-medium $easing-snappy;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Mobile: drawer open — slide it in, reveal the scrim, lock background scroll.
|
|
96
|
+
.sidebar-visible {
|
|
97
|
+
// Standard modal-drawer scroll-lock: while the drawer + scrim are open the
|
|
98
|
+
// page behind must not scroll (otherwise dragging the scrim strip scrolls
|
|
99
|
+
// the content under the fixed drawer, exposing that the drawer is only
|
|
100
|
+
// viewport-high). This covers desktop browsers + Android; iOS Safari ignores
|
|
101
|
+
// body{overflow:hidden} for touch scroll, so the mobile toggle also applies
|
|
102
|
+
// a position:fixed body lock in JS (demo layout.mustache). See
|
|
103
|
+
// docs/mobile-sidebar-overlay.md.
|
|
104
|
+
overflow: hidden;
|
|
105
|
+
|
|
106
|
+
.pc-layout__sidebar,
|
|
107
|
+
.pc-layout__sidebar--icon-collapse {
|
|
108
|
+
transform: translateX(0); // slide in (source order beats the RTL closed rule)
|
|
109
|
+
visibility: visible;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
&::before {
|
|
113
|
+
opacity: 1;
|
|
114
|
+
visibility: visible;
|
|
115
|
+
pointer-events: auto; // tap the scrim to dismiss
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Mobile overlay: the sidebar is a fixed 90vw sheet and resize is disabled in
|
|
120
|
+
// JS at this width (sidebar-resize.js MOBILE_MAX = $mobile-breakpoint). Hide
|
|
121
|
+
// the handle so the coarse-pointer grip pill / edge line don't render as a
|
|
122
|
+
// dead affordance riding the overlay's edge (where it also straddles the
|
|
123
|
+
// backdrop-dismiss tap zone). Touch resize still works in the tablet band
|
|
124
|
+
// above this breakpoint, where the coarse-pointer affordance is kept.
|
|
125
|
+
.pc-sidebar-resize {
|
|
126
|
+
display: none;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Adjust navbar for mobile
|
|
130
|
+
.pc-navbar__inner {
|
|
131
|
+
gap: $spacing-sm;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Legacy navs hard-hide on mobile (navigation is expected in the sidebar).
|
|
135
|
+
// A nav opted into progressive collapse (data-pc-fit-nav) manages its
|
|
136
|
+
// own width at every breakpoint, so it must stay visible here.
|
|
137
|
+
.pc-navmenu:not([data-pc-fit-nav]) {
|
|
138
|
+
display: none;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Hide theme switcher label on mobile
|
|
142
|
+
.theme-switcher {
|
|
143
|
+
label {
|
|
144
|
+
display: none;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
@media (max-width: $tablet-breakpoint) and (min-width: $tablet-breakpoint-min) {
|
|
150
|
+
// Tablet: reduce the sidebar by default, but honour an explicit resize.
|
|
151
|
+
// The default (un-resized) width caps at $sidebar-width-tablet via min() so
|
|
152
|
+
// content gets room and the base $sidebar-width (28.8rem) doesn't dominate a
|
|
153
|
+
// tablet. The old `width: $sidebar-width-tablet` literal (specificity 0,1,0)
|
|
154
|
+
// overrode the var-based base rule outright and snapped every sidebar to 16rem.
|
|
155
|
+
.pc-layout__sidebar {
|
|
156
|
+
width: min(var(--pc-local-sidebar-width), #{$sidebar-width-tablet});
|
|
157
|
+
|
|
158
|
+
&__nav ul li a {
|
|
159
|
+
padding: $spacing-sm $spacing-md;
|
|
160
|
+
font-size: $font-size-sm;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
// Once the user has actually drag-resized (sidebar-resize.js sets this class),
|
|
165
|
+
// honour their exact width here — WITHOUT the tablet cap. This is required for
|
|
166
|
+
// the resize handle to work at all in this band: the drag floor
|
|
167
|
+
// (--pc-local-sidebar-min-width, 18rem) is ABOVE the 16rem cap, so every width
|
|
168
|
+
// the drag can produce is clamped by min() and the sidebar never visibly moves
|
|
169
|
+
// — the handle looks dead. Gating on the explicit-resize class (not just
|
|
170
|
+
// --resizable) keeps the narrow tablet default until the user opts in.
|
|
171
|
+
//
|
|
172
|
+
// MUST exclude .sidebar-hidden: this selector (0,2,1) outweighs
|
|
173
|
+
// `.sidebar-hidden .pc-layout__sidebar { width: 0 }` (0,2,0), so once resized a
|
|
174
|
+
// sidebar stays full-width when the burger hides it and the content never
|
|
175
|
+
// reclaims the space — but ONLY in this tablet band (desktop has no such
|
|
176
|
+
// override). `:not(.sidebar-hidden)` yields to the hide rule while keeping the
|
|
177
|
+
// resized width whenever the sidebar is actually shown.
|
|
178
|
+
body.pc-sidebar-resized:not(.sidebar-hidden) .pc-layout__sidebar {
|
|
179
|
+
width: var(--pc-local-sidebar-width);
|
|
180
|
+
}
|
|
181
|
+
}
|