// SAAP SCSS Mixins // === RESPONSIVE MIXINS === @mixin respond-to($breakpoint) { $breakpoints: ( 'sm': 640px, 'md': 768px, 'lg': 1024px, 'xl': 1280px, '2xl': 1536px ); @if map-has-key($breakpoints, $breakpoint) { @media (min-width: map-get($breakpoints, $breakpoint)) { @content; } } @else { @warn "Breakpoint #{$breakpoint} not found in $breakpoints map"; } } // === FLEX MIXINS === @mixin flex-center { display: flex; align-items: center; justify-content: center; } @mixin flex-between { display: flex; align-items: center; justify-content: space-between; } @mixin flex-col-center { display: flex; flex-direction: column; align-items: center; justify-content: center; } // === BUTTON MIXINS === @mixin button-base { display: inline-flex; align-items: center; justify-content: center; gap: var(--saap-space-2); padding: var(--saap-space-3) var(--saap-space-6); border: none; border-radius: var(--saap-border-radius); font-family: var(--saap-font-family); font-size: var(--saap-text-base); font-weight: var(--saap-font-semibold); line-height: 1; cursor: pointer; transition: var(--saap-transition); text-decoration: none; white-space: nowrap; user-select: none; &:disabled { opacity: 0.6; cursor: not-allowed; transform: none !important; } &:focus { outline: 2px solid var(--saap-primary-400); outline-offset: 2px; } } @mixin button-primary { @include button-base; background: var(--saap-primary-600); color: white; box-shadow: var(--saap-shadow-sm); &:hover:not(:disabled) { background: var(--saap-primary-800); transform: translateY(-2px); box-shadow: var(--saap-shadow-md); } &:active:not(:disabled) { transform: translateY(0); box-shadow: var(--saap-shadow-sm); } } @mixin button-secondary { @include button-base; background: white; color: var(--saap-neutral-700); border: 1px solid var(--saap-neutral-300); &:hover:not(:disabled) { background: var(--saap-neutral-50); border-color: var(--saap-neutral-400); color: var(--saap-neutral-900); } } @mixin button-ghost { @include button-base; background: transparent; color: var(--saap-neutral-600); &:hover:not(:disabled) { background: var(--saap-neutral-100); color: var(--saap-neutral-800); } } // === CARD MIXINS === @mixin card-base { background: white; border-radius: var(--saap-border-radius-lg); box-shadow: var(--saap-shadow-sm); border: 1px solid var(--saap-neutral-200); transition: var(--saap-transition); } @mixin card-hover { &:hover { border-color: var(--saap-primary-300); box-shadow: var(--saap-shadow-md); transform: translateY(-2px); } } // === INPUT MIXINS === @mixin input-base { width: 100%; padding: var(--saap-space-3) var(--saap-space-4); border: 1px solid var(--saap-neutral-300); border-radius: var(--saap-border-radius); background: white; font-size: var(--saap-text-base); color: var(--saap-neutral-800); transition: var(--saap-transition-fast); &::placeholder { color: var(--saap-neutral-500); } &:focus { outline: none; border-color: var(--saap-primary-400); box-shadow: 0 0 0 3px rgba(37, 99, 235, 0.1); } &:disabled { background: var(--saap-neutral-100); cursor: not-allowed; opacity: 0.6; } &.error { border-color: var(--saap-error); &:focus { border-color: var(--saap-error); box-shadow: 0 0 0 3px rgba(239, 68, 68, 0.1); } } } // === BADGE MIXINS === @mixin badge-base { display: inline-flex; align-items: center; gap: var(--saap-space-1); padding: var(--saap-space-1) var(--saap-space-3); border-radius: var(--saap-border-radius-full); font-size: var(--saap-text-xs); font-weight: var(--saap-font-semibold); text-transform: uppercase; letter-spacing: 0.05em; line-height: 1; } @mixin badge-success { @include badge-base; background: var(--saap-success); color: white; } @mixin badge-warning { @include badge-base; background: var(--saap-warning); color: white; } @mixin badge-error { @include badge-base; background: var(--saap-error); color: white; } @mixin badge-info { @include badge-base; background: var(--saap-info); color: white; } // === ANIMATION MIXINS === @mixin loading-shimmer { background: linear-gradient( 90deg, var(--saap-neutral-200) 25%, var(--saap-neutral-100) 50%, var(--saap-neutral-200) 75% ); background-size: 200% 100%; animation: shimmer 2s infinite; } @keyframes shimmer { 0% { background-position: -200% 0; } 100% { background-position: 200% 0; } } // === TRUNCATE TEXT === @mixin truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } @mixin truncate-lines($lines: 2) { display: -webkit-box; -webkit-line-clamp: $lines; -webkit-box-orient: vertical; overflow: hidden; } // === GLASSMORPHISM === @mixin glass { background: rgba(255, 255, 255, 0.1); backdrop-filter: blur(10px); border: 1px solid rgba(255, 255, 255, 0.2); } // === GRADIENT TEXT === @mixin gradient-text($gradient) { background: $gradient; background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; } // === VISUALLY HIDDEN === @mixin visually-hidden { position: absolute !important; width: 1px !important; height: 1px !important; padding: 0 !important; margin: -1px !important; overflow: hidden !important; clip: rect(0, 0, 0, 0) !important; white-space: nowrap !important; border: 0 !important; }