Completa antes de enviar
[nombre del servidor][nombre del producto][qué hace y para quién, en una frase][seis funciones, una frase cada una][enlaces a tres capturas y qué muestra cada una][archivos de logos o "ninguno"][testimonio aprobado, nombre, cargo, empresa o "ninguno"][razón social][dirección][teléfono][email][número de WhatsApp]
En el sitio [nombre del servidor] de mi servidor de hosting de Opus Growth, crea un sitio de marketing estático y rápido para mi software [nombre del producto] que se sienta como las plantillas SaaS modernas de Webflow, sin usar Webflow. Producto: [qué hace y para quién, en una frase]. Funciones principales: [seis funciones, una frase cada una]. Capturas de la app: [enlaces a tres capturas y qué muestra cada una]. Planes: [nombres de los planes, precios mensuales y anuales, si incluyen IVA, qué incluye cada plan]. Logos de clientes que tengo permiso por escrito para mostrar: [archivos de logos o "ninguno"]. Testimonios de clientes: [testimonio aprobado, nombre, cargo, empresa o "ninguno"]. Empresa: [razón social], [dirección], [teléfono], [email], [número de WhatsApp]. Vía de registro o demo: [URL de la página de registro o "demos por WhatsApp y email"]. Dominio: [dominio].
Páginas: inicio (hero con captura del producto, franja de logos, cuadrícula bento de funciones, muestra de producto con pestañas, testimonios, FAQ, llamada a la acción final), funciones (/ozellikler/, cada función con su propio encabezado y ancla), precios (/fiyatlar/: selector, tarjetas de planes, tabla comparativa, FAQ de facturación), contacto (/iletisim/, sin formulario; email, WhatsApp con mensaje prellenado y teléfono), privacidad (/gizlilik/) y 404.html.
Estilo: SaaS moderno de fondo claro. Si no se indica [preferencia de color], fondo blanco roto cálido, texto negro tinta y un único acento vivo (usado solo como fondo, con texto oscuro encima). Dos pesos de una misma familia de Fontshare (por ejemplo Satoshi 400 y 700). Teselas bento grandes y redondeadas, botones tipo píldora, la captura del producto dentro de un marco de ventana oscuro. Sin degradados de morado a azul y sin efecto cristal en todas partes.
Reglas de interacción (interacciones de Webflow sin librería):
1. NO se cargan GSAP, Lenis ni Swiper. Escribe las interacciones en CSS más un único archivo de JS puro de como máximo 3 KB, cargado con defer solo en la página de inicio. El selector de precios no necesita script.
2. Cuadrícula bento: una cuadrícula CSS de 4 columnas en escritorio, una tesela de 2x2 y dos teselas de 2 columnas de ancho, dispuestas de modo que no quede ninguna celda vacía; una columna en móvil. Cada tesela lleva un enlace real al encabezado correspondiente de la página de funciones y toda la tesela es clicable: dale al enlace un ::after con inset:0 (stretched link) y no pongas un segundo enlace en la tesela. Al pasar el cursor y con :focus-within el borde se oscurece, la tesela sube 4 píxeles con transform y el pequeño fragmento de interfaz de su interior se mueve (una lista de pasos se desliza hacia un lado, las barras crecen con scaleY).
3. La franja de logos usa solo logos de clientes que dieron permiso por escrito; si no hay ninguno, omite la sección y no la sustituyas por logos ficticios ni por una lista inventada de "integraciones". La franja son dos copias de la misma lista (la segunda con aria-hidden="true") que se mueven con un @keyframes translate3d(-50%, 0, 0); se pausa al pasar el cursor y al enfocar. Como el movimiento dura más de cinco segundos, WCAG 2.2.2 exige un botón "Pausar franja": el botón está oculto en el HTML, el JS lo muestra y actualiza aria-pressed y su etiqueta. Dale a la fila que contiene el botón un min-height igual a la altura del botón; en la demo la fila crecía al aparecer el botón y se midió un pequeño desplazamiento (CLS 0,002) en escritorio. Con prefers-reduced-motion la animación se detiene, la copia se oculta y los logos pasan a ser una cuadrícula estática con salto de línea.
4. Muestra de producto con pestañas: en el HTML las pestañas son enlaces internos a los paneles (href="#ekran-x") y los tres paneles se ven uno debajo del otro, de modo que el contenido está completo con JS desactivado y para los rastreadores. Dale al contenedor de pestañas role="group" y un aria-label. El JS las convierte en role="tablist", "tab" y "tabpanel", gestiona aria-selected, aria-controls, tabindex y hidden, admite las flechas izquierda y derecha, Inicio y Fin, y selecciona la pestaña correspondiente cuando la página se abre con #ekran-x. Los paneles quedan bajo la primera pantalla, así que ocultarlos no causa desplazamiento de diseño; las imágenes de los paneles usan loading="lazy".
5. El selector de precios funciona sin JS: dos botones de radio dentro de un fieldset (Mensual marcado por defecto) y reglas como `.pricing:has(#donem-yillik:checked) .price-m { display: none }` que muestran los precios anuales. Oculta el radio visualmente pero mantén toda la etiqueta clicable y enfocable con teclado; muestra el anillo de foco con `label:has(input:focus-visible)`. En la vista mensual cada plan muestra una línea "Facturado anualmente: X TL", de modo que ambos precios existen en el texto.
6. Los testimonios de clientes provienen solo de testimonios aprobados que se puedan verificar por nombre, cargo y empresa. Si no tienes ninguno, elimina la sección; si usas uno durante el borrador, hazlo una tarjeta de marcador con borde discontinuo que diga que se rellenará cuando llegue un testimonio real, y pregúntame antes de publicar. No escribas schema Review ni aggregateRating.
7. La captura del producto del hero es el elemento LCP en escritorio: fetchpriority="high", sin lazy, con sizes que indique su ancho real. En móvil el LCP suele ser el texto del encabezado; la captura debe cargar igualmente su versión de 480 píxeles mediante srcset.
Schema: SoftwareApplication en las páginas de inicio y precios (name, applicationCategory "BusinessApplication", operatingSystem, url, image, publisher y una Offer por plan y periodo de facturación: name, price, priceCurrency "TRY", url). Google exige una valoración o reseña para el resultado enriquecido de aplicación de software; sin reseñas genuinas recogidas en tu propio sitio no aparecerán estrellas, y eso no debe resolverse con una valoración inventada. FAQPage en las páginas de inicio, funciones y precios, ContactPage en contacto, BreadcrumbList en las páginas interiores. El primer párrafo de la página de precios responde directamente: "Los precios de [nombre del producto] empiezan en N TL al mes". La tabla comparativa es una `<table>` real y se desplaza horizontalmente en pantallas estrechas dentro de `<section tabindex="0" aria-label="...">`; en la demo un div con role="region" provocó prefer-native-element, y dos secciones etiquetadas con el mismo encabezado provocaron unique-landmark.
Configuración y errores conocidos (cada uno restó puntos en las mediciones de la demo, no te saltes ninguno):
1. Si ya hay un sitio activo 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 solo después de que yo lo apruebe. Luego lee site_design_guide y site_seo_guide. Antes de escribir código, pon la dirección de diseño (tipografía, colores, cuadrícula, elemento distintivo, lenguaje de movimiento y las librerías que NO se cargarán) en un breve archivo ART.md fuera de assets y muéstramelo.
2. Compila Tailwind, no lo cargues desde el CDN. Instálalo con site_run_command y background=true (`npm i -D tailwindcss@3`) y haz seguimiento con site_command_status. Las rutas content de `tailwind.config.js` deben cubrir todos los archivos HTML, las plantillas de `_src` y cualquier archivo JS que escriba clases. `_src/tw.css` contiene la línea `@import "../assets/app.css";` más 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`. Recompila tras cada cambio de HTML.
3. Aloja las fuentes tú mismo. Lee el CSS de la familia Fontshare elegida, descarga el woff2 de cada peso por separado con site_fetch en `assets/fonts/` y escribe las reglas @font-face con `font-display: swap` en `assets/app.css`, que es donde design-check busca una fuente personalizada. Comprueba el nombre font-family en el CSS descargado y confirma que la familia tiene las letras turcas ı, İ, ş y ğ (Tanker no tiene ı). Haz preload de TODOS los pesos usados en la primera pantalla con `<link rel="preload" as="font" type="font/woff2" crossorigin>`, colocado antes de la línea de la hoja de estilos; si son más de tres archivos, usa menos pesos. En la demo, un único peso de cuerpo sin preload llevó el LCP móvil a 2,6 segundos y Performance a 97. La mayoría de las fuentes de Fontshare no tienen el signo ₺, así que escribe los precios con "TL".
4. Haz el menú y el pie de página en HTML estático. No cargues chrome.js, motion.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 -->` en cada página, añadiendo aria-current="page" al enlace activo. Usa marcadores como `[[NAV]]` en lugar de `{{...}}` y no des a las plantillas extensión .html, de lo contrario design-check y seo-check las tratan como páginas a medio hacer. Construye el menú móvil con un `<details>` sin JS. Mantén el nombre del negocio, la dirección y el teléfono como texto plano en el pie de página, y haz que los enlaces del pie y de las migas de pan midan al menos 44 píxeles de alto.
5. Convierte las imágenes al descargarlas con site_fetch: escribe la misma imagen como archivos separados con resize="480x", "800x" y "1200x", image_format="webp", quality=60 (site_fetch no recorta, así que pide el original con la proporción que necesites). Da a cada `<img>` srcset, sizes y width y height acordes a la proporción real. La imagen que es el elemento LCP de la página lleva fetchpriority="high" y no es lazy; las demás imágenes llevan loading="lazy" decoding="async". Si una imagen llena la primera pantalla móvil, sirve un recorte más pequeño a móvil con `<picture>`.
6. Añade `<link rel="icon" href="/favicon.svg" type="image/svg+xml">` a cada página y crea un apple-touch-icon de 180 píxeles a partir del logo con site_fetch y resize="180x180". Sin enlace de favicon el navegador solicita /favicon.ico, registra un 404 y Best Practices baja a 96.
7. Reglas del validador HTML: empieza cada documento con un `<!DOCTYPE html>` en mayúsculas; cada espacio en el texto visible de un enlace tel: debe ser ` `, incluido el que sigue a un prefijo como "Llama: 0212..."; no uses style=""; da a cada botón un type; pon aria-label solo en landmarks, formularios o elementos interactivos (en un ul o en un div sin rol fue un error); nunca etiquetes dos landmarks con el mismo nombre; no dejes espacios al final de las líneas.
8. No te saltes niveles de encabezado: en una página de listado, títulos de tarjeta como h3 justo después del h1 bajaron Accessibility a 98. Al reutilizar una tarjeta, fija su nivel de encabezado por página (h2 en una página de listado, h3 dentro de una sección h2).
9. Llama al atributo de movimiento data-reveal (design-check solo reconoce el movimiento con ese nombre). El JS aplica el estado inicial oculto solo a los bloques que están bajo la pantalla cuando se abre la página, y nunca oculta contenido de la primera pantalla; usa transform, porque el fundido con opacity reduce la auditoría de contraste. Pon el atributo en el bloque que envuelve un encabezado y su descripción, no solo en el encabezado; en la demo un encabezado en espera se deslizó sobre el párrafo de debajo. Con prefers-reduced-motion: reduce no se oculta nada y las animaciones se desactivan.
SEO, AEO y GEO:
1. Usa URL con estilo de directorio y barra final. Rellena el bloque seo de site.config.js y ejecuta `node seo-stamp.mjs`. Escribe el schema específico de cada página en bloques `<script type="application/ld+json">` separados, vinculados al grafo base mediante @id. No anides BreadcrumbList dentro de @graph; mantenlo en su propio bloque, que es la única forma de que seo-check lo vea.
2. Títulos de como máximo 60 caracteres (seo-check marca como error todo lo que tenga menos de 25 o más de 65), descripciones de 130 a 158 caracteres, un h1 por página y al menos 150 palabras de contenido principal en cada página. Las páginas de contacto, privacidad y listados tienden a quedarse cortas; añade información específica de la página, no relleno.
3. El primer párrafo de cada página responde directamente a la pregunta de la página. Escribe FAQ específicas de cada página con `<details>` y márcalas como FAQPage. Muestra el publisher y una fecha de "Última actualización" en un elemento `<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 exacto del sitio en dos frases y una lista de las páginas importantes.
5. Sin invenciones: no escribas reseñas, valoraciones, premios, cifras de clientes, certificados, horarios, coordenadas ni precios sin preguntarme. Deja fuera del schema cualquier campo que no conozcas.
Puertas de control (en orden; no digas "listo" hasta que todas 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); si falta contenido en esa captura, el estado estático está roto. En las capturas de página completa, elementos fijos como una barra sticky pueden aparecer a mitad de página y las imágenes lazy más abajo pueden salir en blanco; no los cuentes como errores, pero comprueba sus rutas.
3. Ejecuta core_web_vitals para cada página con strategy="mobile" y strategy="desktop". Criterio de aceptación: en móvil Performance de al menos 95 (objetivo 99 a 100) y Accessibility, Best Practices y SEO en 100; en escritorio los cuatro en 100. Para una página que no llegue, usa resources=true para encontrar el archivo que la retrasa, corrígelo y vuelve a medir. Después ejecuta seo_audit en la página de inicio con strategy="mobile" y runs=2. No debe quedar ninguna dirección fuera de tu propio dominio en la lista de peticiones de red.
4. Sin desplazamiento horizontal a 360, 390, 768 y 1440 píxeles de ancho, áreas táctiles de al menos 44 píxeles, sin errores en la consola.
Comprobación de interacciones: site_preview no puede mostrar hover ni movimiento. Dime cómo comprobar en un navegador de escritorio que las teselas bento suben al pasar el cursor y al enfocar con Tab, que el botón "Pausar franja" detiene la franja, que las pestañas cambian con las flechas del teclado, que el selector de precios muestra los precios anuales incluso con JavaScript desactivado, y que en un móvil con movimiento reducido los logos pasan a ser una cuadrícula estática.
Tras publicar: previsualiza con site_headers la regla `/assets/* Cache-Control: public, max-age=31536000, immutable` y aplícala cuando yo lo apruebe; a partir de ahí, versiona el nombre del archivo cada vez que cambien el CSS o el JS (site-v2.css, etc.). Envía sitemap.xml con gsc_submit_sitemap y comprueba la página de inicio con gsc_url_inspect. Al final entrégame: una tabla de puntuaciones por página (página, cuatro puntuaciones móvil, cuatro puntuaciones escritorio, LCP, CLS), el resultado de cada puerta de control y la lista de correcciones que aplicaste.