MoShow's picture
I need this app to deliver High resolution products, HD, Ulte-HD, 40K stats
2f9cc52 verified
class CustomFeatureCard extends HTMLElement {
static get observedAttributes() {
return ['type', 'title', 'description', 'icon', 'color'];
}
connectedCallback() {
this.attachShadow({ mode: 'open' });
this.render();
}
getColors(color) {
const colors = {
primary: { from: '#0ea5e9', to: '#0284c7', glow: 'rgba(14, 165, 233, 0.3)' },
secondary: { from: '#d946ef', to: '#c026d3', glow: 'rgba(217, 70, 239, 0.3)' },
accent: { from: '#f97316', to: '#ea580c', glow: 'rgba(249, 115, 22, 0.3)' }
};
return colors[color] || colors.primary;
}
render() {
const type = this.getAttribute('type') || 'image';
const title = this.getAttribute('title') || 'Feature';
const description = this.getAttribute('description') || '';
const icon = this.getAttribute('icon') || 'star';
const colorKey = this.getAttribute('color') || 'primary';
const colors = this.getColors(colorKey);
this.shadowRoot.innerHTML = `
<style>
:host {
display: block;
}
.card {
position: relative;
height: 100%;
background: rgba(30, 41, 59, 0.4);
backdrop-filter: blur(12px);
border: 1px solid rgba(148, 163, 184, 0.1);
border-radius: 24px;
padding: 2rem;
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
overflow: hidden;
cursor: pointer;
}
.card::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
height: 4px;
background: linear-gradient(90deg, ${colors.from}, ${colors.to});
transform: scaleX(0);
transition: transform 0.4s ease;
}
.card:hover {
transform: translateY(-8px) scale(1.02);
border-color: ${colors.from}40;
box-shadow: 0 30px 60px -15px ${colors.glow};
}
.card:hover::before {
transform: scaleX(1);
}
.icon-wrapper {
width: 64px;
height: 64px;
border-radius: 20px;
background: linear-gradient(135deg, ${colors.from}20, ${colors.to}20);
border: 1px solid ${colors.from}30;
display: flex;
align-items: center;
justify-content: center;
margin-bottom: 1.5rem;
transition: all 0.3s ease;
}
.card:hover .icon-wrapper {
transform: scale(1.1) rotate(-5deg);
background: linear-gradient(135deg, ${colors.from}, ${colors.to});
}
.icon-wrapper i {
color: ${colors.from};
transition: color 0.3s ease;
}
.card:hover .icon-wrapper i {
color: white;
}
.badge {
position: absolute;
top: 1.5rem;
right: 1.5rem;
padding: 0.375rem 0.875rem;
background: ${colors.from}15;
border: 1px solid ${colors.from}30;
border-radius: 9999px;
color: ${colors.from};
font-size: 0.75rem;
font-weight: 600;
text-transform: uppercase;
letter-spacing: 0.05em;
}
h3 {
font-size: 1.5rem;
font-weight: 700;
color: #f8fafc;
margin-bottom: 0.75rem;
}
p {
color: #94a3b8;
font-size: 0.9375rem;
line-height: 1.7;
margin-bottom: 1.5rem;
}
.features {
display: flex;
flex-direction: column;
gap: 0.75rem;
}
.feature-item {
display: flex;
align-items: center;
gap: 0.75rem;
font-size: 0.875rem;
color: #64748b;
}
.feature-item i {
color: ${colors.from};
width: 16px;
height: 16px;
}
.resolution-badges {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
margin-top: 1rem;
}
.res-badge {
padding: 0.25rem 0.5rem;
background: rgba(15, 23, 42, 0.6);
border: 1px solid ${colors.from}40;
border-radius: 6px;
font-size: 0.65rem;
color: ${colors.from};
font-weight: 600;
text-transform: uppercase;
}
.res-badge.ultra {
background: linear-gradient(135deg, ${colors.from}30, ${colors.to}30);
border-color: ${colors.from};
}
@keyframes pulse {
0%, 100% { opacity: 0.6; }
50% { opacity: 1; }
}
.cta-arrow {
position: absolute;
bottom: 1.5rem;
right: 1.5rem;
width: 48px;
height: 48px;
border-radius: 50%;
background: rgba(148, 163, 184, 0.1);
display: flex;
align-items: center;
justify-content: center;
opacity: 0;
transform: translateX(-10px);
transition: all 0.3s ease;
}
.card:hover .cta-arrow {
opacity: 1;
transform: translateX(0);
background: ${colors.from};
}
.cta-arrow i {
color: white;
}
</style>
<div class="card" onclick="window.location.href='#studio'">
<span class="badge">${type}</span>
<div class="icon-wrapper">
<i data-feather="${icon}" style="width: 28px; height: 28px;"></i>
</div>
<h3>${title}</h3>
<p>${description}</p>
<div class="features">
${this.getFeatureItems(type, colors.from)}
</div>
<div class="resolution-badges">
<span class="res-badge">4K</span>
<span class="res-badge">8K</span>
<span class="res-badge ultra">16K</span>
<span class="res-badge ultra">20K+</span>
</div>
<div class="cta-arrow">
<i data-feather="arrow-right" style="width: 20px; height: 20px;"></i>
</div>
</div>
`;
}
getFeatureItems(type, color) {
const features = {
image: [
{ icon: 'maximize', text: 'Up to 20K resolution' },
{ icon: 'layers', text: 'AI Upscaling 4x' },
{ icon: 'sliders', text: 'Pro color grading' }
],
video: [
{ icon: 'clock', text: 'Up to 8K 120fps' },
{ icon: 'repeat', text: 'HDR10+ support' },
{ icon: 'film', text: 'Cinema quality' }
],
gif: [
{ icon: 'loader', text: '4K 60fps loops' },
{ icon: 'palette', text: 'Lossless encoding' },
{ icon: 'share-2', text: 'Web optimized' }
],
'3d': [
{ icon: 'box', text: '8K texture maps' },
{ icon: 'grid', text: 'PBR 4K materials' },
{ icon: 'printer', text: 'Micron precision' }
]
};
return (features[type] || features.image).map(f => `
<div class="feature-item">
<i data-feather="${f.icon}" style="color: ${color};"></i>
<span>${f.text}</span>
</div>
`).join('');
}
}
customElements.define('custom-feature-card', CustomFeatureCard);