osi-cards-lib 1.5.41 → 1.5.43

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.
Files changed (44) hide show
  1. package/README.md +1 -1
  2. package/fesm2022/osi-cards-lib.mjs +6109 -3631
  3. package/fesm2022/osi-cards-lib.mjs.map +1 -1
  4. package/index.d.ts +211 -270
  5. package/package.json +4 -3
  6. package/scripts/setup-angular-styles.js +1 -0
  7. package/styles/bundles/_ai-card.scss +11 -4
  8. package/styles/bundles/_card-skeleton.scss +1 -1
  9. package/styles/components/_ai-card-renderer.scss +0 -2
  10. package/styles/components/_badges.scss +1 -2
  11. package/styles/components/_card-actions.scss +5 -4
  12. package/styles/components/_component-styles.scss +1 -1
  13. package/styles/components/cards/_ai-card.scss +7 -13
  14. package/styles/components/sections/_all-sections.generated.scss +0 -3
  15. package/styles/components/sections/_all-sections.scss +88 -64
  16. package/styles/components/sections/_compact-mixins.scss +9 -8
  17. package/styles/components/sections/_component-mixins.scss +40 -11
  18. package/styles/components/sections/_design-system.scss +96 -11
  19. package/styles/components/sections/_design-tokens.scss +1 -1
  20. package/styles/components/sections/_master-compact-system.scss +0 -17
  21. package/styles/components/sections/_minimalistic-design.scss +1 -4
  22. package/styles/components/sections/_modern-effects.scss +1 -3
  23. package/styles/components/sections/_modern-sections.scss +13 -69
  24. package/styles/components/sections/_section-animations.scss +158 -77
  25. package/styles/components/sections/_section-shell.scss +39 -9
  26. package/styles/components/sections/_section-types.generated.scss +0 -3
  27. package/styles/components/sections/_sections-all.scss +7 -0
  28. package/styles/components/sections/_sections-base.scss +340 -64
  29. package/styles/components/sections/_unified-section-style.scss +17 -44
  30. package/styles/components/sections/_visual-effects-library.scss +3 -3
  31. package/styles/core/_bootstrap-reset.scss +1 -1
  32. package/styles/core/_global-unified.scss +2 -6
  33. package/styles/core/_mixins.scss +4 -4
  34. package/styles/core/_surface-layers.scss +20 -11
  35. package/styles/design-system/_section-base.scss +9 -32
  36. package/styles/design-system/_tokens.scss +68 -6
  37. package/styles/design-system/_unified-sections.scss +21 -42
  38. package/styles/layout/_masonry.scss +26 -32
  39. package/styles/layout/_tilt.scss +3 -3
  40. package/styles/mixins/_section-mixins.scss +2 -2
  41. package/styles/reset/_shadow-reset.scss +3 -7
  42. package/styles/responsive.scss +9 -7
  43. package/styles/tokens/_master.scss +271 -79
  44. package/styles/tokens/_section-tokens.generated.scss +0 -7
@@ -6,7 +6,9 @@
6
6
 
7
7
  .ai-section {
8
8
  --section-accent: var(--osi-section-accent);
9
+ --section-border: var(--osi-section-border);
9
10
  --section-border-hover: var(--osi-section-border-hover);
11
+ --section-box-shadow: var(--osi-section-shadow);
10
12
  --section-background: var(--osi-section-background);
11
13
  --section-background-hover: var(--osi-section-background-hover);
12
14
  --section-backdrop-filter: var(--osi-section-backdrop-filter);
@@ -46,21 +48,29 @@
46
48
  .masonry-item & {
47
49
  display: flex !important;
48
50
  flex-direction: column !important;
49
- gap: var(--osi-section-gap, 12px) !important;
51
+ gap: var(--osi-section-gap, 8px) !important;
50
52
  height: auto !important;
51
53
  }
52
- }
53
54
 
