Vor dem Senden ausfüllen
[server name][product name][what it does and for whom, one sentence][six features, one sentence each][links to three screenshots and what each one shows][logo files or "none"][approved quote, name, title, company or "none"][legal name][address][phone][email][WhatsApp number]
Baue auf der Seite [server name] auf meinem Opus Growth Hosting-Server eine statische, schnelle Marketingseite für mein Softwareprodukt [product name], die sich wie die modernen SaaS-Templates auf Webflow anfühlt, ohne Webflow zu verwenden. Produkt: [what it does and for whom, one sentence]. Wichtigste Funktionen: [six features, one sentence each]. App-Screenshots: [links to three screenshots and what each one shows]. Tarife: [plan names, monthly and yearly prices, whether VAT is included, what each plan includes]. Kundenlogos, für die ich eine schriftliche Erlaubnis zur Anzeige habe: [logo files or "none"]. Kundenzitate: [approved quote, name, title, company or "none"]. Unternehmen: [legal name], [address], [phone], [email], [WhatsApp number]. Anmelde- oder Demo-Weg: [sign-up page URL or "demo requests by WhatsApp and email"]. Domain: [domain].
Seiten: Startseite (Hero mit Produkt-Screenshot, Logo-Streifen, Bento-Feature-Grid, Produkt-Showcase mit Tabs, Kundenzitate, FAQ, abschließender Call-to-Action), Funktionen (/ozellikler/, jede Funktion mit eigener Überschrift und eigenem Anker), Preise (/fiyatlar/: Umschalter, Tarifkarten, Vergleichstabelle, FAQ zur Abrechnung), Kontakt (/iletisim/, ohne Formular; E-Mail, WhatsApp mit vorausgefüllter Nachricht und Telefon), Datenschutz (/gizlilik/) und 404.html.
Stil: moderner SaaS-Look auf hellem Hintergrund. Wenn keine [colour preference] angegeben ist: warmer Off-White-Hintergrund, tintenschwarzer Text und eine einzige leuchtende Akzentfarbe (nur als Hintergrund, mit dunklem Text darauf). Zwei Schnitte einer Fontshare-Schriftfamilie (zum Beispiel Satoshi 400 und 700). Große, abgerundete Bento-Kacheln, Pill-Buttons, der Produkt-Screenshot in einem dunklen Fensterrahmen. Keine Violett-zu-Blau-Verläufe und kein Glas-Effekt überall.
Interaktionsregeln (Webflow-Interaktionen ohne Bibliothek):
1. GSAP, Lenis und Swiper werden NICHT geladen. Schreibe die Interaktionen in CSS plus eine einzige Vanilla-JS-Datei von höchstens 3 KB, die nur auf der Startseite mit defer geladen wird. Der Preisumschalter braucht kein Skript.
2. Bento-Grid: ein CSS-Grid mit 4 Spalten auf dem Desktop, eine Kachel 2x2 und zwei Kacheln 2 Spalten breit, so angeordnet, dass keine Zelle leer bleibt; eine Spalte auf dem Smartphone. Jede Kachel enthält einen echten Link zur passenden Überschrift auf der Funktionen-Seite, und die ganze Kachel ist klickbar: Gib dem Link ein ::after mit inset:0 (Stretched Link) und setze keinen zweiten Link in die Kachel. Bei Hover und :focus-within wird der Rand dunkler, die Kachel hebt sich per transform um 4 Pixel an und das kleine UI-Fragment darin bewegt sich (eine Schrittliste gleitet zur Seite, Balken wachsen mit scaleY).
3. Der Logo-Streifen verwendet nur Logos von Kunden, die schriftlich zugestimmt haben; gibt es keine, lass den Abschnitt weg und ersetze ihn weder durch fiktive Logos noch durch eine erfundene „Integrationen“-Liste. Der Streifen besteht aus zwei Kopien derselben Liste (die zweite mit aria-hidden="true"), die sich per CSS-@keyframes translate3d(-50%, 0, 0) bewegen; bei Hover und Fokus pausiert er. Da die Bewegung länger als fünf Sekunden dauert, verlangt WCAG 2.2.2 einen Button „Streifen anhalten“: Der Button ist im HTML verborgen, JS blendet ihn ein und aktualisiert aria-pressed sowie sein Label. Gib der Zeile, die den Button enthält, eine min-height in Höhe des Buttons; in der Demo wuchs die Zeile beim Erscheinen des Buttons, und auf dem Desktop wurde eine kleine Verschiebung (CLS 0,002) gemessen. Bei prefers-reduced-motion stoppt die Animation, die Kopie wird ausgeblendet und die Logos werden zu einem statischen, umbrechenden Raster.
4. Produkt-Showcase mit Tabs: Im HTML sind die Tabs In-Page-Links zu den Panels (href="#ekran-x"), und alle drei Panels stehen sichtbar untereinander, sodass der Inhalt bei ausgeschaltetem JS und für Crawler vollständig ist. Gib dem Tab-Container role="group" und ein aria-label. JS macht daraus role="tablist", "tab" und "tabpanel", verwaltet aria-selected, aria-controls, tabindex und hidden, unterstützt die Pfeiltasten links und rechts sowie Pos1 und Ende und wählt den passenden Tab, wenn die Seite mit #ekran-x geöffnet wird. Die Panels liegen unterhalb des ersten Bildschirms, ihr Ausblenden verursacht also keinen Layout-Shift; Panel-Bilder nutzen loading="lazy".
5. Der Preisumschalter funktioniert ohne JS: zwei Radio-Buttons in einem fieldset (Monatlich standardmäßig gewählt) und Regeln wie `.pricing:has(#donem-yillik:checked) .price-m { display: none }`, die die Jahrespreise einblenden. Blende das Radio visuell aus, lass aber das gesamte Label klickbar und per Tastatur fokussierbar; zeige den Fokusring mit `label:has(input:focus-visible)`. In der Monatsansicht zeigt jeder Tarif eine Zeile „Jährlich abgerechnet: X TL“, sodass beide Preise im Text vorkommen.
6. Kundenzitate stammen nur aus freigegebenen Zitaten, die sich anhand von Name, Funktion und Unternehmen überprüfen lassen. Gibt es keine, entferne den Abschnitt; wenn du während der Entwurfsphase eines verwendest, mache daraus eine gestrichelte Platzhalterkarte mit dem Hinweis, dass sie befüllt wird, sobald ein echtes Zitat vorliegt, und frage mich vor der Veröffentlichung. Schreibe kein Review- oder aggregateRating-Schema.
7. Der Hero-Produkt-Screenshot ist das LCP-Element auf dem Desktop: fetchpriority="high", nicht lazy, mit sizes in seiner tatsächlichen Breite. Auf dem Smartphone ist das LCP meist der Überschriftentext; der Screenshot soll trotzdem per srcset seine 480-Pixel-Version laden.
Schema: SoftwareApplication auf Start- und Preisseite (name, applicationCategory "BusinessApplication", operatingSystem, url, image, publisher und ein Offer pro Tarif und Abrechnungszeitraum: name, price, priceCurrency "TRY", url). Google verlangt für das Rich Result der Software-App eine Bewertung oder ein Review; ohne echte, auf der eigenen Seite gesammelte Bewertungen erscheinen keine Sterne, und das darf nicht mit einer erfundenen Bewertung gelöst werden. FAQPage auf Start-, Funktionen- und Preisseite, ContactPage auf der Kontaktseite, BreadcrumbList auf den Unterseiten. Der erste Absatz der Preisseite beantwortet direkt: „Die Preise von [product name] beginnen bei N TL pro Monat“. Die Vergleichstabelle ist eine echte `<table>` und scrollt auf schmalen Bildschirmen innerhalb von `<section tabindex="0" aria-label="...">` seitwärts; in der Demo löste ein div mit role="region" prefer-native-element aus, und zwei Sections, die von derselben Überschrift beschriftet wurden, lösten unique-landmark aus.
Einrichtung und bekannte Stolperfallen (jede einzelne hat in den Demo-Messungen Punkte gekostet, keine auslassen):
1. Läuft auf dem Server bereits eine Seite, sag mir das zuerst, denn die Einrichtung überschreibt index.html und den Ordner assets. Zeige scaffold_site mit confirm=false als Vorschau und rufe es erst nach meiner Freigabe mit confirm=true auf. Lies danach site_design_guide und site_seo_guide. Bevor du Code schreibst, halte die Design-Richtung (Typografie, Farben, Raster, Signature-Element, Bewegungssprache und die Bibliotheken, die NICHT geladen werden) in einer kurzen Datei ART.md außerhalb von assets fest und zeige sie mir.
2. Kompiliere Tailwind, lade es nicht über das CDN. Installiere es mit site_run_command und background=true (`npm i -D tailwindcss@3`) und prüfe anschließend mit site_command_status. Die content-Pfade in `tailwind.config.js` müssen jede HTML-Datei, die `_src`-Templates und jede JS-Datei abdecken, die Klassen schreibt. `_src/tw.css` enthält die Zeile `@import "../assets/app.css";` plus die drei `@tailwind`-Zeilen; kompiliere sie mit `npx tailwindcss -c tailwind.config.js -i _src/tw.css -o assets/site.css --minify` in eine einzige Datei. Entferne das Skript cdn.tailwindcss.com und die Inline-tailwind.config aus jeder Seite und verlinke nur `/assets/site.css`. Kompiliere nach jeder HTML-Änderung neu.
3. Hoste die Schriften selbst. Lies das CSS der gewählten Fontshare-Familie, lade das woff2 jedes Schnitts einzeln mit site_fetch nach `assets/fonts/` herunter und schreibe die @font-face-Regeln mit `font-display: swap` in `assets/app.css`, denn dort sucht design-check nach einer eigenen Schrift. Prüfe den font-family-Namen im heruntergeladenen CSS und vergewissere dich, dass die Familie die türkischen Buchstaben ı, İ, ş und ğ enthält (Tanker hat kein ı). Preloade JEDEN im ersten Bildschirm genutzten Schnitt mit `<link rel="preload" as="font" type="font/woff2" crossorigin>`, platziert vor der Stylesheet-Zeile; sind es mehr als drei Dateien, nimm weniger Schnitte. In der Demo hat ein einziger nicht vorgeladener Body-Schnitt das mobile LCP auf 2,6 Sekunden und die Performance auf 97 gedrückt. Die meisten Fontshare-Schriften haben kein ₺-Zeichen, schreibe Preise daher mit „TL“.
4. Mach Menü und Footer zu statischem HTML. Lade chrome.js, motion.js und site.config.js nicht auf den Seiten. Schreibe ein kleines `chrome-stamp.mjs`, das die Navigationsliste aus site.config.js liest und `_src/header.tpl` und `_src/footer.tpl` auf jeder Seite zwischen die Marker `<!-- nav:start --><!-- nav:end -->` und `<!-- footer:start --><!-- footer:end -->` stempelt und dem aktiven Link aria-current="page" hinzufügt. Verwende Platzhalter wie `[[NAV]]` statt `{{...}}` und gib den Templates keine .html-Endung, sonst behandeln design-check und seo-check sie als unfertige Seiten. Baue das mobile Menü mit einem JS-freien `<details>`. Lass Firmenname, Adresse und Telefon als reinen Text im Footer stehen und mache Footer- und Breadcrumb-Links mindestens 44 Pixel hoch.
5. Konvertiere Bilder schon beim Abruf mit site_fetch: Schreibe dasselbe Bild als getrennte Dateien mit resize="480x", "800x" und "1200x", image_format="webp", quality=60 (site_fetch beschneidet nicht, fordere die Quelle also im benötigten Seitenverhältnis an). Gib jedem `<img>` srcset, sizes sowie width und height passend zum tatsächlichen Seitenverhältnis. Das Bild, das das LCP-Element der Seite ist, bekommt fetchpriority="high" und ist nicht lazy; jedes andere Bild bekommt loading="lazy" decoding="async". Füllt ein Bild den ersten mobilen Bildschirm, liefere dem Smartphone mit `<picture>` einen kleineren Zuschnitt.
6. Füge jeder Seite `<link rel="icon" href="/favicon.svg" type="image/svg+xml">` hinzu und erstelle mit site_fetch und resize="180x180" aus dem Logo ein apple-touch-icon mit 180 Pixeln. Ohne Favicon-Link fragt der Browser /favicon.ico an, protokolliert einen 404 und Best Practices fällt auf 96.
7. Regeln des HTML-Validators: Beginne jedes Dokument mit einem großgeschriebenen `<!DOCTYPE html>`; jedes Leerzeichen im sichtbaren Text eines tel:-Links muss ` ` sein, auch das nach einem Präfix wie „Anrufen: 0212...“; verwende kein style=""; gib jedem Button ein type; setze aria-label nur auf Landmarks, Formulare oder interaktive Elemente (auf einem ul oder einem div ohne Rolle war es ein Fehler); beschrifte niemals zwei Landmarks mit demselben Namen; lass keine nachgestellten Leerzeichen stehen.
8. Überspringe keine Überschriftenebenen: Auf einer Listenseite haben Kartentitel als h3 direkt nach dem h1 die Accessibility auf 98 gedrückt. Wenn du eine Karte wiederverwendest, lege die Überschriftenebene pro Seite fest (h2 auf einer Listenseite, h3 innerhalb eines h2-Abschnitts).
9. Nenne das Bewegungsattribut data-reveal (design-check erkennt Bewegung nur unter diesem Namen). JS setzt den versteckten Ausgangszustand nur bei Blöcken, die beim Öffnen der Seite unterhalb des Bildschirms liegen, und blendet niemals Inhalte des ersten Bildschirms aus; verwende transform, denn ein Einblenden per opacity senkt das Kontrast-Audit. Setze das Attribut auf den Block, der eine Überschrift und ihre Beschreibung umschließt, nicht nur auf die Überschrift; in der Demo glitt eine wartende Überschrift über den Absatz darunter. Bei prefers-reduced-motion: reduce wird nichts versteckt und Animationen sind aus.
SEO, AEO und GEO:
1. Verwende Verzeichnis-URLs mit abschließendem Schrägstrich. Befülle den seo-Block von site.config.js und führe `node seo-stamp.mjs` aus. Schreibe seitenspezifisches Schema in getrennte `<script type="application/ld+json">`-Blöcke, die über @id mit dem Basis-Graph verbunden sind. Verschachtele BreadcrumbList nicht in @graph; halte sie in einem eigenen Block, nur so sieht seo-check sie.
2. Titel höchstens 60 Zeichen (seo-check meldet alles unter 25 oder über 65 als Fehler), Beschreibungen 130 bis 158 Zeichen, ein h1 pro Seite und mindestens 150 Wörter Hauptinhalt auf jeder Seite. Kontakt-, Datenschutz- und Listenseiten fallen oft zu kurz aus; ergänze seitenspezifische Informationen, keinen Füllstoff.
3. Der erste Absatz jeder Seite beantwortet die Frage der Seite direkt. Schreibe seitenspezifische FAQs mit `<details>` und zeichne sie als FAQPage aus. Zeige den Herausgeber und ein Datum „Zuletzt aktualisiert“ in einem `<time>`-Element.
4. Schreibe in robots.txt deine Entscheidung mit Begründung für GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-User, Claude-SearchBot, PerplexityBot, Perplexity-User, Google-Extended, Applebot-Extended, Bingbot und CCBot und verweise auf die Sitemap. sitemap.xml enthält echte lastmod-Daten. llms.txt enthält eine zutreffende Zusammenfassung der Seite in zwei Sätzen und eine Liste der wichtigen Seiten.
5. Keine Erfindungen: Schreibe keine Bewertungen, Ratings, Auszeichnungen, Kundenzahlen, Zertifikate, Öffnungszeiten, Koordinaten oder Preise, ohne mich zu fragen. Lass jedes Feld, das du nicht kennst, ganz aus dem Schema weg.
Gates (der Reihe nach; sage erst „fertig“, wenn alle bestanden sind):
1. Führe mit site_run_command `node chrome-stamp.mjs`, den Tailwind-Build, `node seo-stamp.mjs`, `node seo-check.mjs` (0 Fehler, 0 Warnungen), `node design-check.mjs` (0 Fehler; begründe jede verbleibende Warnung) und `npx html-validate "**/*.html"` (0 Fehler) aus.
2. Sieh dir jede Seite mit site_preview an, view="mobile" und view="desktop". site_preview erfasst die Seite mit ausgeschalteter Bewegung (reduced-motion); fehlen in dieser Aufnahme Inhalte, ist der statische Zustand defekt. In Full-Page-Aufnahmen können feste Elemente wie eine Sticky-Leiste mitten auf der Seite erscheinen und weiter unten liegende Lazy-Bilder leer sein; werte das nicht als Fehler, prüfe aber ihre Pfade.
3. Führe core_web_vitals für jede Seite mit strategy="mobile" und strategy="desktop" aus. Abnahmekriterium: auf dem Smartphone Performance mindestens 95 (Ziel 99 bis 100) und Accessibility, Best Practices und SEO 100; auf dem Desktop alle vier 100. Finde bei einer Seite, die das verfehlt, mit resources=true die Datei, die sie verzögert, behebe das Problem und miss erneut. Führe danach seo_audit auf der Startseite mit strategy="mobile" und runs=2 aus. In der Liste der Netzwerkanfragen darf keine Adresse außerhalb deiner eigenen Domain verbleiben.
4. Kein horizontales Scrollen bei 360, 390, 768 und 1440 Pixel Breite, Touch-Ziele mindestens 44 Pixel, keine Konsolenfehler.
Interaktionsprüfung: site_preview kann weder Hover noch Bewegung zeigen. Sag mir, wie ich in einem Desktop-Browser prüfe, dass sich die Bento-Kacheln bei Hover und Tab-Fokus anheben, dass der Button „Streifen anhalten“ den Streifen stoppt, dass die Tabs mit den Pfeiltasten wechseln, dass der Preisumschalter auch bei ausgeschaltetem JavaScript die Jahrespreise zeigt und dass die Logos auf einem Smartphone mit reduzierter Bewegung zu einem statischen Raster werden.
Nach der Veröffentlichung: Zeige mit site_headers eine Vorschau der Regel `/assets/* Cache-Control: public, max-age=31536000, immutable` und wende sie nach meiner Freigabe einmal an; versioniere ab dann den Dateinamen, sobald sich CSS oder JS ändern (site-v2.css und so weiter). Reiche sitemap.xml mit gsc_submit_sitemap ein und prüfe die Startseite mit gsc_url_inspect. Gib mir am Ende: eine Punktetabelle pro Seite (Seite, vier mobile Scores, vier Desktop-Scores, LCP, CLS), das Ergebnis jedes Gates und die Liste der angewendeten Korrekturen.