@nuvoui/core 0.3.0 → 0.3.1
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 +6 -3
- package/dist/index.css +1 -1
- package/dist/index.css.map +1 -1
- package/dist/main.css +1 -1
- package/package.json +1 -1
- package/src/logo.png +0 -0
- package/src/logo.svg +12 -0
- package/src/styles/base/_base.scss +1 -7
- package/src/styles/base/_reset.scss +13 -2
- package/src/styles/components/_form.scss +2 -2
- package/src/styles/components/_navbar.scss +40 -24
- package/src/styles/index.scss +3 -0
- package/src/styles/layouts/_flex.scss +46 -48
- package/src/styles/utilities/_animations.scss +3 -4
- package/src/styles/utilities/_colors.scss +0 -12
- package/src/styles/utilities/_display.scss +42 -0
- package/src/styles/utilities/_hamburger.scss +74 -0
- package/src/styles/utilities/_responsive.scss +184 -0
- package/src/styles/utilities/_spacing.scss +11 -0
package/package.json
CHANGED
package/src/logo.png
ADDED
|
Binary file
|
package/src/logo.svg
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<svg width="418" height="418" viewBox="0 0 418 418" fill="none" xmlns="http://www.w3.org/2000/svg">
|
|
2
|
+
<mask id="mask0_4118_5137" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="418" height="418">
|
|
3
|
+
<rect width="418" height="418" fill="#F1F4D8"/>
|
|
4
|
+
</mask>
|
|
5
|
+
<g mask="url(#mask0_4118_5137)">
|
|
6
|
+
<rect width="418" height="418" fill="#F1F4D8"/>
|
|
7
|
+
<path d="M418 419H77L296.5 262.5L418 201V419Z" fill="#0476A4"/>
|
|
8
|
+
<path d="M316.794 -185.998L487.294 109.316L242.011 -2.52617L128 -76.9983L316.794 -185.998Z" fill="#0476A4"/>
|
|
9
|
+
<line x1="-17.2721" y1="410.484" x2="431.728" y2="185.484" stroke="#5FCFFF" stroke-width="28"/>
|
|
10
|
+
<circle cx="267" cy="183" r="66.5" stroke="#FF7B00" stroke-width="15"/>
|
|
11
|
+
</g>
|
|
12
|
+
</svg>
|
|
@@ -69,9 +69,20 @@ select {
|
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
// Remove list styles
|
|
72
|
-
ul
|
|
73
|
-
ol
|
|
72
|
+
ul,
|
|
73
|
+
ol {
|
|
74
74
|
list-style: none;
|
|
75
|
+
margin: 0;
|
|
76
|
+
padding: 0;
|
|
77
|
+
// Modern properties
|
|
78
|
+
padding-inline-start: 0; // Replaces padding-left
|
|
79
|
+
margin-block: 0; // Replaces margin-top/bottom
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
li {
|
|
83
|
+
margin: 0;
|
|
84
|
+
padding: 0;
|
|
85
|
+
margin-block: 0;
|
|
75
86
|
}
|
|
76
87
|
|
|
77
88
|
// Set core root defaults
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
@mixin form-select {
|
|
84
84
|
@include form-input;
|
|
85
85
|
appearance: none;
|
|
86
|
-
background-image: url("data:image/svg+xml,...");
|
|
86
|
+
background-image: url("data:image/svg+xml,..."); // todo: colored arrow svg
|
|
87
87
|
background-repeat: no-repeat;
|
|
88
88
|
background-position: right 1rem center;
|
|
89
89
|
padding-right: 2.5rem;
|
|
@@ -110,7 +110,7 @@
|
|
|
110
110
|
&:checked {
|
|
111
111
|
background-color: var(--primary);
|
|
112
112
|
border-color: var(--primary);
|
|
113
|
-
background-image: url("data:image/svg+xml,...");
|
|
113
|
+
background-image: url("data:image/svg+xml,..."); // todo: colored arrow svg
|
|
114
114
|
}
|
|
115
115
|
}
|
|
116
116
|
|
|
@@ -1,35 +1,24 @@
|
|
|
1
1
|
// _navbar.scss
|
|
2
2
|
|
|
3
|
-
@use '../utilities/
|
|
3
|
+
@use '../utilities/responsive' as Responsive;
|
|
4
4
|
@use '../utilities/shadows' as *;
|
|
5
|
+
@use '../utilities/variables' as *;
|
|
5
6
|
@use '../layouts/container' as Container;
|
|
6
7
|
@use '../layouts/flex' as Flex;
|
|
7
|
-
@use '../layouts/grid' as Grid;
|
|
8
|
-
|
|
9
|
-
:root {
|
|
10
|
-
--shadow-color: 255, 0, 0;
|
|
11
|
-
}
|
|
12
8
|
|
|
13
9
|
.navbar {
|
|
14
|
-
|
|
15
|
-
@include Flex.between;
|
|
16
10
|
@include Container.container-flex;
|
|
17
11
|
|
|
18
|
-
// @include Grid.grid-flow-row;
|
|
19
|
-
// @include Grid.grid-flow-col;
|
|
20
|
-
// @include Grid.grid-cols(2);
|
|
21
|
-
// @include Container.container-grid;
|
|
22
|
-
|
|
23
12
|
& {
|
|
24
13
|
@include Flex.align-center;
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
background-color: var(--nav-bg);
|
|
14
|
+
@include Flex.between;
|
|
28
15
|
|
|
29
16
|
&:hover {
|
|
30
17
|
@include shadow('lg', 'dark');
|
|
31
18
|
}
|
|
32
19
|
|
|
20
|
+
background-color: var(--nav-bg);
|
|
21
|
+
|
|
33
22
|
.logo {
|
|
34
23
|
img {
|
|
35
24
|
max-height: 40px;
|
|
@@ -103,23 +92,50 @@
|
|
|
103
92
|
}
|
|
104
93
|
}
|
|
105
94
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
95
|
+
// Responsive styles
|
|
96
|
+
@include Responsive.media-down(md) {
|
|
109
97
|
.menu {
|
|
98
|
+
transition: all 1.3s ease;
|
|
99
|
+
display: none;
|
|
110
100
|
flex-direction: column;
|
|
101
|
+
background-color: var(--nav-bg);
|
|
102
|
+
position: absolute;
|
|
103
|
+
top: 100%;
|
|
104
|
+
left: 0;
|
|
111
105
|
width: 100%;
|
|
112
106
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
107
|
+
&[data-visible="true"] {
|
|
108
|
+
display: flex;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
li {
|
|
116
112
|
width: 100%;
|
|
113
|
+
text-align: left;
|
|
114
|
+
|
|
115
|
+
.submenu {
|
|
116
|
+
position: relative;
|
|
117
|
+
left: 0;
|
|
118
|
+
top: 0;
|
|
119
|
+
display: none;
|
|
120
|
+
visibility: visible;
|
|
121
|
+
opacity: 1;
|
|
122
|
+
pointer-events: auto;
|
|
123
|
+
box-shadow: none;
|
|
124
|
+
background-color: var(--nav-hover);
|
|
117
125
|
|
|
118
|
-
|
|
119
|
-
|
|
126
|
+
&[data-visible="true"] {
|
|
127
|
+
display: flex;
|
|
128
|
+
flex-direction: column;
|
|
129
|
+
}
|
|
120
130
|
}
|
|
121
131
|
}
|
|
122
132
|
}
|
|
133
|
+
|
|
134
|
+
.navbar__cta {
|
|
135
|
+
width: 100%;
|
|
136
|
+
justify-content: center;
|
|
137
|
+
padding: 1rem 0;
|
|
138
|
+
}
|
|
123
139
|
}
|
|
124
140
|
}
|
|
125
141
|
}
|
package/src/styles/index.scss
CHANGED
|
@@ -9,7 +9,10 @@
|
|
|
9
9
|
// Utilities
|
|
10
10
|
@forward 'utilities/animations';
|
|
11
11
|
@forward 'utilities/colors';
|
|
12
|
+
@forward 'utilities/display';
|
|
13
|
+
@forward 'utilities/hamburger';
|
|
12
14
|
@forward 'utilities/position';
|
|
15
|
+
@forward 'utilities/responsive';
|
|
13
16
|
@forward 'utilities/shadows';
|
|
14
17
|
@forward 'utilities/spacing';
|
|
15
18
|
@forward 'utilities/typography';
|
|
@@ -41,6 +41,12 @@
|
|
|
41
41
|
// Flex Child Mixins
|
|
42
42
|
@mixin w-full {flex: 0 0 100%;}
|
|
43
43
|
@mixin w-auto {flex: 1 1 auto;}
|
|
44
|
+
@mixin grow { flex: 1 1 0%; }
|
|
45
|
+
@mixin no-grow { flex: none; }
|
|
46
|
+
|
|
47
|
+
@mixin w-col($size) {
|
|
48
|
+
flex: 0 0 math.percentage(math.div($size, $column-count));
|
|
49
|
+
}
|
|
44
50
|
|
|
45
51
|
// Base flex container
|
|
46
52
|
.flex {
|
|
@@ -72,19 +78,14 @@
|
|
|
72
78
|
&.items-baseline { align-items: baseline; }
|
|
73
79
|
&.items-stretch { align-items: stretch; }
|
|
74
80
|
|
|
75
|
-
// Gap modifiers
|
|
76
|
-
@for $i from 0 through 8 {
|
|
77
|
-
&.gap-#{$i} { gap: #{$i * 0.25}rem; }
|
|
78
|
-
}
|
|
79
|
-
|
|
80
81
|
// Child flex items (using column count)
|
|
81
|
-
> .w-auto {
|
|
82
|
-
> .w-full {
|
|
83
|
-
|
|
82
|
+
> .w-auto { @include w-auto }
|
|
83
|
+
> .w-full { @include w-full }
|
|
84
|
+
> .grow { @include grow; }
|
|
85
|
+
> .no-grow { @include no-grow; }
|
|
84
86
|
@for $i from 1 through $column-count {
|
|
85
|
-
> .w-#{$i} {
|
|
86
|
-
|
|
87
|
-
}
|
|
87
|
+
> .w-#{$i} { @include w-col($i) }
|
|
88
|
+
> .order-#{$i} { order: $i; }
|
|
88
89
|
}
|
|
89
90
|
}
|
|
90
91
|
|
|
@@ -92,45 +93,42 @@
|
|
|
92
93
|
// Responsive variants
|
|
93
94
|
@each $breakpoint, $width in $breakpoints {
|
|
94
95
|
@media (min-width: $width) {
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
96
|
+
.flex {
|
|
97
|
+
// Direction
|
|
98
|
+
&.row\@#{$breakpoint} { flex-direction: row; }
|
|
99
|
+
&.row-reverse\@#{$breakpoint} { flex-direction: row-reverse; }
|
|
100
|
+
&.col\@#{$breakpoint} { flex-direction: column; }
|
|
101
|
+
&.col-reverse\@#{$breakpoint} { flex-direction: column-reverse; }
|
|
102
|
+
|
|
103
|
+
// Wrap
|
|
104
|
+
&.wrap\@#{$breakpoint} { flex-wrap: wrap; }
|
|
105
|
+
&.nowrap\@#{$breakpoint} { flex-wrap: nowrap; }
|
|
106
|
+
&.wrap-reverse\@#{$breakpoint} { flex-wrap: wrap-reverse; }
|
|
107
|
+
|
|
108
|
+
// Justify
|
|
109
|
+
&.start\@#{$breakpoint} { justify-content: flex-start; }
|
|
110
|
+
&.end\@#{$breakpoint} { justify-content: flex-end; }
|
|
111
|
+
&.center\@#{$breakpoint} { justify-content: center; }
|
|
112
|
+
&.between\@#{$breakpoint} { justify-content: space-between; }
|
|
113
|
+
&.around\@#{$breakpoint} { justify-content: space-around; }
|
|
114
|
+
&.evenly\@#{$breakpoint} { justify-content: space-evenly; }
|
|
113
115
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
116
|
+
// Align
|
|
117
|
+
&.items-start\@#{$breakpoint} { align-items: flex-start; }
|
|
118
|
+
&.items-end\@#{$breakpoint} { align-items: flex-end; }
|
|
119
|
+
&.items-center\@#{$breakpoint} { align-items: center; }
|
|
120
|
+
&.items-baseline\@#{$breakpoint} { align-items: baseline; }
|
|
121
|
+
&.items-stretch\@#{$breakpoint} { align-items: stretch; }
|
|
122
|
+
|
|
123
|
+
// Width (using column count)
|
|
124
|
+
& > .w-auto\@#{$breakpoint} { flex: 1 1 auto; }
|
|
125
|
+
& > .w-full\@#{$breakpoint} { flex: 0 0 100%; }
|
|
126
|
+
& > .grow\@#{$breakpoint} { @include grow; }
|
|
127
|
+
& > .no-grow\@#{$breakpoint} { @include no-grow; }
|
|
128
|
+
@for $i from 1 through $column-count {
|
|
129
|
+
& > .w-#{$i}\@#{$breakpoint} { @include w-col($i) }
|
|
130
|
+
& > .order-#{$i}\@#{$breakpoint} { order: $i; }
|
|
128
131
|
}
|
|
129
132
|
}
|
|
130
|
-
|
|
131
|
-
// Gap
|
|
132
|
-
@for $i from 0 through 8 {
|
|
133
|
-
.flex.gap-#{$i}\@#{$breakpoint} { gap: #{$i * 0.25}rem; }
|
|
134
|
-
}
|
|
135
133
|
}
|
|
136
134
|
}
|
|
@@ -24,8 +24,7 @@ $generated-keyframes: ();
|
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
@mixin animate-move($props) {
|
|
27
|
+
@mixin animate-bounce($props) {
|
|
29
28
|
$defaults: (
|
|
30
29
|
vertical: 0%,
|
|
31
30
|
horizontal: 0%,
|
|
@@ -36,8 +35,8 @@ $generated-keyframes: ();
|
|
|
36
35
|
// Merge with defaults
|
|
37
36
|
$props: map.merge($defaults, $props);
|
|
38
37
|
|
|
39
|
-
$x: map.get($props, '
|
|
40
|
-
$y: map.get($props, '
|
|
38
|
+
$x: map.get($props, 'horizontal');
|
|
39
|
+
$y: map.get($props, 'vertical');
|
|
41
40
|
$duration: map.get($props, 'duration');
|
|
42
41
|
$easing: map.get($props, 'timing');
|
|
43
42
|
$iteration: map.get($props, 'iteration');
|
|
@@ -144,15 +144,3 @@
|
|
|
144
144
|
@include backdrop-filter(blur(5px) saturate(180%));
|
|
145
145
|
background-color: rgba(255, 255, 255, 0.8);
|
|
146
146
|
}
|
|
147
|
-
|
|
148
|
-
// <div class="bg-primary-0">Lightest shade</div>
|
|
149
|
-
// <div class="bg-primary-4">Middle shade</div>
|
|
150
|
-
// <div class="bg-primary-8">Darkest shade</div>
|
|
151
|
-
|
|
152
|
-
// <div class="brand-complementary">Complementary colors</div>
|
|
153
|
-
|
|
154
|
-
// <div class="text-on-background">Accessible text</div>
|
|
155
|
-
|
|
156
|
-
// <div class="glass-effect">
|
|
157
|
-
// Blurred backdrop
|
|
158
|
-
// </div>
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
@use "sass:math";
|
|
2
|
+
@use 'sass:color';
|
|
3
|
+
@use 'sass:map';
|
|
4
|
+
|
|
5
|
+
@use './variables' as *;
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
// Display Mixins
|
|
10
|
+
@mixin d-none { display: none; }
|
|
11
|
+
@mixin d-block { display: block; }
|
|
12
|
+
@mixin d-inline { display: inline; }
|
|
13
|
+
@mixin d-inline-block { display: inline-block; }
|
|
14
|
+
@mixin d-table { display: table; }
|
|
15
|
+
@mixin d-table-row { display: table-row; }
|
|
16
|
+
@mixin d-table-cell { display: table-cell; }
|
|
17
|
+
|
|
18
|
+
// Base Classes
|
|
19
|
+
.hide { @include d-none; }
|
|
20
|
+
.block { @include d-block; }
|
|
21
|
+
.inline { @include d-inline; }
|
|
22
|
+
.inline-block { @include d-inline-block; }
|
|
23
|
+
.d {
|
|
24
|
+
&-table { @include d-table; }
|
|
25
|
+
&-table-row { @include d-table-row; }
|
|
26
|
+
&-table-cell { @include d-table-cell; }
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Responsive Variants
|
|
30
|
+
@each $breakpoint, $width in $breakpoints {
|
|
31
|
+
@media (min-width: $width) {
|
|
32
|
+
.hide\@#{$breakpoint} { @include d-none; }
|
|
33
|
+
.block\@#{$breakpoint} { @include d-block; }
|
|
34
|
+
.inline\@#{$breakpoint} { @include d-inline; }
|
|
35
|
+
.inline-block\@#{$breakpoint} { @include d-inline-block; }
|
|
36
|
+
.d {
|
|
37
|
+
&-table\@#{$breakpoint} { @include d-table; }
|
|
38
|
+
&-table-row\@#{$breakpoint} { @include d-table-row; }
|
|
39
|
+
&-table-cell\@#{$breakpoint} { @include d-table-cell; }
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
@use "sass:math";
|
|
2
|
+
@use 'sass:color';
|
|
3
|
+
@use 'sass:map';
|
|
4
|
+
@use '../utilities/responsive' as Responsive;
|
|
5
|
+
|
|
6
|
+
@use './variables' as *;
|
|
7
|
+
|
|
8
|
+
// _mixins.scss
|
|
9
|
+
@mixin hamburger($color: currentColor, $size: 24px, $thickness: 2px) {
|
|
10
|
+
.hamburger {
|
|
11
|
+
@include Responsive.media-up('md') {
|
|
12
|
+
display: none;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
& {
|
|
16
|
+
--hamburger-color: #{$color};
|
|
17
|
+
--hamburger-size: #{$size};
|
|
18
|
+
--hamburger-thickness: #{$thickness};
|
|
19
|
+
|
|
20
|
+
&:focus {
|
|
21
|
+
outline: none;
|
|
22
|
+
box-shadow: none;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// display: none;
|
|
26
|
+
cursor: pointer;
|
|
27
|
+
width: var(--hamburger-size);
|
|
28
|
+
height: var(--hamburger-size);
|
|
29
|
+
position: relative;
|
|
30
|
+
border: 0;
|
|
31
|
+
background: transparent;
|
|
32
|
+
padding: 0;
|
|
33
|
+
|
|
34
|
+
&[aria-expanded="true"] span {
|
|
35
|
+
&:first-child {
|
|
36
|
+
transform: translateY(7px) rotate(45deg);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
&:nth-child(2) {
|
|
40
|
+
opacity: 0;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
&:last-child {
|
|
44
|
+
transform: translateY(-7px) rotate(-45deg);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
span {
|
|
49
|
+
display: block;
|
|
50
|
+
position: absolute;
|
|
51
|
+
left: 0;
|
|
52
|
+
right: 0;
|
|
53
|
+
height: var(--hamburger-thickness);
|
|
54
|
+
background-color: var(--hamburger-color);
|
|
55
|
+
transform-origin: center;
|
|
56
|
+
transition: transform 0.2s ease,
|
|
57
|
+
opacity 0.2s ease;
|
|
58
|
+
|
|
59
|
+
&:first-child {
|
|
60
|
+
top: 20%;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
&:nth-child(2) {
|
|
64
|
+
top: 50%;
|
|
65
|
+
transform: translateY(-50%);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
&:last-child {
|
|
69
|
+
bottom: 20%;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
@use 'sass:map';
|
|
2
|
+
@use 'sass:meta';
|
|
3
|
+
@use './variables' as *;
|
|
4
|
+
|
|
5
|
+
// Breakpoint mixins
|
|
6
|
+
@mixin media-up($breakpoint) {
|
|
7
|
+
@if map.has-key($breakpoints, $breakpoint) {
|
|
8
|
+
@media screen and (min-width: map.get($breakpoints, $breakpoint)) {
|
|
9
|
+
@content;
|
|
10
|
+
}
|
|
11
|
+
} @else if meta.type-of($breakpoint) == number {
|
|
12
|
+
@media screen and (min-width: $breakpoint) {
|
|
13
|
+
@content;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
@mixin media-down($breakpoint) {
|
|
19
|
+
@if map.has-key($breakpoints, $breakpoint) {
|
|
20
|
+
@media screen and (max-width: (map.get($breakpoints, $breakpoint) - 0.02px)) {
|
|
21
|
+
@content;
|
|
22
|
+
}
|
|
23
|
+
} @else if meta.type-of($breakpoint) == number {
|
|
24
|
+
@media screen and (max-width: ($breakpoint - 0.02px)) {
|
|
25
|
+
@content;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
@mixin media-between($lower, $upper) {
|
|
31
|
+
@if map.has-key($breakpoints, $lower) and map.has-key($breakpoints, $upper) {
|
|
32
|
+
@media screen and (min-width: map.get($breakpoints, $lower)) and
|
|
33
|
+
(max-width: (map.get($breakpoints, $upper) - 0.02px)) {
|
|
34
|
+
@content;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Only at specific breakpoint
|
|
40
|
+
@mixin media-only($breakpoint) {
|
|
41
|
+
@if map.has-key($breakpoints, $breakpoint) {
|
|
42
|
+
$min: map.get($breakpoints, $breakpoint);
|
|
43
|
+
$next-breakpoint: null;
|
|
44
|
+
|
|
45
|
+
@each $name, $width in $breakpoints {
|
|
46
|
+
@if $width > $min and ($next-breakpoint == null or $width < $next-breakpoint) {
|
|
47
|
+
$next-breakpoint: $width;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
@if $next-breakpoint {
|
|
52
|
+
@media (min-width: $min) and (max-width: $next-breakpoint - 1) {
|
|
53
|
+
@content;
|
|
54
|
+
}
|
|
55
|
+
} @else {
|
|
56
|
+
@media (min-width: $min) {
|
|
57
|
+
@content;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// Example: @include container(45em) { }
|
|
64
|
+
@mixin container-query($size) {
|
|
65
|
+
@container (min-width: $size) {
|
|
66
|
+
@content;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// Touch devices
|
|
71
|
+
@mixin touch {
|
|
72
|
+
@media (hover: none) and (pointer: coarse) {
|
|
73
|
+
@content;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Print media
|
|
78
|
+
@mixin print {
|
|
79
|
+
@media print {
|
|
80
|
+
@content;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Retina displays
|
|
85
|
+
@mixin retina {
|
|
86
|
+
@media (-webkit-min-device-pixel-ratio: 2), (min-resolution: 192dpi) {
|
|
87
|
+
@content;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Modern feature detection
|
|
92
|
+
// Example: @include supports(display: grid) { }
|
|
93
|
+
@mixin supports($property) {
|
|
94
|
+
@supports #{$property} {
|
|
95
|
+
@content;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Reduced motion preference
|
|
100
|
+
@mixin reduced-motion {
|
|
101
|
+
@media (prefers-reduced-motion: reduce) {
|
|
102
|
+
@content;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
// High contrast mode
|
|
107
|
+
@mixin high-contrast {
|
|
108
|
+
@media (forced-colors: active) {
|
|
109
|
+
@content;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Dark mode
|
|
114
|
+
@mixin dark-mode {
|
|
115
|
+
@media (prefers-color-scheme: dark) {
|
|
116
|
+
@content;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Device orientation
|
|
121
|
+
@mixin landscape {
|
|
122
|
+
@media screen and (orientation: landscape) {
|
|
123
|
+
@content;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
@mixin portrait {
|
|
128
|
+
@media screen and (orientation: portrait) {
|
|
129
|
+
@content;
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Modern hover capabilities
|
|
134
|
+
@mixin hover-device {
|
|
135
|
+
@media (hover: hover) and (pointer: fine) {
|
|
136
|
+
@content;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// Modern aspect ratio
|
|
141
|
+
@mixin aspect-ratio($ratio) {
|
|
142
|
+
@supports (aspect-ratio: #{$ratio}) {
|
|
143
|
+
aspect-ratio: #{$ratio};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
@supports not (aspect-ratio: #{$ratio}) {
|
|
147
|
+
&::before {
|
|
148
|
+
float: left;
|
|
149
|
+
padding-top: percentage(1 / $ratio);
|
|
150
|
+
content: '';
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
&::after {
|
|
154
|
+
display: block;
|
|
155
|
+
content: '';
|
|
156
|
+
clear: both;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
// Dynamic viewport units (modern browsers)
|
|
162
|
+
@mixin dvh {
|
|
163
|
+
@supports (height: 100dvh) {
|
|
164
|
+
height: 100dvh;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
@supports not (height: 100dvh) {
|
|
168
|
+
height: 100vh;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Safe area insets (notches, home indicators)
|
|
173
|
+
@mixin safe-area-inset($property, $position) {
|
|
174
|
+
#{$property}: env(safe-area-inset-#{$position});
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Color scheme transition
|
|
178
|
+
@mixin color-scheme-transition {
|
|
179
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
180
|
+
transition: background-color 0.3s ease, color 0.3s ease;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
|
|
@@ -105,4 +105,15 @@
|
|
|
105
105
|
.gap-#{$i} { @include gap($i); }
|
|
106
106
|
.gap-x-#{$i} { @include gap-x($i); }
|
|
107
107
|
.gap-y-#{$i} { @include gap-y($i); }
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Responsive Gap Classes
|
|
111
|
+
@each $breakpoint, $width in $breakpoints {
|
|
112
|
+
@media (min-width: $width) {
|
|
113
|
+
@each $i in $spacings {
|
|
114
|
+
.gap-#{$i}\@#{$breakpoint} { gap: $i; }
|
|
115
|
+
.gap-x-#{$i}\@#{$breakpoint} { column-gap: $i; }
|
|
116
|
+
.gap-y-#{$i}\@#{$breakpoint} { row-gap: $i; }
|
|
117
|
+
}
|
|
118
|
+
}
|
|
108
119
|
}
|