<?php
/**
 * Block CSS Generator
 *
 * ブロック属性からMD/TB/SP用のCSS変数を抽出し、
 * キャッシュ可能なCSSファイルを生成する
 */

if (!defined('ABSPATH')) {
    exit;
}

class ZenBlocks_Block_CSS_Generator {

    private $breakpoints;
    private $upload_dir;
    private $css_dir;

    public function __construct() {
        $this->upload_dir = wp_upload_dir();
        $this->upload_dir['baseurl'] = set_url_scheme($this->upload_dir['baseurl']);
        $this->css_dir = $this->upload_dir['basedir'] . '/zenblocks/blocks/';

        // Create directory if not exists
        if (!file_exists($this->css_dir)) {
            wp_mkdir_p($this->css_dir);
        }

    }

    /**
     * Initialize with breakpoints
     */
    public function init($breakpoints) {
        $this->breakpoints = $breakpoints;
    }

    /**
     * Debug log helper（WP_DEBUG有効時のみerror_logに出力）
     */
    private function debug_log($message) {
        if (defined('WP_DEBUG') && WP_DEBUG) {
            // phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log -- Debug logging only when WP_DEBUG is enabled
            error_log('[ZenBlocks] ' . $message);
        }
    }

    /**
     * Generate CSS file for a post
     */
    public function generate_post_css($post_id) {
        $this->debug_log("generate_post_css called for post {$post_id}");

        $post = get_post($post_id);
        if (!$post || !has_blocks($post->post_content)) {
            $this->delete_css_file($post_id);
            $this->debug_log("No blocks found in post {$post_id}");
            return false;
        }

        $blocks = parse_blocks($post->post_content);
        $this->debug_log("Found " . count($blocks) . " blocks in post {$post_id}");

        // Log block names for debugging
        foreach ($blocks as $block) {
            $this->debug_log("Block found: " . ($block['blockName'] ?? 'null'));
        }

        $css = $this->extract_block_css($blocks);
        $this->debug_log("Generated CSS length: " . strlen($css));

        if (empty(trim($css))) {
            $this->delete_css_file($post_id);
            $this->debug_log("No CSS generated for post {$post_id}");
            return false;
        }

        $result = $this->save_css_file($post_id, $css);
        $this->debug_log("CSS file saved: " . ($result ? 'success' : 'failed'));
        return $result;
    }

    /**
     * Extract CSS from blocks recursively
     */
    private function extract_block_css($blocks) {
        $css = '';

        foreach ($blocks as $block) {
            // Process zenblocks blocks
            if (strpos($block['blockName'], 'zenblocks/') === 0) {
                $css .= $this->get_block_css($block);
            }

            // Process inner blocks
            if (!empty($block['innerBlocks'])) {
                $css .= $this->extract_block_css($block['innerBlocks']);
            }
        }

        return $css;
    }

    /**
     * Get CSS for a single block
     */
    private function get_block_css($block) {
        $attrs = $block['attrs'] ?? array();
        $unique_id = $attrs['uniqueId'] ?? '';

        $this->debug_log("Processing block: " . $block['blockName'] . ", uniqueId: " . $unique_id);
        $this->debug_log("Block attributes: " . json_encode($attrs));

        if (empty($unique_id)) {
            $this->debug_log("No uniqueId found for block");
            return '';
        }

        $css = '';
        $block_name = str_replace('zenblocks/', '', $block['blockName']);

        // Get spacing CSS
        $css .= $this->get_spacing_css($attrs, $unique_id, $block_name);

        // Get font size CSS
        $css .= $this->get_font_size_css($attrs, $unique_id, $block_name);

        // Get line height CSS (includes text-main-height)
        $css .= $this->get_line_height_css($attrs, $unique_id);

        // Get letter spacing CSS
        $css .= $this->get_letter_spacing_css($attrs, $unique_id);

        // Get in-button micro text CSS (microText* / --micro-text-*)
        $css .= $this->get_micro_text_css($attrs, $unique_id);

        // Get copy-micro text CSS (copyMicro* / --copy-micro-*)
        $css .= $this->get_copy_micro_text_css($attrs, $unique_id);

        // Get micro border CSS (copy-micro border width, style, color, radius)
        $css .= $this->get_micro_border_css($attrs, $unique_id);

        // Get sub text CSS (copy-sub margin, padding, font-size, font-weight, letter-spacing, line-height)
        $css .= $this->get_sub_text_css($attrs, $unique_id);

        // Get icon size CSS
        $css .= $this->get_icon_size_css($attrs, $unique_id);

        // Get icon position CSS
        $css .= $this->get_icon_position_css($attrs, $unique_id);

        // Get icon color CSS
        $css .= $this->get_icon_color_css($attrs, $unique_id);

        // Get background color CSS
        $css .= $this->get_background_color_css($attrs, $unique_id);

        // Get background base color CSS
        $css .= $this->get_background_base_color_css($attrs, $unique_id);

        // Get background image CSS
        $css .= $this->get_background_image_css($attrs, $unique_id);

        // Get background pattern CSS
        $css .= $this->get_background_pattern_css($attrs, $unique_id);

        // Get border CSS
        $css .= $this->get_border_css($attrs, $unique_id);

        // Get radius CSS
        $css .= $this->get_radius_css($attrs, $unique_id);

        // Get shadow CSS
        $css .= $this->get_shadow_css($attrs, $unique_id);

        // Get inner shadow CSS
        $css .= $this->get_inner_shadow_css($attrs, $unique_id);

        // Get opacity CSS
        $css .= $this->get_opacity_css($attrs, $unique_id);

        // Get icon frame CSS
        $css .= $this->get_icon_frame_css($attrs, $unique_id);

        // Get layout width CSS
        $css .= $this->get_layout_width_css($attrs, $unique_id);

        // Get layout height CSS
        $css .= $this->get_layout_height_css($attrs, $unique_id);

        // Get layout position CSS
        $css .= $this->get_layout_position_css($attrs, $unique_id);

        // Get band CSS
        $css .= $this->get_band_css($attrs, $unique_id);

        // Get thumbnail CSS
        $css .= $this->get_thumbnail_css($attrs, $unique_id);

        $this->debug_log("Block CSS length: " . strlen($css));
        $this->debug_log("Block CSS content: " . $css);
        return $css;
    }

    /**
     * Get spacing CSS variables for MD/TB/SP
     */
    private function get_spacing_css($attrs, $unique_id, $block_name) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');
        $this->debug_log("Enabled breakpoints: " . json_encode($enabled_bps));

        // Only process MD/TB/SP (skip PC)
        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        $this->debug_log("Responsive breakpoints (excluding PC): " . json_encode(array_values($responsive_bps)));

        if (empty($responsive_bps)) {
            $this->debug_log("No responsive breakpoints enabled");
            return '';
        }

        $padding_data = $attrs['paddingV2'] ?? null;
        $margin_data = $attrs['marginV2'] ?? null;

        $this->debug_log("Padding data: " . json_encode($padding_data));
        $this->debug_log("Margin data: " . json_encode($margin_data));

        if (!$padding_data && !$margin_data) {
            $this->debug_log("No padding or margin data found");
            return '';
        }

        $positions = array('top', 'right', 'bottom', 'left');
        $selector = ".zenblocks-{$unique_id}";

        // Group CSS by breakpoint
        $bp_css = array();

        foreach ($responsive_bps as $bp) {
            $bp_vars = array();

            // Padding
            if ($padding_data && isset($padding_data[$bp])) {
                foreach ($positions as $pos) {
                    $value = $this->get_spacing_value($padding_data[$bp], $pos);
                    if ($value !== null) {
                        $bp_vars[] = "--spacing-padding-{$pos}-{$bp}: {$value}";
                    }
                }
            }

            // Margin
            if ($margin_data && isset($margin_data[$bp])) {
                foreach ($positions as $pos) {
                    $value = $this->get_spacing_value($margin_data[$bp], $pos);
                    if ($value !== null) {
                        $bp_vars[] = "--spacing-margin-{$pos}-{$bp}: {$value}";
                    }
                }
            }

            if (!empty($bp_vars)) {
                $bp_css[$bp] = $bp_vars;
            }
        }

