expain this app and evaluate it <html lang="en">
<head>
  <base href=".">
  <title>Lyrical Storybook Creator</title>
  <style>
    /* Font Imports - Optimized */
    @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&family=Montserrat:wght@400;700&display=swap');

    /* Root Variables for Theming */
    :root {
      --primary: #9f7aea;
      --primary-light: #d6bcfa; 
      --primary-dark: #6b46c1;

      --secondary: #4fd1c5;
      --secondary-light: #9decf9;
      --secondary-dark: #319795;

      --bg-primary: #1a202c;
      --bg-secondary: #2d3748;
      --bg-surface: rgba(255, 255, 255, 0.08);

      --text-primary: #ffffff;
      --text-secondary: #e2e8f0;
      --text-muted: #a0aec0;

      --accent: #f6ad55;
      --accent-light: #fbd38d;
      --accent-dark: #dd6b20;

      --hover: rgba(255, 255, 255, 0.12);
      --active: rgba(255, 255, 255, 0.16);
      --focus: rgba(159, 122, 234, 0.6);

      --gradient-start: var(--primary);
      --gradient-end: var(--secondary);
    }

    * {
      box-sizing: border-box;
      margin: 0;
      padding: 0;
    }

    body {
      font-family: 'Roboto', sans-serif;
      color: var(--text-primary);
      background: linear-gradient(135deg, var(--bg-primary) 0%, var(--bg-secondary) 100%);
      line-height: 1.8;
      min-height: 100vh;
    }

    body::before {
      content: '';
      position: fixed;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      z-index: 0;
      opacity: 0.1;
      background-image: url("data:image/svg+xml,%3Csvg width='100' height='100' viewBox='0 0 100 100' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M50 25L25 50L50 75L75 50L50 25Z' fill='%239f7aea' opacity='0.3'/%3E%3Cpath d='M75 25L50 0L25 25L50 50L75 25Z' fill='%234fd1c5' opacity='0.3'/%3E%3Cpath d='M25 75L50 100L75 75L50 50L25 75Z' fill='%234fd1c5' opacity='0.3'/%3E%3C/svg%3E");
      background-repeat: repeat;
    }

    .app {
      position: relative;
      z-index: 1;
      max-width: 1400px;
      padding: 3rem;
    }

    /* Header Styling */
    .header {
      display: flex;
      flex-direction: column;
      align-items: center;
      text-align: center;
      margin-bottom: 4rem;
    }

    .logo {
      margin-bottom: 1rem;
      animation: fadeIn 1s ease-in-out;
    }

    .logo svg {
      filter: drop-shadow(0 4px 8px rgba(0,0,0,0.2));
      transition: transform 0.3s ease;
      width: 80px;
      height: 80px;
    }

    .logo svg:hover {
      transform: scale(1.05);
    }

    @keyframes fadeIn {
      from { opacity: 0; transform: scale(0.8); }
      to { opacity: 1; transform: scale(1); }
    }

    /* Responsive Adjustments for Logo */
    @media (max-width: 768px) {
      .logo svg {
        width: 60px;
        height: 60px;
      }
    }

    /* Header Title and Tagline */
    .header h1 {
      font-family: 'Roboto', sans-serif;
      font-size: 4rem;
      color: var(--text-primary);
      text-shadow: 0 2px 4px rgba(0,0,0,0.3);
      background: linear-gradient(45deg, var(--gradient-start), var(--gradient-end));
      -webkit-background-clip: text;
      -webkit-text-fill-color: transparent;
      margin-bottom: 2rem;
      letter-spacing: -0.5px;
    }

    .header p {
      font-family: 'Roboto', sans-serif;
      font-size: 1.5rem;
      color: var(--text-secondary);
      opacity: 0.9;
      max-width: 600px;
    }

    /* Error Message Styling */
    .error-message {
      display: none;
      background: #e53e3e;
      color: var(--text-primary);
      border: 1px solid #c53030;
      padding: 1rem;
      border-radius: 0.5rem;
      margin-bottom: 1rem;
      text-align: center;
      font-size: 1.2rem;
    }

    /* Success Message Styling */
    .error-message.success {
      background: #48bb78;
      border-color: #38a169;
    }

    /* Project Creation Section */
    .project-creation {
      background: var(--bg-surface);
      border: 1px solid rgba(255,255,255,0.1);
      border-radius: 1.5rem;
      padding: 3rem;
      margin-bottom: 4rem;
      box-shadow: 0 4px 20px rgba(0,0,0,0.2);
    }

    .input-group {
      margin-bottom: 2rem;
    }

    .input-group label {
      display: block;
      margin-bottom: 0.5rem;
      font-weight: 500;
      font-size: 1.2rem;
    }

    textarea, input, select {
      background: var(--bg-surface);
      border: 2px solid rgba(255,255,255,0.2);
      border-radius: 1rem;
      padding: 1.5rem;
      font-family: 'Roboto', sans-serif;
      font-size: 1rem;
      color: var(--text-primary);
      transition: all 0.3s ease;
      width: 100%;
    }

    textarea::placeholder,
    input::placeholder {
      color: var(--text-muted);
    }

    textarea#lyrics {
      min-height: 300px;
      width: 100%;
      line-height: 1.8;
    }

    select {
      cursor: pointer;
    }

    select option {
      background: var(--bg-secondary);
      color: var(--text-primary);
      padding: 1rem;
    }

    select:hover {
      background: #3a3f50;
    }

    select:focus {
      outline: none;
      border-color: var(--focus);
      background: #3a3f50;
    }

    textarea:focus, input:focus {
      border-color: var(--accent);
      box-shadow: 0 0 0 3px var(--focus);
    }

    /* Style Controls Grid */
    .style-controls {
      display: grid;
      grid-template-columns: repeat(3, 1fr);
      gap: 2rem;
      padding: 2rem;
      margin: 2rem 0;
      background: var(--bg-surface);
      border-radius: 0.5rem;
    }

    /* Control Buttons */
    .controls {
      display: flex;
      gap: 1rem;
      margin-top: 2rem;
      justify-content: center;
      flex-wrap: wrap;
    }

    /* Improved Button Styling */
    .btn {
      padding: 1.2rem 2.4rem;
      font-size: 1.1rem;
      border: none;
      border-radius: 0.75rem;
      cursor: pointer;
      transition: all 0.3s ease;
      display: flex;
      align-items: center;
      justify-content: center;
    }

    .btn:hover {
      transform: translateY(-2px);
      opacity: 0.9;
    }

    .btn:disabled {
      opacity: 0.5;
      cursor: not-allowed;
    }

    .btn-primary {
      background: linear-gradient(45deg, var(--primary-dark), var(--primary));
      color: var(--text-primary);
      box-shadow: 0 4px 12px rgba(0,0,0,0.1);
    }

    .btn-secondary {
      background: var(--bg-surface);
      border: 2px solid var(--secondary);
      color: var(--text-primary);
    }

    #resetBtn {
      border: 2px solid var(--accent);
      color: var(--accent);
      background: var(--bg-surface);
    }

    #resetBtn:hover {
      background: var(--accent-light);
      border-color: var(--gradient-end);
      color: var(--gradient-end);
    }

    .btn.generating {
      position: relative;
    }

    .btn.generating::after {
      content: '';
      position: absolute;
      width: 1rem;
      height: 1rem;
      border: 2px solid #fff;
      border-radius: 50%;
      border-left-color: transparent;
      margin-left: 0.5rem;
      animation: spin 1s linear infinite;
    }

    @keyframes spin {
      to { transform: rotate(360deg); }
    }

    /* Storybook Container */
    .storybook-container {
      background: var(--bg-surface);
      border: 1px solid rgba(255,255,255,0.15);
      border-radius: 1.5rem;
      padding: 4rem;
      margin-top: 3rem;
      box-shadow: 0 8px 32px rgba(0,0,0,0.2);
      position: relative;
      overflow: hidden;
    }

    /* Preview Area */
    #previewArea {
      color: #ffffff;
      min-height: 400px;
    }

    /* Storybook Page Styles */
    .storybook-page {
      display: flex;
      flex-direction: column;
      align-items: center;
      text-align: center; 
      margin-bottom: 2rem;
      opacity: 0.7;
    }

    .storybook-page.layout-spread {
      flex-direction: column;
    }

    /* Responsive Grid Layout */
    @media (max-width: 768px) {
      .storybook-page {
        padding: 1rem;
      }
    }

    .page-illustration {
      min-height: 400px;
      border-radius: 1rem;
      overflow: hidden;
      flex: 1;
      margin-bottom: 1rem;
      position: relative;
      background: var(--bg-surface);
    }

    .page-illustration::before {
      content: "Loading...";
      position: absolute;
      top: 50%;
      left: 50%;
      transform: translate(-50%, -50%);
      color: var(--text-secondary);
      font-family: 'Roboto', sans-serif;
    }

    .page-illustration img {
      width: 100%;
      height: 100%;
      object-fit: cover;
      transition: transform 0.3s ease;
      opacity: 0;
      animation: fadeIn 0.5s ease-in forwards;
    }

    @keyframes fadeIn {
      from { opacity: 0; }
      to { opacity: 1; }
    }

    .storybook-page.layout-spread .page-illustration {
      margin-bottom: 0;
    }

    .page-text {
      font-family: 'Roboto', sans-serif;
      font-size: 1.1rem;
      line-height: 1.8;
      color: var(--text-primary);
      padding: 1.5rem 2rem;
      background: var(--bg-surface);
      border-radius: 1rem;
      margin-top: 1rem; 
      width: 100%;
      box-sizing: border-box;
    }

    /* Page Controls */
    .page-controls {
      display: flex;
      justify-content: center;
      align-items: center;
      gap: 2rem;
      margin-top: 3rem;
    }

    .page-btn {
      background: linear-gradient(45deg, var(--primary-dark), var(--primary));
      color: var(--text-primary);
      border: none;
      padding: 0.75rem 1.5rem;
      border-radius: 0.75rem;
      font-family: 'Roboto', sans-serif;
      font-weight: 600;
      box-shadow: 0 4px 12px rgba(0,0,0,0.1);
      transition: all 0.3s ease;
    }

    .page-btn:hover {
      transform: translateY(-3px); 
    }

    /* Page Transition Animation */
    @keyframes pageFlip {
      from { transform: rotateY(0deg); }
      to { transform: rotateY(360deg); }
    }

    .page-transition {
      animation: pageFlip 0.6s ease;
    }

  </style>
  <meta name="referrer" content="no-referrer">
  <meta http-equiv="Cross-Origin-Opener-Policy" content="same-origin">
  <meta http-equiv="Cross-Origin-Embedder-Policy" content="require-corp">
  <script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.5.1/jspdf.umd.min.js"></script>
  <script>
    class PollinationsAPI {
      static retryDelay = 300;
      static maxRetries = 3;
      static requestQueue = [];
      static isProcessingQueue = false;
      static rateLimitDelay = 1000; // 1 second between requests

      static async fetchWithRetry(url, options = {}, retries = this.maxRetries) {
        try {
          const response = await fetch(url, options);
          
          if (response.status === 429) {
            throw new Error('RATE_LIMIT');
          }
          
          if (!response.ok) {
            throw new Error('FETCH_ERROR');
          }
          
          return response;
        } catch (error) {
          if (retries === 0) throw error;
          
          if (error.message === 'RATE_LIMIT') {
            await new Promise(res => setTimeout(res, this.rateLimitDelay));
          } else {
            await new Promise(res => setTimeout(res, this.retryDelay * (this.maxRetries - retries + 1)));
          }
          
          return this.fetchWithRetry(url, options, retries - 1);
        }
      }

      static async queueRequest(requestFn) {
        return new Promise((resolve, reject) => {
          this.requestQueue.push({
            requestFn,
            resolve,
            reject
          });
          
          if (!this.isProcessingQueue) {
            this.processQueue();
          }
        });
      }

      static async processQueue() {
        if (this.requestQueue.length === 0) {
          this.isProcessingQueue = false;
          return;
        }

        this.isProcessingQueue = true;
        const {requestFn, resolve, reject} = this.requestQueue.shift();

        try {
          const result = await requestFn();
          resolve(result);
        } catch (error) {
          reject(error);
        }

        await new Promise(res => setTimeout(res, this.rateLimitDelay));
        this.processQueue();
      }

      static async generateText(prompt) {
        return this.queueRequest(async () => {
          try {
            const url = `https://text.pollinations.ai/${encodeURIComponent(prompt)}`;
            const response = await this.fetchWithRetry(url);
            return response.text();
          } catch (error) {
            if (error.message === 'RATE_LIMIT') {
              throw new Error('Rate limit exceeded. Please try again in a moment.');
            }
            throw new Error('Failed to generate text. Please try again.');
          }
        });
      }

      static async generateImage(prompt, settings = {}) {
        return this.queueRequest(async () => {
          const baseUrl = 'https://image.pollinations.ai/prompt/';
          const params = new URLSearchParams({
            width: settings.width || 1280,
            height: settings.height || 720,
            seed: settings.seed || Math.floor(Math.random() * 1000000),
            nologo: 'true',
            private: 'true',
            // Add cache buster to prevent caching
            t: Date.now()
          });
          
          const encodedPrompt = encodeURIComponent(prompt);
          const url = `${baseUrl}${encodedPrompt}?${params}`;
          
          try {
            const response = await this.fetchWithRetry(url);
            return response.url;
          } catch (error) {
            if (error.message === 'RATE_LIMIT') {
              throw new Error('Rate limit exceeded. Please try again in a moment.');
            }
            throw new Error('Failed to generate image. Please try again.');
          }
        });
      }
    }

    class LyricalStorybookCreator {
      constructor() {
        this.currentPage = 0;
        this.pages = [];
        this.isGenerating = false;
        this.defaultSettings = {
          lyrics: '',
          theme: '',
          styleFilter: 'watercolor',
          bookLayout: 'single',
          textStyle: 'storybook'
        };

        this.selectedStyle = null;
        this.init();
      }

      init() {
        this.applyStylesBtn = document.getElementById('applyStylesBtn');
        this.generateBtn = document.getElementById('generateBtn');
        this.exportBtn = document.getElementById('exportBtn');
        this.resetBtn = document.getElementById('resetBtn');
        this.previewArea = document.getElementById('previewArea');
        
        this.bindEvents();
      }

      bindEvents() {
        this.applyStylesBtn.addEventListener('click', () => this.applyStyles());
        this.generateBtn.addEventListener('click', () => this.generatePages());
        this.exportBtn.addEventListener('click', () => this.exportStorybook());
        this.resetBtn.addEventListener('click', () => this.resetApp());
      }

      showError(message) {
        const errorMessage = document.getElementById('errorMessage');
        errorMessage.textContent = message;
        errorMessage.classList.remove('success');
        errorMessage.classList.add('error');
        errorMessage.style.display = 'block';
        setTimeout(() => {
          errorMessage.style.display = 'none';
        }, 5000);
      }

      showSuccess(message) {
        const errorMessage = document.getElementById('errorMessage');
        errorMessage.textContent = message;
        errorMessage.classList.remove('error');
        errorMessage.classList.add('success');
        errorMessage.style.display = 'block';
        setTimeout(() => {
          errorMessage.style.display = 'none';
          errorMessage.classList.remove('success');
          errorMessage.classList.add('error');
        }, 3000);
      }

      async generatePages() {
        if (this.isGenerating) return;
        
        const lyrics = document.getElementById('lyrics').value;
        const theme = document.getElementById('theme').value;
        
        if (!lyrics || !theme) {
          this.showError('Please enter both lyrics and theme');
          return;
        }

        if (!this.selectedStyle) {
          this.showError('Please apply your style settings first');
          return;
        }

        this.isGenerating = true;
        this.generateBtn.classList.add('generating');
        this.generateBtn.textContent = 'Generating...';
        this.generateBtn.disabled = true;

        try {
          // Split lyrics into 3-4 segments
          const rawSegments = lyrics.split('\n\n').filter(seg => seg.trim());
          let segments;
          
          if (rawSegments.length <= 4) {
            segments = rawSegments;
          } else {
            // Combine segments to get 3-4 balanced pieces
            const targetSegments = rawSegments.length > 6 ? 4 : 3;
            segments = [];
            const segmentsPerGroup = Math.ceil(rawSegments.length / targetSegments);
            
            for (let i = 0; i < rawSegments.length; i += segmentsPerGroup) {
              segments.push(rawSegments.slice(i, i + segmentsPerGroup).join('\n\n'));
            }
          }

          this.pages = [];
          
          for (let i = 0; i < segments.length; ) {
            // Generate first page
            const scenePrompt1 = await PollinationsAPI.generateText(
              `Create a vivid, detailed description for a storybook illustration. 
               Context: These song lyrics: "${segments[i]}"
               Theme: ${theme}
               Style: ${this.selectedStyle.style}
               Consider:
               - The emotional tone and mood
               - Key symbols and metaphors
               - Color palette and lighting
               - Character expressions and poses
               - Environmental details and setting
               - Composition and focal points
               Describe the scene in rich, artistic detail.`
            );

            const imagePrompt1 = `${this.selectedStyle.style} illustration style, 
              masterpiece, professional storybook art, 
              highly detailed, dramatic lighting, vibrant colors, 
              ${theme}, ${scenePrompt1}, 
              trending on artstation, award winning book illustration, 
              artistic masterpiece`;

            const imageUrl1 = await PollinationsAPI.generateImage(
              imagePrompt1,
              {
                width: 1280,
                height: 720,
                seed: Math.floor(Math.random() * 1000000)
              }
            );

            const page1 = {
              lyrics: segments[i],
              description: scenePrompt1,
              imageUrl: imageUrl1,
            };
            i++;

            this.pages.push(page1);
            this.showPage(this.pages.length - 1);
          }

        } catch (error) {
          console.error('Error generating pages:', error);
          this.showError('Error generating pages: ' + error.message);
        } finally {
          this.isGenerating = false;
          this.generateBtn.classList.remove('generating');
          this.generateBtn.textContent = 'Generate Storybook';
          this.generateBtn.disabled = false;
        }
      }

      async applyStyles() {
        const style = document.getElementById('styleFilter').value;
        const layout = document.getElementById('bookLayout').value;
        const textStyle = document.getElementById('textStyle').value;

        // Store the selected styles for later use during generation
        this.selectedStyle = {
          style,
          layout,
          textStyle
        };

        // Update preview area to reflect style choices
        this.previewArea.innerHTML = `
          <div class="storybook-page layout-${layout}">
            <div class="page-illustration">
              <div style="width: 100%; height: 300px; background: var(--bg-surface); border-radius: 1rem; display: flex; align-items: center; justify-content: center;">
                <p style="color: var(--text-secondary);">Styles Applied: ${style} style with ${layout} layout</p>
              </div>
            </div>
            <div class="page-text" style="font-family: ${this.getTextStyleFont(textStyle)}">
              <p>Your selected styles have been applied. Click "Generate Storybook" to create your storybook with these styles!</p>
            </div>
          </div>
        `;

        // Enable the generate button
        this.generateBtn.disabled = false;

        // Show success message
        this.showSuccess('Styles applied! You can now generate your storybook.');
      }

      getTextStyleFont(style) {
        switch(style) {
          case 'storybook': 
            return '"Roboto", sans-serif'; 
          case 'elegant': 
            return '"Montserrat", sans-serif'; 
          case 'modern': 
            return '"Helvetica", sans-serif'; 
          case 'handwritten': 
            return '"Courier", monospace'; 
          case 'classic': 
            return '"Times", serif'; 
          case 'minimalist': 
            return '"Arial", sans-serif'; 
          default: 
            return '"Roboto", sans-serif';
        }
      }

      async exportStorybook() {
        try {
          const { jsPDF } = window.jspdf;
          const doc = new jsPDF({
            orientation: 'portrait',
            unit: 'px',
            format: 'a4',
          });

          // Set the font for the PDF based on text style
          const pdfFont = this.getPDFFont(this.selectedStyle.textStyle);
          doc.setFont(pdfFont);
          doc.setFontSize(12);

          this.exportBtn.disabled = true;
          this.exportBtn.textContent = 'Exporting...';

          for (let i = 0; i < this.pages.length; i++) {
            const page = this.pages[i];
            
            if (this.selectedStyle.layout === 'spread' && i % 2 === 1) continue; 

            if (i > 0 && this.selectedStyle.layout !== 'spread') doc.addPage();

            try {
              const img = new Image();
              img.crossOrigin = 'Anonymous';  
              img.src = page.imageUrl;
              
              const canvas = document.createElement('canvas');
              canvas.width = img.width;
              canvas.height = img.height;
              const ctx = canvas.getContext('2d');
              ctx.drawImage(img, 0, 0);
              const imgData = canvas.toDataURL('JPEG', 0.95);

              const pdfWidth = doc.internal.pageSize.getWidth();
              const pdfHeight = (img.height * pdfWidth) / img.width;
              doc.addImage(imgData, 'JPEG', 0, 0, pdfWidth, pdfHeight);

              const textY = pdfHeight + 10;
              const lines = doc.splitTextToSize(page.lyrics, pdfWidth - 20);
              doc.text(lines, 10, textY);

              // For spread layout, handle two pages together
              if (this.selectedStyle.layout === 'spread' && this.pages[i + 1]) {
                const nextPage = this.pages[i + 1];
                const img2 = new Image();
                img2.crossOrigin = 'Anonymous';  
                img2.src = nextPage.imageUrl;
                
                const canvas2 = document.createElement('canvas');
                canvas2.width = img2.width;
                canvas2.height = img2.height;
                const ctx2 = canvas2.getContext('2d');
                ctx2.drawImage(img2, 0, 0);
                const imgData2 = canvas2.toDataURL('JPEG', 0.95);

                doc.addPage();

                const pdfHeight2 = (img2.height * pdfWidth) / img2.width;
                doc.addImage(imgData2, 'JPEG', 0, 0, pdfWidth, pdfHeight2);

                const lines2 = doc.splitTextToSize(nextPage.lyrics, pdfWidth - 20);
                doc.text(lines2, 10, pdfHeight2 + 10);

                i++; 
              }

            } catch (err) {
              console.error('Error processing page:', err);
              this.showError(`Error processing page ${i + 1}`);
            }
          }
          
          doc.save('lyrical_storybook.pdf');
        } catch (error) {
          console.error('Error exporting storybook:', error);
          this.showError('Failed to export storybook: ' + error.message);
        } finally {
          this.exportBtn.disabled = false;
          this.exportBtn.textContent = 'Export Storybook';
        }
      }

      getPDFFont(style) {
        const fontMap = {
          'storybook': 'helvetica',
          'elegant': 'helvetica', 
          'modern': 'helvetica',
          'handwritten': 'courier',
          'classic': 'times',
          'minimalist': 'helvetica'
        };
        return fontMap[style] || 'helvetica';
      }

      resetApp() {
        document.getElementById('lyrics').value = this.defaultSettings.lyrics;
        document.getElementById('theme').value = this.defaultSettings.theme;
        document.getElementById('styleFilter').value = this.defaultSettings.styleFilter;
        document.getElementById('bookLayout').value = this.defaultSettings.bookLayout;
        document.getElementById('textStyle').value = this.defaultSettings.textStyle;

        this.previewArea.innerHTML = '<p>Preview will appear here</p>';

        this.pages = [];
        this.currentPage = 0;
        this.isGenerating = false;
        this.selectedStyle = null;

        const errorMessage = document.getElementById('errorMessage');
        errorMessage.style.display = 'none';
        errorMessage.classList.remove('success');
        errorMessage.classList.add('error');

        this.generateBtn.classList.remove('generating');
        this.generateBtn.textContent = 'Generate Storybook';
        this.generateBtn.disabled = false;
        this.exportBtn.disabled = false;
        this.exportBtn.textContent = 'Export Storybook';
      }

      showPage(index) {
        if (index >= 0 && index < this.pages.length) {
          this.currentPage = index;
          const page = this.pages[index];

          // Get the selected text style font
          const textStyleFont = this.getTextStyleFont(this.selectedStyle.textStyle);
          const layoutClass = `layout-${this.selectedStyle.layout}`;

          const img = new Image();
          img.crossOrigin = "Anonymous";  
          img.src = page.imageUrl;
          
          img.onload = () => {
            this.previewArea.innerHTML = `
              <div class="storybook-page page-transition ${layoutClass}">
                <div class="page-illustration">
                  <img src="${page.imageUrl}" 
                       alt="Generated story illustration" 
                       width="1280" 
                       height="720"
                       crossorigin="anonymous">
                </div>
                <div class="page-text" style="font-family: ${textStyleFont};">
                  <p>${page.lyrics}</p>
                </div>
              </div>
              <div class="page-controls">
                <button class="page-btn" onclick="lyricalStorybookCreator.previousPage()" ${index === 0 ? 'disabled' : ''} aria-label="Previous Page">Previous</button>
                <span>Page ${index + 1} of ${this.pages.length}</span>
                <button class="page-btn" onclick="lyricalStorybookCreator.nextPage()" ${index === this.pages.length - 1 ? 'disabled' : ''} aria-label="Next Page">Next</button>
              </div>
            `;
          };

          img.onerror = () => {
            console.error('Failed to load image:', page.imageUrl);
            this.showError('Failed to load image. Please try regenerating.');
          };
        }
      }

      nextPage() {
        if (this.currentPage < this.pages.length - 1) {
          this.currentPage++;
          this.showPage(this.currentPage);
        }
      }

      previousPage() {
        if (this.currentPage > 0) {
          this.currentPage--;
          this.showPage(this.currentPage);
        }
      }
    }

    document.addEventListener('DOMContentLoaded', () => {
      window.lyricalStorybookCreator = new LyricalStorybookCreator();
    });
  </script>
  <meta name="referrer" content="no-referrer">
