// Vagabond RPG - SCSS Mixins // =========================== // Flexbox shortcuts @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-column { display: flex; flex-direction: column; } // Grid shortcuts @mixin grid($columns: 1, $gap: $spacing-4) { display: grid; grid-template-columns: repeat($columns, 1fr); gap: $gap; } // Typography @mixin heading($size: $font-size-xl) { font-family: $font-family-header; font-size: $size; font-weight: $font-weight-bold; line-height: $line-height-tight; color: $color-text-primary; } @mixin body-text($size: $font-size-base) { font-family: $font-family-body; font-size: $size; font-weight: $font-weight-normal; line-height: $line-height-normal; color: $color-text-primary; } // Buttons @mixin button-base { display: inline-flex; align-items: center; justify-content: center; padding: $spacing-2 $spacing-4; font-family: $font-family-body; font-size: $font-size-sm; font-weight: $font-weight-medium; line-height: 1; text-decoration: none; border: 1px solid transparent; border-radius: $radius-md; cursor: pointer; transition: all $transition-fast; &:focus { outline: 2px solid $color-accent-primary; outline-offset: 2px; } &:disabled { opacity: 0.5; cursor: not-allowed; } } @mixin button-primary { @include button-base; background-color: $color-accent-primary; color: $color-text-inverse; border-color: $color-accent-secondary; &:hover:not(:disabled) { background-color: $color-accent-secondary; } } @mixin button-secondary { @include button-base; background-color: transparent; color: $color-text-primary; border-color: $color-border; &:hover:not(:disabled) { background-color: $color-parchment-dark; } } // Form inputs @mixin input-base { padding: $spacing-2 $spacing-3; font-family: $font-family-body; font-size: $font-size-base; color: $color-text-primary; background-color: $color-parchment-light; border: 1px solid $color-border; border-radius: $radius-md; transition: border-color $transition-fast; &:focus { outline: none; border-color: $color-accent-primary; box-shadow: 0 0 0 2px rgba($color-accent-primary, 0.2); } &::placeholder { color: $color-text-muted; } &:disabled { background-color: $color-parchment-darker; cursor: not-allowed; } } // Cards/Panels @mixin panel { background-color: $color-parchment; border: 1px solid $color-border; border-radius: $radius-md; box-shadow: 0 1px 3px $shadow-light; } @mixin panel-header { @include flex-between; padding: $spacing-3 $spacing-4; background-color: $color-parchment-dark; border-bottom: 1px solid $color-border; border-radius: $radius-md $radius-md 0 0; } // Scrollbar styling @mixin custom-scrollbar { &::-webkit-scrollbar { width: 8px; height: 8px; } &::-webkit-scrollbar-track { background: $color-parchment-dark; border-radius: $radius-full; } &::-webkit-scrollbar-thumb { background: $color-border; border-radius: $radius-full; &:hover { background: $color-border-dark; } } } // Accessibility - focus visible @mixin focus-visible { &:focus-visible { outline: 2px solid $color-accent-primary; outline-offset: 2px; } } // Screen reader only (visually hidden but accessible) @mixin sr-only { position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px; overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0; } // Truncate text with ellipsis @mixin truncate { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; } // Stat badge (for the large stat numbers) @mixin stat-badge($color: $color-text-primary) { @include flex-center; width: 3rem; height: 3rem; font-family: $font-family-header; font-size: $font-size-3xl; font-weight: $font-weight-bold; color: $color; background-color: $color-parchment-light; border: 2px solid $color-border; border-radius: $radius-md; }