Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: If8fe8b38c1d9c4fecd40ff71f88d2ae06a6a6964
300 lines
5.4 KiB
SCSS
300 lines
5.4 KiB
SCSS
@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;
|
|
}
|
|
}
|