Changeset 3439097
- Timestamp:
- 01/14/2026 01:26:53 AM (6 hours ago)
- Location:
- mini-gallery/trunk
- Files:
-
- 5 added
- 17 edited
-
includes/admin/class-mgwpp-analytics-manager.php (modified) (3 diffs)
-
includes/admin/class-mgwpp_ajax_handler.php (modified) (5 diffs)
-
includes/admin/images/default-gallery.webp (added)
-
includes/admin/images/empty-galleries.webp (added)
-
includes/admin/images/galleries-preview/3d-h-marquee.webp (added)
-
includes/admin/images/galleries-preview/3d-masonry-gallery.webp (added)
-
includes/admin/images/galleries-preview/marquee-gallery.webp (modified) (previous)
-
includes/admin/images/galleries-preview/vertical-marquee.webp (added)
-
includes/admin/js/mgwpp-admin-scripts.js (modified) (6 diffs)
-
includes/admin/views/dashboard/class-mgwpp-dashboard-view.php (modified) (2 diffs)
-
includes/admin/views/edit-gallery/class-mgwpp-edit-gallery.php (modified) (2 diffs)
-
includes/admin/views/edit-gallery/mgwpp-edit-gallery.css (modified) (3 diffs)
-
includes/admin/views/edit-gallery/mgwpp-edit-gallery.js (modified) (2 diffs)
-
includes/admin/views/galleries/class-mgwpp-galleries-view.php (modified) (2 diffs)
-
includes/admin/views/galleries/mgwpp-galleries-view.css (modified) (3 diffs)
-
includes/admin/views/inner-header/class-mgwpp-inner-header.php (modified) (1 diff)
-
includes/admin/views/inner-header/mgwpp-inner-header.js (modified) (3 diffs)
-
includes/functions/class-mgwpp-canvas-shortcode.php (modified) (10 diffs)
-
includes/gallery-types/mgwpp-3d-masonry-gallery/mgwpp-3d-masonry.css (modified) (12 diffs)
-
includes/registration/gallery/class-mgwpp-gallery-capabilities.php (modified) (3 diffs)
-
mini-gallery.php (modified) (2 diffs)
-
readme.txt (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
mini-gallery/trunk/includes/admin/class-mgwpp-analytics-manager.php
r3438312 r3439097 80 80 // Add GA4 tracking via wp_head (standard method for analytics scripts) 81 81 add_action('wp_head', function () use ($measurement_id) { 82 // Output GA4 snippet - async/external scripts for analytics are standard practice 82 // Output GA4 snippet - async/external scripts for analytics are standard practice. 83 // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript -- GA4 requires external async loading from Google's servers 83 84 printf( 84 85 '<script async src="%s"></script>', … … 175 176 global $wpdb; 176 177 178 // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- Custom analytics table requires direct insert 177 179 return $wpdb->insert( 178 180 $wpdb->prefix . 'mgwpp_analytics', … … 199 201 { 200 202 global $wpdb; 203 204 // Table name is safe - constructed from WordPress prefix + hardcoded string 205 // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- Table name is safe (prefix + hardcoded literal) 201 206 $table = $wpdb->prefix . 'mgwpp_analytics'; 202 207 208 // Sanitize event_type for cache key 209 $cache_key = 'mgwpp_event_count_' . sanitize_key($event_type) . '_' . sanitize_key($date_filter); 210 $cached = wp_cache_get($cache_key, 'mgwpp_analytics'); 211 212 if ($cached !== false) { 213 return intval($cached); 214 } 215 203 216 if ($date_filter === 'month') { 217 // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery 218 // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching 219 // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared 204 220 $count = $wpdb->get_var( 205 221 $wpdb->prepare( 206 "SELECT COUNT(*) FROM `{$table}`WHERE event_type = %s AND created_at >= DATE_SUB(NOW(), INTERVAL 1 MONTH)",222 "SELECT COUNT(*) FROM {$table} WHERE event_type = %s AND created_at >= DATE_SUB(NOW(), INTERVAL 1 MONTH)", 207 223 $event_type 208 224 ) 209 225 ); 226 // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery 227 // phpcs:enable WordPress.DB.DirectDatabaseQuery.NoCaching 228 // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared 210 229 } else { 230 // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery 231 // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching 232 // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared 211 233 $count = $wpdb->get_var( 212 234 $wpdb->prepare( 213 "SELECT COUNT(*) FROM `{$table}`WHERE event_type = %s",235 "SELECT COUNT(*) FROM {$table} WHERE event_type = %s", 214 236 $event_type 215 237 ) 216 238 ); 217 } 239 // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery 240 // phpcs:enable WordPress.DB.DirectDatabaseQuery.NoCaching 241 // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared 242 } 243 244 // Cache for 2 minutes 245 wp_cache_set($cache_key, $count, 'mgwpp_analytics', 120); 218 246 219 247 return intval($count); -
mini-gallery/trunk/includes/admin/class-mgwpp_ajax_handler.php
r3438397 r3439097 70 70 } 71 71 72 // 3. Permission Check 73 if (!current_user_can('edit_mgwpp_sooras') ) {72 // 3. Permission Check - Also allow manage_options for fresh installs 73 if (!current_user_can('edit_mgwpp_sooras') && !current_user_can('manage_options')) { 74 74 wp_die( 75 75 esc_html__('Insufficient permissions to preview galleries.', 'mini-gallery'), … … 186 186 } 187 187 188 // 2. Check permissions securely 189 if (!current_user_can('edit_mgwpp_sooras') ) {188 // 2. Check permissions securely - Also allow manage_options for fresh installs 189 if (!current_user_can('edit_mgwpp_sooras') && !current_user_can('manage_options')) { 190 190 wp_send_json_error([ 191 191 'message' => esc_html__('Insufficient permissions', 'mini-gallery') … … 228 228 } 229 229 230 // 3. Check permissions 231 if (!current_user_can('edit_mgwpp_sooras') ) {230 // 3. Check permissions - Also allow manage_options for fresh installs 231 if (!current_user_can('edit_mgwpp_sooras') && !current_user_can('manage_options')) { 232 232 wp_send_json_error(['message' => esc_html__('Insufficient permissions', 'mini-gallery')]); 233 233 } … … 441 441 } 442 442 443 if (!current_user_can('edit_mgwpp_sooras')) { 443 // Also allow manage_options for fresh installs 444 if (!current_user_can('edit_mgwpp_sooras') && !current_user_can('manage_options')) { 444 445 wp_die(esc_html__('You do not have sufficient permissions.', 'mini-gallery')); 445 446 } … … 527 528 } 528 529 529 // Check permissions 530 if (!current_user_can('delete_mgwpp_sooras') ) {530 // Check permissions - Also allow manage_options for fresh installs 531 if (!current_user_can('delete_mgwpp_sooras') && !current_user_can('manage_options')) { 531 532 wp_send_json_error(['message' => __('Insufficient permissions', 'mini-gallery')]); 532 533 } -
mini-gallery/trunk/includes/admin/js/mgwpp-admin-scripts.js
r3438350 r3439097 49 49 }); 50 50 51 // Show multi-select tooltip when media frame opens 52 mediaFrame.on('open', function () { 53 showMediaTooltip(); 54 }); 55 51 56 mediaFrame.open(); 57 } 58 59 // Show a tooltip in the media modal explaining multi-select 60 function showMediaTooltip() { 61 // Wait for the modal to render 62 setTimeout(function () { 63 const $mediaModal = $('.media-modal'); 64 if ($mediaModal.length && !$mediaModal.find('.mgwpp-media-tooltip').length) { 65 const tooltipHtml = $('<div class="mgwpp-media-tooltip">' + 66 '<span class="dashicons dashicons-info"></span>' + 67 '<span>Tip: Hold <strong>Shift</strong> or <strong>Ctrl</strong> and click to select multiple images, then click "Use Selected"</span>' + 68 '<button type="button" class="mgwpp-tooltip-close">×</button>' + 69 '</div>'); 70 71 // Style the tooltip 72 tooltipHtml.css({ 73 'position': 'absolute', 74 'top': '10px', 75 'left': '50%', 76 'transform': 'translateX(-50%)', 77 'background': 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)', 78 'color': '#fff', 79 'padding': '10px 20px', 80 'border-radius': '8px', 81 'font-size': '13px', 82 'z-index': '999999', 83 'display': 'flex', 84 'align-items': 'center', 85 'gap': '8px', 86 'box-shadow': '0 4px 15px rgba(0,0,0,0.2)', 87 'animation': 'fadeIn 0.3s ease' 88 }); 89 90 tooltipHtml.find('.dashicons').css({ 91 'font-size': '18px', 92 'width': '18px', 93 'height': '18px' 94 }); 95 96 tooltipHtml.find('.mgwpp-tooltip-close').css({ 97 'background': 'transparent', 98 'border': 'none', 99 'color': '#fff', 100 'font-size': '18px', 101 'cursor': 'pointer', 102 'margin-left': '10px', 103 'opacity': '0.7' 104 }); 105 106 $mediaModal.append(tooltipHtml); 107 108 // Close button handler 109 tooltipHtml.find('.mgwpp-tooltip-close').on('click', function () { 110 tooltipHtml.fadeOut(200, function () { 111 $(this).remove(); 112 }); 113 }); 114 115 // Auto-hide after 5 seconds 116 setTimeout(function () { 117 tooltipHtml.fadeOut(300, function () { 118 $(this).remove(); 119 }); 120 }, 5000); 121 } 122 }, 300); 52 123 } 53 124 … … 81 152 82 153 updateMediaPreview(attachments, is3D); 154 155 // Auto-submit the form after images are selected 156 if (mediaIds.length > 0) { 157 autoSubmitGalleryForm(); 158 } 83 159 } 84 160 … … 107 183 function updateMediaPreview(attachments, is3D) { 108 184 const preview = $('.mgwpp-media-preview').empty(); 185 const $uploadBtn = $('.mgwpp-media-upload'); 186 const $uploadBtnText = $('#mgwpp-upload-btn-text'); 187 const count = attachments.length; 188 189 // Update button text and appearance to indicate selection 190 if (count > 0) { 191 const mediaType = is3D ? 'model' : 'image'; 192 const pluralType = count === 1 ? mediaType : (is3D ? 'models' : 'images'); 193 $uploadBtnText.text(`✓ ${count} ${pluralType} selected`); 194 $uploadBtn.addClass('has-selection'); 195 $uploadBtn.find('.dashicons').removeClass('dashicons-cloud-upload').addClass('dashicons-yes-alt'); 196 } else { 197 $uploadBtnText.text(mgwppMedia.text_title || 'Select Images'); 198 $uploadBtn.removeClass('has-selection'); 199 $uploadBtn.find('.dashicons').removeClass('dashicons-yes-alt').addClass('dashicons-cloud-upload'); 200 } 201 202 // Show preview thumbnails 109 203 attachments.forEach(attachment => { 110 204 if (is3D || !attachment.sizes) { … … 130 224 } 131 225 }); 226 227 // Make preview container visible if images selected 228 if (count > 0) { 229 $('.mgwpp-media-preview-container').addClass('has-images'); 230 } else { 231 $('.mgwpp-media-preview-container').removeClass('has-images'); 232 } 233 } 234 235 // Auto-submit the gallery creation form after images are selected 236 function autoSubmitGalleryForm() { 237 const $form = $('#mgwpp-create-gallery-form'); 238 const $titleInput = $('#mgwpp-create-gallery-title'); 239 240 // If no title is entered, generate a default one with DD/MM/YYYY HH:MM format 241 if (!$titleInput.val().trim()) { 242 const now = new Date(); 243 const day = String(now.getDate()).padStart(2, '0'); 244 const month = String(now.getMonth() + 1).padStart(2, '0'); 245 const year = now.getFullYear(); 246 const hours = String(now.getHours()).padStart(2, '0'); 247 const minutes = String(now.getMinutes()).padStart(2, '0'); 248 const defaultTitle = `Gallery ${day}/${month}/${year} ${hours}:${minutes}`; 249 $titleInput.val(defaultTitle); 250 } 251 252 // Small delay to let the UI update, then submit 253 setTimeout(function () { 254 $form.trigger('submit'); 255 }, 300); 132 256 } 133 257 … … 173 297 success: (response) => { 174 298 form.data('submitting', false); 299 $('#mgwpp-create-loading').hide(); 300 175 301 if (response.success) { 176 showSuccess(notice); 177 if (response.data.redirect) { 178 setTimeout(() => { 179 window.location.href = response.data.redirect; 180 }, 1000); 181 } 302 // Close the modal 303 closeGalleryModal(); 304 305 // Show success toast notification 306 showToastNotification('Gallery created successfully!', 'success'); 307 308 // Reload the page to show the new gallery 309 setTimeout(() => { 310 window.location.reload(); 311 }, 1500); 182 312 } else { 183 $('#mgwpp-create-loading').hide();184 313 showError({ responseJSON: response }, notice); 185 314 } … … 195 324 } 196 325 326 // Close the gallery creation modal 327 function closeGalleryModal() { 328 const $modal = $('#mgwpp-create-gallery-modal'); 329 const $overlay = $('.mgwpp-modal-overlay'); 330 331 // Remove active class to trigger close animation 332 $modal.removeClass('active'); 333 $overlay.removeClass('active'); 334 335 // Reset the form for next use 336 setTimeout(() => { 337 $('#mgwpp-create-gallery-form')[0]?.reset(); 338 $('#mgwpp-create-selected-media').val(''); 339 $('.mgwpp-media-preview').empty(); 340 $('.mgwpp-media-preview-container').removeClass('has-images'); 341 342 // Reset the upload button 343 const $uploadBtn = $('.mgwpp-media-upload'); 344 const $uploadBtnText = $('#mgwpp-upload-btn-text'); 345 $uploadBtnText.text(mgwppMedia.text_title || 'Select Images'); 346 $uploadBtn.removeClass('has-selection'); 347 $uploadBtn.find('.dashicons').removeClass('dashicons-yes-alt').addClass('dashicons-cloud-upload'); 348 }, 300); 349 } 350 351 // Show toast notification 352 function showToastNotification(message, type) { 353 // Remove any existing toasts 354 $('.mgwpp-toast-notification').remove(); 355 356 // Create toast element 357 const iconClass = type === 'success' ? 'dashicons-yes-alt' : 'dashicons-warning'; 358 const $toast = $(` 359 <div class="mgwpp-toast-notification ${type}"> 360 <span class="dashicons ${iconClass}"></span> 361 <span class="mgwpp-toast-message">${message}</span> 362 </div> 363 `); 364 365 // Append to body 366 $('body').append($toast); 367 368 // Trigger animation 369 setTimeout(() => { 370 $toast.addClass('show'); 371 }, 10); 372 373 // Auto-remove after delay 374 setTimeout(() => { 375 $toast.removeClass('show'); 376 setTimeout(() => { 377 $toast.remove(); 378 }, 300); 379 }, 3000); 380 } 381 197 382 function handleFormSubmission(e) { 198 383 e.preventDefault(); -
mini-gallery/trunk/includes/admin/views/dashboard/class-mgwpp-dashboard-view.php
r3438312 r3439097 85 85 86 86 // Use WP_Query instead of direct database query 87 // phpcs:disable WordPress.DB.SlowDBQuery.slow_db_query_meta_query 87 88 $query = new WP_Query([ 88 89 'post_type' => 'mgwpp_soora', … … 98 99 ], 99 100 ]); 101 // phpcs:enable WordPress.DB.SlowDBQuery.slow_db_query_meta_query 100 102 101 103 $count = $query->post_count; -
mini-gallery/trunk/includes/admin/views/edit-gallery/class-mgwpp-edit-gallery.php
r3438312 r3439097 124 124 ], home_url('/')); 125 125 $preview_url = wp_nonce_url($preview_url, 'mgwpp_preview'); 126 127 // Check for success message - updated is a read-only display flag, sanitized with absint 128 // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only display flag, no data modification 129 $updated = isset($_GET['updated']) ? absint($_GET['updated']) : 0; 126 130 ?> 127 <div class="mgwpp-dashboard-container"> 131 <div class="mgwpp-dashboard-container mgwpp-premium-dashboard"> 132 <?php if ($updated) : ?> 133 <div class="notice notice-success is-dismissible"> 134 <p><?php esc_html_e('Gallery updated successfully!', 'mini-gallery'); ?></p> 135 </div> 136 <?php endif; ?> 137 128 138 <h1><?php 129 139 printf( 130 140 /* translators: %s: Gallery title/name */ 131 esc_html__('Edit: Gallery%s', 'mini-gallery'),141 esc_html__('Edit: %s', 'mini-gallery'), 132 142 esc_html($gallery->post_title) 133 143 ); … … 135 145 136 146 <div class="mgwpp-glass-container"> 137 <div class="mgwpp-editor-column"> 138 <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" id="mgwpp-gallery-form"> 139 <input type="hidden" name="action" value="mgwpp_save_gallery"> 140 <input type="hidden" name="gallery_id" value="<?php echo esc_attr($gallery->ID); ?>"> 141 <?php wp_nonce_field('mgwpp_save_gallery_data', 'mgwpp_gallery_nonce'); ?> 142 143 <div class="mgwpp-edit-section"> 144 <h2><?php esc_html_e('Gallery Title', 'mini-gallery'); ?></h2> 145 <input type="text" name="post_title" value="<?php echo esc_attr($gallery->post_title); ?>" 146 class="widefat"> 147 </div> 148 149 <?php do_action('mgwpp_edit_gallery_before_images', $gallery); ?> 150 151 <div class="mgwpp-edit-section"> 152 <h2> 153 <?php esc_html_e('Gallery Images', 'mini-gallery'); ?> 154 <span class="mgwpp-reorder-hint"><?php esc_html_e('(Drag to reorder)', 'mini-gallery'); ?></span> 155 </h2> 156 <div class="mgwpp-image-manager"> 157 <div class="mgwpp-image-container sortable"> 158 <?php if (!empty($images)) : ?> 159 <?php foreach ($images as $image_id) : 160 $thumb_url = wp_get_attachment_image_url($image_id, 'thumbnail'); 161 if ($thumb_url) : ?> 162 <div class="mgwpp-image-item" data-id="<?php echo esc_attr($image_id); ?>"> 163 <img src="<?php echo esc_url($thumb_url); ?>"> 164 <input type="hidden" name="gallery_images[]" value="<?php echo esc_attr($image_id); ?>"> 165 <div class="mgwpp-item-actions"> 166 <button type="button" class="mgwpp-remove-image" 167 title="<?php esc_attr_e('Remove from gallery', 'mini-gallery'); ?>"> 168 <span class="dashicons dashicons-no"></span> 169 </button> 170 <button type="button" class="mgwpp-delete-image" 171 title="<?php esc_attr_e('Permanently delete', 'mini-gallery'); ?>"> 172 <span class="dashicons dashicons-trash"></span> 173 </button> 174 </div> 147 <form method="post" action="<?php echo esc_url(admin_url('admin-post.php')); ?>" id="mgwpp-gallery-form"> 148 <input type="hidden" name="action" value="mgwpp_save_gallery"> 149 <input type="hidden" name="gallery_id" value="<?php echo esc_attr($gallery->ID); ?>"> 150 <?php wp_nonce_field('mgwpp_save_gallery_data', 'mgwpp_gallery_nonce'); ?> 151 152 <!-- ROW 1: Title Section (Full Width on Top) --> 153 <div class="mgwpp-edit-section mgwpp-title-section"> 154 <h2><span class="dashicons dashicons-edit"></span> <?php esc_html_e('Gallery Title', 'mini-gallery'); ?></h2> 155 <input type="text" name="post_title" value="<?php echo esc_attr($gallery->post_title); ?>" 156 class="widefat" placeholder="<?php esc_attr_e('Enter gallery title...', 'mini-gallery'); ?>"> 157 </div> 158 159 <?php do_action('mgwpp_edit_gallery_before_images', $gallery); ?> 160 161 <!-- ROW 2: Gallery Images Section (Full Width) --> 162 <div class="mgwpp-edit-section mgwpp-images-section"> 163 <h2> 164 <span class="dashicons dashicons-images-alt2"></span> 165 <?php esc_html_e('Gallery Images', 'mini-gallery'); ?> 166 <span class="mgwpp-reorder-hint"><?php esc_html_e('(Drag to reorder)', 'mini-gallery'); ?></span> 167 </h2> 168 <div class="mgwpp-image-manager"> 169 <div class="mgwpp-image-container sortable"> 170 <?php if (!empty($images)) : ?> 171 <?php foreach ($images as $image_id) : 172 $thumb_url = wp_get_attachment_image_url($image_id, 'thumbnail'); 173 if ($thumb_url) : ?> 174 <div class="mgwpp-image-item" data-id="<?php echo esc_attr($image_id); ?>"> 175 <img src="<?php echo esc_url($thumb_url); ?>" alt=""> 176 <input type="hidden" name="gallery_images[]" value="<?php echo esc_attr($image_id); ?>"> 177 <div class="mgwpp-item-actions"> 178 <button type="button" class="mgwpp-remove-image" 179 title="<?php esc_attr_e('Remove from gallery', 'mini-gallery'); ?>"> 180 <span class="dashicons dashicons-no"></span> 181 </button> 182 <button type="button" class="mgwpp-delete-image" 183 title="<?php esc_attr_e('Permanently delete', 'mini-gallery'); ?>"> 184 <span class="dashicons dashicons-trash"></span> 185 </button> 175 186 </div> 176 <?php endif; ?> 177 <?php endforeach; ?> 178 <?php else : ?> 179 <p class="mgwpp-no-images"><?php esc_html_e('No images added to this gallery yet.', 'mini-gallery'); ?></p> 180 <?php endif; ?> 181 </div> 182 <div class="mgwpp-manager-actions"> 183 <button type="button" class="button button-primary mgwpp-add-images"> 184 <?php esc_html_e('Add Images', 'mini-gallery'); ?> 185 </button> 186 <button type="button" class="button mgwpp-save-order" id="mgwpp-save-order-btn"> 187 <?php esc_html_e('Save Order', 'mini-gallery'); ?> 188 </button> 189 </div> 187 </div> 188 <?php endif; ?> 189 <?php endforeach; ?> 190 <?php else : ?> 191 <p class="mgwpp-no-images"> 192 <span class="dashicons dashicons-format-gallery" style="font-size: 32px; width: 32px; height: 32px; margin-bottom: 10px; display: block;"></span> 193 <?php esc_html_e('No images added to this gallery yet. Click "Add Images" to get started.', 'mini-gallery'); ?> 194 </p> 195 <?php endif; ?> 196 </div> 197 <div class="mgwpp-manager-actions"> 198 <button type="button" class="button button-primary mgwpp-add-images"> 199 <span class="dashicons dashicons-cloud-upload"></span> 200 <?php esc_html_e('Add Images', 'mini-gallery'); ?> 201 </button> 202 <button type="button" class="button mgwpp-save-order" id="mgwpp-save-order-btn"> 203 <span class="dashicons dashicons-update"></span> 204 <?php esc_html_e('Save Order', 'mini-gallery'); ?> 205 </button> 190 206 </div> 191 207 </div> 192 193 <div class="mgwpp-preview-column"> 194 <div class="mgwpp-preview-container"> 195 <h2><?php esc_html_e('Gallery Preview', 'mini-gallery'); ?></h2> 196 <div class="mgwpp-preview-frame-container"> 197 <iframe id="mgwpp-preview-frame" src="<?php echo esc_url($preview_url); ?>"></iframe> 198 </div> 199 <p class="description"> 200 <?php esc_html_e('Preview updates automatically when you save changes.', 'mini-gallery'); ?> 201 </p> 208 </div> 209 210 <!-- ROW 3: Live Preview Section (Full Width with Device Toggles) --> 211 <div class="mgwpp-edit-section mgwpp-preview-section"> 212 <div class="mgwpp-preview-header"> 213 <h2><span class="dashicons dashicons-visibility"></span> <?php esc_html_e('Live Preview', 'mini-gallery'); ?></h2> 214 <div class="mgwpp-device-toggles"> 215 <button type="button" class="mgwpp-device-btn active" data-device="desktop" title="<?php esc_attr_e('Desktop', 'mini-gallery'); ?>"> 216 <span class="dashicons dashicons-desktop"></span> 217 </button> 218 <button type="button" class="mgwpp-device-btn" data-device="tablet" title="<?php esc_attr_e('Tablet', 'mini-gallery'); ?>"> 219 <span class="dashicons dashicons-tablet"></span> 220 </button> 221 <button type="button" class="mgwpp-device-btn" data-device="mobile" title="<?php esc_attr_e('Mobile', 'mini-gallery'); ?>"> 222 <span class="dashicons dashicons-smartphone"></span> 223 </button> 202 224 </div> 203 225 </div> 204 205 <div class="mgwpp-edit-section"> 206 <h2><?php esc_html_e('Gallery Type', 'mini-gallery'); ?></h2> 207 <div class="mgwpp-gallery-types"> 208 <?php foreach (self::$gallery_types as $type => $details) : 209 $type_image_url = MG_PLUGIN_URL . '/includes/admin/images/galleries-preview/' . $details[1]; 210 $is_active = $type === $current_type; 211 ?> 212 <div class="mgwpp-gallery-type <?php echo $is_active ? 'active' : ''; ?>"> 213 <label> 214 <input type="radio" name="gallery_type" value="<?php echo esc_attr($type); ?>" 215 <?php checked($is_active); ?>> 216 <div class=""> 217 <img class="mgwpp-stat-card" src="<?php echo esc_url($type_image_url); ?>" 218 width="100%" height="auto" style="max-width: 170px; object-fit: cover" alt="<?php echo esc_attr($details[0]); ?>"> 219 <span><?php echo esc_html($details[0]); ?></span> 220 </div> 221 </label> 222 </div> 223 <?php endforeach; ?> 226 <div class="mgwpp-preview-wrapper" data-device="desktop"> 227 <div class="mgwpp-preview-frame-container"> 228 <iframe id="mgwpp-preview-frame" src="<?php echo esc_url($preview_url . '&minimal=1'); ?>"></iframe> 224 229 </div> 225 230 </div> 226 227 <div class="mgwpp-edit-actions"> 228 <?php submit_button(__('Save Changes', 'mini-gallery'), 'primary', 'submit', false); ?> 231 <p class="description"> 232 <?php esc_html_e('Preview updates automatically when you save. Use device buttons to test responsiveness.', 'mini-gallery'); ?> 233 </p> 234 </div> 235 236 <!-- ROW 3: Gallery Type Selection (Full Width at Bottom) --> 237 <div class="mgwpp-edit-section mgwpp-type-section"> 238 <h2><span class="dashicons dashicons-layout"></span> <?php esc_html_e('Gallery Type', 'mini-gallery'); ?></h2> 239 <div class="mgwpp-gallery-types"> 240 <?php foreach (self::$gallery_types as $type => $details) : 241 $type_image_url = MG_PLUGIN_URL . '/includes/admin/images/galleries-preview/' . $details[1]; 242 $is_active = $type === $current_type; 243 ?> 244 <div class="mgwpp-gallery-type <?php echo $is_active ? 'active' : ''; ?>"> 245 <label> 246 <input type="radio" name="gallery_type" value="<?php echo esc_attr($type); ?>" 247 <?php checked($is_active); ?>> 248 <img class="mgwpp-stat-card" src="<?php echo esc_url($type_image_url); ?>" 249 alt="<?php echo esc_attr($details[0]); ?>"> 250 <span><?php echo esc_html($details[0]); ?></span> 251 </label> 252 </div> 253 <?php endforeach; ?> 229 254 </div> 230 </form> 231 </div> 255 </div> 256 257 <!-- Save Button --> 258 <div class="mgwpp-edit-actions"> 259 <button type="submit" name="submit" class="button button-primary"> 260 <span class="dashicons dashicons-saved"></span> 261 <?php esc_html_e('Save Changes', 'mini-gallery'); ?> 262 </button> 263 </div> 264 </form> 232 265 </div> 233 266 </div> -
mini-gallery/trunk/includes/admin/views/edit-gallery/mgwpp-edit-gallery.css
r3438312 r3439097 1 @import url('https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&family=Plus+Jakarta+Sans:wght@300;400;600;700&display=swap'); 2 3 :root { 4 --mgwpp-edit-preview-height: 70vh; 5 --mgwpp-edit-preview-mobile-height: 50vh; 6 --mgwpp-primary-color: #00f2ff; 7 --mgwpp-secondary-color: #7000ff; 8 --mgwpp-bg-dark: #050505; 9 --mgwpp-bg-panel: rgba(15, 15, 20, 0.8); 10 --mgwpp-border: rgba(255, 255, 255, 0.08); 11 --mgwpp-text-main: #ffffff; 12 --mgwpp-text-muted: rgba(255, 255, 255, 0.6); 13 --mgwpp-radius-lg: 24px; 14 } 15 16 .mgwpp-edit-wrapper { 17 max-width: 1600px; 18 margin: 0 auto; 1 /* ===================================================== 2 Edit Gallery Page - Premium UI Matching Plugin Design 3 ===================================================== */ 4 5 @import url("https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&family=Plus+Jakarta+Sans:wght@300;400;600;700&display=swap"); 6 7 /* ===================================================== 8 CSS Variables - Matching Global Plugin Theme 9 ===================================================== */ 10 .mgwpp-dashboard-container { 11 /* Light Mode Variables (Default) */ 12 --mg-bg-dark: #f0f2f5; 13 --mg-bg-panel: rgba(255, 255, 255, 0.8); 14 --mg-bg-card: rgba(255, 255, 255, 0.4); 15 --mg-border: rgba(0, 0, 0, 0.08); 16 --mg-primary: #0088ff; 17 --mg-primary-glow: rgba(0, 136, 255, 0.2); 18 --mg-secondary: #7000ff; 19 --mg-secondary-glow: rgba(112, 0, 255, 0.2); 20 --mg-text-main: #1a1a2e; 21 --mg-text-muted: rgba(0, 0, 0, 0.5); 22 --mg-danger: #ff004c; 23 --mg-success: #00ad6f; 24 --mg-radius-lg: 24px; 25 --mg-radius-md: 16px; 26 --mg-radius-sm: 8px; 27 --mg-shadow-luxury: 0 20px 50px rgba(0, 0, 0, 0.05); 28 } 29 30 body.mgwpp-dark-mode .mgwpp-dashboard-container { 31 /* Dark Mode Variables Override */ 32 --mg-bg-dark: #050505; 33 --mg-bg-panel: rgba(15, 15, 20, 0.8); 34 --mg-bg-card: rgba(25, 25, 35, 0.4); 35 --mg-border: rgba(255, 255, 255, 0.08); 36 --mg-primary: #00f2ff; 37 --mg-primary-glow: rgba(0, 242, 255, 0.4); 38 --mg-secondary: #7000ff; 39 --mg-secondary-glow: rgba(112, 0, 255, 0.4); 40 --mg-text-main: #ffffff; 41 --mg-text-muted: rgba(255, 255, 255, 0.6); 42 --mg-shadow-luxury: 0 20px 50px rgba(0, 0, 0, 0.8); 43 } 44 45 /* ===================================================== 46 Main Container - Premium Dashboard Style 47 ===================================================== */ 48 .mgwpp-dashboard-container { 49 background: var(--mg-bg-dark); 50 background-image: radial-gradient( 51 circle at 10% 20%, 52 rgba(112, 0, 255, 0.05) 0%, 53 transparent 40% 54 ), 55 radial-gradient( 56 circle at 90% 80%, 57 rgba(0, 242, 255, 0.05) 0%, 58 transparent 40% 59 ); 60 min-height: calc(100vh - 32px); 61 margin-left: -20px; 19 62 padding: 30px; 20 background: var(--mgwpp-bg-dark); 21 color: var(--mgwpp-text-main); 22 font-family: 'Plus Jakarta Sans', sans-serif; 23 min-height: 100vh; 24 } 25 26 .mgwpp-edit-title { 27 margin-bottom: 40px; 28 padding-bottom: 20px; 29 border-bottom: 1px dashed var(--mgwpp-border); 30 display: flex; 31 align-items: center; 32 justify-content: space-between; 33 } 34 35 .mgwpp-edit-title h1 { 36 font-family: 'Orbitron', sans-serif; 63 color: var(--mg-text-main); 64 font-family: "Plus Jakarta Sans", sans-serif; 65 position: relative; 66 overflow-x: hidden; 67 } 68 69 /* Animated Background Aura */ 70 .mgwpp-dashboard-container::before { 71 content: ""; 72 position: absolute; 73 top: -50%; 74 left: -50%; 75 width: 200%; 76 height: 200%; 77 background: radial-gradient( 78 circle at center, 79 rgba(112, 0, 255, 0.03) 0%, 80 transparent 50% 81 ); 82 animation: aura-float 20s infinite linear; 83 pointer-events: none; 84 z-index: 0; 85 } 86 87 @keyframes aura-float { 88 0% { 89 transform: translate(0, 0) rotate(0deg); 90 } 91 100% { 92 transform: translate(10%, 10%) rotate(360deg); 93 } 94 } 95 96 /* ===================================================== 97 Page Header 98 ===================================================== */ 99 .mgwpp-dashboard-container > h1 { 100 color: var(--mg-text-main); 101 font-family: "Orbitron", sans-serif; 37 102 font-size: 28px; 103 font-weight: 700; 104 margin: 0 0 30px 0; 38 105 letter-spacing: 2px; 39 color: var(--mgwpp-text-main); 40 text-shadow: 0 0 15px rgba(0, 242, 255, 0.3); 41 } 42 43 .mgwpp-edit-columns { 44 display: flex; 45 gap: 30px; 46 } 47 48 .mgwpp-settings-column, 49 .mgwpp-preview-column { 50 flex: 1; 51 min-width: 0; 52 } 53 54 .mgwpp-form-section { 55 margin-bottom: 30px; 106 text-shadow: 0 0 20px var(--mg-primary-glow); 107 position: relative; 108 z-index: 1; 109 display: flex; 110 align-items: center; 111 gap: 15px; 112 } 113 114 .mgwpp-dashboard-container > h1::before { 115 content: "✏️"; 116 font-size: 24px; 117 } 118 119 /* ===================================================== 120 Glass Container - Main Panel 121 ===================================================== */ 122 .mgwpp-glass-container { 123 background: var(--mg-bg-panel); 124 backdrop-filter: blur(25px) saturate(180%); 125 -webkit-backdrop-filter: blur(25px) saturate(180%); 126 border: 1px solid var(--mg-border); 127 border-radius: var(--mg-radius-lg); 128 padding: 35px; 129 box-shadow: var(--mg-shadow-luxury); 130 position: relative; 131 z-index: 1; 132 } 133 134 /* ===================================================== 135 Section Layout - All Full Width Stacked 136 ===================================================== */ 137 /* Title Section - Full Width */ 138 .mgwpp-title-section { 139 margin-bottom: 25px; 140 } 141 142 /* Images Section - Full Width */ 143 .mgwpp-images-section { 144 margin-bottom: 25px; 145 } 146 147 /* Type Section - Full Width at Bottom */ 148 .mgwpp-type-section { 149 margin-top: 0; 150 } 151 152 /* ===================================================== 153 Edit Sections - Cards 154 ===================================================== */ 155 .mgwpp-edit-section { 156 background: var(--mg-bg-card); 157 border: 1px solid var(--mg-border); 158 border-radius: var(--mg-radius-md); 56 159 padding: 25px; 57 background: var(--mgwpp-bg-panel); 58 backdrop-filter: blur(25px) saturate(180%); 59 border: 1px solid var(--mgwpp-border); 60 border-radius: var(--mgwpp-radius-lg); 61 box-shadow: 0 20px 50px rgba(0, 0, 0, 0.3); 62 } 63 64 .mgwpp-form-section h2 { 65 margin-top: 0; 160 position: relative; 161 backdrop-filter: blur(10px); 162 transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1); 163 } 164 165 .mgwpp-edit-section::before { 166 content: ""; 167 position: absolute; 168 top: 0; 169 left: 0; 170 right: 0; 171 height: 3px; 172 background: linear-gradient(90deg, var(--mg-primary), var(--mg-secondary)); 173 border-radius: var(--mg-radius-md) var(--mg-radius-md) 0 0; 174 opacity: 0; 175 transition: opacity 0.3s; 176 } 177 178 .mgwpp-edit-section:hover { 179 border-color: var(--mg-primary); 180 box-shadow: 0 10px 30px rgba(0, 0, 0, 0.1), 0 0 15px var(--mg-primary-glow); 181 } 182 183 .mgwpp-edit-section:hover::before { 184 opacity: 1; 185 } 186 187 /* Section Headers */ 188 .mgwpp-edit-section h2 { 189 margin: 0 0 20px 0; 66 190 padding-bottom: 15px; 67 border-bottom: 1px solid var(--mgwpp-border); 68 font-family: 'Orbitron', sans-serif; 69 font-size: 16px; 191 border-bottom: 1px dashed var(--mg-border); 192 font-family: "Orbitron", sans-serif; 193 font-size: 14px; 194 font-weight: 700; 70 195 text-transform: uppercase; 71 196 letter-spacing: 1.5px; 72 color: var(--mgwpp-primary-color); 73 } 74 75 /* Gallery Type Selection */ 76 .mgwpp-gallery-types { 77 display: grid; 78 grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); 79 gap: 15px; 80 } 81 82 .mgwpp-gallery-type { 83 border-radius: var(--mgwpp-border-radius); 84 padding: 10px; 85 cursor: pointer; 86 transition: all 0.2s; 87 background: var(--mgwpp-card-bg-light); 88 } 89 90 .mgwpp-dark-mode .mgwpp-gallery-type { 91 border-color: var(--mgwpp-card-border-dark); 92 background: var(--mgwpp-card-bg-dark); 93 } 94 95 .mgwpp-gallery-type:hover { 96 border-color: var(--mgwpp-primary-color); 97 } 98 99 .mgwpp-gallery-type.active { 100 border-color: var(--mgwpp-primary-color); 101 background-color: var(--mgwpp-primary-light); 102 } 103 104 .mgwpp-type-preview { 105 text-align: center; 106 display: flex; 107 flex-direction: column; 108 align-items: center; 109 } 110 111 .mgwpp-type-preview img { 112 height: auto; 113 max-width: 500px; 197 color: var(--mg-primary); 198 display: flex; 199 align-items: center; 200 gap: 10px; 201 } 202 203 .mgwpp-reorder-hint { 204 font-family: "Plus Jakarta Sans", sans-serif; 205 font-size: 12px; 206 font-weight: 400; 207 color: var(--mg-text-muted); 208 text-transform: none; 209 letter-spacing: normal; 210 } 211 212 /* ===================================================== 213 Form Inputs - Modern Style 214 ===================================================== */ 215 .mgwpp-edit-section input[type="text"].widefat { 114 216 width: 100%; 115 border-radius: 3px; 116 margin-bottom: 8px; 117 } 118 119 /* Image Manager */ 217 background: var(--mg-bg-dark); 218 border: 1px solid var(--mg-border); 219 border-radius: 12px; 220 padding: 14px 18px; 221 color: var(--mg-text-main); 222 font-size: 15px; 223 font-family: "Plus Jakarta Sans", sans-serif; 224 transition: all 0.3s; 225 } 226 227 body.mgwpp-dark-mode .mgwpp-edit-section input[type="text"].widefat { 228 background: rgba(0, 0, 0, 0.4); 229 } 230 231 .mgwpp-edit-section input[type="text"].widefat:focus { 232 border-color: var(--mg-primary); 233 box-shadow: 0 0 0 3px var(--mg-primary-glow); 234 outline: none; 235 } 236 237 .mgwpp-edit-section input[type="text"].widefat::placeholder { 238 color: var(--mg-text-muted); 239 } 240 241 /* ===================================================== 242 Image Manager Section 243 ===================================================== */ 120 244 .mgwpp-image-manager { 121 margin-top: 1 5px;245 margin-top: 10px; 122 246 } 123 247 124 248 .mgwpp-image-container { 125 249 display: grid; 126 grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); 127 gap: 15px; 128 margin-bottom: 15px; 129 } 130 250 grid-template-columns: repeat(auto-fill, minmax(100px, 1fr)); 251 gap: 12px; 252 margin-bottom: 20px; 253 min-height: 100px; 254 } 255 256 /* Image Items - Fixed uniform size */ 131 257 .mgwpp-image-item { 132 258 position: relative; 133 border: 1px solid var(--mgwpp-card-border-light); 134 border-radius: var(--mgwpp-border-radius); 135 padding: 5px; 136 background: var(--mgwpp-card-bg-light); 137 transition: all 0.2s; 138 } 139 140 .mgwpp-dark-mode .mgwpp-image-item { 141 border-color: var(--mgwpp-card-border-dark); 142 background: var(--mgwpp-card-bg-dark); 259 width: 100%; 260 height: 100px; 261 background: rgba(0, 0, 0, 0.3); 262 border: 2px solid var(--mg-border); 263 border-radius: 10px; 264 overflow: hidden; 265 transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1); 266 cursor: grab; 267 display: flex; 268 align-items: center; 269 justify-content: center; 270 } 271 272 .mgwpp-image-item:hover { 273 border-color: var(--mg-primary); 274 transform: translateY(-3px) scale(1.02); 275 box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2), 0 0 15px var(--mg-primary-glow); 276 } 277 278 .mgwpp-image-item:active { 279 cursor: grabbing; 143 280 } 144 281 145 282 .mgwpp-image-item img { 146 283 width: 100%; 147 height: auto; 284 height: 100%; 285 object-fit: contain; 148 286 display: block; 149 border-radius: var(--mgwpp-border-radius-sm); 150 } 151 152 /* Image Index Indicator */ 287 transition: transform 0.3s; 288 padding: 4px; 289 box-sizing: border-box; 290 } 291 292 .mgwpp-image-item:hover img { 293 transform: scale(1.05); 294 } 295 296 /* Image Index Badge */ 153 297 .mgwpp-image-index { 154 position: absolute; 155 top: 5px; 156 left: 5px; 157 background: rgba(0, 0, 0, 0.7); 158 color: white; 159 font-size: 11px; 160 padding: 2px 6px; 161 border-radius: 4px; 162 font-weight: bold; 163 z-index: 10; 164 pointer-events: none; 165 border: 1px solid rgba(255,255,255,0.2); 166 } 167 168 /* Per-image actions (delete buttons) */ 298 position: absolute; 299 top: 8px; 300 left: 8px; 301 background: linear-gradient(135deg, var(--mg-primary), var(--mg-secondary)); 302 color: #fff; 303 font-family: "Orbitron", sans-serif; 304 font-size: 10px; 305 font-weight: 700; 306 padding: 4px 8px; 307 border-radius: 6px; 308 z-index: 10; 309 pointer-events: none; 310 text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3); 311 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); 312 } 313 314 /* Image Action Buttons */ 169 315 .mgwpp-item-actions { 170 316 position: absolute; 171 top: 5px;172 right: 5px;173 display: flex; 174 gap: 3px;317 top: 8px; 318 right: 8px; 319 display: flex; 320 gap: 5px; 175 321 opacity: 0; 176 transition: opacity 0.2s ease; 322 transform: translateY(-5px); 323 transition: all 0.3s ease; 177 324 z-index: 20; 178 325 } … … 180 327 .mgwpp-image-item:hover .mgwpp-item-actions { 181 328 opacity: 1; 329 transform: translateY(0); 182 330 } 183 331 184 332 .mgwpp-item-actions button { 185 333 background: rgba(0, 0, 0, 0.7); 186 border: none; 187 border-radius: 2px; 188 color: white; 334 backdrop-filter: blur(5px); 335 border: 1px solid rgba(255, 255, 255, 0.1); 336 border-radius: 8px; 337 color: #fff; 189 338 cursor: pointer; 190 width: 2 4px;191 height: 2 4px;339 width: 28px; 340 height: 28px; 192 341 display: flex; 193 342 align-items: center; 194 343 justify-content: center; 195 344 padding: 0; 345 transition: all 0.2s; 196 346 } 197 347 198 348 .mgwpp-item-actions button:hover { 199 background: #d54e21; 349 background: var(--mg-danger); 350 border-color: var(--mg-danger); 351 transform: scale(1.1); 200 352 } 201 353 202 354 .mgwpp-item-actions button .dashicons { 203 font-size: 16px; 204 width: 16px; 205 height: 16px; 206 } 207 208 /* Manager actions (Add Images, Save Order) */ 355 font-size: 14px; 356 width: 14px; 357 height: 14px; 358 } 359 360 /* Sortable Feedback */ 361 .mgwpp-image-container.sortable .mgwpp-image-item.ui-sortable-helper { 362 transform: rotate(3deg) scale(1.05); 363 box-shadow: 0 20px 40px rgba(0, 0, 0, 0.4), 0 0 30px var(--mg-primary-glow); 364 z-index: 100; 365 } 366 367 .mgwpp-image-container .ui-sortable-placeholder { 368 background: var(--mg-primary-glow); 369 border: 2px dashed var(--mg-primary); 370 border-radius: 12px; 371 visibility: visible !important; 372 } 373 374 /* No Images Message */ 375 .mgwpp-no-images { 376 color: var(--mg-text-muted); 377 text-align: center; 378 padding: 40px 20px; 379 font-size: 14px; 380 grid-column: 1 / -1; 381 background: rgba(0, 0, 0, 0.1); 382 border-radius: 12px; 383 border: 2px dashed var(--mg-border); 384 } 385 386 body.mgwpp-dark-mode .mgwpp-no-images { 387 background: rgba(255, 255, 255, 0.05); 388 } 389 390 /* ===================================================== 391 Manager Actions - Premium Buttons 392 ===================================================== */ 209 393 .mgwpp-manager-actions { 210 394 display: flex; 211 gap: 10px; 212 margin-top: 15px; 213 } 214 215 /* Preview styles */ 216 .mgwpp-preview-container { 217 background: var(--mgwpp-card-bg-light); 218 border: var(--mgwpp-edit-preview-border); 219 border-radius: var(--mgwpp-border-radius); 395 flex-wrap: wrap; 396 gap: 12px; 397 margin-top: 20px; 398 } 399 400 /* Override WordPress button styles */ 401 .mgwpp-manager-actions .button, 402 .mgwpp-manager-actions .button-primary { 403 display: inline-flex; 404 align-items: center; 405 gap: 8px; 406 padding: 12px 24px; 407 border-radius: var(--mg-radius-sm); 408 font-size: 13px; 409 font-weight: 700; 410 font-family: "Plus Jakarta Sans", sans-serif; 411 text-transform: uppercase; 412 letter-spacing: 0.5px; 413 cursor: pointer; 414 transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1); 415 text-decoration: none; 416 border: 1px solid transparent; 417 position: relative; 220 418 overflow: hidden; 221 padding: 15px; 222 } 223 224 .mgwpp-dark-mode .mgwpp-preview-container { 225 background: var(--mgwpp-card-bg-dark); 226 } 227 419 height: auto; 420 line-height: 1.4; 421 } 422 423 .mgwpp-manager-actions .button::after, 424 .mgwpp-manager-actions .button-primary::after { 425 content: ""; 426 position: absolute; 427 top: 0; 428 left: -100%; 429 width: 100%; 430 height: 100%; 431 background: linear-gradient( 432 90deg, 433 transparent, 434 rgba(255, 255, 255, 0.2), 435 transparent 436 ); 437 transition: 0.5s; 438 } 439 440 .mgwpp-manager-actions .button:hover::after, 441 .mgwpp-manager-actions .button-primary:hover::after { 442 left: 100%; 443 } 444 445 /* Primary Button - Add Images */ 446 .mgwpp-manager-actions .button-primary, 447 .mgwpp-manager-actions .mgwpp-add-images { 448 background: linear-gradient( 449 135deg, 450 var(--mg-primary), 451 var(--mg-secondary) 452 ) !important; 453 color: #fff !important; 454 box-shadow: 0 0 15px var(--mg-primary-glow); 455 border: none !important; 456 } 457 458 .mgwpp-manager-actions .button-primary:hover, 459 .mgwpp-manager-actions .mgwpp-add-images:hover { 460 transform: translateY(-3px) scale(1.02); 461 box-shadow: 0 0 30px var(--mg-primary-glow), 0 10px 25px rgba(0, 0, 0, 0.2); 462 } 463 464 /* Secondary Button - Save Order */ 465 .mgwpp-manager-actions .button:not(.button-primary), 466 .mgwpp-manager-actions .mgwpp-save-order { 467 background: var(--mg-bg-dark) !important; 468 color: var(--mg-text-main) !important; 469 border: 1px solid var(--mg-border) !important; 470 backdrop-filter: blur(5px); 471 } 472 473 body.mgwpp-dark-mode .mgwpp-manager-actions .button:not(.button-primary), 474 body.mgwpp-dark-mode .mgwpp-manager-actions .mgwpp-save-order { 475 background: rgba(255, 255, 255, 0.05) !important; 476 } 477 478 .mgwpp-manager-actions .button:not(.button-primary):hover, 479 .mgwpp-manager-actions .mgwpp-save-order:hover { 480 border-color: var(--mg-primary) !important; 481 box-shadow: 0 0 15px var(--mg-primary-glow); 482 transform: translateY(-2px); 483 } 484 485 /* ===================================================== 486 Preview Section - Full Width with Device Toggles 487 ===================================================== */ 488 .mgwpp-preview-section { 489 margin-bottom: 25px; 490 } 491 492 .mgwpp-preview-header { 493 display: flex; 494 justify-content: space-between; 495 align-items: center; 496 margin-bottom: 20px; 497 padding-bottom: 15px; 498 border-bottom: 1px dashed var(--mg-border); 499 } 500 501 .mgwpp-preview-header h2 { 502 margin: 0; 503 padding: 0; 504 border: none; 505 } 506 507 /* Device Toggle Buttons */ 508 .mgwpp-device-toggles { 509 display: flex; 510 gap: 8px; 511 background: var(--mg-bg-dark); 512 padding: 6px; 513 border-radius: 10px; 514 border: 1px solid var(--mg-border); 515 } 516 517 body.mgwpp-dark-mode .mgwpp-device-toggles { 518 background: rgba(0, 0, 0, 0.4); 519 } 520 521 .mgwpp-device-btn { 522 display: flex; 523 align-items: center; 524 justify-content: center; 525 width: 40px; 526 height: 36px; 527 background: transparent; 528 border: 1px solid transparent; 529 border-radius: 8px; 530 color: var(--mg-text-muted); 531 cursor: pointer; 532 transition: all 0.3s; 533 } 534 535 .mgwpp-device-btn:hover { 536 background: rgba(0, 0, 0, 0.1); 537 color: var(--mg-text-main); 538 } 539 540 body.mgwpp-dark-mode .mgwpp-device-btn:hover { 541 background: rgba(255, 255, 255, 0.1); 542 } 543 544 .mgwpp-device-btn.active { 545 background: linear-gradient(135deg, var(--mg-primary), var(--mg-secondary)); 546 color: #fff; 547 border-color: transparent; 548 box-shadow: 0 0 10px var(--mg-primary-glow); 549 } 550 551 .mgwpp-device-btn .dashicons { 552 font-size: 18px; 553 width: 18px; 554 height: 18px; 555 } 556 557 /* Preview Wrapper - Device Simulation */ 558 .mgwpp-preview-wrapper { 559 background: var(--mg-bg-dark); 560 border-radius: 12px; 561 padding: 20px; 562 display: flex; 563 justify-content: center; 564 align-items: flex-start; 565 min-height: 400px; 566 overflow: auto; 567 border: 1px solid var(--mg-border); 568 } 569 570 body.mgwpp-dark-mode .mgwpp-preview-wrapper { 571 background: rgba(0, 0, 0, 0.3); 572 } 573 574 /* Device Frame Sizes - Taller heights */ 575 .mgwpp-preview-wrapper[data-device="desktop"] .mgwpp-preview-frame-container { 576 width: 100%; 577 max-width: 100%; 578 height: 550px; 579 } 580 581 .mgwpp-preview-wrapper[data-device="tablet"] .mgwpp-preview-frame-container { 582 width: 768px; 583 max-width: 100%; 584 height: 600px; 585 border-radius: 16px; 586 box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3); 587 } 588 589 .mgwpp-preview-wrapper[data-device="mobile"] .mgwpp-preview-frame-container { 590 width: 375px; 591 max-width: 100%; 592 height: 650px; 593 border-radius: 24px; 594 box-shadow: 0 10px 40px rgba(0, 0, 0, 0.3); 595 } 596 597 /* Preview Frame Container */ 228 598 .mgwpp-preview-frame-container { 229 599 position: relative; 230 width: 100%; 231 height: var(--mgwpp-edit-preview-height); 232 border-radius: var(--mgwpp-border-radius-sm); 600 border-radius: 12px; 233 601 overflow: hidden; 234 margin-top: 15px; 602 background: #ffffff; 603 border: 3px solid var(--mg-border); 604 transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1); 235 605 } 236 606 … … 239 609 height: 100%; 240 610 border: 0; 241 background: white; 242 } 243 244 .mgwpp-dark-mode #mgwpp-preview-frame { 245 background: #1e1e1e; 246 } 247 248 /* Responsive layout */ 249 @media (max-width: 1200px) { 250 .mgwpp-edit-columns { 611 background: #fff; 612 display: block; 613 } 614 615 body.mgwpp-dark-mode #mgwpp-preview-frame { 616 background: #1a1a1a; 617 } 618 619 .mgwpp-preview-section .description { 620 color: var(--mg-text-muted); 621 font-size: 12px; 622 margin-top: 15px; 623 display: flex; 624 align-items: center; 625 gap: 8px; 626 justify-content: center; 627 } 628 629 .mgwpp-preview-section .description::before { 630 content: "ℹ️"; 631 font-size: 14px; 632 } 633 634 /* ===================================================== 635 Gallery Type Selection - Modern Cards 636 ===================================================== */ 637 .mgwpp-gallery-types { 638 display: grid; 639 grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); 640 gap: 12px; 641 } 642 643 .mgwpp-gallery-type { 644 background: var(--mg-bg-dark); 645 border: 2px solid var(--mg-border); 646 border-radius: 10px; 647 padding: 10px; 648 cursor: pointer; 649 transition: all 0.3s cubic-bezier(0.23, 1, 0.32, 1); 650 position: relative; 651 overflow: hidden; 652 } 653 654 body.mgwpp-dark-mode .mgwpp-gallery-type { 655 background: rgba(0, 0, 0, 0.3); 656 } 657 658 .mgwpp-gallery-type::before { 659 content: ""; 660 position: absolute; 661 top: 0; 662 left: 0; 663 right: 0; 664 bottom: 0; 665 border-radius: inherit; 666 padding: 2px; 667 background: linear-gradient(135deg, transparent, transparent); 668 -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); 669 mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); 670 -webkit-mask-composite: xor; 671 mask-composite: exclude; 672 pointer-events: none; 673 transition: 0.3s; 674 } 675 676 .mgwpp-gallery-type:hover { 677 border-color: var(--mg-primary); 678 transform: translateY(-3px); 679 box-shadow: 0 10px 25px rgba(0, 0, 0, 0.15), 0 0 15px var(--mg-primary-glow); 680 } 681 682 .mgwpp-gallery-type:hover::before { 683 background: linear-gradient(135deg, var(--mg-primary), var(--mg-secondary)); 684 } 685 686 .mgwpp-gallery-type.active { 687 border-color: var(--mg-primary); 688 background: var(--mg-primary-glow); 689 } 690 691 .mgwpp-gallery-type.active::before { 692 background: linear-gradient(135deg, var(--mg-primary), var(--mg-secondary)); 693 } 694 695 /* Gallery Type Label */ 696 .mgwpp-gallery-type label { 697 cursor: pointer; 698 display: flex; 699 flex-direction: column; 700 align-items: center; 701 } 702 703 .mgwpp-gallery-type input[type="radio"] { 704 position: absolute; 705 opacity: 0; 706 width: 0; 707 height: 0; 708 } 709 710 /* Gallery Type Preview Image - Fixed aspect ratio */ 711 .mgwpp-gallery-type img.mgwpp-stat-card { 712 width: 100%; 713 aspect-ratio: 16 / 10; 714 object-fit: contain; 715 border-radius: 6px; 716 margin-bottom: 8px; 717 transition: transform 0.3s; 718 background: rgba(0, 0, 0, 0.1); 719 } 720 721 body.mgwpp-dark-mode .mgwpp-gallery-type img.mgwpp-stat-card { 722 background: rgba(255, 255, 255, 0.05); 723 } 724 725 .mgwpp-gallery-type:hover img.mgwpp-stat-card { 726 transform: scale(1.03); 727 } 728 729 /* Gallery Type Name */ 730 .mgwpp-gallery-type span { 731 display: block; 732 font-size: 12px; 733 font-weight: 600; 734 color: var(--mg-text-main); 735 text-align: center; 736 letter-spacing: 0.3px; 737 } 738 739 /* Active Selection Indicator */ 740 .mgwpp-gallery-type.active::after { 741 content: "✓"; 742 position: absolute; 743 top: 10px; 744 right: 10px; 745 width: 22px; 746 height: 22px; 747 background: var(--mg-primary); 748 border-radius: 50%; 749 display: flex; 750 align-items: center; 751 justify-content: center; 752 font-size: 12px; 753 color: #fff; 754 font-weight: bold; 755 box-shadow: 0 2px 8px var(--mg-primary-glow); 756 } 757 758 /* ===================================================== 759 Save Changes Button - Main Action 760 ===================================================== */ 761 .mgwpp-edit-actions { 762 margin-top: 30px; 763 padding-top: 25px; 764 border-top: 1px dashed var(--mg-border); 765 display: flex; 766 justify-content: flex-end; 767 } 768 769 .mgwpp-edit-actions #submit, 770 .mgwpp-edit-actions .button-primary { 771 display: inline-flex; 772 align-items: center; 773 gap: 10px; 774 padding: 14px 35px; 775 border-radius: var(--mg-radius-sm); 776 font-size: 14px; 777 font-weight: 700; 778 font-family: "Plus Jakarta Sans", sans-serif; 779 text-transform: uppercase; 780 letter-spacing: 1px; 781 cursor: pointer; 782 transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1); 783 text-decoration: none; 784 border: none !important; 785 background: linear-gradient( 786 135deg, 787 var(--mg-primary), 788 var(--mg-secondary) 789 ) !important; 790 color: #fff !important; 791 box-shadow: 0 0 20px var(--mg-primary-glow); 792 position: relative; 793 overflow: hidden; 794 height: auto; 795 line-height: 1.4; 796 } 797 798 .mgwpp-edit-actions #submit::before, 799 .mgwpp-edit-actions .button-primary::before { 800 content: "💾"; 801 font-size: 16px; 802 } 803 804 .mgwpp-edit-actions #submit::after, 805 .mgwpp-edit-actions .button-primary::after { 806 content: ""; 807 position: absolute; 808 top: 0; 809 left: -100%; 810 width: 100%; 811 height: 100%; 812 background: linear-gradient( 813 90deg, 814 transparent, 815 rgba(255, 255, 255, 0.3), 816 transparent 817 ); 818 transition: 0.5s; 819 } 820 821 .mgwpp-edit-actions #submit:hover, 822 .mgwpp-edit-actions .button-primary:hover { 823 transform: translateY(-3px) scale(1.03); 824 box-shadow: 0 0 40px var(--mg-primary-glow), 0 15px 30px rgba(0, 0, 0, 0.2); 825 } 826 827 .mgwpp-edit-actions #submit:hover::after, 828 .mgwpp-edit-actions .button-primary:hover::after { 829 left: 100%; 830 } 831 832 /* ===================================================== 833 Success Message - Updated Notice 834 ===================================================== */ 835 .mgwpp-dashboard-container .notice-success, 836 .mgwpp-dashboard-container .updated { 837 background: rgba(0, 173, 111, 0.1); 838 border: 1px solid var(--mg-success); 839 border-left: 4px solid var(--mg-success); 840 border-radius: 12px; 841 padding: 15px 20px; 842 margin-bottom: 20px; 843 color: var(--mg-success); 844 font-weight: 500; 845 } 846 847 /* ===================================================== 848 Responsive Adjustments 849 ===================================================== */ 850 @media (max-width: 1024px) { 851 .mgwpp-preview-header { 251 852 flex-direction: column; 252 } 253 254 .mgwpp-preview-column { 255 order: -1; 256 margin-bottom: 30px; 853 gap: 15px; 854 align-items: flex-start; 855 } 856 857 .mgwpp-device-toggles { 858 width: 100%; 859 justify-content: center; 257 860 } 258 861 } 259 862 260 863 @media (max-width: 782px) { 864 .mgwpp-dashboard-container { 865 padding: 15px; 866 margin-left: -10px; 867 } 868 869 .mgwpp-glass-container { 870 padding: 20px; 871 } 872 873 .mgwpp-dashboard-container > h1 { 874 font-size: 20px; 875 } 876 261 877 .mgwpp-gallery-types { 262 grid-template-columns: repeat(auto-fill, minmax(1 50px, 1fr));878 grid-template-columns: repeat(auto-fill, minmax(130px, 1fr)); 263 879 } 264 880 265 881 .mgwpp-image-container { 266 grid-template-columns: repeat(auto-fill, minmax(120px, 1fr)); 267 } 268 269 .mgwpp-preview-frame-container { 270 height: var(--mgwpp-edit-preview-mobile-height); 271 } 272 882 grid-template-columns: repeat(auto-fill, minmax(90px, 1fr)); 883 gap: 10px; 884 } 885 886 .mgwpp-preview-wrapper { 887 padding: 10px; 888 min-height: 300px; 889 } 890 891 .mgwpp-preview-wrapper[data-device="desktop"] .mgwpp-preview-frame-container, 892 .mgwpp-preview-wrapper[data-device="tablet"] .mgwpp-preview-frame-container, 893 .mgwpp-preview-wrapper[data-device="mobile"] .mgwpp-preview-frame-container { 894 height: 350px; 895 } 896 273 897 .mgwpp-manager-actions { 274 898 flex-direction: column; 275 gap: 8px; 276 } 277 } 278 279 /* Sortable UI feedback */ 280 .mgwpp-image-container.sortable { 281 min-height: 100px; 282 } 283 284 .mgwpp-image-container.sortable .mgwpp-image-item { 285 cursor: move; 286 } 287 288 .mgwpp-image-container.sortable .mgwpp-image-item.ui-sortable-helper { 289 transform: rotate(3deg); 290 box-shadow: 0 4px 10px rgba(0, 0, 0, 0.2); 291 } 899 } 900 901 .mgwpp-manager-actions .button, 902 .mgwpp-manager-actions .button-primary { 903 width: 100%; 904 justify-content: center; 905 } 906 } 907 908 @media (max-width: 480px) { 909 .mgwpp-gallery-types { 910 grid-template-columns: repeat(2, 1fr); 911 } 912 913 .mgwpp-image-container { 914 grid-template-columns: repeat(3, 1fr); 915 } 916 917 .mgwpp-device-btn { 918 width: 36px; 919 height: 32px; 920 } 921 } 922 923 /* ===================================================== 924 Animations 925 ===================================================== */ 926 @keyframes fadeInUp { 927 from { 928 opacity: 0; 929 transform: translateY(20px); 930 } 931 to { 932 opacity: 1; 933 transform: translateY(0); 934 } 935 } 936 937 .mgwpp-title-section { 938 animation: fadeInUp 0.5s ease-out backwards; 939 animation-delay: 0.05s; 940 } 941 942 .mgwpp-images-section { 943 animation: fadeInUp 0.5s ease-out backwards; 944 animation-delay: 0.1s; 945 } 946 947 .mgwpp-preview-section { 948 animation: fadeInUp 0.5s ease-out backwards; 949 animation-delay: 0.15s; 950 } 951 952 .mgwpp-type-section { 953 animation: fadeInUp 0.5s ease-out backwards; 954 animation-delay: 0.2s; 955 } 956 957 .mgwpp-edit-actions { 958 animation: fadeInUp 0.5s ease-out backwards; 959 animation-delay: 0.25s; 960 } 961 962 /* Device transition animation */ 963 .mgwpp-device-transition { 964 animation: deviceSwitch 0.4s ease-out; 965 } 966 967 @keyframes deviceSwitch { 968 0% { 969 opacity: 0.5; 970 transform: scale(0.95); 971 } 972 100% { 973 opacity: 1; 974 transform: scale(1); 975 } 976 } 977 978 /* ===================================================== 979 Custom Scrollbar 980 ===================================================== */ 981 .mgwpp-dashboard-container::-webkit-scrollbar { 982 width: 8px; 983 } 984 985 .mgwpp-dashboard-container::-webkit-scrollbar-track { 986 background: var(--mg-bg-dark); 987 } 988 989 .mgwpp-dashboard-container::-webkit-scrollbar-thumb { 990 background: var(--mg-primary); 991 border-radius: 4px; 992 } 993 994 .mgwpp-dashboard-container::-webkit-scrollbar-thumb:hover { 995 background: var(--mg-secondary); 996 } -
mini-gallery/trunk/includes/admin/views/edit-gallery/mgwpp-edit-gallery.js
r3438312 r3439097 94 94 '<img src="' + thumbUrl + '" alt="">' + 95 95 '<input type="hidden" name="gallery_images[]" value="' + attachment.id + '">' + 96 '<button type="button" class="mgwpp-remove-image" title="Remove">×</button>' + 96 '<div class="mgwpp-item-actions">' + 97 '<button type="button" class="mgwpp-remove-image" title="Remove from gallery"><span class="dashicons dashicons-no"></span></button>' + 98 '<button type="button" class="mgwpp-delete-image" title="Permanently delete"><span class="dashicons dashicons-trash"></span></button>' + 99 '</div>' + 97 100 '</div>' 98 101 ); … … 240 243 $('.mgwpp-color-field').wpColorPicker(); 241 244 } 245 246 // Device toggle buttons for responsive preview 247 $('.mgwpp-device-btn').on('click', function () { 248 var $btn = $(this); 249 var device = $btn.data('device'); 250 251 // Update active button state 252 $('.mgwpp-device-btn').removeClass('active'); 253 $btn.addClass('active'); 254 255 // Update preview wrapper data attribute 256 $('.mgwpp-preview-wrapper').attr('data-device', device); 257 258 // Add animation class 259 $('.mgwpp-preview-frame-container').addClass('mgwpp-device-transition'); 260 setTimeout(function () { 261 $('.mgwpp-preview-frame-container').removeClass('mgwpp-device-transition'); 262 }, 400); 263 }); 242 264 }); -
mini-gallery/trunk/includes/admin/views/galleries/class-mgwpp-galleries-view.php
r3438312 r3439097 410 410 <div class="mgwpp-form-group"> 411 411 <label for="mgwpp-create-gallery-title"><?php esc_html_e('Gallery Title', 'mini-gallery'); ?></label> 412 <input type="text" id="mgwpp-create-gallery-title" name="gallery_title" required placeholder="<?php esc_attr_e('Enter gallery title...', 'mini-gallery'); ?>">412 <input type="text" id="mgwpp-create-gallery-title" name="gallery_title" placeholder="<?php esc_attr_e('Enter gallery title (optional - auto-generated if empty)', 'mini-gallery'); ?>"> 413 413 </div> 414 414 … … 448 448 449 449 <div class="mgwpp-modal-footer"> 450 < button type="submit" class="mgwpp-btn mgwpp-btn-primary">451 <span class="dashicons dashicons- yes"></span>452 <?php esc_html_e(' Create Gallery', 'mini-gallery'); ?>453 </ button>450 <p class="mgwpp-auto-create-hint"> 451 <span class="dashicons dashicons-info"></span> 452 <?php esc_html_e('Gallery will be created automatically after selecting images.', 'mini-gallery'); ?> 453 </p> 454 454 </div> 455 455 </form> -
mini-gallery/trunk/includes/admin/views/galleries/mgwpp-galleries-view.css
r3438312 r3439097 1 1 /* Futuristic & Luxury Gallery Dashboard Styles */ 2 2 3 @import url( 'https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&family=Plus+Jakarta+Sans:wght@300;400;600;700&display=swap');3 @import url("https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700&family=Plus+Jakarta+Sans:wght@300;400;600;700&display=swap"); 4 4 5 5 .mgwpp-premium-dashboard { 6 /* Light Mode Variables (Default) */7 --mg-bg-dark: #f0f2f5;8 --mg-bg-panel: rgba(255, 255, 255, 0.8);9 --mg-bg-card: rgba(255, 255, 255, 0.4);10 --mg-border: rgba(0, 0, 0, 0.08);11 --mg-primary: #0088ff;12 --mg-primary-glow: rgba(0, 136, 255, 0.2);13 --mg-secondary: #7000ff;14 --mg-secondary-glow: rgba(112, 0, 255, 0.2);15 --mg-text-main: #1a1a2e;16 --mg-text-muted: rgba(0, 0, 0, 0.5);17 --mg-danger: #ff004c;18 --mg-success: #00ad6f;19 --mg-radius-lg: 24px;20 --mg-radius-md: 16px;21 --mg-radius-sm: 8px;22 --mg-shadow-luxury: 0 20px 50px rgba(0, 0, 0, 0.05);23 24 background: var(--mg-bg-dark);6 /* Light Mode Variables (Default) */ 7 --mg-bg-dark: #f0f2f5; 8 --mg-bg-panel: rgba(255, 255, 255, 0.8); 9 --mg-bg-card: rgba(255, 255, 255, 0.4); 10 --mg-border: rgba(0, 0, 0, 0.08); 11 --mg-primary: #0088ff; 12 --mg-primary-glow: rgba(0, 136, 255, 0.2); 13 --mg-secondary: #7000ff; 14 --mg-secondary-glow: rgba(112, 0, 255, 0.2); 15 --mg-text-main: #1a1a2e; 16 --mg-text-muted: rgba(0, 0, 0, 0.5); 17 --mg-danger: #ff004c; 18 --mg-success: #00ad6f; 19 --mg-radius-lg: 24px; 20 --mg-radius-md: 16px; 21 --mg-radius-sm: 8px; 22 --mg-shadow-luxury: 0 20px 50px rgba(0, 0, 0, 0.05); 23 24 background: var(--mg-bg-dark); 25 25 } 26 26 27 27 body.mgwpp-dark-mode .mgwpp-premium-dashboard { 28 /* Dark Mode Variables Override */29 --mg-bg-dark: #050505;30 --mg-bg-panel: rgba(15, 15, 20, 0.8);31 --mg-bg-card: rgba(25, 25, 35, 0.4);32 --mg-border: rgba(255, 255, 255, 0.08);33 --mg-primary: #00f2ff;34 --mg-primary-glow: rgba(0, 242, 255, 0.4);35 --mg-secondary: #7000ff;36 --mg-secondary-glow: rgba(112, 0, 255, 0.4);37 --mg-text-main: #ffffff;38 --mg-text-muted: rgba(255, 255, 255, 0.6);39 --mg-shadow-luxury: 0 20px 50px rgba(0, 0, 0, 0.8);28 /* Dark Mode Variables Override */ 29 --mg-bg-dark: #050505; 30 --mg-bg-panel: rgba(15, 15, 20, 0.8); 31 --mg-bg-card: rgba(25, 25, 35, 0.4); 32 --mg-border: rgba(255, 255, 255, 0.08); 33 --mg-primary: #00f2ff; 34 --mg-primary-glow: rgba(0, 242, 255, 0.4); 35 --mg-secondary: #7000ff; 36 --mg-secondary-glow: rgba(112, 0, 255, 0.4); 37 --mg-text-main: #ffffff; 38 --mg-text-muted: rgba(255, 255, 255, 0.6); 39 --mg-shadow-luxury: 0 20px 50px rgba(0, 0, 0, 0.8); 40 40 } 41 41 42 42 .mgwpp-premium-dashboard { 43 background-image: 44 radial-gradient(circle at 10% 20%, rgba(112, 0, 255, 0.05) 0%, transparent 40%), 45 radial-gradient(circle at 90% 80%, rgba(0, 242, 255, 0.05) 0%, transparent 40%); 46 min-height: calc(100vh - 32px); 47 margin-left: -20px; 48 padding: 30px; 49 color: var(--mg-text-main); 50 font-family: 'Plus Jakarta Sans', sans-serif; 51 position: relative; 52 overflow-x: hidden; 43 background-image: radial-gradient( 44 circle at 10% 20%, 45 rgba(112, 0, 255, 0.05) 0%, 46 transparent 40% 47 ), 48 radial-gradient( 49 circle at 90% 80%, 50 rgba(0, 242, 255, 0.05) 0%, 51 transparent 40% 52 ); 53 min-height: calc(100vh - 32px); 54 margin-left: -20px; 55 padding: 30px; 56 color: var(--mg-text-main); 57 font-family: "Plus Jakarta Sans", sans-serif; 58 position: relative; 59 overflow-x: hidden; 53 60 } 54 61 55 62 /* Background Mesh Animation */ 56 63 .mgwpp-premium-dashboard::before { 57 content: ''; 58 position: absolute; 59 top: -50%; 60 left: -50%; 61 width: 200%; 62 height: 200%; 63 background: radial-gradient(circle at center, rgba(112, 0, 255, 0.03) 0%, transparent 50%); 64 animation: aura-float 20s infinite linear; 65 pointer-events: none; 66 z-index: 0; 64 content: ""; 65 position: absolute; 66 top: -50%; 67 left: -50%; 68 width: 200%; 69 height: 200%; 70 background: radial-gradient( 71 circle at center, 72 rgba(112, 0, 255, 0.03) 0%, 73 transparent 50% 74 ); 75 animation: aura-float 20s infinite linear; 76 pointer-events: none; 77 z-index: 0; 67 78 } 68 79 69 80 @keyframes aura-float { 70 0% { transform: translate(0, 0) rotate(0deg); } 71 100% { transform: translate(10%, 10%) rotate(360deg); } 81 0% { 82 transform: translate(0, 0) rotate(0deg); 83 } 84 100% { 85 transform: translate(10%, 10%) rotate(360deg); 86 } 72 87 } 73 88 74 89 .mgwpp-premium-dashboard .mgwpp-glass-container { 75 background: var(--mg-bg-panel);76 backdrop-filter: blur(25px) saturate(180%);77 -webkit-backdrop-filter: blur(25px) saturate(180%);78 border: 1px solid var(--mg-border);79 border-radius: var(--mg-radius-lg);80 padding: 40px;81 box-shadow: var(--mg-shadow-luxury);82 position: relative;83 z-index: 1;90 background: var(--mg-bg-panel); 91 backdrop-filter: blur(25px) saturate(180%); 92 -webkit-backdrop-filter: blur(25px) saturate(180%); 93 border: 1px solid var(--mg-border); 94 border-radius: var(--mg-radius-lg); 95 padding: 40px; 96 box-shadow: var(--mg-shadow-luxury); 97 position: relative; 98 z-index: 1; 84 99 } 85 100 86 101 /* Header Styles */ 87 102 .mgwpp-dashboard-header { 88 display: flex;89 justify-content: space-between;90 align-items: center;91 margin-bottom: 40px;92 padding-bottom: 30px;93 border-bottom: 1px dashed var(--mg-border);103 display: flex; 104 justify-content: space-between; 105 align-items: center; 106 margin-bottom: 40px; 107 padding-bottom: 30px; 108 border-bottom: 1px dashed var(--mg-border); 94 109 } 95 110 96 111 .mgwpp-dashboard-header h1 { 97 color: var(--mg-text-main);98 font-family: 'Orbitron', sans-serif;99 font-size: 32px;100 font-weight: 700;101 margin: 0;102 letter-spacing: 2px;103 text-shadow: 0 0 20px var(--mg-primary-glow);112 color: var(--mg-text-main); 113 font-family: "Orbitron", sans-serif; 114 font-size: 32px; 115 font-weight: 700; 116 margin: 0; 117 letter-spacing: 2px; 118 text-shadow: 0 0 20px var(--mg-primary-glow); 104 119 } 105 120 106 121 /* Premium Buttons */ 107 122 .mgwpp-btn { 108 display: inline-flex;109 align-items: center;110 gap: 10px;111 padding: 12px 28px;112 border-radius: var(--mg-radius-sm);113 font-size: 14px;114 font-weight: 700;115 text-transform: uppercase;116 letter-spacing: 1px;117 cursor: pointer;118 transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1);119 text-decoration: none;120 border: 1px solid transparent;121 position: relative;122 overflow: hidden;123 display: inline-flex; 124 align-items: center; 125 gap: 10px; 126 padding: 12px 28px; 127 border-radius: var(--mg-radius-sm); 128 font-size: 14px; 129 font-weight: 700; 130 text-transform: uppercase; 131 letter-spacing: 1px; 132 cursor: pointer; 133 transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1); 134 text-decoration: none; 135 border: 1px solid transparent; 136 position: relative; 137 overflow: hidden; 123 138 } 124 139 125 140 .mgwpp-btn::after { 126 content: ''; 127 position: absolute; 128 top: 0; 129 left: -100%; 130 width: 100%; 131 height: 100%; 132 background: linear-gradient(90deg, transparent, rgba(255,255,255,0.2), transparent); 133 transition: 0.5s; 141 content: ""; 142 position: absolute; 143 top: 0; 144 left: -100%; 145 width: 100%; 146 height: 100%; 147 background: linear-gradient( 148 90deg, 149 transparent, 150 rgba(255, 255, 255, 0.2), 151 transparent 152 ); 153 transition: 0.5s; 134 154 } 135 155 136 156 .mgwpp-btn:hover::after { 137 left: 100%;157 left: 100%; 138 158 } 139 159 140 160 .mgwpp-btn-primary { 141 background: linear-gradient(135deg, var(--mg-primary), var(--mg-secondary));142 color: #fff !important;143 box-shadow: 0 0 15px var(--mg-primary-glow);161 background: linear-gradient(135deg, var(--mg-primary), var(--mg-secondary)); 162 color: #fff !important; 163 box-shadow: 0 0 15px var(--mg-primary-glow); 144 164 } 145 165 146 166 .mgwpp-btn-primary:hover { 147 transform: translateY(-3px) scale(1.02);148 box-shadow: 0 0 30px var(--mg-primary-glow), 0 0 10px var(--mg-secondary-glow);167 transform: translateY(-3px) scale(1.02); 168 box-shadow: 0 0 30px var(--mg-primary-glow), 0 0 10px var(--mg-secondary-glow); 149 169 } 150 170 151 171 .mgwpp-btn-secondary { 152 background: var(--mg-bg-dark);153 color: var(--mg-text-main) !important;154 border: 1px solid var(--mg-border);155 backdrop-filter: blur(5px);172 background: var(--mg-bg-dark); 173 color: var(--mg-text-main) !important; 174 border: 1px solid var(--mg-border); 175 backdrop-filter: blur(5px); 156 176 } 157 177 158 178 body.mgwpp-dark-mode .mgwpp-btn-secondary { 159 background: rgba(255, 255, 255, 0.05);179 background: rgba(255, 255, 255, 0.05); 160 180 } 161 181 162 182 .mgwpp-btn-secondary:hover { 163 background: rgba(0, 0, 0, 0.05);164 border-color: var(--mg-primary);165 box-shadow: 0 0 15px var(--mg-primary-glow);183 background: rgba(0, 0, 0, 0.05); 184 border-color: var(--mg-primary); 185 box-shadow: 0 0 15px var(--mg-primary-glow); 166 186 } 167 187 168 188 body.mgwpp-dark-mode .mgwpp-btn-secondary:hover { 169 background: rgba(255, 255, 255, 0.1);189 background: rgba(255, 255, 255, 0.1); 170 190 } 171 191 172 192 /* Responsive Grid Layout */ 173 193 .mgwpp-gallery-grid { 174 display: grid;175 grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));176 grid-auto-rows: auto;177 gap: 25px;178 padding: 20px 0;194 display: grid; 195 grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); 196 grid-auto-rows: auto; 197 gap: 25px; 198 padding: 20px 0; 179 199 } 180 200 181 201 /* Luxury Card Design */ 182 202 .mgwpp-gallery-card { 183 background: var(--mg-bg-card);184 border: 1px solid var(--mg-border);185 border-radius: var(--mg-radius-md);186 overflow: hidden;187 transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1);188 position: relative;189 backdrop-filter: blur(10px);203 background: var(--mg-bg-card); 204 border: 1px solid var(--mg-border); 205 border-radius: var(--mg-radius-md); 206 overflow: hidden; 207 transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1); 208 position: relative; 209 backdrop-filter: blur(10px); 190 210 } 191 211 192 212 .mgwpp-gallery-card::before { 193 content: ''; 194 position: absolute; 195 top: 0; 196 left: 0; 197 right: 0; 198 bottom: 0; 199 border-radius: inherit; 200 padding: 1px; 201 background: linear-gradient(135deg, var(--mg-border), transparent, var(--mg-border)); 202 -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); 203 mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); 204 -webkit-mask-composite: xor; 205 mask-composite: exclude; 206 pointer-events: none; 207 transition: 0.5s; 213 content: ""; 214 position: absolute; 215 top: 0; 216 left: 0; 217 right: 0; 218 bottom: 0; 219 border-radius: inherit; 220 padding: 1px; 221 background: linear-gradient( 222 135deg, 223 var(--mg-border), 224 transparent, 225 var(--mg-border) 226 ); 227 -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); 228 mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); 229 -webkit-mask-composite: xor; 230 mask-composite: exclude; 231 pointer-events: none; 232 transition: 0.5s; 208 233 } 209 234 210 235 .mgwpp-gallery-card:hover { 211 transform: translateY(-5px);212 border-color: var(--mg-primary);213 box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2), 0 0 15px var(--mg-primary-glow);236 transform: translateY(-5px); 237 border-color: var(--mg-primary); 238 box-shadow: 0 10px 30px rgba(0, 0, 0, 0.2), 0 0 15px var(--mg-primary-glow); 214 239 } 215 240 216 241 body.mgwpp-dark-mode .mgwpp-gallery-card:hover { 217 box-shadow: 0 20px 40px rgba(0, 0, 0, 0.6), 0 0 20px var(--mg-primary-glow);242 box-shadow: 0 20px 40px rgba(0, 0, 0, 0.6), 0 0 20px var(--mg-primary-glow); 218 243 } 219 244 220 245 .mgwpp-gallery-card:hover::before { 221 background: linear-gradient(135deg, var(--mg-primary), var(--mg-secondary));246 background: linear-gradient(135deg, var(--mg-primary), var(--mg-secondary)); 222 247 } 223 248 224 249 .mgwpp-card-inner { 225 display: flex;226 flex-direction: column;227 height: 100%;250 display: flex; 251 flex-direction: column; 252 height: 100%; 228 253 } 229 254 230 255 /* Card Header & Preview */ 231 256 .mgwpp-card-header { 232 position: relative;233 height: 200px;234 background: #0a0a0a;235 overflow: hidden;257 position: relative; 258 height: 200px; 259 background: #0a0a0a; 260 overflow: hidden; 236 261 } 237 262 238 263 /* Glare Effect */ 239 264 .mgwpp-card-glare { 240 position: absolute;241 top: -100%;242 left: -100%;243 width: 200%;244 height: 200%;245 background: linear-gradient(246 45deg,247 transparent 0%,248 rgba(255, 255, 255, 0.05) 45%,249 rgba(255, 255, 255, 0.2) 50%,250 rgba(255, 255, 255, 0.05) 55%,251 transparent 100%252 );253 transition: all 0.6s;254 pointer-events: none;255 z-index: 2;265 position: absolute; 266 top: -100%; 267 left: -100%; 268 width: 200%; 269 height: 200%; 270 background: linear-gradient( 271 45deg, 272 transparent 0%, 273 rgba(255, 255, 255, 0.05) 45%, 274 rgba(255, 255, 255, 0.2) 50%, 275 rgba(255, 255, 255, 0.05) 55%, 276 transparent 100% 277 ); 278 transition: all 0.6s; 279 pointer-events: none; 280 z-index: 2; 256 281 } 257 282 258 283 .mgwpp-gallery-card:hover .mgwpp-card-glare { 259 top: -20%;260 left: -20%;284 top: -20%; 285 left: -20%; 261 286 } 262 287 263 288 .mgwpp-gallery-preview { 264 height: 100%;265 width: 100%;266 position: relative;267 transition: transform 0.8s ease;289 height: 100%; 290 width: 100%; 291 position: relative; 292 transition: transform 0.8s ease; 268 293 } 269 294 270 295 .mgwpp-gallery-card:hover .mgwpp-gallery-preview { 271 transform: scale(1.05);296 transform: scale(1.05); 272 297 } 273 298 274 299 /* Overlay Actions */ 275 300 .mgwpp-card-overlay { 276 position: absolute; 277 top: 0; 278 left: 0; 279 right: 0; 280 bottom: 0; 281 background: radial-gradient(circle at center, rgba(10, 10, 20, 0.4), rgba(0,0,0,0.8)); 282 display: flex; 283 align-items: center; 284 justify-content: center; 285 opacity: 0; 286 transition: all 0.4s; 287 backdrop-filter: blur(8px); 288 z-index: 3; 301 position: absolute; 302 top: 0; 303 left: 0; 304 right: 0; 305 bottom: 0; 306 background: radial-gradient( 307 circle at center, 308 rgba(10, 10, 20, 0.4), 309 rgba(0, 0, 0, 0.8) 310 ); 311 display: flex; 312 align-items: center; 313 justify-content: center; 314 opacity: 0; 315 transition: all 0.4s; 316 backdrop-filter: blur(8px); 317 z-index: 3; 289 318 } 290 319 291 320 .mgwpp-gallery-card:hover .mgwpp-card-overlay { 292 opacity: 1;321 opacity: 1; 293 322 } 294 323 295 324 .mgwpp-overlay-actions { 296 display: flex;297 gap: 15px;298 transform: translateY(20px);299 transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1);325 display: flex; 326 gap: 15px; 327 transform: translateY(20px); 328 transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1); 300 329 } 301 330 302 331 .mgwpp-gallery-card:hover .mgwpp-overlay-actions { 303 transform: translateY(0);332 transform: translateY(0); 304 333 } 305 334 306 335 .mgwpp-overlay-actions a { 307 width: 46px;308 height: 46px;309 background: rgba(255, 255, 255, 0.1);310 border: 1px solid rgba(255, 255, 255, 0.2);311 border-radius: 12px;312 display: flex;313 align-items: center;314 justify-content: center;315 color: #fff;316 text-decoration: none;317 transition: all 0.3s;318 font-size: 18px;336 width: 46px; 337 height: 46px; 338 background: rgba(255, 255, 255, 0.1); 339 border: 1px solid rgba(255, 255, 255, 0.2); 340 border-radius: 12px; 341 display: flex; 342 align-items: center; 343 justify-content: center; 344 color: #fff; 345 text-decoration: none; 346 transition: all 0.3s; 347 font-size: 18px; 319 348 } 320 349 321 350 .mgwpp-overlay-actions a:hover { 322 background: var(--mg-primary);323 border-color: var(--mg-primary);324 transform: translateY(-5px);325 box-shadow: 0 10px 20px var(--mg-primary-glow);326 color: #000;351 background: var(--mg-primary); 352 border-color: var(--mg-primary); 353 transform: translateY(-5px); 354 box-shadow: 0 10px 20px var(--mg-primary-glow); 355 color: #000; 327 356 } 328 357 329 358 .mgwpp-overlay-actions a.submitdelete:hover { 330 background: var(--mg-danger);331 box-shadow: 0 10px 20px rgba(255, 0, 76, 0.4);332 color: #fff;359 background: var(--mg-danger); 360 box-shadow: 0 10px 20px rgba(255, 0, 76, 0.4); 361 color: #fff; 333 362 } 334 363 335 364 /* Bulk Checkbox */ 336 365 .mgwpp-checkbox-wrapper { 337 position: absolute;338 top: 15px;339 left: 15px;340 z-index: 10;366 position: absolute; 367 top: 15px; 368 left: 15px; 369 z-index: 10; 341 370 } 342 371 343 372 .mgwpp-bulk-checkbox { 344 width: 24px;345 height: 24px;346 border: 2px solid var(--mg-primary);347 background: rgba(0, 0, 0, 0.5);348 border-radius: 6px;349 cursor: pointer;350 appearance: none;351 position: relative;352 transition: all 0.3s;373 width: 24px; 374 height: 24px; 375 border: 2px solid var(--mg-primary); 376 background: rgba(0, 0, 0, 0.5); 377 border-radius: 6px; 378 cursor: pointer; 379 appearance: none; 380 position: relative; 381 transition: all 0.3s; 353 382 } 354 383 355 384 .mgwpp-bulk-checkbox:checked { 356 background: var(--mg-primary);385 background: var(--mg-primary); 357 386 } 358 387 359 388 .mgwpp-bulk-checkbox:checked::after { 360 content: '\f15e';361 font-family: 'dashicons';362 color: #fff;363 position: absolute;364 top: 50%;365 left: 50%;366 transform: translate(-50%, -50%);367 font-size: 16px;389 content: "\f15e"; 390 font-family: "dashicons"; 391 color: #fff; 392 position: absolute; 393 top: 50%; 394 left: 50%; 395 transform: translate(-50%, -50%); 396 font-size: 16px; 368 397 } 369 398 370 399 /* Card Body */ 371 400 .mgwpp-card-body { 372 padding: 24px;373 background: linear-gradient(to bottom, transparent, rgba(0,0,0,0.05));374 flex: 1;375 display: flex;376 flex-direction: column;401 padding: 24px; 402 background: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.05)); 403 flex: 1; 404 display: flex; 405 flex-direction: column; 377 406 } 378 407 379 408 body.mgwpp-dark-mode .mgwpp-card-body { 380 background: linear-gradient(to bottom, transparent, rgba(0,0,0,0.4));409 background: linear-gradient(to bottom, transparent, rgba(0, 0, 0, 0.4)); 381 410 } 382 411 383 412 .mgwpp-card-title { 384 font-family: 'Plus Jakarta Sans', sans-serif;385 font-size: 20px;386 font-weight: 700;387 margin-bottom: 8px;388 color: var(--mg-text-main);389 letter-spacing: -0.5px;413 font-family: "Plus Jakarta Sans", sans-serif; 414 font-size: 20px; 415 font-weight: 700; 416 margin-bottom: 8px; 417 color: var(--mg-text-main); 418 letter-spacing: -0.5px; 390 419 } 391 420 392 421 .mgwpp-card-type-badge { 393 padding: 6px 14px;394 background: var(--mg-primary-glow);395 color: var(--mg-primary);396 border: 1px solid var(--mg-primary-glow);397 border-radius: 8px;398 font-family: 'Orbitron', sans-serif;399 font-size: 10px;400 font-weight: 700;401 text-transform: uppercase;402 letter-spacing: 1.5px;422 padding: 6px 14px; 423 background: var(--mg-primary-glow); 424 color: var(--mg-primary); 425 border: 1px solid var(--mg-primary-glow); 426 border-radius: 8px; 427 font-family: "Orbitron", sans-serif; 428 font-size: 10px; 429 font-weight: 700; 430 text-transform: uppercase; 431 letter-spacing: 1.5px; 403 432 } 404 433 405 434 .mgwpp-card-meta { 406 margin: 15px 0;435 margin: 15px 0; 407 436 } 408 437 409 438 .mgwpp-card-date { 410 display: flex;411 align-items: center;412 gap: 8px;413 color: var(--mg-text-muted);414 font-size: 12px;439 display: flex; 440 align-items: center; 441 gap: 8px; 442 color: var(--mg-text-muted); 443 font-size: 12px; 415 444 } 416 445 417 446 /* Shortcode Box - Tech Look */ 418 447 .mgwpp-shortcode-box { 419 background: rgba(0, 0, 0, 0.05);420 border: 1px solid var(--mg-border);421 border-radius: 12px;422 padding: 8px 8px 8px 16px;423 display: flex;424 align-items: center;425 transition: all 0.3s;426 margin-top: auto;448 background: rgba(0, 0, 0, 0.05); 449 border: 1px solid var(--mg-border); 450 border-radius: 12px; 451 padding: 8px 8px 8px 16px; 452 display: flex; 453 align-items: center; 454 transition: all 0.3s; 455 margin-top: auto; 427 456 } 428 457 429 458 body.mgwpp-dark-mode .mgwpp-shortcode-box { 430 background: rgba(0, 0, 0, 0.5);459 background: rgba(0, 0, 0, 0.5); 431 460 } 432 461 433 462 .mgwpp-gallery-card:hover .mgwpp-shortcode-box { 434 border-color: var(--mg-primary-glow);435 background: rgba(255, 255, 255, 0.1);463 border-color: var(--mg-primary-glow); 464 background: rgba(255, 255, 255, 0.1); 436 465 } 437 466 438 467 body.mgwpp-dark-mode .mgwpp-gallery-card:hover .mgwpp-shortcode-box { 439 background: rgba(0, 0, 0, 0.8);468 background: rgba(0, 0, 0, 0.8); 440 469 } 441 470 442 471 .mgwpp-shortcode-box code { 443 font-family: 'SF Mono', 'Fira Code', monospace;444 color: var(--mg-primary);445 font-size: 11px;446 text-shadow: 0 0 10px var(--mg-primary-glow);447 background: transparent;472 font-family: "SF Mono", "Fira Code", monospace; 473 color: var(--mg-primary); 474 font-size: 11px; 475 text-shadow: 0 0 10px var(--mg-primary-glow); 476 background: transparent; 448 477 } 449 478 450 479 .mgwpp-copy-btn { 451 background: rgba(0, 0, 0, 0.05);452 border: 1px solid var(--mg-border);453 color: var(--mg-text-muted);454 width: 36px;455 height: 36px;456 border-radius: 10px;457 transition: 0.3s;458 display: flex;459 align-items: center;460 justify-content: center;461 cursor: pointer;480 background: rgba(0, 0, 0, 0.05); 481 border: 1px solid var(--mg-border); 482 color: var(--mg-text-muted); 483 width: 36px; 484 height: 36px; 485 border-radius: 10px; 486 transition: 0.3s; 487 display: flex; 488 align-items: center; 489 justify-content: center; 490 cursor: pointer; 462 491 } 463 492 464 493 body.mgwpp-dark-mode .mgwpp-copy-btn { 465 background: rgba(255, 255, 255, 0.05);494 background: rgba(255, 255, 255, 0.05); 466 495 } 467 496 468 497 .mgwpp-copy-btn:hover { 469 background: var(--mg-primary);470 color: #fff;471 border-color: var(--mg-primary);472 box-shadow: 0 0 15px var(--mg-primary-glow);498 background: var(--mg-primary); 499 color: #fff; 500 border-color: var(--mg-primary); 501 box-shadow: 0 0 15px var(--mg-primary-glow); 473 502 } 474 503 475 504 body.mgwpp-dark-mode .mgwpp-copy-btn:hover { 476 color: #000;505 color: #000; 477 506 } 478 507 … … 480 509 481 510 .mgwpp-preview-loader { 482 text-align: center;483 padding: 100px 0;511 text-align: center; 512 padding: 100px 0; 484 513 } 485 514 486 515 .mgwpp-loading-spinner { 487 width: 50px;488 height: 50px;489 border: 3px solid var(--mg-border);490 border-top-color: var(--mg-primary);491 border-radius: 50%;492 animation: mg-spin 1s linear infinite;493 margin: 0 auto 20px;516 width: 50px; 517 height: 50px; 518 border: 3px solid var(--mg-border); 519 border-top-color: var(--mg-primary); 520 border-radius: 50%; 521 animation: mg-spin 1s linear infinite; 522 margin: 0 auto 20px; 494 523 } 495 524 496 525 @keyframes mg-spin { 497 to { transform: rotate(360deg); } 526 to { 527 transform: rotate(360deg); 528 } 498 529 } 499 530 500 531 /* Bulk Actions Bar */ 501 532 .mgwpp-bulk-actions-bar { 502 background: var(--mg-bg-panel);503 border: 1px solid var(--mg-border);504 padding: 15px 30px;505 border-radius: var(--mg-radius-md);506 margin-bottom: 30px;507 backdrop-filter: blur(10px);533 background: var(--mg-bg-panel); 534 border: 1px solid var(--mg-border); 535 padding: 15px 30px; 536 border-radius: var(--mg-radius-md); 537 margin-bottom: 30px; 538 backdrop-filter: blur(10px); 508 539 } 509 540 510 541 .mgwpp-bulk-controls select { 511 background: #fff;512 border: 1px solid var(--mg-border);513 color: #000;514 padding: 8px 15px;515 border-radius: 8px;516 font-weight: 600;542 background: #fff; 543 border: 1px solid var(--mg-border); 544 color: #000; 545 padding: 8px 15px; 546 border-radius: 8px; 547 font-weight: 600; 517 548 } 518 549 519 550 body.mgwpp-dark-mode .mgwpp-bulk-controls select { 520 background: #000;521 color: #fff;551 background: #000; 552 color: #fff; 522 553 } 523 554 524 555 /* 3D Model Preview Enhancement */ 525 556 .mgwpp-3d-model-preview { 526 background: radial-gradient(circle at center, #1a1a2a, #050505);557 background: radial-gradient(circle at center, #1a1a2a, #050505); 527 558 } 528 559 529 560 .mgwpp-3d-model-icon svg { 530 filter: drop-shadow(0 0 15px var(--mg-primary));561 filter: drop-shadow(0 0 15px var(--mg-primary)); 531 562 } 532 563 533 564 .mgwpp-3d-model-count { 534 font-family: 'Orbitron', sans-serif;535 font-size: 14px;536 color: var(--mg-primary);537 text-shadow: 0 0 10px var(--mg-primary-glow);565 font-family: "Orbitron", sans-serif; 566 font-size: 14px; 567 color: var(--mg-primary); 568 text-shadow: 0 0 10px var(--mg-primary-glow); 538 569 } 539 570 540 571 /* Custom Scrollbar for Luxury Feel */ 541 572 .mgwpp-premium-dashboard::-webkit-scrollbar { 542 width: 8px;573 width: 8px; 543 574 } 544 575 .mgwpp-premium-dashboard::-webkit-scrollbar-track { 545 background: var(--mg-bg-dark);576 background: var(--mg-bg-dark); 546 577 } 547 578 548 579 /* Modern Modal System */ 549 580 .mgwpp-modal { 550 position: fixed !important;551 top: 0 !important;552 left: 0 !important;553 width: 100% !important;554 height: 100% !important;555 z-index: 999999 !important;556 display: none;557 align-items: center !important;558 justify-content: center !important;559 perspective: 1000px;581 position: fixed !important; 582 top: 0 !important; 583 left: 0 !important; 584 width: 100% !important; 585 height: 100% !important; 586 z-index: 999999 !important; 587 display: none; 588 align-items: center !important; 589 justify-content: center !important; 590 perspective: 1000px; 560 591 } 561 592 … … 564 595 .mgwpp-modal[style*="display: flex"], 565 596 .mgwpp-modal[style*="display: inline-block"] { 566 display: flex !important;597 display: flex !important; 567 598 } 568 599 569 600 .mgwpp-modal-overlay { 570 position: absolute;571 width: 100%;572 height: 100%;573 background: rgba(0, 0, 0, 0.9);574 cursor: pointer;575 z-index: 1;601 position: absolute; 602 width: 100%; 603 height: 100%; 604 background: rgba(0, 0, 0, 0.9); 605 cursor: pointer; 606 z-index: 1; 576 607 } 577 608 578 609 .mgwpp-modal-content { 579 position: relative; 580 width: 95%; 581 max-width: 650px; 582 background: #0f0f0f !important; /* Fixed dark background */ 583 border: 1px solid rgba(255, 255, 255, 0.1); 584 border-radius: 20px; 585 box-shadow: 0 40px 100px rgba(0, 0, 0, 0.8), 0 0 0 1px rgba(255, 255, 255, 0.05); 586 overflow: hidden; 587 z-index: 2; 588 color: #ffffff !important; /* Force white text */ 589 animation: modalSlideUp 0.4s cubic-bezier(0.16, 1, 0.3, 1); 590 backdrop-filter: none !important; /* Remove glassmorphism */ 610 position: relative; 611 width: 95%; 612 max-width: 650px; 613 background: #0f0f0f !important; /* Fixed dark background */ 614 border: 1px solid rgba(255, 255, 255, 0.1); 615 border-radius: 20px; 616 box-shadow: 0 40px 100px rgba(0, 0, 0, 0.8), 617 0 0 0 1px rgba(255, 255, 255, 0.05); 618 overflow: hidden; 619 z-index: 2; 620 color: #ffffff !important; /* Force white text */ 621 animation: modalSlideUp 0.4s cubic-bezier(0.16, 1, 0.3, 1); 622 backdrop-filter: none !important; /* Remove glassmorphism */ 591 623 } 592 624 593 625 @keyframes modalSlideUp { 594 from { opacity: 0; transform: translateY(40px) scale(0.95); } 595 to { opacity: 1; transform: translateY(0) scale(1); } 626 from { 627 opacity: 0; 628 transform: translateY(40px) scale(0.95); 629 } 630 to { 631 opacity: 1; 632 transform: translateY(0) scale(1); 633 } 596 634 } 597 635 598 636 .mgwpp-modal-header { 599 padding: 24px 30px;600 border-bottom: 1px solid rgba(255, 255, 255, 0.08);601 display: flex;602 justify-content: space-between;603 align-items: center;604 background: #161616 !important;637 padding: 24px 30px; 638 border-bottom: 1px solid rgba(255, 255, 255, 0.08); 639 display: flex; 640 justify-content: space-between; 641 align-items: center; 642 background: #161616 !important; 605 643 } 606 644 607 645 .mgwpp-modal-header h2 { 608 margin: 0;609 font-size: 22px;610 font-weight: 700;611 color: #ffffff !important;612 letter-spacing: -0.02em;613 font-family: 'Plus Jakarta Sans', sans-serif;646 margin: 0; 647 font-size: 22px; 648 font-weight: 700; 649 color: #ffffff !important; 650 letter-spacing: -0.02em; 651 font-family: "Plus Jakarta Sans", sans-serif; 614 652 } 615 653 616 654 .mgwpp-modal-close { 617 background: transparent;618 border: none;619 color: #ffffff !important;620 font-size: 32px;621 line-height: 1;622 cursor: pointer;623 transition: all 0.2s;624 width: 40px;625 height: 40px;626 border-radius: 50%;627 display: flex;628 align-items: center;629 justify-content: center;630 opacity: 0.7;655 background: transparent; 656 border: none; 657 color: #ffffff !important; 658 font-size: 32px; 659 line-height: 1; 660 cursor: pointer; 661 transition: all 0.2s; 662 width: 40px; 663 height: 40px; 664 border-radius: 50%; 665 display: flex; 666 align-items: center; 667 justify-content: center; 668 opacity: 0.7; 631 669 } 632 670 633 671 .mgwpp-modal-close:hover { 634 background: rgba(255, 255, 255, 0.1);635 transform: rotate(90deg);636 opacity: 1;672 background: rgba(255, 255, 255, 0.1); 673 transform: rotate(90deg); 674 opacity: 1; 637 675 } 638 676 639 677 .mgwpp-modal-body { 640 padding: 30px;641 max-height: 80vh;642 overflow-y: auto;643 background: #0f0f0f !important;644 color: #ffffff !important;678 padding: 30px; 679 max-height: 80vh; 680 overflow-y: auto; 681 background: #0f0f0f !important; 682 color: #ffffff !important; 645 683 } 646 684 647 685 /* Form Styling */ 648 686 .mgwpp-form-group { 649 margin-bottom: 25px;687 margin-bottom: 25px; 650 688 } 651 689 652 690 .mgwpp-form-group label { 653 display: block;654 font-size: 13px;655 font-weight: 700;656 color: #ffffff !important; /* Force white text */657 margin-bottom: 10px;658 text-transform: uppercase;659 letter-spacing: 0.05em;660 line-height: 1.2;691 display: block; 692 font-size: 13px; 693 font-weight: 700; 694 color: #ffffff !important; /* Force white text */ 695 margin-bottom: 10px; 696 text-transform: uppercase; 697 letter-spacing: 0.05em; 698 line-height: 1.2; 661 699 } 662 700 663 701 .mgwpp-form-group input[type="text"] { 664 width: 100%;665 background: #1a1a1a !important; /* Darker input bg */666 border: 1px solid rgba(255, 255, 255, 0.1);667 border-radius: 12px;668 padding: 12px 18px;669 color: #ffffff !important; /* White text */670 font-size: 15px;671 transition: all 0.2s;702 width: 100%; 703 background: #1a1a1a !important; /* Darker input bg */ 704 border: 1px solid rgba(255, 255, 255, 0.1); 705 border-radius: 12px; 706 padding: 12px 18px; 707 color: #ffffff !important; /* White text */ 708 font-size: 15px; 709 transition: all 0.2s; 672 710 } 673 711 674 712 .mgwpp-form-group input[type="text"]::placeholder { 675 color: var(--mg-text-muted);676 opacity: 0.7;713 color: var(--mg-text-muted); 714 opacity: 0.7; 677 715 } 678 716 679 717 .mgwpp-form-group input[type="text"]:focus { 680 border-color: var(--mg-primary);681 box-shadow: 0 0 0 3px rgba(0, 242, 255, 0.15);682 outline: none;718 border-color: var(--mg-primary); 719 box-shadow: 0 0 0 3px rgba(0, 242, 255, 0.15); 720 outline: none; 683 721 } 684 722 685 723 .mgwpp-select-wrapper { 686 position: relative;724 position: relative; 687 725 } 688 726 689 727 .mgwpp-select-wrapper select { 690 width: 100%;691 appearance: none;692 background: #1a1a1a !important; /* Darker select bg */693 border: 1px solid rgba(255, 255, 255, 0.1);694 border-radius: 12px;695 padding: 12px 18px;696 color: #ffffff !important; /* White text */697 font-size: 15px;698 cursor: pointer;699 outline: none;728 width: 100%; 729 appearance: none; 730 background: #1a1a1a !important; /* Darker select bg */ 731 border: 1px solid rgba(255, 255, 255, 0.1); 732 border-radius: 12px; 733 padding: 12px 18px; 734 color: #ffffff !important; /* White text */ 735 font-size: 15px; 736 cursor: pointer; 737 outline: none; 700 738 } 701 739 702 740 .mgwpp-select-wrapper select option { 703 background: var(--mg-bg-panel);704 color: var(--mg-text-main);741 background: var(--mg-bg-panel); 742 color: var(--mg-text-main); 705 743 } 706 744 707 745 .mgwpp-select-wrapper::after { 708 content: "\f347";709 font-family: dashicons;710 position: absolute;711 right: 15px;712 top: 50%;713 transform: translateY(-50%);714 color: var(--mg-text-main);715 pointer-events: none;746 content: "\f347"; 747 font-family: dashicons; 748 position: absolute; 749 right: 15px; 750 top: 50%; 751 transform: translateY(-50%); 752 color: var(--mg-text-main); 753 pointer-events: none; 716 754 } 717 755 718 756 /* Upload Zone */ 719 757 .mgwpp-media-section { 720 padding: 20px;721 background: rgba(0, 0, 0, 0.15);722 border-radius: 16px;723 border: 1px dashed var(--mg-border);758 padding: 20px; 759 background: rgba(0, 0, 0, 0.15); 760 border-radius: 16px; 761 border: 1px dashed var(--mg-border); 724 762 } 725 763 726 764 .mgwpp-field-hint { 727 font-size: 13px;728 color: var(--mg-primary);729 background: var(--mg-primary-glow);730 padding: 12px 18px;731 border-radius: 12px;732 margin-bottom: 20px;733 display: flex;734 align-items: center;735 gap: 12px;736 border: 1px solid var(--mg-border);737 line-height: 1.4;765 font-size: 13px; 766 color: var(--mg-primary); 767 background: var(--mg-primary-glow); 768 padding: 12px 18px; 769 border-radius: 12px; 770 margin-bottom: 20px; 771 display: flex; 772 align-items: center; 773 gap: 12px; 774 border: 1px solid var(--mg-border); 775 line-height: 1.4; 738 776 } 739 777 740 778 .mgwpp-field-hint .dashicons { 741 font-size: 18px;742 width: 18px;743 height: 18px;779 font-size: 18px; 780 width: 18px; 781 height: 18px; 744 782 } 745 783 746 784 .mgwpp-upload-zone { 747 display: flex;748 flex-direction: column;749 align-items: center;750 gap: 20px;751 padding: 10px 0;785 display: flex; 786 flex-direction: column; 787 align-items: center; 788 gap: 20px; 789 padding: 10px 0; 752 790 } 753 791 754 792 .mgwpp-media-preview-container { 755 width: 100%; 756 min-height: 100px; 793 width: 100%; 794 min-height: 0; 795 transition: all 0.3s ease; 796 } 797 798 .mgwpp-media-preview-container.has-images { 799 min-height: 120px; 800 padding: 15px; 801 background: rgba(0, 173, 111, 0.1); 802 border: 1px solid rgba(0, 173, 111, 0.2); 803 border-radius: 12px; 804 } 805 806 /* Upload Button - Selection State */ 807 .mgwpp-media-upload.has-selection { 808 background: linear-gradient( 809 135deg, 810 rgba(0, 173, 111, 0.15), 811 rgba(0, 173, 111, 0.05) 812 ) !important; 813 border-color: rgba(0, 173, 111, 0.4) !important; 814 color: #00ad6f !important; 815 } 816 817 .mgwpp-media-upload.has-selection:hover { 818 background: linear-gradient( 819 135deg, 820 rgba(0, 173, 111, 0.25), 821 rgba(0, 173, 111, 0.1) 822 ) !important; 823 box-shadow: 0 0 20px rgba(0, 173, 111, 0.3) !important; 824 } 825 826 .mgwpp-media-upload.has-selection .dashicons { 827 color: #00ad6f !important; 757 828 } 758 829 759 830 .mgwpp-media-preview { 760 display: grid;761 grid-template-columns: repeat(auto-fill, minmax(80px, 1fr));762 gap: 15px;763 margin-top: 15px;831 display: grid; 832 grid-template-columns: repeat(auto-fill, minmax(80px, 1fr)); 833 gap: 15px; 834 margin-top: 15px; 764 835 } 765 836 766 837 .media-thumbnail { 767 position: relative;768 aspect-ratio: 1;769 border-radius: 8px;770 overflow: hidden;771 border: 1px solid var(--mg-border);772 background: #000;838 position: relative; 839 aspect-ratio: 1; 840 border-radius: 8px; 841 overflow: hidden; 842 border: 1px solid var(--mg-border); 843 background: #000; 773 844 } 774 845 775 846 .media-thumbnail img { 776 width: 100%;777 height: 100%;778 object-fit: cover;847 width: 100%; 848 height: 100%; 849 object-fit: cover; 779 850 } 780 851 781 852 .media-thumbnail.is-3d::after { 782 content: "\f128";783 font-family: dashicons;784 position: absolute;785 top: 50%;786 left: 50%;787 transform: translate(-50%, -50%);788 color: #fff;789 font-size: 32px;853 content: "\f128"; 854 font-family: dashicons; 855 position: absolute; 856 top: 50%; 857 left: 50%; 858 transform: translate(-50%, -50%); 859 color: #fff; 860 font-size: 32px; 790 861 } 791 862 792 863 .mgwpp-modal-footer { 793 border-top: 1px solid var(--mg-border);794 padding: 24px 30px;795 display: flex;796 justify-content: flex-end;797 background: rgba(255, 255, 255, 0.01);864 border-top: 1px solid var(--mg-border); 865 padding: 24px 30px; 866 display: flex; 867 justify-content: flex-end; 868 background: rgba(255, 255, 255, 0.01); 798 869 } 799 870 800 871 .mgwpp-notice { 801 padding: 12px 15px; 802 border-radius: 8px; 803 margin-top: 20px; 804 font-size: 14px; 805 } 806 807 .mgwpp-notice.success { background: rgba(46, 204, 113, 0.15); color: #2ecc71; border: 1px solid rgba(46, 204, 113, 0.2); } 808 .mgwpp-notice.error { background: rgba(231, 76, 60, 0.15); color: #e74c3c; border: 1px solid rgba(231, 76, 60, 0.2); } 872 padding: 12px 15px; 873 border-radius: 8px; 874 margin-top: 20px; 875 font-size: 14px; 876 } 877 878 .mgwpp-notice.success { 879 background: rgba(46, 204, 113, 0.15); 880 color: #2ecc71; 881 border: 1px solid rgba(46, 204, 113, 0.2); 882 } 883 .mgwpp-notice.error { 884 background: rgba(231, 76, 60, 0.15); 885 color: #e74c3c; 886 border: 1px solid rgba(231, 76, 60, 0.2); 887 } 809 888 810 889 /* Loading State */ 811 890 .mgwpp-loading-overlay { 812 position: absolute;813 top: 0;814 left: 0;815 width: 100%;816 height: 100%;817 background: rgba(5, 5, 5, 0.9);818 z-index: 100;819 display: flex;820 flex-direction: column;821 align-items: center;822 justify-content: center;823 backdrop-filter: blur(15px);824 -webkit-backdrop-filter: blur(15px);891 position: absolute; 892 top: 0; 893 left: 0; 894 width: 100%; 895 height: 100%; 896 background: rgba(5, 5, 5, 0.9); 897 z-index: 100; 898 display: flex; 899 flex-direction: column; 900 align-items: center; 901 justify-content: center; 902 backdrop-filter: blur(15px); 903 -webkit-backdrop-filter: blur(15px); 825 904 } 826 905 827 906 .mgwpp-loading-overlay p { 828 margin: 0;829 font-size: 16px;830 font-weight: 600;831 color: #ffffff;832 letter-spacing: 0.02em;907 margin: 0; 908 font-size: 16px; 909 font-weight: 600; 910 color: #ffffff; 911 letter-spacing: 0.02em; 833 912 } 834 913 835 914 .mgwpp-loading-spinner { 836 width: 40px;837 height: 40px;838 border: 3px solid rgba(0, 242, 255, 0.1);839 border-top: 3px solid var(--mg-primary);840 border-radius: 50%;841 animation: mgwpp-spin 1s linear infinite;842 margin-bottom: 20px;915 width: 40px; 916 height: 40px; 917 border: 3px solid rgba(0, 242, 255, 0.1); 918 border-top: 3px solid var(--mg-primary); 919 border-radius: 50%; 920 animation: mgwpp-spin 1s linear infinite; 921 margin-bottom: 20px; 843 922 } 844 923 845 924 @keyframes mgwpp-spin { 846 0% { transform: rotate(0deg); } 847 100% { transform: rotate(360deg); } 925 0% { 926 transform: rotate(0deg); 927 } 928 100% { 929 transform: rotate(360deg); 930 } 848 931 } 849 932 850 933 .mgwpp-premium-dashboard::-webkit-scrollbar-thumb { 851 background: linear-gradient(var(--mg-primary), var(--mg-secondary));852 border-radius: 10px;934 background: linear-gradient(var(--mg-primary), var(--mg-secondary)); 935 border-radius: 10px; 853 936 } 854 937 855 938 /* 3D Model Preview Styles */ 856 939 .mgwpp-3d-model-preview { 857 width: 100%; 858 height: 100%; 859 display: flex; 860 flex-direction: column; 861 align-items: center; 862 justify-content: center; 863 background: linear-gradient(135deg, rgba(0, 242, 255, 0.05), rgba(112, 0, 255, 0.05)); 864 gap: 15px; 940 width: 100%; 941 height: 100%; 942 display: flex; 943 flex-direction: column; 944 align-items: center; 945 justify-content: center; 946 background: linear-gradient( 947 135deg, 948 rgba(0, 242, 255, 0.05), 949 rgba(112, 0, 255, 0.05) 950 ); 951 gap: 15px; 865 952 } 866 953 867 954 .mgwpp-3d-model-icon { 868 width: 80px;869 height: 80px;870 background: rgba(0, 242, 255, 0.1);871 border-radius: 50%;872 display: flex;873 align-items: center;874 justify-content: center;875 border: 1px solid rgba(0, 242, 255, 0.2);876 box-shadow: 0 0 20px rgba(0, 242, 255, 0.1);955 width: 80px; 956 height: 80px; 957 background: rgba(0, 242, 255, 0.1); 958 border-radius: 50%; 959 display: flex; 960 align-items: center; 961 justify-content: center; 962 border: 1px solid rgba(0, 242, 255, 0.2); 963 box-shadow: 0 0 20px rgba(0, 242, 255, 0.1); 877 964 } 878 965 879 966 .mgwpp-3d-model-icon svg { 880 fill: var(--mg-primary);881 filter: drop-shadow(0 0 5px var(--mg-primary-glow));967 fill: var(--mg-primary); 968 filter: drop-shadow(0 0 5px var(--mg-primary-glow)); 882 969 } 883 970 884 971 .mgwpp-3d-model-count { 885 font-family: 'Orbitron', sans-serif; 886 font-size: 14px; 887 font-weight: 700; 888 color: var(--mg-primary); 889 text-transform: uppercase; 890 letter-spacing: 1px; 891 } 972 font-family: "Orbitron", sans-serif; 973 font-size: 14px; 974 font-weight: 700; 975 color: var(--mg-primary); 976 text-transform: uppercase; 977 letter-spacing: 1px; 978 } 979 980 /* Auto-create hint message */ 981 .mgwpp-auto-create-hint { 982 display: flex; 983 align-items: center; 984 gap: 8px; 985 font-size: 13px; 986 color: var(--mg-text-muted); 987 padding: 12px 16px; 988 background: rgba(0, 242, 255, 0.05); 989 border: 1px dashed var(--mg-primary); 990 border-radius: var(--mg-radius-sm); 991 margin: 0; 992 } 993 994 .mgwpp-auto-create-hint .dashicons { 995 color: var(--mg-primary); 996 font-size: 18px; 997 width: 18px; 998 height: 18px; 999 } 1000 1001 /* Toast Notification Styles */ 1002 .mgwpp-toast-notification { 1003 position: fixed; 1004 top: 40px; 1005 right: 20px; 1006 z-index: 9999999; 1007 display: flex; 1008 align-items: center; 1009 gap: 12px; 1010 padding: 16px 24px; 1011 background: linear-gradient(135deg, #0f0f0f 0%, #1a1a2e 100%); 1012 border: 1px solid rgba(255, 255, 255, 0.1); 1013 border-radius: 14px; 1014 box-shadow: 0 20px 60px rgba(0, 0, 0, 0.6), 0 0 40px rgba(0, 242, 255, 0.15); 1015 color: #fff; 1016 font-family: "Plus Jakarta Sans", sans-serif; 1017 font-size: 14px; 1018 font-weight: 600; 1019 opacity: 0; 1020 transform: translateX(100%); 1021 transition: all 0.4s cubic-bezier(0.23, 1, 0.32, 1); 1022 } 1023 1024 .mgwpp-toast-notification.show { 1025 opacity: 1; 1026 transform: translateX(0); 1027 } 1028 1029 .mgwpp-toast-notification.success { 1030 border-color: rgba(0, 173, 111, 0.3); 1031 } 1032 1033 .mgwpp-toast-notification.success .dashicons { 1034 color: #00ad6f; 1035 font-size: 24px; 1036 width: 24px; 1037 height: 24px; 1038 filter: drop-shadow(0 0 8px rgba(0, 173, 111, 0.6)); 1039 } 1040 1041 .mgwpp-toast-notification.error { 1042 border-color: rgba(255, 0, 76, 0.3); 1043 } 1044 1045 .mgwpp-toast-notification.error .dashicons { 1046 color: #ff004c; 1047 font-size: 24px; 1048 width: 24px; 1049 height: 24px; 1050 filter: drop-shadow(0 0 8px rgba(255, 0, 76, 0.6)); 1051 } 1052 1053 .mgwpp-toast-message { 1054 color: #fff; 1055 letter-spacing: 0.02em; 1056 text-shadow: 0 1px 3px rgba(0, 0, 0, 0.3); 1057 } 1058 892 1059 /* Responsive Adjustments */ 893 1060 @media (max-width: 782px) { 894 .mgwpp-premium-dashboard { 895 padding: 15px; 896 margin-left: -10px; 897 } 898 899 .mgwpp-premium-dashboard .mgwpp-glass-container { 900 padding: 20px; 901 } 902 903 .mgwpp-dashboard-header { 904 flex-direction: column; 905 align-items: flex-start; 906 gap: 20px; 907 } 908 909 .mgwpp-gallery-grid { 910 grid-template-columns: 1fr; 911 } 912 } 913 1061 .mgwpp-premium-dashboard { 1062 padding: 15px; 1063 margin-left: -10px; 1064 } 1065 1066 .mgwpp-premium-dashboard .mgwpp-glass-container { 1067 padding: 20px; 1068 } 1069 1070 .mgwpp-dashboard-header { 1071 flex-direction: column; 1072 align-items: flex-start; 1073 gap: 20px; 1074 } 1075 1076 .mgwpp-gallery-grid { 1077 grid-template-columns: 1fr; 1078 } 1079 } -
mini-gallery/trunk/includes/admin/views/inner-header/class-mgwpp-inner-header.php
r3438312 r3439097 97 97 data-current-theme="<?php echo esc_attr($current_theme); ?>" 98 98 aria-label="<?php esc_attr_e('Toggle dark mode', 'mini-gallery'); ?>"> 99 <span class="dashicons <?php echo esc_attr($current_theme === 'dark' ? 'dashicons- visibility' : 'dashicons-hidden'); ?>"99 <span class="dashicons <?php echo esc_attr($current_theme === 'dark' ? 'dashicons-buddicons-activity' : 'dashicons-admin-appearance'); ?>" 100 100 style="font-size: 35px; width: 35px; height: 35px;"></span> 101 101 </button> -
mini-gallery/trunk/includes/admin/views/inner-header/mgwpp-inner-header.js
r3438312 r3439097 4 4 const loaderOverlay = $('.mgwpp-loader-overlay'); 5 5 6 // Dashicon classes for sun and moon 7 const sunIcon = 'dashicons-admin-appearance'; // Light mode icon (sun/appearance) 8 const moonIcon = 'dashicons-buddicons-activity'; // Dark mode icon (moon/night) 9 6 10 // Apply theme from localStorage immediately on DOM ready to avoid flicker 7 11 applyLocalTheme(); 8 12 9 13 if (themeToggle.length) { 10 const icon = themeToggle.find('img');11 const sunIcon = themeToggle.data('sun');12 const moonIcon = themeToggle.data('moon');13 14 14 themeToggle.on('click', function (e) { 15 15 e.preventDefault(); … … 43 43 }); 44 44 }); 45 } 45 46 46 function applyTheme(theme) { 47 $('body').toggleClass('mgwpp-dark-mode', theme === 'dark'); 48 icon.attr('src', theme === 'dark' ? sunIcon : moonIcon); 49 themeToggle.data('current-theme', theme); 50 } 47 function applyTheme(theme) { 48 $('body').toggleClass('mgwpp-dark-mode', theme === 'dark'); 49 // Update the dashicon class 50 const icon = themeToggle.find('.dashicons'); 51 icon.removeClass(sunIcon + ' ' + moonIcon); 52 icon.addClass(theme === 'dark' ? moonIcon : sunIcon); 53 themeToggle.data('current-theme', theme); 51 54 } 52 55 … … 56 59 $('body').toggleClass('mgwpp-dark-mode', savedTheme === 'dark'); 57 60 if (themeToggle.length) { 58 const icon = themeToggle.find('img'); 59 const sunIcon = themeToggle.data('sun'); 60 const moonIcon = themeToggle.data('moon'); 61 icon.attr('src', savedTheme === 'dark' ? sunIcon : moonIcon); 61 const icon = themeToggle.find('.dashicons'); 62 icon.removeClass(sunIcon + ' ' + moonIcon); 63 icon.addClass(savedTheme === 'dark' ? moonIcon : sunIcon); 62 64 themeToggle.data('current-theme', savedTheme); 63 65 } -
mini-gallery/trunk/includes/functions/class-mgwpp-canvas-shortcode.php
r3438312 r3439097 31 31 } 32 32 33 // Check if canvas module is available 34 if (!class_exists('MGWPP_Canvas_Post_Type')) { 35 return '<!-- Mini Gallery Canvas: Canvas module is not enabled -->'; 36 } 37 33 38 $data = MGWPP_Canvas_Post_Type::get_canvas_data($canvas_id); 34 39 … … 52 57 'background' => '#ffffff' 53 58 ]); 54 59 55 60 $items = isset($data['items']) ? $data['items'] : []; 56 61 57 62 58 63 $slider_id = 'mgwpp-slider-' . $canvas_id; 59 64 $slider_settings = $data['slider_settings'] ?? ['autoplay' => false, 'effect' => 'slide', 'arrows' => true, 'dots' => true]; 60 65 61 66 // Ensure slides fallback 62 67 if (empty($data['slides'])) { 63 $slides = [[ 'id' => 'default', 'items' => $data['items'] ?? []]];68 $slides = [['id' => 'default', 'items' => $data['items'] ?? []]]; 64 69 } else { 65 70 $slides = $data['slides']; … … 67 72 68 73 ob_start(); 69 ?>70 <div id="<?php echo esc_attr($slider_id); ?>" class="mgwpp-canvas-slider" 71 data-settings="<?php echo esc_attr(json_encode($slider_settings)); ?>"72 style="max-width: <?php echo esc_attr($settings['width']); ?>px; aspect-ratio: <?php echo esc_attr($settings['width']); ?> / <?php echo esc_attr($settings['height']); ?>;">73 74 ?> 75 <div id="<?php echo esc_attr($slider_id); ?>" class="mgwpp-canvas-slider" 76 data-settings="<?php echo esc_attr(json_encode($slider_settings)); ?>" 77 style="max-width: <?php echo esc_attr($settings['width']); ?>px; aspect-ratio: <?php echo esc_attr($settings['width']); ?> / <?php echo esc_attr($settings['height']); ?>;"> 78 74 79 <div class="mgwpp-slides-track"> 75 80 <?php foreach ($slides as $index => $slide) : ?> 76 81 <div class="mgwpp-slide <?php echo $index === 0 ? 'active' : ''; ?>" data-slide-index="<?php echo esc_attr($index); ?>" 77 style="background: <?php echo esc_attr($settings['background']); ?>;">82 style="background: <?php echo esc_attr($settings['background']); ?>;"> 78 83 <?php foreach ($slide['items'] as $item) : ?> 79 84 <?php echo wp_kses_post(mgwpp_render_canvas_item($item, $settings)); ?> … … 99 104 </div> 100 105 <?php endif; ?> 101 106 102 107 <script> 103 (function() { 104 const slider = document.getElementById('<?php echo esc_js($slider_id); ?>'); 105 if(!slider) return; 106 107 const track = slider.querySelector('.mgwpp-slides-track'); 108 const slides = Array.from(slider.querySelectorAll('.mgwpp-slide')); 109 const dots = slider.querySelectorAll('.mgwpp-slider-dot'); 110 const prevBtn = slider.querySelector('.mgwpp-slider-arrow.prev'); 111 const nextBtn = slider.querySelector('.mgwpp-slider-arrow.next'); 112 const settings = JSON.parse(slider.dataset.settings); 113 114 // Apply Effect Class 115 slider.classList.add('mgwpp-effect-' + (settings.effect || 'slide')); 116 117 let currentIndex = 0; 118 let autoplayTimer; 119 120 // Initialize positions 121 function updateSlideClasses() { 122 slides.forEach((slide, index) => { 123 slide.classList.remove('active', 'prev-slide', 'next-slide'); 124 125 if (index === currentIndex) { 126 slide.classList.add('active'); 127 } else if (index === getPrevIndex(currentIndex)) { 128 slide.classList.add('prev-slide'); 129 } else if (index === getNextIndex(currentIndex)) { 130 slide.classList.add('next-slide'); 108 (function() { 109 const slider = document.getElementById('<?php echo esc_js($slider_id); ?>'); 110 if (!slider) return; 111 112 const track = slider.querySelector('.mgwpp-slides-track'); 113 const slides = Array.from(slider.querySelectorAll('.mgwpp-slide')); 114 const dots = slider.querySelectorAll('.mgwpp-slider-dot'); 115 const prevBtn = slider.querySelector('.mgwpp-slider-arrow.prev'); 116 const nextBtn = slider.querySelector('.mgwpp-slider-arrow.next'); 117 const settings = JSON.parse(slider.dataset.settings); 118 119 // Apply Effect Class 120 slider.classList.add('mgwpp-effect-' + (settings.effect || 'slide')); 121 122 let currentIndex = 0; 123 let autoplayTimer; 124 125 // Initialize positions 126 function updateSlideClasses() { 127 slides.forEach((slide, index) => { 128 slide.classList.remove('active', 'prev-slide', 'next-slide'); 129 130 if (index === currentIndex) { 131 slide.classList.add('active'); 132 } else if (index === getPrevIndex(currentIndex)) { 133 slide.classList.add('prev-slide'); 134 } else if (index === getNextIndex(currentIndex)) { 135 slide.classList.add('next-slide'); 136 } 137 }); 138 139 // Dots 140 if (dots.length) { 141 dots.forEach((d, i) => { 142 d.classList.toggle('active', i === currentIndex); 143 }); 131 144 } 145 } 146 147 function getPrevIndex(i) { 148 return (i - 1 + slides.length) % slides.length; 149 } 150 151 function getNextIndex(i) { 152 return (i + 1) % slides.length; 153 } 154 155 function goToSlide(index) { 156 if (index === currentIndex) return; 157 158 // Wrap index 159 if (index < 0) index = slides.length - 1; 160 if (index >= slides.length) index = 0; 161 162 currentIndex = index; 163 updateSlideClasses(); 164 } 165 166 // Init 167 updateSlideClasses(); 168 169 if (prevBtn) prevBtn.addEventListener('click', () => { 170 stopAutoplay(); 171 goToSlide(currentIndex - 1); 132 172 }); 133 134 // Dots 135 if(dots.length) { 136 dots.forEach((d, i) => { 137 d.classList.toggle('active', i === currentIndex); 173 if (nextBtn) nextBtn.addEventListener('click', () => { 174 stopAutoplay(); 175 goToSlide(currentIndex + 1); 176 }); 177 178 if (dots.length) { 179 dots.forEach((dot, idx) => { 180 dot.addEventListener('click', () => { 181 stopAutoplay(); 182 goToSlide(idx); 183 }); 138 184 }); 139 185 } 140 } 141 142 function getPrevIndex(i) { 143 return (i - 1 + slides.length) % slides.length; 144 } 145 146 function getNextIndex(i) { 147 return (i + 1) % slides.length; 148 } 149 150 function goToSlide(index) { 151 if (index === currentIndex) return; 152 153 // Wrap index 154 if(index < 0) index = slides.length - 1; 155 if(index >= slides.length) index = 0; 156 157 currentIndex = index; 158 updateSlideClasses(); 159 } 160 161 // Init 162 updateSlideClasses(); 163 164 if(prevBtn) prevBtn.addEventListener('click', () => { stopAutoplay(); goToSlide(currentIndex - 1); }); 165 if(nextBtn) nextBtn.addEventListener('click', () => { stopAutoplay(); goToSlide(currentIndex + 1); }); 166 167 if(dots.length) { 168 dots.forEach((dot, idx) => { 169 dot.addEventListener('click', () => { stopAutoplay(); goToSlide(idx); }); 170 }); 171 } 172 173 function startAutoplay() { 174 if(settings.autoplay && !!settings.autoplaySpeed) { 175 autoplayTimer = setInterval(() => goToSlide(currentIndex + 1), parseInt(settings.autoplaySpeed) || 3000); 176 } 177 } 178 179 function stopAutoplay() { 180 if(autoplayTimer) clearInterval(autoplayTimer); 181 } 182 183 startAutoplay(); 184 })(); 186 187 function startAutoplay() { 188 if (settings.autoplay && !!settings.autoplaySpeed) { 189 autoplayTimer = setInterval(() => goToSlide(currentIndex + 1), parseInt(settings.autoplaySpeed) || 3000); 190 } 191 } 192 193 function stopAutoplay() { 194 if (autoplayTimer) clearInterval(autoplayTimer); 195 } 196 197 startAutoplay(); 198 })(); 185 199 </script> 186 200 </div> 187 <?php201 <?php 188 202 return ob_get_clean(); 189 203 } … … 192 206 * Helper to format CSS values 193 207 */ 194 function mgwpp_format_css_value($val, $is_dimension = true) { 208 function mgwpp_format_css_value($val, $is_dimension = true) 209 { 195 210 if ($val === 'auto') return 'auto'; 196 211 if (is_numeric($val)) { … … 212 227 // Styles calculation 213 228 $styles = []; 214 229 215 230 // Position & Size 216 231 $styles[] = 'width: ' . mgwpp_format_css_value($item['width'] ?? 'auto'); … … 232 247 233 248 $style_str = implode('; ', $styles) . ';'; 234 249 235 250 $type = $item['type'] ?? 'div'; 236 251 $output = '<div class="mgwpp-canvas-item mgwpp-canvas-item-' . esc_attr($type) . '" style="' . esc_attr($style_str) . '">'; … … 238 253 // Inner Content 239 254 $inner_style = 'width: 100%; height: 100%; display: block;'; 240 255 241 256 switch ($type) { 242 257 case 'image': 243 258 $link_start = ''; 244 259 $link_end = ''; 245 260 246 261 if (!empty($item['link'])) { 247 262 $link_start = '<a href="' . esc_url($item['link']) . '" style="display:block;width:100%;height:100%;">'; 248 263 $link_end = '</a>'; 249 264 } 250 265 251 266 $output .= $link_start; 252 267 $output .= '<img src="' . esc_url($item['image_url']) . '" alt="' . esc_attr($item['alt_text'] ?? '') . '" style="width:100%;height:100%;object-fit:cover;display:block;" loading="lazy">'; … … 286 301 esc_attr($item['stroke_color'] ?? '#333') 287 302 ); 288 303 289 304 if (($item['shape_type'] ?? 'rectangle') === 'circle') { 290 305 $shape_style .= ' border-radius: 50%;'; 291 306 } 292 307 293 308 $output .= '<div class="mgwpp-canvas-shape" style="' . esc_attr($shape_style) . '"></div>'; 294 309 break; 295 310 296 311 case 'container': 297 $container_style = sprintf(312 $container_style = sprintf( 298 313 'display: %s; flex-direction: %s; justify-content: %s; align-items: %s; gap: %s; padding: %s; background-color: %s; border: %s solid %s; box-sizing: border-box; width: 100%%; height: 100%%;', 299 314 esc_attr($item['display'] ?? 'flex'), … … 307 322 esc_attr($item['border_color'] ?? 'transparent') 308 323 ); 309 324 310 325 $output .= '<div class="mgwpp-canvas-container" style="' . esc_attr($container_style) . '">'; 311 326 312 327 // Recursive Render 313 328 if (!empty($item['children']) && is_array($item['children'])) { 314 329 // Sort by z-index 315 usort($item['children'], function ($a, $b) {330 usort($item['children'], function ($a, $b) { 316 331 return ($a['z_index'] ?? 0) - ($b['z_index'] ?? 0); 317 332 }); 318 333 319 334 foreach ($item['children'] as $child) { 320 335 $output .= mgwpp_render_canvas_item($child, $settings, false); // false = not root 321 336 } 322 337 } 323 338 324 339 $output .= '</div>'; 325 340 break; -
mini-gallery/trunk/includes/gallery-types/mgwpp-3d-masonry-gallery/mgwpp-3d-masonry.css
r3438312 r3439097 5 5 6 6 .mgwpp-3d-masonry-gallery { 7 --masonry-gap: 12px;8 --masonry-radius: 8px;9 --masonry-columns: 4;10 --masonry-bg: #0a0a0a;11 --masonry-perspective: 1200px;12 13 position: relative;14 width: 100%;15 overflow: hidden;16 background: var(--masonry-bg);17 border-radius: 20px;18 isolation: isolate;7 --masonry-gap: 12px; 8 --masonry-radius: 8px; 9 --masonry-columns: 4; 10 --masonry-bg: #0a0a0a; 11 --masonry-perspective: 1200px; 12 13 position: relative; 14 width: 100%; 15 overflow: hidden; 16 background: var(--masonry-bg); 17 border-radius: 20px; 18 isolation: isolate; 19 19 } 20 20 … … 24 24 25 25 .mgwpp-3d-mode-switcher { 26 position: absolute;27 top: 20px;28 left: 50%;29 transform: translateX(-50%);30 z-index: 100;31 display: flex;32 gap: 4px;33 padding: 4px;34 background: rgba(30, 30, 30, 0.85);35 border-radius: 8px;36 backdrop-filter: blur(12px);37 -webkit-backdrop-filter: blur(12px);38 border: 1px solid rgba(255, 255, 255, 0.1);39 box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4);26 position: absolute; 27 top: 20px; 28 left: 50%; 29 transform: translateX(-50%); 30 z-index: 100; 31 display: flex; 32 gap: 4px; 33 padding: 4px; 34 background: rgba(30, 30, 30, 0.85); 35 border-radius: 8px; 36 backdrop-filter: blur(12px); 37 -webkit-backdrop-filter: blur(12px); 38 border: 1px solid rgba(255, 255, 255, 0.1); 39 box-shadow: 0 4px 24px rgba(0, 0, 0, 0.4); 40 40 } 41 41 42 42 .mgwpp-mode-btn { 43 padding: 8px 16px;44 font-size: 11px;45 font-weight: 600;46 letter-spacing: 0.5px;47 text-transform: uppercase;48 color: rgba(255, 255, 255, 0.6);49 background: transparent;50 border: none;51 border-radius: 5px;52 cursor: pointer;53 transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1);43 padding: 8px 16px; 44 font-size: 11px; 45 font-weight: 600; 46 letter-spacing: 0.5px; 47 text-transform: uppercase; 48 color: rgba(255, 255, 255, 0.6); 49 background: transparent; 50 border: none; 51 border-radius: 5px; 52 cursor: pointer; 53 transition: all 0.25s cubic-bezier(0.4, 0, 0.2, 1); 54 54 } 55 55 56 56 .mgwpp-mode-btn:hover { 57 color: rgba(255, 255, 255, 0.9);58 background: rgba(255, 255, 255, 0.08);57 color: rgba(255, 255, 255, 0.9); 58 background: rgba(255, 255, 255, 0.08); 59 59 } 60 60 61 61 .mgwpp-mode-btn.active { 62 color: #000;63 background: #fff;64 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);62 color: #000; 63 background: #fff; 64 box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3); 65 65 } 66 66 … … 70 70 71 71 .mgwpp-3d-stage { 72 position: relative;73 width: 100%;74 height: 100%;75 display: flex;76 align-items: center;77 justify-content: center;78 perspective: var(--masonry-perspective);79 perspective-origin: 50% 50%;72 position: relative; 73 width: 100%; 74 height: 100%; 75 display: flex; 76 align-items: center; 77 justify-content: center; 78 perspective: var(--masonry-perspective); 79 perspective-origin: 50% 50%; 80 80 } 81 81 82 82 .mgwpp-3d-perspective-wrap { 83 position: relative;84 width: 100%;85 height: 100%;86 transform-style: preserve-3d;87 transition: transform 0.8s cubic-bezier(0.23, 1, 0.32, 1);83 position: relative; 84 width: 100%; 85 height: 100%; 86 transform-style: preserve-3d; 87 transition: transform 0.8s cubic-bezier(0.23, 1, 0.32, 1); 88 88 } 89 89 … … 93 93 94 94 .mgwpp-masonry-columns { 95 display: grid; 96 grid-template-columns: repeat(var(--masonry-columns), 1fr); 97 gap: var(--masonry-gap); 98 height: 100%; 99 padding: 100px var(--masonry-gap) 150px; 100 transform-style: preserve-3d; 95 display: grid; 96 grid-template-columns: repeat(var(--masonry-columns), 1fr); 97 gap: var(--masonry-gap); 98 height: 100%; 99 transform-style: preserve-3d; 101 100 } 102 101 103 102 .mgwpp-masonry-column { 104 position: relative;105 overflow: hidden;106 height: 100%;103 position: relative; 104 overflow: hidden; 105 height: 100%; 107 106 } 108 107 109 108 .mgwpp-masonry-track { 110 display: flex;111 flex-direction: column;112 gap: var(--masonry-gap);113 animation: mgwpp3dMasonryUp 60s linear infinite;114 will-change: transform;109 display: flex; 110 flex-direction: column; 111 gap: var(--masonry-gap); 112 animation: mgwpp3dMasonryUp 60s linear infinite; 113 will-change: transform; 115 114 } 116 115 117 116 /* Direction variants */ 118 117 .mgwpp-masonry-column[data-direction="down"] .mgwpp-masonry-track { 119 animation-name: mgwpp3dMasonryDown;118 animation-name: mgwpp3dMasonryDown; 120 119 } 121 120 122 121 @keyframes mgwpp3dMasonryUp { 123 0% { transform: translateY(0); } 124 100% { transform: translateY(-33.333%); } 122 0% { 123 transform: translateY(0); 124 } 125 100% { 126 transform: translateY(-33.333%); 127 } 125 128 } 126 129 127 130 @keyframes mgwpp3dMasonryDown { 128 0% { transform: translateY(-33.333%); } 129 100% { transform: translateY(0); } 131 0% { 132 transform: translateY(-33.333%); 133 } 134 100% { 135 transform: translateY(0); 136 } 130 137 } 131 138 … … 135 142 136 143 .mgwpp-masonry-item { 137 flex-shrink: 0; 138 position: relative; 139 border-radius: var(--masonry-radius); 140 overflow: hidden; 141 background: #1a1a1a; 142 transform-style: preserve-3d; 143 transition: transform 0.5s cubic-bezier(0.23, 1, 0.32, 1), 144 box-shadow 0.5s ease, 145 z-index 0s 0.5s; 144 flex-shrink: 0; 145 position: relative; 146 border-radius: var(--masonry-radius); 147 overflow: hidden; 148 background: #1a1a1a; 149 transform-style: preserve-3d; 150 transition: transform 0.5s cubic-bezier(0.23, 1, 0.32, 1), 151 box-shadow 0.5s ease, z-index 0s 0.5s; 146 152 } 147 153 148 154 /* Aspect ratio variations for true masonry */ 149 155 .mgwpp-masonry-item.aspect-portrait { 150 aspect-ratio: 3 / 4;156 aspect-ratio: 3 / 4; 151 157 } 152 158 153 159 .mgwpp-masonry-item.aspect-square { 154 aspect-ratio: 1 / 1;160 aspect-ratio: 1 / 1; 155 161 } 156 162 157 163 .mgwpp-masonry-item.aspect-landscape { 158 aspect-ratio: 4 / 3;164 aspect-ratio: 4 / 3; 159 165 } 160 166 161 167 .mgwpp-masonry-item img { 162 display: block; 163 width: 100%; 164 height: 100%; 165 object-fit: cover; 166 transition: transform 0.6s cubic-bezier(0.23, 1, 0.32, 1), 167 filter 0.4s ease; 168 display: block; 169 width: 100%; 170 height: 100%; 171 object-fit: cover; 172 transition: transform 0.6s cubic-bezier(0.23, 1, 0.32, 1), filter 0.4s ease; 168 173 } 169 174 170 175 /* Hover overlay */ 171 176 .mgwpp-item-overlay { 172 position: absolute;173 inset: 0;174 background: linear-gradient(180deg, transparent 60%, rgba(0, 0, 0, 0.6) 100%);175 opacity: 0;176 transition: opacity 0.4s ease;177 pointer-events: none;177 position: absolute; 178 inset: 0; 179 background: linear-gradient(180deg, transparent 60%, rgba(0, 0, 0, 0.6) 100%); 180 opacity: 0; 181 transition: opacity 0.4s ease; 182 pointer-events: none; 178 183 } 179 184 180 185 /* Hover Effects */ 181 186 .mgwpp-masonry-item:hover { 182 transform: scale(1.08) translateZ(30px);183 z-index: 50;184 transition-delay: 0s, 0s, 0s;185 box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);187 transform: scale(1.08) translateZ(30px); 188 z-index: 50; 189 transition-delay: 0s, 0s, 0s; 190 box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5); 186 191 } 187 192 188 193 .mgwpp-masonry-item:hover img { 189 transform: scale(1.15);194 transform: scale(1.15); 190 195 } 191 196 192 197 .mgwpp-masonry-item:hover .mgwpp-item-overlay { 193 opacity: 1;198 opacity: 1; 194 199 } 195 200 … … 200 205 /* WALL MODE - Slight vertical tilt */ 201 206 .mgwpp-3d-masonry-gallery[data-mode="wall"] .mgwpp-3d-perspective-wrap { 202 transform: rotateX(8deg) rotateY(-3deg) translateZ(-50px);207 transform: rotateX(8deg) rotateY(-3deg) translateZ(-50px); 203 208 } 204 209 205 210 .mgwpp-3d-masonry-gallery[data-mode="wall"] .mgwpp-masonry-columns { 206 transform: scale(0.9);211 transform: scale(0.9); 207 212 } 208 213 209 214 /* TABLE MODE - Floor/table perspective */ 210 215 .mgwpp-3d-masonry-gallery[data-mode="table"] .mgwpp-3d-perspective-wrap { 211 transform: rotateX(45deg) rotateZ(0deg) translateY(-10%) translateZ(-100px) scale(0.75); 216 transform: rotateX(45deg) rotateZ(0deg) translateY(-10%) translateZ(-100px) 217 scale(0.75); 212 218 } 213 219 214 220 .mgwpp-3d-masonry-gallery[data-mode="table"] .mgwpp-masonry-item:hover { 215 transform: scale(1.15) translateZ(80px);221 transform: scale(1.15) translateZ(80px); 216 222 } 217 223 218 224 /* TUNNEL MODE - Immersive tunnel effect */ 219 225 .mgwpp-3d-masonry-gallery[data-mode="tunnel"] .mgwpp-3d-perspective-wrap { 220 transform: rotateX(15deg) translateZ(-200px) scale(1.1);226 transform: rotateX(15deg) translateZ(-200px) scale(1.1); 221 227 } 222 228 223 229 .mgwpp-3d-masonry-gallery[data-mode="tunnel"] .mgwpp-masonry-columns { 224 perspective: 800px; 225 } 226 227 .mgwpp-3d-masonry-gallery[data-mode="tunnel"] .mgwpp-masonry-column:first-child { 228 transform: rotateY(15deg) translateZ(-50px); 230 perspective: 800px; 231 } 232 233 .mgwpp-3d-masonry-gallery[data-mode="tunnel"] 234 .mgwpp-masonry-column:first-child { 235 transform: rotateY(15deg) translateZ(-50px); 229 236 } 230 237 231 238 .mgwpp-3d-masonry-gallery[data-mode="tunnel"] .mgwpp-masonry-column:last-child { 232 transform: rotateY(-15deg) translateZ(-50px); 233 } 234 235 .mgwpp-3d-masonry-gallery[data-mode="tunnel"] .mgwpp-masonry-column:nth-child(2) { 236 transform: rotateY(5deg) translateZ(-20px); 237 } 238 239 .mgwpp-3d-masonry-gallery[data-mode="tunnel"] .mgwpp-masonry-column:nth-last-child(2) { 240 transform: rotateY(-5deg) translateZ(-20px); 239 transform: rotateY(-15deg) translateZ(-50px); 240 } 241 242 .mgwpp-3d-masonry-gallery[data-mode="tunnel"] 243 .mgwpp-masonry-column:nth-child(2) { 244 transform: rotateY(5deg) translateZ(-20px); 245 } 246 247 .mgwpp-3d-masonry-gallery[data-mode="tunnel"] 248 .mgwpp-masonry-column:nth-last-child(2) { 249 transform: rotateY(-5deg) translateZ(-20px); 241 250 } 242 251 243 252 /* FLAT MODE - Traditional masonry */ 244 253 .mgwpp-3d-masonry-gallery[data-mode="flat"] .mgwpp-3d-perspective-wrap { 245 transform: none;246 perspective: none;254 transform: none; 255 perspective: none; 247 256 } 248 257 249 258 .mgwpp-3d-masonry-gallery[data-mode="flat"] .mgwpp-masonry-columns { 250 transform: none;259 transform: none; 251 260 } 252 261 253 262 .mgwpp-3d-masonry-gallery[data-mode="flat"] .mgwpp-masonry-item:hover { 254 transform: scale(1.05);263 transform: scale(1.05); 255 264 } 256 265 … … 260 269 261 270 .mgwpp-3d-fade { 262 position: absolute;263 z-index: 50;264 pointer-events: none;271 position: absolute; 272 z-index: 50; 273 pointer-events: none; 265 274 } 266 275 267 276 .mgwpp-3d-fade-top { 268 top: 0; 269 left: 0; 270 right: 0; 271 height: 120px; 272 background: linear-gradient(to bottom, 273 var(--masonry-bg) 0%, 274 rgba(10, 10, 10, 0.9) 20%, 275 rgba(10, 10, 10, 0.5) 50%, 276 transparent 100%); 277 top: 0; 278 left: 0; 279 right: 0; 280 height: 120px; 281 background: linear-gradient( 282 to bottom, 283 var(--masonry-bg) 0%, 284 rgba(10, 10, 10, 0.9) 20%, 285 rgba(10, 10, 10, 0.5) 50%, 286 transparent 100% 287 ); 277 288 } 278 289 279 290 .mgwpp-3d-fade-bottom { 280 bottom: 0; 281 left: 0; 282 right: 0; 283 height: 100px; 284 background: linear-gradient(to top, 285 var(--masonry-bg) 0%, 286 rgba(10, 10, 10, 0.8) 30%, 287 transparent 100%); 291 bottom: 0; 292 left: 0; 293 right: 0; 294 height: 100px; 295 background: linear-gradient( 296 to top, 297 var(--masonry-bg) 0%, 298 rgba(10, 10, 10, 0.8) 30%, 299 transparent 100% 300 ); 288 301 } 289 302 290 303 .mgwpp-3d-fade-left { 291 top: 0; 292 left: 0; 293 bottom: 0; 294 width: 80px; 295 background: linear-gradient(to right, 296 var(--masonry-bg) 0%, 297 rgba(10, 10, 10, 0.5) 50%, 298 transparent 100%); 304 top: 0; 305 left: 0; 306 bottom: 0; 307 width: 80px; 308 background: linear-gradient( 309 to right, 310 var(--masonry-bg) 0%, 311 rgba(10, 10, 10, 0.5) 50%, 312 transparent 100% 313 ); 299 314 } 300 315 301 316 .mgwpp-3d-fade-right { 302 top: 0; 303 right: 0; 304 bottom: 0; 305 width: 80px; 306 background: linear-gradient(to left, 307 var(--masonry-bg) 0%, 308 rgba(10, 10, 10, 0.5) 50%, 309 transparent 100%); 317 top: 0; 318 right: 0; 319 bottom: 0; 320 width: 80px; 321 background: linear-gradient( 322 to left, 323 var(--masonry-bg) 0%, 324 rgba(10, 10, 10, 0.5) 50%, 325 transparent 100% 326 ); 310 327 } 311 328 … … 315 332 316 333 .mgwpp-3d-pause-btn { 317 position: absolute;318 bottom: 20px;319 right: 20px;320 z-index: 100;321 width: 44px;322 height: 44px;323 border: none;324 border-radius: 50%;325 background: rgba(255, 255, 255, 0.1);326 backdrop-filter: blur(12px);327 -webkit-backdrop-filter: blur(12px);328 color: #fff;329 cursor: pointer;330 display: flex;331 align-items: center;332 justify-content: center;333 transition: all 0.3s ease;334 box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3);335 border: 1px solid rgba(255, 255, 255, 0.1);334 position: absolute; 335 bottom: 20px; 336 right: 20px; 337 z-index: 100; 338 width: 44px; 339 height: 44px; 340 border: none; 341 border-radius: 50%; 342 background: rgba(255, 255, 255, 0.1); 343 backdrop-filter: blur(12px); 344 -webkit-backdrop-filter: blur(12px); 345 color: #fff; 346 cursor: pointer; 347 display: flex; 348 align-items: center; 349 justify-content: center; 350 transition: all 0.3s ease; 351 box-shadow: 0 4px 20px rgba(0, 0, 0, 0.3); 352 border: 1px solid rgba(255, 255, 255, 0.1); 336 353 } 337 354 338 355 .mgwpp-3d-pause-btn:hover { 339 background: rgba(255, 255, 255, 0.2);340 transform: scale(1.1);356 background: rgba(255, 255, 255, 0.2); 357 transform: scale(1.1); 341 358 } 342 359 343 360 .mgwpp-3d-pause-btn:focus { 344 outline: 2px solid #3b82f6;345 outline-offset: 2px;361 outline: 2px solid #3b82f6; 362 outline-offset: 2px; 346 363 } 347 364 … … 351 368 352 369 .mgwpp-3d-masonry-gallery[data-pause-hover="true"]:hover .mgwpp-masonry-track { 353 animation-play-state: paused;370 animation-play-state: paused; 354 371 } 355 372 356 373 .mgwpp-3d-masonry-gallery.is-paused .mgwpp-masonry-track { 357 animation-play-state: paused;374 animation-play-state: paused; 358 375 } 359 376 360 377 /* Grayscale Mode */ 361 378 .mgwpp-3d-masonry-gallery[data-grayscale="true"] .mgwpp-masonry-item img { 362 filter: grayscale(100%);379 filter: grayscale(100%); 363 380 } 364 381 365 382 .mgwpp-3d-masonry-gallery[data-grayscale="true"] .mgwpp-masonry-item:hover img { 366 filter: grayscale(0%);383 filter: grayscale(0%); 367 384 } 368 385 … … 372 389 373 390 @media (prefers-reduced-motion: reduce) { 374 .mgwpp-masonry-track {375 animation: none !important;376 }377 378 .mgwpp-masonry-item,379 .mgwpp-masonry-item img,380 .mgwpp-3d-perspective-wrap {381 transition: none !important;382 }383 384 .mgwpp-masonry-item:hover {385 transform: none !important;386 }391 .mgwpp-masonry-track { 392 animation: none !important; 393 } 394 395 .mgwpp-masonry-item, 396 .mgwpp-masonry-item img, 397 .mgwpp-3d-perspective-wrap { 398 transition: none !important; 399 } 400 401 .mgwpp-masonry-item:hover { 402 transform: none !important; 403 } 387 404 } 388 405 … … 392 409 393 410 @media (max-width: 1024px) { 394 .mgwpp-3d-masonry-gallery {395 --masonry-columns: 3;396 }397 398 .mgwpp-3d-mode-switcher {399 padding: 3px;400 }401 402 .mgwpp-mode-btn {403 padding: 6px 12px;404 font-size: 10px;405 }411 .mgwpp-3d-masonry-gallery { 412 --masonry-columns: 3; 413 } 414 415 .mgwpp-3d-mode-switcher { 416 padding: 3px; 417 } 418 419 .mgwpp-mode-btn { 420 padding: 6px 12px; 421 font-size: 10px; 422 } 406 423 } 407 424 408 425 @media (max-width: 768px) { 409 .mgwpp-3d-masonry-gallery {410 --masonry-columns: 2;411 height: 500px !important;412 border-radius: 12px;413 }414 415 .mgwpp-3d-mode-switcher {416 top: 12px;417 }418 419 .mgwpp-mode-btn {420 padding: 5px 10px;421 font-size: 9px;422 }423 424 .mgwpp-3d-fade-top {425 height: 80px;426 }427 428 .mgwpp-3d-fade-bottom {429 height: 60px;430 }431 432 .mgwpp-3d-fade-left,433 .mgwpp-3d-fade-right {434 width: 40px;435 }436 437 /* Reduce 3D intensity on mobile */438 .mgwpp-3d-masonry-gallery[data-mode="wall"] .mgwpp-3d-perspective-wrap {439 transform: rotateX(5deg) rotateY(-2deg);440 }441 442 .mgwpp-3d-masonry-gallery[data-mode="table"] .mgwpp-3d-perspective-wrap {443 transform: rotateX(30deg) translateY(-5%) scale(0.9);444 }445 446 .mgwpp-3d-masonry-gallery[data-mode="tunnel"] .mgwpp-3d-perspective-wrap {447 transform: rotateX(10deg) scale(1);448 }426 .mgwpp-3d-masonry-gallery { 427 --masonry-columns: 2; 428 height: 500px !important; 429 border-radius: 12px; 430 } 431 432 .mgwpp-3d-mode-switcher { 433 top: 12px; 434 } 435 436 .mgwpp-mode-btn { 437 padding: 5px 10px; 438 font-size: 9px; 439 } 440 441 .mgwpp-3d-fade-top { 442 height: 80px; 443 } 444 445 .mgwpp-3d-fade-bottom { 446 height: 60px; 447 } 448 449 .mgwpp-3d-fade-left, 450 .mgwpp-3d-fade-right { 451 width: 40px; 452 } 453 454 /* Reduce 3D intensity on mobile */ 455 .mgwpp-3d-masonry-gallery[data-mode="wall"] .mgwpp-3d-perspective-wrap { 456 transform: rotateX(5deg) rotateY(-2deg); 457 } 458 459 .mgwpp-3d-masonry-gallery[data-mode="table"] .mgwpp-3d-perspective-wrap { 460 transform: rotateX(30deg) translateY(-5%) scale(0.9); 461 } 462 463 .mgwpp-3d-masonry-gallery[data-mode="tunnel"] .mgwpp-3d-perspective-wrap { 464 transform: rotateX(10deg) scale(1); 465 } 449 466 } 450 467 451 468 @media (max-width: 480px) { 452 .mgwpp-3d-masonry-gallery {453 --masonry-columns: 2;454 height: 400px !important;455 }456 457 .mgwpp-3d-pause-btn {458 width: 36px;459 height: 36px;460 bottom: 12px;461 right: 12px;462 }469 .mgwpp-3d-masonry-gallery { 470 --masonry-columns: 2; 471 height: 400px !important; 472 } 473 474 .mgwpp-3d-pause-btn { 475 width: 36px; 476 height: 36px; 477 bottom: 12px; 478 right: 12px; 479 } 463 480 } 464 481 … … 468 485 469 486 .mgwpp-no-images { 470 text-align: center;471 padding: 60px 20px;472 color: #666;473 font-style: italic;474 background: #1a1a1a;475 border-radius: 16px;476 } 487 text-align: center; 488 padding: 60px 20px; 489 color: #666; 490 font-style: italic; 491 background: #1a1a1a; 492 border-radius: 16px; 493 } -
mini-gallery/trunk/includes/registration/gallery/class-mgwpp-gallery-capabilities.php
r3438397 r3439097 11 11 // Only run if capabilities haven't been added yet (check stored version) 12 12 $cap_version = get_option('mgwpp_gallery_cap_version', '0'); 13 $current_version = '1.6 '; // Update this when capabilities change13 $current_version = '1.6.1'; // Update this when capabilities change 14 14 15 15 if ($cap_version === $current_version) { … … 17 17 } 18 18 19 $roles = ['administrator']; 20 foreach ($roles as $role_name) { 21 $role = get_role($role_name); 22 if ($role) { 23 // Add the custom capabilities to the specified roles 24 $role->add_cap('edit_mgwpp_soora'); 25 $role->add_cap('read_mgwpp_soora'); 26 $role->add_cap('delete_mgwpp_soora'); 27 $role->add_cap('edit_mgwpp_sooras'); 28 $role->add_cap('edit_others_mgwpp_sooras'); 29 $role->add_cap('publish_mgwpp_sooras'); 30 $role->add_cap('read_private_mgwpp_sooras'); 31 $role->add_cap('delete_mgwpp_sooras'); 32 $role->add_cap('delete_private_mgwpp_sooras'); 33 $role->add_cap('delete_published_mgwpp_sooras'); 34 $role->add_cap('delete_others_mgwpp_sooras'); 35 $role->add_cap('edit_private_mgwpp_sooras'); 36 $role->add_cap('edit_published_mgwpp_sooras'); 37 $role->add_cap('create_mgwpp_sooras'); 38 } 19 // Assign capabilities to administrator role 20 $admin_role = get_role('administrator'); 21 if ($admin_role) { 22 // Add the custom capabilities for gallery management 23 $admin_role->add_cap('edit_mgwpp_soora'); 24 $admin_role->add_cap('read_mgwpp_soora'); 25 $admin_role->add_cap('delete_mgwpp_soora'); 26 $admin_role->add_cap('edit_mgwpp_sooras'); 27 $admin_role->add_cap('edit_others_mgwpp_sooras'); 28 $admin_role->add_cap('publish_mgwpp_sooras'); 29 $admin_role->add_cap('read_private_mgwpp_sooras'); 30 $admin_role->add_cap('delete_mgwpp_sooras'); 31 $admin_role->add_cap('delete_private_mgwpp_sooras'); 32 $admin_role->add_cap('delete_published_mgwpp_sooras'); 33 $admin_role->add_cap('delete_others_mgwpp_sooras'); 34 $admin_role->add_cap('edit_private_mgwpp_sooras'); 35 $admin_role->add_cap('edit_published_mgwpp_sooras'); 36 $admin_role->add_cap('create_mgwpp_sooras'); 39 37 } 40 38 … … 42 40 update_option('mgwpp_gallery_cap_version', $current_version); 43 41 } 42 43 /** 44 * Check if current user can manage galleries 45 * Works for administrators even if custom capabilities not yet assigned 46 * 47 * @return bool 48 */ 49 public static function current_user_can_manage_galleries() 50 { 51 // Administrators always have access (fallback for fresh installs) 52 if (current_user_can('manage_options')) { 53 return true; 54 } 55 56 // Check custom capability 57 return current_user_can('publish_mgwpp_sooras'); 58 } 44 59 } 45 60 -
mini-gallery/trunk/mini-gallery.php
r3438312 r3439097 4 4 Plugin URI: https://wordpress.org/plugins/mini-gallery/ 5 5 Description: A Fully Open Source WordPress Gallery, Slider and Carousel Alternative for Premium Plugin Sliders. Choose one of our 10 Default Ones, or create your own. 6 Version: 1.6 6 Version: 1.6.1 7 7 Author: AGWS | And Go Web Solutions 8 8 Author URI: https://andgowebsolutions.com … … 24 24 25 25 // Plugin constants 26 define('MG_VERSION', '1.6.1'); 26 27 define('MG_PLUGIN_PATH', plugin_dir_path(__FILE__)); 27 28 define('MG_PLUGIN_URL', plugins_url('', __FILE__)); -
mini-gallery/trunk/readme.txt
r3438312 r3439097 1 1 === Mini Gallery === 2 2 Contributors: @omarashzeinhom 3 Tags: gallery, carousel, slider, 3d, elementor3 Tags: gallery, carousel, slider, 3d, shortcode 4 4 Requires at least: 6.0 5 5 Tested up to: 6.9 6 Version: 1.6 7 Stable tag: 1.6 6 Version: 1.6.1 7 Stable tag: 1.6.1 8 8 Requires PHP: 8.0 9 9 License: GPLv2 or later 10 10 License URI: https://www.gnu.org/licenses/gpl-2.0.html 11 11 12 A lightweight and flexible WordPress gallery plugin , now with Elementor support and 12 gallery types including 3D model viewer.12 A lightweight and flexible WordPress gallery plugin with 17 gallery types including 3D model viewer. Works with any theme using simple shortcodes. 13 13 14 14 == Description == 15 15 16 **Mini Gallery** is a simple, fast, and versatile gallery carousel plugin, now integrated with Elementor page builder!16 **Mini Gallery** is a simple, fast, and versatile gallery plugin that works with any WordPress theme using the standard shortcode system - the most widely accepted and compatible method for embedding content in WordPress. 17 17 18 18 **New in Version 1.6:** … … 43 43 17. **Canvas Editor** - Visual drag-and-drop gallery builder 44 44 45 **Page Builder Integration:** 46 - **Elementor Widget** - Seamlessly integrate galleries into Elementor pages 47 - Drag-and-drop interface for easy gallery placement 48 - Live preview in Elementor editor 45 **Page Builder Compatibility:** 46 - **Universal Shortcode Support** - Works with any page builder (Gutenberg, Elementor, Divi, WPBakery, etc.) 47 - Simple shortcode: `[mgwpp_gallery id="X"]` 48 - Works in posts, pages, widgets, and custom templates 49 - No plugin dependencies - pure WordPress compatibility 49 50 50 51 **Visual Canvas Editor:** … … 95 96 1. Upload the plugin folder to `/wp-content/plugins/`. 96 97 2. Activate the plugin through the 'Plugins' menu in WordPress. 97 3. Use the provided shortcodes or Elementor widget to insert galleries into your pages. 98 4. For 3D models: Upload GLTF/GLB files through Media Library and select "3D Model Carousel" as gallery type. 98 3. Navigate to Gallery > Add New to create your first gallery. 99 4. Select a gallery type, add images from your Media Library. 100 5. Copy the shortcode `[mgwpp_gallery id="X"]` and paste it anywhere in your site. 101 6. For 3D models: Upload GLTF/GLB files through Media Library and select "3D Model Carousel" as gallery type. 99 102 100 103 == Changelog == 104 105 = 1.6.1 = 106 - Improved gallery creation workflow - gallery auto-creates after selecting images 107 - Added multi-select tooltip in media uploader for better UX 108 - Added success toast notification after gallery creation 109 - Modal now closes automatically after successful gallery creation 110 - Added manage_options fallback for fresh installs - works out of the box 111 - Improved database query security with proper caching 112 - Fixed PHPCS warnings and code quality improvements 113 - Updated plugin description to emphasize universal shortcode compatibility 114 - Auto-generated gallery titles now use DD/MM/YYYY HH:MM format 101 115 102 116 = 1.6 = … … 135 149 11. Testimonial Carousel - [Demo](https://minigallery.andgowebsolutions.com/gallery/testimonials-carousel/) 136 150 12. 3D Model Carousel - [Demo](https://minigallery.andgowebsolutions.com/gallery/3d-model-carousel/) (NEW) 137 - Added Elementor widget support.151 - Enhanced shortcode system for universal compatibility. 138 152 - Launched new website: [https://minigallery.andgowebsolutions.com](https://minigallery.andgowebsolutions.com) 139 153 - Live demo available at homepage. … … 149 163 == Frequently Asked Questions == 150 164 151 = Can I use it with Elementor? =152 Yes! Mini Gallery 1.6 comes with full Elementor widget support, allowing you to insert and customize galleries easily.165 = Can I use it with any page builder? = 166 Yes! Mini Gallery uses standard WordPress shortcodes which work with any theme or page builder including Gutenberg, Elementor, Divi, WPBakery, Beaver Builder, and more. Simply use `[mgwpp_gallery id="X"]` anywhere shortcodes are supported. 153 167 154 168 = How many gallery types are available? = 155 There are now 12 gallery types included with Mini Gallery 1.6.169 There are 17 gallery types included with Mini Gallery 1.6, all accessible via the simple shortcode `[mgwpp_gallery id="X"]`. 156 170 157 171 = What 3D file formats are supported? =
Note: See TracChangeset
for help on using the changeset viewer.