        // Generate CSS with media queries
        if (!empty($bp_css)) {
            $css .= "/* Block: {$unique_id} */\n";
            $css .= "{$selector} {\n";
            foreach ($bp_css as $bp => $vars) {
                $css .= "  " . implode(";\n  ", $vars) . ";\n";
            }
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Get spacing value from data
     */
    private function get_spacing_value($bp_data, $position) {
        if (!$bp_data) {
            return null;
        }

        $use_individual = $bp_data['useIndividual'] ?? false;

        if ($use_individual) {
            $unit = $bp_data["{$position}Unit"] ?? 'px';
            if ($unit === 'auto') {
                return 'auto';
            }
            $value = $bp_data[$position] ?? null;
            if ($value !== '' && $value !== null) {
                return "{$value}{$unit}";
            }
        } else {
            $bulk_unit = $bp_data['bulkUnit'] ?? 'px';
            if ($bulk_unit === 'auto') {
                return 'auto';
            }
            $bulk_value = $bp_data['bulk'] ?? null;
            if ($bulk_value !== '' && $bulk_value !== null) {
                return "{$bulk_value}{$bulk_unit}";
            }
        }

        return null;
    }

    /**
     * Get font size CSS variables for MD/TB/SP
     */
    private function get_font_size_css($attrs, $unique_id, $block_name) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        // Only process MD/TB/SP (skip PC)
        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $font_size_data = $attrs['fontSizeV2'] ?? null;
        $font_size_hover_data = $attrs['fontSizeV2Hover'] ?? null;
        $responsive_enabled = $attrs['useResponsiveFontSize'] ?? false;
        $responsive_hover_enabled = $attrs['useResponsiveFontSizeHover'] ?? false;

        if (!$font_size_data && !$font_size_hover_data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();

        // Get PC value for fallback
        $pc_value = $this->get_font_size_value($font_size_data, 'pc', true);
        $pc_hover_value = $this->get_font_size_value($font_size_hover_data, 'pc', false);

        foreach ($responsive_bps as $bp) {
            // Normal font size (with inheritance/fallback)
            if ($font_size_data) {
                $value = $this->get_font_size_value_with_inheritance($font_size_data, $bp, $enabled_bps);
                if ($value) {
                    $bp_vars[] = "--font-size-{$bp}: {$value}";
                } elseif ($pc_value) {
                    // Fallback to PC value
                    $bp_vars[] = "--font-size-{$bp}: {$pc_value}";
                }
            }

            // Hover font size (with inheritance/fallback)
            if ($font_size_hover_data) {
                $hover_value = $this->get_font_size_value_with_inheritance($font_size_hover_data, $bp, $enabled_bps);
                if ($hover_value) {
                    $bp_vars[] = "--font-size-{$bp}-hover: {$hover_value}";
                } elseif ($pc_hover_value) {
                    // Fallback to PC hover value
                    $bp_vars[] = "--font-size-{$bp}-hover: {$pc_hover_value}";
                }
            }
        }

        // Generate CSS
        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Get font size value from V2 data
     */
    private function get_font_size_value($font_size_data, $bp, $use_default = false) {
        if (!$font_size_data || !isset($font_size_data[$bp])) {
            return $use_default ? '1rem' : null;
        }

        $bp_data = $font_size_data[$bp];
        $preset = $bp_data['preset'] ?? null;
        $custom = $bp_data['custom'] ?? null;
        $unit = $bp_data['unit'] ?? 'px';

        if ($preset === 'custom' && $custom) {
            return "{$custom}{$unit}";
        } elseif ($preset && $preset !== '' && $preset !== 'custom') {
            if (strpos($preset, 'preset:') === 0) {
                $slug = str_replace('preset:', '', $preset);
                return "var(--wp--preset--font-size--{$slug})";
            }
            return "{$preset}{$unit}";
        }

        return $use_default ? '1rem' : null;
    }

    /**
     * Get font size value with inheritance (fallback to larger breakpoints)
     */
    private function get_font_size_value_with_inheritance($font_size_data, $target_bp, $enabled_bps) {
        if (!$font_size_data) {
            return null;
        }

        $target_index = array_search($target_bp, $enabled_bps);
        if ($target_index === false) {
            return null;
        }

        // Search from target BP to PC (index 0)
        for ($i = $target_index; $i >= 0; $i--) {
            $bp = $enabled_bps[$i];
            $value = $this->get_font_size_value($font_size_data, $bp, false);
            if ($value) {
                return $value;
            }
        }

        return null;
    }

    /**
     * Get value from {value, unit} breakpoint data (used by line-height, letter-spacing)
     */
    private function get_value_unit_bp($data, $bp, $default_unit = '') {
        if (!$data || !isset($data[$bp])) {
            return null;
        }

        $bp_data = $data[$bp];
        $value = $bp_data['value'] ?? null;
        $unit = $bp_data['unit'] ?? $default_unit;

        if ($value && $value !== '' && $value !== 'custom') {
            return $value . $unit;
        }

        return null;
    }

    /**
     * Get value from {value, unit} data with inheritance (fallback to larger breakpoints)
     */
    private function get_value_unit_with_inheritance($data, $target_bp, $enabled_bps, $default_unit = '') {
        if (!$data) {
            return null;
        }

        $target_index = array_search($target_bp, $enabled_bps);
        if ($target_index === false) {
            return null;
        }

        for ($i = $target_index; $i >= 0; $i--) {
            $bp = $enabled_bps[$i];
            $value = $this->get_value_unit_bp($data, $bp, $default_unit);
            if ($value) {
                return $value;
            }
        }

        return null;
    }

    /**
     * Get line height CSS variables for MD/TB/SP (includes text-main-height)
     */
    private function get_line_height_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $line_height_data = $attrs['lineHeightV2'] ?? null;
        $line_height_hover_data = $attrs['lineHeightV2Hover'] ?? null;

        if (!$line_height_data && !$line_height_hover_data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();

        $pc_value = $this->get_value_unit_bp($line_height_data, 'pc', '');
        $pc_hover_value = $this->get_value_unit_bp($line_height_hover_data, 'pc', '');

        foreach ($responsive_bps as $bp) {
            // Normal line height
            if ($line_height_data) {
                $value = $this->get_value_unit_with_inheritance($line_height_data, $bp, $enabled_bps, '');
                if ($value) {
                    $bp_vars[] = "--line-height-{$bp}: {$value}";
                    $bp_vars[] = "--text-main-height-{$bp}: {$value}em";
                } elseif ($pc_value) {
                    $bp_vars[] = "--line-height-{$bp}: {$pc_value}";
                    $bp_vars[] = "--text-main-height-{$bp}: {$pc_value}em";
                }
            }

            // Hover line height
            if ($line_height_hover_data) {
                $hover_value = $this->get_value_unit_with_inheritance($line_height_hover_data, $bp, $enabled_bps, '');
                if ($hover_value) {
                    $bp_vars[] = "--line-height-{$bp}-hover: {$hover_value}";
                } elseif ($pc_hover_value) {
                    $bp_vars[] = "--line-height-{$bp}-hover: {$pc_hover_value}";
                }
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Get letter spacing CSS variables for MD/TB/SP
     */
    private function get_letter_spacing_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $letter_spacing_data = $attrs['letterSpacingV2'] ?? null;
        $letter_spacing_hover_data = $attrs['letterSpacingV2Hover'] ?? null;

        if (!$letter_spacing_data && !$letter_spacing_hover_data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();

        $pc_value = $this->get_value_unit_bp($letter_spacing_data, 'pc', 'px');
        $pc_hover_value = $this->get_value_unit_bp($letter_spacing_hover_data, 'pc', 'px');

        foreach ($responsive_bps as $bp) {
            // Normal letter spacing
            if ($letter_spacing_data) {
                $value = $this->get_value_unit_with_inheritance($letter_spacing_data, $bp, $enabled_bps, 'px');
                if ($value) {
                    $bp_vars[] = "--letter-spacing-{$bp}: {$value}";
                } elseif ($pc_value) {
                    $bp_vars[] = "--letter-spacing-{$bp}: {$pc_value}";
                }
            }

            // Hover letter spacing
            if ($letter_spacing_hover_data) {
                $hover_value = $this->get_value_unit_with_inheritance($letter_spacing_hover_data, $bp, $enabled_bps, 'px');
                if ($hover_value) {
                    $bp_vars[] = "--letter-spacing-{$bp}-hover: {$hover_value}";
                } elseif ($pc_hover_value) {
                    $bp_vars[] = "--letter-spacing-{$bp}-hover: {$pc_hover_value}";
                }
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Get in-button micro text CSS variables for MD/TB/SP
     * Handles: margin, padding, rotate, font-size, font-weight, letter-spacing, line-height
     * For the in-button micro text area (.wp-block-zenblocks-button-basic-text-micro)
     * Uses microText* attributes and --micro-text-* CSS variables
     */
    private function get_micro_text_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $margin_data = $attrs['microTextMarginV2'] ?? null;
        $padding_data = $attrs['microTextPaddingV2'] ?? null;
        $rotate_data = $attrs['microTextRotateV2'] ?? null;
        $font_size_data = $attrs['microTextFontSizeV2'] ?? null;
        $font_weight_data = $attrs['microTextFontWeightV2'] ?? null;
        $letter_spacing_data = $attrs['microTextLetterSpacingV2'] ?? null;
        $line_height_data = $attrs['microTextLineHeightV2'] ?? null;

        if (!$margin_data && !$padding_data && !$rotate_data && !$font_size_data && !$font_weight_data && !$letter_spacing_data && !$line_height_data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();
        $positions = array('top', 'right', 'bottom', 'left');

        foreach ($responsive_bps as $bp) {
            // Margin
            if ($margin_data && isset($margin_data[$bp])) {
                foreach ($positions as $pos) {
                    $value = $this->get_spacing_value($margin_data[$bp], $pos);
                    if ($value !== null) {
                        $bp_vars[] = "--micro-text-margin-{$pos}-{$bp}: {$value}";
                    }
                }
            }

            // Padding
            if ($padding_data && isset($padding_data[$bp])) {
                foreach ($positions as $pos) {
                    $value = $this->get_spacing_value($padding_data[$bp], $pos);
                    if ($value !== null) {
                        $bp_vars[] = "--micro-text-padding-{$pos}-{$bp}: {$value}";
                    }
                }
            }

            // Rotate
            if ($rotate_data && isset($rotate_data[$bp])) {
                $val = $rotate_data[$bp];
                if ($val !== '' && $val !== null) {
                    $bp_vars[] = "--micro-text-rotate-{$bp}: {$val}deg";
                }
            }

            // Font size (uses {preset, custom, unit} format)
            if ($font_size_data) {
                $value = $this->get_font_size_value($font_size_data, $bp, false);
                if ($value) {
                    $bp_vars[] = "--micro-text-font-size-{$bp}: {$value}";
                }
            }

            // Font weight (simple string)
            if ($font_weight_data && isset($font_weight_data[$bp])) {
                $val = $font_weight_data[$bp];
                if ($val !== '' && $val !== null) {
                    $bp_vars[] = "--micro-text-font-weight-{$bp}: {$val}";
                }
            }

            // Letter spacing (uses {value, unit} format)
            if ($letter_spacing_data) {
                $value = $this->get_value_unit_bp($letter_spacing_data, $bp, 'em');
                if ($value) {
                    $bp_vars[] = "--micro-text-letter-spacing-{$bp}: {$value}";
                }
            }

            // Line height (uses {value, unit} format)
            if ($line_height_data) {
                $value = $this->get_value_unit_bp($line_height_data, $bp, '');
                if ($value) {
                    $bp_vars[] = "--micro-text-line-height-{$bp}: {$value}";
                }
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Get copy-micro text CSS variables for MD/TB/SP
     * Handles: margin, padding, rotate, font-size, font-weight, letter-spacing, line-height
     * For the above-button copy-micro area (.wp-block-zenblocks-button-basic-copy-micro)
     * Uses copyMicro* attributes and --copy-micro-* CSS variables
     */
    private function get_copy_micro_text_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $margin_data = $attrs['copyMicroMarginV2'] ?? null;
        $padding_data = $attrs['copyMicroPaddingV2'] ?? null;
        $rotate_data = $attrs['copyMicroRotateV2'] ?? null;
        $font_size_data = $attrs['copyMicroFontSizeV2'] ?? null;
        $font_weight_data = $attrs['copyMicroFontWeightV2'] ?? null;
        $letter_spacing_data = $attrs['copyMicroLetterSpacingV2'] ?? null;
        $line_height_data = $attrs['copyMicroLineHeightV2'] ?? null;

        if (!$margin_data && !$padding_data && !$rotate_data && !$font_size_data && !$font_weight_data && !$letter_spacing_data && !$line_height_data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();
        $positions = array('top', 'right', 'bottom', 'left');

        foreach ($responsive_bps as $bp) {
            // Margin
            if ($margin_data && isset($margin_data[$bp])) {
                foreach ($positions as $pos) {
                    $value = $this->get_spacing_value($margin_data[$bp], $pos);
                    if ($value !== null) {
                        $bp_vars[] = "--copy-micro-margin-{$pos}-{$bp}: {$value}";
                    }
                }
            }

            // Padding
            if ($padding_data && isset($padding_data[$bp])) {
                foreach ($positions as $pos) {
                    $value = $this->get_spacing_value($padding_data[$bp], $pos);
                    if ($value !== null) {
                        $bp_vars[] = "--copy-micro-padding-{$pos}-{$bp}: {$value}";
                    }
                }
            }

            // Rotate
            if ($rotate_data && isset($rotate_data[$bp])) {
                $val = $rotate_data[$bp];
                if ($val !== '' && $val !== null) {
                    $bp_vars[] = "--copy-micro-rotate-{$bp}: {$val}deg";
                }
            }

            // Font size (uses {preset, custom, unit} format)
            if ($font_size_data) {
                $value = $this->get_font_size_value($font_size_data, $bp, false);
                if ($value) {
                    $bp_vars[] = "--copy-micro-font-size-{$bp}: {$value}";
                }
            }

            // Font weight (simple string)
            if ($font_weight_data && isset($font_weight_data[$bp])) {
                $val = $font_weight_data[$bp];
                if ($val !== '' && $val !== null) {
                    $bp_vars[] = "--copy-micro-font-weight-{$bp}: {$val}";
                }
            }

            // Letter spacing (uses {value, unit} format)
            if ($letter_spacing_data) {
                $value = $this->get_value_unit_bp($letter_spacing_data, $bp, 'em');
                if ($value) {
                    $bp_vars[] = "--copy-micro-letter-spacing-{$bp}: {$value}";
                }
            }

            // Line height (uses {value, unit} format)
            if ($line_height_data) {
                $value = $this->get_value_unit_bp($line_height_data, $bp, '');
                if ($value) {
                    $bp_vars[] = "--copy-micro-line-height-{$bp}: {$value}";
                }
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Get micro border CSS variables for MD/TB/SP
     * Handles: copyMicroBorderV2 (width, style, color), copyMicroBorderRadiusV2
     * Note: border-radius-pc is also output here since save.js doesn't output it with -pc suffix
     */
    private function get_micro_border_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $border_data = $attrs['copyMicroBorderV2'] ?? null;
        $radius_data = $attrs['copyMicroBorderRadiusV2'] ?? null;

        if (!$border_data && !$radius_data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();

        // Output border-radius-pc from PHP since save.js doesn't output it with -pc suffix
        // This is needed for the responsive CSS fallback chain
        if ($radius_data) {
            $pc_value = $this->get_value_unit_bp($radius_data, 'pc', 'px');
            if ($pc_value) {
                $bp_vars[] = "--copy-micro-border-radius-pc: {$pc_value}";
            }
        }

        foreach ($responsive_bps as $bp) {
            // Border width, style, color
            if ($border_data && isset($border_data[$bp])) {
                $bp_border = $border_data[$bp];

                if (isset($bp_border['width']) && $bp_border['width'] !== '' && $bp_border['width'] !== null) {
                    $bp_vars[] = "--copy-micro-border-width-{$bp}: {$bp_border['width']}px";
                }
                if (!empty($bp_border['style'])) {
                    $bp_vars[] = "--copy-micro-border-style-{$bp}: {$bp_border['style']}";
                }
                if (!empty($bp_border['color'])) {
                    $bp_vars[] = "--copy-micro-border-color-{$bp}: {$bp_border['color']}";
                }
            }

            // Border radius (uses {value, unit} format)
            if ($radius_data) {
                $value = $this->get_value_unit_bp($radius_data, $bp, 'px');
                if ($value) {
                    $bp_vars[] = "--copy-micro-border-radius-{$bp}: {$value}";
                }
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Get copy-sub text CSS variables for MD/TB/SP
     * Handles: margin, padding, font-size, font-weight, letter-spacing, line-height
     * For the below-button copy-sub area (.wp-block-zenblocks-button-basic-copy-sub)
     * Uses copySub* attributes and --copy-sub-* CSS variables
     */
    private function get_sub_text_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $margin_data = $attrs['copySubMarginV2'] ?? null;
        $padding_data = $attrs['copySubPaddingV2'] ?? null;
        $font_size_data = $attrs['copySubFontSizeV2'] ?? null;
        $font_weight_data = $attrs['copySubFontWeightV2'] ?? null;
        $letter_spacing_data = $attrs['copySubLetterSpacingV2'] ?? null;
        $line_height_data = $attrs['copySubLineHeightV2'] ?? null;

        if (!$margin_data && !$padding_data && !$font_size_data && !$font_weight_data && !$letter_spacing_data && !$line_height_data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();
        $positions = array('top', 'right', 'bottom', 'left');

        foreach ($responsive_bps as $bp) {
            // Margin
            if ($margin_data && isset($margin_data[$bp])) {
                foreach ($positions as $pos) {
                    $value = $this->get_spacing_value($margin_data[$bp], $pos);
                    if ($value !== null) {
                        $bp_vars[] = "--copy-sub-margin-{$pos}-{$bp}: {$value}";
                    }
                }
            }

            // Padding
            if ($padding_data && isset($padding_data[$bp])) {
                foreach ($positions as $pos) {
                    $value = $this->get_spacing_value($padding_data[$bp], $pos);
                    if ($value !== null) {
                        $bp_vars[] = "--copy-sub-padding-{$pos}-{$bp}: {$value}";
                    }
                }
            }

            // Font size (uses {preset, custom, unit} format)
            if ($font_size_data) {
                $value = $this->get_font_size_value($font_size_data, $bp, false);
                if ($value) {
                    $bp_vars[] = "--copy-sub-font-size-{$bp}: {$value}";
                }
            }

            // Font weight (simple string)
            if ($font_weight_data && isset($font_weight_data[$bp])) {
                $val = $font_weight_data[$bp];
                if ($val !== '' && $val !== null) {
                    $bp_vars[] = "--copy-sub-font-weight-{$bp}: {$val}";
                }
            }

            // Letter spacing (uses {value, unit} format)
            if ($letter_spacing_data) {
                $value = $this->get_value_unit_bp($letter_spacing_data, $bp, 'em');
                if ($value) {
                    $bp_vars[] = "--copy-sub-letter-spacing-{$bp}: {$value}";
                }
            }

            // Line height (uses {value, unit} format)
            if ($line_height_data) {
                $value = $this->get_value_unit_bp($line_height_data, $bp, '');
                if ($value) {
                    $bp_vars[] = "--copy-sub-line-height-{$bp}: {$value}";
                }
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Get icon size CSS variables for MD/TB/SP
     */
    private function get_icon_size_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        // Only process MD/TB/SP (skip PC)
        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $icon_size_data = $attrs['iconSizeV2'] ?? null;
        $icon_size_hover_data = $attrs['iconSizeV2Hover'] ?? null;

        if (!$icon_size_data && !$icon_size_hover_data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();

        foreach ($responsive_bps as $bp) {
            // Normal icon size
            if ($icon_size_data) {
                $value = $this->get_v2_value_with_inheritance($icon_size_data, $bp, 'value', $enabled_bps);
                $unit = $this->get_v2_value_with_inheritance($icon_size_data, $bp, 'unit', $enabled_bps, 'px');
                if ($value !== null && $value !== '') {
                    $bp_vars[] = "--icon-size-{$bp}: {$value}{$unit}";
                }
            }

            // Hover icon size (with fallback to normal)
            $hover_value = $this->get_v2_value_with_inheritance($icon_size_hover_data, $bp, 'value', $enabled_bps);
            $hover_unit = $this->get_v2_value_with_inheritance($icon_size_hover_data, $bp, 'unit', $enabled_bps, 'px');
            if ($hover_value === null || $hover_value === '') {
                // Fallback to normal
                if ($icon_size_data) {
                    $hover_value = $this->get_v2_value_with_inheritance($icon_size_data, $bp, 'value', $enabled_bps);
                    $hover_unit = $this->get_v2_value_with_inheritance($icon_size_data, $bp, 'unit', $enabled_bps, 'px');
                }
            }
            if ($hover_value !== null && $hover_value !== '') {
                $bp_vars[] = "--icon-size-{$bp}-hover: {$hover_value}{$hover_unit}";
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Get icon position CSS variables for MD/TB/SP
     */
    private function get_icon_position_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $data = $attrs['iconPositionV2'] ?? null;
        $hover_data = $attrs['iconPositionV2Hover'] ?? null;

        if (!$data && !$hover_data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();

        foreach ($responsive_bps as $bp) {
            // Normal
            if ($data) {
                $gap = $this->get_v2_value_with_inheritance($data, $bp, 'gap', $enabled_bps);
                $gap_unit = $this->get_v2_value_with_inheritance($data, $bp, 'gapUnit', $enabled_bps, 'px');
                if ($gap !== null && $gap !== '') {
                    $bp_vars[] = "--icon-gap-{$bp}: {$gap}{$gap_unit}";
                }

                // Origin-based positioning
                $origin_x = $this->get_v2_value_with_inheritance($data, $bp, 'originX', $enabled_bps, 'center');
                $origin_y = $this->get_v2_value_with_inheritance($data, $bp, 'originY', $enabled_bps, 'center');
                $offset_x = $this->get_v2_value_with_inheritance($data, $bp, 'offsetX', $enabled_bps, 0);
                $offset_y = $this->get_v2_value_with_inheritance($data, $bp, 'offsetY', $enabled_bps, 0);
                $offset_x_unit = $this->get_v2_value_with_inheritance($data, $bp, 'offsetXUnit', $enabled_bps, '%');
                $offset_y_unit = $this->get_v2_value_with_inheritance($data, $bp, 'offsetYUnit', $enabled_bps, 'px');

                $offset_x_value = "{$offset_x}{$offset_x_unit}";
                $offset_y_value = "{$offset_y}{$offset_y_unit}";

                // X positioning
                if ($origin_x === 'center') {
                    $bp_vars[] = "--icon-left-{$bp}: " . ($offset_x == 0 ? '50%' : "calc(50% + {$offset_x_value})");
                    $bp_vars[] = "--icon-right-{$bp}: auto";
                    $bp_vars[] = "--icon-transform-x-{$bp}: -50%";
                } else {
                    $bp_vars[] = "--icon-left-{$bp}: " . ($origin_x === 'left' ? $offset_x_value : 'auto');
                    $bp_vars[] = "--icon-right-{$bp}: " . ($origin_x === 'right' ? $offset_x_value : 'auto');
                    $bp_vars[] = "--icon-transform-x-{$bp}: 0";
                }

                // Y positioning
                if ($origin_y === 'center') {
                    $bp_vars[] = "--icon-top-{$bp}: " . ($offset_y == 0 ? '50%' : "calc(50% + {$offset_y_value})");
                    $bp_vars[] = "--icon-bottom-{$bp}: auto";
                    $bp_vars[] = "--icon-transform-y-{$bp}: -50%";
                } else {
                    $bp_vars[] = "--icon-top-{$bp}: " . ($origin_y === 'top' ? $offset_y_value : 'auto');
                    $bp_vars[] = "--icon-bottom-{$bp}: " . ($origin_y === 'bottom' ? $offset_y_value : 'auto');
                    $bp_vars[] = "--icon-transform-y-{$bp}: 0";
                }
            }

            // Hover (with fallback to normal)
            $h_gap = $this->get_v2_value_with_inheritance($hover_data, $bp, 'gap', $enabled_bps);
            $h_gap_unit = $this->get_v2_value_with_inheritance($hover_data, $bp, 'gapUnit', $enabled_bps, 'px');
            if ($h_gap === null && $data) {
                $h_gap = $this->get_v2_value_with_inheritance($data, $bp, 'gap', $enabled_bps);
                $h_gap_unit = $this->get_v2_value_with_inheritance($data, $bp, 'gapUnit', $enabled_bps, 'px');
            }
            if ($h_gap !== null && $h_gap !== '') {
                $bp_vars[] = "--icon-gap-{$bp}-hover: {$h_gap}{$h_gap_unit}";
            }

            // Hover origin-based positioning
            $h_origin_x = $this->get_v2_value_with_inheritance($hover_data, $bp, 'originX', $enabled_bps);
            $h_origin_y = $this->get_v2_value_with_inheritance($hover_data, $bp, 'originY', $enabled_bps);
            $h_offset_x = $this->get_v2_value_with_inheritance($hover_data, $bp, 'offsetX', $enabled_bps);
            $h_offset_x_unit = $this->get_v2_value_with_inheritance($hover_data, $bp, 'offsetXUnit', $enabled_bps);
            $h_offset_y = $this->get_v2_value_with_inheritance($hover_data, $bp, 'offsetY', $enabled_bps);
            $h_offset_y_unit = $this->get_v2_value_with_inheritance($hover_data, $bp, 'offsetYUnit', $enabled_bps);

            // Fallback to normal values
            if ($h_origin_x === null && $data) {
                $h_origin_x = $this->get_v2_value_with_inheritance($data, $bp, 'originX', $enabled_bps, 'center');
            }
            if ($h_origin_y === null && $data) {
                $h_origin_y = $this->get_v2_value_with_inheritance($data, $bp, 'originY', $enabled_bps, 'center');
            }
            if ($h_offset_x === null && $data) {
                $h_offset_x = $this->get_v2_value_with_inheritance($data, $bp, 'offsetX', $enabled_bps, 0);
                $h_offset_x_unit = $this->get_v2_value_with_inheritance($data, $bp, 'offsetXUnit', $enabled_bps, '%');
            }
            if ($h_offset_y === null && $data) {
                $h_offset_y = $this->get_v2_value_with_inheritance($data, $bp, 'offsetY', $enabled_bps, 0);
                $h_offset_y_unit = $this->get_v2_value_with_inheritance($data, $bp, 'offsetYUnit', $enabled_bps, 'px');
            }

            if ($h_origin_x === null) $h_origin_x = 'center';
            if ($h_origin_y === null) $h_origin_y = 'center';
            if ($h_offset_x === null) $h_offset_x = 0;
            if ($h_offset_y === null) $h_offset_y = 0;
            if (!$h_offset_x_unit) $h_offset_x_unit = '%';
            if (!$h_offset_y_unit) $h_offset_y_unit = 'px';

            $h_offset_x_value = "{$h_offset_x}{$h_offset_x_unit}";
            $h_offset_y_value = "{$h_offset_y}{$h_offset_y_unit}";

            // Hover X positioning
            if ($h_origin_x === 'center') {
                $bp_vars[] = "--icon-left-{$bp}-hover: " . ($h_offset_x == 0 ? '50%' : "calc(50% + {$h_offset_x_value})");
                $bp_vars[] = "--icon-right-{$bp}-hover: auto";
                $bp_vars[] = "--icon-transform-x-{$bp}-hover: -50%";
            } else {
                $bp_vars[] = "--icon-left-{$bp}-hover: " . ($h_origin_x === 'left' ? $h_offset_x_value : 'auto');
                $bp_vars[] = "--icon-right-{$bp}-hover: " . ($h_origin_x === 'right' ? $h_offset_x_value : 'auto');
                $bp_vars[] = "--icon-transform-x-{$bp}-hover: 0";
            }

            // Hover Y positioning
            if ($h_origin_y === 'center') {
                $bp_vars[] = "--icon-top-{$bp}-hover: " . ($h_offset_y == 0 ? '50%' : "calc(50% + {$h_offset_y_value})");
                $bp_vars[] = "--icon-bottom-{$bp}-hover: auto";
                $bp_vars[] = "--icon-transform-y-{$bp}-hover: -50%";
            } else {
                $bp_vars[] = "--icon-top-{$bp}-hover: " . ($h_origin_y === 'top' ? $h_offset_y_value : 'auto');
                $bp_vars[] = "--icon-bottom-{$bp}-hover: " . ($h_origin_y === 'bottom' ? $h_offset_y_value : 'auto');
                $bp_vars[] = "--icon-transform-y-{$bp}-hover: 0";
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Get icon color CSS variables for MD/TB/SP
     */
    private function get_icon_color_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $data = $attrs['iconColorV2'] ?? null;
        $hover_data = $attrs['iconColorV2Hover'] ?? null;

        if (!$data && !$hover_data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();

        foreach ($responsive_bps as $bp) {
            // Normal
            if ($data) {
                $color = $this->get_v2_value_with_inheritance($data, $bp, 'color', $enabled_bps);
                $alpha = $this->get_v2_value_with_inheritance($data, $bp, 'alpha', $enabled_bps, 1);
                if ($color) {
                    $color_value = $this->get_color_with_alpha($color, $alpha);
                    if ($color_value) {
                        $bp_vars[] = "--icon-color-{$bp}: {$color_value}";
                    }
                }
            }

            // Hover - 通常状態へのフォールバックは行わない（ホバーは独立した設定）
            $h_color = $this->get_v2_value_with_inheritance($hover_data, $bp, 'color', $enabled_bps);
            $h_alpha = $this->get_v2_value_with_inheritance($hover_data, $bp, 'alpha', $enabled_bps, 1);
            if ($h_color) {
                $h_color_value = $this->get_color_with_alpha($h_color, $h_alpha);
                if ($h_color_value) {
                    $bp_vars[] = "--icon-color-{$bp}-hover: {$h_color_value}";
                }
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Get background color CSS variables for MD/TB/SP
     */
    private function get_background_color_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $data = $attrs['backgroundColorV2'] ?? null;
        $hover_data = $attrs['backgroundColorV2Hover'] ?? null;

        if (!$data && !$hover_data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();

        foreach ($responsive_bps as $bp) {
            // Normal: only output if the breakpoint has been explicitly modified from default
            // block.json default: color=#FFFFFF, gradient='', useGradient=false, opacity=0, mixBlendMode=normal
            // If we output default values, the responsive CSS fallback chain can't inherit from PC
            if ($data && !$this->is_bg_color_default($data, $bp)) {
                $bg_value = $this->get_background_color_value($data, $bp, $enabled_bps);
                if ($bg_value) {
                    $bp_vars[] = "--background-color-{$bp}: {$bg_value}";
                }
                $opacity = $this->get_v2_direct_value($data, $bp, 'opacity');
                if ($opacity !== null) {
                    $bp_vars[] = "--background-color-opacity-{$bp}: {$opacity}";
                }
                $mix_blend = $this->get_v2_direct_value($data, $bp, 'mixBlendMode');
                if ($mix_blend !== null && $mix_blend !== '') {
                    $bp_vars[] = "--background-color-mix-blend-mode-{$bp}: {$mix_blend}";
                }
            }

            // Hover: only output if the breakpoint has been explicitly modified from default
            if ($hover_data && !$this->is_bg_color_default($hover_data, $bp)) {
                $h_bg_value = $this->get_background_color_value($hover_data, $bp, $enabled_bps);
                if ($h_bg_value) {
                    $bp_vars[] = "--background-color-{$bp}-hover: {$h_bg_value}";
                }

                $h_opacity = $this->get_v2_direct_value($hover_data, $bp, 'opacity');
                if ($h_opacity !== null && $h_opacity !== '') {
                    $bp_vars[] = "--background-color-opacity-{$bp}-hover: {$h_opacity}";
                }

                $h_mix_blend = $this->get_v2_direct_value($hover_data, $bp, 'mixBlendMode');
                if ($h_mix_blend !== null && $h_mix_blend !== '') {
                    $bp_vars[] = "--background-color-mix-blend-mode-{$bp}-hover: {$h_mix_blend}";
                }
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Check if background color data for a breakpoint matches block.json default
     * Default: color=#FFFFFF, gradient='', useGradient=false, opacity=0, mixBlendMode=normal
     */
    private function is_bg_color_default($data, $bp) {
        if (!isset($data[$bp])) {
            return true;
        }

        $bp_data = $data[$bp];
        $color = $bp_data['color'] ?? '';
        $gradient = $bp_data['gradient'] ?? '';
        $use_gradient = $bp_data['useGradient'] ?? false;
        $opacity = $bp_data['opacity'] ?? 0;
        $mix_blend = $bp_data['mixBlendMode'] ?? 'normal';

        // If all values match the block.json default, this breakpoint hasn't been modified
        return (
            ($color === '#FFFFFF' || $color === '#ffffff' || $color === '') &&
            ($gradient === '' || $gradient === null) &&
            ($use_gradient === false || $use_gradient === 0) &&
            ($opacity === 0 || $opacity === '0' || $opacity === '' || $opacity === null) &&
            ($mix_blend === 'normal' || $mix_blend === '' || $mix_blend === null)
        );
    }

    /**
     * Get direct value for a V2 attribute at a specific breakpoint (no inheritance)
     */
    private function get_v2_direct_value($data, $bp, $key) {
        if (!$data || !isset($data[$bp]) || !isset($data[$bp][$key])) {
            return null;
        }
        $value = $data[$bp][$key];
        if ($value === '' || $value === null) {
            return null;
        }
        return $value;
    }

    /**
     * Get background base color CSS variables for MD/TB/SP
     * Handles backgroundBaseColorV2 and backgroundBaseColorV2Hover
     */
    private function get_background_base_color_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $data = $attrs['backgroundBaseColorV2'] ?? null;
        $hover_data = $attrs['backgroundBaseColorV2Hover'] ?? null;

        if (!$data && !$hover_data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();

        foreach ($responsive_bps as $bp) {
            // Normal: only output if the breakpoint has been modified from block.json default
            // Default: color=#111111, alpha=''
            if ($data && !$this->is_bg_base_color_default($data, $bp)) {
                $use_gradient = $this->get_v2_value_with_inheritance($data, $bp, 'useGradient', $enabled_bps, false);
                $gradient = $this->get_v2_value_with_inheritance($data, $bp, 'gradient', $enabled_bps);
                if ($use_gradient && $gradient) {
                    $bp_vars[] = "--background-base-gradient-{$bp}: {$gradient}";
                    $bp_vars[] = "--background-base-color-{$bp}: transparent";
                } else {
                    $color = $this->get_v2_value_with_inheritance($data, $bp, 'color', $enabled_bps);
                    $alpha = $this->get_v2_value_with_inheritance($data, $bp, 'alpha', $enabled_bps, 1);
                    if ($color) {
                        $value = $this->get_color_with_alpha($color, $alpha);
                        if ($value) {
                            $bp_vars[] = "--background-base-color-{$bp}: {$value}";
                        }
                    }
                }
            }

            // Hover: only output if breakpoint modified from default
            // Default: color=#3f3f3f, alpha=''
            if ($hover_data && !$this->is_bg_base_color_hover_default($hover_data, $bp)) {
                // Check gradient first
                $h_use_gradient = $this->get_v2_value_with_inheritance($hover_data, $bp, 'useGradient', $enabled_bps);
                $h_gradient = $this->get_v2_value_with_inheritance($hover_data, $bp, 'gradient', $enabled_bps);
                // Fallback to normal if hover has no explicit gradient setting
                if ($h_use_gradient === null && $data) {
                    $h_use_gradient = $this->get_v2_value_with_inheritance($data, $bp, 'useGradient', $enabled_bps, false);
                }
                if ($h_gradient === null && $data) {
                    $h_gradient = $this->get_v2_value_with_inheritance($data, $bp, 'gradient', $enabled_bps);
                }

                if ($h_use_gradient && $h_gradient) {
                    $bp_vars[] = "--background-base-gradient-{$bp}-hover: {$h_gradient}";
                    $bp_vars[] = "--background-base-color-{$bp}-hover: transparent";
                } else {
                    $h_color = $this->get_v2_value_with_inheritance($hover_data, $bp, 'color', $enabled_bps);
                    $h_alpha = $this->get_v2_value_with_inheritance($hover_data, $bp, 'alpha', $enabled_bps, 1);
                    if (!$h_color && $data) {
                        $h_color = $this->get_v2_value_with_inheritance($data, $bp, 'color', $enabled_bps);
                        $h_alpha = $this->get_v2_value_with_inheritance($data, $bp, 'alpha', $enabled_bps, 1);
                    }
                    if ($h_color) {
                        $value = $this->get_color_with_alpha($h_color, $h_alpha);
                        if ($value) {
                            $bp_vars[] = "--background-base-color-{$bp}-hover: {$value}";
                            // グラデーション→単色切り替え時、単色をグラデーションとしても設定（白フラッシュ防止）
                            $bp_vars[] = "--background-base-gradient-{$bp}-hover: linear-gradient(0deg, {$value} 0%, {$value} 100%)";
                        } else {
                            $bp_vars[] = "--background-base-gradient-{$bp}-hover: none";
                        }
                    } else {
                        $bp_vars[] = "--background-base-gradient-{$bp}-hover: none";
                    }
                }
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Check if backgroundBaseColorV2 breakpoint matches block.json default
     * Default: color=#111111, alpha=''
     */
    private function is_bg_base_color_default($data, $bp) {
        if (!isset($data[$bp])) {
            return true;
        }
        $bp_data = $data[$bp];
        $color = $bp_data['color'] ?? '';
        $alpha = $bp_data['alpha'] ?? '';
        $use_gradient = $bp_data['useGradient'] ?? null;
        $gradient = $bp_data['gradient'] ?? '';
        return (
            ($color === '#111111' || $color === '' || $color === null) &&
            ($alpha === '' || $alpha === null) &&
            ($use_gradient === null || $use_gradient === false) &&
            ($gradient === '' || $gradient === null)
        );
    }

    /**
     * Check if backgroundBaseColorV2Hover breakpoint matches block.json default
     * Default: color=#3f3f3f, alpha=''
     */
    private function is_bg_base_color_hover_default($data, $bp) {
        if (!isset($data[$bp])) {
            return true;
        }
        $bp_data = $data[$bp];
        $color = $bp_data['color'] ?? '';
        $alpha = $bp_data['alpha'] ?? '';
        $use_gradient = $bp_data['useGradient'] ?? null;
        $gradient = $bp_data['gradient'] ?? '';
        return (
            ($color === '#3f3f3f' || $color === '' || $color === null) &&
            ($alpha === '' || $alpha === null) &&
            ($use_gradient === null || $use_gradient === false) &&
            ($gradient === '' || $gradient === null)
        );
    }

    /**
     * Get background image CSS variables for MD/TB/SP
     * Properties: url, position, size, repeat (+ hover: position, size, repeat)
     */
    private function get_background_image_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $data = $attrs['backgroundImageV2'] ?? null;
        $hover_data = $attrs['backgroundImageV2Hover'] ?? null;

        if (!$data && !$hover_data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();

        foreach ($responsive_bps as $bp) {
            // Normal: only output if the breakpoint has been modified from block.json default
            if ($data && !$this->is_bg_image_default($data, $bp)) {
                $url = $this->get_v2_value_with_inheritance($data, $bp, 'url', $enabled_bps, '');
                $position = $this->get_v2_value_with_inheritance($data, $bp, 'position', $enabled_bps, 'center center');
                $size = $this->get_bg_image_size_value($data, $bp, $enabled_bps);
                $repeat = $this->get_v2_value_with_inheritance($data, $bp, 'repeat', $enabled_bps, 'no-repeat');

                if ($url) {
                    $bp_vars[] = "--background-image-{$bp}: url({$url})";
                } else {
                    $bp_vars[] = "--background-image-{$bp}: none";
                }
                $bp_vars[] = "--background-position-{$bp}: {$position}";
                $bp_vars[] = "--background-size-{$bp}: {$size}";
                $bp_vars[] = "--background-repeat-{$bp}: {$repeat}";
            }

            // Hover: position, size, repeat only (no URL - inherits from normal)
            if ($hover_data && !$this->is_bg_image_default($hover_data, $bp)) {
                // Helper: get hover value with fallback to normal data
                $h_position = $this->get_v2_value_with_inheritance($hover_data, $bp, 'position', $enabled_bps, '');
                if (!$h_position && $data) {
                    $h_position = $this->get_v2_value_with_inheritance($data, $bp, 'position', $enabled_bps, 'center center');
                }
                if (!$h_position) {
                    $h_position = 'center center';
                }

                $h_size = $this->get_bg_image_size_value($hover_data, $bp, $enabled_bps);
                if ($h_size === 'cover' && $data) {
                    // If hover size is default, try to inherit from normal
                    $h_size_raw = $this->get_v2_value_with_inheritance($hover_data, $bp, 'size', $enabled_bps, '');
                    if (!$h_size_raw) {
                        $h_size = $this->get_bg_image_size_value($data, $bp, $enabled_bps);
                    }
                }

                $h_repeat = $this->get_v2_value_with_inheritance($hover_data, $bp, 'repeat', $enabled_bps, '');
                if (!$h_repeat && $data) {
                    $h_repeat = $this->get_v2_value_with_inheritance($data, $bp, 'repeat', $enabled_bps, 'no-repeat');
                }
                if (!$h_repeat) {
                    $h_repeat = 'no-repeat';
                }

                $bp_vars[] = "--background-position-{$bp}-hover: {$h_position}";
                $bp_vars[] = "--background-size-{$bp}-hover: {$h_size}";
                $bp_vars[] = "--background-repeat-{$bp}-hover: {$h_repeat}";
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Check if backgroundImageV2 breakpoint matches block.json default
     * Default: url='', position='center center', size='cover', repeat='no-repeat'
     */
    private function is_bg_image_default($data, $bp) {
        if (!isset($data[$bp])) {
            return true;
        }
        $bp_data = $data[$bp];
        $url = $bp_data['url'] ?? '';
        $position = $bp_data['position'] ?? 'center center';
        $size = $bp_data['size'] ?? 'cover';
        $repeat = $bp_data['repeat'] ?? 'no-repeat';
        return (
            ($url === '' || $url === null) &&
            ($position === 'center center' || $position === '' || $position === null) &&
            ($size === 'cover' || $size === '' || $size === null) &&
            ($repeat === 'no-repeat' || $repeat === '' || $repeat === null)
        );
    }

    /**
     * Get background image size value including custom dimensions (fill/none)
     */
    private function get_bg_image_size_value($data, $bp, $enabled_bps) {
        $size = $this->get_v2_value_with_inheritance($data, $bp, 'size', $enabled_bps, 'cover');
        if ($size === 'fill' || $size === 'none') {
            $custom_width = $this->get_v2_value_with_inheritance($data, $bp, 'customWidth', $enabled_bps, 'auto');
            $custom_width_unit = $this->get_v2_value_with_inheritance($data, $bp, 'customWidthUnit', $enabled_bps, '%');
            $custom_height = $this->get_v2_value_with_inheritance($data, $bp, 'customHeight', $enabled_bps, 'auto');
            $custom_height_unit = $this->get_v2_value_with_inheritance($data, $bp, 'customHeightUnit', $enabled_bps, '%');
            $width = ($custom_width === 'auto') ? 'auto' : "{$custom_width}{$custom_width_unit}";
            $height = ($custom_height === 'auto') ? 'auto' : "{$custom_height}{$custom_height_unit}";
            return "{$width} {$height}";
        }
        return $size;
    }

    /**
     * Get background pattern CSS variables for MD/TB/SP
     */
    private function get_background_pattern_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $data = $attrs['backgroundPatternV2'] ?? null;
        $hover_data = $attrs['backgroundPatternV2Hover'] ?? null;

        if (!$data && !$hover_data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();

        foreach ($responsive_bps as $bp) {
            // Normal
            if ($data) {
                $type = $this->get_v2_value_with_inheritance($data, $bp, 'type', $enabled_bps);
                if ($type) {
                    $bp_vars[] = "--background-pattern-type-{$bp}: {$type}";
                }
                $color = $this->get_v2_value_with_inheritance($data, $bp, 'color', $enabled_bps);
                if ($color) {
                    $bp_vars[] = "--background-pattern-color-{$bp}: {$color}";
                }
                $opacity = $this->get_v2_value_with_inheritance($data, $bp, 'opacity', $enabled_bps);
                if ($opacity !== null && $opacity !== '') {
                    $bp_vars[] = "--background-pattern-opacity-{$bp}: {$opacity}";
                }
                $size = $this->get_v2_value_with_inheritance($data, $bp, 'size', $enabled_bps);
                $size_unit = $this->get_v2_value_with_inheritance($data, $bp, 'sizeUnit', $enabled_bps, 'px');
                if ($size !== null && $size !== '') {
                    $bp_vars[] = "--background-pattern-size-{$bp}: {$size}{$size_unit}";
                }
                $rotate = $this->get_v2_value_with_inheritance($data, $bp, 'rotate', $enabled_bps);
                if ($rotate !== null && $rotate !== '') {
                    $bp_vars[] = "--background-pattern-rotate-{$bp}: {$rotate}deg";
                }
            }

            // Hover (with fallback to normal)
            $h_type = $this->get_v2_value_with_inheritance($hover_data, $bp, 'type', $enabled_bps);
            if (!$h_type && $data) {
                $h_type = $this->get_v2_value_with_inheritance($data, $bp, 'type', $enabled_bps);
            }
            if ($h_type) {
                $bp_vars[] = "--background-pattern-type-{$bp}-hover: {$h_type}";
            }

            $h_color = $this->get_v2_value_with_inheritance($hover_data, $bp, 'color', $enabled_bps);
            if (!$h_color && $data) {
                $h_color = $this->get_v2_value_with_inheritance($data, $bp, 'color', $enabled_bps);
            }
            if ($h_color) {
                $bp_vars[] = "--background-pattern-color-{$bp}-hover: {$h_color}";
            }

            $h_opacity = $this->get_v2_value_with_inheritance($hover_data, $bp, 'opacity', $enabled_bps);
            if ($h_opacity === null && $data) {
                $h_opacity = $this->get_v2_value_with_inheritance($data, $bp, 'opacity', $enabled_bps);
            }
            if ($h_opacity !== null && $h_opacity !== '') {
                $bp_vars[] = "--background-pattern-opacity-{$bp}-hover: {$h_opacity}";
            }

            $h_size = $this->get_v2_value_with_inheritance($hover_data, $bp, 'size', $enabled_bps);
            $h_size_unit = $this->get_v2_value_with_inheritance($hover_data, $bp, 'sizeUnit', $enabled_bps, 'px');
            if ($h_size === null && $data) {
                $h_size = $this->get_v2_value_with_inheritance($data, $bp, 'size', $enabled_bps);
                $h_size_unit = $this->get_v2_value_with_inheritance($data, $bp, 'sizeUnit', $enabled_bps, 'px');
            }
            if ($h_size !== null && $h_size !== '') {
                $bp_vars[] = "--background-pattern-size-{$bp}-hover: {$h_size}{$h_size_unit}";
            }

            $h_rotate = $this->get_v2_value_with_inheritance($hover_data, $bp, 'rotate', $enabled_bps);
            if ($h_rotate === null && $data) {
                $h_rotate = $this->get_v2_value_with_inheritance($data, $bp, 'rotate', $enabled_bps);
            }
            if ($h_rotate !== null && $h_rotate !== '') {
                $bp_vars[] = "--background-pattern-rotate-{$bp}-hover: {$h_rotate}deg";
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Get border CSS variables for MD/TB/SP
     */
    private function get_border_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $data = $attrs['borderV2'] ?? null;
        $hover_data = $attrs['borderV2Hover'] ?? null;

        if (!$data && !$hover_data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();

        foreach ($responsive_bps as $bp) {
            // Normal
            if ($data) {
                $width = $this->get_v2_value_with_inheritance($data, $bp, 'width', $enabled_bps, 0);
                if ($width !== null) {
                    $bp_vars[] = "--styling-border-width-{$bp}: {$width}px";
                }
                $style = $this->get_v2_value_with_inheritance($data, $bp, 'style', $enabled_bps, 'none');
                if ($style) {
                    $bp_vars[] = "--styling-border-style-{$bp}: {$style}";
                }
                $color = $this->get_v2_value_with_inheritance($data, $bp, 'color', $enabled_bps, 'transparent');
                $color_alpha = $this->get_v2_value_with_inheritance($data, $bp, 'colorAlpha', $enabled_bps, 1);
                if ($color) {
                    $color_value = $color === 'transparent' ? 'transparent' : $this->get_color_with_alpha($color, $color_alpha);
                    $bp_vars[] = "--styling-border-color-{$bp}: {$color_value}";
                }
                $box_sizing = $this->get_v2_value_with_inheritance($data, $bp, 'boxSizing', $enabled_bps, 'border-box');
                if ($box_sizing) {
                    $bp_vars[] = "--styling-box-sizing-{$bp}: {$box_sizing}";
                }
            }

            // Hover (with fallback to normal)
            $h_width = $this->get_v2_value_with_inheritance($hover_data, $bp, 'width', $enabled_bps);
            if ($h_width === null && $data) {
                $h_width = $this->get_v2_value_with_inheritance($data, $bp, 'width', $enabled_bps, 0);
            }
            if ($h_width !== null) {
                $bp_vars[] = "--styling-border-width-{$bp}-hover: {$h_width}px";
            }

            $h_style = $this->get_v2_value_with_inheritance($hover_data, $bp, 'style', $enabled_bps);
            if (!$h_style && $data) {
                $h_style = $this->get_v2_value_with_inheritance($data, $bp, 'style', $enabled_bps, 'none');
            }
            if ($h_style) {
                $bp_vars[] = "--styling-border-style-{$bp}-hover: {$h_style}";
            }

            $h_color = $this->get_v2_value_with_inheritance($hover_data, $bp, 'color', $enabled_bps);
            $h_color_alpha = $this->get_v2_value_with_inheritance($hover_data, $bp, 'colorAlpha', $enabled_bps, 1);
            if (!$h_color && $data) {
                $h_color = $this->get_v2_value_with_inheritance($data, $bp, 'color', $enabled_bps, 'transparent');
                $h_color_alpha = $this->get_v2_value_with_inheritance($data, $bp, 'colorAlpha', $enabled_bps, 1);
            }
            if ($h_color) {
                $h_color_value = $h_color === 'transparent' ? 'transparent' : $this->get_color_with_alpha($h_color, $h_color_alpha);
                $bp_vars[] = "--styling-border-color-{$bp}-hover: {$h_color_value}";
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Get radius CSS variables for MD/TB/SP
     */
    private function get_radius_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $data = $attrs['radiusV2'] ?? null;
        $hover_data = $attrs['radiusV2Hover'] ?? null;

        if (!$data && !$hover_data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();
        $corners = array('topLeft', 'topRight', 'bottomRight', 'bottomLeft');

        foreach ($responsive_bps as $bp) {
            // Normal
            if ($data) {
                $bulk = $this->get_v2_value_with_inheritance($data, $bp, 'bulk', $enabled_bps, 0);
                $bulk_unit = $this->get_v2_value_with_inheritance($data, $bp, 'bulkUnit', $enabled_bps, 'px') ?: 'px';
                $use_individual = $this->get_v2_value_with_inheritance($data, $bp, 'useIndividual', $enabled_bps, false);

                $bp_vars[] = "--styling-radius-{$bp}: {$bulk}{$bulk_unit}";

                foreach ($corners as $corner) {
                    $css_corner = strtolower(preg_replace('/([A-Z])/', '-$1', $corner));
                    if ($use_individual) {
                        $value = $this->get_v2_value_with_inheritance($data, $bp, $corner, $enabled_bps, 0);
                        $unit = $this->get_v2_value_with_inheritance($data, $bp, "{$corner}Unit", $enabled_bps, 'px') ?: 'px';
                        $bp_vars[] = "--styling-radius-{$css_corner}-{$bp}: {$value}{$unit}";
                    } else {
                        $bp_vars[] = "--styling-radius-{$css_corner}-{$bp}: {$bulk}{$bulk_unit}";
                    }
                }
            }

            // Hover (with fallback to normal)
            $h_bulk = $this->get_v2_value_with_inheritance($hover_data, $bp, 'bulk', $enabled_bps);
            $h_bulk_unit = $this->get_v2_value_with_inheritance($hover_data, $bp, 'bulkUnit', $enabled_bps, 'px') ?: 'px';
            $h_use_individual = $this->get_v2_value_with_inheritance($hover_data, $bp, 'useIndividual', $enabled_bps);

            if ($h_bulk === null && $data) {
                $h_bulk = $this->get_v2_value_with_inheritance($data, $bp, 'bulk', $enabled_bps, 0);
                $h_bulk_unit = $this->get_v2_value_with_inheritance($data, $bp, 'bulkUnit', $enabled_bps, 'px') ?: 'px';
            }
            if ($h_use_individual === null && $data) {
                $h_use_individual = $this->get_v2_value_with_inheritance($data, $bp, 'useIndividual', $enabled_bps, false);
            }

            if ($h_bulk !== null) {
                $bp_vars[] = "--styling-radius-{$bp}-hover: {$h_bulk}{$h_bulk_unit}";
            }

            foreach ($corners as $corner) {
                $css_corner = strtolower(preg_replace('/([A-Z])/', '-$1', $corner));
                if ($h_use_individual) {
                    $h_value = $this->get_v2_value_with_inheritance($hover_data, $bp, $corner, $enabled_bps);
                    $h_unit = $this->get_v2_value_with_inheritance($hover_data, $bp, "{$corner}Unit", $enabled_bps, 'px') ?: 'px';
                    if ($h_value === null && $data) {
                        $h_value = $this->get_v2_value_with_inheritance($data, $bp, $corner, $enabled_bps, 0);
                        $h_unit = $this->get_v2_value_with_inheritance($data, $bp, "{$corner}Unit", $enabled_bps, 'px') ?: 'px';
                    }
                    if ($h_value !== null) {
                        $bp_vars[] = "--styling-radius-{$css_corner}-{$bp}-hover: {$h_value}{$h_unit}";
                    }
                } elseif ($h_bulk !== null) {
                    $bp_vars[] = "--styling-radius-{$css_corner}-{$bp}-hover: {$h_bulk}{$h_bulk_unit}";
                }
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Get shadow CSS variables for MD/TB/SP
     */
    private function get_shadow_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $data = $attrs['shadowV2'] ?? null;
        $hover_data = $attrs['shadowV2Hover'] ?? null;

        if (!$data && !$hover_data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();

        foreach ($responsive_bps as $bp) {
            // Normal
            if ($data) {
                $shadow_value = $this->get_shadow_value($data, $bp, $enabled_bps);
                if ($shadow_value) {
                    $bp_vars[] = "--styling-shadow-{$bp}: {$shadow_value}";
                }
            }

            // Hover (with fallback to normal)
            $h_shadow_value = $this->get_shadow_value($hover_data, $bp, $enabled_bps);
            if (!$h_shadow_value && $data) {
                $h_shadow_value = $this->get_shadow_value($data, $bp, $enabled_bps);
            }
            if ($h_shadow_value) {
                $bp_vars[] = "--styling-shadow-{$bp}-hover: {$h_shadow_value}";
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Get shadow value string
     */
    private function get_shadow_value($data, $bp, $enabled_bps) {
        if (!$data) {
            return null;
        }

        $use = $this->get_v2_value_with_inheritance($data, $bp, 'use', $enabled_bps, false);
        if (!$use) {
            return 'none';
        }

        $horizontal = $this->get_v2_value_with_inheritance($data, $bp, 'horizontal', $enabled_bps, 0);
        $vertical = $this->get_v2_value_with_inheritance($data, $bp, 'vertical', $enabled_bps, 0);
        $blur = $this->get_v2_value_with_inheritance($data, $bp, 'blur', $enabled_bps, 0);
        $spread = $this->get_v2_value_with_inheritance($data, $bp, 'spread', $enabled_bps, 0);
        $color = $this->get_v2_value_with_inheritance($data, $bp, 'color', $enabled_bps, 'transparent');
        $color_alpha = $this->get_v2_value_with_inheritance($data, $bp, 'colorAlpha', $enabled_bps, 0.2);
        $inset = $this->get_v2_value_with_inheritance($data, $bp, 'inset', $enabled_bps, false);

        $inset_str = $inset ? 'inset ' : '';
        $color_with_alpha = $color === 'transparent' ? 'transparent' : $this->get_color_with_alpha($color, $color_alpha);

        return "{$inset_str}{$horizontal}px {$vertical}px {$blur}px {$spread}px {$color_with_alpha}";
    }

    /**
     * Get inner shadow CSS variables for MD/TB/SP
     */
    private function get_inner_shadow_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $inner_shadow_enabled = $attrs['innerShadowEnabled'] ?? false;
        if (!$inner_shadow_enabled) {
            return '';
        }

        $data = $attrs['innerShadowV2'] ?? null;
        $hover_data = $attrs['innerShadowV2Hover'] ?? null;
        $hover_enabled = $attrs['innerShadowEnabledHover'] ?? $inner_shadow_enabled;

        if (!$data && !$hover_data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();

        foreach ($responsive_bps as $bp) {
            // Normal
            if ($data) {
                $shadow_value = $this->get_inner_shadow_value($data, $bp, $enabled_bps);
                if ($shadow_value) {
                    $bp_vars[] = "--styling-inner-shadow-{$bp}: {$shadow_value}";
                }
            }

            // Hover (with fallback to normal)
            if ($hover_enabled) {
                $h_shadow_value = $this->get_inner_shadow_value($hover_data, $bp, $enabled_bps);
                if (!$h_shadow_value && $data) {
                    $h_shadow_value = $this->get_inner_shadow_value($data, $bp, $enabled_bps);
                }
                if ($h_shadow_value) {
                    $bp_vars[] = "--styling-inner-shadow-{$bp}-hover: {$h_shadow_value}";
                }
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Get inner shadow value string
     */
    private function get_inner_shadow_value($data, $bp, $enabled_bps) {
        if (!$data) {
            return null;
        }

        $use = $this->get_v2_value_with_inheritance($data, $bp, 'use', $enabled_bps, false);
        if (!$use) {
            return 'none';
        }

        $horizontal = $this->get_v2_value_with_inheritance($data, $bp, 'horizontal', $enabled_bps, 0);
        $vertical = $this->get_v2_value_with_inheritance($data, $bp, 'vertical', $enabled_bps, 0);
        $blur = $this->get_v2_value_with_inheritance($data, $bp, 'blur', $enabled_bps, 0);
        $spread = $this->get_v2_value_with_inheritance($data, $bp, 'spread', $enabled_bps, 0);
        $color = $this->get_v2_value_with_inheritance($data, $bp, 'color', $enabled_bps, 'transparent');
        $color_alpha = $this->get_v2_value_with_inheritance($data, $bp, 'colorAlpha', $enabled_bps, 1);

        $color_with_alpha = $color === 'transparent' ? 'transparent' : $this->get_color_with_alpha($color, $color_alpha);

        return "inset {$horizontal}px {$vertical}px {$blur}px {$spread}px {$color_with_alpha}";
    }

    /**
     * Get opacity CSS variables for MD/TB/SP
     */
    private function get_opacity_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $data = $attrs['opacityV2'] ?? null;
        $hover_data = $attrs['opacityV2Hover'] ?? null;

        if (!$data && !$hover_data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();

        foreach ($responsive_bps as $bp) {
            // Normal
            if ($data) {
                $value = $this->get_v2_value_with_inheritance($data, $bp, 'value', $enabled_bps, 100);
                if ($value !== null) {
                    $opacity = $value / 100;
                    $bp_vars[] = "--styling-opacity-{$bp}: {$opacity}";
                }
                $mix_blend = $this->get_v2_value_with_inheritance($data, $bp, 'mixBlendMode', $enabled_bps, 'normal');
                if ($mix_blend) {
                    $bp_vars[] = "--styling-mix-blend-mode-{$bp}: {$mix_blend}";
                }
            }

            // Hover (with fallback to normal)
            $h_value = $this->get_v2_value_with_inheritance($hover_data, $bp, 'value', $enabled_bps);
            if ($h_value === null && $data) {
                $h_value = $this->get_v2_value_with_inheritance($data, $bp, 'value', $enabled_bps, 100);
            }
            if ($h_value !== null) {
                $h_opacity = $h_value / 100;
                $bp_vars[] = "--styling-opacity-{$bp}-hover: {$h_opacity}";
            }

            $h_mix_blend = $this->get_v2_value_with_inheritance($hover_data, $bp, 'mixBlendMode', $enabled_bps);
            if (!$h_mix_blend && $data) {
                $h_mix_blend = $this->get_v2_value_with_inheritance($data, $bp, 'mixBlendMode', $enabled_bps, 'normal');
            }
            if ($h_mix_blend) {
                $bp_vars[] = "--styling-mix-blend-mode-{$bp}-hover: {$h_mix_blend}";
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Get icon frame CSS variables for MD/TB/SP (V1 and V2)
     */
    private function get_icon_frame_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        // V2 data
        $v2_data = $attrs['iconFrameV2'] ?? null;
        $v2_hover_data = $attrs['iconFrameV2Hover'] ?? null;

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();

        foreach ($responsive_bps as $bp) {
            $bp_upper = strtoupper($bp);

            // ==== V2 Processing ====
            if ($v2_data) {
                // Size (width/height)
                $use_individual = $this->get_v2_value_with_inheritance($v2_data, $bp, 'useIndividualSize', $enabled_bps, false);
                if ($use_individual) {
                    $width = $this->get_v2_value_with_inheritance($v2_data, $bp, 'width', $enabled_bps);
                    $width_unit = $this->get_v2_value_with_inheritance($v2_data, $bp, 'widthUnit', $enabled_bps, 'px');
                    if ($width !== null && $width !== '') {
                        $bp_vars[] = "--icon-frame-width-{$bp}: {$width}{$width_unit}";
                    }
                    $height = $this->get_v2_value_with_inheritance($v2_data, $bp, 'height', $enabled_bps);
                    $height_unit = $this->get_v2_value_with_inheritance($v2_data, $bp, 'heightUnit', $enabled_bps, 'px');
                    if ($height !== null && $height !== '') {
                        $bp_vars[] = "--icon-frame-height-{$bp}: {$height}{$height_unit}";
                    }
                } else {
                    $size = $this->get_v2_value_with_inheritance($v2_data, $bp, 'size', $enabled_bps);
                    $size_unit = $this->get_v2_value_with_inheritance($v2_data, $bp, 'sizeUnit', $enabled_bps, 'px');
                    if ($size !== null && $size !== '') {
                        $bp_vars[] = "--icon-frame-width-{$bp}: {$size}{$size_unit}";
                        $bp_vars[] = "--icon-frame-height-{$bp}: {$size}{$size_unit}";
                    }
                }

                // Radius
                $radius = $this->get_v2_value_with_inheritance($v2_data, $bp, 'radius', $enabled_bps);
                $radius_unit = $this->get_v2_value_with_inheritance($v2_data, $bp, 'radiusUnit', $enabled_bps, 'px');
                if ($radius !== null && $radius !== '') {
                    $bp_vars[] = "--icon-frame-radius-{$bp}: {$radius}{$radius_unit}";
                }

                // Border width
                $border_width = $this->get_v2_value_with_inheritance($v2_data, $bp, 'borderWidth', $enabled_bps);
                $border_width_unit = $this->get_v2_value_with_inheritance($v2_data, $bp, 'borderWidthUnit', $enabled_bps, 'px');
                if ($border_width !== null && $border_width !== '') {
                    $bp_vars[] = "--icon-frame-border-width-{$bp}: {$border_width}{$border_width_unit}";
                    // Individual border sides
                    $border_sides = $this->get_v2_value_with_inheritance($v2_data, $bp, 'borderSides', $enabled_bps, array('top', 'right', 'bottom', 'left'));
                    if (is_array($border_sides)) {
                        foreach (array('top', 'right', 'bottom', 'left') as $side) {
                            $side_value = in_array($side, $border_sides) ? "{$border_width}{$border_width_unit}" : '0';
                            $bp_vars[] = "--icon-frame-border-{$side}-width-{$bp}: {$side_value}";
                        }
                    }
                }

                // Border color - 常に出力（デフォルト値でもフロントで必要）
                $border_color = $this->get_v2_value_with_inheritance($v2_data, $bp, 'borderColor', $enabled_bps, 'transparent');
                $bp_vars[] = "--icon-frame-border-color-{$bp}: " . ($border_color ?: 'transparent');

                // Border style - 常に出力（デフォルト値でもフロントで必要）
                $border_style = $this->get_v2_value_with_inheritance($v2_data, $bp, 'borderStyle', $enabled_bps, 'solid');
                $bp_vars[] = "--icon-frame-border-style-{$bp}: " . ($border_style ?: 'solid');

                // Background color - 常に出力（デフォルト値でもフロントで必要）
                $bg_color = $this->get_v2_value_with_inheritance($v2_data, $bp, 'bgColor', $enabled_bps, 'transparent');
                $bp_vars[] = "--icon-frame-bg-color-{$bp}: " . ($bg_color ?: 'transparent');
            }

            // ==== V2 Hover Processing ====
            if ($v2_data || $v2_hover_data) {
                // Size hover (with fallback to normal)
                $hover_use_individual = $this->get_v2_value_with_inheritance($v2_hover_data, $bp, 'useIndividualSize', $enabled_bps);
                if ($hover_use_individual === null && $v2_data) {
                    $hover_use_individual = $this->get_v2_value_with_inheritance($v2_data, $bp, 'useIndividualSize', $enabled_bps, false);
                }

                if ($hover_use_individual) {
                    $h_width = $this->get_v2_value_with_inheritance($v2_hover_data, $bp, 'width', $enabled_bps);
                    if ($h_width === null && $v2_data) {
                        $h_width = $this->get_v2_value_with_inheritance($v2_data, $bp, 'width', $enabled_bps);
                    }
                    $h_width_unit = $this->get_v2_value_with_inheritance($v2_hover_data, $bp, 'widthUnit', $enabled_bps);
                    if (!$h_width_unit && $v2_data) {
                        $h_width_unit = $this->get_v2_value_with_inheritance($v2_data, $bp, 'widthUnit', $enabled_bps, 'px');
                    }
                    if ($h_width !== null && $h_width !== '') {
                        $bp_vars[] = "--icon-frame-width-{$bp}-hover: {$h_width}{$h_width_unit}";
                    }

                    $h_height = $this->get_v2_value_with_inheritance($v2_hover_data, $bp, 'height', $enabled_bps);
                    if ($h_height === null && $v2_data) {
                        $h_height = $this->get_v2_value_with_inheritance($v2_data, $bp, 'height', $enabled_bps);
                    }
                    $h_height_unit = $this->get_v2_value_with_inheritance($v2_hover_data, $bp, 'heightUnit', $enabled_bps);
                    if (!$h_height_unit && $v2_data) {
                        $h_height_unit = $this->get_v2_value_with_inheritance($v2_data, $bp, 'heightUnit', $enabled_bps, 'px');
                    }
                    if ($h_height !== null && $h_height !== '') {
                        $bp_vars[] = "--icon-frame-height-{$bp}-hover: {$h_height}{$h_height_unit}";
                    }
                } else {
                    $h_size = $this->get_v2_value_with_inheritance($v2_hover_data, $bp, 'size', $enabled_bps);
                    if ($h_size === null && $v2_data) {
                        $h_size = $this->get_v2_value_with_inheritance($v2_data, $bp, 'size', $enabled_bps);
                    }
                    $h_size_unit = $this->get_v2_value_with_inheritance($v2_hover_data, $bp, 'sizeUnit', $enabled_bps);
                    if (!$h_size_unit && $v2_data) {
                        $h_size_unit = $this->get_v2_value_with_inheritance($v2_data, $bp, 'sizeUnit', $enabled_bps, 'px');
                    }
                    if ($h_size !== null && $h_size !== '') {
                        $bp_vars[] = "--icon-frame-width-{$bp}-hover: {$h_size}{$h_size_unit}";
                        $bp_vars[] = "--icon-frame-height-{$bp}-hover: {$h_size}{$h_size_unit}";
                    }
                }

                // Radius hover
                $h_radius = $this->get_v2_value_with_inheritance($v2_hover_data, $bp, 'radius', $enabled_bps);
                if ($h_radius === null && $v2_data) {
                    $h_radius = $this->get_v2_value_with_inheritance($v2_data, $bp, 'radius', $enabled_bps);
                }
                $h_radius_unit = $this->get_v2_value_with_inheritance($v2_hover_data, $bp, 'radiusUnit', $enabled_bps);
                if (!$h_radius_unit && $v2_data) {
                    $h_radius_unit = $this->get_v2_value_with_inheritance($v2_data, $bp, 'radiusUnit', $enabled_bps, 'px');
                }
                if ($h_radius !== null && $h_radius !== '') {
                    $bp_vars[] = "--icon-frame-radius-{$bp}-hover: {$h_radius}{$h_radius_unit}";
                }

                // Border width hover - V2 → V1フォールバック
                $h_border_width = $this->get_v2_value_with_inheritance($v2_hover_data, $bp, 'borderWidth', $enabled_bps);
                if ($h_border_width === null && $v2_data) {
                    $h_border_width = $this->get_v2_value_with_inheritance($v2_data, $bp, 'borderWidth', $enabled_bps);
                }
                // V1属性へのフォールバック（UIがV1属性を使用している場合）
                if ($h_border_width === null) {
                    $h_border_width = $attrs["iconFrameBorderWidth{$bp_upper}Hover"] ?? $attrs["iconFrameBorderWidth{$bp_upper}"] ?? null;
                }
                $h_border_width_unit = $this->get_v2_value_with_inheritance($v2_hover_data, $bp, 'borderWidthUnit', $enabled_bps);
                if (!$h_border_width_unit && $v2_data) {
                    $h_border_width_unit = $this->get_v2_value_with_inheritance($v2_data, $bp, 'borderWidthUnit', $enabled_bps, 'px');
                }
                if (!$h_border_width_unit) {
                    $h_border_width_unit = $attrs["iconFrameBorderWidthUnit{$bp_upper}Hover"] ?? $attrs["iconFrameBorderWidthUnit{$bp_upper}"] ?? 'px';
                }
                if ($h_border_width !== null && $h_border_width !== '') {
                    $bp_vars[] = "--icon-frame-border-width-{$bp}-hover: {$h_border_width}{$h_border_width_unit}";
                    // Individual border sides hover - V2 → V1フォールバック → デフォルト値
                    // 通常状態へのフォールバックは行わない（ホバーは独立した設定）
                    $h_border_sides = $this->get_v2_value_with_inheritance($v2_hover_data, $bp, 'borderSides', $enabled_bps);
                    // V1属性へのフォールバック（UIがV1属性を使用している場合）
                    if (!$h_border_sides || !is_array($h_border_sides)) {
                        $h_border_sides = $attrs["iconFrameBorderSides{$bp_upper}Hover"] ?? $attrs['iconFrameBorderSidesHover'] ?? array('top', 'right', 'bottom', 'left');
                    }
                    if (is_array($h_border_sides)) {
                        foreach (array('top', 'right', 'bottom', 'left') as $side) {
                            $side_value = in_array($side, $h_border_sides) ? "{$h_border_width}{$h_border_width_unit}" : '0';
                            $bp_vars[] = "--icon-frame-border-{$side}-width-{$bp}-hover: {$side_value}";
                        }
                    }
                }

                // Border color hover - V2 → V1フォールバック → デフォルト値
                // 通常状態へのフォールバックは行わない（ホバーは独立した設定）
                $h_border_color = $this->get_v2_value_with_inheritance($v2_hover_data, $bp, 'borderColor', $enabled_bps);
                // V1属性へのフォールバック
                if (!$h_border_color) {
                    $h_border_color = $attrs["iconFrameBorderColor{$bp_upper}Hover"] ?? $attrs['iconFrameBorderColorHover'] ?? 'transparent';
                }
                $bp_vars[] = "--icon-frame-border-color-{$bp}-hover: " . ($h_border_color ?: 'transparent');

                // Border style hover - V1属性を優先（UIがV1属性を使用しているため）
                // ホバー属性が存在しない場合はデフォルト値(solid)を使用
                // ※WordPressはデフォルト値と同じ値を保存しないため、属性がない＝デフォルト値
                $h_border_style = $attrs["iconFrameBorderStyle{$bp_upper}Hover"] ?? null;

                // V1ホバーがなければV2ホバーを確認
                if (!$h_border_style) {
                    $h_border_style = $this->get_v2_value_with_inheritance($v2_hover_data, $bp, 'borderStyle', $enabled_bps);
                }
                // ホバー属性が存在しない場合はデフォルト値(solid)を使用
                // 通常状態へのフォールバックは行わない（ホバー時は独立した設定）
                if (!$h_border_style) {
                    $h_border_style = 'solid';
                }

                $bp_vars[] = "--icon-frame-border-style-{$bp}-hover: " . $h_border_style;

                // Background color hover - 通常状態へのフォールバックは行わない（ホバーは独立した設定）
                $h_bg_color = $this->get_v2_value_with_inheritance($v2_hover_data, $bp, 'bgColor', $enabled_bps);
                $bp_vars[] = "--icon-frame-bg-color-{$bp}-hover: " . ($h_bg_color ?: 'transparent');
            }

            // ==== V1 Processing (for blocks without V2) ====
            if (!$v2_data) {
                // V1 Size (width/height)
                $v1_use_individual = $attrs['iconFrameUseIndividualSize'] ?? false;
                if ($v1_use_individual) {
                    $v1_width = $attrs["iconFrameWidth{$bp_upper}"] ?? null;
                    $v1_width_unit = $attrs["iconFrameWidthUnit{$bp_upper}"] ?? 'px';
                    if ($v1_width !== null && $v1_width !== '') {
                        $bp_vars[] = "--icon-frame-width-{$bp}: {$v1_width}{$v1_width_unit}";
                    }
                    $v1_height = $attrs["iconFrameHeight{$bp_upper}"] ?? null;
                    $v1_height_unit = $attrs["iconFrameHeightUnit{$bp_upper}"] ?? 'px';
                    if ($v1_height !== null && $v1_height !== '') {
                        $bp_vars[] = "--icon-frame-height-{$bp}: {$v1_height}{$v1_height_unit}";
                    }
                } else {
                    $v1_size = $attrs["iconFrameSize{$bp_upper}"] ?? null;
                    $v1_size_unit = $attrs["iconFrameSizeUnit{$bp_upper}"] ?? 'px';
                    if ($v1_size !== null && $v1_size !== '') {
                        $bp_vars[] = "--icon-frame-width-{$bp}: {$v1_size}{$v1_size_unit}";
                        $bp_vars[] = "--icon-frame-height-{$bp}: {$v1_size}{$v1_size_unit}";
                    }
                }

                // V1 Radius
                $v1_radius = $attrs["iconFrameRadius{$bp_upper}"] ?? null;
                $v1_radius_unit = $attrs["iconFrameRadiusUnit{$bp_upper}"] ?? 'px';
                if ($v1_radius !== null && $v1_radius !== '') {
                    $bp_vars[] = "--icon-frame-radius-{$bp}: {$v1_radius}{$v1_radius_unit}";
                }

                // V1 Border width
                $v1_border_width = $attrs["iconFrameBorderWidth{$bp_upper}"] ?? null;
                $v1_border_width_unit = $attrs["iconFrameBorderWidthUnit{$bp_upper}"] ?? 'px';
                if ($v1_border_width !== null && $v1_border_width !== '') {
                    $bp_vars[] = "--icon-frame-border-width-{$bp}: {$v1_border_width}{$v1_border_width_unit}";
                    // Individual sides
                    $v1_border_sides = $attrs['iconFrameBorderSides'] ?? array('top', 'right', 'bottom', 'left');
                    if (is_array($v1_border_sides)) {
                        foreach (array('top', 'right', 'bottom', 'left') as $side) {
                            $side_value = in_array($side, $v1_border_sides) ? "{$v1_border_width}{$v1_border_width_unit}" : '0';
                            $bp_vars[] = "--icon-frame-border-{$side}-width-{$bp}: {$side_value}";
                        }
                    }
                }

                // V1 Border color - 常に出力（Alpha対応）
                $v1_border_color_raw = $attrs["iconFrameBorderColor{$bp_upper}"] ?? $attrs['iconFrameBorderColor'] ?? null;
                $v1_border_alpha = $attrs["iconFrameBorderColorAlpha{$bp_upper}"] ?? $attrs['iconFrameBorderColorAlpha'] ?? 1;
                $v1_border_color = $v1_border_color_raw ? $this->get_color_with_alpha($v1_border_color_raw, $v1_border_alpha) : 'transparent';
                $bp_vars[] = "--icon-frame-border-color-{$bp}: {$v1_border_color}";

                // V1 Border style - 常に出力
                $v1_border_style = $attrs["iconFrameBorderStyle{$bp_upper}"] ?? $attrs['iconFrameBorderStyle'] ?? 'solid';
                $bp_vars[] = "--icon-frame-border-style-{$bp}: {$v1_border_style}";

                // V1 Background color - 常に出力（Alpha対応 + グラデーション対応）
                $v1_use_gradient = $attrs["iconFrameBgUseGradient{$bp_upper}"] ?? $attrs['iconFrameBgUseGradient'] ?? false;
                if ($v1_use_gradient) {
                    $v1_gradient = $attrs["iconFrameBgGradient{$bp_upper}"] ?? $attrs['iconFrameBgGradient'] ?? '';
                    $bp_vars[] = "--icon-frame-bg-color-{$bp}: " . ($v1_gradient ?: 'transparent');
                } else {
                    $v1_bg_color_raw = $attrs["iconFrameBgColor{$bp_upper}"] ?? $attrs['iconFrameBgColor'] ?? null;
                    $v1_bg_alpha = $attrs["iconFrameBgColorAlpha{$bp_upper}"] ?? $attrs['iconFrameBgColorAlpha'] ?? 1;
                    $v1_bg_color = $v1_bg_color_raw ? $this->get_color_with_alpha($v1_bg_color_raw, $v1_bg_alpha) : 'transparent';
                    $bp_vars[] = "--icon-frame-bg-color-{$bp}: {$v1_bg_color}";
                }

                // ==== V1 Hover Processing ====
                // V1 Size hover
                if ($v1_use_individual) {
                    $v1_width_hover = $attrs["iconFrameWidth{$bp_upper}Hover"] ?? $attrs["iconFrameWidth{$bp_upper}"] ?? null;
                    $v1_width_unit_hover = $attrs["iconFrameWidthUnit{$bp_upper}Hover"] ?? $attrs["iconFrameWidthUnit{$bp_upper}"] ?? 'px';
                    if ($v1_width_hover !== null && $v1_width_hover !== '') {
                        $bp_vars[] = "--icon-frame-width-{$bp}-hover: {$v1_width_hover}{$v1_width_unit_hover}";
                    }
                    $v1_height_hover = $attrs["iconFrameHeight{$bp_upper}Hover"] ?? $attrs["iconFrameHeight{$bp_upper}"] ?? null;
                    $v1_height_unit_hover = $attrs["iconFrameHeightUnit{$bp_upper}Hover"] ?? $attrs["iconFrameHeightUnit{$bp_upper}"] ?? 'px';
                    if ($v1_height_hover !== null && $v1_height_hover !== '') {
                        $bp_vars[] = "--icon-frame-height-{$bp}-hover: {$v1_height_hover}{$v1_height_unit_hover}";
                    }
                } else {
                    $v1_size_hover = $attrs["iconFrameSize{$bp_upper}Hover"] ?? $attrs["iconFrameSize{$bp_upper}"] ?? null;
                    $v1_size_unit_hover = $attrs["iconFrameSizeUnit{$bp_upper}Hover"] ?? $attrs["iconFrameSizeUnit{$bp_upper}"] ?? 'px';
                    if ($v1_size_hover !== null && $v1_size_hover !== '') {
                        $bp_vars[] = "--icon-frame-width-{$bp}-hover: {$v1_size_hover}{$v1_size_unit_hover}";
                        $bp_vars[] = "--icon-frame-height-{$bp}-hover: {$v1_size_hover}{$v1_size_unit_hover}";
                    }
                }

                // V1 Radius hover
                $v1_radius_hover = $attrs["iconFrameRadius{$bp_upper}Hover"] ?? $attrs["iconFrameRadius{$bp_upper}"] ?? null;
                $v1_radius_unit_hover = $attrs["iconFrameRadiusUnit{$bp_upper}Hover"] ?? $attrs["iconFrameRadiusUnit{$bp_upper}"] ?? 'px';
                if ($v1_radius_hover !== null && $v1_radius_hover !== '') {
                    $bp_vars[] = "--icon-frame-radius-{$bp}-hover: {$v1_radius_hover}{$v1_radius_unit_hover}";
                }

                // V1 Border width hover
                $v1_border_width_hover = $attrs["iconFrameBorderWidth{$bp_upper}Hover"] ?? $attrs["iconFrameBorderWidth{$bp_upper}"] ?? null;
                $v1_border_width_unit_hover = $attrs["iconFrameBorderWidthUnit{$bp_upper}Hover"] ?? $attrs["iconFrameBorderWidthUnit{$bp_upper}"] ?? 'px';
                if ($v1_border_width_hover !== null && $v1_border_width_hover !== '') {
                    $bp_vars[] = "--icon-frame-border-width-{$bp}-hover: {$v1_border_width_hover}{$v1_border_width_unit_hover}";
                    // Individual sides hover - 通常状態へのフォールバックは行わない
                    $v1_border_sides_hover = $attrs["iconFrameBorderSides{$bp_upper}Hover"] ?? $attrs['iconFrameBorderSidesHover'] ?? array('top', 'right', 'bottom', 'left');
                    if (is_array($v1_border_sides_hover)) {
                        foreach (array('top', 'right', 'bottom', 'left') as $side) {
                            $side_value = in_array($side, $v1_border_sides_hover) ? "{$v1_border_width_hover}{$v1_border_width_unit_hover}" : '0';
                            $bp_vars[] = "--icon-frame-border-{$side}-width-{$bp}-hover: {$side_value}";
                        }
                    }
                }

                // V1 Border color hover - 通常状態へのフォールバックは行わない（Alpha対応）
                $v1_border_color_hover_raw = $attrs["iconFrameBorderColor{$bp_upper}Hover"] ?? $attrs['iconFrameBorderColorHover'] ?? null;
                $v1_border_alpha_hover = $attrs["iconFrameBorderColorAlpha{$bp_upper}Hover"] ?? $attrs['iconFrameBorderColorAlphaHover'] ?? 1;
                $v1_border_color_hover = $v1_border_color_hover_raw ? $this->get_color_with_alpha($v1_border_color_hover_raw, $v1_border_alpha_hover) : 'transparent';
                $bp_vars[] = "--icon-frame-border-color-{$bp}-hover: {$v1_border_color_hover}";

                // V1 Border style hover - ホバー属性がなければデフォルト値(solid)を使用
                // 通常状態へのフォールバックは行わない
                $v1_border_style_hover = $attrs["iconFrameBorderStyle{$bp_upper}Hover"] ?? 'solid';
                $bp_vars[] = "--icon-frame-border-style-{$bp}-hover: {$v1_border_style_hover}";

                // V1 Background color hover - 通常状態へのフォールバックは行わない（Alpha対応 + グラデーション対応）
                $v1_use_gradient_hover = $attrs["iconFrameBgUseGradient{$bp_upper}Hover"] ?? $attrs['iconFrameBgUseGradientHover'] ?? false;
                if ($v1_use_gradient_hover) {
                    $v1_gradient_hover = $attrs["iconFrameBgGradient{$bp_upper}Hover"] ?? $attrs['iconFrameBgGradientHover'] ?? '';
                    $bp_vars[] = "--icon-frame-bg-color-{$bp}-hover: " . ($v1_gradient_hover ?: 'transparent');
                } else {
                    $v1_bg_color_hover_raw = $attrs["iconFrameBgColor{$bp_upper}Hover"] ?? $attrs['iconFrameBgColorHover'] ?? null;
                    $v1_bg_alpha_hover = $attrs["iconFrameBgColorAlpha{$bp_upper}Hover"] ?? $attrs['iconFrameBgColorAlphaHover'] ?? 1;
                    $v1_bg_color_hover = $v1_bg_color_hover_raw ? $this->get_color_with_alpha($v1_bg_color_hover_raw, $v1_bg_alpha_hover) : 'transparent';
                    $bp_vars[] = "--icon-frame-bg-color-{$bp}-hover: {$v1_bg_color_hover}";
                }
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Get V2 value with inheritance from upper breakpoints
     */
    private function get_v2_value_with_inheritance($data, $target_bp, $key, $enabled_bps, $default = null) {
        if (!$data) {
            return $default;
        }

        $target_index = array_search($target_bp, $enabled_bps);
        if ($target_index === false) {
            return $default;
        }

        // Search from target BP to PC (index 0)
        for ($i = $target_index; $i >= 0; $i--) {
            $bp = $enabled_bps[$i];
            if (isset($data[$bp]) && isset($data[$bp][$key]) && $data[$bp][$key] !== '' && $data[$bp][$key] !== null) {
                return $data[$bp][$key];
            }
        }

        return $default;
    }

    /**
     * Get color with alpha
     */
    private function get_color_with_alpha($color, $alpha = 1) {
        if (!$color) {
            return null;
        }

        if ($alpha === 1 || $alpha === null) {
            return $color;
        }

        // If it's a hex color, convert to rgba
        if (strpos($color, '#') === 0) {
            $hex = ltrim($color, '#');
            if (strlen($hex) === 3) {
                $hex = $hex[0] . $hex[0] . $hex[1] . $hex[1] . $hex[2] . $hex[2];
            }
            $r = hexdec(substr($hex, 0, 2));
            $g = hexdec(substr($hex, 2, 2));
            $b = hexdec(substr($hex, 4, 2));
            return "rgba({$r}, {$g}, {$b}, {$alpha})";
        }

        return $color;
    }

    /**
     * Get background color value (supports gradient and solid color)
     */
    private function get_background_color_value($data, $bp, $enabled_bps) {
        if (!$data) {
            return null;
        }

        $use_gradient = $this->get_v2_value_with_inheritance($data, $bp, 'useGradient', $enabled_bps, false);

        if ($use_gradient) {
            $gradient = $this->get_v2_value_with_inheritance($data, $bp, 'gradient', $enabled_bps);
            if ($gradient) {
                return $gradient;
            }
        }

        $color = $this->get_v2_value_with_inheritance($data, $bp, 'color', $enabled_bps);
        if ($color) {
            // Convert solid color to gradient format for consistency
            return "linear-gradient(90deg, {$color} 0%, {$color} 100%)";
        }

        return null;
    }

    /**
     * Save CSS file
     */
    private function save_css_file($post_id, $css) {
        $file_path = $this->get_css_path($post_id);

        // Add header comment
        $header = "/* ZenBlocks Block CSS - Post ID: {$post_id} */\n";
        $header .= "/* Generated: " . current_time('mysql') . " */\n\n";

        return file_put_contents($file_path, $header . $css) !== false;
    }

    /**
     * Delete CSS file
     */
    public function delete_css_file($post_id) {
        $file_path = $this->get_css_path($post_id);
        if (file_exists($file_path)) {
            wp_delete_file($file_path);
        }
    }

    /**
     * Get CSS file path
     */
    public function get_css_path($post_id) {
        $post_id = absint($post_id);
        if ($post_id <= 0) {
            return false;
        }
        return $this->css_dir . "zenblocks-{$post_id}.css";
    }

    /**
     * Get CSS file URL
     */
    public function get_css_url($post_id) {
        $post_id = absint($post_id);
        if ($post_id <= 0) {
            return false;
        }
        return $this->upload_dir['baseurl'] . "/zenblocks/blocks/zenblocks-{$post_id}.css";
    }

    /**
     * Check if CSS file exists
     */
    public function css_file_exists($post_id) {
        return file_exists($this->get_css_path($post_id));
    }

    /**
     * Delete all cached CSS files
     *
     * @return array Result with count of deleted files
     */
    public function clear_all_css_cache() {
        $deleted_count = 0;
        $error_count = 0;

        if (!is_dir($this->css_dir)) {
            return array(
                'success' => true,
                'deleted' => 0,
                'errors' => 0,
                'message' => __('No CSS cache directory found.', 'zenblocks')
            );
        }

        // Delete both new format (zenblocks-*.css) and old format (post-*.css) for backward compatibility
        $new_files = glob($this->css_dir . 'zenblocks-*.css') ?: array();
        $old_files = glob($this->css_dir . 'post-*.css') ?: array();
        $files = array_merge($new_files, $old_files);

        if (empty($files)) {
            return array(
                'success' => true,
                'deleted' => 0,
                'errors' => 0,
                'message' => __('No cached CSS files found.', 'zenblocks')
            );
        }

        foreach ($files as $file) {
            if (is_file($file)) {
                wp_delete_file($file);
                if (!file_exists($file)) {
                    $deleted_count++;
                } else {
                    $error_count++;
                }
            }
        }

        return array(
            'success' => $error_count === 0,
            'deleted' => $deleted_count,
            'errors' => $error_count,
            'message' => sprintf(
                // translators: %d: number of deleted CSS files.
                __('Deleted %d CSS files.', 'zenblocks'),
                $deleted_count
            )
        );
    }

    /**
     * Get band CSS variables for MD/TB/SP
     */
    private function get_band_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $image_data = $attrs['bandImageV2'] ?? null;
        $image_hover_data = $attrs['bandImageV2Hover'] ?? null;
        $image_base_color_data = $attrs['bandImageBaseColorV2'] ?? null;
        $image_base_color_hover_data = $attrs['bandImageBaseColorV2Hover'] ?? null;
        $color_data = $attrs['bandColorV2'] ?? null;
        $color_hover_data = $attrs['bandColorV2Hover'] ?? null;
        $pattern_data = $attrs['bandPatternV2'] ?? null;
        $pattern_hover_data = $attrs['bandPatternV2Hover'] ?? null;
        $opacity_data = $attrs['bandOpacityV2'] ?? null;
        $opacity_hover_data = $attrs['bandOpacityV2Hover'] ?? null;
        $transform_data = $attrs['bandTransformV2'] ?? null;
        $transform_hover_data = $attrs['bandTransformV2Hover'] ?? null;

        if (!$image_data && !$image_hover_data && !$image_base_color_data && !$image_base_color_hover_data && !$color_data && !$color_hover_data && !$pattern_data && !$pattern_hover_data && !$opacity_data && !$opacity_hover_data && !$transform_data && !$transform_hover_data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();

        foreach ($responsive_bps as $bp) {
            // ==== Band Image (Normal) ====
            if ($image_data) {
                // Image URL
                $url = $this->get_v2_value_with_inheritance($image_data, $bp, 'url', $enabled_bps);
                if ($url !== null && $url !== '') {
                    $bp_vars[] = "--band-image-{$bp}: url({$url})";
                }

                // Background position
                $position = $this->get_v2_value_with_inheritance($image_data, $bp, 'focalPosition', $enabled_bps, '50% 50%');
                if ($position) {
                    $bp_vars[] = "--band-position-{$bp}: {$position}";
                }

                // Background size
                $object_fit = $this->get_v2_value_with_inheritance($image_data, $bp, 'objectFit', $enabled_bps, 'cover');
                if ($object_fit === 'fill' || $object_fit === 'none') {
                    $bg_width = $this->get_v2_value_with_inheritance($image_data, $bp, 'bgWidth', $enabled_bps, '100');
                    $bg_width_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'bgWidthUnit', $enabled_bps, '%');
                    $bg_height = $this->get_v2_value_with_inheritance($image_data, $bp, 'bgHeight', $enabled_bps, 'auto');
                    $bg_height_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'bgHeightUnit', $enabled_bps, '%');
                    $width = ($bg_width === 'auto') ? 'auto' : "{$bg_width}{$bg_width_unit}";
                    $height = ($bg_height === 'auto') ? 'auto' : "{$bg_height}{$bg_height_unit}";
                    $size = "{$width} {$height}";
                } else {
                    $size = $object_fit;
                }
                if ($size) {
                    $bp_vars[] = "--band-size-{$bp}: {$size}";
                }

                // Background repeat
                $repeat = $this->get_v2_value_with_inheritance($image_data, $bp, 'repeat', $enabled_bps, 'no-repeat');
                if ($repeat) {
                    $bp_vars[] = "--band-repeat-{$bp}: {$repeat}";
                }

                // Frame width
                $frame_width = $this->get_v2_value_with_inheritance($image_data, $bp, 'frameWidth', $enabled_bps);
                $frame_width_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'frameWidthUnit', $enabled_bps, '%');
                if ($frame_width !== null && $frame_width !== '') {
                    $bp_vars[] = "--band-frame-width-{$bp}: {$frame_width}{$frame_width_unit}";
                }

                // Frame height
                $frame_height = $this->get_v2_value_with_inheritance($image_data, $bp, 'frameHeight', $enabled_bps);
                $frame_height_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'frameHeightUnit', $enabled_bps, 'px');
                if ($frame_height !== null && $frame_height !== '') {
                    $bp_vars[] = "--band-frame-height-{$bp}: {$frame_height}{$frame_height_unit}";
                }

                // Border radius
                $radius = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderRadius', $enabled_bps);
                $radius_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderRadiusUnit', $enabled_bps, 'px');
                if ($radius !== null && $radius !== '') {
                    $bp_vars[] = "--band-radius-{$bp}: {$radius}{$radius_unit}";
                }

                // Border
                $border_width = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderWidth', $enabled_bps, 0);
                $border_style = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderStyle', $enabled_bps, 'none');
                $border_color = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderColor', $enabled_bps, 'transparent');
                $border_color_alpha = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderColorAlpha', $enabled_bps, 1);
                $border_box_sizing = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderBoxSizing', $enabled_bps, 'border-box');

                if ($border_width !== null && $border_width !== '') {
                    $bp_vars[] = "--band-border-width-{$bp}: {$border_width}px";
                }
                if ($border_style) {
                    $bp_vars[] = "--band-border-style-{$bp}: {$border_style}";
                }
                if ($border_color !== null && $border_color !== '') {
                    $border_color_value = $border_color === 'transparent' ? 'transparent' : $this->get_color_with_alpha($border_color, $border_color_alpha);
                    $bp_vars[] = "--band-border-color-{$bp}: {$border_color_value}";
                }
                if ($border_box_sizing) {
                    $bp_vars[] = "--band-box-sizing-{$bp}: {$border_box_sizing}";
                }

                // Image base color (from bandImageBaseColorV2)
                if ($image_base_color_data) {
                    $use_gradient = $this->get_v2_value_with_inheritance($image_base_color_data, $bp, 'useGradient', $enabled_bps, false);
                    $gradient = $this->get_v2_value_with_inheritance($image_base_color_data, $bp, 'gradient', $enabled_bps);
                    if ($use_gradient && $gradient) {
                        $bp_vars[] = "--band-base-gradient-{$bp}: {$gradient}";
                        $bp_vars[] = "--band-image-base-color-{$bp}: transparent";
                    } else {
                        $base_color = $this->get_v2_value_with_inheritance($image_base_color_data, $bp, 'color', $enabled_bps);
                        $base_alpha = $this->get_v2_value_with_inheritance($image_base_color_data, $bp, 'alpha', $enabled_bps, 1);
                        if ($base_color) {
                            $base_color_value = $this->get_color_with_alpha($base_color, $base_alpha);
                            $bp_vars[] = "--band-image-base-color-{$bp}: {$base_color_value}";
                        }
                    }
                }

                // Image opacity
                $img_opacity = $this->get_v2_value_with_inheritance($image_data, $bp, 'opacity', $enabled_bps);
                if ($img_opacity !== null && $img_opacity !== '') {
                    $bp_vars[] = "--band-image-opacity-{$bp}: {$img_opacity}";
                }

                // Origin-based positioning
                $origin_x = $this->get_v2_value_with_inheritance($image_data, $bp, 'originX', $enabled_bps, 'left');
                $origin_y = $this->get_v2_value_with_inheritance($image_data, $bp, 'originY', $enabled_bps, 'top');
                $offset_x = $this->get_v2_value_with_inheritance($image_data, $bp, 'offsetX', $enabled_bps, 0);
                $offset_y = $this->get_v2_value_with_inheritance($image_data, $bp, 'offsetY', $enabled_bps, 0);
                $offset_x_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'offsetXUnit', $enabled_bps, 'px');
                $offset_y_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'offsetYUnit', $enabled_bps, 'px');

                $offset_x_value = "{$offset_x}{$offset_x_unit}";
                $offset_y_value = "{$offset_y}{$offset_y_unit}";

                // X positioning
                if ($origin_x === 'center') {
                    $bp_vars[] = "--band-left-{$bp}: " . ($offset_x == 0 ? '50%' : "calc(50% + {$offset_x_value})");
                    $bp_vars[] = "--band-right-{$bp}: auto";
                    $bp_vars[] = "--band-transform-x-{$bp}: -50%";
                } else {
                    $bp_vars[] = "--band-left-{$bp}: " . ($origin_x === 'left' ? $offset_x_value : 'auto');
                    $bp_vars[] = "--band-right-{$bp}: " . ($origin_x === 'right' ? $offset_x_value : 'auto');
                    $bp_vars[] = "--band-transform-x-{$bp}: 0";
                }

                // Y positioning
                if ($origin_y === 'center') {
                    $bp_vars[] = "--band-top-{$bp}: " . ($offset_y == 0 ? '50%' : "calc(50% + {$offset_y_value})");
                    $bp_vars[] = "--band-bottom-{$bp}: auto";
                    $bp_vars[] = "--band-transform-y-{$bp}: -50%";
                } else {
                    $bp_vars[] = "--band-top-{$bp}: " . ($origin_y === 'top' ? $offset_y_value : 'auto');
                    $bp_vars[] = "--band-bottom-{$bp}: " . ($origin_y === 'bottom' ? $offset_y_value : 'auto');
                    $bp_vars[] = "--band-transform-y-{$bp}: 0";
                }
            }

            // ==== Band Image (Hover) ====
            if ($image_data || $image_hover_data) {
                // Position hover
                $h_position = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'focalPosition', $enabled_bps);
                if ($h_position === null && $image_data) {
                    $h_position = $this->get_v2_value_with_inheritance($image_data, $bp, 'focalPosition', $enabled_bps, '50% 50%');
                }
                if ($h_position) {
                    $bp_vars[] = "--band-position-{$bp}-hover: {$h_position}";
                }

                // Size hover
                $h_object_fit = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'objectFit', $enabled_bps);
                if ($h_object_fit === null && $image_data) {
                    $h_object_fit = $this->get_v2_value_with_inheritance($image_data, $bp, 'objectFit', $enabled_bps, 'cover');
                }
                if ($h_object_fit === 'fill' || $h_object_fit === 'none') {
                    $h_bg_width = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'bgWidth', $enabled_bps);
                    if ($h_bg_width === null && $image_data) {
                        $h_bg_width = $this->get_v2_value_with_inheritance($image_data, $bp, 'bgWidth', $enabled_bps, '100');
                    }
                    $h_bg_width_unit = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'bgWidthUnit', $enabled_bps);
                    if (!$h_bg_width_unit && $image_data) {
                        $h_bg_width_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'bgWidthUnit', $enabled_bps, '%');
                    }
                    $h_bg_height = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'bgHeight', $enabled_bps);
                    if ($h_bg_height === null && $image_data) {
                        $h_bg_height = $this->get_v2_value_with_inheritance($image_data, $bp, 'bgHeight', $enabled_bps, 'auto');
                    }
                    $h_bg_height_unit = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'bgHeightUnit', $enabled_bps);
                    if (!$h_bg_height_unit && $image_data) {
                        $h_bg_height_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'bgHeightUnit', $enabled_bps, '%');
                    }
                    $h_width = ($h_bg_width === 'auto') ? 'auto' : "{$h_bg_width}{$h_bg_width_unit}";
                    $h_height = ($h_bg_height === 'auto') ? 'auto' : "{$h_bg_height}{$h_bg_height_unit}";
                    $h_size = "{$h_width} {$h_height}";
                } else {
                    $h_size = $h_object_fit;
                }
                if ($h_size) {
                    $bp_vars[] = "--band-size-{$bp}-hover: {$h_size}";
                }

                // Repeat hover
                $h_repeat = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'repeat', $enabled_bps);
                if ($h_repeat === null && $image_data) {
                    $h_repeat = $this->get_v2_value_with_inheritance($image_data, $bp, 'repeat', $enabled_bps, 'no-repeat');
                }
                if ($h_repeat) {
                    $bp_vars[] = "--band-repeat-{$bp}-hover: {$h_repeat}";
                }

                // Frame width hover
                $h_frame_width = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'frameWidth', $enabled_bps);
                if ($h_frame_width === null && $image_data) {
                    $h_frame_width = $this->get_v2_value_with_inheritance($image_data, $bp, 'frameWidth', $enabled_bps);
                }
                $h_frame_width_unit = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'frameWidthUnit', $enabled_bps);
                if (!$h_frame_width_unit && $image_data) {
                    $h_frame_width_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'frameWidthUnit', $enabled_bps, '%');
                }
                if ($h_frame_width !== null && $h_frame_width !== '') {
                    $bp_vars[] = "--band-frame-width-{$bp}-hover: {$h_frame_width}{$h_frame_width_unit}";
                }

                // Frame height hover
                $h_frame_height = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'frameHeight', $enabled_bps);
                if ($h_frame_height === null && $image_data) {
                    $h_frame_height = $this->get_v2_value_with_inheritance($image_data, $bp, 'frameHeight', $enabled_bps);
                }
                $h_frame_height_unit = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'frameHeightUnit', $enabled_bps);
                if (!$h_frame_height_unit && $image_data) {
                    $h_frame_height_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'frameHeightUnit', $enabled_bps, 'px');
                }
                if ($h_frame_height !== null && $h_frame_height !== '') {
                    $bp_vars[] = "--band-frame-height-{$bp}-hover: {$h_frame_height}{$h_frame_height_unit}";
                }

                // Border radius hover
                $h_radius = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'borderRadius', $enabled_bps);
                if ($h_radius === null && $image_data) {
                    $h_radius = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderRadius', $enabled_bps);
                }
                $h_radius_unit = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'borderRadiusUnit', $enabled_bps);
                if (!$h_radius_unit && $image_data) {
                    $h_radius_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderRadiusUnit', $enabled_bps, 'px');
                }
                if ($h_radius !== null && $h_radius !== '') {
                    $bp_vars[] = "--band-radius-{$bp}-hover: {$h_radius}{$h_radius_unit}";
                }

                // Border hover
                $h_border_width = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'borderWidth', $enabled_bps);
                if ($h_border_width === null && $image_data) {
                    $h_border_width = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderWidth', $enabled_bps, 0);
                }
                $h_border_style = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'borderStyle', $enabled_bps);
                if ($h_border_style === null && $image_data) {
                    $h_border_style = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderStyle', $enabled_bps, 'none');
                }
                $h_border_color = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'borderColor', $enabled_bps);
                $h_border_color_alpha = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'borderColorAlpha', $enabled_bps);
                if ($h_border_color === null && $image_data) {
                    $h_border_color = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderColor', $enabled_bps, 'transparent');
                    $h_border_color_alpha = $h_border_color_alpha !== null ? $h_border_color_alpha : $this->get_v2_value_with_inheritance($image_data, $bp, 'borderColorAlpha', $enabled_bps, 1);
                }
                $h_border_box_sizing = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'borderBoxSizing', $enabled_bps);
                if ($h_border_box_sizing === null && $image_data) {
                    $h_border_box_sizing = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderBoxSizing', $enabled_bps, 'border-box');
                }

                if ($h_border_width !== null && $h_border_width !== '') {
                    $bp_vars[] = "--band-border-width-{$bp}-hover: {$h_border_width}px";
                }
                if ($h_border_style) {
                    $bp_vars[] = "--band-border-style-{$bp}-hover: {$h_border_style}";
                }
                if ($h_border_color !== null && $h_border_color !== '') {
                    $h_border_color_value = $h_border_color === 'transparent' ? 'transparent' : $this->get_color_with_alpha($h_border_color, $h_border_color_alpha ?? 1);
                    $bp_vars[] = "--band-border-color-{$bp}-hover: {$h_border_color_value}";
                }
                if ($h_border_box_sizing) {
                    $bp_vars[] = "--band-box-sizing-{$bp}-hover: {$h_border_box_sizing}";
                }

                // Image base color hover (from bandImageBaseColorV2Hover → bandImageBaseColorV2)
                if ($image_base_color_hover_data || $image_base_color_data) {
                    // Check gradient first
                    $h_use_gradient = $this->get_v2_value_with_inheritance($image_base_color_hover_data, $bp, 'useGradient', $enabled_bps);
                    $h_gradient = $this->get_v2_value_with_inheritance($image_base_color_hover_data, $bp, 'gradient', $enabled_bps);
                    // Fallback to normal if hover has no explicit gradient setting
                    if ($h_use_gradient === null && $image_base_color_data) {
                        $h_use_gradient = $this->get_v2_value_with_inheritance($image_base_color_data, $bp, 'useGradient', $enabled_bps, false);
                    }
                    if ($h_gradient === null && $image_base_color_data) {
                        $h_gradient = $this->get_v2_value_with_inheritance($image_base_color_data, $bp, 'gradient', $enabled_bps);
                    }

                    if ($h_use_gradient && $h_gradient) {
                        $bp_vars[] = "--band-base-gradient-{$bp}-hover: {$h_gradient}";
                        $bp_vars[] = "--band-image-base-color-{$bp}-hover: transparent";
                    } else {
                        $h_base_color = $this->get_v2_value_with_inheritance($image_base_color_hover_data, $bp, 'color', $enabled_bps);
                        $h_base_alpha = $this->get_v2_value_with_inheritance($image_base_color_hover_data, $bp, 'alpha', $enabled_bps);
                        if ($h_base_color === null && $image_base_color_data) {
                            $h_base_color = $this->get_v2_value_with_inheritance($image_base_color_data, $bp, 'color', $enabled_bps);
                            $h_base_alpha = $h_base_alpha !== null ? $h_base_alpha : $this->get_v2_value_with_inheritance($image_base_color_data, $bp, 'alpha', $enabled_bps, 1);
                        }
                        if ($h_base_color) {
                            $h_base_color_value = $this->get_color_with_alpha($h_base_color, $h_base_alpha ?? 1);
                            $bp_vars[] = "--band-image-base-color-{$bp}-hover: {$h_base_color_value}";
                            // グラデーション→単色切り替え時、単色をグラデーションとしても設定（白フラッシュ防止）
                            $bp_vars[] = "--band-base-gradient-{$bp}-hover: linear-gradient(0deg, {$h_base_color_value} 0%, {$h_base_color_value} 100%)";
                        } else {
                            $bp_vars[] = "--band-base-gradient-{$bp}-hover: none";
                        }
                    }
                }

                // Image opacity hover
                $h_img_opacity = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'opacity', $enabled_bps);
                if ($h_img_opacity === null && $image_data) {
                    $h_img_opacity = $this->get_v2_value_with_inheritance($image_data, $bp, 'opacity', $enabled_bps);
                }
                if ($h_img_opacity !== null && $h_img_opacity !== '') {
                    $bp_vars[] = "--band-image-opacity-{$bp}-hover: {$h_img_opacity}";
                }

                // Origin-based positioning hover
                $h_origin_x = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'originX', $enabled_bps);
                $h_origin_y = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'originY', $enabled_bps);
                $h_offset_x = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'offsetX', $enabled_bps);
                $h_offset_y = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'offsetY', $enabled_bps);

                // Fallback to normal values if hover not set
                if ($h_origin_x === null && $image_data) {
                    $h_origin_x = $this->get_v2_value_with_inheritance($image_data, $bp, 'originX', $enabled_bps, 'left');
                }
                if ($h_origin_y === null && $image_data) {
                    $h_origin_y = $this->get_v2_value_with_inheritance($image_data, $bp, 'originY', $enabled_bps, 'top');
                }
                if ($h_offset_x === null && $image_data) {
                    $h_offset_x = $this->get_v2_value_with_inheritance($image_data, $bp, 'offsetX', $enabled_bps, 0);
                }
                if ($h_offset_y === null && $image_data) {
                    $h_offset_y = $this->get_v2_value_with_inheritance($image_data, $bp, 'offsetY', $enabled_bps, 0);
                }

                $h_offset_x_unit = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'offsetXUnit', $enabled_bps);
                if (!$h_offset_x_unit && $image_data) {
                    $h_offset_x_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'offsetXUnit', $enabled_bps, 'px');
                }
                $h_offset_y_unit = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'offsetYUnit', $enabled_bps);
                if (!$h_offset_y_unit && $image_data) {
                    $h_offset_y_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'offsetYUnit', $enabled_bps, 'px');
                }

                if ($h_origin_x !== null || $h_origin_y !== null) {
                    $h_offset_x_value = "{$h_offset_x}{$h_offset_x_unit}";
                    $h_offset_y_value = "{$h_offset_y}{$h_offset_y_unit}";

                    // X positioning hover
                    if ($h_origin_x === 'center') {
                        $bp_vars[] = "--band-left-{$bp}-hover: " . ($h_offset_x == 0 ? '50%' : "calc(50% + {$h_offset_x_value})");
                        $bp_vars[] = "--band-right-{$bp}-hover: auto";
                        $bp_vars[] = "--band-transform-x-{$bp}-hover: -50%";
                    } else {
                        $bp_vars[] = "--band-left-{$bp}-hover: " . ($h_origin_x === 'left' ? $h_offset_x_value : 'auto');
                        $bp_vars[] = "--band-right-{$bp}-hover: " . ($h_origin_x === 'right' ? $h_offset_x_value : 'auto');
                        $bp_vars[] = "--band-transform-x-{$bp}-hover: 0";
                    }

                    // Y positioning hover
                    if ($h_origin_y === 'center') {
                        $bp_vars[] = "--band-top-{$bp}-hover: " . ($h_offset_y == 0 ? '50%' : "calc(50% + {$h_offset_y_value})");
                        $bp_vars[] = "--band-bottom-{$bp}-hover: auto";
                        $bp_vars[] = "--band-transform-y-{$bp}-hover: -50%";
                    } else {
                        $bp_vars[] = "--band-top-{$bp}-hover: " . ($h_origin_y === 'top' ? $h_offset_y_value : 'auto');
                        $bp_vars[] = "--band-bottom-{$bp}-hover: " . ($h_origin_y === 'bottom' ? $h_offset_y_value : 'auto');
                        $bp_vars[] = "--band-transform-y-{$bp}-hover: 0";
                    }
                }
            }

            // ==== Band Color (Normal) ====
            if ($color_data) {
                $use_gradient = $this->get_v2_value_with_inheritance($color_data, $bp, 'useGradient', $enabled_bps, false);
                $gradient = $this->get_v2_value_with_inheritance($color_data, $bp, 'gradient', $enabled_bps);
                $color = $this->get_v2_value_with_inheritance($color_data, $bp, 'color', $enabled_bps, 'transparent');
                $opacity = $this->get_v2_value_with_inheritance($color_data, $bp, 'opacity', $enabled_bps, 1);
                $mix_blend = $this->get_v2_value_with_inheritance($color_data, $bp, 'mixBlendMode', $enabled_bps, 'normal');

                // 単色もlinear-gradient()でラップ（background-image互換 — 背景カラーと同じ方式）
                $effective_color = $color ?: 'transparent';
                $color_value = ($use_gradient && $gradient) ? $gradient : "linear-gradient(90deg, {$effective_color} 0%, {$effective_color} 100%)";
                $bp_vars[] = "--band-color-{$bp}: {$color_value}";
                $bp_vars[] = "--band-color-opacity-{$bp}: {$opacity}";
                $bp_vars[] = "--band-color-blend-mode-{$bp}: {$mix_blend}";
            }

            // ==== Band Color (Hover) ====
            if ($color_data || $color_hover_data) {
                $h_use_gradient = $this->get_v2_value_with_inheritance($color_hover_data, $bp, 'useGradient', $enabled_bps);
                $h_gradient = $this->get_v2_value_with_inheritance($color_hover_data, $bp, 'gradient', $enabled_bps);
                $h_color = $this->get_v2_value_with_inheritance($color_hover_data, $bp, 'color', $enabled_bps);
                $h_opacity = $this->get_v2_value_with_inheritance($color_hover_data, $bp, 'opacity', $enabled_bps);
                $h_mix_blend = $this->get_v2_value_with_inheritance($color_hover_data, $bp, 'mixBlendMode', $enabled_bps);

                // ホバーに明示的なcolor/gradientが設定されていない場合、useGradientはnormal側にフォールバック
                $has_explicit_hover = ($h_color !== null) || ($h_gradient !== null);
                if (!$has_explicit_hover) {
                    $h_use_gradient = null;
                }

                // Fallback to normal values if hover not set
                if ($h_use_gradient === null && $color_data) {
                    $h_use_gradient = $this->get_v2_value_with_inheritance($color_data, $bp, 'useGradient', $enabled_bps, false);
                }
                if ($h_gradient === null && $color_data) {
                    $h_gradient = $this->get_v2_value_with_inheritance($color_data, $bp, 'gradient', $enabled_bps);
                }
                if ($h_color === null && $color_data) {
                    $h_color = $this->get_v2_value_with_inheritance($color_data, $bp, 'color', $enabled_bps, 'transparent');
                }
                if ($h_opacity === null && $color_data) {
                    $h_opacity = $this->get_v2_value_with_inheritance($color_data, $bp, 'opacity', $enabled_bps, 1);
                }
                if ($h_mix_blend === null && $color_data) {
                    $h_mix_blend = $this->get_v2_value_with_inheritance($color_data, $bp, 'mixBlendMode', $enabled_bps, 'normal');
                }

                // 単色もlinear-gradient()でラップ（background-image互換 — 背景カラーと同じ方式）
                $h_effective_color = $h_color ?: 'transparent';
                $h_color_value = ($h_use_gradient && $h_gradient) ? $h_gradient : "linear-gradient(90deg, {$h_effective_color} 0%, {$h_effective_color} 100%)";
                if ($h_color_value) {
                    $bp_vars[] = "--band-color-{$bp}-hover: {$h_color_value}";
                }
                if ($h_opacity !== null) {
                    $bp_vars[] = "--band-color-opacity-{$bp}-hover: {$h_opacity}";
                }
                if ($h_mix_blend) {
                    $bp_vars[] = "--band-color-blend-mode-{$bp}-hover: {$h_mix_blend}";
                }
            }

            // ==== Band Pattern (Normal) ====
            if ($pattern_data) {
                $p_type = $this->get_v2_value_with_inheritance($pattern_data, $bp, 'type', $enabled_bps);
                $p_color = $this->get_v2_value_with_inheritance($pattern_data, $bp, 'color', $enabled_bps, '#000000');
                $p_opacity = $this->get_v2_value_with_inheritance($pattern_data, $bp, 'opacity', $enabled_bps, 0.5);
                $p_size = $this->get_v2_value_with_inheritance($pattern_data, $bp, 'size', $enabled_bps, 3);
                $p_size_unit = $this->get_v2_value_with_inheritance($pattern_data, $bp, 'sizeUnit', $enabled_bps, 'px');
                $p_blend = $this->get_v2_value_with_inheritance($pattern_data, $bp, 'mixBlendMode', $enabled_bps, 'normal');

                if ($p_type && $p_type !== 'none') {
                    $bp_vars[] = "--band-pattern-type-{$bp}: {$p_type}";
                    $bp_vars[] = "--band-pattern-color-{$bp}: {$p_color}";
                    $bp_vars[] = "--band-pattern-opacity-{$bp}: {$p_opacity}";
                    $bp_vars[] = "--band-pattern-size-{$bp}: {$p_size}{$p_size_unit}";
                    $bp_vars[] = "--band-pattern-blend-mode-{$bp}: {$p_blend}";
                }
            }

            // ==== Band Pattern (Hover) ====
            if ($pattern_data || $pattern_hover_data) {
                $hp_type = $this->get_v2_value_with_inheritance($pattern_hover_data, $bp, 'type', $enabled_bps);
                $hp_color = $this->get_v2_value_with_inheritance($pattern_hover_data, $bp, 'color', $enabled_bps);
                $hp_opacity = $this->get_v2_value_with_inheritance($pattern_hover_data, $bp, 'opacity', $enabled_bps);
                $hp_size = $this->get_v2_value_with_inheritance($pattern_hover_data, $bp, 'size', $enabled_bps);
                $hp_size_unit = $this->get_v2_value_with_inheritance($pattern_hover_data, $bp, 'sizeUnit', $enabled_bps);
                $hp_blend = $this->get_v2_value_with_inheritance($pattern_hover_data, $bp, 'mixBlendMode', $enabled_bps);

                // Fallback to normal values if hover not set
                if ($hp_type === null && $pattern_data) {
                    $hp_type = $this->get_v2_value_with_inheritance($pattern_data, $bp, 'type', $enabled_bps);
                }
                if ($hp_color === null && $pattern_data) {
                    $hp_color = $this->get_v2_value_with_inheritance($pattern_data, $bp, 'color', $enabled_bps, '#000000');
                }
                if ($hp_opacity === null && $pattern_data) {
                    $hp_opacity = $this->get_v2_value_with_inheritance($pattern_data, $bp, 'opacity', $enabled_bps, 0.5);
                }
                if ($hp_size === null && $pattern_data) {
                    $hp_size = $this->get_v2_value_with_inheritance($pattern_data, $bp, 'size', $enabled_bps, 3);
                }
                if (!$hp_size_unit && $pattern_data) {
                    $hp_size_unit = $this->get_v2_value_with_inheritance($pattern_data, $bp, 'sizeUnit', $enabled_bps, 'px');
                }
                if ($hp_blend === null && $pattern_data) {
                    $hp_blend = $this->get_v2_value_with_inheritance($pattern_data, $bp, 'mixBlendMode', $enabled_bps, 'normal');
                }

                if ($hp_type && $hp_type !== 'none') {
                    $bp_vars[] = "--band-pattern-type-{$bp}-hover: {$hp_type}";
                    if ($hp_color) {
                        $bp_vars[] = "--band-pattern-color-{$bp}-hover: {$hp_color}";
                    }
                    if ($hp_opacity !== null) {
                        $bp_vars[] = "--band-pattern-opacity-{$bp}-hover: {$hp_opacity}";
                    }
                    if ($hp_size !== null) {
                        $bp_vars[] = "--band-pattern-size-{$bp}-hover: {$hp_size}{$hp_size_unit}";
                    }
                    if ($hp_blend) {
                        $bp_vars[] = "--band-pattern-blend-mode-{$bp}-hover: {$hp_blend}";
                    }
                }
            }

            // ==== Band Opacity (Normal) ====
            if ($opacity_data) {
                $band_opacity = $this->get_v2_value_with_inheritance($opacity_data, $bp, 'value', $enabled_bps, 100);
                $band_blend = $this->get_v2_value_with_inheritance($opacity_data, $bp, 'mixBlendMode', $enabled_bps, 'normal');

                if ($band_opacity !== null && $band_opacity !== '') {
                    $bp_vars[] = "--band-opacity-{$bp}: " . ($band_opacity / 100);
                }
                if ($band_blend) {
                    $bp_vars[] = "--band-blend-mode-{$bp}: {$band_blend}";
                }
            }

            // ==== Band Opacity (Hover) ====
            if ($opacity_data || $opacity_hover_data) {
                $h_band_opacity = $this->get_v2_value_with_inheritance($opacity_hover_data, $bp, 'value', $enabled_bps);
                $h_band_blend = $this->get_v2_value_with_inheritance($opacity_hover_data, $bp, 'mixBlendMode', $enabled_bps);

                // Fallback to normal values if hover not set
                if ($h_band_opacity === null && $opacity_data) {
                    $h_band_opacity = $this->get_v2_value_with_inheritance($opacity_data, $bp, 'value', $enabled_bps, 100);
                }
                if ($h_band_blend === null && $opacity_data) {
                    $h_band_blend = $this->get_v2_value_with_inheritance($opacity_data, $bp, 'mixBlendMode', $enabled_bps, 'normal');
                }

                if ($h_band_opacity !== null && $h_band_opacity !== '') {
                    $bp_vars[] = "--band-opacity-{$bp}-hover: " . ($h_band_opacity / 100);
                }
                if ($h_band_blend) {
                    $bp_vars[] = "--band-blend-mode-{$bp}-hover: {$h_band_blend}";
                }
            }

            // ==== Band Transform (Normal) ====
            if ($transform_data) {
                $skew_x = $this->get_v2_value_with_inheritance($transform_data, $bp, 'skewX', $enabled_bps, 0);
                $skew_y = $this->get_v2_value_with_inheritance($transform_data, $bp, 'skewY', $enabled_bps, 0);

                if ($skew_x !== null && $skew_x !== '') {
                    $bp_vars[] = "--band-skew-x-{$bp}: {$skew_x}deg";
                }
                if ($skew_y !== null && $skew_y !== '') {
                    $bp_vars[] = "--band-skew-y-{$bp}: {$skew_y}deg";
                }
            }

            // ==== Band Transform (Hover) ====
            if ($transform_data || $transform_hover_data) {
                $h_skew_x = $this->get_v2_value_with_inheritance($transform_hover_data, $bp, 'skewX', $enabled_bps);
                $h_skew_y = $this->get_v2_value_with_inheritance($transform_hover_data, $bp, 'skewY', $enabled_bps);

                // Fallback to normal values if hover not set
                if ($h_skew_x === null && $transform_data) {
                    $h_skew_x = $this->get_v2_value_with_inheritance($transform_data, $bp, 'skewX', $enabled_bps, 0);
                }
                if ($h_skew_y === null && $transform_data) {
                    $h_skew_y = $this->get_v2_value_with_inheritance($transform_data, $bp, 'skewY', $enabled_bps, 0);
                }

                if ($h_skew_x !== null && $h_skew_x !== '') {
                    $bp_vars[] = "--band-skew-x-{$bp}-hover: {$h_skew_x}deg";
                }
                if ($h_skew_y !== null && $h_skew_y !== '') {
                    $bp_vars[] = "--band-skew-y-{$bp}-hover: {$h_skew_y}deg";
                }
            }

        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Get thumbnail CSS variables for MD/TB/SP
     * Origin-based positioning (left/right/top/bottom + transform)
     */
    private function get_thumbnail_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $image_data = $attrs['thumbnailImageV2'] ?? null;
        $image_hover_data = $attrs['thumbnailImageV2Hover'] ?? null;
        $color_data = $attrs['thumbnailColorV2'] ?? null;
        $color_hover_data = $attrs['thumbnailColorV2Hover'] ?? null;
        $opacity_data = $attrs['thumbnailOpacityV2'] ?? null;
        $opacity_hover_data = $attrs['thumbnailOpacityV2Hover'] ?? null;

        if (!$image_data && !$image_hover_data && !$color_data && !$color_hover_data && !$opacity_data && !$opacity_hover_data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();

        foreach ($responsive_bps as $bp) {
            // ==== Thumbnail Image (Normal) ====
            if ($image_data) {
                // Image URL
                $url = $this->get_v2_value_with_inheritance($image_data, $bp, 'url', $enabled_bps);
                if ($url !== null && $url !== '') {
                    $bp_vars[] = "--thumbnail-image-{$bp}: url({$url})";
                }

                // Background position
                $position = $this->get_v2_value_with_inheritance($image_data, $bp, 'focalPosition', $enabled_bps, '50% 50%');
                if ($position) {
                    $bp_vars[] = "--thumbnail-position-{$bp}: {$position}";
                }

                // Background size
                $object_fit = $this->get_v2_value_with_inheritance($image_data, $bp, 'objectFit', $enabled_bps, 'cover');
                if ($object_fit === 'fill' || $object_fit === 'none') {
                    $bg_width = $this->get_v2_value_with_inheritance($image_data, $bp, 'bgWidth', $enabled_bps, '100');
                    $bg_width_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'bgWidthUnit', $enabled_bps, '%');
                    $bg_height = $this->get_v2_value_with_inheritance($image_data, $bp, 'bgHeight', $enabled_bps, 'auto');
                    $bg_height_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'bgHeightUnit', $enabled_bps, '%');
                    $width = ($bg_width === 'auto') ? 'auto' : "{$bg_width}{$bg_width_unit}";
                    $height = ($bg_height === 'auto') ? 'auto' : "{$bg_height}{$bg_height_unit}";
                    $size = "{$width} {$height}";
                } else {
                    $size = $object_fit;
                }
                if ($size) {
                    $bp_vars[] = "--thumbnail-size-{$bp}: {$size}";
                }

                // Background repeat
                $repeat = $this->get_v2_value_with_inheritance($image_data, $bp, 'repeat', $enabled_bps, 'no-repeat');
                if ($repeat) {
                    $bp_vars[] = "--thumbnail-repeat-{$bp}: {$repeat}";
                }

                // Frame width
                $frame_width = $this->get_v2_value_with_inheritance($image_data, $bp, 'frameWidth', $enabled_bps);
                $frame_width_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'frameWidthUnit', $enabled_bps, 'px');
                if ($frame_width !== null && $frame_width !== '') {
                    $bp_vars[] = "--thumbnail-frame-width-{$bp}: {$frame_width}{$frame_width_unit}";
                }

                // Frame height
                $frame_height = $this->get_v2_value_with_inheritance($image_data, $bp, 'frameHeight', $enabled_bps);
                $frame_height_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'frameHeightUnit', $enabled_bps, 'px');
                if ($frame_height !== null && $frame_height !== '') {
                    $bp_vars[] = "--thumbnail-frame-height-{$bp}: {$frame_height}{$frame_height_unit}";
                }

                // Border radius
                $radius = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderRadius', $enabled_bps);
                $radius_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderRadiusUnit', $enabled_bps, 'px');
                if ($radius !== null && $radius !== '') {
                    $bp_vars[] = "--thumbnail-radius-{$bp}: {$radius}{$radius_unit}";
                }

                // Border
                $border_width = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderWidth', $enabled_bps, 0);
                $border_style = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderStyle', $enabled_bps, 'none');
                $border_color = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderColor', $enabled_bps, 'transparent');
                $border_color_alpha = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderColorAlpha', $enabled_bps, 1);
                $border_box_sizing = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderBoxSizing', $enabled_bps, 'border-box');
                $bp_vars[] = "--thumbnail-border-width-{$bp}: {$border_width}px";
                $bp_vars[] = "--thumbnail-border-style-{$bp}: {$border_style}";
                $bp_vars[] = "--thumbnail-border-color-{$bp}: " . ($border_color === 'transparent' ? 'transparent' : $this->get_color_with_alpha($border_color, $border_color_alpha));
                $bp_vars[] = "--thumbnail-box-sizing-{$bp}: {$border_box_sizing}";

                // Image base color
                $base_color = $this->get_v2_value_with_inheritance($image_data, $bp, 'color', $enabled_bps);
                $base_alpha = $this->get_v2_value_with_inheritance($image_data, $bp, 'alpha', $enabled_bps, 1);
                if ($base_color) {
                    $base_color_value = $this->get_color_with_alpha($base_color, $base_alpha);
                    $bp_vars[] = "--thumbnail-image-base-color-{$bp}: {$base_color_value}";
                }

                // Origin-based positioning
                $origin_x = $this->get_v2_value_with_inheritance($image_data, $bp, 'originX', $enabled_bps, 'left');
                $origin_y = $this->get_v2_value_with_inheritance($image_data, $bp, 'originY', $enabled_bps, 'top');
                $offset_x = $this->get_v2_value_with_inheritance($image_data, $bp, 'offsetX', $enabled_bps, 0);
                $offset_y = $this->get_v2_value_with_inheritance($image_data, $bp, 'offsetY', $enabled_bps, 0);
                $offset_x_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'offsetXUnit', $enabled_bps, '%');
                $offset_y_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'offsetYUnit', $enabled_bps, '%');

                $offset_x_value = "{$offset_x}{$offset_x_unit}";
                $offset_y_value = "{$offset_y}{$offset_y_unit}";

                // X positioning
                if ($origin_x === 'center') {
                    $bp_vars[] = "--thumbnail-left-{$bp}: " . ($offset_x == 0 ? '50%' : "calc(50% + {$offset_x_value})");
                    $bp_vars[] = "--thumbnail-right-{$bp}: auto";
                    $bp_vars[] = "--thumbnail-transform-x-{$bp}: -50%";
                } else {
                    $bp_vars[] = "--thumbnail-left-{$bp}: " . ($origin_x === 'left' ? $offset_x_value : 'auto');
                    $bp_vars[] = "--thumbnail-right-{$bp}: " . ($origin_x === 'right' ? $offset_x_value : 'auto');
                    $bp_vars[] = "--thumbnail-transform-x-{$bp}: 0";
                }

                // Y positioning
                if ($origin_y === 'center') {
                    $bp_vars[] = "--thumbnail-top-{$bp}: " . ($offset_y == 0 ? '50%' : "calc(50% + {$offset_y_value})");
                    $bp_vars[] = "--thumbnail-bottom-{$bp}: auto";
                    $bp_vars[] = "--thumbnail-transform-y-{$bp}: -50%";
                } else {
                    $bp_vars[] = "--thumbnail-top-{$bp}: " . ($origin_y === 'top' ? $offset_y_value : 'auto');
                    $bp_vars[] = "--thumbnail-bottom-{$bp}: " . ($origin_y === 'bottom' ? $offset_y_value : 'auto');
                    $bp_vars[] = "--thumbnail-transform-y-{$bp}: 0";
                }
            }

            // ==== Thumbnail Image (Hover) ====
            if ($image_data || $image_hover_data) {
                // Position hover
                $h_position = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'focalPosition', $enabled_bps);
                if ($h_position === null && $image_data) {
                    $h_position = $this->get_v2_value_with_inheritance($image_data, $bp, 'focalPosition', $enabled_bps, '50% 50%');
                }
                if ($h_position) {
                    $bp_vars[] = "--thumbnail-position-{$bp}-hover: {$h_position}";
                }

                // Size hover
                $h_object_fit = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'objectFit', $enabled_bps);
                if ($h_object_fit === null && $image_data) {
                    $h_object_fit = $this->get_v2_value_with_inheritance($image_data, $bp, 'objectFit', $enabled_bps, 'cover');
                }
                if ($h_object_fit === 'fill' || $h_object_fit === 'none') {
                    $h_bg_width = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'bgWidth', $enabled_bps);
                    if ($h_bg_width === null && $image_data) {
                        $h_bg_width = $this->get_v2_value_with_inheritance($image_data, $bp, 'bgWidth', $enabled_bps, '100');
                    }
                    $h_bg_width_unit = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'bgWidthUnit', $enabled_bps);
                    if (!$h_bg_width_unit && $image_data) {
                        $h_bg_width_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'bgWidthUnit', $enabled_bps, '%');
                    }
                    $h_bg_height = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'bgHeight', $enabled_bps);
                    if ($h_bg_height === null && $image_data) {
                        $h_bg_height = $this->get_v2_value_with_inheritance($image_data, $bp, 'bgHeight', $enabled_bps, 'auto');
                    }
                    $h_bg_height_unit = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'bgHeightUnit', $enabled_bps);
                    if (!$h_bg_height_unit && $image_data) {
                        $h_bg_height_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'bgHeightUnit', $enabled_bps, '%');
                    }
                    $h_width = ($h_bg_width === 'auto') ? 'auto' : "{$h_bg_width}{$h_bg_width_unit}";
                    $h_height = ($h_bg_height === 'auto') ? 'auto' : "{$h_bg_height}{$h_bg_height_unit}";
                    $h_size = "{$h_width} {$h_height}";
                } else {
                    $h_size = $h_object_fit;
                }
                if ($h_size) {
                    $bp_vars[] = "--thumbnail-size-{$bp}-hover: {$h_size}";
                }

                // Repeat hover
                $h_repeat = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'repeat', $enabled_bps);
                if ($h_repeat === null && $image_data) {
                    $h_repeat = $this->get_v2_value_with_inheritance($image_data, $bp, 'repeat', $enabled_bps, 'no-repeat');
                }
                if ($h_repeat) {
                    $bp_vars[] = "--thumbnail-repeat-{$bp}-hover: {$h_repeat}";
                }

                // Frame width hover
                $h_frame_width = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'frameWidth', $enabled_bps);
                if ($h_frame_width === null && $image_data) {
                    $h_frame_width = $this->get_v2_value_with_inheritance($image_data, $bp, 'frameWidth', $enabled_bps);
                }
                $h_frame_width_unit = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'frameWidthUnit', $enabled_bps);
                if (!$h_frame_width_unit && $image_data) {
                    $h_frame_width_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'frameWidthUnit', $enabled_bps, 'px');
                }
                if ($h_frame_width !== null && $h_frame_width !== '') {
                    $bp_vars[] = "--thumbnail-frame-width-{$bp}-hover: {$h_frame_width}{$h_frame_width_unit}";
                }

                // Frame height hover
                $h_frame_height = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'frameHeight', $enabled_bps);
                if ($h_frame_height === null && $image_data) {
                    $h_frame_height = $this->get_v2_value_with_inheritance($image_data, $bp, 'frameHeight', $enabled_bps);
                }
                $h_frame_height_unit = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'frameHeightUnit', $enabled_bps);
                if (!$h_frame_height_unit && $image_data) {
                    $h_frame_height_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'frameHeightUnit', $enabled_bps, 'px');
                }
                if ($h_frame_height !== null && $h_frame_height !== '') {
                    $bp_vars[] = "--thumbnail-frame-height-{$bp}-hover: {$h_frame_height}{$h_frame_height_unit}";
                }

                // Border radius hover
                $h_radius = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'borderRadius', $enabled_bps);
                if ($h_radius === null && $image_data) {
                    $h_radius = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderRadius', $enabled_bps);
                }
                $h_radius_unit = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'borderRadiusUnit', $enabled_bps);
                if (!$h_radius_unit && $image_data) {
                    $h_radius_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderRadiusUnit', $enabled_bps, 'px');
                }
                if ($h_radius !== null && $h_radius !== '') {
                    $bp_vars[] = "--thumbnail-radius-{$bp}-hover: {$h_radius}{$h_radius_unit}";
                }

                // Border hover
                $h_border_width = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'borderWidth', $enabled_bps);
                if ($h_border_width === null && $image_data) {
                    $h_border_width = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderWidth', $enabled_bps, 0);
                }
                $h_border_style = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'borderStyle', $enabled_bps);
                if ($h_border_style === null && $image_data) {
                    $h_border_style = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderStyle', $enabled_bps, 'none');
                }
                $h_border_color = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'borderColor', $enabled_bps);
                if ($h_border_color === null && $image_data) {
                    $h_border_color = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderColor', $enabled_bps, 'transparent');
                }
                $h_border_color_alpha = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'borderColorAlpha', $enabled_bps);
                if ($h_border_color_alpha === null && $image_data) {
                    $h_border_color_alpha = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderColorAlpha', $enabled_bps, 1);
                }
                $h_border_box_sizing = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'borderBoxSizing', $enabled_bps);
                if ($h_border_box_sizing === null && $image_data) {
                    $h_border_box_sizing = $this->get_v2_value_with_inheritance($image_data, $bp, 'borderBoxSizing', $enabled_bps, 'border-box');
                }
                if ($h_border_width !== null && $h_border_width !== '') {
                    $bp_vars[] = "--thumbnail-border-width-{$bp}-hover: {$h_border_width}px";
                }
                if ($h_border_style) {
                    $bp_vars[] = "--thumbnail-border-style-{$bp}-hover: {$h_border_style}";
                }
                if ($h_border_color !== null && $h_border_color !== '') {
                    $bp_vars[] = "--thumbnail-border-color-{$bp}-hover: " . ($h_border_color === 'transparent' ? 'transparent' : $this->get_color_with_alpha($h_border_color, $h_border_color_alpha ?? 1));
                }
                if ($h_border_box_sizing) {
                    $bp_vars[] = "--thumbnail-box-sizing-{$bp}-hover: {$h_border_box_sizing}";
                }

                // Image base color hover
                $h_base_color = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'color', $enabled_bps);
                $h_base_alpha = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'alpha', $enabled_bps);
                if ($h_base_color === null && $image_data) {
                    $h_base_color = $this->get_v2_value_with_inheritance($image_data, $bp, 'color', $enabled_bps);
                    $h_base_alpha = $h_base_alpha !== null ? $h_base_alpha : $this->get_v2_value_with_inheritance($image_data, $bp, 'alpha', $enabled_bps, 1);
                }
                if ($h_base_color) {
                    $h_base_color_value = $this->get_color_with_alpha($h_base_color, $h_base_alpha ?? 1);
                    $bp_vars[] = "--thumbnail-image-base-color-{$bp}-hover: {$h_base_color_value}";
                }

                // Origin-based positioning hover
                $h_origin_x = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'originX', $enabled_bps);
                $h_origin_y = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'originY', $enabled_bps);
                $h_offset_x = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'offsetX', $enabled_bps);
                $h_offset_y = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'offsetY', $enabled_bps);

                // Fallback to normal values if hover not set
                if ($h_origin_x === null && $image_data) {
                    $h_origin_x = $this->get_v2_value_with_inheritance($image_data, $bp, 'originX', $enabled_bps, 'left');
                }
                if ($h_origin_y === null && $image_data) {
                    $h_origin_y = $this->get_v2_value_with_inheritance($image_data, $bp, 'originY', $enabled_bps, 'top');
                }
                if ($h_offset_x === null && $image_data) {
                    $h_offset_x = $this->get_v2_value_with_inheritance($image_data, $bp, 'offsetX', $enabled_bps, 0);
                }
                if ($h_offset_y === null && $image_data) {
                    $h_offset_y = $this->get_v2_value_with_inheritance($image_data, $bp, 'offsetY', $enabled_bps, 0);
                }

                $h_offset_x_unit = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'offsetXUnit', $enabled_bps);
                if (!$h_offset_x_unit && $image_data) {
                    $h_offset_x_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'offsetXUnit', $enabled_bps, '%');
                }
                $h_offset_y_unit = $this->get_v2_value_with_inheritance($image_hover_data, $bp, 'offsetYUnit', $enabled_bps);
                if (!$h_offset_y_unit && $image_data) {
                    $h_offset_y_unit = $this->get_v2_value_with_inheritance($image_data, $bp, 'offsetYUnit', $enabled_bps, '%');
                }

                if ($h_origin_x !== null || $h_origin_y !== null) {
                    $h_offset_x_value = "{$h_offset_x}{$h_offset_x_unit}";
                    $h_offset_y_value = "{$h_offset_y}{$h_offset_y_unit}";

                    // X positioning hover
                    if ($h_origin_x === 'center') {
                        $bp_vars[] = "--thumbnail-left-{$bp}-hover: " . ($h_offset_x == 0 ? '50%' : "calc(50% + {$h_offset_x_value})");
                        $bp_vars[] = "--thumbnail-right-{$bp}-hover: auto";
                        $bp_vars[] = "--thumbnail-transform-x-{$bp}-hover: -50%";
                    } else {
                        $bp_vars[] = "--thumbnail-left-{$bp}-hover: " . ($h_origin_x === 'left' ? $h_offset_x_value : 'auto');
                        $bp_vars[] = "--thumbnail-right-{$bp}-hover: " . ($h_origin_x === 'right' ? $h_offset_x_value : 'auto');
                        $bp_vars[] = "--thumbnail-transform-x-{$bp}-hover: 0";
                    }

                    // Y positioning hover
                    if ($h_origin_y === 'center') {
                        $bp_vars[] = "--thumbnail-top-{$bp}-hover: " . ($h_offset_y == 0 ? '50%' : "calc(50% + {$h_offset_y_value})");
                        $bp_vars[] = "--thumbnail-bottom-{$bp}-hover: auto";
                        $bp_vars[] = "--thumbnail-transform-y-{$bp}-hover: -50%";
                    } else {
                        $bp_vars[] = "--thumbnail-top-{$bp}-hover: " . ($h_origin_y === 'top' ? $h_offset_y_value : 'auto');
                        $bp_vars[] = "--thumbnail-bottom-{$bp}-hover: " . ($h_origin_y === 'bottom' ? $h_offset_y_value : 'auto');
                        $bp_vars[] = "--thumbnail-transform-y-{$bp}-hover: 0";
                    }
                }
            }

            // ==== Thumbnail Color (Normal) ====
            // Only output if breakpoint has been modified from block.json default
            // Default: color='', gradient='', useGradient=false/null, opacity=0, mixBlendMode=''
            if ($color_data && !$this->is_thumbnail_color_default($color_data, $bp)) {
                $use_gradient = $this->get_v2_value_with_inheritance($color_data, $bp, 'useGradient', $enabled_bps, false);
                $gradient = $this->get_v2_value_with_inheritance($color_data, $bp, 'gradient', $enabled_bps);
                $color = $this->get_v2_value_with_inheritance($color_data, $bp, 'color', $enabled_bps, 'transparent');
                $opacity = $this->get_v2_value_with_inheritance($color_data, $bp, 'opacity', $enabled_bps, 1);
                $mix_blend = $this->get_v2_value_with_inheritance($color_data, $bp, 'mixBlendMode', $enabled_bps, 'normal');

                $color_value = ($use_gradient && $gradient) ? $gradient : $color;
                $bp_vars[] = "--thumbnail-color-{$bp}: {$color_value}";
                $bp_vars[] = "--thumbnail-color-opacity-{$bp}: {$opacity}";
                $bp_vars[] = "--thumbnail-color-blend-mode-{$bp}: {$mix_blend}";
            }

            // ==== Thumbnail Color (Hover) ====
            if ($color_hover_data && !$this->is_thumbnail_color_default($color_hover_data, $bp)) {
                $h_use_gradient = $this->get_v2_value_with_inheritance($color_hover_data, $bp, 'useGradient', $enabled_bps);
                $h_gradient = $this->get_v2_value_with_inheritance($color_hover_data, $bp, 'gradient', $enabled_bps);
                $h_color = $this->get_v2_value_with_inheritance($color_hover_data, $bp, 'color', $enabled_bps);
                $h_opacity = $this->get_v2_value_with_inheritance($color_hover_data, $bp, 'opacity', $enabled_bps);
                $h_blend = $this->get_v2_value_with_inheritance($color_hover_data, $bp, 'mixBlendMode', $enabled_bps);

                // Fallback to normal values
                if ($h_use_gradient === null && $color_data) {
                    $h_use_gradient = $this->get_v2_value_with_inheritance($color_data, $bp, 'useGradient', $enabled_bps, false);
                }
                if ($h_gradient === null && $color_data) {
                    $h_gradient = $this->get_v2_value_with_inheritance($color_data, $bp, 'gradient', $enabled_bps);
                }
                if ($h_color === null && $color_data) {
                    $h_color = $this->get_v2_value_with_inheritance($color_data, $bp, 'color', $enabled_bps, 'transparent');
                }
                if ($h_opacity === null && $color_data) {
                    $h_opacity = $this->get_v2_value_with_inheritance($color_data, $bp, 'opacity', $enabled_bps, 1);
                }
                if ($h_blend === null && $color_data) {
                    $h_blend = $this->get_v2_value_with_inheritance($color_data, $bp, 'mixBlendMode', $enabled_bps, 'normal');
                }

                $h_color_value = ($h_use_gradient && $h_gradient) ? $h_gradient : ($h_color ?? 'transparent');
                $bp_vars[] = "--thumbnail-color-{$bp}-hover: {$h_color_value}";
                if ($h_opacity !== null) {
                    $bp_vars[] = "--thumbnail-color-opacity-{$bp}-hover: {$h_opacity}";
                }
                if ($h_blend) {
                    $bp_vars[] = "--thumbnail-color-blend-mode-{$bp}-hover: {$h_blend}";
                }
            }

            // ==== Thumbnail Opacity (Normal) ====
            if ($opacity_data) {
                $value = $this->get_v2_value_with_inheritance($opacity_data, $bp, 'value', $enabled_bps);
                $mix_blend = $this->get_v2_value_with_inheritance($opacity_data, $bp, 'mixBlendMode', $enabled_bps, 'normal');

                if ($value !== null && $value !== '') {
                    $bp_vars[] = "--thumbnail-opacity-{$bp}: " . ($value / 100);
                }
                if ($mix_blend && $mix_blend !== 'normal') {
                    $bp_vars[] = "--thumbnail-blend-mode-{$bp}: {$mix_blend}";
                }
            }

            // ==== Thumbnail Opacity (Hover) ====
            if ($opacity_data || $opacity_hover_data) {
                $h_value = $this->get_v2_value_with_inheritance($opacity_hover_data, $bp, 'value', $enabled_bps);
                $h_blend = $this->get_v2_value_with_inheritance($opacity_hover_data, $bp, 'mixBlendMode', $enabled_bps);

                // Fallback to normal values
                if ($h_value === null && $opacity_data) {
                    $h_value = $this->get_v2_value_with_inheritance($opacity_data, $bp, 'value', $enabled_bps, 100);
                }
                if ($h_blend === null && $opacity_data) {
                    $h_blend = $this->get_v2_value_with_inheritance($opacity_data, $bp, 'mixBlendMode', $enabled_bps, 'normal');
                }

                if ($h_value !== null && $h_value !== '') {
                    $bp_vars[] = "--thumbnail-opacity-{$bp}-hover: " . ($h_value / 100);
                }
                if ($h_blend && $h_blend !== 'normal') {
                    $bp_vars[] = "--thumbnail-blend-mode-{$bp}-hover: {$h_blend}";
                }
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Check if thumbnailColorV2 breakpoint matches block.json default
     * Default: color='', gradient='', useGradient=false/null, opacity=0, mixBlendMode=''
     */
    private function is_thumbnail_color_default($data, $bp) {
        if (!isset($data[$bp])) {
            return true;
        }
        $bp_data = $data[$bp];
        $color = $bp_data['color'] ?? '';
        $gradient = $bp_data['gradient'] ?? '';
        $use_gradient = $bp_data['useGradient'] ?? null;
        $opacity = $bp_data['opacity'] ?? 0;
        $mix_blend = $bp_data['mixBlendMode'] ?? '';
        return (
            ($color === '' || $color === null) &&
            ($gradient === '' || $gradient === null) &&
            ($use_gradient === false || $use_gradient === null || $use_gradient === 0) &&
            ($opacity === 0 || $opacity === '0' || $opacity === '' || $opacity === null) &&
            ($mix_blend === '' || $mix_blend === null || $mix_blend === 'normal')
        );
    }

    /**
     * Get layout width CSS variables for MD/TB/SP
     */
    private function get_layout_width_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $data = $attrs['layoutWidthV2'] ?? null;

        if (!$data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();

        foreach ($responsive_bps as $bp) {
            // Width
            $use_custom = $this->get_v2_value_with_inheritance($data, $bp, 'useCustom', $enabled_bps, false);
            if ($use_custom) {
                $value = $this->get_v2_value_with_inheritance($data, $bp, 'value', $enabled_bps, 'auto');
                $unit = $this->get_v2_value_with_inheritance($data, $bp, 'unit', $enabled_bps, 'px');
                if ($unit === 'fit-content') {
                    $bp_vars[] = "--layout-width-{$bp}: auto";
                } elseif ($value === 'auto' || $value === '' || $value === null) {
                    $bp_vars[] = "--layout-width-{$bp}: auto";
                } else {
                    $bp_vars[] = "--layout-width-{$bp}: {$value}{$unit}";
                }
            } elseif (isset($data[$bp]) && isset($data[$bp]['useCustom']) && $data[$bp]['useCustom'] === false) {
                $bp_vars[] = "--layout-width-{$bp}: auto";
            }

            // Min Width
            $min_use_custom = $this->get_v2_value_with_inheritance($data, $bp, 'minUseCustom', $enabled_bps, false);
            if ($min_use_custom) {
                $min_value = $this->get_v2_value_with_inheritance($data, $bp, 'minValue', $enabled_bps, 0);
                $min_unit = $this->get_v2_value_with_inheritance($data, $bp, 'minUnit', $enabled_bps, 'px');
                if ($min_unit === 'fit-content') {
                    $bp_vars[] = "--layout-width-min-{$bp}: fit-content";
                } else {
                    $bp_vars[] = "--layout-width-min-{$bp}: {$min_value}{$min_unit}";
                }
            } elseif (isset($data[$bp]) && isset($data[$bp]['minUseCustom']) && $data[$bp]['minUseCustom'] === false) {
                $bp_vars[] = "--layout-width-min-{$bp}: 0";
            }

            // Max Width
            $max_use_custom = $this->get_v2_value_with_inheritance($data, $bp, 'maxUseCustom', $enabled_bps, false);
            if ($max_use_custom) {
                $max_value = $this->get_v2_value_with_inheritance($data, $bp, 'maxValue', $enabled_bps, 'none');
                $max_unit = $this->get_v2_value_with_inheritance($data, $bp, 'maxUnit', $enabled_bps, 'px');
                if ($max_unit === 'fit-content') {
                    $bp_vars[] = "--layout-width-max-{$bp}: fit-content";
                } elseif ($max_value === 'none' || $max_value === '' || $max_value === null) {
                    $bp_vars[] = "--layout-width-max-{$bp}: none";
                } else {
                    $bp_vars[] = "--layout-width-max-{$bp}: {$max_value}{$max_unit}";
                }
            } elseif (isset($data[$bp]) && isset($data[$bp]['maxUseCustom']) && $data[$bp]['maxUseCustom'] === false) {
                $bp_vars[] = "--layout-width-max-{$bp}: none";
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Get layout height CSS variables for MD/TB/SP
     */
    private function get_layout_height_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $data = $attrs['layoutHeightV2'] ?? null;

        if (!$data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();

        foreach ($responsive_bps as $bp) {
            // Height
            $use_custom = $this->get_v2_value_with_inheritance($data, $bp, 'useCustom', $enabled_bps, false);
            if ($use_custom) {
                $value = $this->get_v2_value_with_inheritance($data, $bp, 'value', $enabled_bps, 'auto');
                $unit = $this->get_v2_value_with_inheritance($data, $bp, 'unit', $enabled_bps, 'px');
                if ($value === 'auto' || $value === '' || $value === null) {
                    $bp_vars[] = "--layout-height-{$bp}: auto";
                } else {
                    $bp_vars[] = "--layout-height-{$bp}: {$value}{$unit}";
                }
            } elseif (isset($data[$bp]) && isset($data[$bp]['useCustom']) && $data[$bp]['useCustom'] === false) {
                $bp_vars[] = "--layout-height-{$bp}: auto";
            }

            // Min Height
            $min_use_custom = $this->get_v2_value_with_inheritance($data, $bp, 'minUseCustom', $enabled_bps, false);
            if ($min_use_custom) {
                $min_value = $this->get_v2_value_with_inheritance($data, $bp, 'minValue', $enabled_bps, 0);
                $min_unit = $this->get_v2_value_with_inheritance($data, $bp, 'minUnit', $enabled_bps, 'px');
                $bp_vars[] = "--layout-height-min-{$bp}: {$min_value}{$min_unit}";
            } elseif (isset($data[$bp]) && isset($data[$bp]['minUseCustom']) && $data[$bp]['minUseCustom'] === false) {
                $bp_vars[] = "--layout-height-min-{$bp}: 0";
            }

            // Max Height
            $max_use_custom = $this->get_v2_value_with_inheritance($data, $bp, 'maxUseCustom', $enabled_bps, false);
            if ($max_use_custom) {
                $max_value = $this->get_v2_value_with_inheritance($data, $bp, 'maxValue', $enabled_bps, 'none');
                $max_unit = $this->get_v2_value_with_inheritance($data, $bp, 'maxUnit', $enabled_bps, 'px');
                if ($max_value === 'none' || $max_value === '' || $max_value === null) {
                    $bp_vars[] = "--layout-height-max-{$bp}: none";
                } else {
                    $bp_vars[] = "--layout-height-max-{$bp}: {$max_value}{$max_unit}";
                }
            } elseif (isset($data[$bp]) && isset($data[$bp]['maxUseCustom']) && $data[$bp]['maxUseCustom'] === false) {
                $bp_vars[] = "--layout-height-max-{$bp}: none";
            }
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Get layout position CSS variables for MD/TB/SP
     */
    private function get_layout_position_css($attrs, $unique_id) {
        $css = '';
        $enabled_bps = $this->breakpoints['enabled'] ?? array('pc', 'md', 'tb', 'sp');

        $responsive_bps = array_filter($enabled_bps, function($bp) {
            return $bp !== 'pc';
        });

        if (empty($responsive_bps)) {
            return '';
        }

        $data = $attrs['layoutPositionV2'] ?? null;

        if (!$data) {
            return '';
        }

        $selector = ".zenblocks-{$unique_id}";
        $bp_vars = array();
        $directions = array('top', 'right', 'bottom', 'left');

        foreach ($responsive_bps as $bp) {
            // Skip if breakpoint data is all defaults (empty strings)
            if ($this->is_layout_position_default($data, $bp)) {
                continue;
            }

            // Position type
            $type = $this->get_v2_value_with_inheritance($data, $bp, 'type', $enabled_bps, 'relative');
            $bp_vars[] = "--layout-position-type-{$bp}: {$type}";

            // Directional values (top, right, bottom, left)
            foreach ($directions as $dir) {
                $value = $this->get_v2_value_with_inheritance($data, $bp, $dir, $enabled_bps, 'auto');
                $unit = $this->get_v2_value_with_inheritance($data, $bp, $dir . 'Unit', $enabled_bps, 'px');
                if ($value === 'auto' || $value === '' || $value === null) {
                    $bp_vars[] = "--layout-position-{$dir}-{$bp}: auto";
                } else {
                    $bp_vars[] = "--layout-position-{$dir}-{$bp}: {$value}{$unit}";
                }
            }

            // Z-Index
            $z_index = $this->get_v2_value_with_inheritance($data, $bp, 'zIndex', $enabled_bps, 'auto');
            if ($z_index === 'auto' || $z_index === '' || $z_index === null) {
                $bp_vars[] = "--layout-z-index-{$bp}: auto";
            } else {
                $bp_vars[] = "--layout-z-index-{$bp}: {$z_index}";
            }

            // Transform translate X/Y
            $translate_x = $this->get_v2_value_with_inheritance($data, $bp, 'translateX', $enabled_bps, 0);
            $translate_x_unit = $this->get_v2_value_with_inheritance($data, $bp, 'translateXUnit', $enabled_bps, '%');
            $bp_vars[] = "--layout-transform-translate-x-{$bp}: {$translate_x}{$translate_x_unit}";

            $translate_y = $this->get_v2_value_with_inheritance($data, $bp, 'translateY', $enabled_bps, 0);
            $translate_y_unit = $this->get_v2_value_with_inheritance($data, $bp, 'translateYUnit', $enabled_bps, '%');
            $bp_vars[] = "--layout-transform-translate-y-{$bp}: {$translate_y}{$translate_y_unit}";
        }

        if (!empty($bp_vars)) {
            $css .= "{$selector} {\n";
            $css .= "  " . implode(";\n  ", $bp_vars) . ";\n";
            $css .= "}\n\n";
        }

        return $css;
    }

    /**
     * Check if layout position data for a breakpoint is all defaults (empty strings)
     */
    private function is_layout_position_default($data, $bp) {
        if (!isset($data[$bp])) {
            return true;
        }
        $bp_data = $data[$bp];
        $type = $bp_data['type'] ?? '';
        $top = $bp_data['top'] ?? '';
        $right = $bp_data['right'] ?? '';
        $bottom = $bp_data['bottom'] ?? '';
        $left = $bp_data['left'] ?? '';
        $translate_x = $bp_data['translateX'] ?? '';
        $translate_y = $bp_data['translateY'] ?? '';
        return (
            ($type === '' || $type === null) &&
            ($top === '' || $top === null) &&
            ($right === '' || $right === null) &&
            ($bottom === '' || $bottom === null) &&
            ($left === '' || $left === null) &&
            ($translate_x === '' || $translate_x === null || $translate_x === 0 || $translate_x === '0') &&
            ($translate_y === '' || $translate_y === null || $translate_y === 0 || $translate_y === '0')
        );
    }
}
