Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
| <title>Hybrid Canva + UNO-FLUX Prototype</title> | |
| <link rel="stylesheet" href="style.css" /> | |
| <script src="https://cdn.tailwindcss.com"></script> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css" /> | |
| <!-- Variable-Font Reel Styles --> | |
| <link | |
| href="https://fonts.googleapis.com/css2?family=Roboto+Flex:opsz,wght,wdth,slnt@8..144,100..600,75..125,-12..0&display=swap" | |
| rel="stylesheet" | |
| /> | |
| <style> | |
| /* Reel Reset & Full-Bleed */ | |
| *,*::before,*::after { box-sizing:border-box; margin:0; padding:0 } | |
| .hero { | |
| position: relative; | |
| left: 50%; | |
| right: 50%; | |
| margin-left: -50vw; | |
| margin-right: -50vw; | |
| width: 100vw; | |
| padding: 0.5rem 0; | |
| background: linear-gradient(90deg,#ff6ec4,#7873f5,#42d2ff); | |
| background-size:400% 400%; | |
| animation:bgShift 12s ease-in-out infinite; | |
| } | |
| @keyframes bgShift { 0%,100% { background-position:0% 50% } 50% { background-position:100% 50% } } | |
| .marquee { width:100%; overflow:hidden } | |
| .track-container { display:inline-flex; animation:scroll 60s linear infinite; will-change:transform; } | |
| @keyframes scroll { 0% { transform: translateX(0) } 100% { transform: translateX(-50%) } } | |
| .track { display:inline-flex } | |
| @keyframes axisCycle { | |
| 0% { font-variation-settings: 'slnt' 0, 'wdth' 100, 'wght' 100 } | |
| 33% { font-variation-settings: 'slnt' -6, 'wdth' 100, 'wght' 100 } | |
| 34% { font-variation-settings: 'slnt' -6, 'wdth' 100, 'wght' 100 } | |
| 66% { font-variation-settings: 'slnt' -6, 'wdth' 125, 'wght' 100 } | |
| 67% { font-variation-settings: 'slnt' -6, 'wdth' 125, 'wght' 100 } | |
| 100% { font-variation-settings: 'slnt' -6, 'wdth' 125, 'wght' 600 } | |
| } | |
| .message { | |
| white-space:nowrap; | |
| font-family:'Roboto Flex',sans-serif; | |
| font-size:4rem; | |
| text-transform:uppercase; | |
| color:#fff; | |
| margin:0 1rem; | |
| animation:axisCycle 9s ease-in-out infinite; | |
| will-change:font-variation-settings; | |
| } | |
| .separator { font-size:4rem; color:#fff; margin:0 1rem; } | |
| /* Slides styling */ | |
| .slide { display: none } | |
| .slide.active { display: block } | |
| </style> | |
| </head> | |
| <body class="bg-gray-100 text-gray-900"> | |
| <!-- Variable-Font Reel --> | |
| <div class="hero"> | |
| <div class="marquee"> | |
| <div class="track-container"> | |
| <!-- first loop --> | |
| <div class="track"> | |
| <div class="message">THIS ISN’T A SLIDESHOW IT’S A CONVERSATION STARTER</div> | |
| <div class="separator">●</div> | |
| <div class="message">YOU DON’T JUST CLICK THROUGH YOU SHAPE WHAT COMES NEXT</div> | |
| <div class="separator">●</div> | |
| <div class="message">YOU + YOUR AUDIENCE = THE REAL CONTENT</div> | |
| <div class="separator">●</div> | |
| <div class="message">NOTHING’S SET IN STONE EVERYTHING RESPONDS</div> | |
| <div class="separator">●</div> | |
| <div class="message">CO-CREATE COMMENT CHANGE DIRECTION MID-SLIDE</div> | |
| </div> | |
| <!-- second loop --> | |
| <div class="track"> | |
| <div class="message">THIS ISN’T A SLIDESHOW IT’S A CONVERSATION STARTER</div> | |
| <div class="separator">●</div> | |
| <div class="message">YOU DON’T JUST CLICK THROUGH YOU SHAPE WHAT COMES NEXT</div> | |
| <div class="separator">●</div> | |
| <div class="message">YOU + YOUR AUDIENCE = THE REAL CONTENT</div> | |
| <div class="separator">●</div> | |
| <div class="message">NOTHING’S SET IN STONE EVERYTHING RESPONDS</div> | |
| <div class="separator">●</div> | |
| <div class="message">CO-CREATE COMMENT CHANGE DIRECTION MID-SLIDE</div> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Page 1: Canva Embed with Reflection --> | |
| <div id="canva-container" class="container mx-auto py-8 relative"> | |
| <div style="position: relative; width: 100%; height: 0; padding-top: 56.25%; box-shadow: 0 2px 8px rgba(63,69,81,0.16); overflow: hidden; border-radius: 8px; will-change: transform;"> | |
| <iframe loading="lazy" style="position:absolute; width:100%; height:100%; top:0; left:0; border:none;" src="https://www.canva.com/design/DAGbbUSr_88/ofs63fEKzYjhiByUPBm9WA/view?embed" allowfullscreen allow="fullscreen"></iframe> | |
| </div> | |
| <a href="https://www.canva.com/design/DAGbbUSr_88/ofs63fEKzYjhiByUPBm9WA/view?utm_content=DAGbbUSr_88&utm_campaign=designshare&utm_medium=embeds&utm_source=link" target="_blank" rel="noopener" class="block mt-2 text-center text-sm text-gray-600">Templates & Apps by youssef sharawy</a> | |
| <div class="flex justify-center mt-4 space-x-2"> | |
| <button id="to-slides" class="bg-blue-600 hover:bg-blue-700 text-white px-4 py-2 rounded"><i class="fas fa-arrow-right mr-2"></i>Next</button> | |
| <button id="openReflection" class="bg-yellow-400 hover:bg-yellow-500 text-white px-4 py-2 rounded">✍️ Reflect on slide 5</button> | |
| </div> | |
| <!-- Reflection Modal --> | |
| <div id="reflectionModal" class="fixed inset-0 flex items-center justify-center bg-black bg-opacity-50 hidden"> | |
| <div class="bg-white p-6 rounded-lg shadow-lg max-w-lg w-full mx-4"> | |
| <h3 class="text-xl font-semibold mb-2">Your reflections on slide 5</h3> | |
| <textarea id="reflectionInput" class="w-full h-40 p-2 border border-gray-300 rounded focus:outline-none" placeholder="Type your notes here…"></textarea> | |
| <div class="mt-4 flex justify-end space-x-2"> | |
| <button id="closeReflection" class="px-4 py-2 rounded border border-gray-300">Cancel</button> | |
| <button id="submitReflection" class="px-4 py-2 bg-blue-600 text-white rounded">Save Reflection</button> | |
| </div> | |
| </div> | |
| </div> | |
| </div> | |
| <!-- Page 2+: Custom Slides including Reflections Display --> | |
| <div id="slides-container" class="container mx-auto py-8 hidden"> | |
| <div class="fixed bottom-4 right-4 flex space-x-2"> | |
| <button id="prev-btn" class="bg-blue-600 hover:bg-blue-700 text-white p-3 rounded-full"><i class="fas fa-arrow-left"></i></button> | |
| <button id="next-btn" class="bg-blue-600 hover:bg-blue-700 text-white p-3 rounded-full"><i class="fas fa-arrow-right"></i></button> | |
| </div> | |
| <div class="fixed top-0 left-0 right-0 h-1 bg-gray-200"><div id="progress-bar" class="bg-green-500 h-full transition-all"></div></div> | |
| <div class="fixed top-4 right-4 bg-white px-3 py-1 rounded-full text-sm shadow"><span id="current-slide">1</span>/<span id="total-slides"></span></div> | |
| <div id="slides" class="mt-12 space-y-8"> | |
| <!-- Original Custom Slide --> | |
| <div class="slide active bg-white rounded p-6 shadow"> | |
| <h2 class="text-2xl font-bold mb-2">Custom Slide 1</h2> | |
| <p>This is your first custom slide after the Canva embed.</p> | |
| </div> | |
| <!-- UNO-FLUX Integration --> | |
| <div class="slide bg-white rounded p-6 shadow"> | |
| <h2 class="text-2xl font-bold mb-4">UNO-FLUX Generator</h2> | |
| <div style="position: relative; width: 100%; padding-top: 56.25%; box-shadow: 0 2px 8px rgba(0,0,0,0.1); border-radius: 8px; overflow: hidden;"> | |
| <iframe src="https://bytedance-research-UNO-FLUX.hf.space" frameborder="0" style="position:absolute; top:0; left:0; width:100%; height:100%;"></iframe> | |
| </div> | |
| <p class="mt-2 text-sm text-gray-600">Interact with the UNO-FLUX Space here.</p> | |
| </div> | |
| <!-- Reflection Display Slide --> | |
| <div class="slide bg-white rounded p-6 shadow"> | |
| <h2 class="text-2xl font-bold mb-2">Your Reflections on Slide 5</h2> | |
| <div id="reflectionDisplay" class="prose text-gray-800"></div> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| // Slide logic | |
| const canvaContainer = document.getElementById('canva-container'); | |
| const slidesContainer = document.getElementById('slides-container'); | |
| const slides = document.querySelectorAll('.slide'); | |
| const totalSlidesEl = document.getElementById('total-slides'); | |
| const currentSlideEl = document.getElementById('current-slide'); | |
| const progressBar = document.getElementById('progress-bar'); | |
| let current = 0; | |
| function initSlides() { | |
| const total = slides.length; | |
| totalSlidesEl.textContent = total; | |
| showSlide(0); | |
| document.getElementById('next-btn').onclick = () => showSlide((current + 1) % total); | |
| document.getElementById('prev-btn').onclick = () => { | |
| if (current === 0) { | |
| slidesContainer.classList.add('hidden'); | |
| canvaContainer.classList.remove('hidden'); | |
| } else showSlide(current - 1); | |
| }; | |
| document.addEventListener('keydown', e => { | |
| if (e.key === 'ArrowRight') showSlide((current + 1) % total); | |
| if (e.key === 'ArrowLeft') { | |
| if (current === 0) { | |
| slidesContainer.classList.add('hidden'); | |
| canvaContainer.classList.remove('hidden'); | |
| } else showSlide(current - 1); | |
| } | |
| }); | |
| } | |
| document.getElementById('to-slides').addEventListener('click', () => { | |
| canvaContainer.classList.add('hidden'); | |
| slidesContainer.classList.remove('hidden'); | |
| initSlides(); | |
| }); | |
| function showSlide(idx) { | |
| slides[current].classList.remove('active'); | |
| slides[idx].classList.add('active'); | |
| current = idx; | |
| currentSlideEl.textContent = current + 1; | |
| progressBar.style.width = ((current + 1) / slides.length) * 100 + '%'; | |
| } | |
| // Reflection modal logic | |
| const openBtn = document.getElementById('openReflection'); | |
| const modal = document.getElementById('reflectionModal'); | |
| const closeBtn = document.getElementById('closeReflection'); | |
| const submitBtn = document.getElementById('submitReflection'); | |
| const inputEl = document.getElementById('reflectionInput'); | |
| const reflectionDisplay = document.getElementById('reflectionDisplay'); | |
| // Load saved reflection on startup | |
| const saved = localStorage.getItem('slide5Reflection'); | |
| if (saved) reflectionDisplay.textContent = saved; | |
| openBtn.addEventListener('click', () => { | |
| modal.classList.remove('hidden'); | |
| inputEl.focus(); | |
| }); | |
| closeBtn.addEventListener('click', () => { | |
| modal.classList.add('hidden'); | |
| }); | |
| submitBtn.addEventListener('click', () => { | |
| const notes = inputEl.value.trim(); | |
| if (!notes) { | |
| alert('Please enter your reflection before saving.'); | |
| return; | |
| } | |
| localStorage.setItem('slide5Reflection', notes); | |
| reflectionDisplay.textContent = notes; | |
| modal.classList.add('hidden'); | |
| }); | |
| </script> | |
| </body> | |
| </html> |