<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, viewport-fit=cover">
    <title>SVG viewer</title>
    <style>
        body {
            margin: 0;
            padding: 10px;
            font-family: system-ui, -apple-system, sans-serif;
            min-height: 100vh;
            /* Prevent content shift on mobile when keyboard appears */
            min-height: -webkit-fill-available;
        }

        .container {
            display: flex;
            gap: 10px;
            height: calc(100vh - 20px);
            /* Support for mobile browsers */
            height: calc(100vh - 20px - env(safe-area-inset-bottom));
        }

        .editor, .preview {
            flex: 1;
            display: flex;
            flex-direction: column;
            min-height: 200px; /* Ensure minimum height on mobile */
        }

        textarea {
            flex: 1;
            resize: none;
            padding: 10px;
            font-family: monospace;
            font-size: 14px;
            border: 1px solid #ccc;
            border-radius: 4px;
            /* Improve mobile experience */
            -webkit-overflow-scrolling: touch;
            /* Prevent zoom on mobile devices */
            font-size: 16px;
        }

        canvas {
            flex: 1;
            border: 1px solid #ccc;
            border-radius: 4px;
            background: white;
        }

        h2 {
            margin-top: 0;
            margin-bottom: 10px;
            font-size: 16px;
        }

        .toolbar {
            display: flex;
            gap: 8px;
            margin-bottom: 16px; /* Increased margin for more space below */
            flex-wrap: wrap;
            justify-content: space-between; /* Align error message to the right */
        }

        .toolbar button {
            /* Improve touch targets */
            min-height: 44px;
            padding: 8px 16px;
            /* Prevent text wrapping inside button */
            white-space: nowrap;
            /* Add visual feedback for touch */
            transition: background-color 0.2s;
            -webkit-touch-callout: none;
            user-select: none;
            border: 1px solid #ccc;
            border-radius: 6px;
            background: #f8f8f8;
        }

        .toolbar button:active {
            background-color: #e0e0e0;
        }

        @media (min-width: 1024px) {
            .toolbar {
                flex-wrap: nowrap;
                overflow-x: auto;
                -webkit-overflow-scrolling: touch;
                scrollbar-width: none;
                -ms-overflow-style: none;
                scroll-snap-type: x mandatory;
            }

            .toolbar::-webkit-scrollbar {
                display: none;
            }

            .toolbar button {
                scroll-snap-align: start;
            }
        }

        /* Medium and small screens - stacked buttons */
        @media (max-width: 1023px) {
            .toolbar {
                flex-direction: column;
                width: 100%;
                gap: 4px;
            }

            .toolbar button {
                width: 100%;
                text-align: left;
                justify-content: flex-start;
                padding: 12px 16px;
            }
        }

        /* Small mobile optimization */
        @media (max-width: 480px) {
            .toolbar button {
                padding: 10px 14px;
                font-size: 14px;
            }
        }

        /* Landscape mode optimization */
        @media (orientation: landscape) and (max-height: 500px) {
            .toolbar {
                /* Revert to horizontal scroll for landscape */
                flex-direction: row;
                flex-wrap: nowrap;
                overflow-x: auto;
            }

            .toolbar button {
                width: auto;
                padding: 8px 16px;
                background-image: none;
            }
        }

        /* Media query for mobile devices */
        @media (max-width: 768px) {
            .container {
                flex-direction: column;
                height: auto;
                min-height: 100vh;
            }

            .editor, .preview {
                flex: none;
                height: calc(50vh - 30px); /* Half viewport minus some spacing */
                overflow: hidden; /* Contain scrolling children */
                display: flex;
                flex-direction: column;
            }

            .toolbar {
                flex-direction: column;
                width: 100%;
                gap: 12px; /* Increased gap for more space between buttons */
            }

            textarea, canvas {
                min-height: 200px; /* Minimum height */
                height: 100%;
                overflow-y: auto; /* Enable vertical scrolling */
            }

            h2 {
                font-size: 14px;
                margin-bottom: 8px;
                flex-shrink: 0; /* Prevent header from shrinking */
            }
        }

        /* Landscape mode optimization */
        @media (orientation: landscape) {
            .container {
                flex-direction: row;
                height: calc(100vh - 20px);
            }

            .editor, .preview {
                width: 50%;
                height: 100%;
                overflow: hidden; /* Contain scrolling children */
            }

            .toolbar {
                flex-direction: row;
                flex-wrap: wrap;
                flex-shrink: 0; /* Prevent toolbar from shrinking */
            }
        }

        /* Support for notched phones */
        @supports (padding: max(0px)) {
            body {
                padding-left: max(10px, env(safe-area-inset-left));
                padding-right: max(10px, env(safe-area-inset-right));
                padding-bottom: max(10px, env(safe-area-inset-bottom));
            }
        }

        /* Focus styles for better keyboard navigation */
        .toolbar button:focus {
            outline: 2px solid #0066cc;
            outline-offset: 2px;
        }

        /* High contrast focus indicator for canvas */
        canvas:focus {
            outline: 3px solid #0066cc;
        }

        /* Error message styling */
        .error-message {
            color: #cc0000;
            font-size: 14px;
            margin-top: 4px;
            display: none;
            flex-grow: 1; /* Allow error message to take available space */
            text-align: right; /* Align text to the right */
        }

        /* Enhance focus visibility for WCAG 2.4.7 */
        *:focus {
            outline: 3px solid #0066cc;
            outline-offset: 2px;
        }

        /* Add focus-visible for modern browsers */
        *:focus:not(:focus-visible) {
            outline: none;
        }
        
        *:focus-visible {
            outline: 3px solid #0066cc;
            outline-offset: 2px;
        }

        /* High contrast mode support */
        @media (forced-colors: active) {
            .toolbar button {
                border: 1px solid ButtonBorder;
                background: ButtonFace;
                color: ButtonText;
            }
            
            canvas, textarea {
                border: 1px solid ButtonBorder;
            }
        }

        .export-buttons {
            display: flex;
            gap: 8px;
            margin-top: 8px;
        }

        .export-buttons button {
            min-height: 44px;
            padding: 8px 16px;
            white-space: nowrap;
            transition: background-color 0.2s;
            -webkit-touch-callout: none;
            user-select: none;
            border: 1px solid #ccc;
            border-radius: 6px;
            background: #f8f8f8;
        }

        .export-buttons button:active {
            background-color: #e0e0e0;
        }
    </style>
