Przeglądaj źródła

Styling improvements

Thokoop 7 miesięcy temu
rodzic
commit
a5fc1588f0
3 zmienionych plików z 207 dodań i 206 usunięć
  1. 2 2
      static/js/index.js
  2. 25 24
      templates/base.html
  3. 180 180
      templates/index.html

+ 2 - 2
static/js/index.js

@@ -1447,8 +1447,8 @@ function setupAnimatedPreviewControls() {
         const pixelRatio = (window.devicePixelRatio || 1) * 2;
         
         // Set the display size (CSS pixels)
-        canvas.style.width = displaySize + 'px';
-        canvas.style.height = displaySize + 'px';
+        canvas.style.width = displaySize + '%';
+        canvas.style.height = displaySize + '%';
         
         // Set the actual canvas size (device pixels) - increased resolution
         canvas.width = displaySize * pixelRatio;

+ 25 - 24
templates/base.html

@@ -56,7 +56,7 @@
       @media (max-width: 640px) {
         nav.flex {
           display: grid;
-          grid-template-columns: repeat(6, 1fr);
+          grid-template-columns: repeat(5, 1fr);
           gap: 0;
         }
         nav.flex a {
@@ -254,6 +254,15 @@
     class="bg-gray-50"
     style="font-family: 'Plus Jakarta Sans', 'Noto Sans', sans-serif"
   >
+  <div
+          class="mt-2 w-full text-center px-4 z-50 pointer-events-none absolute"
+          id="status-message-container"
+  >
+      <p
+              class="text-base font-semibold opacity-0 transform -translate-y-2 transition-all duration-300 ease-in-out px-10 py-2 rounded-lg shadow-lg"
+              id="status-message"
+      ></p>
+  </div>
     <div
       class="relative flex size-full min-h-screen flex-col group/design-root overflow-x-hidden"
     >
@@ -277,19 +286,10 @@
             </h1>
             </a>
           </div>
-          <div
-            class="mt-2 w-full text-center px-4"
-            id="status-message-container"
-          >
-            <p
-              class="text-base font-semibold opacity-0 transform -translate-y-2 transition-all duration-300 ease-in-out px-10 py-2 rounded-lg shadow-lg"
-              id="status-message"
-            ></p>
-          </div>
           <div class="flex items-center gap-4">
             <button
               id="theme-toggle"
-              class="p-2 rounded-lg hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-blue-500"
+              class="p-1.5 flex rounded-lg hover:bg-gray-200 focus:outline-none focus:ring-2 focus:ring-blue-500"
               aria-label="Toggle dark mode"
             >
               <span class="material-icons" id="theme-toggle-icon">dark_mode</span>
@@ -299,7 +299,7 @@
         <main class="flex flex-1 justify-center px-4 sm:px-6 lg:px-8 pt-16 sm:pt-20">
           {% block content %}{% endblock %}
         </main>
-        
+
         <!-- Floating Preview Button -->
         <button
           id="toggle-preview-modal-btn"
@@ -308,7 +308,7 @@
         >
           <span class="material-icons text-xl">preview</span>
         </button>
-        
+
         <footer
           class="fixed bottom-0 left-0 right-0 z-10 bg-white border-t border-gray-200 shadow-t-sm"
         >
@@ -350,9 +350,9 @@
     </div>
     {% block scripts %}{% endblock %}
     <script src="/static/js/base.js"></script>
-    
+
     <!-- Player Preview Modal -->
-    <div id="playerPreviewModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50 hidden p-4">
+    <div id="playerPreviewModal" class="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-40 hidden p-4">
         <div class="bg-white rounded-lg shadow-xl w-full max-w-5xl max-h-[95vh] flex flex-col">
             <div class="flex items-center justify-between p-4 border-b border-gray-200 flex-shrink-0">
                 <h2 id="playerPreviewTitle" class="text-xl font-semibold text-gray-800">Pattern Preview</h2>
@@ -369,15 +369,16 @@
                     </div>
                 </div>
             </div>
-            
+
             <!-- Pattern Info and Controls -->
-            <div class="flex-shrink-0 p-4 border-b border-gray-200 flex items-center gap-4">
+            <div class="flex-shrink-0 p-4 border-b border-gray-200 flex items-center gap-4 flex-wrap">
                 <!-- Pattern Preview Image -->
                 <div class="flex-shrink-0">
-                    <img id="modal-pattern-preview-img" class="w-[126px] h-[126px] rounded-full border border-gray-300 object-cover dark:invert" src="">
+                    <img id="modal-pattern-preview-img"
+                         class="w-[126px] h-[126px] rounded-full border border-gray-300 object-cover dark:invert" src="">
                 </div>
-                
-                <div class="flex-grow">
+
+                <div class="flex-grow w-auto">
                     <div class="flex items-center justify-between mb-2">
                         <div class="min-w-0 max-w-[50%]">
                             <div class="overflow-hidden relative">
@@ -439,7 +440,7 @@
             </div>
         </div>
     </div>
-    
+
     <script>
       // Function to show status message
       function showStatusMessage(message, type = "success") {
@@ -503,16 +504,16 @@
       document.addEventListener('DOMContentLoaded', function() {
         const themeToggle = document.getElementById('theme-toggle');
         const themeToggleIcon = document.getElementById('theme-toggle-icon');
-        
+
         // Update icon based on current theme
         function updateThemeIcon() {
           const isDark = document.documentElement.classList.contains('dark');
           themeToggleIcon.textContent = isDark ? 'light_mode' : 'dark_mode';
         }
-        
+
         // Initial icon update
         updateThemeIcon();
-        
+
         // Theme toggle click handler
         themeToggle.addEventListener('click', () => {
           const isDark = document.documentElement.classList.toggle('dark');

+ 180 - 180
templates/index.html

@@ -179,206 +179,206 @@
   background-color:rgb(229, 229, 229);
 }
 
-
-
 {% endblock %}
 
 {% block content %}
 <div class="layout-content-container flex flex-col w-full max-w-5xl h-[calc(100vh-8rem)]">
-  <div class="flex-none bg-gray-50 py-4">
-    <div class="flex flex-wrap items-center justify-between gap-4 mt-8">
-      <h2 class="text-gray-900 text-3xl font-bold leading-tight tracking-tight">
-        Browse Patterns
-      </h2>
-      <div class="relative w-full sm:w-auto flex gap-2 items-center">
-        <div class="flex gap-2 flex-1">
-          <button
-          id="cacheAllButton"
-          class="inline-flex items-cinline-flex items-center justify-center rounded-lg bg-blue-600 px-4 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
-        >
-          <span class="material-icons text-sm">cached</span>
-          Cache All Previews
-        </button>
-          
-          <div class="relative flex-1">
-            <div class="pointer-events-none absolute inset-y-0 left-0 flex items-center pl-3">
-              <span class="material-icons text-gray-400">search</span>
+    <div class="flex-none bg-gray-50 py-4">
+        <div class="flex flex-wrap items-center justify-between gap-4 mt-8">
+            <h2 class="text-gray-900 text-3xl font-bold leading-tight tracking-tight">
+                Browse Patterns
+            </h2>
+
+            <button
+                    id="cacheAllButton"
+                    class="inline-flex gap-2 transition-colors items-center justify-center rounded-lg px-4 py-2.5 text-xs sm:text-sm font-semibold text-white  hover:text-slate-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
+            >
+                <span class="material-icons text-sm pr-2">cached</span>
+                Cache All Previews
+            </button>
+
+            <div class="relative w-full sm:w-auto flex grow gap-2 items-center flex-wrap">
+                <div class="flex gap-2 flex-1">
+                    <div class="relative flex-1">
+                        <input
+                                id="patternSearch"
+                                class="form-input block w-full h-11 rounded-lg border-gray-300 bg-gray-50 py-2.5 p-4 text-gray-900 placeholder-gray-500 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 sm:text-sm"
+                                placeholder="Search patterns..."
+                                type="search"
+                        />
+                        <button
+                                id="searchButton"
+                                class="inline-flex absolute top-0 right-0 h-11 w-11 items-center justify-center rounded-lg bg-blue-600 p-2 text-sm font-semibold text-white shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
+                        >
+                            <span class="material-icons text-sm font-semibold text-white">search</span>
+                        </button>
+                    </div>
+                </div>
+                <!-- Add Pattern Button -->
+                <input
+                        type="file"
+                        id="patternFileInput"
+                        accept=".thr"
+                        class="hidden"
+                />
+                <button
+                        aria-label="Add new pattern"
+                        class="inline-flex items-center justify-center rounded-lg h-11 w-11 bg-blue-600 text-white shadow-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 ml-2 text-xl font-bold"
+                        onclick="document.getElementById('patternFileInput').click()"
+                >
+                    <span class="material-icons">add</span>
+                </button>
             </div>
-            <input
-              id="patternSearch"
-              class="form-input block w-full rounded-lg border-gray-300 bg-gray-50 py-2.5 pl-10 pr-3 text-gray-900 placeholder-gray-500 focus:border-blue-500 focus:ring-1 focus:ring-blue-500 sm:text-sm"
-              placeholder="Search patterns..."
-              type="search"
-            />
-          </div>
-          <button
-            id="searchButton"
-            class="inline-flex items-center justify-center rounded-lg bg-blue-600 px-4 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
-          >
-            Search
-          </button>
         </div>
-        <!-- Add Pattern Button -->
-        <input
-          type="file"
-          id="patternFileInput"
-          accept=".thr"
-          class="hidden"
-        />
-        <button
-          aria-label="Add new pattern"
-          class="inline-flex items-center justify-center rounded-lg h-11 w-11 bg-blue-600 text-white shadow-lg hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 ml-2 text-xl font-bold"
-          onclick="document.getElementById('patternFileInput').click()"
-        >
-          <span class="material-icons">add</span>
-        </button>
-      </div>
-    </div>
-  </div>
-  <section class="flex-1 overflow-y-auto px-4 py-6">
-    <div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4 sm:gap-5 md:gap-6">
-      <!-- All patterns will be populated here -->
     </div>
-  </section>
-</div>
-
-<!-- Status Message Container -->
-<div id="status-message-container" class="fixed top-4 right-4 z-50">
-  <div id="status-message" class="opacity-0 transform -translate-y-2 transition-all duration-300 ease-in-out"></div>
+    <section class="flex-1 overflow-y-auto px-4 py-6">
+        <div class="grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 gap-4 sm:gap-5 md:gap-6">
+            <!-- All patterns will be populated here -->
+        </div>
+    </section>
 </div>
 
 <!-- Pattern Preview Panel -->
-<div id="patternPreviewPanel" class="fixed top-0 bottom-0 right-0 w-full max-w-md transform translate-x-full transition-transform duration-300 ease-in-out z-40 lg:translate-x-0 lg:opacity-0 lg:pointer-events-none">
-  <div class="h-full bg-white shadow-xl">
-    <header class="flex items-center justify-between border-b border-solid border-b-[#f0f2f5] px-6 py-4">
-      <div class="flex items-center gap-3 text-[#111518]">
-        <h2 id="patternPreviewTitle" class="text-[#111518] text-lg font-semibold leading-tight">Pattern Details</h2>
-      </div>
-      <button id="closePreviewPanel" class="flex cursor-pointer items-center justify-center rounded-full p-1.5 text-slate-500 hover:bg-slate-100 hover:text-slate-700 focus:outline-none focus:ring-2 focus:ring-[#0b80ee]">
-        <span class="material-icons text-2xl">close</span>
-      </button>
-    </header>
-    <div class="p-6 overflow-y-auto h-[calc(100%-4rem)]">
-      <div class="mb-6 aspect-square w-full overflow-hidden pattern-preview rounded-full relative group">
-        <img id="patternPreviewImage" alt="Pattern Preview" class="h-full w-full object-cover" src=""/>
-        <!-- Play button overlay for animated preview -->
-        <div id="previewPlayOverlay" class="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 cursor-pointer">
-          <div class="bg-white rounded-full p-3 shadow-lg flex items-center justify-center w-12 h-12">
-            <span class="material-icons text-2xl text-gray-800">play_arrow</span>
-          </div>
-        </div>
-      </div>
-      <div class="mb-4 flex justify-between text-sm">
-        <div class="flex items-center gap-2">
-          <span class="text-slate-500">First:</span>
-          <span id="firstCoordinate" class="font-semibold text-[#111518]">(0, 0)</span>
-        </div>
-        <div class="flex items-center gap-2">
-          <span class="text-slate-500">Last:</span>
-          <span id="lastCoordinate" class="font-semibold text-[#111518]">(0, 0)</span>
-        </div>
-      </div>
-      <div class="mb-4">
-        <h3 class="mb-2 text-sm font-semibold text-slate-700">Pre-Execution Action</h3>
-        <div class="grid grid-cols-2 gap-2">
-          <label class="group relative flex cursor-pointer items-center justify-center rounded-lg border border-slate-300 p-2 text-center text-sm font-medium text-slate-700 transition-all hover:border-[#0b80ee] has-[:checked]:border-[#0b80ee] has-[:checked]:bg-[#0b80ee] has-[:checked]:text-white has-[:checked]:ring-2 has-[:checked]:ring-[#0b80ee] has-[:checked]:ring-offset-2">
-            Adaptive
-            <input checked="" class="peer sr-only" name="preExecutionAction" type="radio" value="adaptive"/>
-          </label>
-          <label class="group relative flex cursor-pointer items-center justify-center rounded-lg border border-slate-300 p-2 text-center text-sm font-medium text-slate-700 transition-all hover:border-[#0b80ee] has-[:checked]:border-[#0b80ee] has-[:checked]:bg-[#0b80ee] has-[:checked]:text-white has-[:checked]:ring-2 has-[:checked]:ring-[#0b80ee] has-[:checked]:ring-offset-2">
-            Clear From Center
-            <input class="peer sr-only" name="preExecutionAction" type="radio" value="clear_from_in"/>
-          </label>
-          <label class="group relative flex cursor-pointer items-center justify-center rounded-lg border border-slate-300 p-2 text-center text-sm font-medium text-slate-700 transition-all hover:border-[#0b80ee] has-[:checked]:border-[#0b80ee] has-[:checked]:bg-[#0b80ee] has-[:checked]:text-white has-[:checked]:ring-2 has-[:checked]:ring-[#0b80ee] has-[:checked]:ring-offset-2">
-            Clear From Perimeter
-            <input class="peer sr-only" name="preExecutionAction" type="radio" value="clear_from_out"/>
-          </label>
-          <label class="group relative flex cursor-pointer items-center justify-center rounded-lg border border-slate-300 p-2 text-center text-sm font-medium text-slate-700 transition-all hover:border-[#0b80ee] has-[:checked]:border-[#0b80ee] has-[:checked]:bg-[#0b80ee] has-[:checked]:text-white has-[:checked]:ring-2 has-[:checked]:ring-[#0b80ee] has-[:checked]:ring-offset-2">
-            Clear Sideway
-            <input class="peer sr-only" name="preExecutionAction" type="radio" value="clear_sideway"/>
-          </label>
-          <label class="group relative flex cursor-pointer items-center justify-center rounded-lg border border-slate-300 p-2 text-center text-sm font-medium text-slate-700 transition-all hover:border-[#0b80ee] has-[:checked]:border-[#0b80ee] has-[:checked]:bg-[#0b80ee] has-[:checked]:text-white has-[:checked]:ring-2 has-[:checked]:ring-[#0b80ee] has-[:checked]:ring-offset-2">
-            None
-            <input class="peer sr-only" name="preExecutionAction" type="radio" value="none"/>
-          </label>
+<div id="patternPreviewPanel"
+     class="fixed top-0 bottom-0 right-0 w-full max-w-md transform translate-x-full transition-transform duration-300 ease-in-out z-40 lg:translate-x-0 lg:opacity-0 lg:pointer-events-none">
+    <div class="h-full bg-white shadow-xl">
+        <header class="flex items-center justify-between border-b border-solid border-b-[#f0f2f5] px-6 py-3 sm:py-4">
+            <div class="flex items-center gap-3 text-[#111518]">
+                <h2 id="patternPreviewTitle" class="text-[#111518] text-lg font-semibold leading-tight">Pattern
+                    Details</h2>
+            </div>
+            <button id="closePreviewPanel"
+                    class="flex cursor-pointer items-center justify-center rounded-full p-1.5 text-slate-500 hover:bg-slate-100 hover:text-slate-700 focus:outline-none focus:ring-2 focus:ring-[#0b80ee]">
+                <span class="material-icons text-2xl">close</span>
+            </button>
+        </header>
+        <div class="p-6 overflow-y-auto h-[calc(100%-4rem)]">
+            <div class="mb-6 aspect-square w-full overflow-hidden pattern-preview rounded-full relative group">
+                <img id="patternPreviewImage" alt="Pattern Preview" class="h-full w-full object-cover" src=""/>
+                <!-- Play button overlay for animated preview -->
+                <div id="previewPlayOverlay"
+                     class="absolute inset-0 flex items-center justify-center opacity-0 group-hover:opacity-100 transition-opacity duration-200 cursor-pointer">
+                    <div class="bg-white rounded-full p-3 shadow-lg flex items-center justify-center w-12 h-12">
+                        <span class="material-icons text-2xl text-gray-800">play_arrow</span>
+                    </div>
+                </div>
+            </div>
+            <div class="mb-4 flex justify-between text-sm">
+                <div class="flex items-center gap-2">
+                    <span class="text-slate-500">First:</span>
+                    <span id="firstCoordinate" class="font-semibold text-[#111518]">(0, 0)</span>
+                </div>
+                <div class="flex items-center gap-2">
+                    <span class="text-slate-500">Last:</span>
+                    <span id="lastCoordinate" class="font-semibold text-[#111518]">(0, 0)</span>
+                </div>
+            </div>
+            <div class="mb-4">
+                <h3 class="mb-2 text-sm font-semibold text-slate-700">Pre-Execution Action</h3>
+                <div class="grid grid-cols-2 gap-2">
+                    <label class="group relative flex cursor-pointer items-center justify-center rounded-lg border border-slate-300 p-2 text-center text-sm font-medium text-slate-700 transition-all hover:border-[#0b80ee] has-[:checked]:border-[#0b80ee] has-[:checked]:bg-[#0b80ee] has-[:checked]:text-white has-[:checked]:ring-2 has-[:checked]:ring-[#0b80ee] has-[:checked]:ring-offset-2">
+                        Adaptive
+                        <input checked="" class="peer sr-only" name="preExecutionAction" type="radio" value="adaptive"/>
+                    </label>
+                    <label class="group relative flex cursor-pointer items-center justify-center rounded-lg border border-slate-300 p-2 text-center text-sm font-medium text-slate-700 transition-all hover:border-[#0b80ee] has-[:checked]:border-[#0b80ee] has-[:checked]:bg-[#0b80ee] has-[:checked]:text-white has-[:checked]:ring-2 has-[:checked]:ring-[#0b80ee] has-[:checked]:ring-offset-2">
+                        Clear From Center
+                        <input class="peer sr-only" name="preExecutionAction" type="radio" value="clear_from_in"/>
+                    </label>
+                    <label class="group relative flex cursor-pointer items-center justify-center rounded-lg border border-slate-300 p-2 text-center text-sm font-medium text-slate-700 transition-all hover:border-[#0b80ee] has-[:checked]:border-[#0b80ee] has-[:checked]:bg-[#0b80ee] has-[:checked]:text-white has-[:checked]:ring-2 has-[:checked]:ring-[#0b80ee] has-[:checked]:ring-offset-2">
+                        Clear From Perimeter
+                        <input class="peer sr-only" name="preExecutionAction" type="radio" value="clear_from_out"/>
+                    </label>
+                    <label class="group relative flex cursor-pointer items-center justify-center rounded-lg border border-slate-300 p-2 text-center text-sm font-medium text-slate-700 transition-all hover:border-[#0b80ee] has-[:checked]:border-[#0b80ee] has-[:checked]:bg-[#0b80ee] has-[:checked]:text-white has-[:checked]:ring-2 has-[:checked]:ring-[#0b80ee] has-[:checked]:ring-offset-2">
+                        Clear Sideway
+                        <input class="peer sr-only" name="preExecutionAction" type="radio" value="clear_sideway"/>
+                    </label>
+                    <label class="group relative flex cursor-pointer items-center justify-center rounded-lg border border-slate-300 p-2 text-center text-sm font-medium text-slate-700 transition-all hover:border-[#0b80ee] has-[:checked]:border-[#0b80ee] has-[:checked]:bg-[#0b80ee] has-[:checked]:text-white has-[:checked]:ring-2 has-[:checked]:ring-[#0b80ee] has-[:checked]:ring-offset-2">
+                        None
+                        <input class="peer sr-only" name="preExecutionAction" type="radio" value="none"/>
+                    </label>
+                </div>
+            </div>
+            <div class="space-y-3">
+                <button id="playPattern"
+                        class="flex w-full items-center justify-center gap-2 rounded-lg bg-[#0b80ee] px-4 py-2.5 text-sm font-semibold text-white shadow-sm transition-colors hover:bg-opacity-90 focus:outline-none focus:ring-2 focus:ring-[#0b80ee] focus:ring-offset-2">
+                    <span class="material-icons text-lg">play_arrow</span>
+                    Play
+                </button>
+                <button id="deletePattern"
+                        class="flex w-full items-center justify-center gap-2 rounded-lg border border-red-500 px-4 py-2.5 text-sm font-semibold text-red-500 shadow-sm transition-colors hover:bg-red-50 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2">
+                    <span class="material-icons text-lg">delete</span>
+                    Delete
+                </button>
+            </div>
         </div>
-      </div>
-      <div class="space-y-3">
-        <button id="playPattern" class="flex w-full items-center justify-center gap-2 rounded-lg bg-[#0b80ee] px-4 py-2.5 text-sm font-semibold text-white shadow-sm transition-colors hover:bg-opacity-90 focus:outline-none focus:ring-2 focus:ring-[#0b80ee] focus:ring-offset-2">
-          <span class="material-icons text-lg">play_arrow</span>
-          Play
-        </button>
-        <button id="deletePattern" class="flex w-full items-center justify-center gap-2 rounded-lg border border-red-500 px-4 py-2.5 text-sm font-semibold text-red-500 shadow-sm transition-colors hover:bg-red-50 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2">
-          <span class="material-icons text-lg">delete</span>
-          Delete
-        </button>
-      </div>
     </div>
-  </div>
 </div>
 
 <!-- Animated Preview Modal -->
 <div id="animatedPreviewModal" class="fixed inset-0 bg-black bg-opacity-50 z-50 hidden">
-  <div class="flex items-center justify-center min-h-screen p-4">
-    <div class="bg-white rounded-lg shadow-xl max-w-4xl w-full max-h-[90vh] overflow-hidden">
-      <!-- Modal Header -->
-      <div class="flex items-center justify-between p-6 border-b border-gray-200">
-        <h3 id="animatedPreviewTitle" class="text-xl font-semibold text-gray-900">Animated Preview</h3>
-        <button id="closeAnimatedPreview" class="text-gray-400 hover:text-gray-600">
-          <span class="material-icons text-2xl">close</span>
-        </button>
-      </div>
-      
-      <!-- Modal Content -->
-      <div class="p-6">
-        <!-- Canvas Container -->
-        <div class="flex justify-center mb-6">
-          <div class="relative w-full max-w-[800px]">
-            <canvas id="animatedPreviewCanvas" width="800" height="800" class="border border-gray-300 rounded-full w-full h-auto max-w-full dark:invert"></canvas>
-            <!-- Play/Pause Overlay -->
-            <div id="playPauseOverlay" class="absolute inset-0 flex items-center justify-center bg-black bg-opacity-20 opacity-0 transition-opacity duration-200 cursor-pointer rounded-full">
-              <div class="bg-white rounded-full p-4 shadow-lg">
-                <span id="playPauseIcon" class="material-icons text-3xl text-gray-800">play_arrow</span>
-              </div>
+    <div class="flex items-center justify-center min-h-screen p-4">
+        <div class="bg-white rounded-lg shadow-xl max-w-4xl w-full max-h-[90vh] flex flex-col overflow-hidden">
+            <!-- Modal Header -->
+            <div class="flex items-center justify-between p-6 border-b border-gray-200 shrink-0">
+                <h3 id="animatedPreviewTitle" class="text-xl font-semibold text-gray-900">Animated Preview</h3>
+                <button id="closeAnimatedPreview" class="text-gray-400 hover:text-gray-600">
+                    <span class="material-icons text-2xl">close</span>
+                </button>
             </div>
-          </div>
-        </div>
-        
-        <!-- Controls -->
-        <div class="space-y-4">
-          <!-- Speed Control -->
-          <div>
-            <label class="block text-sm font-medium text-gray-700 mb-2">Speed</label>
-            <div class="flex items-center gap-4">
-              <input type="range" id="speedSlider" min="0.1" max="5" step="0.1" value="1" class="flex-1">
-              <span id="speedValue" class="text-sm font-medium text-gray-900 w-16">1x</span>
+
+            <!-- Modal Content -->
+            <div class="p-6 overflow-y-auto grow h-full">
+                <!-- Canvas Container -->
+                <div class="relative flex justify-center h-full">
+                    <canvas id="animatedPreviewCanvas"
+                            class="border border-gray-300 rounded-full w-full h-full max-w-full dark:invert"></canvas>
+                    <!-- Play/Pause Overlay -->
+                    <div id="playPauseOverlay"
+                         class="absolute inset-0 flex items-center justify-center bg-black bg-opacity-20 opacity-0 transition-opacity duration-200 cursor-pointer rounded-full">
+                        <div class="bg-white rounded-full p-4 shadow-lg">
+                            <span id="playPauseIcon" class="material-icons text-3xl text-gray-800">play_arrow</span>
+                        </div>
+                    </div>
+                </div>
             </div>
-          </div>
-          
-          <!-- Progress Control -->
-          <div>
-            <label class="block text-sm font-medium text-gray-700 mb-2">Progress</label>
-            <div class="flex items-center gap-4">
-              <input type="range" id="progressSlider" min="0" max="100" step="0.1" value="0" class="flex-1">
-              <span id="progressValue" class="text-sm font-medium text-gray-900 w-20">0%</span>
+
+            <!-- Controls -->
+            <div class="p-6 space-y-4 shrink-0">
+                <!-- Speed Control -->
+                <div>
+                    <label class="block text-sm font-medium text-gray-700 mb-2">Speed</label>
+                    <div class="flex items-center gap-4">
+                        <input type="range" id="speedSlider" min="0.1" max="5" step="0.1" value="1" class="flex-1">
+                        <span id="speedValue" class="text-sm font-medium text-gray-900 w-16">1x</span>
+                    </div>
+                </div>
+
+                <!-- Progress Control -->
+                <div>
+                    <label class="block text-sm font-medium text-gray-700 mb-2">Progress</label>
+                    <div class="flex items-center gap-4">
+                        <input type="range" id="progressSlider" min="0" max="100" step="0.1" value="0"
+                               class="flex-1">
+                        <span id="progressValue" class="text-sm font-medium text-gray-900 w-20">0%</span>
+                    </div>
+                </div>
+
+                <!-- Control Buttons -->
+                <div class="flex items-center justify-center gap-4">
+                    <button id="playPauseBtn"
+                            class="flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700">
+                        <span id="playPauseBtnIcon" class="material-icons">play_arrow</span>
+                        <span id="playPauseBtnText">Play</span>
+                    </button>
+                    <button id="resetBtn"
+                            class="flex items-center gap-2 px-4 py-2 bg-gray-600 text-white rounded-lg hover:bg-gray-700">
+                        <span class="material-icons">replay</span>
+                        Reset
+                    </button>
+                </div>
             </div>
-          </div>
-          
-          <!-- Control Buttons -->
-          <div class="flex items-center justify-center gap-4">
-            <button id="playPauseBtn" class="flex items-center gap-2 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700">
-              <span id="playPauseBtnIcon" class="material-icons">play_arrow</span>
-              <span id="playPauseBtnText">Play</span>
-            </button>
-            <button id="resetBtn" class="flex items-center gap-2 px-4 py-2 bg-gray-600 text-white rounded-lg hover:bg-gray-700">
-              <span class="material-icons">replay</span>
-              Reset
-            </button>
-          </div>
         </div>
-      </div>
     </div>
-  </div>
 </div>
 {% endblock %}
 
@@ -417,7 +417,7 @@ document.getElementById('patternFileInput').addEventListener('change', async fun
 function updateDeleteButtonState(patternName) {
   const deleteButton = document.getElementById('deletePattern');
   if (!deleteButton) return;
-  
+
   if (patternName && patternName.startsWith('custom_patterns/')) {
     deleteButton.classList.remove('delete-button-disabled');
     deleteButton.disabled = false;