portfolio-page/src/scss/sections/services-section.scss

515 lines
11 KiB
SCSS

@use '../globals';
@use '../variables' as *;
.services-section {
min-height: auto;
display: flex;
align-items: center;
padding: $section-padding-y 0;
background: var(--services-background);
// Only apply min-height on larger screens where we have more space
@media (min-width: 1024px) and (min-height: 800px) {
min-height: 100vh;
}
&__container {
max-width: 80rem;
margin: 0 auto;
padding: 0 1rem;
width: 100%;
@include globals.desktop-only {
padding: 0 1.5rem;
}
}
&__header {
text-align: center;
margin-bottom: $services-header-margin;
@include globals.mobile-only {
margin-bottom: 1.5rem;
}
}
&__title {
font-size: 1.875rem;
font-weight: bold;
margin-bottom: 1rem;
color: var(--color-text);
@include globals.desktop-only {
font-size: 2.25rem;
}
@include globals.mobile-only {
font-size: 1.5rem;
}
}
&__subtitle {
font-size: 1.25rem;
color: var(--color-text-muted);
max-width: 32rem;
margin: 0 auto;
@include globals.mobile-only {
font-size: 1rem;
}
}
&__grid {
display: grid;
gap: $services-grid-gap;
// Mobile: 1 card per row (320px - 767px)
@media (max-width: 767px) {
grid-template-columns: 1fr;
gap: $services-grid-gap-mobile;
}
// Tablet Portrait: 2 cards per row (768px - 1023px)
@media (min-width: 768px) and (max-width: 1023px) {
grid-template-columns: repeat(2, 1fr);
}
// Desktop Small: 3 cards per row (1024px - 1279px)
@media (min-width: 1024px) and (max-width: 1279px) {
grid-template-columns: repeat(3, 1fr);
}
// Desktop Large: 3 cards per row (1280px+)
@media (min-width: 1280px) {
grid-template-columns: repeat(3, 1fr);
max-width: 1200px; // Limit width for better card proportions
margin: 0 auto;
}
// Ultra-wide: 4 cards per row (1920px+) - Optional
@media (min-width: 1920px) {
grid-template-columns: repeat(4, 1fr);
max-width: 1600px;
}
}
&__card {
background: white;
border-radius: $card-border-radius-md;
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1),
0 2px 4px -1px rgba(0, 0, 0, 0.06);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
overflow: hidden;
display: flex;
flex-direction: column;
height: auto;
min-height: 250px; // Ensures consistent card heights
position: relative;
border: 1px solid rgba(255, 255, 255, 0.2);
// Add subtle backdrop blur for depth
&::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: inherit;
backdrop-filter: blur(1px);
z-index: -1;
}
&:hover {
transform: translateY(-8px) scale(1.02);
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25),
0 0 0 1px rgba(255, 255, 255, 0.3);
filter: brightness(1.05);
}
&:focus-within {
outline: 3px solid var(--color-focus);
outline-offset: 2px;
}
// Responsive card heights - more flexible approach
@media (min-width: 768px) {
min-height: 280px; // Use min-height instead of fixed height
}
@media (min-width: 1024px) {
min-height: 300px;
}
@media (min-width: 1280px) {
min-height: 320px;
}
// Ensure cards don't get too tall on large screens
@media (min-width: 1920px) {
max-height: 400px;
}
&--primary {
background: var(--service-card-primary-bg);
}
&--secondary {
background: var(--service-card-secondary-bg);
}
&--tertiary {
background: var(--service-card-tertiary-bg);
}
&--quaternary {
background: var(--service-card-quaternary-bg);
}
&--quinary {
background: var(--service-card-quinary-bg);
}
&--senary {
background: var(--service-card-senary-bg);
}
}
&__card-header {
padding: $card-padding-lg;
text-align: center;
flex-shrink: 0;
@media (max-width: 767px) {
padding: $card-padding-sm;
}
}
&__icon {
width: $services-icon-size;
height: $services-icon-size;
margin: 0 auto 1rem auto;
display: block;
filter: drop-shadow(0 2px 4px rgba(0, 0, 0, 0.1));
transition: all 0.3s ease;
@media (max-width: 767px) {
width: 2rem;
height: 2rem;
margin-bottom: 0.75rem;
}
// Add subtle hover animation for icons
.services-section__card:hover & {
transform: scale(1.1) rotate(5deg);
filter: drop-shadow(0 4px 8px rgba(0, 0, 0, 0.2));
}
&--primary {
color: var(--service-icon-primary);
}
&--secondary {
color: var(--service-icon-secondary);
}
&--tertiary {
color: var(--service-icon-tertiary);
}
&--quaternary {
color: var(--service-icon-quaternary);
}
&--quinary {
color: var(--service-icon-quinary);
}
&--senary {
color: var(--service-icon-senary);
}
}
&__card-title {
font-size: 1.125rem;
font-weight: 600;
margin: 0;
line-height: 1.4;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
letter-spacing: 0.025em;
@media (max-width: 767px) {
font-size: 1rem;
}
@media (min-width: 1280px) {
font-size: 1.25rem;
}
&--primary {
color: var(--service-title-primary);
}
&--secondary {
color: var(--service-title-secondary);
}
&--tertiary {
color: var(--service-title-tertiary);
}
&--quaternary {
color: var(--service-title-quaternary);
}
&--quinary {
color: var(--service-title-quinary);
}
&--senary {
color: var(--service-title-senary);
}
}
&__card-content {
padding: 0 $services-card-padding $services-card-padding
$services-card-padding;
flex: 1;
display: flex;
align-items: center;
@media (max-width: 767px) {
padding: 0 1.25rem 1.25rem 1.25rem;
}
}
&__card-description {
margin: 0;
line-height: 1.5;
font-size: 0.875rem;
text-align: center;
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.05);
font-weight: 400;
@media (max-width: 767px) {
font-size: 0.8rem;
line-height: 1.4;
}
@media (min-width: 1280px) {
font-size: 0.9rem;
line-height: 1.6;
}
&--primary {
color: var(--service-description-primary);
}
&--secondary {
color: var(--service-description-secondary);
}
&--tertiary {
color: var(--service-description-tertiary);
}
&--quaternary {
color: var(--service-description-quaternary);
}
&--quinary {
color: var(--service-description-quinary);
}
&--senary {
color: var(--service-description-senary);
}
}
}
// Handle 6 cards specifically for better distribution
.services-section__grid:has(.services-section__card:nth-child(6):last-child) {
// For exactly 6 cards
@media (min-width: 768px) and (max-width: 1023px) {
grid-template-columns: repeat(2, 1fr);
// Make last 2 cards center themselves if needed
.services-section__card:nth-child(5),
.services-section__card:nth-child(6) {
justify-self: center;
}
}
@media (min-width: 1024px) {
grid-template-columns: repeat(3, 1fr);
}
}
// Ultra-compact mobile layout for very small screens
@media (max-height: 700px) and (max-width: 767px) {
.services-section {
min-height: auto;
padding: 1rem 0;
&__header {
margin-bottom: 1rem;
}
&__card {
min-height: 200px;
height: auto;
}
&__card-header {
padding: 1rem;
}
&__icon {
width: 1.75rem;
height: 1.75rem;
margin-bottom: 0.5rem;
}
}
}
// ================================
// WCAG Level AAA Accessibility Enhancements
// ================================
// Enhanced focus states for keyboard navigation
.services-section__card {
// Make cards keyboard accessible
&[tabindex='0'] {
cursor: pointer;
}
// AAA-compliant focus indicator (3px minimum)
&:focus {
outline: 3px solid var(--color-focus-ring, #2563eb);
outline-offset: 2px;
transform: translateY(-2px);
}
// Enhanced hover and focus interaction
&:hover,
&:focus {
transform: translateY(-4px);
box-shadow: $shadow-card-hover;
// When both focused and hovered
&:focus {
outline: 3px solid var(--color-focus-ring, #2563eb);
outline-offset: 2px;
transform: translateY(-6px); // Slightly more lift when focused
}
}
}
// High contrast mode support for better accessibility
@media (prefers-contrast: high) {
.services-section__card {
border: 2px solid currentColor !important;
&:focus {
outline: 4px solid currentColor !important;
outline-offset: 3px !important;
}
// Enhance icon visibility in high contrast
.services-section__icon {
filter: contrast(1.5) !important;
}
}
// Ensure text remains readable in high contrast mode
.services-section__card-title,
.services-section__card-description {
text-shadow: none !important;
}
}
// Reduced motion support
@media (prefers-reduced-motion: reduce) {
.services-section__card {
transition: none !important;
&:hover,
&:focus {
transform: none !important;
}
}
}
// Touch device optimizations for AAA compliance
@media (hover: none) and (pointer: coarse) {
.services-section__card {
// Ensure minimum 44x44px touch targets (cards are already large enough)
min-height: 320px;
// Remove hover effects for true touch devices
&:hover {
transform: none;
box-shadow: $shadow-card;
}
// But maintain focus for keyboard users on touch devices
&:focus {
transform: translateY(-2px);
box-shadow: $shadow-card-hover;
outline: 3px solid var(--color-focus-ring, #2563eb);
outline-offset: 2px;
}
}
}
// Dark theme specific enhancements for better visibility
@media (prefers-color-scheme: dark) {
.services-section__card {
// Enhance card visibility with better shadows in dark mode
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3),
0 2px 4px -1px rgba(0, 0, 0, 0.2);
&:hover,
&:focus {
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.4),
0 10px 10px -5px rgba(0, 0, 0, 0.2);
}
}
}
// Subtle loading animation for cards
@keyframes cardFadeIn {
from {
opacity: 0;
transform: translateY(20px);
}
to {
opacity: 1;
transform: translateY(0);
}
}
// Animation delays for staggered effect
.services-section__card {
animation: cardFadeIn 0.6s ease-out;
&:nth-child(1) {
animation-delay: 0.1s;
}
&:nth-child(2) {
animation-delay: 0.2s;
}
&:nth-child(3) {
animation-delay: 0.3s;
}
&:nth-child(4) {
animation-delay: 0.4s;
}
&:nth-child(5) {
animation-delay: 0.5s;
}
&:nth-child(6) {
animation-delay: 0.6s;
}
}