</head>
<body>
    <main>
        <div class="container" role="application" aria-label="SVG Editor Application">
            <div class="editor">
                <h2 id="editor-label">SVG Editor</h2>
                <div class="toolbar" role="toolbar" aria-label="Error message">
                    <div id="error-message" class="error-message" role="alert"></div>
                </div>
                <textarea 
                    id="svgInput" 
                    spellcheck="false"
                    aria-labelledby="editor-label"
                    aria-describedby="editor-desc error-message"
                    role="textbox"
                >&lt;svg width="200" height="200" xmlns="http://www.w3.org/2000/svg"&gt;
    &lt;circle cx="100" cy="100" r="50" fill="blue" /&gt;
&lt;/svg&gt;</textarea>
                <div class="export-buttons">
                    <button onclick="exportSVG()" aria-label="Export as SVG file">Export SVG</button>
                    <button onclick="exportPNG()" aria-label="Export as PNG image">Export PNG</button>
                </div>
            </div>
            <div class="preview">
                <h2 id="preview-label">Preview</h2>
                <canvas 
                    id="preview" 
                    role="img" 
                    aria-labelledby="preview-label"
                    tabindex="0"
                ></canvas>
            </div>
        </div>
    </main>

    <script>
        const textarea = document.getElementById('svgInput');
        const canvas = document.getElementById('preview');
        const ctx = canvas.getContext('2d');

        // Function to convert SVG string to image data
        const svgToImage = (svgString) => {
            const blob = new Blob([svgString], { type: 'image/svg+xml' });
            const url = URL.createObjectURL(blob);
            return new Promise((resolve, reject) => {
                const img = new Image();
                img.onload = () => {
                    URL.revokeObjectURL(url);
                    resolve(img);
                };
                img.onerror = () => {
                    URL.revokeObjectURL(url);
                    reject(new Error('Failed to load SVG'));
                };
                img.src = url;
            });
        };

        // Function to parse SVG and check for syntax errors
        const checkSVG = (svgString) => {
            const parser = new DOMParser();
            const doc = parser.parseFromString(svgString, 'image/svg+xml');
            const errorNode = doc.querySelector('parsererror');
            return errorNode ? errorNode.textContent : null;
        };

        // Function to update the preview
        const updatePreview = async () => {
            const errorMessage = document.getElementById('error-message');
            const svgString = textarea.value;
            const error = checkSVG(svgString);

            if (error) {
                errorMessage.style.display = 'block';
                errorMessage.textContent = `SVG Syntax Error: ${error}`;
                canvas.setAttribute('aria-label', 'Preview unavailable due to SVG error');
                return;
            }

            try {
                const img = await svgToImage(svgString);
                
                // Set canvas size to match its display size
                const rect = canvas.getBoundingClientRect();
                canvas.width = rect.width;
                canvas.height = rect.height;
                
                // Clear canvas
                ctx.clearRect(0, 0, canvas.width, canvas.height);
                
                // Calculate scaling to fit SVG while maintaining aspect ratio
                const scale = Math.min(
                    canvas.width / img.width,
                    canvas.height / img.height
                );
                
                // Center the image
                const x = (canvas.width - img.width * scale) / 2;
                const y = (canvas.height - img.height * scale) / 2;
                
                // Draw scaled image
                ctx.drawImage(img, x, y, img.width * scale, img.height * scale);

                errorMessage.style.display = 'none';
                errorMessage.textContent = '';
                canvas.setAttribute('aria-label', 'SVG preview showing current editor content');
            } catch (error) {
                console.error('Error updating preview:', error);
                errorMessage.style.display = 'block';
                errorMessage.textContent = 'Error in SVG syntax. Please check your markup.';
                canvas.setAttribute('aria-label', 'Preview unavailable due to SVG error');
            }
        };

        // Update preview when text changes
        textarea.addEventListener('input', () => {
            updatePreview();
        });

        // Handle window resize
        window.addEventListener('resize', () => {
            updatePreview();
        });

        // Initial preview
        updatePreview();

        // Template functions for SVG shapes
        const shapeTemplates = {
            rect: '    <rect x="10" y="10" width="100" height="80" fill="red" />\n',
            circle: '    <circle cx="100" cy="100" r="50" fill="blue" />\n',
            ellipse: '    <ellipse cx="100" cy="100" rx="80" ry="50" fill="green" />\n',
            line: '    <line x1="10" y1="10" x2="190" y2="190" stroke="black" stroke-width="2" />\n',
            path: '    <path d="M 10,10 L 100,10 L 100,100 Z" fill="purple" />\n',
            text: '    <text x="100" y="100" text-anchor="middle">Hello SVG</text>\n'
        };

        // Function to insert template at cursor position
        const insertShape = (shapeType) => {
            const template = shapeTemplates[shapeType];
            const start = textarea.selectionStart;
            const end = textarea.selectionEnd;
            const text = textarea.value;
            
            // Find the closing </svg> tag
            const closingTag = '</svg>';
            const closingTagIndex = text.lastIndexOf(closingTag);
            
            if (closingTagIndex !== -1) {
                // Insert the new shape before the closing tag
                const newText = 
                    text.substring(0, closingTagIndex) +
                    template +
                    text.substring(closingTagIndex);
                
                textarea.value = newText;
                updatePreview();
                
                // Set cursor after inserted template
                const newPosition = closingTagIndex + template.length;
                textarea.setSelectionRange(newPosition, newPosition);
                textarea.focus();
            }
        };

        // Keyboard handling for toolbar
        document.querySelector('.toolbar').addEventListener('keydown', (e) => {
            const buttons = Array.from(e.currentTarget.querySelectorAll('button'));
            const currentIndex = buttons.indexOf(document.activeElement);
            
            switch(e.key) {
                case 'ArrowRight':
                case 'ArrowDown':
                    e.preventDefault();
                    buttons[(currentIndex + 1) % buttons.length].focus();
                    break;
                case 'ArrowLeft':
                case 'ArrowUp':
                    e.preventDefault();
                    buttons[(currentIndex - 1 + buttons.length) % buttons.length].focus();
                    break;
            }
        });

        // Announce successful exports
        const announceExport = (format) => {
            const message = `${format} file exported successfully`;
            const announcement = document.createElement('div');
            announcement.setAttribute('role', 'status');
            announcement.setAttribute('aria-live', 'polite');
            announcement.style.position = 'absolute';
            announcement.style.width = '1px';
            announcement.style.height = '1px';
            announcement.style.overflow = 'hidden';
            announcement.textContent = message;
            document.body.appendChild(announcement);
            setTimeout(() => document.body.removeChild(announcement), 1000);
        };

        // Update export functions
        const exportSVG = () => {
            const svgBlob = new Blob([textarea.value], { type: 'image/svg+xml' });
            const url = URL.createObjectURL(svgBlob);
            const link = document.createElement('a');
            link.href = url;
            link.download = 'drawing.svg';
            document.body.appendChild(link);
            link.click();
            document.body.removeChild(link);
            URL.revokeObjectURL(url);
            announceExport('SVG');
        };

        const exportPNG = () => {
            const tempCanvas = document.createElement('canvas');
            const tempCtx = tempCanvas.getContext('2d');
            
            // Create image from SVG
            svgToImage(textarea.value).then(img => {
                // Set canvas to SVG's native size
                tempCanvas.width = img.width;
                tempCanvas.height = img.height;
                
                // Draw with white background
                tempCtx.fillStyle = 'white';
                tempCtx.fillRect(0, 0, tempCanvas.width, tempCanvas.height);
                tempCtx.drawImage(img, 0, 0);
                
                // Export
                const url = tempCanvas.toDataURL('image/png');
                const link = document.createElement('a');
                link.href = url;
                link.download = 'drawing.png';
                document.body.appendChild(link);
                link.click();
                document.body.removeChild(link);
                announceExport('PNG');
            });
        };
    </script>
</body>
</html>