</head>
<body>
  <div class="app">
    <header class="header">
      <!-- Logo SVG -->
      <div class="logo">
        <svg width="80" height="80" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" aria-labelledby="logoTitle" role="img">
          <title id="logoTitle">Lyrical Storybook Creator Logo</title>
          <circle cx="50" cy="50" r="48" fill="var(--bg-surface)" stroke="var(--primary)" stroke-width="2"></circle>
          <path d="M25 35 Q50 30 75 35 L75 65 Q50 60 25 65 Z" fill="none" stroke="var(--primary)" stroke-width="3"></path>
          <path d="M50 30 L50 60" fill="none" stroke="var(--primary)" stroke-width="2"></path>
          <path d="M35 45 Q38 42 38 48 L38 55 Q35 58 32 55 Q32 52 35 52 Z" fill="var(--accent)"></path>
          <path d="M65 42 Q68 39 68 45 L68 52 Q65 55 62 52 Q62 49 65 49 Z" fill="var(--accent)"></path>
          <path d="M20 70 Q35 65 50 70 Q65 75 80 70" fill="none" stroke="var(--secondary)" stroke-width="2" opacity="0.8"></path>
          <path d="M30 25 L32 30 L27 28 L33 28 L28 30 Z" fill="var(--accent-light)"></path>
          <path d="M70 25 L72 30 L67 28 L73 28 L68 30 Z" fill="var(--accent-light)"></path>
        </svg>
      </div>
      <h1>Lyrical Storybook Creator</h1>
      <p style="font-family: 'Roboto', sans-serif; font-size: 1.8rem; margin-top: 0.5rem;">Transform your lyrics into an illustrated storybook journey</p>
    </header>

    <div class="error-message" id="errorMessage" role="alert"></div>

    <section class="project-creation">
      <div class="input-group">
        <label for="lyrics" style="font-size: 1.5rem; text-align: center; display: block; margin: 0 auto;">Song Lyrics</label>
        <textarea id="lyrics" rows="12" placeholder="Paste your lyrics here..." aria-label="Song Lyrics"></textarea>
      </div>

      <div class="input-group">
        <label for="theme" aria-label="Theme and Mood">Theme &amp; Mood</label>
        <input type="text" id="theme" placeholder="e.g., Magical forest adventure, Cosmic journey through space, Urban night romance" aria-label="Theme and Mood">
      </div>

      <div class="style-controls">
        <div class="input-group">
          <label for="styleFilter" aria-label="Art Style">Art Style</label>
          <select id="styleFilter" aria-label="Art Style">
            <option value="watercolor">Watercolor</option>
            <option value="digital-art">Digital Art</option>
            <option value="oil-painting">Oil Painting</option>
            <option value="anime">Anime Style</option>
            <option value="3d-render">3D Render</option>
            <option value="photorealistic">Photorealistic</option>
            <option value="comic-book">Comic Book</option>
            <option value="children-book">Children's Book</option>
            <option value="concept-art">Concept Art</option>
            <option value="fantasy-art">Fantasy Art</option>
          </select>
        </div>

        <div class="input-group">
          <label for="bookLayout" aria-label="Page Layout">Page Layout</label>
          <select id="bookLayout" aria-label="Page Layout">
            <option value="single">Single Page</option>
            <option value="spread">Double Spread</option>
          </select>
        </div>

        <div class="input-group">
          <label for="textStyle" aria-label="Text Style">Text Style</label>
          <select id="textStyle" aria-label="Text Style">
            <option value="storybook">Storybook (Roboto)</option>
            <option value="elegant">Elegant (Montserrat)</option>
            <option value="modern">Modern (Helvetica)</option>
            <option value="handwritten">Courier</option>
            <option value="classic">Times</option>
            <option value="minimalist">Arial</option>
          </select>
        </div>
      </div>

      <div class="controls">
        <button class="btn btn-primary" id="applyStylesBtn" aria-label="Apply Styles">Apply Styles</button>
        <button class="btn btn-primary" id="generateBtn" aria-label="Generate Storybook">Generate Storybook</button>
        <button class="btn btn-secondary" id="exportBtn" aria-label="Export Storybook">Export Storybook</button>
        <button class="btn btn-secondary" id="resetBtn" aria-label="Reset Application">Reset</button>
      </div>
    </section>

    <div class="storybook-container">
      <div class="preview-content" id="previewArea" aria-live="polite">
        <p>Preview will appear here</p>
      </div>
    </div>
  </div>
</body>
</html>