webdlh-net/Views/Components/Home/_Informasi.cshtml

807 lines
28 KiB
Plaintext

<div class="container max-w-6xl px-4 mx-auto my-12">
<div class="flex flex-col md:flex-row justify-between items-start md:items-start mb-12 gap-4">
<div class="w-full md:w-1/2">
<h2 class="text-2xl md:text-3xl font-bold">Informasi Lingkungan dan</br> Kebersihan <span class="text-red-500 italic">Realtime</span></h2>
</div>
<div class="w-full md:w-1/2">
<div class="flex flex-col gap-2">
<div class="inline-flex flex-wrap md:flex-nowrap mt-2 md:mt-0 bg-amber-100 rounded-full px-3 py-1 items-center hover:bg-amber-200 transition-all duration-300 w-fit">
<i class="h-4 w-4 md:h-5 md:w-5 text-amber-600 mr-2" data-lucide="calendar"></i>
<span class="font-medium text-sm md:text-base">Senin, 10 Februari 2025</span>
</div>
<div>
<p class="text-gray-600 text-balance text-sm md:text-base">
Update terbaru seputar kapasitas, teknologi, dan program keberlanjutan TPST Bantar Gebang dalam pengelolaan sampah Jakarta serta kualitas udara di Provinsi DKI Jakarta.
</p>
</div>
</div>
</div>
</div>
<div class="animate-on-scroll">
<div class="grid grid-cols-1 md:grid-cols-4 gap-4">
<!-- Jumlah Sampah Card -->
<div class="info-card relative bg-gradient-to-br from-orange-400 via-orange-500 to-orange-600 text-white p-6 rounded-xl overflow-hidden h-[140px] group transition-all duration-500 cursor-pointer transform hover:scale-[1.02] hover:shadow-lg card-3d" data-color="orange" data-type="trash">
<!-- Tooltip -->
<div class="tooltip absolute -top-12 left-1/2 -translate-x-1/2 bg-black/80 text-white px-3 py-1.5 rounded-md text-sm whitespace-nowrap opacity-0 group-hover:opacity-100 transition-all duration-300 pointer-events-none z-20 backdrop-blur-sm">
<span>Klik untuk detail informasi</span>
<div class="tooltip-arrow absolute -bottom-1 left-1/2 -translate-x-1/2 w-2 h-2 bg-black/80 rotate-45"></div>
</div>
<div class="particle-container"></div>
<div class="absolute inset-0 bg-gradient-to-r from-white/20 via-white/10 to-transparent animate-spotlight"></div>
<div class="card-glare absolute inset-0 opacity-0 transition-opacity"></div>
<div class="relative z-10 flex flex-col justify-between h-full">
<div class="flex justify-between items-start">
<div>
<h3 class="text-lg md:text-xl leading-tight card-title">Jumlah Sampah<br>Masuk TPST<br>Bantar Gebang</h3>
</div>
<div class="icon-container relative">
<i class="icon-main h-8 w-8 md:h-10 md:w-10" data-lucide="trash-2"></i>
<div class="icon-blob absolute inset-0 bg-white rounded-full scale-0 opacity-0"></div>
</div>
</div>
<div class="text-left card-content-info opacity-0 pointer-events-none">
<div class="flex items-end gap-2">
<div class="text-5xl md:text-7xl font-bold rolling-number" data-target="673">0</div>
<div class="text-lg md:text-sm font-normal">Ton</div>
</div>
<div class="mt-3 inline-flex items-center bg-orange-700 bg-opacity-50 rounded-md px-3 py-1 trend-indicator">
<i class="h-4 w-4 mr-1" data-lucide="arrow-down"></i>
<span class="text-sm">2.5%</span>
<span class="ml-1 text-sm">dari kemarin</span>
</div>
</div>
</div>
</div>
<!-- Jumlah Truk Card -->
<div class="info-card relative bg-gradient-to-br from-yellow-300 via-yellow-400 to-yellow-500 text-white rounded-xl p-6 h-[140px] overflow-hidden group transition-all duration-500 cursor-pointer transform hover:scale-[1.02] hover:shadow-lg card-3d" data-color="yellow" data-type="truck">
<!-- Tooltip -->
<div class="tooltip absolute -top-12 left-1/2 -translate-x-1/2 bg-black/80 text-white px-3 py-1.5 rounded-md text-sm whitespace-nowrap opacity-0 group-hover:opacity-100 transition-all duration-300 pointer-events-none z-20 backdrop-blur-sm">
<span>Klik untuk detail informasi</span>
<div class="tooltip-arrow absolute -bottom-1 left-1/2 -translate-x-1/2 w-2 h-2 bg-black/80 rotate-45"></div>
</div>
<div class="particle-container"></div>
<div class="absolute inset-0 bg-gradient-to-r from-white/20 via-white/10 to-transparent animate-spotlight-diagonal"></div>
<div class="card-glare absolute inset-0 opacity-0 transition-opacity"></div>
<div class="relative z-10 flex flex-col justify-between h-full">
<div class="flex justify-between items-start">
<div>
<h3 class="text-lg md:text-xl leading-tight card-title">Jumlah Truk<br>Masuk TPST<br>Bantar Gebang</h3>
</div>
<div class="icon-container relative">
<i class="icon-main h-8 w-8 md:h-10 md:w-10" data-lucide="truck"></i>
<div class="icon-blob absolute inset-0 bg-white rounded-full scale-0 opacity-0"></div>
</div>
</div>
<div class="text-left card-content-info opacity-0 pointer-events-none">
<div class="flex items-end gap-2">
<div class="text-5xl md:text-7xl font-bold rolling-number" data-target="673">0</div>
<div class="text-lg md:text-sm font-normal">Unit</div>
</div>
<div class="mt-3 inline-flex items-center bg-yellow-700 bg-opacity-50 rounded-md px-3 py-1 trend-indicator">
<i class="h-4 w-4 mr-1" data-lucide="arrow-down"></i>
<span class="text-sm">2.5%</span>
<span class="ml-1 text-sm">dari kemarin</span>
</div>
</div>
</div>
</div>
<!-- Kualitas Udara Terbaik -->
<div class="info-card relative bg-gradient-to-br from-green-500 via-green-600 to-green-700 text-white p-6 rounded-xl overflow-hidden h-[140px] group transition-all duration-500 cursor-pointer transform hover:scale-[1.02] hover:shadow-lg card-3d" data-color="green" data-type="wind">
<!-- Tooltip -->
<div class="tooltip absolute -top-12 left-1/2 -translate-x-1/2 bg-black/80 text-white px-3 py-1.5 rounded-md text-sm whitespace-nowrap opacity-0 group-hover:opacity-100 transition-all duration-300 pointer-events-none z-20 backdrop-blur-sm">
<span>Klik untuk detail informasi</span>
<div class="tooltip-arrow absolute -bottom-1 left-1/2 -translate-x-1/2 w-2 h-2 bg-black/80 rotate-45"></div>
</div>
<div class="particle-container"></div>
<div class="absolute inset-0 bg-gradient-to-r from-white/20 via-white/10 to-transparent animate-spotlight-slow"></div>
<div class="card-glare absolute inset-0 opacity-0 transition-opacity"></div>
<div class="relative z-10 flex flex-col justify-between h-full">
<div class="flex justify-between items-start">
<div>
<h3 class="text-lg md:text-xl leading-tight card-title">Kualitas Udara<br>Terbaik</h3>
</div>
<div class="icon-container relative">
<i class="icon-main h-8 w-8 md:h-10 md:w-10" data-lucide="wind"></i>
<div class="icon-blob absolute inset-0 bg-white rounded-full scale-0 opacity-0"></div>
</div>
</div>
<div class="text-left card-content-info opacity-0 pointer-events-none">
<div class="flex items-end gap-2">
<div class="text-5xl md:text-7xl font-bold rolling-number" data-target="8">0</div>
<div class="text-lg md:text-sm font-normal">ISPU</div>
</div>
<div class="mt-3 inline-flex items-center bg-green-700 bg-opacity-50 rounded-md px-3 py-1 trend-indicator">
<i class="h-4 w-4 mr-1" data-lucide="arrow-up"></i>
<span class="text-sm">2.5 μg/</span>
<span class="ml-1 text-sm">PM2</span>
</div>
</div>
</div>
</div>
<!-- Kualitas Udara Terburuk -->
<div class="info-card relative bg-gradient-to-br from-red-500 via-red-600 to-red-700 text-white p-6 rounded-xl overflow-hidden h-[140px] group transition-all duration-500 cursor-pointer transform hover:scale-[1.02] hover:shadow-lg card-3d" data-color="red" data-type="tornado">
<!-- Tooltip -->
<div class="tooltip absolute -top-12 left-1/2 -translate-x-1/2 bg-black/80 text-white px-3 py-1.5 rounded-md text-sm whitespace-nowrap opacity-0 group-hover:opacity-100 transition-all duration-300 pointer-events-none z-20 backdrop-blur-sm">
<span>Klik untuk detail informasi</span>
<div class="tooltip-arrow absolute -bottom-1 left-1/2 -translate-x-1/2 w-2 h-2 bg-black/80 rotate-45"></div>
</div>
<div class="particle-container"></div>
<div class="absolute inset-0 bg-gradient-to-r from-white/20 via-white/10 to-transparent animate-spotlight-reverse"></div>
<div class="card-glare absolute inset-0 opacity-0 transition-opacity"></div>
<div class="relative z-10 flex flex-col justify-between h-full">
<div class="flex justify-between items-start">
<div>
<h3 class="text-lg md:text-xl leading-tight card-title">Kualitas Udara<br>Terburuk</h3>
</div>
<div class="icon-container relative">
<i class="icon-main h-8 w-8 md:h-10 md:w-10" data-lucide="tornado"></i>
<div class="icon-blob absolute inset-0 bg-white rounded-full scale-0 opacity-0"></div>
</div>
</div>
<div class="text-left card-content-info opacity-0 pointer-events-none">
<div class="flex items-end gap-2">
<div class="text-5xl md:text-7xl font-bold rolling-number" data-target="8">0</div>
<div class="text-lg md:text-sm font-normal">ISPU</div>
</div>
<div class="mt-3 inline-flex items-center bg-red-700 bg-opacity-50 rounded-md px-3 py-1 trend-indicator">
<i class="h-4 w-4 mr-1" data-lucide="arrow-down"></i>
<span class="text-sm">2.5 μg/</span>
<span class="ml-1 text-sm">PM2</span>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<register-block dynamic-section="css" key="cssInformasi">
<link href="https://unpkg.com/aos@2.3.1/dist/aos.css" rel="stylesheet">
<style>
@@keyframes spotlight {
0% {
transform: translateX(-100%) skew(-20deg);
}
100% {
transform: translateX(200%) skew(-20deg);
}
}
@@keyframes spotlight-slow {
0% {
transform: translateX(-100%) skew(-15deg);
}
100% {
transform: translateX(200%) skew(-15deg);
}
}
@@keyframes spotlight-reverse {
0% {
transform: translateX(200%) skew(20deg);
}
100% {
transform: translateX(-100%) skew(20deg);
}
}
@@keyframes spotlight-diagonal {
0% {
transform: translate(-100%, -50%) skew(-25deg);
}
100% {
transform: translate(200%, 50%) skew(-25deg);
}
}
.animate-spotlight {
animation: spotlight 3s ease-in-out infinite;
}
.animate-spotlight-slow {
animation: spotlight-slow 4s ease-in-out infinite;
}
.animate-spotlight-reverse {
animation: spotlight-reverse 3.5s ease-in-out infinite;
}
.animate-spotlight-diagonal {
animation: spotlight-diagonal 4.5s ease-in-out infinite;
}
.info-card {
transition: all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.1), 0 4px 6px -2px rgba(0, 0, 0, 0.05);
transform-style: preserve-3d;
backface-visibility: hidden;
position: relative;
z-index: 1;
}
.info-card:hover .card-glare {
opacity: 0.1;
}
.info-card.expanded {
height: 240px;
box-shadow: 0 20px 25px -5px rgba(0, 0, 0, 0.2), 0 10px 10px -5px rgba(0, 0, 0, 0.1);
transform: translateY(-5px);
z-index: 2;
}
.card-glare {
background: linear-gradient(
135deg,
rgba(255, 255, 255, 0.35) 0%,
rgba(255, 255, 255, 0) 60%
);
transition: opacity 0.3s ease;
}
.particle {
position: absolute;
border-radius: 50%;
background-color: rgba(255, 255, 255, 0.5);
pointer-events: none;
}
.trend-indicator {
transition: all 0.3s ease;
}
.info-card.expanded .trend-indicator {
transform: translateY(0);
opacity: 1;
}
.icon-container {
transition: transform 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.info-card.expanded .icon-container {
transform: scale(1.2) translateY(-5px);
}
.icon-blob {
transition: all 0.5s cubic-bezier(0.34, 1.56, 0.64, 1);
}
.info-card.expanded .icon-blob {
transform: scale(2);
opacity: 0.15;
}
.info-card:hover .icon-blob {
transform: scale(1.5);
opacity: 0.1;
}
@@media (prefers-reduced-motion: no-preference) {
.rolling-number {
position: relative;
display: inline-block;
overflow: hidden;
}
.rolling-number::after {
content: "";
position: absolute;
left: 0;
right: 0;
height: 2px;
bottom: 5px;
background: rgba(255, 255, 255, 0.3);
transform: scaleX(0);
transition: transform 1s ease;
transform-origin: left;
}
.info-card.expanded .rolling-number::after {
transform: scaleX(1);
}
}
/* Custom Card Effects */
.info-card[data-type="trash"].expanded {
background-image: linear-gradient(to bottom right, #f97316, #ea580c, #c2410c);
}
.info-card[data-type="wind"].expanded {
background-image: linear-gradient(to bottom right, #22c55e, #16a34a, #15803d);
}
.info-card[data-type="tornado"].expanded {
background-image: linear-gradient(to bottom right, #ef4444, #dc2626, #b91c1c);
}
.info-card[data-type="truck"].expanded {
background-image: linear-gradient(to bottom right, #facc15, #eab308, #ca8a04);
}
/* Tooltip Styling */
.tooltip {
box-shadow: 0 10px 15px -3px rgba(0, 0, 0, 0.2);
transform: translateY(10px);
transition: all 0.3s ease;
z-index: 50;
pointer-events: none;
}
.info-card:hover .tooltip {
transform: translateY(0);
}
.info-card.expanded .tooltip {
opacity: 0 !important;
visibility: hidden;
}
.tooltip-arrow {
filter: drop-shadow(0 2px 3px rgba(0, 0, 0, 0.15));
}
/* Responsive tooltip */
@@media (max-width: 768px) {
.tooltip {
width: 90%;
max-width: 200px;
left: 50%;
white-space: normal;
text-align: center;
}
}
/* Pulse animation for tooltip visibility */
@@keyframes pulseScale {
0%, 100% { transform: scale(1); }
50% { transform: scale(1.05); }
}
.info-card:not(.expanded):hover .icon-container {
animation: pulseScale 1.5s infinite;
}
</style>
</register-block>
<register-block dynamic-section="scripts" key="jsInformasi">
<script src="https://unpkg.com/aos@2.3.1/dist/aos.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/gsap.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.12.2/ScrollTrigger.min.js"></script>
<script>
AOS.init();
gsap.registerPlugin(ScrollTrigger);
</script>
<script>
document.addEventListener("DOMContentLoaded", function () {
// Rolling numbers animation
const rollingNumbers = document.querySelectorAll('.rolling-number');
const infoCards = document.querySelectorAll('.info-card');
// Add 3D card effect
infoCards.forEach(card => {
card.addEventListener('mousemove', function(e) {
if (!this.classList.contains('expanded')) {
const rect = this.getBoundingClientRect();
const x = e.clientX - rect.left;
const y = e.clientY - rect.top;
const centerX = rect.width / 2;
const centerY = rect.height / 2;
const rotateY = (x - centerX) / 20;
const rotateX = (centerY - y) / 20;
gsap.to(this, {
rotateY: rotateY,
rotateX: rotateX,
duration: 0.5,
ease: "power1.out",
});
// Move glare with cursor
const glare = this.querySelector('.card-glare');
gsap.to(glare, {
opacity: 0.15,
top: `${y}px`,
left: `${x}px`,
duration: 0.3
});
}
});
card.addEventListener('mouseleave', function() {
if (!this.classList.contains('expanded')) {
gsap.to(this, {
rotateY: 0,
rotateX: 0,
duration: 0.5,
ease: "elastic.out(1, 0.3)"
});
const glare = this.querySelector('.card-glare');
gsap.to(glare, {
opacity: 0,
duration: 0.3
});
}
});
// Create particles for each card
const particleContainer = card.querySelector('.particle-container');
const cardType = card.getAttribute('data-type');
createParticles(particleContainer, cardType);
});
function createParticles(container, type) {
const particleCount = 12;
for (let i = 0; i < particleCount; i++) {
const particle = document.createElement('div');
particle.classList.add('particle');
// Set size (varied)
const size = Math.random() * 4 + 2;
particle.style.width = `${size}px`;
particle.style.height = `${size}px`;
// Set initial position
const posX = Math.random() * 100;
const posY = Math.random() * 100;
particle.style.left = `${posX}%`;
particle.style.top = `${posY}%`;
// Set opacity
particle.style.opacity = Math.random() * 0.5 + 0.1;
// Add to container
container.appendChild(particle);
}
}
function animateParticles(card) {
const particles = card.querySelectorAll('.particle');
const cardType = card.getAttribute('data-type');
let tl = gsap.timeline();
particles.forEach(particle => {
const duration = Math.random() * 3 + 2;
const delay = Math.random() * 2;
let animation;
switch(cardType) {
case 'trash':
// Upward floating particles
animation = {
y: `-=${Math.random() * 30 + 20}`,
x: `+=${(Math.random() - 0.5) * 20}`,
opacity: 0,
duration: duration,
delay: delay,
ease: "power1.out"
};
break;
case 'wind':
// Sideways flowing particles
animation = {
x: `+=${Math.random() * 50 + 30}`,
y: `+=${(Math.random() - 0.5) * 20}`,
opacity: 0,
duration: duration,
delay: delay,
ease: "power1.inOut"
};
break;
case 'tornado':
// Swirling particles
const angle = Math.random() * 360;
const radius = Math.random() * 30 + 10;
animation = {
motionPath: {
path: `M0,0 C${radius/2},${-radius} ${radius},${-radius/2} ${radius},0 C${radius},${radius/2} ${radius/2},${radius} 0,0`,
curviness: 1.5
},
opacity: 0,
duration: duration,
delay: delay,
ease: "power1.inOut"
};
break;
case 'truck':
// Horizontal line particles
animation = {
x: `+=${Math.random() * 40 + 20}`,
opacity: 0,
duration: duration,
delay: delay,
ease: "power1.inOut"
};
break;
default:
animation = {
y: `-=${Math.random() * 30 + 20}`,
opacity: 0,
duration: duration,
delay: delay,
ease: "power1.out"
};
}
tl.fromTo(particle,
{ opacity: 0, x: 0, y: 0, scale: 0 },
{ ...animation, scale: 1, repeat: -1 },
0
);
});
return tl;
}
// Scroll-triggered card expansion
infoCards.forEach((card, index) => {
ScrollTrigger.create({
trigger: card,
start: "top 85%",
end: "bottom 15%",
onEnter: () => {
// Slower delay for smoother expansion - increased from 0.2 to 0.5
gsap.delayedCall(index * 0.5, () => {
expandCard(card);
});
},
onLeave: () => {
// Collapse when scrolling down past the card
gsap.delayedCall(index * 0.1, () => {
collapseCard(card);
});
},
onEnterBack: () => {
// Re-expand when scrolling back up into view with slower timing
gsap.delayedCall(index * 0.3, () => {
expandCard(card);
});
},
onLeaveBack: () => {
// Collapse when scrolling up past the card
gsap.delayedCall(index * 0.1, () => {
collapseCard(card);
});
}
});
});
function expandCard(card) {
if (card.classList.contains('expanded')) return;
const content = card.querySelector('.card-content-info');
const iconContainer = card.querySelector('.icon-container');
const iconBlob = card.querySelector('.icon-blob');
// Mark as expanded
card.classList.add('expanded');
// Initialize particle animation property if not exists
if (!card._particleAnimation) {
card._particleAnimation = null;
}
// Slower, more smooth expansion animation
gsap.to(card, {
height: 240,
rotateX: 0,
rotateY: 0,
duration: 0.8, // Increased from 0.5 to 0.8
ease: "power2.out" // Changed to smoother easing
});
// Animate icon with bounce - slower timing
gsap.to(iconContainer, {
scale: 1.2,
y: -5,
duration: 0.8, // Increased from 0.5 to 0.8
ease: "back.out(1.2)" // Less aggressive bounce
});
// Animate icon blob - slower
gsap.to(iconBlob, {
scale: 2,
opacity: 0.15,
duration: 0.7, // Increased from 0.5 to 0.7
ease: "power2.out"
});
// Fade in content with longer delay and stagger
const contentElements = content.children;
gsap.to(content, {
opacity: 1,
duration: 0.2, // Increased from 0.1 to 0.2
delay: 0.4 // Increased from 0.2 to 0.4
});
gsap.fromTo(contentElements,
{ y: 20, opacity: 0 }, // Increased y from 15 to 20
{
y: 0,
opacity: 1,
duration: 0.6, // Increased from 0.4 to 0.6
stagger: 0.15, // Increased from 0.1 to 0.15
delay: 0.4, // Increased from 0.2 to 0.4
ease: "power2.out" // Smoother easing
}
);
// Start particle animation for this card only
card._particleAnimation = animateParticles(card);
// Activate rolling numbers if they're in this card with delay
setTimeout(() => {
const cardNumbers = card.querySelectorAll('.rolling-number');
cardNumbers.forEach(number => {
const target = parseInt(number.getAttribute("data-target"));
let current = 0;
const increment = target / 90; // Slower rolling - increased from 60 to 90
const updateNumber = () => {
current += increment;
if (current < target) {
number.textContent = Math.floor(current);
requestAnimationFrame(updateNumber);
} else {
number.textContent = target;
}
};
updateNumber();
});
}, 500); // Delay rolling numbers by 500ms
}
function collapseCard(card) {
if (!card.classList.contains('expanded')) return;
const content = card.querySelector('.card-content-info');
const iconContainer = card.querySelector('.icon-container');
const iconBlob = card.querySelector('.icon-blob');
// Smooth collapse animation
gsap.to(card, {
height: 140,
rotateX: 0,
rotateY: 0,
clearProps: "transform",
duration: 0.6, // Increased from 0.5 to 0.6
ease: "power2.inOut", // Smoother easing
onComplete: () => {
card.classList.remove('expanded');
}
});
// Reset icon animation - slower
gsap.to(iconContainer, {
scale: 1,
y: 0,
duration: 0.6, // Increased from 0.5 to 0.6
ease: "power2.inOut"
});
// Reset icon blob - slower
gsap.to(iconBlob, {
scale: 0,
opacity: 0,
duration: 0.4, // Increased from 0.3 to 0.4
ease: "power2.inOut"
});
// Fade out content - faster but smoother
gsap.to(content, {
opacity: 0,
duration: 0.3,
ease: "power2.inOut"
});
// Stop particle animation if it exists
if (card._particleAnimation) {
card._particleAnimation.kill();
card._particleAnimation = null;
}
// Reset rolling numbers
const cardNumbers = card.querySelectorAll('.rolling-number');
cardNumbers.forEach(number => {
number.textContent = '0';
});
}
// Observer for rolling numbers (keep existing)
const observer = new IntersectionObserver((entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
const element = entry.target;
const target = parseInt(element.getAttribute("data-target"));
let current = 0;
const increment = target / 120;
const updateNumber = () => {
current += increment;
if (current < target) {
element.textContent = Math.floor(current);
requestAnimationFrame(updateNumber);
} else {
element.textContent = target;
}
};
updateNumber();
observer.unobserve(element);
}
});
});
rollingNumbers.forEach((number) => {
observer.observe(number);
});
// Modified card click handlers - now only for collapsing
infoCards.forEach(card => {
card.addEventListener('click', function() {
// Only allow collapsing if already expanded
if (this.classList.contains('expanded')) {
collapseCard(this);
}
});
});
// Add tooltip functionality (keep existing)
infoCards.forEach(card => {
// Set aria attributes for accessibility
card.setAttribute('aria-label', 'Kartu informasi akan terbuka otomatis saat scroll');
card.setAttribute('role', 'region');
card.setAttribute('tabindex', '0');
// Support keyboard interaction for collapsing
card.addEventListener('keydown', function(e) {
if ((e.key === 'Enter' || e.key === ' ') && this.classList.contains('expanded')) {
e.preventDefault();
collapseCard(this);
}
});
// Update tooltip text
const tooltip = card.querySelector('.tooltip span');
if (tooltip) {
tooltip.textContent = 'Klik untuk tutup detail';
}
// Hide tooltip when card is expanded
card.addEventListener('click', function() {
const tooltip = this.querySelector('.tooltip');
if (tooltip) {
if (this.classList.contains('expanded')) {
tooltip.style.opacity = '0';
tooltip.style.visibility = 'hidden';
} else {
setTimeout(() => {
if (!this.classList.contains('expanded')) {
tooltip.style.opacity = '';
tooltip.style.visibility = '';
}
}, 500);
}
}
});
});
});
</script>
</register-block>