54
- .ai-section--main {
55
- --section-background: var(--osi-section-background-main);
56
- --section-background-hover: var(--osi-section-background-main-hover);
57
- }
55
+ // Direct hover styles for sections (ensures they work regardless of mixin application)
56
+ // Smooth transitions for hover effects
57
+ transition:
58
+ border-color var(--osi-card-transition-normal, 0.22s) cubic-bezier(0.4, 0, 0.2, 1),
59
+ box-shadow var(--osi-card-transition-normal, 0.22s) cubic-bezier(0.4, 0, 0.2, 1);
58
60
 
59
- .ai-section--contrast {
60
- --section-background: var(--osi-section-background-contrast);
61
- --section-background-hover: var(--osi-section-background-contrast-hover);
61
+ // Hover state: gentle shadow with 30% more contrasty cool color and 20% more contrasty border
62
+ &:hover {
63
+ border-color: var(--osi-section-border-hover-enhanced-color);
64
+ box-shadow: var(--osi-section-shadow-hover-enhanced);
65
+ }
66
+
67
+ @media (prefers-reduced-motion: reduce) {
68
+ transition: none;
69
+ }
62
70
  }
63
71
 
72
+ /* All sections now use unified background - removed --main and --contrast variants for consistency */
73
+
64
74
  .ai-section__header {
65
75
  @include section-header(column, var(--osi-section-header-gap));
66
76
  flex-direction: column !important;
@@ -194,6 +204,10 @@
194
204
  @include section-body(var(--osi-section-gap-internal));
195
205
  padding: 0 !important;
196
206
  margin: 0 !important;
207
+ width: 100% !important; // Ensure section body uses full width
208
+ max-width: 100% !important; // Ensure section body uses full width
209
+ min-width: 0 !important; // Allow shrinking for proper resizing
210
+ box-sizing: border-box !important; // Include padding in width
197
211
  }
198
212
 
199
213
  /* Consistent empty state styling for all sections */
@@ -272,6 +286,11 @@
272
286
 
273
287
  .ai-section--overview {
274
288
  --section-accent: var(--osi-section-accent-overview);
289
+
290
+ // Reduce title font size by 1.5px for Executive Summary
291
+ .ai-section__title {
292
+ font-size: calc(var(--osi-section-title-font-size) - 1.5px) !important;
293
+ }
275
294
  }
276
295
 
277
296
  .ai-section--list,
@@ -357,6 +376,17 @@
357
376
  box-sizing: border-box !important;
358
377
  display: flex !important;
359
378
  flex-direction: column !important;
379
+ padding: 0 !important; // No padding - sections should use 100% width
380
+ margin: 0 !important; // No margin - sections should use 100% width
381
+
382
+ /* Ensure all direct children use full width */
383
+ > * {
384
+ width: 100% !important;
385
+ max-width: 100% !important;
386
+ box-sizing: border-box !important;
387
+ }
388
+
389
+ /* Design moved to section-item level - wrapper is now minimal */
360
390
  }
361
391
 
362
392
  /* Ensure FAQ section specifically resizes properly */
@@ -11,16 +11,13 @@
11
11
  @import "../../../components/sections/chart-section/chart-section.scss"; // chart
12
12
  @import "../../../components/sections/contact-card-section/contact-card-section.scss"; // contact-card
13
13
  @import "../../../components/sections/event-section/event-section.scss"; // event
14
- @import "../../../components/sections/fallback-section/fallback-section.scss"; // fallback
15
14
  @import "../../../components/sections/faq-section/faq-section.scss"; // faq
16
15
  @import "../../../components/sections/financials-section/financials-section.scss"; // financials
17
16
  @import "../../../components/sections/gallery-section/gallery-section.scss"; // gallery
18
- @import "../../../components/sections/info-section/info-section.scss"; // info
19
17
  @import "../../../components/sections/list-section/list-section.scss"; // list
20
18
  @import "../../../components/sections/map-section/map-section.scss"; // map
21
19
  @import "../../../components/sections/network-card-section/network-card-section.scss"; // network-card
22
20
  @import "../../../components/sections/news-section/news-section.scss"; // news
23
- @import "../../../components/sections/overview-section/overview-section.scss"; // overview
24
21
  @import "../../../components/sections/product-section/product-section.scss"; // product
25
22
  @import "../../../components/sections/quotation-section/quotation-section.scss"; // quotation
