summaryrefslogtreecommitdiffstats
path: root/src/objects/_card.scss
diff options
context:
space:
mode:
authorVolpeon <git@volpeon.ink>2026-07-22 12:27:09 +0200
committerVolpeon <git@volpeon.ink>2026-07-22 12:27:09 +0200
commitcc5329a5f4d3ea91cac93bc7f9b8f943b7ced226 (patch)
treed16dea8f0a5edca2b610ecabeac5e93a4d98be2f /src/objects/_card.scss
parentUpdate _index.scss (diff)
downloadiro-design-master.tar.gz
iro-design-master.tar.bz2
iro-design-master.zip
Diffstat (limited to 'src/objects/_card.scss')
-rw-r--r--src/objects/_card.scss389
1 files changed, 216 insertions, 173 deletions
diff --git a/src/objects/_card.scss b/src/objects/_card.scss
index b8bc727..3275bc8 100644
--- a/src/objects/_card.scss
+++ b/src/objects/_card.scss
@@ -1,84 +1,95 @@
1@use 'sass:meta'; 1@use "sass:meta";
2@use 'pkg:iro-sass/src/bem'; 2@use "pkg:iro-sass/bem";
3@use 'pkg:iro-sass/src/props'; 3@use "pkg:iro-sass/props";
4@use '../props' as *; 4@use "../props" as *;
5@use 'avatar.vars' as avatar; 5@use "avatar.vars" as avatar;
6 6
7@forward 'card.vars'; 7@forward "card.vars";
8@use 'card.vars' as vars; 8@use "card.vars" as vars;
9 9
10@mixin styles { 10@mixin styles {
11 @include materialize-at-root(meta.module-variables('vars')); 11 @include materialize-at-root(meta.module-variables("vars"));
12 12
13 @include bem.object('card') { 13 @include bem.object("card") {
14 position: relative; 14 position: relative;
15 display: flex; 15 display: flex;
16 flex-direction: column; 16 flex-direction: column;
17 background-color: props.get(vars.$bg-color); 17 background-color: props.get(vars.$bg-color);
18 border: props.get(vars.$border-width) solid transparent; 18 border: props.get(vars.$border-width) solid transparent;
19 border-color: props.get(vars.$border-color); 19 border-color: props.get(vars.$border-color);
20 border-radius: props.get(vars.$rounding); 20 border-radius: props.get(vars.$rounding);
21 transition: transform .2s, background-color .2s, border-color .2s, box-shadow .2s; 21 transition:
22 transform 0.2s,
23 background-color 0.2s,
24 border-color 0.2s,
25 box-shadow 0.2s;
22 26
23 @include bem.multi('&:link, &:visited, &:enabled', 'modifier' 'interactive', 'modifier' 'collapsible') { 27 @include bem.multi(
28 "&:link, &:visited, &:enabled",
29 "modifier" "interactive",
30 "modifier" "collapsible"
31 ) {
24 &:hover, 32 &:hover,
25 &:active, 33 &:active,
26 &:focus-visible { 34 &:focus-visible {
27 background-color: props.get(vars.$hover--bg-color); 35 background-color: props.get(vars.$hover--bg-color);
28 border-color: props.get(vars.$hover--border-color); 36 border-color: props.get(vars.$hover--border-color);
29 box-shadow: none; 37 box-shadow: none;
30 transform: translateY(props.get(vars.$hover--offset-b)); 38 transform: translateY(props.get(vars.$hover--offset-b));
31 } 39 }
32 40
33 &:focus-visible { 41 &:focus-visible {
34 margin: calc(-1 * props.get(vars.$key-focus--border-width)); 42 margin: calc(-1 * props.get(vars.$key-focus--border-width));
35 outline: props.get(vars.$key-focus--border-color) solid props.get(vars.$key-focus--border-width); 43 outline: props.get(vars.$key-focus--border-color) solid
36 border: calc(props.get(vars.$key-focus--border-offset) + props.get(vars.$border-width)) solid transparent; 44 props.get(vars.$key-focus--border-width);
37 border-radius: calc(props.get(vars.$rounding) + props.get(vars.$key-focus--border-offset)); 45 border: calc(
38 box-shadow: 46 props.get(vars.$key-focus--border-offset) + props.get(vars.$border-width)
39 0 0 0 47 )
40 calc(props.get(vars.$key-focus--border-width) + props.get(vars.$key-focus--outline-width)) 48 solid transparent;
49 border-radius: calc(
50 props.get(vars.$rounding) + props.get(vars.$key-focus--border-offset)
51 );
52 box-shadow: 0 0 0
53 calc(
54 props.get(vars.$key-focus--border-width) +
55 props.get(vars.$key-focus--outline-width)
56 )
41 props.get(vars.$key-focus--outline-color); 57 props.get(vars.$key-focus--outline-color);
42 transition: transform .2s; 58 transition: transform 0.2s;
43 } 59 }
44 } 60 }
45 61
46 @include bem.modifier('borderless') { 62 @include bem.modifier("borderless") {
47 border-color: props.get(vars.$bg-color); 63 border-color: props.get(vars.$bg-color);
48 } 64 }
49 65
50 @include bem.modifier('shadow') { 66 @include bem.modifier("shadow") {
51 box-shadow: 67 box-shadow: props.get(vars.$shadow-x) props.get(vars.$shadow-y)
52 props.get(vars.$shadow-x) 68 props.get(vars.$shadow-blur) props.get(vars.$shadow-grow)
53 props.get(vars.$shadow-y)
54 props.get(vars.$shadow-blur)
55 props.get(vars.$shadow-grow)
56 props.get(vars.$shadow-color); 69 props.get(vars.$shadow-color);
57 70
58 @include bem.modifier('quiet') { 71 @include bem.modifier("quiet") {
59 @include bem.elem('image') { 72 @include bem.elem("image") {
60 box-shadow: 73 box-shadow: props.get(vars.$shadow-x) props.get(vars.$shadow-y)
61 props.get(vars.$shadow-x) 74 props.get(vars.$shadow-blur) props.get(vars.$shadow-grow)
62 props.get(vars.$shadow-y)
63 props.get(vars.$shadow-blur)
64 props.get(vars.$shadow-grow)
65 props.get(vars.$shadow-color); 75 props.get(vars.$shadow-color);
66 } 76 }
67 } 77 }
68 } 78 }
69 79
70 @include bem.modifier('highlight') { 80 @include bem.modifier("highlight") {
71 margin: calc(props.get(vars.$border-width) - props.get(vars.$highlight--border-width)); 81 margin: calc(props.get(vars.$border-width) - props.get(vars.$highlight--border-width));
72 border-color: props.get(vars.$highlight--border-color); 82 border-color: props.get(vars.$highlight--border-color);
73 border-width: props.get(vars.$highlight--border-width); 83 border-width: props.get(vars.$highlight--border-width);
74 box-shadow: 84 box-shadow: props.get(vars.$highlight--shadow-x) props.get(vars.$highlight--shadow-y)
75 props.get(vars.$highlight--shadow-x) 85 props.get(vars.$highlight--shadow-blur) props.get(vars.$highlight--shadow-grow)
76 props.get(vars.$highlight--shadow-y)
77 props.get(vars.$highlight--shadow-blur)
78 props.get(vars.$highlight--shadow-grow)
79 props.get(vars.$highlight--shadow-color); 86 props.get(vars.$highlight--shadow-color);
80 87
81 @include bem.multi('&:link, &:visited, &:enabled', 'modifier' 'interactive', 'modifier' 'collapsible') { 88 @include bem.multi(
89 "&:link, &:visited, &:enabled",
90 "modifier" "interactive",
91 "modifier" "collapsible"
92 ) {
82 &:hover, 93 &:hover,
83 &:active { 94 &:active {
84 border-color: props.get(vars.$highlight--border-color); 95 border-color: props.get(vars.$highlight--border-color);
@@ -86,207 +97,238 @@
86 } 97 }
87 } 98 }
88 99
89 @include bem.elem('avatar') { 100 @include bem.elem("avatar") {
90 margin-block-start: props.get(vars.$pad-b); 101 margin-block-start: props.get(vars.$pad-b);
91 margin-inline-start: props.get(vars.$pad-i); 102 margin-inline-start: props.get(vars.$pad-i);
92 } 103 }
93 104
94 @include bem.elem('image') { 105 @include bem.elem("image") {
95 position: relative; 106 position: relative;
96 display: block; 107 display: block;
97 flex: 0 0 auto; 108 flex: 0 0 auto;
98 inline-size: calc(100% + 2 * props.get(vars.$border-width)); 109 inline-size: calc(100% + 2 * props.get(vars.$border-width));
99 margin: calc(-1 * props.get(vars.$border-width)); 110 margin: calc(-1 * props.get(vars.$border-width));
100 overflow: hidden; 111 overflow: hidden;
101 object-fit: cover; 112 object-fit: cover;
102 transition: background-color .2s, transform .2s, opacity .2s; 113 transition:
114 background-color 0.2s,
115 transform 0.2s,
116 opacity 0.2s;
103 117
104 &:first-child { 118 &:first-child {
105 border-start-start-radius: calc(props.get(vars.$rounding) - props.get(vars.$border-width)); 119 border-start-start-radius: calc(
106 border-start-end-radius: calc(props.get(vars.$rounding) - props.get(vars.$border-width)); 120 props.get(vars.$rounding) - props.get(vars.$border-width)
121 );
122 border-start-end-radius: calc(
123 props.get(vars.$rounding) - props.get(vars.$border-width)
124 );
107 } 125 }
108 126
109 &:last-child { 127 &:last-child {
110 border-end-start-radius: calc(props.get(vars.$rounding) - props.get(vars.$border-width)); 128 border-end-start-radius: calc(
111 border-end-end-radius: calc(props.get(vars.$rounding) - props.get(vars.$border-width)); 129 props.get(vars.$rounding) - props.get(vars.$border-width)
130 );
131 border-end-end-radius: calc(
132 props.get(vars.$rounding) - props.get(vars.$border-width)
133 );
112 } 134 }
113 135
114 @include bem.next-elem('avatar') { 136 @include bem.next-elem("avatar") {
115 margin-block-start: calc(-.7 * props.get(avatar.$size--xl)); 137 margin-block-start: calc(-0.7 * props.get(avatar.$size--xl));
116 } 138 }
117 } 139 }
118 140
119 @include bem.elem('image-img') { 141 @include bem.elem("image-img") {
120 display: block; 142 display: block;
121 inline-size: 100%; 143 inline-size: 100%;
122 block-size: 100%; 144 block-size: 100%;
123 object-fit: cover; 145 object-fit: cover;
124 } 146 }
125 147
126 @include bem.elem('image-overlay') { 148 @include bem.elem("image-overlay") {
127 position: absolute; 149 position: absolute;
128 inset-block-end: 0; 150 inset-block-end: 0;
129 inset-inline: 0; 151 inset-inline: 0;
130 z-index: 5; 152 z-index: 5;
131 padding-block: props.get(vars.$image-overlay--pad-b); 153 padding-block: props.get(vars.$image-overlay--pad-b);
132 padding-inline: props.get(vars.$image-overlay--pad-i); 154 padding-inline: props.get(vars.$image-overlay--pad-i);
133 } 155 }
134 156
135 @include bem.elem('body') { 157 @include bem.elem("body") {
136 flex: 0 0 auto; 158 flex: 0 0 auto;
137 padding-block: props.get(vars.$pad-b); 159 padding-block: props.get(vars.$pad-b);
138 padding-inline: props.get(vars.$pad-i); 160 padding-inline: props.get(vars.$pad-i);
139 161
140 &::before { 162 &::before {
141 display: block; 163 display: block;
142 margin-block: -100em 100em; 164 margin-block: -100em 100em;
143 content: ''; 165 content: "";
144 } 166 }
145 167
146 @include bem.modifier('no-mbs-neutralize') { 168 @include bem.modifier("no-mbs-neutralize") {
147 &::before { 169 &::before {
148 display: none; 170 display: none;
149 } 171 }
150 } 172 }
151 173
152 @include bem.modifier('main') { 174 @include bem.modifier("main") {
153 flex-shrink: 1; 175 flex-shrink: 1;
154 block-size: 100%; 176 block-size: 100%;
155 min-block-size: 0; 177 min-block-size: 0;
156 } 178 }
157 } 179 }
158 180
159 @include bem.elem('content') { 181 @include bem.elem("content") {
160 margin-block-start: props.get(vars.$spacing); 182 margin-block-start: props.get(vars.$spacing);
161 } 183 }
162 184
163 @include bem.elem('footer') { 185 @include bem.elem("footer") {
164 flex: 0 0 auto; 186 flex: 0 0 auto;
165 padding-block: 0 props.get(vars.$pad-b); 187 padding-block: 0 props.get(vars.$pad-b);
166 padding-inline: props.get(vars.$pad-i); 188 padding-inline: props.get(vars.$pad-i);
167 margin-block-start: calc(-1 * props.get(vars.$pad-b)); 189 margin-block-start: calc(-1 * props.get(vars.$pad-b));
168 190
169 &::before { 191 &::before {
170 display: block; 192 display: block;
171 block-size: props.get(vars.$divider-width); 193 block-size: props.get(vars.$divider-width);
172 margin-block: props.get(vars.$spacing); 194 margin-block: props.get(vars.$spacing);
173 content: ''; 195 content: "";
174 background-color: props.get(vars.$divider-width); 196 background-color: props.get(vars.$divider-width);
175 } 197 }
176 } 198 }
177 199
178 @include bem.modifier('quiet') { 200 @include bem.modifier("quiet") {
179 margin-inline: 0; 201 margin-inline: 0;
180 background-color: transparent; 202 background-color: transparent;
181 border: 0; 203 border: 0;
182 box-shadow: none; 204 box-shadow: none;
183 205
184 @include bem.multi('&:link, &:visited, &:enabled', 'modifier' 'interactive', 'modifier' 'collapsible') { 206 @include bem.multi(
207 "&:link, &:visited, &:enabled",
208 "modifier" "interactive",
209 "modifier" "collapsible"
210 ) {
185 &:hover, 211 &:hover,
186 &:active, 212 &:active,
187 &:focus-visible { 213 &:focus-visible {
188 background-color: transparent; 214 background-color: transparent;
189 transform: none; 215 transform: none;
190 216
191 @include bem.elem('image') { 217 @include bem.elem("image") {
192 background-color: props.get(vars.$quiet--hover--image-color); 218 background-color: props.get(vars.$quiet--hover--image-color);
193 opacity: .75; 219 opacity: 0.75;
194 transform: translateY(props.get(vars.$hover--offset-b)); 220 transform: translateY(props.get(vars.$hover--offset-b));
195 } 221 }
196 } 222 }
197 223
198 &:focus-visible { 224 &:focus-visible {
199 margin: 0; 225 margin: 0;
200 outline: none; 226 outline: none;
201 border: 0; 227 border: 0;
202 box-shadow: none; 228 box-shadow: none;
203 229
204 @include bem.elem('image') { 230 @include bem.elem("image") {
205 margin: calc(-1 * props.get(vars.$key-focus--border-width) - props.get(vars.$border-width)); 231 margin: calc(
206 outline: props.get(vars.$key-focus--border-color) solid props.get(vars.$key-focus--border-width); 232 -1 *
233 props.get(vars.$key-focus--border-width) - props.get(
234 vars.$border-width
235 )
236 );
237 outline: props.get(vars.$key-focus--border-color) solid
238 props.get(vars.$key-focus--border-width);
207 background-color: props.get(vars.$quiet--hover--image-color); 239 background-color: props.get(vars.$quiet--hover--image-color);
208 border: props.get(vars.$key-focus--border-offset) solid transparent; 240 border: props.get(vars.$key-focus--border-offset) solid transparent;
209 border-radius: calc(props.get(vars.$rounding) + props.get(vars.$key-focus--border-offset)); 241 border-radius: calc(
210 box-shadow: 242 props.get(vars.$rounding) + props.get(vars.$key-focus--border-offset)
211 0 243 );
212 0 244 box-shadow: 0 0 0
213 0 245 calc(
214 calc(props.get(vars.$key-focus--border-width) + props.get(vars.$key-focus--outline-width)) 246 props.get(vars.$key-focus--border-width) +
247 props.get(vars.$key-focus--outline-width)
248 )
215 props.get(vars.$key-focus--outline-color); 249 props.get(vars.$key-focus--outline-color);
216 opacity: 1; 250 opacity: 1;
217 } 251 }
218 } 252 }
219 } 253 }
220 254
221 @include bem.elem('image') { 255 @include bem.elem("image") {
222 position: relative; 256 position: relative;
223 background-color: props.get(vars.$quiet--image-color); 257 background-color: props.get(vars.$quiet--image-color);
224 background-clip: padding-box; 258 background-clip: padding-box;
225 border-radius: props.get(vars.$rounding); 259 border-radius: props.get(vars.$rounding);
226 } 260 }
227 261
228 @include bem.elem('body') { 262 @include bem.elem("body") {
229 padding: 0; 263 padding: 0;
230 padding-block-start: props.get(vars.$spacing); 264 padding-block-start: props.get(vars.$spacing);
231 } 265 }
232 266
233 @include bem.elem('footer') { 267 @include bem.elem("footer") {
234 padding-inline: 0; 268 padding-inline: 0;
235 } 269 }
236 } 270 }
237 271
238 @include bem.modifier('thumbnail') { 272 @include bem.modifier("thumbnail") {
239 @include bem.elem('image') { 273 @include bem.elem("image") {
240 border-radius: props.get(vars.$rounding); 274 border-radius: props.get(vars.$rounding);
241 } 275 }
242 276
243 @include bem.elem('body') { 277 @include bem.elem("body") {
244 position: absolute; 278 position: absolute;
245 inset-block-end: calc(-1 * props.get(vars.$border-width)); 279 inset-block-end: calc(-1 * props.get(vars.$border-width));
246 inset-inline: calc(-1 * props.get(vars.$border-width)); 280 inset-inline: calc(-1 * props.get(vars.$border-width));
247 z-index: 10; 281 z-index: 10;
248 visibility: hidden; 282 visibility: hidden;
249 background-color: props.get(vars.$hover--bg-color); 283 background-color: props.get(vars.$hover--bg-color);
250 border-color: transparent; 284 border-color: transparent;
251 border-style: solid; 285 border-style: solid;
252 border-width: 0 props.get(vars.$border-width) props.get(vars.$border-width); 286 border-width: 0 props.get(vars.$border-width) props.get(vars.$border-width);
253 border-end-start-radius: calc(props.get(vars.$rounding) - props.get(vars.$border-width)); 287 border-end-start-radius: calc(
254 border-end-end-radius: calc(props.get(vars.$rounding) - props.get(vars.$border-width)); 288 props.get(vars.$rounding) - props.get(vars.$border-width)
255 opacity: 0; 289 );
290 border-end-end-radius: calc(
291 props.get(vars.$rounding) - props.get(vars.$border-width)
292 );
293 opacity: 0;
256 transition: 294 transition:
257 border-color .2s ease, 295 border-color 0.2s ease,
258 opacity .2s ease, 296 opacity 0.2s ease,
259 visibility 0s .2s linear; 297 visibility 0s 0.2s linear;
260 } 298 }
261 299
262 @include bem.multi('&:link, &:visited, &:enabled', 'modifier' 'interactive', 'modifier' 'collapsible') { 300 @include bem.multi(
301 "&:link, &:visited, &:enabled",
302 "modifier" "interactive",
303 "modifier" "collapsible"
304 ) {
263 &:hover, 305 &:hover,
264 &:active, 306 &:active,
265 &:focus-visible { 307 &:focus-visible {
266 @include bem.elem('body') { 308 @include bem.elem("body") {
267 visibility: visible; 309 visibility: visible;
268 border-color: props.get(vars.$hover--border-color); 310 border-color: props.get(vars.$hover--border-color);
269 opacity: 1; 311 opacity: 1;
270 transition: 312 transition:
271 border-color .2s ease, 313 border-color 0.2s ease,
272 opacity .2s ease, 314 opacity 0.2s ease,
273 visibility .2s linear; 315 visibility 0.2s linear;
274 } 316 }
275 } 317 }
276 } 318 }
277 } 319 }
278 320
279 @include bem.modifier('horizontal') { 321 @include bem.modifier("horizontal") {
280 flex-direction: row; 322 flex-direction: row;
281 align-items: center; 323 align-items: center;
282 324
283 @include bem.elem('image') { 325 @include bem.elem("image") {
284 align-self: stretch; 326 align-self: stretch;
285 inline-size: auto; 327 inline-size: auto;
286 328
287 &:first-child { 329 &:first-child {
288 border-start-end-radius: 0; 330 border-start-end-radius: 0;
289 border-end-start-radius: props.get(vars.$rounding); 331 border-end-start-radius: props.get(vars.$rounding);
290 } 332 }
291 333
292 &:last-child { 334 &:last-child {
@@ -295,37 +337,38 @@
295 } 337 }
296 } 338 }
297 339
298 @include bem.elem('body') { 340 @include bem.elem("body") {
299 @include bem.modifier('main') { 341 @include bem.modifier("main") {
300 block-size: auto; 342 block-size: auto;
301 min-block-size: none; 343 min-block-size: none;
302 inline-size: 100%; 344 inline-size: 100%;
303 min-inline-size: 0; 345 min-inline-size: 0;
304 } 346 }
305 } 347 }
306 } 348 }
307 349
308 @include bem.modifier('collapsible') { 350 @include bem.modifier("collapsible") {
309 display: block; 351 display: block;
310 interpolate-size: allow-keywords; 352 interpolate-size: allow-keywords;
311 353
312 @include bem.elem("header") { 354 @include bem.elem("header") {
313 display: flex; 355 display: flex;
314 align-items: center; 356 align-items: center;
315 gap: 1em; 357 gap: 1em;
316 cursor: pointer; 358 cursor: pointer;
317 359
318 &::before { 360 &::before {
319 margin: 0; 361 margin: 0;
320 inline-size: 1em; 362 inline-size: 1em;
321 font-size: 0.8em; 363 font-size: 0.8em;
322 content: "▶"; 364 content: "▶";
323 } 365 }
324 366
325 &:focus-visible { 367 &:focus-visible {
326 outline: props.get(vars.$key-focus--border-color) solid props.get(vars.$key-focus--border-width); 368 outline: props.get(vars.$key-focus--border-color) solid
369 props.get(vars.$key-focus--border-width);
327 outline-offset: calc(-1 * props.get(vars.$key-focus--border-width)); 370 outline-offset: calc(-1 * props.get(vars.$key-focus--border-width));
328 border-radius: calc(props.get(vars.$rounding) - props.get(vars.$border-width)); 371 border-radius: calc(props.get(vars.$rounding) - props.get(vars.$border-width));
329 } 372 }
330 373
331 @include bem.next-elem("body") { 374 @include bem.next-elem("body") {
@@ -334,7 +377,7 @@
334 } 377 }
335 378
336 &::details-content { 379 &::details-content {
337 opacity: 0; 380 opacity: 0;
338 block-size: 0; 381 block-size: 0;
339 overflow-y: clip; 382 overflow-y: clip;
340 transition: 383 transition:
@@ -351,7 +394,7 @@
351 } 394 }
352 395
353 &::details-content { 396 &::details-content {
354 opacity: 1; 397 opacity: 1;
355 block-size: auto; 398 block-size: auto;
356 } 399 }
357 } 400 }