515 lines
11 KiB
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;
|
|
}
|
|
}
|