@oardi/css-utils 0.94.1 → 0.95.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oardi/css-utils",
3
- "version": "0.94.1",
3
+ "version": "0.95.0",
4
4
  "author": "Ardian Shala",
5
5
  "homepage": "https://css-utils.oardi.com",
6
6
  "description": "Powerful set of semantic css classes with support for breakpoints, directions and spacings",
package/readme.md CHANGED
@@ -68,6 +68,26 @@ Responsive utilities are mobile-first. Classes without a breakpoint apply at eve
68
68
  </div>
69
69
  ```
70
70
 
71
+ ## Browser support
72
+
73
+ The minimum supported versions for the compiled library CSS are:
74
+
75
+ | Browser | Minimum version |
76
+ | ----------------------------------- | --------------- |
77
+ | Chrome / Edge (desktop and Android) | 122 |
78
+ | Firefox (desktop and Android) | 128 |
79
+ | Safari (macOS and iOS/iPadOS) | 18 |
80
+
81
+ This feature baseline includes cascade layers, `:has()`, `color-mix()` and relative `rgb()` colors used by component states and backdrops. Older browsers and Internet Explorer are outside the support policy. Modal entry animations using `@starting-style` are a progressive enhancement; the dialog remains usable without that animation.
82
+
83
+ All solid `.bg-*` utilities provide authored text colors and matching SVG fills. Theme colors use `--on-*`, surfaces use `--text-color` or `--text-inverse`, and fixed colors use black/white fallbacks selected from the Sass palette.
84
+
85
+ `@supports (color: contrast-color(white))` enables automatic black/white foreground selection. Without it, `.bg-opacity-*` theme backgrounds remain **opaque** so their authored foreground stays readable, including nested backgrounds. With it, opacity and contrast against the composited backdrop are enabled. According to [MDN browser compatibility data](https://github.com/mdn/browser-compat-data/blob/main/css/types/color.json), `contrast-color()` starts at Chrome/Edge 147, Firefox 146 and Safari/iOS 26; relative RGB support establishes the lower baseline above. Feature detection determines which path runs.
86
+
87
+ When overriding theme colors, keep their `--on-*` tokens in sync. When changing surfaces, update their matching text tokens. Gray fallbacks are calculated at Sass compilation time; runtime gray or black/white token overrides require checking foreground contrast and, where needed, an explicit `.text-*` utility. Explicit text utilities continue to override the automatic foreground.
88
+
89
+ These versions define the support target, not a claim that every browser release is exercised in CI. Regression tests cover the compiled fallback and enhancement branches and default light/dark contrast; application integrations should also be checked in their target browsers. The SCSS package supplies no JavaScript: interactive behavior belongs to the consuming application.
90
+
71
91
  ## Customize the design
72
92
 
73
93
  Define overrides after the library import to adapt the global design tokens:
@@ -2,7 +2,7 @@
2
2
  .form-control {
3
3
  --form-control-bg-color: var(--bg-surface);
4
4
  --form-control-border-width: var(--border-width);
5
- --form-control-border-color: var(--border-color);
5
+ --form-control-border-color: var(--control-border-color);
6
6
  --form-control-border-radius: var(--border-radius);
7
7
 
8
8
  --form-control-padding-y: var(--spacer-1);
@@ -95,7 +95,7 @@
95
95
  .form-select {
96
96
  --form-select-bg-color: var(--bg-surface);
97
97
  --form-select-border-width: var(--border-width);
98
- --form-select-border-color: var(--border-color);
98
+ --form-select-border-color: var(--control-border-color);
99
99
  --form-select-border-radius: var(--border-radius);
100
100
 
101
101
  --form-select-padding-y: var(--spacer-1);
@@ -198,7 +198,7 @@
198
198
 
199
199
  --form-check-input-bg-color: var(--bg-surface);
200
200
  --form-check-input-border-width: var(--border-width);
201
- --form-check-input-border-color: var(--border-color);
201
+ --form-check-input-border-color: var(--control-border-color);
202
202
 
203
203
  --form-check-input-checked-bg-color: var(--primary);
204
204
  --form-check-input-checked-border-color: var(--primary);
@@ -345,7 +345,7 @@
345
345
 
346
346
  --form-switch-input-bg-color: var(--bg-highlight);
347
347
  --form-switch-input-border-width: var(--border-width);
348
- --form-switch-input-border-color: var(--border-color);
348
+ --form-switch-input-border-color: var(--control-border-color);
349
349
  --form-switch-input-border-radius: 9999px;
350
350
 
351
351
  --form-switch-input-checked-bg-color: var(--primary);
@@ -1,3 +1,4 @@
1
+ @use 'sass:color';
1
2
  @use 'sass:map';
2
3
  @use './display.scss';
3
4
  @use './theme.scss' as theme;
@@ -15,6 +16,17 @@ $-widths: (
15
16
 
16
17
  $-overflow-wrap-values: normal, break-word, anywhere;
17
18
 
19
+ // Guard the dynamic value: a var() declaration can otherwise become invalid only
20
+ // at computed-value time, when an earlier color declaration cannot rescue it.
21
+ @mixin -background-foreground($background, $fallback) {
22
+ color: $fallback;
23
+ fill: currentcolor;
24
+
25
+ @supports (color: contrast-color(white)) {
26
+ color: contrast-color($background);
27
+ }
28
+ }
29
+
18
30
  @layer utilities {
19
31
  // positions
20
32
  @each $value in map.get(theme.$theme, positions) {
@@ -37,34 +49,39 @@ $-overflow-wrap-values: normal, break-word, anywhere;
37
49
  --bg-opacity: 1;
38
50
  --bg-opacity-backdrop: var(--#{$name});
39
51
 
40
- color: contrast-color(var(--#{$name}));
41
- fill: currentcolor;
42
- background-color: rgb(from var(--#{$name}) r g b / var(--bg-opacity));
43
-
44
- &:where(.bg-opacity-10, .bg-opacity-25, .bg-opacity-50, .bg-opacity-75) {
45
- --bg-opacity-backdrop: inherit;
46
- --bg-opacity-composite: color-mix(
47
- in srgb,
48
- var(--#{$name}) var(--bg-opacity-percentage),
49
- var(--bg-opacity-backdrop)
50
- );
51
- --bg-opacity-rendered: var(--bg-opacity-composite);
52
-
53
- color: contrast-color(var(--bg-opacity-composite));
54
- fill: currentcolor;
55
- }
52
+ background-color: var(--#{$name});
53
+ @include -background-foreground(var(--#{$name}), var(--on-#{$name}));
54
+
55
+ // Keep the authored foreground paired with an opaque background unless
56
+ // the browser can choose text against the actual translucent composite.
57
+ @supports (color: contrast-color(white)) {
58
+ background-color: rgb(from var(--#{$name}) r g b / var(--bg-opacity));
59
+
60
+ &:where(.bg-opacity-10, .bg-opacity-25, .bg-opacity-50, .bg-opacity-75) {
61
+ --bg-opacity-backdrop: inherit;
62
+ --bg-opacity-composite: color-mix(
63
+ in srgb,
64
+ var(--#{$name}) var(--bg-opacity-percentage),
65
+ var(--bg-opacity-backdrop)
66
+ );
67
+ --bg-opacity-rendered: var(--bg-opacity-composite);
68
+
69
+ color: contrast-color(var(--bg-opacity-composite));
70
+ fill: currentcolor;
71
+ }
56
72
 
57
- :where(.bg-opacity-10, .bg-opacity-25, .bg-opacity-50, .bg-opacity-75)
58
- > &:where(.bg-opacity-10, .bg-opacity-25, .bg-opacity-50, .bg-opacity-75) {
59
- --bg-opacity-rendered: inherit;
60
- --bg-opacity-composite: color-mix(
61
- in srgb,
62
- var(--#{$name}) var(--bg-opacity-percentage),
63
- var(--bg-opacity-rendered)
64
- );
65
-
66
- color: contrast-color(var(--bg-opacity-composite));
67
- fill: currentcolor;
73
+ :where(.bg-opacity-10, .bg-opacity-25, .bg-opacity-50, .bg-opacity-75)
74
+ > &:where(.bg-opacity-10, .bg-opacity-25, .bg-opacity-50, .bg-opacity-75) {
75
+ --bg-opacity-rendered: inherit;
76
+ --bg-opacity-composite: color-mix(
77
+ in srgb,
78
+ var(--#{$name}) var(--bg-opacity-percentage),
79
+ var(--bg-opacity-rendered)
80
+ );
81
+
82
+ color: contrast-color(var(--bg-opacity-composite));
83
+ fill: currentcolor;
84
+ }
68
85
  }
69
86
  }
70
87
  }
@@ -73,18 +90,16 @@ $-overflow-wrap-values: normal, break-word, anywhere;
73
90
  --bg-opacity: 1;
74
91
  --bg-opacity-backdrop: var(--white);
75
92
 
76
- color: contrast-color(var(--white));
77
- fill: currentcolor;
78
93
  background-color: var(--white);
94
+ @include -background-foreground(var(--white), var(--black));
79
95
  }
80
96
 
81
97
  .bg-black {
82
98
  --bg-opacity: 1;
83
99
  --bg-opacity-backdrop: var(--black);
84
100
 
85
- color: contrast-color(var(--black));
86
- fill: currentcolor;
87
101
  background-color: var(--black);
102
+ @include -background-foreground(var(--black), var(--white));
88
103
  }
89
104
 
90
105
  @each $name, $value in map.get(theme.$theme, grays) {
@@ -92,9 +107,15 @@ $-overflow-wrap-values: normal, break-word, anywhere;
92
107
  --bg-opacity: 1;
93
108
  --bg-opacity-backdrop: var(--gray-#{$name});
94
109
 
95
- color: contrast-color(var(--gray-#{$name}));
96
- fill: currentcolor;
110
+ // XYZ Y is relative luminance; this threshold selects the higher
111
+ // black/white contrast ratio, including Sass palette overrides.
112
+ $fallback: var(--white);
113
+ @if color.channel($value, 'y', $space: xyz) > 0.1791287847 {
114
+ $fallback: var(--black);
115
+ }
116
+
97
117
  background-color: var(--gray-#{$name});
118
+ @include -background-foreground(var(--gray-#{$name}), $fallback);
98
119
  }
99
120
  }
100
121
 
@@ -102,54 +123,48 @@ $-overflow-wrap-values: normal, break-word, anywhere;
102
123
  --bg-opacity: 1;
103
124
  --bg-opacity-backdrop: var(--bg-body);
104
125
 
105
- color: contrast-color(var(--bg-body));
106
- fill: currentcolor;
107
126
  background-color: var(--bg-body);
127
+ @include -background-foreground(var(--bg-body), var(--text-color));
108
128
  }
109
129
 
110
130
  .bg-surface {
111
131
  --bg-opacity: 1;
112
132
  --bg-opacity-backdrop: var(--bg-surface);
113
133
 
114
- color: contrast-color(var(--bg-surface));
115
- fill: currentcolor;
116
134
  background-color: var(--bg-surface);
135
+ @include -background-foreground(var(--bg-surface), var(--text-color));
117
136
  }
118
137
 
119
138
  .bg-inverse {
120
139
  --bg-opacity: 1;
121
140
  --bg-opacity-backdrop: var(--bg-inverse);
122
141
 
123
- color: contrast-color(var(--bg-inverse));
124
- fill: currentcolor;
125
142
  background-color: var(--bg-inverse);
143
+ @include -background-foreground(var(--bg-inverse), var(--text-inverse));
126
144
  }
127
145
 
128
146
  .bg-surface-hover {
129
147
  --bg-opacity: 1;
130
148
  --bg-opacity-backdrop: var(--bg-surface-hover);
131
149
 
132
- color: contrast-color(var(--bg-surface-hover));
133
- fill: currentcolor;
134
150
  background-color: var(--bg-surface-hover);
151
+ @include -background-foreground(var(--bg-surface-hover), var(--text-color));
135
152
  }
136
153
 
137
154
  .bg-highlight {
138
155
  --bg-opacity: 1;
139
156
  --bg-opacity-backdrop: var(--bg-highlight);
140
157
 
141
- color: contrast-color(var(--bg-highlight));
142
- fill: currentcolor;
143
158
  background-color: var(--bg-highlight);
159
+ @include -background-foreground(var(--bg-highlight), var(--text-color));
144
160
  }
145
161
 
146
162
  .bg-active {
147
163
  --bg-opacity: 1;
148
164
  --bg-opacity-backdrop: var(--bg-active);
149
165
 
150
- color: contrast-color(var(--bg-active));
151
- fill: currentcolor;
152
166
  background-color: var(--bg-active);
167
+ @include -background-foreground(var(--bg-active), var(--text-color));
153
168
  }
154
169
 
155
170
  .bg-opacity-10 {
@@ -59,6 +59,7 @@
59
59
 
60
60
  --border-width: 1px;
61
61
  --border-color: var(--gray-100);
62
+ --control-border-color: var(--gray-550);
62
63
 
63
64
  --border-radius-sm: 0.25rem;
64
65
  --border-radius: 0.5rem;
@@ -68,7 +69,7 @@
68
69
  --disabled-bg-color: var(--gray-300);
69
70
  --disabled-border-color: var(--gray-50);
70
71
 
71
- --shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.1);
72
+ --shadow-sm: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.125);
72
73
  --shadow: 0 0.25rem 1rem rgba(0, 0, 0, 0.15);
73
74
  --shadow-lg: 0 1rem 2rem rgba(0, 0, 0, 0.2);
74
75
 
@@ -120,6 +121,7 @@
120
121
  --text-inverse: var(--gray-900);
121
122
 
122
123
  --border-color: var(--gray-650);
124
+ --control-border-color: var(--gray-350);
123
125
 
124
126
  --disabled-text-color: var(--gray-550);
125
127
  --disabled-bg-color: var(--gray-750);