@use 'variables' as *; // Utility mixins @mixin flex($direction: row, $justify: flex-start, $align: stretch, $gap: 0) { display: flex; flex-direction: $direction; justify-content: $justify; align-items: $align; @if $gap != 0 { gap: $gap; } } @mixin flex-center { display: flex; align-items: center; justify-content: center; } @mixin flex-between { display: flex; justify-content: space-between; align-items: center; } // Text mixins @mixin text-truncate { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; } @mixin text-uppercase($letter-spacing: $letter-spacing-wider) { text-transform: uppercase; letter-spacing: $letter-spacing; } @mixin font-mono($size: $font-size-md) { font-family: $font-family-mono; font-size: $size; } // Button mixins @mixin button-base { padding: 5px 12px; border-radius: $radius-sm; border: none; cursor: pointer; font-size: $font-size-md; font-weight: $font-weight-medium; transition: all $transition-base; display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; line-height: 1.5; } @mixin button-variant($bg, $color, $border: null, $hover-bg: null) { background: $bg; color: $color; @if $border { border: 1px solid $border; } @if $hover-bg { &:hover { background: $hover-bg; } } } @mixin button-ghost { background: transparent; border: none; } // Card mixins @mixin card($padding: $space-8) { background: $bg-2; border: 1px solid $border; border-radius: $radius; padding: $padding; } @mixin card-header { display: flex; justify-content: space-between; align-items: center; margin-bottom: $space-6; } // Form mixins @mixin input-base { padding: 6px 10px; border-radius: $radius-sm; border: 1px solid $border; background: $bg-0; color: $text-0; font-size: $font-size-lg; outline: none; transition: border-color $transition-slow; font-family: inherit; &::placeholder { color: $text-2; } &:focus { border-color: $accent; } } @mixin form-label { display: block; font-size: $font-size-base; font-weight: $font-weight-semibold; color: $text-1; margin-bottom: $space-2; @include text-uppercase($letter-spacing-wide); } // Scrollbar mixins @mixin scrollbar($width: 5px, $thumb-color: $overlay-strong, $track-color: transparent) { &::-webkit-scrollbar { width: $width; height: $width; } &::-webkit-scrollbar-track { background: $track-color; } &::-webkit-scrollbar-thumb { background: $thumb-color; border-radius: 3px; &:hover { background: $border-strong; } } scrollbar-width: thin; scrollbar-color: $thumb-color $track-color; } // Status/state mixins @mixin status-dot($size: 6px) { width: $size; height: $size; border-radius: 50%; flex-shrink: 0; } @mixin disabled-state($opacity: 0.4) { opacity: $opacity; cursor: not-allowed; pointer-events: none; } @mixin focus-outline($color: $accent, $width: 2px, $offset: 2px) { &:focus-visible { outline: $width solid $color; outline-offset: $offset; } } // Animation mixins @mixin animation($name, $duration: 0.7s, $timing: linear, $iteration: infinite) { animation: $name $duration $timing $iteration; } @mixin fade-in($duration: 0.1s) { animation: fade-in $duration ease-out; } @mixin slide-up($duration: 0.15s, $distance: 8px) { animation: slide-up $duration ease-out; @keyframes slide-up { from { opacity: 0; transform: translateY($distance); } to { opacity: 1; transform: translateY(0); } } } @mixin pulse($duration: 1.5s) { animation: pulse $duration infinite; } @mixin skeleton-pulse { animation: skeleton-pulse 1.5s ease-in-out infinite; background: $bg-3; } // Badge mixins @mixin badge-base { display: inline-flex; align-items: center; gap: $space-2; padding: $space-1 $space-3; border-radius: $radius-xl; font-size: $font-size-sm; font-weight: $font-weight-medium; } @mixin badge-variant($bg, $color) { background: $bg; color: $color; } // Tooltip mixins @mixin tooltip-trigger { display: inline-flex; align-items: center; justify-content: center; width: 14px; height: 14px; border-radius: 50%; background: $bg-3; color: $text-2; font-size: $font-size-xs; font-weight: $font-weight-bold; cursor: help; position: relative; flex-shrink: 0; margin-left: $space-2; &:hover { background: $accent-dim; color: $accent-text; } } @mixin tooltip-content { display: none; position: absolute; bottom: calc(100% + 6px); left: 50%; transform: translateX(-50%); padding: 6px 10px; background: $bg-3; border: 1px solid $border; border-radius: $radius-sm; color: $text-0; font-size: $font-size-base; font-weight: $font-weight-normal; line-height: $line-height-normal; white-space: normal; width: 220px; text-transform: none; letter-spacing: normal; box-shadow: $shadow; z-index: 100; pointer-events: none; } // Media queries @mixin mobile { @media (max-width: 768px) { @content; } } @mixin tablet { @media (min-width: 769px) and (max-width: 1024px) { @content; } } @mixin desktop { @media (min-width: 1025px) { @content; } } // Reduced motion @mixin respect-reduced-motion { @media (prefers-reduced-motion: reduce) { animation-duration: 0.01ms !important; animation-iteration-count: 1 !important; transition-duration: 0.01ms !important; } }