Análisis Comparativo — Prompts Gastronómicos IA
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root {
–black: #080808;
–deep: #0f0e0c;
–coal: #1a1815;
–gold: #c9a84c;
–amber: #e8b84b;
–cream: #f0e6cc;
–white: #faf7f2;
–muted: #7a7060;
–doc-a: #c9a84c;
–doc-b: #6b8fa3;
}
html { scroll-behavior: smooth; }
body {
background: var(–black);
color: var(–cream);
font-family: ‘DM Mono’, monospace;
overflow-x: hidden;
cursor: crosshair;
}
body::before {
content: »;
position: fixed;
inset: 0;
background-image: url(«data:image/svg+xml,%3Csvg viewBox=’0 0 256 256′ xmlns=’http://www.w3.org/2000/svg’%3E%3Cfilter id=’noise’%3E%3CfeTurbulence type=’fractalNoise’ baseFrequency=’0.9′ numOctaves=’4′ stitchTiles=’stitch’/%3E%3C/filter%3E%3Crect width=’100%25′ height=’100%25′ filter=’url(%23noise)’ opacity=’0.04’/%3E%3C/svg%3E»);
pointer-events: none;
z-index: 9999;
opacity: 0.6;
}
#progress {
position: fixed;
top: 0; left: 0;
height: 2px;
background: linear-gradient(90deg, var(–gold), var(–amber));
width: 0%;
z-index: 1000;
transition: width 0.1s linear;
box-shadow: 0 0 12px var(–amber);
}
.hero {
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
overflow: hidden;
padding: 4rem 2rem;
}
.hero-bg {
position: absolute;
inset: 0;
background:
radial-gradient(ellipse 80% 60% at 50% 0%, rgba(201,168,76,0.12) 0%, transparent 70%),
radial-gradient(ellipse 60% 40% at 20% 100%, rgba(107,143,163,0.08) 0%, transparent 60%),
var(–black);
}
.hero-bg-lines {
position: absolute;
inset: 0;
background-image:
linear-gradient(rgba(201,168,76,0.04) 1px, transparent 1px),
linear-gradient(90deg, rgba(201,168,76,0.04) 1px, transparent 1px);
background-size: 60px 60px;
animation: gridMove 20s linear infinite;
}
@keyframes gridMove {
0% { transform: translateY(0); }
100% { transform: translateY(60px); }
}
.hero-tag {
font-family: ‘DM Mono’, monospace;
font-size: 0.65rem;
letter-spacing: 0.3em;
color: var(–gold);
text-transform: uppercase;
border: 1px solid rgba(201,168,76,0.3);
padding: 0.4rem 1.2rem;
margin-bottom: 3rem;
position: relative;
z-index: 1;
animation: fadeInDown 1s ease 0.3s both;
}
.hero-title {
font-family: ‘Playfair Display’, serif;
font-size: clamp(3rem, 8vw, 7rem);
font-weight: 900;
line-height: 0.95;
text-align: center;
position: relative;
z-index: 1;
animation: fadeInUp 1s ease 0.5s both;
}
.hero-title .line-gold {
display: block;
background: linear-gradient(135deg, var(–gold) 0%, var(–amber) 50%, var(–cream) 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.hero-title .line-white {
display: block;
color: var(–white);
font-style: italic;
opacity: 0.15;
font-size: 0.5em;
letter-spacing: 0.05em;
margin-top: 0.5rem;
}
.hero-subtitle {
font-family: ‘Cormorant Garamond’, serif;
font-size: clamp(1rem, 2.5vw, 1.4rem);
font-style: italic;
color: var(–muted);
text-align: center;
max-width: 600px;
margin-top: 2.5rem;
line-height: 1.6;
position: relative;
z-index: 1;
animation: fadeInUp 1s ease 0.8s both;
}
.hero-scroll {
position: absolute;
bottom: 2rem;
left: 50%;
transform: translateX(-50%);
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
z-index: 1;
animation: fadeInUp 1s ease 1.2s both;
}
.hero-scroll span {
font-size: 0.55rem;
letter-spacing: 0.3em;
color: var(–muted);
text-transform: uppercase;
}
.scroll-line {
width: 1px;
height: 50px;
background: linear-gradient(var(–gold), transparent);
animation: scrollPulse 2s ease-in-out infinite;
}
@keyframes scrollPulse {
0%, 100% { opacity: 0.3; transform: scaleY(1); }
50% { opacity: 1; transform: scaleY(1.2); }
}
section {
padding: 8rem 2rem;
max-width: 1100px;
margin: 0 auto;
position: relative;
}
.section-number {
font-family: ‘Playfair Display’, serif;
font-size: 12rem;
font-weight: 900;
position: absolute;
top: 3rem;
right: -2rem;
color: rgba(201,168,76,0.04);
line-height: 1;
user-select: none;
pointer-events: none;
}
.section-label {
font-size: 0.6rem;
letter-spacing: 0.35em;
color: var(–gold);
text-transform: uppercase;
margin-bottom: 1.5rem;
display: flex;
align-items: center;
gap: 1rem;
}
.section-label::before {
content: »;
display: block;
width: 30px;
height: 1px;
background: var(–gold);
}
.section-title {
font-family: ‘Playfair Display’, serif;
font-size: clamp(2rem, 4vw, 3.5rem);
font-weight: 700;
line-height: 1.1;
margin-bottom: 3rem;
color: var(–white);
}
.docs-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 2px;
margin: 4rem 0;
}
.doc-card {
padding: 3rem;
position: relative;
overflow: hidden;
transition: all 0.4s ease;
}
.doc-card::before {
content: »;
position: absolute;
inset: 0;
opacity: 0;
transition: opacity 0.4s ease;
}
.doc-card:hover::before { opacity: 1; }
.doc-card.doc-a {
background: rgba(201,168,76,0.05);
border: 1px solid rgba(201,168,76,0.15);
border-right: none;
}
.doc-card.doc-a::before {
background: linear-gradient(135deg, rgba(201,168,76,0.08) 0%, transparent 60%);
}
.doc-card.doc-a:hover { border-color: rgba(201,168,76,0.4); }
.doc-card.doc-b {
background: rgba(107,143,163,0.05);
border: 1px solid rgba(107,143,163,0.15);
}
.doc-card.doc-b::before {
background: linear-gradient(135deg, rgba(107,143,163,0.08) 0%, transparent 60%);
}
.doc-card.doc-b:hover { border-color: rgba(107,143,163,0.4); }
.doc-badge {
display: inline-block;
font-size: 0.6rem;
letter-spacing: 0.25em;
text-transform: uppercase;
padding: 0.3rem 0.8rem;
margin-bottom: 2rem;
font-family: ‘DM Mono’, monospace;
}
.doc-a .doc-badge {
color: var(–gold);
border: 1px solid rgba(201,168,76,0.4);
background: rgba(201,168,76,0.08);
}
.doc-b .doc-badge {
color: #6b8fa3;
border: 1px solid rgba(107,143,163,0.4);
background: rgba(107,143,163,0.08);
}
.doc-card h3 {
font-family: ‘Playfair Display’, serif;
font-size: 1.4rem;
font-weight: 700;
line-height: 1.3;
margin-bottom: 1rem;
}
.doc-a h3 { color: var(–cream); }
.doc-b h3 { color: #b8cdd9; }
.doc-card p {
font-family: ‘Cormorant Garamond’, serif;
font-size: 1rem;
line-height: 1.7;
color: var(–muted);
font-style: italic;
}
.doc-stat {
margin-top: 2rem;
padding-top: 2rem;
border-top: 1px solid rgba(255,255,255,0.06);
display: flex;
gap: 2rem;
}
.doc-stat-item { display: flex; flex-direction: column; gap: 0.3rem; }
.doc-stat-item .num {
font-family: ‘Playfair Display’, serif;
font-size: 2rem;
font-weight: 900;
line-height: 1;
}
.doc-a .doc-stat-item .num { color: var(–gold); }
.doc-b .doc-stat-item .num { color: #6b8fa3; }
.doc-stat-item .label {
font-size: 0.6rem;
letter-spacing: 0.2em;
text-transform: uppercase;
color: var(–muted);
}
.criteria-list {
display: flex;
flex-direction: column;
gap: 3px;
margin: 3rem 0;
}
.criteria-item {
display: grid;
grid-template-columns: 2rem 1fr 1fr 1fr;
gap: 0;
overflow: hidden;
}
.criteria-num {
background: rgba(201,168,76,0.06);
border: 1px solid rgba(201,168,76,0.1);
display: flex;
align-items: center;
justify-content: center;
font-family: ‘Playfair Display’, serif;
font-size: 0.7rem;
color: rgba(201,168,76,0.5);
writing-mode: vertical-rl;
letter-spacing: 0.2em;
padding: 1rem 0;
min-height: 120px;
}
.criteria-title-col {
padding: 2rem;
background: rgba(255,255,255,0.02);
border: 1px solid rgba(255,255,255,0.05);
border-left: none;
display: flex;
flex-direction: column;
justify-content: center;
}
.criteria-title-col h4 {
font-family: ‘Playfair Display’, serif;
font-size: 1.1rem;
color: var(–white);
margin-bottom: 0.5rem;
}
.criteria-title-col p {
font-family: ‘Cormorant Garamond’, serif;
font-size: 0.9rem;
color: var(–muted);
font-style: italic;
line-height: 1.5;
}
.criteria-score {
padding: 2rem;
display: flex;
flex-direction: column;
justify-content: center;
gap: 0.8rem;
border: 1px solid rgba(255,255,255,0.03);
border-left: none;
}
.criteria-score.winner-a { background: rgba(201,168,76,0.07); border-left: 2px solid rgba(201,168,76,0.4); }
.criteria-score.winner-b { background: rgba(107,143,163,0.07); border-left: 2px solid rgba(107,143,163,0.4); }
.score-label {
font-size: 0.55rem;
letter-spacing: 0.25em;
text-transform: uppercase;
color: var(–muted);
}
.score-bar-wrap {
position: relative;
height: 4px;
background: rgba(255,255,255,0.06);
border-radius: 2px;
overflow: hidden;
}
.score-bar {
height: 100%;
border-radius: 2px;
width: 0%;
transition: width 1.5s cubic-bezier(0.16, 1, 0.3, 1);
}
.score-bar.a { background: linear-gradient(90deg, var(–gold), var(–amber)); }
.score-bar.b { background: linear-gradient(90deg, #4a7a96, #6b8fa3); }
.score-value {
font-family: ‘Playfair Display’, serif;
font-size: 1.5rem;
font-weight: 900;
line-height: 1;
}
.criteria-score.winner-a .score-value { color: var(–gold); }
.criteria-score.winner-b .score-value { color: #6b8fa3; }
.score-tag {
font-size: 0.55rem;
letter-spacing: 0.15em;
text-transform: uppercase;
padding: 0.2rem 0.5rem;
display: inline-block;
width: fit-content;
}
.tag-win { background: rgba(201,168,76,0.15); color: var(–gold); }
.tag-good { background: rgba(107,143,163,0.15); color: #6b8fa3; }
.tag-partial { background: rgba(255,255,255,0.05); color: var(–muted); }
.table-wrap { overflow-x: auto; margin: 3rem 0; }
table {
width: 100%;
border-collapse: separate;
border-spacing: 0 3px;
font-size: 0.8rem;
}
th {
padding: 1rem 1.5rem;
text-align: left;
font-size: 0.55rem;
letter-spacing: 0.3em;
text-transform: uppercase;
color: var(–muted);
background: rgba(255,255,255,0.02);
border-bottom: 1px solid rgba(255,255,255,0.06);
}
th.col-a { color: var(–gold); }
th.col-b { color: #6b8fa3; }
td {
padding: 1rem 1.5rem;
background: rgba(255,255,255,0.02);
vertical-align: middle;
transition: background 0.2s;
line-height: 1.5;
color: var(–cream);
}
td.topic { color: var(–muted); font-style: italic; font-family: ‘Cormorant Garamond’, serif; font-size: 1rem; }
.check { color: var(–gold); }
.cross { color: rgba(107,143,163,0.5); }
.partial { color: var(–muted); }
.verdict-section {
padding: 8rem 2rem;
position: relative;
overflow: hidden;
}
.verdict-bg {
position: absolute;
inset: 0;
background: radial-gradient(ellipse 100% 80% at 50% 50%, rgba(201,168,76,0.07) 0%, transparent 70%), var(–black);
pointer-events: none;
}
.verdict-inner {
max-width: 900px;
margin: 0 auto;
text-align: center;
position: relative;
z-index: 1;
}
.verdict-line {
width: 1px;
height: 80px;
background: linear-gradient(transparent, var(–gold));
margin: 0 auto 3rem;
}
.verdict-title {
font-family: ‘Playfair Display’, serif;
font-size: clamp(1rem, 2vw, 1.2rem);
font-weight: 400;
letter-spacing: 0.4em;
text-transform: uppercase;
color: var(–gold);
margin-bottom: 1.5rem;
}
.verdict-winner {
font-family: ‘Playfair Display’, serif;
font-size: clamp(3rem, 8vw, 6rem);
font-weight: 900;
line-height: 0.95;
background: linear-gradient(135deg, var(–gold) 0%, var(–amber) 50%, #fff8e8 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
margin-bottom: 1rem;
}
.verdict-subtitle {
font-family: ‘Cormorant Garamond’, serif;
font-size: clamp(1rem, 2vw, 1.3rem);
font-style: italic;
color: var(–muted);
max-width: 600px;
margin: 0 auto 4rem;
line-height: 1.7;
}
.final-scores {
display: grid;
grid-template-columns: 1fr auto 1fr;
gap: 2rem;
align-items: center;
margin: 4rem 0;
}
.final-score-card {
padding: 3rem;
text-align: center;
border: 1px solid;
position: relative;
overflow: hidden;
}
.final-score-card::before {
content: »;
position: absolute;
inset: 0;
opacity: 0.06;
}
.final-score-card.winner-card { border-color: rgba(201,168,76,0.5); }
.final-score-card.winner-card::before { background: radial-gradient(ellipse at center, var(–gold), transparent); }
.final-score-card.loser-card { border-color: rgba(107,143,163,0.3); }
.final-score-card.loser-card::before { background: radial-gradient(ellipse at center, #6b8fa3, transparent); }
.final-score-label {
font-size: 0.6rem;
letter-spacing: 0.3em;
text-transform: uppercase;
color: var(–muted);
margin-bottom: 1.5rem;
}
.final-score-name {
font-family: ‘Playfair Display’, serif;
font-size: 1rem;
font-style: italic;
margin-bottom: 2rem;
line-height: 1.4;
}
.winner-card .final-score-name { color: var(–cream); }
.loser-card .final-score-name { color: var(–muted); }
.final-score-num {
font-family: ‘Playfair Display’, serif;
font-size: 6rem;
font-weight: 900;
line-height: 1;
}
.winner-card .final-score-num {
background: linear-gradient(135deg, var(–gold), var(–amber));
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.loser-card .final-score-num { color: rgba(107,143,163,0.6); }
.final-score-of { font-size: 0.7rem; color: var(–muted); letter-spacing: 0.2em; margin-top: 0.5rem; }
.vs-divider {
font-family: ‘Playfair Display’, serif;
font-size: 2rem;
color: rgba(255,255,255,0.1);
text-align: center;
}
.insights-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 3px;
margin: 3rem 0;
}
.insight-card {
padding: 2.5rem;
background: rgba(255,255,255,0.02);
border: 1px solid rgba(255,255,255,0.05);
position: relative;
overflow: hidden;
transition: all 0.3s ease;
}
.insight-card:hover {
background: rgba(201,168,76,0.04);
border-color: rgba(201,168,76,0.2);
}
.insight-card::before {
content: »;
position: absolute;
left: 0; top: 0; bottom: 0;
width: 2px;
background: var(–gold);
transform: scaleY(0);
transform-origin: bottom;
transition: transform 0.4s ease;
}
.insight-card:hover::before { transform: scaleY(1); }
.insight-icon { font-size: 1.5rem; margin-bottom: 1rem; }
.insight-card h4 {
font-family: ‘Playfair Display’, serif;
font-size: 1rem;
color: var(–gold);
margin-bottom: 0.8rem;
}
.insight-card p {
font-family: ‘Cormorant Garamond’, serif;
font-size: 1rem;
color: var(–muted);
font-style: italic;
line-height: 1.6;
}
.closing {
padding: 6rem 2rem;
text-align: center;
border-top: 1px solid rgba(255,255,255,0.05);
}
.closing-quote {
font-family: ‘Cormorant Garamond’, serif;
font-size: clamp(1.2rem, 3vw, 2rem);
font-style: italic;
color: rgba(240,230,204,0.5);
max-width: 700px;
margin: 0 auto 3rem;
line-height: 1.6;
}
.closing-quote em { color: var(–gold); font-style: normal; }
.closing-credit {
font-size: 0.6rem;
letter-spacing: 0.3em;
text-transform: uppercase;
color: rgba(255,255,255,0.1);
}
.divider {
width: 100%;
height: 1px;
background: linear-gradient(90deg, transparent, rgba(201,168,76,0.2), transparent);
margin: 2rem 0;
}
@keyframes fadeInDown {
from { opacity: 0; transform: translateY(-20px); }
to { opacity: 1; transform: translateY(0); }
}
@keyframes fadeInUp {
from { opacity: 0; transform: translateY(30px); }
to { opacity: 1; transform: translateY(0); }
}
.reveal {
opacity: 0;
transform: translateY(40px);
transition: opacity 0.8s ease, transform 0.8s cubic-bezier(0.16, 1, 0.3, 1);
}
.reveal.visible { opacity: 1; transform: translateY(0); }
.reveal-delay-1 { transition-delay: 0.1s; }
.reveal-delay-2 { transition-delay: 0.2s; }
.reveal-delay-3 { transition-delay: 0.35s; }
.reveal-delay-4 { transition-delay: 0.5s; }
.winner-glow { animation: glow 3s ease-in-out infinite; }
@keyframes glow {
0%, 100% { box-shadow: 0 0 30px rgba(201,168,76,0.1), 0 0 60px rgba(201,168,76,0.05); }
50% { box-shadow: 0 0 50px rgba(201,168,76,0.2), 0 0 100px rgba(201,168,76,0.1); }
}
.particle {
position: fixed;
width: 1px;
height: 1px;
background: var(–gold);
border-radius: 50%;
pointer-events: none;
opacity: 0;
animation: float 15s ease-in-out infinite;
}
@keyframes float {
0% { opacity: 0; transform: translateY(100vh) translateX(0); }
10% { opacity: 0.4; }
90% { opacity: 0.1; }
100% { opacity: 0; transform: translateY(-100px) translateX(var(–drift)); }
}
@media (max-width: 768px) {
.docs-grid { grid-template-columns: 1fr; }
.doc-card.doc-a { border-right: 1px solid rgba(201,168,76,0.15); border-bottom: none; }
.criteria-item { grid-template-columns: 1.5rem 1fr; }
.criteria-score { display: none; }
.criteria-score:last-child { display: flex; }
.insights-grid { grid-template-columns: 1fr; }
.final-scores { grid-template-columns: 1fr; }
.vs-divider { display: none; }
.section-number { display: none; }
}
Prompts
Gastronómicos
con Inteligencia Artificial
Una evaluación rigurosa de dos investigaciones sobre generación de imágenes de comida hiperrealista — medida en cinco dimensiones científicas
Scroll
Cara a cara:
¿Qué se compara?
Investigación Profunda para Prompts de Comida Hiperrealista en IA
Un marco teórico-práctico exhaustivo que combina fundamentos ópticos, vocabulario técnico y guías por plataforma para producir imágenes gastronómicas fotorrealistas.
Fuentes citadas
Prompts listos
Plataformas
Guía SIMPLE para Generar Imágenes Gastronómicas Realistas con IA
Una guía práctica orientada a usuarios sin experiencia previa, con vocabulario descriptivo, ángulos, iluminación y ejemplos concretos de prompts funcionales.
Fuentes citadas
Prompts listos
Plataformas
Cinco dimensiones
científicas
Profundidad Conceptual
¿El documento explica el mecanismo causal o solo enumera? ¿Existe un marco teórico unificador?
Razonamiento causal ✓
Descripción plana
Evidencia y Citación
Calidad y cantidad de fuentes. Prioridad: documentación primaria de industria vs. blogs secundarios.
+60% fuentes primarias ✓
Fuentes secundarias
Cobertura Temática
Amplitud de temas: vocabulario, ángulos, luz, equipo, plataformas, anti-patterns, tendencias, GPT.
Multi-plataforma ✓
Sin diferenciación
Aplicabilidad Práctica
¿Los prompts son production-ready? ¿Diferencian por plataforma? ¿Hay framework reutilizable?
MJ + OpenAI + SD ✓
Sin parámetros
Rigor Metodológico
Corrección técnica sobre el comportamiento real de los modelos generativos de difusión.
Señales semánticas ✓
Cámaras = efecto directo ✗
¿Qué cubre
cada documento?
| Tema evaluado | Doc. A — Investigación Profunda | Doc. B — Guía Simple |
|---|---|---|
| Marco teórico unificador | ✓ Principio de credibilidad como base | — No existe |
| Vocabulario de texturas | ✓ Tabla con mecanismo causal | ✓ Tabla descriptiva |
| Ángulos y composición | ✓ Con justificación técnica | ✓ Descriptivo sin justificación |
| Iluminación (subsecciones) | ✓ 7 subsecciones detalladas | ◑ 4 subsecciones |
| Equipo fotográfico | ✓ Tabla por focal con contexto | ✓ Tabla similar |
| Parámetros por plataforma | ✓ MJ + OpenAI + SD separados | ✗ No diferenciado |
| Anti-patterns + checklist | ✓ Checklist de 5 puntos verificable | ◑ Solo lista de palabras |
| System prompt GPT especializado | ✓ Production-ready con I/O definido | ◑ Simplificado |
| Corrección técnica sobre modelos IA | ✓ Señal semántica vs. física real | ✗ Cámaras = efecto directo (incorrecto) |
| Tendencias 2024-2025 | ✓ Con fuentes de industria | ◑ Enumerativo sin respaldo |
Superior en las 5 de 5 dimensiones evaluadas, con diferencias que van desde +60% en fuentes primarias hasta rigor técnico genuino sobre el comportamiento real de los modelos generativos.
para Prompts Hiperrealistas
Gastronómicas con IA
Lo que esto
significa
Causalidad sobre descripción
El Documento A no solo dice qué funciona, sino por qué funciona a nivel óptico y semántico. Esa diferencia es fundamental para adaptar prompts a nuevas situaciones.
Diferenciación por plataforma
Ningún prompt funciona igual en Midjourney, DALL-E y Stable Diffusion. El Documento A es el único que aborda esta distinción crítica con ejemplos concretos.
Corrección técnica importa
Decir que una cámara tiene «efecto técnico directo» es incorrecto. Los modelos de difusión usan esos nombres como señales semánticas en el espacio latente, no como simuladores físicos.
El Documento B tiene valor
Para usuarios nuevos sin experiencia, la Guía Simple es un punto de entrada legítimo y bien organizado. Pero no es investigación profunda: es exactamente lo que su nombre dice.
«El realismo apetitoso no se logra haciendo la comida impecable;
se logra haciendo la escena creíble.»
window.addEventListener(‘scroll’, () => {
const scroll = window.scrollY;
const height = document.body.scrollHeight – window.innerHeight;
document.getElementById(‘progress’).style.width = (scroll / height * 100) + ‘%’;
});
const observer = new IntersectionObserver((entries) => {
entries.forEach(e => {
if (e.isIntersecting) {
e.target.classList.add(‘visible’);
e.target.querySelectorAll(‘.counter[data-target]’).forEach(animateCounter);
e.target.querySelectorAll(‘.score-bar[data-width]’).forEach(animateBar);
observer.unobserve(e.target);
}
});
}, { threshold: 0.15 });
document.querySelectorAll(‘.reveal’).forEach(el => observer.observe(el));
document.querySelectorAll(‘.criteria-item, .doc-card, .final-score-card’).forEach(item => {
const io = new IntersectionObserver((entries) => {
entries.forEach(e => {
if (e.isIntersecting) {
e.target.querySelectorAll(‘.score-bar[data-width]’).forEach(animateBar);
e.target.querySelectorAll(‘.counter[data-target]’).forEach(animateCounter);
io.unobserve(e.target);
}
});
}, { threshold: 0.3 });
io.observe(item);
});
function animateCounter(el) {
if (el.dataset.animated) return;
el.dataset.animated = true;
const target = parseInt(el.dataset.target);
const duration = 1800;
const start = performance.now();
function update(now) {
const elapsed = now – start;
const progress = Math.min(elapsed / duration, 1);
const eased = 1 – Math.pow(1 – progress, 4);
el.textContent = Math.round(eased * target);
if (progress { bar.style.width = bar.dataset.width + ‘%’; }, 100);
}
window.addEventListener(‘mousemove’, (e) => {
const x = (e.clientX / window.innerWidth – 0.5) * 20;
const y = (e.clientY / window.innerHeight – 0.5) * 20;
const lines = document.querySelector(‘.hero-bg-lines’);
if (lines) lines.style.transform = `translate(${x * 0.3}px, ${y * 0.3}px)`;
});