summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVolpeon <git@volpeon.ink>2024-10-18 18:08:24 +0200
committerVolpeon <git@volpeon.ink>2024-10-18 18:08:24 +0200
commit365c56edcc36b5b92902bac01ce44b43d01e8685 (patch)
tree644611792591a76e605068d0c9e230fad6a633e7 /src
parentRevamped variable management (diff)
downloadiro-design-365c56edcc36b5b92902bac01ce44b43d01e8685.tar.gz
iro-design-365c56edcc36b5b92902bac01ce44b43d01e8685.tar.bz2
iro-design-365c56edcc36b5b92902bac01ce44b43d01e8685.zip
Refactoring
Diffstat (limited to 'src')
-rw-r--r--src/_apca.scss (renamed from src/functions/colors/_apca.scss)12
-rw-r--r--src/_functions.scss51
-rw-r--r--src/_iro-design.scss40
-rw-r--r--src/_mixins.scss38
-rw-r--r--src/_props.scss113
-rw-r--r--src/_themes.scss (renamed from src/_palettes.scss)28
-rw-r--r--src/_vars.scss214
-rw-r--r--src/_vars.vars.scss203
-rw-r--r--src/functions/colors/_index.scss1
-rw-r--r--src/index.scss11
-rw-r--r--src/layouts/_button-group.scss16
-rw-r--r--src/layouts/_button-group.vars.scss4
-rw-r--r--src/layouts/_card-list.scss76
-rw-r--r--src/layouts/_card-list.vars.scss19
-rw-r--r--src/layouts/_container.scss27
-rw-r--r--src/layouts/_container.vars.scss22
-rw-r--r--src/layouts/_flex.scss27
-rw-r--r--src/layouts/_form.scss58
-rw-r--r--src/layouts/_form.vars.scss5
-rw-r--r--src/layouts/_media.scss40
-rw-r--r--src/layouts/_media.vars.scss16
-rw-r--r--src/layouts/_overflow.scss11
-rw-r--r--src/objects/_action-button.scss179
-rw-r--r--src/objects/_action-button.vars.scss185
-rw-r--r--src/objects/_alert.scss43
-rw-r--r--src/objects/_alert.vars.scss0
-rw-r--r--src/objects/_avatar.scss165
-rw-r--r--src/objects/_backdrop.scss26
-rw-r--r--src/objects/_badge.scss300
-rw-r--r--src/objects/_button.scss301
-rw-r--r--src/objects/_card.scss170
-rw-r--r--src/objects/_checkbox.scss261
-rw-r--r--src/objects/_divider.scss203
-rw-r--r--src/objects/_emoji.scss73
-rw-r--r--src/objects/_field-label.scss86
-rw-r--r--src/objects/_heading.scss116
-rw-r--r--src/objects/_icon.scss26
-rw-r--r--src/objects/_lightbox.scss313
-rw-r--r--src/objects/_menu.scss137
-rw-r--r--src/objects/_palette.scss62
-rw-r--r--src/objects/_popover.scss51
-rw-r--r--src/objects/_radio.scss185
-rw-r--r--src/objects/_side-nav.scss122
-rw-r--r--src/objects/_status-indicator.scss39
-rw-r--r--src/objects/_switch.scss222
-rw-r--r--src/objects/_table.scss168
-rw-r--r--src/objects/_text-field.scss213
-rw-r--r--src/scopes/_blockquotes.scss25
-rw-r--r--src/scopes/_blockquotes.vars.scss11
-rw-r--r--src/scopes/_code.scss39
-rw-r--r--src/scopes/_code.vars.scss18
-rw-r--r--src/scopes/_headings.scss115
-rw-r--r--src/scopes/_headings.vars.scss0
-rw-r--r--src/scopes/_implicit.scss152
-rw-r--r--src/scopes/_implicit.vars.scss7
-rw-r--r--src/scopes/_links.scss93
-rw-r--r--src/scopes/_links.vars.scss47
-rw-r--r--src/scopes/_lists.scss59
-rw-r--r--src/scopes/_lists.vars.scss8
-rw-r--r--src/scopes/_tables.scss104
-rw-r--r--src/scopes/_tables.vars.scss24
61 files changed, 5020 insertions, 360 deletions
diff --git a/src/functions/colors/_apca.scss b/src/_apca.scss
index 0c03529..c65f46e 100644
--- a/src/functions/colors/_apca.scss
+++ b/src/_apca.scss
@@ -1,5 +1,5 @@
1/* stylelint-disable scss/dollar-variable-pattern */ 1// stylelint-disable scss/dollar-variable-pattern
2/* stylelint-disable scss/at-function-pattern */ 2// stylelint-disable scss/at-function-pattern
3 3
4@use 'sass:color'; 4@use 'sass:color';
5@use 'sass:list'; 5@use 'sass:list';
@@ -33,7 +33,7 @@ $SA98G: (
33 mOffsetOut: .312865795870758, 33 mOffsetOut: .312865795870758,
34); 34);
35 35
36@function apca_sRGB_to_Y($color) { 36@function sRGB_to_Y($color) {
37 $rgb: color.to-space($color, rgb); 37 $rgb: color.to-space($color, rgb);
38 38
39 @return map.get($SA98G, sRco) * math.pow(math.div(color.channel($rgb, 'red'), 255), map.get($SA98G, mainTRC)) + 39 @return map.get($SA98G, sRco) * math.pow(math.div(color.channel($rgb, 'red'), 255), map.get($SA98G, mainTRC)) +
@@ -41,12 +41,12 @@ $SA98G: (
41 map.get($SA98G, sBco) * math.pow(math.div(color.channel($rgb, 'blue'), 255), map.get($SA98G, mainTRC)); 41 map.get($SA98G, sBco) * math.pow(math.div(color.channel($rgb, 'blue'), 255), map.get($SA98G, mainTRC));
42} 42}
43 43
44@function apca_Y_to_sRGB($y) { 44@function Y_to_sRGB($y) {
45 $c: math.round(math.pow($y, math.div(1, map.get($SA98G, mainTRC))) * 255); 45 $c: math.round(math.pow($y, math.div(1, map.get($SA98G, mainTRC))) * 255);
46 @return rgb($c, $c, $c); 46 @return rgb($c, $c, $c);
47} 47}
48 48
49@function apcaContrast($txtY, $bgY) { 49@function contrast($txtY, $bgY) {
50 /* stylelint-disable-next-line @stylistic/number-no-trailing-zeros */ 50 /* stylelint-disable-next-line @stylistic/number-no-trailing-zeros */
51 $icp: .0 1.1; 51 $icp: .0 1.1;
52 52
@@ -84,7 +84,7 @@ $SA98G: (
84 @return $outputContrast * 100; 84 @return $outputContrast * 100;
85} 85}
86 86
87@function apcaReverse($contrast, $knownY, $knownType: 'bg') { 87@function reverse($contrast, $knownY, $knownType: 'bg') {
88 $unknownY: $knownY; 88 $unknownY: $knownY;
89 89
90 $knownExp: 0; 90 $knownExp: 0;
diff --git a/src/_functions.scss b/src/_functions.scss
index 4807cc1..ad45975 100644
--- a/src/_functions.scss
+++ b/src/_functions.scss
@@ -4,67 +4,40 @@
4@use 'sass:list'; 4@use 'sass:list';
5@use 'sass:meta'; 5@use 'sass:meta';
6 6
7@use 'iro-sass/src/index' as iro; 7@use 'iro-sass/src/iro-sass' as iro;
8@use 'iro-sass/src/easing' as easing; 8@use 'iro-sass/src/easing';
9@use 'functions/colors' as iro-colors; 9@use 'apca';
10@use 'palettes'; 10@use 'themes';
11
12@function font-prop($data, $overrides, $key, $prop) {
13 @if (map.has-key($overrides, $prop)) {
14 @return map.get($overrides, $prop);
15 } @else if (map.has-key($data, $prop)) {
16 @return global-dim(--font $key $prop);
17 }
18 @return null;
19}
20
21@function set-font($key, $overrides: ()) {
22 $font: iro.props-get-static(list.join(--dims --font, $key), $global: true);
23
24 $map: (
25 font-family: font-prop($font, $overrides, $key, --family),
26 font-size: font-prop($font, $overrides, $key, --size),
27 font-weight: font-prop($font, $overrides, $key, --weight),
28 font-style: font-prop($font, $overrides, $key, --style),
29 line-height: font-prop($font, $overrides, $key, --line-height),
30 text-transform: font-prop($font, $overrides, $key, --transform),
31 letter-spacing: font-prop($font, $overrides, $key, --spacing),
32 font-variant-alternates: font-prop($font, $overrides, $key, --variant-alternates),
33 font-feature-settings: font-prop($font, $overrides, $key, --feature-settings),
34 );
35
36 @return $map;
37}
38 11
39@function palette($base-color, $contrasts, $chroma-range: 1, $ref-color: $base-color) { 12@function palette($base-color, $contrasts, $chroma-range: 1, $ref-color: $base-color) {
40 $base-lch: color.to-space($base-color, oklch); 13 $base-lch: color.to-space($base-color, oklch);
41 $ref-lch: color.to-space($ref-color, oklch); 14 $ref-lch: color.to-space($ref-color, oklch);
42 15
43 $ref-l: color.channel($ref-lch, 'lightness'); 16 $ref-l: color.channel($ref-lch, 'lightness');
44 $ref-y: iro-colors.apca_sRGB_to_Y($ref-lch); 17 $ref-y: apca.sRGB_to_Y($ref-lch);
45 18
46 $cmax: math.max(map.values($contrasts)...); 19 $cmax: math.max(map.values($contrasts)...);
47 $cmax: math.max($cmax, math.abs(math.min(map.values($contrasts)...))); 20 $cmax: math.max($cmax, math.abs(math.min(map.values($contrasts)...)));
48 21
49 $black-y: iro-colors.apca_sRGB_to_Y(#000); 22 $black-y: apca.sRGB_to_Y(#000);
50 $white-y: iro-colors.apca_sRGB_to_Y(#fff); 23 $white-y: apca.sRGB_to_Y(#fff);
51 24
52 $chroma-inv: false; 25 $chroma-inv: false;
53 @if $chroma-range < 0 { 26 @if $chroma-range < 0 {
54 $chroma-inv: true; 27 $chroma-inv: true;
55 $chroma-range: -1 * $chroma-range; 28 $chroma-range: -1 * $chroma-range;
56 } 29 }
57 $chroma-easing: meta.get-function(palettes.$palette-chroma-easing, $module: easing); 30 $chroma-easing: meta.get-function(themes.$palette-chroma-easing, $module: easing);
58 31
59 $palette: (); 32 $palette: ();
60 33
61 @each $key, $contrast in $contrasts { 34 @each $key, $contrast in $contrasts {
62 $y: iro-colors.apcaReverse($contrast, $ref-y); 35 $y: apca.reverse($contrast, $ref-y);
63 $l: color.channel($base-lch, 'lightness'); 36 $l: color.channel($base-lch, 'lightness');
64 $c: 1; 37 $c: 1;
65 38
66 @if $y != false { 39 @if $y != false {
67 $l: color.channel(iro-colors.apca_Y_to_sRGB($y), 'lightness', oklch); 40 $l: color.channel(apca.Y_to_sRGB($y), 'lightness', oklch);
68 } @else { 41 } @else {
69 $y: $ref-y; 42 $y: $ref-y;
70 } 43 }
@@ -80,8 +53,8 @@
80 53
81 $color: oklch($l ($c * color.channel($base-lch, 'chroma')) color.channel($base-lch, 'hue')); 54 $color: oklch($l ($c * color.channel($base-lch, 'chroma')) color.channel($base-lch, 'hue'));
82 55
83 $contrast-black: iro-colors.apcaContrast($black-y, $y); 56 $contrast-black: apca.contrast($black-y, $y);
84 $contrast-white: iro-colors.apcaContrast($white-y, $y); 57 $contrast-white: apca.contrast($white-y, $y);
85 58
86 $palette: map.set($palette, $key, $color); 59 $palette: map.set($palette, $key, $color);
87 $palette: map.set($palette, #{$key}-text, if(math.abs($contrast-black) > math.abs($contrast-white), #000, #fff)); 60 $palette: map.set($palette, #{$key}-text, if(math.abs($contrast-black) > math.abs($contrast-white), #000, #fff));
diff --git a/src/_iro-design.scss b/src/_iro-design.scss
new file mode 100644
index 0000000..f0f1e50
--- /dev/null
+++ b/src/_iro-design.scss
@@ -0,0 +1,40 @@
1$breakpoints: (
2 lg: 1340px,
3 md: 900px,
4 sm: 620px,
5 xs: 400px,
6) !default;
7
8@forward 'include-media/dist/include-media' as media--* with (
9 $breakpoints: $breakpoints !default,
10 $unit-intervals: (
11 'px': 1,
12 'em': .01,
13 'rem': .01,
14 '': 0
15 ) !default,
16);
17
18@forward 'iro-sass/src/responsive' as iro-responsive--* with (
19 $named-viewports: $breakpoints !default
20);
21
22@forward 'vars' as vars--*;
23
24@forward 'layouts/button-group' as l-button-group--*;
25@forward 'layouts/card-list' as l-card-list--*;
26@forward 'layouts/container' as l-container--*;
27@forward 'layouts/flex' as l-flex--*;
28@forward 'layouts/form' as l-form--*;
29@forward 'layouts/media' as l-media--*;
30@forward 'layouts/overflow' as l-overflow--*;
31
32@forward 'scopes/implicit' as s-implicit--*;
33@forward 'scopes/blockquotes' as s-blockquotes--*;
34@forward 'scopes/code' as s-code--*;
35//@use 'scopes/headings' as s-headings--*;
36@forward 'scopes/links' as s-links--*;
37@forward 'scopes/lists' as s-lists--*;
38//@use 'scopes/tables' as s-tables--*;
39
40@forward 'objects/action-button' as o-action-button--*;
diff --git a/src/_mixins.scss b/src/_mixins.scss
new file mode 100644
index 0000000..49d3b6f
--- /dev/null
+++ b/src/_mixins.scss
@@ -0,0 +1,38 @@
1@use 'sass:list';
2@use 'functions' as fn;
3
4@mixin set-font($basis, $values: ()) {
5 $values: fn.set-font($basis, $values);
6
7 @each $prop, $value in $values {
8 @if $value != null {
9 #{$prop}: $value;
10 }
11 }
12}
13
14@mixin heading-strong($size) {
15 font-size: fn.global-dim(list.join(--heading, $size));
16 color: fn.global-color(--heading);
17}
18
19@mixin heading-medium($size) {
20 @include set-font(--standard, (
21 --line-height: null,
22 --size: fn.global-dim(list.join(--heading, $size)),
23 --weight: bold
24 ));
25
26 color: fn.global-color(--heading);
27}
28
29@mixin heading-faint($size) {
30 @include set-font(--standard, (
31 --line-height: null,
32 --size: fn.global-dim(list.join(--heading, $size)),
33 --weight: 500,
34 --spacing: 1px
35 ));
36
37 color: fn.global-color(--text-mute);
38}
diff --git a/src/_props.scss b/src/_props.scss
index f7f54c5..ac1dfd5 100644
--- a/src/_props.scss
+++ b/src/_props.scss
@@ -1,105 +1,40 @@
1@use 'sass:list'; 1@use 'sass:list';
2@use 'sass:map'; 2@use 'sass:map';
3@use 'sass:meta'; 3@use 'sass:meta';
4@use 'themes';
5@use 'include-media/dist/include-media' as media;
6@use 'iro-sass/src/iro-sass' as iro;
4 7
5@use 'iro-sass/src/functions' as functions; 8@forward 'iro-sass/src/props';
6 9
7@function is-prop-ref($value) { 10@mixin materialize($ref) {
8 @if meta.type-of($value) != 'list' { 11 @if meta.type-of($ref) == 'map' {
9 @return false; 12 $ref: map.values($ref);
10 } 13 }
11 @if list.length($value) != 3 {
12 @return false;
13 }
14 @if list.nth($value, 1) != 'prop-ref' {
15 @return false;
16 }
17 @return true;
18}
19
20@function def($name, $value: ()) {
21 @return ('prop-ref' $name $value);
22}
23
24@function merge($ref, $value) {
25 @if not is-prop-ref($ref) {
26 @return $ref;
27 }
28
29 $v: list.nth($ref, 3);
30 $ref: list.set-nth($ref, 3, map.deep-merge($v, $value));
31 @return $ref;
32}
33
34@function get-deep($name, $value, $key: (), $keys...) {
35 @if is-prop-ref($value) {
36 // $value: list.nth($value, 3);
37 @return get($value, $key, $keys);
38 }
39 @if meta.type-of($value) == 'map' {
40 @if list.length($keys) == 0 {
41 @return #{$name}#{$key} map.get($value, $key);
42 } @else {
43 @return get-deep(#{$name}#{$key}, map.get($value, $key), $keys...);
44 }
45 }
46 @return $name $value;
47}
48 14
49@function map-to-vars($name, $map) { 15 :root {
50 @if meta.type-of($map) != 'map' { 16 @include iro.props-materialize($ref);
51 @return var($name);
52 }
53
54 $out: ();
55
56 @each $key, $value in $map {
57 $out: map.set($out, $key, map-to-vars(#{$name}#{$key}, $value));
58 }
59
60 @return $out;
61}
62
63@function get($ref, $key: (), $keys...) {
64 @if not is-prop-ref($ref) {
65 @return $ref;
66 }
67
68 $name: list.nth($ref, 2);
69 $value: get(list.nth($ref, 3));
70 17
71 @if meta.type-of($value) == 'map' { 18 @each $breakpoint in map.keys(media.$breakpoints) {
72 $res: get-deep($name, $value, $key, $keys...); 19 @include media.media('<=#{$breakpoint}') {
73 $name: list.nth($res, 1); 20 @include iro.props-materialize($ref, $breakpoint);
74 $value: list.nth($res, 2); 21 }
75 } @else if meta.type-of($value) == 'list' {
76 $i: 1;
77 @each $item in $value {
78 $value: list.set-nth($value, $i, get($item));
79 $i: $i + 1;
80 } 22 }
81 }
82 23
83 @return map-to-vars($name, $value); 24 @media (prefers-color-scheme: dark) {
84} 25 @include iro.props-materialize($ref, 'dark');
85
86@mixin declare-helper($name, $value) {
87 @if meta.type-of($value) == 'map' {
88 @each $key, $value in $value {
89 @include declare-helper(#{$name}#{$key}, $value);
90 } 26 }
91 } @else {
92 #{$name}: #{$value};
93 } 27 }
94}
95
96@mixin materialize($refs) {
97 @each $ref in $refs {
98 @if is-prop-ref($ref) {
99 $name: list.nth($ref, 2);
100 $value: get(list.nth($ref, 3));
101 28
102 @include declare-helper($name, $value); 29 @each $theme-name in map.keys(themes.$themes) {
30 @if $theme-name != themes.$theme-default {
31 @include iro.bem-theme($theme-name) {
32 @include iro.props-materialize($ref);
33
34 @media (prefers-color-scheme: dark) {
35 @include iro.props-materialize($ref, 'dark');
36 }
37 }
103 } 38 }
104 } 39 }
105} 40}
diff --git a/src/_palettes.scss b/src/_themes.scss
index f8c5b23..a90d049 100644
--- a/src/_palettes.scss
+++ b/src/_themes.scss
@@ -1,31 +1,9 @@
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 'include-media/dist/include-media' as media;
8 6
9iro.$vars-root-size: 16px;
10
11media.$breakpoints: (
12 lg: 1340px,
13 md: 900px,
14 sm: 620px,
15 xs: 400px,
16);
17
18media.$unit-intervals: (
19 'px': 1,
20 'em': .01,
21 'rem': .01,
22 '': 0
23);
24
25res.$named-viewports: media.$breakpoints;
26
27$palette-precision: .01 !default;
28
29$palette-chroma-easing: 'ease' !default; 7$palette-chroma-easing: 'ease' !default;
30 8
31$static-colors-override: () !default; 9$static-colors-override: () !default;
@@ -227,8 +205,10 @@ $theme-dark: map.deep-merge((
227 205
228$themes-override: () !default; 206$themes-override: () !default;
229$themes: map.deep-merge(( 207$themes: map.deep-merge((
230 light: $theme-light, 208 main: (
231 dark: $theme-dark, 209 light: $theme-light,
210 dark: $theme-dark,
211 )
232), $themes-override) !default; 212), $themes-override) !default;
233 213
234$theme-default: list.nth(map.keys($themes), 1) !default; 214$theme-default: list.nth(map.keys($themes), 1) !default;
diff --git a/src/_vars.scss b/src/_vars.scss
index aaa38a0..78ead7c 100644
--- a/src/_vars.scss
+++ b/src/_vars.scss
@@ -1,199 +1,33 @@
1@use 'sass:map'; 1@use 'sass:map';
2@use 'sass:meta'; 2@use 'sass:meta';
3@use 'sass:list'; 3@use 'iro-sass/src/props';
4@use 'iro-sass/src/index' as iro; 4@use 'themes';
5@use 'include-media/dist/include-media' as media; 5
6@use 'functions' as fn; 6@use 'vars.vars' as vars;
7@use 'palettes'; 7@forward 'vars.vars';
8@use 'props'; 8
9 9@mixin vars {
10$size--0: props.def(--size--0, 0) !default; 10 @each $theme-name, $theme in vars.$themes {
11$size--10: props.def(--size--10, iro.fn-px-to-rem(1px)) !default; 11 @if $theme-name == themes.$theme-default {
12$size--25: props.def(--size--25, iro.fn-px-to-rem(2px)) !default; 12 :root {
13$size--40: props.def(--size--40, iro.fn-px-to-rem(3px)) !default; 13 @include props.materialize(map.get($theme, 'light'));
14$size--50: props.def(--size--50, iro.fn-px-to-rem(4px)) !default; 14
15$size--65: props.def(--size--65, iro.fn-px-to-rem(5px)) !default; 15 @if map.has-key($theme, 'dark') {
16$size--75: props.def(--size--75, iro.fn-px-to-rem(6px)) !default; 16 @media (prefers-color-scheme: dark) {
17$size--85: props.def(--size--85, iro.fn-px-to-rem(7px)) !default; 17 @include props.materialize(map.get($theme, 'dark'));
18$size--100: props.def(--size--100, iro.fn-px-to-rem(8px)) !default; 18 }
19$size--115: props.def(--size--115, iro.fn-px-to-rem(9px)) !default;
20$size--125: props.def(--size--125, iro.fn-px-to-rem(10px)) !default;
21$size--130: props.def(--size--130, iro.fn-px-to-rem(11px)) !default;
22$size--150: props.def(--size--150, iro.fn-px-to-rem(12px)) !default;
23$size--160: props.def(--size--160, iro.fn-px-to-rem(13px)) !default;
24$size--175: props.def(--size--175, iro.fn-px-to-rem(14px)) !default;
25$size--200: props.def(--size--200, iro.fn-px-to-rem(16px)) !default;
26$size--225: props.def(--size--225, iro.fn-px-to-rem(18px)) !default;
27$size--250: props.def(--size--250, iro.fn-px-to-rem(20px)) !default;
28$size--275: props.def(--size--275, iro.fn-px-to-rem(22px)) !default;
29$size--300: props.def(--size--300, iro.fn-px-to-rem(24px)) !default;
30$size--325: props.def(--size--325, iro.fn-px-to-rem(26px)) !default;
31$size--350: props.def(--size--350, iro.fn-px-to-rem(28px)) !default;
32$size--375: props.def(--size--375, iro.fn-px-to-rem(30px)) !default;
33$size--400: props.def(--size--400, iro.fn-px-to-rem(32px)) !default;
34$size--450: props.def(--size--450, iro.fn-px-to-rem(36px)) !default;
35$size--500: props.def(--size--500, iro.fn-px-to-rem(40px)) !default;
36$size--550: props.def(--size--550, iro.fn-px-to-rem(44px)) !default;
37$size--600: props.def(--size--600, iro.fn-px-to-rem(48px)) !default;
38$size--650: props.def(--size--650, iro.fn-px-to-rem(52px)) !default;
39$size--700: props.def(--size--700, iro.fn-px-to-rem(56px)) !default;
40$size--800: props.def(--size--800, iro.fn-px-to-rem(64px)) !default;
41$size--900: props.def(--size--900, iro.fn-px-to-rem(72px)) !default;
42$size--1000: props.def(--size--1000, iro.fn-px-to-rem(80px)) !default;
43$size--1200: props.def(--size--1200, iro.fn-px-to-rem(96px)) !default;
44$size--1600: props.def(--size--1600, iro.fn-px-to-rem(128px)) !default;
45$size--2000: props.def(--size--2000, iro.fn-px-to-rem(160px)) !default;
46$size--2400: props.def(--size--2400, iro.fn-px-to-rem(192px)) !default;
47$size--2500: props.def(--size--2500, iro.fn-px-to-rem(200px)) !default;
48$size--2600: props.def(--size--2600, iro.fn-px-to-rem(208px)) !default;
49$size--2800: props.def(--size--2800, iro.fn-px-to-rem(224px)) !default;
50$size--3200: props.def(--size--3200, iro.fn-px-to-rem(256px)) !default;
51$size--3400: props.def(--size--3400, iro.fn-px-to-rem(272px)) !default;
52$size--3500: props.def(--size--3500, iro.fn-px-to-rem(280px)) !default;
53$size--3600: props.def(--size--3600, iro.fn-px-to-rem(288px)) !default;
54$size--3800: props.def(--size--3800, iro.fn-px-to-rem(304px)) !default;
55$size--4600: props.def(--size--4600, iro.fn-px-to-rem(368px)) !default;
56$size--5000: props.def(--size--5000, iro.fn-px-to-rem(400px)) !default;
57$size--6000: props.def(--size--6000, iro.fn-px-to-rem(480px)) !default;
58
59$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;
60$font--standard--line-height: props.def(--font--standard--line-height, 1.5) !default;
61$font--standard--feature-settings: props.def(--font--standard--feature-settings, ('\'ss01\'')) !default;
62
63$font--headline--family: props.def(--font--headline--family, ('Inter', props.get($font--standard--family))) !default;
64$font--headline--line-height: props.def(--font--headline--line-height, 1.3) !default;
65$font--headline--weight: props.def(--font--headline--weight, 800) !default;
66$font--headline--feature-settings: props.def(--font--headline--feature-settings, ('\'opsz\'' 32, '\'ss01\'', '\'cv06\'')) !default;
67
68$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;
69$font--mono--line-height: props.def(--font--mono--line-height, 1.4) !default;
70
71$font-size--50: props.def(--font-size--50, iro.fn-px-to-rem(12px)) !default;
72$font-size--75: props.def(--font-size--75 , iro.fn-px-to-rem(13px)) !default;
73$font-size--100: props.def(--font-size--100, iro.fn-px-to-rem(14px)) !default;
74$font-size--150: props.def(--font-size--150, iro.fn-px-to-rem(16px)) !default;
75$font-size--200: props.def(--font-size--200, iro.fn-px-to-rem(18px)) !default;
76$font-size--300: props.def(--font-size--300, iro.fn-px-to-rem(20px)) !default;
77$font-size--400: props.def(--font-size--400, iro.fn-px-to-rem(24px)) !default;
78$font-size--500: props.def(--font-size--500, iro.fn-px-to-rem(28px)) !default;
79$font-size--600: props.def(--font-size--600, iro.fn-px-to-rem(32px)) !default;
80$font-size--700: props.def(--font-size--700, iro.fn-px-to-rem(36px)) !default;
81$font-size--800: props.def(--font-size--800, iro.fn-px-to-rem(40px)) !default;
82$font-size--900: props.def(--font-size--900, iro.fn-px-to-rem(45px)) !default;
83$font-size--1000: props.def(--font-size--1000, iro.fn-px-to-rem(50px)) !default;
84$font-size--1100: props.def(--font-size--1100, iro.fn-px-to-rem(60px)) !default;
85
86$border-width--thick: props.def(--border-width--thick, 4px) !default;
87$border-width--medium: props.def(--border-width--medium, 2px) !default;
88$border-width--thin: props.def(--border-width--thin, 1px) !default;
89
90$shadow--x: props.def(--shadow--x, 0) !default;
91$shadow--y: props.def(--shadow--y, 1px) !default;
92$shadow--blur: props.def(--shadow--blur, 4px) !default;
93
94$rounding: props.def(--rounding, 4px) !default;
95
96$key-focus--outline-width: props.def(--key-focus--outline-width, props.get($border-width--thick)) !default;
97$key-focus--border: props.def(--key-focus--border, props.get($border-width--medium)) !default;
98$key-focus--border-offset: props.def(--key-focus--border-offset, props.get($border-width--medium)) !default;
99
100$paragraph--margin-bs: props.def(--paragraph--margin-bs, props.get($size--300)) !default;
101
102$heading--margin-bs: props.def(--heading--margin-bs, props.get($size--700)) !default;
103$heading--margin-bs-sibling: props.def(--heading--margin-bs-sibling, props.get($size--325)) !default;
104$heading--xxl: props.def(--heading--xxl, props.get($font-size--300)) !default;
105$heading--xl: props.def(--heading--xl, props.get($font-size--200)) !default;
106$heading--lg: props.def(--heading--lg, props.get($font-size--150)) !default;
107$heading--md: props.def(--heading--md, props.get($font-size--100)) !default;
108$heading--sm: props.def(--heading--sm, props.get($font-size--75)) !default;
109$heading--xs: props.def(--heading--xs, props.get($font-size--50)) !default;
110$heading--display--xxl: props.def(--heading--display--xxl, props.get($font-size--1100)) !default;
111$heading--display--xl: props.def(--heading--display--xl, props.get($font-size--700)) !default;
112$heading--display--lg: props.def(--heading--display--lg, props.get($font-size--300)) !default;
113$heading--display--md: props.def(--heading--display--md, props.get($font-size--150)) !default;
114$heading--display--sm: props.def(--heading--display--sm, props.get($font-size--75)) !default;
115$heading--display--xs: props.def(--heading--display--xs, props.get($font-size--50)) !default;
116$heading--display-sm--xxl: props.def(--heading--display-sm--xxl, props.get($font-size--900)) !default;
117$heading--display-sm--xl: props.def(--heading--display-sm--xl, props.get($font-size--600)) !default;
118$heading--display-sm--lg: props.def(--heading--display-sm--lg, props.get($font-size--200)) !default;
119$heading--display-sm--md: props.def(--heading--display-sm--md, props.get($font-size--100)) !default;
120$heading--display-sm--sm: props.def(--heading--display-sm--sm, props.get($font-size--75)) !default;
121$heading--display-sm--xs: props.def(--heading--display-sm--xs, props.get($font-size--50)) !default;
122
123$list--indent: props.def(--list--indent, props.get($size--400)) !default;
124$list--compact-indent: props.def(--list--indent, props.get($size--250)) !default;
125
126//
127
128$static-colors: props.def(--static-colors);
129@each $palette-name, $palette in map.get(palettes.$static-colors, --palettes) {
130 $palette: fn.palette($palette, map.get(palettes.$static-colors, --contrasts), 1, map.get(palettes.$static-colors, --base));
131 $static-colors: props.merge($static-colors, ( $palette-name: $palette ));
132}
133
134//
135
136$transparent-colors: props.def(--transparent-colors);
137@each $palette-name, $palette in (--black: #000 #fff, --white: #fff #000) {
138 $color: list.nth($palette, 1);
139 $text: list.nth($palette, 2);
140
141 $palette: fn.transparent-palette($color, $text, map.get(palettes.$static-colors, --transparents));
142 $transparent-colors: props.merge($transparent-colors, ( $palette-name: $palette ));
143}
144
145//
146
147$themes: props.def(--themes);
148@each $theme-name, $theme in palettes.$themes {
149 $themes: props.merge($themes, ( --#{$theme-name}: () ));
150
151 @each $palette-name, $palette in map.get($theme, --palettes) {
152 $base-color: list.nth($palette, 1);
153 $contrasts: list.nth($palette, 2);
154 $ranges: list.nth($palette, 3);
155
156 $palette: fn.palette($base-color, map.get($theme, --contrasts, $contrasts), map.get($theme, --ranges, $ranges), list.nth(map.get($theme, --palettes, --base), 1));
157 $themes: props.merge($themes, ( --#{$theme-name}: ( $palette-name: $palette ) ));
158 }
159
160 @each $color, $value in map.get($theme, --constants) {
161 $themes: props.merge($themes, ( --#{$theme-name}: ( $color: $value ) ));
162 }
163
164 @each $color, $ref in map.get($theme, --semantic) {
165 $res: ();
166
167 @if meta.type-of($ref) == 'map' {
168 @each $key, $r in $ref {
169 $repo-name: list.nth($r, 1);
170 $re1: list.nth($r, 2);
171 $re2: iro.fn-list-slice($r, 3);
172
173 $res2: null;
174
175 @if $repo-name == --static {
176 $res2: props.get($static-colors, $re1, $re2...);
177 } @else {
178 $res2: props.get($themes, --#{$theme-name}, $re1, $re2...);
179 } 19 }
180
181 $res: map.merge($res, ($key: $res2));
182 } 20 }
183 } @else { 21 } @else {
184 $repo-name: list.nth($ref, 1); 22 @include iro.bem-theme($theme-name) {
185 $ref1: list.nth($ref, 2); 23 @include props.materialize(map.get($theme, 'light'));
186 $ref2: iro.fn-list-slice($ref, 3); 24
187 25 @if map.has-key($theme, 'dark') {
188 $res: null; 26 @media (prefers-color-scheme: dark) {
189 27 @include props.materialize(map.get($theme, 'dark'));
190 @if $repo-name == --static { 28 }
191 $res: props.get($static-colors, $ref1, $ref2...); 29 }
192 } @else {
193 $res: props.get($themes, --#{$theme-name}, $ref1, $ref2...);
194 } 30 }
195 } 31 }
196
197 $themes: props.merge($themes, ( --#{$theme-name}: ( $color: $res ) ));
198 } 32 }
199} 33}
diff --git a/src/_vars.vars.scss b/src/_vars.vars.scss
new file mode 100644
index 0000000..cc11b89
--- /dev/null
+++ b/src/_vars.vars.scss
@@ -0,0 +1,203 @@
1@use 'sass:map';
2@use 'sass:meta';
3@use 'sass:list';
4@use 'iro-sass/src/iro-sass' as iro;
5@use 'functions' as fn;
6@use 'themes';
7@use 'props';
8
9$size--0: props.def(--size--0, 0) !default;
10$size--10: props.def(--size--10, iro.fn-px-to-rem(1px)) !default;
11$size--25: props.def(--size--25, iro.fn-px-to-rem(2px)) !default;
12$size--40: props.def(--size--40, iro.fn-px-to-rem(3px)) !default;
13$size--50: props.def(--size--50, iro.fn-px-to-rem(4px)) !default;
14$size--65: props.def(--size--65, iro.fn-px-to-rem(5px)) !default;
15$size--75: props.def(--size--75, iro.fn-px-to-rem(6px)) !default;
16$size--85: props.def(--size--85, iro.fn-px-to-rem(7px)) !default;
17$size--100: props.def(--size--100, iro.fn-px-to-rem(8px)) !default;
18$size--115: props.def(--size--115, iro.fn-px-to-rem(9px)) !default;
19$size--125: props.def(--size--125, iro.fn-px-to-rem(10px)) !default;
20$size--130: props.def(--size--130, iro.fn-px-to-rem(11px)) !default;
21$size--150: props.def(--size--150, iro.fn-px-to-rem(12px)) !default;
22$size--160: props.def(--size--160, iro.fn-px-to-rem(13px)) !default;
23$size--175: props.def(--size--175, iro.fn-px-to-rem(14px)) !default;
24$size--200: props.def(--size--200, iro.fn-px-to-rem(16px)) !default;
25$size--225: props.def(--size--225, iro.fn-px-to-rem(18px)) !default;
26$size--250: props.def(--size--250, iro.fn-px-to-rem(20px)) !default;
27$size--275: props.def(--size--275, iro.fn-px-to-rem(22px)) !default;
28$size--300: props.def(--size--300, iro.fn-px-to-rem(24px)) !default;
29$size--325: props.def(--size--325, iro.fn-px-to-rem(26px)) !default;
30$size--350: props.def(--size--350, iro.fn-px-to-rem(28px)) !default;
31$size--375: props.def(--size--375, iro.fn-px-to-rem(30px)) !default;
32$size--400: props.def(--size--400, iro.fn-px-to-rem(32px)) !default;
33$size--450: props.def(--size--450, iro.fn-px-to-rem(36px)) !default;
34$size--500: props.def(--size--500, iro.fn-px-to-rem(40px)) !default;
35$size--550: props.def(--size--550, iro.fn-px-to-rem(44px)) !default;
36$size--600: props.def(--size--600, iro.fn-px-to-rem(48px)) !default;
37$size--650: props.def(--size--650, iro.fn-px-to-rem(52px)) !default;
38$size--700: props.def(--size--700, iro.fn-px-to-rem(56px)) !default;
39$size--800: props.def(--size--800, iro.fn-px-to-rem(64px)) !default;
40$size--900: props.def(--size--900, iro.fn-px-to-rem(72px)) !default;
41$size--1000: props.def(--size--1000, iro.fn-px-to-rem(80px)) !default;
42$size--1200: props.def(--size--1200, iro.fn-px-to-rem(96px)) !default;
43$size--1600: props.def(--size--1600, iro.fn-px-to-rem(128px)) !default;
44$size--2000: props.def(--size--2000, iro.fn-px-to-rem(160px)) !default;
45$size--2400: props.def(--size--2400, iro.fn-px-to-rem(192px)) !default;
46$size--2500: props.def(--size--2500, iro.fn-px-to-rem(200px)) !default;
47$size--2600: props.def(--size--2600, iro.fn-px-to-rem(208px)) !default;
48$size--2800: props.def(--size--2800, iro.fn-px-to-rem(224px)) !default;
49$size--3200: props.def(--size--3200, iro.fn-px-to-rem(256px)) !default;
50$size--3400: props.def(--size--3400, iro.fn-px-to-rem(272px)) !default;
51$size--3500: props.def(--size--3500, iro.fn-px-to-rem(280px)) !default;
52$size--3600: props.def(--size--3600, iro.fn-px-to-rem(288px)) !default;
53$size--3800: props.def(--size--3800, iro.fn-px-to-rem(304px)) !default;
54$size--4600: props.def(--size--4600, iro.fn-px-to-rem(368px)) !default;
55$size--5000: props.def(--size--5000, iro.fn-px-to-rem(400px)) !default;
56$size--6000: props.def(--size--6000, iro.fn-px-to-rem(480px)) !default;
57
58$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;
59$font--standard--line-height: props.def(--font--standard--line-height, 1.5) !default;
60$font--standard--feature-settings: props.def(--font--standard--feature-settings, ('\'ss01\'')) !default;
61
62$font--headline--family: props.def(--font--headline--family, ('Inter', props.get($font--standard--family))) !default;
63$font--headline--line-height: props.def(--font--headline--line-height, 1.3) !default;
64$font--headline--weight: props.def(--font--headline--weight, 800) !default;
65$font--headline--feature-settings: props.def(--font--headline--feature-settings, ('\'opsz\'' 32, '\'ss01\'', '\'cv06\'')) !default;
66
67$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;
68$font--mono--line-height: props.def(--font--mono--line-height, 1.4) !default;
69
70$font-size--50: props.def(--font-size--50, iro.fn-px-to-rem(12px)) !default;
71$font-size--75: props.def(--font-size--75 , iro.fn-px-to-rem(13px)) !default;
72$font-size--100: props.def(--font-size--100, iro.fn-px-to-rem(14px)) !default;
73$font-size--150: props.def(--font-size--150, iro.fn-px-to-rem(16px)) !default;
74$font-size--200: props.def(--font-size--200, iro.fn-px-to-rem(18px)) !default;
75$font-size--300: props.def(--font-size--300, iro.fn-px-to-rem(20px)) !default;
76$font-size--400: props.def(--font-size--400, iro.fn-px-to-rem(24px)) !default;
77$font-size--500: props.def(--font-size--500, iro.fn-px-to-rem(28px)) !default;
78$font-size--600: props.def(--font-size--600, iro.fn-px-to-rem(32px)) !default;
79$font-size--700: props.def(--font-size--700, iro.fn-px-to-rem(36px)) !default;
80$font-size--800: props.def(--font-size--800, iro.fn-px-to-rem(40px)) !default;
81$font-size--900: props.def(--font-size--900, iro.fn-px-to-rem(45px)) !default;
82$font-size--1000: props.def(--font-size--1000, iro.fn-px-to-rem(50px)) !default;
83$font-size--1100: props.def(--font-size--1100, iro.fn-px-to-rem(60px)) !default;
84
85$border-width--thick: props.def(--border-width--thick, 4px) !default;
86$border-width--medium: props.def(--border-width--medium, 2px) !default;
87$border-width--thin: props.def(--border-width--thin, 1px) !default;
88
89$shadow--x: props.def(--shadow--x, 0) !default;
90$shadow--y: props.def(--shadow--y, 1px) !default;
91$shadow--blur: props.def(--shadow--blur, 4px) !default;
92
93$rounding: props.def(--rounding, 4px) !default;
94
95$key-focus--outline-width: props.def(--key-focus--outline-width, props.get($border-width--thick)) !default;
96$key-focus--border-width: props.def(--key-focus--border-width, props.get($border-width--medium)) !default;
97$key-focus--border-offset: props.def(--key-focus--border-offset, props.get($border-width--medium)) !default;
98
99$heading--xxl: props.def(--heading--xxl, props.get($font-size--300)) !default;
100$heading--xl: props.def(--heading--xl, props.get($font-size--200)) !default;
101$heading--lg: props.def(--heading--lg, props.get($font-size--150)) !default;
102$heading--md: props.def(--heading--md, props.get($font-size--100)) !default;
103$heading--sm: props.def(--heading--sm, props.get($font-size--75)) !default;
104$heading--xs: props.def(--heading--xs, props.get($font-size--50)) !default;
105$heading--display--xxl: props.def(--heading--display--xxl, props.get($font-size--1100)) !default;
106$heading--display--xl: props.def(--heading--display--xl, props.get($font-size--700)) !default;
107$heading--display--lg: props.def(--heading--display--lg, props.get($font-size--300)) !default;
108$heading--display--md: props.def(--heading--display--md, props.get($font-size--150)) !default;
109$heading--display--sm: props.def(--heading--display--sm, props.get($font-size--75)) !default;
110$heading--display--xs: props.def(--heading--display--xs, props.get($font-size--50)) !default;
111$heading--display-sm--xxl: props.def(--heading--display-sm--xxl, props.get($font-size--900)) !default;
112$heading--display-sm--xl: props.def(--heading--display-sm--xl, props.get($font-size--600)) !default;
113$heading--display-sm--lg: props.def(--heading--display-sm--lg, props.get($font-size--200)) !default;
114$heading--display-sm--md: props.def(--heading--display-sm--md, props.get($font-size--100)) !default;
115$heading--display-sm--sm: props.def(--heading--display-sm--sm, props.get($font-size--75)) !default;
116$heading--display-sm--xs: props.def(--heading--display-sm--xs, props.get($font-size--50)) !default;
117
118$list--indent: props.def(--list--indent, props.get($size--400)) !default;
119$list--compact-indent: props.def(--list--indent, props.get($size--250)) !default;
120
121//
122
123$static-colors: props.def(--static-colors);
124
125@each $palette-name, $palette in map.get(themes.$static-colors, --palettes) {
126 $palette: fn.palette($palette, map.get(themes.$static-colors, --contrasts), 1, map.get(themes.$static-colors, --base));
127 $static-colors: props.merge($static-colors, ( $palette-name: $palette ));
128}
129
130//
131
132$transparent-colors: props.def(--transparent-colors);
133
134@each $palette-name, $palette in (--black: #000 #fff, --white: #fff #000) {
135 $color: list.nth($palette, 1);
136 $text: list.nth($palette, 2);
137
138 $palette: fn.transparent-palette($color, $text, map.get(themes.$static-colors, --transparents));
139 $transparent-colors: props.merge($transparent-colors, ( $palette-name: $palette ));
140}
141
142//
143
144$themes: ();
145
146@each $theme-name, $theme in themes.$themes {
147 @each $variant-name, $variant in $theme {
148 $compiled: props.def(--colors);
149
150 @each $palette-name, $palette in map.get($variant, --palettes) {
151 $base-color: list.nth($palette, 1);
152 $contrasts: list.nth($palette, 2);
153 $ranges: list.nth($palette, 3);
154
155 $palette: fn.palette($base-color, map.get($variant, --contrasts, $contrasts), map.get($variant, --ranges, $ranges), list.nth(map.get($variant, --palettes, --base), 1));
156 $compiled: props.merge($compiled, ( $palette-name: $palette ));
157 }
158
159 @each $color, $value in map.get($variant, --constants) {
160 $compiled: props.merge($compiled, ( $color: $value ));
161 }
162
163 @each $color, $ref in map.get($variant, --semantic) {
164 $res: ();
165
166 @if meta.type-of($ref) == 'map' {
167 @each $key, $r in $ref {
168 $repo-name: list.nth($r, 1);
169 $re1: list.nth($r, 2);
170 $re2: iro.fn-list-slice($r, 3);
171
172 $res2: null;
173
174 @if $repo-name == --static {
175 $res2: props.get($static-colors, $re1, $re2...);
176 } @else {
177 $res2: props.get($compiled, $re1, $re2...);
178 }
179
180 $res: map.merge($res, ($key: $res2));
181 }
182 } @else {
183 $repo-name: list.nth($ref, 1);
184 $ref1: list.nth($ref, 2);
185 $ref2: iro.fn-list-slice($ref, 3);
186
187 $res: null;
188
189 @if $repo-name == --static {
190 $res: props.get($static-colors, $ref1, $ref2...);
191 } @else {
192 $res: props.get($compiled, $ref1, $ref2...);
193 }
194 }
195
196 $compiled: props.merge($compiled, ( $color: $res ));
197 }
198
199 $themes: map.set($themes, $theme-name, $variant-name, $compiled);
200 }
201}
202
203$theme: map.get($themes, themes.$theme-default, light) !default;
diff --git a/src/functions/colors/_index.scss b/src/functions/colors/_index.scss
deleted file mode 100644
index 9dad0f9..0000000
--- a/src/functions/colors/_index.scss
+++ /dev/null
@@ -1 +0,0 @@
1@forward 'apca';
diff --git a/src/index.scss b/src/index.scss
deleted file mode 100644
index 5c2a1e8..0000000
--- a/src/index.scss
+++ /dev/null
@@ -1,11 +0,0 @@
1@use 'sass:map';
2@use 'sass:meta';
3
4@use 'props';
5@use 'vars';
6
7$vars: map.values(meta.module-variables('vars'));
8
9:root {
10 @include props.materialize($vars);
11}
diff --git a/src/layouts/_button-group.scss b/src/layouts/_button-group.scss
new file mode 100644
index 0000000..95b63c9
--- /dev/null
+++ b/src/layouts/_button-group.scss
@@ -0,0 +1,16 @@
1@use 'sass:meta';
2@use 'iro-sass/src/iro-sass' as iro;
3@use '../props';
4
5@forward 'button-group.vars';
6@use 'button-group.vars' as vars;
7
8@mixin styles {
9 @include props.materialize(meta.module-variables('vars'));
10
11 @include iro.bem-layout('button-group') {
12 display: flex;
13 flex-wrap: wrap;
14 gap: props.get(vars.$spacing);
15 }
16}
diff --git a/src/layouts/_button-group.vars.scss b/src/layouts/_button-group.vars.scss
new file mode 100644
index 0000000..ac57b44
--- /dev/null
+++ b/src/layouts/_button-group.vars.scss
@@ -0,0 +1,4 @@
1@use '../props';
2@use '../vars';
3
4$spacing: props.def(--l-button-group--spacing, props.get(vars.$size--150)) !default;
diff --git a/src/layouts/_card-list.scss b/src/layouts/_card-list.scss
new file mode 100644
index 0000000..1aea7bc
--- /dev/null
+++ b/src/layouts/_card-list.scss
@@ -0,0 +1,76 @@
1@use 'sass:meta';
2@use 'include-media/dist/include-media' as media;
3@use 'iro-sass/src/iro-sass' as iro;
4@use '../props';
5
6@forward 'card-list.vars';
7@use 'card-list.vars' as vars;
8
9@mixin styles {
10 @include props.materialize(meta.module-variables('vars'));
11
12 @include iro.bem-layout('card-list') {
13 display: flex;
14 flex-direction: column;
15 gap: props.get(vars.$row-gap) props.get(vars.$col-gap);
16
17 @include iro.bem-modifier('grid') {
18 display: grid;
19 grid-template-columns: repeat(auto-fill, minmax(props.get(vars.$grid--col-width), 1fr));
20 gap: props.get(vars.$grid--col-gap);
21
22 @include iro.bem-modifier('quiet') {
23 row-gap: props.get(vars.$grid--row-gap);
24 }
25 }
26
27 @include iro.bem-modifier('masonry') {
28 display: block;
29 columns: auto props.get(vars.$masonry--col-width);
30 column-gap: props.get(vars.$masonry--col-gap);
31
32 @include iro.bem-elem('card') {
33 margin-block-end: props.get(vars.$masonry--col-gap);
34 break-inside: avoid;
35 }
36
37 @include iro.bem-modifier('quiet') {
38 @include iro.bem-elem('card') {
39 margin-block-end: props.get(vars.$masonry--row-gap);
40 }
41 }
42 }
43
44 @include iro.bem-modifier('masonry-h') {
45 flex-flow: row wrap;
46 gap: props.get(vars.$masonry-h--col-gap);
47
48 &::after {
49 display: block;
50 flex: 1 0 auto;
51 inline-size: props.get(vars.$masonry-h--row-height);
52 block-size: 0;
53 content: '';
54 }
55
56 @include iro.bem-elem('card') {
57 flex: 1 0 auto;
58 max-inline-size: 100%;
59 }
60
61 @include iro.bem-elem('card-image') {
62 block-size: props.get(vars.$masonry-h--row-height);
63 }
64
65 @include iro.bem-modifier('quiet') {
66 row-gap: props.get(vars.$masonry-h--row-gap);
67 }
68 }
69
70 @include iro.bem-modifier('aspect-5\\/4') {
71 @include iro.bem-elem('card-image') {
72 aspect-ratio: 5 / 4;
73 }
74 }
75 }
76}
diff --git a/src/layouts/_card-list.vars.scss b/src/layouts/_card-list.vars.scss
new file mode 100644
index 0000000..b3aaac4
--- /dev/null
+++ b/src/layouts/_card-list.vars.scss
@@ -0,0 +1,19 @@
1@use '../props';
2@use '../vars';
3
4$row-gap: props.def(--l-card-list--row-gap, props.get(vars.$size--800)) !default;
5$col-gap: props.def(--l-card-list--col-gap, props.get(vars.$size--400)) !default;
6
7$grid--row-gap: props.def(--l-card-list--grid--row-gap, props.get(vars.$size--800)) !default;
8$grid--col-gap: props.def(--l-card-list--grid--col-gap, props.get(vars.$size--400)) !default;
9$grid--col-width: props.def(--l-card-list--grid--col-width, props.get(vars.$size--3200)) !default;
10
11$masonry--row-gap: props.def(--l-card-list--masonry--row-gap, props.get(vars.$size--800)) !default;
12$masonry--col-gap: props.def(--l-card-list--masonry--col-gap, props.get(vars.$size--400)) !default;
13$masonry--col-width: props.def(--l-card-list--masonry--col-width, props.get(vars.$size--3200)) !default;
14
15$masonry-h--row-gap: props.def(--l-card-list--masonry-h--row-gap, props.get(vars.$size--800)) !default;
16$masonry-h--col-gap: props.def(--l-card-list--masonry-h--col-gap, props.get(vars.$size--400)) !default;
17$masonry-h--row-height: props.def(--l-card-list--masonry-h--row-height, props.get(vars.$size--3200)) !default;
18
19$border-color: props.def(--l-card-list--border-color, props.get(vars.$theme, --border)) !default;
diff --git a/src/layouts/_container.scss b/src/layouts/_container.scss
new file mode 100644
index 0000000..34c4bf0
--- /dev/null
+++ b/src/layouts/_container.scss
@@ -0,0 +1,27 @@
1@use 'sass:meta';
2@use 'iro-sass/src/iro-sass' as iro;
3@use '../props';
4
5@forward 'container.vars';
6@use 'container.vars' as vars;
7
8@mixin styles {
9 @include props.materialize(meta.module-variables('vars'));
10
11 @include iro.bem-layout('container') {
12 @each $mod, $size in vars.$fixed-sizes {
13 @include iro.bem-modifier($mod) {
14 max-inline-size: props.get($size);
15 margin-inline: auto;
16 }
17 }
18
19 @include iro.bem-modifier('pad-i') {
20 padding-inline: props.get(vars.$pad-i);
21 }
22
23 @include iro.bem-modifier('pad-b') {
24 padding-block: props.get(vars.$pad-b);
25 }
26 }
27}
diff --git a/src/layouts/_container.vars.scss b/src/layouts/_container.vars.scss
new file mode 100644
index 0000000..8b2258a
--- /dev/null
+++ b/src/layouts/_container.vars.scss
@@ -0,0 +1,22 @@
1@use 'iro-sass/src/iro-sass' as iro;
2@use '../props';
3@use '../vars';
4
5$fixed-125: props.def(--l-container--fixed-125, iro.fn-px-to-rem(720px)) !default;
6$fixed: props.def(--l-container--fixed, iro.fn-px-to-rem(610px)) !default;
7$fixed-75: props.def(--l-container--fixed-75, iro.fn-px-to-rem(500px)) !default;
8
9$fixed-sizes: (
10 'fixed-125': $fixed-125,
11 'fixed': $fixed,
12 'fixed-75': $fixed-75
13) !default;
14
15$pad-i: props.def(--l-container--pad-i, props.get(vars.$size--400)) !default;
16$pad-b: props.def(--l-container--pad-b, props.get(vars.$size--800)) !default;
17
18$pad-i--sm: props.def(--l-container--pad-i, props.get(vars.$size--200), 'sm') !default;
19$pad-b--sm: props.def(--l-container--pad-b, props.get(vars.$size--600), 'sm') !default;
20
21$pad-i--xs: props.def(--l-container--pad-i, props.get(vars.$size--150), 'xs') !default;
22$pad-b--xs: props.def(--l-container--pad-b, props.get(vars.$size--450), 'xs') !default;
diff --git a/src/layouts/_flex.scss b/src/layouts/_flex.scss
new file mode 100644
index 0000000..6cc9dc6
--- /dev/null
+++ b/src/layouts/_flex.scss
@@ -0,0 +1,27 @@
1@use 'iro-sass/src/iro-sass' as iro;
2
3@mixin styles {
4 @include iro.bem-layout('flex') {
5 display: flex;
6
7 @include iro.bem-modifier('align-stretch') {
8 align-items: stretch;
9 }
10
11 @include iro.bem-modifier('align-center') {
12 align-items: center;
13 }
14
15 @include iro.bem-modifier('align-start') {
16 align-items: flex-start;
17 }
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}
diff --git a/src/layouts/_form.scss b/src/layouts/_form.scss
new file mode 100644
index 0000000..824d7ca
--- /dev/null
+++ b/src/layouts/_form.scss
@@ -0,0 +1,58 @@
1@use 'sass:meta';
2@use 'iro-sass/src/iro-sass' as iro;
3@use '../props';
4
5@forward 'form.vars';
6@use 'form.vars' as vars;
7
8@mixin styles {
9 @include props.materialize(meta.module-variables('vars'));
10
11 @include iro.bem-layout('form') {
12 display: flex;
13 flex-direction: column;
14 gap: props.get(vars.$item-spacing-b) props.get(vars.$label-spacing-i);
15
16 @include iro.bem-elem('item') {
17 display: block;
18 }
19
20 @include iro.bem-elem('item-content') {
21 @include iro.bem-modifier('align-start') {
22 align-self: start;
23 }
24 }
25
26 @include iro.bem-modifier('row') {
27 flex-direction: row;
28 align-items: flex-end;
29 }
30
31 @include iro.bem-modifier('labels-start', 'labels-end') {
32 display: grid;
33 grid-template-rows: auto;
34 grid-template-columns: auto 1fr;
35 align-items: baseline;
36
37 @include iro.bem-elem('item') {
38 display: contents;
39 }
40
41 @include iro.bem-elem('item-label') {
42 grid-column: 1;
43 padding-inline-end: 0;
44 }
45
46 @include iro.bem-elem('item-content') {
47 grid-column: 2;
48 margin-block-start: 0;
49 }
50 }
51
52 @include iro.bem-modifier('labels-end') {
53 @include iro.bem-elem('item-label') {
54 text-align: end;
55 }
56 }
57 }
58}
diff --git a/src/layouts/_form.vars.scss b/src/layouts/_form.vars.scss
new file mode 100644
index 0000000..45faf29
--- /dev/null
+++ b/src/layouts/_form.vars.scss
@@ -0,0 +1,5 @@
1@use '../props';
2@use '../vars';
3
4$item-spacing-b: props.def(--l-form--item-spacing-b, props.get(vars.$size--325)) !default;
5$label-spacing-i: props.def(--l-form--label-spacing-i, props.get(vars.$size--325)) !default;
diff --git a/src/layouts/_media.scss b/src/layouts/_media.scss
new file mode 100644
index 0000000..7483f12
--- /dev/null
+++ b/src/layouts/_media.scss
@@ -0,0 +1,40 @@
1@use 'sass:meta';
2@use 'iro-sass/src/iro-sass' as iro;
3@use '../props';
4
5@forward 'media.vars';
6@use 'media.vars' as vars;
7
8@mixin styles {
9 @include props.materialize(meta.module-variables('vars'));
10
11 @include iro.bem-layout('media') {
12 display: flex;
13 gap: props.get(vars.$gap);
14 align-items: center;
15 line-height: 1.4;
16
17 @each $mod, $size in vars.$sizes {
18 @include iro.bem-modifier($mod) {
19 gap: props.get($size);
20 }
21 }
22
23 @include iro.bem-modifier('wrap') {
24 flex-wrap: wrap;
25 }
26
27 @include iro.bem-elem('block') {
28 flex: 0 0 auto;
29
30 @include iro.bem-modifier('shrink', 'main') {
31 flex-shrink: 1;
32 min-inline-size: 0;
33 }
34
35 @include iro.bem-modifier('main') {
36 inline-size: 100%;
37 }
38 }
39 }
40}
diff --git a/src/layouts/_media.vars.scss b/src/layouts/_media.vars.scss
new file mode 100644
index 0000000..3444611
--- /dev/null
+++ b/src/layouts/_media.vars.scss
@@ -0,0 +1,16 @@
1@use '../props';
2@use '../vars';
3
4$gap: props.def(--l-media--gap, props.get(vars.$size--150)) !default;
5
6$gapless: props.def(--l-media--gapless, 0) !default;
7$sm: props.def(--l-media--sm, props.get(vars.$size--100)) !default;
8$lg: props.def(--l-media--lg, props.get(vars.$size--300)) !default;
9$xl: props.def(--l-media--xl, props.get(vars.$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
new file mode 100644
index 0000000..2589d2c
--- /dev/null
+++ b/src/layouts/_overflow.scss
@@ -0,0 +1,11 @@
1@use 'iro-sass/src/iro-sass' as iro;
2@use '../props';
3@use '../vars';
4
5@mixin styles {
6 @include iro.bem-layout('overflow') {
7 overflow: auto;
8 scrollbar-color: props.get(vars.$theme, --text-disabled) transparent;
9 }
10}
11
diff --git a/src/objects/_action-button.scss b/src/objects/_action-button.scss
new file mode 100644
index 0000000..0a65b8d
--- /dev/null
+++ b/src/objects/_action-button.scss
@@ -0,0 +1,179 @@
1@use 'sass:list';
2@use 'sass:map';
3@use 'sass:meta';
4@use 'iro-sass/src/iro-sass' as iro;
5@use '../props';
6
7@forward 'action-button.vars';
8@use 'action-button.vars' as vars;
9
10@mixin -apply-theme($theme, $key: ()) {
11 color: props.get($theme, list.join($key, --disabled --label)...);
12 background-color: props.get($theme, list.join($key, --disabled --bg)...);
13 border-color: props.get($theme, list.join($key, --disabled --border)...);
14
15 &::after {
16 outline-color: props.get($theme, list.join($key, --key-focus --border)...);
17 box-shadow:
18 0
19 0
20 0
21 calc(props.get(vars.$key-focus--border-width) + props.get(vars.$key-focus--outline-width))
22 props.get($theme, list.join($key, --key-focus --outline-width)...);
23 }
24
25 &:link,
26 &:visited,
27 &:enabled {
28 color: props.get($theme, list.join($key, --label)...);
29 background-color: props.get($theme, list.join($key, --bg)...);
30 border-color: props.get($theme, list.join($key, --border)...);
31
32 &:hover,
33 &:focus-visible {
34 color: props.get($theme, list.join($key, --hover --label)...);
35 background-color: props.get($theme, list.join($key, --hover --bg)...);
36 border-color: props.get($theme, list.join($key, --hover --border)...);
37 }
38
39 &:active {
40 color: props.get($theme, list.join($key, --active --label)...);
41 background-color: props.get($theme, list.join($key, --active --bg)...);
42 border-color: props.get($theme, list.join($key, --active --border)...);
43 }
44 }
45
46 @include iro.bem-modifier('quiet') {
47 color: props.get($theme, list.join($key, --quiet --disabled --label)...);
48 background-color: transparent;
49 border-color: transparent;
50
51 &:link,
52 &:visited,
53 &:enabled {
54 color: props.get($theme, list.join($key, --quiet --label)...);
55 background-color: transparent;
56 border-color: transparent;
57
58 &:hover,
59 &:focus-visible {
60 color: props.get($theme, list.join($key, --quiet --hover --label)...);
61 background-color: props.get($theme, list.join($key, --quiet --hover --bg)...);
62 border-color: transparent;
63 }
64
65 &:active {
66 color: props.get($theme, list.join($key, --quiet --active --label)...);
67 background-color: props.get($theme, list.join($key, --quiet --active --bg)...);
68 border-color: transparent;
69 }
70 }
71 }
72
73 @include iro.bem-is('selected') {
74 color: props.get($theme, list.join($key, --selected --disabled --label)...);
75 background-color: props.get($theme, list.join($key, --selected --disabled --bg)...);
76 border-color: props.get($theme, list.join($key, --selected --disabled --border)...);
77
78 &:link,
79 &:visited,
80 &:enabled {
81 color: props.get($theme, list.join($key, --selected --label)...);
82 background-color: props.get($theme, list.join($key, --selected --bg)...);
83 border-color: props.get($theme, list.join($key, --selected --border)...);
84
85 &:hover,
86 &:focus-visible {
87 color: props.get($theme, list.join($key, --selected --hover --label)...);
88 background-color: props.get($theme, list.join($key, --selected --hover --bg)...);
89 border-color: props.get($theme, list.join($key, --selected --hover --border)...);
90 }
91
92 &:active {
93 color: props.get($theme, list.join($key, --selected --active --label)...);
94 background-color: props.get($theme, list.join($key, --selected --active --bg)...);
95 border-color: props.get($theme, list.join($key, --selected --active --border)...);
96 }
97 }
98 }
99}
100
101@mixin styles {
102 @include props.materialize(meta.module-variables('vars'));
103
104 @include iro.bem-object('action-button') {
105 position: relative;
106 display: inline-block;
107 padding-block: props.get(vars.$pad-b);
108 padding-inline: props.get(vars.$pad-i);
109 line-height: props.get(vars.$line-height);
110 text-align: center;
111 text-decoration: none;
112 text-overflow: ellipsis;
113 white-space: nowrap;
114 border: props.get(vars.$border-width) solid transparent;
115 border-radius: props.get(vars.$rounding);
116
117 &::after {
118 position: absolute;
119 inset: calc(-1 * props.get(vars.$border-width) - props.get(vars.$key-focus--border-offset));
120 z-index: 1;
121 display: none;
122 pointer-events: none;
123 content: '';
124 border-radius: calc(props.get(vars.$rounding) + props.get(vars.$key-focus--border-offset));
125 outline: transparent solid props.get(vars.$key-focus--border-width);
126 }
127
128 &:link,
129 &:visited,
130 &:enabled {
131 &:focus-visible {
132 &::after {
133 display: block;
134 }
135 }
136 }
137
138 @include -apply-theme(vars.$default-theme);
139
140 @each $theme in map.keys(props.get(vars.$static-themes)) {
141 @include iro.bem-modifier($theme) {
142 @include -apply-theme(vars.$static-themes, $theme);
143 }
144 }
145
146 @include iro.bem-modifier('pill') {
147 padding-inline: props.get(vars.$pad-i-pill);
148 border-radius: 100em;
149
150 &::after {
151 border-radius: 100em;
152 }
153 }
154
155 @each $mod, $pad-i, $pad-i-pill, $pad-b, $font-size in vars.$fixed-sizes {
156 @include iro.bem-modifier($mod) {
157 padding-block: props.get($pad-i);
158 padding-inline: props.get($pad-i);
159 font-size: props.get($font-size);
160
161 @include iro.bem-modifier('pill') {
162 padding-inline: props.get($pad-i-pill);
163 }
164 }
165 }
166
167 @include iro.bem-modifier('icon') {
168 inline-size: calc(1em * props.get(vars.$line-height) + 2 * props.get(vars.$pad-b));
169 padding-inline: 0;
170
171 @each $mod, $pad-i, $pad-i-pill, $pad-b, $font-size in vars.$fixed-sizes {
172 @include iro.bem-modifier($mod) {
173 inline-size: calc(1em * props.get(vars.$line-height) + 2 * props.get($pad-b));
174 padding-inline: 0;
175 }
176 }
177 }
178 }
179}
diff --git a/src/objects/_action-button.vars.scss b/src/objects/_action-button.vars.scss
new file mode 100644
index 0000000..16d9e7f
--- /dev/null
+++ b/src/objects/_action-button.vars.scss
@@ -0,0 +1,185 @@
1@use 'sass:map';
2@use '../props';
3@use '../vars';
4
5$line-height: props.def(--o-action-button--line-height, 1.4) !default;
6$pad-i: props.def(--o-action-button--pad-i, props.get(vars.$size--150)) !default;
7$pad-i-pill: props.def(--o-action-button--pad-i-pill, props.get(vars.$size--200)) !default;
8$pad-b: props.def(--o-action-button--pad-b, props.get(vars.$size--85)) !default;
9$border-width: props.def(--o-action-button--border-width, props.get(vars.$border-width--thin)) !default;
10$rounding: props.def(--o-action-button--rounding, props.get(vars.$rounding)) !default;
11$font-size: props.def(--o-action-button--font-size, props.get(vars.$font-size--100)) !default;
12
13$pad-i--sm: props.def(--o-action-button--pad-i, props.get(vars.$size--100), 'sm') !default;
14$pad-i-pill--sm: props.def(--o-action-button--pad-i-pill, props.get(vars.$size--150), 'sm') !default;
15$pad-b--sm: props.def(--o-action-button--pad-b, props.get(vars.$size--40), 'sm') !default;
16$font-size--sm: props.def(--o-action-button--font-size, props.get(vars.$font-size--75), 'sm') !default;
17
18$pad-i--lg: props.def(--o-action-button--pad-i, props.get(vars.$size--175), 'lg') !default;
19$pad-i-pill--lg: props.def(--o-action-button--pad-i-pill, props.get(vars.$size--225), 'lg') !default;
20$pad-b--lg: props.def(--o-action-button--pad-b, props.get(vars.$size--115), 'lg') !default;
21$font-size--lg: props.def(--o-action-button--font-size, props.get(vars.$font-size--150), 'lg') !default;
22
23$pad-i--xl: props.def(--o-action-button--pad-i, props.get(vars.$size--225), 'xl') !default;
24$pad-i-pill--xl: props.def(--o-action-button--pad-i-pill, props.get(vars.$size--300), 'xl') !default;
25$pad-b--xl: props.def(--o-action-button--pad-b, props.get(vars.$size--150), 'xl') !default;
26$font-size--xl: props.def(--o-action-button--font-size, props.get(vars.$font-size--200), 'xl') !default;
27
28$key-focus--border-width: props.def(--o-action-button--key-focus--border-width, props.get(vars.$key-focus--border-width)) !default;
29$key-focus--border-offset: props.def(--o-action-button--key-focus--border-offset, props.get(vars.$key-focus--border-offset)) !default;
30$key-focus--outline-width: props.def(--o-action-button--key-focus--outline-width, props.get(vars.$key-focus--outline-width)) !default;
31
32$fixed-sizes: (
33 'sm' $pad-i--sm $pad-i-pill--sm $pad-b--sm $font-size--sm,
34 'lg' $pad-i--lg $pad-i-pill--lg $pad-b--lg $font-size--lg,
35 'xl' $pad-i--xl $pad-i-pill--xl $pad-b--xl $font-size--xl,
36) !default;
37
38$default-theme: props.def(--o-action-button, (
39 --bg-color: props.get(vars.$theme, --base, --75),
40 --label-color: props.get(vars.$theme, --text),
41 --border-color: props.get(vars.$theme, --border-strong),
42
43 --hover: (
44 --bg-color: props.get(vars.$theme, --border-mute),
45 --label-color: props.get(vars.$theme, --heading),
46 --border-color: props.get(vars.$theme, --text-mute-more),
47 ),
48
49 --active: (
50 --bg-color: props.get(vars.$theme, --border),
51 --label-color: props.get(vars.$theme, --heading),
52 --border-color: props.get(vars.$theme, --text-mute),
53 ),
54
55 --disabled: (
56 --bg-color: props.get(vars.$theme, --bg-l1),
57 --label-color: props.get(vars.$theme, --border-strong),
58 --border-color: props.get(vars.$theme, --border),
59 ),
60
61 --key-focus: (
62 --border-color: props.get(vars.$theme, --focus, --border),
63 --outline-color: props.get(vars.$theme, --focus, --outline),
64 ),
65
66 --selected: (
67 --bg-color: props.get(vars.$theme, --text-mute),
68 --label-color: props.get(vars.$theme, --base, --50),
69 --border-color: props.get(vars.$theme, --text-mute),
70
71 --hover: (
72 --bg-color: props.get(vars.$theme, --text),
73 --label-color: props.get(vars.$theme, --base, --50),
74 --border-color: props.get(vars.$theme, --text),
75 ),
76
77 --active: (
78 --bg-color: props.get(vars.$theme, --heading),
79 --label-color: props.get(vars.$theme, --base, --50),
80 --border-color: props.get(vars.$theme, --heading),
81 ),
82
83 --disabled: (
84 --bg-color: props.get(vars.$theme, --border-mute),
85 --label-color: props.get(vars.$theme, --border-strong),
86 --border-color: props.get(vars.$theme, --border-mute),
87 ),
88 ),
89
90 --quiet: (
91 --label-color: props.get(vars.$theme, --text),
92
93 --hover: (
94 --bg-color: props.get(vars.$theme, --border-mute),
95 --label-color: props.get(vars.$theme, --heading),
96 ),
97
98 --active: (
99 --bg-color: props.get(vars.$theme, --border),
100 --label-color: props.get(vars.$theme, --heading),
101 ),
102
103 --disabled: (
104 --label-color: props.get(vars.$theme, --border-strong),
105 ),
106 ),
107)) !default;
108
109$static-themes: props.def(--o-action-button);
110@each $theme in map.keys(props.get(vars.$transparent-colors)) {
111 $button-theme: #{$theme}-static;
112
113 $static-themes: props.merge($static-themes, (
114 $button-theme: (
115 --bg-color: props.get(vars.$transparent-colors, $theme, --100),
116 --label-color: props.get(vars.$transparent-colors, $theme, --900),
117 --border-color: props.get(vars.$transparent-colors, $theme, --400),
118
119 --hover: (
120 --bg-color: props.get(vars.$transparent-colors, $theme, --300),
121 --label-color: props.get(vars.$transparent-colors, $theme, --900),
122 --border-color: props.get(vars.$transparent-colors, $theme, --500),
123 ),
124
125 --active: (
126 --bg-color: props.get(vars.$transparent-colors, $theme, --400),
127 --label-color: props.get(vars.$transparent-colors, $theme, --900),
128 --border-color: props.get(vars.$transparent-colors, $theme, --600),
129 ),
130
131 --disabled: (
132 --bg-color: props.get(vars.$transparent-colors, $theme, --100),
133 --label-color: props.get(vars.$transparent-colors, $theme, --500),
134 --border-color: props.get(vars.$transparent-colors, $theme, --300),
135 ),
136
137 --key-focus: (
138 --border-color: props.get(vars.$transparent-colors, $theme, --900),
139 --outline-color: props.get(vars.$transparent-colors, $theme, --300),
140 ),
141
142 --selected: (
143 --bg-color: props.get(vars.$transparent-colors, $theme, --800),
144 --label-color: props.get(vars.$transparent-colors, $theme, --text),
145 --border-color: props.get(vars.$transparent-colors, $theme, --100),
146
147 --hover: (
148 --bg-color: props.get(vars.$transparent-colors, $theme, --900),
149 --label-color: props.get(vars.$transparent-colors, $theme, --text),
150 --border-color: props.get(vars.$transparent-colors, $theme, --100),
151 ),
152
153 --active: (
154 --bg-color: props.get(vars.$transparent-colors, $theme, --900),
155 --label-color: props.get(vars.$transparent-colors, $theme, --text),
156 --border-color: props.get(vars.$transparent-colors, $theme, --100),
157 ),
158
159 --disabled: (
160 --bg-color: props.get(vars.$transparent-colors, $theme, --200),
161 --label-color: props.get(vars.$transparent-colors, $theme, --500),
162 --border-color: props.get(vars.$transparent-colors, $theme, --100),
163 ),
164 ),
165
166 --quiet: (
167 --label-color: props.get(vars.$transparent-colors, $theme, --900),
168
169 --hover: (
170 --bg-color: props.get(vars.$transparent-colors, $theme, --300),
171 --label-color: props.get(vars.$transparent-colors, $theme, --900),
172 ),
173
174 --active: (
175 --bg-color: props.get(vars.$transparent-colors, $theme, --400),
176 --label-color: props.get(vars.$transparent-colors, $theme, --900),
177 ),
178
179 --disabled: (
180 --label-color: props.get(vars.$transparent-colors, $theme, --500),
181 ),
182 ),
183 )
184 ));
185}
diff --git a/src/objects/_alert.scss b/src/objects/_alert.scss
new file mode 100644
index 0000000..774b443
--- /dev/null
+++ b/src/objects/_alert.scss
@@ -0,0 +1,43 @@
1@use 'iro-sass/src/iro-sass' as iro;
2@use '../functions' as fn;
3
4$themes: 'accent' 'positive' 'negative' 'warning' !default;
5
6@include iro.props-namespace('alert') {
7 @include iro.props-store((
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
20 @each $theme in $themes {
21 @include iro.props-store((
22 --colors: (
23 --#{$theme}: (
24 --border: fn.global-color(--#{$theme} --700),
25 ),
26 ),
27 ));
28 }
29
30 @include iro.bem-object(iro.props-namespace()) {
31 padding-block: fn.dim(--pad-b);
32 padding-inline: fn.dim(--pad-i);
33 background-color: fn.color(--bg);
34 border: fn.dim(--border) solid fn.color(--border);
35 border-radius: fn.dim(--rounding);
36
37 @each $theme in $themes {
38 @include iro.bem-modifier($theme) {
39 border-color: fn.color(--#{$theme} --border);
40 }
41 }
42 }
43}
diff --git a/src/objects/_alert.vars.scss b/src/objects/_alert.vars.scss
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/objects/_alert.vars.scss
diff --git a/src/objects/_avatar.scss b/src/objects/_avatar.scss
new file mode 100644
index 0000000..d9c1105
--- /dev/null
+++ b/src/objects/_avatar.scss
@@ -0,0 +1,165 @@
1@use 'sass:list';
2@use 'iro-sass/src/iro-sass' as iro;
3@use '../functions' as fn;
4
5$sizes: 'xs' 'sm' 'lg' 'xl' 'xxl' 'xxxl';
6
7@mixin status($size: ()) {
8 @include iro.bem-elem('status') {
9 inline-size: fn.dim(list.join($size, --indicator-size));
10 block-size: fn.dim(list.join($size, --indicator-size));
11
12 @include iro.bem-next-elem('content') {
13 mask-image: radial-gradient(circle calc(.5 * fn.dim(list.join($size, --indicator-size)) + fn.dim(--indicator-spacing)) at
14 calc(100% - .5 * fn.dim(list.join($size, --indicator-size)))
15 calc(100% - .5 * fn.dim(list.join($size, --indicator-size))),
16 transparent 95%,
17 #fff);
18 }
19 }
20}
21
22@include iro.props-namespace('avatar') {
23 @include iro.props-store((
24 --dims: (
25 --size: fn.global-dim(--size --500),
26 --font-size: fn.global-dim(--font-size --100),
27 --indicator-size: fn.global-dim(--size --150),
28 --indicator-spacing: fn.global-dim(--size --40),
29 --rounding: 25%,
30
31 --xxxl: (
32 --size: fn.global-dim(--size --1600),
33 --font-size: fn.global-dim(--font-size --800),
34 --indicator-size: fn.global-dim(--size --400),
35 ),
36 --xxl: (
37 --size: fn.global-dim(--size --1200),
38 --font-size: fn.global-dim(--font-size --600),
39 --indicator-size: fn.global-dim(--size --300),
40 ),
41 --xl: (
42 --size: fn.global-dim(--size --800),
43 --font-size: fn.global-dim(--font-size --300),
44 --indicator-size: fn.global-dim(--size --225),
45 ),
46 --lg: (
47 --size: fn.global-dim(--size --650),
48 --font-size: fn.global-dim(--font-size --200),
49 --indicator-size: fn.global-dim(--size --175),
50 ),
51 --sm: (
52 --size: fn.global-dim(--size --375),
53 --font-size: fn.global-dim(--font-size --75),
54 --indicator-size: fn.global-dim(--size --125),
55 ),
56 --xs: (
57 --size: fn.global-dim(--size --250),
58 --font-size: fn.global-dim(--font-size --50),
59 --indicator-size: fn.global-dim(--size --100),
60 ),
61
62 --key-focus: (
63 --border: fn.global-dim(--key-focus --border),
64 --border-offset: fn.global-dim(--key-focus --border-offset),
65 --outline: fn.global-dim(--key-focus --outline),
66 ),
67 ),
68 --colors: (
69 --h: 354,
70 --s: 44%,
71 --l: 45%,
72
73 --key-focus: (
74 --border: fn.global-color(--focus --border),
75 --outline: fn.global-color(--focus --outline),
76 ),
77 ),
78 ));
79
80 @include iro.bem-object(iro.props-namespace()) {
81 position: relative;
82 display: inline-block;
83 font-size: fn.dim(--font-size);
84 font-style: normal;
85 vertical-align: .05em;
86 border-radius: fn.dim(--rounding);
87
88 &::after {
89 position: absolute;
90 inset: calc(-1 * fn.dim(--key-focus --border-offset));
91 z-index: 1;
92 display: none;
93 pointer-events: none;
94 content: '';
95 border: fn.dim(--key-focus --border-offset) solid transparent;
96 border-radius: fn.dim(--rounding);
97 outline: fn.color(--key-focus --border) solid fn.dim(--key-focus --border);
98 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(--key-focus --outline);
99 }
100
101 @include iro.bem-elem('status') {
102 position: absolute;
103 inset-block-end: 0;
104 inset-inline-end: 0;
105 }
106
107 @include status;
108
109 @include iro.bem-elem('content') {
110 display: block;
111 inline-size: fn.dim(--size);
112 block-size: fn.dim(--size);
113 line-height: fn.dim(--size);
114 text-align: center;
115 object-fit: cover;
116 object-position: center center;
117 border-radius: fn.dim(--rounding);
118 }
119
120 @include iro.bem-modifier('circle') {
121 border-radius: 100%;
122
123 &::after {
124 border-radius: 100%;
125 }
126
127 @include iro.bem-elem('content') {
128 border-radius: 100%;
129 }
130 }
131
132 @include iro.bem-modifier('placeholder') {
133 @include iro.bem-elem('content') {
134 background-color: hsl(0, 0%, fn.color(--l));
135 }
136 }
137
138 @include iro.bem-modifier('colored') {
139 @include iro.bem-elem('content') {
140 color: #fff;
141 background-color: hsl(fn.color(--h), fn.color(--s), fn.color(--l));
142 }
143 }
144
145 @each $size in $sizes {
146 @include iro.bem-modifier($size) {
147 font-size: fn.dim(--#{$size} --font-size);
148
149 @include status(--#{$size});
150
151 @include iro.bem-elem('content') {
152 inline-size: fn.dim(--#{$size} --size);
153 block-size: fn.dim(--#{$size} --size);
154 line-height: fn.dim(--#{$size} --size);
155 }
156 }
157 }
158
159 &:focus-visible {
160 &::after {
161 display: block;
162 }
163 }
164 }
165}
diff --git a/src/objects/_backdrop.scss b/src/objects/_backdrop.scss
new file mode 100644
index 0000000..9e0cc1e
--- /dev/null
+++ b/src/objects/_backdrop.scss
@@ -0,0 +1,26 @@
1@use 'iro-sass/src/iro-sass' as iro;
2@use '../functions' as fn;
3
4@include iro.props-namespace('backdrop') {
5 @include iro.props-store((
6 --dims: (
7 --z-index: 10000,
8 --blur: 2em,
9 ),
10 --colors: (
11 --bg: rgba(#000, .75),
12 ),
13 ));
14
15 @include iro.bem-object(iro.props-namespace()) {
16 position: fixed;
17 inset: 0;
18 z-index: fn.dim(--z-index);
19 box-sizing: border-box;
20 display: flex;
21 flex-direction: column;
22 overflow: auto;
23 background-color: fn.color(--bg);
24 backdrop-filter: blur(fn.dim(--blur));
25 }
26}
diff --git a/src/objects/_badge.scss b/src/objects/_badge.scss
new file mode 100644
index 0000000..72d85ff
--- /dev/null
+++ b/src/objects/_badge.scss
@@ -0,0 +1,300 @@
1@use 'sass:string';
2@use 'iro-sass/src/iro-sass' 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 color: fn.color(--#{$theme} --label);
11 background-color: fn.color(--#{$theme} --bg);
12
13 &:link,
14 &:visited,
15 &:enabled {
16 &:hover,
17 &:focus-visible {
18 color: fn.color(--#{$theme} --hover --label);
19 background-color: fn.color(--#{$theme} --hover --bg);
20 }
21
22 &:active {
23 color: fn.color(--#{$theme} --active --label);
24 background-color: fn.color(--#{$theme} --active --bg);
25 }
26 }
27
28 @include iro.bem-modifier('quiet') {
29 color: fn.color(--#{$theme}-quiet --label);
30 background-color: fn.color(--#{$theme}-quiet --bg);
31
32 &:link,
33 &:visited,
34 &:enabled {
35 &:hover,
36 &:focus-visible {
37 color: fn.color(--#{$theme}-quiet --hover --label);
38 background-color: fn.color(--#{$theme}-quiet --hover --bg);
39 }
40
41 &:active {
42 color: fn.color(--#{$theme}-quiet --active --label);
43 background-color: fn.color(--#{$theme}-quiet --active --bg);
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 position: relative;
194 display: inline-block;
195 padding-block: fn.dim(--pad-b);
196 padding-inline: fn.dim(--pad-i);
197 font-size: fn.dim(--font-size);
198 line-height: fn.global-dim(--font --standard --line-height);
199 color: fn.color(--label);
200 text-align: center;
201 text-decoration: none;
202 background-color: fn.color(--bg);
203 background-clip: padding-box;
204 border-radius: fn.dim(--rounding);
205
206 &::after {
207 position: absolute;
208 inset: calc(-1 * fn.dim(--key-focus --border-offset));
209 z-index: 1;
210 display: none;
211 pointer-events: none;
212 content: '';
213 border-radius: calc(fn.dim(--rounding) + fn.dim(--key-focus --border-offset));
214 outline: fn.color(--key-focus --border) solid fn.dim(--key-focus --border);
215 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(--key-focus --outline);
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 color: fn.color(--quiet --label);
237 background-color: fn.color(--quiet --bg);
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
new file mode 100644
index 0000000..097bc21
--- /dev/null
+++ b/src/objects/_button.scss
@@ -0,0 +1,301 @@
1@use 'sass:list';
2@use 'iro-sass/src/iro-sass' as iro;
3@use '../functions' as fn;
4
5$sizes: 'sm' 'lg' 'xl' !default;
6$themes: 'accent' 'negative' !default;
7$static-themes: 'black' 'white' !default;
8
9@mixin theme($theme: ()) {
10 &:link,
11 &:visited,
12 &:enabled {
13 color: fn.color(list.join($theme, --label));
14 background-color: fn.color(list.join($theme, --bg));
15 border-color: transparent;
16 }
17
18 @include iro.bem-modifier('outline') {
19 &:link,
20 &:visited,
21 &:enabled {
22 color: fn.color(list.join($theme, --outline-label));
23 background-color: transparent;
24 border-color: fn.color(list.join($theme, --outline-border));
25 }
26 }
27
28 &:link,
29 &:visited,
30 &:enabled {
31 &:hover,
32 &:focus-visible {
33 color: fn.color(list.join($theme, --hover --label));
34 background-color: fn.color(list.join($theme, --hover --bg));
35 border-color: transparent;
36 }
37
38 &:active {
39 color: fn.color(list.join($theme, --active --label));
40 background-color: fn.color(list.join($theme, --active --bg));
41 border-color: transparent;
42 }
43 }
44}
45
46@mixin static-theme($theme: ()) {
47 color: fn.color(list.join($theme, --disabled --label));
48 background-color: fn.color(list.join($theme, --disabled --bg));
49 border-color: transparent;
50
51 &::after {
52 outline: fn.color(list.join($theme, --key-focus --border)) solid fn.dim(--key-focus --border);
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));
54 }
55
56 @include iro.bem-modifier('outline') {
57 background-color: transparent;
58 border-color: fn.color(list.join($theme, --disabled --outline-border));
59 }
60
61 @include theme($theme);
62
63 @include iro.bem-modifier('primary') {
64 @include theme(list.join($theme, --primary));
65 }
66}
67
68@include iro.props-namespace('button') {
69 @include iro.props-store((
70 --dims: (
71 --line-height: 1.4,
72 --pad-i: fn.global-dim(--size --200),
73 --pad-i-label: fn.global-dim(--size --75),
74 --pad-b: fn.global-dim(--size --65),
75 --border: fn.global-dim(--border --medium),
76 --rounding: 10em,
77 --font-size: fn.global-dim(--font-size --100),
78
79 --sm: (
80 --pad-i: fn.global-dim(--size --150),
81 --pad-i-label: fn.global-dim(--size --50),
82 --pad-b: fn.global-dim(--size --25),
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
110 --hover: (
111 --bg: fn.global-color(--border),
112 --label: fn.global-color(--heading),
113 ),
114 --active: (
115 --bg: fn.global-color(--border-strong),
116 --label: fn.global-color(--heading),
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
135 --hover: (
136 --bg: fn.global-color(--base --900),
137 --label: fn.global-color(--base --900-text),
138 ),
139 --active: (
140 --bg: fn.global-color(--base --900),
141 --label: fn.global-color(--base --900-text),
142 ),
143 ),
144 ),
145 ));
146
147 @each $theme in $themes {
148 @include iro.props-store((
149 --colors: (
150 --#{$theme}: (
151 --bg: fn.global-color(--#{$theme}-static --900),
152 --label: fn.global-color(--#{$theme}-static --900-text),
153 --outline-border: fn.global-color(--#{$theme} --900),
154 --outline-label: fn.global-color(--#{$theme} --1000),
155
156 --hover: (
157 --bg: fn.global-color(--#{$theme}-static --1000),
158 --label: fn.global-color(--#{$theme}-static --1000-text),
159 ),
160 --active: (
161 --bg: fn.global-color(--#{$theme}-static --1100),
162 --label: fn.global-color(--#{$theme}-static --1100-text),
163 ),
164 ),
165 ),
166 ));
167 }
168
169 @each $theme in $static-themes {
170 @include iro.props-store((
171 --colors: (
172 --static-#{$theme}: (
173 --bg: fn.global-color(--#{$theme}-transparent --200),
174 --label: fn.global-color(--#{$theme}-transparent --900),
175 --outline-border: fn.global-color(--#{$theme}-transparent --300),
176 --outline-label: fn.global-color(--#{$theme}-transparent --900),
177
178 --hover: (
179 --bg: fn.global-color(--#{$theme}-transparent --300),
180 --label: fn.global-color(--#{$theme}-transparent --900),
181 ),
182 --active: (
183 --bg: fn.global-color(--#{$theme}-transparent --400),
184 --label: fn.global-color(--#{$theme}-transparent --900),
185 ),
186 --disabled: (
187 --bg: fn.global-color(--#{$theme}-transparent --200),
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
198 --primary: (
199 --bg: fn.global-color(--#{$theme}-transparent --800),
200 --label: fn.global-color(--#{$theme}-transparent --text),
201 --outline-border: fn.global-color(--#{$theme}-transparent --800),
202 --outline-label: fn.global-color(--#{$theme}-transparent --900),
203
204 --hover: (
205 --bg: fn.global-color(--#{$theme}-transparent --900),
206 --label: fn.global-color(--#{$theme}-transparent --text),
207 ),
208 --active: (
209 --bg: fn.global-color(--#{$theme}-transparent --900),
210 --label: fn.global-color(--#{$theme}-transparent --text),
211 ),
212 ),
213 ),
214 ),
215 ));
216 }
217
218 @include iro.bem-object(iro.props-namespace()) {
219 position: relative;
220 display: inline-block;
221 padding-block: fn.dim(--pad-b);
222 padding-inline: fn.dim(--pad-i);
223 font-size: fn.dim(--font-size);
224 font-weight: 500;
225 line-height: fn.dim(--line-height);
226 color: fn.color(--disabled --label);
227 text-align: center;
228 text-decoration: none;
229 background-color: fn.color(--disabled --bg);
230 border: fn.dim(--border) solid transparent;
231 border-color: fn.color(--disabled --bg);
232 border-radius: fn.dim(--rounding);
233
234 &::after {
235 position: absolute;
236 inset: calc(-1 * fn.dim(--border) - fn.dim(--key-focus --border-offset));
237 z-index: 1;
238 display: none;
239 pointer-events: none;
240 content: '';
241 border-radius: calc(fn.dim(--rounding) + fn.dim(--key-focus --border-offset));
242 outline: fn.color(--key-focus --border) solid fn.dim(--key-focus --border);
243 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(--key-focus --outline);
244 }
245
246 &:link,
247 &:visited,
248 &:enabled {
249 &:focus-visible {
250 &::after {
251 display: block;
252 }
253 }
254 }
255
256 @include iro.bem-elem('label') {
257 margin-inline: fn.dim(--pad-i-label);
258 }
259
260 @include iro.bem-modifier('block') {
261 display: block;
262 }
263
264 @include iro.bem-modifier('outline') {
265 background-color: transparent;
266 border-color: fn.color(--disabled --outline-border);
267 }
268
269 @each $size in $sizes {
270 @include iro.bem-modifier($size) {
271 padding-block: fn.dim(--#{$size} --pad-b);
272 padding-inline: fn.dim(--#{$size} --pad-i);
273 font-size: fn.dim(--#{$size} --font-size);
274
275 @include iro.bem-elem('label') {
276 margin-inline: fn.dim(--#{$size} --pad-i-label);
277 }
278 }
279 }
280
281 @include static-theme;
282
283 @each $theme in $themes {
284 @include iro.bem-modifier($theme) {
285 @include theme(--#{$theme});
286 }
287 }
288
289 @each $theme in $static-themes {
290 @include iro.bem-modifier(static-#{$theme}) {
291 @include static-theme(--static-#{$theme});
292 }
293 }
294
295 @include iro.bem-modifier('round') {
296 inline-size: calc(1em * fn.dim(--line-height) + 2 * fn.dim(--pad-b));
297 padding-inline: 0;
298 border-radius: 100em;
299 }
300 }
301}
diff --git a/src/objects/_card.scss b/src/objects/_card.scss
new file mode 100644
index 0000000..cc9afc9
--- /dev/null
+++ b/src/objects/_card.scss
@@ -0,0 +1,170 @@
1@use 'iro-sass/src/iro-sass' as iro;
2@use '../functions' as fn;
3
4@include iro.props-namespace('card') {
5 @include iro.props-store((
6 --dims: (
7 --divider: fn.global-dim(--border --thin),
8 --pad-i: fn.global-dim(--size --300),
9 --pad-b: fn.global-dim(--size --250),
10 --spacing: fn.global-dim(--size --200),
11 --rounding: fn.global-dim(--rounding),
12
13 --hover: (
14 --offset-b: calc(-1 * fn.global-dim(--size --65)),
15 ),
16
17 --key-focus: (
18 --border: fn.global-dim(--key-focus --border),
19 --border-offset: fn.global-dim(--key-focus --border-offset),
20 --outline: fn.global-dim(--key-focus --outline),
21 ),
22 ),
23 --colors: (
24 --bg: fn.global-color(--bg-l2),
25 --divider: fn.global-color(--border-mute),
26
27 --key-focus: (
28 --label: fn.global-color(--focus --text),
29 --border: fn.global-color(--focus --border),
30 --outline: fn.global-color(--focus --outline),
31 ),
32
33 --quiet: (
34 --image: fn.global-color(--bg-base),
35
36 --hover: (
37 --image: fn.global-color(--border),
38 ),
39 )
40 ),
41 ));
42
43 @include iro.bem-object(iro.props-namespace()) {
44 display: block;
45 margin: calc(-1 * fn.dim(--key-focus --border));
46 background-color: fn.color(--bg);
47 background-clip: content-box;
48 border: fn.dim(--key-focus --border-offset) solid transparent;
49 border-radius: calc(fn.dim(--rounding) + fn.dim(--key-focus --border-offset));
50 transition: transform .2s;
51
52 @include iro.bem-multi('&:link, &:visited, &:enabled', 'modifier' 'interactive') {
53 &:hover,
54 &:active,
55 &:focus-visible {
56 transform: translateY(fn.dim(--hover --offset-b));
57 }
58
59 &:focus-visible {
60 outline: fn.color(--key-focus --border) solid fn.dim(--key-focus --border);
61 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(--key-focus --outline);
62 }
63 }
64
65 @include iro.bem-elem('avatar') {
66 margin-block-start: fn.dim(--pad-b);
67 margin-inline-start: fn.dim(--pad-i);
68 }
69
70 @include iro.bem-elem('image') {
71 display: block;
72 inline-size: 100%;
73 object-fit: cover;
74 transition: transform .2s, opacity .2s;
75
76 &:first-child {
77 border-start-start-radius: fn.dim(--rounding);
78 border-start-end-radius: fn.dim(--rounding);
79 }
80
81 &:last-child {
82 border-end-start-radius: fn.dim(--rounding);
83 border-end-end-radius: fn.dim(--rounding);
84 }
85
86 @include iro.bem-next-elem('avatar') {
87 margin-block-start: calc(-.7 * fn.foreign-dim(--avatar, --xl --size));
88 }
89 }
90
91 @include iro.bem-elem('body') {
92 padding-block: fn.dim(--pad-b);
93 padding-inline: fn.dim(--pad-i);
94
95 &::before {
96 display: block;
97 margin-block: -100em 100em;
98 content: '';
99 }
100 }
101
102 @include iro.bem-elem('content') {
103 margin-block-start: fn.dim(--spacing);
104 }
105
106 @include iro.bem-elem('footer') {
107 padding-block: 0 fn.dim(--pad-b);
108 padding-inline: fn.dim(--pad-i);
109 margin-block-start: calc(-1 * fn.dim(--pad-b));
110
111 &::before {
112 display: block;
113 block-size: fn.dim(--divider);
114 margin-block: fn.dim(--spacing);
115 content: '';
116 background-color: fn.color(--divider);
117 }
118 }
119
120 @include iro.bem-modifier('quiet') {
121 position: relative;
122 background-color: transparent;
123 border: 0;
124
125 @include iro.bem-multi('&:link, &:visited, &:enabled', 'modifier' 'interactive') {
126 &:hover,
127 &:active,
128 &:focus-visible {
129 transform: none;
130
131 @include iro.bem-elem('image') {
132 background-color: fn.color(--quiet --hover --image);
133 opacity: .75;
134 transform: translateY(fn.dim(--hover --offset-b));
135 }
136 }
137
138 &:focus-visible {
139 outline: none;
140 box-shadow: none;
141
142 @include iro.bem-elem('image') {
143 background-color: fn.color(--quiet --hover --image);
144 outline: fn.color(--key-focus --border) solid fn.dim(--key-focus --border);
145 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(--key-focus --outline);
146 opacity: 1;
147 }
148 }
149 }
150
151 @include iro.bem-elem('image') {
152 position: relative;
153 margin: calc(-1 * fn.dim(--key-focus --border));
154 background-color: fn.color(--quiet --image);
155 background-clip: padding-box;
156 border: fn.dim(--key-focus --border-offset) solid transparent;
157 border-radius: calc(fn.dim(--rounding) + fn.dim(--key-focus --border-offset));
158 }
159
160 @include iro.bem-elem('body') {
161 padding: 0;
162 padding-block-start: fn.dim(--spacing);
163 }
164
165 @include iro.bem-elem('footer') {
166 padding-inline: 0;
167 }
168 }
169 }
170}
diff --git a/src/objects/_checkbox.scss b/src/objects/_checkbox.scss
new file mode 100644
index 0000000..8d82cd5
--- /dev/null
+++ b/src/objects/_checkbox.scss
@@ -0,0 +1,261 @@
1@use 'iro-sass/src/iro-sass' as iro;
2@use '../functions' as fn;
3
4@include iro.props-namespace('checkbox') {
5 @include iro.props-store((
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
15 --key-focus: (
16 --border: fn.global-dim(--key-focus --border),
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
49 @include iro.bem-object(iro.props-namespace()) {
50 position: relative;
51 display: inline-block;
52 padding-block: fn.dim(--pad-b);
53 padding-inline: fn.dim(--pad-i);
54 margin-inline:
55 calc(-1 * fn.dim(--pad-i) - fn.dim(--key-focus --border-offset))
56 calc(fn.dim(--spacing-sibling) - fn.dim(--pad-b) - fn.dim(--key-focus --border-offset));
57
58 @include iro.bem-elem('box') {
59 position: relative;
60 display: inline-block;
61 flex: 0 0 auto;
62 inline-size: fn.dim(--size);
63 block-size: fn.dim(--size);
64 margin-block-start: calc(.5em * fn.global-dim(--font --standard --line-height) - .5 * fn.dim(--size) - fn.dim(--key-focus --border-offset));
65 vertical-align: top;
66 background-color: fn.color(--box-border);
67 background-clip: padding-box;
68 border: fn.dim(--key-focus --border-offset) solid transparent;
69 border-radius: calc(fn.dim(--border) + fn.dim(--key-focus --border-offset));
70
71 &::before,
72 &::after {
73 position: absolute;
74 display: block;
75 content: '';
76 }
77
78 &::before {
79 inset-block-start: fn.dim(--border);
80 inset-inline-start: fn.dim(--border);
81 z-index: 2;
82 inline-size: calc(fn.dim(--size) - 2 * fn.dim(--border));
83 block-size: calc(fn.dim(--size) - 2 * fn.dim(--border));
84 background-color: fn.color(--box-bg);
85 transition: transform .2s ease;
86 }
87
88 &::after {
89 inset-block-start: calc(.5 * fn.dim(--size) - 1px);
90 inset-inline-start: calc(1.5 * fn.dim(--border));
91 z-index: 3;
92 box-sizing: border-box;
93 inline-size: calc(fn.dim(--size) - 3 * fn.dim(--border));
94 block-size: 0;
95 border-color: fn.color(--box-bg);
96 border-style: solid;
97 border-radius: 2px;
98 transition: transform .2s ease;
99 transform: scale(0);
100 border-block-width: 0 2px;
101 border-inline-width: 0 2px;
102 }
103 }
104
105 @include iro.bem-elem('check-icon') {
106 position: absolute;
107 inset-block-start: calc(1 * fn.dim(--border));
108 inset-inline-start: calc(1 * fn.dim(--border));
109 z-index: 2;
110 display: block;
111 inline-size: calc(100% - 2 * fn.dim(--border));
112 block-size: calc(100% - 2 * fn.dim(--border));
113 margin: 0;
114 color: fn.color(--box-bg);
115 stroke-width: iro.fn-px-to-rem(3px);
116 transition: transform .2s ease;
117 transform: scale(0);
118 transform-origin: 40% 90%;
119 }
120
121 @include iro.bem-elem('label') {
122 margin-inline-start: calc(fn.dim(--label-gap) - fn.dim(--key-focus --border-offset));
123 }
124
125 @include iro.bem-elem('native') {
126 position: absolute;
127 inset-block-start: 0;
128 inset-inline-start: 0;
129 z-index: -1;
130 inline-size: 100%;
131 block-size: 100%;
132 padding: 0;
133 margin: 0;
134 overflow: hidden;
135 appearance: none;
136 border-radius: fn.dim(--rounding);
137
138 &:hover,
139 &:focus-visible {
140 @include iro.bem-sibling-elem('label') {
141 color: fn.color(--hover --label);
142 }
143
144 @include iro.bem-sibling-elem('box') {
145 background-color: fn.color(--hover --box-border);
146 }
147 }
148
149 &:checked {
150 @include iro.bem-sibling-elem('box') {
151 &::before {
152 transform: scale(0);
153 }
154
155 @include iro.bem-elem('check-icon') {
156 transform: scale(1);
157 }
158 }
159 }
160
161 &:indeterminate {
162 @include iro.bem-sibling-elem('box') {
163 &::before {
164 transform: scale(0);
165 }
166
167 &::after {
168 transform: scale(1);
169 }
170
171 @include iro.bem-elem('check-icon') {
172 transform: scale(0);
173 }
174 }
175 }
176
177 &:disabled {
178 @include iro.bem-sibling-elem('label') {
179 color: fn.color(--disabled --label);
180 }
181
182 @include iro.bem-sibling-elem('box') {
183 background-color: fn.color(--disabled --box-border);
184
185 &::before {
186 background-color: fn.color(--disabled --box-bg);
187 }
188 }
189 }
190
191 &:focus-visible {
192 @include iro.bem-sibling-elem('label') {
193 color: fn.color(--key-focus --label);
194 }
195
196 @include iro.bem-sibling-elem('box') {
197 outline: fn.color(--key-focus --border) solid fn.dim(--key-focus --border);
198 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(--key-focus --outline);
199 }
200 }
201 }
202
203 @include iro.bem-modifier('standalone') {
204 @include iro.bem-elem('box') {
205 margin-block-start: 0;
206 }
207 }
208
209 @include iro.bem-modifier('accent') {
210 @include iro.bem-elem('native') {
211 &:checked {
212 @include iro.bem-sibling-elem('box') {
213 background-color: fn.color(--accent --box-border);
214 }
215
216 &:hover,
217 &:focus-visible {
218 @include iro.bem-sibling-elem('box') {
219 background-color: fn.color(--accent --hover --box-border);
220 }
221 }
222 }
223
224 &:indeterminate {
225 @include iro.bem-sibling-elem('box') {
226 background-color: fn.color(--accent --box-border);
227 }
228
229 &:hover,
230 &:focus-visible {
231 @include iro.bem-sibling-elem('box') {
232 background-color: fn.color(--accent --hover --box-border);
233 }
234 }
235 }
236
237 &:disabled {
238 @include iro.bem-sibling-elem('box') {
239 background-color: fn.color(--disabled --box-border);
240
241 &::before {
242 background-color: fn.color(--disabled --box-bg);
243 }
244 }
245
246 &:checked {
247 @include iro.bem-sibling-elem('box') {
248 background-color: fn.color(--disabled --box-border);
249 }
250 }
251
252 &:indeterminate {
253 @include iro.bem-sibling-elem('box') {
254 background-color: fn.color(--disabled --box-border);
255 }
256 }
257 }
258 }
259 }
260 }
261}
diff --git a/src/objects/_divider.scss b/src/objects/_divider.scss
new file mode 100644
index 0000000..7d96206
--- /dev/null
+++ b/src/objects/_divider.scss
@@ -0,0 +1,203 @@
1@use 'sass:map';
2@use 'iro-sass/src/iro-sass' as iro;
3@use '../functions' as fn;
4@use '../config';
5
6$static-themes: 'black' 'white' !default;
7
8@include iro.props-namespace('divider') {
9 @include iro.props-store((
10 --dims: (
11 --margin-b: fn.global-dim(--size --85),
12
13 --strong: (
14 --border: fn.global-dim(--border --thick),
15 --label-font-size: fn.global-dim(--font-size --100),
16 ),
17 --medium: (
18 --border: fn.global-dim(--border --medium),
19 --label-font-size: fn.global-dim(--font-size --75),
20 ),
21 --faint: (
22 --border: fn.global-dim(--border --thin),
23 --label-font-size: fn.global-dim(--font-size --50),
24 ),
25 ),
26 --colors: (
27 --strong: (
28 --bg: fn.global-color(--text),
29 --label: fn.global-color(--text),
30 ),
31 --medium: (
32 --bg: fn.global-color(--border),
33 --label: fn.global-color(--text-mute),
34 ),
35 --faint: (
36 --bg: fn.global-color(--border),
37 --label: fn.global-color(--text-mute-more),
38 ),
39 ),
40 ));
41
42 @each $color in map.keys(map.get(config.$themes, config.$theme-default, --palettes)) {
43 @if $color != '--base' {
44 @include iro.props-store((
45 --colors: (
46 $color: (
47 --bg: fn.global-color($color --800),
48 --label: fn.global-color($color --1000),
49 )
50 ),
51 ));
52 }
53 }
54
55 @each $theme in $static-themes {
56 @include iro.props-store((
57 --colors: (
58 --static-#{$theme}: (
59 --strong: (
60 --bg: fn.global-color(--#{$theme}-transparent --800),
61 --label: fn.global-color(--#{$theme}-transparent --900),
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
76 @include iro.bem-object(iro.props-namespace()) {
77 display: flex;
78 flex: 0 0 auto;
79 flex-direction: row;
80 align-items: center;
81 block-size: 1em;
82 margin-block: fn.dim(--margin-b);
83 font-size: fn.dim(--strong --label-font-size);
84 font-weight: 700;
85 line-height: 1;
86 color: fn.color(--strong --label);
87 text-transform: uppercase;
88 letter-spacing: .5px;
89
90 &::before,
91 &::after {
92 flex: 1 1 auto;
93 inline-size: 100%;
94 block-size: fn.dim(--strong --border);
95 content: '';
96 background-color: fn.color(--strong --bg);
97 }
98
99 &::before {
100 display: block;
101 }
102
103 @include iro.bem-elem('label') {
104 flex: 0 0 auto;
105 }
106
107 @include iro.bem-modifier('vertical') {
108 align-self: stretch;
109 inline-size: 1px;
110 block-size: auto;
111 margin-block: 0;
112 background-color: fn.color(--faint --bg);
113
114 &::before,
115 &::after {
116 display: none;
117 }
118 }
119
120 @include iro.bem-modifier('medium') {
121 font-size: fn.dim(--medium --label-font-size);
122 font-weight: 500;
123 color: fn.color(--medium --label);
124
125 &::before,
126 &::after {
127 block-size: fn.dim(--medium --border);
128 background-color: fn.color(--medium --bg);
129 }
130 }
131
132 @include iro.bem-modifier('faint') {
133 font-size: fn.dim(--faint --label-font-size);
134 font-weight: 500;
135 color: fn.color(--faint --label);
136
137 &::before,
138 &::after {
139 block-size: fn.dim(--faint --border);
140 background-color: fn.color(--faint --bg);
141 }
142 }
143
144 @include iro.bem-modifier('labelled') {
145 &::before {
146 margin-inline-end: 1em;
147 }
148
149 &::after {
150 display: block;
151 margin-inline-start: 1em;
152 }
153 }
154
155 @each $color in 'blue' 'purple' 'red' 'green' 'yellow' {
156 @include iro.bem-modifier($color) {
157 &::before,
158 &::after {
159 background-color: fn.color(--#{$color} --bg);
160 }
161
162 @include iro.bem-elem('label') {
163 color: fn.color(--#{$color} --label);
164 }
165 }
166 }
167
168 @each $theme in $static-themes {
169 @include iro.bem-modifier(static-#{$theme}) {
170 &::before,
171 &::after {
172 background-color: fn.color(--static-#{$theme} --strong --bg);
173 }
174
175 @include iro.bem-elem('label') {
176 color: fn.color(--static-#{$theme} --strong --label);
177 }
178
179 @include iro.bem-modifier('medium') {
180 &::before,
181 &::after {
182 background-color: fn.color(--static-#{$theme} --medium --bg);
183 }
184
185 @include iro.bem-elem('label') {
186 color: fn.color(--static-#{$theme} --medium --label);
187 }
188 }
189
190 @include iro.bem-modifier('faint') {
191 &::before,
192 &::after {
193 background-color: fn.color(--static-#{$theme} --faint --bg);
194 }
195
196 @include iro.bem-elem('label') {
197 color: fn.color(--static-#{$theme} --faint --label);
198 }
199 }
200 }
201 }
202 }
203}
diff --git a/src/objects/_emoji.scss b/src/objects/_emoji.scss
new file mode 100644
index 0000000..41c614c
--- /dev/null
+++ b/src/objects/_emoji.scss
@@ -0,0 +1,73 @@
1@use 'iro-sass/src/iro-sass' as iro;
2@use '../functions' as fn;
3@use 'sass:math';
4
5@use 'icon';
6
7@include iro.props-namespace('emoji') {
8 @include iro.props-store((
9 --dims: (
10 --size: calc(1 / 14 * 18em),
11 --pad: .3em,
12 --rounding: fn.global-dim(--rounding),
13 --zoom: 3,
14 --valign: -.25em,
15
16 --125: (
17 --size: calc(1 / 14 * 23em),
18 --valign: -.45em,
19 ),
20
21 --150: (
22 --size: calc(1 / 14 * 28em),
23 --valign: -.65em,
24 ),
25
26 --200: (
27 --size: calc(1 / 14 * 38em),
28 --valign: -1em,
29 )
30 ),
31 --colors: (
32 --bg: fn.global-color(--border-mute),
33 )
34 ));
35
36 @include iro.bem-object(iro.props-namespace()) {
37 position: relative;
38 display: inline-block;
39 inline-size: calc(fn.dim(--size));
40 block-size: calc(fn.dim(--size));
41 padding: calc(fn.dim(--pad));
42 margin: calc(-1 * fn.dim(--pad));
43 vertical-align: fn.dim(--valign);
44 object-fit: contain;
45
46 @include iro.bem-modifier('icon') {
47 margin: calc(-1 * fn.dim(--pad) - .5 * (fn.dim(--size) - fn.foreign-dim(--icon, --size)));
48 vertical-align: fn.foreign-dim(--icon, --valign);
49 }
50
51 @each $size in '125' '150' '200' {
52 @include iro.bem-modifier($size) {
53 inline-size: fn.dim(--#{$size} --size);
54 block-size: fn.dim(--#{$size} --size);
55 vertical-align: fn.dim(--#{$size} --valign);
56
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 border-radius: calc(fn.dim(--rounding) / fn.dim(--zoom));
65 transition: transform .2s ease, background-color .2s ease;
66
67 &:hover {
68 background-color: fn.color(--bg);
69 transform: scale(fn.dim(--zoom));
70 }
71 }
72 }
73}
diff --git a/src/objects/_field-label.scss b/src/objects/_field-label.scss
new file mode 100644
index 0000000..ba3841a
--- /dev/null
+++ b/src/objects/_field-label.scss
@@ -0,0 +1,86 @@
1@use 'iro-sass/src/iro-sass' as iro;
2@use '../functions' as fn;
3
4@include iro.props-namespace('field-label') {
5 @include iro.props-store((
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
20 @include iro.bem-object(iro.props-namespace()) {
21 display: block;
22
23 @include iro.bem-elem('label') {
24 display: block;
25 flex: 0 0 auto;
26 padding-inline-end: fn.dim(--spacing-i);
27 font-size: fn.dim(--label-font-size);
28 font-weight: 400;
29 line-height: 1.3;
30 color: fn.color(--label);
31
32 @include iro.bem-next-elem('content') {
33 margin-block-start: fn.dim(--spacing-b);
34 }
35 }
36
37 @include iro.bem-elem('content') {
38 display: block;
39 flex: 1 1 auto;
40 }
41
42 @include iro.bem-elem('hint') {
43 display: block;
44 margin-block-start: fn.dim(--spacing-b);
45 font-size: fn.dim(--hint-font-size);
46 color: fn.color(--hint);
47 }
48
49 @include iro.bem-is('invalid') {
50 @include iro.bem-elem('hint') {
51 color: fn.color(--error-hint);
52 }
53 }
54
55 @include iro.bem-is('disabled') {
56 @include iro.bem-elem('label', 'hint') {
57 color: fn.color(--disabled);
58 }
59 }
60
61 @include iro.bem-modifier('align-start', 'align-end') {
62 display: flex;
63 align-items: baseline;
64
65 @include iro.bem-elem('label') {
66 display: inline-block;
67
68 @include iro.bem-next-elem('content') {
69 margin-block-start: 0;
70 }
71 }
72 }
73
74 @include iro.bem-modifier('align-start') {
75 @include iro.bem-elem('label') {
76 text-align: start;
77 }
78 }
79
80 @include iro.bem-modifier('align-end') {
81 @include iro.bem-elem('label') {
82 text-align: end;
83 }
84 }
85 }
86}
diff --git a/src/objects/_heading.scss b/src/objects/_heading.scss
new file mode 100644
index 0000000..7fbafea
--- /dev/null
+++ b/src/objects/_heading.scss
@@ -0,0 +1,116 @@
1@use 'iro-sass/src/iro-sass' as iro;
2@use '../functions' as fn;
3@use '../mixins' as mx;
4@use '../config';
5@use 'include-media/dist/include-media' as media;
6
7$sizes: 'xxl' 'xl' 'lg' 'md' 'sm' 'xs';
8
9@include iro.props-namespace('heading') {
10 @include iro.props-store((
11 --dims: (
12 --offset: -.02em,
13 ),
14 --colors: (
15 --bg: fn.global-color(--base --50),
16 ),
17 ));
18
19 @include iro.bem-object(iro.props-namespace()) {
20 @include mx.set-font(--headline);
21
22 display: block;
23 margin-block-start: fn.global-dim(--heading --margin-bs);
24 text-transform: none;
25 letter-spacing: normal;
26 transform: translateX(fn.dim(--offset));
27
28 & + & {
29 margin-block-start: fn.global-dim(--heading --margin-bs-sibling);
30 }
31
32 @include iro.bem-elem('highlight') {
33 background-image: linear-gradient(to top,
34 transparent .05em,
35 fn.color(--bg) .05em,
36 fn.color(--bg) .5em,
37 transparent .5em);
38 }
39
40 @include iro.bem-modifier('xxl') {
41 @include mx.heading-strong(--xxl);
42 }
43
44 @include iro.bem-modifier('xl') {
45 @include mx.heading-strong(--xl);
46 }
47
48 @include iro.bem-modifier('lg') {
49 @include mx.heading-medium(--lg);
50 }
51
52 @include iro.bem-modifier('md') {
53 @include mx.heading-medium(--md);
54 }
55
56 @include iro.bem-modifier('sm') {
57 @include mx.heading-faint(--sm);
58 }
59
60 @include iro.bem-modifier('xs') {
61 @include mx.heading-faint(--xs);
62 }
63
64 @include iro.bem-modifier('display') {
65 @include mx.set-font(--headline);
66
67 @include iro.bem-modifier('xxl') {
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 @include iro.bem-modifier('xl') {
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 @include iro.bem-modifier('lg') {
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 @include iro.bem-modifier('md') {
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 @include iro.bem-modifier('sm') {
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 @include iro.bem-modifier('xs') {
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}
diff --git a/src/objects/_icon.scss b/src/objects/_icon.scss
new file mode 100644
index 0000000..7cbb7db
--- /dev/null
+++ b/src/objects/_icon.scss
@@ -0,0 +1,26 @@
1@use 'iro-sass/src/iro-sass' as iro;
2@use '../functions' as fn;
3
4@include iro.props-namespace('icon') {
5 @include iro.props-store((
6 --dims: (
7 --stroke: 1.5px,
8 --size: calc(1 / 14 * 16em),
9 --valign: -.2em,
10 )
11 ));
12
13 @include iro.bem-object(iro.props-namespace()) {
14 display: inline;
15 inline-size: fn.dim(--size);
16 block-size: fn.dim(--size);
17 vertical-align: fn.dim(--valign);
18 stroke-linecap: round;
19 stroke-linejoin: round;
20 stroke-width: fn.dim(--stroke);
21
22 @include iro.bem-modifier('block') {
23 display: block;
24 }
25 }
26}
diff --git a/src/objects/_lightbox.scss b/src/objects/_lightbox.scss
new file mode 100644
index 0000000..edbc62a
--- /dev/null
+++ b/src/objects/_lightbox.scss
@@ -0,0 +1,313 @@
1@use 'iro-sass/src/iro-sass' as iro;
2@use '../functions' as fn;
3
4@use 'action-button';
5
6$static-themes: 'black' 'white' !default;
7
8@include iro.props-namespace('lightbox') {
9 @include iro.props-store((
10 --dims: (
11 --pad: fn.global-dim(--size --150),
12
13 --thumbnail: (
14 --size: fn.global-dim(--size --700),
15 --rounding: fn.global-dim(--rounding),
16 --spacing: fn.global-dim(--size --100),
17 --border: fn.global-dim(--border --thin),
18
19 --selected: (
20 --border: fn.global-dim(--border --medium),
21 ),
22
23 --key-focus: (
24 --border: fn.global-dim(--key-focus --border),
25 --border-offset: fn.global-dim(--key-focus --border-offset),
26 --outline: fn.global-dim(--key-focus --outline),
27 ),
28 ),
29
30 --close-button: (
31 --font-size: fn.global-dim(--font-size --200),
32 ),
33
34 --nav-button: (
35 --width: fn.global-dim(--size --2000),
36 --height: fn.global-dim(--size --3800),
37 --font-size: fn.global-dim(--font-size --200),
38 ),
39 ),
40 --colors: (
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
52 --key-focus: (
53 --border: fn.global-color(--focus --border),
54 --outline: fn.global-color(--focus --outline),
55 ),
56 ),
57 ),
58 ));
59
60 @each $theme in $static-themes {
61 @include iro.props-store((
62 --colors: (
63 --static-#{$theme}: (
64 --text: fn.global-color(--white-transparent --800),
65 --thumbnail: (
66 --border: fn.global-color(--white-transparent --400),
67
68 --hover: (
69 --border: fn.global-color(--white-transparent --500),
70 ),
71
72 --selected: (
73 --border: fn.global-color(--white-transparent --900),
74 ),
75
76 --key-focus: (
77 --border: fn.global-color(--#{$theme}-transparent --900),
78 --outline: fn.global-color(--#{$theme}-transparent --300),
79 ),
80 ),
81 )
82 )
83 ));
84 }
85
86 @include iro.props-store((
87 --dims: (
88 --thumbnail: (
89 --size: fn.global-dim(--size --600),
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 box-sizing: border-box;
100 display: grid;
101 flex: 1 1 auto;
102 grid-template-areas:
103 'header header header'
104 'prev content next'
105 'thumbnails thumbnails thumbnails'
106 'footer footer footer';
107 grid-template-rows: auto minmax(0, 1fr) auto auto;
108 grid-template-columns: auto minmax(0, 1fr) auto;
109 min-block-size: 0;
110
111 @include iro.bem-elem('header') {
112 display: flex;
113 grid-area: header;
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 box-sizing: border-box;
121 display: none;
122 grid-area: content;
123 place-self: center;
124 max-inline-size: 100%;
125 max-block-size: 100%;
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
135 @include iro.bem-next-elem('nav-btn') {
136 display: block;
137 }
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 display: flex;
171 grid-area: thumbnails;
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
178 @include iro.bem-elem('footer') {
179 display: flex;
180 grid-area: footer;
181 align-items: flex-start;
182 padding-block: 0 fn.dim(--pad);
183 padding-inline: fn.dim(--pad);
184 }
185
186 @include iro.bem-elem('thumbnail') {
187 position: relative;
188 flex: 0 0 auto;
189 inline-size: fn.dim(--thumbnail --size);
190 block-size: fn.dim(--thumbnail --size);
191 overflow: hidden;
192 border-radius: fn.dim(--thumbnail --rounding);
193 outline: fn.dim(--thumbnail --border) solid fn.color(--thumbnail --border);
194 outline-offset: calc(-1 * fn.dim(--thumbnail --border));
195 opacity: .75;
196
197 &:hover,
198 &:active,
199 &:focus-visible {
200 outline-color: fn.color(--thumbnail --hover --border);
201 opacity: 1;
202 }
203
204 @include iro.bem-is('selected') {
205 $focus-border-offset: calc(-1 * fn.dim(--thumbnail --selected --border));
206
207 margin: $focus-border-offset;
208 border: fn.dim(--thumbnail --selected --border) solid fn.color(--thumbnail --selected --border);
209 border-radius: calc(fn.dim(--thumbnail --rounding) - $focus-border-offset);
210 outline: none;
211 opacity: 1;
212 }
213
214 &:focus-visible {
215 $focus-border-offset: calc(-1 * fn.dim(--thumbnail --key-focus --border-offset));
216
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 position: absolute;
228 inset-block-start: 0;
229 inset-inline-start: 0;
230 display: block;
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 position: relative;
253 display: none;
254 align-self: center;
255 overflow: visible;
256 font-size: fn.dim(--nav-button --font-size);
257
258 &::before {
259 position: absolute;
260 inset-block-start: 50%;
261 display: block;
262 inline-size: fn.dim(--nav-button --width);
263 block-size: fn.dim(--nav-button --height);
264 content: '';
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
291 @include iro.bem-elem('thumbnail') {
292 outline-color: fn.color(--static-#{$theme} --thumbnail --border);
293
294 &:hover,
295 &:active,
296 &:focus-visible {
297 outline-color: fn.color(--static-#{$theme} --thumbnail --hover --border);
298 }
299
300 @include iro.bem-is('selected') {
301 border-color: fn.color(--static-#{$theme} --thumbnail --selected --border);
302 }
303
304 &:focus-visible {
305 border-color: transparent;
306 outline-color: fn.color(--static-#{$theme} --thumbnail --key-focus --border);
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);
308 }
309 }
310 }
311 }
312 }
313}
diff --git a/src/objects/_menu.scss b/src/objects/_menu.scss
new file mode 100644
index 0000000..12e9755
--- /dev/null
+++ b/src/objects/_menu.scss
@@ -0,0 +1,137 @@
1/* stylelint-disable length-zero-no-unit */
2
3@use 'iro-sass/src/iro-sass' as iro;
4@use '../functions' as fn;
5
6@use './icon';
7
8@include iro.props-namespace('menu') {
9 @include iro.props-store((
10 --dims: (
11 --spacing: 0em,
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
53 @include iro.bem-object(iro.props-namespace()) {
54 display: flex;
55 flex-direction: column;
56 gap: fn.dim(--spacing);
57
58 @include iro.bem-elem('header') {
59 padding-block: fn.dim(--item --pad-b);
60 padding-inline: fn.dim(--item --pad-i);
61 font-size: fn.dim(--header --font-size);
62 font-weight: 500;
63 color: fn.color(--header --label);
64 text-transform: uppercase;
65 letter-spacing: .5px;
66
67 @include iro.bem-next-twin-elem {
68 margin-block-start: calc(fn.dim(--separator) + fn.dim(--spacing));
69 }
70 }
71
72 @include iro.bem-elem('item') {
73 padding-block: fn.dim(--item --pad-b);
74 padding-inline: fn.dim(--item --pad-i);
75 margin: calc(-1 * fn.dim(--item --key-focus --outline));
76 color: fn.color(--item --disabled --label);
77 background-clip: padding-box;
78 border: fn.dim(--item --key-focus --outline) solid transparent;
79 border-radius: calc(fn.dim(--item --rounding) + fn.dim(--item --key-focus --outline));
80
81 &:link,
82 &:visited,
83 &:enabled {
84 color: currentColor;
85
86 @include iro.bem-multi('&:hover, &:focus-visible', 'is' 'selected') {
87 color: fn.color(--item --hover --label);
88 background-color: fn.color(--item --hover --bg);
89 }
90
91 &:active {
92 color: fn.color(--item --active --label);
93 background-color: fn.color(--item --active --bg);
94 }
95
96 &:focus-visible {
97 outline: fn.color(--item --key-focus --border) solid fn.dim(--item --key-focus --border);
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);
99 }
100 }
101
102 @include iro.bem-next-elem('header') {
103 margin-block-start: calc(fn.dim(--separator) + fn.dim(--spacing));
104 }
105 }
106
107 @include iro.bem-elem('header') {
108 &:link,
109 &:visited,
110 &:enabled {
111 color: fn.color(--header --label);
112 }
113 }
114
115 @include iro.bem-elem('separator') {
116 block-size: 1px;
117 margin-block: fn.dim(--separator);
118 margin-inline: fn.dim(--item --pad-i);
119 background-color: fn.color(--separator);
120 }
121
122 @include iro.bem-elem('slot') {
123 padding-block: fn.dim(--item --pad-b);
124 padding-inline: fn.dim(--item --pad-i);
125 }
126
127 @include iro.bem-elem('icon-slot') {
128 display: flex;
129 justify-content: center;
130 inline-size: fn.foreign-dim(--icon, --size);
131 }
132
133 @include iro.bem-modifier('pull') {
134 margin: calc(-1 * fn.dim(--item --pad-i));
135 }
136 }
137}
diff --git a/src/objects/_palette.scss b/src/objects/_palette.scss
new file mode 100644
index 0000000..8291750
--- /dev/null
+++ b/src/objects/_palette.scss
@@ -0,0 +1,62 @@
1@use 'sass:map';
2@use 'sass:list';
3@use 'sass:string';
4@use 'iro-sass/src/iro-sass' as iro;
5@use '../functions' as fn;
6@use '../config';
7
8@include iro.props-namespace('palette') {
9 @include iro.bem-object(iro.props-namespace()) {
10 display: flex;
11 block-size: 3em;
12
13 @include iro.bem-elem('item') {
14 flex: 1 1 auto;
15
16 $palette: map.get(config.$themes, config.$theme-default, --palettes, --base);
17 $contrasts: map.get(config.$themes, config.$theme-default, --contrasts, list.nth($palette, 2));
18
19 @for $i from 1 through list.length($contrasts) {
20 $key: list.nth(map.keys($contrasts), $i);
21
22 &:nth-child(#{$i}) {
23 background-color: fn.global-color(--base $key);
24 }
25 }
26 }
27
28 @each $palette-name, $palette in map.get(config.$themes, config.$theme-default, --palettes) {
29 $contrasts: map.get(config.$themes, config.$theme-default, --contrasts, list.nth($palette, 2));
30
31 @include iro.bem-modifier(string.slice($palette-name, 3)) {
32 @include iro.bem-elem('item') {
33 @for $i from 1 through list.length($contrasts) {
34 $key: list.nth(map.keys($contrasts), $i);
35
36 &:nth-child(#{$i}) {
37 background-color: fn.global-color($palette-name $key);
38 }
39 }
40 }
41 }
42 }
43
44 @include iro.bem-modifier('static') {
45 @each $palette-name, $palette in map.get(config.$static-colors, --palettes) {
46 $contrasts: map.get(config.$static-colors, --contrasts);
47
48 @include iro.bem-modifier(string.slice($palette-name, 3)) {
49 @include iro.bem-elem('item') {
50 @for $i from 1 through list.length($contrasts) {
51 $key: list.nth(map.keys($contrasts), $i);
52
53 &:nth-child(#{$i}) {
54 background-color: fn.global-color(#{$palette-name}-static $key);
55 }
56 }
57 }
58 }
59 }
60 }
61 }
62}
diff --git a/src/objects/_popover.scss b/src/objects/_popover.scss
new file mode 100644
index 0000000..13550eb
--- /dev/null
+++ b/src/objects/_popover.scss
@@ -0,0 +1,51 @@
1@use 'iro-sass/src/iro-sass' as iro;
2@use '../functions' as fn;
3
4@include iro.props-namespace('popover') {
5 @include iro.props-store((
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
26 @include iro.bem-object(iro.props-namespace()) {
27 position: absolute;
28 inset-block-start: 0;
29 inset-inline-start: 0;
30 z-index: fn.dim(--z-index);
31 padding-block: fn.dim(--pad-b);
32 padding-inline: fn.dim(--pad-i);
33 background-color: fn.color(--bg);
34 filter: fn.color(--filter);
35 border: fn.dim(--border) solid fn.color(--border);
36 border-radius: fn.dim(--rounding);
37 transform: translate(var(--x), var(--y));
38
39 @include iro.bem-modifier('up-left') {
40 transform: translate(var(--x), calc(var(--y) - 100%));
41 }
42
43 @include iro.bem-modifier('up-right') {
44 transform: translate(calc(var(--x) - 100%), calc(var(--y) - 100%));
45 }
46
47 @include iro.bem-modifier('down-right') {
48 transform: translate(calc(var(--x) - 100%), var(--y));
49 }
50 }
51}
diff --git a/src/objects/_radio.scss b/src/objects/_radio.scss
new file mode 100644
index 0000000..ad3e8d4
--- /dev/null
+++ b/src/objects/_radio.scss
@@ -0,0 +1,185 @@
1@use 'iro-sass/src/iro-sass' as iro;
2@use '../functions' as fn;
3
4@include iro.props-namespace('radio') {
5 @include iro.props-store((
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
15 --key-focus: (
16 --border: fn.global-dim(--key-focus --border),
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
49 @include iro.bem-object(iro.props-namespace()) {
50 position: relative;
51 display: inline-block;
52 padding-block: fn.dim(--pad-b);
53 padding-inline: fn.dim(--pad-i);
54 margin-inline:
55 calc(-1 * fn.dim(--pad-i) - fn.dim(--key-focus --border-offset))
56 calc(fn.dim(--spacing-sibling) - fn.dim(--pad-i) - fn.dim(--key-focus --border-offset));
57
58 @include iro.bem-elem('circle') {
59 display: inline-block;
60 flex: 0 0 auto;
61 inline-size: fn.dim(--diameter);
62 block-size: fn.dim(--diameter);
63 margin-block-start: calc(.5em * fn.global-dim(--font --standard --line-height) - .5 * fn.dim(--diameter) - fn.dim(--key-focus --border-offset));
64 vertical-align: top;
65 background-color: fn.color(--circle-border);
66 background-clip: padding-box;
67 border: fn.dim(--key-focus --border-offset) solid transparent;
68 border-radius: 2em;
69
70 &::after {
71 position: relative;
72 inset-block-start: fn.dim(--border);
73 inset-inline-start: fn.dim(--border);
74 display: block;
75 inline-size: calc(fn.dim(--diameter) - 2 * fn.dim(--border));
76 block-size: calc(fn.dim(--diameter) - 2 * fn.dim(--border));
77 content: '';
78 background-color: fn.color(--circle-bg);
79 border-radius: fn.dim(--diameter);
80 transition: transform .2s ease;
81 }
82 }
83
84 @include iro.bem-elem('label') {
85 margin-inline-start: calc(fn.dim(--label-gap) - fn.dim(--key-focus --border-offset));
86 }
87
88 @include iro.bem-elem('native') {
89 position: absolute;
90 inset-block-start: 0;
91 inset-inline-start: 0;
92 z-index: -1;
93 inline-size: 100%;
94 block-size: 100%;
95 padding: 0;
96 margin: 0;
97 overflow: hidden;
98 appearance: none;
99 border-radius: fn.dim(--rounding);
100
101 &:hover,
102 &:focus-visible {
103 @include iro.bem-sibling-elem('label') {
104 color: fn.color(--hover --label);
105 }
106
107 @include iro.bem-sibling-elem('circle') {
108 background-color: fn.color(--hover --circle-border);
109 }
110 }
111
112 &:checked {
113 @include iro.bem-sibling-elem('circle') {
114 &::after {
115 transform: scale(.44);
116 }
117 }
118 }
119
120 &:disabled {
121 @include iro.bem-sibling-elem('label') {
122 color: fn.color(--disabled --label);
123 }
124
125 @include iro.bem-sibling-elem('circle') {
126 background-color: fn.color(--disabled --circle-border);
127
128 &::after {
129 background-color: fn.color(--disabled --circle-bg);
130 }
131 }
132 }
133
134 &:focus-visible {
135 @include iro.bem-sibling-elem('label') {
136 color: fn.color(--key-focus --label);
137 }
138
139 @include iro.bem-sibling-elem('circle') {
140 outline: fn.color(--key-focus --border) solid fn.dim(--key-focus --border);
141 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(--key-focus --outline);
142 }
143 }
144 }
145
146 @include iro.bem-modifier('standalone') {
147 @include iro.bem-elem('circle') {
148 margin-block-start: 0;
149 }
150 }
151
152 @include iro.bem-modifier('accent') {
153 @include iro.bem-elem('native') {
154 &:checked {
155 @include iro.bem-sibling-elem('circle') {
156 background-color: fn.color(--accent --circle-border);
157 }
158
159 &:hover,
160 &:focus-visible {
161 @include iro.bem-sibling-elem('circle') {
162 background-color: fn.color(--accent --hover --circle-border);
163 }
164 }
165 }
166
167 &:disabled {
168 @include iro.bem-sibling-elem('circle') {
169 background-color: fn.color(--disabled --circle-border);
170
171 &::after {
172 background-color: fn.color(--disabled --circle-bg);
173 }
174 }
175
176 &:checked {
177 @include iro.bem-sibling-elem('circle') {
178 background-color: fn.color(--disabled --circle-border);
179 }
180 }
181 }
182 }
183 }
184 }
185}
diff --git a/src/objects/_side-nav.scss b/src/objects/_side-nav.scss
new file mode 100644
index 0000000..237b5aa
--- /dev/null
+++ b/src/objects/_side-nav.scss
@@ -0,0 +1,122 @@
1@use 'iro-sass/src/iro-sass' as iro;
2@use '../functions' as fn;
3
4@use './icon';
5
6@include iro.props-namespace('side-nav') {
7 @include iro.props-store((
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
50 @include iro.bem-object(iro.props-namespace()) {
51 display: flex;
52 flex-direction: column;
53 gap: fn.dim(--spacing);
54
55 @include iro.bem-elem('header') {
56 padding-block: fn.dim(--item --pad-b);
57 padding-inline: fn.dim(--item --pad-i);
58 font-size: fn.dim(--header --font-size);
59 font-weight: 500;
60 color: fn.color(--header --label);
61 text-transform: uppercase;
62 letter-spacing: .5px;
63
64 @include iro.bem-next-twin-elem {
65 margin-block-start: calc(fn.dim(--separator) + fn.dim(--spacing));
66 }
67 }
68
69 @include iro.bem-elem('item') {
70 padding-block: fn.dim(--item --pad-b);
71 padding-inline: fn.dim(--item --pad-i);
72 margin: calc(-1 * fn.dim(--item --key-focus --border-offset));
73 color: fn.color(--item --disabled --label);
74 background-clip: padding-box;
75 border: fn.dim(--item --key-focus --border-offset) solid transparent;
76 border-radius: calc(fn.dim(--item --rounding) + fn.dim(--item --key-focus --border-offset));
77
78 &:link,
79 &:visited,
80 &:enabled {
81 color: currentColor;
82
83 @include iro.bem-multi('&:hover, &:focus-visible', 'is' 'selected') {
84 color: fn.color(--item --hover --label);
85 background-color: fn.color(--item --hover --bg);
86 }
87
88 &:active {
89 color: fn.color(--item --active --label);
90 background-color: fn.color(--item --active --bg);
91 }
92
93 &:focus-visible {
94 outline: fn.color(--item --key-focus --border) solid fn.dim(--item --key-focus --border);
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);
96 }
97 }
98
99 @include iro.bem-next-elem('header') {
100 margin-block-start: calc(fn.dim(--separator) + fn.dim(--spacing));
101 }
102 }
103
104 @include iro.bem-elem('header') {
105 &:link,
106 &:visited,
107 &:enabled {
108 color: fn.color(--header --label);
109 }
110 }
111
112 @include iro.bem-elem('separator') {
113 block-size: fn.dim(--separator);
114 }
115
116 @include iro.bem-elem('icon-slot') {
117 display: flex;
118 justify-content: center;
119 inline-size: fn.foreign-dim(--icon, --size);
120 }
121 }
122}
diff --git a/src/objects/_status-indicator.scss b/src/objects/_status-indicator.scss
new file mode 100644
index 0000000..ce1794a
--- /dev/null
+++ b/src/objects/_status-indicator.scss
@@ -0,0 +1,39 @@
1@use 'iro-sass/src/iro-sass' as iro;
2@use '../functions' as fn;
3
4$themes: 'accent' 'positive' 'negative' 'warning' !default;
5
6@include iro.props-namespace('status-indicator') {
7 @include iro.props-store((
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
17 @each $theme in $themes {
18 @include iro.props-store((
19 --colors: (
20 --#{$theme}: fn.global-color(--#{$theme} --700),
21 ),
22 ));
23 }
24
25 @include iro.bem-object(iro.props-namespace()) {
26 display: inline-block;
27 inline-size: fn.dim(--size);
28 block-size: fn.dim(--size);
29 vertical-align: middle;
30 background-color: fn.color(--default);
31 border-radius: 10em;
32
33 @each $theme in $themes {
34 @include iro.bem-is($theme) {
35 background-color: fn.color(--#{$theme});
36 }
37 }
38 }
39}
diff --git a/src/objects/_switch.scss b/src/objects/_switch.scss
new file mode 100644
index 0000000..fa903b1
--- /dev/null
+++ b/src/objects/_switch.scss
@@ -0,0 +1,222 @@
1@use 'iro-sass/src/iro-sass' as iro;
2@use '../functions' as fn;
3
4@include iro.props-namespace('switch') {
5 @include iro.props-store((
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
16 --key-focus: (
17 --border: fn.global-dim(--key-focus --border),
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
52 @include iro.bem-object(iro.props-namespace()) {
53 position: relative;
54 display: inline-block;
55 padding-block: fn.dim(--pad-b);
56 padding-inline: fn.dim(--pad-i);
57 margin-inline:
58 calc(-1 * fn.dim(--pad-i) - fn.dim(--key-focus --border-offset))
59 calc(fn.dim(--spacing-sibling) - fn.dim(--pad-i) - fn.dim(--key-focus --border-offset));
60
61 @include iro.bem-elem('indicator') {
62 display: inline-block;
63 flex: 0 0 auto;
64 inline-size: fn.dim(--width);
65 block-size: fn.dim(--height);
66 margin-block-start: calc(.5em * fn.global-dim(--font --standard --line-height) - .5 * fn.dim(--height) - fn.dim(--key-focus --border-offset));
67 vertical-align: top;
68 background-color: fn.color(--track-bg);
69 background-clip: padding-box;
70 border: fn.dim(--key-focus --border-offset) solid transparent;
71 border-radius: 2em;
72 transition: background-color .2s ease;
73
74 &::after {
75 display: block;
76 inline-size: calc(fn.dim(--height) - 2 * fn.dim(--border));
77 block-size: calc(fn.dim(--height) - 2 * fn.dim(--border));
78 content: '';
79 background-color: fn.color(--handle-bg);
80 border: fn.dim(--border) solid fn.color(--handle-border);
81 border-radius: fn.dim(--width);
82 transition: transform .2s ease;
83 }
84 }
85
86 @include iro.bem-elem('label') {
87 margin-inline-start: fn.dim(--label-gap);
88 }
89
90 @include iro.bem-elem('native') {
91 position: absolute;
92 inset-block-start: 0;
93 inset-inline-start: 0;
94 z-index: -1;
95 inline-size: 100%;
96 block-size: 100%;
97 padding: 0;
98 margin: 0;
99 overflow: hidden;
100 appearance: none;
101 border-radius: fn.dim(--rounding);
102
103 &:hover,
104 &:focus-visible {
105 @include iro.bem-sibling-elem('label') {
106 color: fn.color(--hover --label);
107 }
108
109 @include iro.bem-sibling-elem('indicator') {
110 &::after {
111 border-color: fn.color(--hover --handle-border);
112 }
113 }
114 }
115
116 &:checked {
117 @include iro.bem-sibling-elem('indicator') {
118 background-color: fn.color(--handle-border);
119
120 &::after {
121 border-color: fn.color(--handle-border);
122 transform: translate(calc(fn.dim(--width) - fn.dim(--height) + .5px), 0);
123 }
124 }
125
126 &:hover,
127 &:focus-visible {
128 @include iro.bem-sibling-elem('indicator') {
129 background-color: fn.color(--hover --handle-border);
130
131 &::after {
132 border-color: fn.color(--hover --handle-border);
133 }
134 }
135 }
136 }
137
138 &:disabled {
139 @include iro.bem-sibling-elem('label') {
140 color: fn.color(--disabled --label);
141 }
142
143 @include iro.bem-sibling-elem('indicator') {
144 background-color: fn.color(--disabled --track-bg);
145
146 &::after {
147 background-color: fn.color(--disabled --handle-bg);
148 border-color: fn.color(--disabled --handle-border);
149 }
150 }
151
152 &:checked {
153 @include iro.bem-sibling-elem('indicator') {
154 background-color: fn.color(--disabled --handle-border);
155
156 &::after {
157 border-color: fn.color(--disabled --handle-border);
158 }
159 }
160 }
161 }
162
163 &:focus-visible {
164 @include iro.bem-sibling-elem('label') {
165 color: fn.color(--key-focus --label);
166 }
167
168 @include iro.bem-sibling-elem('indicator') {
169 outline: fn.color(--key-focus --border) solid fn.dim(--key-focus --border);
170 box-shadow: 0 0 0 calc(fn.dim(--key-focus --border) + fn.dim(--key-focus --outline)) fn.color(--key-focus --outline);
171 }
172 }
173 }
174
175 @include iro.bem-modifier('standalone') {
176 @include iro.bem-elem('indicator') {
177 margin-block-start: 0;
178 }
179 }
180
181 @include iro.bem-modifier('accent') {
182 @include iro.bem-elem('native') {
183 &:checked {
184 @include iro.bem-sibling-elem('indicator') {
185 background-color: fn.color(--accent --handle-border);
186
187 &::after {
188 border-color: fn.color(--accent --handle-border);
189 }
190 }
191
192 &:hover,
193 &:focus-visible {
194 @include iro.bem-sibling-elem('indicator') {
195 background-color: fn.color(--accent --hover --handle-border);
196
197 &::after {
198 border-color: fn.color(--accent --hover --handle-border);
199 }
200 }
201 }
202 }
203
204 &:disabled {
205 @include iro.bem-sibling-elem('label') {
206 color: fn.color(--disabled --label);
207 }
208
209 &:checked {
210 @include iro.bem-sibling-elem('indicator') {
211 background-color: fn.color(--disabled --handle-border);
212
213 &::after {
214 border-color: fn.color(--disabled --handle-border);
215 }
216 }
217 }
218 }
219 }
220 }
221 }
222}
diff --git a/src/objects/_table.scss b/src/objects/_table.scss
new file mode 100644
index 0000000..5b16d66
--- /dev/null
+++ b/src/objects/_table.scss
@@ -0,0 +1,168 @@
1@use 'iro-sass/src/iro-sass' as iro;
2@use '../functions' as fn;
3@use '../mixins' as mx;
4
5@include iro.props-namespace('table') {
6 @include iro.props-store((
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
13 --sm: (
14 --pad-b: fn.global-dim(--size --75),
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
30 @include iro.bem-object(iro.props-namespace()) {
31 border-spacing: 0;
32 border-collapse: separate;
33
34 @include iro.bem-modifier('fixed') {
35 table-layout: fixed;
36 }
37
38 @include iro.bem-elem('head-cell') {
39 @include mx.set-font(--standard, (
40 --line-height: null,
41 --size: fn.global-dim(--font-size --50),
42 --weight: bold,
43 --transform: uppercase,
44 --spacing: .5px
45 ));
46 padding-block: fn.dim(--pad-b);
47
48 padding-inline: fn.dim(--pad-i);
49 color: fn.color(--heading);
50 text-align: start;
51 }
52
53 @include iro.bem-elem('cell') {
54 padding-block: fn.dim(--pad-b);
55 padding-inline: fn.dim(--pad-i);
56 border-color: fn.color(--border);
57 border-style: solid;
58 border-width: 0;
59 border-block-start-width: fn.dim(--border);
60
61 @include iro.bem-modifier('divider') {
62 border-inline-end-width: fn.dim(--border);
63 }
64 }
65
66 @include iro.bem-elem('row') {
67 &:last-child {
68 @include iro.bem-elem('cell') {
69 border-block-end-width: fn.dim(--border);
70 }
71 }
72 }
73
74 @include iro.bem-modifier('flush') {
75 @include iro.bem-elem('head-cell', 'cell') {
76 &:first-child {
77 padding-inline-start: 0;
78 }
79
80 &:last-child {
81 padding-inline-end: 0;
82 }
83 }
84 }
85
86 @include iro.bem-modifier('box') {
87 @include iro.bem-elem('cell') {
88 background-color: fn.color(--box --bg);
89
90 &:first-child {
91 border-inline-start-width: fn.dim(--border);
92 }
93
94 &:last-child {
95 border-inline-end-width: fn.dim(--border);
96 }
97 }
98
99 @include iro.bem-elem('row') {
100 &:first-child {
101 @include iro.bem-elem('cell') {
102 &:first-child {
103 border-start-start-radius: fn.dim(--rounding);
104 }
105
106 &:last-child {
107 border-start-end-radius: fn.dim(--rounding);
108 }
109 }
110 }
111
112 &:last-child {
113 @include iro.bem-elem('cell') {
114 &:first-child {
115 border-end-start-radius: fn.dim(--rounding);
116 }
117
118 &:last-child {
119 border-end-end-radius: fn.dim(--rounding);
120 }
121 }
122 }
123 }
124 }
125
126 @include iro.bem-modifier('interactive') {
127 @include iro.bem-elem('row') {
128 @include iro.bem-elem('cell') {
129 cursor: pointer;
130 }
131
132 &:hover {
133 @include iro.bem-elem('cell') {
134 background-color: fn.color(--hover);
135 }
136 }
137
138 &:active {
139 @include iro.bem-elem('cell') {
140 background-color: fn.color(--active);
141 }
142 }
143 }
144
145 @include iro.bem-modifier('box') {
146 @include iro.bem-elem('row') {
147 &:hover {
148 @include iro.bem-elem('cell') {
149 background-color: fn.color(--box --hover);
150 }
151 }
152
153 &:active {
154 @include iro.bem-elem('cell') {
155 background-color: fn.color(--box --active);
156 }
157 }
158 }
159 }
160 }
161
162 @include iro.bem-modifier('sm') {
163 @include iro.bem-elem('head-cell', 'cell') {
164 padding-block: fn.dim(--sm --pad-b);
165 }
166 }
167 }
168}
diff --git a/src/objects/_text-field.scss b/src/objects/_text-field.scss
new file mode 100644
index 0000000..cfb5a6d
--- /dev/null
+++ b/src/objects/_text-field.scss
@@ -0,0 +1,213 @@
1@use 'iro-sass/src/iro-sass' as iro;
2@use '../functions' as fn;
3
4@mixin invalid {
5 $focus-border-offset: calc(fn.dim(--border) - fn.dim(--focus --border));
6
7 @include iro.bem-sibling-elem('bg') {
8 inset-block: $focus-border-offset;
9 inset-inline: $focus-border-offset;
10 border: fn.dim(--focus --border) solid fn.color(--error --border);
11 border-radius: calc(fn.dim(--rounding) - $focus-border-offset);
12 }
13
14 &:hover {
15 @include iro.bem-sibling-elem('bg') {
16 border-color: fn.color(--error --hover --border);
17 }
18 }
19
20 &:focus {
21 @include iro.bem-sibling-elem('bg') {
22 border-color: fn.color(--error --focus --border);
23 }
24 }
25}
26
27@mixin keyboard-focus {
28 @include iro.bem-sibling-elem('bg') {
29 border-color: fn.color(--key-focus --border);
30 outline: fn.color(--key-focus --outline) solid fn.dim(--key-focus --border);
31 //outline-offset: fn.dim(--focus --border);
32 }
33}
34
35@include iro.props-namespace('text-field') {
36 @include iro.props-store((
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
44 --extended: (
45 --pad: fn.global-dim(--size --50),
46 ),
47
48 --focus: (
49 --border: fn.global-dim(--border --medium),
50 ),
51
52 --key-focus: (
53 --border: fn.global-dim(--key-focus --outline),
54 ),
55 ),
56 --colors: (
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
91 @include iro.bem-object(iro.props-namespace()) {
92 $focus-border-offset: calc(fn.dim(--border) - fn.dim(--focus --border));
93
94 position: relative;
95 min-inline-size: 0;
96 background-color: fn.color(--bg);
97 border-radius: fn.dim(--rounding);
98
99 @include iro.bem-elem('bg') {
100 position: absolute;
101 inset-block: 0;
102 inset-inline: 0;
103 display: block;
104 pointer-events: none;
105 border: fn.dim(--border) solid fn.color(--border);
106 border-radius: fn.dim(--rounding);
107 }
108
109 @include iro.bem-elem('native') {
110 box-sizing: border-box;
111 inline-size: 100%;
112 padding-block: calc(fn.dim(--pad-b) - .5em * (fn.dim(--line-height) - 1));
113 padding-inline: fn.dim(--pad-i);
114 font: inherit;
115 line-height: fn.dim(--line-height);
116 color: fn.color(--text);
117 appearance: none;
118 resize: none;
119 background-color: transparent;
120 border: 1px solid transparent;
121
122 &::placeholder {
123 font-style: italic;
124 color: fn.color(--placeholder);
125 opacity: 1;
126 }
127
128 &:hover {
129 @include iro.bem-sibling-elem('bg') {
130 border-color: fn.color(--hover --border);
131 }
132 }
133
134 &:focus {
135 outline: 0;
136
137 @include iro.bem-sibling-elem('bg') {
138 inset-block: $focus-border-offset;
139 inset-inline: $focus-border-offset;
140 border: fn.dim(--focus --border) solid fn.color(--focus --border);
141 border-radius: calc(fn.dim(--rounding) - $focus-border-offset);
142 }
143 }
144
145 &:invalid {
146 @include invalid;
147 }
148
149 &:focus-visible,
150 &:invalid:focus-visible {
151 @include keyboard-focus;
152 }
153 }
154
155 @include iro.bem-modifier('extended') {
156 padding: fn.dim(--extended --pad);
157
158 @include iro.bem-multi('&', 'elem' 'bg') {
159 border-radius: calc(fn.dim(--rounding) + fn.dim(--extended --pad));
160 }
161
162 @include iro.bem-elem('native') {
163 &:focus {
164 @include iro.bem-sibling-elem('bg') {
165 border-radius: calc(fn.dim(--rounding) + fn.dim(--extended --pad) - $focus-border-offset);
166 }
167 }
168 }
169 }
170
171 @include iro.bem-is('invalid') {
172 @include iro.bem-elem('native') {
173 @include invalid;
174
175 &:focus-visible {
176 @include keyboard-focus;
177 }
178 }
179 }
180
181 @include iro.bem-is('disabled') {
182 background-color: fn.color(--disabled --bg);
183
184 @include iro.bem-elem('native') {
185 color: fn.color(--disabled --text);
186
187 &::placeholder {
188 color: fn.color(--disabled --placeholder);
189 }
190 }
191
192 @include iro.bem-elem('bg') {
193 border-color: fn.color(--disabled --border);
194 }
195
196 @include iro.bem-is('invalid') {
197 @include iro.bem-elem('native') {
198 @include iro.bem-sibling-elem('bg') {
199 border-color: fn.color(--disabled --border);
200 }
201 }
202 }
203
204 @include iro.bem-elem('native') {
205 &:invalid {
206 @include iro.bem-sibling-elem('bg') {
207 border-color: fn.color(--disabled --border);
208 }
209 }
210 }
211 }
212 }
213}
diff --git a/src/scopes/_blockquotes.scss b/src/scopes/_blockquotes.scss
new file mode 100644
index 0000000..7f93e42
--- /dev/null
+++ b/src/scopes/_blockquotes.scss
@@ -0,0 +1,25 @@
1@use 'sass:meta';
2@use 'iro-sass/src/iro-sass' as iro;
3@use '../props';
4
5@forward 'blockquotes.vars';
6@use 'blockquotes.vars' as vars;
7
8@mixin styles {
9 @include props.materialize(meta.module-variables('vars'));
10
11 @include iro.bem-scope('blockquotes') {
12 blockquote {
13 padding-inline-start: calc(props.get(vars.$indent) - props.get(vars.$border-width));
14 margin-block: props.get(vars.$margin-bs);
15 margin-inline: 1px 0;
16 border-inline-start: props.get(vars.$border-width) solid props.get(vars.$border-color);
17 }
18
19 @include iro.bem-modifier('compact') {
20 blockquote {
21 padding-inline-start: calc(props.get(vars.$compact--indent) - props.get(vars.$border-width));
22 }
23 }
24 }
25}
diff --git a/src/scopes/_blockquotes.vars.scss b/src/scopes/_blockquotes.vars.scss
new file mode 100644
index 0000000..a3f8d85
--- /dev/null
+++ b/src/scopes/_blockquotes.vars.scss
@@ -0,0 +1,11 @@
1@use '../props';
2@use '../vars';
3@use './implicit.vars' as implicit-vars;
4
5$indent: props.def(--s-blockquotes--indent, props.get(vars.$list--indent)) !default;
6$margin-bs: props.def(--s-blockquotes--margin-bs, props.get(implicit-vars.$paragraph--margin-bs)) !default;
7$border-width: props.def(--s-blockquotes--border-width, props.get(vars.$border-width--thick)) !default;
8
9$compact--indent: props.def(--s-blockquotes--compact--indent, props.get(vars.$list--compact-indent)) !default;
10
11$border-color: props.def(--s-blockquotes--border-width, props.get(vars.$theme, --border)) !default;
diff --git a/src/scopes/_code.scss b/src/scopes/_code.scss
new file mode 100644
index 0000000..0d8cdd0
--- /dev/null
+++ b/src/scopes/_code.scss
@@ -0,0 +1,39 @@
1@use 'sass:meta';
2@use 'iro-sass/src/iro-sass' as iro;
3@use '../props';
4
5@forward 'code.vars';
6@use 'code.vars' as vars;
7
8@mixin styles {
9 @include props.materialize(meta.module-variables('vars'));
10
11 @include iro.bem-scope('code') {
12 code {
13 padding-block: props.get(vars.$inline--pad-b);
14 padding-inline: props.get(vars.$inline--pad-i);
15 color: props.get(vars.$inline--fg);
16 background-color: props.get(vars.$inline--bg);
17 border-radius: props.get(vars.$inline--rounding);
18 }
19
20 pre {
21 padding-block: props.get(vars.$block--pad-b);
22 padding-inline: props.get(vars.$block--pad-i);
23 margin-block: props.get(vars.$block--margin-bs) 0;
24 margin-inline: 0;
25 color: props.get(vars.$block--fg);
26 background-color: props.get(vars.$block--bg);
27 border-radius: props.get(vars.$block--rounding);
28
29 code {
30 display: inline-block;
31 padding: 0;
32 margin-inline-end: props.get(vars.$block--pad-i);
33 color: currentColor;
34 background-color: transparent;
35 border-radius: 0;
36 }
37 }
38 }
39}
diff --git a/src/scopes/_code.vars.scss b/src/scopes/_code.vars.scss
new file mode 100644
index 0000000..27d75f7
--- /dev/null
+++ b/src/scopes/_code.vars.scss
@@ -0,0 +1,18 @@
1@use '../props';
2@use '../vars';
3@use './implicit.vars' as implicit-vars;
4
5$inline--pad-i: props.def(--s-code--inline--pad-i, props.get(vars.$size--50)) !default;
6$inline--pad-b: props.def(--s-code--inline--pad-b, props.get(vars.$size--10)) !default;
7$inline--rounding: props.def(--s-code--inline--rounding, props.get(vars.$rounding)) !default;
8
9$block--pad-i: props.def(--s-code--block--pad-i, props.get(vars.$size--150)) !default;
10$block--pad-b: props.def(--s-code--block--pad-b, props.get(vars.$size--85)) !default;
11$block--margin-bs: props.def(--s-code--block--margin-bs, props.get(implicit-vars.$paragraph--margin-bs)) !default;
12$block--rounding: props.def(--s-code--block--rounding, props.get(vars.$rounding)) !default;
13
14$inline--fg: props.def(--s-code--inline--fg, props.get(vars.$theme, --red, --1200)) !default;
15$inline--bg: props.def(--s-code--inline--bg, props.get(vars.$theme, --red, --200)) !default;
16
17$block--fg: props.def(--s-code--block--fg, props.get(vars.$theme, --text)) !default;
18$block--bg: props.def(--s-code--block--bg, props.get(vars.$theme, --base, --50)) !default;
diff --git a/src/scopes/_headings.scss b/src/scopes/_headings.scss
new file mode 100644
index 0000000..e97e9f2
--- /dev/null
+++ b/src/scopes/_headings.scss
@@ -0,0 +1,115 @@
1@use 'include-media/dist/include-media' as media;
2@use 'iro-sass/src/iro-sass' as iro;
3@use '../mixins' as mx;
4@use '../props';
5@use '../vars';
6
7@mixin styles {
8 @include iro.bem-scope('headings') {
9 h1,
10 h2,
11 h3,
12 h4,
13 h5,
14 h6 {
15 @include mx.set-font(--headline);
16
17 display: block;
18 text-transform: none;
19 letter-spacing: normal;
20 transform: translateX(-.06em);
21 }
22
23
24 h1 {
25 @include mx.heading-strong(--xxl);
26 }
27
28 h2 {
29 @include mx.heading-strong(--xl);
30 }
31
32 h3 {
33 @include mx.heading-medium(--lg);
34 }
35
36 h4 {
37 @include mx.heading-medium(--md);
38 }
39
40 h5 {
41 @include mx.heading-faint(--sm);
42 }
43
44 h6 {
45 @include mx.heading-faint(--xs);
46 }
47
48 @include iro.bem-elem('highlight') {
49 background-image: linear-gradient(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 @include iro.bem-modifier('display') {
57 h1,
58 h2,
59 h3,
60 h4,
61 h5,
62 h6 {
63 @include mx.set-font(--headline);
64 }
65
66 h1 {
67 @include mx.heading-strong(--display --xxl);
68
69 @include media.media('<=md') {
70 @include mx.heading-strong(--display-sm --xxl);
71 }
72 }
73
74 h2 {
75 @include mx.heading-strong(--display --xl);
76
77 @include media.media('<=md') {
78 @include mx.heading-strong(--display-sm --xl);
79 }
80 }
81
82 h3 {
83 @include mx.heading-strong(--display --lg);
84
85 @include media.media('<=md') {
86 @include mx.heading-strong(--display-sm --lg);
87 }
88 }
89
90 h4 {
91 @include mx.heading-strong(--display --md);
92
93 @include media.media('<=md') {
94 @include mx.heading-strong(--display-sm --md);
95 }
96 }
97
98 h5 {
99 @include mx.heading-medium(--display --sm);
100
101 @include media.media('<=md') {
102 @include mx.heading-medium(--display-sm --sm);
103 }
104 }
105
106 h6 {
107 @include mx.heading-faint(--display --xs);
108
109 @include media.media('<=md') {
110 @include mx.heading-faint(--display-sm --xs);
111 }
112 }
113 }
114 }
115}
diff --git a/src/scopes/_headings.vars.scss b/src/scopes/_headings.vars.scss
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/scopes/_headings.vars.scss
diff --git a/src/scopes/_implicit.scss b/src/scopes/_implicit.scss
new file mode 100644
index 0000000..9c17868
--- /dev/null
+++ b/src/scopes/_implicit.scss
@@ -0,0 +1,152 @@
1@use 'sass:math';
2@use 'sass:meta';
3@use 'iro-sass/src/iro-sass' as iro;
4@use '../props';
5@use '../vars' as global-vars;
6
7@forward 'implicit.vars';
8@use 'implicit.vars' as vars;
9
10@mixin styles {
11 @include props.materialize(meta.module-variables('vars'));
12
13 html {
14 accent-color: props.get(global-vars.$theme, --accent, --600);
15 scrollbar-color: props.get(global-vars.$theme, --text-disabled) transparent;
16 }
17
18 html,
19 body {
20 block-size: 100%;
21 }
22
23 body {
24 //@include mx.set-font(--standard, (--size: fn.dim(--font-size --100)));
25
26 padding: 0;
27 margin: 0;
28 color: props.get(global-vars.$theme, --text);
29 background-color: props.get(global-vars.$theme, --bg-base);
30 }
31
32 pre,
33 code {
34 font-feature-settings: 'calt' 0, 'dlig' 1, 'ss09' 1;
35 }
36
37 pre,
38 code {
39 //@include mx.set-font(--mono, (--size: .93em));
40 }
41
42 pre {
43 margin: 0;
44 overflow-x: auto;
45
46 code {
47 font-size: 1em;
48 color: currentColor;
49 }
50 }
51
52 h1,
53 h2,
54 h3,
55 h4,
56 h5,
57 h6 {
58 //@include mx.heading-medium(--md);
59
60 margin-block: props.get(vars.$heading--margin-bs) 0;
61
62 & + & {
63 margin-block-start: props.get(vars.$heading--margin-bs-sibling);
64 }
65 }
66
67 p {
68 margin-block: props.get(vars.$paragraph--margin-bs) 0;
69
70 &:empty {
71 display: none;
72 }
73 }
74
75 strong {
76 font-weight: bold;
77 }
78
79 small {
80 font-size: props.get(global-vars.$font-size--75);
81 }
82
83 ul,
84 ol {
85 padding: 0;
86 margin: 0;
87 list-style: none;
88 }
89
90 li {
91 padding: 0;
92 margin: 0;
93 }
94
95 :focus,
96 :focus-visible {
97 outline: 0;
98 }
99
100 :link,
101 :visited {
102 color: currentColor;
103 text-decoration: none;
104 }
105
106
107 button,
108 input,
109 textarea {
110 box-sizing: content-box;
111 padding: 0;
112 margin: 0;
113 font-family: inherit;
114 font-size: 1em;
115 font-style: inherit;
116 font-weight: inherit;
117 line-height: inherit;
118 color: currentColor;
119 text-align: inherit;
120 text-transform: inherit;
121 appearance: none;
122 background: none;
123 border: 0;
124
125 &::-moz-focus-inner {
126 border: 0;
127 }
128 }
129
130 input,
131 textarea {
132 &::placeholder {
133 color: props.get(global-vars.$theme, --text-mute);
134 opacity: 1;
135 }
136
137 &:disabled {
138 color: props.get(global-vars.$theme, --text-disabled);
139 }
140 }
141
142 textarea {
143 block-size: calc(1em * props.get(global-vars.$font--standard--line-height));
144 }
145
146 hr {
147 block-size: props.get(global-vars.$border-width--thin);
148 margin: 0;
149 background-color: props.get(global-vars.$theme, --border-color);
150 border: 0;
151 }
152}
diff --git a/src/scopes/_implicit.vars.scss b/src/scopes/_implicit.vars.scss
new file mode 100644
index 0000000..c18ca78
--- /dev/null
+++ b/src/scopes/_implicit.vars.scss
@@ -0,0 +1,7 @@
1@use '../props';
2@use '../vars';
3
4$paragraph--margin-bs: props.def(--s-implicit--paragraph--margin-bs, props.get(vars.$size--300)) !default;
5
6$heading--margin-bs: props.def(--s-implicit--heading--margin-bs, props.get(vars.$size--700)) !default;
7$heading--margin-bs-sibling: props.def(--s-implicit--heading--margin-bs-sibling, props.get(vars.$size--325)) !default;
diff --git a/src/scopes/_links.scss b/src/scopes/_links.scss
new file mode 100644
index 0000000..69793b2
--- /dev/null
+++ b/src/scopes/_links.scss
@@ -0,0 +1,93 @@
1@use 'sass:map';
2@use 'sass:meta';
3@use 'iro-sass/src/iro-sass' as iro;
4@use '../props';
5
6@forward 'links.vars';
7@use 'links.vars' as vars;
8
9@mixin styles {
10 @include props.materialize(meta.module-variables('vars'));
11
12 @include iro.bem-scope('links') {
13 :link,
14 :visited {
15 color: currentColor;
16 text-decoration: underline;
17 text-decoration-thickness: props.get(vars.$underline-width);
18 text-decoration-color: props.get(vars.$underline-color);
19 border-radius: props.get(vars.$rounding);
20 box-decoration-break: clone;
21
22 &:hover {
23 text-decoration: underline;
24 text-decoration-skip-ink: none;
25 text-decoration-thickness: props.get(vars.$hover--underline-width);
26 }
27
28 &:focus-visible {
29 color: props.get(vars.$key-focus--text-color);
30 text-decoration: none;
31 outline: props.get(vars.$key-focus--border-color) solid props.get(vars.$key-focus--border-width);
32 box-shadow:
33 0
34 0
35 0
36 calc(props.get(vars.$key-focus--border-width) + props.get(vars.$key-focus--outline-width))
37 props.get(vars.$key-focus--outline-color);
38 }
39 }
40
41 @include iro.bem-modifier('invisible') {
42 :link,
43 :visited {
44 text-decoration: none;
45 }
46 }
47
48 @include iro.bem-modifier('colored') {
49 :link {
50 color: props.get(vars.$colored--text-color);
51 text-decoration-color: props.get(vars.$colored--underline-color);
52
53 &:hover {
54 color: props.get(vars.$colored--hover--text-color);
55 }
56 }
57
58 :visited {
59 color: props.get(vars.$colored--visited--text-color);
60 text-decoration-color: props.get(vars.$colored--visited--underline-color);
61
62 &:hover {
63 color: props.get(vars.$colored--visited--hover--text-color);
64 }
65 }
66 }
67
68 @each $theme in map.keys(props.get(vars.$static-themes)) {
69 @include iro.bem-modifier($theme) {
70 :link,
71 :visited {
72 color: props.get(vars.$static-themes, $theme, --text-color);
73 text-decoration-color: props.get(vars.$static-themes, $theme, --underline-color);
74
75 &:hover {
76 color: props.get(vars.$static-themes, $theme, --hover, --text-color);
77 }
78
79 &:focus-visible {
80 color: props.get(vars.$static-themes, $theme, --key-focus, --text-color);
81 outline-color: props.get(vars.$static-themes, $theme, --key-focus, --border-color);
82 box-shadow:
83 0
84 0
85 0
86 calc(props.get(vars.$key-focus--border-width) + props.get(vars.$key-focus--outline-width))
87 props.get(vars.$static-themes, $theme, --key-focus, --outline-color);
88 }
89 }
90 }
91 }
92 }
93}
diff --git a/src/scopes/_links.vars.scss b/src/scopes/_links.vars.scss
new file mode 100644
index 0000000..7880204
--- /dev/null
+++ b/src/scopes/_links.vars.scss
@@ -0,0 +1,47 @@
1@use 'sass:map';
2@use '../props';
3@use '../vars';
4
5$rounding: props.def(--s-links--rounding, props.get(vars.$rounding)) !default;
6$underline-width: props.def(--s-links--underline-width, props.get(vars.$border-width--thin)) !default;
7$hover--underline-width: props.def(--s-links--hover--underline-width, props.get(vars.$border-width--medium)) !default;
8
9$key-focus--border-width: props.def(--s-links--key-focus--border-width, props.get(vars.$key-focus--border-width)) !default;
10$key-focus--border-offset: props.def(--s-links--key-focus--border-offset, props.get(vars.$key-focus--border-offset)) !default;
11$key-focus--outline-width: props.def(--s-links--key-focus--outline-width, props.get(vars.$key-focus--outline-width)) !default;
12
13$underline-color: props.def(--s-links--underline-color, props.get(vars.$theme, --text-mute-more)) !default;
14
15$colored--text-color: props.def(--s-links--colored--text-color, props.get(vars.$theme, --accent, --1100)) !default;
16$colored--underline-color: props.def(--s-links--colored--underline-color, props.get(vars.$theme, --accent, --600)) !default;
17$colored--hover--text-color: props.def(--s-links--colored--hover--text-color, props.get(vars.$theme, --accent, --1300)) !default;
18
19$colored--visited--text-color: props.def(--s-links--colored--visited--text-color, props.get(vars.$theme, --purple, --1100)) !default;
20$colored--visited--underline-color: props.def(--s-links--colored--visited--underline-color, props.get(vars.$theme, --purple, --600)) !default;
21$colored--visited--hover--text-color: props.def(--s-links--colored--visited--hover--text-color, props.get(vars.$theme, --purple, --1300)) !default;
22
23$key-focus--text-color: props.def(--s-links--key-focus--text-color, props.get(vars.$theme, --focus, --text)) !default;
24$key-focus--border-color: props.def(--s-links--key-focus--border-color, props.get(vars.$theme, --focus, --border)) !default;
25$key-focus--outline-color: props.def(--s-links--key-focus--outline-color, props.get(vars.$theme, --focus, --outline)) !default;
26
27$static-themes: props.def(--s-links);
28@each $theme in map.keys(props.get(vars.$transparent-colors)) {
29 $link-theme: #{$theme}-static;
30
31 $static-themes: props.merge($static-themes, (
32 $link-theme: (
33 --text-color: props.get(vars.$transparent-colors, $theme, --800),
34 --underline-color: props.get(vars.$transparent-colors, $theme, --500),
35
36 --hover: (
37 --text-color: props.get(vars.$transparent-colors, $theme, --900),
38 ),
39
40 --key-focus: (
41 --text-color: props.get(vars.$transparent-colors, $theme, --900),
42 --border-color: props.get(vars.$transparent-colors, $theme, --900),
43 --outline-color: props.get(vars.$transparent-colors, $theme, --300),
44 ),
45 )
46 ));
47}
diff --git a/src/scopes/_lists.scss b/src/scopes/_lists.scss
new file mode 100644
index 0000000..db555a9
--- /dev/null
+++ b/src/scopes/_lists.scss
@@ -0,0 +1,59 @@
1@use 'sass:meta';
2@use 'iro-sass/src/iro-sass' as iro;
3@use '../props';
4@use '../vars' as global-vars;
5
6@forward 'lists.vars';
7@use 'lists.vars' as vars;
8
9@mixin styles {
10 @include props.materialize(meta.module-variables('vars'));
11
12 @include iro.bem-scope('lists') {
13 ul,
14 ol {
15 padding-inline-start: props.get(vars.$indent);
16 margin-block-start: props.get(vars.$margin-bs);
17
18 ul,
19 ol {
20 margin-block-start: 0;
21 }
22 }
23
24 ul {
25 list-style: disc;
26 }
27
28 ol {
29 list-style: decimal;
30 }
31
32 dl {
33 padding: 0;
34 margin-block: props.get(vars.$margin-bs) 0;
35 margin-inline: 0;
36 }
37
38 dt {
39 font-weight: bold;
40 color: props.get(global-vars.$theme, --heading);
41 }
42
43 dd {
44 margin-block: 0;
45 margin-inline: props.get(vars.$indent) 0;
46 }
47
48 @include iro.bem-modifier('compact') {
49 ul,
50 ol {
51 padding-inline-start: calc(props.get(vars.$compact--indent) - 3px);
52 }
53
54 dd {
55 margin-inline-start: calc(props.get(vars.$compact--indent) - 3px);
56 }
57 }
58 }
59}
diff --git a/src/scopes/_lists.vars.scss b/src/scopes/_lists.vars.scss
new file mode 100644
index 0000000..609cfb5
--- /dev/null
+++ b/src/scopes/_lists.vars.scss
@@ -0,0 +1,8 @@
1@use '../props';
2@use '../vars';
3@use './implicit.vars' as implicit-vars;
4
5$indent: props.def(--s-lists--indent, calc(props.get(vars.$list--indent) + 1em)) !default;
6$margin-bs: props.def(--s-lists--margin-bs, props.get(implicit-vars.$paragraph--margin-bs)) !default;
7
8$compact--indent: props.def(--s-lists--compact--indent, props.get(vars.$list--compact-indent)) !default;
diff --git a/src/scopes/_tables.scss b/src/scopes/_tables.scss
new file mode 100644
index 0000000..f722864
--- /dev/null
+++ b/src/scopes/_tables.scss
@@ -0,0 +1,104 @@
1@use 'sass:meta';
2@use 'iro-sass/src/iro-sass' as iro;
3@use '../functions' as fn;
4@use '../mixins' as mx;
5
6@forward 'lists.vars';
7@use 'lists.vars' as vars;
8
9@mixin styles {
10 @include props.materialize(meta.module-variables('vars'));
11
12 @include iro.bem-scope('tables') {
13 table {
14 margin-block-start: fn.dim(--margin-bs);
15 border-spacing: 0;
16 border-collapse: separate;
17 }
18
19 th {
20 @include mx.set-font(--standard, (
21 --line-height: null,
22 --size: fn.global-dim(--font-size --50),
23 --weight: bold,
24 --transform: uppercase,
25 --spacing: .5px
26 ));
27
28 padding-block: fn.dim(--pad-b);
29 padding-inline: fn.dim(--pad-i);
30 color: fn.color(--heading);
31 text-align: start;
32 }
33
34 td {
35 padding-block: fn.dim(--pad-b);
36 padding-inline: fn.dim(--pad-i);
37 border-color: fn.color(--border);
38 border-style: solid;
39 border-width: 0;
40 border-block-start-width: fn.dim(--border);
41 }
42
43 tr {
44 &:last-child {
45 td {
46 border-block-end-width: fn.dim(--border);
47 }
48 }
49 }
50
51 @include iro.bem-modifier('flush') {
52 th,
53 td {
54 &:first-child {
55 padding-inline-start: 0;
56 }
57
58 &:last-child {
59 padding-inline-end: 0;
60 }
61 }
62 }
63
64 @include iro.bem-modifier('box') {
65 td {
66 background-color: fn.color(--box --bg);
67
68 &:first-child {
69 border-inline-start-width: fn.dim(--border);
70 }
71
72 &:last-child {
73 border-inline-end-width: fn.dim(--border);
74 }
75 }
76
77 tr {
78 &:first-child {
79 td {
80 &:first-child {
81 border-start-start-radius: fn.dim(--rounding);
82 }
83
84 &:last-child {
85 border-start-end-radius: fn.dim(--rounding);
86 }
87 }
88 }
89
90 &:last-child {
91 td {
92 &:first-child {
93 border-end-start-radius: fn.dim(--rounding);
94 }
95
96 &:last-child {
97 border-end-end-radius: fn.dim(--rounding);
98 }
99 }
100 }
101 }
102 }
103 }
104}
diff --git a/src/scopes/_tables.vars.scss b/src/scopes/_tables.vars.scss
new file mode 100644
index 0000000..2c3f255
--- /dev/null
+++ b/src/scopes/_tables.vars.scss
@@ -0,0 +1,24 @@
1@use '../props';
2@use '../vars';
3
4$indent: props.def(--s-lists--indent, calc(props.get(vars.$list--indent) + 1em)) !default;
5$margin-bs: props.def(--s-lists--margin-bs, props.get(vars.$paragraph--margin-bs)) !default;
6
7$compact--indent: props.def(--s-lists--compact--indent, props.get(vars.$list--compact-indent)) !default;
8
9@include iro.props-store((
10 --dims: (
11 --pad-i: fn.foreign-dim(--table, --pad-i),
12 --pad-b: fn.foreign-dim(--table, --pad-b),
13 --rounding: fn.foreign-dim(--table, --rounding),
14 --border: fn.foreign-dim(--table, --border),
15 --margin-bs: fn.global-dim(--paragraph --margin-bs),
16 ),
17 --colors: (
18 --border: fn.foreign-color(--table, --border),
19 --heading: fn.foreign-color(--table, --heading),
20 --box: (
21 --bg: fn.foreign-color(--table, --box --bg),
22 )
23 )
24));