101 lines
2.0 KiB
SCSS
101 lines
2.0 KiB
SCSS
// =============================================================================
|
|
// abstracts/_mixins.scss
|
|
// Responsive helpers and reusable patterns.
|
|
// =============================================================================
|
|
|
|
// Bulma-matching breakpoint mixins.
|
|
@mixin mobile {
|
|
@media screen and (max-width: 768px) { @content; }
|
|
}
|
|
|
|
@mixin tablet {
|
|
@media screen and (min-width: 769px) { @content; }
|
|
}
|
|
|
|
@mixin tablet-only {
|
|
@media screen and (min-width: 769px) and (max-width: 1023px) { @content; }
|
|
}
|
|
|
|
@mixin desktop {
|
|
@media screen and (min-width: 1024px) { @content; }
|
|
}
|
|
|
|
@mixin widescreen {
|
|
@media screen and (min-width: 1216px) { @content; }
|
|
}
|
|
|
|
// Truncate text to N lines using -webkit-line-clamp.
|
|
@mixin line-clamp($lines: 2) {
|
|
display: -webkit-box;
|
|
-webkit-line-clamp: $lines;
|
|
-webkit-box-orient: vertical;
|
|
overflow: hidden;
|
|
}
|
|
|
|
// Visually hidden (accessible).
|
|
@mixin visually-hidden {
|
|
position: absolute;
|
|
width: 1px;
|
|
height: 1px;
|
|
padding: 0;
|
|
margin: -1px;
|
|
overflow: hidden;
|
|
clip: rect(0, 0, 0, 0);
|
|
white-space: nowrap;
|
|
border: 0;
|
|
}
|
|
|
|
// Aspect-ratio box.
|
|
@mixin aspect-ratio($w, $h) {
|
|
position: relative;
|
|
|
|
&::before {
|
|
content: '';
|
|
display: block;
|
|
padding-top: percentage($h / $w);
|
|
}
|
|
|
|
> * {
|
|
position: absolute;
|
|
inset: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
object-fit: cover;
|
|
}
|
|
}
|
|
|
|
// Focus visible ring (WCAG 2.1).
|
|
@mixin focus-ring($color: var(--color-primary)) {
|
|
&:focus-visible {
|
|
outline: 3px solid $color;
|
|
outline-offset: 2px;
|
|
}
|
|
}
|
|
|
|
// Card elevation with hover lift.
|
|
@mixin card-lift {
|
|
transition: transform var(--transition-base), box-shadow var(--transition-base);
|
|
|
|
&:hover {
|
|
transform: translateY(-4px);
|
|
box-shadow: var(--card-shadow-hover);
|
|
}
|
|
}
|
|
|
|
// Skeleton loading shimmer.
|
|
@mixin skeleton-shimmer {
|
|
background: linear-gradient(
|
|
90deg,
|
|
var(--color-surface) 25%,
|
|
rgba(255, 255, 255, 0.5) 50%,
|
|
var(--color-surface) 75%
|
|
);
|
|
background-size: 200% 100%;
|
|
animation: skeleton-shimmer 1.5s infinite;
|
|
}
|
|
|
|
@keyframes skeleton-shimmer {
|
|
0% { background-position: 200% 0; }
|
|
100% { background-position: -200% 0; }
|
|
}
|