Completa antes de enviar
[nombre del servidor][nombre del negocio][servicio][distritos][teléfono][número][enlace o "ninguno"][dirección][horario de apertura][titulares y oferta][GTM-XXXXXXX][nombre de la cuenta]
En mi servidor de hosting de Opus Growth [nombre del servidor], crea una única página de campaña para el tráfico de Google Ads y Meta Ads, además de una página de privacidad. No hay formulario; los visitantes nos contactan por teléfono, WhatsApp o un enlace de reserva. Datos: negocio [nombre del negocio], servicio [servicio], zona [distritos], teléfono [teléfono], WhatsApp [número], enlace de reserva [enlace o "ninguno"], dirección [dirección], horario [horario de apertura], titulares del anuncio y oferta principal [titulares y oferta], contenedor de Tag Manager [GTM-XXXXXXX], cuenta de Google Ads [nombre de la cuenta], cuenta publicitaria de Meta [nombre de la cuenta].
Coherencia de mensaje (message match): el h1 repite la promesa del titular del anuncio con las mismas palabras (servicio, zona, oferta principal). No pongas en la página ninguna promesa que no esté en el anuncio, ni en el anuncio ninguna que no esté en la página. Si los titulares de Google y Meta difieren, usa el del anuncio que más gasta y sugiere cómo alinear el otro anuncio con la página. En salud, legal o finanzas, no prometas certezas ("garantizado", "100 %").
Estructura de la página: la barra superior contiene solo el nombre de la marca y un botón de llamada, sin menú, para que los visitantes no se distraigan. Hero: h1, una descripción de una frase, tres botones (Llamar ahora, Escribir por WhatsApp, Elegir hora), cuatro puntos breves de confianza debajo y una imagen. Después, el proceso en tres pasos, qué determina el precio (con la respuesta primero, si no publicas precios), preguntas frecuentes, una llamada a la acción final y un pie de página con nombre, dirección, teléfono y el enlace de privacidad. En móvil, fija una barra de dos botones (Llamar, WhatsApp) en la parte inferior de la pantalla y da al body un padding inferior de la misma altura para que nada quede oculto debajo ni se desplace. El enlace de WhatsApp usa wa.me con un mensaje prerrellenado. Mantén un aspecto sobrio y fiable: una sola familia tipográfica (por ejemplo General Sans, dos pesos), un solo color de acento y un botón de WhatsApp en verde oscuro con un contraste mínimo de 4,5:1 frente al texto blanco.
Reglas de movimiento y medición:
1. Movimiento ligero sin librerías: no cargues GSAP, Lenis ni Swiper. Transiciones de hover y pulsación en los botones; en las tarjetas de los pasos, una pequeña subida controlada por scroll que use solo transform, dentro de `@supports (animation-timeline: view())` y solo para visitantes que no pidan movimiento reducido. No uses opacity: en la demo, las tarjetas atenuadas bajo la pantalla fallaron el contraste y Accesibilidad bajó a 96. Nada en la primera pantalla empieza con una animación de entrada.
2. Carga la capa de medición como `assets/tag.js` con defer:
a. `window.dataLayer` y los valores por defecto de Consent Mode v2: ad_storage, ad_user_data, ad_personalization y analytics_storage en "denied", wait_for_update 500.
b. Da a cada enlace de acción data-conv="phone", "whatsapp" o "booking" y un data-conv-place con el nombre de su sección. Un único listener de clics los envía a dataLayer como `{event: "phone_click" | "whatsapp_click" | "booking_click", conv_place, page_path}`.
c. No pongas el snippet clásico de GTM en `<head>`; inyéctalo tras el evento load con requestIdleCallback, para que las etiquetas nunca retrasen el primer renderizado.
d. Añade una pequeña barra de consentimiento fija: Rechazar y Aceptar como botones del mismo peso, con la elección guardada en el navegador y enviada como actualización de consentimiento. En móvil queda por encima de la barra de acciones y lo bastante baja como para no tapar el botón principal del hero.
3. Tag Manager: primero muestra el estado actual con list_gtm_containers, list_gtm_triggers y gtm_workspace_status. Propón tres activadores de evento personalizado con create_gtm_trigger (phone_click, whatsapp_click, booking_click). Localiza en Google Ads la conversión de contacto y su valor send_to con list_conversion_actions y get_conversion_tags. Para que quien llama y además escribe no se cuente dos veces, propón vincular teléfono y WhatsApp a una única conversión "Clic de contacto" que se cuente una sola vez; si no existe, indica qué crearías y espera mi aprobación. Propón una etiqueta de conversión de Google Ads con create_gtm_tag (tag_type "sp"). Para Meta, localiza el píxel con list_meta_pixels; si el código base del píxel no está en el contenedor, propónlo como etiqueta de HTML personalizado en todas las páginas y, por separado, las etiquetas que envían `fbq('track','Contact')` en los clics y `fbq('track','Schedule')` en la reserva. Ejecuta cada herramienta primero con confirm=false, muestra la lista de cambios y créalos tras mi aprobación. Muestra primero publish_gtm_container con confirm=false, publica tras mi aprobación e indica la versión que se puede restaurar.
4. Plan de pruebas: escribe paso a paso cómo puedo ver en el modo de vista previa de GTM qué etiqueta se dispara con cada uno de los tres botones, y que no se escribe ninguna cookie publicitaria cuando se rechaza el consentimiento.
5. Después de añadir GTM y las etiquetas, ejecuta core_web_vitals de nuevo, porque las etiquetas pueden bajar la puntuación, y muestra la diferencia en una tabla. Para evitar que los bloqueadores de anuncios bloqueen la etiqueta de Google, previsualiza la ruta de medición propia (first-party) con site_tag_gateway y configúrala tras mi aprobación.
Configuración y trampas conocidas (cada una bajó una puntuación en las mediciones de la demo, no te las saltes):
1. Si ya hay un sitio en producción en el servidor, avísame primero, porque la configuración sobrescribe index.html y la carpeta assets. Previsualiza scaffold_site con confirm=false y llámalo con confirm=true tras mi aprobación. Después lee site_design_guide y site_seo_guide. Antes de escribir código, pon la dirección de diseño (tipografía, color, rejilla, elemento distintivo, lenguaje de movimiento y las librerías que NO se cargarán) en un breve ART.md fuera de assets y muéstramelo.
2. Compila Tailwind en lugar de cargarlo desde el CDN. Instálalo con site_run_command y background=true: `npm i -D tailwindcss@3`, seguido de site_command_status. Las rutas content de `tailwind.config.js` deben cubrir todos los archivos HTML, las plantillas y cualquier archivo JS que escriba nombres de clase. `_src/tw.css` contiene la línea `@import "../assets/app.css";` y las tres líneas `@tailwind`; compílalo en un único archivo con `npx tailwindcss -c tailwind.config.js -i _src/tw.css -o assets/site.css --minify`. Elimina el script cdn.tailwindcss.com y el tailwind.config en línea de todas las páginas y enlaza solo `/assets/site.css`. Vuelve a compilar tras cada cambio de HTML.
3. Aloja las fuentes tú mismo. Lee el CSS de las familias de Fontshare que elijas, descarga el archivo woff2 de cada peso en `assets/fonts/` con site_fetch y escribe las reglas @font-face con `font-display: swap` en `assets/app.css`; design-check busca ahí una fuente personalizada. Comprueba el nombre font-family en el CSS descargado, porque Fontshare puede devolver otra familia cuando un peso no existe. Precarga la fuente del encabezado de la primera pantalla y la del texto en todas las páginas con `<link rel="preload" as="font" type="font/woff2" crossorigin>`; en la demo esto eliminó el desplazamiento de diseño causado por el cambio de fuente (CLS de 0,024 a 0). La mayoría de las fuentes de Fontshare no tienen el glifo ₺, así que escribe "TL" en los precios.
4. Haz que el menú y el pie de página sean HTML estático. No cargues chrome.js ni site.config.js en las páginas. Escribe un pequeño `chrome-stamp.mjs` que lea la lista de navegación de site.config.js y estampe `_src/header.tpl` y `_src/footer.tpl` entre los marcadores `<!-- nav:start --><!-- nav:end -->` y `<!-- footer:start --><!-- footer:end -->` de cada página, añadiendo aria-current="page" al enlace actual. No des a las plantillas la extensión .html y usa marcadores como `[[NAV]]` en lugar de `{{...}}`, de lo contrario design-check y seo-check los leen como páginas sin terminar. Construye el menú móvil sin JS con `<details>`. Mantén el nombre del negocio, la dirección y el teléfono en el pie de página como texto plano.
5. Convierte las imágenes al descargarlas con site_fetch: escribe la misma foto en archivos separados con resize="480x", "800x" y "1200x", image_format="webp", quality=65. Da a cada `<img>` srcset, sizes, width y height. La imagen principal de la primera pantalla lleva fetchpriority="high" y nunca es lazy; las demás llevan loading="lazy" decoding="async". Si la imagen principal llena la pantalla del móvil, sirve un recorte más ancho y más ligero en móvil con `<picture>` (en la demo el hero móvil pasó de 89 KB a 43 KB).
6. Crea un favicon PNG de 48 px a partir del logotipo con site_fetch y añade `<link rel="icon">` a todas las páginas. Sin él, el navegador registra un 404 y Mejores prácticas baja a 96.
7. Reglas del validador de HTML: empieza cada documento con un `<!DOCTYPE html>` en mayúsculas (los archivos iniciales del kit lo traen en minúsculas), usa ` ` para los espacios en el texto visible de los enlaces tel:, no uses nunca un atributo style="" y da a cada botón type="button".
SEO, AEO y GEO:
1. Usa URL de directorio con barra final (/gizlilik/). Rellena el bloque seo de site.config.js y ejecuta `node seo-stamp.mjs`. Escribe el schema específico de cada página (en la página de campaña, WebPage, un Service vinculado a #business como provider con areaServed, y FAQPage; en la de privacidad, WebPage y BreadcrumbList. En site.config.js usa el subtipo de LocalBusiness más específico, por ejemplo HousePainter, Plumber, Dentist) en bloques `<script type="application/ld+json">` separados y vincúlalo al grafo base con @id. No entierres BreadcrumbList dentro de un @graph; dale su propio bloque, porque es la única forma de que seo-check lo detecte. La página de privacidad explica las cookies, las etiquetas de medición y cómo cambiar la elección de consentimiento.
2. Títulos de 48 a 60 caracteres (seo-check marca como error todo lo que pase de 65), descripciones de 145 a 158 caracteres, un único h1 por página. Cada página necesita al menos 150 palabras de contenido principal; las páginas de contacto y de privacidad suelen quedarse cortas.
3. El primer párrafo de cada página responde directamente a la pregunta de la página. Escribe unas preguntas frecuentes específicas de la página con `<details>` y márcalas como FAQPage. Muestra la organización editora y una fecha de "Última actualización" con `<time>`.
4. En robots.txt, escribe tu decisión con su motivo para GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-User, Claude-SearchBot, PerplexityBot, Perplexity-User, Google-Extended, Applebot-Extended, Bingbot y CCBot, y apunta al sitemap. sitemap.xml lleva fechas lastmod reales. llms.txt contiene un resumen fiel de dos frases del sitio y la lista de páginas clave.
5. No inventes nada: ni reseñas, ni valoraciones, ni premios, ni cifras de clientes, ni certificados, ni horarios, ni coordenadas, ni precios, salvo que yo te los dé. Deja fuera del schema los campos desconocidos.
Controles de calidad (en orden; no lo des por terminado hasta que todos pasen):
1. Con site_run_command ejecuta `node chrome-stamp.mjs`, la compilación de Tailwind, `node seo-stamp.mjs`, `node seo-check.mjs` (0 errores, 0 advertencias), `node design-check.mjs` (0 errores; justifica cualquier advertencia que quede) y `npx html-validate "**/*.html"` (0 errores).
2. Revisa cada página con site_preview, view="mobile" y view="desktop". site_preview captura la página con el movimiento desactivado (reduced-motion), así que si falta contenido en esa imagen, el estado sin movimiento está roto. En las capturas de página completa, las imágenes lazy más abajo pueden aparecer vacías; no es un error, pero comprueba sus rutas.
3. Ejecuta core_web_vitals para cada página con strategy="mobile" y strat