.container { position: relative; width: 100%; height: 450px; overflow: hidden; touch-action: none; margin: 40px 0 60px 0; perspective: 1000px; cursor: grab; user-select: none; } /* Left and right fade out masks */ .leftMask, .rightMask { position: absolute; top: 0; bottom: 0; width: 100px; z-index: 20; pointer-events: none; } .leftMask { left: 0; background: linear-gradient(to right, #0b1220, transparent); } .rightMask { right: 0; background: linear-gradient(to left, #0b1220, transparent); } .container.dragging { cursor: grabbing; } .carouselWrapper { position: relative; width: 100%; height: 100%; display: flex; align-items: center; justify-content: center; transform-style: preserve-3d; perspective: 1500px; } /* Entering edge helpers to ensure ease-out even with <5 products */ /* entering helpers removed (reverted) */ /* Edge fade-out on shift for better intuition */ .carouselWrapper.shiftingLeft .cardContainer.positionNeg2 { opacity: 0; transform: translateX(-420px) rotateY(62deg) scale(0.66); } .carouselWrapper.shiftingRight .cardContainer.position2 { opacity: 0; transform: translateX(420px) rotateY(-62deg) scale(0.66); } .cardContainer { position: absolute; width: 320px; height: 370px; cursor: pointer; transform-style: preserve-3d; will-change: transform; backface-visibility: hidden; transform-origin: center center; transition: transform 0.8s cubic-bezier(0.22, 1, 0.36, 1), opacity 0.8s cubic-bezier(0.22, 1, 0.36, 1); transform: translateX(0) rotateY(0) scale(1); opacity: 1; z-index: 1; box-sizing: border-box; aspect-ratio: 320/370; } .cardWrapper { width: 100%; height: 100%; padding: 0 15px; transform-style: preserve-3d; backface-visibility: hidden; box-sizing: border-box; position: relative; z-index: 2; /* ensure content stacks above shadow */ } /* Ground shadow to enhance 3D standing effect */ .cardShadow { position: absolute; left: 50%; bottom: 6px; width: 92%; height: 32px; transform: translateX(-50%) scale(1); background: radial-gradient(ellipse at center, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0.32) 45%, rgba(0,0,0,0) 78%); filter: blur(8px); opacity: 0.45; pointer-events: none; z-index: 1; } .cardContainer.position0 .cardShadow { opacity: 0.8; transform: translateX(-50%) scale(1.15); } .cardContainer.positionNeg1 .cardShadow, .cardContainer.position1 .cardShadow { opacity: 0.55; transform: translateX(-50%) scale(1.02); } .cardContainer.positionNeg2 .cardShadow, .cardContainer.position2 .cardShadow { opacity: 0.42; transform: translateX(-50%) scale(0.96); } /* Initial state: subtle pop-in */ .cardContainer.initial { transform: translateX(0) translateY(20px) rotateY(0) scale(0.92); opacity: 0; z-index: 1; } /* New load spread: compact fan-out from center */ .cardContainer.spread.positionNeg2 { transform: translateX(-320px) translateZ(-120px) rotateY(10deg) scale(0.9); opacity: 0.8; } .cardContainer.spread.positionNeg1 { transform: translateX(-160px) translateZ(-60px) rotateY(6deg) scale(0.97); opacity: 0.9; } .cardContainer.spread.position0 { transform: translateX(0) translateZ(0) rotateY(0) scale(1.06); opacity: 1; } .cardContainer.spread.position1 { transform: translateX(160px) translateZ(-60px) rotateY(-6deg) scale(0.97); opacity: 0.9; } .cardContainer.spread.position2 { transform: translateX(320px) translateZ(-120px) rotateY(-10deg) scale(0.9); opacity: 0.8; } /* Position classes for coverflow effect (closer to center) */ .cardContainer.positionNeg2 { transform: translateX(-380px) rotateY(55deg) scale(0.7); opacity: 1; z-index: 5; } .cardContainer.positionNeg1 { transform: translateX(-190px) rotateY(35deg) scale(0.8); opacity: 1; z-index: 10; } .cardContainer.position0 { transform: translateX(0) rotateY(0deg) scale(1); opacity: 1; z-index: 15; } .cardContainer.position1 { transform: translateX(190px) rotateY(-35deg) scale(0.8); opacity: 1; z-index: 10; } .cardContainer.position2 { transform: translateX(380px) rotateY(-55deg) scale(0.7); opacity: 1; z-index: 5; } /* Edge-enter overrides (placed after position rules to win cascade) */ .cardContainer.enterFromRight.position1, .cardContainer.enterFromRight.position2 { opacity: 0; transform: translateX(520px) rotateY(-62deg) scale(0.66); } .cardContainer.enterFromLeft.positionNeg1, .cardContainer.enterFromLeft.positionNeg2 { opacity: 0; transform: translateX(-520px) rotateY(62deg) scale(0.66); } .cardImage { width: 100%; height: 120px; background-size: cover; background-position: center; background-repeat: no-repeat; transition: transform 0.4s ease; position: relative; background-color: #f1f5f9; display: flex; align-items: center; justify-content: center; flex-shrink: 0; object-fit: cover; aspect-ratio: 4/3; overflow: hidden; } .placeholderImage { display: flex; align-items: center; justify-content: center; width: 100%; height: 100%; background-color: #f1f5f9; object-fit: cover; aspect-ratio: 4/3; overflow: hidden; } .placeholderImage span { font-size: 2rem; opacity: 0.3; } .cardContent { padding: 1rem; flex: 1; display: flex; flex-direction: column; } .cardTitle { font-size: 1.1rem; font-weight: 700; color: #1e293b; margin-bottom: 0.5rem; line-height: 1.3; flex: 1; } .cardDescription { color: #64748b; line-height: 1.5; margin-bottom: 1rem; font-size: 0.85rem; flex: 1; } .cardFooter { display: flex; justify-content: space-between; align-items: center; border-top: 1px solid #e2e8f0; padding-top: 1rem; margin-top: auto; } .priceContainer { flex: 1; } .price { font-size: 1rem; font-weight: 700; } .freePrice { color: #059669; } .paidPrice { color: #2563eb; } .enrollButton { background: linear-gradient(135deg, #6a59ff 0%, #8261ee 100%); color: white; border: none; padding: 0.5rem 1rem; border-radius: 8px; font-size: 0.8rem; font-weight: 600; cursor: pointer; transition: all 0.3s ease; box-shadow: 0 4px 15px rgba(106, 89, 255, 0.2); flex-shrink: 0; } .enrollButton:hover { transform: translateY(-2px); box-shadow: 0 6px 20px rgba(106, 89, 255, 0.3); } .enrollButton:active { transform: translateY(0); } .noCourses { text-align: center; grid-column: 1 / -1; padding: 3rem; color: #64748b; } .loadingCourses { text-align: center; grid-column: 1 / -1; padding: 3rem; color: #64748b; display: flex; align-items: center; justify-content: center; gap: 1rem; } .loadingSpinner { width: 24px; height: 24px; border: 3px solid #e2e8f0; border-top: 3px solid #6a59ff; border-radius: 50%; animation: spin 1s linear infinite; } @keyframes spin { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } /* Navigation buttons */ .navButton { position: absolute; top: 50%; transform: translateY(-50%); width: 50px; height: 50px; border-radius: 50%; background-color: white; border: 2px solid #e2e8f0; display: flex; align-items: center; justify-content: center; cursor: pointer; transition: all 0.3s ease; color: #475569; z-index: 100; box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08); } .navButton:hover:not(:disabled) { border-color: #6a59ff; color: #6a59ff; box-shadow: 0 6px 16px rgba(0, 0, 0, 0.12); } .navButton:disabled { opacity: 0.5; cursor: not-allowed; } .navButton:first-of-type { left: 30px; } .navButton:last-of-type { right: 30px; } /* Dots indicator */ .dotsContainer { position: absolute; bottom: -40px; left: 50%; transform: translateX(-50%); display: flex; gap: 12px; z-index: 100; } .dot { width: 12px; height: 12px; border-radius: 50%; background-color: #cbd5e1; border: none; cursor: pointer; transition: all 0.3s ease; transform: scale(1); } .dot.active { background-color: #6a59ff; transform: scale(1.2); } .dot:hover { background-color: #94a3b8; } /* Responsive design */ @media (max-width: 1200px) { .container { height: 430px; margin: 35px 0 55px 0; } .cardContainer { width: 300px; height: 350px; } .navButton { width: 45px; height: 45px; } .navButton:first-of-type { left: 25px; } .navButton:last-of-type { right: 25px; } .dotsContainer { bottom: -35px; } .leftMask, .rightMask { width: 80px; } } @media (max-width: 992px) { .container { height: 410px; margin: 30px 0 50px 0; } .cardContainer { width: 280px; height: 330px; } .cardWrapper { padding: 0 12px; } .navButton { width: 40px; height: 40px; } .navButton:first-of-type { left: 20px; } .navButton:last-of-type { right: 20px; } .dotsContainer { bottom: -30px; } .dot { width: 10px; height: 10px; } .leftMask, .rightMask { width: 70px; } } @media (max-width: 768px) { .container { height: 380px; margin: 25px 0 45px 0; } .cardContainer { width: 250px; height: 300px; } .cardWrapper { padding: 0 10px; } .navButton { width: 35px; height: 35px; } .navButton:first-of-type { left: 15px; } .navButton:last-of-type { right: 15px; } .navButton svg { width: 20px; height: 20px; } .dotsContainer { bottom: -25px; gap: 10px; } .dot { width: 9px; height: 9px; } .leftMask, .rightMask { width: 60px; } } @media (max-width: 576px) { .container { height: 320px; margin: 20px 0 40px 0; } .cardContainer { width: 200px; height: 250px; } .cardWrapper { padding: 0 6px; } .navButton { width: 30px; height: 30px; } .navButton:first-of-type { left: 10px; } .navButton:last-of-type { right: 10px; } .navButton svg { width: 16px; height: 16px; } .dotsContainer { bottom: -20px; gap: 8px; } .dot { width: 8px; height: 8px; } /* Adjust positions for smaller screens */ .cardContainer.positionNeg2 { transform: translateX(-280px) rotateY(55deg) scale(0.6); } .cardContainer.positionNeg1 { transform: translateX(-140px) rotateY(35deg) scale(0.75); } .cardContainer.position1 { transform: translateX(140px) rotateY(-35deg) scale(0.75); } .cardContainer.position2 { transform: translateX(280px) rotateY(-55deg) scale(0.6); } .leftMask, .rightMask { width: 50px; } } @media (max-width: 400px) { .container { height: 280px; margin: 15px 0 35px 0; } .cardContainer { width: 180px; height: 230px; } .navButton { width: 28px; height: 28px; } .navButton svg { width: 14px; height: 14px; } .dotsContainer { bottom: -18px; } .dot { width: 7px; height: 7px; } /* Further adjust positions for very small screens */ .cardContainer.positionNeg2 { transform: translateX(-240px) rotateY(55deg) scale(0.5); } .cardContainer.positionNeg1 { transform: translateX(-120px) rotateY(35deg) scale(0.7); } .cardContainer.position1 { transform: translateX(120px) rotateY(-35deg) scale(0.7); } .cardContainer.position2 { transform: translateX(240px) rotateY(-55deg) scale(0.5); } .leftMask, .rightMask { width: 40px; } }