/**
 * AI Prompt Library for Website Generation
 *
 * Generates a complete, self-contained multi-page website as HTML files
 * using plain HTML, CSS, and JavaScript — NO React, NO frameworks,
 * NO CDN dependencies required (except Google Fonts).
 *
 * This follows the same proven pattern as landingPageWebsitePrompts.ts
 * but is adapted for full websites with multiple pages/sections from
 * Website Planner data.
 */

import { buildLanguageDirective } from './websitePlannerPrompts';

export interface WebsiteSection {
  name: string;
  enabled?: boolean;
  purpose?: string;
  contentRequirement?: string;
  uiNotes?: string;
  cta?: string;
  seoNotes?: string;
  priority?: string;
}

export interface WebsitePage {
  name: string;
  url?: string;
  pageType?: string;
  goal?: string;
  metaTitle?: string;
  metaDescription?: string;
  sections?: string[];
}

/**
 * Turn a planner page into the HTML filename the site will use.
 * The home page is always index.html; everything else uses its URL slug.
 * Exported so the generator route and the prompt agree on the exact filenames —
 * the navigation on every page is built from these.
 */
export function websitePageFileName(page: WebsitePage, index: number): string {
  const raw = (page.url || page.name || '').trim().toLowerCase();
  const slug = raw.replace(/^https?:\/\/[^/]+/, '').replace(/^\/+|\/+$/g, '').replace(/[^a-z0-9/-]+/g, '-').replace(/-+/g, '-');
  const isHome = index === 0 || !slug || slug === 'home' || slug === 'index' || raw === '/';
  if (isHome) return 'index.html';
  return `${slug.replace(/\//g, '-')}.html`;
}

/** One entry in the shared navigation that every page must render identically. */
export interface WebsiteNavEntry {
  name: string;
  file: string;
  active?: boolean;
}

export interface WebsiteWebsiteInputs {
  // Website planner data
  websiteName: string;
  websiteType?: string;
  domain?: string;
  primaryCTA?: string;
  secondaryCTA?: string;
  targetAudience?: string;
  country?: string;
  language?: string;
  seoTargetRegion?: string;
  uiStyle?: string;
  animationNotes?: string;
  responsiveNotes?: string;
  accessibilityNotes?: string;
  /**
   * Website Settings chosen in the wizard's AI Prompt step, already rendered as
   * directive lines by services/aiContext/websiteAiSettings. Empty for websites
   * saved before that panel existed, which keeps their prompt unchanged.
   */
  designSettingsDirectives?: string[];

  // Sections and pages
  sections?: WebsiteSection[];
  pages?: WebsitePage[];
  contentBlocks?: any[];
  features?: any[];
  faqs?: any[];
  caseStudies?: any[];

  // Business profile
  companyName?: string;
  companyIndustry?: string;
  companyDescription?: string;
  companyMission?: string;
  companyUsp?: string;
  companyWebsite?: string;

  // Visual identity — colors (flat structure from ModuleData)
  primaryColor?: string;
  accentColor?: string;
  secondaryColor?: string;
  backgroundColor?: string;
  surfaceColor?: string;
  textColor?: string;
  textMutedColor?: string;

  // Visual identity — fonts
  headingFont?: string;
  bodyFont?: string;
  accentFont?: string;

  // Brand strategy
  brandTagline?: string;
  brandVoice?: string;
  brandPersonality?: string[];
  brandValues?: string[];
  brandPositioning?: string;
  brandPromise?: string;
  elevatorPitch?: string;
  keyMessages?: string[];

  // Logo
  logoUrl?: string;
  logoAlt?: string;

  // Brand images (from brand assets)
  heroImageUrl?: string;
  heroImageAlt?: string;
  backgroundImageUrl?: string;
  brandPatternUrl?: string;
  ogImageUrl?: string;

  // Context-aware image data
  industry?: string;
  industryKeywords?: string[];
  productImages?: Array<{ name: string; description: string; url: string }>;
  serviceDescriptions?: string[];

  // SEO
  metaTitle?: string;
  metaDescription?: string;

  // Generation options
  responsive?: boolean;

  /**
   * Shared navigation for the whole site. Set when generating ONE page at a time:
   * `pages` then holds only the page being generated, while this holds every page
   * so the nav and footer links are identical and correct across the site.
   */
  navPages?: WebsiteNavEntry[];
  /** Exact filename the generated page must use (single-page generation). */
  targetFile?: string;
}

export interface PromptResult {
  systemPrompt: string;
  userPrompt: string;
  maxTokens: number;
}

// ============================================
// HELPER: Build Google Fonts <link> tag
// ============================================

function buildGoogleFontsLink(inputs: WebsiteWebsiteInputs): string {
  const fonts = new Set<string>();
  if (inputs.headingFont) fonts.add(inputs.headingFont);
  if (inputs.bodyFont) fonts.add(inputs.bodyFont);
  if (inputs.accentFont) fonts.add(inputs.accentFont);
  if (fonts.size === 0) fonts.add('Inter');

  const families = Array.from(fonts).map(f =>
    f.replace(/\s+/g, '+') + ':wght@400;500;600;700'
  ).join('&family=');

  return `<link href="https://fonts.googleapis.com/css2?family=${families}&display=swap" rel="stylesheet">`;
}

// ============================================
// HELPER: Build brand context section for user prompt
// ============================================

function buildBrandContextSection(inputs: WebsiteWebsiteInputs): string {
  const parts: string[] = [];

  if (inputs.companyDescription) parts.push(`Company Description: ${inputs.companyDescription}`);
  if (inputs.companyMission) parts.push(`Mission: ${inputs.companyMission}`);
  if (inputs.companyUsp) parts.push(`Unique Selling Proposition: ${inputs.companyUsp}`);

  if (inputs.brandTagline) parts.push(`Brand Tagline: "${inputs.brandTagline}"`);
  if (inputs.brandVoice) parts.push(`Brand Voice: ${inputs.brandVoice}`);
  if (inputs.brandPersonality?.length) parts.push(`Brand Personality: ${inputs.brandPersonality.join(', ')}`);
  if (inputs.brandValues?.length) parts.push(`Brand Values: ${inputs.brandValues.join(', ')}`);
  if (inputs.brandPositioning) parts.push(`Brand Positioning: ${inputs.brandPositioning}`);
  if (inputs.brandPromise) parts.push(`Brand Promise: ${inputs.brandPromise}`);
  if (inputs.elevatorPitch) parts.push(`Elevator Pitch: ${inputs.elevatorPitch}`);
  if (inputs.keyMessages?.length) {
    parts.push(`Key Messages:`);
    inputs.keyMessages.slice(0, 5).forEach((m, i) => {
      parts.push(`  ${i + 1}. ${m}`);
    });
  }

  // Industry-specific image context
  if (inputs.industry || inputs.industryKeywords?.length) {
    const industryLabel = inputs.industry || 'General';
    const keywordsLabel = inputs.industryKeywords?.length ? inputs.industryKeywords.join(', ') : industryLabel;
    parts.push(`\nINDUSTRY CONTEXT: This is a ${industryLabel} company. All content, imagery descriptions, and section themes MUST be relevant to the ${industryLabel} industry. Draw on your knowledge of ${keywordsLabel} — common pain points, industry terminology, typical customer expectations, competitive landscape, and sector-specific value propositions. Write content that demonstrates deep understanding of the ${industryLabel} space. Do NOT use generic business language — use ${industryLabel}-specific vocabulary and examples.`);
  }

  if (inputs.productImages?.length) {
    parts.push(`\nPRODUCT IMAGES (use these in Features, Benefits, and Product sections as <img> tags with descriptive alt text):`);
    inputs.productImages.forEach(p => {
      parts.push(`  - ${p.name}: ${p.description || 'Product image'} → ${p.url}`);
    });
  }

  if (inputs.serviceDescriptions?.length) {
    parts.push(`\nSERVICES: ${inputs.serviceDescriptions.join('; ')}`);
  }

  if (parts.length === 0) return '';
  return `BRAND CONTEXT (use this to inform tone, messaging, content, and imagery):\n${parts.join('\n')}`;
}

