Spaces:
Running
Running
File size: 2,177 Bytes
b57b902 97f71e2 b57b902 97f71e2 b57b902 97f71e2 b57b902 97f71e2 b57b902 97f71e2 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
class ServiceCard extends HTMLElement {
connectedCallback() {
const icon = this.getAttribute('icon') || 'code';
const title = this.getAttribute('title') || 'Service';
const description = this.getAttribute('description') || 'Professional service description';
const link = this.getAttribute('link');
const target = this.getAttribute('target') || '_self';
const content = `
<div class="card bg-white rounded-xl shadow-md overflow-hidden hover-scale transition-all-300 animate-on-scroll">
<div class="p-8">
<div class="icon-container w-16 h-16 rounded-lg bg-primary-100 text-primary-500 flex items-center justify-center mb-6">
<i data-feather="${icon}" class="w-8 h-8"></i>
</div>
<h3 class="text-xl font-bold mb-3 text-gray-800">${title}</h3>
<p class="text-gray-600">${description}</p>
</div>
</div>
`;
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
.card {
transition: all 0.3s ease;
}
.card:hover {
transform: translateY(-5px);
box-shadow: 0 10px 25px -5px rgba(0, 0, 0, 0.1);
}
.icon-container {
transition: all 0.3s ease;
}
.card:hover .icon-container {
background-color: #10b981;
color: white;
}
a {
display: block;
text-decoration: none;
color: inherit;
}
</style>
${link ? `<a href="${link}" target="${target}">${content}</a>` : content}
`;
// Initialize feather icons after component is rendered
setTimeout(() => {
if (this.shadowRoot.querySelector('i')) {
feather.replace();
}
}, 100);
}
}
customElements.define('service-card', ServiceCard); |