Plugin Directory

Changeset 3439097


Ignore:
Timestamp:
01/14/2026 01:26:53 AM (6 hours ago)
Author:
omarashzeinhom
Message:

Version 1.6.1 - Improved gallery creation workflow with auto-submit, multi-select tooltip, shortcode-focused documentation, admin permissions out-of-box support

Location:
mini-gallery/trunk
Files:
5 added
17 edited

Legend:

Unmodified
Added
Removed
  • mini-gallery/trunk/includes/admin/class-mgwpp-analytics-manager.php

    r3438312 r3439097  
    8080        // Add GA4 tracking via wp_head (standard method for analytics scripts)
    8181        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
    8384            printf(
    8485                '<script async src="%s"></script>',
     
    175176        global $wpdb;
    176177
     178        // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery -- Custom analytics table requires direct insert
    177179        return $wpdb->insert(
    178180            $wpdb->prefix . 'mgwpp_analytics',
     
    199201    {
    200202        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)
    201206        $table = $wpdb->prefix . 'mgwpp_analytics';
    202207
     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
    203216        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
    204220            $count = $wpdb->get_var(
    205221                $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)",
    207223                    $event_type
    208224                )
    209225            );
     226            // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery
     227            // phpcs:enable WordPress.DB.DirectDatabaseQuery.NoCaching
     228            // phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
    210229        } else {
     230            // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery
     231            // phpcs:disable WordPress.DB.DirectDatabaseQuery.NoCaching
     232            // phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
    211233            $count = $wpdb->get_var(
    212234                $wpdb->prepare(
    213                     "SELECT COUNT(*) FROM `{$table}` WHERE event_type = %s",
     235                    "SELECT COUNT(*) FROM {$table} WHERE event_type = %s",
    214236                    $event_type
    215237                )
    216238            );
    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);
    218246
    219247        return intval($count);
  • mini-gallery/trunk/includes/admin/class-mgwpp_ajax_handler.php

    r3438397 r3439097  
    7070        }
    7171
    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')) {
    7474            wp_die(
    7575                esc_html__('Insufficient permissions to preview galleries.', 'mini-gallery'),
     
    186186        }
    187187
    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')) {
    190190            wp_send_json_error([
    191191                'message' => esc_html__('Insufficient permissions', 'mini-gallery')
     
    228228            }
    229229
    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')) {
    232232                wp_send_json_error(['message' => esc_html__('Insufficient permissions', 'mini-gallery')]);
    233233            }
     
    441441        }
    442442
    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')) {
    444445            wp_die(esc_html__('You do not have sufficient permissions.', 'mini-gallery'));
    445446        }
     
    527528        }
    528529
    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')) {
    531532            wp_send_json_error(['message' => __('Insufficient permissions', 'mini-gallery')]);
    532533        }
  • mini-gallery/trunk/includes/admin/js/mgwpp-admin-scripts.js

    r3438350 r3439097  
    4949        });
    5050
     51        // Show multi-select tooltip when media frame opens
     52        mediaFrame.on('open', function () {
     53            showMediaTooltip();
     54        });
     55
    5156        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">&times;</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);
    52123    }
    53124
     
    81152
    82153        updateMediaPreview(attachments, is3D);
     154
     155        // Auto-submit the form after images are selected
     156        if (mediaIds.length > 0) {
     157            autoSubmitGalleryForm();
     158        }
    83159    }
    84160
     
    107183    function updateMediaPreview(attachments, is3D) {
    108184        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
    109203        attachments.forEach(attachment => {
    110204            if (is3D || !attachment.sizes) {
     
    130224            }
    131225        });
     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);
    132256    }
    133257
     
    173297            success: (response) => {
    174298                form.data('submitting', false);
     299                $('#mgwpp-create-loading').hide();
     300
    175301                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);
    182312                } else {
    183                     $('#mgwpp-create-loading').hide();
    184313                    showError({ responseJSON: response }, notice);
    185314                }
     
    195324    }
    196325
     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
    197382    function handleFormSubmission(e) {
    198383        e.preventDefault();
  • mini-gallery/trunk/includes/admin/views/dashboard/class-mgwpp-dashboard-view.php

    r3438312 r3439097  
    8585
    8686        // Use WP_Query instead of direct database query
     87        // phpcs:disable WordPress.DB.SlowDBQuery.slow_db_query_meta_query
    8788        $query = new WP_Query([
    8889            'post_type'      => 'mgwpp_soora',
     
    9899            ],
    99100        ]);
     101        // phpcs:enable WordPress.DB.SlowDBQuery.slow_db_query_meta_query
    100102
    101103        $count = $query->post_count;
  • mini-gallery/trunk/includes/admin/views/edit-gallery/class-mgwpp-edit-gallery.php

    r3438312 r3439097  
    124124        ], home_url('/'));
    125125        $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;
    126130?>
    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
    128138            <h1><?php
    129139                printf(
    130140                    /* translators: %s: Gallery title/name */
    131                     esc_html__('Edit: Gallery %s', 'mini-gallery'),
     141                    esc_html__('Edit: %s', 'mini-gallery'),
    132142                    esc_html($gallery->post_title)
    133143                );
     
    135145
    136146            <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>
    175186                                                </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>
    190206                            </div>
    191207                        </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>
    202224                            </div>
    203225                        </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>
    224229                            </div>
    225230                        </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; ?>
    229254                        </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>
    232265            </div>
    233266        </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
     30body.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;
    1962  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;
    37102  font-size: 28px;
     103  font-weight: 700;
     104  margin: 0 0 30px 0;
    38105  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);
    56159  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;
    66190  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;
    70195  text-transform: uppercase;
    71196  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 {
    114216  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
     227body.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   ===================================================== */
    120244.mgwpp-image-manager {
    121   margin-top: 15px;
     245  margin-top: 10px;
    122246}
    123247
    124248.mgwpp-image-container {
    125249  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 */
    131257.mgwpp-image-item {
    132258  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;
    143280}
    144281
    145282.mgwpp-image-item img {
    146283  width: 100%;
    147   height: auto;
     284  height: 100%;
     285  object-fit: contain;
    148286  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 */
    153297.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 */
    169315.mgwpp-item-actions {
    170316  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;
    175321  opacity: 0;
    176   transition: opacity 0.2s ease;
     322  transform: translateY(-5px);
     323  transition: all 0.3s ease;
    177324  z-index: 20;
    178325}
     
    180327.mgwpp-image-item:hover .mgwpp-item-actions {
    181328  opacity: 1;
     329  transform: translateY(0);
    182330}
    183331
    184332.mgwpp-item-actions button {
    185333  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;
    189338  cursor: pointer;
    190   width: 24px;
    191   height: 24px;
     339  width: 28px;
     340  height: 28px;
    192341  display: flex;
    193342  align-items: center;
    194343  justify-content: center;
    195344  padding: 0;
     345  transition: all 0.2s;
    196346}
    197347
    198348.mgwpp-item-actions button:hover {
    199   background: #d54e21;
     349  background: var(--mg-danger);
     350  border-color: var(--mg-danger);
     351  transform: scale(1.1);
    200352}
    201353
    202354.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
     386body.mgwpp-dark-mode .mgwpp-no-images {
     387  background: rgba(255, 255, 255, 0.05);
     388}
     389
     390/* =====================================================
     391   Manager Actions - Premium Buttons
     392   ===================================================== */
    209393.mgwpp-manager-actions {
    210394  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;
    220418  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
     473body.mgwpp-dark-mode .mgwpp-manager-actions .button:not(.button-primary),
     474body.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
     517body.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
     540body.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
     570body.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 */
    228598.mgwpp-preview-frame-container {
    229599  position: relative;
    230   width: 100%;
    231   height: var(--mgwpp-edit-preview-height);
    232   border-radius: var(--mgwpp-border-radius-sm);
     600  border-radius: 12px;
    233601  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);
    235605}
    236606
     
    239609  height: 100%;
    240610  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
     615body.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
     654body.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
     721body.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 {
    251852    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;
    257860  }
    258861}
    259862
    260863@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
    261877  .mgwpp-gallery-types {
    262     grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
     878    grid-template-columns: repeat(auto-fill, minmax(130px, 1fr));
    263879  }
    264880
    265881  .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
    273897  .mgwpp-manager-actions {
    274898    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  
    9494                        '<img src="' + thumbUrl + '" alt="">' +
    9595                        '<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>' +
    97100                        '</div>'
    98101                    );
     
    240243        $('.mgwpp-color-field').wpColorPicker();
    241244    }
     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    });
    242264});
  • mini-gallery/trunk/includes/admin/views/galleries/class-mgwpp-galleries-view.php

    r3438312 r3439097  
    410410                        <div class="mgwpp-form-group">
    411411                            <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'); ?>">
    413413                        </div>
    414414
     
    448448
    449449                        <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>
    454454                        </div>
    455455                    </form>
  • mini-gallery/trunk/includes/admin/views/galleries/mgwpp-galleries-view.css

    r3438312 r3439097  
    11/* Futuristic & Luxury Gallery Dashboard Styles */
    22
    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");
    44
    55.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);
    2525}
    2626
    2727body.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);
    4040}
    4141
    4242.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;
    5360}
    5461
    5562/* Background Mesh Animation */
    5663.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;
    6778}
    6879
    6980@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  }
    7287}
    7388
    7489.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;
    8499}
    85100
    86101/* Header Styles */
    87102.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);
    94109}
    95110
    96111.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);
    104119}
    105120
    106121/* Premium Buttons */
    107122.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;
    123138}
    124139
    125140.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;
    134154}
    135155
    136156.mgwpp-btn:hover::after {
    137     left: 100%;
     157  left: 100%;
    138158}
    139159
    140160.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);
    144164}
    145165
    146166.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);
    149169}
    150170
    151171.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);
    156176}
    157177
    158178body.mgwpp-dark-mode .mgwpp-btn-secondary {
    159     background: rgba(255, 255, 255, 0.05);
     179  background: rgba(255, 255, 255, 0.05);
    160180}
    161181
    162182.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);
    166186}
    167187
    168188body.mgwpp-dark-mode .mgwpp-btn-secondary:hover {
    169     background: rgba(255, 255, 255, 0.1);
     189  background: rgba(255, 255, 255, 0.1);
    170190}
    171191
    172192/* Responsive Grid Layout */
    173193.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;
    179199}
    180200
    181201/* Luxury Card Design */
    182202.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);
    190210}
    191211
    192212.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;
    208233}
    209234
    210235.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);
    214239}
    215240
    216241body.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);
    218243}
    219244
    220245.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));
    222247}
    223248
    224249.mgwpp-card-inner {
    225     display: flex;
    226     flex-direction: column;
    227     height: 100%;
     250  display: flex;
     251  flex-direction: column;
     252  height: 100%;
    228253}
    229254
    230255/* Card Header & Preview */
    231256.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;
    236261}
    237262
    238263/* Glare Effect */
    239264.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;
    256281}
    257282
    258283.mgwpp-gallery-card:hover .mgwpp-card-glare {
    259     top: -20%;
    260     left: -20%;
     284  top: -20%;
     285  left: -20%;
    261286}
    262287
    263288.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;
    268293}
    269294
    270295.mgwpp-gallery-card:hover .mgwpp-gallery-preview {
    271     transform: scale(1.05);
     296  transform: scale(1.05);
    272297}
    273298
    274299/* Overlay Actions */
    275300.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;
    289318}
    290319
    291320.mgwpp-gallery-card:hover .mgwpp-card-overlay {
    292     opacity: 1;
     321  opacity: 1;
    293322}
    294323
    295324.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);
    300329}
    301330
    302331.mgwpp-gallery-card:hover .mgwpp-overlay-actions {
    303     transform: translateY(0);
     332  transform: translateY(0);
    304333}
    305334
    306335.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;
    319348}
    320349
    321350.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;
    327356}
    328357
    329358.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;
    333362}
    334363
    335364/* Bulk Checkbox */
    336365.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;
    341370}
    342371
    343372.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;
    353382}
    354383
    355384.mgwpp-bulk-checkbox:checked {
    356     background: var(--mg-primary);
     385  background: var(--mg-primary);
    357386}
    358387
    359388.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;
    368397}
    369398
    370399/* Card Body */
    371400.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;
    377406}
    378407
    379408body.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));
    381410}
    382411
    383412.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;
    390419}
    391420
    392421.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;
    403432}
    404433
    405434.mgwpp-card-meta {
    406     margin: 15px 0;
     435  margin: 15px 0;
    407436}
    408437
    409438.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;
    415444}
    416445
    417446/* Shortcode Box - Tech Look */
    418447.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;
    427456}
    428457
    429458body.mgwpp-dark-mode .mgwpp-shortcode-box {
    430     background: rgba(0, 0, 0, 0.5);
     459  background: rgba(0, 0, 0, 0.5);
    431460}
    432461
    433462.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);
    436465}
    437466
    438467body.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);
    440469}
    441470
    442471.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;
    448477}
    449478
    450479.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;
    462491}
    463492
    464493body.mgwpp-dark-mode .mgwpp-copy-btn {
    465     background: rgba(255, 255, 255, 0.05);
     494  background: rgba(255, 255, 255, 0.05);
    466495}
    467496
    468497.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);
    473502}
    474503
    475504body.mgwpp-dark-mode .mgwpp-copy-btn:hover {
    476     color: #000;
     505  color: #000;
    477506}
    478507
     
    480509
    481510.mgwpp-preview-loader {
    482     text-align: center;
    483     padding: 100px 0;
     511  text-align: center;
     512  padding: 100px 0;
    484513}
    485514
    486515.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;
    494523}
    495524
    496525@keyframes mg-spin {
    497     to { transform: rotate(360deg); }
     526  to {
     527    transform: rotate(360deg);
     528  }
    498529}
    499530
    500531/* Bulk Actions Bar */
    501532.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);
    508539}
    509540
    510541.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;
    517548}
    518549
    519550body.mgwpp-dark-mode .mgwpp-bulk-controls select {
    520     background: #000;
    521     color: #fff;
     551  background: #000;
     552  color: #fff;
    522553}
    523554
    524555/* 3D Model Preview Enhancement */
    525556.mgwpp-3d-model-preview {
    526     background: radial-gradient(circle at center, #1a1a2a, #050505);
     557  background: radial-gradient(circle at center, #1a1a2a, #050505);
    527558}
    528559
    529560.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));
    531562}
    532563
    533564.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);
    538569}
    539570
    540571/* Custom Scrollbar for Luxury Feel */
    541572.mgwpp-premium-dashboard::-webkit-scrollbar {
    542     width: 8px;
     573  width: 8px;
    543574}
    544575.mgwpp-premium-dashboard::-webkit-scrollbar-track {
    545     background: var(--mg-bg-dark);
     576  background: var(--mg-bg-dark);
    546577}
    547578
    548579/* Modern Modal System */
    549580.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;
    560591}
    561592
     
    564595.mgwpp-modal[style*="display: flex"],
    565596.mgwpp-modal[style*="display: inline-block"] {
    566     display: flex !important;
     597  display: flex !important;
    567598}
    568599
    569600.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;
    576607}
    577608
    578609.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 */
    591623}
    592624
    593625@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  }
    596634}
    597635
    598636.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;
    605643}
    606644
    607645.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;
    614652}
    615653
    616654.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;
    631669}
    632670
    633671.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;
    637675}
    638676
    639677.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;
    645683}
    646684
    647685/* Form Styling */
    648686.mgwpp-form-group {
    649     margin-bottom: 25px;
     687  margin-bottom: 25px;
    650688}
    651689
    652690.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;
    661699}
    662700
    663701.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;
    672710}
    673711
    674712.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;
    677715}
    678716
    679717.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;
    683721}
    684722
    685723.mgwpp-select-wrapper {
    686     position: relative;
     724  position: relative;
    687725}
    688726
    689727.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;
    700738}
    701739
    702740.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);
    705743}
    706744
    707745.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;
    716754}
    717755
    718756/* Upload Zone */
    719757.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);
    724762}
    725763
    726764.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;
    738776}
    739777
    740778.mgwpp-field-hint .dashicons {
    741     font-size: 18px;
    742     width: 18px;
    743     height: 18px;
     779  font-size: 18px;
     780  width: 18px;
     781  height: 18px;
    744782}
    745783
    746784.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;
    752790}
    753791
    754792.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;
    757828}
    758829
    759830.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;
    764835}
    765836
    766837.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;
    773844}
    774845
    775846.media-thumbnail img {
    776     width: 100%;
    777     height: 100%;
    778     object-fit: cover;
     847  width: 100%;
     848  height: 100%;
     849  object-fit: cover;
    779850}
    780851
    781852.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;
    790861}
    791862
    792863.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);
    798869}
    799870
    800871.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}
    809888
    810889/* Loading State */
    811890.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);
    825904}
    826905
    827906.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;
    833912}
    834913
    835914.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;
    843922}
    844923
    845924@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  }
    848931}
    849932
    850933.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;
    853936}
    854937
    855938/* 3D Model Preview Styles */
    856939.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;
    865952}
    866953
    867954.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);
    877964}
    878965
    879966.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));
    882969}
    883970
    884971.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
    8921059/* Responsive Adjustments */
    8931060@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  
    9797                data-current-theme="<?php echo esc_attr($current_theme); ?>"
    9898                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'); ?>"
    100100                    style="font-size: 35px; width: 35px; height: 35px;"></span>
    101101            </button>
  • mini-gallery/trunk/includes/admin/views/inner-header/mgwpp-inner-header.js

    r3438312 r3439097  
    44    const loaderOverlay = $('.mgwpp-loader-overlay');
    55
     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
    610    // Apply theme from localStorage immediately on DOM ready to avoid flicker
    711    applyLocalTheme();
    812
    913    if (themeToggle.length) {
    10         const icon = themeToggle.find('img');
    11         const sunIcon = themeToggle.data('sun');
    12         const moonIcon = themeToggle.data('moon');
    13 
    1414        themeToggle.on('click', function (e) {
    1515            e.preventDefault();
     
    4343            });
    4444        });
     45    }
    4546
    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);
    5154    }
    5255
     
    5659            $('body').toggleClass('mgwpp-dark-mode', savedTheme === 'dark');
    5760            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);
    6264                themeToggle.data('current-theme', savedTheme);
    6365            }
  • mini-gallery/trunk/includes/functions/class-mgwpp-canvas-shortcode.php

    r3438312 r3439097  
    3131    }
    3232
     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
    3338    $data = MGWPP_Canvas_Post_Type::get_canvas_data($canvas_id);
    3439
     
    5257        'background' => '#ffffff'
    5358    ]);
    54    
     59
    5560    $items = isset($data['items']) ? $data['items'] : [];
    5661
    57    
     62
    5863    $slider_id = 'mgwpp-slider-' . $canvas_id;
    5964    $slider_settings = $data['slider_settings'] ?? ['autoplay' => false, 'effect' => 'slide', 'arrows' => true, 'dots' => true];
    60    
     65
    6166    // Ensure slides fallback
    6267    if (empty($data['slides'])) {
    63         $slides = [[ 'id' => 'default', 'items' => $data['items'] ?? [] ]];
     68        $slides = [['id' => 'default', 'items' => $data['items'] ?? []]];
    6469    } else {
    6570        $slides = $data['slides'];
     
    6772
    6873    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
    7479        <div class="mgwpp-slides-track">
    7580            <?php foreach ($slides as $index => $slide) : ?>
    7681                <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']); ?>;">
    7883                    <?php foreach ($slide['items'] as $item) : ?>
    7984                        <?php echo wp_kses_post(mgwpp_render_canvas_item($item, $settings)); ?>
     
    99104            </div>
    100105        <?php endif; ?>
    101        
     106
    102107        <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                        });
    131144                    }
     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);
    132172                });
    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                        });
    138184                    });
    139185                }
    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            })();
    185199        </script>
    186200    </div>
    187     <?php
     201<?php
    188202    return ob_get_clean();
    189203}
     
    192206 * Helper to format CSS values
    193207 */
    194 function mgwpp_format_css_value($val, $is_dimension = true) {
     208function mgwpp_format_css_value($val, $is_dimension = true)
     209{
    195210    if ($val === 'auto') return 'auto';
    196211    if (is_numeric($val)) {
     
    212227    // Styles calculation
    213228    $styles = [];
    214    
     229
    215230    // Position & Size
    216231    $styles[] = 'width: ' . mgwpp_format_css_value($item['width'] ?? 'auto');
     
    232247
    233248    $style_str = implode('; ', $styles) . ';';
    234    
     249
    235250    $type = $item['type'] ?? 'div';
    236251    $output = '<div class="mgwpp-canvas-item mgwpp-canvas-item-' . esc_attr($type) . '" style="' . esc_attr($style_str) . '">';
     
    238253    // Inner Content
    239254    $inner_style = 'width: 100%; height: 100%; display: block;';
    240    
     255
    241256    switch ($type) {
    242257        case 'image':
    243258            $link_start = '';
    244259            $link_end = '';
    245            
     260
    246261            if (!empty($item['link'])) {
    247262                $link_start = '<a href="' . esc_url($item['link']) . '" style="display:block;width:100%;height:100%;">';
    248263                $link_end = '</a>';
    249264            }
    250            
     265
    251266            $output .= $link_start;
    252267            $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">';
     
    286301                esc_attr($item['stroke_color'] ?? '#333')
    287302            );
    288            
     303
    289304            if (($item['shape_type'] ?? 'rectangle') === 'circle') {
    290305                $shape_style .= ' border-radius: 50%;';
    291306            }
    292            
     307
    293308            $output .= '<div class="mgwpp-canvas-shape" style="' . esc_attr($shape_style) . '"></div>';
    294309            break;
    295310
    296311        case 'container':
    297              $container_style = sprintf(
     312            $container_style = sprintf(
    298313                '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%%;',
    299314                esc_attr($item['display'] ?? 'flex'),
     
    307322                esc_attr($item['border_color'] ?? 'transparent')
    308323            );
    309            
     324
    310325            $output .= '<div class="mgwpp-canvas-container" style="' . esc_attr($container_style) . '">';
    311            
     326
    312327            // Recursive Render
    313328            if (!empty($item['children']) && is_array($item['children'])) {
    314329                // Sort by z-index
    315                 usort($item['children'], function($a, $b) {
     330                usort($item['children'], function ($a, $b) {
    316331                    return ($a['z_index'] ?? 0) - ($b['z_index'] ?? 0);
    317332                });
    318                
     333
    319334                foreach ($item['children'] as $child) {
    320335                    $output .= mgwpp_render_canvas_item($child, $settings, false); // false = not root
    321336                }
    322337            }
    323            
     338
    324339            $output .= '</div>';
    325340            break;
  • mini-gallery/trunk/includes/gallery-types/mgwpp-3d-masonry-gallery/mgwpp-3d-masonry.css

    r3438312 r3439097  
    55
    66.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;
    1919}
    2020
     
    2424
    2525.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);
    4040}
    4141
    4242.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);
    5454}
    5555
    5656.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);
    5959}
    6060
    6161.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);
    6565}
    6666
     
    7070
    7171.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%;
    8080}
    8181
    8282.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);
    8888}
    8989
     
    9393
    9494.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;
    101100}
    102101
    103102.mgwpp-masonry-column {
    104     position: relative;
    105     overflow: hidden;
    106     height: 100%;
     103  position: relative;
     104  overflow: hidden;
     105  height: 100%;
    107106}
    108107
    109108.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;
    115114}
    116115
    117116/* Direction variants */
    118117.mgwpp-masonry-column[data-direction="down"] .mgwpp-masonry-track {
    119     animation-name: mgwpp3dMasonryDown;
     118  animation-name: mgwpp3dMasonryDown;
    120119}
    121120
    122121@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  }
    125128}
    126129
    127130@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  }
    130137}
    131138
     
    135142
    136143.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;
    146152}
    147153
    148154/* Aspect ratio variations for true masonry */
    149155.mgwpp-masonry-item.aspect-portrait {
    150     aspect-ratio: 3 / 4;
     156  aspect-ratio: 3 / 4;
    151157}
    152158
    153159.mgwpp-masonry-item.aspect-square {
    154     aspect-ratio: 1 / 1;
     160  aspect-ratio: 1 / 1;
    155161}
    156162
    157163.mgwpp-masonry-item.aspect-landscape {
    158     aspect-ratio: 4 / 3;
     164  aspect-ratio: 4 / 3;
    159165}
    160166
    161167.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;
    168173}
    169174
    170175/* Hover overlay */
    171176.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;
    178183}
    179184
    180185/* Hover Effects */
    181186.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);
    186191}
    187192
    188193.mgwpp-masonry-item:hover img {
    189     transform: scale(1.15);
     194  transform: scale(1.15);
    190195}
    191196
    192197.mgwpp-masonry-item:hover .mgwpp-item-overlay {
    193     opacity: 1;
     198  opacity: 1;
    194199}
    195200
     
    200205/* WALL MODE - Slight vertical tilt */
    201206.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);
    203208}
    204209
    205210.mgwpp-3d-masonry-gallery[data-mode="wall"] .mgwpp-masonry-columns {
    206     transform: scale(0.9);
     211  transform: scale(0.9);
    207212}
    208213
    209214/* TABLE MODE - Floor/table perspective */
    210215.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);
    212218}
    213219
    214220.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);
    216222}
    217223
    218224/* TUNNEL MODE - Immersive tunnel effect */
    219225.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);
    221227}
    222228
    223229.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);
    229236}
    230237
    231238.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);
    241250}
    242251
    243252/* FLAT MODE - Traditional masonry */
    244253.mgwpp-3d-masonry-gallery[data-mode="flat"] .mgwpp-3d-perspective-wrap {
    245     transform: none;
    246     perspective: none;
     254  transform: none;
     255  perspective: none;
    247256}
    248257
    249258.mgwpp-3d-masonry-gallery[data-mode="flat"] .mgwpp-masonry-columns {
    250     transform: none;
     259  transform: none;
    251260}
    252261
    253262.mgwpp-3d-masonry-gallery[data-mode="flat"] .mgwpp-masonry-item:hover {
    254     transform: scale(1.05);
     263  transform: scale(1.05);
    255264}
    256265
     
    260269
    261270.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;
    265274}
    266275
    267276.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  );
    277288}
    278289
    279290.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  );
    288301}
    289302
    290303.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  );
    299314}
    300315
    301316.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  );
    310327}
    311328
     
    315332
    316333.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);
    336353}
    337354
    338355.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);
    341358}
    342359
    343360.mgwpp-3d-pause-btn:focus {
    344     outline: 2px solid #3b82f6;
    345     outline-offset: 2px;
     361  outline: 2px solid #3b82f6;
     362  outline-offset: 2px;
    346363}
    347364
     
    351368
    352369.mgwpp-3d-masonry-gallery[data-pause-hover="true"]:hover .mgwpp-masonry-track {
    353     animation-play-state: paused;
     370  animation-play-state: paused;
    354371}
    355372
    356373.mgwpp-3d-masonry-gallery.is-paused .mgwpp-masonry-track {
    357     animation-play-state: paused;
     374  animation-play-state: paused;
    358375}
    359376
    360377/* Grayscale Mode */
    361378.mgwpp-3d-masonry-gallery[data-grayscale="true"] .mgwpp-masonry-item img {
    362     filter: grayscale(100%);
     379  filter: grayscale(100%);
    363380}
    364381
    365382.mgwpp-3d-masonry-gallery[data-grayscale="true"] .mgwpp-masonry-item:hover img {
    366     filter: grayscale(0%);
     383  filter: grayscale(0%);
    367384}
    368385
     
    372389
    373390@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  }
    387404}
    388405
     
    392409
    393410@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  }
    406423}
    407424
    408425@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  }
    449466}
    450467
    451468@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  }
    463480}
    464481
     
    468485
    469486.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  
    1111        // Only run if capabilities haven't been added yet (check stored version)
    1212        $cap_version = get_option('mgwpp_gallery_cap_version', '0');
    13         $current_version = '1.6'; // Update this when capabilities change
     13        $current_version = '1.6.1'; // Update this when capabilities change
    1414
    1515        if ($cap_version === $current_version) {
     
    1717        }
    1818
    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');
    3937        }
    4038
     
    4240        update_option('mgwpp_gallery_cap_version', $current_version);
    4341    }
     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    }
    4459}
    4560
  • mini-gallery/trunk/mini-gallery.php

    r3438312 r3439097  
    44Plugin URI: https://wordpress.org/plugins/mini-gallery/
    55Description: 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
     6Version: 1.6.1
    77Author: AGWS | And Go Web Solutions
    88Author URI: https://andgowebsolutions.com
     
    2424
    2525// Plugin constants
     26define('MG_VERSION', '1.6.1');
    2627define('MG_PLUGIN_PATH', plugin_dir_path(__FILE__));
    2728define('MG_PLUGIN_URL', plugins_url('', __FILE__));
  • mini-gallery/trunk/readme.txt

    r3438312 r3439097  
    11=== Mini Gallery ===
    22Contributors: @omarashzeinhom
    3 Tags: gallery, carousel, slider, 3d, elementor
     3Tags: gallery, carousel, slider, 3d, shortcode
    44Requires at least: 6.0
    55Tested up to: 6.9
    6 Version: 1.6
    7 Stable tag: 1.6
     6Version: 1.6.1
     7Stable tag: 1.6.1
    88Requires PHP: 8.0
    99License: GPLv2 or later
    1010License URI: https://www.gnu.org/licenses/gpl-2.0.html
    1111
    12 A lightweight and flexible WordPress gallery plugin, now with Elementor support and 12 gallery types including 3D model viewer.
     12A lightweight and flexible WordPress gallery plugin with 17 gallery types including 3D model viewer. Works with any theme using simple shortcodes.
    1313
    1414== Description ==
    1515
    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.
    1717
    1818**New in Version 1.6:**
     
    434317. **Canvas Editor** - Visual drag-and-drop gallery builder
    4444
    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
    4950
    5051**Visual Canvas Editor:**
     
    95961. Upload the plugin folder to `/wp-content/plugins/`.
    96972. 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.
     983. Navigate to Gallery > Add New to create your first gallery.
     994. Select a gallery type, add images from your Media Library.
     1005. Copy the shortcode `[mgwpp_gallery id="X"]` and paste it anywhere in your site.
     1016. For 3D models: Upload GLTF/GLB files through Media Library and select "3D Model Carousel" as gallery type.
    99102
    100103== 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
    101115
    102116= 1.6 =
     
    135149  11. Testimonial Carousel - [Demo](https://minigallery.andgowebsolutions.com/gallery/testimonials-carousel/)
    136150  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.
    138152- Launched new website: [https://minigallery.andgowebsolutions.com](https://minigallery.andgowebsolutions.com)
    139153- Live demo available at homepage.
     
    149163== Frequently Asked Questions ==
    150164
    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? =
     166Yes! 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.
    153167
    154168= How many gallery types are available? =
    155 There are now 12 gallery types included with Mini Gallery 1.6.
     169There are 17 gallery types included with Mini Gallery 1.6, all accessible via the simple shortcode `[mgwpp_gallery id="X"]`.
    156170
    157171= What 3D file formats are supported? =
Note: See TracChangeset for help on using the changeset viewer.