// ============================================
// PROMPT BUILDERS
// ============================================

export function buildWebsiteWebsitePrompt(inputs: WebsiteWebsiteInputs): PromptResult {
  const enabledSections = inputs.sections?.filter(s => s.enabled !== false) || [];
  const sections = enabledSections.slice(0, 12); // Allow more sections for a full website

  // Build detailed section descriptions
  // Build detailed section descriptions with the REAL copy, not just a brief.
  // This block used to emit only name/purpose/contentRequirement/uiNotes/cta,
  // so everything the user generated or wrote in the Content step — headline,
  // subheadline, description, bullet points, trust statements — never reached
  // the AI and it invented its own. Mirrors the Landing Page generator.
  const sectionDetails = sections.map((s: any, i) => {
    const parts = [`${i + 1}. ${s.name}`];
    if (s.headline) parts.push(`   Headline: "${s.headline}"`);
    if (s.subheadline) parts.push(`   Subheadline: "${s.subheadline}"`);
    if (s.description) parts.push(`   Description: ${s.description}`);
    if (Array.isArray(s.bulletPoints) && s.bulletPoints.length > 0) {
      parts.push(`   Key Points:`);
      s.bulletPoints.slice(0, 6).forEach((bp: string) => parts.push(`     - ${bp}`));
    }
    if (Array.isArray(s.trustStatements) && s.trustStatements.length > 0) {
      parts.push(`   Trust Statements:`);
      s.trustStatements.slice(0, 4).forEach((ts: string) => parts.push(`     - ${ts}`));
    }
    if (s.purpose) parts.push(`   Purpose: ${s.purpose}`);
    if (s.contentRequirement) parts.push(`   Content: ${s.contentRequirement}`);
    if (s.uiNotes) parts.push(`   UI Notes: ${s.uiNotes}`);
    if (s.conversionNotes) parts.push(`   Conversion Notes: ${s.conversionNotes}`);
    if (s.cta) parts.push(`   CTA: "${s.cta}"`);
    if (s.priority) parts.push(`   Priority: ${s.priority}`);
    return parts.join('\n');
  }).join('\n\n');

  // Build page structure
  const pages = inputs.pages || [];
  const pageDetails = pages.length > 0
    ? pages.map((p, i) => {
        const parts = [`${i + 1}. ${p.name} (${p.url || `/${p.name.toLowerCase().replace(/\s+/g, '-')}`})`];
        if (p.pageType) parts.push(`   Type: ${p.pageType}`);
        if (p.goal) parts.push(`   Goal: ${p.goal}`);
        if (p.metaTitle) parts.push(`   Meta Title: ${p.metaTitle}`);
        return parts.join('\n');
      }).join('\n\n')
    : '';

  // Brand colors
  const primaryColor = inputs.primaryColor || '#7C6BF0';
  const accentColor = inputs.accentColor || '#C8FF2E';
  const secondaryColor = inputs.secondaryColor || '#1E293B';
  const backgroundColor = inputs.backgroundColor || '#0a0a0f';
  const surfaceColor = inputs.surfaceColor || 'rgba(30, 41, 59, 0.5)';
  const textColor = inputs.textColor || '#f1f5f9';
  const textMutedColor = inputs.textMutedColor || '#64748b';

  // Fonts
  const headingFont = inputs.headingFont || 'Inter';
  const bodyFont = inputs.bodyFont || 'Inter';

  // Names
  const businessName = inputs.companyName || inputs.websiteName || 'Company';
  const industry = inputs.companyIndustry || 'General';

  // Google Fonts link
  const fontLink = buildGoogleFontsLink(inputs);

  // Logo instruction
  const logoInstruction = inputs.logoUrl
    ? `LOGO: Use an actual <img> tag for the logo: <img src="${inputs.logoUrl}" alt="${inputs.logoAlt || businessName}" style="height:36px;width:auto;vertical-align:middle;"> — wrap this in <a href="#" class="nav-logo">. The logo image MUST be used; do NOT replace it with text.`
    : `LOGO: Use text-based logo — display "${businessName}" in font-bold with the accent color as a text logo wrapped in <a href="#" class="nav-logo">.`;

  // Hero image instruction
  const heroImageInstruction = inputs.heroImageUrl
    ? `HERO IMAGE: You MUST include this image in the hero section. Use it as an <img> tag with class "hero-image" alongside the headline/subheadline, OR as a hero background with class "hero-background" (object-fit:cover, opacity:0.15, position:absolute, inset:0, z-index:0). The hero image URL is: ${inputs.heroImageUrl}. The hero section MUST include this image — do NOT omit it.`
    : '';

  const backgroundInstruction = inputs.backgroundImageUrl
    ? `BACKGROUND TEXTURE: Use this image as a subtle repeating background across sections. Apply it using a <div class="pattern-overlay"> overlay on sections with CSS background-image: url(${inputs.backgroundImageUrl}). Set opacity to 0.04 and background-size to 200px.`
    : '';

  const brandPatternInstruction = inputs.brandPatternUrl
    ? `BRAND PATTERN: Use this image as a subtle decorative pattern overlay on alternating sections. Apply with a <div class="pattern-overlay"> using CSS background-image: url(${inputs.brandPatternUrl}). Set opacity to 0.04 and background-size to 200px so it is barely visible as a texture.`
    : '';

  const ogImageInstruction = inputs.ogImageUrl
    ? `<meta property="og:image" content="${inputs.ogImageUrl}">`
    : '';

  // Brand context section
  const brandContext = buildBrandContextSection(inputs);

  // Convert hex color to RGB
  const hexToRgb = (hex: string) => {
    const h = hex.replace('#', '');
    return `${parseInt(h.slice(0, 2), 16)}, ${parseInt(h.slice(2, 4), 16)}, ${parseInt(h.slice(4, 6), 16)}`;
  };
  const primaryRgb = hexToRgb(primaryColor);
  const accentRgb = hexToRgb(accentColor);

  const websiteType = inputs.websiteType || 'corporate';
  const targetAudience = inputs.targetAudience || `potential ${industry} customers`;
  const primaryCTA = inputs.primaryCTA || 'Get Started';
  const secondaryCTA = inputs.secondaryCTA || 'Learn More';

  // Build language directive for non-English content generation
  const languageDirective = buildLanguageDirective(inputs.language);

  const systemPrompt = `You are an expert frontend developer specializing in professional multi-page websites. You write clean, modern HTML, CSS, and JavaScript — NO frameworks.

IMPORTANT: You MUST respond with ONLY a valid JSON object. No markdown code fences, no explanatory text before or after.

Generate a COMPLETE, PRODUCTION-READY multi-page website as separate HTML files. No React, no Tailwind CDN, no Babel, no frameworks — only plain HTML + inline CSS + vanilla JavaScript. This is a ${websiteType} website for a ${industry} company.${languageDirective}

JSON structure:
{
  "files": [
    { "path": "index.html", "content": "<!DOCTYPE html>..." },
    { "path": "about.html", "content": "<!DOCTYPE html>..." },
    { "path": "services.html", "content": "<!DOCTYPE html>..." }
  ]
}

You MUST generate ONE HTML file for EACH page listed in the PAGE STRUCTURE. The home page is always "index.html". Other pages use the URL from the page structure as the filename (e.g., "/about" becomes "about.html", "/contact" becomes "contact.html").

CRITICAL MULTI-PAGE RULES:
1. Each HTML file must be COMPLETE and self-contained — it must include ALL CSS (the full <style> block), ALL JavaScript, and ALL fonts in every page. This ensures any page works when opened directly.
2. The navigation MUST be identical across ALL pages — same HTML structure, same links, same logo, same CTA button, same mobile menu, same overlay. The ONLY difference is which nav link has class="active" (the current page). Copy the exact same <nav>, mobile-menu, and menu-overlay HTML into every page.
3. The footer MUST be identical across ALL pages — same links, same copyright, same social links.
4. The active nav link on each page must have the class "active" to indicate the current page.
5. Each page must have its own <title> and <meta description> matching the page's SEO data.
6. The home page (index.html) must include the hero section and the most important sections.
7. Other pages must include content relevant to their page type (About page = team/history/mission, Services page = service details, Contact page = form/info, etc.)
8. NAVBAR CONSISTENCY IS NON-NEGOTIABLE: Every page MUST use the exact same <nav class="nav"> HTML structure with the same nav-inner, nav-logo, nav-links, CTA button, mobile-menu-btn, menu-overlay, and mobile-menu. The only difference between pages is which link has class="active".

== PAGE STRUCTURE (one HTML file per page) ==

Each page follows this structure:

<!DOCTYPE html>
<html lang="${inputs.language || 'en'}>
<head>
  — meta charset, viewport, title, SEO meta tags
${ogImageInstruction ? '  — <meta property="og:image" content="' + inputs.ogImageUrl + '">\n' : ''}  — ${fontLink}
  — ALL styles in a single <style> block (no external CSS files, no Tailwind)
  — Minimal inline JS in <script> tags at end of <body>
</head>
<body>
  — <div class="scroll-progress"></div> (before nav)
  — <nav> Sticky navigation with logo, page links, CTA button, mobile hamburger menu
  — <section id="hero"> Hero section
  — <section> for each enabled section from the sections list
  — <footer> Comprehensive footer
  — <script> for all interactivity (scroll animations, mobile menu, smooth scroll, counters, sticky nav, progress bar)
</body>
</html>

== CSS REQUIREMENTS (all in one <style> block) ==

*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
body { font-family: '${bodyFont}', system-ui, sans-serif; background: ${backgroundColor}; color: #e2e8f0; line-height: 1.6; overflow-x: hidden; }
html { scroll-behavior: smooth; }

CSS variables for easy theming (use these throughout ALL styles):
:root {
  --primary: ${primaryColor};
  --accent: ${accentColor};
  --secondary: ${secondaryColor};
  --bg-dark: ${backgroundColor};
  --bg-card: ${surfaceColor};
  --bg-section: #0f1729;
  --border: #334155;
  --text-primary: ${textColor};
  --text-secondary: #94a3b8;
  --text-muted: ${textMutedColor};
}

Layout classes:
.container { max-width: 1200px; margin: 0 auto; padding: 0 1.5rem; }
.section { padding: 5rem 0; position: relative; }
.section-alt { background: var(--bg-section); }
.section-divider { height: 1px; background: linear-gradient(90deg, transparent, var(--border), transparent); margin: 0; }

Typography:
h1 { font-size: clamp(2rem, 5vw, 3.5rem); font-weight: 700; line-height: 1.15; color: var(--text-primary); font-family: '${headingFont}', '${bodyFont}', system-ui, sans-serif; }
h2 { font-size: clamp(1.5rem, 3vw, 2.25rem); font-weight: 600; color: var(--text-primary); font-family: '${headingFont}', '${bodyFont}', system-ui, sans-serif; }
h3 { font-family: '${headingFont}', '${bodyFont}', system-ui, sans-serif; }
p { color: var(--text-secondary); line-height: 1.7; }
a { color: var(--primary); text-decoration: none; transition: color 0.2s; }

Buttons:
.btn { display: inline-flex; align-items: center; justify-content: center; padding: 0.875rem 2rem; border-radius: 0.5rem; font-weight: 600; font-size: 1rem; cursor: pointer; transition: all 0.2s; border: none; }
.btn-primary { background: var(--accent); color: #0d1117; }
.btn-primary:hover { filter: brightness(1.1); transform: translateY(-1px); }
.btn-secondary { background: transparent; color: var(--text-primary); border: 1px solid var(--border); }
.btn-secondary:hover { border-color: var(--primary); color: var(--primary); }
.btn-group { display: flex; gap: 1rem; flex-wrap: wrap; }
.badge { display: inline-block; padding: 0.25rem 0.75rem; font-size: 0.75rem; font-weight: 600; border-radius: 9999px; background: rgba(124, 107, 240, 0.15); color: var(--primary); border: 1px solid rgba(124, 107, 240, 0.3); }

Grid helpers:
.grid { display: grid; gap: 2rem; }
.grid-2 { grid-template-columns: repeat(2, 1fr); }
.grid-3 { grid-template-columns: repeat(3, 1fr); }
.grid-4 { grid-template-columns: repeat(4, 1fr); }
.stats-grid { display: grid; gap: 2rem; }
.testimonial-grid { display: grid; gap: 2rem; }
.pricing-grid { display: grid; gap: 2rem; }
.team-grid { display: grid; gap: 2rem; }
.feature-grid { display: grid; gap: 2rem; }

Cards:
.card { background: var(--bg-card); border: 1px solid var(--border); border-radius: 0.75rem; padding: 2rem; transition: all 0.3s; overflow: hidden; }
.card:hover { border-color: var(--primary); transform: translateY(-2px); box-shadow: 0 8px 30px rgba(0,0,0,0.3); }
.card-image { width: 100%; height: 200px; object-fit: cover; border-radius: 0.75rem 0.75rem 0 0; }
.card-body { padding: 1.5rem; }

Images:
.hero-image { width: 100%; max-width: 600px; height: auto; object-fit: contain; border-radius: 0.75rem; box-shadow: 0 20px 60px rgba(0,0,0,0.3); }
.hero-background { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0.15; z-index: 0; }
.section-image { width: 100%; height: auto; border-radius: 0.75rem; object-fit: cover; box-shadow: 0 4px 20px rgba(0,0,0,0.2); }
.gallery-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1rem; }
.gallery-item { position: relative; overflow: hidden; border-radius: 0.75rem; aspect-ratio: 16/9; }
.gallery-item img { width: 100%; height: 100%; object-fit: cover; transition: transform 0.4s ease; }
.gallery-item:hover img { transform: scale(1.05); }
.testimonial-avatar { width: 48px; height: 48px; border-radius: 50%; object-fit: cover; border: 2px solid var(--border); }
.pattern-overlay { position: absolute; inset: 0; opacity: 0.04; background-repeat: repeat; background-size: 200px; pointer-events: none; z-index: 0; }
.logo-client { height: 32px; width: auto; opacity: 0.6; filter: grayscale(1); transition: all 0.3s; }
.logo-client:hover { opacity: 1; filter: grayscale(0); }
.icon-feature { width: 48px; height: 48px; display: flex; align-items: center; justify-content: center; border-radius: 0.75rem; background: rgba(124, 107, 240, 0.1); color: var(--primary); }
.icon-feature svg { width: 24px; height: 24px; stroke: currentColor; fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }

Scroll progress bar:
.scroll-progress { position: fixed; top: 0; left: 0; height: 3px; background: linear-gradient(90deg, var(--primary), var(--accent)); z-index: 100; width: 0; transition: width 0.1s; }

Counter animation:
.counter { font-size: clamp(2rem, 4vw, 3rem); font-weight: 700; color: var(--accent); line-height: 1; }
.counter-suffix { font-size: clamp(1.5rem, 3vw, 2rem); font-weight: 700; color: var(--accent); }

Scroll animations (6 variants + stagger delays):
CRITICAL: Content MUST be visible by default. Only hide for animation when JavaScript is ready. This ensures content is always readable even if JS fails.
.fade-in { opacity: 1; transform: none; transition: opacity 0.6s ease-out, transform 0.6s ease-out; }
html.js-anim .fade-in { opacity: 0; transform: translateY(30px); }
html.js-anim .fade-in.visible { opacity: 1; transform: translateY(0); }
.fade-in-left { opacity: 1; transform: none; transition: opacity 0.6s ease-out, transform 0.6s ease-out; }
html.js-anim .fade-in-left { opacity: 0; transform: translateX(-30px); }
html.js-anim .fade-in-left.visible { opacity: 1; transform: translateX(0); }
.fade-in-right { opacity: 1; transform: none; transition: opacity 0.6s ease-out, transform 0.6s ease-out; }
html.js-anim .fade-in-right { opacity: 0; transform: translateX(30px); }
html.js-anim .fade-in-right.visible { opacity: 1; transform: translateX(0); }
.fade-in-up { opacity: 1; transform: none; transition: opacity 0.5s ease-out, transform 0.5s ease-out; }
html.js-anim .fade-in-up { opacity: 0; transform: translateY(20px); }
html.js-anim .fade-in-up.visible { opacity: 1; transform: translateY(0); }
.scale-in { opacity: 1; transform: none; transition: opacity 0.5s ease-out, transform 0.5s ease-out; }
html.js-anim .scale-in { opacity: 0; transform: scale(0.9); }
html.js-anim .scale-in.visible { opacity: 1; transform: scale(1); }
.slide-up { opacity: 1; transform: none; transition: opacity 0.7s ease-out, transform 0.7s ease-out; }
html.js-anim .slide-up { opacity: 0; transform: translateY(50px); }
html.js-anim .slide-up.visible { opacity: 1; transform: translateY(0); }
.stagger-1 { transition-delay: 0.1s; }
.stagger-2 { transition-delay: 0.2s; }
.stagger-3 { transition-delay: 0.3s; }
.stagger-4 { transition-delay: 0.4s; }
.stagger-5 { transition-delay: 0.5s; }
.stagger-6 { transition-delay: 0.6s; }

Hover interactions:
.card-hover-lift { transition: transform 0.3s ease, box-shadow 0.3s ease; }
.card-hover-lift:hover { transform: translateY(-4px); box-shadow: 0 12px 40px rgba(0,0,0,0.4); }
.btn-glow { position: relative; overflow: hidden; }
.btn-glow::after { content: ''; position: absolute; top: -50%; left: -50%; width: 200%; height: 200%; background: radial-gradient(circle, rgba(255,255,255,0.15) 0%, transparent 60%); opacity: 0; transition: opacity 0.3s; pointer-events: none; }
.btn-glow:hover::after { opacity: 1; }
.image-zoom { overflow: hidden; }
.image-zoom img { transition: transform 0.4s ease; }
.image-zoom:hover img { transform: scale(1.08); }
.icon-float { animation: float 3s ease-in-out infinite; }
@keyframes float { 0%, 100% { transform: translateY(0); } 50% { transform: translateY(-8px); } }
.gradient-text { background: linear-gradient(135deg, var(--primary), var(--accent)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; }
.border-glow { position: relative; }
.border-glow::before { content: ''; position: absolute; inset: -1px; border-radius: inherit; background: linear-gradient(135deg, var(--primary), var(--accent)); z-index: -1; opacity: 0; transition: opacity 0.3s; }
.border-glow:hover::before { opacity: 1; }

Sticky nav (MUST be identical HTML structure on EVERY page — same links, same logo, same CTA, same mobile menu):
.nav { position: fixed; top: 0; left: 0; right: 0; z-index: 50; padding: 1rem 0; transition: transform 0.3s ease, background 0.3s ease; }
.nav.scrolled { background: rgba(10, 10, 15, 0.95); backdrop-filter: blur(12px); border-bottom: 1px solid var(--border); }
.nav-inner { display: flex; align-items: center; justify-content: space-between; max-width: 1200px; margin: 0 auto; padding: 0 1.5rem; }
.nav-logo { display: flex; align-items: center; gap: 0.5rem; text-decoration: none; color: var(--text-primary); font-weight: 700; font-size: 1.25rem; }
.nav-logo span { color: var(--primary); }
.nav-links { display: flex; align-items: center; gap: 2rem; }
.nav-links a { color: var(--text-secondary); text-decoration: none; font-size: 0.9rem; font-weight: 500; transition: color 0.2s; position: relative; }
.nav-links a:hover { color: var(--text-primary); }
.nav-links a.active { color: var(--accent); }
.nav-links a.active::after { content: ''; position: absolute; bottom: -4px; left: 0; right: 0; height: 2px; background: var(--accent); border-radius: 1px; }
.nav-cta { margin-left: 1rem; }
.nav-spacer { height: 80px; }
.mobile-menu-btn { display: none; background: none; border: none; color: var(--text-primary); font-size: 1.5rem; cursor: pointer; padding: 0.25rem; }

Hero section:
.hero { min-height: 100vh; display: flex; align-items: center; position: relative; padding-top: 80px; background: radial-gradient(ellipse at 50% 50%, rgba(${primaryRgb}, 0.1) 0%, transparent 70%); }

Section scroll offset (prevents anchor nav from hiding content behind the fixed header):
section[id] { scroll-margin-top: 80px; }

Footer:
.footer { background: var(--bg-dark); border-top: 1px solid var(--border); padding: 3rem 0 1.5rem; }
.footer a { color: var(--text-secondary); transition: color 0.2s; }
.footer a:hover { color: var(--primary); }
.footer-grid { display: grid; grid-template-columns: 2fr 1fr 1fr 1fr; gap: 2rem; }
.footer-bottom { border-top: 1px solid var(--border); margin-top: 2rem; padding-top: 1.5rem; text-align: center; color: var(--text-muted); font-size: 0.875rem; }

Mobile menu (MUST be identical on EVERY page):
.mobile-menu { position: fixed; top: 0; right: -100%; width: 280px; height: 100vh; background: var(--bg-dark); border-left: 1px solid var(--border); transition: right 0.3s ease; z-index: 60; padding: 2rem; }
.mobile-menu.open { right: 0; }
.mobile-menu .close-btn { background: none; border: none; color: var(--text-primary); font-size: 1.5rem; cursor: pointer; position: absolute; top: 1rem; right: 1rem; }
.mobile-menu nav { display: flex; flex-direction: column; gap: 1.5rem; margin-top: 3rem; }
.mobile-menu nav a { color: var(--text-secondary); font-size: 1.1rem; font-weight: 500; text-decoration: none; transition: color 0.2s; }
.mobile-menu nav a:hover, .mobile-menu nav a.active { color: var(--accent); }
.menu-overlay { position: fixed; inset: 0; background: rgba(0,0,0,0.5); z-index: 55; opacity: 0; pointer-events: none; transition: opacity 0.3s; }
.menu-overlay.open { opacity: 1; pointer-events: auto; }

Responsive — 5 breakpoints (mobile-first). CRITICAL: Every page MUST include ALL responsive breakpoints. Responsive design is NON-NEGOTIABLE — the site MUST look good on mobile (320px), tablet (768px), and desktop (1280px+):
@media (max-width: 479px) {
  .container { padding: 0 0.75rem; }
  .section { padding: 2.5rem 0; }
  h1 { font-size: 1.75rem; }
  h2 { font-size: 1.25rem; }
  .hero { min-height: 70vh; padding-top: 70px; }
  .hero-content { grid-template-columns: 1fr !important; text-align: center; }
  .hero-text { max-width: 100%; }
  .hero-text p { max-width: 100%; }
  .hero-visual { order: -1; }
  .hero-visual img { max-width: 100%; }
  .btn { padding: 0.625rem 1.25rem; font-size: 0.85rem; width: 100%; }
  .btn-group { flex-direction: column; width: 100%; }
  .card { padding: 1rem; }
  .card-image { height: 140px; }
  .gallery-grid { grid-template-columns: 1fr; }
  .gallery-item { aspect-ratio: 16/9; }
  .section-image { max-width: 100%; }
  .testimonial-avatar { width: 40px; height: 40px; }
  .logo-client { height: 24px; }
  .pattern-overlay { display: none; }
  .footer-grid { grid-template-columns: 1fr; }
  .nav-links { display: none; }
  .nav-cta-desktop { display: none; }
  .mobile-menu-btn { display: block; }
  .hero-content { text-align: center; }
  .hero-text { max-width: 100%; }
  .stats-grid { grid-template-columns: 1fr 1fr; }
  .testimonial-grid { grid-template-columns: 1fr; }
  .pricing-grid { grid-template-columns: 1fr; }
  .team-grid { grid-template-columns: 1fr; }
  .feature-grid { grid-template-columns: 1fr; }
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
  .cta-grid { grid-template-columns: 1fr; }
  .contact-grid { grid-template-columns: 1fr; }
  .lead-grid { grid-template-columns: 1fr; }
  .trust-line { justify-content: center; }
  .stats-row { justify-content: center; }
  .footer-bottom { flex-direction: column; gap: 1rem; text-align: center; }
  .pricing-toggle { flex-wrap: wrap; }
  .hero-trust { justify-content: center; flex-wrap: wrap; }
  .hero-trust-avatars { justify-content: center; }
  .comparison-table { font-size: 0.75rem; }
  .comparison-table th, .comparison-table td { padding: 0.5rem; }
  .feature-showcase { grid-template-columns: 1fr !important; }
  .feature-showcase-reverse { grid-template-columns: 1fr !important; direction: ltr; }
  .about-grid { grid-template-columns: 1fr; }
  .about-values { grid-template-columns: 1fr; }
  .section-header { text-align: center; }
  .nav-inner { padding: 0 0.75rem; }
}
@media (min-width: 480px) and (max-width: 767px) {
  .container { padding: 0 1rem; }
  .section { padding: 3rem 0; }
  h1 { font-size: clamp(1.75rem, 5vw, 2.25rem); }
  .hero { min-height: 80vh; }
  .hero-content { grid-template-columns: 1fr !important; text-align: center; }
  .hero-text { max-width: 100%; }
  .hero-text p { max-width: 100%; margin-left: auto; margin-right: auto; }
  .hero-visual img { max-width: 400px; }
  section[id] { scroll-margin-top: 70px; }
  .grid-2, .grid-3, .grid-4 { grid-template-columns: 1fr; }
  .card-image { height: 160px; }
  .gallery-grid { grid-template-columns: repeat(2, 1fr); }
  .footer-grid { grid-template-columns: 1fr 1fr; }
  .stats-grid { grid-template-columns: repeat(2, 1fr); }
  .testimonial-grid { grid-template-columns: 1fr; }
  .pricing-grid { grid-template-columns: 1fr; }
  .cta-grid { grid-template-columns: 1fr; }
  .contact-grid { grid-template-columns: 1fr; }
  .lead-grid { grid-template-columns: 1fr; }
  .feature-showcase { grid-template-columns: 1fr !important; }
  .feature-showcase-reverse { grid-template-columns: 1fr !important; direction: ltr; }
  .about-grid { grid-template-columns: 1fr; }
  .nav-links { display: none; }
  .nav-cta-desktop { display: none; }
  .mobile-menu-btn { display: block; }
}
@media (min-width: 768px) and (max-width: 1023px) {
  .grid-4 { grid-template-columns: repeat(2, 1fr); }
  .grid-3 { grid-template-columns: repeat(2, 1fr); }
  .gallery-grid { grid-template-columns: repeat(2, 1fr); }
  .footer-grid { grid-template-columns: 2fr 1fr 1fr; }
  .hero-image { max-width: 450px; }
  .hero-content { grid-template-columns: 1fr 1fr; gap: 2rem; }
  .stats-grid { grid-template-columns: repeat(2, 1fr); }
  .card { padding: 1.5rem; }
  .pricing-grid { grid-template-columns: 1fr; }
  .testimonial-grid { grid-template-columns: repeat(2, 1fr); }
  .cta-grid { grid-template-columns: 1fr; }
  .contact-grid { grid-template-columns: 1fr; }
  .lead-grid { grid-template-columns: 1fr; }
  .feature-showcase { grid-template-columns: 1fr 1fr; }
  .feature-showcase-reverse { grid-template-columns: 1fr 1fr; direction: rtl; }
  .feature-showcase-reverse > * { direction: ltr; }
  .about-grid { grid-template-columns: 1fr 1fr; gap: 2rem; }
  .feature-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (min-width: 1024px) and (max-width: 1279px) {
  .container { max-width: 960px; }
  .grid-4 { grid-template-columns: repeat(3, 1fr); }
  .hero-image { max-width: 500px; }
}
@media (min-width: 1280px) {
  .container { max-width: 1200px; }
  .hero { min-height: 100vh; }
  .stats-grid { grid-template-columns: repeat(4, 1fr); }
  .feature-grid { grid-template-columns: repeat(3, 1fr); }
}

== HTML SECTIONS ==

CRITICAL HTML STRUCTURE RULE — Content visibility:
Immediately after the closing </style> tag and before </head>, add this EXACT script to enable scroll animations (it MUST be in the <head> so animations are enabled before the body renders):
<script>document.documentElement.classList.add('js-anim')</script>
Also add this <noscript> fallback right after the above script (ensures content is visible if JavaScript is disabled):
<noscript><style>.fade-in,.fade-in-left,.fade-in-right,.fade-in-up,.scale-in,.slide-up{opacity:1!important;transform:none!important}</style></noscript>
These are NON-NEGOTIABLE. Without the script, ALL section content will be invisible because the animation CSS uses html.js-anim to hide elements until they scroll into view. The noscript fallback ensures content is visible even without JavaScript.

Build these sections in order:

1. <div class="scroll-progress"></div> — Scroll progress bar at the very top of <body> (before <nav>).

2. <nav> — Sticky header with logo and navigation. CRITICAL: The navbar HTML structure MUST be identical across ALL pages — same logo, same links, same CTA, same mobile menu. Use this EXACT structure on every page:
   <nav class="nav">
     <div class="nav-inner">
       <a href="index.html" class="nav-logo">Brand<span>Name</span></a>
       <div class="nav-links">
         <!-- One <a> per page, href matches the page filename. Current page gets class="active" -->
       </div>
       <div style="display:flex;align-items:center;gap:0.75rem;">
         <a href="#cta" class="btn btn-primary btn-glow nav-cta nav-cta-desktop">${primaryCTA}</a>
         <button class="mobile-menu-btn" onclick="toggleMenu()">☰</button>
       </div>
     </div>
   </nav>
   <div class="nav-spacer"></div>
   <div class="menu-overlay" onclick="closeMenu()"></div>
   <div class="mobile-menu">
     <button class="close-btn" onclick="closeMenu()">✕</button>
     <nav>
       <!-- Same links as desktop nav, current page has class="active" -->
     </nav>
     <a href="#cta" class="btn btn-primary btn-glow" style="margin-top:1.5rem;text-align:center;" onclick="closeMenu()">${primaryCTA}</a>
   </div>
   ${logoInstruction}
   - Replace "Brand<span>Name</span>" with the actual brand name (the <span> part uses accent color)
   - Replace nav links with links to ALL pages in the site using relative hrefs (href="pricing.html", href="features.html", etc.)
   - The active link on each page MUST have class="active" — e.g., on pricing.html the Pricing link gets class="active"
   - The mobile menu MUST include ALL the same links as the desktop nav plus the CTA button
   - The menu-overlay div MUST be present and call closeMenu() on click
   - The nav-cta-desktop class hides the desktop CTA on mobile (responsive CSS handles this)

3. <section id="hero"> — Full-viewport hero with headline, subheadline, and CTAs. Background uses the CSS hero class above. Apply class "gradient-text" to the <h1> headline for a gradient effect. Add class "btn-glow" to the primary CTA button.
   ${heroImageInstruction || 'The hero section MUST have a radial gradient background using the CSS .hero class above. Add a trust line below the CTAs.'}
   ${backgroundInstruction}
   ${brandPatternInstruction}
   Add class "fade-in" to the hero content wrapper for entrance animation.

4. One <section> per enabled section from the SECTIONS list. Each section MUST:
   - Use the section name as heading and purpose/content as body text
   - Have an id attribute for navigation (id="features", id="about", etc.)
   - Use proper semantic HTML (heading levels, lists, etc.)
   - Alternate between default and .section-alt backgrounds
   - Include class "fade-in" on the section wrapper for scroll reveal animation
   - Add stagger classes to cards/items within grids: first card gets "stagger-1", second "stagger-2", etc.
   - Add class "card-hover-lift" to feature and benefit cards for hover lift effect
   - Add class "image-zoom" to image containers for hover zoom effect
   - Add class "icon-float" to feature icon containers for subtle floating animation
   - For stats/numbers sections, use the counter pattern: <span class="counter" data-target="NUMBER" data-suffix="SUFFIX">0</span>

5. <footer> — Business name, copyright year, navigation links, social links.

== JAVASCRIPT (single <script> at end of body) ==

Include ALL of the following vanilla JavaScript:

// === Scroll Reveal Animations ===
const observerOptions = { threshold: 0.1, rootMargin: '0px 0px -50px 0px' };
const observer = new IntersectionObserver((entries) => {
  entries.forEach(entry => { if (entry.isIntersecting) { entry.target.classList.add('visible'); } });
}, observerOptions);
document.querySelectorAll('.fade-in, .fade-in-left, .fade-in-right, .fade-in-up, .scale-in, .slide-up').forEach(el => observer.observe(el));

// === Safety: reveal all hidden elements after 5 seconds (fallback if observer misses any) ===
setTimeout(() => {
  document.querySelectorAll('.fade-in:not(.visible),.fade-in-left:not(.visible),.fade-in-right:not(.visible),.fade-in-up:not(.visible),.scale-in:not(.visible),.slide-up:not(.visible)').forEach(el => el.classList.add('visible'));
}, 5000);

// === Counter Animation ===
function animateCounter(el) {
  const target = parseInt(el.getAttribute('data-target'), 10);
  const suffix = el.getAttribute('data-suffix') || '';
  const duration = 2000;
  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, 3);
    const current = Math.round(eased * target);
    el.textContent = current.toLocaleString() + suffix;
    if (progress < 1) requestAnimationFrame(update);
  }
  requestAnimationFrame(update);
}
const counterObserver = new IntersectionObserver((entries) => {
  entries.forEach(entry => {
    if (entry.isIntersecting && !entry.target.dataset.animated) {
      entry.target.dataset.animated = 'true';
      animateCounter(entry.target);
    }
  });
}, { threshold: 0.3 });
document.querySelectorAll('.counter').forEach(el => counterObserver.observe(el));

// === Sticky Nav (hide on scroll down, show on scroll up) + Active Link ===
const nav = document.querySelector('.nav');
let lastScroll = 0;
const navLinks = document.querySelectorAll('.nav a[href^="#"]');
const sections = document.querySelectorAll('section[id]');
function updateActiveNav() {
  let current = '';
  sections.forEach(section => {
    const sectionTop = section.offsetTop - 100;
    if (window.scrollY >= sectionTop) current = section.getAttribute('id');
  });
  navLinks.forEach(link => {
    link.classList.remove('active');
    if (link.getAttribute('href') === '#' + current) link.classList.add('active');
  });
}
window.addEventListener('scroll', () => {
  const currentScroll = window.scrollY;
  nav.classList.toggle('scrolled', currentScroll > 50);
  if (currentScroll > lastScroll && currentScroll > 200) {
    nav.style.transform = 'translateY(-100%)';
  } else {
    nav.style.transform = 'translateY(0)';
  }
  nav.style.transition = 'transform 0.3s ease, background 0.3s ease';
  lastScroll = currentScroll;
  updateActiveNav();
});
updateActiveNav();

// === Scroll Progress Bar ===
const progressBar = document.querySelector('.scroll-progress');
if (progressBar) {
  window.addEventListener('scroll', () => {
    const scrollTop = document.documentElement.scrollTop;
    const scrollHeight = document.documentElement.scrollHeight - document.documentElement.clientHeight;
    const progress = (scrollTop / scrollHeight) * 100;
    progressBar.style.width = progress + '%';
  });
}

// === Mobile Menu ===
function toggleMenu() { document.querySelector('.mobile-menu').classList.toggle('open'); document.querySelector('.menu-overlay').classList.toggle('open'); }
function closeMenu() { document.querySelector('.mobile-menu').classList.remove('open'); document.querySelector('.menu-overlay').classList.remove('open'); }
document.querySelector('.menu-overlay')?.addEventListener('click', closeMenu);

// === Smooth Scroll ===
document.querySelectorAll('a[href^="#"]').forEach(a => { a.addEventListener('click', (e) => { e.preventDefault(); const target = document.querySelector(a.getAttribute('href')); if (target) { target.scrollIntoView({ behavior: 'smooth', block: 'start' }); closeMenu(); } }); });

== CONTENT RULES ==

- Use the EXACT section names and purposes provided in the SECTIONS list
- Where a section supplies a Headline, Subheadline, Description, Key Points or Trust Statements, USE THAT COPY VERBATIM. It was written or approved by the user — do not paraphrase it, shorten it, or replace it with your own wording. Only wrap it in the right markup.
- Every section must have REAL, SPECIFIC content — NO "Lorem ipsum", NO placeholder text, NO "[Your text here]"
- If a section lacks detail, write relevant, specific content about ${businessName} in the ${industry} industry
- Include realistic business details matching a ${industry} company
- Target audience: ${targetAudience}
- Primary CTA: "${primaryCTA}"
- Secondary CTA: "${secondaryCTA}"
- Use proper HTML semantics: <h1> only once in hero, <h2> for section headings, <h3> for subsections
- CRITICAL: NEVER use emoji characters (🎯📊🚀💡⚡🔧✅🌟 etc.) for icons — they render inconsistently across platforms and look unprofessional. ALWAYS use inline SVG icons inside .icon-feature containers instead. See the SVG ICON list in the CONTEXT-AWARE VISUALS section above for ready-to-use SVG code for common icons.
- RESPONSIVE DESIGN IS NON-NEGOTIABLE: Every page MUST include ALL 5 responsive breakpoints in the CSS (479px, 480-767px, 768-1023px, 1024-1279px, 1280px+). Every page MUST work properly on mobile (320px+), tablet (768px+), and desktop (1280px+). Test mentally that grids collapse to single columns on mobile, buttons are full-width on small screens, hero sections stack vertically, and text remains readable at all sizes.
- CRITICAL: The <nav> is position:fixed, so the hero section MUST use padding-top:80px to prevent the navbar from overlapping the hero content. Add <div class="nav-spacer"></div> immediately after </nav> as a fallback. All sections with id attributes MUST use scroll-margin-top:80px so anchor navigation doesn't hide content behind the fixed navbar.
${inputs.brandVoice ? `- Follow the brand voice: "${inputs.brandVoice}" — match this tone in ALL content` : ''}
${inputs.brandPersonality?.length ? `- Reflect these personality traits in the writing style: ${inputs.brandPersonality.join(', ')}` : ''}
${inputs.brandTagline ? `- Incorporate or reference the brand tagline "${inputs.brandTagline}" in the hero or CTA sections` : ''}
${inputs.uiStyle ? `- UI Style preference: ${inputs.uiStyle}` : '- Use a modern, professional dark-theme design'}
${inputs.animationNotes ? `- Animation notes: ${inputs.animationNotes}` : ''}
${inputs.responsiveNotes ? `- Responsive notes: ${inputs.responsiveNotes}` : ''}
${inputs.accessibilityNotes ? `- Accessibility notes: ${inputs.accessibilityNotes}` : ''}
${inputs.designSettingsDirectives?.length ? `\nWEBSITE SETTINGS (the user's explicit choices — these take precedence over the generic defaults above):\n${inputs.designSettingsDirectives.join('\n')}` : ''}

== CONTEXT-AWARE VISUALS & IMAGES ==

PRIORITY ORDER for images:
1. BRAND IMAGES (highest priority): When heroImageUrl or productImages URLs are provided, use those EXACT URLs in <img> tags. These are the company's real images — ALWAYS prefer them over anything else.
2. CSS-BASED VISUALS (second priority): When no specific image URL is provided for a section, use brand-consistent CSS visual treatments INSTEAD of random stock photos. Random photos from placeholder services look disconnected from the brand. Instead, create visual sections using:
   - Brand-colored gradient backgrounds (linear-gradient, radial-gradient using --primary, --accent, --bg-dark)
   - SVG ICONS inside .icon-feature containers — use inline SVG icons (NOT emoji). Common icons and their SVG code:
     * Target: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><circle cx="12" cy="12" r="6"/><circle cx="12" cy="12" r="2"/></svg>
     * Chart: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 20V10"/><path d="M12 20V4"/><path d="M6 20v-6"/></svg>
     * Rocket: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4.5 16.5c-1.5 1.26-2 5-2 5s3.74-.5 5-2c.71-.84.7-2.13-.09-2.91a2.18 2.18 0 0 0-2.91-.09z"/><path d="m12 15-3-3a22 22 0 0 1 2-3.95A12.88 12.88 0 0 1 22 2c0 2.72-.78 7.5-6 11a22.35 22.35 0 0 1-4 2z"/><path d="M9 12H4s.55-3.03 2-4c1.62-1.08 5 0 5 0"/><path d="M12 15v5s3.03-.55 4-2c1.08-1.62 0-5 0-5"/></svg>
     * Lightbulb: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M15 14c.2-1 .7-1.7 1.5-2.5 1-.9 1.5-2.2 1.5-3.5A6 6 0 0 0 6 8c0 1 .2 2.2 1.5 3.5.7.7 1.3 1.5 1.5 2.5"/><path d="M9 18h6"/><path d="M10 22h4"/></svg>
     * Lightning: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M13 2 3 14h9l-1 8 10-12h-9l1-8z"/></svg>
     * Wrench/Gear: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z"/></svg>
     * Check/Shield: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z"/><path d="m9 12 2 2 4-4"/></svg>
     * Star: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2"/></svg>
     * Users: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2"/><circle cx="9" cy="7" r="4"/><path d="M22 21v-2a4 4 0 0 0-3-3.87"/><path d="M16 3.13a4 4 0 0 1 0 7.75"/></svg>
     * Link: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"/><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"/></svg>
     * Globe: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><path d="M2 12h20"/><path d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z"/></svg>
     * Heart: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.82 0-3.13.83-4.5 1.75C10.63 3.83 9.32 3 7.5 3A5.5 5.5 0 0 0 2 8.5c0 2.3 1.51 4.04 3 5.5l7 7Z"/></svg>
     * Mail: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect width="20" height="16" x="2" y="4" rx="2"/><path d="m22 7-8.97 5.7a1.94 1.94 0 0 1-2.06 0L2 7"/></svg>
     * Phone: <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"/></svg>
   - CSS-only pattern decorations (dots, lines, circles) using ::before/::after pseudo-elements
   - Colored stat cards with large numbers using --accent color
   - Testimonial cards with initials in colored circles instead of random avatar photos
   - CSS border-glow cards and gradient-text headings for visual interest
3. NEVER USE PLACEHOLDER IMAGE SERVICES like picsum.photos, unsplash, or random stock photo URLs. These return generic unrelated photos that make the page look disconnected from the brand.

When creating CSS-based visuals for sections without images:
- Hero section (if no heroImageUrl): Use a rich radial-gradient background with --primary color, add floating CSS shapes or decorative dots using ::before/::after pseudo-elements. Add .gradient-text to the <h1>.
- Features section: Use .icon-feature containers with inline SVG icons (NOT emoji — emoji characters render inconsistently across platforms and look unprofessional). Each feature card should have an SVG icon + heading + description pattern. See the SVG ICON list above for common icons.
- About/Team section: Use a CSS grid with colored stat blocks and gradient accents. If team members are listed, use initials in colored circles.
- Testimonials: Use initials in colored circles (.testimonial-avatar with CSS background) instead of random face photos. Quote marks and gradient borders make testimonials visually rich.
- Gallery section: Use a CSS grid with brand-colored gradient cards showing stats, achievements, or milestones — each with an icon, number, and label.
- CTA section: Use bold gradient background (--primary to --accent) with no image needed.
- Stats/Numbers section: Use large .gradient-text numbers with labels, no images needed.

== CRITICAL: CSS AND VISIBILITY RULES ==

The <style> block is ESSENTIAL. Without it, the page renders as unstyled plain HTML.
- The <style> block MUST appear inside <head>, BEFORE the closing </head> tag
- The <style> block MUST contain ALL the CSS listed above (reset, variables, layout, typography, buttons, grid, cards, images, gallery, footer, animations, nav, hero, mobile menu, responsive breakpoints)
- The <style> block MUST be at least 4500 characters long — a full website with multiple sections, animations, responsive breakpoints, and modern interactions needs comprehensive CSS
- DO NOT truncate or abbreviate the CSS — every selector and property from the CSS REQUIREMENTS section above MUST be included
- The <style> block must come BEFORE any </head> or </html> — it cannot appear after </body>

CONTENT VISIBILITY (CRITICAL — follow these steps EXACTLY or sections will be invisible):
1. Immediately after </style> and before </head>, add: <script>document.documentElement.classList.add('js-anim')</script>
2. Right after that script, add: <noscript><style>.fade-in,.fade-in-left,.fade-in-right,.fade-in-up,.scale-in,.slide-up{opacity:1!important;transform:none!important}</style></noscript>
3. These two lines are NON-NEGOTIABLE — they ensure section content is visible even if JavaScript fails to load. Without them, ALL content with fade-in classes will be permanently invisible.
4. The JavaScript at the end of <body> MUST include the safety timeout that reveals all hidden elements after 5 seconds.

ESCAPE ALL QUOTES AND NEWLINES PROPERLY in JSON strings. The index.html content will be a large string — escape every " as \\" and every newline as \\n. Do NOT use template literals or unescaped characters.

Return ONLY the JSON object. No markdown fences. No commentary.`;

  // Build the user prompt with brand context
  const brandContextSection = buildBrandContextSection(inputs);

  // Build image summary for user prompt
  const imageSummaryParts: string[] = [];
  if (inputs.heroImageUrl) {
    imageSummaryParts.push(`HERO IMAGE URL (MUST use in hero section as <img> or background): ${inputs.heroImageUrl}`);
  }
  if (inputs.backgroundImageUrl) {
    imageSummaryParts.push(`BACKGROUND TEXTURE URL (use as subtle pattern overlay): ${inputs.backgroundImageUrl}`);
  }
  if (inputs.brandPatternUrl) {
    imageSummaryParts.push(`BRAND PATTERN URL (use as decorative overlay): ${inputs.brandPatternUrl}`);
  }
  if (inputs.productImages && inputs.productImages.length > 0) {
    imageSummaryParts.push(`PRODUCT IMAGES (use in Features, Benefits, and Product sections — these are REAL product photos, HIGHEST PRIORITY over any placeholder):`);
    inputs.productImages.forEach(p => {
      imageSummaryParts.push(`  - ${p.name}: ${p.description || 'Product image'} → ${p.url}`);
    });
  }
  const imageSummaryText = imageSummaryParts.length > 0
    ? `\n\nAVAILABLE IMAGES (use these EXACT URLs in <img> tags — these are the company's REAL images, HIGHEST PRIORITY. Product images MUST be used in Features/Benefits/Product sections):\n${imageSummaryParts.join('\n')}`
    : '\n\nNO SPECIFIC IMAGES PROVIDED — use CSS-based visual treatments (gradients, icons, patterns) as described in the CONTEXT-AWARE VISUALS section. Do NOT use random stock photos or placeholder image services.';

  // Build page info
  // Shared navigation + single-page directive. Both are set when the generator
  // asks for ONE page per AI call, which is how a multi-page site is built without
  // the response being truncated: every call still gets the full link list so the
  // navigation and footer are identical across pages.
  const navEntries = inputs.navPages || [];
  const navInstruction = navEntries.length > 0
    ? `\n\n== SHARED NAVIGATION (identical on every page — use these exact hrefs) ==\n${navEntries
        .map((n) => `- ${n.name} → href=\"${n.file}\"${n.active ? '  (THIS page — give this link class=\"active\")' : ''}`)
        .join('\n')}\nThe footer must repeat these same links.`
    : '';
  const singlePageInstruction = inputs.targetFile
    ? `\n\n== GENERATE EXACTLY ONE FILE ==\nReturn a files array containing ONLY \"${inputs.targetFile}\" — that one page, complete and self-contained (full <style> block, full JavaScript, real content). Do NOT return any other page.`
    : '';

  const pageInfo = pages.length > 0
    ? `\n\nPAGE STRUCTURE (generate a separate HTML file for each page, linked together with navigation):\n${pageDetails}`
    : '';

  // The planner's FAQs were being accepted as an input and then never written
  // into the prompt, so the AI invented its own generic questions. Pass them
  // through verbatim and require FAQ schema markup, the way the planner intends.
  const faqList = Array.isArray(inputs.faqs)
    ? inputs.faqs.filter((f: any) => f && typeof f.question === 'string' && f.question.trim())
    : [];
  const faqDetails = faqList.length > 0
    ? `\n\nFAQS (use these EXACT questions and answers — do not invent your own. Render them in an FAQ section on the page that lists an FAQ section, and emit matching FAQPage JSON-LD schema in <head>):\n${
        faqList
          .map((f: any, i: number) => `${i + 1}. Q: ${f.question}\n   A: ${f.answer || ''}`)
          .join('\n')
      }`
    : '';

  const userPrompt = `Generate a ${websiteType} website for "${businessName}" (${industry}).

Website Type: ${websiteType}
${inputs.domain ? `Domain: ${inputs.domain}` : ''}
Primary Goal: Convert ${targetAudience}
Primary CTA: "${primaryCTA}"
Secondary CTA: "${secondaryCTA}"
${inputs.country ? `Country: ${inputs.country}` : ''}
${inputs.seoTargetRegion ? `SEO Region: ${inputs.seoTargetRegion}` : ''}

${inputs.metaTitle || inputs.websiteName ? `Title: ${inputs.metaTitle || inputs.websiteName}` : ''}
${inputs.metaDescription ? `Meta Description: ${inputs.metaDescription}` : ''}

SECTIONS (include ALL of these with their content):
${sectionDetails || 'Include: Hero, Features, About, Services, Testimonials, CTA, Footer'}${pageInfo}${faqDetails}

Design:
- Primary color: ${primaryColor}
- Accent/CTA color: ${accentColor}
${secondaryColor ? `- Secondary color: ${secondaryColor}` : ''}
- Background: ${backgroundColor}
${headingFont !== 'Inter' ? `- Heading font: ${headingFont}` : ''}
${bodyFont !== 'Inter' ? `- Body font: ${bodyFont}` : ''}

${brandContextSection ? brandContextSection + '\n' : ''}${imageSummaryText}${imageSummaryText ? '\n' : ''}${inputs.targetFile ? `Generate the single HTML file \"${inputs.targetFile}\" as JSON.` : 'Generate ALL HTML files listed in the PAGE STRUCTURE as JSON.'} Each HTML file must be COMPLETE with full CSS, working JavaScript, proper navigation links to all other pages, and real content. Every page must include the same shared navigation and footer.${pages.length === 0 && !inputs.targetFile ? ' If no PAGE STRUCTURE is provided, generate a single index.html with all sections.' : ''}${navInstruction}${singlePageInstruction}

Return ONLY JSON now:`;

  // Scale maxTokens based on how many sections this page has.
  // The Home page (or any page with all sections) generates much more HTML/CSS/JS
  // than inner pages (which only have 2-4 sections). A fixed 16000 tokens is fine
  // for inner pages but too small for the Home page — it gets truncated mid-HTML,
  // resulting in missing sections, broken CSS, or no footer/JavaScript.
  // Token budget: base 16000 for small pages, +2000 per additional section beyond 4.
  const sectionCount = sections.length;
  const scaledMaxTokens = sectionCount <= 4
    ? 16000
    : Math.min(16000 + (sectionCount - 4) * 2000, 32000);

  return { systemPrompt, userPrompt, maxTokens: scaledMaxTokens };
}