Fill in before sending
[server name][year][organisation name][what it does, where, founding year][one sentence][figure, unit, one-sentence explanation][for each chart, title, periods and values][income sources and expense lines, amounts and shares][chapter names and the text or notes for each][items][which records, how missing data was handled][editor's name, date]
On my Opus Growth hosting server [server name], build the [year] impact report of [organisation name] as a site that tells its story as you scroll. Organisation: [what it does, where, founding year]. The report's main message: [one sentence]. The four headline figures: [figure, unit, one-sentence explanation]. Chart data: [for each chart, title, periods and values]. Budget: [income sources and expense lines, amounts and shares]. Chapters: [chapter names and the text or notes for each]. Next year's plan: [items]. Where the figures come from and their limits: [which records, how missing data was handled]. Prepared by and publication date: [editor's name, date]. Contact: [email], [phone], [address]. Domain: [domain]. Photos: [links; no faces of children or beneficiaries].
Pages: report (/: cover headline, answer-first summary paragraph, author and date, cover image, sticky chapter navigation and, in order, year summary, chapters, budget, next year's plan and questions about the report), methodology (/yontem/: the source and limits of every figure), organisation and contact (/dernek/ or a name that suits your organisation), privacy and KVKK (/gizlilik/) and 404.html. Write the charts as static SVG generated from the values I gave, not with Chart.js or D3; do not round the values and check that totals add up. Show the budget as a `<table>` without any minimum width, not as a chart.
Style: a long read like a newspaper data story. Paper-toned background, a Fontshare serif for headings (for example Bespoke Serif) and a readable body face that supports tabular-nums (for example Epilogue), with at most two chart colours. On desktop a 220 px sticky chapter list on the left; on phones a horizontally scrollable chapter strip that sticks to the top, with a thin reading progress line under it.
Motion rules (the hardest part, follow them to the letter):
1. Libraries: only the GSAP 3.13 core and ScrollTrigger, only on the report page. Lenis is NOT loaded, because native scrolling is more comfortable for a long read; SplitText and chart libraries are not loaded either. No scripts at all on the methodology, organisation and privacy pages.
2. Line charts: every line is a `<path pathLength="1">` and is fully drawn in the HTML. JS sets strokeDasharray 1 and strokeDashoffset 1 only on charts below the screen at load and brings the offset to 0 with ScrollTrigger scrub (start "top 75%", end "bottom 65%"); data points grow in as the line passes them. Make SVG text at least 22 units in a 600-unit viewBox so it stays above 12 px on phones, and leave at least 40 units on the right so the last axis label is not cut off.
3. Every chart is an `<svg role="img" aria-labelledby>` with a title and a desc that states all values in a sentence; the figcaption shows the source and links to the methodology note, and DIRECTLY AFTER the figure a `<details>` labelled "View the data as a table" holds a real `<table>`. That table is the text version of the data for both accessibility and AI search.
4. Counters: the final value is written in the HTML in Turkish format (such as 31.540). The visual number sits in an aria-hidden span and the same value sits in an sr-only span for screen readers. JS resets to 0 only the counters below the screen at load and counts them up with Intl.NumberFormat("tr-TR") when they enter the screen; never rewind a number that is already visible. Give the number tabular-nums and a minimum width equal to the final value's character count (with a Tailwind class, not a style attribute) so the line does not move as it counts.
5. Chapter navigation: links are anchors that work without JS. JS uses ScrollTrigger per chapter to find the active one, sets aria-current="true" on its link and scrolls the phone strip sideways so the active link is visible (the strip, not the page). Put the stickiness on the sidebar (aside) that is a direct child of the grid spanning the whole report, not on the inner nav; in the demo sticky on the inner nav never stuck on phones.
6. No other motion apart from the reading progress line and images that appear with data-reveal.
Setup and known traps (each one cost points or broke something in the demo measurement, do not skip any):
1. If a live site is already on the server, tell me first, because setup overwrites index.html and the assets folder. Preview scaffold_site with confirm=false and call confirm=true after my approval. Then read site_design_guide and site_seo_guide. Before writing code, put the design direction (typography, colour, grid, signature element, motion language and the libraries that will NOT be loaded) in a short ART.md outside assets and show it to me.
2. Compile Tailwind, do not load it from the CDN. Install `npm i -D tailwindcss@3` with site_run_command and background=true, and watch it with site_command_status. The content paths in `tailwind.config.js` must cover every HTML file, every template and every JS file that writes classes. `_src/tw.css` holds an `@import "../assets/app.css";` line and the three `@tailwind` lines; compile it into one file with `npx tailwindcss -c tailwind.config.js -i _src/tw.css -o assets/site.css --minify`. Remove the cdn.tailwindcss.com script and the inline tailwind.config from the pages and link only `/assets/site.css`. Recompile after every HTML change.
3. Self-host the fonts. First check that the Fontshare family you pick has the Turkish letters (ş, ğ, ı, İ, ç, ö, ü): in the demo Tanker had no dotless ı and Outfit had no ş, ğ or İ, so those letters would fall back to another font in headings. Download each weight's woff2 separately with site_fetch into `assets/fonts/`, write the @font-face rules with `font-display: swap` into `assets/app.css` (design-check looks for the custom font there) and check the font-family name in the CSS you downloaded. Preload the heading and body fonts used above the fold on every page with `<link rel="preload" as="font" type="font/woff2" crossorigin>`, before the stylesheet; do not preload more than two files, because preloading a third weight in the demo made mobile LCP 0.2 seconds longer. Most Fontshare fonts lack the ₺ sign, so write "TL" for prices.
4. Make the menu and footer static HTML. Do not load chrome.js or site.config.js on the pages. Write a small `chrome-stamp.mjs` that reads the nav list from site.config.js and stamps `_src/header.tpl` and `_src/footer.tpl` between the `<!-- nav:start --><!-- nav:end -->` and `<!-- footer:start --><!-- footer:end -->` markers on every page, adding aria-current="page" to the active link. Templates must not end in .html and must use placeholders like `[[NAV]]` instead of `{{...}}`. Build the mobile menu without JS using `<details>`. Keep the organisation name, address and phone as plain text in the footer, and make every touch target at least 44x44 px, footer and breadcrumb links included.
5. Convert images while downloading them with site_fetch: write the same photo with resize="480x", "800x" and "1200x", image_format="webp", quality=65 to separate files. site_fetch never crops; when an Unsplash photo needs another ratio, download the cropped version by adding parameters such as `?w=1600&h=1200&fit=crop` to its URL. Give every `<img>` srcset, sizes and a width and height that match the real ratio. The main above-the-fold image gets fetchpriority="high" and is not lazy; the others get loading="lazy" decoding="async". If the main image fills the screen on mobile, serve a smaller crop with `<picture>`.
6. Write the SVG version of the logo as favicon.svg with site_write_file and add `<link rel="icon" href="/favicon.svg" type="image/svg+xml">` to every page. Without a favicon the browser logs a 404 and Best Practices drops to 96.
7. HTML validator rules: start with an upper-case `<!DOCTYPE html>`, use ` ` for the spaces in the visible text of tel: links, never use a style="" attribute, give every button type="button", and do not put a `<details>` inside a `<figure>` after its figcaption.
8. Download the motion libraries (GSAP, ScrollTrigger) from jsdelivr into `assets/vendor/` with site_fetch, pin the version and load them only on the report page. Do not use `<script defer>`; put a small loader at the end of the page that waits for the load event, two requestAnimationFrame calls and then requestIdleCallback, and appends the scripts in order with async=false. A one-line script in `<head>` adds the `js` class to `<html>` and the `anim` class unless prefers-reduced-motion is "reduce"; without `anim` the loader downloads nothing. Define hidden start states only under `.anim`, and add a CSS animation as a safety net that reveals every hidden element after 2.5 seconds in case the library never arrives. In earlier demos deferred libraries pushed mobile LCP to 3.2 seconds; with this loader the pages measured 99 to 100. Name the attribute for scroll-revealed elements data-reveal; design-check only recognises motion by that name.
SEO, AEO and GEO:
1. Use directory-style URLs with a trailing slash (/yontem/, /dernek/, /gizlilik/). Fill in the seo block of site.config.js and run `node seo-stamp.mjs`. Write the page-specific schema (report page WebPage with a Report as mainEntity, including headline, datePublished, dateModified, image, author (Person, the editor) and publisher, plus FAQPage; methodology Article; organisation page AboutPage with a subtype that fits the organisation (for example NGO); BreadcrumbList on inner pages. If there is no office people visit, localBusiness:false in site.config.js) in separate `<script type="application/ld+json">` blocks and link them to the base graph by @id. Do not nest BreadcrumbList inside @graph; keep it in its own block, because that is the only way seo-check sees it.
2. Keep titles at 60 characters or fewer (seo-check flags anything over 65 as an error), descriptions between 120 and 158 characters, one h1 per page and no skipped heading levels (an h3 straight after the h1 dropped accessibility to 98). Every page needs at least 150 words of main content; contact and privacy pages tend to fall short.
3. The first paragraph of every page answers the page's question directly. Write page-specific FAQs with `<details>` and mark them up as FAQPage. Show the publishing organisation and a "Last updated" date in `<time>`.
4. In robots.txt, write down and justify your decision for GPTBot, OAI-SearchBot, ChatGPT-User, ClaudeBot, Claude-User, Claude-SearchBot, PerplexityBot, Perplexity-User, Google-Extended, Applebot-Extended, Bingbot and CCBot, and point to the sitemap. Give sitemap.xml real lastmod dates. llms.txt holds an accurate two-sentence summary of the site, the key facts and a list of the important pages.
5. No invention: do not write reviews, ratings, awards, customer counts, certificates, opening hours, coordinates or prices without asking me. Leave any field you do not know out of the schema entirely.
Gates (in order; do not say "done" until all pass):
1. With site_run_command run `node chrome-stamp.mjs`, the Tailwind build, `node seo-stamp.mjs`, `node seo-check.mjs` (0 errors, 0 warnings), `node design-check.mjs` (0 errors; justify any remaining warning) and `npx html-validate "**/*.html"` (0 errors).
2. View every page with site_preview using view="mobile" and view="desktop". site_preview captures the page with motion turned off (reduced-motion); if content is missing in that capture, the motionless state is broken. Lazy images further down may be blank in the full-page capture; do not count that as an error, but check their paths.
3. Run core_web_vitals with strategy="mobile" and strategy="desktop" for every page. Acceptance: on mobile Performance at least 95 and Accessibility, Best Practices and SEO 100; on desktop all four at least 95. For a page that misses, find the slow file with resources=true, fix it and measure again. Then run seo_audit on the home page with strategy="mobile" and runs=2. No address outside your own domain may remain in the network request list.
4. No horizontal scrolling at 360, 390, 768 and 1440 px, touch targets of at least 44 px and no console errors. The site must also look flawless inside a 390x790 and a 1440x898 frame, as on the prompt pages.
Motion check: site_preview cannot show motion, so tell me what to look for in my own browser. On desktop the counters should count from zero to the final value when they come into view, chart lines should draw from left to right as you scroll with points appearing in turn, and the chapter list on the left should mark the chapter you are reading. On a phone the chapter strip should stay stuck at the top and slide the active chapter into view. With reduce motion on and with JavaScript off, every figure shows its final value and every chart is fully drawn; the data tables can be opened.
After publishing: preview the `/assets/* Cache-Control: public, max-age=31536000, immutable` rule with site_headers and apply it after my approval; from then on, version the file name whenever CSS or JS changes (site-v2.css and so on). Submit sitemap.xml with gsc_submit_sitemap and check the home page with gsc_url_inspect. Finally give me: a per-page score table (page, four mobile scores, four desktop scores, LCP, CLS), the gate results, the result of the interactions you tried in a browser and the list of fixes you applied.