26
23
  @import "../../../components/sections/social-media-section/social-media-section.scss"; // social-media
@@ -24,3 +24,10 @@
24
24
  // ALL SECTION STYLES (Unified)
25
25
  // ============================================================================
26
26
  @import "all-sections";
27
+
28
+ // ============================================================================
29
+ // INDIVIDUAL SECTION COMPONENT STYLES
30
+ // ============================================================================
31
+ // Import individual section component SCSS files
32
+ // These are the styles from each section's component styleUrls
33
+ @import "section-types.generated";
@@ -7,6 +7,7 @@
7
7
  // =====================================================================
8
8
 
9
9
  @use "../../tokens/master" as *;
10
+ @use "section-animations" as *;
10
11
 
11
12
  // =====================================================================
12
13
  // GRID MIXINS
@@ -139,63 +140,62 @@
139
140
  }
140
141
 
141
142
  // =====================================================================
142
- // UNIVERSAL CARD MIXIN - Uses CSS Variables Only
143
+ // UNIVERSAL CARD MIXIN - Single Source of Truth
143
144
  // =====================================================================
145
+ // This is the PRIMARY base mixin for all card styling.
146
+ // All card variants should extend this mixin.
147
+ // Uses standardized --osi-section-item-* tokens.
144
148
 
145
- @mixin card {
149
+ @mixin card($spacing: "normal") {
150
+ // Background & Border - using standardized tokens
146
151
  background: var(--osi-section-item-background);
147
152
  border: var(--osi-section-item-border);
148
153
  border-radius: var(--osi-section-item-border-radius);
149
154
  box-shadow: var(--osi-section-item-shadow);
150
- padding: var(--card-padding);
151
155
 
156
+ // Padding - using standardized tokens with spacing parameter
157
+ @if $spacing == "compact" {
158
+ padding: var(--osi-section-item-padding-compact);
159
+ } @else if $spacing == "spacious" {
160
+ padding: var(--osi-section-item-padding-spacious);
161
+ } @else {
162
+ padding: var(--osi-section-item-padding-normal);
163
+ }
164
+
165
+ // Layout
152
166
  display: flex;
153
167
  flex-direction: column;
154
- gap: var(--card-gap);
168
+ gap: var(--osi-section-item-gap);
155
169
  min-height: var(--card-min-height, auto);
156
170
 
171
+ // Interaction
157
172
  cursor: pointer;
158
173
  position: relative;
159
174
  overflow: hidden;
160
175
  overflow-x: hidden; /* Prevent horizontal scrolling */
161
- max-width: 100%;
162
- box-sizing: border-box;
176
+ width: 100% !important; // Ensure full width
177
+ max-width: 100% !important; // Ensure full width
178
+ box-sizing: border-box !important; // Include padding/border in width
163
179
  text-align: left;
164
180
  word-wrap: break-word;
165
181
  overflow-wrap: break-word;
166
182
 
167
- transition:
168
- background var(--duration-base) var(--ease-out),
169
- box-shadow var(--duration-base) var(--ease-out),
170
- border-color var(--duration-base) var(--ease-out);
183
+ // Transitions - using standardized transition token
184
+ transition: var(--osi-section-item-transition);
171
185
 
172
- // Subtle accent border indicator
173
- &::before {
174
- content: "";
175
- position: absolute;
176
- top: 0;
177
- left: 0;
178
- right: 0;
179
- height: var(--border-width-default);
180
- background: linear-gradient(90deg, var(--accent, var(--osi-accent)) 0%, transparent 100%);
181
- opacity: 0;
182
- transition: opacity var(--duration-base) var(--ease-out);
183
- border-radius: var(--osi-section-item-border-radius) var(--osi-section-item-border-radius) 0 0;
184
- }
186
+ // Metal reflection effect (default left-to-right)
187
+ // Position-based direction will be handled by CSS selectors
188
+ @include section-metal-reflection("ltr");
185
189
 
186
190
  &:hover {
187
- background: var(--osi-section-item-background-hover);
188
- border-color: var(--osi-section-item-border-hover);
189
- box-shadow: var(--osi-section-item-shadow-hover);
190
-
191
- &::before {
192
- opacity: 0.6;
193
- }
191
+ // Keep background unchanged - only border and shadow change
192
+ // background: var(--osi-section-item-background-hover); // Removed - background stays the same
193
+ border-color: var(--osi-section-item-border-hover-enhanced-color);
194
+ box-shadow: var(--osi-section-item-shadow-hover-enhanced);
194
195
  }
195
196
 
196
197
  &:focus-visible {
197
- outline: var(--border-width-accent-sm) solid var(--accent, var(--osi-accent));
198
- outline-offset: var(--border-width-accent-sm);
198
+ outline: none;
199
199
  }
200
200
 
201
201
  @media (prefers-reduced-motion: reduce) {
@@ -203,6 +203,52 @@
203
203
  }
204
204
  }
205
205
 
206
+ // =====================================================================
207
+ // LIST ITEM MIXIN
208
+ // =====================================================================
209
+ // Standardized list item styling extending base card
210
+ // Used for items within list sections
211
+
212
+ @mixin list-item($spacing: "normal") {
213
+ @include card($spacing);
214
+
215
+ // List-specific styling
216
+ // Items in lists typically don't need borders or shadows
217
+ border: none;
218
+ box-shadow: none;
219
+ background: transparent;
220
+
221
+ // Use margin for list item separation (not padding)
222
+ margin-bottom: var(--osi-section-item-margin-sm);
223
+
224
+ &:not(:last-child) {
225
+ border-bottom: 1px solid var(--border);
226
+ padding-bottom: var(--osi-section-item-gap-md);
227
+ margin-bottom: var(--osi-section-item-gap-md);
228
+ }
229
+
230
+ &:hover {
231
+ background: var(--osi-section-item-background-hover);
232
+ }
233
+
234
+ // No accent border for list items
235
+ &::before {
236
+ display: none;
237
+ }
238
+ }
239
+
240
+ // =====================================================================
241
+ // LIST CONTAINER MIXIN
242
+ // =====================================================================
243
+ // Container for list items - uses standardized tokens
244
+
245
+ @mixin list-container($spacing: "normal") {
246
+ @include card($spacing);
247
+
248
+ // List containers can have different styling if needed
249
+ gap: var(--osi-section-item-gap);
250
+ }
251
+
206
252
  // =====================================================================
207
253
  // UNIFIED SECTION CARD CLASS
208
254
  // =====================================================================
@@ -213,6 +259,91 @@
213
259
 
214
260
  .section-card {
215
261
  @include card;
262
+ & {
263
+ width: 100% !important; // Ensure full width
264
+ max-width: 100% !important; // Ensure full width
265
+ box-sizing: border-box !important; // Include padding/border in width
266
+ }
267
+ }
268
+
269
+ // =====================================================================
270
+ // GLOBAL SECTION ITEM HOVER ENHANCEMENT
271
+ // =====================================================================
272
+ // Ensure all section items get enhanced hover effects
273
+ // This applies to any element with .section-item class
274
+ // Higher specificity to ensure it overrides component-specific styles
275
+ // Each section item gets its own independent hover animation
276
+
277
+ .section-item {
278
+ // Enhanced hover effects for all section items
279
+ // Ensure border and shadow transitions are included
280
+ transition:
281
+ border-color var(--osi-card-transition-normal, 0.22s) cubic-bezier(0.4, 0, 0.2, 1),
282
+ box-shadow var(--osi-card-transition-normal, 0.22s) cubic-bezier(0.4, 0, 0.2, 1),
283
+ var(--osi-section-item-transition);
284
+
285
+ // Ensure each section item has its own metal reflection animation
286
+ position: relative;
287
+ overflow: hidden;
288
+
289
+ // Metal reflection pseudo-element for each individual item
290
+ // Using ::before to avoid conflicts with components that use ::after
291
+ &::before {
292
+ content: "";
293
+ position: absolute;
294
+ top: 0;
295
+ left: 0;
296
+ right: 0;
297
+ bottom: 0;
298
+ pointer-events: none;
299
+ z-index: 1;
300
+ opacity: 0;
301
+ border-radius: inherit;
302
+ animation: none;
303
+
304
+ // Default: left-to-right reflection with sweep animation (more discrete)
305
+ background: linear-gradient(
306
+ 90deg,
307
+ transparent 0%,
308
+ rgba(255, 255, 255, 0.2) 20%,
309
+ rgba(255, 255, 255, 0.3) 40%,
310
+ rgba(255, 255, 255, 0.2) 60%,
311
+ transparent 100%
312
+ );
313
+ width: 50%;
314
+
315
+ // Use overlay blend mode for metallic appearance
316
+ mix-blend-mode: overlay;
317
+ }
318
+
319
+ &:hover {
320
+ // Keep background unchanged - only border and shadow change
321
+ // Use !important to ensure these styles take precedence
322
+ border-color: var(--osi-section-item-border-hover-enhanced-color) !important;
323
+ box-shadow: var(--osi-section-item-shadow-hover-enhanced) !important;
324
+ // Ensure background doesn't change
325
+ background: var(--osi-section-item-background) !important;
326
+
327
+ // Trigger metal sweep animation for this specific item independently
328
+ // Default direction (will be overridden by position-based selectors below)
329
+ &::before {
330
+ opacity: 1;
331
+ animation: metal-sweep-ltr 0.23s ease-out forwards;
332
+ }
333
+ }
334
+
335
+ // Reset animation when hover ends so it can play again on next hover for this item
336
+ &:not(:hover)::before {
337
+ animation: none;
338
+ opacity: 0;
339
+ }
340
+
341
+ @media (prefers-reduced-motion: reduce) {
342
+ transition: none;
343
+ &::after {
344
+ display: none;
345
+ }
346
+ }
216
347
  }
217
348
 
218
349
  // =====================================================================
@@ -227,6 +358,7 @@
227
358
  color: var(--muted-foreground);
228
359
  line-height: 1.3;
229
360
  font-family: inherit;
361
+ margin-bottom: 0.05em; // Reduced gap between label and value
230
362
  }
