summaryrefslogtreecommitdiffstats
path: root/src/layouts
diff options
context:
space:
mode:
Diffstat (limited to 'src/layouts')
-rw-r--r--src/layouts/_button-group.scss17
-rw-r--r--src/layouts/_button-group.vars.scss4
-rw-r--r--src/layouts/_card-list.scss237
-rw-r--r--src/layouts/_card-list.vars.scss29
-rw-r--r--src/layouts/_container.scss42
-rw-r--r--src/layouts/_container.vars.scss25
-rw-r--r--src/layouts/_flex.scss24
-rw-r--r--src/layouts/_form.scss80
-rw-r--r--src/layouts/_hlist.scss74
-rw-r--r--src/layouts/_hlist.vars.scss16
-rw-r--r--src/layouts/_media.scss50
-rw-r--r--src/layouts/_media.vars.scss8
-rw-r--r--src/layouts/_overflow.scss8
-rw-r--r--src/layouts/_split-view.scss148
-rw-r--r--src/layouts/_split-view.vars.scss5
15 files changed, 515 insertions, 252 deletions
diff --git a/src/layouts/_button-group.scss b/src/layouts/_button-group.scss
deleted file mode 100644
index c51ae7e..0000000
--- a/src/layouts/_button-group.scss
+++ /dev/null
@@ -1,17 +0,0 @@
1@use 'sass:meta';
2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
5
6@forward 'button-group.vars';
7@use 'button-group.vars' as vars;
8
9@mixin styles {
10 @include materialize-at-root(meta.module-variables('vars'));
11
12 @include bem.layout('button-group') {
13 display: flex;
14 flex-wrap: wrap;
15 gap: props.get(vars.$spacing);
16 }
17}
diff --git a/src/layouts/_button-group.vars.scss b/src/layouts/_button-group.vars.scss
deleted file mode 100644
index 95ac8f8..0000000
--- a/src/layouts/_button-group.vars.scss
+++ /dev/null
@@ -1,4 +0,0 @@
1@use 'iro-sass/src/props';
2@use '../core.vars' as core;
3
4$spacing: props.def(--l-button-group--spacing, props.get(core.$size--150)) !default;
diff --git a/src/layouts/_card-list.scss b/src/layouts/_card-list.scss
index 8ef40c5..8f96ce0 100644
--- a/src/layouts/_card-list.scss
+++ b/src/layouts/_card-list.scss
@@ -4,79 +4,200 @@
4@use 'iro-sass/src/props'; 4@use 'iro-sass/src/props';
5@use '../props' as *; 5@use '../props' as *;
6 6
7@use '../objects/card.vars' as card;
8
7@forward 'card-list.vars'; 9@forward 'card-list.vars';
8@use 'card-list.vars' as vars; 10@use 'card-list.vars' as vars;
9 11
10@mixin styles { 12@mixin styles {
11 @include materialize-at-root(meta.module-variables('vars')); 13 @include materialize-at-root(meta.module-variables('vars'));
14
15 @include bem.layout('card-list') {
16 display: flex;
17 flex-direction: column;
18 gap: props.get(vars.$row-gap);
19
20 @include bem.modifier('merge') {
21 position: relative;
22 gap: 0;
23 border-radius: props.get(card.$rounding);
24
25 @include bem.elem('card') {
26 border-color: props.get(card.$border-color) props.get(card.$border-color) props.get(vars.$border-color);
27 background-clip: content-box;
28 box-shadow: none;
29
30 &:not(:last-child) {
31 position: relative;
32 border-end-start-radius: 0;
33 border-end-end-radius: 0;
34 }
35
36 @include bem.multi('&:link, &:visited, &:enabled', 'modifier' 'interactive', 'modifier' 'collapsible') {
37 &:hover,
38 &:active,
39 &:focus-visible {
40 transform: none;
41 }
42
43 &:focus-visible {
44 z-index: 10;
45 }
46 }
47
48 @include bem.next-twin-elem {
49 margin-block-start: calc(-1 * props.get(card.$border-width));
50 border-block-start-color: transparent;
51 border-start-start-radius: 0;
52 border-start-end-radius: 0;
53
54 @include bem.multi('&:link, &:visited, &:enabled', 'modifier' 'interactive', 'modifier' 'collapsible') {
55 &:hover,
56 &:active {
57 border-block-start-color: props.get(card.$hover--border-color);
58 }
59
60 &:focus-visible {
61 margin-block-start: calc(-1 * props.get(card.$border-width) - props.get(card.$key-focus--border-width));
62 }
63 }
64 }
65
66 &:last-child {
67 border-block-end-color: props.get(card.$border-color);
68 }
69
70 @include bem.multi('&:link, &:visited, &:enabled', 'modifier' 'interactive', 'modifier' 'collapsible') {
71 &:hover,
72 &:active {
73 border-color: props.get(card.$hover--border-color);
74 }
75
76 &:focus-visible {
77 border-color: props.get(card.$hover--bg-color);
78 box-shadow:
79 0 0 0
80 calc(props.get(card.$key-focus--border-width) + props.get(card.$key-focus--outline-width))
81 props.get(card.$key-focus--outline-color);
82 }
83 }
84 }
85
86 @include bem.modifier('borderless') {
87 @include bem.elem('card') {
88 border-color: props.get(card.$bg-color) props.get(card.$bg-color) props.get(vars.$border-color);
89
90 @include bem.next-twin-elem {
91 border-block-start-color: transparent;
92 }
93
94 &:last-child {
95 border-block-end-color: props.get(card.$bg-color);
96 }
97
98 @include bem.multi('&:link, &:visited, &:enabled', 'modifier' 'interactive', 'modifier' 'collapsible') {
99 &:hover,
100 &:active {
101 border-color: props.get(card.$hover--border-color);
102 }
103
104 &:focus-visible {
105 border-color: props.get(card.$hover--bg-color);
106 }
107 }
108 }
109 }
110
111 @include bem.modifier('shadow') {
112 box-shadow:
113 props.get(vars.$shadow-x)
114 props.get(vars.$shadow-y)
115 props.get(vars.$shadow-blur)
116 props.get(vars.$shadow-grow)
117 props.get(card.$shadow-color);
118 }
119
120 @include bem.modifier('interactive') {
121 transition: transform .2s, box-shadow .2s;
122
123 &:hover,
124 &:active,
125 &:focus-within {
126 box-shadow: none;
127 transform: translateY(props.get(card.$hover--offset-b));
128 }
129 }
130 }
131
132 @include bem.modifier('quiet') {
133 row-gap: props.get(vars.$quiet--row-gap);
134 }
12 135
13 @include bem.layout('card-list') {
14 display: flex;
15 flex-direction: column;
16 gap: props.get(vars.$row-gap);
17 136
18 @include bem.modifier('quiet') { 137 @each $mod, $row-gap, $col-gap, $col-width, $quiet--row-gap, $breakpoint in vars.$grid-layouts {
19 row-gap: props.get(vars.$quiet--row-gap); 138 @include bem.modifier($mod) {
20 } 139 display: grid;
140 grid-template-columns: repeat(auto-fill, minmax(props.get($col-width), 1fr));
141 gap: props.get($row-gap) props.get($col-gap);
21 142
22 @include bem.modifier('grid') { 143 @include bem.modifier('quiet') {
23 display: grid; 144 row-gap: props.get($quiet--row-gap);
24 grid-template-columns: repeat(auto-fill, minmax(props.get(vars.$grid--col-width), 1fr)); 145 }
25 gap: props.get(vars.$grid--row-gap) props.get(vars.$grid--col-gap);
26 146
27 @include bem.modifier('quiet') { 147 @include media.media('<=#{$breakpoint}') {
28 row-gap: props.get(vars.$grid--quiet--row-gap); 148 display: flex;
29 } 149 }
30 } 150 }
151 }
31 152
32 @include bem.modifier('masonry') { 153 @include bem.modifier('masonry') {
33 display: block; 154 display: block;
34 columns: auto props.get(vars.$masonry--col-width); 155 columns: auto props.get(vars.$masonry--col-width);
35 column-gap: props.get(vars.$masonry--col-gap); 156 column-gap: props.get(vars.$masonry--col-gap);
36 157
37 @include bem.elem('card') { 158 @include bem.elem('card') {
38 margin-block-end: props.get(vars.$masonry--row-gap); 159 margin-block-end: props.get(vars.$masonry--row-gap);
39 break-inside: avoid; 160 break-inside: avoid;
40 } 161 }
41 162
42 @include bem.modifier('quiet') { 163 @include bem.modifier('quiet') {
43 @include bem.elem('card') { 164 @include bem.elem('card') {
44 margin-block-end: props.get(vars.$masonry--quiet--row-gap); 165 margin-block-end: props.get(vars.$masonry--quiet--row-gap);
45 } 166 }
46 } 167 }
47 } 168 }
48 169
49 @include bem.modifier('masonry-h') { 170 @include bem.modifier('masonry-h') {
50 flex-flow: row wrap; 171 flex-flow: row wrap;
51 gap: props.get(vars.$masonry-h--row-gap) props.get(vars.$masonry-h--col-gap); 172 gap: props.get(vars.$masonry-h--row-gap) props.get(vars.$masonry-h--col-gap);
52 173
53 @include bem.modifier('no-flush') { 174 @include bem.modifier('no-flush') {
54 &::after { 175 &::after {
55 display: block; 176 display: block;
56 flex: 1 0 auto; 177 flex: 1 0 auto;
57 inline-size: props.get(vars.$masonry-h--row-height); 178 inline-size: props.get(vars.$masonry-h--row-height);
58 content: ''; 179 content: '';
59 } 180 }
60 } 181 }
61 182
62 @include bem.elem('card') { 183 @include bem.elem('card') {
63 flex: 1 0 auto; 184 flex: 1 0 auto;
64 max-inline-size: 100%; 185 max-inline-size: 100%;
65 } 186 }
66 187
67 @include bem.elem('card-image') { 188 @include bem.elem('card-image') {
68 block-size: props.get(vars.$masonry-h--row-height); 189 block-size: props.get(vars.$masonry-h--row-height);
69 } 190 }
70 191
71 @include bem.modifier('quiet') { 192 @include bem.modifier('quiet') {
72 row-gap: props.get(vars.$masonry-h--quiet--row-gap); 193 row-gap: props.get(vars.$masonry-h--quiet--row-gap);
73 } 194 }
74 } 195 }
75 196
76 @include bem.modifier('aspect-5\\/4') { 197 @include bem.modifier('aspect-5\\/4') {
77 @include bem.elem('card-image') { 198 @include bem.elem('card-image') {
78 aspect-ratio: 5 / 4; 199 aspect-ratio: 5 / 4;
79 } 200 }
80 } 201 }
81 } 202 }
82} 203}
diff --git a/src/layouts/_card-list.vars.scss b/src/layouts/_card-list.vars.scss
index f77bfbf..d860ec9 100644
--- a/src/layouts/_card-list.vars.scss
+++ b/src/layouts/_card-list.vars.scss
@@ -1,14 +1,31 @@
1@use 'iro-sass/src/props'; 1@use 'iro-sass/src/props';
2@use '../core.vars' as core; 2@use '../core.vars' as core;
3@use '../objects/card' as card;
3 4
4$row-gap: props.def(--l-card-list--row-gap, props.get(core.$size--200)) !default; 5$row-gap: props.def(--l-card-list--row-gap, props.get(core.$size--200)) !default;
5$quiet--row-gap: props.def(--l-card-list--quiet--row-gap, props.get(core.$size--800)) !default; 6$quiet--row-gap: props.def(--l-card-list--quiet--row-gap, props.get(core.$size--800)) !default;
6 7
7$grid--row-gap: props.def(--l-card-list--grid--row-gap, props.get(core.$size--400)) !default; 8$grid--row-gap: props.def(--l-card-list--grid--row-gap, props.get(core.$size--600)) !default;
8$grid--col-gap: props.def(--l-card-list--grid--col-gap, props.get(core.$size--400)) !default; 9$grid--col-gap: props.def(--l-card-list--grid--col-gap, props.get(core.$size--600)) !default;
9$grid--col-width: props.def(--l-card-list--grid--col-width, props.get(core.$size--3200)) !default; 10$grid--col-width: props.def(--l-card-list--grid--col-width, props.get(core.$size--3200)) !default;
10$grid--quiet--row-gap: props.def(--l-card-list--grid--quiet--row-gap, props.get(core.$size--800)) !default; 11$grid--quiet--row-gap: props.def(--l-card-list--grid--quiet--row-gap, props.get(core.$size--800)) !default;
11 12
13$grid-sm--row-gap: props.def(--l-card-list--grid-sm--row-gap, props.get(core.$size--200)) !default;
14$grid-sm--col-gap: props.def(--l-card-list--grid-sm--col-gap, props.get(core.$size--200)) !default;
15$grid-sm--col-width: props.def(--l-card-list--grid-sm--col-width, props.get(core.$size--4600)) !default;
16$grid-sm--quiet--row-gap: props.def(--l-card-list--grid-sm--quiet--row-gap, props.get(core.$size--800)) !default;
17
18$grid-xs--row-gap: props.def(--l-card-list--grid-xs--row-gap, props.get(core.$size--200)) !default;
19$grid-xs--col-gap: props.def(--l-card-list--grid-xs--col-gap, props.get(core.$size--200)) !default;
20$grid-xs--col-width: props.def(--l-card-list--grid-xs--col-width, props.get(core.$size--1600)) !default;
21$grid-xs--quiet--row-gap: props.def(--l-card-list--grid-xs--quiet--row-gap, props.get(core.$size--800)) !default;
22
23$grid-layouts: (
24 'grid' $grid--row-gap $grid--col-gap $grid--col-width $grid--quiet--row-gap sm,
25 'grid-sm' $grid-sm--row-gap $grid-sm--col-gap $grid-sm--col-width $grid-sm--quiet--row-gap sm,
26 'grid-xs' $grid-xs--row-gap $grid-xs--col-gap $grid-xs--col-width $grid-xs--quiet--row-gap xs,
27) !default;
28
12$masonry--row-gap: props.def(--l-card-list--masonry--row-gap, props.get(core.$size--400)) !default; 29$masonry--row-gap: props.def(--l-card-list--masonry--row-gap, props.get(core.$size--400)) !default;
13$masonry--col-gap: props.def(--l-card-list--masonry--col-gap, props.get(core.$size--400)) !default; 30$masonry--col-gap: props.def(--l-card-list--masonry--col-gap, props.get(core.$size--400)) !default;
14$masonry--col-width: props.def(--l-card-list--masonry--col-width, props.get(core.$size--3200)) !default; 31$masonry--col-width: props.def(--l-card-list--masonry--col-width, props.get(core.$size--3200)) !default;
@@ -19,4 +36,10 @@ $masonry-h--col-gap: props.def(--l-card-list--masonry-h--col-gap, props.g
19$masonry-h--row-height: props.def(--l-card-list--masonry-h--row-height, props.get(core.$size--3200)) !default; 36$masonry-h--row-height: props.def(--l-card-list--masonry-h--row-height, props.get(core.$size--3200)) !default;
20$masonry-h--quiet--row-gap: props.def(--l-card-list--masonry-h--quiet--row-gap, props.get(core.$size--800)) !default; 37$masonry-h--quiet--row-gap: props.def(--l-card-list--masonry-h--quiet--row-gap, props.get(core.$size--800)) !default;
21 38
22$border-color: props.def(--l-card-list--border-color, props.get(core.$theme, --border), 'color') !default; 39$shadow-x: props.def(--l-card-list--shadow-x, props.get(card.$shadow-x)) !default;
40$shadow-y: props.def(--l-card-list--shadow-y, props.get(card.$shadow-y)) !default;
41$shadow-blur: props.def(--l-card-list--shadow-blur, props.get(card.$shadow-blur)) !default;
42$shadow-grow: props.def(--l-card-list--shadow-grow, props.get(card.$shadow-grow)) !default;
43
44$border-color: props.def(--l-card-list--border-color, props.get(card.$border-color), 'color') !default;
45$border-color-dark: props.def(--l-card-list--border-color, props.get(core.$theme, --border-mute), 'dark') !default;
diff --git a/src/layouts/_container.scss b/src/layouts/_container.scss
index 17ab2f0..05d99a8 100644
--- a/src/layouts/_container.scss
+++ b/src/layouts/_container.scss
@@ -7,22 +7,34 @@
7@use 'container.vars' as vars; 7@use 'container.vars' as vars;
8 8
9@mixin styles { 9@mixin styles {
10 @include materialize-at-root(meta.module-variables('vars')); 10 @include materialize-at-root(meta.module-variables('vars'));
11 11
12 @include bem.layout('container') { 12 @include bem.layout('container') {
13 @each $mod, $size in vars.$fixed-sizes { 13 @each $mod, $size in vars.$fixed-sizes {
14 @include bem.modifier($mod) { 14 @include bem.modifier($mod) {
15 max-inline-size: props.get($size); 15 max-inline-size: props.get($size);
16 margin-inline: auto; 16 margin-inline: auto;
17 } 17 }
18 } 18 }
19 19
20 @include bem.modifier('pad-i') { 20 @include bem.modifier('pad-i') {
21 padding-inline: props.get(vars.$pad-i); 21 padding-inline: props.get(vars.$pad-i);
22 } 22 }
23 23
24 @include bem.modifier('pad-b') { 24 @include bem.modifier('pad-b') {
25 padding-block: props.get(vars.$pad-b); 25 padding-block: props.get(vars.$pad-b);
26 } 26 }
27 } 27
28 @each $mod, $pad-i, $pad-b in vars.$sizes {
29 @include bem.modifier($mod) {
30 @include bem.modifier('pad-i') {
31 padding-inline: props.get($pad-i);
32 }
33
34 @include bem.modifier('pad-b') {
35 padding-block: props.get($pad-b);
36 }
37 }
38 }
39 }
28} 40}
diff --git a/src/layouts/_container.vars.scss b/src/layouts/_container.vars.scss
index 56b6c89..285b784 100644
--- a/src/layouts/_container.vars.scss
+++ b/src/layouts/_container.vars.scss
@@ -7,16 +7,33 @@ $fixed-150: props.def(--l-container--fixed-150, fn.px-to-rem(860px)) !default;
7$fixed: props.def(--l-container--fixed, fn.px-to-rem(680px)) !default; 7$fixed: props.def(--l-container--fixed, fn.px-to-rem(680px)) !default;
8 8
9$fixed-sizes: ( 9$fixed-sizes: (
10 'fixed-200': $fixed-200, 10 'fixed-200': $fixed-200,
11 'fixed-150': $fixed-150, 11 'fixed-150': $fixed-150,
12 'fixed': $fixed 12 'fixed': $fixed
13) !default; 13) !default;
14 14
15$pad-i: props.def(--l-container--pad-i, props.get(core.$size--400)) !default; 15$pad-i: props.def(--l-container--pad-i, props.get(core.$size--600)) !default;
16$pad-b: props.def(--l-container--pad-b, props.get(core.$size--800)) !default; 16$pad-b: props.def(--l-container--pad-b, props.get(core.$size--800)) !default;
17 17
18$pad-i--md: props.def(--l-container--pad-i, props.get(core.$size--400), 'md') !default;
19$pad-b--md: props.def(--l-container--pad-b, props.get(core.$size--700), 'md') !default;
20
18$pad-i--sm: props.def(--l-container--pad-i, props.get(core.$size--200), 'sm') !default; 21$pad-i--sm: props.def(--l-container--pad-i, props.get(core.$size--200), 'sm') !default;
19$pad-b--sm: props.def(--l-container--pad-b, props.get(core.$size--600), 'sm') !default; 22$pad-b--sm: props.def(--l-container--pad-b, props.get(core.$size--600), 'sm') !default;
20 23
21$pad-i--xs: props.def(--l-container--pad-i, props.get(core.$size--150), 'xs') !default; 24$pad-i--xs: props.def(--l-container--pad-i, props.get(core.$size--150), 'xs') !default;
22$pad-b--xs: props.def(--l-container--pad-b, props.get(core.$size--450), 'xs') !default; 25$pad-b--xs: props.def(--l-container--pad-b, props.get(core.$size--450), 'xs') !default;
26
27$sm--pad-i: props.def(--l-container--sm--pad-i, props.get(core.$size--300)) !default;
28$sm--pad-b: props.def(--l-container--sm--pad-b, props.get(core.$size--800)) !default;
29
30$sm--pad-i--sm: props.def(--l-container--sm--pad-i, props.get(core.$size--200), 'sm') !default;
31$sm--pad-b--sm: props.def(--l-container--sm--pad-b, props.get(core.$size--600), 'sm') !default;
32
33$sm--pad-i--xs: props.def(--l-container--sm--pad-i, props.get(core.$size--150), 'xs') !default;
34$sm--pad-b--xs: props.def(--l-container--sm--pad-b, props.get(core.$size--450), 'xs') !default;
35
36$sizes: (
37 'sm' $sm--pad-i $sm--pad-b,
38 'md' $sm--pad-i $sm--pad-b,
39) !default;
diff --git a/src/layouts/_flex.scss b/src/layouts/_flex.scss
index 902ecdb..c99b253 100644
--- a/src/layouts/_flex.scss
+++ b/src/layouts/_flex.scss
@@ -1,19 +1,19 @@
1@use 'iro-sass/src/bem'; 1@use 'iro-sass/src/bem';
2 2
3@mixin styles { 3@mixin styles {
4 @include bem.layout('flex') { 4 @include bem.layout('flex') {
5 display: flex; 5 display: flex;
6 6
7 @include bem.modifier('column') { 7 @include bem.modifier('column') {
8 flex-direction: column; 8 flex-direction: column;
9 } 9 }
10 10
11 @include bem.modifier('wrap') { 11 @include bem.modifier('wrap') {
12 flex-wrap: wrap; 12 flex-wrap: wrap;
13 } 13 }
14 14
15 @include bem.modifier('wrap-reverse') { 15 @include bem.modifier('wrap-reverse') {
16 flex-wrap: wrap-reverse; 16 flex-wrap: wrap-reverse;
17 } 17 }
18 } 18 }
19} 19}
diff --git a/src/layouts/_form.scss b/src/layouts/_form.scss
index 5f0567b..c804262 100644
--- a/src/layouts/_form.scss
+++ b/src/layouts/_form.scss
@@ -7,53 +7,53 @@
7@use 'form.vars' as vars; 7@use 'form.vars' as vars;
8 8
9@mixin styles { 9@mixin styles {
10 @include materialize-at-root(meta.module-variables('vars')); 10 @include materialize-at-root(meta.module-variables('vars'));
11 11
12 @include bem.layout('form') { 12 @include bem.layout('form') {
13 display: flex; 13 display: flex;
14 flex-direction: column; 14 flex-direction: column;
15 gap: props.get(vars.$item-spacing-b) props.get(vars.$label-spacing-i); 15 gap: props.get(vars.$item-spacing-b) props.get(vars.$label-spacing-i);
16 16
17 @include bem.elem('item') { 17 @include bem.elem('item') {
18 display: block; 18 display: block;
19 } 19 }
20 20
21 @include bem.elem('item-content') { 21 @include bem.elem('item-content') {
22 @include bem.modifier('align-start') { 22 @include bem.modifier('align-start') {
23 align-self: start; 23 align-self: start;
24 } 24 }
25 } 25 }
26 26
27 @include bem.modifier('row') { 27 @include bem.modifier('row') {
28 flex-direction: row; 28 flex-direction: row;
29 align-items: flex-end; 29 align-items: flex-end;
30 } 30 }
31 31
32 @include bem.modifier('labels-start', 'labels-end') { 32 @include bem.modifier('labels-start', 'labels-end') {
33 display: grid; 33 display: grid;
34 grid-template-rows: auto; 34 grid-template-rows: auto;
35 grid-template-columns: auto 1fr; 35 grid-template-columns: auto 1fr;
36 align-items: baseline; 36 align-items: baseline;
37 37
38 @include bem.elem('item') { 38 @include bem.elem('item') {
39 display: contents; 39 display: contents;
40 } 40 }
41 41
42 @include bem.elem('item-label') { 42 @include bem.elem('item-label') {
43 grid-column: 1; 43 grid-column: 1;
44 padding-inline-end: 0; 44 padding-inline-end: 0;
45 } 45 }
46 46
47 @include bem.elem('item-content') { 47 @include bem.elem('item-content') {
48 grid-column: 2; 48 grid-column: 2;
49 margin-block-start: 0; 49 margin-block-start: 0;
50 } 50 }
51 } 51 }
52 52
53 @include bem.modifier('labels-end') { 53 @include bem.modifier('labels-end') {
54 @include bem.elem('item-label') { 54 @include bem.elem('item-label') {
55 text-align: end; 55 text-align: end;
56 } 56 }
57 } 57 }
58 } 58 }
59} 59}
diff --git a/src/layouts/_hlist.scss b/src/layouts/_hlist.scss
new file mode 100644
index 0000000..06eb8dd
--- /dev/null
+++ b/src/layouts/_hlist.scss
@@ -0,0 +1,74 @@
1@use 'sass:meta';
2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
5
6@forward 'hlist.vars';
7@use 'hlist.vars' as vars;
8@use '../objects/button.vars' as button;
9
10@mixin styles {
11 @include materialize-at-root(meta.module-variables('vars'));
12
13 @include bem.layout('hlist') {
14 display: inline-flex;
15 flex-wrap: wrap;
16 gap: props.get(vars.$gap);
17
18 @each $mod, $size in vars.$sizes {
19 @include bem.modifier($mod) {
20 gap: props.get($size);
21
22 @include bem.modifier('separated') {
23 @include bem.elem('item') {
24 @include bem.next-twin-elem {
25 &::before {
26 content: '·';
27 margin-inline: calc(.65 * props.get($size));
28 }
29 }
30 }
31 }
32 }
33 }
34
35 @include bem.modifier('separated') {
36 gap: 0;
37
38 @include bem.elem('item') {
39 @include bem.next-twin-elem {
40 &::before {
41 content: '·';
42 margin-inline: calc(.65 * props.get(vars.$gap));
43 }
44 }
45 }
46 }
47
48 @include bem.modifier('buttons') {
49 margin-inline: calc(-1 * props.get(button.$pad-i) - props.get(button.$border-width));
50
51 @include bem.modifier('pill') {
52 margin-inline: calc(-1 * props.get(button.$pad-i-pill) - props.get(button.$border-width));
53 }
54
55 @include bem.modifier('icon') {
56 margin-inline: calc(-1 * props.get(button.$pad-b) - props.get(button.$border-width) - .5em * (props.get(button.$line-height) - 1));
57 }
58
59 @each $mod, $pad-i, $pad-i-label, $pad-i-pill, $pad-b, $font-size in button.$fixed-sizes {
60 @include bem.modifier('buttons-#{$mod}') {
61 margin-inline: calc(-1 * props.get($pad-i) - props.get(button.$border-width));
62
63 @include bem.modifier('pill') {
64 margin-inline: calc(-1 * props.get($pad-i-pill) - props.get(button.$border-width));
65 }
66
67 @include bem.modifier('icon') {
68 margin-inline: calc(-1 * props.get($pad-b) - props.get(button.$border-width) - .5em * (props.get(button.$line-height) - 1));
69 }
70 }
71 }
72 }
73 }
74}
diff --git a/src/layouts/_hlist.vars.scss b/src/layouts/_hlist.vars.scss
new file mode 100644
index 0000000..fecded5
--- /dev/null
+++ b/src/layouts/_hlist.vars.scss
@@ -0,0 +1,16 @@
1@use 'iro-sass/src/props';
2@use '../core.vars' as core;
3
4$gap: props.def(--l-hlist--gap, props.get(core.$size--150)) !default;
5
6$gapless: props.def(--l-hlist--gapless, 0) !default;
7$sm: props.def(--l-hlist--sm, props.get(core.$size--100)) !default;
8$lg: props.def(--l-hlist--lg, props.get(core.$size--300)) !default;
9$xl: props.def(--l-hlist--xl, props.get(core.$size--450)) !default;
10
11$sizes: (
12 'gapless': $gapless,
13 'sm': $sm,
14 'lg': $lg,
15 'xl': $xl,
16) !default;
diff --git a/src/layouts/_media.scss b/src/layouts/_media.scss
index 2192db5..929e60f 100644
--- a/src/layouts/_media.scss
+++ b/src/layouts/_media.scss
@@ -7,35 +7,35 @@
7@use 'media.vars' as vars; 7@use 'media.vars' as vars;
8 8
9@mixin styles { 9@mixin styles {
10 @include materialize-at-root(meta.module-variables('vars')); 10 @include materialize-at-root(meta.module-variables('vars'));
11 11
12 @include bem.layout('media') { 12 @include bem.layout('media') {
13 display: flex; 13 display: flex;
14 gap: props.get(vars.$gap); 14 gap: props.get(vars.$gap);
15 align-items: center; 15 align-items: center;
16 line-height: 1.4; 16 line-height: 1.4;
17 17
18 @each $mod, $size in vars.$sizes { 18 @each $mod, $size in vars.$sizes {
19 @include bem.modifier($mod) { 19 @include bem.modifier($mod) {
20 gap: props.get($size); 20 gap: props.get($size);
21 } 21 }
22 } 22 }
23 23
24 @include bem.modifier('wrap') { 24 @include bem.modifier('wrap') {
25 flex-wrap: wrap; 25 flex-wrap: wrap;
26 } 26 }
27 27
28 @include bem.elem('block') { 28 @include bem.elem('block') {
29 flex: 0 0 auto; 29 flex: 0 0 auto;
30 30
31 @include bem.modifier('shrink', 'main') { 31 @include bem.modifier('shrink', 'main') {
32 flex-shrink: 1; 32 flex-shrink: 1;
33 min-inline-size: 0; 33 min-inline-size: 0;
34 } 34 }
35 35
36 @include bem.modifier('main') { 36 @include bem.modifier('main') {
37 inline-size: 100%; 37 inline-size: 100%;
38 } 38 }
39 } 39 }
40 } 40 }
41} 41}
diff --git a/src/layouts/_media.vars.scss b/src/layouts/_media.vars.scss
index fd6d986..dcb10de 100644
--- a/src/layouts/_media.vars.scss
+++ b/src/layouts/_media.vars.scss
@@ -9,8 +9,8 @@ $lg: props.def(--l-media--lg, props.get(core.$size--300)) !default;
9$xl: props.def(--l-media--xl, props.get(core.$size--450)) !default; 9$xl: props.def(--l-media--xl, props.get(core.$size--450)) !default;
10 10
11$sizes: ( 11$sizes: (
12 'gapless': $gapless, 12 'gapless': $gapless,
13 'sm': $sm, 13 'sm': $sm,
14 'lg': $lg, 14 'lg': $lg,
15 'xl': $xl, 15 'xl': $xl,
16) !default; 16) !default;
diff --git a/src/layouts/_overflow.scss b/src/layouts/_overflow.scss
index 9fba7eb..6d31d37 100644
--- a/src/layouts/_overflow.scss
+++ b/src/layouts/_overflow.scss
@@ -3,9 +3,9 @@
3@use '../core.vars' as core; 3@use '../core.vars' as core;
4 4
5@mixin styles { 5@mixin styles {
6 @include bem.layout('overflow') { 6 @include bem.layout('overflow') {
7 overflow: auto; 7 overflow: auto;
8 scrollbar-color: props.get(core.$theme, --text-disabled) transparent; 8 scrollbar-color: props.get(core.$theme, --text-disabled) transparent;
9 } 9 }
10} 10}
11 11
diff --git a/src/layouts/_split-view.scss b/src/layouts/_split-view.scss
index f522254..3cbd775 100644
--- a/src/layouts/_split-view.scss
+++ b/src/layouts/_split-view.scss
@@ -8,84 +8,102 @@
8@use 'split-view.vars' as vars; 8@use 'split-view.vars' as vars;
9 9
10@mixin styles { 10@mixin styles {
11 @include materialize-at-root(meta.module-variables('vars')); 11 @include materialize-at-root(meta.module-variables('vars'));
12 12
13 @include bem.layout('split-view') { 13 @include bem.layout('split-view') {
14 display: flex; 14 display: flex;
15 gap: props.get(vars.$col-gap); 15 gap: props.get(vars.$col-gap);
16 align-items: start; 16 align-items: start;
17 17
18 @include bem.elem('panel') { 18 @include bem.elem('panel') {
19 flex: 1 1 auto; 19 flex: 1 1 auto;
20 inline-size: 100%; 20 inline-size: 100%;
21 min-inline-size: 0; 21 min-inline-size: 0;
22 22
23 @include bem.modifier('side-25') { 23 &::before {
24 flex: 0 0 auto; 24 display: block;
25 inline-size: 25%; 25 margin-block: -100em 100em;
26 min-inline-size: props.get(vars.$panel--side-25--min); 26 content: '';
27 } 27 }
28 28
29 @include bem.modifier('sticky-0') { 29 @include bem.modifier('side-25') {
30 position: sticky; 30 flex: 0 0 auto;
31 inset-block-start: 0; 31 inline-size: 25%;
32 } 32 }
33 33
34 @include bem.modifier('sticky') { 34 @include bem.modifier('min-50') {
35 position: sticky; 35 min-inline-size: props.get(vars.$panel--min-50);
36 inset-block-start: props.get(vars.$panel--sticky-offset); 36 }
37 }
38 37
39 @include bem.modifier('sticky-400') { 38 @include bem.modifier('min-100') {
40 position: sticky; 39 min-inline-size: props.get(vars.$panel--min-100);
41 inset-block-start: calc(props.get(vars.$panel--sticky-400--inset) + props.get(vars.$panel--sticky-offset)); 40 }
42 }
43 41
44 @include bem.modifier('sticky-1200') { 42 @include bem.modifier('min-200') {
45 position: sticky; 43 min-inline-size: props.get(vars.$panel--min-200);
46 inset-block-start: calc(props.get(vars.$panel--sticky-1200--inset) + props.get(vars.$panel--sticky-offset)); 44 }
47 }
48 }
49 45
50 @include bem.modifier('gapless') { 46 @include bem.modifier('sticky') {
51 gap: props.get(vars.$gapless); 47 position: sticky;
48 inset-block-start: props.get(vars.$panel--sticky-offset);
49 }
52 50
53 @include bem.elem('panel') { 51 @include bem.modifier('sticky-400') {
54 @include bem.modifier('side-25') { 52 position: sticky;
55 min-inline-size: calc(props.get(vars.$panel--side-25--min) + props.get(vars.$col-gap) - props.get(vars.$gapless)); 53 inset-block-start: calc(props.get(vars.$panel--sticky-400--inset) + props.get(vars.$panel--sticky-offset));
56 } 54 }
57 } 55 }
58 }
59 56
60 @include bem.elem('content') { 57 @include bem.modifier('gapless') {
61 inline-size: 100%; 58 gap: props.get(vars.$gapless);
62 }
63 59
64 @include media.media('<=md') { 60 @include bem.elem('panel') {
65 flex-direction: column; 61 @include bem.modifier('min-50') {
66 gap: props.get(vars.$row-gap); 62 min-inline-size: calc(props.get(vars.$panel--min-50) + props.get(vars.$col-gap) - props.get(vars.$gapless));
67 align-items: stretch; 63 }
68 64
69 @include bem.modifier('gapless') { 65 @include bem.modifier('min-100') {
70 gap: props.get(vars.$gapless); 66 min-inline-size: calc(props.get(vars.$panel--min-100) + props.get(vars.$col-gap) - props.get(vars.$gapless));
71 } 67 }
72 68
73 @include bem.modifier('wrap-reverse') { 69 @include bem.modifier('min-200') {
74 flex-direction: column-reverse; 70 min-inline-size: calc(props.get(vars.$panel--min-200) + props.get(vars.$col-gap) - props.get(vars.$gapless));
75 } 71 }
72 }
73 }
76 74
77 @include bem.elem('panel') { 75 @include bem.elem('content') {
78 inline-size: auto; 76 inline-size: 100%;
79 77 }
80 @include bem.modifier('side-25') {
81 inline-size: auto;
82 min-inline-size: 0;
83 }
84 78
85 @include bem.modifier('sticky', 'sticky-400', 'sticky-1200') { 79 @include media.media('<=md') {
86 position: static; 80 flex-direction: column;
87 } 81 gap: props.get(vars.$row-gap);
88 } 82 align-items: stretch;
89 } 83
90 } 84 @include bem.modifier('gapless') {
85 gap: props.get(vars.$gapless);
86 }
87
88 @include bem.modifier('wrap-reverse') {
89 flex-direction: column-reverse;
90 }
91
92 @include bem.elem('panel') {
93 inline-size: auto;
94
95 @include bem.modifier('side-25') {
96 inline-size: auto;
97 }
98
99 @include bem.modifier('min-50', 'min-100', 'min-200') {
100 min-inline-size: 0;
101 }
102
103 @include bem.modifier('sticky', 'sticky-400') {
104 position: static;
105 }
106 }
107 }
108 }
91} 109}
diff --git a/src/layouts/_split-view.vars.scss b/src/layouts/_split-view.vars.scss
index d519939..c3583b9 100644
--- a/src/layouts/_split-view.vars.scss
+++ b/src/layouts/_split-view.vars.scss
@@ -6,7 +6,10 @@ $row-gap: props.def(--l-split-view--row-gap, props.get(core.$size--600)) !defau
6 6
7$gapless: props.def(--l-split-view--gapless, 0rem) !default; 7$gapless: props.def(--l-split-view--gapless, 0rem) !default;
8 8
9$panel--side-25--min: props.def(--l-split-view--panel--side-25--min, props.get(core.$size--3200)) !default; 9$panel--min-50: props.def(--l-split-view--panel--min-50, props.get(core.$size--2400)) !default;
10$panel--min-100: props.def(--l-split-view--panel--min-100, props.get(core.$size--3200)) !default;
11$panel--min-200: props.def(--l-split-view--panel--min-200, props.get(core.$size--4200)) !default;
12
10$panel--sticky-400--inset: props.def(--l-split-view--panel--sticky-400--inset, props.get(core.$size--400)) !default; 13$panel--sticky-400--inset: props.def(--l-split-view--panel--sticky-400--inset, props.get(core.$size--400)) !default;
11$panel--sticky-1200--inset: props.def(--l-split-view--panel--sticky-1200--inset, props.get(core.$size--1200)) !default; 14$panel--sticky-1200--inset: props.def(--l-split-view--panel--sticky-1200--inset, props.get(core.$size--1200)) !default;
12 15