summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/.old/layouts/_message-group.scss139
-rw-r--r--src/.old/objects/_dialog.scss152
-rw-r--r--src/.old/objects/_icon-nav.scss20
-rw-r--r--src/.old/objects/_list-group.scss61
-rw-r--r--src/.old/objects/_message.scss51
-rw-r--r--src/.old/objects/_overflow-button.scss243
-rw-r--r--src/_apca.scss127
-rw-r--r--src/_apply-vars.scss17
-rw-r--r--src/_base.scss145
-rw-r--r--src/_config.defaults.scss197
-rw-r--r--src/_config.scss237
-rw-r--r--src/_core.scss45
-rw-r--r--src/_core.vars.scss183
-rw-r--r--src/_declare-vars.scss274
-rw-r--r--src/_functions.scss174
-rw-r--r--src/_iro-design.scss76
-rw-r--r--src/_layers.scss3
-rw-r--r--src/_layouts.scss8
-rw-r--r--src/_mixins.scss42
-rw-r--r--src/_objects.scss28
-rw-r--r--src/_props.scss48
-rw-r--r--src/_scopes.scss6
-rw-r--r--src/_themes.scss86
-rw-r--r--src/_utils.scss501
-rw-r--r--src/functions/colors/_apca.scss127
-rw-r--r--src/functions/colors/_index.scss2
-rw-r--r--src/functions/colors/_oklch.scss88
-rw-r--r--src/index.scss10
-rw-r--r--src/layouts/_button-group.scss60
-rw-r--r--src/layouts/_button-group.vars.scss16
-rw-r--r--src/layouts/_card-list.scss222
-rw-r--r--src/layouts/_card-list.vars.scss41
-rw-r--r--src/layouts/_container.scss61
-rw-r--r--src/layouts/_container.vars.scss22
-rw-r--r--src/layouts/_flex.scss36
-rw-r--r--src/layouts/_form.scss107
-rw-r--r--src/layouts/_form.vars.scss5
-rw-r--r--src/layouts/_media.scss70
-rw-r--r--src/layouts/_media.vars.scss16
-rw-r--r--src/layouts/_overflow.scss16
-rw-r--r--src/layouts/_split-view.scss91
-rw-r--r--src/layouts/_split-view.vars.scss13
-rw-r--r--src/objects/_action-button.scss343
-rw-r--r--src/objects/_alert.scss73
-rw-r--r--src/objects/_alert.vars.scss36
-rw-r--r--src/objects/_avatar.scss251
-rw-r--r--src/objects/_avatar.vars.scss58
-rw-r--r--src/objects/_backdrop.scss43
-rw-r--r--src/objects/_backdrop.vars.scss6
-rw-r--r--src/objects/_badge.scss300
-rw-r--r--src/objects/_button.scss530
-rw-r--r--src/objects/_button.vars.scss374
-rw-r--r--src/objects/_card.scss388
-rw-r--r--src/objects/_card.vars.scss39
-rw-r--r--src/objects/_checkbox.scss428
-rw-r--r--src/objects/_checkbox.vars.scss32
-rw-r--r--src/objects/_divider.scss355
-rw-r--r--src/objects/_divider.vars.scss79
-rw-r--r--src/objects/_emoji.scss105
-rw-r--r--src/objects/_emoji.vars.scss26
-rw-r--r--src/objects/_field-label.scss134
-rw-r--r--src/objects/_field-label.vars.scss12
-rw-r--r--src/objects/_figure.scss26
-rw-r--r--src/objects/_figure.vars.scss9
-rw-r--r--src/objects/_heading.scss162
-rw-r--r--src/objects/_heading.vars.scss123
-rw-r--r--src/objects/_icon.scss43
-rw-r--r--src/objects/_icon.vars.scss5
-rw-r--r--src/objects/_lightbox.scss404
-rw-r--r--src/objects/_lightbox.vars.scss33
-rw-r--r--src/objects/_menu.scss205
-rw-r--r--src/objects/_menu.vars.scss29
-rw-r--r--src/objects/_navbar.scss191
-rw-r--r--src/objects/_navbar.vars.scss84
-rw-r--r--src/objects/_palette.scss95
-rw-r--r--src/objects/_placeholders.scss22
-rw-r--r--src/objects/_placeholders.vars.scss6
-rw-r--r--src/objects/_popover.scss84
-rw-r--r--src/objects/_popover.vars.scss19
-rw-r--r--src/objects/_radio.scss295
-rw-r--r--src/objects/_radio.vars.scss33
-rw-r--r--src/objects/_side-nav.scss182
-rw-r--r--src/objects/_side-nav.vars.scss28
-rw-r--r--src/objects/_status-indicator.scss56
-rw-r--r--src/objects/_status-indicator.vars.scss26
-rw-r--r--src/objects/_switch.scss352
-rw-r--r--src/objects/_switch.vars.scss37
-rw-r--r--src/objects/_tabbar.scss113
-rw-r--r--src/objects/_tabbar.vars.scss25
-rw-r--r--src/objects/_table.scss267
-rw-r--r--src/objects/_table.vars.scss25
-rw-r--r--src/objects/_text-field.scss338
-rw-r--r--src/objects/_text-field.vars.scss39
-rw-r--r--src/objects/_thumbnail.scss104
-rw-r--r--src/objects/_thumbnail.vars.scss51
-rw-r--r--src/scopes/_blockquotes.scss50
-rw-r--r--src/scopes/_blockquotes.vars.scss11
-rw-r--r--src/scopes/_body.scss59
-rw-r--r--src/scopes/_body.vars.scss12
-rw-r--r--src/scopes/_code.scss89
-rw-r--r--src/scopes/_code.vars.scss18
-rw-r--r--src/scopes/_figures.scss21
-rw-r--r--src/scopes/_headings.scss171
-rw-r--r--src/scopes/_implicit.scss180
-rw-r--r--src/scopes/_implicit.vars.scss26
-rw-r--r--src/scopes/_links.scss230
-rw-r--r--src/scopes/_links.vars.scss49
-rw-r--r--src/scopes/_lists.scss102
-rw-r--r--src/scopes/_lists.vars.scss8
-rw-r--r--src/scopes/_tables.scss185
-rw-r--r--src/scopes/_tables.vars.scss4
111 files changed, 6293 insertions, 5911 deletions
diff --git a/src/.old/layouts/_message-group.scss b/src/.old/layouts/_message-group.scss
deleted file mode 100644
index 235e242..0000000
--- a/src/.old/layouts/_message-group.scss
+++ /dev/null
@@ -1,139 +0,0 @@
1@use 'iro-sass/src/index' as iro;
2@use '../functions' as fn;
3
4// @use '../objects/message';
5
6@include iro.props-namespace('message-group') {
7 @include iro.props-store((
8 --dims: (
9 --spacing-x: fn.global-dim(--size --225),
10 --spacing-y: fn.global-dim(--size --150),
11 --arrow-size: fn.global-dim(--size --100),
12
13 --compact: (
14 --spacing-x: fn.global-dim(--size --225),
15 --spacing-y: fn.global-dim(--size --50),
16 )
17 )
18 ));
19
20 @include iro.bem-layout(iro.props-namespace()) {
21 display: grid;
22 grid-template-columns: auto 1fr;
23 grid-auto-rows: auto;
24 grid-template-areas: 'avatar message' 'avatar .';
25 align-items: flex-start;
26 gap: 0 fn.dim(--spacing-x);
27
28 @include iro.bem-elem('avatar') {
29 grid-area: avatar;
30 block-size: 0;
31 }
32
33 @include iro.bem-elem('message') {
34 grid-column: message;
35 position: relative;
36 box-sizing: border-box;
37 min-inline-size: 0;
38 max-inline-size: 100%;
39
40 &::before {
41 content: '';
42 display: none;
43 position: absolute;
44 top: 0;
45 left: calc(-1 * fn.dim(--arrow-size));
46 border: fn.dim(--arrow-size) solid fn.global-color(--bg-l2);
47 border-bottom-color: transparent;
48 border-left-color: transparent;
49 }
50
51 @include iro.bem-next-twin-elem {
52 margin-top: fn.dim(--spacing-y);
53 }
54 }
55
56 @include iro.bem-modifier('right') {
57 @include iro.bem-elem('message') {
58 &::before {
59 right: calc(-1 * fn.dim(--arrow-size));
60 left: auto;
61 border-right-color: transparent;
62 border-left-color: fn.global-color(--bg-l2);
63 }
64 }
65 }
66
67 @include iro.bem-modifier('compact') {
68 gap: 0 fn.dim(--compact --spacing-x);
69
70 @include iro.bem-modifier('left') {
71 justify-items: start;
72 }
73
74 @include iro.bem-modifier('right') {
75 justify-items: end;
76 }
77
78 @include iro.bem-elem('message') {
79 @include iro.bem-next-twin-elem {
80 margin-top: fn.dim(--compact --spacing-y);
81 }
82 }
83 }
84
85 @include iro.bem-modifier('right') {
86 grid-template-columns: 1fr auto;
87 grid-template-areas: 'message avatar' '. avatar';
88 }
89
90 @include iro.bem-modifier('no-avatar') {
91 grid-template-columns: 1fr;
92 grid-template-areas: 'message';
93
94 @include iro.bem-elem('avatar') {
95 display: none;
96 }
97 }
98
99 @include iro.bem-modifier('arrow') {
100 @include iro.bem-elem('message') {
101 &::before {
102 display: block;
103 }
104
105 @include iro.bem-next-twin-elem {
106 &::before {
107 display: none;
108 }
109 }
110 }
111 }
112
113 & + & {
114 @include iro.bem-modifier('merge') {
115 margin-top: fn.dim(--spacing-y);
116
117 @include iro.bem-elem('avatar') {
118 visibility: hidden;
119 }
120
121 @include iro.bem-modifier('compact') {
122 margin-top: fn.dim(--compact --spacing-y);
123 }
124
125 @include iro.bem-elem('merge-hide') {
126 display: none;
127 }
128
129 @include iro.bem-modifier('arrow') {
130 @include iro.bem-elem('message') {
131 &::before {
132 display: none;
133 }
134 }
135 }
136 }
137 }
138 }
139}
diff --git a/src/.old/objects/_dialog.scss b/src/.old/objects/_dialog.scss
deleted file mode 100644
index 9333ce6..0000000
--- a/src/.old/objects/_dialog.scss
+++ /dev/null
@@ -1,152 +0,0 @@
1@use 'iro-sass/src/index' as iro;
2@use '../functions' as fn;
3
4@include iro.props-namespace('dialog') {
5 @include iro.props-store((
6 --dims: (
7 --width-sm: iro.fn-px-to-rem(500px),
8 --width-md: iro.fn-px-to-rem(800px),
9 --width-lg: iro.fn-px-to-rem(1100px),
10 --rounding: 4px,
11 --border: 1px,
12
13 --header: (
14 --pad-x: fn.global-dim(--size --75),
15 --pad-y: fn.global-dim(--size --75),
16 ),
17
18 --sidebar: (
19 --pad-x: fn.global-dim(--size --75),
20 --pad-y: fn.global-dim(--size --75),
21 ),
22
23 --body: (
24 --pad-x: fn.global-dim(--size --200),
25 --pad-y: fn.global-dim(--size --200),
26 )
27 ),
28 ), 'dims');
29
30 @include iro.props-store((
31 --dims: (
32 --pad-x: fn.global-dim(--size --300),
33 --pad-y: fn.global-dim(--size --300),
34 ),
35 ), 'md');
36
37 @include iro.props-store((
38 --colors: (
39 --border: fn.global-color(--border --stable),
40 ),
41 ), 'colors');
42
43 @include iro.bem-object(iro.props-namespace()) {
44 display: grid;
45 grid-template-rows: auto auto 1fr auto auto;
46 grid-template-columns: auto 1fr;
47 grid-template-areas:
48 'sidebar-header header'
49 'sidebar top'
50 'sidebar body'
51 'sidebar bottom'
52 'sidebar footer';
53 position: relative;
54 box-sizing: border-box;
55 flex: 0 0 auto;
56 width: 100%;
57 max-width: fn.dim(--width-md);
58 margin: 0 auto;
59 overflow: hidden;
60 border-radius: fn.dim(--rounding);
61 background-clip: padding-box;
62 background-color: fn.global-color(--bg);
63 color: fn.global-color(--fg);
64
65 @include iro.bem-modifier('sm') {
66 max-width: fn.dim(--width-sm);
67 }
68
69 @include iro.bem-modifier('lg') {
70 max-width: fn.dim(--width-lg);
71 }
72
73 @include iro.bem-elem('header') {
74 grid-area: sidebar-header / sidebar-header / header / header;
75 padding: fn.dim(--header --pad-y) fn.dim(--header --pad-x);
76
77 @include iro.bem-modifier('sidebar') {
78 grid-area: sidebar-header;
79 border-right: 1px solid fn.color(--border);
80
81 @include iro.bem-sibling-elem('header') {
82 grid-area: header;
83 }
84 }
85 }
86
87 @include iro.bem-elem('title') {
88 margin-top: 0;
89 padding-right: calc(fn.dim(--body --pad-x) - fn.dim(--header --pad-x));
90 padding-left: calc(fn.dim(--body --pad-x) - fn.dim(--header --pad-x));
91 }
92
93 @include iro.bem-elem('close-btn') {
94 margin-left: auto;
95 }
96
97 @include iro.bem-elem('sidebar') {
98 grid-area: sidebar;
99 padding: fn.dim(--sidebar --pad-y) fn.dim(--sidebar --pad-x);
100 overflow: auto;
101 border-right: 1px solid fn.color(--border);
102 }
103
104 @include iro.bem-elem('top') {
105 grid-area: top;
106 min-width: 0;
107 padding: fn.dim(--body --pad-y) fn.dim(--body --pad-x);
108
109 @include iro.bem-sibling-elem('body') {
110 padding-top: 0;
111 }
112 }
113
114 @include iro.bem-elem('bottom') {
115 grid-area: bottom;
116 min-width: 0;
117 padding: fn.dim(--body --pad-y) fn.dim(--body --pad-x);
118
119 @include iro.bem-sibling-elem('body') {
120 padding-bottom: 0;
121 }
122 }
123
124 @include iro.bem-elem('body') {
125 grid-area: body;
126 min-width: 0;
127 min-height: 0;
128 padding: fn.dim(--body --pad-y) fn.dim(--body --pad-x);
129 }
130
131 @include iro.bem-elem('footer') {
132 grid-area: footer;
133 justify-content: flex-end;
134 padding: fn.dim(--body --pad-y) fn.dim(--body --pad-x);
135 }
136
137 @include iro.bem-modifier('scrollable') {
138 flex-shrink: 1;
139
140 @include iro.bem-elem('body') {
141 overflow: auto;
142 scrollbar-color: fn.global-color(--obj-lo) transparent;
143 }
144 }
145
146 @include iro.bem-modifier('flat') {
147 @include iro.bem-elem('body') {
148 padding-top: 0;
149 }
150 }
151 }
152}
diff --git a/src/.old/objects/_icon-nav.scss b/src/.old/objects/_icon-nav.scss
deleted file mode 100644
index d1c6539..0000000
--- a/src/.old/objects/_icon-nav.scss
+++ /dev/null
@@ -1,20 +0,0 @@
1@use 'iro-sass/src/index' as iro;
2@use '../functions' as fn;
3
4@include iro.props-namespace('icon-nav') {
5 @include iro.props-store((
6 --dims: (
7 --spacing: fn.global-dim(--size --100),
8 )
9 ), 'dims');
10
11 @include iro.bem-object(iro.props-namespace()) {
12 display: flex;
13 align-items: center;
14 gap: fn.dim(--spacing);
15
16 @include iro.bem-modifier('vertical') {
17 flex-direction: column;
18 }
19 }
20}
diff --git a/src/.old/objects/_list-group.scss b/src/.old/objects/_list-group.scss
deleted file mode 100644
index a346828..0000000
--- a/src/.old/objects/_list-group.scss
+++ /dev/null
@@ -1,61 +0,0 @@
1@use 'iro-sass/src/index' as iro;
2@use '../functions' as fn;
3
4@include iro.props-namespace('list-group') {
5 @include iro.props-store((
6 --dims: (
7 --pad-i: fn.global-dim(--size --175),
8 --pad-b: fn.global-dim(--size --125),
9 --rounding: fn.global-dim(--rounding),
10 --border: fn.global-dim(--border --thin),
11 ),
12 --colors: (
13 --bg: fn.global-color(--base --75),
14 --border: fn.global-color(--border),
15 --hover: fn.global-color(--border-mute),
16 --active: fn.global-color(--border),
17 )
18 ));
19
20 @include iro.bem-object(iro.props-namespace()) {
21 border: fn.dim(--border) solid fn.color(--border);
22 border-radius: fn.dim(--rounding);
23 background-color: fn.color(--bg);
24
25 @include iro.bem-elem('item') {
26 padding-block: fn.dim(--pad-b);
27 padding-inline: fn.dim(--pad-i);
28
29 @include iro.bem-next-twin-elem {
30 border-width: 0;
31 border-block-start-width: fn.dim(--border);
32 border-style: solid;
33 border-color: fn.color(--border);
34 }
35
36 @include iro.bem-multi('&:link, &:visited, &:enabled', 'modifier' 'interactive') {
37 &:hover,
38 &:focus-visible {
39 background-color: fn.color(--hover);
40 }
41
42 &:active {
43 background-color: fn.color(--active);
44 }
45 }
46 }
47
48 @include iro.bem-modifier('horizontal') {
49 display: flex;
50
51 @include iro.bem-elem('item') {
52 flex: 1 0 auto;
53
54 @include iro.bem-next-twin-elem {
55 border-block-start-width: 0;
56 border-inline-start-width: fn.dim(--border);
57 }
58 }
59 }
60 }
61}
diff --git a/src/.old/objects/_message.scss b/src/.old/objects/_message.scss
deleted file mode 100644
index 283ce26..0000000
--- a/src/.old/objects/_message.scss
+++ /dev/null
@@ -1,51 +0,0 @@
1@use 'iro-sass/src/index' as iro;
2@use '../functions' as fn;
3
4@include iro.props-namespace('message') {
5 @include iro.props-store((
6 --dims: (
7 --bubble: (
8 --pad-x: fn.global-dim(--size --200),
9 --pad-y: fn.global-dim(--size --150),
10 --rounding: 0,
11
12 --75: (
13 --pad-x: fn.global-dim(--size --150),
14 --pad-y: fn.global-dim(--size --85),
15 ),
16 ),
17 )
18 ), 'dims');
19
20 @include iro.props-store((
21 --colors: (
22 --highlight: fn.global-color(--fg-lo),
23 ),
24 ), 'colors');
25
26 @include iro.bem-object(iro.props-namespace()) {
27 @include iro.bem-elem('suffix') {
28 margin-left: 1em;
29 float: right;
30 }
31
32 @include iro.bem-modifier('bubble') {
33 padding: fn.dim(--bubble --pad-y) fn.dim(--bubble --pad-x);
34 border-radius: fn.dim(--bubble --rounding);
35 background-color: fn.global-color(--bg);
36 color: fn.global-color(--fg);
37
38 @include iro.bem-elem('suffix') {
39 transform: translate(.2em, .2em);
40 }
41
42 @include iro.bem-modifier('highlight') {
43 box-shadow: -3px 0 0 0 fn.color(--highlight);
44 }
45
46 @include iro.bem-modifier('75') {
47 padding: fn.dim(--bubble --75 --pad-y) fn.dim(--bubble --75 --pad-x);
48 }
49 }
50 }
51}
diff --git a/src/.old/objects/_overflow-button.scss b/src/.old/objects/_overflow-button.scss
deleted file mode 100644
index b15ea1f..0000000
--- a/src/.old/objects/_overflow-button.scss
+++ /dev/null
@@ -1,243 +0,0 @@
1@use 'iro-sass/src/index' as iro;
2@use '../functions' as fn;
3
4@include iro.props-namespace('overflow-button') {
5 @include iro.props-store((
6 --dims: (
7 --pad-x: calc(fn.global-dim(--size --125) - 1px),
8 --pad-y: calc(fn.global-dim(--size --125) - 1px),
9 --spacing: fn.global-dim(--size --50)
10 ),
11 ), 'dims');
12
13 @include iro.props-store((
14 --colors: (
15 --label: fn.global-color(--fg),
16
17 --hover: (
18 --bg: fn.global-color(--obj-hi),
19 --label: fn.global-color(--fg-lo),
20 ),
21 --active: (
22 --bg: fn.global-color(--obj),
23 --label: fn.global-color(--fg-lo),
24 ),
25 --selected: (
26 --bg: fn.global-color(--obj-hi),
27 --label: fn.global-color(--fg),
28
29 --hover: (
30 --bg: fn.global-color(--obj),
31 --label: fn.global-color(--fg-lo),
32 ),
33 ),
34 --disabled: (
35 --label: fn.global-color(--fg-hi3),
36 ),
37 --key-focus: (
38 --border: fn.global-color(--focus --fill),
39 --shadow: fn.global-color(--focus --shadow),
40 ),
41
42 --red: (
43 --hover: (
44 --bg: fn.global-color(--red --quiet --bg),
45 --label: fn.global-color(--red --quiet --fg),
46 ),
47 --active: (
48 --bg: fn.global-color(--red --quiet --obj),
49 --label: fn.global-color(--red --quiet --fg-lo),
50 ),
51
52 --selected: (
53 --bg: fn.global-color(--red --quiet --bg),
54 --label: fn.global-color(--red --quiet --fg),
55
56 --hover: (
57 --bg: fn.global-color(--red --quiet --obj),
58 --label: fn.global-color(--red --quiet --fg-lo),
59 ),
60 ),
61 ),
62
63 --blue: (
64 --hover: (
65 --bg: fn.global-color(--blue --quiet --bg),
66 --label: fn.global-color(--blue --quiet --fg),
67 ),
68 --active: (
69 --bg: fn.global-color(--blue --quiet --obj),
70 --label: fn.global-color(--blue --quiet --fg-lo),
71 ),
72
73 --selected: (
74 --bg: fn.global-color(--blue --quiet --bg),
75 --label: fn.global-color(--blue --quiet --fg),
76
77 --hover: (
78 --bg: fn.global-color(--blue --quiet --obj),
79 --label: fn.global-color(--blue --quiet --fg-lo),
80 ),
81 ),
82 ),
83
84 --green: (
85 --hover: (
86 --bg: fn.global-color(--green --quiet --bg),
87 --label: fn.global-color(--green --quiet --fg),
88 ),
89 --active: (
90 --bg: fn.global-color(--green --quiet --obj),
91 --label: fn.global-color(--green --quiet --fg-lo),
92 ),
93
94 --selected: (
95 --bg: fn.global-color(--green --quiet --bg),
96 --label: fn.global-color(--green --quiet --fg),
97
98 --hover: (
99 --bg: fn.global-color(--green --quiet --obj),
100 --label: fn.global-color(--green --quiet --fg-lo),
101 ),
102 ),
103 )
104 ),
105 ), 'colors');
106
107 @include iro.bem-object(iro.props-namespace()) {
108 display: inline-block;
109 color: fn.color(--disabled --label);
110
111 @include iro.bem-elem('outside') {
112 display: inline-block;
113 margin-right: fn.dim(--spacing);
114 }
115
116 @include iro.bem-elem('inside') {
117 display: inline-block;
118 padding: fn.dim(--pad-y) fn.dim(--pad-x);
119 border: 2px solid transparent;
120 border-radius: 100em;
121 line-height: 1;
122 text-align: center;
123 text-decoration: none;
124 text-overflow: ellipsis;
125 white-space: nowrap;
126
127 @include iro.bem-next-elem('outside') {
128 margin-right: 0;
129 margin-left: fn.dim(--spacing);
130 }
131 }
132
133 &:link,
134 &:visited,
135 &:enabled {
136 color: fn.color(--label);
137
138 &:hover {
139 @include iro.bem-elem('inside') {
140 background-color: fn.color(--hover --bg);
141 color: fn.color(--hover --label);
142 }
143 }
144
145 &:active {
146 @include iro.bem-elem('inside') {
147 background-color: fn.color(--active --bg);
148 color: fn.color(--active --label);
149 }
150 }
151
152 @include iro.bem-at-theme('keyboard') {
153 &:focus {
154 @include iro.bem-elem('inside') {
155 background-color: fn.color(--hover --bg);
156 color: fn.color(--hover --label);
157 }
158 }
159 }
160 }
161
162 @include iro.bem-is('selected') {
163 @include iro.bem-elem('inside') {
164 background-color: fn.color(--selected --bg);
165 }
166
167 &:link,
168 &:visited,
169 &:enabled {
170 @include iro.bem-elem('inside') {
171 color: fn.color(--selected --label);
172 }
173
174 &:hover,
175 &:active {
176 @include iro.bem-elem('inside') {
177 background-color: fn.color(--selected --hover --bg);
178 color: fn.color(--selected --hover --label);
179 }
180 }
181
182 @include iro.bem-at-theme('keyboard') {
183 &:focus {
184 @include iro.bem-elem('inside') {
185 background-color: fn.color(--selected --bg);
186 color: fn.color(--selected --hover --label);
187 }
188 }
189 }
190 }
191 }
192
193 @each $color in 'red' 'blue' 'green' {
194 @include iro.bem-modifier($color) {
195 &:link,
196 &:visited,
197 &:enabled {
198 &:hover {
199 @include iro.bem-elem('inside') {
200 background-color: fn.color(--#{$color} --hover --bg);
201 color: fn.color(--#{$color} --hover --label);
202 }
203 }
204
205 &:active {
206 @include iro.bem-elem('inside') {
207 background-color: fn.color(--#{$color} --active --bg);
208 color: fn.color(--#{$color} --active --label);
209 }
210 }
211 }
212
213 @include iro.bem-is('selected') {
214 &:link,
215 &:visited,
216 &:enabled {
217 @include iro.bem-elem('inside') {
218 background-color: fn.color(--#{$color} --selected --bg);
219 color: fn.color(--#{$color} --selected --label);
220 }
221
222 &:hover,
223 &:active {
224 @include iro.bem-elem('inside') {
225 background-color: fn.color(--#{$color} --selected --hover --bg);
226 color: fn.color(--#{$color} --selected --hover --label);
227 }
228 }
229 }
230 }
231 }
232 }
233
234 @include iro.bem-at-theme('keyboard') {
235 &:focus {
236 @include iro.bem-elem('inside') {
237 border-color: fn.color(--key-focus --border);
238 box-shadow: fn.color(--key-focus --shadow);
239 }
240 }
241 }
242 }
243}
diff --git a/src/_apca.scss b/src/_apca.scss
new file mode 100644
index 0000000..c5da4a0
--- /dev/null
+++ b/src/_apca.scss
@@ -0,0 +1,127 @@
1// stylelint-disable scss/dollar-variable-pattern
2// stylelint-disable scss/at-function-pattern
3
4@use 'sass:color';
5@use 'sass:list';
6@use 'sass:map';
7@use 'sass:math';
8
9$SA98G: (
10 mainTRC: 2.4,
11
12 sRco: .2126729,
13 sGco: .7151522,
14 sBco: .072175,
15
16 normBG: .56,
17 normTXT: .57,
18 revTXT: .62,
19 revBG: .65,
20
21 blkThrs: .022,
22 blkClmp: 1.414,
23 scaleBoW: 1.14,
24 scaleWoB: 1.14,
25 loBoWoffset: .027,
26 loWoBoffset: .027,
27 deltaYmin: .0005,
28 loClip: .0001,
29
30 mFactor: 1.9468554433171,
31 mOffsetIn: .0387393816571401,
32 mExpAdj: .283343396420869,
33 mOffsetOut: .312865795870758,
34);
35
36@function sRGB_to_Y($color) {
37 $rgb: color.to-space($color, rgb);
38
39 @return map.get($SA98G, sRco) * math.pow(math.div(color.channel($rgb, 'red'), 255), map.get($SA98G, mainTRC)) +
40 map.get($SA98G, sGco) * math.pow(math.div(color.channel($rgb, 'green'), 255), map.get($SA98G, mainTRC)) +
41 map.get($SA98G, sBco) * math.pow(math.div(color.channel($rgb, 'blue'), 255), map.get($SA98G, mainTRC));
42}
43
44@function Y_to_sRGB($y) {
45 $c: math.round(math.pow($y, math.div(1, map.get($SA98G, mainTRC))) * 255);
46 @return rgb($c, $c, $c);
47}
48
49@function contrast($txtY, $bgY) {
50 /* stylelint-disable-next-line @stylistic/number-no-trailing-zeros */
51 $icp: .0 1.1;
52
53 @if math.min($txtY, $bgY) < list.nth($icp, 1) or math.max($txtY, $bgY) > list.nth($icp, 2) {
54 @return 0;
55 }
56
57 @if $txtY <= map.get($SA98G, blkThrs) {
58 $txtY: $txtY + math.pow(map.get($SA98G, blkThrs) - $txtY, map.get($SA98G, blkClmp));
59 }
60 @if $bgY <= map.get($SA98G, blkThrs) {
61 $bgY: $bgY + math.pow(map.get($SA98G, blkThrs) - $bgY, map.get($SA98G, blkClmp));
62 }
63
64 @if math.abs($bgY - $txtY) < map.get($SA98G, deltaYmin) {
65 @return 0;
66 }
67
68 $outputContrast: 0;
69
70 @if $bgY > $txtY {
71 $SAPC: map.get($SA98G, scaleBoW) * (math.pow($bgY, map.get($SA98G, normBG)) - math.pow($txtY, map.get($SA98G, normTXT)));
72
73 @if $SAPC >= map.get($SA98G, loClip) {
74 $outputContrast: $SAPC - map.get($SA98G, loBoWoffset);
75 }
76 } @else {
77 $SAPC: map.get($SA98G, scaleWoB) * (math.pow($bgY, map.get($SA98G, revBG)) - math.pow($txtY, map.get($SA98G, revTXT)));
78
79 @if $SAPC <= -1 * map.get($SA98G, loClip) {
80 $outputContrast: $SAPC + map.get($SA98G, loWoBoffset);
81 }
82 }
83
84 @return $outputContrast * 100;
85}
86
87@function reverse($contrast, $knownY, $knownType: 'bg') {
88 $unknownY: $knownY;
89
90 $knownExp: 0;
91 $unknownExp: 0;
92
93 $scale: map.get($SA98G, if($contrast > 0, scaleBoW, scaleWoB));
94 $offset: map.get($SA98G, if($contrast > 0, loBoWoffset, loWoBoffset));
95
96 $contrast: math.div($contrast * .01 + $offset, $scale);
97
98 @if $knownY <= map.get($SA98G, blkThrs) {
99 $knownY: $knownY + math.pow(map.get($SA98G, blkThrs) - $knownY, map.get($SA98G, blkClmp));
100 }
101
102 @if $knownType == 'bg' {
103 $knownExp: map.get($SA98G, if($contrast > 0, normBG, revBG));
104 $unknownExp: map.get($SA98G, if($contrast > 0, normTXT, revTXT));
105 $unknownY: math.pow(math.pow($knownY, $knownExp) - $contrast, math.div(1, $unknownExp));
106 } @else {
107 $knownExp: map.get($SA98G, if($contrast > 0, normTXT, revTXT));
108 $unknownExp: map.get($SA98G, if($contrast > 0, normBG, revBG));
109 $unknownY: math.pow($contrast + math.pow($knownY, $knownExp), math.div(1, $unknownExp));
110 }
111
112 @if '#{$unknownY}' == '#{math.sqrt(-1)}' {
113 @return false;
114 }
115
116 @if $unknownY > 1.06 or $unknownY < 0 {
117 @return false;
118 }
119
120 @if $unknownY <= map.get($SA98G, blkThrs) {
121 $unknownY: math.pow(($unknownY + map.get($SA98G, mOffsetIn)) * map.get($SA98G, mFactor), math.div(map.get($SA98G, mExpAdj), map.get($SA98G, blkClmp))) * math.div(1, map.get($SA98G, mFactor)) - map.get($SA98G, mOffsetOut);
122 }
123
124 $unknownY: math.max(math.min($unknownY, 1), 0);
125
126 @return $unknownY;
127}
diff --git a/src/_apply-vars.scss b/src/_apply-vars.scss
deleted file mode 100644
index a2ee404..0000000
--- a/src/_apply-vars.scss
+++ /dev/null
@@ -1,17 +0,0 @@
1@use 'sass:map';
2@use 'iro-sass/src/index' as iro;
3@use 'include-media/dist/include-media' as media;
4
5:root {
6 @include iro.props-assign;
7
8 @each $breakpoint in map.keys(media.$breakpoints) {
9 @include media.media('<=#{$breakpoint}') {
10 @include iro.props-assign($breakpoint);
11 }
12 }
13
14 @media (prefers-color-scheme: dark) {
15 @include iro.props-assign('dark');
16 }
17}
diff --git a/src/_base.scss b/src/_base.scss
deleted file mode 100644
index 8e4c1d9..0000000
--- a/src/_base.scss
+++ /dev/null
@@ -1,145 +0,0 @@
1@use 'sass:math';
2@use 'iro-sass/src/index' as iro;
3@use 'functions' as fn;
4@use 'mixins' as mx;
5@use 'config';
6
7html {
8 scrollbar-color: fn.color(--text-disabled) transparent;
9 accent-color: fn.color(--accent --600);
10}
11
12html,
13body {
14 block-size: 100%;
15}
16
17body {
18 @include mx.set-font(--standard, (--size: fn.dim(--font-size --100)));
19
20 margin: 0;
21 padding: 0;
22 background-color: fn.color(--bg-base);
23 color: fn.color(--text);
24}
25
26pre,
27code {
28 font-feature-settings: 'calt' 0, 'dlig' 1, 'ss09' 1;
29}
30
31pre,
32code {
33 @include mx.set-font(--mono, (--size: .93em));
34}
35
36pre {
37 margin: 0;
38 overflow-x: auto;
39
40 code {
41 color: currentColor;
42 font-size: 1em;
43 }
44}
45
46h1,
47h2,
48h3,
49h4,
50h5,
51h6 {
52 @include mx.heading-medium(--md);
53
54 margin-block: fn.dim(--heading --margin-bs) 0;
55
56 & + & {
57 margin-block-start: fn.dim(--heading --margin-bs-sibling);
58 }
59}
60
61p {
62 margin-block: fn.dim(--paragraph --margin-bs) 0;
63
64 &:empty {
65 display: none;
66 }
67}
68
69strong {
70 font-weight: bold;
71}
72
73small {
74 font-size: fn.dim(--font-size --75);
75}
76
77ul,
78ol {
79 margin: 0;
80 padding: 0;
81 list-style: none;
82}
83
84li {
85 margin: 0;
86 padding: 0;
87}
88
89:focus,
90:focus-visible {
91 outline: 0;
92}
93
94:link,
95:visited {
96 color: currentColor;
97 text-decoration: none;
98}
99
100
101button,
102input,
103textarea {
104 box-sizing: content-box;
105 margin: 0;
106 padding: 0;
107 border: 0;
108 background: none;
109 color: currentColor;
110 font-family: inherit;
111 font-size: 1em;
112 font-style: inherit;
113 font-weight: inherit;
114 line-height: inherit;
115 text-align: inherit;
116 text-transform: inherit;
117 appearance: none;
118
119 &::-moz-focus-inner {
120 border: 0;
121 }
122}
123
124input,
125textarea {
126 &::placeholder {
127 opacity: 1;
128 color: fn.color(--text-mute);
129 }
130
131 &:disabled {
132 color: fn.color(--text-disabled);
133 }
134}
135
136textarea {
137 block-size: calc(1em * fn.dim(--font --standard --line-height));
138}
139
140hr {
141 block-size: fn.dim(--border --thin);
142 margin: 0;
143 border: 0;
144 background-color: fn.color(--border);
145}
diff --git a/src/_config.defaults.scss b/src/_config.defaults.scss
new file mode 100644
index 0000000..861b600
--- /dev/null
+++ b/src/_config.defaults.scss
@@ -0,0 +1,197 @@
1@use 'sass:list';
2@use 'sass:map';
3@use 'sass:math';
4@use 'iro-sass/src/easing' as easing;
5
6$static-colors: (
7 --base: hsl(0, 0%, 98%),
8
9 --levels: (
10 --100: math.div(0, 12) * 110 - 10,
11 --200: math.div(1, 12) * 110 - 10,
12 --300: math.div(2, 12) * 110 - 10,
13 --400: math.div(3, 12) * 110 - 10,
14 --500: math.div(4, 12) * 110 - 10,
15 --600: math.div(5, 12) * 110 - 10,
16 --700: math.div(6, 12) * 110 - 10,
17 --800: math.div(7, 12) * 110 - 10,
18 --900: math.div(8, 12) * 110 - 10,
19 --1000: math.div(9, 12) * 110 - 10,
20 --1100: math.div(10, 12) * 110 - 10,
21 --1200: math.div(11, 12) * 110 - 10,
22 --1300: math.div(12, 12) * 110 - 10,
23 ),
24
25 --palettes: (
26 --blue: oklch(56% .14 275.25),
27 --purple: oklch(56% .14 305.58),
28 --red: oklch(56% .14 14.69),
29 --green: oklch(56% .14 150.48),
30 --yellow: oklch(56% .14 84.08),
31 ),
32
33 --transparents: (
34 --100: 0,
35 --200: .1,
36 --300: .25,
37 --400: .4,
38 --500: .55,
39 --600: .7,
40 --700: .8,
41 --800: .9,
42 --900: 1,
43 ),
44);
45
46$semantic-colors-common: (
47 --accent: --blue,
48 --accent-static: --blue-static,
49 --positive: --green,
50 --positive-static: --green-static,
51 --negative: --red,
52 --negative-static: --red-static,
53 --warning: --yellow,
54 --warning-static: --yellow-static,
55
56 --focus-raw: --accent,
57 --focus-static: --accent-static,
58
59 --border-mute: --base --200,
60 --border: --base --300,
61 --border-strong: --base --400,
62
63 --text-disabled: --base --500,
64 --text-mute-more: --base --600,
65 --text-mute: --base --700,
66 --text: --base --800,
67 --heading: --base --900,
68
69 --focus: (
70 --outline: --focus-raw --400,
71 --border-mute: --focus-raw --900,
72 --border: --focus-raw --1000,
73 --border-text: --focus-raw --1000-text,
74 --border-strong: --focus-raw --1100,
75 --text: --focus-raw --1100,
76 ),
77);
78
79$theme-light: (
80 --levels: (
81 --grays: (
82 --50: (-8) (.2 + .8 * easing.ease(math.div(0, 12))),
83 --75: (-4) (.2 + .8 * easing.ease(math.div(1, 12))),
84 --100: (0) (.2 + .8 * easing.ease(math.div(2, 12))),
85
86 --200: (easing.cubic-bezier(.2, .1, .9, .9, math.div(1, 7)) * 98) (.2 + .8 * easing.ease(math.div(3, 12))),
87 --300: (easing.cubic-bezier(.2, .1, .9, .9, math.div(2, 7)) * 98) (.2 + .8 * easing.ease(math.div(4, 12))),
88 --400: (easing.cubic-bezier(.2, .1, .9, .9, math.div(3, 7)) * 98) (.2 + .8 * easing.ease(math.div(5, 12))),
89
90 --500: (easing.cubic-bezier(.2, .1, .9, .9, math.div(4, 7)) * 98) (.2 + .8 * easing.ease(math.div(6, 12))),
91 --600: (easing.cubic-bezier(.2, .1, .9, .9, math.div(5, 7)) * 98) (.2 + .8 * easing.ease(math.div(7, 12))),
92 --700: (easing.cubic-bezier(.2, .1, .9, .9, math.div(6, 7)) * 98) (.2 + .8 * easing.ease(math.div(8, 12))),
93 --800: (easing.cubic-bezier(.2, .1, .9, .9, math.div(7, 7)) * 98) (.2 + .8 * easing.ease(math.div(9, 12))),
94 --900: (106) (.2 + .8 * easing.ease(math.div(10, 12))),
95 ),
96
97 --colors: (
98 --100: (math.div(0, 12) * 94 + 7) (.2 + .8 * easing.ease(math.div(0, 12))),
99 --200: (math.div(1, 12) * 94 + 7) (.2 + .8 * easing.ease(math.div(1, 12))),
100 --300: (math.div(2, 12) * 94 + 7) (.2 + .8 * easing.ease(math.div(2, 12))),
101 --400: (math.div(3, 12) * 94 + 7) (.2 + .8 * easing.ease(math.div(3, 12))),
102 --500: (math.div(4, 12) * 94 + 7) (.2 + .8 * easing.ease(math.div(4, 12))),
103 --600: (math.div(5, 12) * 94 + 7) (.2 + .8 * easing.ease(math.div(5, 12))),
104 --700: (math.div(6, 12) * 94 + 7) (.2 + .8 * easing.ease(math.div(6, 12))),
105 --800: (math.div(7, 12) * 94 + 7) (.2 + .8 * easing.ease(math.div(7, 12))),
106 --900: (math.div(8, 12) * 94 + 7) (.2 + .8 * easing.ease(math.div(8, 12))),
107 --1000: (math.div(9, 12) * 94 + 7) (.2 + .8 * easing.ease(math.div(9, 12))),
108 --1100: (math.div(10, 12) * 94 + 7) (.2 + .8 * easing.ease(math.div(10, 12))),
109 --1200: (math.div(11, 12) * 94 + 7) (.2 + .8 * easing.ease(math.div(11, 12))),
110 --1300: (math.div(12, 12) * 94 + 7) (.2 + .8 * easing.ease(math.div(12, 12))),
111 ),
112 ),
113
114 --palettes: (
115 --base: hsl(260, 70%, 98%) --grays,
116 --blue: oklch(56% .16 275.25) --colors,
117 --purple: oklch(56% .16 305.58) --colors,
118 --red: oklch(56% .16 14.69) --colors,
119 --green: oklch(56% .16 150.48) --colors,
120 --yellow: oklch(56% .16 84.08) --colors,
121 ),
122
123 --semantic: map.merge($semantic-colors-common, (
124 --bg-l2: --base --50,
125 --bg-l1: --base --100,
126 --bg-base: --base --200,
127
128 --box: (
129 --border: --base --200,
130 --border-strong: --base --300,
131 ),
132 )),
133
134 --constants: (
135 --shadow: rgba(#000, .1),
136 ),
137);
138
139$theme-dark: (
140 --levels: (
141 --grays: (
142 --50: (4.4) (.3 + .7 * easing.ease(math.div(10, 12))),
143 --75: (2.5) (.3 + .7 * easing.ease(math.div(9, 12))),
144 --100: (0) (.3 + .7 * easing.ease(math.div(8, 12))),
145
146 --200: (easing.cubic-bezier(.3, .1, .8, .8, math.div(1, 8)) * -108) (.3 + .7 * easing.ease(math.div(7, 12))),
147 --300: (easing.cubic-bezier(.3, .1, .8, .8, math.div(2, 8)) * -108) (.3 + .7 * easing.ease(math.div(6, 12))),
148 --400: (easing.cubic-bezier(.3, .1, .8, .8, math.div(3, 8)) * -108) (.3 + .7 * easing.ease(math.div(5, 12))),
149
150 --500: (easing.cubic-bezier(.3, .1, .8, .8, math.div(4, 8)) * -108) (.3 + .7 * easing.ease(math.div(4, 12))),
151 --600: (easing.cubic-bezier(.3, .1, .8, .8, math.div(5, 8)) * -108) (.3 + .7 * easing.ease(math.div(3, 12))),
152 --700: (easing.cubic-bezier(.3, .1, .8, .8, math.div(6, 8)) * -108) (.3 + .7 * easing.ease(math.div(2, 12))),
153 --800: (easing.cubic-bezier(.3, .1, .8, .8, math.div(7, 8)) * -108) (.3 + .7 * easing.ease(math.div(1, 12))),
154 --900: (easing.cubic-bezier(.3, .1, .8, .8, math.div(8, 8)) * -108) (.3 + .7 * easing.ease(math.div(0, 12))),
155 ),
156
157 --colors: (
158 --100: (easing.cubic-bezier(.2, .1, .8, .8, math.div(0, 12)) * -109 - .5) (.3 + .7 * easing.ease(math.div(0, 12))),
159 --200: (easing.cubic-bezier(.2, .1, .8, .8, math.div(1, 12)) * -109 - .5) (.3 + .7 * easing.ease(math.div(1, 12))),
160 --300: (easing.cubic-bezier(.2, .1, .8, .8, math.div(2, 12)) * -109 - .5) (.3 + .7 * easing.ease(math.div(2, 12))),
161 --400: (easing.cubic-bezier(.2, .1, .8, .8, math.div(3, 12)) * -109 - .5) (.3 + .7 * easing.ease(math.div(3, 12))),
162 --500: (easing.cubic-bezier(.2, .1, .8, .8, math.div(4, 12)) * -109 - .5) (.3 + .7 * easing.ease(math.div(4, 12))),
163 --600: (easing.cubic-bezier(.2, .1, .8, .8, math.div(5, 12)) * -109 - .5) (.3 + .7 * easing.ease(math.div(5, 12))),
164 --700: (easing.cubic-bezier(.2, .1, .8, .8, math.div(6, 12)) * -109 - .5) (.3 + .7 * easing.ease(math.div(6, 12))),
165 --800: (easing.cubic-bezier(.2, .1, .8, .8, math.div(7, 12)) * -109 - .5) (.3 + .7 * easing.ease(math.div(7, 12))),
166 --900: (easing.cubic-bezier(.2, .1, .8, .8, math.div(8, 12)) * -109 - .5) (.3 + .7 * easing.ease(math.div(8, 12))),
167 --1000: (easing.cubic-bezier(.2, .1, .8, .8, math.div(9, 12)) * -109 - .5) (.3 + .7 * easing.ease(math.div(9, 12))),
168 --1100: (easing.cubic-bezier(.2, .1, .8, .8, math.div(10, 12)) * -109 - .5) (.3 + .7 * easing.ease(math.div(10, 12))),
169 --1200: (easing.cubic-bezier(.2, .1, .8, .8, math.div(11, 12)) * -109 - .5) (.3 + .7 * easing.ease(math.div(11, 12))),
170 --1300: (easing.cubic-bezier(.2, .1, .8, .8, math.div(12, 12)) * -109 - .5) (.3 + .7 * easing.ease(math.div(12, 12))),
171 ),
172 ),
173
174 --palettes: (
175 --base: hsl(257, 7%, 20%) --grays,
176 --blue: oklch(56% .16 275.25) --colors,
177 --purple: oklch(56% .16 305.58) --colors,
178 --red: oklch(56% .16 14.69) --colors,
179 --green: oklch(56% .16 150.48) --colors,
180 --yellow: oklch(56% .16 84.08) --colors,
181 ),
182
183 --semantic: map.merge($semantic-colors-common, (
184 --bg-base: --base --50,
185 --bg-l1: --base --75,
186 --bg-l2: --base --100,
187
188 --box: (
189 --border: --base --100,
190 --border-strong: --base --100,
191 ),
192 )),
193
194 --constants: (
195 --shadow: rgba(#000, .35),
196 ),
197);
diff --git a/src/_config.scss b/src/_config.scss
index 5449a04..764d953 100644
--- a/src/_config.scss
+++ b/src/_config.scss
@@ -1,230 +1,29 @@
1@use 'sass:list'; 1@use 'sass:list';
2@use 'sass:map'; 2@use 'sass:map';
3@use 'sass:math'; 3@use 'sass:math';
4@use 'iro-sass/src/index' as iro;
5@use 'iro-sass/src/responsive' as res;
6@use 'iro-sass/src/easing' as easing; 4@use 'iro-sass/src/easing' as easing;
7@use 'include-media/dist/include-media' as media; 5@use 'config.defaults' as def;
8@use '@oddbird/blend';
9 6
10iro.$vars-root-size: 16px; 7$static-colors-override: () !default;
8$static-colors: map.deep-merge(def.$static-colors, $static-colors-override) !default;
11 9
12media.$breakpoints: ( 10$semantic-colors-common-override: () !default;
13 lg: 1340px, 11$semantic-colors-common: map.deep-merge(def.$semantic-colors-common, $semantic-colors-common-override) !default;
14 md: 900px,
15 sm: 620px,
16 xs: 400px,
17);
18 12
19media.$unit-intervals: ( 13$theme-light-override: () !default;
20 'px': 1, 14$theme-light: map.deep-merge(def.$theme-light, $theme-light-override) !default;
21 'em': .01,
22 'rem': .01,
23 '': 0
24);
25 15
26res.$named-viewports: media.$breakpoints; 16$theme-dark-override: () !default;
17$theme-dark: map.deep-merge(def.$theme-dark, $theme-dark-override) !default;
27 18
28$palette-precision: 0.01 !default; 19$themes-override: () !default;
29 20$themes: map.deep-merge((
30$palette-chroma-easing: 'ease' !default; 21 --main: (
31 22 light: $theme-light,
32$static-colors: ( 23 dark: $theme-dark,
33 --base: hsl(0, 0%, 98%), 24 ),
34 25), $themes-override) !default;
35 --contrasts: (
36 --100: math.div( 0, 12) * 110 - 10,
37 --200: math.div( 1, 12) * 110 - 10,
38 --300: math.div( 2, 12) * 110 - 10,
39 --400: math.div( 3, 12) * 110 - 10,
40 --500: math.div( 4, 12) * 110 - 10,
41 --600: math.div( 5, 12) * 110 - 10,
42 --700: math.div( 6, 12) * 110 - 10,
43 --800: math.div( 7, 12) * 110 - 10,
44 --900: math.div( 8, 12) * 110 - 10,
45 --1000: math.div( 9, 12) * 110 - 10,
46 --1100: math.div(10, 12) * 110 - 10,
47 --1200: math.div(11, 12) * 110 - 10,
48 --1300: math.div(12, 12) * 110 - 10,
49 ),
50
51 --palettes: (
52 --blue: oklch(56% 0.14 265.25),
53 --purple: oklch(56% 0.14 305.58),
54 --red: oklch(56% 0.14 18.69),
55 --green: oklch(56% 0.14 150.48),
56 --yellow: oklch(56% 0.14 84.08),
57 ),
58
59 --transparents: (
60 --100: 0,
61 --200: .1,
62 --300: .25,
63 --400: .4,
64 --500: .55,
65 --600: .7,
66 --700: .8,
67 --800: .9,
68 --900: 1,
69 ),
70) !default;
71
72$semantic-colors-common: (
73 --accent: --blue,
74 --accent-static: --blue-static,
75 --positive: --green,
76 --positive-static: --green-static,
77 --negative: --red,
78 --negative-static: --red-static,
79 --warning: --yellow,
80 --warning-static: --yellow-static,
81
82 --focus-raw: --accent,
83 --focus-static: --accent-static,
84
85 --border-mute: --base --200,
86 --border: --base --300,
87 --border-strong: --base --400,
88
89 --text-disabled: --base --500,
90 --text-mute-more: --base --600,
91 --text-mute: --base --700,
92 --text: --base --800,
93 --heading: --base --900,
94
95 --focus: (
96 --outline: --focus-raw --400,
97 --border-mute: --focus-raw --900,
98 --border: --focus-raw --1000,
99 --border-text: --focus-raw --1000-text,
100 --border-strong: --focus-raw --1100,
101 --text: --focus-raw --1100,
102 ),
103) !default;
104
105$theme-light: (
106 --contrasts: (
107 --grays: (
108 --50: -8,
109 --75: -4,
110 --100: 0,
111
112 --200: easing.cubic-bezier(.2, .1, .9, .9, math.div(1, 7)) * 100,
113 --300: easing.cubic-bezier(.2, .1, .9, .9, math.div(2, 7)) * 100,
114 --400: easing.cubic-bezier(.2, .1, .9, .9, math.div(3, 7)) * 100,
115
116 --500: easing.cubic-bezier(.2, .1, .9, .9, math.div(4, 7)) * 100,
117 --600: easing.cubic-bezier(.2, .1, .9, .9, math.div(5, 7)) * 100,
118 --700: easing.cubic-bezier(.2, .1, .9, .9, math.div(6, 7)) * 100,
119 --800: easing.cubic-bezier(.2, .1, .9, .9, math.div(7, 7)) * 100,
120 --900: 108,
121 ),
122
123 --colors: (
124 --100: math.div( 0, 12) * 96 + 5,
125 --200: math.div( 1, 12) * 96 + 5,
126 --300: math.div( 2, 12) * 96 + 5,
127 --400: math.div( 3, 12) * 96 + 5,
128 --500: math.div( 4, 12) * 96 + 5,
129 --600: math.div( 5, 12) * 96 + 5,
130 --700: math.div( 6, 12) * 96 + 5,
131 --800: math.div( 7, 12) * 96 + 5,
132 --900: math.div( 8, 12) * 96 + 5,
133 --1000: math.div( 9, 12) * 96 + 5,
134 --1100: math.div(10, 12) * 96 + 5,
135 --1200: math.div(11, 12) * 96 + 5,
136 --1300: math.div(12, 12) * 96 + 5,
137 ),
138 ),
139
140 --ranges: (
141 --full: 1,
142 --muted: .1,
143 ),
144
145 --palettes: (
146 --base: hsl(0, 0%, 98%) --grays --full,
147 --blue: oklch(56% 0.16 265.25) --colors --muted,
148 --purple: oklch(56% 0.16 305.58) --colors --muted,
149 --red: oklch(56% 0.16 18.69) --colors --muted,
150 --green: oklch(56% 0.16 150.48) --colors --muted,
151 --yellow: oklch(56% 0.16 84.08) --colors --muted,
152 ),
153
154 --semantic: map.merge($semantic-colors-common, (
155 --bg-l2: --base --50,
156 --bg-l1: --base --100,
157 --bg-base: --base --200,
158 )),
159
160 --constants: (
161 --shadow: rgba(#000, 0.15),
162 ),
163) !default;
164
165$theme-dark: (
166 --contrasts: (
167 --grays: (
168 --50: 4.4,
169 --75: 2.2,
170 --100: 0,
171
172 --200: easing.cubic-bezier(.3, .1, .8, .8, math.div(1, 8)) * -108,
173 --300: easing.cubic-bezier(.3, .1, .8, .8, math.div(2, 8)) * -108,
174 --400: easing.cubic-bezier(.3, .1, .8, .8, math.div(3, 8)) * -108,
175
176 --500: easing.cubic-bezier(.3, .1, .8, .8, math.div(4, 8)) * -108,
177 --600: easing.cubic-bezier(.3, .1, .8, .8, math.div(5, 8)) * -108,
178 --700: easing.cubic-bezier(.3, .1, .8, .8, math.div(6, 8)) * -108,
179 --800: easing.cubic-bezier(.3, .1, .8, .8, math.div(7, 8)) * -108,
180 --900: easing.cubic-bezier(.3, .1, .8, .8, math.div(8, 8)) * -108,
181 ),
182
183 --colors: (
184 --100: math.div( 0, 12) * -100 - 5,
185 --200: math.div( 1, 12) * -100 - 5,
186 --300: math.div( 2, 12) * -100 - 5,
187 --400: math.div( 3, 12) * -100 - 5,
188 --500: math.div( 4, 12) * -100 - 5,
189 --600: math.div( 5, 12) * -100 - 5,
190 --700: math.div( 6, 12) * -100 - 5,
191 --800: math.div( 7, 12) * -100 - 5,
192 --900: math.div( 8, 12) * -100 - 5,
193 --1000: math.div( 9, 12) * -100 - 5,
194 --1100: math.div(10, 12) * -100 - 5,
195 --1200: math.div(11, 12) * -100 - 5,
196 --1300: math.div(12, 12) * -100 - 5,
197 ),
198 ),
199
200 --ranges: (
201 --full: 1,
202 --muted: .3,
203 ),
204
205 --palettes: (
206 --base: hsl(0, 0%, 20%) --grays --full,
207 --blue: oklch(56% 0.16 265.25) --colors --muted,
208 --purple: oklch(56% 0.16 305.58) --colors --muted,
209 --red: oklch(56% 0.16 18.69) --colors --muted,
210 --green: oklch(56% 0.16 150.48) --colors --muted,
211 --yellow: oklch(56% 0.16 84.08) --colors --muted,
212 ),
213
214 --semantic: map.merge($semantic-colors-common, (
215 --bg-base: --base --50,
216 --bg-l1: --base --75,
217 --bg-l2: --base --100,
218 )),
219
220 --constants: (
221 --shadow: rgba(#000, 0.5),
222 ),
223) !default;
224
225$themes: (
226 light: $theme-light,
227 dark: $theme-dark,
228) !default;
229 26
230$theme-default: list.nth(map.keys($themes), 1) !default; 27$theme-default: list.nth(map.keys($themes), 1) !default;
28
29$explicit-dark-theme: false !default;
diff --git a/src/_core.scss b/src/_core.scss
new file mode 100644
index 0000000..7be4b0d
--- /dev/null
+++ b/src/_core.scss
@@ -0,0 +1,45 @@
1@use 'sass:map';
2@use 'sass:meta';
3@use 'sass:string';
4@use 'iro-sass/src/bem';
5@use 'iro-sass/src/props';
6@use 'config';
7
8@use 'core.vars' as vars;
9@forward 'core.vars';
10
11@mixin styles {
12 @each $theme-name, $theme in vars.$themes {
13 @if $theme-name == config.$theme-default {
14 :root {
15 @include props.materialize(map.values(meta.module-variables('vars')));
16
17 @if map.has-key($theme, 'dark') {
18 @media (prefers-color-scheme: dark) {
19 @include props.materialize(map.get($theme, 'dark'));
20 }
21 }
22 }
23
24 @if map.has-key($theme, 'dark') and config.$explicit-dark-theme {
25 @include bem.theme('dark') {
26 @include props.materialize(map.values(meta.module-variables('vars')));
27 @include props.materialize(map.get($theme, 'dark'));
28 }
29 }
30 } @else {
31 @include bem.theme(string.slice($theme-name, 3)) {
32 @include props.materialize(map.get($theme, 'light'));
33
34 color: props.get(vars.$theme, --text);
35 background-color: props.get(vars.$theme, --bg-base);
36
37 @if map.has-key($theme, 'dark') {
38 @media (prefers-color-scheme: dark) {
39 @include props.materialize(map.get($theme, 'dark'));
40 }
41 }
42 }
43 }
44 }
45}
diff --git a/src/_core.vars.scss b/src/_core.vars.scss
new file mode 100644
index 0000000..f7a9ebc
--- /dev/null
+++ b/src/_core.vars.scss
@@ -0,0 +1,183 @@
1// stylelint-disable scss/dollar-variable-pattern
2
3@use 'sass:map';
4@use 'sass:meta';
5@use 'sass:list';
6@use 'functions' as fn;
7@use 'config';
8@use 'iro-sass/src/functions';
9@use 'iro-sass/src/props';
10
11$size--0: props.def(--size--0, 0) !default;
12$size--10: props.def(--size--10, functions.px-to-rem(1px)) !default;
13$size--25: props.def(--size--25, functions.px-to-rem(2px)) !default;
14$size--40: props.def(--size--40, functions.px-to-rem(3px)) !default;
15$size--50: props.def(--size--50, functions.px-to-rem(4px)) !default;
16$size--65: props.def(--size--65, functions.px-to-rem(5px)) !default;
17$size--75: props.def(--size--75, functions.px-to-rem(6px)) !default;
18$size--85: props.def(--size--85, functions.px-to-rem(7px)) !default;
19$size--100: props.def(--size--100, functions.px-to-rem(8px)) !default;
20$size--115: props.def(--size--115, functions.px-to-rem(9px)) !default;
21$size--125: props.def(--size--125, functions.px-to-rem(10px)) !default;
22$size--130: props.def(--size--130, functions.px-to-rem(11px)) !default;
23$size--150: props.def(--size--150, functions.px-to-rem(12px)) !default;
24$size--160: props.def(--size--160, functions.px-to-rem(13px)) !default;
25$size--175: props.def(--size--175, functions.px-to-rem(14px)) !default;
26$size--200: props.def(--size--200, functions.px-to-rem(16px)) !default;
27$size--225: props.def(--size--225, functions.px-to-rem(18px)) !default;
28$size--250: props.def(--size--250, functions.px-to-rem(20px)) !default;
29$size--275: props.def(--size--275, functions.px-to-rem(22px)) !default;
30$size--300: props.def(--size--300, functions.px-to-rem(24px)) !default;
31$size--325: props.def(--size--325, functions.px-to-rem(26px)) !default;
32$size--350: props.def(--size--350, functions.px-to-rem(28px)) !default;
33$size--375: props.def(--size--375, functions.px-to-rem(30px)) !default;
34$size--400: props.def(--size--400, functions.px-to-rem(32px)) !default;
35$size--450: props.def(--size--450, functions.px-to-rem(36px)) !default;
36$size--500: props.def(--size--500, functions.px-to-rem(40px)) !default;
37$size--550: props.def(--size--550, functions.px-to-rem(44px)) !default;
38$size--600: props.def(--size--600, functions.px-to-rem(48px)) !default;
39$size--650: props.def(--size--650, functions.px-to-rem(52px)) !default;
40$size--700: props.def(--size--700, functions.px-to-rem(56px)) !default;
41$size--800: props.def(--size--800, functions.px-to-rem(64px)) !default;
42$size--900: props.def(--size--900, functions.px-to-rem(72px)) !default;
43$size--1000: props.def(--size--1000, functions.px-to-rem(80px)) !default;
44$size--1200: props.def(--size--1200, functions.px-to-rem(96px)) !default;
45$size--1600: props.def(--size--1600, functions.px-to-rem(128px)) !default;
46$size--2000: props.def(--size--2000, functions.px-to-rem(160px)) !default;
47$size--2400: props.def(--size--2400, functions.px-to-rem(192px)) !default;
48$size--2500: props.def(--size--2500, functions.px-to-rem(200px)) !default;
49$size--2600: props.def(--size--2600, functions.px-to-rem(208px)) !default;
50$size--2800: props.def(--size--2800, functions.px-to-rem(224px)) !default;
51$size--3200: props.def(--size--3200, functions.px-to-rem(256px)) !default;
52$size--3400: props.def(--size--3400, functions.px-to-rem(272px)) !default;
53$size--3500: props.def(--size--3500, functions.px-to-rem(280px)) !default;
54$size--3600: props.def(--size--3600, functions.px-to-rem(288px)) !default;
55$size--3800: props.def(--size--3800, functions.px-to-rem(304px)) !default;
56$size--4600: props.def(--size--4600, functions.px-to-rem(368px)) !default;
57$size--5000: props.def(--size--5000, functions.px-to-rem(400px)) !default;
58$size--6000: props.def(--size--6000, functions.px-to-rem(480px)) !default;
59
60$font--standard--family: props.def(--font--standard--family, ('Inter', 'Open Sans', 'Segoe UI', 'Droid Sans', Roboto, Oxygen, 'Helvetica Neue', Helvetica, Tahoma, Arial, sans-serif)) !default;
61$font--standard--line-height: props.def(--font--standard--line-height, 1.5) !default;
62$font--standard--feature-settings: props.def(--font--standard--feature-settings, ('\'ss01\'')) !default;
63
64$font--headline--family: props.def(--font--headline--family, ('Inter', props.get($font--standard--family))) !default;
65$font--headline--line-height: props.def(--font--headline--line-height, 1.3) !default;
66$font--headline--weight: props.def(--font--headline--weight, 800) !default;
67$font--headline--feature-settings: props.def(--font--headline--feature-settings, ('\'opsz\'' 32, '\'ss01\'', '\'cv06\'')) !default;
68
69$font--mono--family: props.def(--font--mono--family, ('Iosevka Term SS09', 'IBM Plex Mono', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', Courier, monospace)) !default;
70$font--mono--line-height: props.def(--font--mono--line-height, 1.4) !default;
71$font--mono--feature-settings: props.def(--font--mono--feature-settings, ('\'calt\'' 0, '\'dlig\' 1', '\'ss09\' 1')) !default;
72
73$font-size--50: props.def(--font-size--50, functions.px-to-rem(12px)) !default;
74$font-size--75: props.def(--font-size--75 , functions.px-to-rem(13px)) !default;
75$font-size--100: props.def(--font-size--100, functions.px-to-rem(14px)) !default;
76$font-size--150: props.def(--font-size--150, functions.px-to-rem(16px)) !default;
77$font-size--200: props.def(--font-size--200, functions.px-to-rem(18px)) !default;
78$font-size--300: props.def(--font-size--300, functions.px-to-rem(20px)) !default;
79$font-size--400: props.def(--font-size--400, functions.px-to-rem(24px)) !default;
80$font-size--500: props.def(--font-size--500, functions.px-to-rem(28px)) !default;
81$font-size--600: props.def(--font-size--600, functions.px-to-rem(32px)) !default;
82$font-size--700: props.def(--font-size--700, functions.px-to-rem(36px)) !default;
83$font-size--800: props.def(--font-size--800, functions.px-to-rem(40px)) !default;
84$font-size--900: props.def(--font-size--900, functions.px-to-rem(45px)) !default;
85$font-size--1000: props.def(--font-size--1000, functions.px-to-rem(50px)) !default;
86$font-size--1100: props.def(--font-size--1100, functions.px-to-rem(60px)) !default;
87
88$border-width--thick: props.def(--border-width--thick, 4px) !default;
89$border-width--medium: props.def(--border-width--medium, 2px) !default;
90$border-width--thin: props.def(--border-width--thin, 1px) !default;
91
92$shadow--l1--x: props.def(--shadow--l1--x, 0) !default;
93$shadow--l1--y: props.def(--shadow--l1--y, 2px) !default;
94$shadow--l1--blur: props.def(--shadow--l1--blur, 3px) !default;
95$shadow--l1--grow: props.def(--shadow--l1--grow, -1px) !default;
96
97$shadow--l2--x: props.def(--shadow--l2--x, 0) !default;
98$shadow--l2--y: props.def(--shadow--l2--y, 5px) !default;
99$shadow--l2--blur: props.def(--shadow--l2--blur, 12px) !default;
100$shadow--l2--grow: props.def(--shadow--l2--grow, -4px) !default;
101
102$rounding: props.def(--rounding, 12px) !default;
103$rounding--sm: props.def(--rounding--sm, 4px) !default;
104
105$key-focus--outline-width: props.def(--key-focus--outline-width, props.get($border-width--thick)) !default;
106$key-focus--border-width: props.def(--key-focus--border-width, props.get($border-width--medium)) !default;
107$key-focus--border-offset: props.def(--key-focus--border-offset, props.get($border-width--medium)) !default;
108
109$list--indent: props.def(--list--indent, props.get($size--400)) !default;
110$list--compact-indent: props.def(--list--compact-indent, props.get($size--250)) !default;
111
112$sticky-top-offset: props.def(--sticky-top-offset, 0rem) !default;
113
114//
115
116$-static-colors: ();
117
118@each $palette-name, $palette in map.get(config.$static-colors, --palettes) {
119 $palette: fn.palette($palette, map.get(config.$static-colors, --levels), map.get(config.$static-colors, --base));
120 $-static-colors: map.merge($-static-colors, ( $palette-name: $palette ));
121}
122
123//
124
125$transparent-colors: props.def(--transparent-colors, (), 'color');
126
127@each $palette-name, $palette in (--black: #000 #fff, --white: #fff #000) {
128 $color: list.nth($palette, 1);
129 $text: list.nth($palette, 2);
130
131 $palette: fn.transparent-palette($color, $text, map.get(config.$static-colors, --transparents));
132 $transparent-colors: props.merge($transparent-colors, ( $palette-name: $palette ));
133}
134
135//
136
137$themes: ();
138
139@each $theme-name, $theme in config.$themes {
140 @each $variant-name, $variant in $theme {
141 @if $variant != null {
142 $compiled: props.def(--colors, (), 'color');
143
144 @each $palette-name, $palette in $-static-colors {
145 $compiled: props.merge($compiled, ( #{$palette-name}-static: $palette ));
146 }
147
148 @each $palette-name, $palette in map.get($variant, --palettes) {
149 $base-color: list.nth($palette, 1);
150 $levels: list.nth($palette, 2);
151
152 $palette: fn.palette($base-color, map.get($variant, --levels, $levels), list.nth(map.get($variant, --palettes, --base), 1));
153 $compiled: props.merge($compiled, ( $palette-name: $palette ));
154 }
155
156 @each $color, $value in map.get($variant, --constants) {
157 $compiled: props.merge($compiled, ( $color: $value ));
158 }
159
160 @each $color, $ref in map.get($variant, --semantic) {
161 $res: ();
162
163 @if meta.type-of($ref) == 'map' {
164 @each $key, $r in $ref {
165 $re1: list.nth($r, 1);
166 $re2: functions.list-slice($r, 2);
167 $res: map.merge($res, ($key: props.get($compiled, $re1, $re2...)));
168 }
169 } @else {
170 $ref1: list.nth($ref, 1);
171 $ref2: functions.list-slice($ref, 2);
172 $res: props.get($compiled, $ref1, $ref2...);
173 }
174
175 $compiled: props.merge($compiled, ( $color: $res ));
176 }
177
178 $themes: map.set($themes, $theme-name, $variant-name, $compiled);
179 }
180 }
181}
182
183$theme: map.get($themes, config.$theme-default, light) !default;
diff --git a/src/_declare-vars.scss b/src/_declare-vars.scss
deleted file mode 100644
index e205354..0000000
--- a/src/_declare-vars.scss
+++ /dev/null
@@ -1,274 +0,0 @@
1@use 'sass:map';
2@use 'sass:meta';
3@use 'sass:list';
4@use 'iro-sass/src/index' as iro;
5@use 'include-media/dist/include-media' as media;
6@use '@oddbird/blend';
7@use 'functions' as fn;
8@use 'config';
9
10@include iro.props-store((
11 --dims: (
12 --size: (
13 --0: 0,
14 --10: iro.fn-px-to-rem(1px),
15 --25: iro.fn-px-to-rem(2px),
16 --40: iro.fn-px-to-rem(3px),
17 --50: iro.fn-px-to-rem(4px),
18 --65: iro.fn-px-to-rem(5px),
19 --75: iro.fn-px-to-rem(6px),
20 --85: iro.fn-px-to-rem(7px),
21 --100: iro.fn-px-to-rem(8px),
22 --115: iro.fn-px-to-rem(9px),
23 --125: iro.fn-px-to-rem(10px),
24 --130: iro.fn-px-to-rem(11px),
25 --150: iro.fn-px-to-rem(12px),
26 --160: iro.fn-px-to-rem(13px),
27 --175: iro.fn-px-to-rem(14px),
28 --200: iro.fn-px-to-rem(16px),
29 --225: iro.fn-px-to-rem(18px),
30 --250: iro.fn-px-to-rem(20px),
31 --275: iro.fn-px-to-rem(22px),
32 --300: iro.fn-px-to-rem(24px),
33 --325: iro.fn-px-to-rem(26px),
34 --350: iro.fn-px-to-rem(28px),
35 --375: iro.fn-px-to-rem(30px),
36 --400: iro.fn-px-to-rem(32px),
37 --450: iro.fn-px-to-rem(36px),
38 --500: iro.fn-px-to-rem(40px),
39 --550: iro.fn-px-to-rem(44px),
40 --600: iro.fn-px-to-rem(48px),
41 --650: iro.fn-px-to-rem(52px),
42 --700: iro.fn-px-to-rem(56px),
43 --800: iro.fn-px-to-rem(64px),
44 --900: iro.fn-px-to-rem(72px),
45 --1000: iro.fn-px-to-rem(80px),
46 --1200: iro.fn-px-to-rem(96px),
47 --1600: iro.fn-px-to-rem(128px),
48 --2000: iro.fn-px-to-rem(160px),
49 --2400: iro.fn-px-to-rem(192px),
50 --2500: iro.fn-px-to-rem(200px),
51 --2600: iro.fn-px-to-rem(208px),
52 --2800: iro.fn-px-to-rem(224px),
53 --3200: iro.fn-px-to-rem(256px),
54 --3400: iro.fn-px-to-rem(272px),
55 --3500: iro.fn-px-to-rem(280px),
56 --3600: iro.fn-px-to-rem(288px),
57 --3800: iro.fn-px-to-rem(304px),
58 --4600: iro.fn-px-to-rem(368px),
59 --5000: iro.fn-px-to-rem(400px),
60 --6000: iro.fn-px-to-rem(480px),
61 ),
62
63 --font: (
64 --standard: (
65 --family: ('Inter', 'Open Sans', 'Segoe UI', 'Droid Sans', Roboto, Oxygen, 'Helvetica Neue', Helvetica, Tahoma, Arial, sans-serif),
66 --line-height: 1.5,
67 --feature-settings: ('\'ss01\''),
68 ),
69 --headline: (
70 --family: ('Inter', fn.dim(--font --standard --family, null)),
71 --line-height: 1.3,
72 --weight: 800,
73 --feature-settings: ('\'opsz\'' 32, '\'ss01\'', '\'cv06\''),
74 ),
75 --mono: (
76 --family: ('Iosevka Term SS09', 'IBM Plex Mono', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', Courier, monospace),
77 --line-height: 1.4,
78 )
79 ),
80
81 --font-size: (
82 --50: iro.fn-px-to-rem(12px),
83 --75: iro.fn-px-to-rem(13px),
84 --100: iro.fn-px-to-rem(14px),
85 --150: iro.fn-px-to-rem(16px),
86 --200: iro.fn-px-to-rem(18px),
87 --300: iro.fn-px-to-rem(20px),
88 --400: iro.fn-px-to-rem(24px),
89 --500: iro.fn-px-to-rem(28px),
90 --600: iro.fn-px-to-rem(32px),
91 --700: iro.fn-px-to-rem(36px),
92 --800: iro.fn-px-to-rem(40px),
93 --900: iro.fn-px-to-rem(45px),
94 --1000: iro.fn-px-to-rem(50px),
95 --1100: iro.fn-px-to-rem(60px),
96 ),
97
98 --border: (
99 --thick: 4px,
100 --medium: 2px,
101 --thin: 1px,
102 ),
103
104 --shadow: (
105 --x: 0,
106 --y: 1px,
107 --blur: 4px,
108 ),
109
110 --rounding: 4px,
111
112 --key-focus: (
113 --outline: fn.dim(--border --thick, null),
114 --border: fn.dim(--border --medium, null),
115 --border-offset: fn.dim(--border --medium, null),
116 ),
117
118 --paragraph: (
119 --margin-bs: fn.dim(--size --300, null),
120 ),
121
122 --heading: (
123 --margin-bs: fn.dim(--size --700, null),
124 --margin-bs-sibling: fn.dim(--size --325, null),
125
126 --xxl: fn.dim(--font-size --300, null),
127 --xl: fn.dim(--font-size --200, null),
128 --lg: fn.dim(--font-size --150, null),
129 --md: fn.dim(--font-size --100, null),
130 --sm: fn.dim(--font-size --75, null),
131 --xs: fn.dim(--font-size --50, null),
132
133 --display: (
134 --xxl: fn.dim(--font-size --1100, null),
135 --xl: fn.dim(--font-size --700, null),
136 --lg: fn.dim(--font-size --300, null),
137 --md: fn.dim(--font-size --150, null),
138 --sm: fn.dim(--font-size --75, null),
139 --xs: fn.dim(--font-size --50, null),
140 ),
141
142 --display-sm: (
143 --xxl: fn.dim(--font-size --900, null),
144 --xl: fn.dim(--font-size --600, null),
145 --lg: fn.dim(--font-size --200, null),
146 --md: fn.dim(--font-size --100, null),
147 --sm: fn.dim(--font-size --75, null),
148 --xs: fn.dim(--font-size --50, null),
149 )
150 ),
151
152 --list: (
153 --indent: fn.dim(--size --400, null),
154 --compact-indent: fn.dim(--size --250, null),
155 ),
156 ),
157));
158
159@each $breakpoint in map.keys(media.$breakpoints) {
160 @include media.media('<=#{$breakpoint}') {
161 @include iro.props-store((), $breakpoint);
162 }
163}
164
165@include iro.props-store((
166 --dims: (
167 --heading: (
168 --margin-bs: fn.dim(--size --600, null),
169 ),
170
171 --list: (
172 --indent: fn.dim(--size --300),
173 ),
174 )
175), 'sm');
176
177@include iro.props-store((
178 --dims: (
179 --heading: (
180 --margin-bs: fn.dim(--size --500, null),
181 ),
182
183 --list: (
184 --indent: fn.dim(--size --250),
185 ),
186 )
187), 'xs');
188
189//
190
191@each $palette-name, $palette in map.get(config.$static-colors, --palettes) {
192 @include iro.props-store((
193 --colors: (
194 #{$palette-name}-static: fn.palette(
195 $palette,
196 map.get(config.$static-colors, --contrasts),
197 1,
198 map.get(config.$static-colors, --base),
199 ),
200 ),
201 ));
202}
203
204@each $palette-name, $palette in (--black: #000 #fff, --white: #fff #000) {
205 $color: list.nth($palette, 1);
206 $text: list.nth($palette, 2);
207
208 @include iro.props-store((
209 --colors: (
210 #{$palette-name}-transparent: fn.transparent-palette(
211 $color,
212 $text,
213 map.get(config.$static-colors, --transparents),
214 ),
215 ),
216 ));
217}
218
219@each $theme-name, $theme in config.$themes {
220 $tree: if($theme-name == config.$theme-default, iro.$props-default-tree, $theme-name);
221
222 @each $palette-name, $palette in map.get($theme, --palettes) {
223 $base-color: list.nth($palette, 1);
224 $contrasts: list.nth($palette, 2);
225 $ranges: list.nth($palette, 3);
226
227 @include iro.props-store((
228 --colors: (
229 $palette-name: fn.palette(
230 $base-color,
231 map.get($theme, --contrasts, $contrasts),
232 map.get($theme, --ranges, $ranges),
233 list.nth(map.get($theme, --palettes, --base), 1),
234 ),
235 ),
236 ), $tree);
237 }
238
239 @each $color, $value in map.get($theme, --constants) {
240 @include iro.props-store((
241 --colors: (
242 $color: $value,
243 ),
244 ), $tree);
245 }
246
247 @each $color, $ref in map.get($theme, --semantic) {
248 $res: ();
249
250 @if meta.type-of($ref) == 'map' {
251 @each $key, $r in $ref {
252 $res: map.set($res, $key, fn.color($r));
253 }
254 } @else {
255 $res: fn.color($ref);
256 }
257
258 @include iro.props-store((
259 --colors: (
260 $color: $res,
261 ),
262 ), $tree);
263 }
264}
265
266@each $theme-name, $theme in config.$themes {
267 $tree: if($theme-name == config.$theme-default, iro.$props-default-tree, $theme-name);
268
269 @include iro.props-store((
270 --colors: (
271
272 ),
273 ), $tree);
274}
diff --git a/src/_functions.scss b/src/_functions.scss
index d615614..ec1f9d8 100644
--- a/src/_functions.scss
+++ b/src/_functions.scss
@@ -4,149 +4,67 @@
4@use 'sass:list'; 4@use 'sass:list';
5@use 'sass:meta'; 5@use 'sass:meta';
6 6
7@use '@oddbird/blend'; 7@use 'iro-sass/src/easing';
8@use '@oddbird/blend/sass/convert' as blend-convert; 8@use 'apca';
9 9
10@use 'iro-sass/src/index' as iro; 10@function palette($base-color, $levels, $ref-color: $base-color) {
11@use 'iro-sass/src/easing' as easing; 11 $base-lch: color.to-space($base-color, oklch);
12@use 'functions/colors' as iro-colors; 12 $ref-lch: color.to-space($ref-color, oklch);
13@use 'config';
14 13
15@function color($key, $tree: iro.$props-default-tree, $default: null, $global: false) { 14 $ref-l: color.channel($ref-lch, 'lightness');
16 @return iro.props-get(list.join(--colors, $key), $tree, $default, $global); 15 $ref-y: apca.sRGB_to_Y($ref-lch);
17}
18 16
19@function global-color($key, $tree: iro.$props-default-tree, $default: null, $global: true) { 17 $black-y: apca.sRGB_to_Y(#000);
20 @return color($key, $tree, $default, $global); 18 $white-y: apca.sRGB_to_Y(#fff);
21}
22 19
23@function foreign-color($foreign-key, $key, $tree: iro.$props-default-tree, $default: null, $global: true) { 20 $palette: ();
24 @return iro.props-get(list.join($foreign-key --colors, $key), $tree, $default, $global);
25}
26 21
27@function dim($key, $tree: iro.$props-default-tree, $default: null, $global: false) { 22 @each $key, $level in $levels {
28 @return iro.props-get(list.join(--dims, $key), $tree, $default, $global); 23 $color: list.nth($level, 1);
29} 24 $y: 0;
25 $c: 1;
26 $h: 0deg;
30 27
31@function global-dim($key, $tree: iro.$props-default-tree, $default: null, $global: true) { 28 @if list.length($level) > 1 {
32 @return dim($key, $tree, $default, $global); 29 $c: list.nth($level, 2);
33} 30 }
31 @if list.length($level) > 2 {
32 $h: list.nth($level, 3);
33 }
34 34
35@function foreign-dim($foreign-key, $key, $tree: iro.$props-default-tree, $default: null, $global: true) { 35 @if meta.type-of($color) != 'color' {
36 @return iro.props-get(list.join($foreign-key --dims, $key), $tree, $default, $global); 36 $y: apca.reverse($color, $ref-y);
37} 37 $l: color.channel($base-lch, 'lightness');
38 38
39@function font-prop($data, $overrides, $key, $prop) { 39 @if $y != false {
40 @if (map.has-key($overrides, $prop)) { 40 $l: color.channel(apca.Y_to_sRGB($y), 'lightness', oklch);
41 @return map.get($overrides, $prop); 41 } @else {
42 } @else if (map.has-key($data, $prop)) { 42 $y: $ref-y;
43 @return global-dim(--font $key $prop); 43 }
44 }
45 @return null;
46}
47 44
48@function set-font($key, $overrides: ()) { 45 $color: oklch($l ($c * color.channel($base-lch, 'chroma')) ($h + color.channel($base-lch, 'hue')));
49 $font: iro.props-get-static(list.join(--dims --font, $key), $global: true); 46 } @else {
47 $y: apca.sRGB_to_Y($color);
48 }
50 49
51 $map: ( 50 $contrast-black: apca.contrast($black-y, $y);
52 font-family: font-prop($font, $overrides, $key, --family), 51 $contrast-white: apca.contrast($white-y, $y);
53 font-size: font-prop($font, $overrides, $key, --size),
54 font-weight: font-prop($font, $overrides, $key, --weight),
55 font-style: font-prop($font, $overrides, $key, --style),
56 line-height: font-prop($font, $overrides, $key, --line-height),
57 text-transform: font-prop($font, $overrides, $key, --transform),
58 letter-spacing: font-prop($font, $overrides, $key, --spacing),
59 font-variant-alternates: font-prop($font, $overrides, $key, --variant-alternates),
60 font-feature-settings: font-prop($font, $overrides, $key, --feature-settings),
61 );
62 52
63 @return $map; 53 $palette: map.set($palette, $key, $color);
64} 54 $palette: map.set($palette, #{$key}-text, if(math.abs($contrast-black) > math.abs($contrast-white), #000, #fff));
55 }
65 56
66@function lum($color) { 57 @return $palette;
67 @return list.nth(blend-convert.lin_sRGB_to_XYZ(blend-convert.lin_sRGB(blend-convert.sassToRgb($color))), 2) + .05;
68}
69
70@function palette($base-color, $contrasts, $chroma-range: 1, $reference-color: $base-color) {
71 $base-lch: iro-colors.parse-oklch($base-color);
72 $ref-lch: iro-colors.parse-oklch($reference-color);
73 $ref-l: list.nth($ref-lch, 1);
74 $ref-y: iro-colors.apca_sRGB_to_Y($reference-color);
75
76 $cmax: math.max(map.values($contrasts)...);
77 $cmax: math.max($cmax, math.abs(math.min(map.values($contrasts)...)));
78
79 $black-y: iro-colors.apca_sRGB_to_Y(#000);
80 $white-y: iro-colors.apca_sRGB_to_Y(#fff);
81
82 $chroma-easing: meta.get-function(config.$palette-chroma-easing, $module: easing);
83
84 $palette: ();
85
86 @each $key, $contrast in $contrasts {
87 //$i: math.div(list.length($palette), 2 * (list.length($contrasts) - 1));
88 $y: iro-colors.apcaReverse($contrast, $ref-y);
89 $l: list.nth($base-lch, 1);
90 $c: 1;
91
92 @if $y != false {
93 $y-lch: blend-convert.Lab_to_LCH(
94 iro-colors.lin_sRGB_to_Oklab(
95 blend-convert.lin_sRGB(
96 blend-convert.sassToRgb(
97 iro-colors.apca_Y_to_sRGB($y)
98 )
99 )
100 )
101 );
102 $l: list.nth($y-lch, 1);
103 } @else {
104 $y: $ref-y;
105 }
106
107 @if $chroma-range != 1 {
108 $c: if(
109 $ref-l > .5,
110 math.clamp(0, math.div($contrast, $cmax), 1),
111 -1 * math.clamp(-1, math.div($contrast, $cmax), 0)
112 );
113 $c: meta.call($chroma-easing, $c);
114 $c: $chroma-range + (1 - $chroma-range) * $c;
115 }
116
117 $color: oklch(($l * 100%) ($c * list.nth($base-lch, 2)) list.nth($base-lch, 3));
118 //$color: $l, $c * list.nth($base-lch, 2), list.nth($base-lch, 3);
119 //$color: blend-convert.rgbToSass(
120 // blend-convert.gam_sRGB(
121 // iro-colors.Oklab_to_lin_sRGB(
122 // blend-convert.LCH_to_Lab($color)
123 // )
124 // )
125 //);
126
127 $contrast-black: iro-colors.apcaContrast($black-y, $y);
128 $contrast-white: iro-colors.apcaContrast($white-y, $y);
129
130 $palette: map.set($palette, $key, $color);
131 $palette: map.set($palette, #{$key}-text, if(math.abs($contrast-black) > math.abs($contrast-white), #000, #fff));
132 //$palette: map.set($palette, #{$key}-text, blend.contrast($color));
133 }
134
135 @return $palette;
136} 58}
137 59
138@function transparent-palette($color, $text, $alphas) { 60@function transparent-palette($color, $text, $alphas) {
139 $palette: ( 61 $palette: (
140 --text: $text, 62 --text: $text,
141 ); 63 );
142 64
143 @each $key, $alpha in $alphas { 65 @each $key, $alpha in $alphas {
144 $palette: map.set($palette, $key, rgba($color, $alpha)); 66 $palette: map.set($palette, $key, rgba($color, $alpha));
145 } 67 }
146
147 @return $palette;
148}
149 68
150@function px-to-em($size, $base: iro.$vars-root-size) { 69 @return $palette;
151 @return math.div($size, $base) * 1em;
152} 70}
diff --git a/src/_iro-design.scss b/src/_iro-design.scss
new file mode 100644
index 0000000..22e50c0
--- /dev/null
+++ b/src/_iro-design.scss
@@ -0,0 +1,76 @@
1$breakpoints: (
2 lg: 1340px,
3 md: 900px,
4 sm: 620px,
5 xs: 400px,
6) !default;
7
8@use 'iro-sass/src/responsive' with (
9 $named-viewports: $breakpoints
10);
11
12@forward 'include-media/dist/include-media' as media--* with (
13 $breakpoints: $breakpoints,
14 $unit-intervals: (
15 'px': 1,
16 'em': .01,
17 'rem': .01,
18 '': 0
19 ) !default,
20);
21
22@forward 'config.defaults' as config-defaults--*;
23@forward 'config' as config--*;
24@forward 'props' as props--*;
25@forward 'core' as core--*;
26@forward 'layers' as layers--*;
27
28@forward 'layouts/button-group' as l-button-group--*;
29@forward 'layouts/card-list' as l-card-list--*;
30@forward 'layouts/container' as l-container--*;
31@forward 'layouts/flex' as l-flex--*;
32@forward 'layouts/form' as l-form--*;
33@forward 'layouts/media' as l-media--*;
34@forward 'layouts/overflow' as l-overflow--*;
35@forward 'layouts/split-view' as l-split-view--*;
36
37@forward 'scopes/implicit' as s-implicit--*;
38@forward 'scopes/body' as s-body--*;
39@forward 'scopes/blockquotes' as s-blockquotes--*;
40@forward 'scopes/code' as s-code--*;
41@forward 'scopes/figures' as s-figures--*;
42@forward 'scopes/headings' as s-headings--*;
43@forward 'scopes/links' as s-links--*;
44@forward 'scopes/lists' as s-lists--*;
45@forward 'scopes/tables' as s-tables--*;
46
47@forward 'objects/alert' as o-alert--*;
48@forward 'objects/avatar' as o-avatar--*;
49@forward 'objects/backdrop' as o-backdrop--*;
50@forward 'objects/button' as o-button--*;
51@forward 'objects/card' as o-card--*;
52@forward 'objects/checkbox' as o-checkbox--*;
53@forward 'objects/divider' as o-divider--*;
54@forward 'objects/emoji' as o-emoji--*;
55@forward 'objects/figure' as o-figure--*;
56@forward 'objects/field-label' as o-field-label--*;
57@forward 'objects/heading' as o-heading--*;
58@forward 'objects/icon' as o-icon--*;
59@forward 'objects/lightbox' as o-lightbox--*;
60@forward 'objects/menu' as o-menu--*;
61@forward 'objects/navbar' as o-navbar--*;
62@forward 'objects/palette' as o-palette--*;
63@forward 'objects/placeholders' as o-placeholders--*;
64@forward 'objects/popover' as o-popover--*;
65@forward 'objects/radio' as o-radio--*;
66@forward 'objects/side-nav' as o-side-nav--*;
67@forward 'objects/status-indicator' as o-status-indicator--*;
68@forward 'objects/switch' as o-switch--*;
69@forward 'objects/table' as o-table--*;
70@forward 'objects/tabbar' as o-tabbar--*;
71@forward 'objects/text-field' as o-text-field--*;
72@forward 'objects/thumbnail' as o-thumbnail--*;
73
74@forward 'utils' as utils--*;
75
76@forward 'themes' as themes--*;
diff --git a/src/_layers.scss b/src/_layers.scss
new file mode 100644
index 0000000..2a80190
--- /dev/null
+++ b/src/_layers.scss
@@ -0,0 +1,3 @@
1@mixin styles {
2 @layer scope, theme, object, layout, component, utility;
3}
diff --git a/src/_layouts.scss b/src/_layouts.scss
deleted file mode 100644
index 572308d..0000000
--- a/src/_layouts.scss
+++ /dev/null
@@ -1,8 +0,0 @@
1@use 'layouts/media';
2@use 'layouts/container';
3@use 'layouts/button-group';
4@use 'layouts/form';
5@use 'layouts/flex';
6@use 'layouts/overflow';
7@use 'layouts/card-list';
8//@use 'layouts/message-group';
diff --git a/src/_mixins.scss b/src/_mixins.scss
index dca6831..8899778 100644
--- a/src/_mixins.scss
+++ b/src/_mixins.scss
@@ -2,37 +2,37 @@
2@use 'functions' as fn; 2@use 'functions' as fn;
3 3
4@mixin set-font($basis, $values: ()) { 4@mixin set-font($basis, $values: ()) {
5 $values: fn.set-font($basis, $values); 5 $values: fn.set-font($basis, $values);
6 6
7 @each $prop, $value in $values { 7 @each $prop, $value in $values {
8 @if $value != null { 8 @if $value != null {
9 #{$prop}: $value; 9 #{$prop}: $value;
10 } 10 }
11 } 11 }
12} 12}
13 13
14@mixin heading-strong($size) { 14@mixin heading-strong($size) {
15 color: fn.global-color(--heading); 15 font-size: fn.global-dim(list.join(--heading, $size));
16 font-size: fn.global-dim(list.join(--heading, $size)); 16 color: fn.global-color(--heading);
17} 17}
18 18
19@mixin heading-medium($size) { 19@mixin heading-medium($size) {
20 @include set-font(--standard, ( 20 @include set-font(--standard, (
21 --line-height: null, 21 --line-height: null,
22 --size: fn.global-dim(list.join(--heading, $size)), 22 --size: fn.global-dim(list.join(--heading, $size)),
23 --weight: bold 23 --weight: bold
24 )); 24 ));
25 25
26 color: fn.global-color(--heading); 26 color: fn.global-color(--heading);
27} 27}
28 28
29@mixin heading-faint($size) { 29@mixin heading-faint($size) {
30 @include set-font(--standard, ( 30 @include set-font(--standard, (
31 --line-height: null, 31 --line-height: null,
32 --size: fn.global-dim(list.join(--heading, $size)), 32 --size: fn.global-dim(list.join(--heading, $size)),
33 --weight: 500, 33 --weight: 500,
34 --spacing: 1px 34 --spacing: 1px
35 )); 35 ));
36 36
37 color: fn.global-color(--text-mute); 37 color: fn.global-color(--text-mute);
38} 38}
diff --git a/src/_objects.scss b/src/_objects.scss
deleted file mode 100644
index c5049cd..0000000
--- a/src/_objects.scss
+++ /dev/null
@@ -1,28 +0,0 @@
1@use 'objects/icon';
2@use 'objects/emoji';
3@use 'objects/heading';
4@use 'objects/divider';
5@use 'objects/badge';
6@use 'objects/button';
7@use 'objects/text-field';
8@use 'objects/field-label';
9@use 'objects/radio';
10@use 'objects/checkbox';
11@use 'objects/switch';
12@use 'objects/action-button';
13// @use 'objects/overflow-button';
14@use 'objects/status-indicator';
15@use 'objects/avatar';
16// @use 'objects/message';
17@use 'objects/side-nav';
18@use 'objects/popover';
19@use 'objects/menu';
20@use 'objects/card';
21// @use 'objects/icon-nav';
22@use 'objects/backdrop';
23// @use 'objects/dialog';
24@use 'objects/lightbox';
25// @use 'objects/list-group';
26@use 'objects/table';
27@use 'objects/alert';
28@use 'objects/palette';
diff --git a/src/_props.scss b/src/_props.scss
new file mode 100644
index 0000000..0b2306d
--- /dev/null
+++ b/src/_props.scss
@@ -0,0 +1,48 @@
1@use 'sass:list';
2@use 'sass:map';
3@use 'sass:meta';
4@use 'sass:string';
5@use 'config';
6@use 'include-media/dist/include-media' as media;
7@use 'iro-sass/src/bem';
8@use 'iro-sass/src/props';
9
10@mixin materialize-at-root($ref) {
11 @if meta.type-of($ref) == 'map' {
12 $ref: map.values($ref);
13 }
14
15 :root {
16 @include props.materialize($ref, null);
17 @include props.materialize($ref, 'color');
18
19 @each $breakpoint in map.keys(media.$breakpoints) {
20 @include media.media('<=#{$breakpoint}') {
21 @include props.materialize($ref, $breakpoint);
22 }
23 }
24
25 @media (prefers-color-scheme: dark) {
26 @include props.materialize($ref, 'dark');
27 }
28 }
29
30 @if config.$explicit-dark-theme {
31 @include bem.theme('dark') {
32 @include props.materialize($ref, 'color');
33 @include props.materialize($ref, 'dark');
34 }
35 }
36
37 @each $theme-name in map.keys(config.$themes) {
38 @if $theme-name != config.$theme-default {
39 @include bem.theme(string.slice($theme-name, 3)) {
40 @include props.materialize($ref, 'color');
41
42 @media (prefers-color-scheme: dark) {
43 @include props.materialize($ref, 'dark');
44 }
45 }
46 }
47 }
48}
diff --git a/src/_scopes.scss b/src/_scopes.scss
deleted file mode 100644
index a3aeb6c..0000000
--- a/src/_scopes.scss
+++ /dev/null
@@ -1,6 +0,0 @@
1@use 'scopes/links';
2@use 'scopes/code';
3@use 'scopes/blockquotes';
4@use 'scopes/lists';
5@use 'scopes/headings';
6@use 'scopes/tables';
diff --git a/src/_themes.scss b/src/_themes.scss
index 8296064..fe5a0cb 100644
--- a/src/_themes.scss
+++ b/src/_themes.scss
@@ -1,26 +1,74 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:map';
2@use 'functions' as fn; 2@use 'sass:string';
3@use 'iro-sass/src/bem';
4@use 'iro-sass/src/props';
5@use 'include-media/dist/include-media' as media;
3 6
4$static-themes: 'black' 'white' !default; 7@use 'core.vars' as vars;
8@forward 'core.vars';
5 9
6@include iro.bem-theme('base') { 10@mixin styles {
7 background-color: fn.global-color(--bg-base); 11 @include bem.theme('base') {
8} 12 background-color: props.get(vars.$theme, --bg-base);
9 13
10@include iro.bem-theme('l1') { 14 @include bem.suffix('light') {
11 background-color: fn.global-color(--bg-l1); 15 @media (prefers-color-scheme: light) {
12} 16 background-color: props.get(vars.$theme, --bg-base);
17 }
18 }
13 19
14@include iro.bem-theme('l2') { 20 @include bem.suffix('dark') {
15 background-color: fn.global-color(--bg-l2); 21 @media (prefers-color-scheme: dark) {
16} 22 background-color: props.get(vars.$theme, --bg-base);
23 }
24 }
25 }
17 26
18@include iro.bem-theme('50') { 27 @include bem.theme('l1') {
19 background-color: fn.global-color(--base --50); 28 background-color: props.get(vars.$theme, --bg-l1);
20} 29
30 @include bem.suffix('light') {
31 @media (prefers-color-scheme: light) {
32 background-color: props.get(vars.$theme, --bg-l1);
33 }
34 }
35
36 @include bem.suffix('dark') {
37 @media (prefers-color-scheme: dark) {
38 background-color: props.get(vars.$theme, --bg-l1);
39 }
40 }
41 }
42
43 @include bem.theme('l2') {
44 background-color: props.get(vars.$theme, --bg-l2);
45
46 @include bem.suffix('light') {
47 @media (prefers-color-scheme: light) {
48 background-color: props.get(vars.$theme, --bg-l2);
49 }
50 }
51
52 @include bem.suffix('dark') {
53 @media (prefers-color-scheme: dark) {
54 background-color: props.get(vars.$theme, --bg-l2);
55 }
56 }
57 }
58
59 @include bem.theme('50') {
60 background-color: props.get(vars.$theme, --base, --50);
61
62 @include bem.suffix('light') {
63 @media (prefers-color-scheme: light) {
64 background-color: props.get(vars.$theme, --base, --50);
65 }
66 }
21 67
22@each $theme in $static-themes { 68 @include bem.suffix('dark') {
23 @include iro.bem-theme(static-#{$theme}) { 69 @media (prefers-color-scheme: dark) {
24 color: fn.global-color(--#{$theme}-transparent --800); 70 background-color: props.get(vars.$theme, --base, --50);
25 } 71 }
72 }
73 }
26} 74}
diff --git a/src/_utils.scss b/src/_utils.scss
index d5a3478..3dae3b6 100644
--- a/src/_utils.scss
+++ b/src/_utils.scss
@@ -1,209 +1,380 @@
1@use 'sass:map'; 1@use 'sass:map';
2@use 'iro-sass/src/index' as iro; 2@use 'sass:string';
3@use 'functions' as fn; 3@use 'iro-sass/src/bem';
4@use 'iro-sass/src/props';
4@use 'include-media/dist/include-media' as media; 5@use 'include-media/dist/include-media' as media;
5 6
6$dirs: ( 7@use 'core.vars' as vars;
7 '': '', 8@forward 'core.vars';
8 'bs': '-block-start', 9
9 'be': '-block-end', 10/* stylelint-disable-next-line scss/dollar-variable-pattern */
10 'b': '-block', 11$-dirs: (
11 'is': '-inline-start', 12 '': '',
12 'ie': '-inline-end', 13 'b': '-block',
13 'i': '-inline', 14 'bs': '-block-start',
15 'be': '-block-end',
16 'i': '-inline',
17 'is': '-inline-start',
18 'ie': '-inline-end',
14) !default; 19) !default;
15 20
16$sizes: 0 10 50 75 100 125 200 400 700 800 !default; 21/* stylelint-disable-next-line scss/dollar-variable-pattern */
22$-sizes: (
23 0: vars.$size--0,
24 10: vars.$size--10,
25 50: vars.$size--50,
26 75: vars.$size--75,
27 100: vars.$size--100,
28 125: vars.$size--125,
29 200: vars.$size--200,
30 400: vars.$size--400,
31 700: vars.$size--700,
32 800: vars.$size--800,
33) !default;
17 34
18@include iro.bem-utility('d-block') { 35$-font-sizes: (
19 display: block; 36 50: vars.$font-size--50,
20} 37 75: vars.$font-size--75,
38 100: vars.$font-size--100,
39 150: vars.$font-size--150,
40 200: vars.$font-size--200,
41 300: vars.$font-size--300,
42) !default;
21 43
22@include iro.bem-utility('d-inline-block') { 44@mixin styles {
23 display: inline-block; 45 @include bem.utility('d-block') {
24} 46 display: block;
47 }
25 48
26@include iro.bem-utility('d-contents') { 49 @include bem.utility('d-inline-block') {
27 display: contents; 50 display: inline-block;
28} 51 }
29 52
30@include iro.bem-utility('td-none') { 53 @include bem.utility('d-contents') {
31 text-decoration: none; 54 display: contents;
32} 55 }
33 56
34@include iro.bem-utility('d-none') { 57 @include bem.utility('d-flex') {
35 display: none; 58 display: flex;
59 }
36 60
37 @each $breakpoint in map.keys(media.$breakpoints) { 61 @include bem.utility('td-none') {
38 @include media.media('<=#{$breakpoint}') { 62 text-decoration: none;
39 @include iro.bem-suffix('#{$breakpoint}-lo') { 63 }
40 display: none;
41 }
42 }
43 64
44 @include media.media('>#{$breakpoint}') { 65 @include bem.utility('d-none') {
45 @include iro.bem-suffix('#{$breakpoint}-hi') { 66 display: none;
46 display: none;
47 }
48 }
49 }
50 67
51 @include iro.bem-at-theme('js') { 68 @each $breakpoint in map.keys(media.$breakpoints) {
52 @include iro.bem-suffix('js') { 69 @include media.media('<=#{$breakpoint}') {
53 display: none; 70 @include bem.suffix('#{$breakpoint}-lo') {
54 } 71 display: none;
55 } 72 }
73 }
56 74
57 @include iro.bem-at-theme('no-js') { 75 @include media.media('>#{$breakpoint}') {
58 @include iro.bem-suffix('no-js') { 76 @include bem.suffix('#{$breakpoint}-hi') {
59 display: none; 77 display: none;
60 } 78 }
61 } 79 }
80 }
62 81
63 @include iro.bem-suffix('empty') { 82 @include bem.at-theme('js') {
64 &:empty { 83 @include bem.suffix('js') {
65 display: none; 84 display: none;
66 } 85 }
67 } 86 }
68}
69 87
70@include iro.bem-utility('ta-start') { 88 @include bem.at-theme('no-js') {
71 text-align: start; 89 @include bem.suffix('no-js') {
72} 90 display: none;
91 }
92 }
73 93
74@include iro.bem-utility('ta-end') { 94 @include bem.suffix('empty') {
75 text-align: end; 95 &:empty {
76} 96 display: none;
97 }
98 }
99 }
77 100
78@include iro.bem-utility('ta-center') { 101 @include bem.utility('va-top') {
79 text-align: center; 102 vertical-align: top;
80} 103 }
81 104
82@include iro.bem-utility('fw-normal') { 105 @include bem.utility('va-baseline') {
83 font-weight: normal; 106 vertical-align: baseline;
84} 107 }
85 108
86@include iro.bem-utility('ai-center') { 109 @include bem.utility('va-middle') {
87 align-items: center; 110 vertical-align: middle;
88} 111 }
89 112
90@include iro.bem-utility('ai-start') { 113 @include bem.utility('va-bottom') {
91 align-items: flex-start; 114 vertical-align: bottom;
92} 115 }
93 116
94@include iro.bem-utility('ai-end') { 117 @include bem.utility('ta-start') {
95 align-items: flex-end; 118 text-align: start;
96} 119 }
97 120
98@include iro.bem-utility('jc-center') { 121 @include bem.utility('ta-end') {
99 justify-content: center; 122 text-align: end;
100} 123 }
101 124
102@include iro.bem-utility('jc-start') { 125 @include bem.utility('ta-center') {
103 justify-content: flex-start; 126 text-align: center;
104} 127 }
105 128
106@include iro.bem-utility('jc-end') { 129 @include bem.utility('fw-normal') {
107 justify-content: flex-end; 130 font-weight: normal;
108} 131 }
109 132
110@include iro.bem-utility('c-heading') { 133 @include bem.utility('ai-center') {
111 color: fn.color(--heading); 134 align-items: center;
112} 135 }
113 136
114@include iro.bem-utility('c-text') { 137 @include bem.utility('ai-start') {
115 color: fn.color(--text); 138 align-items: flex-start;
116} 139 }
117 140
118@include iro.bem-utility('c-mute') { 141 @include bem.utility('ai-end') {
119 color: fn.color(--text-mute); 142 align-items: flex-end;
120} 143 }
121 144
122@include iro.bem-utility('c-mute-more') { 145 @include bem.utility('ac-center') {
123 color: fn.color(--text-mute-more); 146 align-content: center;
124} 147 }
125 148
126@each $dir, $prop in (is: inline-size, bs: block-size) { 149 @include bem.utility('jc-center') {
127 @include iro.bem-utility('#{$dir}-100') { 150 justify-content: center;
128 #{$prop}: 100%; 151 }
129 } 152
130 153 @include bem.utility('jc-start') {
131 @include iro.bem-utility('#{$dir}-75') { 154 justify-content: flex-start;
132 #{$prop}: 75%; 155 }
133 } 156
157 @include bem.utility('jc-end') {
158 justify-content: flex-end;
159 }
160
161 @include bem.utility('tt-upper') {
162 text-transform: uppercase;
163 }
164
165 @include bem.utility('tt-lower') {
166 text-transform: lowercase;
167 }
168
169 @include bem.utility('c-heading') {
170 color: props.get(vars.$theme, --heading);
171
172 @each $theme in map.keys(props.get(vars.$transparent-colors)) {
173 $theme-name: static-#{string.slice($theme, 3)};
134 174
135 @include iro.bem-utility('#{$dir}-50') { 175 @include bem.at-theme($theme-name) {
136 #{$prop}: 50%; 176 color: props.get(vars.$transparent-colors, $theme, --900);
137 } 177 }
178 }
179 }
180
181 @include bem.utility('c-text') {
182 color: props.get(vars.$theme, --text);
183
184 @each $theme in map.keys(props.get(vars.$transparent-colors)) {
185 $theme-name: static-#{string.slice($theme, 3)};
138 186
139 @include iro.bem-utility('#{$dir}-25') { 187 @include bem.at-theme($theme-name) {
140 #{$prop}: 25%; 188 color: props.get(vars.$transparent-colors, $theme, --800);
141 } 189 }
190 }
191 }
192
193 @include bem.utility('c-mute') {
194 color: props.get(vars.$theme, --text-mute);
195
196 @each $theme in map.keys(props.get(vars.$transparent-colors)) {
197 $theme-name: static-#{string.slice($theme, 3)};
142 198
143 @include iro.bem-utility('#{$dir}-1px') { 199 @include bem.at-theme($theme-name) {
144 #{$prop}: 1px; 200 color: props.get(vars.$transparent-colors, $theme, --700);
145 } 201 }
202 }
203 }
204
205 @include bem.utility('c-mute-more') {
206 color: props.get(vars.$theme, --text-mute-more);
207
208 @each $theme in map.keys(props.get(vars.$transparent-colors)) {
209 $theme-name: static-#{string.slice($theme, 3)};
146 210
147 @include iro.bem-utility('#{$dir}-0') { 211 @include bem.at-theme($theme-name) {
148 #{$prop}: 0; 212 color: props.get(vars.$transparent-colors, $theme, --600);
149 } 213 }
150} 214 }
215 }
151 216
152@include iro.bem-utility('elp') { 217 @each $mod, $size in $-font-sizes {
153 overflow: hidden; 218 @include bem.utility('fs-#{$mod}') {
154 text-overflow: ellipsis; 219 font-size: props.get($size);
155 white-space: nowrap; 220 }
156} 221 }
157 222
158@include iro.bem-utility('p-static') { 223 @each $dir, $prop in (is: inline-size, bs: block-size) {
159 position: static; 224 @include bem.utility('#{$dir}-100') {
160} 225 #{$prop}: 100%;
226 }
227
228 @include bem.utility('#{$dir}-75') {
229 #{$prop}: 75%;
230 }
231
232 @include bem.utility('#{$dir}-50') {
233 #{$prop}: 50%;
234 }
235
236 @include bem.utility('#{$dir}-25') {
237 #{$prop}: 25%;
238 }
239
240 @include bem.utility('#{$dir}-1px') {
241 #{$prop}: 1px;
242 }
243
244 @include bem.utility('#{$dir}-0') {
245 #{$prop}: 0;
246 }
247 }
161 248
162@include iro.bem-utility('p-relative') { 249 @include bem.utility('elp') {
163 position: relative; 250 overflow: hidden;
164} 251 text-overflow: ellipsis;
252 white-space: nowrap;
253 }
165 254
166@include iro.bem-utility('p-fixed') { 255 @include bem.utility('o-auto') {
167 position: fixed; 256 overflow: auto;
168} 257 }
169 258
170@include iro.bem-utility('p-sticky-bs') { 259 @include bem.utility('o-hidden') {
171 position: sticky; 260 overflow: hidden;
172 inset-block-start: 0; 261 }
173}
174 262
175@each $dir, $suffix in $dirs { 263 @include bem.utility('p-static') {
176 @include iro.bem-utility('m#{$dir}-auto') { 264 position: static;
177 margin#{$suffix}: auto; 265 }
178 } 266
179 267 @include bem.utility('p-relative') {
180 @include iro.bem-utility('p#{$dir}-auto') { 268 position: relative;
181 padding#{$suffix}: auto; 269 }
182 } 270
271 @include bem.utility('p-fixed') {
272 position: fixed;
273 }
274
275 @include bem.utility('p-sticky-bs') {
276 position: sticky;
277 inset-block-start: props.get(vars.$sticky-top-offset);
278 }
279
280 @include bem.utility('p-sticky-be') {
281 position: sticky;
282 inset-block-end: 0;
283 }
183 284
184 @each $size in $sizes { 285 @include bem.utility('br-round') {
185 @include iro.bem-utility('m#{$dir}-#{$size}') { 286 border-radius: props.get(vars.$rounding);
186 margin#{$suffix}: fn.global-dim(--size --#{$size}); 287 }
187 } 288
289 @include bem.utility('br-round-sm') {
290 border-radius: props.get(vars.$rounding--sm);
291 }
292
293 @each $dir, $suffix in $-dirs {
294 @include bem.utility('m#{$dir}-auto') {
295 margin#{$suffix}: auto;
296 }
188 297
189 @include iro.bem-utility('p#{$dir}-#{$size}') { 298 @include bem.utility('p#{$dir}-auto') {
190 padding#{$suffix}: fn.global-dim(--size --#{$size}); 299 padding#{$suffix}: auto;
191 } 300 }
192 } 301
193 302 @each $mod, $size in $-sizes {
194 @include iro.bem-utility('b#{$dir}-0') { 303 @include bem.utility('m#{$dir}-#{$mod}') {
195 border#{$suffix}: 0; 304 margin#{$suffix}: props.get($size);
196 } 305 }
197 306
198 @include iro.bem-utility('b#{$dir}-1') { 307 @include bem.utility('p#{$dir}-#{$mod}') {
199 border#{$suffix}: fn.global-dim(--border --thin) solid fn.global-color(--border); 308 padding#{$suffix}: props.get($size);
200 } 309 }
201} 310 }
311
312 @include bem.utility('b#{$dir}-0') {
313 border#{$suffix}: 0;
314
315 @include bem.suffix('light') {
316 @media (prefers-color-scheme: light) {
317 border#{$suffix}: 0;
318 }
319 }
320
321 @include bem.suffix('dark') {
322 @media (prefers-color-scheme: dark) {
323 border#{$suffix}: 0;
324 }
325 }
326 }
327
328 @include bem.utility('b#{$dir}-1') {
329 border#{$suffix}: props.get(vars.$border-width--thin) solid props.get(vars.$theme, --border);
330
331 @include bem.suffix('light') {
332 @media (prefers-color-scheme: light) {
333 border#{$suffix}: props.get(vars.$border-width--thin) solid props.get(vars.$theme, --border);
334 }
335 }
336
337 @include bem.suffix('dark') {
338 @media (prefers-color-scheme: dark) {
339 border#{$suffix}: props.get(vars.$border-width--thin) solid props.get(vars.$theme, --border);
340 }
341 }
342 }
343
344 @include bem.utility('b#{$dir}-1-mute') {
345 border#{$suffix}: props.get(vars.$border-width--thin) solid props.get(vars.$theme, --border-mute);
346
347 @include bem.suffix('light') {
348 @media (prefers-color-scheme: light) {
349 border#{$suffix}: props.get(vars.$border-width--thin) solid props.get(vars.$theme, --border-mute);
350 }
351 }
352
353 @include bem.suffix('dark') {
354 @media (prefers-color-scheme: dark) {
355 border#{$suffix}: props.get(vars.$border-width--thin) solid props.get(vars.$theme, --border-mute);
356 }
357 }
358 }
359 }
202 360
203@include iro.bem-utility('mbs-neutralize') { 361 @include bem.utility('mbs-neutralize') {
204 &::before { 362 &::before {
205 content: ''; 363 display: block;
206 display: block; 364 margin-block: -100em 100em;
207 margin-block: -100em 100em; 365 content: '';
208 } 366 }
367 }
368
369 @include bem.utility('sr-only') {
370 position: absolute;
371 width: 1px;
372 height: 1px;
373 padding: 0;
374 margin: -1px;
375 overflow: hidden;
376 white-space: nowrap;
377 border: 0;
378 clip-path: inset(50%);
379 }
209} 380}
diff --git a/src/functions/colors/_apca.scss b/src/functions/colors/_apca.scss
deleted file mode 100644
index d9236b2..0000000
--- a/src/functions/colors/_apca.scss
+++ /dev/null
@@ -1,127 +0,0 @@
1/* stylelint-disable scss/dollar-variable-pattern */
2/* stylelint-disable scss/at-function-pattern */
3
4@use 'sass:color';
5@use 'sass:list';
6@use 'sass:map';
7@use 'sass:math';
8
9$SA98G: (
10 mainTRC: 2.4,
11
12 sRco: 0.2126729,
13 sGco: 0.7151522,
14 sBco: 0.0721750,
15
16 normBG: 0.56,
17 normTXT: 0.57,
18 revTXT: 0.62,
19 revBG: 0.65,
20
21 blkThrs: 0.022,
22 blkClmp: 1.414,
23 scaleBoW: 1.14,
24 scaleWoB: 1.14,
25 loBoWoffset: 0.027,
26 loWoBoffset: 0.027,
27 deltaYmin: 0.0005,
28 loClip: 0.0001,
29
30 mFactor: 1.94685544331710,
31 mOffsetIn: 0.03873938165714010,
32 mExpAdj: 0.2833433964208690,
33 mOffsetOut: 0.3128657958707580,
34);
35
36@function apca_sRGB_to_Y($color) {
37 @return map.get($SA98G, sRco) * math.pow(math.div(color.red($color), 255), map.get($SA98G, mainTRC)) +
38 map.get($SA98G, sGco) * math.pow(math.div(color.green($color), 255), map.get($SA98G, mainTRC)) +
39 map.get($SA98G, sBco) * math.pow(math.div(color.blue($color), 255), map.get($SA98G, mainTRC));
40}
41
42@function apca_Y_to_sRGB($y) {
43 $c: math.round(math.pow($y, math.div(1, map.get($SA98G, mainTRC))) * 255);
44 @return rgb($c, $c, $c);
45}
46
47@function apcaContrast($txtY, $bgY) {
48 $icp: 0.0 1.1;
49
50 @if math.min($txtY, $bgY) < list.nth($icp, 1) or math.max($txtY, $bgY) > list.nth($icp, 2) {
51 @return 0;
52 }
53
54 @if $txtY <= map.get($SA98G, blkThrs) {
55 $txtY: $txtY + math.pow(map.get($SA98G, blkThrs) - $txtY, map.get($SA98G, blkClmp));
56 }
57 @if $bgY <= map.get($SA98G, blkThrs) {
58 $bgY: $bgY + math.pow(map.get($SA98G, blkThrs) - $bgY, map.get($SA98G, blkClmp));
59 }
60
61 @if math.abs($bgY - $txtY) < map.get($SA98G, deltaYmin) {
62 @return 0;
63 }
64
65 $outputContrast: 0;
66
67 @if $bgY > $txtY {
68 $SAPC: map.get($SA98G, scaleBoW) * (math.pow($bgY, map.get($SA98G, normBG)) - math.pow($txtY, map.get($SA98G, normTXT)));
69
70 @if $SAPC >= map.get($SA98G, loClip) {
71 $outputContrast: $SAPC - map.get($SA98G, loBoWoffset);
72 }
73 } @else {
74 $SAPC: map.get($SA98G, scaleWoB) * (math.pow($bgY, map.get($SA98G, revBG)) - math.pow($txtY, map.get($SA98G, revTXT)));
75
76 @if $SAPC <= -1 * map.get($SA98G, loClip) {
77 $outputContrast: $SAPC + map.get($SA98G, loWoBoffset);
78 }
79 }
80
81 @return $outputContrast * 100.0;
82}
83
84@function apcaReverse($contrast, $knownY, $knownType: 'bg') {
85 $unknownY: $knownY;
86
87 $knownExp: 0;
88 $unknownExp: 0;
89
90 $scale: map.get($SA98G, if($contrast > 0, scaleBoW, scaleWoB));
91 $offset: map.get($SA98G, if($contrast > 0, loBoWoffset, loWoBoffset));
92
93 $contrast: math.div($contrast * 0.01 + $offset, $scale);
94
95 @if $knownY <= map.get($SA98G, blkThrs) {
96 $knownY: $knownY + math.pow(map.get($SA98G, blkThrs) - $knownY, map.get($SA98G, blkClmp));
97 }
98
99 @if $knownType == 'bg' {
100 $knownExp: map.get($SA98G, if($contrast > 0, normBG, revBG));
101 $unknownExp: map.get($SA98G, if($contrast > 0, normTXT, revTXT));
102 $unknownY: math.pow(math.pow($knownY, $knownExp) - $contrast, math.div(1, $unknownExp));
103 } @else {
104 $knownExp: map.get($SA98G, if($contrast > 0, normTXT, revTXT));
105 $unknownExp: map.get($SA98G, if($contrast > 0, normBG, revBG));
106 $unknownY: math.pow($contrast + math.pow($knownY, $knownExp), math.div(1, $unknownExp));
107 }
108
109 @if '#{$unknownY}' == '#{math.sqrt(-1)}' {
110 @return false;
111 }
112
113 @if $unknownY > 1.06 or $unknownY < 0 {
114 @return false;
115 }
116
117 @if $unknownY <= map.get($SA98G, blkThrs) {
118 $unknownY: math.pow(
119 ($unknownY + map.get($SA98G, mOffsetIn)) * map.get($SA98G, mFactor),
120 math.div(map.get($SA98G, mExpAdj), map.get($SA98G, blkClmp))
121 ) * math.div(1, map.get($SA98G, mFactor)) - map.get($SA98G, mOffsetOut);
122 }
123
124 $unknownY: math.max(math.min($unknownY, 1), 0);
125
126 @return $unknownY;
127}
diff --git a/src/functions/colors/_index.scss b/src/functions/colors/_index.scss
deleted file mode 100644
index 26c3027..0000000
--- a/src/functions/colors/_index.scss
+++ /dev/null
@@ -1,2 +0,0 @@
1@forward 'apca';
2@forward 'oklch';
diff --git a/src/functions/colors/_oklch.scss b/src/functions/colors/_oklch.scss
deleted file mode 100644
index e3df041..0000000
--- a/src/functions/colors/_oklch.scss
+++ /dev/null
@@ -1,88 +0,0 @@
1/* stylelint-disable scss/dollar-variable-pattern */
2/* stylelint-disable scss/at-function-pattern */
3
4@use 'sass:list';
5@use 'sass:math';
6@use 'sass:meta';
7@use 'sass:string';
8@use '@oddbird/blend/sass/convert' as blend-convert;
9@use '@oddbird/blend/sass/utils/pow';
10@use 'iro-sass/src/index' as iro;
11
12@function lin_sRGB_to_Oklab($color) {
13 $r_: list.nth($color, 1);
14 $g_: list.nth($color, 2);
15 $b_: list.nth($color, 3);
16
17 $l: pow.cbrt(0.4122214708 * $r_ + 0.5363325363 * $g_ + 0.0514459929 * $b_);
18 $m: pow.cbrt(0.2119034982 * $r_ + 0.6806995451 * $g_ + 0.1073969566 * $b_);
19 $s: pow.cbrt(0.0883024619 * $r_ + 0.2817188376 * $g_ + 0.6299787005 * $b_);
20
21 @return (
22 0.2104542553 * $l + 0.7936177850 * $m - 0.0040720468 * $s,
23 1.9779984951 * $l - 2.4285922050 * $m + 0.4505937099 * $s,
24 0.0259040371 * $l + 0.7827717662 * $m - 0.8086757660 * $s,
25 );
26}
27
28@function Oklab_to_lin_sRGB($color) {
29 $l_: list.nth($color, 1);
30 $a_: list.nth($color, 2);
31 $b_: list.nth($color, 3);
32
33 $l: $l_ + 0.3963377774 * $a_ + 0.2158037573 * $b_;
34 $m: $l_ - 0.1055613458 * $a_ - 0.0638541728 * $b_;
35 $s: $l_ - 0.0894841775 * $a_ - 1.2914855480 * $b_;
36
37 $l: $l * $l * $l;
38 $m: $m * $m * $m;
39 $s: $s * $s * $s;
40
41 @return (
42 4.0767416621 * $l - 3.3077115913 * $m + 0.2309699292 * $s,
43 -1.2684380046 * $l + 2.6097574011 * $m - 0.3413193965 * $s,
44 -0.0041960863 * $l - 0.7034186147 * $m + 1.7076147010 * $s,
45 );
46}
47
48@function oklch($arg) {
49 $l: math.div(list.nth($arg, 1), 100%);
50 $c: list.nth($arg, 2);
51 $h: list.nth($arg, 3);
52
53 @return blend-convert.rgbToSass(
54 blend-convert.gam_sRGB(
55 Oklab_to_lin_sRGB(
56 blend-convert.LCH_to_Lab($l $c $h)
57 )
58 )
59 );
60}
61
62@function parse-oklch($color) {
63 @if meta.type-of($color) == 'color' {
64 @return blend-convert.Lab_to_LCH(
65 lin_sRGB_to_Oklab(
66 blend-convert.lin_sRGB(
67 blend-convert.sassToRgb($color)
68 )
69 )
70 );
71 }
72
73 @if meta.type-of($color) != 'string' {
74 @return null;
75 }
76
77 @if string.slice($color, 1, 6) == 'oklch(' {
78 $args: string.split(string.slice($color, 7, -2), ' ');
79
80 $l: math.div(iro.fn-to-number(list.nth($args, 1)), 100%);
81 $c: iro.fn-to-number(list.nth($args, 2));
82 $h: iro.fn-to-number(list.nth($args, 3));
83
84 @return $l $c $h;
85 }
86
87 @return null;
88}
diff --git a/src/index.scss b/src/index.scss
deleted file mode 100644
index 50927e2..0000000
--- a/src/index.scss
+++ /dev/null
@@ -1,10 +0,0 @@
1@use 'declare-vars';
2
3@use 'base';
4@use 'layouts';
5@use 'objects';
6@use 'scopes';
7@use 'themes';
8@use 'utils';
9
10@use 'apply-vars';
diff --git a/src/layouts/_button-group.scss b/src/layouts/_button-group.scss
index a70d27a..44719be 100644
--- a/src/layouts/_button-group.scss
+++ b/src/layouts/_button-group.scss
@@ -1,16 +1,50 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
3 5
4@include iro.props-namespace('button-group') { 6@forward 'button-group.vars';
5 @include iro.props-store(( 7@use 'button-group.vars' as vars;
6 --dims: ( 8@use '../objects/button.vars' as button;
7 --spacing: fn.global-dim(--size --150),
8 ),
9 ));
10 9
11 @include iro.bem-layout(iro.props-namespace()) { 10@mixin styles {
12 display: flex; 11 @include materialize-at-root(meta.module-variables('vars'));
13 gap: fn.dim(--spacing); 12
14 flex-wrap: wrap; 13 @include bem.layout('button-group') {
15 } 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 }
23
24 @include bem.modifier('align-block') {
25 margin-inline: calc(-1 * props.get(button.$pad-i) - props.get(button.$border-width));
26
27 @include bem.modifier('pill') {
28 margin-inline: calc(-1 * props.get(button.$pad-i-pill) - props.get(button.$border-width));
29 }
30
31 @include bem.modifier('icon') {
32 margin-inline: calc(-1 * props.get(button.$pad-b) - props.get(button.$border-width) - .5em * (props.get(button.$line-height) - 1));
33 }
34
35 @each $mod, $pad-i, $pad-i-label, $pad-i-pill, $pad-b, $font-size in button.$fixed-sizes {
36 @include bem.modifier('action-#{$mod}') {
37 margin-inline: calc(-1 * props.get($pad-i) - props.get(button.$border-width));
38
39 @include bem.modifier('pill') {
40 margin-inline: calc(-1 * props.get($pad-i-pill) - props.get(button.$border-width));
41 }
42
43 @include bem.modifier('icon') {
44 margin-inline: calc(-1 * props.get($pad-b) - props.get(button.$border-width) - .5em * (props.get(button.$line-height) - 1));
45 }
46 }
47 }
48 }
49 }
16} 50}
diff --git a/src/layouts/_button-group.vars.scss b/src/layouts/_button-group.vars.scss
new file mode 100644
index 0000000..b56eec7
--- /dev/null
+++ b/src/layouts/_button-group.vars.scss
@@ -0,0 +1,16 @@
1@use 'iro-sass/src/props';
2@use '../core.vars' as core;
3
4$gap: props.def(--l-button-group--gap, props.get(core.$size--150)) !default;
5
6$gapless: props.def(--l-button-group--gapless, 0) !default;
7$sm: props.def(--l-button-group--sm, props.get(core.$size--100)) !default;
8$lg: props.def(--l-button-group--lg, props.get(core.$size--300)) !default;
9$xl: props.def(--l-button-group--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/_card-list.scss b/src/layouts/_card-list.scss
index 65b6a66..aedbfd0 100644
--- a/src/layouts/_card-list.scss
+++ b/src/layouts/_card-list.scss
@@ -1,96 +1,158 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn;
3@use 'include-media/dist/include-media' as media; 2@use 'include-media/dist/include-media' as media;
3@use 'iro-sass/src/bem';
4@use 'iro-sass/src/props';
5@use '../props' as *;
4 6
5@include iro.props-namespace('card-list') { 7@forward 'card-list.vars';
6 @include iro.props-store(( 8@use 'card-list.vars' as vars;
7 --dims: (
8 --row-gap: fn.global-dim(--size --800),
9 --col-gap: fn.global-dim(--size --400),
10 9
11 --grid: ( 10@mixin styles {
12 --row-gap: fn.global-dim(--size --800), 11 @include materialize-at-root(meta.module-variables('vars'));
13 --col-gap: fn.global-dim(--size --400),
14 --col-width: fn.global-dim(--size --3200),
15 ),
16 --masonry: (
17 --row-gap: fn.global-dim(--size --800),
18 --col-gap: fn.global-dim(--size --400),
19 --col-width: fn.global-dim(--size --3200),
20 ),
21 --masonry-h: (
22 --row-gap: fn.global-dim(--size --800),
23 --col-gap: fn.global-dim(--size --400),
24 --row-height: fn.global-dim(--size --3200),
25 )
26 ),
27 --colors: (
28 --border: fn.global-color(--border),
29 ),
30 ));
31 12
32 @include iro.bem-layout(iro.props-namespace()) { 13 @include bem.layout('card-list') {
33 display: flex; 14 display: flex;
34 flex-direction: column; 15 flex-direction: column;
35 gap: fn.dim(--row-gap) fn.dim(--col-gap); 16 gap: props.get(vars.$row-gap);
36 17
37 @include iro.bem-modifier('grid') { 18 @include bem.modifier('merge') {
38 display: grid; 19 position: relative;
39 grid-template-columns: repeat(auto-fill, minmax(fn.dim(--grid --col-width), 1fr)); 20 gap: calc(2 * props.get(vars.$merge-padding) + props.get(vars.$border-width));
40 gap: fn.dim(--grid --col-gap); 21 padding: props.get(vars.$merge-padding);
22 background-color: props.get(vars.$card-bg-color);
23 border: props.get(vars.$border-width) solid props.get(vars.$border-color);
24 border-radius: calc(props.get(vars.$rounding) + props.get(vars.$merge-padding));
41 25
42 @include iro.bem-modifier('quiet') { 26 @include bem.elem('card') {
43 row-gap: fn.dim(--grid --row-gap); 27 &:not(:last-child) {
44 } 28 position: relative;
45 } 29 border-end-start-radius: 0;
30 border-end-end-radius: 0;
46 31
47 @include iro.bem-modifier('masonry') { 32 &::after {
48 display: block; 33 position: absolute;
49 columns: auto fn.dim(--masonry --col-width); 34 inset-block-start: calc(100% + props.get(vars.$merge-padding) + props.get(vars.$border-width));
50 column-gap: fn.dim(--masonry --col-gap); 35 inset-inline: calc(-1 * props.get(vars.$merge-padding) - props.get(vars.$border-width));
36 display: block;
37 block-size: props.get(vars.$border-width);
38 content: '';
39 background-color: props.get(vars.$border-color);
40 }
41 }
51 42
52 @include iro.bem-elem('card') { 43 &:hover,
53 margin-block-end: fn.dim(--masonry --col-gap); 44 &:active,
54 break-inside: avoid; 45 &:focus-visible {
55 } 46 transform: none;
47 }
56 48
57 @include iro.bem-modifier('quiet') { 49 @include bem.next-twin-elem {
58 @include iro.bem-elem('card') { 50 border-start-start-radius: 0;
59 margin-block-end: fn.dim(--masonry --row-gap); 51 border-start-end-radius: 0;
60 } 52 }
61 } 53 }
62 }
63 54
64 @include iro.bem-modifier('masonry-h') { 55 @include bem.modifier('borderless') {
65 flex-flow: row wrap; 56 border-color: props.get(vars.$card-bg-color);
66 gap: fn.dim(--masonry-h --col-gap);
67 57
68 &::after { 58 @include bem.elem('card') {
69 content: ''; 59 &:not(:last-child) {
70 display: block; 60 &::after {
71 flex: 1 0 auto; 61 inset-inline: calc(-1 * props.get(vars.$merge-padding) - 2 * props.get(vars.$border-width));
72 inline-size: fn.dim(--masonry-h --row-height); 62 }
73 block-size: 0; 63 }
74 } 64 }
65 }
75 66
76 @include iro.bem-elem('card') { 67 @include bem.modifier('shadow') {
77 flex: 1 0 auto; 68 box-shadow:
78 max-inline-size: 100%; 69 props.get(vars.$shadow-x)
79 } 70 props.get(vars.$shadow-y)
71 props.get(vars.$shadow-blur)
72 props.get(vars.$shadow-grow)
73 props.get(vars.$shadow-color);
74 }
75 }
80 76
81 @include iro.bem-elem('card-image') { 77 @include bem.modifier('quiet') {
82 block-size: fn.dim(--masonry-h --row-height); 78 row-gap: props.get(vars.$quiet--row-gap);
83 } 79 }
84 80
85 @include iro.bem-modifier('quiet') { 81 @include bem.modifier('grid') {
86 row-gap: fn.dim(--masonry-h --row-gap); 82 display: grid;
87 } 83 grid-template-columns: repeat(auto-fill, minmax(props.get(vars.$grid--col-width), 1fr));
88 } 84 gap: props.get(vars.$grid--row-gap) props.get(vars.$grid--col-gap);
89 85
90 @include iro.bem-modifier('aspect-5\\/4') { 86 @include bem.modifier('quiet') {
91 @include iro.bem-elem('card-image') { 87 row-gap: props.get(vars.$grid--quiet--row-gap);
92 aspect-ratio: 5 / 4; 88 }
93 } 89 }
94 } 90
95 } 91 @include bem.modifier('grid-sm') {
92 display: grid;
93 grid-template-columns: repeat(auto-fill, minmax(props.get(vars.$grid-sm--col-width), 1fr));
94 gap: props.get(vars.$grid-sm--row-gap) props.get(vars.$grid-sm--col-gap);
95
96 @include bem.modifier('grid-sm') {
97 @include media.media('<=md') {
98 display: flex;
99 gap: props.get(vars.$row-gap);
100 }
101 }
102
103 @include bem.modifier('quiet') {
104 row-gap: props.get(vars.$grid-sm--quiet--row-gap);
105 }
106 }
107
108 @include bem.modifier('masonry') {
109 display: block;
110 columns: auto props.get(vars.$masonry--col-width);
111 column-gap: props.get(vars.$masonry--col-gap);
112
113 @include bem.elem('card') {
114 margin-block-end: props.get(vars.$masonry--row-gap);
115 break-inside: avoid;
116 }
117
118 @include bem.modifier('quiet') {
119 @include bem.elem('card') {
120 margin-block-end: props.get(vars.$masonry--quiet--row-gap);
121 }
122 }
123 }
124
125 @include bem.modifier('masonry-h') {
126 flex-flow: row wrap;
127 gap: props.get(vars.$masonry-h--row-gap) props.get(vars.$masonry-h--col-gap);
128
129 @include bem.modifier('no-flush') {
130 &::after {
131 display: block;
132 flex: 1 0 auto;
133 inline-size: props.get(vars.$masonry-h--row-height);
134 content: '';
135 }
136 }
137
138 @include bem.elem('card') {
139 flex: 1 0 auto;
140 max-inline-size: 100%;
141 }
142
143 @include bem.elem('card-image') {
144 block-size: props.get(vars.$masonry-h--row-height);
145 }
146
147 @include bem.modifier('quiet') {
148 row-gap: props.get(vars.$masonry-h--quiet--row-gap);
149 }
150 }
151
152 @include bem.modifier('aspect-5\\/4') {
153 @include bem.elem('card-image') {
154 aspect-ratio: 5 / 4;
155 }
156 }
157 }
96} 158}
diff --git a/src/layouts/_card-list.vars.scss b/src/layouts/_card-list.vars.scss
new file mode 100644
index 0000000..75e72cc
--- /dev/null
+++ b/src/layouts/_card-list.vars.scss
@@ -0,0 +1,41 @@
1@use 'iro-sass/src/props';
2@use '../core.vars' as core;
3@use '../objects/card' as card;
4
5$border-width: props.def(--l-card-list--border-width, props.get(card.$border-width)) !default;
6$merge-padding: props.def(--l-card-list--merge-padding, props.get(core.$border-width--thick)) !default;
7$rounding: props.def(--l-card-list--rounding, props.get(card.$rounding)) !default;
8
9$row-gap: props.def(--l-card-list--row-gap, props.get(core.$size--200)) !default;
10$quiet--row-gap: props.def(--l-card-list--quiet--row-gap, props.get(core.$size--800)) !default;
11
12$grid--row-gap: props.def(--l-card-list--grid--row-gap, props.get(core.$size--400)) !default;
13$grid--col-gap: props.def(--l-card-list--grid--col-gap, props.get(core.$size--400)) !default;
14$grid--col-width: props.def(--l-card-list--grid--col-width, props.get(core.$size--3200)) !default;
15$grid--quiet--row-gap: props.def(--l-card-list--grid--quiet--row-gap, props.get(core.$size--800)) !default;
16
17$grid-sm--row-gap: props.def(--l-card-list--grid-md--row-gap, props.get(core.$size--200)) !default;
18$grid-sm--col-gap: props.def(--l-card-list--grid-md--col-gap, props.get(core.$size--200)) !default;
19$grid-sm--col-width: props.def(--l-card-list--grid-md--col-width, props.get(core.$size--4600)) !default;
20$grid-sm--quiet--row-gap: props.def(--l-card-list--grid-sm--quiet--row-gap, props.get(core.$size--800)) !default;
21
22$masonry--row-gap: props.def(--l-card-list--masonry--row-gap, props.get(core.$size--400)) !default;
23$masonry--col-gap: props.def(--l-card-list--masonry--col-gap, props.get(core.$size--400)) !default;
24$masonry--col-width: props.def(--l-card-list--masonry--col-width, props.get(core.$size--3200)) !default;
25$masonry--quiet--row-gap: props.def(--l-card-list--masonry--quiet--row-gap, props.get(core.$size--800)) !default;
26
27$masonry-h--row-gap: props.def(--l-card-list--masonry-h--row-gap, props.get(core.$size--400)) !default;
28$masonry-h--col-gap: props.def(--l-card-list--masonry-h--col-gap, props.get(core.$size--400)) !default;
29$masonry-h--row-height: props.def(--l-card-list--masonry-h--row-height, props.get(core.$size--3200)) !default;
30$masonry-h--quiet--row-gap: props.def(--l-card-list--masonry-h--quiet--row-gap, props.get(core.$size--800)) !default;
31
32$shadow-x: props.def(--l-card-list--shadow-x, props.get(card.$shadow-x)) !default;
33$shadow-y: props.def(--l-card-list--shadow-y, props.get(card.$shadow-y)) !default;
34$shadow-blur: props.def(--l-card-list--shadow-blur, props.get(card.$shadow-blur)) !default;
35$shadow-grow: props.def(--l-card-list--shadow-grow, props.get(card.$shadow-grow)) !default;
36
37$card-bg-color: props.def(--l-card-list--bg-color, props.get(card.$bg-color), 'color') !default;
38$border-color: props.def(--l-card-list--border-color, props.get(card.$border-color), 'color') !default;
39$shadow-color: props.def(--l-card-list--shadow-color, props.get(card.$shadow-color), 'color') !default;
40
41$border-color-dark: props.def(--l-card-list--border-color, props.get(core.$theme, --bg-l1), 'dark') !default;
diff --git a/src/layouts/_container.scss b/src/layouts/_container.scss
index d13c4f3..0ae68c1 100644
--- a/src/layouts/_container.scss
+++ b/src/layouts/_container.scss
@@ -1,45 +1,28 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
3 5
4@include iro.props-namespace('container') { 6@forward 'container.vars';
5 @include iro.props-store(( 7@use 'container.vars' as vars;
6 --dims: (
7 --narrow-125: iro.fn-px-to-rem(720px),
8 --narrow: iro.fn-px-to-rem(610px),
9 --narrow-75: iro.fn-px-to-rem(500px),
10 --pad-i: fn.global-dim(--size --400),
11 --pad-b: fn.global-dim(--size --800),
12 )
13 ));
14 8
15 @include iro.props-store(( 9@mixin styles {
16 --dims: ( 10 @include materialize-at-root(meta.module-variables('vars'));
17 --pad-i: fn.global-dim(--size --200),
18 --pad-b: fn.global-dim(--size --600),
19 )
20 ), 'sm');
21 11
22 @include iro.props-store(( 12 @include bem.layout('container') {
23 --dims: ( 13 @each $mod, $size in vars.$fixed-sizes {
24 --pad-i: fn.global-dim(--size --150), 14 @include bem.modifier($mod) {
25 --pad-b: fn.global-dim(--size --450), 15 max-inline-size: props.get($size);
26 ) 16 margin-inline: auto;
27 ), 'xs'); 17 }
18 }
28 19
29 @include iro.bem-layout(iro.props-namespace()) { 20 @include bem.modifier('pad-i') {
30 @each $size in 'narrow-125' 'narrow' 'narrow-75' { 21 padding-inline: props.get(vars.$pad-i);
31 @include iro.bem-modifier($size) { 22 }
32 max-inline-size: fn.dim(--#{$size});
33 margin-inline: auto;
34 }
35 }
36 23
37 @include iro.bem-modifier('pad-i') { 24 @include bem.modifier('pad-b') {
38 padding-inline: fn.dim(--pad-i); 25 padding-block: props.get(vars.$pad-b);
39 } 26 }
40 27 }
41 @include iro.bem-modifier('pad-b') {
42 padding-block: fn.dim(--pad-b);
43 }
44 }
45} 28}
diff --git a/src/layouts/_container.vars.scss b/src/layouts/_container.vars.scss
new file mode 100644
index 0000000..8f0cef6
--- /dev/null
+++ b/src/layouts/_container.vars.scss
@@ -0,0 +1,22 @@
1@use 'iro-sass/src/functions' as fn;
2@use 'iro-sass/src/props';
3@use '../core.vars' as core;
4
5$fixed-200: props.def(--l-container--fixed-200, fn.px-to-rem(1300px)) !default;
6$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;
8
9$fixed-sizes: (
10 'fixed-200': $fixed-200,
11 'fixed-150': $fixed-150,
12 'fixed': $fixed
13) !default;
14
15$pad-i: props.def(--l-container--pad-i, props.get(core.$size--400)) !default;
16$pad-b: props.def(--l-container--pad-b, props.get(core.$size--800)) !default;
17
18$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;
20
21$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;
diff --git a/src/layouts/_flex.scss b/src/layouts/_flex.scss
index d3f4f9c..c99b253 100644
--- a/src/layouts/_flex.scss
+++ b/src/layouts/_flex.scss
@@ -1,27 +1,19 @@
1@use 'iro-sass/src/index' as iro; 1@use 'iro-sass/src/bem';
2 2
3@include iro.props-namespace('flex') { 3@mixin styles {
4 @include iro.bem-layout(iro.props-namespace()) { 4 @include bem.layout('flex') {
5 display: flex; 5 display: flex;
6 6
7 @include iro.bem-modifier('align-stretch') { 7 @include bem.modifier('column') {
8 align-items: stretch; 8 flex-direction: column;
9 } 9 }
10 10
11 @include iro.bem-modifier('align-center') { 11 @include bem.modifier('wrap') {
12 align-items: center; 12 flex-wrap: wrap;
13 } 13 }
14 14
15 @include iro.bem-modifier('align-start') { 15 @include bem.modifier('wrap-reverse') {
16 align-items: flex-start; 16 flex-wrap: wrap-reverse;
17 } 17 }
18 18 }
19 @include iro.bem-modifier('align-end') {
20 align-items: flex-end;
21 }
22
23 @include iro.bem-modifier('column') {
24 flex-direction: column;
25 }
26 }
27} 19}
diff --git a/src/layouts/_form.scss b/src/layouts/_form.scss
index f6b60ea..c804262 100644
--- a/src/layouts/_form.scss
+++ b/src/layouts/_form.scss
@@ -1,62 +1,59 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
3 5
4// @use '../objects/field-label'; 6@forward 'form.vars';
7@use 'form.vars' as vars;
5 8
6@include iro.props-namespace('form') { 9@mixin styles {
7 @include iro.props-store(( 10 @include materialize-at-root(meta.module-variables('vars'));
8 --dims: (
9 --item-spacing-b: fn.global-dim(--size --325),
10 --label-spacing-i: fn.global-dim(--size --325),
11 --hint-font-size: fn.global-dim(--font-size --75),
12 ),
13 ));
14 11
15 @include iro.bem-layout(iro.props-namespace()) { 12 @include bem.layout('form') {
16 display: flex; 13 display: flex;
17 flex-direction: column; 14 flex-direction: column;
18 gap: fn.dim(--item-spacing-b) fn.dim(--label-spacing-i); 15 gap: props.get(vars.$item-spacing-b) props.get(vars.$label-spacing-i);
19 16
20 @include iro.bem-elem('item') { 17 @include bem.elem('item') {
21 display: block; 18 display: block;
22 } 19 }
23 20
24 @include iro.bem-elem('item-content') { 21 @include bem.elem('item-content') {
25 @include iro.bem-modifier('align-start') { 22 @include bem.modifier('align-start') {
26 align-self: start; 23 align-self: start;
27 } 24 }
28 } 25 }
29 26
30 @include iro.bem-modifier('row') { 27 @include bem.modifier('row') {
31 flex-direction: row; 28 flex-direction: row;
32 align-items: flex-end; 29 align-items: flex-end;
33 } 30 }
34 31
35 @include iro.bem-modifier('labels-start', 'labels-end') { 32 @include bem.modifier('labels-start', 'labels-end') {
36 display: grid; 33 display: grid;
37 grid-template-columns: auto 1fr; 34 grid-template-rows: auto;
38 grid-template-rows: auto; 35 grid-template-columns: auto 1fr;
39 align-items: baseline; 36 align-items: baseline;
40 37
41 @include iro.bem-elem('item') { 38 @include bem.elem('item') {
42 display: contents; 39 display: contents;
43 } 40 }
44 41
45 @include iro.bem-elem('item-label') { 42 @include bem.elem('item-label') {
46 grid-column: 1; 43 grid-column: 1;
47 padding-inline-end: 0; 44 padding-inline-end: 0;
48 } 45 }
49 46
50 @include iro.bem-elem('item-content') { 47 @include bem.elem('item-content') {
51 grid-column: 2; 48 grid-column: 2;
52 margin-block-start: 0; 49 margin-block-start: 0;
53 } 50 }
54 } 51 }
55 52
56 @include iro.bem-modifier('labels-end') { 53 @include bem.modifier('labels-end') {
57 @include iro.bem-elem('item-label') { 54 @include bem.elem('item-label') {
58 text-align: end; 55 text-align: end;
59 } 56 }
60 } 57 }
61 } 58 }
62} 59}
diff --git a/src/layouts/_form.vars.scss b/src/layouts/_form.vars.scss
new file mode 100644
index 0000000..c533e6b
--- /dev/null
+++ b/src/layouts/_form.vars.scss
@@ -0,0 +1,5 @@
1@use 'iro-sass/src/props';
2@use '../core.vars' as core;
3
4$item-spacing-b: props.def(--l-form--item-spacing-b, props.get(core.$size--325)) !default;
5$label-spacing-i: props.def(--l-form--label-spacing-i, props.get(core.$size--325)) !default;
diff --git a/src/layouts/_media.scss b/src/layouts/_media.scss
index c42aa3e..929e60f 100644
--- a/src/layouts/_media.scss
+++ b/src/layouts/_media.scss
@@ -1,47 +1,41 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
3 5
4$sizes: 'gapless' 'sm' 'lg' 'xl' !default; 6@forward 'media.vars';
7@use 'media.vars' as vars;
5 8
6@include iro.props-namespace('media') { 9@mixin styles {
7 @include iro.props-store(( 10 @include materialize-at-root(meta.module-variables('vars'));
8 --dims: (
9 --gap: fn.global-dim(--size --150),
10 11
11 --gapless: 0, 12 @include bem.layout('media') {
12 --sm: fn.global-dim(--size --100), 13 display: flex;
13 --lg: fn.global-dim(--size --300), 14 gap: props.get(vars.$gap);
14 --xl: fn.global-dim(--size --450), 15 align-items: center;
15 ) 16 line-height: 1.4;
16 ));
17 17
18 @include iro.bem-layout(iro.props-namespace()) { 18 @each $mod, $size in vars.$sizes {
19 display: flex; 19 @include bem.modifier($mod) {
20 align-items: center; 20 gap: props.get($size);
21 gap: fn.dim(--gap); 21 }
22 line-height: 1.4; 22 }
23 23
24 @each $size in $sizes { 24 @include bem.modifier('wrap') {
25 @include iro.bem-modifier($size) { 25 flex-wrap: wrap;
26 gap: fn.dim(--#{$size}); 26 }
27 }
28 }
29 27
30 @include iro.bem-modifier('wrap') { 28 @include bem.elem('block') {
31 flex-wrap: wrap; 29 flex: 0 0 auto;
32 }
33 30
34 @include iro.bem-elem('block') { 31 @include bem.modifier('shrink', 'main') {
35 flex: 0 0 auto; 32 flex-shrink: 1;
33 min-inline-size: 0;
34 }
36 35
37 @include iro.bem-modifier('shrink', 'main') { 36 @include bem.modifier('main') {
38 flex-shrink: 1; 37 inline-size: 100%;
39 min-inline-size: 0; 38 }
40 } 39 }
41 40 }
42 @include iro.bem-modifier('main') {
43 inline-size: 100%;
44 }
45 }
46 }
47} 41}
diff --git a/src/layouts/_media.vars.scss b/src/layouts/_media.vars.scss
new file mode 100644
index 0000000..dcb10de
--- /dev/null
+++ b/src/layouts/_media.vars.scss
@@ -0,0 +1,16 @@
1@use 'iro-sass/src/props';
2@use '../core.vars' as core;
3
4$gap: props.def(--l-media--gap, props.get(core.$size--150)) !default;
5
6$gapless: props.def(--l-media--gapless, 0) !default;
7$sm: props.def(--l-media--sm, props.get(core.$size--100)) !default;
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;
10
11$sizes: (
12 'gapless': $gapless,
13 'sm': $sm,
14 'lg': $lg,
15 'xl': $xl,
16) !default;
diff --git a/src/layouts/_overflow.scss b/src/layouts/_overflow.scss
index 8643bbf..6d31d37 100644
--- a/src/layouts/_overflow.scss
+++ b/src/layouts/_overflow.scss
@@ -1,9 +1,11 @@
1@use 'iro-sass/src/index' as iro; 1@use 'iro-sass/src/bem';
2@use '../functions' as fn; 2@use 'iro-sass/src/props';
3@use '../core.vars' as core;
3 4
4@include iro.props-namespace('overflow') { 5@mixin styles {
5 @include iro.bem-layout(iro.props-namespace()) { 6 @include bem.layout('overflow') {
6 overflow: auto; 7 overflow: auto;
7 scrollbar-color: fn.global-color(--text-disabled) transparent; 8 scrollbar-color: props.get(core.$theme, --text-disabled) transparent;
8 } 9 }
9} 10}
11
diff --git a/src/layouts/_split-view.scss b/src/layouts/_split-view.scss
new file mode 100644
index 0000000..6469a7d
--- /dev/null
+++ b/src/layouts/_split-view.scss
@@ -0,0 +1,91 @@
1@use 'sass:meta';
2@use 'include-media/dist/include-media' as media;
3@use 'iro-sass/src/bem';
4@use 'iro-sass/src/props';
5@use '../props' as *;
6
7@forward 'split-view.vars';
8@use 'split-view.vars' as vars;
9
10@mixin styles {
11 @include materialize-at-root(meta.module-variables('vars'));
12
13 @include bem.layout('split-view') {
14 display: flex;
15 gap: props.get(vars.$col-gap);
16 align-items: start;
17
18 @include bem.elem('panel') {
19 flex: 1 1 auto;
20 inline-size: 100%;
21 min-inline-size: 0;
22
23 @include bem.modifier('side-25') {
24 flex: 0 0 auto;
25 inline-size: 25%;
26 min-inline-size: props.get(vars.$panel--side-25--min);
27 }
28
29 @include bem.modifier('sticky-0') {
30 position: sticky;
31 inset-block-start: 0;
32 }
33
34 @include bem.modifier('sticky') {
35 position: sticky;
36 inset-block-start: props.get(vars.$panel--sticky-offset);
37 }
38
39 @include bem.modifier('sticky-400') {
40 position: sticky;
41 inset-block-start: calc(props.get(vars.$panel--sticky-400--inset) + props.get(vars.$panel--sticky-offset));
42 }
43
44 @include bem.modifier('sticky-1200') {
45 position: sticky;
46 inset-block-start: calc(props.get(vars.$panel--sticky-1200--inset) + props.get(vars.$panel--sticky-offset));
47 }
48 }
49
50 @include bem.modifier('gapless') {
51 gap: props.get(vars.$gapless);
52
53 @include bem.elem('panel') {
54 @include bem.modifier('side-25') {
55 min-inline-size: calc(props.get(vars.$panel--side-25--min) + props.get(vars.$col-gap) - props.get(vars.$gapless));
56 }
57 }
58 }
59
60 @include bem.elem('content') {
61 inline-size: 100%;
62 }
63
64 @include media.media('<=md') {
65 flex-direction: column;
66 gap: props.get(vars.$row-gap);
67 align-items: stretch;
68
69 @include bem.modifier('gapless') {
70 gap: props.get(vars.$gapless);
71 }
72
73 @include bem.modifier('wrap-reverse') {
74 flex-direction: column-reverse;
75 }
76
77 @include bem.elem('panel') {
78 inline-size: auto;
79
80 @include bem.modifier('side-25') {
81 inline-size: auto;
82 min-inline-size: 0;
83 }
84
85 @include bem.modifier('sticky', 'sticky-400', 'sticky-1200') {
86 position: static;
87 }
88 }
89 }
90 }
91}
diff --git a/src/layouts/_split-view.vars.scss b/src/layouts/_split-view.vars.scss
new file mode 100644
index 0000000..d519939
--- /dev/null
+++ b/src/layouts/_split-view.vars.scss
@@ -0,0 +1,13 @@
1@use 'iro-sass/src/props';
2@use '../core.vars' as core;
3
4$col-gap: props.def(--l-split-view--col-gap, props.get(core.$size--800)) !default;
5$row-gap: props.def(--l-split-view--row-gap, props.get(core.$size--600)) !default;
6
7$gapless: props.def(--l-split-view--gapless, 0rem) !default;
8
9$panel--side-25--min: props.def(--l-split-view--panel--side-25--min, props.get(core.$size--3200)) !default;
10$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;
12
13$panel--sticky-offset: props.def(--l-split-view--panel--sticky-offset, props.get(core.$sticky-top-offset)) !default;
diff --git a/src/objects/_action-button.scss b/src/objects/_action-button.scss
deleted file mode 100644
index 7fe9d44..0000000
--- a/src/objects/_action-button.scss
+++ /dev/null
@@ -1,343 +0,0 @@
1@use 'sass:list';
2@use 'iro-sass/src/index' as iro;
3@use '../functions' as fn;
4
5$sizes: 'sm' 'lg' 'xl' !default;
6$static-themes: 'black' 'white' !default;
7
8@mixin static-theme($theme: ()) {
9 border-color: fn.color(list.join($theme, --disabled --border));
10 background-color: fn.color(list.join($theme, --disabled --bg));
11 color: fn.color(list.join($theme, --disabled --label));
12
13 &::after {
14 outline-color: fn.color(list.join($theme, --key-focus --border));
15 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(list.join($theme, --key-focus --outline));
16 }
17
18 &:link,
19 &:visited,
20 &:enabled {
21 border-color: fn.color(list.join($theme, --border));
22 background-color: fn.color(list.join($theme, --bg));
23 color: fn.color(list.join($theme, --label));
24
25 &:hover,
26 &:focus-visible {
27 border-color: fn.color(list.join($theme, --hover --border));
28 background-color: fn.color(list.join($theme, --hover --bg));
29 color: fn.color(list.join($theme, --hover --label));
30 }
31
32 &:active {
33 border-color: fn.color(list.join($theme, --active --border));
34 background-color: fn.color(list.join($theme, --active --bg));
35 color: fn.color(list.join($theme, --active --label));
36 }
37 }
38
39 @include iro.bem-modifier('quiet') {
40 border-color: transparent;
41 background-color: transparent;
42 color: fn.color(list.join($theme, --quiet --disabled --label));
43
44 &:link,
45 &:visited,
46 &:enabled {
47 border-color: transparent;
48 background-color: transparent;
49 color: fn.color(list.join($theme, --quiet --label));
50
51 &:hover,
52 &:focus-visible {
53 border-color: transparent;
54 background-color: fn.color(list.join($theme, --quiet --hover --bg));
55 color: fn.color(list.join($theme, --quiet --hover --label));
56 }
57
58 &:active {
59 border-color: transparent;
60 background-color: fn.color(list.join($theme, --quiet --active --bg));
61 color: fn.color(list.join($theme, --quiet --active --label));
62 }
63 }
64 }
65
66 @include iro.bem-is('selected') {
67 border-color: fn.color(list.join($theme, --selected --disabled --border));
68 background-color: fn.color(list.join($theme, --selected --disabled --bg));
69 color: fn.color(list.join($theme, --selected --disabled --label));
70
71 &:link,
72 &:visited,
73 &:enabled {
74 border-color: fn.color(list.join($theme, --selected --border));
75 background-color: fn.color(list.join($theme, --selected --bg));
76 color: fn.color(list.join($theme, --selected --label));
77
78 &:hover,
79 &:focus-visible {
80 border-color: fn.color(list.join($theme, --selected --hover --border));
81 background-color: fn.color(list.join($theme, --selected --hover --bg));
82 color: fn.color(list.join($theme, --selected --hover --label));
83 }
84
85 &:active {
86 border-color: fn.color(list.join($theme, --selected --active --border));
87 background-color: fn.color(list.join($theme, --selected --active --bg));
88 color: fn.color(list.join($theme, --selected --active --label));
89 }
90 }
91 }
92}
93
94@include iro.props-namespace('action-button') {
95 @include iro.props-store((
96 --dims: (
97 --line-height: 1.4,
98 --pad-i: fn.global-dim(--size --150),
99 --pad-i-pill: fn.global-dim(--size --200),
100 --pad-b: fn.global-dim(--size --85),
101 --border: fn.global-dim(--border --thin),
102 --rounding: fn.global-dim(--rounding),
103 --font-size: fn.global-dim(--font-size --100),
104
105 --sm: (
106 --pad-i: fn.global-dim(--size --100),
107 --pad-i-pill: fn.global-dim(--size --150),
108 --pad-b: fn.global-dim(--size --40),
109 --font-size: fn.global-dim(--font-size --75),
110 ),
111 --lg: (
112 --pad-i: fn.global-dim(--size --175),
113 --pad-i-pill: fn.global-dim(--size --225),
114 --pad-b: fn.global-dim(--size --115),
115 --font-size: fn.global-dim(--font-size --150),
116 ),
117 --xl: (
118 --pad-i: fn.global-dim(--size --225),
119 --pad-i-pill: fn.global-dim(--size --300),
120 --pad-b: fn.global-dim(--size --150),
121 --font-size: fn.global-dim(--font-size --200),
122 ),
123
124 --key-focus: (
125 --border: fn.global-dim(--key-focus --border),
126 --border-offset: fn.global-dim(--key-focus --border-offset),
127 --outline: fn.global-dim(--key-focus --outline),
128 ),
129 ),
130 --colors: (
131 --bg: fn.global-color(--base --75),
132 --label: fn.global-color(--text),
133 --border: fn.global-color(--border-strong),
134
135 --hover: (
136 --bg: fn.global-color(--border-mute),
137 --label: fn.global-color(--heading),
138 --border: fn.global-color(--text-mute-more),
139 ),
140 --active: (
141 --bg: fn.global-color(--border),
142 --label: fn.global-color(--heading),
143 --border: fn.global-color(--text-mute),
144 ),
145 --disabled: (
146 --bg: fn.global-color(--bg-l1),
147 --label: fn.global-color(--border-strong),
148 --border: fn.global-color(--border),
149 ),
150 --key-focus: (
151 --border: fn.global-color(--focus --border),
152 --outline: fn.global-color(--focus --outline),
153 ),
154
155 --selected: (
156 --bg: fn.global-color(--text-mute),
157 --label: fn.global-color(--base --50),
158 --border: fn.global-color(--text-mute),
159
160 --hover: (
161 --bg: fn.global-color(--text),
162 --label: fn.global-color(--base --50),
163 --border: fn.global-color(--text),
164 ),
165 --active: (
166 --bg: fn.global-color(--heading),
167 --label: fn.global-color(--base --50),
168 --border: fn.global-color(--heading),
169 ),
170 --disabled: (
171 --bg: fn.global-color(--border-mute),
172 --label: fn.global-color(--border-strong),
173 --border: fn.global-color(--border-mute),
174 ),
175 ),
176
177 --quiet: (
178 --label: fn.global-color(--text),
179
180 --hover: (
181 --bg: fn.global-color(--border-mute),
182 --label: fn.global-color(--heading),
183 ),
184 --active: (
185 --bg: fn.global-color(--border),
186 --label: fn.global-color(--heading),
187 ),
188 --disabled: (
189 --label: fn.global-color(--border-strong),
190 ),
191 ),
192 ),
193 ));
194
195 @each $theme in $static-themes {
196 @include iro.props-store((
197 --colors: (
198 --static-#{$theme}: (
199 --bg: fn.global-color(--#{$theme}-transparent --100),
200 --label: fn.global-color(--#{$theme}-transparent --900),
201 --border: fn.global-color(--#{$theme}-transparent --400),
202
203 --hover: (
204 --bg: fn.global-color(--#{$theme}-transparent --300),
205 --label: fn.global-color(--#{$theme}-transparent --900),
206 --border: fn.global-color(--#{$theme}-transparent --500),
207 ),
208 --active: (
209 --bg: fn.global-color(--#{$theme}-transparent --400),
210 --label: fn.global-color(--#{$theme}-transparent --900),
211 --border: fn.global-color(--#{$theme}-transparent --600),
212 ),
213 --disabled: (
214 --bg: fn.global-color(--#{$theme}-transparent --100),
215 --label: fn.global-color(--#{$theme}-transparent --500),
216 --border: fn.global-color(--#{$theme}-transparent --300),
217 ),
218 --key-focus: (
219 --border: fn.global-color(--#{$theme}-transparent --900),
220 --outline: fn.global-color(--#{$theme}-transparent --300),
221 ),
222
223 --selected: (
224 --bg: fn.global-color(--#{$theme}-transparent --800),
225 --label: fn.global-color(--#{$theme}-transparent --text),
226 --border: fn.global-color(--#{$theme}-transparent --100),
227
228 --hover: (
229 --bg: fn.global-color(--#{$theme}-transparent --900),
230 --label: fn.global-color(--#{$theme}-transparent --text),
231 --border: fn.global-color(--#{$theme}-transparent --100),
232 ),
233 --active: (
234 --bg: fn.global-color(--#{$theme}-transparent --900),
235 --label: fn.global-color(--#{$theme}-transparent --text),
236 --border: fn.global-color(--#{$theme}-transparent --100),
237 ),
238 --disabled: (
239 --bg: fn.global-color(--#{$theme}-transparent --200),
240 --label: fn.global-color(--#{$theme}-transparent --500),
241 --border: fn.global-color(--#{$theme}-transparent --100),
242 ),
243 ),
244
245 --quiet: (
246 --label: fn.global-color(--#{$theme}-transparent --900),
247
248 --hover: (
249 --bg: fn.global-color(--#{$theme}-transparent --300),
250 --label: fn.global-color(--#{$theme}-transparent --900),
251 ),
252 --active: (
253 --bg: fn.global-color(--#{$theme}-transparent --400),
254 --label: fn.global-color(--#{$theme}-transparent --900),
255 ),
256 --disabled: (
257 --label: fn.global-color(--#{$theme}-transparent --500),
258 ),
259 ),
260 ),
261 )
262 ));
263 }
264
265 @include iro.bem-object(iro.props-namespace()) {
266 display: inline-block;
267 position: relative;
268 padding-block: fn.dim(--pad-b);
269 padding-inline: fn.dim(--pad-i);
270 border: fn.dim(--border) solid fn.color(--disabled --border);
271 border-radius: fn.dim(--rounding);
272 background-color: fn.color(--disabled --bg);
273 color: fn.color(--disabled --label);
274 line-height: fn.dim(--line-height);
275 text-align: center;
276 text-decoration: none;
277 text-overflow: ellipsis;
278 white-space: nowrap;
279
280 &::after {
281 content: '';
282 display: none;
283 position: absolute;
284 z-index: 1;
285 inset: calc(-1 * fn.dim(--border) - fn.dim(--key-focus --border-offset));
286 border-radius: calc(fn.dim(--rounding) + fn.dim(--key-focus --border-offset));
287 outline: fn.color(--key-focus --border) solid fn.dim(--key-focus --border);
288 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(--key-focus --outline);
289 pointer-events: none;
290 }
291
292 &:link,
293 &:visited,
294 &:enabled {
295 &:focus-visible {
296 &::after {
297 display: block;
298 }
299 }
300 }
301
302 @include static-theme;
303
304 @each $theme in $static-themes {
305 @include iro.bem-modifier(static-#{$theme}) {
306 @include static-theme(--static-#{$theme});
307 }
308 }
309
310 @include iro.bem-modifier('pill') {
311 padding-inline: fn.dim(--pad-i-pill);
312 border-radius: 100em;
313
314 &::after {
315 border-radius: 100em;
316 }
317 }
318
319 @each $size in $sizes {
320 @include iro.bem-modifier($size) {
321 padding-block: fn.dim(--#{$size} --pad-b);
322 padding-inline: fn.dim(--#{$size} --pad-i);
323 font-size: fn.dim(--#{$size} --font-size);
324
325 @include iro.bem-modifier('pill') {
326 padding-inline: fn.dim(--#{$size} --pad-i-pill);
327 }
328 }
329 }
330
331 @include iro.bem-modifier('icon') {
332 inline-size: calc(1em * fn.dim(--line-height) + 2 * fn.dim(--pad-b));
333 padding-inline: 0;
334
335 @each $size in $sizes {
336 @include iro.bem-modifier($size) {
337 inline-size: calc(1em * fn.dim(--line-height) + 2 * fn.dim(--#{$size} --pad-b));
338 padding-inline: 0;
339 }
340 }
341 }
342 }
343}
diff --git a/src/objects/_alert.scss b/src/objects/_alert.scss
index 067c00c..697ac18 100644
--- a/src/objects/_alert.scss
+++ b/src/objects/_alert.scss
@@ -1,43 +1,40 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:map';
2@use '../functions' as fn; 2@use 'sass:meta';
3@use 'iro-sass/src/bem';
4@use 'iro-sass/src/props';
5@use '../props' as *;
3 6
4$themes: 'accent' 'positive' 'negative' 'warning' !default; 7@forward 'alert.vars';
8@use 'alert.vars' as vars;
5 9
6@include iro.props-namespace('alert') { 10@mixin styles {
7 @include iro.props-store(( 11 @include materialize-at-root(meta.module-variables('vars'));
8 --dims: (
9 --border: fn.global-dim(--border --medium),
10 --pad-i: fn.global-dim(--size --250),
11 --pad-b: fn.global-dim(--size --200),
12 --rounding: fn.global-dim(--rounding),
13 ),
14 --colors: (
15 --bg: fn.global-color(--bg-l2),
16 --border: fn.global-color(--text-mute-more),
17 ),
18 ));
19 12
20 @each $theme in $themes { 13 @include bem.object('alert') {
21 @include iro.props-store(( 14 padding-block: props.get(vars.$pad-b);
22 --colors: ( 15 padding-inline: props.get(vars.$pad-i);
23 --#{$theme}: ( 16 background-color: props.get(vars.$bg-color);
24 --border: fn.global-color(--#{$theme} --700), 17 border: props.get(vars.$border-width) solid transparent;
25 ), 18 border-color: props.get(vars.$border-color);
26 ), 19 border-radius: props.get(vars.$rounding);
27 )); 20 box-shadow:
28 } 21 props.get(vars.$shadow-x)
22 props.get(vars.$shadow-y)
23 props.get(vars.$shadow-blur)
24 props.get(vars.$shadow-grow)
25 props.get(vars.$shadow-color);
29 26
30 @include iro.bem-object(iro.props-namespace()) { 27 @each $mod, $theme in vars.$themes-config {
31 padding-block: fn.dim(--pad-b); 28 @include bem.modifier($mod) {
32 padding-inline: fn.dim(--pad-i); 29 background-color: props.get(vars.$themes, $theme, --bg-color);
33 border: fn.dim(--border) solid fn.color(--border); 30 border-color: props.get(vars.$themes, $theme, --border-color);
34 border-radius: fn.dim(--rounding); 31 box-shadow:
35 background-color: fn.color(--bg); 32 props.get(vars.$shadow-x)
36 33 props.get(vars.$shadow-y)
37 @each $theme in $themes { 34 props.get(vars.$shadow-blur)
38 @include iro.bem-modifier($theme) { 35 props.get(vars.$shadow-grow)
39 border-color: fn.color(--#{$theme} --border); 36 props.get(vars.$themes, $theme, --shadow-color);
40 } 37 }
41 } 38 }
42 } 39 }
43} 40}
diff --git a/src/objects/_alert.vars.scss b/src/objects/_alert.vars.scss
new file mode 100644
index 0000000..62d3414
--- /dev/null
+++ b/src/objects/_alert.vars.scss
@@ -0,0 +1,36 @@
1@use 'iro-sass/src/props';
2@use '../core.vars' as core;
3
4$border-width: props.def(--o-alert--border-width, props.get(core.$border-width--medium)) !default;
5$pad-i: props.def(--o-alert--pad-i, props.get(core.$size--250)) !default;
6$pad-b: props.def(--o-alert--pad-b, props.get(core.$size--200)) !default;
7$rounding: props.def(--o-alert--rounding, props.get(core.$rounding)) !default;
8
9$shadow-x: props.def(--o-alert--shadow-x, props.get(core.$shadow--l2--x)) !default;
10$shadow-y: props.def(--o-alert--shadow-y, props.get(core.$shadow--l2--y)) !default;
11$shadow-blur: props.def(--o-alert--shadow-blur, props.get(core.$shadow--l2--blur)) !default;
12$shadow-grow: props.def(--o-alert--shadow-grow, props.get(core.$shadow--l2--grow)) !default;
13
14$bg-color: props.def(--o-alert--bg-color, props.get(core.$theme, --bg-l2), 'color') !default;
15$border-color: props.def(--o-alert--border-color, props.get(core.$theme, --text-mute-more) props.get(core.$theme, --text-mute-more) props.get(core.$theme, --text-mute), 'color') !default;
16
17$shadow-color: props.def(--o-alert--shadow-color, props.get(core.$transparent-colors, --black, --200), 'color') !default;
18
19$themes-config: (
20 accent: --accent,
21 positive: --positive,
22 negative: --negative,
23 warning: --warning,
24) !default;
25
26$themes: props.def(--o-alert, (), 'color');
27
28@each $theme, $key in $themes-config {
29 $themes: props.merge($themes, (
30 $key: (
31 --bg-color: props.get(core.$theme, --bg-l2),
32 --border-color: props.get(core.$theme, $key, --700) props.get(core.$theme, $key, --700) props.get(core.$theme, $key, --800),
33 --shadow-color: props.get(core.$theme, $key, --200),
34 )
35 ));
36}
diff --git a/src/objects/_avatar.scss b/src/objects/_avatar.scss
index 19bff10..9d51ffb 100644
--- a/src/objects/_avatar.scss
+++ b/src/objects/_avatar.scss
@@ -1,167 +1,126 @@
1@use 'sass:list'; 1@use 'sass:meta';
2@use 'iro-sass/src/index' as iro; 2@use 'iro-sass/src/bem';
3@use '../functions' as fn; 3@use 'iro-sass/src/props';
4@use '../props' as *;
4 5
5$sizes: 'xs' 'sm' 'lg' 'xl' 'xxl' 'xxxl'; 6@forward 'avatar.vars';
7@use 'avatar.vars' as vars;
6 8
7@mixin status($size: ()) { 9@mixin status($indicator-size) {
8 @include iro.bem-elem('status') { 10 @include bem.elem('status') {
9 inline-size: fn.dim(list.join($size, --indicator-size)); 11 inline-size: props.get($indicator-size);
10 block-size: fn.dim(list.join($size, --indicator-size)); 12 block-size: props.get($indicator-size);
11 13
12 @include iro.bem-next-elem('content') { 14 @include bem.sibling-elem('content') {
13 mask-image: radial-gradient( 15 mask-image: radial-gradient(circle calc(.5 * props.get($indicator-size) + props.get(vars.$indicator-spacing)) at
14 circle calc(.5 * fn.dim(list.join($size, --indicator-size)) + fn.dim(--indicator-spacing)) at 16 calc(100% - .5 * props.get($indicator-size))
15 calc(100% - .5 * fn.dim(list.join($size, --indicator-size))) 17 calc(100% - .5 * props.get($indicator-size)),
16 calc(100% - .5 * fn.dim(list.join($size, --indicator-size))), 18 transparent 95%,
17 transparent 95%, 19 #fff);
18 #fff 20 }
19 ); 21 }
20 }
21 }
22} 22}
23 23
24@include iro.props-namespace('avatar') { 24@mixin styles {
25 @include iro.props-store(( 25 @include materialize-at-root(meta.module-variables('vars'));
26 --dims: (
27 --size: fn.global-dim(--size --500),
28 --font-size: fn.global-dim(--font-size --100),
29 --indicator-size: fn.global-dim(--size --150),
30 --indicator-spacing: fn.global-dim(--size --40),
31 --rounding: 25%,
32 26
33 --xxxl: ( 27 @include bem.object('avatar') {
34 --size: fn.global-dim(--size --1600), 28 position: relative;
35 --font-size: fn.global-dim(--font-size --800), 29 display: inline-block;
36 --indicator-size: fn.global-dim(--size --400), 30 font-size: props.get(vars.$font-size);
37 ), 31 font-style: normal;
38 --xxl: ( 32 vertical-align: .05em;
39 --size: fn.global-dim(--size --1200), 33 border-radius: props.get(vars.$rounding);
40 --font-size: fn.global-dim(--font-size --600),
41 --indicator-size: fn.global-dim(--size --300),
42 ),
43 --xl: (
44 --size: fn.global-dim(--size --800),
45 --font-size: fn.global-dim(--font-size --300),
46 --indicator-size: fn.global-dim(--size --225),
47 ),
48 --lg: (
49 --size: fn.global-dim(--size --650),
50 --font-size: fn.global-dim(--font-size --200),
51 --indicator-size: fn.global-dim(--size --175),
52 ),
53 --sm: (
54 --size: fn.global-dim(--size --375),
55 --font-size: fn.global-dim(--font-size --75),
56 --indicator-size: fn.global-dim(--size --125),
57 ),
58 --xs: (
59 --size: fn.global-dim(--size --250),
60 --font-size: fn.global-dim(--font-size --50),
61 --indicator-size: fn.global-dim(--size --100),
62 ),
63
64 --key-focus: (
65 --border: fn.global-dim(--key-focus --border),
66 --border-offset: fn.global-dim(--key-focus --border-offset),
67 --outline: fn.global-dim(--key-focus --outline),
68 ),
69 ),
70 --colors: (
71 --h: 354,
72 --s: 44%,
73 --l: 45%,
74 34
75 --key-focus: ( 35 &::after {
76 --border: fn.global-color(--focus --border), 36 position: absolute;
77 --outline: fn.global-color(--focus --outline), 37 inset: calc(-1 * props.get(vars.$key-focus--border-offset));
78 ), 38 z-index: 1;
79 ), 39 display: none;
80 )); 40 pointer-events: none;
41 outline: props.get(vars.$key-focus--border-color) solid props.get(vars.$key-focus--border-width);
42 content: '';
43 border: props.get(vars.$key-focus--border-offset) solid transparent;
44 border-radius: props.get(vars.$rounding);
45 box-shadow:
46 0
47 0
48 0
49 calc(props.get(vars.$key-focus--border-width) + props.get(vars.$key-focus--outline-width))
50 props.get(vars.$key-focus--outline-color);
51 }
81 52
82 @include iro.bem-object(iro.props-namespace()) { 53 @include bem.elem('status') {
83 display: inline-block; 54 position: absolute;
84 position: relative; 55 inset-block-end: 0;
85 border-radius: fn.dim(--rounding); 56 inset-inline-end: 0;
86 font-size: fn.dim(--font-size); 57 }
87 font-style: normal;
88 vertical-align: .05em;
89 58
90 &::after { 59 @include status(vars.$indicator-size);
91 content: '';
92 display: none;
93 position: absolute;
94 z-index: 1;
95 inset: calc(-1 * fn.dim(--key-focus --border-offset));
96 border: fn.dim(--key-focus --border-offset) solid transparent;
97 border-radius: fn.dim(--rounding);
98 outline: fn.color(--key-focus --border) solid fn.dim(--key-focus --border);
99 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(--key-focus --outline);
100 pointer-events: none;
101 }
102 60
103 @include iro.bem-elem('status') { 61 @include bem.elem('content') {
104 position: absolute; 62 display: block;
105 inset-inline-end: 0; 63 inline-size: props.get(vars.$size);
106 inset-block-end: 0; 64 block-size: props.get(vars.$size);
107 } 65 line-height: props.get(vars.$size);
66 text-align: center;
67 object-fit: cover;
68 object-position: center center;
69 border-radius: props.get(vars.$rounding);
70 }
108 71
109 @include status; 72 @include bem.modifier('circle') {
73 border-radius: 100%;
110 74
111 @include iro.bem-elem('content') { 75 &::after {
112 display: block; 76 border-radius: 100%;
113 inline-size: fn.dim(--size); 77 }
114 block-size: fn.dim(--size);
115 border-radius: fn.dim(--rounding);
116 line-height: fn.dim(--size);
117 text-align: center;
118 object-fit: cover;
119 object-position: center center;
120 }
121 78
122 @include iro.bem-modifier('circle') { 79 @include bem.elem('content') {
123 border-radius: 100%; 80 border-radius: 100%;
81 }
82 }
124 83
125 &::after { 84 @include bem.modifier('placeholder') {
126 border-radius: 100%; 85 @include bem.elem('content') {
127 } 86 background-color: hsl(0, 0%, props.get(vars.$bg-color--l));
87 }
88 }
128 89
129 @include iro.bem-elem('content') { 90 @include bem.modifier('colored') {
130 border-radius: 100%; 91 @include bem.elem('content') {
131 } 92 color: #fff;
132 } 93 background-color: hsl(props.get(vars.$bg-color--h), props.get(vars.$bg-color--s), props.get(vars.$bg-color--l));
94 }
95 }
133 96
134 @include iro.bem-modifier('placeholder') { 97 @include bem.modifier('colored-gradient') {
135 @include iro.bem-elem('content') { 98 @include bem.elem('content') {
136 background-color: hsl(0, 0%, fn.color(--l)); 99 color: #fff;
137 } 100 background: linear-gradient(props.get(vars.$bg-angle),
138 } 101 hsl(props.get(vars.$bg-color--h), props.get(vars.$bg-color--s), props.get(vars.$bg-color--l)),
102 hsl(props.get(vars.$bg-color-2--h), props.get(vars.$bg-color-2--s), props.get(vars.$bg-color-2--l)));
103 }
104 }
139 105
140 @include iro.bem-modifier('colored') { 106 @each $mod, $size, $font-size, $indicator-size in vars.$sizes {
141 @include iro.bem-elem('content') { 107 @include bem.modifier($mod) {
142 background-color: hsl(fn.color(--h), fn.color(--s), fn.color(--l)); 108 font-size: props.get($font-size);
143 color: #fff;
144 }
145 }
146
147 @each $size in $sizes {
148 @include iro.bem-modifier($size) {
149 font-size: fn.dim(--#{$size} --font-size);
150 109
151 @include status(--#{$size}); 110 @include status($indicator-size);
152 111
153 @include iro.bem-elem('content') { 112 @include bem.elem('content') {
154 inline-size: fn.dim(--#{$size} --size); 113 inline-size: props.get($size);
155 block-size: fn.dim(--#{$size} --size); 114 block-size: props.get($size);
156 line-height: fn.dim(--#{$size} --size); 115 line-height: props.get($size);
157 } 116 }
158 } 117 }
159 } 118 }
160 119
161 &:focus-visible { 120 &:focus-visible {
162 &::after { 121 &::after {
163 display: block; 122 display: block;
164 } 123 }
165 } 124 }
166 } 125 }
167} 126}
diff --git a/src/objects/_avatar.vars.scss b/src/objects/_avatar.vars.scss
new file mode 100644
index 0000000..2374f5a
--- /dev/null
+++ b/src/objects/_avatar.vars.scss
@@ -0,0 +1,58 @@
1@use 'iro-sass/src/props';
2@use '../core.vars' as core;
3
4$size: props.def(--o-avatar--size, props.get(core.$size--500)) !default;
5$font-size: props.def(--o-avatar--font-size, props.get(core.$font-size--100)) !default;
6$indicator-size: props.def(--o-avatar--indicator-size, props.get(core.$size--150)) !default;
7$indicator-spacing: props.def(--o-avatar--indicator-spacing, props.get(core.$size--40)) !default;
8$rounding: props.def(--o-avatar--rounding, 25%) !default;
9
10$size--xxxl: props.def(--o-avatar--xxxl--size, props.get(core.$size--1600)) !default;
11$font-size--xxxl: props.def(--o-avatar--xxxl--font-size, props.get(core.$font-size--800)) !default;
12$indicator-size--xxxl: props.def(--o-avatar--xxxl--indicator-size, props.get(core.$size--400)) !default;
13
14$size--xxl: props.def(--o-avatar--xxl--size, props.get(core.$size--1200)) !default;
15$font-size--xxl: props.def(--o-avatar--xxl--font-size, props.get(core.$font-size--600)) !default;
16$indicator-size--xxl: props.def(--o-avatar--xxl--indicator-size, props.get(core.$size--300)) !default;
17
18$size--xl: props.def(--o-avatar--xl--size, props.get(core.$size--800)) !default;
19$font-size--xl: props.def(--o-avatar--xl--font-size, props.get(core.$font-size--300)) !default;
20$indicator-size--xl: props.def(--o-avatar--xl--indicator-size, props.get(core.$size--225)) !default;
21
22$size--lg: props.def(--o-avatar--lg--size, props.get(core.$size--650)) !default;
23$font-size--lg: props.def(--o-avatar--lg--font-size, props.get(core.$font-size--200)) !default;
24$indicator-size--lg: props.def(--o-avatar--lg--indicator-size, props.get(core.$size--175)) !default;
25
26$size--sm: props.def(--o-avatar--sm--size, props.get(core.$size--375)) !default;
27$font-size--sm: props.def(--o-avatar--sm--font-size, props.get(core.$font-size--75)) !default;
28$indicator-size--sm: props.def(--o-avatar--sm--indicator-size, props.get(core.$size--125)) !default;
29
30$size--xs: props.def(--o-avatar--xs--size, props.get(core.$size--250)) !default;
31$font-size--xs: props.def(--o-avatar--xs--font-size, props.get(core.$font-size--50)) !default;
32$indicator-size--xs: props.def(--o-avatar--xs--indicator-size, props.get(core.$size--100)) !default;
33
34$key-focus--border-width: props.def(--o-avatar--key-focus--border-width, props.get(core.$key-focus--border-width)) !default;
35$key-focus--border-offset: props.def(--o-avatar--key-focus--border-offset, props.get(core.$key-focus--border-offset)) !default;
36$key-focus--outline-width: props.def(--o-avatar--key-focus--outline-width, props.get(core.$key-focus--outline-width)) !default;
37
38$bg-color--h: props.def(--o-avatar--bg-color--h, 354, 'color') !default;
39$bg-color--s: props.def(--o-avatar--bg-color--s, 44%, 'color') !default;
40$bg-color--l: props.def(--o-avatar--bg-color--l, 45%, 'color') !default;
41
42$bg-color-2--h: props.def(--o-avatar--bg-color-2--h, 354, 'color') !default;
43$bg-color-2--s: props.def(--o-avatar--bg-color-2--s, 44%, 'color') !default;
44$bg-color-2--l: props.def(--o-avatar--bg-color-2--l, 45%, 'color') !default;
45
46$bg-angle: props.def(--o-avatar--bg-angle, 180deg) !default;
47
48$key-focus--border-color: props.def(--o-avatar--key-focus--border-color, props.get(core.$theme, --focus, --border), 'color') !default;
49$key-focus--outline-color: props.def(--o-avatar--key-focus--outline-color, props.get(core.$theme, --focus, --outline), 'color') !default;
50
51$sizes: (
52 'xs' $size--xs $font-size--xs $indicator-size--xs,
53 'sm' $size--sm $font-size--sm $indicator-size--sm,
54 'lg' $size--lg $font-size--lg $indicator-size--lg,
55 'xl' $size--xl $font-size--xl $indicator-size--xl,
56 'xxl' $size--xxl $font-size--xxl $indicator-size--xxl,
57 'xxxl' $size--xxxl $font-size--xxxl $indicator-size--xxxl,
58) !default;
diff --git a/src/objects/_backdrop.scss b/src/objects/_backdrop.scss
index d0eaf52..346cf5f 100644
--- a/src/objects/_backdrop.scss
+++ b/src/objects/_backdrop.scss
@@ -1,26 +1,23 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
3 5
4@include iro.props-namespace('backdrop') { 6@forward 'backdrop.vars';
5 @include iro.props-store(( 7@use 'backdrop.vars' as vars;
6 --dims: (
7 --z-index: 10000,
8 --blur: 2em,
9 ),
10 --colors: (
11 --bg: rgba(#000, .75),
12 ),
13 ));
14 8
15 @include iro.bem-object(iro.props-namespace()) { 9@mixin styles {
16 display: flex; 10 @include materialize-at-root(meta.module-variables('vars'));
17 position: fixed; 11
18 z-index: fn.dim(--z-index); 12 @include bem.object('backdrop') {
19 inset: 0; 13 position: fixed;
20 box-sizing: border-box; 14 inset: 0;
21 flex-direction: column; 15 z-index: props.get(vars.$z-index);
22 overflow: auto; 16 box-sizing: border-box;
23 background-color: fn.color(--bg); 17 display: flex;
24 backdrop-filter: blur(fn.dim(--blur)); 18 flex-direction: column;
25 } 19 overflow: auto;
20 background-color: props.get(vars.$bg-color);
21 backdrop-filter: blur(props.get(vars.$blur));
22 }
26} 23}
diff --git a/src/objects/_backdrop.vars.scss b/src/objects/_backdrop.vars.scss
new file mode 100644
index 0000000..8bae733
--- /dev/null
+++ b/src/objects/_backdrop.vars.scss
@@ -0,0 +1,6 @@
1@use 'iro-sass/src/props';
2@use '../core.vars' as core;
3
4$z-index: props.def(--o-backdrop--z-index, 10000) !default;
5$blur: props.def(--o-backdrop--blur, 2em) !default;
6$bg-color: props.def(--o-backdrop--bg-color, props.get(core.$transparent-colors, --black, --600), 'color') !default;
diff --git a/src/objects/_badge.scss b/src/objects/_badge.scss
deleted file mode 100644
index 4e1662f..0000000
--- a/src/objects/_badge.scss
+++ /dev/null
@@ -1,300 +0,0 @@
1@use 'sass:string';
2@use 'iro-sass/src/index' as iro;
3@use '../functions' as fn;
4
5$sizes: 'sm' 'lg' 'xl' !default;
6$themes: 'accent' 'positive' 'negative' 'warning' !default;
7$static-themes: 'black' 'white' !default;
8
9@mixin theme($theme) {
10 background-color: fn.color(--#{$theme} --bg);
11 color: fn.color(--#{$theme} --label);
12
13 &:link,
14 &:visited,
15 &:enabled {
16 &:hover,
17 &:focus-visible {
18 background-color: fn.color(--#{$theme} --hover --bg);
19 color: fn.color(--#{$theme} --hover --label);
20 }
21
22 &:active {
23 background-color: fn.color(--#{$theme} --active --bg);
24 color: fn.color(--#{$theme} --active --label);
25 }
26 }
27
28 @include iro.bem-modifier('quiet') {
29 background-color: fn.color(--#{$theme}-quiet --bg);
30 color: fn.color(--#{$theme}-quiet --label);
31
32 &:link,
33 &:visited,
34 &:enabled {
35 &:hover,
36 &:focus-visible {
37 background-color: fn.color(--#{$theme}-quiet --hover --bg);
38 color: fn.color(--#{$theme}-quiet --hover --label);
39 }
40
41 &:active {
42 background-color: fn.color(--#{$theme}-quiet --active --bg);
43 color: fn.color(--#{$theme}-quiet --active --label);
44 }
45 }
46 }
47
48 @if string.slice($theme, 1, 7) == 'static-' {
49 &::after {
50 outline: fn.color(--#{$theme} --key-focus --border) solid fn.dim(--key-focus --border);
51 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(--#{$theme} --key-focus --outline);
52 }
53 }
54}
55
56@include iro.props-namespace('badge') {
57 @include iro.props-store((
58 --dims: (
59 --pad-b: fn.global-dim(--size --50),
60 --pad-i: fn.global-dim(--size --100),
61 --pad-i-pill: fn.global-dim(--size --150),
62 --pad-i-label: fn.global-dim(--size --50),
63 --rounding: fn.global-dim(--rounding),
64 --font-size: fn.global-dim(--font-size --75),
65
66 --sm: (
67 --pad-b: fn.global-dim(--size --25),
68 --pad-i: fn.global-dim(--size --75),
69 --pad-i-pill: fn.global-dim(--size --125),
70 --pad-i-label: fn.global-dim(--size --25),
71 --font-size: fn.global-dim(--font-size --50),
72 ),
73 --lg: (
74 --pad-b: fn.global-dim(--size --75),
75 --pad-i: fn.global-dim(--size --125),
76 --pad-i-pill: fn.global-dim(--size --175),
77 --pad-i-label: fn.global-dim(--size --50),
78 --font-size: fn.global-dim(--font-size --100),
79 ),
80 --xl: (
81 --pad-b: fn.global-dim(--size --100),
82 --pad-i: fn.global-dim(--size --150),
83 --pad-i-pill: fn.global-dim(--size --225),
84 --pad-i-label: fn.global-dim(--size --75),
85 --font-size: fn.global-dim(--font-size --150),
86 ),
87
88 --key-focus: (
89 --border: fn.global-dim(--key-focus --border),
90 --border-offset: fn.global-dim(--key-focus --border-offset),
91 --outline: fn.global-dim(--key-focus --outline),
92 ),
93 ),
94 --colors: (
95 --bg: fn.global-color(--text-mute),
96 --label: fn.global-color(--bg-l2),
97 --hover: (
98 --bg: fn.global-color(--text),
99 ),
100 --active: (
101 --bg: fn.global-color(--heading),
102 ),
103 --key-focus: (
104 --label: fn.global-color(--focus --text),
105 --border: fn.global-color(--focus --border),
106 --outline: fn.global-color(--focus --outline),
107 ),
108
109 --quiet: (
110 --bg: fn.global-color(--border-mute),
111 --label: fn.global-color(--heading),
112 --hover: (
113 --bg: fn.global-color(--border),
114 ),
115 --active: (
116 --bg: fn.global-color(--border-strong),
117 ),
118 ),
119 ),
120 ));
121
122 @each $theme in $themes {
123 @include iro.props-store((
124 --colors: (
125 --#{$theme}: (
126 --bg: fn.global-color(--#{$theme}-static --900),
127 --label: fn.global-color(--#{$theme}-static --900-text),
128 --hover: (
129 --bg: fn.global-color(--#{$theme}-static --1000),
130 --label: fn.global-color(--#{$theme}-static --1000-text),
131 ),
132 --active: (
133 --bg: fn.global-color(--#{$theme}-static --1100),
134 --label: fn.global-color(--#{$theme}-static --1000-text),
135 ),
136 ),
137
138 --#{$theme}-quiet: (
139 --bg: fn.global-color(--#{$theme} --200),
140 --label: fn.global-color(--#{$theme} --1100),
141 --hover: (
142 --bg: fn.global-color(--#{$theme} --300),
143 --label: fn.global-color(--#{$theme} --1200),
144 ),
145 --active: (
146 --bg: fn.global-color(--#{$theme} --400),
147 --label: fn.global-color(--#{$theme} --1300),
148 ),
149 )
150 ),
151 ));
152 }
153
154 @each $theme in $static-themes {
155 @include iro.props-store((
156 --colors: (
157 --static-#{$theme}: (
158 --bg: fn.global-color(--#{$theme}-transparent --800),
159 --label: fn.global-color(--#{$theme}-transparent --text),
160 --hover: (
161 --bg: fn.global-color(--#{$theme}-transparent --900),
162 --label: fn.global-color(--#{$theme}-transparent --text),
163 ),
164 --active: (
165 --bg: fn.global-color(--#{$theme}-transparent --900),
166 --label: fn.global-color(--#{$theme}-transparent --text),
167 ),
168 --key-focus: (
169 --bg: fn.global-color(--#{$theme}-transparent --100),
170 --label: fn.global-color(--#{$theme}-transparent --900),
171 --border: fn.global-color(--#{$theme}-transparent --900),
172 --outline: fn.global-color(--#{$theme}-transparent --300),
173 ),
174 ),
175
176 --static-#{$theme}-quiet: (
177 --bg: fn.global-color(--#{$theme}-transparent --200),
178 --label: fn.global-color(--#{$theme}-transparent --900),
179 --hover: (
180 --bg: fn.global-color(--#{$theme}-transparent --300),
181 --label: fn.global-color(--#{$theme}-transparent --900),
182 ),
183 --active: (
184 --bg: fn.global-color(--#{$theme}-transparent --400),
185 --label: fn.global-color(--#{$theme}-transparent --900),
186 ),
187 )
188 )
189 ));
190 }
191
192 @include iro.bem-object(iro.props-namespace()) {
193 display: inline-block;
194 position: relative;
195 padding-block: fn.dim(--pad-b);
196 padding-inline: fn.dim(--pad-i);
197 border-radius: fn.dim(--rounding);
198 background-color: fn.color(--bg);
199 background-clip: padding-box;
200 color: fn.color(--label);
201 font-size: fn.dim(--font-size);
202 line-height: fn.global-dim(--font --standard --line-height);
203 text-align: center;
204 text-decoration: none;
205
206 &::after {
207 content: '';
208 display: none;
209 position: absolute;
210 z-index: 1;
211 inset: calc(-1 * fn.dim(--key-focus --border-offset));
212 border-radius: calc(fn.dim(--rounding) + fn.dim(--key-focus --border-offset));
213 outline: fn.color(--key-focus --border) solid fn.dim(--key-focus --border);
214 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(--key-focus --outline);
215 pointer-events: none;
216 }
217
218 &:link,
219 &:visited,
220 &:enabled {
221 &:hover,
222 &:focus-visible {
223 background-color: fn.color(--hover --bg);
224 }
225
226 &:active {
227 background-color: fn.color(--active --bg);
228 }
229 }
230
231 @include iro.bem-elem('label') {
232 margin-inline: fn.dim(--pad-i-label);
233 }
234
235 @include iro.bem-modifier('quiet') {
236 background-color: fn.color(--quiet --bg);
237 color: fn.color(--quiet --label);
238
239 &:link,
240 &:visited,
241 &:enabled {
242 &:hover,
243 &:focus-visible {
244 background-color: fn.color(--quiet --hover --bg);
245 }
246
247 &:active {
248 background-color: fn.color(--quiet --active --bg);
249 }
250 }
251 }
252
253 @each $theme in $themes {
254 @include iro.bem-modifier($theme) {
255 @include theme($theme);
256 }
257 }
258
259 &:link,
260 &:visited,
261 &:enabled {
262 &:focus-visible {
263 &::after {
264 display: block;
265 }
266 }
267 }
268
269 @each $theme in $static-themes {
270 @include iro.bem-modifier(static-#{$theme}) {
271 @include theme(static-#{$theme});
272 }
273 }
274
275 @include iro.bem-modifier('pill') {
276 padding-inline: fn.dim(--pad-i-pill);
277 border-radius: 10em;
278
279 &::after {
280 border-radius: 10em;
281 }
282 }
283
284 @each $size in $sizes {
285 @include iro.bem-modifier($size) {
286 padding-block: fn.dim(--#{$size} --pad-b);
287 padding-inline: fn.dim(--#{$size} --pad-i);
288 font-size: fn.dim(--#{$size} --font-size);
289
290 @include iro.bem-elem('label') {
291 margin-inline: fn.dim(--#{$size} --pad-i-label);
292 }
293
294 @include iro.bem-modifier('pill') {
295 padding-inline: fn.dim(--#{$size} --pad-i-pill);
296 }
297 }
298 }
299 }
300}
diff --git a/src/objects/_button.scss b/src/objects/_button.scss
index 3ef4813..8163cf9 100644
--- a/src/objects/_button.scss
+++ b/src/objects/_button.scss
@@ -1,301 +1,285 @@
1@use 'sass:list'; 1@use 'sass:list';
2@use 'iro-sass/src/index' as iro; 2@use 'sass:map';
3@use '../functions' as fn; 3@use 'sass:meta';
4@use 'sass:string';
5@use 'iro-sass/src/bem';
6@use 'iro-sass/src/props';
7@use '../props' as *;
4 8
5$sizes: 'sm' 'lg' 'xl' !default; 9@forward 'button.vars';
6$themes: 'accent' 'negative' !default; 10@use 'button.vars' as vars;
7$static-themes: 'black' 'white' !default;
8 11
9@mixin theme($theme: ()) { 12@mixin -apply-theme($theme, $key: ()) {
10 &:link, 13 color: props.get($theme, list.join($key, --disabled --label-color)...);
11 &:visited, 14 background-color: props.get($theme, list.join($key, --disabled --bg-color)...);
12 &:enabled { 15 border-color: props.get($theme, list.join($key, --disabled --border-color)...);
13 border-color: transparent;
14 background-color: fn.color(list.join($theme, --bg));
15 color: fn.color(list.join($theme, --label));
16 }
17
18 @include iro.bem-modifier('outline') {
19 &:link,
20 &:visited,
21 &:enabled {
22 border-color: fn.color(list.join($theme, --outline-border));
23 background-color: transparent;
24 color: fn.color(list.join($theme, --outline-label));
25 }
26 }
27 16
28 &:link, 17 &::after {
29 &:visited, 18 outline-color: props.get($theme, list.join($key, --key-focus --border-color)...);
30 &:enabled { 19 box-shadow:
31 &:hover, 20 0
32 &:focus-visible { 21 0
33 border-color: transparent; 22 0
34 background-color: fn.color(list.join($theme, --hover --bg)); 23 calc(props.get(vars.$key-focus--border-width) + props.get(vars.$key-focus--outline-width))
35 color: fn.color(list.join($theme, --hover --label)); 24 props.get($theme, list.join($key, --key-focus --outline-color)...);
36 } 25 }
37 26
38 &:active { 27 &:link,
39 border-color: transparent; 28 &:visited,
40 background-color: fn.color(list.join($theme, --active --bg)); 29 &:enabled {
41 color: fn.color(list.join($theme, --active --label)); 30 color: props.get($theme, list.join($key, --label-color)...);
42 } 31 background-color: props.get($theme, list.join($key, --bg-color)...);
43 } 32 border-color: props.get($theme, list.join($key, --border-color)...);
44} 33 box-shadow:
34 props.get(vars.$shadow-x)
35 props.get(vars.$shadow-y)
36 props.get(vars.$shadow-blur)
37 props.get(vars.$shadow-grow)
38 props.get($theme, list.join($key, --shadow-color)...);
39
40 &:hover,
41 &:focus-visible {
42 color: props.get($theme, list.join($key, --hover --label-color)...);
43 background-color: props.get($theme, list.join($key, --hover --bg-color)...);
44 border-color: props.get($theme, list.join($key, --hover --border-color)...);
45 }
45 46
46@mixin static-theme($theme: ()) { 47 &:active {
47 border-color: transparent; 48 color: props.get($theme, list.join($key, --active --label-color)...);
48 background-color: fn.color(list.join($theme, --disabled --bg)); 49 background-color: props.get($theme, list.join($key, --active --bg-color)...);
49 color: fn.color(list.join($theme, --disabled --label)); 50 border-color: props.get($theme, list.join($key, --active --border-color)...);
51 box-shadow: none;
52 }
53 }
50 54
51 &::after { 55 @include bem.modifier('badge') {
52 outline: fn.color(list.join($theme, --key-focus --border)) solid fn.dim(--key-focus --border); 56 color: props.get($theme, list.join($key, --badge --label-color)...);
53 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(list.join($theme, --key-focus --outline)); 57 background-color: props.get($theme, list.join($key, --badge --bg-color)...);
54 } 58 border-color: props.get($theme, list.join($key, --badge --border-color)...);
55 59 box-shadow: none;
56 @include iro.bem-modifier('outline') {
57 border-color: fn.color(list.join($theme, --disabled --outline-border));
58 background-color: transparent;
59 }
60 60
61 @include theme($theme); 61 &:link,
62 &:visited,
63 &:enabled {
64 color: props.get($theme, list.join($key, --badge --label-color)...);
65 background-color: props.get($theme, list.join($key, --badge --bg-color)...);
66 border-color: props.get($theme, list.join($key, --badge --border-color)...);
67 box-shadow: none;
62 68
63 @include iro.bem-modifier('primary') { 69 &:hover,
64 @include theme(list.join($theme, --primary)); 70 &:focus-visible {
65 } 71 color: props.get($theme, list.join($key, --badge --hover --label-color)...);
66} 72 background-color: props.get($theme, list.join($key, --badge --hover --bg-color)...);
73 border-color: props.get($theme, list.join($key, --badge --hover --border-color)...);
74 }
67 75
68@include iro.props-namespace('button') { 76 &:active {
69 @include iro.props-store(( 77 color: props.get($theme, list.join($key, --badge --active --label-color)...);
70 --dims: ( 78 background-color: props.get($theme, list.join($key, --badge --active --bg-color)...);
71 --line-height: 1.4, 79 border-color: props.get($theme, list.join($key, --badge --active --border-color)...);
72 --pad-i: fn.global-dim(--size --200), 80 }
73 --pad-i-label: fn.global-dim(--size --75), 81 }
74 --pad-b: fn.global-dim(--size --65), 82 }
75 --border: fn.global-dim(--border --medium),
76 --rounding: 10em,
77 --font-size: fn.global-dim(--font-size --100),
78 83
79 --sm: ( 84 @include bem.modifier('quiet') {
80 --pad-i: fn.global-dim(--size --150), 85 color: props.get($theme, list.join($key, --quiet --disabled --label-color)...);
81 --pad-i-label: fn.global-dim(--size --50), 86 background-color: transparent;
82 --pad-b: fn.global-dim(--size --25), 87 border-color: transparent;
83 --font-size: fn.global-dim(--font-size --75),
84 ),
85 --lg: (
86 --pad-i: fn.global-dim(--size --250),
87 --pad-i-label: fn.global-dim(--size --100),
88 --pad-b: fn.global-dim(--size --100),
89 --font-size: fn.global-dim(--font-size --150),
90 ),
91 --xl: (
92 --pad-i: fn.global-dim(--size --300),
93 --pad-i-label: fn.global-dim(--size --150),
94 --pad-b: fn.global-dim(--size --150),
95 --font-size: fn.global-dim(--font-size --200),
96 ),
97
98 --key-focus: (
99 --border: fn.global-dim(--key-focus --border),
100 --border-offset: fn.global-dim(--key-focus --border-offset),
101 --outline: fn.global-dim(--key-focus --outline),
102 ),
103 ),
104 --colors: (
105 --bg: fn.global-color(--border-mute),
106 --label: fn.global-color(--text),
107 --outline-border: fn.global-color(--border),
108 --outline-label: fn.global-color(--text),
109 88
110 --hover: ( 89 &:link,
111 --bg: fn.global-color(--border), 90 &:visited,
112 --label: fn.global-color(--heading), 91 &:enabled {
113 ), 92 color: props.get($theme, list.join($key, --quiet --label-color)...);
114 --active: ( 93 background-color: transparent;
115 --bg: fn.global-color(--border-strong), 94 border-color: transparent;
116 --label: fn.global-color(--heading), 95 box-shadow: none;
117 ),
118 --disabled: (
119 --bg: fn.global-color(--border-mute),
120 --outline-border: fn.global-color(--border),
121 --label: fn.global-color(--text-disabled),
122 ),
123 --key-focus: (
124 --label: fn.global-color(--focus --text),
125 --border: fn.global-color(--focus --border),
126 --outline: fn.global-color(--focus --outline),
127 ),
128
129 --primary: (
130 --bg: fn.global-color(--base --800),
131 --label: fn.global-color(--base --800-text),
132 --outline-border: fn.global-color(--base --800),
133 --outline-label: fn.global-color(--text),
134 96
135 --hover: ( 97 &:hover,
136 --bg: fn.global-color(--base --900), 98 &:focus-visible {
137 --label: fn.global-color(--base --900-text), 99 color: props.get($theme, list.join($key, --quiet --hover --label-color)...);
138 ), 100 background-color: props.get($theme, list.join($key, --quiet --hover --bg-color)...);
139 --active: ( 101 border-color: transparent;
140 --bg: fn.global-color(--base --900), 102 }
141 --label: fn.global-color(--base --900-text),
142 ),
143 ),
144 ),
145 ));
146 103
147 @each $theme in $themes { 104 &:active {
148 @include iro.props-store(( 105 color: props.get($theme, list.join($key, --quiet --active --label-color)...);
149 --colors: ( 106 background-color: props.get($theme, list.join($key, --quiet --active --bg-color)...);
150 --#{$theme}: ( 107 border-color: transparent;
151 --bg: fn.global-color(--#{$theme}-static --900), 108 }
152 --label: fn.global-color(--#{$theme}-static --900-text), 109 }
153 --outline-border: fn.global-color(--#{$theme} --900), 110 }
154 --outline-label: fn.global-color(--#{$theme} --1000),
155 111
156 --hover: ( 112 @include bem.is('highlighted') {
157 --bg: fn.global-color(--#{$theme}-static --1000), 113 &:link,
158 --label: fn.global-color(--#{$theme}-static --1000-text), 114 &:visited,
159 ), 115 &:enabled {
160 --active: ( 116 &,
161 --bg: fn.global-color(--#{$theme}-static --1100), 117 &:hover,
162 --label: fn.global-color(--#{$theme}-static --1100-text), 118 &:focus-visible {
163 ), 119 border-color: props.get($theme, list.join($key, --highlighted --border-color)...);
164 ), 120 }
165 ),
166 ));
167 }
168 121
169 @each $theme in $static-themes { 122 box-shadow:
170 @include iro.props-store(( 123 0 0 0 1px props.get($theme, list.join($key, --highlighted --border-color)...),
171 --colors: ( 124 props.get(vars.$shadow-x)
172 --static-#{$theme}: ( 125 props.get(vars.$shadow-y)
173 --bg: fn.global-color(--#{$theme}-transparent --200), 126 props.get(vars.$shadow-blur)
174 --label: fn.global-color(--#{$theme}-transparent --900), 127 props.get(vars.$shadow-grow)
175 --outline-border: fn.global-color(--#{$theme}-transparent --300), 128 props.get($theme, list.join($key, --highlighted --shadow-color)...);
176 --outline-label: fn.global-color(--#{$theme}-transparent --900),
177 129
178 --hover: ( 130 &:focus-visible {
179 --bg: fn.global-color(--#{$theme}-transparent --300), 131 box-shadow:
180 --label: fn.global-color(--#{$theme}-transparent --900), 132 props.get(vars.$shadow-x)
181 ), 133 props.get(vars.$shadow-y)
182 --active: ( 134 props.get(vars.$shadow-blur)
183 --bg: fn.global-color(--#{$theme}-transparent --400), 135 props.get(vars.$shadow-grow)
184 --label: fn.global-color(--#{$theme}-transparent --900), 136 props.get($theme, list.join($key, --shadow-color)...);
185 ), 137 }
186 --disabled: ( 138 }
187 --bg: fn.global-color(--#{$theme}-transparent --200), 139 }
188 --outline-border: fn.global-color(--#{$theme}-transparent --300),
189 --label: fn.global-color(--#{$theme}-transparent --500),
190 ),
191 --key-focus: (
192 --bg: fn.global-color(--#{$theme}-transparent --100),
193 --label: fn.global-color(--#{$theme}-transparent --900),
194 --border: fn.global-color(--#{$theme}-transparent --900),
195 --outline: fn.global-color(--#{$theme}-transparent --300),
196 ),
197 140
198 --primary: ( 141 @include bem.is('selected') {
199 --bg: fn.global-color(--#{$theme}-transparent --800), 142 color: props.get($theme, list.join($key, --selected --disabled --label-color)...);
200 --label: fn.global-color(--#{$theme}-transparent --text), 143 background-color: props.get($theme, list.join($key, --selected --disabled --bg-color)...);
201 --outline-border: fn.global-color(--#{$theme}-transparent --800), 144 border-color: props.get($theme, list.join($key, --selected --disabled --border-color)...);
202 --outline-label: fn.global-color(--#{$theme}-transparent --900), 145
146 @include bem.multi('&:link, &:visited, &:enabled', 'modifier' 'badge') {
147 color: props.get($theme, list.join($key, --selected --label-color)...);
148 background-color: props.get($theme, list.join($key, --selected --bg-color)...);
149 border-color: props.get($theme, list.join($key, --selected --border-color)...);
150 }
151
152 &:link,
153 &:visited,
154 &:enabled {
155 &:hover,
156 &:focus-visible {
157 color: props.get($theme, list.join($key, --selected --hover --label-color)...);
158 background-color: props.get($theme, list.join($key, --selected --hover --bg-color)...);
159 border-color: props.get($theme, list.join($key, --selected --hover --border-color)...);
160 }
203 161
204 --hover: ( 162 &:active {
205 --bg: fn.global-color(--#{$theme}-transparent --900), 163 color: props.get($theme, list.join($key, --selected --active --label-color)...);
206 --label: fn.global-color(--#{$theme}-transparent --text), 164 background-color: props.get($theme, list.join($key, --selected --active --bg-color)...);
207 ), 165 border-color: props.get($theme, list.join($key, --selected --active --border-color)...);
208 --active: ( 166 }
209 --bg: fn.global-color(--#{$theme}-transparent --900), 167 }
210 --label: fn.global-color(--#{$theme}-transparent --text), 168 }
211 ), 169}
212 ),
213 ),
214 ),
215 ));
216 }
217 170
218 @include iro.bem-object(iro.props-namespace()) { 171@mixin styles {
219 display: inline-block; 172 @include materialize-at-root(meta.module-variables('vars'));
220 position: relative;
221 padding-block: fn.dim(--pad-b);
222 padding-inline: fn.dim(--pad-i);
223 border: fn.dim(--border) solid transparent;
224 border-radius: fn.dim(--rounding);
225 border-color: fn.color(--disabled --bg);
226 background-color: fn.color(--disabled --bg);
227 color: fn.color(--disabled --label);
228 font-size: fn.dim(--font-size);
229 font-weight: 500;
230 line-height: fn.dim(--line-height);
231 text-align: center;
232 text-decoration: none;
233 173
234 &::after { 174 @include bem.object('button') {
235 content: ''; 175 position: relative;
236 display: none; 176 display: inline-block;
237 position: absolute; 177 padding-block: props.get(vars.$pad-b);
238 z-index: 1; 178 padding-inline: props.get(vars.$pad-i);
239 inset: calc(-1 * fn.dim(--border) - fn.dim(--key-focus --border-offset)); 179 text-overflow: ellipsis;
240 border-radius: calc(fn.dim(--rounding) + fn.dim(--key-focus --border-offset)); 180 font-size: props.get(vars.$font-size);
241 outline: fn.color(--key-focus --border) solid fn.dim(--key-focus --border); 181 line-height: props.get(vars.$line-height);
242 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(--key-focus --outline); 182 text-align: center;
243 pointer-events: none; 183 white-space: nowrap;
244 } 184 text-decoration: none;
185 border: props.get(vars.$border-width) solid transparent;
186 border-radius: props.get(vars.$rounding);
187 transition: color .1s, background-color .1s, border-color .1s, box-shadow .1s;
245 188
246 &:link, 189 &::after {
247 &:visited, 190 position: absolute;
248 &:enabled { 191 inset: calc(-1 * props.get(vars.$border-width) - props.get(vars.$key-focus--border-offset));
249 &:focus-visible { 192 z-index: 1;
250 &::after { 193 display: none;
251 display: block; 194 pointer-events: none;
252 } 195 outline: transparent solid props.get(vars.$key-focus--border-width);
253 } 196 content: '';
254 } 197 border-radius: calc(props.get(vars.$rounding) + props.get(vars.$key-focus--border-offset));
198 }
255 199
256 @include iro.bem-elem('label') { 200 &:link,
257 margin-inline: fn.dim(--pad-i-label); 201 &:visited,
258 } 202 &:enabled {
259 203 &:focus-visible {
260 @include iro.bem-modifier('block') { 204 transition: none;
261 display: block;
262 }
263
264 @include iro.bem-modifier('outline') {
265 border-color: fn.color(--disabled --outline-border);
266 background-color: transparent;
267 }
268 205
269 @each $size in $sizes { 206 &::after {
270 @include iro.bem-modifier($size) { 207 display: block;
271 padding-block: fn.dim(--#{$size} --pad-b); 208 }
272 padding-inline: fn.dim(--#{$size} --pad-i); 209 }
273 font-size: fn.dim(--#{$size} --font-size); 210 }
274 211
275 @include iro.bem-elem('label') { 212 @include bem.elem('label') {
276 margin-inline: fn.dim(--#{$size} --pad-i-label); 213 margin-inline: props.get(vars.$pad-i-label);
277 } 214 }
278 }
279 }
280 215
281 @include static-theme; 216 @include -apply-theme(vars.$default-theme);
282 217
283 @each $theme in $themes { 218 @each $theme in map.keys(props.get(vars.$themes)) {
284 @include iro.bem-modifier($theme) { 219 @include bem.modifier(string.slice($theme, 3)) {
285 @include theme(--#{$theme}); 220 @include -apply-theme(vars.$themes, $theme);
286 } 221 }
287 } 222 }
288 223
289 @each $theme in $static-themes { 224 @include bem.modifier('pill') {
290 @include iro.bem-modifier(static-#{$theme}) { 225 padding-inline: props.get(vars.$pad-i-pill);
291 @include static-theme(--static-#{$theme}); 226 border-radius: 100em;
292 } 227
293 } 228 &::after {
229 border-radius: 100em;
230 }
231 }
232
233 @include bem.modifier('icon') {
234 inline-size: calc(1em * props.get(vars.$line-height) + 2 * props.get(vars.$pad-b));
235 padding-inline: 0;
236 }
237
238 @each $mod, $pad-i, $pad-i-label, $pad-i-pill, $pad-b, $font-size in vars.$fixed-sizes {
239 @include bem.modifier($mod) {
240 padding-block: props.get($pad-b);
241 padding-inline: props.get($pad-i);
242 font-size: props.get($font-size);
243
244 @include bem.elem('label') {
245 margin-inline: props.get($pad-i-label);
246 }
247
248 @include bem.modifier('pill') {
249 padding-inline: props.get($pad-i-pill);
250 }
251
252 @include bem.modifier('icon') {
253 inline-size: calc(1em * props.get(vars.$line-height) + 2 * props.get($pad-b));
254 padding-inline: 0;
255 }
256 }
257 }
258
259 @include bem.modifier('align-block') {
260 margin-inline: calc(-1 * props.get(vars.$pad-i) - props.get(vars.$border-width));
261
262 @include bem.modifier('pill') {
263 margin-inline: calc(-1 * props.get(vars.$pad-i-pill) - props.get(vars.$border-width));
264 }
265
266 @include bem.modifier('icon') {
267 margin-inline: calc(-1 * props.get(vars.$pad-b) - props.get(vars.$border-width) - .5em * (props.get(vars.$line-height) - 1));
268 }
269
270 @each $mod, $pad-i, $pad-i-label, $pad-i-pill, $pad-b, $font-size in vars.$fixed-sizes {
271 @include bem.modifier($mod) {
272 margin-inline: calc(-1 * props.get($pad-i) - props.get(vars.$border-width));
294 273
295 @include iro.bem-modifier('round') { 274 @include bem.modifier('pill') {
296 inline-size: calc(1em * fn.dim(--line-height) + 2 * fn.dim(--pad-b)); 275 margin-inline: calc(-1 * props.get($pad-i-pill) - props.get(vars.$border-width));
297 padding-inline: 0; 276 }
298 border-radius: 100em; 277
299 } 278 @include bem.modifier('icon') {
300 } 279 margin-inline: calc(-1 * props.get($pad-b) - props.get(vars.$border-width) - .5em * (props.get(vars.$line-height) - 1));
280 }
281 }
282 }
283 }
284 }
301} 285}
diff --git a/src/objects/_button.vars.scss b/src/objects/_button.vars.scss
new file mode 100644
index 0000000..6e2298f
--- /dev/null
+++ b/src/objects/_button.vars.scss
@@ -0,0 +1,374 @@
1@use 'sass:map';
2@use 'sass:string';
3@use 'iro-sass/src/props';
4@use '../core.vars' as core;
5
6$line-height: props.def(--o-button--line-height, 1.4) !default;
7$border-width: props.def(--o-button--border-width, props.get(core.$border-width--thin)) !default;
8$rounding: props.def(--o-button--rounding, props.get(core.$rounding--sm)) !default;
9
10$pad-i--sm: props.def(--o-button--sm--pad-i, props.get(core.$size--75)) !default;
11$pad-i-label--sm: props.def(--o-button--sm--pad-i-label, props.get(core.$size--25)) !default;
12$pad-i-pill--sm: props.def(--o-button--sm--pad-i-pill, props.get(core.$size--115)) !default;
13$pad-b--sm: props.def(--o-button--sm--pad-b, props.get(core.$size--40)) !default;
14$font-size--sm: props.def(--o-button--sm--font-size, props.get(core.$font-size--75)) !default;
15
16$pad-i: props.def(--o-button--pad-i, props.get(core.$size--115)) !default;
17$pad-i-label: props.def(--o-button--pad-i-label, props.get(core.$size--40)) !default;
18$pad-i-pill: props.def(--o-button--pad-i-pill, props.get(core.$size--150)) !default;
19$pad-b: props.def(--o-button--pad-b, props.get(core.$size--85)) !default;
20$font-size: props.def(--o-button--font-size, props.get(core.$font-size--100)) !default;
21
22$pad-i--lg: props.def(--o-button--lg--pad-i, props.get(core.$size--160)) !default;
23$pad-i-label--lg: props.def(--o-button--lg--pad-i-label, props.get(core.$size--65)) !default;
24$pad-i-pill--lg: props.def(--o-button--lg--pad-i-pill, props.get(core.$size--175)) !default;
25$pad-b--lg: props.def(--o-button--lg--pad-b, props.get(core.$size--115)) !default;
26$font-size--lg: props.def(--o-button--lg--font-size, props.get(core.$font-size--150)) !default;
27
28$pad-i--xl: props.def(--o-button--xl--pad-i, props.get(core.$size--200)) !default;
29$pad-i-label--xl: props.def(--o-button--xl--pad-i-label, props.get(core.$size--85)) !default;
30$pad-i-pill--xl: props.def(--o-button--xl--pad-i-pill, props.get(core.$size--225)) !default;
31$pad-b--xl: props.def(--o-button--xl--pad-b, props.get(core.$size--150)) !default;
32$font-size--xl: props.def(--o-button--xl--font-size, props.get(core.$font-size--200)) !default;
33
34$shadow-x: props.def(--o-button--shadow-x, props.get(core.$shadow--l1--x)) !default;
35$shadow-y: props.def(--o-button--shadow-y, props.get(core.$shadow--l1--y)) !default;
36$shadow-blur: props.def(--o-button--shadow-blur, props.get(core.$shadow--l1--blur)) !default;
37$shadow-grow: props.def(--o-button--shadow-grow, props.get(core.$shadow--l1--grow)) !default;
38
39$key-focus--border-width: props.def(--o-button--key-focus--border-width, props.get(core.$key-focus--border-width)) !default;
40$key-focus--border-offset: props.def(--o-button--key-focus--border-offset, props.get(core.$key-focus--border-offset)) !default;
41$key-focus--outline-width: props.def(--o-button--key-focus--outline-width, props.get(core.$key-focus--outline-width)) !default;
42
43$fixed-sizes: (
44 'sm' $pad-i--sm $pad-i-label--sm $pad-i-pill--sm $pad-b--sm $font-size--sm,
45 'lg' $pad-i--lg $pad-i-label--lg $pad-i-pill--lg $pad-b--lg $font-size--lg,
46 'xl' $pad-i--xl $pad-i-label--xl $pad-i-pill--xl $pad-b--xl $font-size--xl,
47) !default;
48
49$themes: props.def(--o-button, (), 'color');
50
51$default-theme-override: () !default;
52$default-theme: map.deep-merge((
53 --bg-color: props.get(core.$theme, --bg-l2),
54 --label-color: props.get(core.$theme, --text),
55 --border-color: props.get(core.$theme, --box, --border) props.get(core.$theme, --box, --border) props.get(core.$theme, --box, --border-strong),
56 --shadow-color: props.get(core.$theme, --shadow),
57
58 --hover: (
59 --bg-color: props.get(core.$theme, --bg-l1),
60 --label-color: props.get(core.$theme, --heading),
61 --border-color: props.get(core.$theme, --border),
62 ),
63
64 --active: (
65 --bg-color: props.get(core.$theme, --border-mute),
66 --label-color: props.get(core.$theme, --heading),
67 --border-color: props.get(core.$theme, --border-strong),
68 ),
69
70 --disabled: (
71 --bg-color: transparent,
72 --label-color: props.get(core.$theme, --border-strong),
73 --border-color: props.get(core.$theme, --text-disabled),
74 ),
75
76 --key-focus: (
77 --border-color: props.get(core.$theme, --focus, --border),
78 --outline-color: props.get(core.$theme, --focus, --outline),
79 ),
80
81 --highlighted: (
82 --border-color: props.get(core.$theme, --focus, --border),
83 --shadow-color: props.get(core.$theme, --focus, --outline),
84 ),
85
86 --selected: (
87 --bg-color: props.get(core.$theme, --text),
88 --label-color: props.get(core.$theme, --base, --50),
89 --border-color: props.get(core.$theme, --text) props.get(core.$theme, --text) props.get(core.$theme, --heading),
90
91 --hover: (
92 --bg-color: props.get(core.$theme, --heading),
93 --label-color: props.get(core.$theme, --base, --50),
94 --border-color: props.get(core.$theme, --heading),
95 ),
96
97 --active: (
98 --bg-color: props.get(core.$theme, --heading),
99 --label-color: props.get(core.$theme, --base, --50),
100 --border-color: props.get(core.$theme, --heading),
101 ),
102
103 --disabled: (
104 --bg-color: props.get(core.$theme, --border-mute),
105 --label-color: props.get(core.$theme, --border-strong),
106 --border-color: props.get(core.$theme, --border-mute),
107 ),
108 ),
109
110 --badge: (
111 --bg-color: props.get(core.$theme, --border-mute),
112 --label-color: props.get(core.$theme, --heading),
113 --border-color: props.get(core.$theme, --border-mute),
114
115 --hover: (
116 --bg-color: props.get(core.$theme, --border),
117 --label-color: props.get(core.$theme, --heading),
118 --border-color: props.get(core.$theme, --border),
119 ),
120
121 --active: (
122 --bg-color: props.get(core.$theme, --border-strong),
123 --label-color: props.get(core.$theme, --heading),
124 --border-color: props.get(core.$theme, --border-strong),
125 ),
126 ),
127
128 --quiet: (
129 --label-color: props.get(core.$theme, --text),
130
131 --hover: (
132 --bg-color: props.get(core.$theme, --border-mute),
133 --label-color: props.get(core.$theme, --heading),
134 ),
135
136 --active: (
137 --bg-color: props.get(core.$theme, --border),
138 --label-color: props.get(core.$theme, --heading),
139 ),
140
141 --disabled: (
142 --label-color: props.get(core.$theme, --border-strong),
143 ),
144 ),
145), $default-theme-override) !default;
146$default-theme: props.def(--o-button, $default-theme, 'color');
147
148$default-theme-dark-override: () !default;
149$default-theme-dark: map.deep-merge((
150 --bg-color: props.get(core.$theme, --border-mute),
151 --border-color: props.get(core.$theme, --border-mute),
152
153 --hover: (
154 --bg-color: props.get(core.$theme, --border),
155 --border-color: props.get(core.$theme, --border),
156 ),
157
158 --active: (
159 --bg-color: props.get(core.$theme, --border-strong),
160 --border-color: props.get(core.$theme, --border-strong),
161 ),
162
163 --selected: (
164 --border-color: props.get(core.$theme, --text),
165 ),
166), $default-theme-override) !default;
167$default-theme-dark: props.def(--o-button, $default-theme-dark, 'dark');
168
169@each $theme in map.keys(props.get(core.$transparent-colors)) {
170 $button-theme: --static-#{string.slice($theme, 3)};
171
172 $themes: props.merge($themes, (
173 $button-theme: (
174 --bg-color: props.get(core.$transparent-colors, $theme, --200),
175 --label-color: props.get(core.$transparent-colors, $theme, --900),
176 --border-color: props.get(core.$transparent-colors, $theme, --300) props.get(core.$transparent-colors, $theme, --300) props.get(core.$transparent-colors, $theme, --400),
177 --shadow-color: props.get(core.$transparent-colors, --black, --200),
178
179 --hover: (
180 --bg-color: props.get(core.$transparent-colors, $theme, --300),
181 --label-color: props.get(core.$transparent-colors, $theme, --900),
182 --border-color: props.get(core.$transparent-colors, $theme, --400),
183 ),
184
185 --active: (
186 --bg-color: props.get(core.$transparent-colors, $theme, --400),
187 --label-color: props.get(core.$transparent-colors, $theme, --900),
188 --border-color: props.get(core.$transparent-colors, $theme, --500),
189 ),
190
191 --disabled: (
192 --bg-color: props.get(core.$transparent-colors, $theme, --100),
193 --label-color: props.get(core.$transparent-colors, $theme, --500),
194 --border-color: props.get(core.$transparent-colors, $theme, --300),
195 ),
196
197 --key-focus: (
198 --border-color: props.get(core.$transparent-colors, $theme, --900),
199 --outline-color: props.get(core.$transparent-colors, $theme, --300),
200 ),
201
202 --highlighted: (
203 --border-color: props.get(core.$transparent-colors, $theme, --900),
204 --shadow-color: props.get(core.$transparent-colors, --black, --200),
205 ),
206
207 --selected: (
208 --bg-color: props.get(core.$transparent-colors, $theme, --800),
209 --label-color: props.get(core.$transparent-colors, $theme, --text),
210 --border-color: props.get(core.$transparent-colors, $theme, --100) props.get(core.$transparent-colors, $theme, --100) props.get(core.$transparent-colors, $theme, --200),
211
212 --hover: (
213 --bg-color: props.get(core.$transparent-colors, $theme, --900),
214 --label-color: props.get(core.$transparent-colors, $theme, --text),
215 --border-color: props.get(core.$transparent-colors, $theme, --100),
216 ),
217
218 --active: (
219 --bg-color: props.get(core.$transparent-colors, $theme, --900),
220 --label-color: props.get(core.$transparent-colors, $theme, --text),
221 --border-color: props.get(core.$transparent-colors, $theme, --100),
222 ),
223
224 --disabled: (
225 --bg-color: props.get(core.$transparent-colors, $theme, --200),
226 --label-color: props.get(core.$transparent-colors, $theme, --500),
227 --border-color: props.get(core.$transparent-colors, $theme, --100),
228 ),
229 ),
230
231 --badge: (
232 --bg-color: props.get(core.$transparent-colors, $theme, --200),
233 --label-color: props.get(core.$transparent-colors, $theme, --900),
234 --border-color: transparent,
235
236 --hover: (
237 --bg-color: props.get(core.$transparent-colors, $theme, --300),
238 --label-color: props.get(core.$transparent-colors, $theme, --900),
239 --border-color: transparent,
240 ),
241
242 --active: (
243 --bg-color: props.get(core.$transparent-colors, $theme, --400),
244 --label-color: props.get(core.$transparent-colors, $theme, --900),
245 --border-color: transparent,
246 ),
247 ),
248
249 --quiet: (
250 --label-color: props.get(core.$transparent-colors, $theme, --900),
251
252 --hover: (
253 --bg-color: props.get(core.$transparent-colors, $theme, --200),
254 --label-color: props.get(core.$transparent-colors, $theme, --900),
255 ),
256
257 --active: (
258 --bg-color: props.get(core.$transparent-colors, $theme, --300),
259 --label-color: props.get(core.$transparent-colors, $theme, --900),
260 ),
261
262 --disabled: (
263 --label-color: props.get(core.$transparent-colors, $theme, --500),
264 ),
265 ),
266 )
267 ));
268}
269
270$themes-config: (
271 accent: --accent,
272 positive: --positive,
273 negative: --negative,
274 warning: --warning,
275) !default;
276
277@each $theme, $key in $themes-config {
278 $themes: props.merge($themes, (
279 --#{$theme}: (
280 --bg-color: props.get(core.$theme, $key, --100),
281 --label-color: props.get(core.$theme, $key, --1100),
282 --border-color: props.get(core.$theme, $key, --500) props.get(core.$theme, $key, --500) props.get(core.$theme, $key, --600),
283 --shadow-color: props.get(core.$theme, $key, --200),
284
285 --hover: (
286 --bg-color: props.get(core.$theme, $key, --200),
287 --label-color: props.get(core.$theme, $key, --1200),
288 --border-color: props.get(core.$theme, $key, --600),
289 ),
290
291 --active: (
292 --bg-color: props.get(core.$theme, $key, --300),
293 --label-color: props.get(core.$theme, $key, --1300),
294 --border-color: props.get(core.$theme, $key, --800),
295 ),
296
297 --disabled: (
298 --bg-color: props.get(core.$theme, --bg-l1),
299 --label-color: props.get(core.$theme, --border-strong),
300 --border-color: props.get(core.$theme, --border),
301 ),
302
303 --key-focus: (
304 --border-color: props.get(core.$theme, --focus, --border),
305 --outline-color: props.get(core.$theme, --focus, --outline),
306 ),
307
308 --highlighted: (
309 --border-color: props.get(core.$theme, $key, --900),
310 --shadow-color: props.get(core.$theme, $key, --200),
311 ),
312
313 --selected: (
314 --bg-color: props.get(core.$theme, #{$key}-static, --900),
315 --label-color: props.get(core.$theme, #{$key}-static, --900-text),
316 --border-color: props.get(core.$theme, #{$key}-static, --900) props.get(core.$theme, #{$key}-static, --900) props.get(core.$theme, #{$key}-static, --1000),
317
318 --hover: (
319 --bg-color: props.get(core.$theme, #{$key}-static, --1000),
320 --label-color: props.get(core.$theme, #{$key}-static, --1000-text),
321 --border-color: props.get(core.$theme, #{$key}-static, --1000),
322 ),
323
324 --active: (
325 --bg-color: props.get(core.$theme, #{$key}-static, --1100),
326 --label-color: props.get(core.$theme, #{$key}-static, --1100-text),
327 --border-color: props.get(core.$theme, #{$key}-static, --1100),
328 ),
329
330 --disabled: (
331 --bg-color: props.get(core.$theme, --border-mute),
332 --label-color: props.get(core.$theme, --border-strong),
333 --border-color: props.get(core.$theme, --border-mute),
334 ),
335 ),
336
337 --badge: (
338 --bg-color: props.get(core.$theme, $key, --100),
339 --label-color: props.get(core.$theme, $key, --1100),
340 --border-color: props.get(core.$theme, $key, --300),
341
342 --hover: (
343 --bg-color: props.get(core.$theme, $key, --200),
344 --label-color: props.get(core.$theme, $key, --1200),
345 --border-color: props.get(core.$theme, $key, --400),
346 ),
347
348 --active: (
349 --bg-color: props.get(core.$theme, $key, --300),
350 --label-color: props.get(core.$theme, $key, --1300),
351 --border-color: props.get(core.$theme, $key, --500),
352 ),
353 ),
354
355 --quiet: (
356 --label-color: props.get(core.$theme, $key, --1100),
357
358 --hover: (
359 --bg-color: props.get(core.$theme, $key, --200),
360 --label-color: props.get(core.$theme, $key, --1200),
361 ),
362
363 --active: (
364 --bg-color: props.get(core.$theme, $key, --300),
365 --label-color: props.get(core.$theme, $key, --1300),
366 ),
367
368 --disabled: (
369 --label-color: props.get(core.$theme, --border-strong),
370 ),
371 ),
372 )
373 ));
374}
diff --git a/src/objects/_card.scss b/src/objects/_card.scss
index f56a96c..ebab339 100644
--- a/src/objects/_card.scss
+++ b/src/objects/_card.scss
@@ -1,165 +1,277 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
5@use 'avatar.vars' as avatar;
3 6
4@include iro.props-namespace('card') { 7@forward 'card.vars';
5 @include iro.props-store(( 8@use 'card.vars' as vars;
6 --dims: (
7 --border: fn.global-dim(--border --thin),
8 --divider: fn.global-dim(--border --thin),
9 --pad-i: fn.global-dim(--size --300),
10 --pad-b: fn.global-dim(--size --250),
11 --spacing: fn.global-dim(--size --200),
12 --rounding: fn.global-dim(--rounding),
13 9
14 --key-focus: ( 10@mixin styles {
15 --border: fn.global-dim(--key-focus --border), 11 @include materialize-at-root(meta.module-variables('vars'));
16 --border-offset: fn.global-dim(--key-focus --border-offset),
17 --outline: fn.global-dim(--key-focus --outline),
18 ),
19 ),
20 --colors: (
21 --bg: fn.global-color(--bg-l2),
22 --border: fn.global-color(--border-mute),
23 --divider: fn.global-color(--border-mute),
24 12
25 --hover: ( 13 @include bem.object('card') {
26 --border: fn.global-color(--border), 14 position: relative;
27 ), 15 display: flex;
16 flex-direction: column;
17 background-color: props.get(vars.$bg-color);
18 border: props.get(vars.$border-width) solid transparent;
19 border-color: props.get(vars.$border-color);
20 border-radius: props.get(vars.$rounding);
21 transition: transform .2s, background-color .2s, border-color .2s, box-shadow .2s;
28 22
29 --key-focus: ( 23 @include bem.multi('&:link, &:visited, &:enabled', 'modifier' 'interactive') {
30 --label: fn.global-color(--focus --text), 24 &:hover,
31 --border: fn.global-color(--focus --border), 25 &:active,
32 --outline: fn.global-color(--focus --outline), 26 &:focus-visible {
33 ), 27 background-color: props.get(vars.$hover--bg-color);
28 border-color: props.get(vars.$hover--border-color);
29 box-shadow: none;
30 transform: translateY(props.get(vars.$hover--offset-b));
31 }
34 32
35 --quiet: ( 33 &:focus-visible {
36 --image: fn.global-color(--bg-base), 34 margin: calc(-1 * props.get(vars.$key-focus--border-width));
35 outline: props.get(vars.$key-focus--border-color) solid props.get(vars.$key-focus--border-width);
36 border: calc(props.get(vars.$key-focus--border-offset) + props.get(vars.$border-width)) solid transparent;
37 border-radius: calc(props.get(vars.$rounding) + props.get(vars.$key-focus--border-offset));
38 box-shadow:
39 0 0 0
40 calc(props.get(vars.$key-focus--border-width) + props.get(vars.$key-focus--outline-width))
41 props.get(vars.$key-focus--outline-color);
42 transition: transform .2s;
43 }
44 }
37 45
38 --hover: ( 46 @include bem.modifier('borderless') {
39 --image: fn.global-color(--border), 47 border-color: props.get(vars.$bg-color);
40 ), 48 }
41 )
42 ),
43 ));
44 49
45 @include iro.bem-object(iro.props-namespace()) { 50 @include bem.modifier('shadow') {
46 display: block; 51 box-shadow:
47 border: fn.dim(--border) solid fn.color(--border); 52 props.get(vars.$shadow-x)
48 border-radius: fn.dim(--rounding); 53 props.get(vars.$shadow-y)
49 background-color: fn.color(--bg); 54 props.get(vars.$shadow-blur)
55 props.get(vars.$shadow-grow)
56 props.get(vars.$shadow-color);
50 57
51 @include iro.bem-multi('&:link, &:visited, &:enabled', 'modifier' 'interactive') { 58 @include bem.modifier('quiet') {
52 &:hover, 59 @include bem.elem('image') {
53 &:focus-visible, 60 box-shadow:
54 &:active { 61 props.get(vars.$shadow-x)
55 border-color: fn.color(--hover --border); 62 props.get(vars.$shadow-y)
56 } 63 props.get(vars.$shadow-blur)
64 props.get(vars.$shadow-grow)
65 props.get(vars.$shadow-color);
66 }
67 }
68 }
57 69
58 &:focus-visible { 70 @include bem.elem('avatar') {
59 border-color: fn.color(--key-focus --border); 71 margin-block-start: props.get(vars.$pad-b);
60 outline: fn.color(--key-focus --border) solid calc(fn.dim(--key-focus --border) - fn.dim(--border)); 72 margin-inline-start: props.get(vars.$pad-i);
61 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(--key-focus --outline); 73 }
62 }
63 }
64 74
65 @include iro.bem-elem('avatar') { 75 @include bem.elem('image') {
66 margin-block-start: fn.dim(--pad-b); 76 position: relative;
67 margin-inline-start: fn.dim(--pad-i); 77 display: block;
68 } 78 flex: 0 0 auto;
79 inline-size: calc(100% + 2 * props.get(vars.$border-width));
80 margin: calc(-1 * props.get(vars.$border-width));
81 overflow: hidden;
82 object-fit: cover;
83 transition: background-color .2s, transform .2s, opacity .2s;
69 84
70 @include iro.bem-elem('image') { 85 &:first-child {
71 display: block; 86 border-start-start-radius: calc(props.get(vars.$rounding) - props.get(vars.$border-width));
72 inline-size: 100%; 87 border-start-end-radius: calc(props.get(vars.$rounding) - props.get(vars.$border-width));
73 object-fit: cover; 88 }
74 89
75 &:first-child { 90 &:last-child {
76 border-start-start-radius: calc(fn.dim(--rounding) - fn.dim(--border)); 91 border-end-start-radius: calc(props.get(vars.$rounding) - props.get(vars.$border-width));
77 border-start-end-radius: calc(fn.dim(--rounding) - fn.dim(--border)); 92 border-end-end-radius: calc(props.get(vars.$rounding) - props.get(vars.$border-width));
78 } 93 }
79 94
80 &:last-child { 95 @include bem.next-elem('avatar') {
81 border-end-start-radius: calc(fn.dim(--rounding) - fn.dim(--border)); 96 margin-block-start: calc(-.7 * props.get(avatar.$size--xl));
82 border-end-end-radius: calc(fn.dim(--rounding) - fn.dim(--border)); 97 }
83 } 98 }
84 99
85 @include iro.bem-next-elem('avatar') { 100 @include bem.elem('image-img') {
86 margin-block-start: calc(-.7 * fn.foreign-dim(--avatar, --xl --size)); 101 display: block;
87 } 102 inline-size: 100%;
88 } 103 object-fit: cover;
104 }
89 105
90 @include iro.bem-elem('body') { 106 @include bem.elem('image-overlay') {
91 padding-block: fn.dim(--pad-b); 107 position: absolute;
92 padding-inline: fn.dim(--pad-i); 108 inset-block-end: 0;
109 inset-inline: 0;
110 z-index: 5;
111 padding-block: props.get(vars.$image-overlay--pad-b);
112 padding-inline: props.get(vars.$image-overlay--pad-i);
113 }
93 114
94 &::before { 115 @include bem.elem('body') {
95 content: ''; 116 flex: 1 0 auto;
96 display: block; 117 padding-block: props.get(vars.$pad-b);
97 margin-block: -100em 100em; 118 padding-inline: props.get(vars.$pad-i);
98 }
99 }
100 119
101 @include iro.bem-elem('content') { 120 &::before {
102 margin-block-start: fn.dim(--spacing); 121 display: block;
103 } 122 margin-block: -100em 100em;
123 content: '';
124 }
125 }
104 126
105 @include iro.bem-elem('footer') { 127 @include bem.elem('content') {
106 padding-block: 0 fn.dim(--pad-b); 128 margin-block-start: props.get(vars.$spacing);
107 padding-inline: fn.dim(--pad-i); 129 }
108 margin-block-start: calc(-1 * fn.dim(--pad-b));
109 130
110 &::before { 131 @include bem.elem('footer') {
111 content: ''; 132 flex: 0 0 auto;
112 display: block; 133 padding-block: 0 props.get(vars.$pad-b);
113 block-size: fn.dim(--divider); 134 padding-inline: props.get(vars.$pad-i);
114 margin-block: fn.dim(--spacing); 135 margin-block-start: calc(-1 * props.get(vars.$pad-b));
115 background-color: fn.color(--divider);
116 }
117 }
118 136
119 @include iro.bem-modifier('quiet') { 137 &::before {
120 position: relative; 138 display: block;
121 border: 0; 139 block-size: props.get(vars.$divider-width);
122 background-color: transparent; 140 margin-block: props.get(vars.$spacing);
141 content: '';
142 background-color: props.get(vars.$divider-width);
143 }
144 }
123 145
124 @include iro.bem-multi('&:link, &:visited, &:enabled', 'modifier' 'interactive') { 146 @include bem.modifier('quiet') {
125 &:hover, 147 margin-inline: 0;
126 &:active { 148 background-color: transparent;
127 @include iro.bem-elem('image') { 149 border: 0;
128 opacity: .75; 150 box-shadow: none;
129 background-color: fn.color(--quiet --hover --image);
130 }
131 }
132 151
133 &:focus-visible { 152 @include bem.multi('&:link, &:visited, &:enabled', 'modifier' 'interactive') {
134 outline: none; 153 &:hover,
135 box-shadow: none; 154 &:active,
155 &:focus-visible {
156 background-color: transparent;
157 transform: none;
136 158
137 @include iro.bem-elem('image') { 159 @include bem.elem('image') {
138 outline: fn.color(--key-focus --border) solid fn.dim(--key-focus --border); 160 background-color: props.get(vars.$quiet--hover--image-color);
139 opacity: 1; 161 opacity: .75;
140 background-color: fn.color(--quiet --hover --image); 162 transform: translateY(props.get(vars.$hover--offset-b));
141 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(--key-focus --outline); 163 }
142 } 164 }
143 }
144 }
145 165
146 @include iro.bem-elem('image') { 166 &:focus-visible {
147 position: relative; 167 margin: 0;
148 margin: calc(-1 * fn.dim(--key-focus --border)); 168 outline: none;
149 border: fn.dim(--key-focus --border-offset) solid transparent; 169 border: 0;
150 border-radius: calc(fn.dim(--rounding) + fn.dim(--key-focus --border-offset)); 170 box-shadow: none;
151 background-color: fn.color(--quiet --image);
152 background-clip: padding-box;
153 }
154 171
155 @include iro.bem-elem('body') { 172 @include bem.elem('image') {
156 padding: 0; 173 margin: calc(-1 * props.get(vars.$key-focus--border-width));
157 padding-block-start: fn.dim(--spacing); 174 outline: props.get(vars.$key-focus--border-color) solid props.get(vars.$key-focus--border-width);
158 } 175 background-color: props.get(vars.$quiet--hover--image-color);
176 border: props.get(vars.$key-focus--border-offset) solid transparent;
177 border-radius: calc(props.get(vars.$rounding) + props.get(vars.$key-focus--border-offset));
178 box-shadow:
179 0
180 0
181 0
182 calc(props.get(vars.$key-focus--border-width) + props.get(vars.$key-focus--outline-width))
183 props.get(vars.$key-focus--outline-color);
184 opacity: 1;
185 }
186 }
187 }
159 188
160 @include iro.bem-elem('footer') { 189 @include bem.elem('image') {
161 padding-inline: 0; 190 position: relative;
162 } 191 background-color: props.get(vars.$quiet--image-color);
163 } 192 background-clip: padding-box;
164 } 193 border-radius: props.get(vars.$rounding);
194 }
195
196 @include bem.elem('body') {
197 padding: 0;
198 padding-block-start: props.get(vars.$spacing);
199 }
200
201 @include bem.elem('footer') {
202 padding-inline: 0;
203 }
204 }
205
206 @include bem.modifier('thumbnail') {
207 @include bem.elem('image') {
208 border-radius: props.get(vars.$rounding);
209 }
210
211 @include bem.elem('body') {
212 position: absolute;
213 inset-block-end: calc(-1 * props.get(vars.$border-width));
214 inset-inline: calc(-1 * props.get(vars.$border-width));
215 z-index: 10;
216 visibility: hidden;
217 background-color: props.get(vars.$hover--bg-color);
218 border-color: transparent;
219 border-style: solid;
220 border-width: 0 props.get(vars.$border-width) props.get(vars.$border-width);
221 border-end-start-radius: calc(props.get(vars.$rounding) - props.get(vars.$border-width));
222 border-end-end-radius: calc(props.get(vars.$rounding) - props.get(vars.$border-width));
223 opacity: 0;
224 transition:
225 border-color .2s ease,
226 opacity .2s ease,
227 visibility 0s .2s linear;
228 }
229
230 @include bem.multi('&:link, &:visited, &:enabled', 'modifier' 'interactive') {
231 &:hover,
232 &:active,
233 &:focus-visible {
234 @include bem.elem('body') {
235 visibility: visible;
236 border-color: props.get(vars.$hover--border-color);
237 opacity: 1;
238 transition:
239 border-color .2s ease,
240 opacity .2s ease,
241 visibility .2s linear;
242 }
243 }
244 }
245 }
246
247 @include bem.modifier('horizontal') {
248 flex-direction: row;
249 align-items: center;
250
251 @include bem.elem('image') {
252 align-self: stretch;
253 inline-size: auto;
254
255 &:first-child {
256 border-start-end-radius: 0;
257 border-end-start-radius: props.get(vars.$rounding);
258 }
259
260 &:last-child {
261 border-start-end-radius: props.get(vars.$rounding);
262 border-end-start-radius: 0;
263 }
264 }
265
266 @include bem.elem('body') {
267 flex: 0 0 auto;
268
269 @include bem.modifier('main') {
270 flex-shrink: 1;
271 inline-size: 100%;
272 min-inline-size: 0;
273 }
274 }
275 }
276 }
165} 277}
diff --git a/src/objects/_card.vars.scss b/src/objects/_card.vars.scss
new file mode 100644
index 0000000..ebfba10
--- /dev/null
+++ b/src/objects/_card.vars.scss
@@ -0,0 +1,39 @@
1@use 'sass:map';
2@use 'iro-sass/src/props';
3@use '../core.vars' as core;
4
5$divider-width: props.def(--o-card--divider-width, props.get(core.$border-width--thin)) !default;
6$border-width: props.def(--o-card--border-width, props.get(core.$border-width--thin)) !default;
7$sub-border-width: props.def(--o-card--sub-border-width, props.get(core.$border-width--thick)) !default;
8$pad-i: props.def(--o-card--pad-i, props.get(core.$size--300)) !default;
9$pad-b: props.def(--o-card--pad-b, props.get(core.$size--250)) !default;
10$spacing: props.def(--o-card--spacing, props.get(core.$size--200)) !default;
11$rounding: props.def(--o-card--rounding, props.get(core.$rounding)) !default;
12$image-overlay--pad-i: props.def(--o-card--image-overlay--pad-i, props.get($pad-i)) !default;
13$image-overlay--pad-b: props.def(--o-card--image-overlay--pad-b, props.get($pad-b)) !default;
14
15$hover--offset-b: props.def(--o-card--hover--offset-b, calc(-1 * props.get(core.$size--65))) !default;
16
17$shadow-x: props.def(--o-card--shadow-x, props.get(core.$shadow--l1--x)) !default;
18$shadow-y: props.def(--o-card--shadow-y, props.get(core.$shadow--l1--y)) !default;
19$shadow-blur: props.def(--o-card--shadow-blur, props.get(core.$shadow--l1--blur)) !default;
20$shadow-grow: props.def(--o-card--shadow-grow, props.get(core.$shadow--l1--grow)) !default;
21
22$key-focus--border-width: props.def(--o-card--key-focus--border-width, props.get(core.$key-focus--border-width)) !default;
23$key-focus--border-offset: props.def(--o-card--key-focus--border-offset, props.get(core.$key-focus--border-offset)) !default;
24$key-focus--outline-width: props.def(--o-card--key-focus--outline-width, props.get(core.$key-focus--outline-width)) !default;
25
26$shadow-color: props.def(--o-card--shadow-color, props.get(core.$theme, --shadow), 'color') !default;
27$bg-color: props.def(--o-card--bg-color, props.get(core.$theme, --bg-l2), 'color') !default;
28$border-color: props.def(--o-card--border-color, props.get(core.$theme, --box, --border), 'color') !default;
29$divider-color: props.def(--o-card--divider-color, props.get(core.$theme, --border-mute), 'color') !default;
30
31$hover--bg-color: props.def(--o-card--hover--bg-color, color-mix(in lch, props.get($bg-color), props.get(core.$theme, --border-mute)), 'color') !default;
32$hover--border-color: props.def(--o-card--hover--border-color, props.get(core.$theme, --border), 'color') !default;
33
34$key-focus--label-color: props.def(--o-card--key-focus--label-color, props.get(core.$theme, --focus, --text), 'color') !default;
35$key-focus--border-color: props.def(--o-card--key-focus--border-color, props.get(core.$theme, --focus, --border), 'color') !default;
36$key-focus--outline-color: props.def(--o-card--key-focus--outline-color, props.get(core.$theme, --focus, --outline), 'color') !default;
37
38$quiet--image-color: props.def(--o-card--quiet--image-color, props.get(core.$theme, --bg-base), 'color') !default;
39$quiet--hover--image-color: props.def(--o-card--quiet--hover--image-color, props.get(core.$theme, --border), 'color') !default;
diff --git a/src/objects/_checkbox.scss b/src/objects/_checkbox.scss
index 8527948..5faafb9 100644
--- a/src/objects/_checkbox.scss
+++ b/src/objects/_checkbox.scss
@@ -1,261 +1,231 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/functions' as fn;
4@use 'iro-sass/src/props';
5@use '../props' as *;
6@use '../core.vars' as core;
3 7
4@include iro.props-namespace('checkbox') { 8@forward 'checkbox.vars';
5 @include iro.props-store(( 9@use 'checkbox.vars' as vars;
6 --dims: (
7 --size: fn.global-dim(--size --175),
8 --label-gap: fn.global-dim(--size --125),
9 --border: fn.global-dim(--border --medium),
10 --pad-i: fn.global-dim(--size --65),
11 --pad-b: fn.global-dim(--size --65),
12 --rounding: fn.global-dim(--rounding),
13 --spacing-sibling: fn.global-dim(--size --300),
14 10
15 --key-focus: ( 11@mixin styles {
16 --border: fn.global-dim(--key-focus --border), 12 @include materialize-at-root(meta.module-variables('vars'));
17 --border-offset: fn.global-dim(--key-focus --border-offset),
18 --outline: fn.global-dim(--key-focus --outline),
19 ),
20 ),
21 --colors: (
22 --box-border: fn.global-color(--text-mute-more),
23 --box-bg: fn.global-color(--base --75),
24
25 --hover: (
26 --label: fn.global-color(--heading),
27 --box-border: fn.global-color(--text-mute),
28 ),
29 --accent: (
30 --box-border: fn.global-color(--accent --900),
31
32 --hover: (
33 --box-border: fn.global-color(--accent --1000),
34 ),
35 ),
36 --disabled: (
37 --label: fn.global-color(--text-disabled),
38 --box-border: fn.global-color(--border-strong),
39 --box-bg: fn.global-color(--base --75),
40 ),
41 --key-focus: (
42 --label: fn.global-color(--focus --text),
43 --border: fn.global-color(--focus --border),
44 --outline: fn.global-color(--focus --outline),
45 ),
46 ),
47 ));
48 13
49 @include iro.bem-object(iro.props-namespace()) { 14 @include bem.object('checkbox') {
50 display: inline-block; 15 position: relative;
51 position: relative; 16 display: inline-block;
52 margin-inline: 17 padding-block: props.get(vars.$pad-b);
53 calc(-1 * fn.dim(--pad-i) - fn.dim(--key-focus --border-offset)) 18 padding-inline: props.get(vars.$pad-i);
54 calc(fn.dim(--spacing-sibling) - fn.dim(--pad-b) - fn.dim(--key-focus --border-offset)); 19 margin-inline:
55 padding-block: fn.dim(--pad-b); 20 calc(-1 * props.get(vars.$pad-i) - props.get(vars.$key-focus--border-offset))
56 padding-inline: fn.dim(--pad-i); 21 calc(props.get(vars.$spacing-sibling) - props.get(vars.$pad-b) - props.get(vars.$key-focus--border-offset));
57 22
58 @include iro.bem-elem('box') { 23 @include bem.elem('box') {
59 display: inline-block; 24 position: relative;
60 position: relative; 25 display: inline-block;
61 flex: 0 0 auto; 26 flex: 0 0 auto;
62 inline-size: fn.dim(--size); 27 inline-size: props.get(vars.$size);
63 block-size: fn.dim(--size); 28 block-size: props.get(vars.$size);
64 margin-block-start: calc(.5em * fn.global-dim(--font --standard --line-height) - .5 * fn.dim(--size) - fn.dim(--key-focus --border-offset)); 29 margin-block-start: calc(.5em * props.get(core.$font--standard--line-height) - .5 * props.get(vars.$size) - props.get(vars.$key-focus--border-offset));
65 border: fn.dim(--key-focus --border-offset) solid transparent; 30 vertical-align: top;
66 border-radius: calc(fn.dim(--border) + fn.dim(--key-focus --border-offset)); 31 background-color: props.get(vars.$box-border-color);
67 background-color: fn.color(--box-border); 32 background-clip: padding-box;
68 background-clip: padding-box; 33 border: props.get(vars.$key-focus--border-offset) solid transparent;
69 vertical-align: top; 34 border-radius: calc(props.get(vars.$border-width) + props.get(vars.$key-focus--border-offset));
70 35
71 &::before, 36 &::before,
72 &::after { 37 &::after {
73 content: ''; 38 position: absolute;
74 display: block; 39 display: block;
75 position: absolute; 40 content: '';
76 } 41 }
77 42
78 &::before { 43 &::before {
79 z-index: 2; 44 inset-block-start: props.get(vars.$border-width);
80 inset-block-start: fn.dim(--border); 45 inset-inline-start: props.get(vars.$border-width);
81 inset-inline-start: fn.dim(--border); 46 z-index: 2;
82 inline-size: calc(fn.dim(--size) - 2 * fn.dim(--border)); 47 inline-size: calc(props.get(vars.$size) - 2 * props.get(vars.$border-width));
83 block-size: calc(fn.dim(--size) - 2 * fn.dim(--border)); 48 block-size: calc(props.get(vars.$size) - 2 * props.get(vars.$border-width));
84 transition: transform .2s ease; 49 background-color: props.get(vars.$box-bg-color);
85 background-color: fn.color(--box-bg); 50 transition: transform .2s ease;
86 } 51 }
87 52
88 &::after { 53 &::after {
89 z-index: 3; 54 inset-block-start: calc(.5 * props.get(vars.$size) - 1px);
90 inset-block-start: calc(.5 * fn.dim(--size) - 1px); 55 inset-inline-start: calc(1.5 * props.get(vars.$border-width));
91 inset-inline-start: calc(1.5 * fn.dim(--border)); 56 z-index: 3;
92 box-sizing: border-box; 57 box-sizing: border-box;
93 inline-size: calc(fn.dim(--size) - 3 * fn.dim(--border)); 58 inline-size: calc(props.get(vars.$size) - 3 * props.get(vars.$border-width));
94 block-size: 0; 59 block-size: 0;
95 transform: scale(0); 60 border-color: props.get(vars.$box-bg-color);
96 transition: transform .2s ease; 61 border-style: solid;
97 border-block-width: 0 2px; 62 border-radius: 2px;
98 border-inline-width: 0 2px; 63 transform: scale(0);
99 border-style: solid; 64 transition: transform .2s ease;
100 border-radius: 2px; 65 border-block-width: 0 2px;
101 border-color: fn.color(--box-bg); 66 border-inline-width: 0 2px;
102 } 67 }
103 } 68 }
104 69
105 @include iro.bem-elem('check-icon') { 70 @include bem.elem('check-icon') {
106 display: block; 71 position: absolute;
107 position: absolute; 72 inset-block-start: calc(1 * props.get(vars.$border-width));
108 z-index: 2; 73 inset-inline-start: calc(1 * props.get(vars.$border-width));
109 inset-block-start: calc(1 * fn.dim(--border)); 74 z-index: 2;
110 inset-inline-start: calc(1 * fn.dim(--border)); 75 display: block;
111 inline-size: calc(100% - 2 * fn.dim(--border)); 76 inline-size: calc(100% - 2 * props.get(vars.$border-width));
112 block-size: calc(100% - 2 * fn.dim(--border)); 77 block-size: calc(100% - 2 * props.get(vars.$border-width));
113 margin: 0; 78 margin: 0;
114 transform: scale(0); 79 color: props.get(vars.$box-bg-color);
115 transform-origin: 40% 90%; 80 stroke-width: fn.px-to-rem(3px);
116 transition: transform .2s ease; 81 transform: scale(0);
117 stroke-width: iro.fn-px-to-rem(3px); 82 transform-origin: 40% 90%;
118 color: fn.color(--box-bg); 83 transition: transform .2s ease;
119 } 84 }
120 85
121 @include iro.bem-elem('label') { 86 @include bem.elem('label') {
122 margin-inline-start: calc(fn.dim(--label-gap) - fn.dim(--key-focus --border-offset)); 87 margin-inline-start: calc(props.get(vars.$label-gap) - props.get(vars.$key-focus--border-offset));
123 } 88 }
124 89
125 @include iro.bem-elem('native') { 90 @include bem.elem('native') {
126 appearance: none; 91 position: absolute;
127 position: absolute; 92 inset-block-start: 0;
128 z-index: -1; 93 inset-inline-start: 0;
129 inset-block-start: 0; 94 z-index: -1;
130 inset-inline-start: 0; 95 inline-size: 100%;
131 inline-size: 100%; 96 block-size: 100%;
132 block-size: 100%; 97 padding: 0;
133 margin: 0; 98 margin: 0;
134 padding: 0; 99 overflow: hidden;
135 overflow: hidden; 100 appearance: none;
136 border-radius: fn.dim(--rounding); 101 border-radius: props.get(vars.$rounding);
137 102
138 &:hover, 103 &:hover,
139 &:focus-visible { 104 &:focus-visible {
140 @include iro.bem-sibling-elem('label') { 105 @include bem.sibling-elem('label') {
141 color: fn.color(--hover --label); 106 color: props.get(vars.$hover--label-color);
142 } 107 }
143 108
144 @include iro.bem-sibling-elem('box') { 109 @include bem.sibling-elem('box') {
145 background-color: fn.color(--hover --box-border); 110 background-color: props.get(vars.$hover--box-border-color);
146 } 111 }
147 } 112 }
148 113
149 &:checked { 114 &:checked {
150 @include iro.bem-sibling-elem('box') { 115 @include bem.sibling-elem('box') {
151 &::before { 116 &::before {
152 transform: scale(0); 117 transform: scale(0);
153 } 118 }
154 119
155 @include iro.bem-elem('check-icon') { 120 @include bem.elem('check-icon') {
156 transform: scale(1); 121 transform: scale(1);
157 } 122 }
158 } 123 }
159 } 124 }
160 125
161 &:indeterminate { 126 &:indeterminate {
162 @include iro.bem-sibling-elem('box') { 127 @include bem.sibling-elem('box') {
163 &::before { 128 &::before {
164 transform: scale(0); 129 transform: scale(0);
165 } 130 }
166 131
167 &::after { 132 &::after {
168 transform: scale(1); 133 transform: scale(1);
169 } 134 }
170 135
171 @include iro.bem-elem('check-icon') { 136 @include bem.elem('check-icon') {
172 transform: scale(0); 137 transform: scale(0);
173 } 138 }
174 } 139 }
175 } 140 }
176 141
177 &:disabled { 142 &:disabled {
178 @include iro.bem-sibling-elem('label') { 143 @include bem.sibling-elem('label') {
179 color: fn.color(--disabled --label); 144 color: props.get(vars.$disabled--label-color);
180 } 145 }
181 146
182 @include iro.bem-sibling-elem('box') { 147 @include bem.sibling-elem('box') {
183 background-color: fn.color(--disabled --box-border); 148 background-color: props.get(vars.$disabled--box-border-color);
184 149
185 &::before { 150 &::before {
186 background-color: fn.color(--disabled --box-bg); 151 background-color: props.get(vars.$disabled--box-bg-color);
187 } 152 }
188 } 153 }
189 } 154 }
190 155
191 &:focus-visible { 156 &:focus-visible {
192 @include iro.bem-sibling-elem('label') { 157 @include bem.sibling-elem('label') {
193 color: fn.color(--key-focus --label); 158 color: props.get(vars.$key-focus--label-color);
194 } 159 }
195 160
196 @include iro.bem-sibling-elem('box') { 161 @include bem.sibling-elem('box') {
197 outline: fn.color(--key-focus --border) solid fn.dim(--key-focus --border); 162 outline: props.get(vars.$key-focus--border-color) solid props.get(vars.$key-focus--border-width);
198 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(--key-focus --outline); 163 box-shadow:
199 } 164 0
200 } 165 0
201 } 166 0
167 calc(props.get(vars.$key-focus--border-width) + props.get(vars.$key-focus--outline-width))
168 props.get(vars.$key-focus--outline-color);
169 }
170 }
171 }
202 172
203 @include iro.bem-modifier('standalone') { 173 @include bem.modifier('standalone') {
204 @include iro.bem-elem('box') { 174 @include bem.elem('box') {
205 margin-block-start: 0; 175 margin-block-start: 0;
206 } 176 }
207 } 177 }
208 178
209 @include iro.bem-modifier('accent') { 179 @include bem.modifier('accent') {
210 @include iro.bem-elem('native') { 180 @include bem.elem('native') {
211 &:checked { 181 &:checked {
212 @include iro.bem-sibling-elem('box') { 182 @include bem.sibling-elem('box') {
213 background-color: fn.color(--accent --box-border); 183 background-color: props.get(vars.$accent--box-border-color);
214 } 184 }
215 185
216 &:hover, 186 &:hover,
217 &:focus-visible { 187 &:focus-visible {
218 @include iro.bem-sibling-elem('box') { 188 @include bem.sibling-elem('box') {
219 background-color: fn.color(--accent --hover --box-border); 189 background-color: props.get(vars.$accent--hover--box-border-color);
220 } 190 }
221 } 191 }
222 } 192 }
223 193
224 &:indeterminate { 194 &:indeterminate {
225 @include iro.bem-sibling-elem('box') { 195 @include bem.sibling-elem('box') {
226 background-color: fn.color(--accent --box-border); 196 background-color: props.get(vars.$accent--box-border-color);
227 } 197 }
228 198
229 &:hover, 199 &:hover,
230 &:focus-visible { 200 &:focus-visible {
231 @include iro.bem-sibling-elem('box') { 201 @include bem.sibling-elem('box') {
232 background-color: fn.color(--accent --hover --box-border); 202 background-color: props.get(vars.$accent--hover--box-border-color);
233 } 203 }
234 } 204 }
235 } 205 }
236 206
237 &:disabled { 207 &:disabled {
238 @include iro.bem-sibling-elem('box') { 208 @include bem.sibling-elem('box') {
239 background-color: fn.color(--disabled --box-border); 209 background-color: props.get(vars.$disabled--box-border-color);
240 210
241 &::before { 211 &::before {
242 background-color: fn.color(--disabled --box-bg); 212 background-color: props.get(vars.$disabled--box-bg-color);
243 } 213 }
244 } 214 }
245 215
246 &:checked { 216 &:checked {
247 @include iro.bem-sibling-elem('box') { 217 @include bem.sibling-elem('box') {
248 background-color: fn.color(--disabled --box-border); 218 background-color: props.get(vars.$disabled--box-border-color);
249 } 219 }
250 } 220 }
251 221
252 &:indeterminate { 222 &:indeterminate {
253 @include iro.bem-sibling-elem('box') { 223 @include bem.sibling-elem('box') {
254 background-color: fn.color(--disabled --box-border); 224 background-color: props.get(vars.$disabled--box-border-color);
255 } 225 }
256 } 226 }
257 } 227 }
258 } 228 }
259 } 229 }
260 } 230 }
261} 231}
diff --git a/src/objects/_checkbox.vars.scss b/src/objects/_checkbox.vars.scss
new file mode 100644
index 0000000..25a0d3d
--- /dev/null
+++ b/src/objects/_checkbox.vars.scss
@@ -0,0 +1,32 @@
1@use 'sass:map';
2@use 'iro-sass/src/props';
3@use '../core.vars' as core;
4
5$size: props.def(--o-checkbox--size, props.get(core.$size--175)) !default;
6$label-gap: props.def(--o-checkbox--label-gap, props.get(core.$size--125)) !default;
7$border-width: props.def(--o-checkbox--border-width, props.get(core.$border-width--medium)) !default;
8$pad-i: props.def(--o-checkbox--pad-i, props.get(core.$size--65)) !default;
9$pad-b: props.def(--o-checkbox--pad-b, props.get(core.$size--65)) !default;
10$rounding: props.def(--o-checkbox--rounding, props.get(core.$rounding--sm)) !default;
11$spacing-sibling: props.def(--o-checkbox--spacing-sibling, props.get(core.$size--300)) !default;
12
13$key-focus--border-width: props.def(--o-checkbox--key-focus--border-width, props.get(core.$key-focus--border-width)) !default;
14$key-focus--border-offset: props.def(--o-checkbox--key-focus--border-offset, props.get(core.$key-focus--border-offset)) !default;
15$key-focus--outline-width: props.def(--o-checkbox--key-focus--outline-width, props.get(core.$key-focus--outline-width)) !default;
16
17$box-border-color: props.def(--o-checkbox--box-border-color, props.get(core.$theme, --text-mute-more), 'color') !default;
18$box-bg-color: props.def(--o-checkbox--box-bg-color, props.get(core.$theme, --base, --75), 'color') !default;
19
20$hover--label-color: props.def(--o-checkbox--hover--label-color, props.get(core.$theme, --heading), 'color') !default;
21$hover--box-border-color: props.def(--o-checkbox--hover--box-border-color, props.get(core.$theme, --text-mute), 'color') !default;
22
23$accent--box-border-color: props.def(--o-checkbox--accent--box-border-color, props.get(core.$theme, --accent, --900), 'color') !default;
24$accent--hover--box-border-color: props.def(--o-checkbox--accent--hover--box-border-color, props.get(core.$theme, --accent, --1000), 'color') !default;
25
26$disabled--label-color: props.def(--o-checkbox--disabled--label-color, props.get(core.$theme, --text-disabled), 'color') !default;
27$disabled--box-border-color: props.def(--o-checkbox--disabled--box-border-color, props.get(core.$theme, --border-strong), 'color') !default;
28$disabled--box-bg-color: props.def(--o-checkbox--disabled--box-bg-color, props.get(core.$theme, --base, --75), 'color') !default;
29
30$key-focus--label-color: props.def(--o-checkbox--key-focus--label-color, props.get(core.$theme, --focus, --text), 'color') !default;
31$key-focus--border-color: props.def(--o-checkbox--key-focus--border-color, props.get(core.$theme, --focus, --border), 'color') !default;
32$key-focus--outline-color: props.def(--o-checkbox--key-focus--outline-color, props.get(core.$theme, --focus, --outline), 'color') !default;
diff --git a/src/objects/_divider.scss b/src/objects/_divider.scss
index d1e2897..27af173 100644
--- a/src/objects/_divider.scss
+++ b/src/objects/_divider.scss
@@ -1,203 +1,204 @@
1@use 'sass:map'; 1@use 'sass:map';
2@use 'iro-sass/src/index' as iro; 2@use 'sass:meta';
3@use '../functions' as fn; 3@use 'sass:string';
4@use '../config'; 4@use 'iro-sass/src/bem';
5@use 'iro-sass/src/props';
6@use '../props' as *;
7@use '../core.vars' as core;
5 8
6$static-themes: 'black' 'white' !default; 9@forward 'divider.vars';
10@use 'divider.vars' as vars;
7 11
8@include iro.props-namespace('divider') { 12@mixin styles {
9 @include iro.props-store(( 13 @include materialize-at-root(meta.module-variables('vars'));
10 --dims: ( 14
11 --margin-b: fn.global-dim(--size --85), 15 @include bem.object('divider') {
12 16 display: flex;
13 --strong: ( 17 flex: 0 0 auto;
14 --border: fn.global-dim(--border --thick), 18 flex-direction: row;
15 --label-font-size: fn.global-dim(--font-size --100), 19 align-items: center;
16 ), 20 block-size: 1em;
17 --medium: ( 21 margin-block: props.get(vars.$margin-b);
18 --border: fn.global-dim(--border --medium), 22 font-size: props.get(vars.$strong--label-font-size);
19 --label-font-size: fn.global-dim(--font-size --75), 23 font-weight: 700;
20 ), 24 line-height: 1;
21 --faint: ( 25 color: props.get(vars.$strong--label-color);
22 --border: fn.global-dim(--border --thin), 26 text-transform: uppercase;
23 --label-font-size: fn.global-dim(--font-size --50), 27 letter-spacing: .5px;
24 ), 28 background-color: transparent;
25 ), 29
26 --colors: ( 30 &::before,
27 --strong: ( 31 &::after {
28 --bg: fn.global-color(--text), 32 flex: 1 1 auto;
29 --label: fn.global-color(--text), 33 inline-size: 100%;
30 ), 34 block-size: props.get(vars.$strong--border-width);
31 --medium: ( 35 content: '';
32 --bg: fn.global-color(--border), 36 background-color: props.get(vars.$strong--bg-color);
33 --label: fn.global-color(--text-mute), 37 }
34 ), 38
35 --faint: ( 39 &::before {
36 --bg: fn.global-color(--border), 40 display: block;
37 --label: fn.global-color(--text-mute-more), 41 }
38 ), 42
39 ), 43 @include bem.elem('label') {
40 )); 44 flex: 0 0 auto;
45 }
46
47 @include bem.modifier('vertical') {
48 align-self: stretch;
49 inline-size: props.get(vars.$vertical--border-width);
50 block-size: auto;
51 margin-block: 0;
52 background-color: props.get(vars.$strong--bg-color);
41 53
42 @each $color in map.keys(map.get(config.$themes, config.$theme-default, --palettes)) { 54 &::before,
43 @if $color != '--base' { 55 &::after {
44 @include iro.props-store(( 56 display: none;
45 --colors: ( 57 }
46 $color: ( 58 }
47 --bg: fn.global-color($color --800),
48 --label: fn.global-color($color --1000),
49 )
50 ),
51 ));
52 }
53 }
54 59
55 @each $theme in $static-themes { 60 @include bem.modifier('dot') {
56 @include iro.props-store(( 61 align-self: center;
57 --colors: ( 62 inline-size: props.get(vars.$dot--size);
58 --static-#{$theme}: ( 63 block-size: props.get(vars.$dot--size);
59 --strong: ( 64 margin-block: 0;
60 --bg: fn.global-color(--#{$theme}-transparent --800), 65 background-color: props.get(vars.$strong--bg-color);
61 --label: fn.global-color(--#{$theme}-transparent --900), 66 border-radius: props.get(vars.$dot--size);
62 ),
63 --medium: (
64 --bg: fn.global-color(--#{$theme}-transparent --300),
65 --label: fn.global-color(--#{$theme}-transparent --500),
66 ),
67 --faint: (
68 --bg: fn.global-color(--#{$theme}-transparent --300),
69 --label: fn.global-color(--#{$theme}-transparent --500),
70 ),
71 )
72 ),
73 ));
74 }
75 67
76 @include iro.bem-object(iro.props-namespace()) { 68 &::before,
77 display: flex; 69 &::after {
78 flex: 0 0 auto; 70 display: none;
79 flex-direction: row; 71 }
80 align-items: center; 72 }
81 block-size: 1em;
82 margin-block: fn.dim(--margin-b);
83 color: fn.color(--strong --label);
84 font-size: fn.dim(--strong --label-font-size);
85 font-weight: 700;
86 letter-spacing: .5px;
87 line-height: 1;
88 text-transform: uppercase;
89 73
90 &::before, 74 @include bem.modifier('medium') {
91 &::after { 75 font-size: props.get(vars.$medium--label-font-size);
92 content: ''; 76 font-weight: 500;
93 flex: 1 1 auto; 77 color: props.get(vars.$medium--label-color);
94 inline-size: 100%;
95 block-size: fn.dim(--strong --border);
96 background-color: fn.color(--strong --bg);
97 }
98 78
99 &::before { 79 &::before,
100 display: block; 80 &::after {
101 } 81 block-size: props.get(vars.$medium--border-width);
82 background-color: props.get(vars.$medium--bg-color);
83 }
102 84
103 @include iro.bem-elem('label') { 85 @include bem.modifier('vertical') {
104 flex: 0 0 auto; 86 background-color: props.get(vars.$medium--bg-color);
105 } 87 }
106 88
107 @include iro.bem-modifier('vertical') { 89 @include bem.modifier('dot') {
108 align-self: stretch; 90 background-color: props.get(vars.$medium--bg-color);
109 inline-size: 1px; 91 }
110 block-size: auto; 92 }
111 margin-block: 0;
112 background-color: fn.color(--faint --bg);
113 93
114 &::before, 94 @include bem.modifier('quiet') {
115 &::after { 95 font-size: props.get(vars.$quiet--label-font-size);
116 display: none; 96 font-weight: 500;
117 } 97 color: props.get(vars.$quiet--label-color);
118 }
119 98
120 @include iro.bem-modifier('medium') { 99 &::before,
121 color: fn.color(--medium --label); 100 &::after {
122 font-size: fn.dim(--medium --label-font-size); 101 block-size: props.get(vars.$quiet--border-width);
123 font-weight: 500; 102 background-color: props.get(vars.$quiet--bg-color);
103 }
124 104
125 &::before, 105 @include bem.modifier('vertical') {
126 &::after { 106 background-color: props.get(vars.$vertical--quiet--bg-color);
127 block-size: fn.dim(--medium --border); 107 }
128 background-color: fn.color(--medium --bg);
129 }
130 }
131 108
132 @include iro.bem-modifier('faint') { 109 @include bem.modifier('dot') {
133 color: fn.color(--faint --label); 110 background-color: props.get(vars.$dot--quiet--bg-color);
134 font-size: fn.dim(--faint --label-font-size); 111 }
135 font-weight: 500; 112 }
136 113
137 &::before, 114 @include bem.modifier('faint') {
138 &::after { 115 font-size: props.get(vars.$faint--label-font-size);
139 block-size: fn.dim(--faint --border); 116 font-weight: 500;
140 background-color: fn.color(--faint --bg); 117 color: props.get(vars.$faint--label-color);
141 }
142 }
143 118
144 @include iro.bem-modifier('labelled') { 119 &::before,
145 &::before { 120 &::after {
146 margin-inline-end: 1em; 121 block-size: props.get(vars.$faint--border-width);
147 } 122 background-color: props.get(vars.$faint--bg-color);
123 }
148 124
149 &::after { 125 @include bem.modifier('vertical') {
150 display: block; 126 background-color: props.get(vars.$vertical--quiet--bg-color);
151 margin-inline-start: 1em; 127 }
152 }
153 }
154 128
155 @each $color in 'blue' 'purple' 'red' 'green' 'yellow' { 129 @include bem.modifier('dot') {
156 @include iro.bem-modifier($color) { 130 background-color: props.get(vars.$dot--quiet--bg-color);
157 &::before, 131 }
158 &::after { 132 }
159 background-color: fn.color(--#{$color} --bg);
160 }
161 133
162 @include iro.bem-elem('label') { 134 @include bem.modifier('labelled') {
163 color: fn.color(--#{$color} --label); 135 &::before {
164 } 136 margin-inline-end: 1em;
165 } 137 }
166 }
167 138
168 @each $theme in $static-themes { 139 &::after {
169 @include iro.bem-modifier(static-#{$theme}) { 140 display: block;
170 &::before, 141 margin-inline-start: 1em;
171 &::after { 142 }
172 background-color: fn.color(--static-#{$theme} --strong --bg); 143 }
173 }
174 144
175 @include iro.bem-elem('label') { 145 @each $theme in map.keys(props.get(vars.$themes)) {
176 color: fn.color(--static-#{$theme} --strong --label); 146 @include bem.modifier(string.slice($theme, 3)) {
177 } 147 &::before,
148 &::after {
149 background-color: props.get(vars.$themes, $theme, --bg);
150 }
178 151
179 @include iro.bem-modifier('medium') { 152 @include bem.elem('label') {
180 &::before, 153 color: props.get(vars.$themes, $theme, --label);
181 &::after { 154 }
182 background-color: fn.color(--static-#{$theme} --medium --bg); 155 }
183 } 156 }
157
158 @each $theme in map.keys(props.get(vars.$static-themes)) {
159 @include bem.modifier(string.slice($theme, 3)) {
160 &::before,
161 &::after {
162 background-color: props.get(vars.$static-themes, $theme, --strong, --bg);
163 }
164
165 @include bem.elem('label') {
166 color: props.get(vars.$static-themes, $theme, --strong, --label);
167 }
168
169 @include bem.modifier('medium') {
170 &::before,
171 &::after {
172 background-color: props.get(vars.$static-themes, $theme, --medium, --bg);
173 }
174
175 @include bem.elem('label') {
176 color: props.get(vars.$static-themes, $theme, --medium, --label);
177 }
178 }
179
180 @include bem.modifier('quiet') {
181 &::before,
182 &::after {
183 background-color: props.get(vars.$static-themes, $theme, --quiet, --bg);
184 }
184 185
185 @include iro.bem-elem('label') { 186 @include bem.elem('label') {
186 color: fn.color(--static-#{$theme} --medium --label); 187 color: props.get(vars.$static-themes, $theme, --quiet, --label);
187 } 188 }
188 } 189 }
189 190
190 @include iro.bem-modifier('faint') { 191 @include bem.modifier('faint') {
191 &::before, 192 &::before,
192 &::after { 193 &::after {
193 background-color: fn.color(--static-#{$theme} --faint --bg); 194 background-color: props.get(vars.$static-themes, $theme, --faint, --bg);
194 } 195 }
195 196
196 @include iro.bem-elem('label') { 197 @include bem.elem('label') {
197 color: fn.color(--static-#{$theme} --faint --label); 198 color: props.get(vars.$static-themes, $theme, --faint, --label);
198 } 199 }
199 } 200 }
200 } 201 }
201 } 202 }
202 } 203 }
203} 204}
diff --git a/src/objects/_divider.vars.scss b/src/objects/_divider.vars.scss
new file mode 100644
index 0000000..688fbb3
--- /dev/null
+++ b/src/objects/_divider.vars.scss
@@ -0,0 +1,79 @@
1@use 'sass:map';
2@use 'sass:string';
3@use 'iro-sass/src/props';
4@use '../core.vars' as core;
5
6$margin-b: props.def(--o-divider--size, props.get(core.$size--85)) !default;
7$vertical--border-width: props.def(--o-divider--vertical--width, props.get(core.$border-width--thin)) !default;
8$dot--size: props.def(--o-divider--dot--size, props.get(core.$size--50)) !default;
9
10$strong--border-width: props.def(--o-divider--strong--border-width, props.get(core.$border-width--thick)) !default;
11$strong--label-font-size: props.def(--o-divider--strong--label-font-size, props.get(core.$font-size--100)) !default;
12
13$medium--border-width: props.def(--o-divider--medium--border-width, props.get(core.$border-width--medium)) !default;
14$medium--label-font-size: props.def(--o-divider--medium--label-font-size, props.get(core.$font-size--75)) !default;
15
16$quiet--border-width: props.def(--o-divider--quiet--border-width, props.get(core.$border-width--thin)) !default;
17$quiet--label-font-size: props.def(--o-divider--quiet--label-font-size, props.get(core.$font-size--50)) !default;
18
19$faint--border-width: props.def(--o-divider--faint--border-width, props.get(core.$border-width--thin)) !default;
20$faint--label-font-size: props.def(--o-divider--faint--label-font-size, props.get(core.$font-size--50)) !default;
21
22$strong--bg-color: props.def(--o-divider--strong--bg-color, props.get(core.$theme, --text), 'color') !default;
23$strong--label-color: props.def(--o-divider--strong--label-color, props.get(core.$theme, --text), 'color') !default;
24
25$medium--bg-color: props.def(--o-divider--medium--bg-color, props.get(core.$theme, --border), 'color') !default;
26$medium--label-color: props.def(--o-divider--medium--label-color, props.get(core.$theme, --text-mute), 'color') !default;
27
28$quiet--bg-color: props.def(--o-divider--quiet--bg-color, props.get(core.$theme, --border), 'color') !default;
29$quiet--label-color: props.def(--o-divider--quiet--label-color, props.get(core.$theme, --text-mute-more), 'color') !default;
30
31$faint--bg-color: props.def(--o-divider--faint--bg-color, props.get(core.$theme, --border-mute), 'color') !default;
32$faint--label-color: props.def(--o-divider--faint--label-color, props.get(core.$theme, --text-disabled), 'color') !default;
33
34$vertical--quiet--bg-color: props.def(--o-divider--vertical--quiet--bg-color, props.get(core.$theme, --border-mute), 'color') !default;
35
36$dot--quiet--bg-color: props.def(--o-divider--dot--quiet--bg-color, props.get(core.$theme, --border-mute), 'color') !default;
37
38$static-themes: props.def(--o-divider, (), 'color');
39
40@each $theme in map.keys(props.get(core.$transparent-colors)) {
41 $button-theme: --static-#{string.slice($theme, 3)};
42
43 $static-themes: props.merge($static-themes, (
44 $button-theme: (
45 --strong: (
46 --bg: props.get(core.$transparent-colors, $theme, --800),
47 --label: props.get(core.$transparent-colors, $theme, --900),
48 ),
49 --medium: (
50 --bg: props.get(core.$transparent-colors, $theme, --300),
51 --label: props.get(core.$transparent-colors, $theme, --500),
52 ),
53 --quiet: (
54 --bg: props.get(core.$transparent-colors, $theme, --300),
55 --label: props.get(core.$transparent-colors, $theme, --500),
56 ),
57 --faint: (
58 --bg: props.get(core.$transparent-colors, $theme, --200),
59 --label: props.get(core.$transparent-colors, $theme, --400),
60 ),
61 )
62 ));
63}
64
65$themes-config: (
66 accent: --accent,
67 negative: --negative,
68) !default;
69
70$themes: props.def(--o-divider, (), 'color');
71
72@each $theme, $key in $themes-config {
73 $themes: props.merge($themes, (
74 --#{$theme}: (
75 --bg: props.get(core.$theme, $key, --800),
76 --label: props.get(core.$theme, $key, --1000),
77 )
78 ));
79}
diff --git a/src/objects/_emoji.scss b/src/objects/_emoji.scss
index d8d1289..fd36535 100644
--- a/src/objects/_emoji.scss
+++ b/src/objects/_emoji.scss
@@ -1,73 +1,50 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use 'sass:math'; 3@use 'iro-sass/src/props';
4@use '../props' as *;
5@use 'icon.vars' as icon;
4 6
5@use 'icon'; 7@forward 'emoji.vars';
8@use 'emoji.vars' as vars;
6 9
7@include iro.props-namespace('emoji') { 10@mixin styles {
8 @include iro.props-store(( 11 @include materialize-at-root(meta.module-variables('vars'));
9 --dims: (
10 --size: calc(1 / 14 * 18em),
11 --pad: .3em,
12 --rounding: fn.global-dim(--rounding),
13 --zoom: 3,
14 --valign: -.25em,
15 12
16 --125: ( 13 @include bem.object('emoji') {
17 --size: calc(1 / 14 * 23em), 14 position: relative;
18 --valign: -.45em, 15 display: inline-block;
19 ), 16 inline-size: calc(props.get(vars.$size));
17 block-size: calc(props.get(vars.$size));
18 padding: calc(props.get(vars.$pad));
19 margin: calc(-1 * props.get(vars.$pad));
20 vertical-align: props.get(vars.$valign);
21 object-fit: contain;
20 22
21 --150: ( 23 @include bem.modifier('icon') {
22 --size: calc(1 / 14 * 28em), 24 margin: calc(-1 * props.get(vars.$pad) - .5 * (props.get(vars.$size) - props.get(icon.$size)));
23 --valign: -.65em, 25 vertical-align: props.get(icon.$valign);
24 ), 26 }
25 27
26 --200: ( 28 @each $mod, $size, $valign in vars.$sizes {
27 --size: calc(1 / 14 * 38em), 29 @include bem.modifier($mod) {
28 --valign: -1em, 30 inline-size: props.get($size);
29 ) 31 block-size: props.get($size);
30 ), 32 vertical-align: props.get($valign);
31 --colors: (
32 --bg: fn.global-color(--border-mute),
33 )
34 ));
35 33
36 @include iro.bem-object(iro.props-namespace()) { 34 @include bem.modifier('icon') {
37 display: inline-block; 35 margin: calc(-1 * props.get(vars.$pad) - .5 * (props.get($size) - props.get(icon.$size)));
38 position: relative; 36 }
39 inline-size: calc(fn.dim(--size)); 37 }
40 block-size: calc(fn.dim(--size)); 38 }
41 margin: calc(-1 * fn.dim(--pad));
42 padding: calc(fn.dim(--pad));
43 vertical-align: fn.dim(--valign);
44 object-fit: contain;
45 39
46 @include iro.bem-modifier('icon') { 40 @include bem.modifier('zoomable') {
47 margin: calc(-1 * fn.dim(--pad) - .5 * (fn.dim(--size) - fn.foreign-dim(--icon, --size))); 41 border-radius: calc(props.get(vars.$rounding) / props.get(vars.$zoom));
48 vertical-align: fn.foreign-dim(--icon, --valign); 42 transition: transform .2s ease, background-color .2s ease;
49 }
50 43
51 @each $size in '125' '150' '200' { 44 &:hover {
52 @include iro.bem-modifier($size) { 45 background-color: props.get(vars.$bg-color);
53 inline-size: fn.dim(--#{$size} --size); 46 transform: scale(props.get(vars.$zoom));
54 block-size: fn.dim(--#{$size} --size); 47 }
55 vertical-align: fn.dim(--#{$size} --valign); 48 }
56 49 }
57 @include iro.bem-modifier('icon') {
58 margin: calc(-1 * fn.dim(--pad) - .5 * (fn.dim(--#{$size} --size) - fn.foreign-dim(--icon, --size)));
59 }
60 }
61 }
62
63 @include iro.bem-modifier('zoomable') {
64 transition: transform .2s ease, background-color .2s ease;
65 border-radius: calc(fn.dim(--rounding) / fn.dim(--zoom));
66
67 &:hover {
68 transform: scale(fn.dim(--zoom));
69 background-color: fn.color(--bg);
70 }
71 }
72 }
73} 50}
diff --git a/src/objects/_emoji.vars.scss b/src/objects/_emoji.vars.scss
new file mode 100644
index 0000000..b7a8a43
--- /dev/null
+++ b/src/objects/_emoji.vars.scss
@@ -0,0 +1,26 @@
1@use 'sass:map';
2@use 'iro-sass/src/props';
3@use '../core.vars' as core;
4
5$size: props.def(--o-emoji--size, calc(1 / 14 * 18em)) !default;
6$pad: props.def(--o-emoji--pad, .3em) !default;
7$rounding: props.def(--o-emoji--rounding, props.get(core.$rounding--sm)) !default;
8$zoom: props.def(--o-emoji--zoom, 3) !default;
9$valign: props.def(--o-emoji--valign, -.25em) !default;
10
11$size--125: props.def(--o-emoji--125--size, calc(1 / 14 * 23em)) !default;
12$valign--125: props.def(--o-emoji--125--valign, -.45em) !default;
13
14$size--150: props.def(--o-emoji--150--size, calc(1 / 14 * 28em)) !default;
15$valign--150: props.def(--o-emoji--150--valign, -.65em) !default;
16
17$size--200: props.def(--o-emoji--200--size, calc(1 / 14 * 38em)) !default;
18$valign--200: props.def(--o-emoji--200--valign, -1em) !default;
19
20$sizes: (
21 '125' $size--125 $valign--125,
22 '150' $size--150 $valign--150,
23 '200' $size--200 $valign--200,
24) !default;
25
26$bg-color: props.def(--o-emoji--bg-color, props.get(core.$theme, --border-mute), 'color') !default;
diff --git a/src/objects/_field-label.scss b/src/objects/_field-label.scss
index 1518ea6..aa12eb5 100644
--- a/src/objects/_field-label.scss
+++ b/src/objects/_field-label.scss
@@ -1,86 +1,76 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
3 5
4@include iro.props-namespace('field-label') { 6@forward 'field-label.vars';
5 @include iro.props-store(( 7@use 'field-label.vars' as vars;
6 --dims: (
7 --spacing-i: fn.global-dim(--size --150),
8 --spacing-b: fn.global-dim(--size --85),
9 --label-font-size: fn.global-dim(--font-size --75),
10 --hint-font-size: fn.global-dim(--font-size --75),
11 ),
12 --colors: (
13 --label: fn.global-color(--text-mute),
14 --hint: fn.global-color(--text-mute),
15 --error-hint: fn.global-color(--negative --900),
16 --disabled: fn.global-color(--text-disabled),
17 ),
18 ));
19 8
20 @include iro.bem-object(iro.props-namespace()) { 9@mixin styles {
21 display: block; 10 @include materialize-at-root(meta.module-variables('vars'));
22 11
23 @include iro.bem-elem('label') { 12 @include bem.object('field-label') {
24 display: block; 13 @include bem.elem('label') {
25 flex: 0 0 auto; 14 display: block;
26 padding-inline-end: fn.dim(--spacing-i); 15 flex: 0 0 auto;
27 color: fn.color(--label); 16 padding-inline-end: props.get(vars.$spacing-i);
28 font-size: fn.dim(--label-font-size); 17 font-size: props.get(vars.$label-font-size);
29 font-weight: 400; 18 font-weight: 400;
30 line-height: 1.3; 19 line-height: 1.3;
20 color: props.get(vars.$label-color);
31 21
32 @include iro.bem-next-elem('content') { 22 @include bem.next-elem('content') {
33 margin-block-start: fn.dim(--spacing-b); 23 margin-block-start: props.get(vars.$spacing-b);
34 } 24 }
35 } 25 }
36 26
37 @include iro.bem-elem('content') { 27 @include bem.elem('content') {
38 display: block; 28 display: block;
39 flex: 1 1 auto; 29 flex: 1 1 auto;
40 } 30 }
41 31
42 @include iro.bem-elem('hint') { 32 @include bem.elem('hint') {
43 display: block; 33 display: block;
44 margin-block-start: fn.dim(--spacing-b); 34 margin-block-start: props.get(vars.$spacing-b);
45 color: fn.color(--hint); 35 font-size: props.get(vars.$hint-font-size);
46 font-size: fn.dim(--hint-font-size); 36 color: props.get(vars.$hint-color);
47 } 37 }
48 38
49 @include iro.bem-is('invalid') { 39 @include bem.is('invalid') {
50 @include iro.bem-elem('hint') { 40 @include bem.elem('hint') {
51 color: fn.color(--error-hint); 41 color: props.get(vars.$error-hint-color);
52 } 42 }
53 } 43 }
54 44
55 @include iro.bem-is('disabled') { 45 @include bem.is('disabled') {
56 @include iro.bem-elem('label', 'hint') { 46 @include bem.elem('label', 'hint') {
57 color: fn.color(--disabled); 47 color: props.get(vars.$disabled-color);
58 } 48 }
59 } 49 }
60 50
61 @include iro.bem-modifier('align-start', 'align-end') { 51 @include bem.modifier('align-start', 'align-end') {
62 display: flex; 52 display: flex;
63 align-items: baseline; 53 align-items: baseline;
64 54
65 @include iro.bem-elem('label') { 55 @include bem.elem('label') {
66 display: inline-block; 56 display: inline-block;
67 57
68 @include iro.bem-next-elem('content') { 58 @include bem.next-elem('content') {
69 margin-block-start: 0; 59 margin-block-start: 0;
70 } 60 }
71 } 61 }
72 } 62 }
73 63
74 @include iro.bem-modifier('align-start') { 64 @include bem.modifier('align-start') {
75 @include iro.bem-elem('label') { 65 @include bem.elem('label') {
76 text-align: start; 66 text-align: start;
77 } 67 }
78 } 68 }
79 69
80 @include iro.bem-modifier('align-end') { 70 @include bem.modifier('align-end') {
81 @include iro.bem-elem('label') { 71 @include bem.elem('label') {
82 text-align: end; 72 text-align: end;
83 } 73 }
84 } 74 }
85 } 75 }
86} 76}
diff --git a/src/objects/_field-label.vars.scss b/src/objects/_field-label.vars.scss
new file mode 100644
index 0000000..844a10b
--- /dev/null
+++ b/src/objects/_field-label.vars.scss
@@ -0,0 +1,12 @@
1@use 'iro-sass/src/props';
2@use '../core.vars' as core;
3
4$spacing-i: props.def(--o-field-label--spacing-i, props.get(core.$size--150)) !default;
5$spacing-b: props.def(--o-field-label--spacing-b, props.get(core.$size--85)) !default;
6$label-font-size: props.def(--o-field-label--label-font-size, props.get(core.$font-size--75)) !default;
7$hint-font-size: props.def(--o-field-label--hint-font-size, props.get(core.$font-size--75)) !default;
8
9$label-color: props.def(--o-field-label--label-color, props.get(core.$theme, --text-mute), 'color') !default;
10$hint-color: props.def(--o-field-label--hint-color, props.get(core.$theme, --text-mute), 'color') !default;
11$error-hint-color: props.def(--o-field-label--error-hint-color, props.get(core.$theme, --negative, --900), 'color') !default;
12$disabled-color: props.def(--o-field-label--disabled-color, props.get(core.$theme, --text-disabled), 'color') !default;
diff --git a/src/objects/_figure.scss b/src/objects/_figure.scss
new file mode 100644
index 0000000..27e0f6a
--- /dev/null
+++ b/src/objects/_figure.scss
@@ -0,0 +1,26 @@
1@use 'sass:meta';
2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
5
6@forward 'figure.vars';
7@use 'figure.vars' as vars;
8
9@mixin styles {
10 @include materialize-at-root(meta.module-variables('vars'));
11
12 @include bem.object('figure') {
13 @include bem.elem('caption') {
14 padding-block: props.get(vars.$pad-b);
15 font-size: props.get(vars.$font-size);
16 color: props.get(vars.$text-color);
17 border-block-end: props.get(vars.$border-width) solid props.get(vars.$border-color);
18
19 &::before {
20 display: block;
21 margin-block: -100em 100em;
22 content: '';
23 }
24 }
25 }
26}
diff --git a/src/objects/_figure.vars.scss b/src/objects/_figure.vars.scss
new file mode 100644
index 0000000..78f5d15
--- /dev/null
+++ b/src/objects/_figure.vars.scss
@@ -0,0 +1,9 @@
1@use 'iro-sass/src/props';
2@use '../core.vars' as core;
3
4$pad-b: props.def(--o-figure--pad-b, props.get(core.$size--100)) !default;
5$border-width: props.def(--o-figure--border-width, props.get(core.$border-width--thin)) !default;
6$font-size: props.def(--o-figure--font-size, props.get(core.$font-size--100)) !default;
7
8$text-color: props.def(--o-figure--text-color, props.get(core.$theme, --text-mute-more), 'color') !default;
9$border-color: props.def(--o-figure--border-color, props.get(core.$theme, --border), 'color') !default;
diff --git a/src/objects/_heading.scss b/src/objects/_heading.scss
index 7990a6b..d27b595 100644
--- a/src/objects/_heading.scss
+++ b/src/objects/_heading.scss
@@ -1,118 +1,60 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use '../mixins' as mx; 3@use 'iro-sass/src/props';
4@use '../config'; 4@use '../props' as *;
5@use 'include-media/dist/include-media' as media;
6 5
7$sizes: 'xxl' 'xl' 'lg' 'md' 'sm' 'xs'; 6@forward 'heading.vars';
7@use 'heading.vars' as vars;
8 8
9@include iro.props-namespace('heading') { 9@mixin styles {
10 @include iro.props-store(( 10 @include materialize-at-root(meta.module-variables('vars'));
11 --dims: (
12 --offset: -.02em,
13 ),
14 --colors: (
15 --bg: fn.global-color(--base --50),
16 ),
17 ));
18 11
19 @include iro.bem-object(iro.props-namespace()) { 12 @include bem.object('heading') {
20 @include mx.set-font(--headline); 13 display: block;
14 margin-block-start: props.get(vars.$margin-bs);
15 font-family: props.get(vars.$font-family);
16 font-weight: props.get(vars.$font-weight);
17 font-feature-settings: props.get(vars.$feature-settings);
18 line-height: props.get(vars.$line-height);
19 color: props.get(vars.$text-color);
20 text-transform: none;
21 letter-spacing: normal;
21 22
22 display: block; 23 & + & {
23 margin-block-start: fn.global-dim(--heading --margin-bs); 24 margin-block-start: props.get(vars.$margin-bs-sibling);
24 transform: translateX(fn.dim(--offset)); 25 }
25 letter-spacing: normal;
26 text-transform: none;
27 26
28 & + & { 27 @include bem.elem('highlight') {
29 margin-block-start: fn.global-dim(--heading --margin-bs-sibling); 28 background-image: linear-gradient(to top,
30 } 29 transparent .05em,
30 props.get(vars.$bg-color) .05em,
31 props.get(vars.$bg-color) .5em,
32 transparent .5em);
33 }
31 34
32 @include iro.bem-elem('highlight') { 35 @each $mod, $font-family, $line-height, $font-size, $font-weight, $letter-spacing, $feature-settings in vars.$sizes {
33 background-image: linear-gradient( 36 @include bem.modifier($mod) {
34 to top, 37 font-family: props.get($font-family);
35 transparent .05em, 38 font-size: props.get($font-size);
36 fn.color(--bg) .05em, 39 font-weight: props.get($font-weight);
37 fn.color(--bg) .5em, 40 font-feature-settings: props.get($feature-settings);
38 transparent .5em 41 line-height: props.get($line-height);
39 ); 42 letter-spacing: props.get($letter-spacing);
40 } 43 }
44 }
41 45
42 @include iro.bem-modifier('xxl') { 46 @include bem.modifier('display') {
43 @include mx.heading-strong(--xxl); 47 @each $mod, $font-family, $line-height, $font-size, $font-weight, $letter-spacing, $feature-settings in vars.$display--sizes {
44 } 48 @include bem.modifier($mod) {
45 49 font-family: props.get($font-family);
46 @include iro.bem-modifier('xl') { 50 font-size: props.get($font-size);
47 @include mx.heading-strong(--xl); 51 font-weight: props.get($font-weight);
48 } 52 font-feature-settings: props.get($feature-settings);
49 53 line-height: props.get($line-height);
50 @include iro.bem-modifier('lg') { 54 letter-spacing: props.get($letter-spacing);
51 @include mx.heading-medium(--lg); 55 transform: translateX(props.get(vars.$offset));
52 } 56 }
53 57 }
54 @include iro.bem-modifier('md') { 58 }
55 @include mx.heading-medium(--md); 59 }
56 }
57
58 @include iro.bem-modifier('sm') {
59 @include mx.heading-faint(--sm);
60 }
61
62 @include iro.bem-modifier('xs') {
63 @include mx.heading-faint(--xs);
64 }
65
66 @include iro.bem-modifier('display') {
67 @include mx.set-font(--headline);
68
69 @include iro.bem-modifier('xxl') {
70 @include mx.heading-strong(--display --xxl);
71
72 @include media.media('<=md') {
73 @include mx.heading-strong(--display-sm --xxl);
74 }
75 }
76
77 @include iro.bem-modifier('xl') {
78 @include mx.heading-strong(--display --xl);
79
80 @include media.media('<=md') {
81 @include mx.heading-strong(--display-sm --xl);
82 }
83 }
84
85 @include iro.bem-modifier('lg') {
86 @include mx.heading-strong(--display --lg);
87
88 @include media.media('<=md') {
89 @include mx.heading-strong(--display-sm --lg);
90 }
91 }
92
93 @include iro.bem-modifier('md') {
94 @include mx.heading-strong(--display --md);
95
96 @include media.media('<=md') {
97 @include mx.heading-strong(--display-sm --md);
98 }
99 }
100
101 @include iro.bem-modifier('sm') {
102 @include mx.heading-medium(--display --sm);
103
104 @include media.media('<=md') {
105 @include mx.heading-medium(--display-sm --sm);
106 }
107 }
108
109 @include iro.bem-modifier('xs') {
110 @include mx.heading-faint(--display --xs);
111
112 @include media.media('<=md') {
113 @include mx.heading-faint(--display-sm --xs);
114 }
115 }
116 }
117 }
118} 60}
diff --git a/src/objects/_heading.vars.scss b/src/objects/_heading.vars.scss
new file mode 100644
index 0000000..1d6df26
--- /dev/null
+++ b/src/objects/_heading.vars.scss
@@ -0,0 +1,123 @@
1@use 'iro-sass/src/props';
2@use '../core.vars' as core;
3
4$offset: props.def(--o-heading--offset, -.02em) !default;
5$margin-bs: props.def(--o-heading--margin-bs, props.get(core.$size--700)) !default;
6$margin-bs-sibling: props.def(--o-heading--margin-bs-sibling, props.get(core.$size--325)) !default;
7
8$text-color: props.def(--o-heading--text-color, props.get(core.$theme, --heading), 'color') !default;
9$bg-color: props.def(--o-heading--bg-color, props.get(core.$theme, --base, --50), 'color') !default;
10
11$font-family: props.def(--o-heading--font-family, props.get(core.$font--standard--family)) !default;
12$line-height: props.def(--o-heading--line-height, props.get(core.$font--standard--line-height)) !default;
13$font-weight: props.def(--o-heading--font-weight, bold) !default;
14$feature-settings: props.def(--o-heading--feature-settings, props.get(core.$font--standard--feature-settings)) !default;
15
16$font-family--xxl: props.def(--o-heading--xxl--font-family, props.get(core.$font--headline--family)) !default;
17$line-height--xxl: props.def(--o-heading--xxl--line-height, props.get(core.$font--headline--line-height)) !default;
18$font-size--xxl: props.def(--o-heading--xxl--font-size, props.get(core.$font-size--300)) !default;
19$font-weight--xxl: props.def(--o-heading--xxl--font-weight, props.get(core.$font--headline--weight)) !default;
20$letter-spacing--xxl: props.def(--o-heading--xxl--letter-spacing, 0) !default;
21$feature-settings--xxl: props.def(--o-heading--xxl--feature-settings, props.get(core.$font--headline--feature-settings)) !default;
22
23$font-family--xl: props.def(--o-heading--xl--font-family, props.get(core.$font--headline--family)) !default;
24$line-height--xl: props.def(--o-heading--xl--line-height, props.get(core.$font--headline--line-height)) !default;
25$font-size--xl: props.def(--o-heading--xl--font-size, props.get(core.$font-size--200)) !default;
26$font-weight--xl: props.def(--o-heading--xl--font-weight, props.get(core.$font--headline--weight)) !default;
27$letter-spacing--xl: props.def(--o-heading--xl--letter-spacing, 0) !default;
28$feature-settings--xl: props.def(--o-heading--xl--feature-settings, props.get(core.$font--headline--feature-settings)) !default;
29
30$font-family--lg: props.def(--o-heading--lg--font-family, props.get(core.$font--standard--family)) !default;
31$line-height--lg: props.def(--o-heading--lg--line-height, props.get(core.$font--standard--line-height)) !default;
32$font-size--lg: props.def(--o-heading--lg--font-size, props.get(core.$font-size--150)) !default;
33$font-weight--lg: props.def(--o-heading--lg--font-weight, bold) !default;
34$letter-spacing--lg: props.def(--o-heading--lg--letter-spacing, 0) !default;
35$feature-settings--lg: props.def(--o-heading--lg--feature-settings, props.get(core.$font--standard--feature-settings)) !default;
36
37$font-family--md: props.def(--o-heading--md--font-family, props.get(core.$font--standard--family)) !default;
38$line-height--md: props.def(--o-heading--md--line-height, props.get(core.$font--standard--line-height)) !default;
39$font-size--md: props.def(--o-heading--md--font-size, props.get(core.$font-size--100)) !default;
40$font-weight--md: props.def(--o-heading--md--font-weight, bold) !default;
41$letter-spacing--md: props.def(--o-heading--md--letter-spacing, 0) !default;
42$feature-settings--md: props.def(--o-heading--md--feature-settings, props.get(core.$font--standard--feature-settings)) !default;
43
44$font-family--sm: props.def(--o-heading--sm--font-family, props.get(core.$font--standard--family)) !default;
45$line-height--sm: props.def(--o-heading--sm--line-height, props.get(core.$font--standard--line-height)) !default;
46$font-size--sm: props.def(--o-heading--sm--font-size, props.get(core.$font-size--75)) !default;
47$font-weight--sm: props.def(--o-heading--sm--font-weight, 500) !default;
48$letter-spacing--sm: props.def(--o-heading--sm--letter-spacing, 1px) !default;
49$feature-settings--sm: props.def(--o-heading--sm--feature-settings, props.get(core.$font--standard--feature-settings)) !default;
50
51$font-family--xs: props.def(--o-heading--xs--font-family, props.get(core.$font--standard--family)) !default;
52$line-height--xs: props.def(--o-heading--xs--line-height, props.get(core.$font--standard--line-height)) !default;
53$font-size--xs: props.def(--o-heading--xs--font-size, props.get(core.$font-size--50)) !default;
54$font-weight--xs: props.def(--o-heading--xs--font-weight, 500) !default;
55$letter-spacing--xs: props.def(--o-heading--xs--letter-spacing, 1px) !default;
56$feature-settings--xs: props.def(--o-heading--xs--feature-settings, props.get(core.$font--standard--feature-settings)) !default;
57
58$sizes: (
59 'xs' $font-family--xs $line-height--xs $font-size--xs $font-weight--xs $letter-spacing--xs $feature-settings--xs,
60 'sm' $font-family--sm $line-height--sm $font-size--sm $font-weight--sm $letter-spacing--sm $feature-settings--sm,
61 'md' $font-family--md $line-height--md $font-size--md $font-weight--md $letter-spacing--md $feature-settings--md,
62 'lg' $font-family--lg $line-height--lg $font-size--lg $font-weight--lg $letter-spacing--lg $feature-settings--lg,
63 'xl' $font-family--xl $line-height--xl $font-size--xl $font-weight--xl $letter-spacing--xl $feature-settings--xl,
64 'xxl' $font-family--xxl $line-height--xxl $font-size--xxl $font-weight--xxl $letter-spacing--xxl $feature-settings--xxl,
65) !default;
66
67$display--font-family--xxl: props.def(--o-heading--display--xxl--font-family, props.get(core.$font--headline--family)) !default;
68$display--line-height--xxl: props.def(--o-heading--display--xxl--line-height, props.get(core.$font--headline--line-height)) !default;
69$display--font-size--xxl: props.def(--o-heading--display--xxl--font-size, props.get(core.$font-size--1100)) !default;
70$display--font-weight--xxl: props.def(--o-heading--display--xxl--font-weight, props.get(core.$font--headline--weight)) !default;
71$display--letter-spacing--xxl: props.def(--o-heading--display--xxl--letter-spacing, 0) !default;
72$display--feature-settings--xxl: props.def(--o-heading--display--xxl--feature-settings, props.get(core.$font--headline--feature-settings)) !default;
73
74$display--font-family--xl: props.def(--o-heading--display--xl--font-family, props.get(core.$font--headline--family)) !default;
75$display--line-height--xl: props.def(--o-heading--display--xl--line-height, props.get(core.$font--headline--line-height)) !default;
76$display--font-size--xl: props.def(--o-heading--display--xl--font-size, props.get(core.$font-size--700)) !default;
77$display--font-weight--xl: props.def(--o-heading--display--xl--font-weight, props.get(core.$font--headline--weight)) !default;
78$display--letter-spacing--xl: props.def(--o-heading--display--xl--letter-spacing, 0) !default;
79$display--feature-settings--xl: props.def(--o-heading--display--xl--feature-settings, props.get(core.$font--headline--feature-settings)) !default;
80
81$display--font-family--lg: props.def(--o-heading--display--lg--font-family, props.get(core.$font--headline--family)) !default;
82$display--line-height--lg: props.def(--o-heading--display--lg--line-height, props.get(core.$font--headline--line-height)) !default;
83$display--font-size--lg: props.def(--o-heading--display--lg--font-size, props.get(core.$font-size--300)) !default;
84$display--font-weight--lg: props.def(--o-heading--display--lg--font-weight, props.get(core.$font--headline--weight)) !default;
85$display--letter-spacing--lg: props.def(--o-heading--display--lg--letter-spacing, 0) !default;
86$display--feature-settings--lg: props.def(--o-heading--display--lg--feature-settings, props.get(core.$font--headline--feature-settings)) !default;
87
88$display--font-family--md: props.def(--o-heading--display--md--font-family, props.get(core.$font--headline--family)) !default;
89$display--line-height--md: props.def(--o-heading--display--md--line-height, props.get(core.$font--headline--line-height)) !default;
90$display--font-size--md: props.def(--o-heading--display--md--font-size, props.get(core.$font-size--150)) !default;
91$display--font-weight--md: props.def(--o-heading--display--md--font-weight, props.get(core.$font--headline--weight)) !default;
92$display--letter-spacing--md: props.def(--o-heading--display--md--letter-spacing, 0) !default;
93$display--feature-settings--md: props.def(--o-heading--display--md--feature-settings, props.get(core.$font--headline--feature-settings)) !default;
94
95$display--font-family--sm: props.def(--o-heading--display--sm--font-family, props.get(core.$font--standard--family)) !default;
96$display--line-height--sm: props.def(--o-heading--display--sm--line-height, props.get(core.$font--standard--line-height)) !default;
97$display--font-size--sm: props.def(--o-heading--display--sm--font-size, props.get(core.$font-size--75)) !default;
98$display--font-weight--sm: props.def(--o-heading--display--sm--font-weight, bold) !default;
99$display--letter-spacing--sm: props.def(--o-heading--display--sm--letter-spacing, 0) !default;
100$display--feature-settings--sm: props.def(--o-heading--display--sm--feature-settings, props.get(core.$font--standard--feature-settings)) !default;
101
102$display--font-family--xs: props.def(--o-heading--display--xs--font-family, props.get(core.$font--standard--family)) !default;
103$display--line-height--xs: props.def(--o-heading--display--xs--line-height, props.get(core.$font--standard--line-height)) !default;
104$display--font-size--xs: props.def(--o-heading--display--xs--font-size, props.get(core.$font-size--50)) !default;
105$display--font-weight--xs: props.def(--o-heading--display--xs--font-weight, 500) !default;
106$display--letter-spacing--xs: props.def(--o-heading--display--xs--letter-spacing, 1px) !default;
107$display--feature-settings--xs: props.def(--o-heading--display--xs--feature-settings, props.get(core.$font--standard--feature-settings)) !default;
108
109$display--font-size--xxl--md: props.def(--o-heading--display--xxl--font-size, props.get(core.$font-size--900), 'md') !default;
110$display--font-size--xl--md: props.def(--o-heading--display--xl--font-size, props.get(core.$font-size--600), 'md') !default;
111$display--font-size--lg--md: props.def(--o-heading--display--lg--font-size, props.get(core.$font-size--200), 'md') !default;
112$display--font-size--md--md: props.def(--o-heading--display--md--font-size, props.get(core.$font-size--100), 'md') !default;
113$display--font-size--sm--md: props.def(--o-heading--display--sm--font-size, props.get(core.$font-size--75), 'md') !default;
114$display--font-size--xs--md: props.def(--o-heading--display--xs--font-size, props.get(core.$font-size--50), 'md') !default;
115
116$display--sizes: (
117 'xs' $display--font-family--xs $display--line-height--xs $display--font-size--xs $display--font-weight--xs $display--letter-spacing--xs $display--feature-settings--xs,
118 'sm' $display--font-family--sm $display--line-height--sm $display--font-size--sm $display--font-weight--sm $display--letter-spacing--sm $display--feature-settings--sm,
119 'md' $display--font-family--md $display--line-height--md $display--font-size--md $display--font-weight--md $display--letter-spacing--md $display--feature-settings--md,
120 'lg' $display--font-family--lg $display--line-height--lg $display--font-size--lg $display--font-weight--lg $display--letter-spacing--lg $display--feature-settings--lg,
121 'xl' $display--font-family--xl $display--line-height--xl $display--font-size--xl $display--font-weight--xl $display--letter-spacing--xl $display--feature-settings--xl,
122 'xxl' $display--font-family--xxl $display--line-height--xxl $display--font-size--xxl $display--font-weight--xxl $display--letter-spacing--xxl $display--feature-settings--xxl,
123) !default;
diff --git a/src/objects/_icon.scss b/src/objects/_icon.scss
index 1491dd9..1941960 100644
--- a/src/objects/_icon.scss
+++ b/src/objects/_icon.scss
@@ -1,26 +1,25 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
3 5
4@include iro.props-namespace('icon') { 6@forward 'icon.vars';
5 @include iro.props-store(( 7@use 'icon.vars' as vars;
6 --dims: (
7 --stroke: 1.5px,
8 --size: calc(1 / 14 * 16em),
9 --valign: -.2em,
10 )
11 ));
12 8
13 @include iro.bem-object(iro.props-namespace()) { 9@mixin styles {
14 display: inline; 10 @include materialize-at-root(meta.module-variables('vars'));
15 inline-size: fn.dim(--size);
16 block-size: fn.dim(--size);
17 stroke-width: fn.dim(--stroke);
18 stroke-linecap: round;
19 stroke-linejoin: round;
20 vertical-align: fn.dim(--valign);
21 11
22 @include iro.bem-modifier('block') { 12 @include bem.object('icon') {
23 display: block; 13 display: inline;
24 } 14 inline-size: props.get(vars.$size);
25 } 15 block-size: props.get(vars.$size);
16 vertical-align: props.get(vars.$valign);
17 stroke-width: props.get(vars.$stroke-width);
18 stroke-linecap: round;
19 stroke-linejoin: round;
20
21 @include bem.modifier('block') {
22 display: block;
23 }
24 }
26} 25}
diff --git a/src/objects/_icon.vars.scss b/src/objects/_icon.vars.scss
new file mode 100644
index 0000000..ff1541d
--- /dev/null
+++ b/src/objects/_icon.vars.scss
@@ -0,0 +1,5 @@
1@use 'iro-sass/src/props';
2
3$stroke-width: props.def(--o-icon--stroke-width, 1.5px) !default;
4$size: props.def(--o-icon--size, calc(1 / 14 * 16em)) !default;
5$valign: props.def(--o-icon--valign, -.18em) !default;
diff --git a/src/objects/_lightbox.scss b/src/objects/_lightbox.scss
index 8ad8584..b95148f 100644
--- a/src/objects/_lightbox.scss
+++ b/src/objects/_lightbox.scss
@@ -1,313 +1,135 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:map';
2@use '../functions' as fn; 2@use 'sass:meta';
3@use 'sass:string';
4@use 'iro-sass/src/bem';
5@use 'iro-sass/src/props';
6@use '../props' as *;
3 7
4@use 'action-button'; 8@forward 'lightbox.vars';
9@use 'lightbox.vars' as vars;
5 10
6$static-themes: 'black' 'white' !default; 11@mixin styles {
12 @include materialize-at-root(meta.module-variables('vars'));
7 13
8@include iro.props-namespace('lightbox') { 14 @include bem.object('lightbox') {
9 @include iro.props-store(( 15 flex: 1 1 auto;
10 --dims: ( 16 min-block-size: 0;
11 --pad: fn.global-dim(--size --150),
12 17
13 --thumbnail: ( 18 @include bem.elem('header') {
14 --size: fn.global-dim(--size --700), 19 display: flex;
15 --rounding: fn.global-dim(--rounding), 20 grid-area: header;
16 --spacing: fn.global-dim(--size --100), 21 align-items: flex-start;
17 --border: fn.global-dim(--border --thin), 22 padding-block-start: props.get(vars.$pad);
18 23 padding-inline: props.get(vars.$pad);
19 --selected: ( 24 }
20 --border: fn.global-dim(--border --medium),
21 ),
22 25
23 --key-focus: ( 26 @include bem.elem('img') {
24 --border: fn.global-dim(--key-focus --border), 27 box-sizing: border-box;
25 --border-offset: fn.global-dim(--key-focus --border-offset), 28 display: block;
26 --outline: fn.global-dim(--key-focus --outline), 29 grid-area: content;
27 ), 30 place-self: center;
28 ), 31 inline-size: auto;
32 max-inline-size: 100%;
33 block-size: auto;
34 max-block-size: props.get(vars.$image--max-height);
35 padding: props.get(vars.$pad);
36 margin-inline: auto;
37 border-radius: calc(props.get(vars.$pad) + props.get(vars.$image--border-radius));
38 }
29 39
30 --close-button: ( 40 @include bem.elem('thumbnails') {
31 --font-size: fn.global-dim(--font-size --200), 41 display: none;
32 ), 42 grid-area: thumbnails;
43 gap: props.get(vars.$thumbnails--spacing);
44 padding: props.get(vars.$pad);
45 margin-block-start: calc(-1 * props.get(vars.$pad));
46 overflow: auto;
47 }
33 48
34 --nav-button: ( 49 @include bem.elem('close-btn') {
35 --width: fn.global-dim(--size --2000), 50 display: none;
36 --height: fn.global-dim(--size --3800), 51 flex: 0 0 auto;
37 --font-size: fn.global-dim(--font-size --200), 52 margin-block-start: calc(-.5 * props.get(vars.$pad));
38 ), 53 margin-inline: auto calc(-.5 * props.get(vars.$pad));
39 ), 54 font-size: props.get(vars.$close-button--font-size);
40 --colors: ( 55 }
41 --thumbnail: (
42 --border: fn.global-color(--border-strong),
43
44 --hover: (
45 --border: fn.global-color(--text-mute-more),
46 ),
47
48 --selected: (
49 --border: fn.global-color(--heading),
50 ),
51 56
52 --key-focus: ( 57 @include bem.elem('nav-btn') {
53 --border: fn.global-color(--focus --border), 58 position: relative;
54 --outline: fn.global-color(--focus --outline), 59 display: none;
55 ), 60 align-self: center;
56 ), 61 overflow: visible;
57 ), 62 font-size: props.get(vars.$nav-button--font-size);
58 ));
59 63
60 @each $theme in $static-themes { 64 &::before {
61 @include iro.props-store(( 65 position: absolute;
62 --colors: ( 66 inset-block-start: 50%;
63 --static-#{$theme}: ( 67 display: block;
64 --text: fn.global-color(--white-transparent --800), 68 inline-size: props.get(vars.$nav-button--inline-size);
65 --thumbnail: ( 69 block-size: props.get(vars.$nav-button--block-size);
66 --border: fn.global-color(--white-transparent --400), 70 content: '';
67 71 transform: translateY(-50%);
68 --hover: ( 72 }
69 --border: fn.global-color(--white-transparent --500),
70 ),
71
72 --selected: (
73 --border: fn.global-color(--white-transparent --900),
74 ),
75 73
76 --key-focus: ( 74 @include bem.modifier('prev') {
77 --border: fn.global-color(--#{$theme}-transparent --900), 75 grid-area: prev;
78 --outline: fn.global-color(--#{$theme}-transparent --300), 76 margin-inline: calc(.5 * props.get(vars.$pad)) calc(-1 * props.get(vars.$pad));
79 ),
80 ),
81 )
82 )
83 ));
84 }
85 77
86 @include iro.props-store(( 78 &::before {
87 --dims: ( 79 inset-inline-start: 0;
88 --thumbnail: ( 80 }
89 --size: fn.global-dim(--size --600), 81 }
90 ),
91 --nav-button: (
92 --width: fn.global-dim(--size --2500),
93 --height: fn.global-dim(--size --2500),
94 ),
95 ),
96 ), 'md');
97
98 @include iro.bem-object(iro.props-namespace()) {
99 display: grid;
100 grid-template-rows: auto minmax(0, 1fr) auto auto;
101 grid-template-columns: auto minmax(0, 1fr) auto;
102 grid-template-areas:
103 'header header header'
104 'prev content next'
105 'thumbnails thumbnails thumbnails'
106 'footer footer footer';
107 box-sizing: border-box;
108 min-block-size: 0;
109 flex: 1 1 auto;
110
111 @include iro.bem-elem('header') {
112 grid-area: header;
113 display: flex;
114 align-items: flex-start;
115 padding-block-start: fn.dim(--pad);
116 padding-inline: fn.dim(--pad);
117 }
118
119 @include iro.bem-elem('img') {
120 display: none;
121 box-sizing: border-box;
122 grid-area: content;
123 max-inline-size: 100%;
124 max-block-size: 100%;
125 place-self: center;
126 padding: fn.dim(--pad);
127
128 @include iro.bem-sibling-elem('img') {
129 @include iro.bem-modifier('default') {
130 display: block;
131
132 @include iro.bem-next-elem('nav-btn') {
133 display: block;
134 82
135 @include iro.bem-next-elem('nav-btn') { 83 @include bem.modifier('next') {
136 display: block; 84 grid-area: next;
137 } 85 margin-inline: calc(-1 * props.get(vars.$pad)) calc(.5 * props.get(vars.$pad));
138 }
139 }
140 }
141
142 @include iro.bem-multi('&:target', 'is' 'visible') {
143 display: block;
144
145 @include iro.bem-next-elem('nav-btn') {
146 display: block;
147
148 @include iro.bem-next-elem('nav-btn') {
149 display: block;
150 }
151 }
152
153 @include iro.bem-sibling-elem('img') {
154 @include iro.bem-modifier('default') {
155 display: none;
156
157 @include iro.bem-next-elem('nav-btn') {
158 display: none;
159
160 @include iro.bem-next-elem('nav-btn') {
161 display: none;
162 }
163 }
164 }
165 }
166 }
167 }
168
169 @include iro.bem-elem('thumbnails') {
170 grid-area: thumbnails;
171 display: flex;
172 gap: fn.dim(--thumbnail --spacing);
173 padding: fn.dim(--pad);
174 margin-block-start: calc(-1 * fn.dim(--pad));
175 overflow: auto;
176 }
177 86
178 @include iro.bem-elem('footer') { 87 &::before {
179 grid-area: footer; 88 inset-inline-end: 0;
180 display: flex; 89 }
181 align-items: flex-start; 90 }
182 padding-block: 0 fn.dim(--pad); 91 }
183 padding-inline: fn.dim(--pad);
184 }
185 92
186 @include iro.bem-elem('thumbnail') { 93 @include bem.modifier('interactive') {
187 position: relative; 94 display: grid;
188 flex: 0 0 auto; 95 grid-template-areas:
189 inline-size: fn.dim(--thumbnail --size); 96 'header header header'
190 block-size: fn.dim(--thumbnail --size); 97 'prev content next'
191 overflow: hidden; 98 'thumbnails thumbnails thumbnails';
192 border-radius: fn.dim(--thumbnail --rounding); 99 grid-template-rows: auto minmax(0, 1fr) auto auto;
193 outline: fn.dim(--thumbnail --border) solid fn.color(--thumbnail --border); 100 grid-template-columns: auto minmax(0, 1fr) auto;
194 outline-offset: calc(-1 * fn.dim(--thumbnail --border));
195 opacity: .75;
196 101
197 &:hover, 102 @include bem.modifier('fullscreen') {
198 &:active, 103 block-size: props.get(vars.$fullscreen--height);
199 &:focus-visible { 104 }
200 outline-color: fn.color(--thumbnail --hover --border);
201 opacity: 1;
202 }
203 105
204 @include iro.bem-is('selected') { 106 @include bem.elem('img') {
205 $focus-border-offset: calc(-1 * fn.dim(--thumbnail --selected --border)); 107 display: none;
108 max-block-size: 100%;
109 margin-inline: 0;
206 110
207 margin: $focus-border-offset; 111 @include bem.multi('&:target', 'is' 'visible') {
208 border: fn.dim(--thumbnail --selected --border) solid fn.color(--thumbnail --selected --border); 112 display: block;
209 border-radius: calc(fn.dim(--thumbnail --rounding) - $focus-border-offset); 113 }
210 outline: none; 114 }
211 opacity: 1;
212 }
213 115
214 &:focus-visible { 116 @include bem.elem('thumbnails') {
215 $focus-border-offset: calc(-1 * fn.dim(--thumbnail --key-focus --border-offset)); 117 display: flex;
216 118 }
217 margin: $focus-border-offset;
218 border: fn.dim(--thumbnail --key-focus --border-offset) solid transparent;
219 border-radius: calc(fn.dim(--thumbnail --rounding) - $focus-border-offset);
220 outline: fn.dim(--thumbnail --key-focus --border) solid fn.color(--thumbnail --key-focus --border);
221 outline-offset: 0;
222 box-shadow: 0 0 0 calc(fn.dim(--thumbnail --key-focus --outline) + fn.dim(--thumbnail --key-focus --border)) fn.color(--thumbnail --key-focus --outline);
223 }
224 }
225
226 @include iro.bem-elem('thumbnail-img') {
227 display: block;
228 position: absolute;
229 inset-block-start: 0;
230 inset-inline-start: 0;
231 inline-size: 100%;
232 block-size: 100%;
233 object-fit: cover;
234 object-position: center center;
235 }
236
237 @include iro.bem-elem('thumbnail-icon') {
238 position: absolute;
239 inset-block-start: 50%;
240 inset-inline-start: 50%;
241 transform: translate(-50%, -50%);
242 }
243
244 @include iro.bem-elem('close-btn') {
245 flex: 0 0 auto;
246 margin-block-start: calc(-.5 * fn.dim(--pad));
247 margin-inline: auto calc(-.5 * fn.dim(--pad));
248 font-size: fn.dim(--close-button --font-size);
249 }
250
251 @include iro.bem-elem('nav-btn') {
252 display: none;
253 position: relative;
254 align-self: center;
255 overflow: visible;
256 font-size: fn.dim(--nav-button --font-size);
257
258 &::before {
259 content: '';
260 display: block;
261 position: absolute;
262 inset-block-start: 50%;
263 inline-size: fn.dim(--nav-button --width);
264 block-size: fn.dim(--nav-button --height);
265 transform: translateY(-50%);
266 }
267
268 @include iro.bem-modifier('prev') {
269 grid-area: prev;
270 margin-inline: calc(.5 * fn.dim(--pad)) calc(-1 * fn.dim(--pad));
271
272 &::before {
273 inset-inline-start: 0;
274 }
275 }
276
277 @include iro.bem-modifier('next') {
278 grid-area: next;
279 margin-inline: calc(-1 * fn.dim(--pad)) calc(.5 * fn.dim(--pad));
280
281 &::before {
282 inset-inline-end: 0;
283 }
284 }
285 }
286
287 @each $theme in $static-themes {
288 @include iro.bem-modifier(static-#{$theme}) {
289 color: fn.color(--static-#{$theme} --text);
290 119
291 @include iro.bem-elem('thumbnail') { 120 @include bem.elem('close-btn') {
292 outline-color: fn.color(--static-#{$theme} --thumbnail --border); 121 display: block;
122 }
293 123
294 &:hover, 124 @include bem.elem('nav-btn') {
295 &:active, 125 display: block;
296 &:focus-visible { 126 }
297 outline-color: fn.color(--static-#{$theme} --thumbnail --hover --border); 127 }
298 }
299
300 @include iro.bem-is('selected') {
301 border-color: fn.color(--static-#{$theme} --thumbnail --selected --border);
302 }
303 128
304 &:focus-visible { 129 @each $theme in map.keys(props.get(vars.$static-themes)) {
305 border-color: transparent; 130 @include bem.modifier(string.slice($theme, 3)) {
306 outline-color: fn.color(--static-#{$theme} --thumbnail --key-focus --border); 131 color: props.get(vars.$static-themes, $theme, --text);
307 box-shadow: 0 0 0 calc(fn.dim(--thumbnail --key-focus --outline) + fn.dim(--thumbnail --key-focus --border)) fn.color(--static-#{$theme} --thumbnail --key-focus --outline); 132 }
308 } 133 }
309 } 134 }
310 }
311 }
312 }
313} 135}
diff --git a/src/objects/_lightbox.vars.scss b/src/objects/_lightbox.vars.scss
new file mode 100644
index 0000000..6d22aa8
--- /dev/null
+++ b/src/objects/_lightbox.vars.scss
@@ -0,0 +1,33 @@
1@use 'sass:map';
2@use 'sass:string';
3@use 'iro-sass/src/props';
4@use '../core.vars' as core;
5
6$pad: props.def(--o-lightbox--pad, props.get(core.$size--150)) !default;
7$fullscreen--height: props.def(--o-lightbox--fullscreen--height, 100vh) !default;
8
9$image--max-height: props.def(--o-lightbox--image--max-height, calc(100vh - props.get(core.$size--600))) !default;
10$image--border-radius: props.def(--o-lightbox--image--border-radius, props.get(core.$rounding)) !default;
11
12$close-button--font-size: props.def(--o-lightbox--close-button--font-size, props.get(core.$font-size--200)) !default;
13
14$nav-button--inline-size: props.def(--o-lightbox--nav-button--inline-size, props.get(core.$size--2000)) !default;
15$nav-button--block-size: props.def(--o-lightbox--nav-button--block-size, props.get(core.$size--3800)) !default;
16$nav-button--font-size: props.def(--o-lightbox--nav-button--font-size, props.get(core.$font-size--200)) !default;
17
18$nav-button--inline-size--md: props.def(--o-lightbox--nav-button--inline-size, props.get(core.$size--2500), 'md') !default;
19$nav-button--block-size--md: props.def(--o-lightbox--nav-button--block-size, props.get(core.$size--2500), 'md') !default;
20
21$thumbnails--spacing: props.def(--o-lightbox--thumbnails--spacing, props.get(core.$size--100)) !default;
22
23$static-themes: props.def(--o-lightbox, (), 'color');
24
25@each $theme in map.keys(props.get(core.$transparent-colors)) {
26 $lightbox-theme: --static-#{string.slice($theme, 3)};
27
28 $static-themes: props.merge($static-themes, (
29 $lightbox-theme: (
30 --text: props.get(core.$transparent-colors, $theme, --800),
31 )
32 ));
33}
diff --git a/src/objects/_menu.scss b/src/objects/_menu.scss
index 0f691a2..f370067 100644
--- a/src/objects/_menu.scss
+++ b/src/objects/_menu.scss
@@ -1,137 +1,102 @@
1/* stylelint-disable length-zero-no-unit */ 1@use 'sass:meta';
2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
5@use 'icon.vars' as icon;
2 6
3@use 'iro-sass/src/index' as iro; 7@forward 'menu.vars';
4@use '../functions' as fn; 8@use 'menu.vars' as vars;
5 9
6@use './icon'; 10@mixin styles {
11 @include materialize-at-root(meta.module-variables('vars'));
7 12
8@include iro.props-namespace('menu') { 13 @include bem.object('menu') {
9 @include iro.props-store(( 14 display: flex;
10 --dims: ( 15 flex-direction: column;
11 --spacing: 0em, 16 gap: props.get(vars.$spacing);
12 --header: (
13 --font-size: fn.global-dim(--font-size --50),
14 ),
15 --separator: fn.global-dim(--size --100),
16 --item: (
17 --pad-i: fn.global-dim(--size --150),
18 --pad-b: fn.global-dim(--size --100),
19 --rounding: 0em,
20
21 --key-focus: (
22 --border: fn.global-dim(--key-focus --border),
23 --border-offset: fn.global-dim(--key-focus --border-offset),
24 --outline: fn.global-dim(--key-focus --outline),
25 ),
26 ),
27 ),
28 --colors: (
29 --separator: fn.global-color(--border),
30 --header: (
31 --label: fn.global-color(--heading),
32 ),
33 --item: (
34 --hover: (
35 --bg: fn.global-color(--border-mute),
36 --label: fn.global-color(--heading),
37 ),
38 --active: (
39 --bg: fn.global-color(--border),
40 --label: fn.global-color(--heading),
41 ),
42 --disabled: (
43 --label: fn.global-color(--text-disabled),
44 ),
45 --key-focus: (
46 --border: fn.global-color(--focus --border),
47 --outline: fn.global-color(--focus --outline),
48 ),
49 ),
50 ),
51 ));
52 17
53 @include iro.bem-object(iro.props-namespace()) { 18 @include bem.elem('header') {
54 display: flex; 19 padding-block: props.get(vars.$item--pad-b);
55 flex-direction: column; 20 padding-inline: props.get(vars.$item--pad-i);
56 gap: fn.dim(--spacing); 21 font-size: props.get(vars.$header--font-size);
22 font-weight: 500;
23 color: props.get(vars.$header--label-color);
24 text-transform: uppercase;
25 letter-spacing: .5px;
57 26
58 @include iro.bem-elem('header') { 27 @include bem.next-twin-elem {
59 padding-block: fn.dim(--item --pad-b); 28 margin-block-start: calc(props.get(vars.$separator-width) + props.get(vars.$spacing));
60 padding-inline: fn.dim(--item --pad-i); 29 }
61 color: fn.color(--header --label); 30 }
62 font-size: fn.dim(--header --font-size);
63 font-weight: 500;
64 letter-spacing: .5px;
65 text-transform: uppercase;
66 31
67 @include iro.bem-next-twin-elem { 32 @include bem.elem('item') {
68 margin-block-start: calc(fn.dim(--separator) + fn.dim(--spacing)); 33 padding-block: props.get(vars.$item--pad-b);
69 } 34 padding-inline: props.get(vars.$item--pad-i);
70 } 35 margin: calc(-1 * props.get(vars.$item--key-focus--outline-width));
36 color: props.get(vars.$item--disabled--label-color);
37 background-clip: padding-box;
38 border: props.get(vars.$item--key-focus--outline-width) solid transparent;
39 border-radius: calc(props.get(vars.$item--rounding) + props.get(vars.$item--key-focus--outline-width));
71 40
72 @include iro.bem-elem('item') { 41 &:link,
73 padding-block: fn.dim(--item --pad-b); 42 &:visited,
74 padding-inline: fn.dim(--item --pad-i); 43 &:enabled {
75 margin: calc(-1 * fn.dim(--item --key-focus --outline)); 44 color: currentColor;
76 border: fn.dim(--item --key-focus --outline) solid transparent;
77 border-radius: calc(fn.dim(--item --rounding) + fn.dim(--item --key-focus --outline));
78 color: fn.color(--item --disabled --label);
79 background-clip: padding-box;
80 45
81 &:link, 46 @include bem.multi('&:hover, &:focus-visible', 'is' 'selected') {
82 &:visited, 47 color: props.get(vars.$item--hover--label-color);
83 &:enabled { 48 background-color: props.get(vars.$item--hover--bg-color);
84 color: currentColor; 49 }
85 50
86 @include iro.bem-multi('&:hover, &:focus-visible', 'is' 'selected') { 51 &:active {
87 background-color: fn.color(--item --hover --bg); 52 color: props.get(vars.$item--active--label-color);
88 color: fn.color(--item --hover --label); 53 background-color: props.get(vars.$item--active--bg-color);
89 } 54 }
90 55
91 &:active { 56 &:focus-visible {
92 background-color: fn.color(--item --active --bg); 57 outline: props.get(vars.$item--key-focus--border-color) solid props.get(vars.$item--key-focus--border-width);
93 color: fn.color(--item --active --label); 58 box-shadow:
94 } 59 0
60 0
61 0
62 calc(props.get(vars.$item--key-focus--border-width) + props.get(vars.$item--key-focus--outline-width))
63 props.get(vars.$item--key-focus--outline-color);
64 }
65 }
95 66
96 &:focus-visible { 67 @include bem.next-elem('header') {
97 outline: fn.color(--item --key-focus --border) solid fn.dim(--item --key-focus --border); 68 margin-block-start: calc(props.get(vars.$separator-width) + props.get(vars.$spacing));
98 box-shadow: 0 0 0 calc(fn.dim(--item --key-focus --border) + fn.dim(--item --key-focus --outline)) fn.color(--item --key-focus --outline); 69 }
99 } 70 }
100 }
101 71
102 @include iro.bem-next-elem('header') { 72 @include bem.elem('header') {
103 margin-block-start: calc(fn.dim(--separator) + fn.dim(--spacing)); 73 &:link,
104 } 74 &:visited,
105 } 75 &:enabled {
76 color: props.get(vars.$header--label-color);
77 }
78 }
106 79
107 @include iro.bem-elem('header') { 80 @include bem.elem('separator') {
108 &:link, 81 block-size: 1px;
109 &:visited, 82 margin-block: props.get(vars.$separator-width);
110 &:enabled { 83 margin-inline: props.get(vars.$item--pad-i);
111 color: fn.color(--header --label); 84 background-color: props.get(vars.$separator-color);
112 } 85 }
113 }
114 86
115 @include iro.bem-elem('separator') { 87 @include bem.elem('slot') {
116 block-size: 1px; 88 padding-block: props.get(vars.$item--pad-b);
117 margin-block: fn.dim(--separator); 89 padding-inline: props.get(vars.$item--pad-i);
118 margin-inline: fn.dim(--item --pad-i); 90 }
119 background-color: fn.color(--separator);
120 }
121 91
122 @include iro.bem-elem('slot') { 92 @include bem.elem('icon-slot') {
123 padding-block: fn.dim(--item --pad-b); 93 display: flex;
124 padding-inline: fn.dim(--item --pad-i); 94 justify-content: center;
125 } 95 inline-size: props.get(icon.$size);
96 }
126 97
127 @include iro.bem-elem('icon-slot') { 98 @include bem.modifier('pull') {
128 display: flex; 99 margin: calc(-1 * props.get(vars.$item--pad-i));
129 justify-content: center; 100 }
130 inline-size: fn.foreign-dim(--icon, --size); 101 }
131 }
132
133 @include iro.bem-modifier('pull') {
134 margin: calc(-1 * fn.dim(--item --pad-i));
135 }
136 }
137} 102}
diff --git a/src/objects/_menu.vars.scss b/src/objects/_menu.vars.scss
new file mode 100644
index 0000000..d242a1f
--- /dev/null
+++ b/src/objects/_menu.vars.scss
@@ -0,0 +1,29 @@
1@use 'sass:map';
2@use 'iro-sass/src/props';
3@use '../core.vars' as core;
4
5$spacing: props.def(--o-menu--spacing, 0em) !default;
6$header--font-size: props.def(--o-menu--header--font-size, props.get(core.$font-size--50)) !default;
7$separator-width: props.def(--o-menu--separator-width, props.get(core.$size--100)) !default;
8
9$item--pad-i: props.def(--o-menu--item--pad-i, props.get(core.$size--150)) !default;
10$item--pad-b: props.def(--o-menu--item--pad-b, props.get(core.$size--100)) !default;
11$item--rounding: props.def(--o-menu--item--rounding, 0em) !default;
12
13$item--key-focus--border-width: props.def(--o-menu--item--key-focus--border-width, props.get(core.$key-focus--border-width)) !default;
14$item--key-focus--border-offset: props.def(--o-menu--item--key-focus--border-offset, props.get(core.$key-focus--border-offset)) !default;
15$item--key-focus--outline-width: props.def(--o-menu--item--key-focus--outline-width, props.get(core.$key-focus--outline-width)) !default;
16
17$separator-color: props.def(--o-menu--separator-color, props.get(core.$theme, --border), 'color') !default;
18$header--label-color: props.def(--o-menu--header--label-color, props.get(core.$theme, --heading), 'color') !default;
19
20$item--hover--bg-color: props.def(--o-menu--item--hover--bg-color, props.get(core.$theme, --border-mute), 'color') !default;
21$item--hover--label-color: props.def(--o-menu--item--hover--label-color, props.get(core.$theme, --heading), 'color') !default;
22
23$item--active--bg-color: props.def(--o-menu--item--active--bg-color, props.get(core.$theme, --border), 'color') !default;
24$item--active--label-color: props.def(--o-menu--item--active--label-color, props.get(core.$theme, --heading), 'color') !default;
25
26$item--disabled--label-color: props.def(--o-menu--item--disabled--label-color, props.get(core.$theme, --text-disabled), 'color') !default;
27
28$item--key-focus--border-color: props.def(--o-menu--item--key-focus--border-color, props.get(core.$theme, --focus, --border), 'color') !default;
29$item--key-focus--outline-color: props.def(--o-menu--item--key-focus--outline-color, props.get(core.$theme, --focus, --outline), 'color') !default;
diff --git a/src/objects/_navbar.scss b/src/objects/_navbar.scss
new file mode 100644
index 0000000..ec03c62
--- /dev/null
+++ b/src/objects/_navbar.scss
@@ -0,0 +1,191 @@
1@use 'sass:map';
2@use 'sass:meta';
3@use 'sass:string';
4@use 'iro-sass/src/bem';
5@use 'iro-sass/src/props';
6@use '../props' as *;
7
8@forward 'navbar.vars';
9@use 'navbar.vars' as vars;
10
11@mixin styles {
12 @include materialize-at-root(meta.module-variables('vars'));
13
14 @include bem.object('navbar') {
15 display: flex;
16 block-size: props.get(vars.$block-size);
17
18 @include bem.elem('item-content-text') {
19 margin-inline: props.get(vars.$item--pad-i-label);
20 }
21
22 @include bem.elem('item-content') {
23 position: relative;
24 padding-block: props.get(vars.$item--pad-b);
25 padding-inline: props.get(vars.$item--pad-i);
26 font-size: props.get(vars.$item--font-size);
27 color: currentColor;
28 white-space: nowrap;
29 border-radius: 100em;
30
31 &::after {
32 position: absolute;
33 inset: calc(-1 * props.get(vars.$key-focus--border-offset));
34 z-index: -10;
35 display: block;
36 visibility: hidden;
37 pointer-events: none;
38 outline: props.get(vars.$default-theme, --key-focus, --border) solid props.get(vars.$key-focus--border-width);
39 content: '';
40 border-radius: 100em;
41 box-shadow:
42 0
43 0
44 0
45 calc(props.get(vars.$key-focus--border-width) + props.get(vars.$key-focus--outline-width))
46 props.get(vars.$default-theme, --key-focus, --outline);
47 }
48 }
49
50 @include bem.elem('item') {
51 display: flex;
52 flex-direction: column;
53 align-items: center;
54 justify-content: center;
55 inline-size: 100%;
56 padding-inline: calc(.5 * props.get(vars.$spacing));
57 font-weight: 500;
58 color: props.get(vars.$default-theme, --disabled, --label-color);
59
60 &:link,
61 &:visited,
62 &:enabled {
63 color: props.get(vars.$default-theme, --label-color);
64
65 &:hover,
66 &:focus-visible {
67 color: props.get(vars.$default-theme, --hover, --label-color);
68
69 @include bem.elem('item-content') {
70 background-color: props.get(vars.$default-theme, --hover, --bg-color);
71 }
72 }
73
74 &:focus-visible {
75 @include bem.elem('item-content') {
76 &::after {
77 visibility: visible;
78 }
79 }
80 }
81
82 &:active {
83 color: props.get(vars.$default-theme, --active, --label-color);
84
85 @include bem.elem('item-content') {
86 background-color: props.get(vars.$default-theme, --active, --bg-color);
87 }
88 }
89 }
90
91 @include bem.is('selected') {
92 font-weight: bold;
93 color: props.get(vars.$default-theme, --selected, --disabled, --label-color);
94
95 @include bem.elem('item-content') {
96 background-color: props.get(vars.$default-theme, --selected, --disabled, --bg-color);
97 }
98
99 &:link,
100 &:visited,
101 &:enabled {
102 color: props.get(vars.$default-theme, --selected, --label-color);
103
104 @include bem.elem('item-content') {
105 background-color: props.get(vars.$default-theme, --selected, --bg-color);
106 }
107
108 &:hover,
109 &:focus-visible {
110 color: props.get(vars.$default-theme, --selected, --hover, --label-color);
111
112 @include bem.elem('item-content') {
113 background-color: props.get(vars.$default-theme, --selected, --hover, --bg-color);
114 }
115 }
116
117 &:active {
118 color: props.get(vars.$default-theme, --selected, --active, --label-color);
119
120 @include bem.elem('item-content') {
121 background-color: props.get(vars.$default-theme, --selected, --active, --bg-color);
122 }
123 }
124 }
125 }
126 }
127
128 @include bem.modifier('hide-unselected') {
129 @include bem.elem('item') {
130 display: none;
131
132 @include bem.is('selected') {
133 display: flex;
134 }
135 }
136 }
137
138 @include bem.modifier('adapt') {
139 gap: props.get(vars.$spacing);
140 block-size: 100%;
141
142 @include bem.elem('item') {
143 padding-inline: 0;
144 }
145 }
146
147
148 @include bem.modifier('align-block') {
149 margin-inline: calc(-1 * props.get(vars.$item--pad-i));
150 }
151
152 @include bem.modifier('quiet') {
153 @include bem.elem('item') {
154 @include bem.is('selected') {
155 color: props.get(vars.$default-theme, --quiet, --selected, --disabled, --label-color);
156
157 @include bem.elem('item-content') {
158 background-color: props.get(vars.$default-theme, --quiet, --selected, --disabled, --bg-color);
159 }
160
161 &:link,
162 &:visited,
163 &:enabled {
164 color: props.get(vars.$default-theme, --quiet, --selected, --label-color);
165
166 @include bem.elem('item-content') {
167 background-color: props.get(vars.$default-theme, --quiet, --selected, --bg-color);
168 }
169
170 &:hover,
171 &:focus-visible {
172 color: props.get(vars.$default-theme, --quiet, --selected, --hover, --label-color);
173
174 @include bem.elem('item-content') {
175 background-color: props.get(vars.$default-theme, --quiet, --selected, --hover, --bg-color);
176 }
177 }
178
179 &:active {
180 color: props.get(vars.$default-theme, --quiet, --selected, --active, --label-color);
181
182 @include bem.elem('item-content') {
183 background-color: props.get(vars.$default-theme, --quiet, --selected, --active, --bg-color);
184 }
185 }
186 }
187 }
188 }
189 }
190 }
191}
diff --git a/src/objects/_navbar.vars.scss b/src/objects/_navbar.vars.scss
new file mode 100644
index 0000000..8e18def
--- /dev/null
+++ b/src/objects/_navbar.vars.scss
@@ -0,0 +1,84 @@
1@use 'sass:map';
2@use 'sass:string';
3@use 'iro-sass/src/props';
4@use '../core.vars' as core;
5
6$block-size: props.def(--o-navbar--block-size, props.get(core.$size--800)) !default;
7$spacing: props.def(--o-navbar--spacing, props.get(core.$size--200)) !default;
8
9$item--pad-i: props.def(--o-navbar--item--pad-i, props.get(core.$size--150)) !default;
10$item--pad-i-label: props.def(--o-navbar--item--pad-i-label, props.get(core.$size--25)) !default;
11$item--pad-b: props.def(--o-navbar--item--pad-b, props.get(core.$size--40)) !default;
12$item--font-size: props.def(--o-navbar--item--font-size, props.get(core.$font-size--75)) !default;
13
14$key-focus--border-width: props.def(--o-navbar--key-focus--border-width, props.get(core.$key-focus--border-width)) !default;
15$key-focus--border-offset: props.def(--o-navbar--key-focus--border-offset, props.get(core.$key-focus--border-offset)) !default;
16$key-focus--outline-width: props.def(--o-navbar--key-focus--outline-width, props.get(core.$key-focus--outline-width)) !default;
17
18$default-theme-override: () !default;
19$default-theme: map.deep-merge((
20 --label-color: props.get(core.$theme, --text),
21
22 --hover: (
23 --bg-color: props.get(core.$theme, --border-mute),
24 --label-color: props.get(core.$theme, --heading),
25 ),
26
27 --active: (
28 --bg-color: props.get(core.$theme, --border),
29 --label-color: props.get(core.$theme, --heading),
30 ),
31
32 --disabled: (
33 --label-color: props.get(core.$theme, --border-strong),
34 ),
35
36 --key-focus: (
37 --label: props.get(core.$theme, --focus, --text),
38 --border: props.get(core.$theme, --focus, --border),
39 --outline: props.get(core.$theme, --focus, --outline),
40 ),
41
42 --selected: (
43 --bg-color: props.get(core.$theme, --heading),
44 --label-color: props.get(core.$theme, --base, --50),
45
46 --hover: (
47 --bg-color: props.get(core.$theme, --text),
48 --label-color: props.get(core.$theme, --base, --50),
49 ),
50
51 --active: (
52 --bg-color: props.get(core.$theme, --text-mute),
53 --label-color: props.get(core.$theme, --base, --50),
54 ),
55
56 --disabled: (
57 --bg-color: props.get(core.$theme, --border-mute),
58 --label-color: props.get(core.$theme, --border-strong),
59 ),
60 ),
61
62 --quiet: (
63 --selected: (
64 --bg-color: props.get(core.$theme, --accent, --200),
65 --label-color: props.get(core.$theme, --accent, --1100),
66
67 --hover: (
68 --bg-color: props.get(core.$theme, --accent, --300),
69 --label-color: props.get(core.$theme, --accent, --1200),
70 ),
71
72 --active: (
73 --bg-color: props.get(core.$theme, --accent, --400),
74 --label-color: props.get(core.$theme, --accent, --1300),
75 ),
76
77 --disabled: (
78 --bg-color: props.get(core.$theme, --accent, --200),
79 --label-color: props.get(core.$theme, --accent, --800),
80 ),
81 )
82 )
83), $default-theme-override) !default;
84$default-theme: props.def(--o-navbar, $default-theme, 'color');
diff --git a/src/objects/_palette.scss b/src/objects/_palette.scss
index 19f282f..79c0f6c 100644
--- a/src/objects/_palette.scss
+++ b/src/objects/_palette.scss
@@ -1,62 +1,63 @@
1@use 'sass:map';
2@use 'sass:list'; 1@use 'sass:list';
2@use 'sass:map';
3@use 'sass:string'; 3@use 'sass:string';
4@use 'iro-sass/src/index' as iro; 4@use 'iro-sass/src/bem';
5@use '../functions' as fn;
6@use '../config'; 5@use '../config';
6@use 'iro-sass/src/props';
7@use '../core.vars' as core;
7 8
8@include iro.props-namespace('palette') { 9@mixin styles {
9 @include iro.bem-object(iro.props-namespace()) { 10 @include bem.object('palette') {
10 display: flex; 11 display: flex;
11 block-size: 3em; 12 block-size: 3em;
12 13
13 @include iro.bem-elem('item') { 14 @include bem.elem('item') {
14 flex: 1 1 auto; 15 flex: 1 1 auto;
15 16
16 $palette: map.get(config.$themes, config.$theme-default, --palettes, --base); 17 $palette: map.get(config.$themes, config.$theme-default, light, --palettes, --base);
17 $contrasts: map.get(config.$themes, config.$theme-default, --contrasts, list.nth($palette, 2)); 18 $levels: map.get(config.$themes, config.$theme-default, light, --levels, list.nth($palette, 2));
18 19
19 @for $i from 1 through list.length($contrasts) { 20 @for $i from 1 through list.length($levels) {
20 $key: list.nth(map.keys($contrasts), $i); 21 $key: list.nth(map.keys($levels), $i);
21 22
22 &:nth-child(#{$i}) { 23 &:nth-child(#{$i}) {
23 background-color: fn.global-color(--base $key); 24 background-color: props.get(core.$theme, --base, $key);
24 } 25 }
25 } 26 }
26 } 27 }
27 28
28 @each $palette-name, $palette in map.get(config.$themes, config.$theme-default, --palettes) { 29 @each $palette-name, $palette in map.get(config.$themes, config.$theme-default, light, --palettes) {
29 $contrasts: map.get(config.$themes, config.$theme-default, --contrasts, list.nth($palette, 2)); 30 $levels: map.get(config.$themes, config.$theme-default, light, --levels, list.nth($palette, 2));
30 31
31 @include iro.bem-modifier(string.slice($palette-name, 3)) { 32 @include bem.modifier(string.slice($palette-name, 3)) {
32 @include iro.bem-elem('item') { 33 @include bem.elem('item') {
33 @for $i from 1 through list.length($contrasts) { 34 @for $i from 1 through list.length($levels) {
34 $key: list.nth(map.keys($contrasts), $i); 35 $key: list.nth(map.keys($levels), $i);
35 36
36 &:nth-child(#{$i}) { 37 &:nth-child(#{$i}) {
37 background-color: fn.global-color($palette-name $key); 38 background-color: props.get(core.$theme, $palette-name, $key);
38 } 39 }
39 } 40 }
40 } 41 }
41 } 42 }
42 } 43 }
43 44
44 @include iro.bem-modifier('static') { 45 @include bem.modifier('static') {
45 @each $palette-name, $palette in map.get(config.$static-colors, --palettes) { 46 @each $palette-name, $palette in map.get(config.$static-colors, --palettes) {
46 $contrasts: map.get(config.$static-colors, --contrasts); 47 $levels: map.get(config.$static-colors, --levels);
47 48
48 @include iro.bem-modifier(string.slice($palette-name, 3)) { 49 @include bem.modifier(string.slice($palette-name, 3)) {
49 @include iro.bem-elem('item') { 50 @include bem.elem('item') {
50 @for $i from 1 through list.length($contrasts) { 51 @for $i from 1 through list.length($levels) {
51 $key: list.nth(map.keys($contrasts), $i); 52 $key: list.nth(map.keys($levels), $i);
52 53
53 &:nth-child(#{$i}) { 54 &:nth-child(#{$i}) {
54 background-color: fn.global-color(#{$palette-name}-static $key); 55 background-color: props.get(core.$theme, #{$palette-name}-static, $key);
55 } 56 }
56 } 57 }
57 } 58 }
58 } 59 }
59 } 60 }
60 } 61 }
61 } 62 }
62} 63}
diff --git a/src/objects/_placeholders.scss b/src/objects/_placeholders.scss
new file mode 100644
index 0000000..80fc913
--- /dev/null
+++ b/src/objects/_placeholders.scss
@@ -0,0 +1,22 @@
1@use 'sass:meta';
2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
5
6@forward 'placeholders.vars';
7@use 'placeholders.vars' as vars;
8
9@mixin styles {
10 @include materialize-at-root(meta.module-variables('vars'));
11
12 @include bem.object('placeholders') {
13 @include bem.elem('placeholder') {
14 display: inline-block;
15 min-block-size: props.get(vars.$min-block-size);
16 vertical-align: middle;
17 background-color: currentColor;
18 border-radius: props.get(vars.$rounding);
19 opacity: props.get(vars.$opacity);
20 }
21 }
22}
diff --git a/src/objects/_placeholders.vars.scss b/src/objects/_placeholders.vars.scss
new file mode 100644
index 0000000..a2e41e2
--- /dev/null
+++ b/src/objects/_placeholders.vars.scss
@@ -0,0 +1,6 @@
1@use 'iro-sass/src/props';
2@use '../core.vars' as core;
3
4$min-block-size: props.def(--o-placeholder--min-block-size, 1em) !default;
5$rounding: props.def(--o-placeholder--rounding, props.get(core.$rounding)) !default;
6$opacity: props.def(--o-placeholder--opacity, .5) !default;
diff --git a/src/objects/_popover.scss b/src/objects/_popover.scss
index 5ad58ec..2746477 100644
--- a/src/objects/_popover.scss
+++ b/src/objects/_popover.scss
@@ -1,51 +1,45 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
3 5
4@include iro.props-namespace('popover') { 6@forward 'popover.vars';
5 @include iro.props-store(( 7@use 'popover.vars' as vars;
6 --dims: (
7 --z-index: 10000,
8 --pad-i: 0,
9 --pad-b: fn.global-dim(--size --85),
10 --separator: fn.global-dim(--size --85),
11 --rounding: fn.global-dim(--rounding),
12 --border: fn.global-dim(--border --thin),
13 ),
14 --colors: (
15 --bg: fn.global-color(--bg-l2),
16 --border: fn.global-color(--border),
17 --filter: drop-shadow(
18 fn.global-dim(--shadow --x)
19 fn.global-dim(--shadow --y)
20 fn.global-dim(--shadow --blur)
21 fn.global-color(--shadow)
22 ),
23 ),
24 ));
25 8
26 @include iro.bem-object(iro.props-namespace()) { 9@mixin styles {
27 position: absolute; 10 @include materialize-at-root(meta.module-variables('vars'));
28 z-index: fn.dim(--z-index);
29 inset-block-start: 0;
30 inset-inline-start: 0;
31 padding-block: fn.dim(--pad-b);
32 padding-inline: fn.dim(--pad-i);
33 transform: translate(var(--x), var(--y));
34 border: fn.dim(--border) solid fn.color(--border);
35 border-radius: fn.dim(--rounding);
36 background-color: fn.color(--bg);
37 filter: fn.color(--filter);
38 11
39 @include iro.bem-modifier('up-left') { 12 @include bem.object('popover') {
40 transform: translate(var(--x), calc(var(--y) - 100%)); 13 position: fixed;
41 } 14 inset-block-start: 0;
15 inset-inline-start: 0;
16 z-index: props.get(vars.$z-index);
17 padding-block: props.get(vars.$pad-b);
18 padding-inline: props.get(vars.$pad-i);
19 margin: 0;
20 color: currentColor;
21 background-color: props.get(vars.$bg-color);
22 border: props.get(vars.$border-width) solid transparent;
23 border-color: props.get(vars.$border-color);
24 border-radius: props.get(vars.$rounding);
25 box-shadow:
26 props.get(vars.$shadow-x)
27 props.get(vars.$shadow-y)
28 props.get(vars.$shadow-blur)
29 props.get(vars.$shadow-grow)
30 props.get(vars.$shadow-color);
31 transform: translate(var(--x), var(--y));
42 32
43 @include iro.bem-modifier('up-right') { 33 @include bem.modifier('up-left') {
44 transform: translate(calc(var(--x) - 100%), calc(var(--y) - 100%)); 34 transform: translate(var(--x), calc(var(--y) - 100%));
45 } 35 }
46 36
47 @include iro.bem-modifier('down-right') { 37 @include bem.modifier('up-right') {
48 transform: translate(calc(var(--x) - 100%), var(--y)); 38 transform: translate(calc(var(--x) - 100%), calc(var(--y) - 100%));
49 } 39 }
50 } 40
41 @include bem.modifier('down-right') {
42 transform: translate(calc(var(--x) - 100%), var(--y));
43 }
44 }
51} 45}
diff --git a/src/objects/_popover.vars.scss b/src/objects/_popover.vars.scss
new file mode 100644
index 0000000..e560d1b
--- /dev/null
+++ b/src/objects/_popover.vars.scss
@@ -0,0 +1,19 @@
1@use 'sass:map';
2@use 'iro-sass/src/props';
3@use '../core.vars' as core;
4
5$z-index: props.def(--o-popover--z-index, 11000) !default;
6$pad-i: props.def(--o-popover--pad-i, 0) !default;
7$pad-b: props.def(--o-popover--pad-b, props.get(core.$size--85)) !default;
8$separator-width: props.def(--o-popover--separator-width, props.get(core.$size--85)) !default;
9$rounding: props.def(--o-popover--rounding, props.get(core.$rounding)) !default;
10$border-width: props.def(--o-popover--border-width, props.get(core.$border-width--thin)) !default;
11
12$shadow-x: props.def(--o-popover--shadow-x, props.get(core.$shadow--l2--x)) !default;
13$shadow-y: props.def(--o-popover--shadow-y, props.get(core.$shadow--l2--y)) !default;
14$shadow-blur: props.def(--o-popover--shadow-blur, props.get(core.$shadow--l2--blur)) !default;
15$shadow-grow: props.def(--o-popover--shadow-grow, props.get(core.$shadow--l2--grow)) !default;
16
17$bg-color: props.def(--o-popover--bg-color, props.get(core.$theme, --bg-l2), 'color') !default;
18$border-color: props.def(--o-popover--border-color, props.get(core.$theme, --box, --border) props.get(core.$theme, --box, --border) props.get(core.$theme, --box, --border-strong), 'color') !default;
19$shadow-color: props.def(--o-popover--shadow-color, props.get(core.$theme, --shadow), 'color') !default;
diff --git a/src/objects/_radio.scss b/src/objects/_radio.scss
index 9fa937d..8327a15 100644
--- a/src/objects/_radio.scss
+++ b/src/objects/_radio.scss
@@ -1,185 +1,154 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
5@use '../core.vars' as core;
3 6
4@include iro.props-namespace('radio') { 7@forward 'radio.vars';
5 @include iro.props-store(( 8@use 'radio.vars' as vars;
6 --dims: (
7 --diameter: fn.global-dim(--size --200),
8 --label-gap: fn.global-dim(--size --125),
9 --border: fn.global-dim(--border --medium),
10 --pad-i: fn.global-dim(--size --65),
11 --pad-b: fn.global-dim(--size --65),
12 --rounding: fn.global-dim(--rounding),
13 --spacing-sibling: fn.global-dim(--size --300),
14 9
15 --key-focus: ( 10@mixin styles {
16 --border: fn.global-dim(--key-focus --border), 11 @include materialize-at-root(meta.module-variables('vars'));
17 --border-offset: fn.global-dim(--key-focus --border-offset),
18 --outline: fn.global-dim(--key-focus --outline),
19 ),
20 ),
21 --colors: (
22 --circle-border: fn.global-color(--text-mute-more),
23 --circle-bg: fn.global-color(--base --75),
24
25 --hover: (
26 --label: fn.global-color(--heading),
27 --circle-border: fn.global-color(--text-mute),
28 ),
29 --accent: (
30 --circle-border: fn.global-color(--accent --900),
31
32 --hover: (
33 --circle-border: fn.global-color(--accent --1000),
34 ),
35 ),
36 --disabled: (
37 --label: fn.global-color(--text-disabled),
38 --circle-border: fn.global-color(--border-strong),
39 --circle-bg: fn.global-color(--base --75),
40 ),
41 --key-focus: (
42 --label: fn.global-color(--focus --text),
43 --border: fn.global-color(--focus --border),
44 --outline: fn.global-color(--focus --outline),
45 ),
46 ),
47 ));
48 12
49 @include iro.bem-object(iro.props-namespace()) { 13 @include bem.object('radio') {
50 display: inline-block; 14 position: relative;
51 position: relative; 15 display: inline-block;
52 margin-inline: 16 padding-block: props.get(vars.$pad-b);
53 calc(-1 * fn.dim(--pad-i) - fn.dim(--key-focus --border-offset)) 17 padding-inline: props.get(vars.$pad-i);
54 calc(fn.dim(--spacing-sibling) - fn.dim(--pad-i) - fn.dim(--key-focus --border-offset)); 18 margin-inline:
55 padding-block: fn.dim(--pad-b); 19 calc(-1 * props.get(vars.$pad-i) - props.get(vars.$key-focus--border-offset))
56 padding-inline: fn.dim(--pad-i); 20 calc(props.get(vars.$spacing-sibling) - props.get(vars.$pad-i) - props.get(vars.$key-focus--border-offset));
57 21
58 @include iro.bem-elem('circle') { 22 @include bem.elem('circle') {
59 display: inline-block; 23 display: inline-block;
60 flex: 0 0 auto; 24 flex: 0 0 auto;
61 inline-size: fn.dim(--diameter); 25 inline-size: props.get(vars.$diameter);
62 block-size: fn.dim(--diameter); 26 block-size: props.get(vars.$diameter);
63 margin-block-start: calc(.5em * fn.global-dim(--font --standard --line-height) - .5 * fn.dim(--diameter) - fn.dim(--key-focus --border-offset)); 27 margin-block-start: calc(.5em * props.get(core.$font--standard--line-height) - .5 * props.get(vars.$diameter) - props.get(vars.$key-focus--border-offset));
64 border: fn.dim(--key-focus --border-offset) solid transparent; 28 vertical-align: top;
65 border-radius: 2em; 29 background-color: props.get(vars.$circle-border-color);
66 background-color: fn.color(--circle-border); 30 background-clip: padding-box;
67 background-clip: padding-box; 31 border: props.get(vars.$key-focus--border-offset) solid transparent;
68 vertical-align: top; 32 border-radius: 2em;
69 33
70 &::after { 34 &::after {
71 content: ''; 35 position: relative;
72 display: block; 36 inset-block-start: props.get(vars.$border-width);
73 position: relative; 37 inset-inline-start: props.get(vars.$border-width);
74 inset-block-start: fn.dim(--border); 38 display: block;
75 inset-inline-start: fn.dim(--border); 39 inline-size: calc(props.get(vars.$diameter) - 2 * props.get(vars.$border-width));
76 inline-size: calc(fn.dim(--diameter) - 2 * fn.dim(--border)); 40 block-size: calc(props.get(vars.$diameter) - 2 * props.get(vars.$border-width));
77 block-size: calc(fn.dim(--diameter) - 2 * fn.dim(--border)); 41 content: '';
78 transition: transform .2s ease; 42 background-color: props.get(vars.$circle-bg-color);
79 border-radius: fn.dim(--diameter); 43 border-radius: props.get(vars.$diameter);
80 background-color: fn.color(--circle-bg); 44 transition: transform .2s ease;
81 } 45 }
82 } 46 }
83 47
84 @include iro.bem-elem('label') { 48 @include bem.elem('label') {
85 margin-inline-start: calc(fn.dim(--label-gap) - fn.dim(--key-focus --border-offset)); 49 margin-inline-start: calc(props.get(vars.$label-gap) - props.get(vars.$key-focus--border-offset));
86 } 50 }
87 51
88 @include iro.bem-elem('native') { 52 @include bem.elem('native') {
89 appearance: none; 53 position: absolute;
90 position: absolute; 54 inset-block-start: 0;
91 z-index: -1; 55 inset-inline-start: 0;
92 inset-block-start: 0; 56 z-index: -1;
93 inset-inline-start: 0; 57 inline-size: 100%;
94 inline-size: 100%; 58 block-size: 100%;
95 block-size: 100%; 59 padding: 0;
96 margin: 0; 60 margin: 0;
97 padding: 0; 61 overflow: hidden;
98 overflow: hidden; 62 appearance: none;
99 border-radius: fn.dim(--rounding); 63 border-radius: props.get(vars.$rounding);
100 64
101 &:hover, 65 &:hover,
102 &:focus-visible { 66 &:focus-visible {
103 @include iro.bem-sibling-elem('label') { 67 @include bem.sibling-elem('label') {
104 color: fn.color(--hover --label); 68 color: props.get(vars.$hover--label-color);
105 } 69 }
106 70
107 @include iro.bem-sibling-elem('circle') { 71 @include bem.sibling-elem('circle') {
108 background-color: fn.color(--hover --circle-border); 72 background-color: props.get(vars.$hover--circle-border-color);
109 } 73 }
110 } 74 }
111 75
112 &:checked { 76 &:checked {
113 @include iro.bem-sibling-elem('circle') { 77 @include bem.sibling-elem('circle') {
114 &::after { 78 &::after {
115 transform: scale(.44); 79 transform: scale(.44);
116 } 80 }
117 } 81 }
118 } 82 }
119 83
120 &:disabled { 84 &:disabled {
121 @include iro.bem-sibling-elem('label') { 85 @include bem.sibling-elem('label') {
122 color: fn.color(--disabled --label); 86 color: props.get(vars.$disabled--label-color);
123 } 87 }
124 88
125 @include iro.bem-sibling-elem('circle') { 89 @include bem.sibling-elem('circle') {
126 background-color: fn.color(--disabled --circle-border); 90 background-color: props.get(vars.$disabled--circle-border-color);
127 91
128 &::after { 92 &::after {
129 background-color: fn.color(--disabled --circle-bg); 93 background-color: props.get(vars.$disabled--circle-bg-color);
130 } 94 }
131 } 95 }
132 } 96 }
133 97
134 &:focus-visible { 98 &:focus-visible {
135 @include iro.bem-sibling-elem('label') { 99 @include bem.sibling-elem('label') {
136 color: fn.color(--key-focus --label); 100 color: props.get(vars.$key-focus--label-color);
137 } 101 }
138 102
139 @include iro.bem-sibling-elem('circle') { 103 @include bem.sibling-elem('circle') {
140 outline: fn.color(--key-focus --border) solid fn.dim(--key-focus --border); 104 outline: props.get(vars.$key-focus--border-color) solid props.get(vars.$key-focus--border-width);
141 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(--key-focus --outline); 105 box-shadow:
142 } 106 0
143 } 107 0
144 } 108 0
109 calc(props.get(vars.$key-focus--border-width) + props.get(vars.$key-focus--outline-width))
110 props.get(vars.$key-focus--outline-color);
111 }
112 }
113 }
145 114
146 @include iro.bem-modifier('standalone') { 115 @include bem.modifier('standalone') {
147 @include iro.bem-elem('circle') { 116 @include bem.elem('circle') {
148 margin-block-start: 0; 117 margin-block-start: 0;
149 } 118 }
150 } 119 }
151 120
152 @include iro.bem-modifier('accent') { 121 @include bem.modifier('accent') {
153 @include iro.bem-elem('native') { 122 @include bem.elem('native') {
154 &:checked { 123 &:checked {
155 @include iro.bem-sibling-elem('circle') { 124 @include bem.sibling-elem('circle') {
156 background-color: fn.color(--accent --circle-border); 125 background-color: props.get(vars.$accent--circle-border-color);
157 } 126 }
158 127
159 &:hover, 128 &:hover,
160 &:focus-visible { 129 &:focus-visible {
161 @include iro.bem-sibling-elem('circle') { 130 @include bem.sibling-elem('circle') {
162 background-color: fn.color(--accent --hover --circle-border); 131 background-color: props.get(vars.$accent--hover--circle-border-color);
163 } 132 }
164 } 133 }
165 } 134 }
166 135
167 &:disabled { 136 &:disabled {
168 @include iro.bem-sibling-elem('circle') { 137 @include bem.sibling-elem('circle') {
169 background-color: fn.color(--disabled --circle-border); 138 background-color: props.get(vars.$disabled--circle-border-color);
170 139
171 &::after { 140 &::after {
172 background-color: fn.color(--disabled --circle-bg); 141 background-color: props.get(vars.$disabled--circle-bg-color);
173 } 142 }
174 } 143 }
175 144
176 &:checked { 145 &:checked {
177 @include iro.bem-sibling-elem('circle') { 146 @include bem.sibling-elem('circle') {
178 background-color: fn.color(--disabled --circle-border); 147 background-color: props.get(vars.$disabled--circle-border-color);
179 } 148 }
180 } 149 }
181 } 150 }
182 } 151 }
183 } 152 }
184 } 153 }
185} 154}
diff --git a/src/objects/_radio.vars.scss b/src/objects/_radio.vars.scss
new file mode 100644
index 0000000..b18ae2b
--- /dev/null
+++ b/src/objects/_radio.vars.scss
@@ -0,0 +1,33 @@
1@use 'sass:map';
2@use 'iro-sass/src/props';
3@use '../core.vars' as core;
4
5$diameter: props.def(--o-radio--diameter, props.get(core.$size--200)) !default;
6$label-gap: props.def(--o-radio--label-gap, props.get(core.$size--125)) !default;
7$border-width: props.def(--o-radio--border-width, props.get(core.$border-width--medium)) !default;
8$pad-i: props.def(--o-radio--pad-i, props.get(core.$size--65)) !default;
9$pad-b: props.def(--o-radio--pad-b, props.get(core.$size--65)) !default;
10$rounding: props.def(--o-radio--rounding, props.get(core.$rounding--sm)) !default;
11$spacing-sibling: props.def(--o-radio--spacing-sibling, props.get(core.$size--300)) !default;
12
13$key-focus--border-width: props.def(--o-radio--key-focus--border-width, props.get(core.$key-focus--border-width)) !default;
14$key-focus--border-offset: props.def(--o-radio--key-focus--border-offset, props.get(core.$key-focus--border-offset)) !default;
15$key-focus--outline-width: props.def(--o-radio--key-focus--outline-width, props.get(core.$key-focus--outline-width)) !default;
16
17$circle-border-color: props.def(--o-radio--circle-border-color, props.get(core.$theme, --text-mute-more), 'color') !default;
18$circle-bg-color: props.def(--o-radio--circle-bg-color, props.get(core.$theme, --base, --75), 'color') !default;
19
20$hover--label-color: props.def(--o-radio--hover--label-color, props.get(core.$theme, --heading), 'color') !default;
21$hover--circle-border-color: props.def(--o-radio--hover--circle-border-color, props.get(core.$theme, --text-mute), 'color') !default;
22
23$accent--circle-border-color: props.def(--o-radio--accent--circle-border-color, props.get(core.$theme, --accent, --900), 'color') !default;
24
25$accent--hover--circle-border-color: props.def(--o-radio--accent--hover--circle-border-color, props.get(core.$theme, --accent, --1000), 'color') !default;
26
27$disabled--label-color: props.def(--o-radio--disabled--label-color, props.get(core.$theme, --text-disabled), 'color') !default;
28$disabled--circle-border-color: props.def(--o-radio--disabled--circle-border-color, props.get(core.$theme, --border-strong), 'color') !default;
29$disabled--circle-bg-color: props.def(--o-radio--disabled--circle-bg-color, props.get(core.$theme, --base, --75), 'color') !default;
30
31$key-focus--label-color: props.def(--o-radio--key-focus--label-color, props.get(core.$theme, --focus, --text), 'color') !default;
32$key-focus--border-color: props.def(--o-radio--key-focus--border-color, props.get(core.$theme, --focus, --border), 'color') !default;
33$key-focus--outline-color: props.def(--o-radio--key-focus--outline-color, props.get(core.$theme, --focus, --outline), 'color') !default;
diff --git a/src/objects/_side-nav.scss b/src/objects/_side-nav.scss
index 8e4e131..4a1feda 100644
--- a/src/objects/_side-nav.scss
+++ b/src/objects/_side-nav.scss
@@ -1,122 +1,90 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
5@use 'icon.vars' as icon;
3 6
4@use './icon'; 7@forward 'side-nav.vars';
8@use 'side-nav.vars' as vars;
5 9
6@include iro.props-namespace('side-nav') { 10@mixin styles {
7 @include iro.props-store(( 11 @include materialize-at-root(meta.module-variables('vars'));
8 --dims: (
9 --spacing: fn.global-dim(--size --50),
10 --header: (
11 --font-size: fn.global-dim(--font-size --50),
12 ),
13 --separator: fn.global-dim(--size --200),
14 --item: (
15 --pad-i: fn.global-dim(--size --150),
16 --pad-b: fn.global-dim(--size --100),
17 --rounding: fn.global-dim(--rounding),
18
19 --key-focus: (
20 --border: fn.global-dim(--key-focus --border),
21 --border-offset: fn.global-dim(--key-focus --border-offset),
22 --outline: fn.global-dim(--key-focus --outline),
23 ),
24 ),
25 ),
26 --colors: (
27 --header: (
28 --label: fn.global-color(--text-mute-more),
29 ),
30 --item: (
31 --hover: (
32 --bg: fn.global-color(--border-mute),
33 --label: fn.global-color(--heading),
34 ),
35 --active: (
36 --bg: fn.global-color(--border),
37 --label: fn.global-color(--heading),
38 ),
39 --disabled: (
40 --label: fn.global-color(--text-disabled),
41 ),
42 --key-focus: (
43 --border: fn.global-color(--focus --border),
44 --outline: fn.global-color(--focus --outline),
45 ),
46 ),
47 ),
48 ));
49 12
50 @include iro.bem-object(iro.props-namespace()) { 13 @include bem.object('side-nav') {
51 display: flex; 14 display: flex;
52 flex-direction: column; 15 flex-direction: column;
53 gap: fn.dim(--spacing); 16 gap: props.get(vars.$spacing);
54 17
55 @include iro.bem-elem('header') { 18 @include bem.elem('header') {
56 padding-block: fn.dim(--item --pad-b); 19 padding-block: props.get(vars.$item--pad-b);
57 padding-inline: fn.dim(--item --pad-i); 20 padding-inline: props.get(vars.$item--pad-i);
58 color: fn.color(--header --label); 21 font-size: props.get(vars.$header--font-size);
59 font-size: fn.dim(--header --font-size); 22 font-weight: 500;
60 font-weight: 500; 23 color: props.get(vars.$header--label-color);
61 letter-spacing: .5px; 24 text-transform: uppercase;
62 text-transform: uppercase; 25 letter-spacing: .5px;
63 26
64 @include iro.bem-next-twin-elem { 27 @include bem.next-twin-elem {
65 margin-block-start: calc(fn.dim(--separator) + fn.dim(--spacing)); 28 margin-block-start: calc(props.get(vars.$separator) + props.get(vars.$spacing));
66 } 29 }
67 } 30 }
68 31
69 @include iro.bem-elem('item') { 32 @include bem.elem('item') {
70 padding-block: fn.dim(--item --pad-b); 33 padding-block: props.get(vars.$item--pad-b);
71 padding-inline: fn.dim(--item --pad-i); 34 padding-inline: props.get(vars.$item--pad-i);
72 margin: calc(-1 * fn.dim(--item --key-focus --border-offset)); 35 margin: calc(-1 * props.get(vars.$item--key-focus--border-offset));
73 border: fn.dim(--item --key-focus --border-offset) solid transparent; 36 color: props.get(vars.$item--disabled--label-color);
74 border-radius: calc(fn.dim(--item --rounding) + fn.dim(--item --key-focus --border-offset)); 37 background-clip: padding-box;
75 color: fn.color(--item --disabled --label); 38 border: props.get(vars.$item--key-focus--border-offset) solid transparent;
76 background-clip: padding-box; 39 border-radius: calc(props.get(vars.$item--rounding) + props.get(vars.$item--key-focus--border-offset));
77 40
78 &:link, 41 &:link,
79 &:visited, 42 &:visited,
80 &:enabled { 43 &:enabled {
81 color: currentColor; 44 color: currentColor;
82 45
83 @include iro.bem-multi('&:hover, &:focus-visible', 'is' 'selected') { 46 @include bem.multi('&:hover, &:focus-visible', 'is' 'selected') {
84 background-color: fn.color(--item --hover --bg); 47 color: props.get(vars.$item--hover--label-color);
85 color: fn.color(--item --hover --label); 48 background-color: props.get(vars.$item--hover--bg-color);
86 } 49 }
87 50
88 &:active { 51 &:active {
89 background-color: fn.color(--item --active --bg); 52 color: props.get(vars.$item--active--label-color);
90 color: fn.color(--item --active --label); 53 background-color: props.get(vars.$item--active--bg-color);
91 } 54 }
92 55
93 &:focus-visible { 56 &:focus-visible {
94 outline: fn.color(--item --key-focus --border) solid fn.dim(--item --key-focus --border); 57 outline: props.get(vars.$item--key-focus--border-color) solid props.get(vars.$item--key-focus--border-width);
95 box-shadow: 0 0 0 calc(fn.dim(--item --key-focus --border) + fn.dim(--item --key-focus --outline)) fn.color(--item --key-focus --outline); 58 box-shadow:
96 } 59 0
97 } 60 0
61 0
62 calc(props.get(vars.$item--key-focus--border-width) + props.get(vars.$item--key-focus--outline-width))
63 props.get(vars.$item--key-focus--outline-color);
64 }
65 }
98 66
99 @include iro.bem-next-elem('header') { 67 @include bem.next-elem('header') {
100 margin-block-start: calc(fn.dim(--separator) + fn.dim(--spacing)); 68 margin-block-start: calc(props.get(vars.$separator) + props.get(vars.$spacing));
101 } 69 }
102 } 70 }
103 71
104 @include iro.bem-elem('header') { 72 @include bem.elem('header') {
105 &:link, 73 &:link,
106 &:visited, 74 &:visited,
107 &:enabled { 75 &:enabled {
108 color: fn.color(--header --label); 76 color: props.get(vars.$header--label-color);
109 } 77 }
110 } 78 }
111 79
112 @include iro.bem-elem('separator') { 80 @include bem.elem('separator') {
113 block-size: fn.dim(--separator); 81 block-size: props.get(vars.$separator);
114 } 82 }
115 83
116 @include iro.bem-elem('icon-slot') { 84 @include bem.elem('icon-slot') {
117 display: flex; 85 display: flex;
118 justify-content: center; 86 justify-content: center;
119 inline-size: fn.foreign-dim(--icon, --size); 87 inline-size: props.get(icon.$size);
120 } 88 }
121 } 89 }
122} 90}
diff --git a/src/objects/_side-nav.vars.scss b/src/objects/_side-nav.vars.scss
new file mode 100644
index 0000000..711b2a7
--- /dev/null
+++ b/src/objects/_side-nav.vars.scss
@@ -0,0 +1,28 @@
1@use 'sass:map';
2@use 'iro-sass/src/props';
3@use '../core.vars' as core;
4
5$spacing: props.def(--o-side-nav--spacing, props.get(core.$size--50)) !default;
6$header--font-size: props.def(--o-side-nav--header--font-size, props.get(core.$font-size--50)) !default;
7$separator: props.def(--o-side-nav--separator, props.get(core.$size--200)) !default;
8
9$item--pad-i: props.def(--o-side-nav--item--pad-i, props.get(core.$size--150)) !default;
10$item--pad-b: props.def(--o-side-nav--item--pad-b, props.get(core.$size--100)) !default;
11$item--rounding: props.def(--o-side-nav--item--rounding, props.get(core.$rounding--sm)) !default;
12
13$item--key-focus--border-width: props.def(--o-side-nav--item--key-focus--border-width, props.get(core.$key-focus--border-width)) !default;
14$item--key-focus--border-offset: props.def(--o-side-nav--item--key-focus--border-offset, props.get(core.$key-focus--border-offset)) !default;
15$item--key-focus--outline-width: props.def(--o-side-nav--item--key-focus--outline-width, props.get(core.$key-focus--outline-width)) !default;
16
17$header--label-color: props.def(--o-side-nav--header--label-color, props.get(core.$theme, --text-mute-more), 'color') !default;
18
19$item--hover--bg-color: props.def(--o-side-nav--item--hover--bg-color, props.get(core.$theme, --border-mute), 'color') !default;
20$item--hover--label-color: props.def(--o-side-nav--item--hover--label-color, props.get(core.$theme, --heading), 'color') !default;
21
22$item--active--bg-color: props.def(--o-side-nav--item--active--bg-color, props.get(core.$theme, --border), 'color') !default;
23$item--active--label-color: props.def(--o-side-nav--item--active--label-color, props.get(core.$theme, --heading), 'color') !default;
24
25$item--disabled--label-color: props.def(--o-side-nav--item--disabled--label-color, props.get(core.$theme, --text-disabled), 'color') !default;
26
27$item--key-focus--border-color: props.def(--o-side-nav--item--key-focus--border-color, props.get(core.$theme, --focus, --border), 'color') !default;
28$item--key-focus--outline-color: props.def(--o-side-nav--item--key-focus--outline-color, props.get(core.$theme, --focus, --outline), 'color') !default;
diff --git a/src/objects/_status-indicator.scss b/src/objects/_status-indicator.scss
index 416e65e..4e4aa42 100644
--- a/src/objects/_status-indicator.scss
+++ b/src/objects/_status-indicator.scss
@@ -1,39 +1,27 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:map';
2@use '../functions' as fn; 2@use 'sass:meta';
3@use 'sass:string';
4@use 'iro-sass/src/bem';
5@use 'iro-sass/src/props';
6@use '../props' as *;
3 7
4$themes: 'accent' 'positive' 'negative' 'warning' !default; 8@forward 'status-indicator.vars';
9@use 'status-indicator.vars' as vars;
5 10
6@include iro.props-namespace('status-indicator') { 11@mixin styles {
7 @include iro.props-store(( 12 @include materialize-at-root(meta.module-variables('vars'));
8 --dims: (
9 --size: fn.global-dim(--size --125),
10 ),
11 --colors: (
12 --default: fn.global-color(--border-strong),
13 --primary: fn.global-color(--text),
14 ),
15 ));
16 13
17 @each $theme in $themes { 14 @include bem.object('status-indicator') {
18 @include iro.props-store(( 15 display: inline-block;
19 --colors: ( 16 inline-size: props.get(vars.$size);
20 --#{$theme}: fn.global-color(--#{$theme} --700), 17 block-size: props.get(vars.$size);
21 ), 18 background-color: props.get(vars.$default);
22 )); 19 border-radius: 10em;
23 }
24 20
25 @include iro.bem-object(iro.props-namespace()) { 21 @each $theme in map.keys(props.get(vars.$themes)) {
26 display: inline-block; 22 @include bem.is(string.slice($theme, 3)) {
27 inline-size: fn.dim(--size); 23 background-color: props.get(vars.$themes, $theme);
28 block-size: fn.dim(--size); 24 }
29 border-radius: 10em; 25 }
30 background-color: fn.color(--default); 26 }
31 vertical-align: middle;
32
33 @each $theme in $themes {
34 @include iro.bem-is($theme) {
35 background-color: fn.color(--#{$theme});
36 }
37 }
38 }
39} 27}
diff --git a/src/objects/_status-indicator.vars.scss b/src/objects/_status-indicator.vars.scss
new file mode 100644
index 0000000..55b446a
--- /dev/null
+++ b/src/objects/_status-indicator.vars.scss
@@ -0,0 +1,26 @@
1@use 'sass:map';
2@use 'iro-sass/src/props';
3@use '../config';
4@use '../core.vars' as core;
5
6$size: props.def(--o-status-indicator--size, props.get(core.$size--125)) !default;
7
8$default: props.def(--o-status-indicator--default, props.get(core.$theme, --border-strong), 'color') !default;
9$primary: props.def(--o-status-indicator--primary, props.get(core.$theme, --text), 'color') !default;
10
11$themes-config: (
12 accent: --accent,
13 positive: --positive,
14 negative: --negative,
15 warning: --warning,
16) !default;
17
18$themes: props.def(--o-status-indicator, (), 'color');
19
20@each $theme, $key in $themes-config {
21 @if $theme != --base {
22 $themes: props.merge($themes, (
23 --#{$theme}: props.get(core.$theme, $key, --700),
24 ));
25 }
26}
diff --git a/src/objects/_switch.scss b/src/objects/_switch.scss
index e1f1132..48cec24 100644
--- a/src/objects/_switch.scss
+++ b/src/objects/_switch.scss
@@ -1,222 +1,188 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
5@use '../core.vars' as core;
3 6
4@include iro.props-namespace('switch') { 7@forward 'switch.vars';
5 @include iro.props-store(( 8@use 'switch.vars' as vars;
6 --dims: (
7 --width: fn.global-dim(--size --350),
8 --height: fn.global-dim(--size --200),
9 --label-gap: fn.global-dim(--size --125),
10 --border: fn.global-dim(--border --medium),
11 --pad-i: fn.global-dim(--size --65),
12 --pad-b: fn.global-dim(--size --65),
13 --rounding: fn.global-dim(--rounding),
14 --spacing-sibling: fn.global-dim(--size --300),
15 9
16 --key-focus: ( 10@mixin styles {
17 --border: fn.global-dim(--key-focus --border), 11 @include materialize-at-root(meta.module-variables('vars'));
18 --border-offset: fn.global-dim(--key-focus --border-offset),
19 --outline: fn.global-dim(--key-focus --outline),
20 ),
21 ),
22 --colors: (
23 --track-bg: fn.global-color(--border),
24 --handle-border: fn.global-color(--text-mute-more),
25 --handle-bg: fn.global-color(--base --50),
26
27 --hover: (
28 --label: fn.global-color(--heading),
29 --handle-border: fn.global-color(--text-mute),
30 ),
31 --accent: (
32 --handle-border: fn.global-color(--accent --900),
33
34 --hover: (
35 --handle-border: fn.global-color(--accent --1000),
36 ),
37 ),
38 --disabled: (
39 --label: fn.global-color(--text-disabled),
40 --track-bg: fn.global-color(--border),
41 --handle-border: fn.global-color(--border-strong),
42 --handle-bg: fn.global-color(--base --50),
43 ),
44 --key-focus: (
45 --label: fn.global-color(--focus --text),
46 --border: fn.global-color(--focus --border),
47 --outline: fn.global-color(--focus --outline),
48 ),
49 ),
50 ));
51 12
52 @include iro.bem-object(iro.props-namespace()) { 13 @include bem.object('switch') {
53 display: inline-block; 14 position: relative;
54 position: relative; 15 display: inline-block;
55 margin-inline: 16 padding-block: props.get(vars.$pad-b);
56 calc(-1 * fn.dim(--pad-i) - fn.dim(--key-focus --border-offset)) 17 padding-inline: props.get(vars.$pad-i);
57 calc(fn.dim(--spacing-sibling) - fn.dim(--pad-i) - fn.dim(--key-focus --border-offset)); 18 margin-inline:
58 padding-inline: fn.dim(--pad-i); 19 calc(-1 * props.get(vars.$pad-i) - props.get(vars.$key-focus--border-offset))
59 padding-block: fn.dim(--pad-b); 20 calc(props.get(vars.$spacing-sibling) - props.get(vars.$pad-i) - props.get(vars.$key-focus--border-offset));
60 21
61 @include iro.bem-elem('indicator') { 22 @include bem.elem('indicator') {
62 display: inline-block; 23 display: inline-block;
63 flex: 0 0 auto; 24 flex: 0 0 auto;
64 inline-size: fn.dim(--width); 25 inline-size: props.get(vars.$inline-size);
65 block-size: fn.dim(--height); 26 block-size: props.get(vars.$block-size);
66 margin-block-start: calc(.5em * fn.global-dim(--font --standard --line-height) - .5 * fn.dim(--height) - fn.dim(--key-focus --border-offset)); 27 margin-block-start: calc(.5em * props.get(core.$font--standard--line-height) - .5 * props.get(vars.$block-size) - props.get(vars.$key-focus--border-offset));
67 transition: background-color .2s ease; 28 vertical-align: top;
68 border: fn.dim(--key-focus --border-offset) solid transparent; 29 background-color: props.get(vars.$track-bg-color);
69 border-radius: 2em; 30 background-clip: padding-box;
70 background-color: fn.color(--track-bg); 31 border: props.get(vars.$key-focus--border-offset) solid transparent;
71 background-clip: padding-box; 32 border-radius: 2em;
72 vertical-align: top; 33 transition: background-color .2s ease;
73 34
74 &::after { 35 &::after {
75 content: ''; 36 display: block;
76 display: block; 37 inline-size: calc(props.get(vars.$block-size) - 2 * props.get(vars.$border-width));
77 inline-size: calc(fn.dim(--height) - 2 * fn.dim(--border)); 38 block-size: calc(props.get(vars.$block-size) - 2 * props.get(vars.$border-width));
78 block-size: calc(fn.dim(--height) - 2 * fn.dim(--border)); 39 content: '';
79 transition: transform .2s ease; 40 background-color: props.get(vars.$handle-bg-color);
80 border: fn.dim(--border) solid fn.color(--handle-border); 41 border: props.get(vars.$border-width) solid props.get(vars.$handle-border-color);
81 border-radius: fn.dim(--width); 42 border-radius: props.get(vars.$inline-size);
82 background-color: fn.color(--handle-bg); 43 transition: transform .2s ease;
83 } 44 }
84 } 45 }
85 46
86 @include iro.bem-elem('label') { 47 @include bem.elem('label') {
87 margin-inline-start: fn.dim(--label-gap); 48 margin-inline-start: props.get(vars.$label-gap);
88 } 49 }
89 50
90 @include iro.bem-elem('native') { 51 @include bem.elem('native') {
91 appearance: none; 52 position: absolute;
92 position: absolute; 53 inset-block-start: 0;
93 z-index: -1; 54 inset-inline-start: 0;
94 inset-block-start: 0; 55 z-index: -1;
95 inset-inline-start: 0; 56 inline-size: 100%;
96 inline-size: 100%; 57 block-size: 100%;
97 block-size: 100%; 58 padding: 0;
98 margin: 0; 59 margin: 0;
99 padding: 0; 60 overflow: hidden;
100 overflow: hidden; 61 appearance: none;
101 border-radius: fn.dim(--rounding); 62 border-radius: props.get(vars.$rounding);
102 63
103 &:hover, 64 &:hover,
104 &:focus-visible { 65 &:focus-visible {
105 @include iro.bem-sibling-elem('label') { 66 @include bem.sibling-elem('label') {
106 color: fn.color(--hover --label); 67 color: props.get(vars.$hover--label-color);
107 } 68 }
108 69
109 @include iro.bem-sibling-elem('indicator') { 70 @include bem.sibling-elem('indicator') {
110 &::after { 71 &::after {
111 border-color: fn.color(--hover --handle-border); 72 border-color: props.get(vars.$hover--handle-border-color);
112 } 73 }
113 } 74 }
114 } 75 }
115 76
116 &:checked { 77 &:checked {
117 @include iro.bem-sibling-elem('indicator') { 78 @include bem.sibling-elem('indicator') {
118 background-color: fn.color(--handle-border); 79 background-color: props.get(vars.$handle-border-color);
119 80
120 &::after { 81 &::after {
121 transform: translate(calc(fn.dim(--width) - fn.dim(--height) + .5px), 0); 82 border-color: props.get(vars.$handle-border-color);
122 border-color: fn.color(--handle-border); 83 transform: translate(calc(props.get(vars.$inline-size) - props.get(vars.$block-size) + .5px), 0);
123 } 84 }
124 } 85 }
125 86
126 &:hover, 87 &:hover,
127 &:focus-visible { 88 &:focus-visible {
128 @include iro.bem-sibling-elem('indicator') { 89 @include bem.sibling-elem('indicator') {
129 background-color: fn.color(--hover --handle-border); 90 background-color: props.get(vars.$hover--handle-border-color);
130 91
131 &::after { 92 &::after {
132 border-color: fn.color(--hover --handle-border); 93 border-color: props.get(vars.$hover--handle-border-color);
133 } 94 }
134 } 95 }
135 } 96 }
136 } 97 }
137 98
138 &:disabled { 99 &:disabled {
139 @include iro.bem-sibling-elem('label') { 100 @include bem.sibling-elem('label') {
140 color: fn.color(--disabled --label); 101 color: props.get(vars.$disabled--label-color);
141 } 102 }
142 103
143 @include iro.bem-sibling-elem('indicator') { 104 @include bem.sibling-elem('indicator') {
144 background-color: fn.color(--disabled --track-bg); 105 background-color: props.get(vars.$disabled--track-bg-color);
145 106
146 &::after { 107 &::after {
147 border-color: fn.color(--disabled --handle-border); 108 background-color: props.get(vars.$disabled--handle-bg-color);
148 background-color: fn.color(--disabled --handle-bg); 109 border-color: props.get(vars.$disabled--handle-border-color);
149 } 110 }
150 } 111 }
151 112
152 &:checked { 113 &:checked {
153 @include iro.bem-sibling-elem('indicator') { 114 @include bem.sibling-elem('indicator') {
154 background-color: fn.color(--disabled --handle-border); 115 background-color: props.get(vars.$disabled--handle-border-color);
155 116
156 &::after { 117 &::after {
157 border-color: fn.color(--disabled --handle-border); 118 border-color: props.get(vars.$disabled--handle-border-color);
158 } 119 }
159 } 120 }
160 } 121 }
161 } 122 }
162 123
163 &:focus-visible { 124 &:focus-visible {
164 @include iro.bem-sibling-elem('label') { 125 @include bem.sibling-elem('label') {
165 color: fn.color(--key-focus --label); 126 color: props.get(vars.$key-focus--label-color);
166 } 127 }
167 128
168 @include iro.bem-sibling-elem('indicator') { 129 @include bem.sibling-elem('indicator') {
169 outline: fn.color(--key-focus --border) solid fn.dim(--key-focus --border); 130 outline: props.get(vars.$key-focus--border-color) solid props.get(vars.$key-focus--border-width);
170 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(--key-focus --outline); 131 box-shadow:
171 } 132 0
172 } 133 0
173 } 134 0
135 calc(props.get(vars.$key-focus--border-width) + props.get(vars.$key-focus--outline-width))
136 props.get(vars.$key-focus--outline-color);
137 }
138 }
139 }
174 140
175 @include iro.bem-modifier('standalone') { 141 @include bem.modifier('standalone') {
176 @include iro.bem-elem('indicator') { 142 @include bem.elem('indicator') {
177 margin-block-start: 0; 143 margin-block-start: 0;
178 } 144 }
179 } 145 }
180 146
181 @include iro.bem-modifier('accent') { 147 @include bem.modifier('accent') {
182 @include iro.bem-elem('native') { 148 @include bem.elem('native') {
183 &:checked { 149 &:checked {
184 @include iro.bem-sibling-elem('indicator') { 150 @include bem.sibling-elem('indicator') {
185 background-color: fn.color(--accent --handle-border); 151 background-color: props.get(vars.$accent--handle-border-color);
186 152
187 &::after { 153 &::after {
188 border-color: fn.color(--accent --handle-border); 154 border-color: props.get(vars.$accent--handle-border-color);
189 } 155 }
190 } 156 }
191 157
192 &:hover, 158 &:hover,
193 &:focus-visible { 159 &:focus-visible {
194 @include iro.bem-sibling-elem('indicator') { 160 @include bem.sibling-elem('indicator') {
195 background-color: fn.color(--accent --hover --handle-border); 161 background-color: props.get(vars.$accent--hover--handle-border-color);
196 162
197 &::after { 163 &::after {
198 border-color: fn.color(--accent --hover --handle-border); 164 border-color: props.get(vars.$accent--hover--handle-border-color);
199 } 165 }
200 } 166 }
201 } 167 }
202 } 168 }
203 169
204 &:disabled { 170 &:disabled {
205 @include iro.bem-sibling-elem('label') { 171 @include bem.sibling-elem('label') {
206 color: fn.color(--disabled --label); 172 color: props.get(vars.$disabled--label-color);
207 } 173 }
208 174
209 &:checked { 175 &:checked {
210 @include iro.bem-sibling-elem('indicator') { 176 @include bem.sibling-elem('indicator') {
211 background-color: fn.color(--disabled --handle-border); 177 background-color: props.get(vars.$disabled--handle-border-color);
212 178
213 &::after { 179 &::after {
214 border-color: fn.color(--disabled --handle-border); 180 border-color: props.get(vars.$disabled--handle-border-color);
215 } 181 }
216 } 182 }
217 } 183 }
218 } 184 }
219 } 185 }
220 } 186 }
221 } 187 }
222} 188}
diff --git a/src/objects/_switch.vars.scss b/src/objects/_switch.vars.scss
new file mode 100644
index 0000000..10489a5
--- /dev/null
+++ b/src/objects/_switch.vars.scss
@@ -0,0 +1,37 @@
1@use 'sass:map';
2@use 'iro-sass/src/props';
3@use '../core.vars' as core;
4
5$inline-size: props.def(--o-switch--inline-size, props.get(core.$size--350)) !default;
6$block-size: props.def(--o-switch--block-size, props.get(core.$size--200)) !default;
7$label-gap: props.def(--o-switch--label-gap, props.get(core.$size--125)) !default;
8$border-width: props.def(--o-switch--border-width, props.get(core.$border-width--medium)) !default;
9$pad-i: props.def(--o-switch--pad-i, props.get(core.$size--65)) !default;
10$pad-b: props.def(--o-switch--pad-b, props.get(core.$size--65)) !default;
11$rounding: props.def(--o-switch--rounding, props.get(core.$rounding--sm)) !default;
12$spacing-sibling: props.def(--o-switch--spacing-sibling, props.get(core.$size--300)) !default;
13
14$key-focus--border-width: props.def(--o-switch--key-focus--border-width, props.get(core.$key-focus--border-width)) !default;
15$key-focus--border-offset: props.def(--o-switch--key-focus--border-offset, props.get(core.$key-focus--border-offset)) !default;
16$key-focus--outline-width: props.def(--o-switch--key-focus--outline-width, props.get(core.$key-focus--outline-width)) !default;
17
18$track-bg-color: props.def(--o-switch--track-bg-color, props.get(core.$theme, --border), 'color') !default;
19$handle-border-color: props.def(--o-switch--handle-border-color, props.get(core.$theme, --text-mute-more), 'color') !default;
20$handle-bg-color: props.def(--o-switch--handle-bg-color, props.get(core.$theme, --base, --50), 'color') !default;
21
22$hover--label-color: props.def(--o-switch--hover--label-color, props.get(core.$theme, --heading), 'color') !default;
23$hover--handle-border-color: props.def(--o-switch--hover--handle-border-color, props.get(core.$theme, --text-mute), 'color') !default;
24
25$accent--handle-border-color: props.def(--o-switch--accent--handle-border-color, props.get(core.$theme, --accent, --900), 'color') !default;
26
27$accent--hover--handle-border-color: props.def(--o-switch--accent--hover--handle-border-color, props.get(core.$theme, --accent, --1000), 'color') !default;
28
29$disabled--label-color: props.def(--o-switch--disabled--label-color, props.get(core.$theme, --text-disabled), 'color') !default;
30$disabled--track-bg-color: props.def(--o-switch--disabled--track-bg-color, props.get(core.$theme, --border), 'color') !default;
31$disabled--handle-border-color: props.def(--o-switch--disabled--handle-border-color, props.get(core.$theme, --border-strong), 'color') !default;
32$disabled--handle-bg-color: props.def(--o-switch--disabled--handle-bg-color, props.get(core.$theme, --base, --50), 'color') !default;
33
34$key-focus--label-color: props.def(--o-switch--key-focus--label-color, props.get(core.$theme, --focus, --text), 'color') !default;
35$key-focus--border-color: props.def(--o-switch--key-focus--border-color, props.get(core.$theme, --focus, --border), 'color') !default;
36$key-focus--outline-color: props.def(--o-switch--key-focus--outline-color, props.get(core.$theme, --focus, --outline), 'color') !default;
37
diff --git a/src/objects/_tabbar.scss b/src/objects/_tabbar.scss
new file mode 100644
index 0000000..a9daaae
--- /dev/null
+++ b/src/objects/_tabbar.scss
@@ -0,0 +1,113 @@
1@use 'sass:map';
2@use 'sass:meta';
3@use 'sass:string';
4@use 'iro-sass/src/bem';
5@use 'iro-sass/src/props';
6@use '../props' as *;
7
8@forward 'tabbar.vars';
9@use 'tabbar.vars' as vars;
10
11@mixin styles {
12 @include materialize-at-root(meta.module-variables('vars'));
13
14 @include bem.object('tabbar') {
15 min-inline-size: 0;
16 block-size: props.get(vars.$block-size);
17 overflow: hidden;
18
19 &::after {
20 display: block;
21 block-size: props.get(vars.$indicator--width);
22 margin-block-start: calc(-1 * props.get(vars.$indicator--width));
23 content: '';
24 background-color: props.get(vars.$railing--bg-color);
25 }
26
27 @include bem.elem('tabs') {
28 display: flex;
29 block-size: 100%;
30 margin-inline: calc(-.5 * props.get(vars.$spacing));
31 overflow-inline: auto;
32 }
33
34 @include bem.modifier('quiet') {
35 box-shadow: none;
36 }
37
38 @include bem.modifier('adapt') {
39 block-size: 100%;
40 }
41
42 @include bem.elem('tab') {
43 position: relative;
44 display: flex;
45 align-items: center;
46 padding-inline: calc(.5 * props.get(vars.$spacing));
47 color: props.get(vars.$tab--text-color);
48 white-space: nowrap;
49
50 &::before {
51 position: absolute;
52 inset-block-start: 50%;
53 inset-inline: calc(-1 * props.get(vars.$tab--pad-i) + .5 * props.get(vars.$spacing));
54 z-index: -10;
55 block-size: 1.5em;
56 content: '';
57 border-radius: props.get(vars.$rounding);
58 transform: translateY(-50%);
59 }
60
61 &::after {
62 position: absolute;
63 inset-block-end: 0;
64 inset-inline: calc(.5 * props.get(vars.$spacing));
65 z-index: 10;
66 display: none;
67 block-size: props.get(vars.$indicator--width);
68 content: '';
69 background-color: props.get(vars.$tab--selected--text-color);
70 }
71
72 &:link,
73 &:visited {
74 &:hover,
75 &:active,
76 &:focus-visible {
77 color: props.get(vars.$tab--selected--text-color);
78 }
79
80 &:focus-visible {
81 &::before {
82 color: props.get(vars.$key-focus--text-color);
83 text-decoration: none;
84 outline: props.get(vars.$key-focus--border-color) solid props.get(vars.$key-focus--border-width);
85 box-shadow: 0 0 0
86 calc(props.get(vars.$key-focus--border-width) + props.get(vars.$key-focus--outline-width))
87 props.get(vars.$key-focus--outline-color);
88 }
89 }
90 }
91
92 @include bem.is('selected') {
93 color: props.get(vars.$tab--selected--text-color);
94
95 &::after {
96 display: block;
97 }
98 }
99 }
100
101 @include bem.modifier('accent') {
102 @include bem.elem('tab') {
103 &::after {
104 background-color: props.get(vars.$tab--accent--text-color);
105 }
106
107 @include bem.is('selected') {
108 color: props.get(vars.$tab--accent--text-color);
109 }
110 }
111 }
112 }
113}
diff --git a/src/objects/_tabbar.vars.scss b/src/objects/_tabbar.vars.scss
new file mode 100644
index 0000000..4095629
--- /dev/null
+++ b/src/objects/_tabbar.vars.scss
@@ -0,0 +1,25 @@
1@use 'sass:map';
2@use 'sass:string';
3@use 'iro-sass/src/props';
4@use '../core.vars' as core;
5
6$block-size: props.def(--o-tabbar--block-size, props.get(core.$size--700)) !default;
7$rounding: props.def(--o-tabbar--rounding, props.get(core.$rounding--sm)) !default;
8$spacing: props.def(--o-tabbar--spacing, props.get(core.$size--400)) !default;
9$tab--pad-i: props.def(--o-tabbar--tab--pad-i, props.get(core.$size--50)) !default;
10
11$indicator--width: props.def(--o-tabbar--indicator--width, props.get(core.$border-width--medium)) !default;
12
13$key-focus--border-width: props.def(--o-tabbar--key-focus--border-width, props.get(core.$key-focus--border-width)) !default;
14$key-focus--border-offset: props.def(--o-tabbar--key-focus--border-offset, props.get(core.$key-focus--border-offset)) !default;
15$key-focus--outline-width: props.def(--o-tabbar--key-focus--outline-width, props.get(core.$key-focus--outline-width)) !default;
16
17$tab--text-color: props.def(--o-tabbar--tab--text-color, props.get(core.$theme, --text-mute), 'color') !default;
18$tab--selected--text-color: props.def(--o-tabbar--tab--selected--text-color, props.get(core.$theme, --heading), 'color') !default;
19$tab--accent--text-color: props.def(--o-tabbar--tab--accent--text-color, props.get(core.$theme, --accent, --1100), 'color') !default;
20
21$railing--bg-color: props.def(--o-tabbar--railing--bg-color, props.get(core.$theme, --border-mute), 'color') !default;
22
23$key-focus--text-color: props.def(--o-tabbar--key-focus--text-color, props.get(core.$theme, --focus, --text), 'color') !default;
24$key-focus--border-color: props.def(--o-tabbar--key-focus--border-color, props.get(core.$theme, --focus, --border), 'color') !default;
25$key-focus--outline-color: props.def(--o-tabbar--key-focus--outline-color, props.get(core.$theme, --focus, --outline), 'color') !default;
diff --git a/src/objects/_table.scss b/src/objects/_table.scss
index 2c9f65b..9e4891d 100644
--- a/src/objects/_table.scss
+++ b/src/objects/_table.scss
@@ -1,168 +1,147 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use '../mixins' as mx; 3@use 'iro-sass/src/props';
4@use '../props' as *;
4 5
5@include iro.props-namespace('table') { 6@forward 'table.vars';
6 @include iro.props-store(( 7@use 'table.vars' as vars;
7 --dims: (
8 --pad-i: fn.global-dim(--size --175),
9 --pad-b: fn.global-dim(--size --125),
10 --rounding: fn.global-dim(--rounding),
11 --border: fn.global-dim(--border --thin),
12 8
13 --sm: ( 9@mixin styles {
14 --pad-b: fn.global-dim(--size --75), 10 @include materialize-at-root(meta.module-variables('vars'));
15 )
16 ),
17 --colors: (
18 --border: fn.global-color(--border),
19 --heading: fn.global-color(--heading),
20 --hover: fn.global-color(--border-mute),
21 --active: fn.global-color(--border),
22 --box: (
23 --bg: fn.global-color(--base --50),
24 --hover: fn.global-color(--bg-base),
25 --active: fn.global-color(--border-mute),
26 )
27 )
28 ));
29 11
30 @include iro.bem-object(iro.props-namespace()) { 12 @include bem.object('table') {
31 border-spacing: 0; 13 border-spacing: 0;
32 border-collapse: separate; 14 border-collapse: separate;
33 15
34 @include iro.bem-modifier('fixed') { 16 @include bem.modifier('fixed') {
35 table-layout: fixed; 17 table-layout: fixed;
36 } 18 }
37 19
38 @include iro.bem-elem('head-cell') { 20 @include bem.elem('head-cell') {
39 @include mx.set-font(--standard, ( 21 padding-block: props.get(vars.$pad-b);
40 --line-height: null, 22 padding-inline: props.get(vars.$pad-i);
41 --size: fn.global-dim(--font-size --50), 23 font-family: props.get(vars.$heading--font-family);
42 --weight: bold, 24 font-size: props.get(vars.$heading--font-size);
43 --transform: uppercase, 25 font-weight: props.get(vars.$heading--font-weight);
44 --spacing: .5px 26 color: props.get(vars.$heading-color);
45 )); 27 text-align: start;
28 text-transform: props.get(vars.$heading--text-transform);
29 letter-spacing: props.get(vars.$heading--letter-spacing);
30 }
46 31
47 padding-inline: fn.dim(--pad-i); 32 @include bem.elem('cell') {
48 padding-block: fn.dim(--pad-b); 33 padding-block: props.get(vars.$pad-b);
49 color: fn.color(--heading); 34 padding-inline: props.get(vars.$pad-i);
50 text-align: start; 35 border-color: props.get(vars.$border-color);
51 } 36 border-style: solid;
37 border-width: 0;
38 border-block-start-width: props.get(vars.$border-width);
52 39
53 @include iro.bem-elem('cell') { 40 @include bem.modifier('divider') {
54 padding-inline: fn.dim(--pad-i); 41 border-inline-end-width: props.get(vars.$border-width);
55 padding-block: fn.dim(--pad-b); 42 }
56 border-width: 0; 43 }
57 border-block-start-width: fn.dim(--border);
58 border-style: solid;
59 border-color: fn.color(--border);
60 44
61 @include iro.bem-modifier('divider') { 45 @include bem.elem('row') {
62 border-inline-end-width: fn.dim(--border); 46 &:last-child {
63 } 47 @include bem.elem('cell') {
64 } 48 border-block-end-width: props.get(vars.$border-width);
49 }
50 }
51 }
65 52
66 @include iro.bem-elem('row') { 53 @include bem.modifier('flush') {
67 &:last-child { 54 @include bem.elem('head-cell', 'cell') {
68 @include iro.bem-elem('cell') { 55 &:first-child {
69 border-block-end-width: fn.dim(--border); 56 padding-inline-start: 0;
70 } 57 }
71 }
72 }
73 58
74 @include iro.bem-modifier('flush') { 59 &:last-child {
75 @include iro.bem-elem('head-cell', 'cell') { 60 padding-inline-end: 0;
76 &:first-child { 61 }
77 padding-inline-start: 0; 62 }
78 } 63 }
79 64
80 &:last-child { 65 @include bem.modifier('box') {
81 padding-inline-end: 0; 66 @include bem.elem('cell') {
82 } 67 background-color: props.get(vars.$box--bg-color);
83 }
84 }
85
86 @include iro.bem-modifier('box') {
87 @include iro.bem-elem('cell') {
88 background-color: fn.color(--box --bg);
89 68
90 &:first-child { 69 &:first-child {
91 border-inline-start-width: fn.dim(--border); 70 border-inline-start-width: props.get(vars.$border-width);
92 } 71 }
93 72
94 &:last-child { 73 &:last-child {
95 border-inline-end-width: fn.dim(--border); 74 border-inline-end-width: props.get(vars.$border-width);
96 } 75 }
97 } 76 }
98 77
99 @include iro.bem-elem('row') { 78 @include bem.elem('row') {
100 &:first-child { 79 &:first-child {
101 @include iro.bem-elem('cell') { 80 @include bem.elem('cell') {
102 &:first-child { 81 &:first-child {
103 border-start-start-radius: fn.dim(--rounding); 82 border-start-start-radius: props.get(vars.$rounding);
104 } 83 }
105 84
106 &:last-child { 85 &:last-child {
107 border-start-end-radius: fn.dim(--rounding); 86 border-start-end-radius: props.get(vars.$rounding);
108 } 87 }
109 } 88 }
110 } 89 }
111 90
112 &:last-child { 91 &:last-child {
113 @include iro.bem-elem('cell') { 92 @include bem.elem('cell') {
114 &:first-child { 93 &:first-child {
115 border-end-start-radius: fn.dim(--rounding); 94 border-end-start-radius: props.get(vars.$rounding);
116 } 95 }
117 96
118 &:last-child { 97 &:last-child {
119 border-end-end-radius: fn.dim(--rounding); 98 border-end-end-radius: props.get(vars.$rounding);
120 } 99 }
121 } 100 }
122 } 101 }
123 } 102 }
124 } 103 }
125 104
126 @include iro.bem-modifier('interactive') { 105 @include bem.modifier('interactive') {
127 @include iro.bem-elem('row') { 106 @include bem.elem('row') {
128 @include iro.bem-elem('cell') { 107 @include bem.elem('cell') {
129 cursor: pointer; 108 cursor: pointer;
130 } 109 }
131 110
132 &:hover { 111 &:hover {
133 @include iro.bem-elem('cell') { 112 @include bem.elem('cell') {
134 background-color: fn.color(--hover); 113 background-color: props.get(vars.$hover--bg-color);
135 } 114 }
136 } 115 }
137 116
138 &:active { 117 &:active {
139 @include iro.bem-elem('cell') { 118 @include bem.elem('cell') {
140 background-color: fn.color(--active); 119 background-color: props.get(vars.$active--bg-color);
141 } 120 }
142 } 121 }
143 } 122 }
144 123
145 @include iro.bem-modifier('box') { 124 @include bem.modifier('box') {
146 @include iro.bem-elem('row') { 125 @include bem.elem('row') {
147 &:hover { 126 &:hover {
148 @include iro.bem-elem('cell') { 127 @include bem.elem('cell') {
149 background-color: fn.color(--box --hover); 128 background-color: props.get(vars.$box--hover--bg-color);
150 } 129 }
151 } 130 }
152 131
153 &:active { 132 &:active {
154 @include iro.bem-elem('cell') { 133 @include bem.elem('cell') {
155 background-color: fn.color(--box --active); 134 background-color: props.get(vars.$box--active--bg-color);
156 } 135 }
157 } 136 }
158 } 137 }
159 } 138 }
160 } 139 }
161 140
162 @include iro.bem-modifier('sm') { 141 @include bem.modifier('sm') {
163 @include iro.bem-elem('head-cell', 'cell') { 142 @include bem.elem('head-cell', 'cell') {
164 padding-block: fn.dim(--sm --pad-b); 143 padding-block: props.get(vars.$pad-b--sm);
165 } 144 }
166 } 145 }
167 } 146 }
168} 147}
diff --git a/src/objects/_table.vars.scss b/src/objects/_table.vars.scss
new file mode 100644
index 0000000..b8d8093
--- /dev/null
+++ b/src/objects/_table.vars.scss
@@ -0,0 +1,25 @@
1@use 'sass:map';
2@use 'iro-sass/src/props';
3@use '../core.vars' as core;
4
5$pad-i: props.def(--o-table--pad-i, props.get(core.$size--175)) !default;
6$pad-b: props.def(--o-table--pad-b, props.get(core.$size--125)) !default;
7$rounding: props.def(--o-table--rounding, props.get(core.$rounding--sm)) !default;
8$border-width: props.def(--o-table--border-width, props.get(core.$border-width--thin)) !default;
9
10$heading--font-family: props.def(--o-table--heading--font-family, props.get(core.$font--standard--family)) !default;
11$heading--font-size: props.def(--o-table--heading--font-size, props.get(core.$font-size--50)) !default;
12$heading--font-weight: props.def(--o-table--heading--font-weight, bold) !default;
13$heading--text-transform: props.def(--o-table--heading--text-transform, uppercase) !default;
14$heading--letter-spacing: props.def(--o-table--heading--letter-spacing, .5px) !default;
15
16$pad-b--sm: props.def(--o-table--sm--pad-b, props.get(core.$size--75)) !default;
17
18$border-color: props.def(--o-table--border-color, props.get(core.$theme, --border), 'color') !default;
19$heading-color: props.def(--o-table--heading-color, props.get(core.$theme, --heading), 'color') !default;
20$hover--bg-color: props.def(--o-table--hover--bg-color, props.get(core.$theme, --border-mute), 'color') !default;
21$active--bg-color: props.def(--o-table--active--bg-color, props.get(core.$theme, --border), 'color') !default;
22
23$box--bg-color: props.def(--o-table--box--bg-color, props.get(core.$theme, --base, --50), 'color') !default;
24$box--hover--bg-color: props.def(--o-table--box--hover--bg-color, props.get(core.$theme, --bg-base), 'color') !default;
25$box--active--bg-color: props.def(--o-table--box--active--bg-color, props.get(core.$theme, --border-mute), 'color') !default;
diff --git a/src/objects/_text-field.scss b/src/objects/_text-field.scss
index 6611ea6..b89e148 100644
--- a/src/objects/_text-field.scss
+++ b/src/objects/_text-field.scss
@@ -1,213 +1,187 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
3 5
4@mixin invalid { 6@forward 'text-field.vars';
5 $focus-border-offset: calc(fn.dim(--border) - fn.dim(--focus --border)); 7@use 'text-field.vars' as vars;
8
9@mixin -invalid {
10 $focus-border-offset: calc(props.get(vars.$border-width) - props.get(vars.$focus--border-width));
6 11
7 @include iro.bem-sibling-elem('bg') { 12 @include bem.sibling-elem('bg') {
8 inset-block: $focus-border-offset; 13 inset-block: $focus-border-offset;
9 inset-inline: $focus-border-offset; 14 inset-inline: $focus-border-offset;
10 border: fn.dim(--focus --border) solid fn.color(--error --border); 15 border: props.get(vars.$focus--border-width) solid props.get(vars.$error--border-color);
11 border-radius: calc(fn.dim(--rounding) - $focus-border-offset); 16 border-radius: calc(props.get(vars.$rounding) - $focus-border-offset);
12 } 17 }
13 18
14 &:hover { 19 &:hover {
15 @include iro.bem-sibling-elem('bg') { 20 @include bem.sibling-elem('bg') {
16 border-color: fn.color(--error --hover --border); 21 border-color: props.get(vars.$error--hover--border-color);
17 } 22 }
18 } 23 }
19 24
20 &:focus { 25 &:focus {
21 @include iro.bem-sibling-elem('bg') { 26 @include bem.sibling-elem('bg') {
22 border-color: fn.color(--error --focus --border); 27 border-color: props.get(vars.$error--focus--border-color);
23 } 28 }
24 } 29 }
25} 30}
26 31
27@mixin keyboard-focus { 32@mixin -keyboard-focus {
28 @include iro.bem-sibling-elem('bg') { 33 @include bem.sibling-elem('bg') {
29 border-color: fn.color(--key-focus --border); 34 outline: props.get(vars.$key-focus--outline-color) solid props.get(vars.$key-focus--border-width);
30 outline: fn.color(--key-focus --outline) solid fn.dim(--key-focus --border); 35 border-color: props.get(vars.$key-focus--border-color);
31 //outline-offset: fn.dim(--focus --border); 36 //outline-offset: props.get(vars.$focus --border);
32 } 37 }
33} 38}
34 39
35@include iro.props-namespace('text-field') { 40@mixin styles {
36 @include iro.props-store(( 41 @include materialize-at-root(meta.module-variables('vars'));
37 --dims: (
38 --line-height: 1.4,
39 --pad-i: fn.global-dim(--size --125),
40 --pad-b: fn.global-dim(--size --125),
41 --border: fn.global-dim(--border --thin),
42 --rounding: fn.global-dim(--rounding),
43 42
44 --extended: ( 43 @include bem.object('text-field') {
45 --pad: fn.global-dim(--size --50), 44 $focus-border-offset: calc(props.get(vars.$border-width) - props.get(vars.$focus--border-width));
46 ), 45
46 position: relative;
47 min-inline-size: 0;
48 background-color: props.get(vars.$bg-color);
49 border-radius: props.get(vars.$rounding);
47 50
48 --focus: ( 51 @include bem.elem('bg') {
49 --border: fn.global-dim(--border --medium), 52 position: absolute;
50 ), 53 inset-block: 0;
51 54 inset-inline: 0;
52 --key-focus: ( 55 display: block;
53 --border: fn.global-dim(--key-focus --outline), 56 pointer-events: none;
54 ), 57 border: props.get(vars.$border-width) solid props.get(vars.$border-color);
55 ), 58 border-radius: props.get(vars.$rounding);
56 --colors: ( 59 }
57 --bg: fn.global-color(--base --50),
58 --placeholder: fn.global-color(--text-mute-more),
59 --text: fn.global-color(--text),
60 --border: fn.global-color(--border-strong),
61
62 --hover: (
63 --border: fn.global-color(--text-mute-more),
64 ),
65 --focus: (
66 --border: fn.global-color(--focus --border),
67 ),
68 --key-focus: (
69 --border: fn.global-color(--focus --border),
70 --outline: fn.global-color(--focus --outline),
71 ),
72 --error: (
73 --border: fn.global-color(--negative --700),
74
75 --hover: (
76 --border: fn.global-color(--negative --900),
77 ),
78 --focus: (
79 --border: fn.global-color(--negative --900),
80 ),
81 ),
82 --disabled: (
83 --bg: fn.global-color(--border-mute),
84 --placeholder: fn.global-color(--text-disabled),
85 --text: fn.global-color(--text-disabled),
86 --border: fn.global-color(--border-mute),
87 ),
88 ),
89 ));
90 60
91 @include iro.bem-object(iro.props-namespace()) { 61 @include bem.elem('native') {
92 $focus-border-offset: calc(fn.dim(--border) - fn.dim(--focus --border)); 62 box-sizing: border-box;
93 63 inline-size: 100%;
94 position: relative; 64 padding-block: calc(props.get(vars.$pad-b) - .5em * (props.get(vars.$line-height) - 1));
95 min-inline-size: 0; 65 padding-inline: props.get(vars.$pad-i);
96 border-radius: fn.dim(--rounding); 66 font: inherit;
97 background-color: fn.color(--bg); 67 line-height: props.get(vars.$line-height);
68 color: props.get(vars.$text-color);
69 appearance: none;
70 resize: none;
71 background-color: transparent;
72 border: 1px solid transparent;
73
74 &::placeholder {
75 font-style: italic;
76 color: props.get(vars.$placeholder-color);
77 opacity: 1;
78 }
79
80 &:hover {
81 @include bem.sibling-elem('bg') {
82 border-color: props.get(vars.$hover--border-color);
83 }
84 }
98 85
99 @include iro.bem-elem('bg') { 86 &:focus {
100 display: block; 87 outline: 0;
101 position: absolute;
102 inset-block: 0;
103 inset-inline: 0;
104 border: fn.dim(--border) solid fn.color(--border);
105 border-radius: fn.dim(--rounding);
106 pointer-events: none;
107 }
108 88
109 @include iro.bem-elem('native') { 89 @include bem.sibling-elem('bg') {
110 box-sizing: border-box; 90 inset-block: $focus-border-offset;
111 inline-size: 100%; 91 inset-inline: $focus-border-offset;
112 padding-block: calc(fn.dim(--pad-b) - .5em * (fn.dim(--line-height) - 1)); 92 border: props.get(vars.$focus--border-width) solid props.get(vars.$focus--border-color);
113 padding-inline: fn.dim(--pad-i); 93 border-radius: calc(props.get(vars.$rounding) - $focus-border-offset);
114 border: 1px solid transparent; 94 }
115 background-color: transparent; 95 }
116 color: fn.color(--text);
117 font: inherit;
118 line-height: fn.dim(--line-height);
119 resize: none;
120 appearance: none;
121 96
122 &::placeholder { 97 &:invalid {
123 opacity: 1; 98 @include -invalid;
124 color: fn.color(--placeholder); 99 }
125 font-style: italic;
126 }
127 100
128 &:hover { 101 &:focus-visible,
129 @include iro.bem-sibling-elem('bg') { 102 &:invalid:focus-visible {
130 border-color: fn.color(--hover --border); 103 @include -keyboard-focus;
131 } 104 }
132 } 105 }
133 106
134 &:focus { 107 @include bem.modifier('extended') {
135 outline: 0; 108 padding: props.get(vars.$extended--pad);
136 109
137 @include iro.bem-sibling-elem('bg') { 110 @include bem.multi('&', 'elem' 'bg') {
138 inset-block: $focus-border-offset; 111 border-radius: calc(props.get(vars.$rounding) + props.get(vars.$extended--pad));
139 inset-inline: $focus-border-offset; 112 }
140 border: fn.dim(--focus --border) solid fn.color(--focus --border);
141 border-radius: calc(fn.dim(--rounding) - $focus-border-offset);
142 }
143 }
144 113
145 &:invalid { 114 @include bem.elem('native') {
146 @include invalid; 115 &:focus {
147 } 116 @include bem.sibling-elem('bg') {
117 border-radius: calc(props.get(vars.$rounding) + props.get(vars.$extended--pad) - $focus-border-offset);
118 }
119 }
120 }
121 }
148 122
149 &:focus-visible, 123 @include bem.modifier('pill') {
150 &:invalid:focus-visible { 124 @include bem.multi('&', 'elem' 'bg') {
151 @include keyboard-focus; 125 border-radius: 100em;
152 } 126 }
153 }
154 127
155 @include iro.bem-modifier('extended') { 128 @include bem.elem('native') {
156 padding: fn.dim(--extended --pad); 129 padding-inline: props.get(vars.$pad-i-pill);
157 130
158 @include iro.bem-multi('&', 'elem' 'bg') { 131 &:focus {
159 border-radius: calc(fn.dim(--rounding) + fn.dim(--extended --pad)); 132 @include bem.sibling-elem('bg') {
160 } 133 border-radius: 100em;
134 }
135 }
136 }
161 137
162 @include iro.bem-elem('native') { 138 @include bem.modifier('extended') {
163 &:focus { 139 @include bem.elem('native') {
164 @include iro.bem-sibling-elem('bg') { 140 padding-inline: props.get(vars.$pad-i);
165 border-radius: calc(fn.dim(--rounding) + fn.dim(--extended --pad) - $focus-border-offset); 141 }
166 } 142 }
167 } 143 }
168 }
169 }
170 144
171 @include iro.bem-is('invalid') { 145 @include bem.is('invalid') {
172 @include iro.bem-elem('native') { 146 @include bem.elem('native') {
173 @include invalid; 147 @include -invalid;
174 148
175 &:focus-visible { 149 &:focus-visible {
176 @include keyboard-focus; 150 @include -keyboard-focus;
177 } 151 }
178 } 152 }
179 } 153 }
180 154
181 @include iro.bem-is('disabled') { 155 @include bem.is('disabled') {
182 background-color: fn.color(--disabled --bg); 156 background-color: props.get(vars.$disabled--bg-color);
183 157
184 @include iro.bem-elem('native') { 158 @include bem.elem('native') {
185 color: fn.color(--disabled --text); 159 color: props.get(vars.$disabled--text-color);
186 160
187 &::placeholder { 161 &::placeholder {
188 color: fn.color(--disabled --placeholder); 162 color: props.get(vars.$disabled--placeholder-color);
189 } 163 }
190 } 164 }
191 165
192 @include iro.bem-elem('bg') { 166 @include bem.elem('bg') {
193 border-color: fn.color(--disabled --border); 167 border-color: props.get(vars.$disabled--border-color);
194 } 168 }
195 169
196 @include iro.bem-is('invalid') { 170 @include bem.is('invalid') {
197 @include iro.bem-elem('native') { 171 @include bem.elem('native') {
198 @include iro.bem-sibling-elem('bg') { 172 @include bem.sibling-elem('bg') {
199 border-color: fn.color(--disabled --border); 173 border-color: props.get(vars.$disabled--border-color);
200 } 174 }
201 } 175 }
202 } 176 }
203 177
204 @include iro.bem-elem('native') { 178 @include bem.elem('native') {
205 &:invalid { 179 &:invalid {
206 @include iro.bem-sibling-elem('bg') { 180 @include bem.sibling-elem('bg') {
207 border-color: fn.color(--disabled --border); 181 border-color: props.get(vars.$disabled--border-color);
208 } 182 }
209 } 183 }
210 } 184 }
211 } 185 }
212 } 186 }
213} 187}
diff --git a/src/objects/_text-field.vars.scss b/src/objects/_text-field.vars.scss
new file mode 100644
index 0000000..51099d8
--- /dev/null
+++ b/src/objects/_text-field.vars.scss
@@ -0,0 +1,39 @@
1@use 'sass:map';
2@use 'iro-sass/src/props';
3@use '../core.vars' as core;
4
5$line-height: props.def(--o-text-field--line-height, 1.4) !default;
6$pad-i: props.def(--o-text-field--pad-i, props.get(core.$size--125)) !default;
7$pad-i-pill: props.def(--o-text-field--pad-i-pill, props.get(core.$size--175)) !default;
8$pad-b: props.def(--o-text-field--pad-b, props.get(core.$size--125)) !default;
9$border-width: props.def(--o-text-field--border-width, props.get(core.$border-width--thin)) !default;
10$rounding: props.def(--o-text-field--rounding, props.get(core.$rounding--sm)) !default;
11
12$extended--pad: props.def(--o-text-field--extended--pad, props.get(core.$size--50)) !default;
13
14$focus--border-width: props.def(--o-text-field--focus--border-width, props.get(core.$border-width--medium)) !default;
15
16$key-focus--border-width: props.def(--o-text-field--key-focus--border-width, props.get(core.$key-focus--outline-width)) !default;
17
18$bg-color: props.def(--o-text-field--bg-color, props.get(core.$theme, --base, --50), 'color') !default;
19$placeholder-color: props.def(--o-text-field--placeholder-color, props.get(core.$theme, --text-mute-more), 'color') !default;
20$text-color: props.def(--o-text-field--text-color, props.get(core.$theme, --text), 'color') !default;
21$border-color: props.def(--o-text-field--border-color, props.get(core.$theme, --border-strong), 'color') !default;
22
23$hover--border-color: props.def(--o-text-field--hover--border-color, props.get(core.$theme, --text-mute-more), 'color') !default;
24
25$focus--border-color: props.def(--o-text-field--focus--border-color, props.get(core.$theme, --focus, --border), 'color') !default;
26
27$key-focus--border-color: props.def(--o-text-field--key-focus--border-color, props.get(core.$theme, --focus, --border), 'color') !default;
28$key-focus--outline-color: props.def(--o-text-field--key-focus--outline-color, props.get(core.$theme, --focus, --outline), 'color') !default;
29
30$error--border-color: props.def(--o-text-field--error--border-color, props.get(core.$theme, --negative, --700), 'color') !default;
31
32$error--hover--border-color: props.def(--o-text-field--error--hover--border-color, props.get(core.$theme, --negative, --900), 'color') !default;
33
34$error--focus--border-color: props.def(--o-text-field--error--focus--border-color, props.get(core.$theme, --negative, --900), 'color') !default;
35
36$disabled--bg-color: props.def(--o-text-field--disabled--bg-color, props.get(core.$theme, --border-mute), 'color') !default;
37$disabled--placeholder-color: props.def(--o-text-field--disabled--placeholder-color, props.get(core.$theme, --text-disabled), 'color') !default;
38$disabled--text-color: props.def(--o-text-field--disabled--text-color, props.get(core.$theme, --text-disabled), 'color') !default;
39$disabled--border-color: props.def(--o-text-field--disabled--border-color, props.get(core.$theme, --border-mute), 'color') !default;
diff --git a/src/objects/_thumbnail.scss b/src/objects/_thumbnail.scss
new file mode 100644
index 0000000..60a98af
--- /dev/null
+++ b/src/objects/_thumbnail.scss
@@ -0,0 +1,104 @@
1@use 'sass:map';
2@use 'sass:meta';
3@use 'sass:string';
4@use 'iro-sass/src/bem';
5@use 'iro-sass/src/props';
6@use '../props' as *;
7
8@forward 'thumbnail.vars';
9@use 'thumbnail.vars' as vars;
10
11@mixin styles {
12 @include materialize-at-root(meta.module-variables('vars'));
13
14 @include bem.object('thumbnail') {
15 position: relative;
16 display: block;
17 flex: 0 0 auto;
18 inline-size: props.get(vars.$size);
19 block-size: props.get(vars.$size);
20 overflow: hidden;
21 outline: props.get(vars.$border-color) solid props.get(vars.$border-width);
22 outline-offset: calc(-1 * props.get(vars.$border-width));
23 border-radius: props.get(vars.$rounding);
24 opacity: .75;
25
26 &:hover,
27 &:active,
28 &:focus-visible {
29 outline-color: props.get(vars.$hover--border-color);
30 opacity: 1;
31 }
32
33 @include bem.is('selected') {
34 $focus-border-offset: calc(-1 * props.get(vars.$selected--border-width));
35
36 margin: $focus-border-offset;
37 outline: none;
38 border: props.get(vars.$selected--border-width) solid props.get(vars.$selected--border-color);
39 border-radius: calc(props.get(vars.$rounding) - $focus-border-offset);
40 opacity: 1;
41 }
42
43 @include bem.elem('image') {
44 position: absolute;
45 inset-block-start: 0;
46 inset-inline-start: 0;
47 display: block;
48 inline-size: 100%;
49 block-size: 100%;
50 object-fit: cover;
51 object-position: center center;
52 }
53
54 @include bem.elem('icon') {
55 position: absolute;
56 inset-block-start: 50%;
57 inset-inline-start: 50%;
58 transform: translate(-50%, -50%);
59 }
60
61 &:focus-visible {
62 $focus-border-offset: calc(-1 * props.get(vars.$key-focus--border-offset));
63
64 margin: $focus-border-offset;
65 outline: props.get(vars.$key-focus--border-color) solid props.get(vars.$key-focus--border-width);
66 outline-offset: 0;
67 border: props.get(vars.$key-focus--border-offset) solid transparent;
68 border-radius: calc(props.get(vars.$rounding) - $focus-border-offset);
69 box-shadow:
70 0
71 0
72 0
73 calc(props.get(vars.$key-focus--outline-width) + props.get(vars.$key-focus--border-width))
74 props.get(vars.$key-focus--outline-color);
75 }
76
77 @each $theme in map.keys(props.get(vars.$static-themes)) {
78 @include bem.modifier(string.slice($theme, 3)) {
79 outline-color: props.get(vars.$static-themes, $theme, --border);
80
81 &:hover,
82 &:active,
83 &:focus-visible {
84 outline-color: props.get(vars.$static-themes, $theme, --hover, --border);
85 }
86
87 @include bem.is('selected') {
88 border-color: props.get(vars.$static-themes, $theme, --selected, --border);
89 }
90
91 &:focus-visible {
92 outline-color: props.get(vars.$static-themes, $theme, --key-focus, --border);
93 border-color: transparent;
94 box-shadow:
95 0
96 0
97 0
98 calc(props.get(vars.$key-focus--outline-width) + props.get(vars.$key-focus--border-width))
99 props.get(vars.$static-themes, $theme, --key-focus, --outline);
100 }
101 }
102 }
103 }
104}
diff --git a/src/objects/_thumbnail.vars.scss b/src/objects/_thumbnail.vars.scss
new file mode 100644
index 0000000..e49e52e
--- /dev/null
+++ b/src/objects/_thumbnail.vars.scss
@@ -0,0 +1,51 @@
1@use 'sass:map';
2@use 'sass:string';
3@use 'iro-sass/src/props';
4@use '../core.vars' as core;
5
6$size: props.def(--o-thumbnail--size, props.get(core.$size--700)) !default;
7$rounding: props.def(--o-thumbnail--rounding, props.get(core.$rounding--sm)) !default;
8$spacing: props.def(--o-thumbnail--spacing, props.get(core.$size--100)) !default;
9$border-width: props.def(--o-thumbnail--border-width, props.get(core.$border-width--thin)) !default;
10
11$selected--border-width: props.def(--o-thumbnail--selected--border-width, props.get(core.$border-width--medium)) !default;
12
13$key-focus--border-width: props.def(--o-thumbnail--key-focus--border-width, props.get(core.$key-focus--border-width)) !default;
14$key-focus--border-offset: props.def(--o-thumbnail--key-focus--border-offset, props.get(core.$key-focus--border-offset)) !default;
15$key-focus--outline-width: props.def(--o-thumbnail--key-focus--outline-width, props.get(core.$key-focus--outline-width)) !default;
16
17$border-color: props.def(--o-thumbnail--border-color, props.get(core.$theme, --border-strong), 'color') !default;
18
19$hover--border-color: props.def(--o-thumbnail--hover--border-color, props.get(core.$theme, --text-mute-more), 'color') !default;
20
21$selected--border-color: props.def(--o-thumbnail--selected--border-color, props.get(core.$theme, --heading), 'color') !default;
22
23$key-focus--border-color: props.def(--o-thumbnail--key-focus--border-color, props.get(core.$theme, --focus, --border), 'color') !default;
24$key-focus--outline-color: props.def(--o-thumbnail--key-focus--outline-color, props.get(core.$theme, --focus, --outline), 'color') !default;
25
26$size--md: props.def(--o-thumbnail--size, props.get(core.$size--600), 'md') !default;
27
28$static-themes: props.def(--o-thumbnail, (), 'color');
29
30@each $theme in map.keys(props.get(core.$transparent-colors)) {
31 $thumbnail-theme: --static-#{string.slice($theme, 3)};
32
33 $static-themes: props.merge($static-themes, (
34 $thumbnail-theme: (
35 --border: props.get(core.$transparent-colors, $theme, --400),
36
37 --hover: (
38 --border: props.get(core.$transparent-colors, $theme, --500),
39 ),
40
41 --selected: (
42 --border: props.get(core.$transparent-colors, $theme, --900),
43 ),
44
45 --key-focus: (
46 --border: props.get(core.$transparent-colors, $theme, --900),
47 --outline: props.get(core.$transparent-colors, $theme, --300),
48 ),
49 )
50 ));
51}
diff --git a/src/scopes/_blockquotes.scss b/src/scopes/_blockquotes.scss
index f6a13fe..a99add8 100644
--- a/src/scopes/_blockquotes.scss
+++ b/src/scopes/_blockquotes.scss
@@ -1,34 +1,26 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
3 5
4@include iro.props-namespace('blockquotes') { 6@forward 'blockquotes.vars';
5 @include iro.props-store(( 7@use 'blockquotes.vars' as vars;
6 --dims: (
7 --indent: fn.global-dim(--list --indent),
8 --margin-bs: fn.global-dim(--paragraph --margin-bs),
9 --border: fn.global-dim(--border --thick),
10 8
11 --compact: ( 9@mixin styles {
12 --indent: fn.global-dim(--list --compact-indent), 10 @include materialize-at-root(meta.module-variables('vars'));
13 ),
14 ),
15 --colors: (
16 --border: fn.global-color(--border),
17 )
18 ));
19 11
20 @include iro.bem-scope(iro.props-namespace()) { 12 @include bem.scope('blockquotes') {
21 blockquote { 13 blockquote {
22 margin-block: fn.dim(--margin-bs); 14 padding-inline-start: calc(props.get(vars.$indent) - props.get(vars.$border-width));
23 margin-inline: 1px 0; 15 margin-block: props.get(vars.$margin-bs) 0;
24 padding-inline-start: calc(fn.dim(--indent) - fn.dim(--border)); 16 margin-inline: 1px 0;
25 border-inline-start: fn.dim(--border) solid fn.color(--border); 17 border-inline-start: props.get(vars.$border-width) solid props.get(vars.$border-color);
26 } 18 }
27 19
28 @include iro.bem-modifier('compact') { 20 @include bem.modifier('compact') {
29 blockquote { 21 blockquote {
30 padding-inline-start: calc(fn.dim(--compact --indent) - fn.dim(--border)); 22 padding-inline-start: calc(props.get(vars.$compact--indent) - props.get(vars.$border-width));
31 } 23 }
32 } 24 }
33 } 25 }
34} 26}
diff --git a/src/scopes/_blockquotes.vars.scss b/src/scopes/_blockquotes.vars.scss
new file mode 100644
index 0000000..6aae242
--- /dev/null
+++ b/src/scopes/_blockquotes.vars.scss
@@ -0,0 +1,11 @@
1@use 'iro-sass/src/props';
2@use '../core.vars' as core;
3@use './implicit.vars' as implicit;
4
5$indent: props.def(--s-blockquotes--indent, props.get(core.$list--indent)) !default;
6$margin-bs: props.def(--s-blockquotes--margin-bs, props.get(implicit.$paragraph--margin-bs)) !default;
7$border-width: props.def(--s-blockquotes--border-width, props.get(core.$border-width--thick)) !default;
8
9$compact--indent: props.def(--s-blockquotes--compact--indent, props.get(core.$list--compact-indent)) !default;
10
11$border-color: props.def(--s-blockquotes--border-color, props.get(core.$theme, --border), 'color') !default;
diff --git a/src/scopes/_body.scss b/src/scopes/_body.scss
new file mode 100644
index 0000000..f307f58
--- /dev/null
+++ b/src/scopes/_body.scss
@@ -0,0 +1,59 @@
1@use 'sass:meta';
2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
5
6@forward 'body.vars';
7@use 'body.vars' as vars;
8
9@mixin styles {
10 @include materialize-at-root(meta.module-variables('vars'));
11
12 @include bem.scope('body') {
13 font-size: props.get(vars.$font-size);
14 line-height: props.get(vars.$line-height);
15
16 strong {
17 color: props.get(vars.$strong--text-color);
18 }
19
20 p,
21 ul,
22 ol {
23 max-inline-size: props.get(vars.$paragraph--max-inline-size);
24 margin-block-start: props.get(vars.$paragraph--margin-bs);
25 }
26
27 ul,
28 ol {
29 box-sizing: border-box;
30 }
31
32 img {
33 display: block;
34 inline-size: auto;
35 max-inline-size: 100%;
36 block-size: auto;
37 max-block-size: props.get(vars.$img--max-block-size);
38 margin-block-start: props.get(vars.$paragraph--margin-bs);
39 }
40
41 figure {
42 margin-block-start: props.get(vars.$paragraph--margin-bs);
43
44 img {
45 margin-block: 0;
46 }
47 }
48
49 hr {
50 margin-block: calc(2 * props.get(vars.$paragraph--margin-bs));
51 }
52
53 table,
54 pre,
55 blockquote {
56 margin-block-start: props.get(vars.$paragraph--margin-bs);
57 }
58 }
59}
diff --git a/src/scopes/_body.vars.scss b/src/scopes/_body.vars.scss
new file mode 100644
index 0000000..1de2cfd
--- /dev/null
+++ b/src/scopes/_body.vars.scss
@@ -0,0 +1,12 @@
1@use 'iro-sass/src/props';
2@use '../core.vars' as core;
3
4@use '../layouts/container.vars' as container;
5
6$font-size: props.def(--s-body--font-size, props.get(core.$font-size--150)) !default;
7$line-height: props.def(--s-body--line-height, calc(props.get(core.$font--standard--line-height) + .1)) !default;
8$paragraph--margin-bs: props.def(--s-body--paragraph--margin-bs, props.get(core.$size--300)) !default;
9$paragraph--max-inline-size: props.def(--s-body--paragraph--max-inline-size, props.get(container.$fixed)) !default;
10$img--max-block-size: props.def(--s-body--img--max-block-size, none) !default;
11
12$strong--text-color: props.def(--s-body--strong--text-color, props.get(core.$theme, --heading), 'color') !default;
diff --git a/src/scopes/_code.scss b/src/scopes/_code.scss
index 4df711b..8147a14 100644
--- a/src/scopes/_code.scss
+++ b/src/scopes/_code.scss
@@ -1,59 +1,40 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
3 5
4@include iro.props-namespace('code') { 6@forward 'code.vars';
5 @include iro.props-store(( 7@use 'code.vars' as vars;
6 --dims: (
7 --inline: (
8 --pad-i: fn.global-dim(--size --50),
9 --pad-b: fn.global-dim(--size --10),
10 --rounding: fn.global-dim(--rounding),
11 ),
12 --block: (
13 --pad-i: fn.global-dim(--size --150),
14 --pad-b: fn.global-dim(--size --85),
15 --margin-bs: fn.global-dim(--paragraph --margin-bs),
16 --rounding: fn.global-dim(--rounding),
17 )
18 ),
19 --colors: (
20 --inline: (
21 --fg: fn.global-color(--red --1200),
22 --bg: fn.global-color(--red --200),
23 ),
24 --block: (
25 --fg: fn.global-color(--text),
26 --bg: fn.global-color(--base --50),
27 )
28 )
29 ));
30 8
31 @include iro.bem-scope(iro.props-namespace()) { 9@mixin styles {
32 code { 10 @include materialize-at-root(meta.module-variables('vars'));
33 padding-block: fn.dim(--inline --pad-b);
34 padding-inline: fn.dim(--inline --pad-i);
35 border-radius: fn.dim(--inline --rounding);
36 background-color: fn.color(--inline --bg);
37 color: fn.color(--inline --fg);
38 }
39 11
40 pre { 12 @include bem.scope('code') {
41 margin-block: fn.dim(--block --margin-bs) 0; 13 code {
42 margin-inline: 0; 14 padding-block: props.get(vars.$inline--pad-b);
43 padding-block: fn.dim(--block --pad-b); 15 padding-inline: props.get(vars.$inline--pad-i);
44 padding-inline: fn.dim(--block --pad-i); 16 color: props.get(vars.$inline--fg);
45 border-radius: fn.dim(--block --rounding); 17 background-color: props.get(vars.$inline--bg);
46 background-color: fn.color(--block --bg); 18 border-radius: props.get(vars.$inline--rounding);
47 color: fn.color(--block --fg); 19 }
48 20
49 code { 21 pre {
50 display: inline-block; 22 padding-block: props.get(vars.$block--pad-b);
51 margin-inline-end: fn.dim(--block --pad-i); 23 padding-inline: props.get(vars.$block--pad-i);
52 padding: 0; 24 margin-block: props.get(vars.$block--margin-bs) 0;
53 border-radius: 0; 25 margin-inline: 0;
54 background-color: transparent; 26 color: props.get(vars.$block--fg);
55 color: currentColor; 27 background-color: props.get(vars.$block--bg);
56 } 28 border-radius: props.get(vars.$block--rounding);
57 } 29
58 } 30 code {
31 display: inline-block;
32 padding: 0;
33 margin-inline-end: props.get(vars.$block--pad-i);
34 color: currentColor;
35 background-color: transparent;
36 border-radius: 0;
37 }
38 }
39 }
59} 40}
diff --git a/src/scopes/_code.vars.scss b/src/scopes/_code.vars.scss
new file mode 100644
index 0000000..08472f2
--- /dev/null
+++ b/src/scopes/_code.vars.scss
@@ -0,0 +1,18 @@
1@use 'iro-sass/src/props';
2@use '../core.vars' as core;
3@use './implicit.vars' as implicit;
4
5$inline--pad-i: props.def(--s-code--inline--pad-i, props.get(core.$size--50)) !default;
6$inline--pad-b: props.def(--s-code--inline--pad-b, props.get(core.$size--10)) !default;
7$inline--rounding: props.def(--s-code--inline--rounding, props.get(core.$rounding--sm)) !default;
8
9$block--pad-i: props.def(--s-code--block--pad-i, props.get(core.$size--150)) !default;
10$block--pad-b: props.def(--s-code--block--pad-b, props.get(core.$size--85)) !default;
11$block--margin-bs: props.def(--s-code--block--margin-bs, props.get(implicit.$paragraph--margin-bs)) !default;
12$block--rounding: props.def(--s-code--block--rounding, props.get(core.$rounding--sm)) !default;
13
14$inline--fg: props.def(--s-code--inline--fg, props.get(core.$theme, --heading), 'color') !default;
15$inline--bg: props.def(--s-code--inline--bg, props.get(core.$theme, --base, --200), 'color') !default;
16
17$block--fg: props.def(--s-code--block--fg, props.get(core.$theme, --text), 'color') !default;
18$block--bg: props.def(--s-code--block--bg, props.get(core.$theme, --base, --50), 'color') !default;
diff --git a/src/scopes/_figures.scss b/src/scopes/_figures.scss
new file mode 100644
index 0000000..d931820
--- /dev/null
+++ b/src/scopes/_figures.scss
@@ -0,0 +1,21 @@
1@use 'sass:meta';
2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../objects/figure.vars' as figure;
5
6@mixin styles {
7 @include bem.scope('figures') {
8 figcaption {
9 padding-block: props.get(figure.$pad-b);
10 font-size: props.get(figure.$font-size);
11 color: props.get(figure.$text-color);
12 border-block-end: props.get(figure.$border-width) solid props.get(figure.$border-color);
13
14 &::before {
15 display: block;
16 margin-block: -100em 100em;
17 content: '';
18 }
19 }
20 }
21}
diff --git a/src/scopes/_headings.scss b/src/scopes/_headings.scss
index 9593792..f8a7854 100644
--- a/src/scopes/_headings.scss
+++ b/src/scopes/_headings.scss
@@ -1,116 +1,67 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:map';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use '../mixins' as mx; 3@use 'iro-sass/src/props';
4@use 'include-media/dist/include-media' as media; 4@use '../objects/heading.vars' as heading;
5 5
6@include iro.props-namespace('headings') { 6@mixin styles {
7 @include iro.bem-scope(iro.props-namespace()) { 7 /* stylelint-disable-next-line scss/dollar-variable-pattern */
8 h1, 8 $-size-map: (
9 h2, 9 xs: h6,
10 h3, 10 sm: h5,
11 h4, 11 md: h4,
12 h5, 12 lg: h3,
13 h6 { 13 xl: h2,
14 @include mx.set-font(--headline); 14 xxl: h1,
15 );
15 16
16 display: block; 17 @include bem.scope('headings') {
17 transform: translateX(-.06em); 18 h1,
18 letter-spacing: normal; 19 h2,
19 text-transform: none; 20 h3,
20 } 21 h4,
22 h5,
23 h6 {
24 display: block;
25 margin-block-start: props.get(heading.$margin-bs);
26 font-family: props.get(heading.$font-family);
27 font-weight: props.get(heading.$font-weight);
28 font-feature-settings: props.get(heading.$feature-settings);
29 line-height: props.get(heading.$line-height);
30 text-transform: none;
31 letter-spacing: normal;
32 transform: translateX(props.get(heading.$offset));
33 }
21 34
35 @include bem.elem('highlight') {
36 background-image: linear-gradient(to top,
37 transparent .15em,
38 props.get(heading.$bg-color) .15em,
39 props.get(heading.$bg-color) .6em,
40 transparent .6em);
41 }
22 42
23 h1 { 43 @each $mod, $font-family, $line-height, $font-size, $font-weight, $letter-spacing, $feature-settings in heading.$sizes {
24 @include mx.heading-strong(--xxl); 44 #{map.get($-size-map, $mod)} {
25 } 45 font-family: props.get($font-family);
46 font-size: props.get($font-size);
47 font-weight: props.get($font-weight);
48 font-feature-settings: props.get($feature-settings);
49 line-height: props.get($line-height);
50 letter-spacing: props.get($letter-spacing);
51 }
52 }
26 53
27 h2 { 54 @include bem.modifier('display') {
28 @include mx.heading-strong(--xl); 55 @each $mod, $font-family, $line-height, $font-size, $font-weight, $letter-spacing, $feature-settings in heading.$display--sizes {
29 } 56 #{map.get($-size-map, $mod)} {
30 57 font-family: props.get($font-family);
31 h3 { 58 font-size: props.get($font-size);
32 @include mx.heading-medium(--lg); 59 font-weight: props.get($font-weight);
33 } 60 font-feature-settings: props.get($feature-settings);
34 61 line-height: props.get($line-height);
35 h4 { 62 letter-spacing: props.get($letter-spacing);
36 @include mx.heading-medium(--md); 63 }
37 } 64 }
38 65 }
39 h5 { 66 }
40 @include mx.heading-faint(--sm);
41 }
42
43 h6 {
44 @include mx.heading-faint(--xs);
45 }
46
47 @include iro.bem-elem('highlight') {
48 background-image: linear-gradient(
49 to top,
50 transparent .15em,
51 fn.foreign-color(--heading, --bg) .15em,
52 fn.foreign-color(--heading, --bg) .6em,
53 transparent .6em
54 );
55 }
56
57 @include iro.bem-modifier('display') {
58 h1,
59 h2,
60 h3,
61 h4,
62 h5,
63 h6 {
64 @include mx.set-font(--headline);
65 }
66
67 h1 {
68 @include mx.heading-strong(--display --xxl);
69
70 @include media.media('<=md') {
71 @include mx.heading-strong(--display-sm --xxl);
72 }
73 }
74
75 h2 {
76 @include mx.heading-strong(--display --xl);
77
78 @include media.media('<=md') {
79 @include mx.heading-strong(--display-sm --xl);
80 }
81 }
82
83 h3 {
84 @include mx.heading-strong(--display --lg);
85
86 @include media.media('<=md') {
87 @include mx.heading-strong(--display-sm --lg);
88 }
89 }
90
91 h4 {
92 @include mx.heading-strong(--display --md);
93
94 @include media.media('<=md') {
95 @include mx.heading-strong(--display-sm --md);
96 }
97 }
98
99 h5 {
100 @include mx.heading-medium(--display --sm);
101
102 @include media.media('<=md') {
103 @include mx.heading-medium(--display-sm --sm);
104 }
105 }
106
107 h6 {
108 @include mx.heading-faint(--display --xs);
109
110 @include media.media('<=md') {
111 @include mx.heading-faint(--display-sm --xs);
112 }
113 }
114 }
115 }
116} 67}
diff --git a/src/scopes/_implicit.scss b/src/scopes/_implicit.scss
new file mode 100644
index 0000000..cee1639
--- /dev/null
+++ b/src/scopes/_implicit.scss
@@ -0,0 +1,180 @@
1@use 'sass:map';
2@use 'sass:math';
3@use 'sass:meta';
4@use 'sass:string';
5@use 'iro-sass/src/bem';
6@use 'iro-sass/src/props';
7@use '../props' as *;
8@use '../core.vars' as core;
9
10@forward 'implicit.vars';
11@use 'implicit.vars' as vars;
12
13@mixin styles {
14 @include materialize-at-root(meta.module-variables('vars'));
15
16 @layer scope {
17 html {
18 accent-color: props.get(core.$theme, --accent, --600);
19 scrollbar-color: props.get(core.$theme, --text-disabled) transparent;
20 }
21
22 body {
23 padding: 0;
24 margin: 0;
25 font-family: props.get(vars.$body--font-family);
26 font-size: props.get(vars.$body--font-size);
27 font-feature-settings: props.get(vars.$body--feature-settings);
28 line-height: props.get(vars.$body--line-height);
29 color: props.get(core.$theme, --text);
30 background-color: props.get(core.$theme, --bg-base);
31 }
32
33 pre,
34 code {
35 font-family: props.get(vars.$code--font-family);
36 font-size: props.get(vars.$code--font-size);
37 font-feature-settings: props.get(vars.$code--feature-settings);
38 line-height: props.get(vars.$code--line-height);
39 }
40
41 pre {
42 margin: 0;
43 overflow-x: auto;
44
45 code {
46 font-size: 1em;
47 color: currentColor;
48 }
49 }
50
51 h1,
52 h2,
53 h3,
54 h4,
55 h5,
56 h6 {
57 margin-block: props.get(vars.$heading--margin-bs) 0;
58 font-family: props.get(vars.$heading--font-family);
59 font-size: props.get(vars.$heading--font-size);
60 font-weight: props.get(vars.$heading--font-weight);
61 font-feature-settings: props.get(vars.$heading--feature-settings);
62 line-height: props.get(vars.$heading--line-height);
63 color: props.get(vars.$heading--color);
64
65 & + & {
66 margin-block-start: props.get(vars.$heading--margin-bs-sibling);
67 }
68 }
69
70 p {
71 margin-block: props.get(vars.$paragraph--margin-bs) 0;
72
73 &:empty {
74 display: none;
75 }
76 }
77
78 strong {
79 font-weight: bold;
80 }
81
82 small {
83 font-size: props.get(vars.$small--font-size);
84 }
85
86 ul,
87 ol {
88 padding: 0;
89 margin: 0;
90 list-style: none;
91 }
92
93 li {
94 padding: 0;
95 margin: 0;
96 }
97
98 :focus,
99 :focus-visible {
100 outline: 0;
101 }
102
103 :link,
104 :visited {
105 color: currentColor;
106 text-decoration: none;
107 }
108
109
110 button,
111 input,
112 textarea {
113 box-sizing: content-box;
114 padding: 0;
115 margin: 0;
116 font-family: inherit;
117 font-size: 1em;
118 font-style: inherit;
119 font-weight: inherit;
120 line-height: inherit;
121 color: currentColor;
122 text-align: inherit;
123 text-transform: inherit;
124 appearance: none;
125 background: none;
126 border: 0;
127
128 &::-moz-focus-inner {
129 border: 0;
130 }
131 }
132
133 input,
134 textarea {
135 &::placeholder {
136 color: props.get(core.$theme, --text-mute);
137 opacity: 1;
138 }
139
140 &:disabled {
141 color: props.get(core.$theme, --text-disabled);
142 }
143 }
144
145 textarea {
146 block-size: calc(1em * props.get(core.$font--standard--line-height));
147 }
148
149 hr {
150 block-size: props.get(core.$border-width--thin);
151 margin: 0;
152 background-color: props.get(core.$theme, --border);
153 border: 0;
154 }
155
156 figure {
157 padding: 0;
158 margin: 0;
159 }
160
161 @each $theme in map.keys(props.get(core.$transparent-colors)) {
162 .t-static-#{string.slice($theme, 3)} {
163 color: props.get(core.$transparent-colors, $theme, --800);
164
165 h1,
166 h2,
167 h3,
168 h4,
169 h5,
170 h6 {
171 color: props.get(core.$transparent-colors, $theme, --900);
172 }
173
174 hr {
175 color: props.get(core.$transparent-colors, $theme, --400);
176 }
177 }
178 }
179 }
180}
diff --git a/src/scopes/_implicit.vars.scss b/src/scopes/_implicit.vars.scss
new file mode 100644
index 0000000..388f0af
--- /dev/null
+++ b/src/scopes/_implicit.vars.scss
@@ -0,0 +1,26 @@
1@use 'iro-sass/src/props';
2@use '../core.vars' as core;
3
4$paragraph--margin-bs: props.def(--s-implicit--paragraph--margin-bs, props.get(core.$size--200)) !default;
5
6$small--font-size: props.def(--s-implicit--small--font-size, props.get(core.$font-size--75)) !default;
7
8$body--font-family: props.def(--s-implicit--body--font-family, props.get(core.$font--standard--family)) !default;
9$body--line-height: props.def(--s-implicit--body--line-height, props.get(core.$font--standard--line-height)) !default;
10$body--font-size: props.def(--s-implicit--body--font-size, props.get(core.$font-size--100));
11$body--feature-settings: props.def(--s-implicit--body--feature-settings, props.get(core.$font--standard--feature-settings)) !default;
12
13$code--font-family: props.def(--s-implicit--code--font-family, props.get(core.$font--mono--family)) !default;
14$code--line-height: props.def(--s-implicit--code--line-height, props.get(core.$font--mono--line-height)) !default;
15$code--font-size: props.def(--s-implicit--code--font-size, .93em);
16$code--feature-settings: props.def(--s-implicit--code--feature-settings, props.get(core.$font--mono--feature-settings)) !default;
17
18$heading--margin-bs: props.def(--s-implicit--heading--margin-bs, props.get(core.$size--700)) !default;
19$heading--margin-bs-sibling: props.def(--s-implicit--heading--margin-bs-sibling, props.get(core.$size--325)) !default;
20$heading--font-family: props.def(--s-implicit--heading--font-family, props.get(core.$font--standard--family)) !default;
21$heading--line-height: props.def(--s-implicit--heading--line-height, props.get(core.$font--standard--line-height)) !default;
22$heading--font-weight: props.def(--s-implicit--heading--font-weight, bold) !default;
23$heading--font-size: props.def(--s-implicit--heading--font-size, props.get(core.$font-size--100));
24$heading--feature-settings: props.def(--s-implicit--heading--feature-settings, props.get(core.$font--standard--feature-settings)) !default;
25
26$heading--color: props.def(--s-implicit--heading--color, props.get(core.$theme, --heading), 'color') !default;
diff --git a/src/scopes/_links.scss b/src/scopes/_links.scss
index d47c406..9ade0c2 100644
--- a/src/scopes/_links.scss
+++ b/src/scopes/_links.scss
@@ -1,143 +1,119 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:map';
2@use '../functions' as fn; 2@use 'sass:meta';
3@use 'sass:string';
4@use 'iro-sass/src/bem';
5@use 'iro-sass/src/props';
6@use '../props' as *;
3 7
4$static-themes: 'black' 'white' !default; 8@forward 'links.vars';
9@use 'links.vars' as vars;
5 10
6@include iro.props-namespace('links') { 11@mixin styles {
7 @include iro.props-store(( 12 @include materialize-at-root(meta.module-variables('vars'));
8 --dims: (
9 --rounding: fn.global-dim(--rounding),
10 --underline: fn.global-dim(--border --thin),
11 13
12 --hover: ( 14 @include bem.scope('links') {
13 --underline: fn.global-dim(--border --medium), 15 :link,
14 ), 16 :visited {
17 color: currentColor;
18 text-decoration: underline;
19 text-decoration-thickness: props.get(vars.$underline-width);
20 text-decoration-color: props.get(vars.$underline-color);
21 border-radius: props.get(vars.$rounding-sm);
22 box-decoration-break: clone;
15 23
16 --key-focus: ( 24 &:hover {
17 --border: fn.global-dim(--key-focus --border), 25 text-decoration: underline;
18 --border-offset: fn.global-dim(--key-focus --border-offset), 26 text-decoration-thickness: props.get(vars.$hover--underline-width);
19 --outline: fn.global-dim(--key-focus --border), 27 text-decoration-skip-ink: none;
20 ), 28 }
21 ),
22 --colors: (
23 --underline: fn.global-color(--text-mute-more),
24 29
25 --colored: ( 30 &:focus-visible {
26 --text: fn.global-color(--accent --1100), 31 color: props.get(vars.$key-focus--text-color);
27 --underline: fn.global-color(--accent --600), 32 text-decoration: none;
33 outline: props.get(vars.$key-focus--border-color) solid props.get(vars.$key-focus--border-width);
34 box-shadow:
35 0
36 0
37 0
38 calc(props.get(vars.$key-focus--border-width) + props.get(vars.$key-focus--outline-width))
39 props.get(vars.$key-focus--outline-color);
40 }
41 }
28 42
29 --hover: ( 43 @include bem.modifier('invisible') {
30 --text: fn.global-color(--accent --1300), 44 :link,
31 ), 45 :visited {
32 46 text-decoration: none;
33 --visited: ( 47 }
34 --text: fn.global-color(--purple --1100), 48 }
35 --underline: fn.global-color(--purple --600),
36
37 --hover: (
38 --text: fn.global-color(--purple --1300),
39 ),
40 ),
41 ),
42 49
43 --key-focus: ( 50 @include bem.modifier('colored') {
44 --text: fn.global-color(--focus --text), 51 :link {
45 --border: fn.global-color(--focus --border), 52 color: props.get(vars.$colored--text-color);
46 --outline: fn.global-color(--focus --outline), 53 text-decoration-color: props.get(vars.$colored--underline-color);
47 ),
48 ),
49 ));
50 54
51 @each $theme in $static-themes { 55 &:hover {
52 @include iro.props-store(( 56 color: props.get(vars.$colored--hover--text-color);
53 --colors: ( 57 }
54 --static-#{$theme}: ( 58 }
55 --text: fn.global-color(--#{$theme}-transparent --800),
56 --underline: fn.global-color(--#{$theme}-transparent --500),
57
58 --hover: (
59 --text: fn.global-color(--#{$theme}-transparent --900),
60 ),
61 59
62 --key-focus: ( 60 :visited {
63 --text: fn.global-color(--#{$theme}-transparent --900), 61 color: props.get(vars.$colored--visited--text-color);
64 --border: fn.global-color(--#{$theme}-transparent --900), 62 text-decoration-color: props.get(vars.$colored--visited--underline-color);
65 --outline: fn.global-color(--#{$theme}-transparent --300),
66 ),
67 )
68 )
69 ));
70 }
71 63
72 @include iro.bem-scope(iro.props-namespace()) { 64 &:hover {
73 :link, 65 color: props.get(vars.$colored--visited--hover--text-color);
74 :visited { 66 }
75 border-radius: fn.dim(--rounding); 67 }
76 color: currentColor; 68 }
77 text-decoration: underline;
78 text-decoration-color: fn.color(--underline);
79 text-decoration-thickness: fn.dim(--underline);
80 box-decoration-break: clone;
81 69
82 &:hover { 70 @each $theme in map.keys(props.get(vars.$static-themes)) {
83 text-decoration: underline; 71 @include bem.modifier(string.slice($theme, 3)) {
84 text-decoration-thickness: fn.dim(--hover --underline); 72 :link,
85 text-decoration-skip-ink: none; 73 :visited {
86 } 74 color: props.get(vars.$static-themes, $theme, --text-color);
75 text-decoration-color: props.get(vars.$static-themes, $theme, --underline-color);
87 76
88 &:focus-visible { 77 &:hover {
89 outline: fn.color(--key-focus --border) solid fn.dim(--key-focus --border); 78 color: props.get(vars.$static-themes, $theme, --hover, --text-color);
90 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(--key-focus --outline); 79 }
91 color: fn.color(--key-focus --text);
92 text-decoration: none;
93 }
94 }
95 80
96 @include iro.bem-modifier('invisible') { 81 &:focus-visible {
97 :link, 82 color: props.get(vars.$static-themes, $theme, --key-focus, --text-color);
98 :visited { 83 outline-color: props.get(vars.$static-themes, $theme, --key-focus, --border-color);
99 text-decoration: none; 84 box-shadow:
100 } 85 0
101 } 86 0
87 0
88 calc(props.get(vars.$key-focus--border-width) + props.get(vars.$key-focus--outline-width))
89 props.get(vars.$static-themes, $theme, --key-focus, --outline-color);
90 }
91 }
92 }
93 }
102 94
103 @include iro.bem-modifier('colored') { 95 @include bem.elem('image') {
104 :link { 96 img {
105 color: fn.color(--colored --text); 97 margin-inline: calc(-1 * props.get(vars.$key-focus--border-offset));
106 text-decoration-color: fn.color(--colored --underline); 98 border: props.get(vars.$key-focus--border-offset) solid transparent;
107 99 border-radius: calc(props.get(vars.$rounding) + props.get(vars.$key-focus--border-offset));
108 &:hover { 100 }
109 color: fn.color(--colored --hover --text);
110 }
111 }
112 101
113 :visited { 102 &:link,
114 color: fn.color(--colored --visited --text); 103 &:visited {
115 text-decoration-color: fn.color(--colored --visited --underline); 104 &:focus-visible {
116 105 outline: none;
117 &:hover { 106 box-shadow: none;
118 color: fn.color(--colored --visited --hover --text); 107
119 } 108 img {
120 } 109 outline: props.get(vars.$key-focus--border-color) solid
121 } 110 props.get(vars.$key-focus--border-width);
122 111 box-shadow: 0 0 0
123 @each $theme in $static-themes { 112 calc(props.get(vars.$key-focus--border-width) + props.get(vars.$key-focus--outline-width))
124 @include iro.bem-modifier(static-#{$theme}) { 113 props.get(vars.$key-focus--outline-color);
125 :link, 114 }
126 :visited { 115 }
127 color: fn.color(--static-#{$theme} --text); 116 }
128 text-decoration-color: fn.color(--static-#{$theme} --underline); 117 }
129 118 }
130 &:hover {
131 color: fn.color(--static-#{$theme} --hover --text);
132 }
133
134 &:focus-visible {
135 outline-color: fn.color(--static-#{$theme} --key-focus --border);
136 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(--static-#{$theme} --key-focus --outline);
137 color: fn.color(--static-#{$theme} --key-focus --text);
138 }
139 }
140 }
141 }
142 }
143} 119}
diff --git a/src/scopes/_links.vars.scss b/src/scopes/_links.vars.scss
new file mode 100644
index 0000000..c69cc32
--- /dev/null
+++ b/src/scopes/_links.vars.scss
@@ -0,0 +1,49 @@
1@use 'sass:map';
2@use 'sass:string';
3@use 'iro-sass/src/props';
4@use '../core.vars' as core;
5
6$rounding: props.def(--s-links--rounding, props.get(core.$rounding)) !default;
7$rounding-sm: props.def(--s-links--rounding-sm, props.get(core.$rounding--sm)) !default;
8$underline-width: props.def(--s-links--underline-width, props.get(core.$border-width--thin)) !default;
9$hover--underline-width: props.def(--s-links--hover--underline-width, props.get(core.$border-width--medium)) !default;
10
11$key-focus--border-width: props.def(--s-links--key-focus--border-width, props.get(core.$key-focus--border-width)) !default;
12$key-focus--border-offset: props.def(--s-links--key-focus--border-offset, props.get(core.$key-focus--border-offset)) !default;
13$key-focus--outline-width: props.def(--s-links--key-focus--outline-width, props.get(core.$key-focus--outline-width)) !default;
14
15$underline-color: props.def(--s-links--underline-color, props.get(core.$theme, --text-mute-more), 'color') !default;
16
17$colored--text-color: props.def(--s-links--colored--text-color, props.get(core.$theme, --accent, --1100), 'color') !default;
18$colored--underline-color: props.def(--s-links--colored--underline-color, props.get(core.$theme, --accent, --600), 'color') !default;
19$colored--hover--text-color: props.def(--s-links--colored--hover--text-color, props.get(core.$theme, --accent, --1300), 'color') !default;
20
21$colored--visited--text-color: props.def(--s-links--colored--visited--text-color, props.get(core.$theme, --purple, --1100), 'color') !default;
22$colored--visited--underline-color: props.def(--s-links--colored--visited--underline-color, props.get(core.$theme, --purple, --600), 'color') !default;
23$colored--visited--hover--text-color: props.def(--s-links--colored--visited--hover--text-color, props.get(core.$theme, --purple, --1300), 'color') !default;
24
25$key-focus--text-color: props.def(--s-links--key-focus--text-color, props.get(core.$theme, --focus, --text), 'color') !default;
26$key-focus--border-color: props.def(--s-links--key-focus--border-color, props.get(core.$theme, --focus, --border), 'color') !default;
27$key-focus--outline-color: props.def(--s-links--key-focus--outline-color, props.get(core.$theme, --focus, --outline), 'color') !default;
28
29$static-themes: props.def(--s-links, (), 'color');
30@each $theme in map.keys(props.get(core.$transparent-colors)) {
31 $link-theme: --static-#{string.slice($theme, 3)};
32
33 $static-themes: props.merge($static-themes, (
34 $link-theme: (
35 --text-color: currentColor,
36 --underline-color: props.get(core.$transparent-colors, $theme, --500),
37
38 --hover: (
39 --text-color: props.get(core.$transparent-colors, $theme, --900),
40 ),
41
42 --key-focus: (
43 --text-color: props.get(core.$transparent-colors, $theme, --900),
44 --border-color: props.get(core.$transparent-colors, $theme, --900),
45 --outline-color: props.get(core.$transparent-colors, $theme, --300),
46 ),
47 )
48 ));
49}
diff --git a/src/scopes/_lists.scss b/src/scopes/_lists.scss
index bad9731..fc8a577 100644
--- a/src/scopes/_lists.scss
+++ b/src/scopes/_lists.scss
@@ -1,66 +1,60 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use 'iro-sass/src/props';
4@use '../props' as *;
5@use '../core.vars' as core;
3 6
4@include iro.props-namespace('lists') { 7@forward 'lists.vars';
5 @include iro.props-store(( 8@use 'lists.vars' as vars;
6 --dims: (
7 --indent: calc(fn.global-dim(--list --indent) + 1em),
8 --margin-bs: fn.global-dim(--paragraph --margin-bs),
9 9
10 --compact: ( 10@mixin styles {
11 --indent: fn.global-dim(--list --compact-indent), 11 @include materialize-at-root(meta.module-variables('vars'));
12 ),
13 ),
14 --colors: (
15 --border: fn.global-color(--border-mute),
16 )
17 ));
18 12
19 @include iro.bem-scope(iro.props-namespace()) { 13 @include bem.scope('lists') {
20 ul, 14 ul,
21 ol { 15 ol {
22 margin-block-start: fn.dim(--margin-bs); 16 padding-inline-start: props.get(vars.$indent);
23 padding-inline-start: fn.dim(--indent); 17 margin-block-start: props.get(vars.$margin-bs);
24 18
25 ul, 19 ul,
26 ol { 20 ol {
27 margin-block-start: 0; 21 margin-block-start: 0;
28 } 22 }
29 } 23 }
30 24
31 ul { 25 ul {
32 list-style: disc; 26 list-style: disc;
33 } 27 }
34 28
35 ol { 29 ol {
36 list-style: decimal; 30 list-style: decimal;
37 } 31 }
38 32
39 dl { 33 dl {
40 margin-block: fn.dim(--margin-bs) 0; 34 padding: 0;
41 margin-inline: 0; 35 margin-block: props.get(vars.$margin-bs) 0;
42 padding: 0; 36 margin-inline: 0;
43 } 37 }
44 38
45 dt { 39 dt {
46 color: fn.global-color(--heading); 40 font-weight: bold;
47 font-weight: bold; 41 color: props.get(core.$theme, --heading);
48 } 42 }
49 43
50 dd { 44 dd {
51 margin-block: 0; 45 margin-block: 0;
52 margin-inline: fn.dim(--indent) 0; 46 margin-inline: props.get(vars.$indent) 0;
53 } 47 }
54 48
55 @include iro.bem-modifier('compact') { 49 @include bem.modifier('compact') {
56 ul, 50 ul,
57 ol { 51 ol {
58 padding-inline-start: calc(fn.dim(--compact --indent) - 3px); 52 padding-inline-start: calc(props.get(vars.$compact--indent) - 3px);
59 } 53 }
60 54
61 dd { 55 dd {
62 margin-inline-start: calc(fn.dim(--compact --indent) - 3px); 56 margin-inline-start: calc(props.get(vars.$compact--indent) - 3px);
63 } 57 }
64 } 58 }
65 } 59 }
66} 60}
diff --git a/src/scopes/_lists.vars.scss b/src/scopes/_lists.vars.scss
new file mode 100644
index 0000000..8c46bc3
--- /dev/null
+++ b/src/scopes/_lists.vars.scss
@@ -0,0 +1,8 @@
1@use 'iro-sass/src/props';
2@use '../core.vars' as core;
3@use './implicit.vars' as implicit;
4
5$indent: props.def(--s-lists--indent, calc(props.get(core.$list--indent) + 1em)) !default;
6$margin-bs: props.def(--s-lists--margin-bs, props.get(implicit.$paragraph--margin-bs)) !default;
7
8$compact--indent: props.def(--s-lists--compact--indent, props.get(core.$list--compact-indent)) !default;
diff --git a/src/scopes/_tables.scss b/src/scopes/_tables.scss
index 9b2124d..5b64301 100644
--- a/src/scopes/_tables.scss
+++ b/src/scopes/_tables.scss
@@ -1,115 +1,102 @@
1@use 'iro-sass/src/index' as iro; 1@use 'sass:meta';
2@use '../functions' as fn; 2@use 'iro-sass/src/bem';
3@use '../mixins' as mx; 3@use 'iro-sass/src/props';
4@use '../props' as *;
5@use '../objects/table.vars' as table;
4 6
5@include iro.props-namespace('tables') { 7@forward 'tables.vars';
6 @include iro.props-store(( 8@use 'tables.vars' as vars;
7 --dims: (
8 --pad-i: fn.foreign-dim(--table, --pad-i),
9 --pad-b: fn.foreign-dim(--table, --pad-b),
10 --rounding: fn.foreign-dim(--table, --rounding),
11 --border: fn.foreign-dim(--table, --border),
12 --margin-bs: fn.global-dim(--paragraph --margin-bs),
13 ),
14 --colors: (
15 --border: fn.foreign-color(--table, --border),
16 --heading: fn.foreign-color(--table, --heading),
17 --box: (
18 --bg: fn.foreign-color(--table, --box --bg),
19 )
20 )
21 ));
22 9
23 @include iro.bem-scope(iro.props-namespace()) { 10@mixin styles {
24 table { 11 @include materialize-at-root(meta.module-variables('vars'));
25 margin-block-start: fn.dim(--margin-bs);
26 border-spacing: 0;
27 border-collapse: separate;
28 }
29 12
30 th { 13 @include bem.scope('tables') {
31 @include mx.set-font(--standard, ( 14 table {
32 --line-height: null, 15 margin-block-start: props.get(vars.$margin-bs);
33 --size: fn.global-dim(--font-size --50), 16 border-spacing: 0;
34 --weight: bold, 17 border-collapse: separate;
35 --transform: uppercase, 18 }
36 --spacing: .5px
37 ));
38 19
39 padding-block: fn.dim(--pad-b); 20 th {
40 padding-inline: fn.dim(--pad-i); 21 padding-block: props.get(table.$pad-b);
41 color: fn.color(--heading); 22 padding-inline: props.get(table.$pad-i);
42 text-align: start; 23 font-family: props.get(table.$heading--font-family);
43 } 24 font-size: props.get(table.$heading--font-size);
25 font-weight: props.get(table.$heading--font-weight);
26 color: props.get(table.$heading-color);
27 text-align: start;
28 text-transform: props.get(table.$heading--text-transform);
29 letter-spacing: props.get(table.$heading--letter-spacing);
30 }
44 31
45 td { 32 td {
46 padding-block: fn.dim(--pad-b); 33 padding-block: props.get(table.$pad-b);
47 padding-inline: fn.dim(--pad-i); 34 padding-inline: props.get(table.$pad-i);
48 border-width: 0; 35 border-color: props.get(table.$border-color);
49 border-block-start-width: fn.dim(--border); 36 border-style: solid;
50 border-style: solid; 37 border-width: 0;
51 border-color: fn.color(--border); 38 border-block-start-width: props.get(table.$border-width);
52 } 39 }
53 40
54 tr { 41 tr {
55 &:last-child { 42 &:last-child {
56 td { 43 td {
57 border-block-end-width: fn.dim(--border); 44 border-block-end-width: props.get(table.$border-width);
58 } 45 }
59 } 46 }
60 } 47 }
61 48
62 @include iro.bem-modifier('flush') { 49 @include bem.modifier('flush') {
63 th, 50 th,
64 td { 51 td {
65 &:first-child { 52 &:first-child {
66 padding-inline-start: 0; 53 padding-inline-start: 0;
67 } 54 }
68 55
69 &:last-child { 56 &:last-child {
70 padding-inline-end: 0; 57 padding-inline-end: 0;
71 } 58 }
72 } 59 }
73 } 60 }
74 61
75 @include iro.bem-modifier('box') { 62 @include bem.modifier('box') {
76 td { 63 td {
77 background-color: fn.color(--box --bg); 64 background-color: props.get(table.$box--bg-color);
78 65
79 &:first-child { 66 &:first-child {
80 border-inline-start-width: fn.dim(--border); 67 border-inline-start-width: props.get(table.$border-width);
81 } 68 }
82 69
83 &:last-child { 70 &:last-child {
84 border-inline-end-width: fn.dim(--border); 71 border-inline-end-width: props.get(table.$border-width);
85 } 72 }
86 } 73 }
87 74
88 tr { 75 tr {
89 &:first-child { 76 &:first-child {
90 td { 77 td {
91 &:first-child { 78 &:first-child {
92 border-start-start-radius: fn.dim(--rounding); 79 border-start-start-radius: props.get(table.$rounding);
93 } 80 }
94 81
95 &:last-child { 82 &:last-child {
96 border-start-end-radius: fn.dim(--rounding); 83 border-start-end-radius: props.get(table.$rounding);
97 } 84 }
98 } 85 }
99 } 86 }
100 87
101 &:last-child { 88 &:last-child {
102 td { 89 td {
103 &:first-child { 90 &:first-child {
104 border-end-start-radius: fn.dim(--rounding); 91 border-end-start-radius: props.get(table.$rounding);
105 } 92 }
106 93
107 &:last-child { 94 &:last-child {
108 border-end-end-radius: fn.dim(--rounding); 95 border-end-end-radius: props.get(table.$rounding);
109 } 96 }
110 } 97 }
111 } 98 }
112 } 99 }
113 } 100 }
114 } 101 }
115} 102}
diff --git a/src/scopes/_tables.vars.scss b/src/scopes/_tables.vars.scss
new file mode 100644
index 0000000..362b70f
--- /dev/null
+++ b/src/scopes/_tables.vars.scss
@@ -0,0 +1,4 @@
1@use 'iro-sass/src/props';
2@use 'implicit.vars' as implicit;
3
4$margin-bs: props.def(--s-tables--margin-bs, props.get(implicit.$paragraph--margin-bs)) !default;