231
363
 
232
364
  @mixin metric-value {
@@ -241,7 +373,7 @@
241
373
  @mixin section-description {
242
374
  font-size: var(--card-subtitle-font-size);
243
375
  color: var(--muted-foreground);
244
- line-height: 1.5;
376
+ line-height: 1.3; // Reduced from 1.5 for tighter spacing
245
377
  font-weight: 400;
246
378
  font-family: inherit;
247
379
  }
@@ -260,13 +392,16 @@
260
392
  // =====================================================================
261
393
 
262
394
  @mixin section-empty-state {
263
- padding: var(--osi-section-padding);
395
+ padding: var(--osi-section-container-padding);
264
396
  text-align: center;
265
397
  color: var(--muted-foreground);
266
- border: var(--border-width-default) dashed var(--border);
398
+ border: var(--osi-section-item-border-width) dashed var(--border);
267
399
  border-radius: var(--osi-section-item-border-radius);
268
400
  background: var(--osi-section-item-background);
269
401
  min-height: auto;
402
+
403
+ // Use standardized spacing
404
+ margin: var(--osi-section-item-margin-md);
270
405
  }
271
406
 
272
407
  @mixin section-empty-icon {
@@ -356,6 +491,136 @@
356
491
  background: var(--muted);
357
492
  }
358
493
 
494
+ // =====================================================================
495
+ // POSITION-BASED METAL REFLECTION DIRECTION
496
+ // =====================================================================
497
+ //
498
+ // Detects card position in grid and applies appropriate reflection direction.
499
+ // Left-positioned cards: left-to-right reflection
500
+ // Right-positioned cards: right-to-left reflection
501
+ //
502
+
503
+ // For masonry grid items - detect position based on column
504
+ // Targets section items nested within masonry items
505
+ // Left side items: right-to-left animation (rtl)
506
+ // Right side items: left-to-right animation (ltr)
507
+ .masonry-container,
508
+ .masonry-grid-container {
509
+ // Items in first columns (left side) - right-to-left reflection
510
+ .masonry-item:nth-child(4n + 1),
511
+ .masonry-item:nth-child(4n + 2) {
512
+ // Target all section items and cards within the masonry item
513
+ .section-item,
514
+ .unified-card,
515
+ .section-card,
516
+ [class*="-card"]:not([class*="__"]),
517
+ [class*="-item"]:not([class*="__"]) {
518
+ &::before {
519
+ // Right-to-left reflection for left side items
520
+ background: linear-gradient(
521
+ 270deg,
522
+ transparent 0%,
523
+ rgba(255, 255, 255, 0.2) 20%,
524
+ rgba(255, 255, 255, 0.3) 40%,
525
+ rgba(255, 255, 255, 0.2) 60%,
526
+ transparent 100%
527
+ ) !important;
528
+ }
529
+
530
+ &:hover::before {
531
+ animation: metal-sweep-rtl 0.23s ease-out forwards !important;
532
+ }
533
+ }
534
+ }
535
+
536
+ // Items in last columns (right side) - left-to-right reflection
537
+ .masonry-item:nth-child(4n + 3),
538
+ .masonry-item:nth-child(4n + 4),
539
+ .masonry-item[data-col-span="2"]:nth-child(odd),
540
+ .masonry-item[data-col-span="3"],
541
+ .masonry-item[data-col-span="4"] {
542
+ // Target all section items and cards within the masonry item
543
+ .section-item,
544
+ .unified-card,
545
+ .section-card,
546
+ [class*="-card"]:not([class*="__"]),
547
+ [class*="-item"]:not([class*="__"]) {
548
+ &::before {
549
+ // Left-to-right reflection for right side items
550
+ background: linear-gradient(
551
+ 90deg,
552
+ transparent 0%,
553
+ rgba(255, 255, 255, 0.2) 20%,
554
+ rgba(255, 255, 255, 0.3) 40%,
555
+ rgba(255, 255, 255, 0.2) 60%,
556
+ transparent 100%
557
+ ) !important;
558
+ }
559
+
560
+ &:hover::before {
561
+ animation: metal-sweep-ltr 0.23s ease-out forwards !important;
562
+ }
563
+ }
564
+ }
565
+ }
566
+
567
+ // For CSS Grid layouts - detect based on grid column position
568
+ @supports (grid-template-rows: masonry) {
569
+ .masonry-container--native {
570
+ // Items starting in first columns (left side) - right-to-left reflection
571
+ .masonry-item:nth-child(4n + 1),
572
+ .masonry-item:nth-child(4n + 2) {
573
+ .section-item,
574
+ .unified-card,
575
+ .section-card,
576
+ [class*="-card"]:not([class*="__"]),
577
+ [class*="-item"]:not([class*="__"]) {
578
+ &::before {
579
+ // Right-to-left reflection for left side items
580
+ background: linear-gradient(
581
+ 270deg,
582
+ transparent 0%,
583
+ rgba(255, 255, 255, 0.2) 20%,
584
+ rgba(255, 255, 255, 0.3) 40%,
585
+ rgba(255, 255, 255, 0.2) 60%,
586
+ transparent 100%
587
+ ) !important;
588
+ }
589
+
590
+ &:hover::before {
591
+ animation: metal-sweep-rtl 0.23s ease-out forwards !important;
592
+ }
593
+ }
594
+ }
595
+
596
+ // Items in last columns (right side) - left-to-right reflection
597
+ .masonry-item:nth-child(4n + 3),
598
+ .masonry-item:nth-child(4n + 4) {
599
+ .section-item,
600
+ .unified-card,
601
+ .section-card,
602
+ [class*="-card"]:not([class*="__"]),
603
+ [class*="-item"]:not([class*="__"]) {
604
+ &::before {
605
+ // Left-to-right reflection for right side items
606
+ background: linear-gradient(
607
+ 90deg,
608
+ transparent 0%,
609
+ rgba(255, 255, 255, 0.2) 20%,
610
+ rgba(255, 255, 255, 0.3) 40%,
611
+ rgba(255, 255, 255, 0.2) 60%,
612
+ transparent 100%
613
+ ) !important;
614
+ }
615
+
616
+ &:hover::before {
617
+ animation: metal-sweep-ltr 0.23s ease-out forwards !important;
618
+ }
619
+ }
620
+ }
621
+ }
622
+ }
623
+
359
624
  // =====================================================================
360
625
  // REDUCED MOTION
361
626
  // =====================================================================
@@ -373,13 +638,14 @@
373
638
  }
