pinakes/crates/pinakes-ui/assets/styles/_mixins.scss
NotAShelf 3ccddce7fd
treewide: fix various UI bugs; optimize crypto dependencies & format
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: If8fe8b38c1d9c4fecd40ff71f88d2ae06a6a6964
2026-03-06 18:29:33 +03:00

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;
}
}