374
639
 
375
640
  // =====================================================================
376
- // ANIMATION SYSTEM
641
+ // ANIMATION SYSTEM - Standardized
377
642
  // =====================================================================
643
+ // Single unified animation system for all items/fields
378
644
 
379
- @keyframes section-item-stream {
645
+ @keyframes item-stream {
380
646
  0% {
381
647
  opacity: 0;
382
- transform: translate3d(0, var(--motion-distance-sm), 0);
648
+ transform: translate3d(0, var(--osi-motion-distance-sm, 8px), 0);
383
649
  }
384
650
  100% {
385
651
  opacity: 1;
@@ -387,50 +653,60 @@
387
653
  }
388
654
  }
389
655
 
390
- @mixin section-item-animation {
391
- &.section-item-streaming {
392
- animation: section-item-stream 0.25s ease-out forwards;
656
+ // Unified animation mixin for all items and fields
657
+ @mixin item-animation {
658
+ // Standard streaming state
659
+ &.item-streaming {
660
+ animation: item-stream var(--osi-section-item-animation-duration, 220ms)
661
+ var(--osi-section-item-animation-easing, cubic-bezier(0.4, 0, 0.2, 1)) forwards;
393
662
  }
394
663
 
395
- &.section-item-entered {
664
+ // Completed state (animation done)
665
+ &.item-entered {
396
666
  animation: none;
397
667
  }
398
668
 
669
+ // Stagger delays for sequential animations
399
670
  @for $i from 0 through 15 {
400
- &.section-item-stagger-#{$i} {
401
- animation-delay: calc(#{$i} * 30ms);
671
+ &.item-stagger-#{$i} {
672
+ animation-delay: calc(#{$i} * var(--osi-section-item-stagger-delay, 30ms));
402
673
  }
403
674
  }
404
- }
405
675
 
406
- @mixin legacy-item-animation {
407
- &.item-streaming {
408
- animation: section-item-stream 0.25s ease-out forwards;
676
+ // Respect reduced motion preferences
677
+ @media (prefers-reduced-motion: reduce) {
678
+ animation: none !important;
409
679
  }
680
+ }
410
681
 
411
- &.item-entered {
412
- animation: none;
413
- }
682
+ // Legacy support mixins (deprecated but kept for backward compatibility)
683
+ @mixin section-item-animation {
684
+ @include item-animation;
685
+ @warn "section-item-animation is deprecated. Use @include item-animation instead.";
414
686
 
415
- @for $i from 0 through 15 {
416
- &.item-stagger-#{$i} {
417
- animation-delay: calc(#{$i} * 30ms);
418
- }
687
+ // Legacy class name support
688
+ &.section-item-streaming {
689
+ @extend .item-streaming;
690
+ }
691
+ &.section-item-entered {
692
+ @extend .item-entered;
419
693
  }
420
694
  }
421
695
 
696
+ @mixin legacy-item-animation {
697
+ @include item-animation;
698
+ @warn "legacy-item-animation is deprecated. Use @include item-animation instead.";
699
+ }
700
+
422
701
  @mixin legacy-field-animation {
702
+ @include item-animation;
703
+ @warn "legacy-field-animation is deprecated. Use @include item-animation instead.";
704
+
705
+ // Legacy class name support
423
706
  &.field-streaming {
424
- animation: section-item-stream 0.25s ease-out forwards;
707
+ @extend .item-streaming;
425
708
  }
426
-
427
709
  &.field-entered {
428
- animation: none;
429
- }
430
-
431
- @for $i from 0 through 15 {
432
- &.field-stagger-#{$i} {
433
- animation-delay: calc(#{$i} * 30ms);
434
- }
710
+ @extend .item-entered;
435
711
  }
436
712
  }