import { __, getLocaleData } from "@wordpress/i18n";
import { InspectorControls, useBlockProps, BlockControls, MediaUpload, MediaUploadCheck } from "@wordpress/block-editor";
import { PanelBody, SelectControl, TextControl, TextareaControl, ToolbarGroup, ToolbarButton, ToolbarDropdownMenu, Dropdown, MenuGroup, MenuItem, RangeControl, ColorPalette, __experimentalUnitControl as UnitControl, Modal, Button } from "@wordpress/components";
import { justifyLeft, justifyCenter, justifyRight, update } from "@wordpress/icons";
import { useState, useEffect, useRef, useCallback, useMemo } from "@wordpress/element";
import { useSelect, useDispatch } from "@wordpress/data";
import { createBlock } from "@wordpress/blocks";
import { applyFilters } from "@wordpress/hooks";
import { PREVIEW_STORE } from "../../../store/preview";

// ==================================================
// Feature Flag: ホバープレビュー機能
// true: ホバータブ選択時にホバー状態をプレビュー表示
// false: 無効化（従来の動作 - マウスホバーのみでホバー状態表示）
// ==================================================
const ENABLE_HOVER_PREVIEW = true;

const getDocsLanguageSegment = () => {
  const data = getLocaleData("zenblocks") || getLocaleData();
  const rawLocale = String((data && data[""] && data[""].lang) || "").toLowerCase().replace("-", "_");

  if (rawLocale.startsWith("ja")) return "ja";
  if (rawLocale.startsWith("de")) return "de";
  if (rawLocale.startsWith("es")) return "es";
  if (rawLocale.startsWith("fr")) return "fr";
  if (rawLocale.startsWith("id")) return "id";
  if (rawLocale.startsWith("it")) return "it";
  if (rawLocale.startsWith("ko")) return "ko";
  if (rawLocale.startsWith("nl")) return "nl";
  if (rawLocale.startsWith("pt")) return "pt-br";
  if (rawLocale.startsWith("zh")) return "zh-tw";
  return "en";
};

const getDocsLinkLabel = () => {
  const lang = getDocsLanguageSegment();

  if (lang === "ja") return "ドキュメントを見る";
  if (lang === "de") return "Dokumentation ansehen";
  if (lang === "es") return "Ver documentación";
  if (lang === "fr") return "Voir la documentation";
  if (lang === "id") return "Lihat dokumentasi";
  if (lang === "it") return "Vedi documentazione";
  if (lang === "ko") return "문서 보기";
  if (lang === "nl") return "Documentatie bekijken";
  if (lang === "pt-br") return "Ver documentação";
  if (lang === "zh-tw") return "查看文件";
  return "View Documentation";
};

// ブレークポイントマイグレーション
import { useBreakpointMigration } from "../../../core/useBreakpointMigration";

// レスポンシブタブコンポーネント
import { ResponsiveTabProvider } from "../../common/components/ResponsiveTabContext";
import { ResponsiveTabProviderV2, useResponsiveTabV2 } from "../../common/components/ResponsiveTabContextV2";
import ResponsiveControlV2 from "../../common/components/ResponsiveControlV2";
import { getEnabledBreakpoints } from "../../../core/breakpoints";

// スティッキーホバータブ
import StickyHoverTab from "../../common/components/StickyHoverTab";

// スティッキーパネル
import StickyCollapsiblePanel from "../../common/components/StickyCollapsiblePanel";

// プレビューモード
import PreviewDeviceControl from "../../common/components/PreviewDeviceControl";

// フォントファミリー設定モジュール
import FontFamilySettingV8, { getFontFamilyValue, getFontFamilyValueV8 } from "../../common/components/settings-modules/font/FontFamilySettingV8";

// フォントサイズ設定モジュール
import FontSizeSettingV8, { getDirectFontSize, getFontSizeValueV8, getDirectFontSizeV8 } from "../../common/components/settings-modules/font/FontSizeSettingV8";

// フォントウェイト設定モジュール
import { getFontWeightValue, getDirectFontWeight, getFontWeightValueV8, getDirectFontWeightV8 } from "../../common/components/settings-modules/font/FontWeightSettingV8";

// 行間設定モジュール
import FontLineHeightSettingV7, { getLineHeightValue, getDirectLineHeight, getDirectLineHeightV8 } from "../../common/components/settings-modules/font/FontLineHeightSettingV7";
import FontLineHeightSettingV8, { getDirectLineHeightV8 as getDirectLineHeightV8New } from "../../common/components/settings-modules/font/FontLineHeightSettingV8";

// 文字間設定モジュール
import FontLetterSpacingSettingV8, { getLetterSpacingValue, getDirectLetterSpacing, getLetterSpacingValueV8, getDirectLetterSpacingV8 } from "../../common/components/settings-modules/font/FontLetterSpacingSettingV8";

// 文字色設定モジュール
import FontColorSetting, { hexToRgba } from "../../common/components/settings-modules/font/FontColorSetting";

// カスタムカラーパレット
import CustomColorPalette from "../../common/components/CustomColorPalette";

// テキストシャドウ設定モジュール
import FontTextShadowSetting, { getTextShadowValue } from "../../common/components/settings-modules/font/FontTextShadowSetting";
import FontTextShadowSettingV2 from "../../common/components/settings-modules/font/FontTextShadowSettingV2";

// 共通ユーティリティ関数
import {
  getTextShadowValueHover,
  getTextShadowValueV2,
  getFontSizeStylesForEditor,
  getFontSizeHoverStylesForEditor,
  getFontWeightValueHover,
  getLineHeightValueHover,
  getLetterSpacingValueHover,
  getSpacingStylesForEditor,
  getBorderStylesForEditor,
  getBorderHoverStylesForEditor,
  getRadiusStylesForEditor,
  getRadiusHoverStylesForEditor,
  getShadowStylesForEditor,
  getShadowHoverStylesForEditor,
  getInnerShadowStylesForEditor,
  getInnerShadowHoverStylesForEditor,
  getOpacityStylesForEditor,
  getOpacityHoverStylesForEditor,
  getLayoutPositionStylesForEditor,
  getIconFrameStylesForEditor,
  getIconFrameHoverStylesForEditor,
  getBackgroundColorStylesV2ForEditor,
  getBackgroundColorHoverStylesV2ForEditor,
  getBackgroundImageStylesV2ForEditor,
  getBackgroundImageHoverStylesV2ForEditor,
  getBackgroundBaseColorStylesV2ForEditor,
  getBackgroundBaseColorHoverStylesV2ForEditor,
  getBackgroundPatternStylesV2ForEditor,
  getBackgroundPatternHoverStylesV2ForEditor,
  getGradientColorAtPosition,
  getIconSizeStylesV2ForEditor,
  getIconSizeHoverStylesV2ForEditor,
  getIconPositionStylesV2ForEditor,
  getIconPositionHoverStylesV2ForEditor,
  getIconColorStylesV2ForEditor,
  getIconColorHoverStylesV2ForEditor,
  getLayoutWidthStylesV2ForEditor,
  getLayoutHeightStylesV2ForEditor,
  getThumbnailImageStylesV2ForEditor,
  getThumbnailImageHoverStylesV2ForEditor,
  getThumbnailColorStylesV2ForEditor,
  getThumbnailColorHoverStylesV2ForEditor,
  getThumbnailImageBaseColorStylesV2ForEditor,
  getThumbnailImageBaseColorHoverStylesV2ForEditor,
  getThumbnailOpacityStylesV2ForEditor,
  getThumbnailOpacityHoverStylesV2ForEditor,
  getBandImageStylesV2ForEditor,
  getBandImageHoverStylesV2ForEditor,
  getBandColorStylesV2ForEditor,
  getBandColorHoverStylesV2ForEditor,
  getBandImageBaseColorStylesV2ForEditor,
  getBandImageBaseColorHoverStylesV2ForEditor,
  getBandPatternStylesV2ForEditor,
  getBandPatternHoverStylesV2ForEditor,
  getBandOpacityStylesV2ForEditor,
  getBandOpacityHoverStylesV2ForEditor,
  getBandTransformStylesV2ForEditor,
  getBandTransformHoverStylesV2ForEditor,
  getPreviewStyles,
} from "../../common/utils";

// テキスト幅測定ユーティリティ
import { calculateMinWidthForFit } from "../../common/utils/measureTextWidth";

// スペーシング設定用モジュール
import SpacingPaddingSettingV8, { getPaddingValueV8, getDirectPaddingV8 } from "../../common/components/settings-modules/spacing/SpacingPaddingSettingV8";
import SpacingMarginSettingV8, { getMarginValueV8, getDirectMarginV8 } from "../../common/components/settings-modules/spacing/SpacingMarginSettingV8";

// 背景設定用モジュール
import { getBackgroundPatternType } from "../../common/components/settings-modules/background/BackgroundPatternSettingV7";
import { getBandPatternType } from "../../common/components/settings-modules/band/BandPatternSettingV7";

// スタイリング設定用モジュール
import StylingShadowSettingV7 from "../../common/components/settings-modules/styling/StylingShadowSettingV7";
import StylingInnerShadowSettingV5 from "../../common/components/settings-modules/styling/StylingInnerShadowSettingV5";
import StylingOpacitySettingV7 from "../../common/components/settings-modules/styling/StylingOpacitySettingV7";
import StylingBorderSettingV8, { getBorderValueV8, getDirectBorderValueV8 } from "../../common/components/settings-modules/styling/StylingBorderSettingV8";
import StylingRadiusSettingV8, { getRadiusValueV8, getDirectRadiusValueV8 } from "../../common/components/settings-modules/styling/StylingRadiusSettingV8";
import StylingRadiusSimpleSettingV8, { getDirectRadiusSimpleV8, getRadiusSimpleV8 } from "../../common/components/settings-modules/styling/StylingRadiusSimpleSettingV8";

// 表示設定用モジュール
import DisplaySettingV7, { getDisplayClassesV2, getDisplayClassesForEditor } from "../../common/components/settings-modules/display/DisplaySettingV7";

// アイコン設定用モジュール
import { getCurrentIconColor, renderSVGIcon } from "../../common/components/settings-modules/icon/IconSelectSetting";
import IconSelectSettingV7 from "../../common/components/settings-modules/icon/IconSelectSettingV7";
import IconColorSettingV7 from "../../common/components/settings-modules/icon/IconColorSettingV7";

import BackgroundColorSettingV7 from "../../common/components/settings-modules/background/BackgroundColorSettingV7";
import BackgroundImageSettingV7 from "../../common/components/settings-modules/background/BackgroundImageSettingV7";
import BackgroundPatternSettingV7 from "../../common/components/settings-modules/background/BackgroundPatternSettingV7";
import BackgroundBaseColorSettingV7, { getBackgroundBaseColorValue, getDirectBackgroundBaseColor } from "../../common/components/settings-modules/background/BackgroundBaseColorSettingV7";
import IconSizeSettingV7 from "../../common/components/settings-modules/icon/IconSizeSettingV7";
import IconPositionSettingV7 from "../../common/components/settings-modules/icon/IconPositionSettingV7";
import LayoutWidthSettingV7 from "../../common/components/settings-modules/layout/LayoutWidthSettingV7";
import LayoutHeightSettingV7 from "../../common/components/settings-modules/layout/LayoutHeightSettingV7";
import LayoutPositionSettingV7 from "../../common/components/settings-modules/layout/LayoutPositionSettingV7";

// ボタンパターン関連
import ButtonPatternSelector from "./components/ButtonPatternSelector";
import {
  getProcessedPatterns,
  hasVideoMedia,
  hasResponsiveImageUrl,
  hasBandPattern,
  isBandColorVisible,
  hasV2IconFrame,
  isNonEmptyString,
  BREAKPOINTS,
} from "./patterns";
import { getDefaultAttributes } from "./utils/resetAttributes";
import "./components/button-pattern-selector.css";

// カスタムパターン関連
import CustomPatternManager, { SavePatternButton } from "../../common/components/CustomPatternManager";
import ButtonPatternPreview from "./components/ButtonPatternPreview";

// アニメーションプレビュー関連 (PRO版で addFilter 経由で注入)

// PanelBodyWithSync
import PanelBodyWithSync from "../../common/components/PanelBodyWithSync";

// Pro機能
import ProPanelShell, { ProOverlayOnly } from "../../common/components/ProPanelShell";
import { PlusOverlayOnly } from "../../common/components/PlusPanelShell";
import PlusFeatureOverlay from "../../common/components/PlusFeatureOverlay";
import { isPlus } from "../../../utils/is-pro";
import ProFeatureNotice from "../../common/components/ProFeatureNotice";
import { isPro } from "../../../utils/is-pro";

const hasThumbnailImage = (attributes) => {
  const data = attributes.thumbnailImageV2;
  if (data) {
    return Object.values(data).some((bp) => bp && bp.url && bp.url !== "");
  }
  return !!(attributes.thumbnailUrlPC || attributes.thumbnailUrlMD || attributes.thumbnailUrlTB || attributes.thumbnailUrlSP);
};

const hasThumbnailMedia = (attributes) => {
  if (attributes.thumbnailMediaType === "video") {
    return !!attributes.thumbnailVideoUrl;
  }
  return hasThumbnailImage(attributes);
};

const hasBackgroundVideo = (attributes) => {
  return attributes.backgroundMediaType === "video" && !!attributes.backgroundVideoUrl;
};

/**
 * Detect if the block uses any Pro-only features that would be
 * stripped on the frontend for free users.
 * Uses the same helpers as isProPresetAttributes() in patterns/index.js.
 */
const detectProFeatures = (attributes) => {
  const hasTextAnimation =
    (isNonEmptyString(attributes.hoverAnimation) && attributes.hoverAnimation !== "none") ||
    (isNonEmptyString(attributes.textAnimation) && attributes.textAnimation !== "none");
  const hasIconAnimation = isNonEmptyString(attributes.iconAnimation) && attributes.iconAnimation !== "none";
  const hasFrameAnimation = isNonEmptyString(attributes.frameAnimation) && attributes.frameAnimation !== "none";
  const hasButtonAnimation = isNonEmptyString(attributes.buttonAnimation) && attributes.buttonAnimation !== "none";

  const hasThumbnail = hasThumbnailMedia(attributes);

  const hasBand =
    hasVideoMedia(attributes.bandMediaType, attributes.bandVideoUrl) ||
    hasResponsiveImageUrl(attributes.bandImageV2) ||
    hasBandPattern(attributes.bandPatternV2) ||
    hasBandPattern(attributes.bandPatternV2Hover) ||
    BREAKPOINTS.some(
      (bp) =>
        isBandColorVisible(attributes.bandColorV2?.[bp]) ||
        isBandColorVisible(attributes.bandColorV2Hover?.[bp]) ||
        isBandColorVisible(attributes.bandImageBaseColorV2?.[bp]) ||
        isBandColorVisible(attributes.bandImageBaseColorV2Hover?.[bp])
    );

  const hasBgVideo = hasVideoMedia(attributes.backgroundMediaType, attributes.backgroundVideoUrl);

  // Check V2 icon frame first. For legacy attributes, only check keys whose
  // block.json defaults are 0/null/"" to avoid false positives from non-zero defaults
  // (e.g. iconFrameWidthPC defaults to 48 in block.json).
  const hasIconFrame = hasV2IconFrame(attributes) || (() => {
    const safeNumericKeys = [
      "iconFrameSize", "iconFrameWidth", "iconFrameHeight", "iconFrameBorderWidth", "iconFrameRadius",
      "iconFrameSizePC", "iconFrameSizeMD", "iconFrameSizeTB", "iconFrameSizeSP",
      "iconFrameWidthMD", "iconFrameHeightMD", "iconFrameBorderWidthMD", "iconFrameRadiusMD",
    ];
    if (safeNumericKeys.some((key) => Number(attributes[key] ?? 0) > 0)) return true;
    const colorKeys = [
      "iconFrameBgColor", "iconFrameBgColorPC", "iconFrameBgColorMD", "iconFrameBgColorTB", "iconFrameBgColorSP",
      "iconFrameBorderColor", "iconFrameBorderColorPC", "iconFrameBorderColorMD", "iconFrameBorderColorTB", "iconFrameBorderColorSP",
    ];
    return colorKeys.some((key) => isNonEmptyString(attributes[key]) && attributes[key] !== "transparent");
  })();

  const hasAnyAnimation = hasTextAnimation || hasIconAnimation || hasFrameAnimation || hasButtonAnimation;

  const hasMicroText = isNonEmptyString(attributes.microText);
  const hasSubText = isNonEmptyString(attributes.subText);

  return {
    hasTextAnimation,
    hasIconAnimation,
    hasFrameAnimation,
    hasButtonAnimation,
    hasAnyAnimation,
    hasThumbnail,
    hasBand,
    hasBgVideo,
    hasIconFrame,
    hasMicroText,
    hasSubText,
    hasAny: hasAnyAnimation || hasThumbnail || hasBand || hasBgVideo || hasIconFrame || hasMicroText || hasSubText,
  };
};

const getV2ValueWithFallback = (data, device, key, fallback) => {
  const order = ["pc", "md", "tb", "sp"];
  const idx = Math.max(0, order.indexOf(device));
  for (let i = idx; i >= 0; i--) {
    const bp = order[i];
    const value = data?.[bp]?.[key];
    if (value !== undefined && value !== null && value !== "") return value;
  }
  return fallback;
};

const getVideoPresentationFromImageData = (data, device = "pc") => {
  const fit = getV2ValueWithFallback(data, device, "objectFit", "cover");
  const position = getV2ValueWithFallback(data, device, "focalPosition", "50% 50%");
  const bgWidth = getV2ValueWithFallback(data, device, "bgWidth", "100");
  const bgWidthUnit = getV2ValueWithFallback(data, device, "bgWidthUnit", "%");
  const bgHeight = getV2ValueWithFallback(data, device, "bgHeight", "100");
  const bgHeightUnit = getV2ValueWithFallback(data, device, "bgHeightUnit", "%");
  const width = bgWidth === "auto" ? "100%" : `${bgWidth}${bgWidthUnit}`;
  const height = bgHeight === "auto" ? "100%" : `${bgHeight}${bgHeightUnit}`;
  return {
    fit: fit === "contain" ? "contain" : fit === "none" ? "none" : fit === "fill" ? "fill" : "cover",
    position,
    width: fit === "fill" || fit === "none" ? width : "100%",
    height: fit === "fill" || fit === "none" ? height : "100%",
  };
};

const parseFocalPositionToPercent = (position, fallbackX = 50, fallbackY = 50) => {
  const parts = String(position || "").trim().split(/\s+/);
  const xRaw = parts[0] || `${fallbackX}%`;
  const yRaw = parts[1] || `${fallbackY}%`;
  const x = clampPercent(parseFloat(String(xRaw).replace("%", "")), fallbackX);
  const y = clampPercent(parseFloat(String(yRaw).replace("%", "")), fallbackY);
  return { x, y };
};

const getVideoPresentationDefaultsFromImageData = (data, device = "pc") => {
  const fit = getV2ValueWithFallback(data, device, "objectFit", "cover");
  const position = getV2ValueWithFallback(data, device, "focalPosition", "50% 50%");
  const pos = parseFocalPositionToPercent(position, 50, 50);
  const width = getV2ValueWithFallback(data, device, "bgWidth", "100");
  const widthUnit = getV2ValueWithFallback(data, device, "bgWidthUnit", "%");
  const height = getV2ValueWithFallback(data, device, "bgHeight", "100");
  const heightUnit = getV2ValueWithFallback(data, device, "bgHeightUnit", "%");
  return { fit, positionX: pos.x, positionY: pos.y, width, widthUnit, height, heightUnit };
};

const pickValue = (value, fallback) => {
  return value === undefined || value === null || value === "" ? fallback : value;
};

const getVideoPresentationFromAttributes = ({
  fit,
  positionX,
  positionY,
  customWidth,
  customWidthUnit,
  customHeight,
  customHeightUnit,
  fallbackData,
  device = "pc",
}) => {
  const defaults = getVideoPresentationDefaultsFromImageData(fallbackData, device);
  const resolvedFit = (() => {
    const value = pickValue(fit, defaults.fit);
    if (value === "contain" || value === "fill" || value === "none") return value;
    return "cover";
  })();
  const resolvedX = clampPercent(pickValue(positionX, defaults.positionX), defaults.positionX);
  const resolvedY = clampPercent(pickValue(positionY, defaults.positionY), defaults.positionY);
  const size = getCustomSizeValue(
    resolvedFit,
    pickValue(customWidth, defaults.width),
    pickValue(customWidthUnit, defaults.widthUnit),
    pickValue(customHeight, defaults.height),
    pickValue(customHeightUnit, defaults.heightUnit),
  );
  return {
    fit: resolvedFit,
    positionX: resolvedX,
    positionY: resolvedY,
    position: `${resolvedX}% ${resolvedY}%`,
    width: size.width,
    height: size.height,
    embedWidth: size.embedWidth,
    embedHeight: size.embedHeight,
    backgroundSize: size.backgroundSize,
  };
};

const getBackgroundVideoConfig = (url) => {
  const input = String(url || "").trim();
  if (!input) return { type: "none", embedUrl: "", fileUrl: "", videoId: "" };

  const iframeSrcMatch = input.match(/<iframe[\s\S]*?\ssrc=["']([^"']+)["']/i);
  const raw = (iframeSrcMatch ? iframeSrcMatch[1] : input).replace(/&amp;/g, "&").trim();
  if (!raw) return { type: "none", embedUrl: "", fileUrl: "", videoId: "" };

  let parsed;
  try {
    parsed = new URL(raw);
  } catch (e) {
    return { type: "file", embedUrl: "", fileUrl: raw, videoId: "" };
  }

  const host = parsed.hostname.replace(/^www\./, "");
  const path = parsed.pathname;

  if (host === "youtu.be") {
    const id = path.split("/").filter(Boolean)[0];
    if (id) {
      return {
        type: "youtube",
        embedUrl: `https://www.youtube-nocookie.com/embed/${id}?autoplay=1&mute=1&controls=0&loop=1&playlist=${id}&playsinline=1&rel=0&modestbranding=1`,
        fileUrl: "",
        videoId: id,
      };
    }
  }

  if (host === "youtube.com" || host === "youtube-nocookie.com" || host.endsWith(".youtube.com")) {
    let id = parsed.searchParams.get("v") || "";
    if (!id) {
      const parts = path.split("/").filter(Boolean);
      if (parts[0] === "embed" || parts[0] === "shorts") {
        id = parts[1] || "";
      }
    }
    if (id) {
      return {
        type: "youtube",
        embedUrl: `https://www.youtube-nocookie.com/embed/${id}?autoplay=1&mute=1&controls=0&loop=1&playlist=${id}&playsinline=1&rel=0&modestbranding=1`,
        fileUrl: "",
        videoId: id,
      };
    }
  }

  if (host === "vimeo.com" || host.endsWith(".vimeo.com")) {
    let id = "";
    const parts = path.split("/").filter(Boolean);
    if (parts[0] === "video") {
      id = parts[1] || "";
    } else {
      id = parts.find((p) => /^\d+$/.test(p)) || "";
    }
    if (id) {
      return {
        type: "vimeo",
        embedUrl: `https://player.vimeo.com/video/${id}?autoplay=1&muted=1&loop=1&background=1&title=0&byline=0&portrait=0`,
        fileUrl: "",
        videoId: id,
      };
    }
  }

  return { type: "file", embedUrl: "", fileUrl: raw, videoId: "" };
};

const getEditorVideoThumbnailUrl = (config) => {
  if (config.type === "youtube" && config.videoId) {
    return `https://img.youtube.com/vi/${config.videoId}/maxresdefault.jpg`;
  }
  return "";
};

const clampPercent = (value, fallback = 50) => {
  const num = Number(value);
  if (!Number.isFinite(num)) return fallback;
  return Math.max(0, Math.min(100, num));
};

const mapFitToBackgroundSize = (fit) => {
  if (fit === "contain") return "contain";
  if (fit === "fill") return "100% 100%";
  if (fit === "none") return "auto";
  return "cover";
};

const getCustomSizeValue = (fit, width, widthUnit, height, heightUnit) => {
  if (fit !== "fill" && fit !== "none") {
    return { width: "100%", height: "100%", backgroundSize: mapFitToBackgroundSize(fit), embedWidth: fit === "cover" ? "177.78%" : "100%", embedHeight: fit === "cover" ? "177.78%" : "100%" };
  }
  const w = width === "auto" ? "auto" : `${width || "100"}${widthUnit || "%"}`;
  const h = height === "auto" ? "auto" : `${height || "100"}${heightUnit || "%"}`;
  const embedW = w === "auto" ? "100%" : w;
  const embedH = h === "auto" ? "100%" : h;
  return { width: w, height: h, backgroundSize: `${w} ${h}`, embedWidth: embedW, embedHeight: embedH };
};

const getThumbnailStylesForEdit = (attributes, previewDevice = 'pc') => {
  const data = attributes.thumbnailImageV2;
  if (data) {
    return {
      ...getThumbnailImageStylesV2ForEditor(attributes, previewDevice),
      ...getThumbnailImageHoverStylesV2ForEditor(attributes, previewDevice),
      ...getThumbnailColorStylesV2ForEditor(attributes, previewDevice),
      ...getThumbnailColorHoverStylesV2ForEditor(attributes, previewDevice),
      ...getThumbnailImageBaseColorStylesV2ForEditor(attributes, previewDevice),
      ...getThumbnailImageBaseColorHoverStylesV2ForEditor(attributes, previewDevice),
      ...getThumbnailOpacityStylesV2ForEditor(attributes, previewDevice),
      ...getThumbnailOpacityHoverStylesV2ForEditor(attributes, previewDevice),
      // Thumbnail transition variables are handled by richTextStyle section
    };
  }
  return {
    "--thumbnail-frame-width-pc": `${attributes.thumbnailFrameWidthPC || 60}${attributes.thumbnailFrameWidthUnitPC || "px"}`,
    "--thumbnail-frame-width-tb": `${attributes.thumbnailFrameWidthTB ?? attributes.thumbnailFrameWidthPC ?? 60}${
      attributes.thumbnailFrameWidthUnitTB || attributes.thumbnailFrameWidthUnitPC || "px"
    }`,
    "--thumbnail-frame-width-sp": `${attributes.thumbnailFrameWidthSP ?? attributes.thumbnailFrameWidthTB ?? attributes.thumbnailFrameWidthPC ?? 60}${
      attributes.thumbnailFrameWidthUnitSP || attributes.thumbnailFrameWidthUnitTB || attributes.thumbnailFrameWidthUnitPC || "px"
    }`,
    "--thumbnail-frame-height-pc": `${attributes.thumbnailFrameHeightPC || 60}${attributes.thumbnailFrameHeightUnitPC || "px"}`,
    "--thumbnail-frame-height-tb": `${attributes.thumbnailFrameHeightTB ?? attributes.thumbnailFrameHeightPC ?? 60}${
      attributes.thumbnailFrameHeightUnitTB || attributes.thumbnailFrameHeightUnitPC || "px"
    }`,
    "--thumbnail-frame-height-sp": `${attributes.thumbnailFrameHeightSP ?? attributes.thumbnailFrameHeightTB ?? attributes.thumbnailFrameHeightPC ?? 60}${
      attributes.thumbnailFrameHeightUnitSP || attributes.thumbnailFrameHeightUnitTB || attributes.thumbnailFrameHeightUnitPC || "px"
    }`,
    "--thumbnail-radius-pc": `${attributes.thumbnailBorderRadiusPC ?? 0}${attributes.thumbnailBorderRadiusUnitPC || "px"}`,
    "--thumbnail-radius-tb": `${attributes.thumbnailBorderRadiusTB ?? attributes.thumbnailBorderRadiusPC ?? 0}${
      attributes.thumbnailBorderRadiusUnitTB || attributes.thumbnailBorderRadiusUnitPC || "px"
    }`,
    "--thumbnail-radius-sp": `${attributes.thumbnailBorderRadiusSP ?? attributes.thumbnailBorderRadiusTB ?? attributes.thumbnailBorderRadiusPC ?? 0}${
      attributes.thumbnailBorderRadiusUnitSP || attributes.thumbnailBorderRadiusUnitTB || attributes.thumbnailBorderRadiusUnitPC || "px"
    }`,
    "--thumbnail-image-pc": attributes.thumbnailUrlPC ? `url(${attributes.thumbnailUrlPC})` : "none",
    "--thumbnail-image-md": attributes.thumbnailUrlMD ? `url(${attributes.thumbnailUrlMD})` : attributes.thumbnailUrlPC ? `url(${attributes.thumbnailUrlPC})` : "none",
    "--thumbnail-image-tb": attributes.thumbnailUrlTB
      ? `url(${attributes.thumbnailUrlTB})`
      : attributes.thumbnailUrlMD || attributes.thumbnailUrlPC
      ? `url(${attributes.thumbnailUrlMD || attributes.thumbnailUrlPC})`
      : "none",
    "--thumbnail-image-sp": attributes.thumbnailUrlSP
      ? `url(${attributes.thumbnailUrlSP})`
      : attributes.thumbnailUrlTB || attributes.thumbnailUrlMD || attributes.thumbnailUrlPC
      ? `url(${attributes.thumbnailUrlTB || attributes.thumbnailUrlMD || attributes.thumbnailUrlPC})`
      : "none",
    "--thumbnail-position-pc": attributes.thumbnailFocalPositionPC || "50% 50%",
    "--thumbnail-position-tb": attributes.thumbnailFocalPositionTB || attributes.thumbnailFocalPositionPC || "50% 50%",
    "--thumbnail-position-sp": attributes.thumbnailFocalPositionSP || attributes.thumbnailFocalPositionTB || attributes.thumbnailFocalPositionPC || "50% 50%",
    "--thumbnail-size-pc": attributes.thumbnailObjectFitPC || "cover",
    "--thumbnail-size-tb": attributes.thumbnailObjectFitTB || attributes.thumbnailObjectFitPC || "cover",
    "--thumbnail-size-sp": attributes.thumbnailObjectFitSP || attributes.thumbnailObjectFitTB || attributes.thumbnailObjectFitPC || "cover",
    "--thumbnail-offset-x-pc": `${attributes.thumbnailOffsetXPC ?? 0}${attributes.thumbnailOffsetXUnitPC || "%"}`,
    "--thumbnail-offset-x-tb": `${attributes.thumbnailOffsetXTB ?? attributes.thumbnailOffsetXPC ?? 0}${attributes.thumbnailOffsetXUnitTB || attributes.thumbnailOffsetXUnitPC || "%"}`,
    "--thumbnail-offset-x-sp": `${attributes.thumbnailOffsetXSP ?? attributes.thumbnailOffsetXTB ?? attributes.thumbnailOffsetXPC ?? 0}${
      attributes.thumbnailOffsetXUnitSP || attributes.thumbnailOffsetXUnitTB || attributes.thumbnailOffsetXUnitPC || "%"
    }`,
    "--thumbnail-offset-y-pc": `${attributes.thumbnailOffsetYPC ?? 0}${attributes.thumbnailOffsetYUnitPC || "%"}`,
    "--thumbnail-offset-y-tb": `${attributes.thumbnailOffsetYTB ?? attributes.thumbnailOffsetYPC ?? 0}${attributes.thumbnailOffsetYUnitTB || attributes.thumbnailOffsetYUnitPC || "%"}`,
    "--thumbnail-offset-y-sp": `${attributes.thumbnailOffsetYSP ?? attributes.thumbnailOffsetYTB ?? attributes.thumbnailOffsetYPC ?? 0}${
      attributes.thumbnailOffsetYUnitSP || attributes.thumbnailOffsetYUnitTB || attributes.thumbnailOffsetYUnitPC || "%"
    }`,
    "--thumbnail-color-pc": attributes.thumbnailColorPC || "transparent",
    "--thumbnail-color-tb": attributes.thumbnailColorTB || attributes.thumbnailColorPC || "transparent",
    "--thumbnail-color-sp": attributes.thumbnailColorSP || attributes.thumbnailColorTB || attributes.thumbnailColorPC || "transparent",
    "--thumbnail-color-opacity-pc": attributes.thumbnailColorOpacityPC ?? 1,
    "--thumbnail-color-opacity-tb": attributes.thumbnailColorOpacityTB ?? attributes.thumbnailColorOpacityPC ?? 1,
    "--thumbnail-color-opacity-sp": attributes.thumbnailColorOpacitySP ?? attributes.thumbnailColorOpacityTB ?? attributes.thumbnailColorOpacityPC ?? 1,
    // レガシー属性用ホバーCSS変数（通常状態の値をデフォルトとして使用）
    "--thumbnail-frame-width-pc-hover": `${attributes.thumbnailFrameWidthPCHover ?? attributes.thumbnailFrameWidthPC ?? 60}${attributes.thumbnailFrameWidthUnitPCHover || attributes.thumbnailFrameWidthUnitPC || "px"}`,
    "--thumbnail-frame-height-pc-hover": `${attributes.thumbnailFrameHeightPCHover ?? attributes.thumbnailFrameHeightPC ?? 60}${attributes.thumbnailFrameHeightUnitPCHover || attributes.thumbnailFrameHeightUnitPC || "px"}`,
    "--thumbnail-radius-pc-hover": `${attributes.thumbnailBorderRadiusPCHover ?? attributes.thumbnailBorderRadiusPC ?? 0}${attributes.thumbnailBorderRadiusUnitPCHover || attributes.thumbnailBorderRadiusUnitPC || "px"}`,
    "--thumbnail-offset-x-pc-hover": `${attributes.thumbnailOffsetXPCHover ?? attributes.thumbnailOffsetXPC ?? 0}${attributes.thumbnailOffsetXUnitPCHover || attributes.thumbnailOffsetXUnitPC || "%"}`,
    "--thumbnail-offset-y-pc-hover": `${attributes.thumbnailOffsetYPCHover ?? attributes.thumbnailOffsetYPC ?? 0}${attributes.thumbnailOffsetYUnitPCHover || attributes.thumbnailOffsetYUnitPC || "%"}`,
    "--thumbnail-image-pc-hover": attributes.thumbnailUrlPCHover ? `url(${attributes.thumbnailUrlPCHover})` : attributes.thumbnailUrlPC ? `url(${attributes.thumbnailUrlPC})` : "none",
    "--thumbnail-position-pc-hover": attributes.thumbnailFocalPositionPCHover || attributes.thumbnailFocalPositionPC || "50% 50%",
    "--thumbnail-size-pc-hover": attributes.thumbnailObjectFitPCHover || attributes.thumbnailObjectFitPC || "cover",
    "--thumbnail-color-pc-hover": attributes.thumbnailColorPCHover || attributes.thumbnailColorPC || "transparent",
    "--thumbnail-color-opacity-pc-hover": attributes.thumbnailColorOpacityPCHover ?? attributes.thumbnailColorOpacityPC ?? 1,
    // Thumbnail transition variables are handled by richTextStyle section
  };
};

const getBandStylesForEdit = (attributes, previewDevice = 'pc') => {
  return {
    ...getBandImageStylesV2ForEditor(attributes, previewDevice),
    ...getBandImageHoverStylesV2ForEditor(attributes, previewDevice),
    ...getBandColorStylesV2ForEditor(attributes, previewDevice),
    ...getBandColorHoverStylesV2ForEditor(attributes, previewDevice),
    ...getBandImageBaseColorStylesV2ForEditor(attributes, previewDevice),
    ...getBandImageBaseColorHoverStylesV2ForEditor(attributes, previewDevice),
    ...getBandPatternStylesV2ForEditor(attributes, previewDevice),
    ...getBandPatternHoverStylesV2ForEditor(attributes, previewDevice),
    ...getBandOpacityStylesV2ForEditor(attributes, previewDevice),
    ...getBandOpacityHoverStylesV2ForEditor(attributes, previewDevice),
    ...getBandTransformStylesV2ForEditor(attributes, previewDevice),
    ...getBandTransformHoverStylesV2ForEditor(attributes, previewDevice),
    // Band transition variables are handled by richTextStyle section
  };
};

/**
 * ButtonBasic Edit Component
 */

function ButtonBasicEditInner({ attributes, setAttributes: setAttributesOriginal, clientId }) {
  const buttonBasicDocsTopUrl = `https://zenblockswp.com/${getDocsLanguageSegment()}/docs/block/element/buttonbasic/`;
  const buttonBasicDocsLabel = getDocsLinkLabel();

  // プレビューデバイス状態をグローバルストアから取得（全ブロック間で共有）
  const previewDevice = useSelect(
    (select) => select(PREVIEW_STORE).getDevice(),
    []
  );
  const { setDevice: setPreviewDevice } = useDispatch(PREVIEW_STORE);

  const backgroundVideoConfig = getBackgroundVideoConfig(attributes.backgroundVideoUrl);
  const isEmbedBackgroundVideo = backgroundVideoConfig.type === "youtube" || backgroundVideoConfig.type === "vimeo";
  const thumbnailVideoConfig = getBackgroundVideoConfig(attributes.thumbnailVideoUrl);
  const isEmbedThumbnailVideo = thumbnailVideoConfig.type === "youtube" || thumbnailVideoConfig.type === "vimeo";
  const bandVideoConfig = getBackgroundVideoConfig(attributes.bandVideoUrl);
  const isEmbedBandVideo = bandVideoConfig.type === "youtube" || bandVideoConfig.type === "vimeo";
  const backgroundVideoFit = attributes.backgroundVideoFit || "cover";
  const backgroundVideoPositionX = clampPercent(attributes.backgroundVideoPositionX, 50);
  const backgroundVideoPositionY = clampPercent(attributes.backgroundVideoPositionY, 50);
  const backgroundPosterFit = attributes.backgroundPosterFit || "cover";
  const backgroundPosterPositionX = clampPercent(attributes.backgroundPosterPositionX, 50);
  const backgroundPosterPositionY = clampPercent(attributes.backgroundPosterPositionY, 50);
  const videoSize = getCustomSizeValue(
    backgroundVideoFit,
    attributes.backgroundVideoCustomWidth,
    attributes.backgroundVideoCustomWidthUnit,
    attributes.backgroundVideoCustomHeight,
    attributes.backgroundVideoCustomHeightUnit,
  );
  const posterSize = getCustomSizeValue(
    backgroundPosterFit,
    attributes.backgroundPosterCustomWidth,
    attributes.backgroundPosterCustomWidthUnit,
    attributes.backgroundPosterCustomHeight,
    attributes.backgroundPosterCustomHeightUnit,
  );
  const videoInlineStyle = {
    width: videoSize.width === "auto" ? "100%" : videoSize.width,
    height: videoSize.height === "auto" ? "100%" : videoSize.height,
    objectFit: backgroundVideoFit === "fill" ? "fill" : backgroundVideoFit === "none" ? "none" : backgroundVideoFit,
    objectPosition: `${backgroundVideoPositionX}% ${backgroundVideoPositionY}%`,
    position: "absolute",
    top: "50%",
    left: "50%",
    transform: `translate(calc(-50% + ${backgroundVideoPositionX - 50}%), calc(-50% + ${backgroundVideoPositionY - 50}%))`,
    maxWidth: "none",
    maxHeight: "none",
  };
  const iframeInlineStyle = {
    width: videoSize.embedWidth,
    height: videoSize.embedHeight,
    transform: `translate(calc(-50% + ${backgroundVideoPositionX - 50}%), calc(-50% + ${backgroundVideoPositionY - 50}%))`,
  };
  const posterInlineStyle = {
    backgroundSize: posterSize.backgroundSize,
    backgroundPosition: `${backgroundPosterPositionX}% ${backgroundPosterPositionY}%`,
    backgroundImage: attributes.backgroundVideoPoster ? `url(${attributes.backgroundVideoPoster})` : "none",
  };
  const thumbnailVideoPresentation = getVideoPresentationFromAttributes({
    fit: attributes.thumbnailVideoFit,
    positionX: attributes.thumbnailVideoPositionX,
    positionY: attributes.thumbnailVideoPositionY,
    customWidth: attributes.thumbnailVideoCustomWidth,
    customWidthUnit: attributes.thumbnailVideoCustomWidthUnit,
    customHeight: attributes.thumbnailVideoCustomHeight,
    customHeightUnit: attributes.thumbnailVideoCustomHeightUnit,
    fallbackData: attributes.thumbnailImageV2,
    device: previewDevice || "pc",
  });
  const thumbnailPosterPresentation = getVideoPresentationFromAttributes({
    fit: attributes.thumbnailPosterFit,
    positionX: attributes.thumbnailPosterPositionX,
    positionY: attributes.thumbnailPosterPositionY,
    customWidth: attributes.thumbnailPosterCustomWidth,
    customWidthUnit: attributes.thumbnailPosterCustomWidthUnit,
    customHeight: attributes.thumbnailPosterCustomHeight,
    customHeightUnit: attributes.thumbnailPosterCustomHeightUnit,
    fallbackData: attributes.thumbnailImageV2,
    device: previewDevice || "pc",
  });
  const thumbnailVideoInlineStyle = {
    width: thumbnailVideoPresentation.width === "auto" ? "100%" : thumbnailVideoPresentation.width,
    height: thumbnailVideoPresentation.height === "auto" ? "100%" : thumbnailVideoPresentation.height,
    objectFit: thumbnailVideoPresentation.fit,
    objectPosition: thumbnailVideoPresentation.position,
    position: "absolute",
    top: "50%",
    left: "50%",
    transform: `translate(calc(-50% + ${thumbnailVideoPresentation.positionX - 50}%), calc(-50% + ${thumbnailVideoPresentation.positionY - 50}%))`,
    maxWidth: "none",
    maxHeight: "none",
  };
  const thumbnailIframeInlineStyle = {
    width: thumbnailVideoPresentation.embedWidth,
    height: thumbnailVideoPresentation.embedHeight,
    position: "absolute",
    top: "50%",
    left: "50%",
    transform: `translate(calc(-50% + ${thumbnailVideoPresentation.positionX - 50}%), calc(-50% + ${thumbnailVideoPresentation.positionY - 50}%))`,
    border: 0,
    display: "block",
    pointerEvents: "none",
    maxWidth: "none",
    maxHeight: "none",
  };
  const thumbnailPosterInlineStyle = {
    backgroundSize: thumbnailPosterPresentation.backgroundSize,
    backgroundPosition: thumbnailPosterPresentation.position,
    backgroundImage: attributes.thumbnailVideoPoster ? `url(${attributes.thumbnailVideoPoster})` : "none",
  };
  const bandVideoPresentation = getVideoPresentationFromAttributes({
    fit: attributes.bandVideoFit,
    positionX: attributes.bandVideoPositionX,
    positionY: attributes.bandVideoPositionY,
    customWidth: attributes.bandVideoCustomWidth,
    customWidthUnit: attributes.bandVideoCustomWidthUnit,
    customHeight: attributes.bandVideoCustomHeight,
    customHeightUnit: attributes.bandVideoCustomHeightUnit,
    fallbackData: attributes.bandImageV2,
    device: previewDevice || "pc",
  });
  const bandPosterPresentation = getVideoPresentationFromAttributes({
    fit: attributes.bandPosterFit,
    positionX: attributes.bandPosterPositionX,
    positionY: attributes.bandPosterPositionY,
    customWidth: attributes.bandPosterCustomWidth,
    customWidthUnit: attributes.bandPosterCustomWidthUnit,
    customHeight: attributes.bandPosterCustomHeight,
    customHeightUnit: attributes.bandPosterCustomHeightUnit,
    fallbackData: attributes.bandImageV2,
    device: previewDevice || "pc",
  });
  const bandVideoInlineStyle = {
    width: bandVideoPresentation.width === "auto" ? "100%" : bandVideoPresentation.width,
    height: bandVideoPresentation.height === "auto" ? "100%" : bandVideoPresentation.height,
    objectFit: bandVideoPresentation.fit,
    objectPosition: bandVideoPresentation.position,
    position: "absolute",
    top: "50%",
    left: "50%",
    transform: `translate(calc(-50% + ${bandVideoPresentation.positionX - 50}%), calc(-50% + ${bandVideoPresentation.positionY - 50}%))`,
    maxWidth: "none",
    maxHeight: "none",
    opacity: (attributes.bandImageV2?.pc?.opacity !== undefined && attributes.bandImageV2?.pc?.opacity !== "") ? attributes.bandImageV2.pc.opacity : 1,
  };
  const bandIframeInlineStyle = {
    width: bandVideoPresentation.embedWidth,
    height: bandVideoPresentation.embedHeight,
    position: "absolute",
    top: "50%",
    left: "50%",
    transform: `translate(calc(-50% + ${bandVideoPresentation.positionX - 50}%), calc(-50% + ${bandVideoPresentation.positionY - 50}%))`,
    border: 0,
    display: "block",
    pointerEvents: "none",
    maxWidth: "none",
    maxHeight: "none",
  };
  const bandPosterInlineStyle = {
    backgroundSize: bandPosterPresentation.backgroundSize,
    backgroundPosition: bandPosterPresentation.position,
    backgroundImage: attributes.bandVideoPoster ? `url(${attributes.bandVideoPoster})` : "none",
  };

  // プレビュー切り替え中・設定変更中はトランジションを無効化
  const [isSwitchingPreview, setIsSwitchingPreview] = useState(false);
  const switchingTimeoutRef = useRef(null);
  const prevDeviceRef = useRef(previewDevice);

  // 設定変更時もトランジションを無効化するラップされたsetAttributes
  // すべての子コンポーネントはこのラップされたsetAttributesを使用する
  const setAttributes = useCallback((newAttributes) => {
    setIsSwitchingPreview(true);
    if (switchingTimeoutRef.current) {
      clearTimeout(switchingTimeoutRef.current);
    }
    switchingTimeoutRef.current = setTimeout(() => {
      setIsSwitchingPreview(false);
    }, 100); // 100msでReactの再レンダリング完了を待つ
    setAttributesOriginal(newAttributes);
  }, [setAttributesOriginal]);

  // プレビューデバイス変更時にトランジションを一時無効化
  useEffect(() => {
    if (prevDeviceRef.current !== previewDevice) {
      setIsSwitchingPreview(true);
      if (switchingTimeoutRef.current) {
        clearTimeout(switchingTimeoutRef.current);
      }
      switchingTimeoutRef.current = setTimeout(() => {
        setIsSwitchingPreview(false);
      }, 350); // iframe幅トランジション(0.3s)をカバー
      prevDeviceRef.current = previewDevice;
    }
  }, [previewDevice]);

  // クリーンアップ
  useEffect(() => {
    return () => {
      if (switchingTimeoutRef.current) {
        clearTimeout(switchingTimeoutRef.current);
      }
    };
  }, []);

  // 新規挿入フラグ（uniqueIdが未設定 = 新規配置されたブロック）
  const isNewBlock = useRef(!attributes.uniqueId);

  // uniqueIdを生成（ブロック固有のCSS用）
  useEffect(() => {
    if (!attributes.uniqueId) {
      const newUniqueId = `btn-${clientId.substring(0, 8)}`;
      setAttributesOriginal({ uniqueId: newUniqueId });
    }
  }, [attributes.uniqueId, clientId, setAttributesOriginal]);

  const { openGeneralSidebar } = useDispatch("core/edit-post");

  // マイグレーションは元のsetAttributesを使用（トランジション無効化不要）
  useBreakpointMigration(attributes, setAttributesOriginal);
  const [activeStateTab, setActiveStateTab] = useState("normal");
  const [showSyncConfirmModal, setShowSyncConfirmModal] = useState(false);

  // Free Preview mode state (editor-only, not saved)
  const [isFreePreview, setIsFreePreview] = useState(false);
  const proFeatures = useMemo(() => detectProFeatures(attributes), [
    // Animations
    attributes.hoverAnimation, attributes.textAnimation, attributes.iconAnimation, attributes.frameAnimation, attributes.buttonAnimation,
    // Thumbnail
    attributes.thumbnailImageV2, attributes.thumbnailUrlPC, attributes.thumbnailUrlMD, attributes.thumbnailUrlTB, attributes.thumbnailUrlSP,
    attributes.thumbnailMediaType, attributes.thumbnailVideoUrl,
    // Band
    attributes.bandImageV2, attributes.bandMediaType, attributes.bandVideoUrl,
    attributes.bandPatternV2, attributes.bandPatternV2Hover,
    attributes.bandColorV2, attributes.bandColorV2Hover,
    attributes.bandImageBaseColorV2, attributes.bandImageBaseColorV2Hover,
    // Background video
    attributes.backgroundMediaType, attributes.backgroundVideoUrl,
    // Icon frame
    attributes.iconFrameV2,
    attributes.iconFrameSize, attributes.iconFrameWidth, attributes.iconFrameHeight,
    attributes.iconFrameBorderWidth, attributes.iconFrameRadius,
    attributes.iconFrameBgColor, attributes.iconFrameBorderColor,
  ]);
  const isProUser = isPro();
  const showProBadge = !isProUser && proFeatures.hasAny;

  const PANEL_STORAGE_KEY = "zenblocks-buttonBasic-panels";

  const getStoredPanelStates = () => {
    try {
      const saved = window.localStorage.getItem(PANEL_STORAGE_KEY);
      return saved ? JSON.parse(saved) : {};
    } catch (e) {
      return {};
    }
  };

  const savePanelStates = (states) => {
    try {
      window.localStorage.setItem(PANEL_STORAGE_KEY, JSON.stringify(states));
    } catch (e) {}
  };

  const defaultPanelStates = {
    designPanel: false,
    designCustomPanel: false,
    designPresetPanel: false,
    animationPanel: false,
    textAnimationSubPanel: false,
    iconAnimationSubPanel: false,
    frameAnimationSubPanel: false,
    buttonAnimationSubPanel: false,
    textAnimationTransitionPanel: false,
    iconAnimationTransitionPanel: false,
    frameAnimationTransitionPanel: false,
    buttonAnimationTransitionPanel: false,
    tabPanel: false,
    additionalPanel: false,
    basic: false,
    textSettings: false,
    tagSettings: false,
    microTextSettings: false,
    subTextSettings: false,
    copyMicroSettings: false,
    copySubSettings: false,
    style: false,
    display: false,
    textColor: false,
    textShadow: false,
    background: false,
    backgroundImage: false,
    backgroundColor: false,
    backgroundPattern: false,
    backgroundBaseColor: false,
    backgroundTransition: false,
    border: false,
    radius: false,
    shadow: false,
    opacity: false,
    styleTransition: false,
    font: false,
    fontFamily: false,
    fontSize: false,
    fontWeight: false,
    lineHeight: false,
    letterSpacing: false,
    icon: false,
    iconSelect: false,
    iconSize: false,
    iconPosition: false,
    iconFrame: false,
    iconFrameSize: false,
    iconFrameBgColor: false,
    iconFrameRadius: false,
    iconFrameBorder: false,
    iconFrameTransition: false,
    iconTransition: false,
    thumbnail: false,
    thumbnailImage: false,
    thumbnailImageBaseColor: false,
    thumbnailColor: false,
    thumbnailSize: false,
    thumbnailBorder: false,
    thumbnailRadius: false,
    thumbnailPosition: false,
    thumbnailOpacity: false,
    thumbnailTransition: false,
    band: false,
    bandColor: false,
    bandPattern: false,
    bandImage: false,
    bandImageBaseColor: false,
    bandSize: false,
    bandBorder: false,
    bandRadius: false,
    bandPosition: false,
    bandOpacity: false,
    bandTransform: false,
    bandTransition: false,
    spacing: false,
    padding: false,
    margin: false,
    layout: false,
    width: false,
    height: false,
    position: false,
    layerOrder: false,
  };

  const [panelStates, setPanelStates] = useState(() => ({
    ...defaultPanelStates,
    ...getStoredPanelStates(),
  }));

  const togglePanel = (panelKey) => {
    setPanelStates((prev) => {
      const newStates = { ...prev, [panelKey]: !prev[panelKey] };
      savePanelStates(newStates);
      return newStates;
    });
  };

  const scrollToPanel = (panelId) => {
    setTimeout(() => {
      const anchor = document.getElementById(`panel-anchor-${panelId}`);
      if (!anchor) return;

      const sidebar = anchor.closest(".interface-complementary-area");
      if (!sidebar) return;

      // 固定ヘッダーの高さを計算
      let fixedHeadersHeight = 0;

      // サイドバーヘッダー
      const sidebarHeader = sidebar.querySelector(".interface-complementary-area-header");
      if (sidebarHeader) fixedHeadersHeight += sidebarHeader.offsetHeight;

      // プレビューデバイスコントロール
      const previewDeviceControl = sidebar.querySelector(".zenblocks-preview-device-control");
      if (previewDeviceControl) fixedHeadersHeight += previewDeviceControl.offsetHeight;

      // 親パネルのトグル（StickyCollapsiblePanel）
      const parentPanel = anchor.closest(".custom-collapsible-panel");
      if (parentPanel) {
        const panelToggle = parentPanel.querySelector(".custom-panel-toggle");
        if (panelToggle) fixedHeadersHeight += panelToggle.offsetHeight;
      }

      // ホバータブ
      const hoverTab = sidebar.querySelector(".zenblocks-tab-head-hover");
      if (hoverTab) fixedHeadersHeight += hoverTab.offsetHeight;

      // パネルごとのスクロールマージン調整
      // 固定表示がないパネルは負のマージンで上に位置調整
      const noStickyPanels = [
        "additionalPanel",
        "animationPanel",
        // 追加設定のサブパネル
        "copyMicroSettings",
        "copySubSettings",
        "microTextSettings",
        "subTextSettings",
        // アニメーション設定のサブパネル
        "textAnimationSubPanel",
        "iconAnimationSubPanel",
        "frameAnimationSubPanel",
        "buttonAnimationSubPanel",
      ];
      const extraMarginPanels = ["background", "backgroundColor"];
      let scrollMargin = 10;
      if (noStickyPanels.includes(panelId)) {
        scrollMargin = -50;
      } else if (extraMarginPanels.includes(panelId)) {
        scrollMargin = 110;
      }

      // スクロール位置を計算
      const anchorRect = anchor.getBoundingClientRect();
      const sidebarRect = sidebar.getBoundingClientRect();
      const scrollTop = sidebar.scrollTop + anchorRect.top - sidebarRect.top - fixedHeadersHeight - scrollMargin;

      sidebar.scrollTo({ top: Math.max(0, scrollTop), behavior: "smooth" });
    }, 350);
  };

  const buttonSettingPanels = ["basic", "display", "style", "background", "font", "icon", "thumbnail", "spacing", "layout"];

  const buttonSettingSubPanels = [
    "tagSettings",
    "textSettings",
    "textColor",
    "textShadow",
    "border",
    "radius",
    "innerShadow",
    "shadow",
    "opacity",
    "styleTransition",
    "backgroundColor",
    "backgroundImage",
    "backgroundPattern",
    "backgroundBaseColor",
    "backgroundTransition",
    "fontFamily",
    "fontSize",
    "fontWeight",
    "lineHeight",
    "letterSpacing",
    "iconSelect",
    "iconSize",
    "iconPosition",
    "iconFrame",
    "iconFrameSize",
    "iconFrameBgColor",
    "iconFrameBorder",
    "iconFrameRadius",
    "iconFrameTransition",
    "iconTransition",
    "thumbnailImage",
    "thumbnailImageBaseColor",
    "thumbnailColor",
    "thumbnailSize",
    "thumbnailBorder",
    "thumbnailRadius",
    "thumbnailPosition",
    "padding",
    "margin",
    "width",
    "height",
    "position",
  ];

  const openPanelExclusively = (targetPanels, openSubPanels = []) => {
    openGeneralSidebar("edit-post/block");
    const targets = Array.isArray(targetPanels) ? targetPanels : [targetPanels];
    const subPanelsToOpen = Array.isArray(openSubPanels) ? openSubPanels : [openSubPanels];
    setPanelStates((prev) => {
      const newStates = { ...prev };
      newStates.tabPanel = true;
      newStates.designPanel = false;
      buttonSettingPanels.forEach((panel) => {
        newStates[panel] = targets.includes(panel);
      });
      buttonSettingSubPanels.forEach((subPanel) => {
        newStates[subPanel] = subPanelsToOpen.includes(subPanel);
      });
      targets.forEach((target) => {
        newStates[target] = true;
      });
      savePanelStates(newStates);
      return newStates;
    });
  };

  const openDesignPanelExclusively = () => {
    openGeneralSidebar("edit-post/block");
    setPanelStates((prev) => {
      const newStates = { ...prev };
      newStates.designPanel = true;
      newStates.tabPanel = false;
      newStates.designCustomPanel = true;
      newStates.designPresetPanel = true;
      buttonSettingPanels.forEach((panel) => {
        newStates[panel] = false;
      });
      buttonSettingSubPanels.forEach((subPanel) => {
        newStates[subPanel] = false;
      });
      savePanelStates(newStates);
      return newStates;
    });
    scrollToPanel("designPanel");
  };

  // 新規ブロック挿入時にデザイン設定のプリセットタブを自動で開く
  useEffect(() => {
    if (isNewBlock.current) {
      isNewBlock.current = false;
      setTimeout(() => {
        openGeneralSidebar("edit-post/block");
        setPanelStates((prev) => {
          const newStates = { ...prev };
          newStates.designPanel = true;
          newStates.tabPanel = false;
          newStates.designCustomPanel = false;
          newStates.designPresetPanel = true;
          buttonSettingPanels.forEach((panel) => {
            newStates[panel] = false;
          });
          buttonSettingSubPanels.forEach((subPanel) => {
            newStates[subPanel] = false;
          });
          savePanelStates(newStates);
          return newStates;
        });
        scrollToPanel("designPanel");
      }, 100);
    }
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  const copyDefaultToHover = (attrList) => {
    const hoverAttributes = {};
    attrList.forEach((attr) => {
      if (attributes[attr] !== undefined) {
        // オブジェクトの場合はディープコピーを行う（React の変更検知のため）
        const value = attributes[attr];
        if (typeof value === 'object' && value !== null) {
          hoverAttributes[attr + "Hover"] = JSON.parse(JSON.stringify(value));
        } else {
          hoverAttributes[attr + "Hover"] = value;
        }
      }
    });
    setAttributes(hoverAttributes);
  };

  const attrGroups = {
    content: ["content"],
    textColor: ["textColor", "textColorAlpha"],
    textShadow: [
      "textShadowEnabled",
      "textShadowOffsetX",
      "textShadowOffsetXUnit",
      "textShadowOffsetY",
      "textShadowOffsetYUnit",
      "textShadowBlur",
      "textShadowBlurUnit",
      "textShadowColor",
      "textShadowColorAlpha",
    ],
    backgroundImage: ["backgroundImageV2", "useResponsiveBackgroundImage"],
    backgroundColor: ["backgroundColorV2", "useResponsiveBackgroundColor"],
    backgroundPattern: ["backgroundPatternV2", "useResponsiveBackgroundPattern"],
    backgroundBaseColor: ["backgroundBaseColorV2", "useResponsiveBackgroundBaseColor"],
    border: ["borderV2", "borderEnabled", "useResponsiveBorder"],
    radius: ["radiusV2", "useResponsiveRadius"],
    shadow: ["shadowV2", "shadowEnabled", "useResponsiveShadow"],
    innerShadow: ["innerShadowV2", "innerShadowEnabled", "useResponsiveInnerShadow"],
    opacity: ["opacityV2", "useResponsiveOpacity"],
    fontFamily: ["fontFamily"],
    fontSize: ["fontSizeV2", "useResponsiveFontSize"],
    fontWeight: ["fontWeightV2", "useResponsiveFontWeight"],
    lineHeight: ["lineHeightV2", "useResponsiveLineHeight"],
    letterSpacing: ["letterSpacingV2", "useResponsiveLetterSpacing"],
    iconSelect: ["icon", "iconColor", "iconStrokeWidth"],
    iconColor: ["iconColorV2", "useResponsiveIconColor"],
    iconSize: ["iconSizeV2", "useResponsiveIconSize"],
    iconPosition: ["iconPositionV2", "useResponsiveIconPosition"],
    iconFrameSize: [
      "iconFrameSize",
      "iconFrameSizeUnit",
      "iconFrameWidth",
      "iconFrameWidthUnit",
      "iconFrameHeight",
      "iconFrameHeightUnit",
      "iconFrameUseIndividualSize",
      "iconFrameSizePC",
      "iconFrameSizeMD",
      "iconFrameSizeTB",
      "iconFrameSizeSP",
      "iconFrameSizeUnitPC",
      "iconFrameSizeUnitMD",
      "iconFrameSizeUnitTB",
      "iconFrameSizeUnitSP",
      "iconFrameWidthPC",
      "iconFrameWidthMD",
      "iconFrameWidthTB",
      "iconFrameWidthSP",
      "iconFrameWidthUnitPC",
      "iconFrameWidthUnitMD",
      "iconFrameWidthUnitTB",
      "iconFrameWidthUnitSP",
      "iconFrameHeightPC",
      "iconFrameHeightMD",
      "iconFrameHeightTB",
      "iconFrameHeightSP",
      "iconFrameHeightUnitPC",
      "iconFrameHeightUnitMD",
      "iconFrameHeightUnitTB",
      "iconFrameHeightUnitSP",
      "useResponsiveIconFrameSize",
    ],
    iconFrameBgColor: [
      "iconFrameBgColor",
      "iconFrameBgColorPC",
      "iconFrameBgColorMD",
      "iconFrameBgColorTB",
      "iconFrameBgColorSP",
      "iconFrameBgColorAlpha",
      "iconFrameBgColorAlphaPC",
      "iconFrameBgColorAlphaMD",
      "iconFrameBgColorAlphaTB",
      "iconFrameBgColorAlphaSP",
      "useResponsiveIconFrameColor",
    ],
    iconFrameBorder: [
      "iconFrameBorderSides",
      "iconFrameBorderSidesPC",
      "iconFrameBorderSidesMD",
      "iconFrameBorderSidesTB",
      "iconFrameBorderSidesSP",
      "iconFrameBorderColor",
      "iconFrameBorderColorPC",
      "iconFrameBorderColorMD",
      "iconFrameBorderColorTB",
      "iconFrameBorderColorSP",
      "iconFrameBorderColorAlpha",
      "iconFrameBorderColorAlphaPC",
      "iconFrameBorderColorAlphaMD",
      "iconFrameBorderColorAlphaTB",
      "iconFrameBorderColorAlphaSP",
      "iconFrameBorderWidth",
      "iconFrameBorderWidthUnit",
      "iconFrameBorderWidthPC",
      "iconFrameBorderWidthMD",
      "iconFrameBorderWidthTB",
      "iconFrameBorderWidthSP",
      "iconFrameBorderWidthUnitPC",
      "iconFrameBorderWidthUnitMD",
      "iconFrameBorderWidthUnitTB",
      "iconFrameBorderWidthUnitSP",
      "useResponsiveIconFrameBorder",
      "iconFrameBorderStyle",
      "iconFrameBorderStylePC",
      "iconFrameBorderStyleMD",
      "iconFrameBorderStyleTB",
      "iconFrameBorderStyleSP",
    ],
    iconFrameRadius: [
      "iconFrameRadius",
      "iconFrameRadiusUnit",
      "iconFrameRadiusPC",
      "iconFrameRadiusMD",
      "iconFrameRadiusTB",
      "iconFrameRadiusSP",
      "iconFrameRadiusUnitPC",
      "iconFrameRadiusUnitMD",
      "iconFrameRadiusUnitTB",
      "iconFrameRadiusUnitSP",
      "useResponsiveIconFrameRadius",
    ],
    iconFrame: [
      // Size
      "iconFrameSize",
      "iconFrameSizeUnit",
      "iconFrameWidth",
      "iconFrameWidthUnit",
      "iconFrameHeight",
      "iconFrameHeightUnit",
      "iconFrameUseIndividualSize",
      "iconFrameSizePC",
      "iconFrameSizeMD",
      "iconFrameSizeTB",
      "iconFrameSizeSP",
      "iconFrameSizeUnitPC",
      "iconFrameSizeUnitMD",
      "iconFrameSizeUnitTB",
      "iconFrameSizeUnitSP",
      "iconFrameWidthPC",
      "iconFrameWidthMD",
      "iconFrameWidthTB",
      "iconFrameWidthSP",
      "iconFrameWidthUnitPC",
      "iconFrameWidthUnitMD",
      "iconFrameWidthUnitTB",
      "iconFrameWidthUnitSP",
      "iconFrameHeightPC",
      "iconFrameHeightMD",
      "iconFrameHeightTB",
      "iconFrameHeightSP",
      "iconFrameHeightUnitPC",
      "iconFrameHeightUnitMD",
      "iconFrameHeightUnitTB",
      "iconFrameHeightUnitSP",
      "useResponsiveIconFrameSize",
      // BgColor
      "iconFrameBgColor",
      "iconFrameBgColorPC",
      "iconFrameBgColorMD",
      "iconFrameBgColorTB",
      "iconFrameBgColorSP",
      "iconFrameBgColorAlpha",
      "iconFrameBgColorAlphaPC",
      "iconFrameBgColorAlphaMD",
      "iconFrameBgColorAlphaTB",
      "iconFrameBgColorAlphaSP",
      "useResponsiveIconFrameColor",
      // Border
      "iconFrameBorderSides",
      "iconFrameBorderSidesPC",
      "iconFrameBorderSidesMD",
      "iconFrameBorderSidesTB",
      "iconFrameBorderSidesSP",
      "iconFrameBorderColor",
      "iconFrameBorderColorPC",
      "iconFrameBorderColorMD",
      "iconFrameBorderColorTB",
      "iconFrameBorderColorSP",
      "iconFrameBorderColorAlpha",
      "iconFrameBorderColorAlphaPC",
      "iconFrameBorderColorAlphaMD",
      "iconFrameBorderColorAlphaTB",
      "iconFrameBorderColorAlphaSP",
      "iconFrameBorderWidth",
      "iconFrameBorderWidthUnit",
      "iconFrameBorderWidthPC",
      "iconFrameBorderWidthMD",
      "iconFrameBorderWidthTB",
      "iconFrameBorderWidthSP",
      "iconFrameBorderWidthUnitPC",
      "iconFrameBorderWidthUnitMD",
      "iconFrameBorderWidthUnitTB",
      "iconFrameBorderWidthUnitSP",
      "useResponsiveIconFrameBorder",
      "iconFrameBorderStyle",
      "iconFrameBorderStylePC",
      "iconFrameBorderStyleMD",
      "iconFrameBorderStyleTB",
      "iconFrameBorderStyleSP",
      // Radius
      "iconFrameRadius",
      "iconFrameRadiusUnit",
      "iconFrameRadiusPC",
      "iconFrameRadiusMD",
      "iconFrameRadiusTB",
      "iconFrameRadiusSP",
      "iconFrameRadiusUnitPC",
      "iconFrameRadiusUnitMD",
      "iconFrameRadiusUnitTB",
      "iconFrameRadiusUnitSP",
      "useResponsiveIconFrameRadius",
    ],
    thumbnail: [
      "thumbnailUrlPC",
      "thumbnailUrlMD",
      "thumbnailUrlTB",
      "thumbnailUrlSP",
      "thumbnailFocalPositionPC",
      "thumbnailFocalPositionMD",
      "thumbnailFocalPositionTB",
      "thumbnailFocalPositionSP",
      "thumbnailOffsetXPC",
      "thumbnailOffsetXMD",
      "thumbnailOffsetXTB",
      "thumbnailOffsetXSP",
      "thumbnailOffsetXUnitPC",
      "thumbnailOffsetXUnitMD",
      "thumbnailOffsetXUnitTB",
      "thumbnailOffsetXUnitSP",
      "thumbnailOffsetYPC",
      "thumbnailOffsetYMD",
      "thumbnailOffsetYTB",
      "thumbnailOffsetYSP",
      "thumbnailOffsetYUnitPC",
      "thumbnailOffsetYUnitMD",
      "thumbnailOffsetYUnitTB",
      "thumbnailOffsetYUnitSP",
      "thumbnailId",
      "thumbnailAlt",
      "thumbnailFrameWidthPC",
      "thumbnailFrameWidthMD",
      "thumbnailFrameWidthTB",
      "thumbnailFrameWidthSP",
      "thumbnailFrameWidthUnitPC",
      "thumbnailFrameWidthUnitMD",
      "thumbnailFrameWidthUnitTB",
      "thumbnailFrameWidthUnitSP",
      "thumbnailFrameHeightPC",
      "thumbnailFrameHeightMD",
      "thumbnailFrameHeightTB",
      "thumbnailFrameHeightSP",
      "thumbnailFrameHeightUnitPC",
      "thumbnailFrameHeightUnitMD",
      "thumbnailFrameHeightUnitTB",
      "thumbnailFrameHeightUnitSP",
      "thumbnailBgWidthPC",
      "thumbnailBgWidthMD",
      "thumbnailBgWidthTB",
      "thumbnailBgWidthSP",
      "thumbnailBgWidthUnitPC",
      "thumbnailBgWidthUnitMD",
      "thumbnailBgWidthUnitTB",
      "thumbnailBgWidthUnitSP",
      "thumbnailBgHeightPC",
      "thumbnailBgHeightMD",
      "thumbnailBgHeightTB",
      "thumbnailBgHeightSP",
      "thumbnailBgHeightUnitPC",
      "thumbnailBgHeightUnitMD",
      "thumbnailBgHeightUnitTB",
      "thumbnailBgHeightUnitSP",
      "thumbnailBorderRadiusPC",
      "thumbnailBorderRadiusMD",
      "thumbnailBorderRadiusTB",
      "thumbnailBorderRadiusSP",
      "thumbnailBorderRadiusUnitPC",
      "thumbnailBorderRadiusUnitMD",
      "thumbnailBorderRadiusUnitTB",
      "thumbnailBorderRadiusUnitSP",
      "thumbnailObjectFitPC",
      "thumbnailObjectFitMD",
      "thumbnailObjectFitTB",
      "thumbnailObjectFitSP",
      "thumbnailColorPC",
      "thumbnailColorMD",
      "thumbnailColorTB",
      "thumbnailColorSP",
      "thumbnailColorOpacityPC",
      "thumbnailColorOpacityMD",
      "thumbnailColorOpacityTB",
      "thumbnailColorOpacitySP",
      "thumbnailUseGradientPC",
      "thumbnailUseGradientMD",
      "thumbnailUseGradientTB",
      "thumbnailUseGradientSP",
      "thumbnailGradientPC",
      "thumbnailGradientMD",
      "thumbnailGradientTB",
      "thumbnailGradientSP",
      "thumbnailColorMixBlendModePC",
      "thumbnailColorMixBlendModeMD",
      "thumbnailColorMixBlendModeTB",
      "thumbnailColorMixBlendModeSP",
      "responsiveThumbnailColor",
    ],
    thumbnailImage: ["thumbnailImageV2"],
    thumbnailImageBaseColor: ["thumbnailImageBaseColorV2", "useResponsiveThumbnailImageBaseColor"],
    thumbnailColor: [
      "thumbnailColorPC",
      "thumbnailColorMD",
      "thumbnailColorTB",
      "thumbnailColorSP",
      "thumbnailColorOpacityPC",
      "thumbnailColorOpacityMD",
      "thumbnailColorOpacityTB",
      "thumbnailColorOpacitySP",
      "thumbnailUseGradientPC",
      "thumbnailUseGradientMD",
      "thumbnailUseGradientTB",
      "thumbnailUseGradientSP",
      "thumbnailGradientPC",
      "thumbnailGradientMD",
      "thumbnailGradientTB",
      "thumbnailGradientSP",
      "thumbnailColorMixBlendModePC",
      "thumbnailColorMixBlendModeMD",
      "thumbnailColorMixBlendModeTB",
      "thumbnailColorMixBlendModeSP",
      "responsiveThumbnailColor",
    ],
    thumbnailSize: [
      "thumbnailFrameWidthPC",
      "thumbnailFrameWidthMD",
      "thumbnailFrameWidthTB",
      "thumbnailFrameWidthSP",
      "thumbnailFrameWidthUnitPC",
      "thumbnailFrameWidthUnitMD",
      "thumbnailFrameWidthUnitTB",
      "thumbnailFrameWidthUnitSP",
      "thumbnailFrameHeightPC",
      "thumbnailFrameHeightMD",
      "thumbnailFrameHeightTB",
      "thumbnailFrameHeightSP",
      "thumbnailFrameHeightUnitPC",
      "thumbnailFrameHeightUnitMD",
      "thumbnailFrameHeightUnitTB",
      "thumbnailFrameHeightUnitSP",
    ],
    thumbnailRadius: [
      "thumbnailBorderRadiusPC",
      "thumbnailBorderRadiusMD",
      "thumbnailBorderRadiusTB",
      "thumbnailBorderRadiusSP",
      "thumbnailBorderRadiusUnitPC",
      "thumbnailBorderRadiusUnitMD",
      "thumbnailBorderRadiusUnitTB",
      "thumbnailBorderRadiusUnitSP",
    ],
    thumbnailPosition: [
      "thumbnailOffsetXPC",
      "thumbnailOffsetXMD",
      "thumbnailOffsetXTB",
      "thumbnailOffsetXSP",
      "thumbnailOffsetXUnitPC",
      "thumbnailOffsetXUnitMD",
      "thumbnailOffsetXUnitTB",
      "thumbnailOffsetXUnitSP",
      "thumbnailOffsetYPC",
      "thumbnailOffsetYMD",
      "thumbnailOffsetYTB",
      "thumbnailOffsetYSP",
      "thumbnailOffsetYUnitPC",
      "thumbnailOffsetYUnitMD",
      "thumbnailOffsetYUnitTB",
      "thumbnailOffsetYUnitSP",
    ],
  };

  const attrGroupsLevel1 = {
    basic: ["content"],
    style: [...attrGroups.textColor, ...attrGroups.textShadow, ...attrGroups.border, ...attrGroups.radius, ...attrGroups.innerShadow, ...attrGroups.shadow, ...attrGroups.opacity],
    background: [...attrGroups.backgroundColor, ...attrGroups.backgroundImage, ...attrGroups.backgroundPattern, ...attrGroups.backgroundBaseColor],
    font: [...attrGroups.fontFamily, ...attrGroups.fontSize, ...attrGroups.fontWeight, ...attrGroups.lineHeight, ...attrGroups.letterSpacing],
    icon: [...attrGroups.iconSelect, ...attrGroups.iconColor, ...attrGroups.iconSize, ...attrGroups.iconPosition, ...attrGroups.iconFrame],
    thumbnail: ["thumbnailImageV2", "useResponsiveThumbnailImage", "useResponsiveThumbnailSize", "useResponsiveThumbnailRadius", "useResponsiveThumbnailPosition", "useResponsiveThumbnailBorder", "thumbnailImageBaseColorV2", "useResponsiveThumbnailImageBaseColor", "thumbnailColorV2", "useResponsiveThumbnailColor", "thumbnailOpacityV2", "useResponsiveThumbnailOpacity"],
    band: ["bandImageV2", "useResponsiveBandImage", "useResponsiveBandSize", "useResponsiveBandRadius", "useResponsiveBandPosition", "useResponsiveBandBorder", "bandImageBaseColorV2", "useResponsiveBandImageBaseColor", "bandColorV2", "useResponsiveBandColor", "bandPatternV2", "useResponsiveBandPattern", "bandOpacityV2", "useResponsiveBandOpacity", "bandTransformV2", "useResponsiveBandTransform"],
  };

  const attrGroupsLevel0 = {
    all: [...attrGroupsLevel1.basic, ...attrGroupsLevel1.style, ...attrGroupsLevel1.background, ...attrGroupsLevel1.font, ...attrGroupsLevel1.icon, ...attrGroupsLevel1.thumbnail, ...attrGroupsLevel1.band],
  };

  const createSyncHandler = (group) => () => copyDefaultToHover(attrGroups[group]);
  const createSyncHandlerLevel1 = (group) => () => copyDefaultToHover(attrGroupsLevel1[group]);
  const createSyncHandlerLevel0 = (group) => () => copyDefaultToHover(attrGroupsLevel0[group]);

  const {
    content,
    contentHover,
    tagName,
    href,
    target,
    rel,
    buttonType,
    ariaLabel,
    linkTitle,
    fontSize,
    fontWeight,
    lineHeight,
    letterSpacing,
    textColor,
    textColorHover,
    // アイコン関連の属性
    icon,
    iconColor,
    iconSize,
    iconSizeUnit,
    iconSizePC,
    iconSizeSP,
    iconSizeUnitPC,
    iconSizeUnitSP,
    useResponsiveIconSize,
    iconStrokeWidth,
    iconGap,
    iconGapPC,
    iconGapSP,
    iconGapUnit,
    iconGapUnitPC,
    iconGapUnitSP,
    useResponsiveIconGap,
    // アイコン位置微調整関連の属性
    iconOffsetX,
    iconOffsetXPC,
    iconOffsetXSP,
    iconOffsetXUnit,
    iconOffsetXUnitPC,
    iconOffsetXUnitSP,
    useResponsiveIconOffsetX,
    iconOffsetY,
    iconOffsetYPC,
    iconOffsetYSP,
    iconOffsetYUnit,
    iconOffsetYUnitPC,
    iconOffsetYUnitSP,
    useResponsiveIconOffsetY,
    // ホバー用アイコン関連の属性
    iconHover,
    iconColorHover,
    iconStrokeWidthHover,
  } = attributes;

  // 編集画面ではPC表示を使用
  const currentDeviceTab = "pc";

  // SP向けの入力値を独立して管理するための状態
  const [spCustomFontSizeInput, setSpCustomFontSizeInput] = useState(null);

  // SP向けのline-height入力値を独立して管理するための状態
  const [spCustomLineHeightInput, setSpCustomLineHeightInput] = useState(null);

  // SP向けのletter-spacing入力値を独立して管理するための状態
  const [spCustomLetterSpacingInput, setSpCustomLetterSpacingInput] = useState(null);

  // 新しい属性のデフォルト値を設定
  const fontSizeUnit = attributes.fontSizeUnit || "px";
  const useCustomFontSize = attributes.useCustomFontSize || true;
  const customFontSize = attributes.customFontSize || "90";
  const fontSizePC = attributes.fontSizePC || fontSize || "custom";
  const fontSizeSP = attributes.fontSizeSP || fontSize || "custom";
  const fontSizeUnitPC = attributes.fontSizeUnitPC || fontSizeUnit;
  const fontSizeUnitSP = attributes.fontSizeUnitSP || "vw";
  // PC・SP別のカスタムフォントサイズを設定
  const customFontSizePC = attributes.customFontSizePC || customFontSize || "90";
  const customFontSizeSP = attributes.customFontSizeSP || "8";

  // SPのカスタムフォントサイズの値を更新する関数（最適化版）
  useEffect(() => {
    // attributesが更新された時にSPの入力値を含めた状態を初期化（長さが異なる場合のみ）
    if (attributes.customFontSizeSP !== undefined && spCustomFontSizeInput !== attributes.customFontSizeSP) {
      setSpCustomFontSizeInput(attributes.customFontSizeSP);
    }
  }, [attributes.customFontSizeSP, spCustomFontSizeInput]); // 循環参照を明示的に管理

  // SP用の入力値を取得する関数
  const getSpCustomFontSizeValue = () => {
    // 状態が初期化されている場合は、その値を使用
    if (spCustomFontSizeInput !== null) {
      return spCustomFontSizeInput;
    }
    // 初期化されていない場合は属性から取得
    return attributes.customFontSizeSP || "";
  };

  // fontWeight関連の属性のデフォルト値を設定
  const fontWeightPC = attributes.fontWeightPC || fontWeight || "normal";
  const fontWeightSP = attributes.fontWeightSP || fontWeight || "normal";
  const useResponsiveFontWeight = attributes.useResponsiveFontWeight !== undefined ? attributes.useResponsiveFontWeight : true;

  // line-height関連の属性のデフォルト値を設定
  const lineHeightUnit = attributes.lineHeightUnit || "";
  const useCustomLineHeight = attributes.useCustomLineHeight || false;
  const customLineHeight = attributes.customLineHeight || "1.2";
  const lineHeightPC = attributes.lineHeightPC || lineHeight || "custom";
  const lineHeightSP = attributes.lineHeightSP || lineHeight || "custom";
  const lineHeightUnitPC = attributes.lineHeightUnitPC || lineHeightUnit;
  const lineHeightUnitSP = attributes.lineHeightUnitSP || lineHeightUnit;
  // PC・SP別のカスタムline-heightを設定
  const customLineHeightPC = attributes.customLineHeightPC || customLineHeight || "1.2";
  const customLineHeightSP = attributes.customLineHeightSP || customLineHeight || "1.2";

  // SPのカスタムline-heightの値を更新する関数（最適化版）
  useEffect(() => {
    // attributesが更新された時にSPの入力値を含めた状態を初期化（値が異なる場合のみ）
    if (attributes.customLineHeightSP !== undefined && spCustomLineHeightInput !== attributes.customLineHeightSP) {
      setSpCustomLineHeightInput(attributes.customLineHeightSP);
    }
  }, [attributes.customLineHeightSP, spCustomLineHeightInput]); // 循環参照を明示的に管理

  // SP用のline-height入力値を取得する関数
  const getSpCustomLineHeightValue = () => {
    // 状態が初期化されている場合は、その値を使用
    if (spCustomLineHeightInput !== null) {
      return spCustomLineHeightInput;
    }
    // 初期化されていない場合は属性から取得
    return attributes.customLineHeightSP || "1.2";
  };

  // letter-spacing関連の属性のデフォルト値を設定
  const letterSpacingUnit = attributes.letterSpacingUnit || "px";
  const useCustomLetterSpacing = attributes.useCustomLetterSpacing || false;
  const customLetterSpacing = attributes.customLetterSpacing || "0";
  const letterSpacingPC = attributes.letterSpacingPC || letterSpacing || "custom";
  const letterSpacingSP = attributes.letterSpacingSP || letterSpacing || "custom";
  const letterSpacingUnitPC = attributes.letterSpacingUnitPC || letterSpacingUnit;
  const letterSpacingUnitSP = attributes.letterSpacingUnitSP || letterSpacingUnit;
  // PC・SP別のカスタムletter-spacingを設定
  const customLetterSpacingPC = attributes.customLetterSpacingPC || customLetterSpacing || "0";
  const customLetterSpacingSP = attributes.customLetterSpacingSP || customLetterSpacing || "0";

  // SPのカスタムletter-spacingの値を更新する関数（最適化版）
  useEffect(() => {
    // attributesが更新された時にSPの入力値を含めた状態を初期化（値が異なる場合のみ）
    if (attributes.customLetterSpacingSP !== undefined && spCustomLetterSpacingInput !== attributes.customLetterSpacingSP) {
      setSpCustomLetterSpacingInput(attributes.customLetterSpacingSP);
    }
  }, [attributes.customLetterSpacingSP, spCustomLetterSpacingInput]); // 循環参照を明示的に管理

  // fit選択時にテキスト幅を測定してmin-widthを自動設定
  const buttonContent = attributes.content;
  const layoutWidthData = attributes.layoutWidthV2;
  const layoutWidthUnit = layoutWidthData?.pc?.unit;
  const currentMinValue = layoutWidthData?.pc?.minValue;
  
  useEffect(() => {
    if (!layoutWidthData?.pc) return;
    if (layoutWidthUnit !== "fit-content") return;
    
    const calculatedWidth = calculateMinWidthForFit(buttonContent, attributes);
    if (calculatedWidth <= 0) return;
    
    const currentMinVal = layoutWidthData?.pc?.minValue;
    const currentMaxVal = layoutWidthData?.pc?.maxValue;
    if (currentMinVal === calculatedWidth && currentMaxVal === calculatedWidth) {
      return;
    }
    const newLayoutWidthData = JSON.parse(JSON.stringify(layoutWidthData));
    newLayoutWidthData.pc.minUseCustom = true;
    newLayoutWidthData.pc.minValue = calculatedWidth;
    newLayoutWidthData.pc.minUnit = "px";
    newLayoutWidthData.pc.maxUseCustom = true;
    newLayoutWidthData.pc.maxValue = calculatedWidth;
    newLayoutWidthData.pc.maxUnit = "px";
    
    setAttributes({ layoutWidthV2: newLayoutWidthData });
  }, [buttonContent, layoutWidthUnit, layoutWidthData, attributes, setAttributes]);

  // SP用のletter-spacing入力値を取得する関数
  const getSpCustomLetterSpacingValue = () => {
    // 状態が初期化されている場合は、その値を使用
    if (spCustomLetterSpacingInput !== null) {
      return spCustomLetterSpacingInput;
    }
    // 初期化されていない場合は属性から取得
    return attributes.customLetterSpacingSP || "0";
  };

  // 現在のタブに基づいてフォントサイズを取得
  const currentFontSize = getDirectFontSize(attributes, currentDeviceTab);

  // 現在のタブに基づいてfont-weightを取得
  const currentFontWeight = getDirectFontWeight(attributes, currentDeviceTab);

  // HTMLタグ オプション
  const tagNameOptions = [
    { label: __("Link (a)", "zenblocks"), value: "a" },
    { label: __("Button (button)", "zenblocks"), value: "button" },
  ];

  // target オプション
  const targetOptions = [
    { label: __("Same Page", "zenblocks"), value: "" },
    { label: __("New Tab (_blank)", "zenblocks"), value: "_blank" },
  ];

  // rel オプション
  const relOptions = [
    { label: __("None", "zenblocks"), value: "" },
    { label: __("nofollow", "zenblocks"), value: "nofollow" },
    { label: __("noopener", "zenblocks"), value: "noopener" },
    { label: __("noreferrer", "zenblocks"), value: "noreferrer" },
    { label: __("nofollow noopener", "zenblocks"), value: "nofollow noopener" },
  ];

  // buttonType オプション
  const buttonTypeOptions = [
    { label: __("button", "zenblocks"), value: "button" },
    { label: __("submit", "zenblocks"), value: "submit" },
    { label: __("reset", "zenblocks"), value: "reset" },
  ];

  // CSS変数とスタイルを結合（エディタ用: PC変数のみ出力、値はプレビューデバイスに応じて変更）
  const spacingStyles = getSpacingStylesForEditor(attributes, previewDevice);

  // RichTextのスタイル設定
  // Note: lineHeightとletterSpacingはCSS変数（--line-height-pc, --letter-spacing-pc）でのみ制御
  // インラインスタイルで設定するとCSS変数による子要素への適用と競合するため削除
  const richTextStyle = {
    fontSize: currentFontSize,
    fontFamily: getFontFamilyValue(attributes.fontFamily) || undefined,
    fontWeight: currentFontWeight,
    color: textColor === "transparent" ? "transparent" : hexToRgba(textColor, attributes.textColorAlpha ?? 1),
    "--text-color": textColor === "transparent" ? "transparent" : hexToRgba(textColor, attributes.textColorAlpha ?? 1),
    "--text-shadow": getTextShadowValue(attributes) || undefined,
    "--text-color-hover": attributes.textColorHover === "transparent" ? "transparent" : hexToRgba(attributes.textColorHover, attributes.textColorAlphaHover ?? 1),
    "--text-shadow-hover": getTextShadowValueHover(attributes) || undefined,
    ...getFontSizeStylesForEditor(attributes, previewDevice),
    // フォントウェイト（通常状態）- レスポンシブ対応
    "--font-weight-pc": getFontWeightValue(attributes, "pc"),
    "--font-weight-md": getDirectFontWeight(attributes, "md"),
    "--font-weight-tb": getDirectFontWeight(attributes, "tb"),
    "--font-weight-sp": getDirectFontWeight(attributes, "sp"),
    // 行間（通常状態）- レスポンシブ対応
    "--line-height-pc": getLineHeightValue(attributes, "pc"),
    "--line-height-md": getDirectLineHeight(attributes, "md"),
    "--line-height-tb": getDirectLineHeight(attributes, "tb"),
    "--line-height-sp": getDirectLineHeight(attributes, "sp"),
    // テキストメインの高さ（通常状態）- レスポンシブ対応
    "--text-main-height-pc": `${getLineHeightValue(attributes, "pc") || "1.6"}em`,
    "--text-main-height-md": getDirectLineHeight(attributes, "md") ? `${getDirectLineHeight(attributes, "md")}em` : undefined,
    "--text-main-height-tb": getDirectLineHeight(attributes, "tb") ? `${getDirectLineHeight(attributes, "tb")}em` : undefined,
    "--text-main-height-sp": getDirectLineHeight(attributes, "sp") ? `${getDirectLineHeight(attributes, "sp")}em` : undefined,
    // 文字間（通常状態）- レスポンシブ対応
    "--letter-spacing-pc": getLetterSpacingValue(attributes, "pc"),
    "--letter-spacing-md": getDirectLetterSpacing(attributes, "md"),
    "--letter-spacing-tb": getDirectLetterSpacing(attributes, "tb"),
    "--letter-spacing-sp": getDirectLetterSpacing(attributes, "sp"),
    "--copy-micro-text-color": attributes.copyMicroTextColor || undefined,
    "--copy-micro-bg-color": attributes.copyMicroBgUseGradient ? "transparent" : (attributes.copyMicroBgColor || undefined),
    "--copy-micro-bg-gradient": attributes.copyMicroBgUseGradient ? (attributes.copyMicroBgGradient || undefined) : undefined,
    "--copy-micro-bg-gradient-mid-color": attributes.copyMicroBgUseGradient ? (getGradientColorAtPosition(attributes.copyMicroBgGradient, 50) || undefined) : undefined,
    "--copy-micro-border-width": `${getBorderValueV8(attributes, "copyMicroBorderV2", "pc", "width")}px`,
    "--copy-micro-border-width-pc": getDirectBorderValueV8(attributes, "copyMicroBorderV2", "pc", "width") !== undefined ? `${getDirectBorderValueV8(attributes, "copyMicroBorderV2", "pc", "width")}px` : undefined,
    "--copy-micro-border-width-md": getDirectBorderValueV8(attributes, "copyMicroBorderV2", "md", "width") !== undefined ? `${getDirectBorderValueV8(attributes, "copyMicroBorderV2", "md", "width")}px` : undefined,
    "--copy-micro-border-width-tb": getDirectBorderValueV8(attributes, "copyMicroBorderV2", "tb", "width") !== undefined ? `${getDirectBorderValueV8(attributes, "copyMicroBorderV2", "tb", "width")}px` : undefined,
    "--copy-micro-border-width-sp": getDirectBorderValueV8(attributes, "copyMicroBorderV2", "sp", "width") !== undefined ? `${getDirectBorderValueV8(attributes, "copyMicroBorderV2", "sp", "width")}px` : undefined,
    "--copy-micro-border-style": getBorderValueV8(attributes, "copyMicroBorderV2", "pc", "style") || "solid",
    "--copy-micro-border-style-pc": getDirectBorderValueV8(attributes, "copyMicroBorderV2", "pc", "style"),
    "--copy-micro-border-style-md": getDirectBorderValueV8(attributes, "copyMicroBorderV2", "md", "style"),
    "--copy-micro-border-style-tb": getDirectBorderValueV8(attributes, "copyMicroBorderV2", "tb", "style"),
    "--copy-micro-border-style-sp": getDirectBorderValueV8(attributes, "copyMicroBorderV2", "sp", "style"),
    "--copy-micro-border-color": getBorderValueV8(attributes, "copyMicroBorderV2", "pc", "color") || "#000000",
    "--copy-micro-border-color-pc": getDirectBorderValueV8(attributes, "copyMicroBorderV2", "pc", "color"),
    "--copy-micro-border-color-md": getDirectBorderValueV8(attributes, "copyMicroBorderV2", "md", "color"),
    "--copy-micro-border-color-tb": getDirectBorderValueV8(attributes, "copyMicroBorderV2", "tb", "color"),
    "--copy-micro-border-color-sp": getDirectBorderValueV8(attributes, "copyMicroBorderV2", "sp", "color"),
    "--copy-micro-border-radius": getRadiusSimpleV8(attributes, "copyMicroBorderRadiusV2", "pc", "0px"),
    "--copy-micro-border-radius-pc": getDirectRadiusSimpleV8(attributes, "copyMicroBorderRadiusV2", "pc"),
    "--copy-micro-border-radius-md": getDirectRadiusSimpleV8(attributes, "copyMicroBorderRadiusV2", "md"),
    "--copy-micro-border-radius-tb": getDirectRadiusSimpleV8(attributes, "copyMicroBorderRadiusV2", "tb"),
    "--copy-micro-border-radius-sp": getDirectRadiusSimpleV8(attributes, "copyMicroBorderRadiusV2", "sp"),
    "--copy-micro-font-family": attributes.copyMicroFontFamily || undefined,
    "--copy-micro-font-size": attributes.copyMicroFontSize ? `${attributes.copyMicroFontSize}${attributes.copyMicroFontSizeUnit || "em"}` : undefined,
    "--copy-micro-margin-top-pc": getDirectMarginV8(attributes, "copyMicroMarginV2", "pc", "top") ?? "0px",
    "--copy-micro-margin-right-pc": getDirectMarginV8(attributes, "copyMicroMarginV2", "pc", "right") ?? "auto",
    "--copy-micro-margin-bottom-pc": getDirectMarginV8(attributes, "copyMicroMarginV2", "pc", "bottom") ?? "8px",
    "--copy-micro-margin-left-pc": getDirectMarginV8(attributes, "copyMicroMarginV2", "pc", "left") ?? "auto",
    "--copy-micro-margin-top-md": getDirectMarginV8(attributes, "copyMicroMarginV2", "md", "top"),
    "--copy-micro-margin-right-md": getDirectMarginV8(attributes, "copyMicroMarginV2", "md", "right"),
    "--copy-micro-margin-bottom-md": getDirectMarginV8(attributes, "copyMicroMarginV2", "md", "bottom"),
    "--copy-micro-margin-left-md": getDirectMarginV8(attributes, "copyMicroMarginV2", "md", "left"),
    "--copy-micro-margin-top-tb": getDirectMarginV8(attributes, "copyMicroMarginV2", "tb", "top"),
    "--copy-micro-margin-right-tb": getDirectMarginV8(attributes, "copyMicroMarginV2", "tb", "right"),
    "--copy-micro-margin-bottom-tb": getDirectMarginV8(attributes, "copyMicroMarginV2", "tb", "bottom"),
    "--copy-micro-margin-left-tb": getDirectMarginV8(attributes, "copyMicroMarginV2", "tb", "left"),
    "--copy-micro-margin-top-sp": getDirectMarginV8(attributes, "copyMicroMarginV2", "sp", "top"),
    "--copy-micro-margin-right-sp": getDirectMarginV8(attributes, "copyMicroMarginV2", "sp", "right"),
    "--copy-micro-margin-bottom-sp": getDirectMarginV8(attributes, "copyMicroMarginV2", "sp", "bottom"),
    "--copy-micro-margin-left-sp": getDirectMarginV8(attributes, "copyMicroMarginV2", "sp", "left"),
    "--copy-micro-padding-top-pc": getDirectPaddingV8(attributes, "copyMicroPaddingV2", "pc", "top") ?? "0px",
    "--copy-micro-padding-right-pc": getDirectPaddingV8(attributes, "copyMicroPaddingV2", "pc", "right") ?? "0px",
    "--copy-micro-padding-bottom-pc": getDirectPaddingV8(attributes, "copyMicroPaddingV2", "pc", "bottom") ?? "0px",
    "--copy-micro-padding-left-pc": getDirectPaddingV8(attributes, "copyMicroPaddingV2", "pc", "left") ?? "0px",
    "--copy-micro-padding-top-md": getDirectPaddingV8(attributes, "copyMicroPaddingV2", "md", "top"),
    "--copy-micro-padding-right-md": getDirectPaddingV8(attributes, "copyMicroPaddingV2", "md", "right"),
    "--copy-micro-padding-bottom-md": getDirectPaddingV8(attributes, "copyMicroPaddingV2", "md", "bottom"),
    "--copy-micro-padding-left-md": getDirectPaddingV8(attributes, "copyMicroPaddingV2", "md", "left"),
    "--copy-micro-padding-top-tb": getDirectPaddingV8(attributes, "copyMicroPaddingV2", "tb", "top"),
    "--copy-micro-padding-right-tb": getDirectPaddingV8(attributes, "copyMicroPaddingV2", "tb", "right"),
    "--copy-micro-padding-bottom-tb": getDirectPaddingV8(attributes, "copyMicroPaddingV2", "tb", "bottom"),
    "--copy-micro-padding-left-tb": getDirectPaddingV8(attributes, "copyMicroPaddingV2", "tb", "left"),
    "--copy-micro-padding-top-sp": getDirectPaddingV8(attributes, "copyMicroPaddingV2", "sp", "top"),
    "--copy-micro-padding-right-sp": getDirectPaddingV8(attributes, "copyMicroPaddingV2", "sp", "right"),
    "--copy-micro-padding-bottom-sp": getDirectPaddingV8(attributes, "copyMicroPaddingV2", "sp", "bottom"),
    "--copy-micro-padding-left-sp": getDirectPaddingV8(attributes, "copyMicroPaddingV2", "sp", "left"),
    "--copy-micro-rotate": attributes.copyMicroRotate ? `${attributes.copyMicroRotate}deg` : undefined,
    "--copy-sub-margin-top-pc": getDirectMarginV8(attributes, "copySubMarginV2", "pc", "top") ?? "8px",
    "--copy-sub-margin-right-pc": getDirectMarginV8(attributes, "copySubMarginV2", "pc", "right") ?? "auto",
    "--copy-sub-margin-bottom-pc": getDirectMarginV8(attributes, "copySubMarginV2", "pc", "bottom") ?? "0px",
    "--copy-sub-margin-left-pc": getDirectMarginV8(attributes, "copySubMarginV2", "pc", "left") ?? "auto",
    "--copy-sub-margin-top-md": getDirectMarginV8(attributes, "copySubMarginV2", "md", "top"),
    "--copy-sub-margin-right-md": getDirectMarginV8(attributes, "copySubMarginV2", "md", "right"),
    "--copy-sub-margin-bottom-md": getDirectMarginV8(attributes, "copySubMarginV2", "md", "bottom"),
    "--copy-sub-margin-left-md": getDirectMarginV8(attributes, "copySubMarginV2", "md", "left"),
    "--copy-sub-margin-top-tb": getDirectMarginV8(attributes, "copySubMarginV2", "tb", "top"),
    "--copy-sub-margin-right-tb": getDirectMarginV8(attributes, "copySubMarginV2", "tb", "right"),
    "--copy-sub-margin-bottom-tb": getDirectMarginV8(attributes, "copySubMarginV2", "tb", "bottom"),
    "--copy-sub-margin-left-tb": getDirectMarginV8(attributes, "copySubMarginV2", "tb", "left"),
    "--copy-sub-margin-top-sp": getDirectMarginV8(attributes, "copySubMarginV2", "sp", "top"),
    "--copy-sub-margin-right-sp": getDirectMarginV8(attributes, "copySubMarginV2", "sp", "right"),
    "--copy-sub-margin-bottom-sp": getDirectMarginV8(attributes, "copySubMarginV2", "sp", "bottom"),
    "--copy-sub-margin-left-sp": getDirectMarginV8(attributes, "copySubMarginV2", "sp", "left"),
    "--copy-sub-padding-top-pc": getDirectPaddingV8(attributes, "copySubPaddingV2", "pc", "top") ?? "0px",
    "--copy-sub-padding-right-pc": getDirectPaddingV8(attributes, "copySubPaddingV2", "pc", "right") ?? "0px",
    "--copy-sub-padding-bottom-pc": getDirectPaddingV8(attributes, "copySubPaddingV2", "pc", "bottom") ?? "0px",
    "--copy-sub-padding-left-pc": getDirectPaddingV8(attributes, "copySubPaddingV2", "pc", "left") ?? "0px",
    "--copy-sub-padding-top-md": getDirectPaddingV8(attributes, "copySubPaddingV2", "md", "top"),
    "--copy-sub-padding-right-md": getDirectPaddingV8(attributes, "copySubPaddingV2", "md", "right"),
    "--copy-sub-padding-bottom-md": getDirectPaddingV8(attributes, "copySubPaddingV2", "md", "bottom"),
    "--copy-sub-padding-left-md": getDirectPaddingV8(attributes, "copySubPaddingV2", "md", "left"),
    "--copy-sub-padding-top-tb": getDirectPaddingV8(attributes, "copySubPaddingV2", "tb", "top"),
    "--copy-sub-padding-right-tb": getDirectPaddingV8(attributes, "copySubPaddingV2", "tb", "right"),
    "--copy-sub-padding-bottom-tb": getDirectPaddingV8(attributes, "copySubPaddingV2", "tb", "bottom"),
    "--copy-sub-padding-left-tb": getDirectPaddingV8(attributes, "copySubPaddingV2", "tb", "left"),
    "--copy-sub-padding-top-sp": getDirectPaddingV8(attributes, "copySubPaddingV2", "sp", "top"),
    "--copy-sub-padding-right-sp": getDirectPaddingV8(attributes, "copySubPaddingV2", "sp", "right"),
    "--copy-sub-padding-bottom-sp": getDirectPaddingV8(attributes, "copySubPaddingV2", "sp", "bottom"),
    "--copy-sub-padding-left-sp": getDirectPaddingV8(attributes, "copySubPaddingV2", "sp", "left"),
    "--copy-sub-rotate": attributes.copySubRotate ? `${attributes.copySubRotate}deg` : undefined,
    "--copy-sub-text-color": attributes.copySubTextColor || undefined,
    "--copy-micro-font-family": getFontFamilyValueV8(attributes.copyMicroFontFamilyV2) || undefined,
    "--copy-micro-font-size-pc": getDirectFontSizeV8(attributes, "copyMicroFontSizeV2", "pc") || undefined,
    "--copy-micro-font-size-md": getDirectFontSizeV8(attributes, "copyMicroFontSizeV2", "md") || undefined,
    "--copy-micro-font-size-tb": getDirectFontSizeV8(attributes, "copyMicroFontSizeV2", "tb") || undefined,
    "--copy-micro-font-size-sp": getDirectFontSizeV8(attributes, "copyMicroFontSizeV2", "sp") || undefined,
    "--copy-micro-font-weight-pc": getDirectFontWeightV8(attributes, "copyMicroFontWeightV2", "pc") || undefined,
    "--copy-micro-font-weight-md": getDirectFontWeightV8(attributes, "copyMicroFontWeightV2", "md") || undefined,
    "--copy-micro-font-weight-tb": getDirectFontWeightV8(attributes, "copyMicroFontWeightV2", "tb") || undefined,
    "--copy-micro-font-weight-sp": getDirectFontWeightV8(attributes, "copyMicroFontWeightV2", "sp") || undefined,
    "--copy-micro-letter-spacing-pc": getDirectLetterSpacingV8(attributes, "copyMicroLetterSpacingV2", "pc") || undefined,
    "--copy-micro-letter-spacing-md": getDirectLetterSpacingV8(attributes, "copyMicroLetterSpacingV2", "md") || undefined,
    "--copy-micro-letter-spacing-tb": getDirectLetterSpacingV8(attributes, "copyMicroLetterSpacingV2", "tb") || undefined,
    "--copy-micro-letter-spacing-sp": getDirectLetterSpacingV8(attributes, "copyMicroLetterSpacingV2", "sp") || undefined,
    "--copy-micro-line-height-pc": getDirectLineHeightV8New(attributes, "copyMicroLineHeightV2", "pc") || undefined,
    "--copy-micro-line-height-md": getDirectLineHeightV8New(attributes, "copyMicroLineHeightV2", "md") || undefined,
    "--copy-micro-line-height-tb": getDirectLineHeightV8New(attributes, "copyMicroLineHeightV2", "tb") || undefined,
    "--copy-micro-line-height-sp": getDirectLineHeightV8New(attributes, "copyMicroLineHeightV2", "sp") || undefined,
    "--copy-micro-text-shadow": getTextShadowValueV2(attributes.copyMicroTextShadowV2, "pc") || undefined,
    "--copy-micro-text-shadow-md": getTextShadowValueV2(attributes.copyMicroTextShadowV2, "md") || undefined,
    "--copy-micro-text-shadow-tb": getTextShadowValueV2(attributes.copyMicroTextShadowV2, "tb") || undefined,
    "--copy-micro-text-shadow-sp": getTextShadowValueV2(attributes.copyMicroTextShadowV2, "sp") || undefined,
    "--copy-sub-font-family": getFontFamilyValueV8(attributes.copySubFontFamilyV2) || undefined,
    "--copy-sub-font-size-pc": getDirectFontSizeV8(attributes, "copySubFontSizeV2", "pc") || undefined,
    "--copy-sub-font-size-md": getDirectFontSizeV8(attributes, "copySubFontSizeV2", "md") || undefined,
    "--copy-sub-font-size-tb": getDirectFontSizeV8(attributes, "copySubFontSizeV2", "tb") || undefined,
    "--copy-sub-font-size-sp": getDirectFontSizeV8(attributes, "copySubFontSizeV2", "sp") || undefined,
    "--copy-sub-font-weight-pc": getDirectFontWeightV8(attributes, "copySubFontWeightV2", "pc") || undefined,
    "--copy-sub-font-weight-md": getDirectFontWeightV8(attributes, "copySubFontWeightV2", "md") || undefined,
    "--copy-sub-font-weight-tb": getDirectFontWeightV8(attributes, "copySubFontWeightV2", "tb") || undefined,
    "--copy-sub-font-weight-sp": getDirectFontWeightV8(attributes, "copySubFontWeightV2", "sp") || undefined,
    "--copy-sub-letter-spacing-pc": getDirectLetterSpacingV8(attributes, "copySubLetterSpacingV2", "pc") || undefined,
    "--copy-sub-letter-spacing-md": getDirectLetterSpacingV8(attributes, "copySubLetterSpacingV2", "md") || undefined,
    "--copy-sub-letter-spacing-tb": getDirectLetterSpacingV8(attributes, "copySubLetterSpacingV2", "tb") || undefined,
    "--copy-sub-letter-spacing-sp": getDirectLetterSpacingV8(attributes, "copySubLetterSpacingV2", "sp") || undefined,
    "--copy-sub-line-height-pc": getDirectLineHeightV8New(attributes, "copySubLineHeightV2", "pc") || undefined,
    "--copy-sub-line-height-md": getDirectLineHeightV8New(attributes, "copySubLineHeightV2", "md") || undefined,
    "--copy-sub-line-height-tb": getDirectLineHeightV8New(attributes, "copySubLineHeightV2", "tb") || undefined,
    "--copy-sub-line-height-sp": getDirectLineHeightV8New(attributes, "copySubLineHeightV2", "sp") || undefined,
    "--copy-sub-text-shadow": getTextShadowValueV2(attributes.copySubTextShadowV2, "pc") || undefined,
    "--copy-sub-text-shadow-md": getTextShadowValueV2(attributes.copySubTextShadowV2, "md") || undefined,
    "--copy-sub-text-shadow-tb": getTextShadowValueV2(attributes.copySubTextShadowV2, "tb") || undefined,
    "--copy-sub-text-shadow-sp": getTextShadowValueV2(attributes.copySubTextShadowV2, "sp") || undefined,
    // マイクロテキスト レイアウト V2（レスポンシブ対応）
    "--micro-text-margin-top-pc": getDirectMarginV8(attributes, "microTextMarginV2", "pc", "top") ?? "0px",
    "--micro-text-margin-right-pc": getDirectMarginV8(attributes, "microTextMarginV2", "pc", "right") ?? "0px",
    "--micro-text-margin-bottom-pc": getDirectMarginV8(attributes, "microTextMarginV2", "pc", "bottom") ?? "0px",
    "--micro-text-margin-left-pc": getDirectMarginV8(attributes, "microTextMarginV2", "pc", "left") ?? "0px",
    "--micro-text-margin-top-md": getDirectMarginV8(attributes, "microTextMarginV2", "md", "top"),
    "--micro-text-margin-right-md": getDirectMarginV8(attributes, "microTextMarginV2", "md", "right"),
    "--micro-text-margin-bottom-md": getDirectMarginV8(attributes, "microTextMarginV2", "md", "bottom"),
    "--micro-text-margin-left-md": getDirectMarginV8(attributes, "microTextMarginV2", "md", "left"),
    "--micro-text-margin-top-tb": getDirectMarginV8(attributes, "microTextMarginV2", "tb", "top"),
    "--micro-text-margin-right-tb": getDirectMarginV8(attributes, "microTextMarginV2", "tb", "right"),
    "--micro-text-margin-bottom-tb": getDirectMarginV8(attributes, "microTextMarginV2", "tb", "bottom"),
    "--micro-text-margin-left-tb": getDirectMarginV8(attributes, "microTextMarginV2", "tb", "left"),
    "--micro-text-margin-top-sp": getDirectMarginV8(attributes, "microTextMarginV2", "sp", "top"),
    "--micro-text-margin-right-sp": getDirectMarginV8(attributes, "microTextMarginV2", "sp", "right"),
    "--micro-text-margin-bottom-sp": getDirectMarginV8(attributes, "microTextMarginV2", "sp", "bottom"),
    "--micro-text-margin-left-sp": getDirectMarginV8(attributes, "microTextMarginV2", "sp", "left"),
    "--micro-text-padding-top-pc": getDirectPaddingV8(attributes, "microTextPaddingV2", "pc", "top") ?? "0px",
    "--micro-text-padding-right-pc": getDirectPaddingV8(attributes, "microTextPaddingV2", "pc", "right") ?? "0px",
    "--micro-text-padding-bottom-pc": getDirectPaddingV8(attributes, "microTextPaddingV2", "pc", "bottom") ?? "0px",
    "--micro-text-padding-left-pc": getDirectPaddingV8(attributes, "microTextPaddingV2", "pc", "left") ?? "0px",
    "--micro-text-padding-top-md": getDirectPaddingV8(attributes, "microTextPaddingV2", "md", "top"),
    "--micro-text-padding-right-md": getDirectPaddingV8(attributes, "microTextPaddingV2", "md", "right"),
    "--micro-text-padding-bottom-md": getDirectPaddingV8(attributes, "microTextPaddingV2", "md", "bottom"),
    "--micro-text-padding-left-md": getDirectPaddingV8(attributes, "microTextPaddingV2", "md", "left"),
    "--micro-text-padding-top-tb": getDirectPaddingV8(attributes, "microTextPaddingV2", "tb", "top"),
    "--micro-text-padding-right-tb": getDirectPaddingV8(attributes, "microTextPaddingV2", "tb", "right"),
    "--micro-text-padding-bottom-tb": getDirectPaddingV8(attributes, "microTextPaddingV2", "tb", "bottom"),
    "--micro-text-padding-left-tb": getDirectPaddingV8(attributes, "microTextPaddingV2", "tb", "left"),
    "--micro-text-padding-top-sp": getDirectPaddingV8(attributes, "microTextPaddingV2", "sp", "top"),
    "--micro-text-padding-right-sp": getDirectPaddingV8(attributes, "microTextPaddingV2", "sp", "right"),
    "--micro-text-padding-bottom-sp": getDirectPaddingV8(attributes, "microTextPaddingV2", "sp", "bottom"),
    "--micro-text-padding-left-sp": getDirectPaddingV8(attributes, "microTextPaddingV2", "sp", "left"),
    "--micro-text-rotate-pc": attributes.microTextRotateV2?.pc !== undefined && attributes.microTextRotateV2?.pc !== "" ? `${attributes.microTextRotateV2.pc}deg` : "0deg",
    "--micro-text-rotate-md": attributes.microTextRotateV2?.md !== undefined && attributes.microTextRotateV2?.md !== "" ? `${attributes.microTextRotateV2.md}deg` : undefined,
    "--micro-text-rotate-tb": attributes.microTextRotateV2?.tb !== undefined && attributes.microTextRotateV2?.tb !== "" ? `${attributes.microTextRotateV2.tb}deg` : undefined,
    "--micro-text-rotate-sp": attributes.microTextRotateV2?.sp !== undefined && attributes.microTextRotateV2?.sp !== "" ? `${attributes.microTextRotateV2.sp}deg` : undefined,
    "--micro-text-text-color": attributes.microTextTextColor ? hexToRgba(attributes.microTextTextColor, attributes.microTextTextColorAlpha ?? 1) : undefined,
    "--micro-text-text-shadow": getTextShadowValueV2(attributes.microTextTextShadowV2, "pc") || undefined,
    "--micro-text-text-shadow-md": getTextShadowValueV2(attributes.microTextTextShadowV2, "md") || undefined,
    "--micro-text-text-shadow-tb": getTextShadowValueV2(attributes.microTextTextShadowV2, "tb") || undefined,
    "--micro-text-text-shadow-sp": getTextShadowValueV2(attributes.microTextTextShadowV2, "sp") || undefined,
    "--micro-text-font-family": getFontFamilyValueV8(attributes.microTextFontFamilyV2) || undefined,
    "--micro-text-font-size-pc": getDirectFontSizeV8(attributes, "microTextFontSizeV2", "pc") || undefined,
    "--micro-text-font-size-md": getDirectFontSizeV8(attributes, "microTextFontSizeV2", "md") || undefined,
    "--micro-text-font-size-tb": getDirectFontSizeV8(attributes, "microTextFontSizeV2", "tb") || undefined,
    "--micro-text-font-size-sp": getDirectFontSizeV8(attributes, "microTextFontSizeV2", "sp") || undefined,
    "--micro-text-font-weight-pc": getDirectFontWeightV8(attributes, "microTextFontWeightV2", "pc") || undefined,
    "--micro-text-font-weight-md": getDirectFontWeightV8(attributes, "microTextFontWeightV2", "md") || undefined,
    "--micro-text-font-weight-tb": getDirectFontWeightV8(attributes, "microTextFontWeightV2", "tb") || undefined,
    "--micro-text-font-weight-sp": getDirectFontWeightV8(attributes, "microTextFontWeightV2", "sp") || undefined,
    "--micro-text-letter-spacing-pc": getDirectLetterSpacingV8(attributes, "microTextLetterSpacingV2", "pc") || undefined,
    "--micro-text-letter-spacing-md": getDirectLetterSpacingV8(attributes, "microTextLetterSpacingV2", "md") || undefined,
    "--micro-text-letter-spacing-tb": getDirectLetterSpacingV8(attributes, "microTextLetterSpacingV2", "tb") || undefined,
    "--micro-text-letter-spacing-sp": getDirectLetterSpacingV8(attributes, "microTextLetterSpacingV2", "sp") || undefined,
    "--micro-text-line-height-pc": getDirectLineHeightV8(attributes, "microTextLineHeightV2", "pc") || undefined,
    "--micro-text-line-height-md": getDirectLineHeightV8(attributes, "microTextLineHeightV2", "md") || undefined,
    "--micro-text-line-height-tb": getDirectLineHeightV8(attributes, "microTextLineHeightV2", "tb") || undefined,
    "--micro-text-line-height-sp": getDirectLineHeightV8(attributes, "microTextLineHeightV2", "sp") || undefined,
    // サブテキスト レイアウト V2（レスポンシブ対応）
    "--sub-text-margin-top-pc": getDirectMarginV8(attributes, "subTextMarginV2", "pc", "top") ?? "0px",
    "--sub-text-margin-right-pc": getDirectMarginV8(attributes, "subTextMarginV2", "pc", "right") ?? "0px",
    "--sub-text-margin-bottom-pc": getDirectMarginV8(attributes, "subTextMarginV2", "pc", "bottom") ?? "0px",
    "--sub-text-margin-left-pc": getDirectMarginV8(attributes, "subTextMarginV2", "pc", "left") ?? "0px",
    "--sub-text-margin-top-md": getDirectMarginV8(attributes, "subTextMarginV2", "md", "top"),
    "--sub-text-margin-right-md": getDirectMarginV8(attributes, "subTextMarginV2", "md", "right"),
    "--sub-text-margin-bottom-md": getDirectMarginV8(attributes, "subTextMarginV2", "md", "bottom"),
    "--sub-text-margin-left-md": getDirectMarginV8(attributes, "subTextMarginV2", "md", "left"),
    "--sub-text-margin-top-tb": getDirectMarginV8(attributes, "subTextMarginV2", "tb", "top"),
    "--sub-text-margin-right-tb": getDirectMarginV8(attributes, "subTextMarginV2", "tb", "right"),
    "--sub-text-margin-bottom-tb": getDirectMarginV8(attributes, "subTextMarginV2", "tb", "bottom"),
    "--sub-text-margin-left-tb": getDirectMarginV8(attributes, "subTextMarginV2", "tb", "left"),
    "--sub-text-margin-top-sp": getDirectMarginV8(attributes, "subTextMarginV2", "sp", "top"),
    "--sub-text-margin-right-sp": getDirectMarginV8(attributes, "subTextMarginV2", "sp", "right"),
    "--sub-text-margin-bottom-sp": getDirectMarginV8(attributes, "subTextMarginV2", "sp", "bottom"),
    "--sub-text-margin-left-sp": getDirectMarginV8(attributes, "subTextMarginV2", "sp", "left"),
    "--sub-text-padding-top-pc": getDirectPaddingV8(attributes, "subTextPaddingV2", "pc", "top") ?? "0px",
    "--sub-text-padding-right-pc": getDirectPaddingV8(attributes, "subTextPaddingV2", "pc", "right") ?? "0px",
    "--sub-text-padding-bottom-pc": getDirectPaddingV8(attributes, "subTextPaddingV2", "pc", "bottom") ?? "0px",
    "--sub-text-padding-left-pc": getDirectPaddingV8(attributes, "subTextPaddingV2", "pc", "left") ?? "0px",
    "--sub-text-padding-top-md": getDirectPaddingV8(attributes, "subTextPaddingV2", "md", "top"),
    "--sub-text-padding-right-md": getDirectPaddingV8(attributes, "subTextPaddingV2", "md", "right"),
    "--sub-text-padding-bottom-md": getDirectPaddingV8(attributes, "subTextPaddingV2", "md", "bottom"),
    "--sub-text-padding-left-md": getDirectPaddingV8(attributes, "subTextPaddingV2", "md", "left"),
    "--sub-text-padding-top-tb": getDirectPaddingV8(attributes, "subTextPaddingV2", "tb", "top"),
    "--sub-text-padding-right-tb": getDirectPaddingV8(attributes, "subTextPaddingV2", "tb", "right"),
    "--sub-text-padding-bottom-tb": getDirectPaddingV8(attributes, "subTextPaddingV2", "tb", "bottom"),
    "--sub-text-padding-left-tb": getDirectPaddingV8(attributes, "subTextPaddingV2", "tb", "left"),
    "--sub-text-padding-top-sp": getDirectPaddingV8(attributes, "subTextPaddingV2", "sp", "top"),
    "--sub-text-padding-right-sp": getDirectPaddingV8(attributes, "subTextPaddingV2", "sp", "right"),
    "--sub-text-padding-bottom-sp": getDirectPaddingV8(attributes, "subTextPaddingV2", "sp", "bottom"),
    "--sub-text-padding-left-sp": getDirectPaddingV8(attributes, "subTextPaddingV2", "sp", "left"),
    "--sub-text-rotate-pc": attributes.subTextRotateV2?.pc !== undefined && attributes.subTextRotateV2?.pc !== "" ? `${attributes.subTextRotateV2.pc}deg` : "0deg",
    "--sub-text-rotate-md": attributes.subTextRotateV2?.md !== undefined && attributes.subTextRotateV2?.md !== "" ? `${attributes.subTextRotateV2.md}deg` : undefined,
    "--sub-text-rotate-tb": attributes.subTextRotateV2?.tb !== undefined && attributes.subTextRotateV2?.tb !== "" ? `${attributes.subTextRotateV2.tb}deg` : undefined,
    "--sub-text-rotate-sp": attributes.subTextRotateV2?.sp !== undefined && attributes.subTextRotateV2?.sp !== "" ? `${attributes.subTextRotateV2.sp}deg` : undefined,
    "--sub-text-text-color": attributes.subTextTextColor ? hexToRgba(attributes.subTextTextColor, attributes.subTextTextColorAlpha ?? 1) : undefined,
    "--sub-text-text-shadow": getTextShadowValueV2(attributes.subTextTextShadowV2, "pc") || undefined,
    "--sub-text-text-shadow-md": getTextShadowValueV2(attributes.subTextTextShadowV2, "md") || undefined,
    "--sub-text-text-shadow-tb": getTextShadowValueV2(attributes.subTextTextShadowV2, "tb") || undefined,
    "--sub-text-text-shadow-sp": getTextShadowValueV2(attributes.subTextTextShadowV2, "sp") || undefined,
    "--sub-text-font-family": getFontFamilyValueV8(attributes.subTextFontFamilyV2) || undefined,
    "--sub-text-font-size-pc": getDirectFontSizeV8(attributes, "subTextFontSizeV2", "pc") || undefined,
    "--sub-text-font-size-md": getDirectFontSizeV8(attributes, "subTextFontSizeV2", "md") || undefined,
    "--sub-text-font-size-tb": getDirectFontSizeV8(attributes, "subTextFontSizeV2", "tb") || undefined,
    "--sub-text-font-size-sp": getDirectFontSizeV8(attributes, "subTextFontSizeV2", "sp") || undefined,
    "--sub-text-font-weight-pc": getDirectFontWeightV8(attributes, "subTextFontWeightV2", "pc") || undefined,
    "--sub-text-font-weight-md": getDirectFontWeightV8(attributes, "subTextFontWeightV2", "md") || undefined,
    "--sub-text-font-weight-tb": getDirectFontWeightV8(attributes, "subTextFontWeightV2", "tb") || undefined,
    "--sub-text-font-weight-sp": getDirectFontWeightV8(attributes, "subTextFontWeightV2", "sp") || undefined,
    "--sub-text-letter-spacing-pc": getDirectLetterSpacingV8(attributes, "subTextLetterSpacingV2", "pc") || undefined,
    "--sub-text-letter-spacing-md": getDirectLetterSpacingV8(attributes, "subTextLetterSpacingV2", "md") || undefined,
    "--sub-text-letter-spacing-tb": getDirectLetterSpacingV8(attributes, "subTextLetterSpacingV2", "tb") || undefined,
    "--sub-text-letter-spacing-sp": getDirectLetterSpacingV8(attributes, "subTextLetterSpacingV2", "sp") || undefined,
    "--sub-text-line-height-pc": getDirectLineHeightV8(attributes, "subTextLineHeightV2", "pc") || undefined,
    "--sub-text-line-height-md": getDirectLineHeightV8(attributes, "subTextLineHeightV2", "md") || undefined,
    "--sub-text-line-height-tb": getDirectLineHeightV8(attributes, "subTextLineHeightV2", "tb") || undefined,
    "--sub-text-line-height-sp": getDirectLineHeightV8(attributes, "subTextLineHeightV2", "sp") || undefined,
    "--font-family": getFontFamilyValue(attributes.fontFamily) || "inherit",
    ...getFontSizeHoverStylesForEditor(attributes, previewDevice),
    // フォントウェイト（ホバー状態）- レスポンシブ対応
    "--font-weight-pc-hover": getFontWeightValueHover(attributes, "pc") || undefined,
    "--font-weight-md-hover": getDirectFontWeight(attributes, "md", true) || undefined,
    "--font-weight-tb-hover": getDirectFontWeight(attributes, "tb", true) || undefined,
    "--font-weight-sp-hover": getDirectFontWeight(attributes, "sp", true) || undefined,
    // 行間（ホバー状態）- レスポンシブ対応
    "--line-height-pc-hover": getLineHeightValueHover(attributes, "pc") || undefined,
    "--line-height-md-hover": getDirectLineHeight(attributes, "md", true) || undefined,
    "--line-height-tb-hover": getDirectLineHeight(attributes, "tb", true) || undefined,
    "--line-height-sp-hover": getDirectLineHeight(attributes, "sp", true) || undefined,
    // 文字間（ホバー状態）- レスポンシブ対応
    "--letter-spacing-pc-hover": getLetterSpacingValueHover(attributes, "pc") || undefined,
    "--letter-spacing-md-hover": getDirectLetterSpacing(attributes, "md", true) || undefined,
    "--letter-spacing-tb-hover": getDirectLetterSpacing(attributes, "tb", true) || undefined,
    "--letter-spacing-sp-hover": getDirectLetterSpacing(attributes, "sp", true) || undefined,
    "--font-family-hover": getFontFamilyValue(attributes.fontFamilyHover) || undefined,
    ...spacingStyles,
    ...getBackgroundColorStylesV2ForEditor(attributes, previewDevice),
    ...getBackgroundColorHoverStylesV2ForEditor(attributes, previewDevice),
    ...getBackgroundImageStylesV2ForEditor(attributes, previewDevice),
    ...getBackgroundImageHoverStylesV2ForEditor(attributes, previewDevice),
    ...getBackgroundBaseColorStylesV2ForEditor(attributes, previewDevice),
    ...getBackgroundBaseColorHoverStylesV2ForEditor(attributes, previewDevice),
    ...getBackgroundPatternStylesV2ForEditor(attributes, previewDevice),
    ...getBackgroundPatternHoverStylesV2ForEditor(attributes, previewDevice),
    ...(attributes.backgroundMediaType === "video"
      ? {
          "--background-video-fit": backgroundVideoFit,
          "--background-video-position-x": `${backgroundVideoPositionX}%`,
          "--background-video-position-y": `${backgroundVideoPositionY}%`,
          "--background-video-offset-x": `${backgroundVideoPositionX - 50}%`,
          "--background-video-offset-y": `${backgroundVideoPositionY - 50}%`,
          "--background-video-width": videoSize.width,
          "--background-video-height": videoSize.height,
          "--background-video-embed-width": videoSize.embedWidth,
          "--background-video-embed-height": videoSize.embedHeight,
          "--background-poster-size": posterSize.backgroundSize,
          "--background-poster-position-x": `${backgroundPosterPositionX}%`,
          "--background-poster-position-y": `${backgroundPosterPositionY}%`,
          "--background-video-poster-image": attributes.backgroundVideoPoster ? `url(${attributes.backgroundVideoPoster})` : "none",
        }
      : {}),
    ...getBorderStylesForEditor(attributes, previewDevice),
    ...getBorderHoverStylesForEditor(attributes, previewDevice),
    ...getRadiusStylesForEditor(attributes, previewDevice),
    ...getRadiusHoverStylesForEditor(attributes, previewDevice),
    ...getShadowStylesForEditor(attributes, previewDevice),
    ...getShadowHoverStylesForEditor(attributes, previewDevice),
    ...getInnerShadowStylesForEditor(attributes, previewDevice),
    ...getInnerShadowHoverStylesForEditor(attributes, previewDevice),
    ...getOpacityStylesForEditor(attributes, previewDevice),
    ...getOpacityHoverStylesForEditor(attributes, previewDevice),
    ...getLayoutWidthStylesV2ForEditor(attributes, previewDevice),
    ...getLayoutHeightStylesV2ForEditor(attributes, previewDevice),
    ...getLayoutPositionStylesForEditor(attributes, previewDevice),
    ...getIconSizeStylesV2ForEditor(attributes, previewDevice),
    ...getIconSizeHoverStylesV2ForEditor(attributes, previewDevice),
    ...getIconPositionStylesV2ForEditor(attributes, previewDevice),
    ...getIconPositionHoverStylesV2ForEditor(attributes, previewDevice),
    ...getIconColorStylesV2ForEditor(attributes, previewDevice),
    ...getIconColorHoverStylesV2ForEditor(attributes, previewDevice),
    ...(icon &&
      icon !== "" && {
        "--icon-stroke-width": iconStrokeWidth || 1.75,
        "--icon-stroke-width-hover": attributes.iconStrokeWidthHover !== undefined ? attributes.iconStrokeWidthHover : iconStrokeWidth || 1.75,
      }),
    "--button-content-justify": attributes.buttonContentJustify || "center",
    "--text-align": attributes.textAlign || "center",
    "--text-align-items": attributes.textAlign === "left" ? "flex-start" : attributes.textAlign === "right" ? "flex-end" : "center",
    ...getIconFrameStylesForEditor(attributes, previewDevice),
    ...getIconFrameHoverStylesForEditor(attributes, previewDevice),
    ...(hasThumbnailImage(attributes) ? getThumbnailStylesForEdit(attributes, previewDevice) : {}),
    ...getBandStylesForEdit(attributes, previewDevice),
    // Transition/animation variables（デフォルト値は省略 - SCSSフォールバックが適用される）
    // 常に出力が必要な変数（block.jsonデフォルト ≠ SCSSフォールバック、またはSCSSフォールバックなし）
    "--text-animation-duration": `${attributes.textAnimationTransitionDuration || 300}ms`,
    "--text-animation-easing": attributes.textAnimationTransitionEasing || "ease-out",
    "--icon-transition-duration": `${attributes.iconTransitionDuration ?? 300}ms`,
    "--style-transition-duration": `${attributes.styleTransitionDuration ?? 300}ms`,
    "--frame-animation-interval": `${attributes.frameAnimationInterval ?? 1000}ms`,
    "--frame-animation-total": `${(attributes.frameAnimationTransitionDuration || 2000) + (attributes.frameAnimationInterval ?? 1000)}ms`,
    "--button-animation-duration": `${attributes.buttonAnimationTransitionDuration || 2000}ms`,
    "--button-animation-interval": `${attributes.buttonAnimationInterval ?? 1000}ms`,
    "--button-animation-total": `${(attributes.buttonAnimationTransitionDuration || 2000) + (attributes.buttonAnimationInterval ?? 1000)}ms`,
    // デフォルト値省略可能な変数（block.jsonデフォルト = SCSSフォールバック）
    ...((attributes.textAnimationTransitionDelay || 0) !== 0 ? { "--text-animation-delay": `${attributes.textAnimationTransitionDelay || 0}ms` } : {}),
    ...((attributes.iconAnimationTransitionDuration || 500) !== 500 ? { "--icon-animation-duration": `${attributes.iconAnimationTransitionDuration || 500}ms` } : {}),
    ...((attributes.iconAnimationTransitionDelay || 200) !== 200 ? { "--icon-animation-delay": `${attributes.iconAnimationTransitionDelay || 200}ms` } : {}),
    ...((attributes.iconAnimationTransitionEasing || "ease-in-out") !== "ease-in-out" ? { "--icon-animation-easing": attributes.iconAnimationTransitionEasing || "ease-in-out" } : {}),
    ...((attributes.iconTransitionDelay ?? 0) !== 0 ? { "--icon-transition-delay": `${attributes.iconTransitionDelay ?? 0}ms` } : {}),
    ...((attributes.iconTransitionEasing || "ease") !== "ease" ? { "--icon-transition-easing": attributes.iconTransitionEasing || "ease" } : {}),
    ...((attributes.frameAnimationTransitionDuration || 2000) !== 2000 ? { "--frame-animation-duration": `${attributes.frameAnimationTransitionDuration || 2000}ms` } : {}),
    ...((attributes.frameAnimationTransitionEasing || "ease-in-out") !== "ease-in-out" ? { "--frame-animation-easing": attributes.frameAnimationTransitionEasing || "ease-in-out" } : {}),
    ...((attributes.buttonAnimationTransitionEasing || "ease-in-out") !== "ease-in-out" ? { "--button-animation-easing": attributes.buttonAnimationTransitionEasing || "ease-in-out" } : {}),
    ...((attributes.backgroundTransitionDuration ?? 150) !== 150 ? { "--background-transition-duration": `${attributes.backgroundTransitionDuration ?? 150}ms` } : {}),
    ...((attributes.backgroundTransitionDelay ?? 0) !== 0 ? { "--background-transition-delay": `${attributes.backgroundTransitionDelay ?? 0}ms` } : {}),
    ...((attributes.backgroundTransitionEasing || "ease") !== "ease" ? { "--background-transition-easing": attributes.backgroundTransitionEasing || "ease" } : {}),
    ...((attributes.thumbnailTransitionDuration ?? 300) !== 300 ? { "--thumbnail-transition-duration": `${attributes.thumbnailTransitionDuration ?? 300}ms` } : {}),
    ...((attributes.thumbnailTransitionDelay ?? 0) !== 0 ? { "--thumbnail-transition-delay": `${attributes.thumbnailTransitionDelay ?? 0}ms` } : {}),
    ...((attributes.thumbnailTransitionEasing || "ease") !== "ease" ? { "--thumbnail-transition-easing": attributes.thumbnailTransitionEasing || "ease" } : {}),
    ...((attributes.bandTransitionDuration ?? 300) !== 300 ? { "--band-transition-duration": `${attributes.bandTransitionDuration ?? 300}ms` } : {}),
    ...((attributes.bandTransitionDelay ?? 0) !== 0 ? { "--band-transition-delay": `${attributes.bandTransitionDelay ?? 0}ms` } : {}),
    ...((attributes.bandTransitionEasing || "ease") !== "ease" ? { "--band-transition-easing": attributes.bandTransitionEasing || "ease" } : {}),
    ...((attributes.styleTransitionDelay ?? 0) !== 0 ? { "--style-transition-delay": `${attributes.styleTransitionDelay ?? 0}ms` } : {}),
    ...((attributes.styleTransitionEasing || "ease") !== "ease" ? { "--style-transition-easing": attributes.styleTransitionEasing || "ease" } : {}),
    // Layer z-index
    ...(attributes.layerZIndex?.content !== undefined && attributes.layerZIndex.content !== 20 ? { "--layer-z-index-content": attributes.layerZIndex.content } : {}),
    ...(attributes.layerZIndex?.thumbnail !== undefined && attributes.layerZIndex.thumbnail !== 10 ? { "--layer-z-index-thumbnail": attributes.layerZIndex.thumbnail } : {}),
    ...(attributes.layerZIndex?.band !== undefined && attributes.layerZIndex.band !== 5 ? { "--layer-z-index-band": attributes.layerZIndex.band } : {}),
    ...(attributes.layerZIndex?.bg !== undefined && attributes.layerZIndex.bg !== 0 ? { "--layer-z-index-bg": attributes.layerZIndex.bg } : {}),
  };

  const finalRichTextStyle = getPreviewStyles(richTextStyle, previewDevice);

  const handleAlignmentChange = (alignment) => {
    const currentMargin = attributes.marginV2 || {
      pc: { bulk: 0, bulkUnit: "px", top: 0, topUnit: "px", right: 0, rightUnit: "px", bottom: 0, bottomUnit: "px", left: 0, leftUnit: "px", useIndividual: false },
      md: { bulk: "", bulkUnit: "px", top: "", topUnit: "px", right: "", rightUnit: "px", bottom: "", bottomUnit: "px", left: "", leftUnit: "px", useIndividual: false },
      tb: { bulk: "", bulkUnit: "px", top: "", topUnit: "px", right: "", rightUnit: "px", bottom: "", bottomUnit: "px", left: "", leftUnit: "px", useIndividual: false },
      sp: { bulk: "", bulkUnit: "px", top: "", topUnit: "px", right: "", rightUnit: "px", bottom: "", bottomUnit: "px", left: "", leftUnit: "px", useIndividual: false },
    };
    const newMargin = JSON.parse(JSON.stringify(currentMargin));
    newMargin.pc.useIndividual = true;

    if (alignment === "left") {
      newMargin.pc.left = 0;
      newMargin.pc.leftUnit = "px";
      newMargin.pc.right = 0;
      newMargin.pc.rightUnit = "auto";
    } else if (alignment === "center") {
      newMargin.pc.left = 0;
      newMargin.pc.leftUnit = "auto";
      newMargin.pc.right = 0;
      newMargin.pc.rightUnit = "auto";
    } else if (alignment === "right") {
      newMargin.pc.left = 0;
      newMargin.pc.leftUnit = "auto";
      newMargin.pc.right = 0;
      newMargin.pc.rightUnit = "px";
    }
    setAttributes({ marginV2: newMargin });
  };

  const getCurrentAlignment = () => {
    const marginData = attributes.marginV2;
    if (!marginData || !marginData.pc) return "center";

    const pcData = marginData.pc;
    const leftUnit = pcData.leftUnit || "px";
    const rightUnit = pcData.rightUnit || "px";

    if (leftUnit !== "auto" && rightUnit === "auto") {
      return "left";
    } else if (leftUnit === "auto" && rightUnit !== "auto") {
      return "right";
    } else {
      return "center";
    }
  };

  const handleContentJustifyChange = (justify) => {
    const textAlignMap = {
      "flex-start": "left",
      center: "center",
      "flex-end": "right",
    };
    setAttributes({
      buttonContentJustify: justify,
      textAlign: textAlignMap[justify] || "center",
    });
  };

  const renderTextWithChars = (text) => {
    if (!text) return null;
    return Array.from(text).map((char, index) => (
      <span key={index} className="char" style={{ ["--char-index"]: index }}>
        {char === " " ? "\u00A0" : char}
      </span>
    ));
  };

  const hoverText = contentHover || content;

  const displayClasses = getDisplayClassesForEditor(attributes, previewDevice);
  const frameAnimationClass = attributes.frameAnimation && attributes.frameAnimation !== "none" ? ` zenblocks-button-frame-animation-${attributes.frameAnimation}` : "";
  const buttonAnimationClass = attributes.buttonAnimation && attributes.buttonAnimation !== "none" ? ` zenblocks-button-animation-${attributes.buttonAnimation}` : "";
  const microcopyDesignClass = attributes.copyMicro ? ` zenblocks-microcopy-${attributes.copyMicroDesign || "01"}` : "";
  const uniqueIdClass = attributes.uniqueId ? ` zenblocks-${attributes.uniqueId}` : "";

  const blockProps = useBlockProps({
    className: `wp-block-zenblocks-button-basic button-basic zenblocks-button-hover-animation-icon-${attributes.iconAnimation || "01"} zenblocks-button-hover-animation-text-${
      attributes.hoverAnimation || "01"
    }${frameAnimationClass}${buttonAnimationClass}${microcopyDesignClass}${uniqueIdClass}${attributes.layoutUseCustomPositionPC ? " is-custom-position-pc" : ""}${attributes.layoutUseCustomPositionMD ? " is-custom-position-md" : ""}${
      attributes.layoutUseCustomPositionTB ? " is-custom-position-tb" : ""
    }${attributes.layoutUseCustomPositionSP ? " is-custom-position-sp" : ""}${attributes.backgroundMediaType === "video" ? " is-bg-video" : ""}${displayClasses.length > 0 ? " " + displayClasses.join(" ") : ""}${isSwitchingPreview ? " is-switching-preview" : ""}${ENABLE_HOVER_PREVIEW && activeStateTab === "hover" ? " is-hover-preview" : ""}${isFreePreview && showProBadge ? " is-free-preview" : ""}`.trim(),
    style: finalRichTextStyle,
  });

  return (
    <>
      <BlockControls>
        {showProBadge && (
          <ToolbarGroup>
            <ToolbarButton
              icon={() => (
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 300 299" width="20" height="20" fill="currentColor">
                  <path d="M222.12,68.81c.63-1.06-.13-2.41-1.37-2.41H88.85c-.66,0-1.2.54-1.2,1.2v35.18c0,.66.54,1.2,1.2,1.2h63.24c1.24,0,2,1.35,1.37,2.41l-75.58,123.8c-.63,1.06.13,2.41,1.37,2.41h131.91c.66,0,1.2-.54,1.2-1.2v-35.18c0-.66-.54-1.2-1.2-1.2h-65.4c-1.24,0-2-1.35-1.37-2.41l77.74-123.8Z" />
                </svg>
              )}
              label={isFreePreview ? __("Exit Free Preview", "zenblocks") : __("Preview as Free", "zenblocks")}
              isPressed={isFreePreview}
              onClick={() => setIsFreePreview(!isFreePreview)}
              className="zenblocks-toolbar-pro-badge"
            />
          </ToolbarGroup>
        )}
        <ToolbarGroup>
          <ToolbarButton
            icon={() => (
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="currentColor">
                <path d="M7 2l10 9.5-4.5 1 2.5 6-2 1-2.5-6L7 16.5V2z" />
              </svg>
            )}
            label={activeStateTab === "hover" ? __("Hover style active", "zenblocks") : __("Default style active", "zenblocks")}
            isPressed={ENABLE_HOVER_PREVIEW && activeStateTab === "hover"}
            onClick={() => {
              if (!ENABLE_HOVER_PREVIEW) return;
              setActiveStateTab(activeStateTab === "hover" ? "normal" : "hover");
            }}
          />
        </ToolbarGroup>
        <ToolbarGroup>
          <ToolbarDropdownMenu
            icon={() => {
              if (attributes.buttonContentJustify === "flex-end") {
                return (
                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style={{ fill: "none", stroke: "currentColor" }} strokeLinecap="round" strokeLinejoin="round">
                    <path strokeWidth="2" d="M20 4v16" />
                    <path strokeWidth="2" d="M4 6h12" />
                    <path strokeWidth="2" d="M10 12h6" />
                    <path strokeWidth="2" d="M6 18h10" />
                  </svg>
                );
              }
              if (attributes.buttonContentJustify === "center") {
                return (
                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style={{ fill: "none", stroke: "currentColor" }} strokeLinecap="round" strokeLinejoin="round">
                    <path strokeWidth="2" d="M4 6l16 0" />
                    <path strokeWidth="2" d="M8 12l8 0" />
                    <path strokeWidth="2" d="M6 18l12 0" />
                  </svg>
                );
              }
              return (
                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style={{ fill: "none", stroke: "currentColor" }} strokeLinecap="round" strokeLinejoin="round">
                  <path strokeWidth="2" d="M4 4v16" />
                  <path strokeWidth="2" d="M8 6h12" />
                  <path strokeWidth="2" d="M8 12h6" />
                  <path strokeWidth="2" d="M8 18h10" />
                </svg>
              );
            }}
            label={__("Text Alignment", "zenblocks")}
            controls={[
              {
                icon: () => (
                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style={{ fill: "none", stroke: "currentColor" }} strokeLinecap="round" strokeLinejoin="round">
                    <path strokeWidth="2" d="M4 4v16" />
                    <path strokeWidth="2" d="M8 6h12" />
                    <path strokeWidth="2" d="M8 12h6" />
                    <path strokeWidth="2" d="M8 18h10" />
                  </svg>
                ),
                title: __("Align Text Left", "zenblocks"),
                isActive: attributes.buttonContentJustify === "flex-start",
                onClick: () => handleContentJustifyChange("flex-start"),
              },
              {
                icon: () => (
                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style={{ fill: "none", stroke: "currentColor" }} strokeLinecap="round" strokeLinejoin="round">
                    <path strokeWidth="2" d="M4 6l16 0" />
                    <path strokeWidth="2" d="M8 12l8 0" />
                    <path strokeWidth="2" d="M6 18l12 0" />
                  </svg>
                ),
                title: __("Align Text Center", "zenblocks"),
                isActive: attributes.buttonContentJustify === "center",
                onClick: () => handleContentJustifyChange("center"),
              },
              {
                icon: () => (
                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style={{ fill: "none", stroke: "currentColor" }} strokeLinecap="round" strokeLinejoin="round">
                    <path strokeWidth="2" d="M20 4v16" />
                    <path strokeWidth="2" d="M4 6h12" />
                    <path strokeWidth="2" d="M10 12h6" />
                    <path strokeWidth="2" d="M6 18h10" />
                  </svg>
                ),
                title: __("Align Text Right", "zenblocks"),
                isActive: attributes.buttonContentJustify === "flex-end",
                onClick: () => handleContentJustifyChange("flex-end"),
              },
            ]}
          />
        </ToolbarGroup>
        <ToolbarGroup>
          <ToolbarDropdownMenu
            icon={getCurrentAlignment() === "right" ? justifyRight : getCurrentAlignment() === "center" ? justifyCenter : justifyLeft}
            label={__("Button Alignment", "zenblocks")}
            controls={[
              {
                icon: justifyLeft,
                title: __("Align Button Left", "zenblocks"),
                isActive: getCurrentAlignment() === "left",
                onClick: () => handleAlignmentChange("left"),
              },
              {
                icon: justifyCenter,
                title: __("Align Button Center", "zenblocks"),
                isActive: getCurrentAlignment() === "center",
                onClick: () => handleAlignmentChange("center"),
              },
              {
                icon: justifyRight,
                title: __("Align Button Right", "zenblocks"),
                isActive: getCurrentAlignment() === "right",
                onClick: () => handleAlignmentChange("right"),
              },
            ]}
          />
        </ToolbarGroup>
        <ToolbarGroup>
          <ToolbarDropdownMenu
            icon={() => {
              const maxWidth = attributes.layoutWidthV2?.pc?.maxValue;
              if (maxWidth === 260) return <span style={{ fontWeight: 600, fontSize: "13px" }}>S</span>;
              if (maxWidth === 340) return <span style={{ fontWeight: 600, fontSize: "13px" }}>M</span>;
              if (maxWidth === 560) return <span style={{ fontWeight: 600, fontSize: "13px" }}>L</span>;
              return (
                <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" style={{ fill: "none", stroke: "currentColor" }} strokeLinecap="round" strokeLinejoin="round">
                  <path strokeWidth="2" d="M4 11v8a1 1 0 0 0 1 1h8m-9 -14v-1a1 1 0 0 1 1 -1h1m5 0h2m5 0h1a1 1 0 0 1 1 1v1m0 5v2m0 5v1a1 1 0 0 1 -1 1h-1" />
                  <path strokeWidth="2" d="M4 12h7a1 1 0 0 1 1 1v7" />
                </svg>
              );
            }}
            label={__("Size", "zenblocks")}
            controls={[
              {
                icon: () => <span style={{ fontWeight: 600, fontSize: "13px", width: "25px", display: "inline-block", textAlign: "center" }}>S</span>,
                title: __("max-width: 260px", "zenblocks"),
                isActive: attributes.layoutWidthV2?.pc?.maxValue === 260,
                onClick: () => {
                  const currentWidthData = attributes.layoutWidthV2 || {};
                  const newWidthData = {
                    pc: { useCustom: true, value: 100, unit: "%", minUseCustom: false, minValue: 0, minUnit: "px", maxUseCustom: true, maxValue: 260, maxUnit: "px" },
                    md: currentWidthData.md || { useCustom: null, value: "", unit: "", minUseCustom: null, minValue: "", minUnit: "", maxUseCustom: null, maxValue: "", maxUnit: "" },
                    tb: currentWidthData.tb || { useCustom: null, value: "", unit: "", minUseCustom: null, minValue: "", minUnit: "", maxUseCustom: null, maxValue: "", maxUnit: "" },
                    sp: { useCustom: true, value: 100, unit: "%", minUseCustom: false, minValue: 0, minUnit: "px", maxUseCustom: true, maxValue: 260, maxUnit: "px" },
                  };
                  const currentHeightData = attributes.layoutHeightV2 || {};
                  const newHeightData = {
                    pc: { useCustom: true, value: 100, unit: "%", minUseCustom: true, minValue: 50, minUnit: "px", maxUseCustom: false, maxValue: 0, maxUnit: "px" },
                    md: currentHeightData.md || { useCustom: null, value: "", unit: "", minUseCustom: null, minValue: "", minUnit: "", maxUseCustom: null, maxValue: "", maxUnit: "" },
                    tb: currentHeightData.tb || { useCustom: null, value: "", unit: "", minUseCustom: null, minValue: "", minUnit: "", maxUseCustom: null, maxValue: "", maxUnit: "" },
                    sp: { useCustom: true, value: 100, unit: "%", minUseCustom: true, minValue: 50, minUnit: "px", maxUseCustom: false, maxValue: 0, maxUnit: "px" },
                  };
                  const newPaddingData = {
                    pc: { bulk: 10, bulkUnit: "px", top: 10, topUnit: "px", right: 10, rightUnit: "px", bottom: 10, bottomUnit: "px", left: 10, leftUnit: "px", useIndividual: false },
                    md: { bulk: "", bulkUnit: "px", top: "", topUnit: "px", right: "", rightUnit: "px", bottom: "", bottomUnit: "px", left: "", leftUnit: "px", useIndividual: false },
                    tb: { bulk: "", bulkUnit: "px", top: "", topUnit: "px", right: "", rightUnit: "px", bottom: "", bottomUnit: "px", left: "", leftUnit: "px", useIndividual: false },
                    sp: { bulk: 10, bulkUnit: "px", top: 10, topUnit: "px", right: 10, rightUnit: "px", bottom: 10, bottomUnit: "px", left: 10, leftUnit: "px", useIndividual: false },
                  };
                  setAttributes({ layoutWidthV2: newWidthData, layoutHeightV2: newHeightData, paddingV2: newPaddingData });
                },
              },
              {
                icon: () => <span style={{ fontWeight: 600, fontSize: "13px", width: "25px", display: "inline-block", textAlign: "center" }}>M</span>,
                title: __("max-width: 340px", "zenblocks"),
                isActive: attributes.layoutWidthV2?.pc?.maxValue === 340,
                onClick: () => {
                  const currentWidthData = attributes.layoutWidthV2 || {};
                  const newWidthData = {
                    pc: { useCustom: true, value: 100, unit: "%", minUseCustom: false, minValue: 0, minUnit: "px", maxUseCustom: true, maxValue: 340, maxUnit: "px" },
                    md: currentWidthData.md || { useCustom: null, value: "", unit: "", minUseCustom: null, minValue: "", minUnit: "", maxUseCustom: null, maxValue: "", maxUnit: "" },
                    tb: currentWidthData.tb || { useCustom: null, value: "", unit: "", minUseCustom: null, minValue: "", minUnit: "", maxUseCustom: null, maxValue: "", maxUnit: "" },
                    sp: { useCustom: true, value: 100, unit: "%", minUseCustom: false, minValue: 0, minUnit: "px", maxUseCustom: true, maxValue: 340, maxUnit: "px" },
                  };
                  const currentHeightData = attributes.layoutHeightV2 || {};
                  const newHeightData = {
                    pc: { useCustom: true, value: 100, unit: "%", minUseCustom: true, minValue: 70, minUnit: "px", maxUseCustom: false, maxValue: 0, maxUnit: "px" },
                    md: currentHeightData.md || { useCustom: null, value: "", unit: "", minUseCustom: null, minValue: "", minUnit: "", maxUseCustom: null, maxValue: "", maxUnit: "" },
                    tb: currentHeightData.tb || { useCustom: null, value: "", unit: "", minUseCustom: null, minValue: "", minUnit: "", maxUseCustom: null, maxValue: "", maxUnit: "" },
                    sp: { useCustom: true, value: 100, unit: "%", minUseCustom: true, minValue: 70, minUnit: "px", maxUseCustom: false, maxValue: 0, maxUnit: "px" },
                  };
                  const newPaddingData = {
                    pc: { bulk: 10, bulkUnit: "px", top: 10, topUnit: "px", right: 10, rightUnit: "px", bottom: 10, bottomUnit: "px", left: 10, leftUnit: "px", useIndividual: false },
                    md: { bulk: "", bulkUnit: "px", top: "", topUnit: "px", right: "", rightUnit: "px", bottom: "", bottomUnit: "px", left: "", leftUnit: "px", useIndividual: false },
                    tb: { bulk: "", bulkUnit: "px", top: "", topUnit: "px", right: "", rightUnit: "px", bottom: "", bottomUnit: "px", left: "", leftUnit: "px", useIndividual: false },
                    sp: { bulk: 10, bulkUnit: "px", top: 10, topUnit: "px", right: 10, rightUnit: "px", bottom: 10, bottomUnit: "px", left: 10, leftUnit: "px", useIndividual: false },
                  };
                  setAttributes({ layoutWidthV2: newWidthData, layoutHeightV2: newHeightData, paddingV2: newPaddingData });
                },
              },
              {
                icon: () => <span style={{ fontWeight: 600, fontSize: "13px", width: "25px", display: "inline-block", textAlign: "center" }}>L</span>,
                title: __("max-width: 560px", "zenblocks"),
                isActive: attributes.layoutWidthV2?.pc?.maxValue === 560,
                onClick: () => {
                  const currentWidthData = attributes.layoutWidthV2 || {};
                  const newWidthData = {
                    pc: { useCustom: true, value: 100, unit: "%", minUseCustom: false, minValue: 0, minUnit: "px", maxUseCustom: true, maxValue: 560, maxUnit: "px" },
                    md: currentWidthData.md || { useCustom: null, value: "", unit: "", minUseCustom: null, minValue: "", minUnit: "", maxUseCustom: null, maxValue: "", maxUnit: "" },
                    tb: currentWidthData.tb || { useCustom: null, value: "", unit: "", minUseCustom: null, minValue: "", minUnit: "", maxUseCustom: null, maxValue: "", maxUnit: "" },
                    sp: { useCustom: true, value: 100, unit: "%", minUseCustom: false, minValue: 0, minUnit: "px", maxUseCustom: true, maxValue: 560, maxUnit: "px" },
                  };
                  const currentHeightData = attributes.layoutHeightV2 || {};
                  const newHeightData = {
                    pc: { useCustom: true, value: 100, unit: "%", minUseCustom: true, minValue: 80, minUnit: "px", maxUseCustom: false, maxValue: 0, maxUnit: "px" },
                    md: currentHeightData.md || { useCustom: null, value: "", unit: "", minUseCustom: null, minValue: "", minUnit: "", maxUseCustom: null, maxValue: "", maxUnit: "" },
                    tb: currentHeightData.tb || { useCustom: null, value: "", unit: "", minUseCustom: null, minValue: "", minUnit: "", maxUseCustom: null, maxValue: "", maxUnit: "" },
                    sp: { useCustom: true, value: 100, unit: "%", minUseCustom: true, minValue: 80, minUnit: "px", maxUseCustom: false, maxValue: 0, maxUnit: "px" },
                  };
                  const newPaddingData = {
                    pc: { bulk: 10, bulkUnit: "px", top: 10, topUnit: "px", right: 10, rightUnit: "px", bottom: 10, bottomUnit: "px", left: 10, leftUnit: "px", useIndividual: false },
                    md: { bulk: "", bulkUnit: "px", top: "", topUnit: "px", right: "", rightUnit: "px", bottom: "", bottomUnit: "px", left: "", leftUnit: "px", useIndividual: false },
                    tb: { bulk: "", bulkUnit: "px", top: "", topUnit: "px", right: "", rightUnit: "px", bottom: "", bottomUnit: "px", left: "", leftUnit: "px", useIndividual: false },
                    sp: { bulk: 10, bulkUnit: "px", top: 10, topUnit: "px", right: 10, rightUnit: "px", bottom: 10, bottomUnit: "px", left: 10, leftUnit: "px", useIndividual: false },
                  };
                  setAttributes({ layoutWidthV2: newWidthData, layoutHeightV2: newHeightData, paddingV2: newPaddingData });
                },
              },
            ]}
          />
        </ToolbarGroup>
        <ToolbarGroup>
          <Dropdown
            popoverProps={{ className: "zenblocks-button-settings-popover" }}
            renderToggle={({ isOpen, onToggle }) => (
              <ToolbarButton
                icon={() => (
                  <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style={{ fill: "none", stroke: "currentColor" }} strokeLinecap="round" strokeLinejoin="round">
                    <path strokeWidth="1.5" d="M4 8h4v4h-4z" />
                    <path strokeWidth="1.5" d="M6 4l0 4" />
                    <path strokeWidth="1.5" d="M6 12l0 8" />
                    <path strokeWidth="1.5" d="M10 14h4v4h-4z" />
                    <path strokeWidth="1.5" d="M12 4l0 10" />
                    <path strokeWidth="1.5" d="M12 18l0 2" />
                    <path strokeWidth="1.5" d="M16 5h4v4h-4z" />
                    <path strokeWidth="1.5" d="M18 4l0 1" />
                    <path strokeWidth="1.5" d="M18 9l0 11" />
                  </svg>
                )}
                label={__("Button Settings", "zenblocks")}
                onClick={onToggle}
                aria-expanded={isOpen}
              />
            )}
            renderContent={({ onClose }) => (
              <MenuGroup className="zenblocks-button-settings-menu">
                <div className="zenblocks-menu-item-with-sync">
                  <MenuItem
                    onClick={() => {
                      openPanelExclusively("basic");
                      setPanelStates((prev) => {
                        const newStates = { ...prev, textSettings: true };
                        savePanelStates(newStates);
                        return newStates;
                      });
                      scrollToPanel("textSettings");
                      onClose();
                    }}
                  >
                    <span className="zenblocks-menu-item-icon">
                      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style={{ fill: "none", stroke: "currentColor" }} strokeLinecap="round" strokeLinejoin="round">
                        <path strokeWidth="1.75" d="M15 12h6" />
                        <path strokeWidth="1.75" d="M15 6h6" />
                        <path strokeWidth="1.75" d="m3 13 3.553-7.724a.5.5 0 0 1 .894 0L11 13" />
                        <path strokeWidth="1.75" d="M3 18h18" />
                        <path strokeWidth="1.75" d="M3.92 11h6.16" />
                      </svg>
                    </span>
                    {__("Text Input", "zenblocks")}
                  </MenuItem>
                  <Button
                    className="zenblocks-toolbar-sync-button"
                    icon={update}
                    label={__("Sync Text to Hover", "zenblocks")}
                    showTooltip
                    tooltipPosition="top"
                    onClick={(e) => {
                      e.preventDefault();
                      e.stopPropagation();
                      createSyncHandlerLevel1("basic")();
                    }}
                  />
                </div>
                <div className="zenblocks-menu-item-with-sync">
                  <MenuItem
                    onClick={() => {
                      openPanelExclusively("style", "textColor");
                      scrollToPanel("textColor");
                      onClose();
                    }}
                  >
                    <span className="zenblocks-menu-item-icon">
                      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style={{ fill: "none", stroke: "currentColor" }} strokeLinecap="round" strokeLinejoin="round">
                        <path strokeWidth="1.75" d="M12 21a9 9 0 0 1 0 -18c4.97 0 9 3.582 9 8c0 1.06 -.474 2.078 -1.318 2.828c-.844 .75 -1.989 1.172 -3.182 1.172h-2.5a2 2 0 0 0 -1 3.75a1.3 1.3 0 0 1 -1 2.25" />
                        <circle cx="8.5" cy="10.5" r="1" fill="currentColor" />
                        <circle cx="12.5" cy="7.5" r="1" fill="currentColor" />
                        <circle cx="16.5" cy="10.5" r="1" fill="currentColor" />
                      </svg>
                    </span>
                    {__("Text Color Settings", "zenblocks")}
                  </MenuItem>
                  <Button
                    className="zenblocks-toolbar-sync-button"
                    icon={update}
                    label={__("Sync Text Color to Hover", "zenblocks")}
                    showTooltip
                    tooltipPosition="top"
                    onClick={(e) => {
                      e.preventDefault();
                      e.stopPropagation();
                      createSyncHandler("textColor")();
                    }}
                  />
                </div>
                <div className="zenblocks-menu-item-with-sync">
                  <MenuItem
                    onClick={() => {
                      openPanelExclusively("font");
                      scrollToPanel("font");
                      onClose();
                    }}
                  >
                    <span className="zenblocks-menu-item-icon">
                      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style={{ fill: "none", stroke: "currentColor" }} strokeLinecap="round" strokeLinejoin="round">
                        <path strokeWidth="1.75" d="M3 16v-6a2 2 0 1 1 4 0v6" />
                        <path strokeWidth="1.75" d="M3 13h4" />
                        <path strokeWidth="1.75" d="M10 8v6a2 2 0 1 0 4 0v-1a2 2 0 1 0 -4 0v1" />
                        <path strokeWidth="1.75" d="M20.732 12a2 2 0 0 0 -3.732 1v1a2 2 0 0 0 3.726 1.01" />
                      </svg>
                    </span>
                    {__("Font Settings", "zenblocks")}
                  </MenuItem>
                  <Button
                    className="zenblocks-toolbar-sync-button"
                    icon={update}
                    label={__("Sync Font to Hover", "zenblocks")}
                    showTooltip
                    tooltipPosition="top"
                    onClick={(e) => {
                      e.preventDefault();
                      e.stopPropagation();
                      createSyncHandlerLevel1("font")();
                    }}
                  />
                </div>
                <div className="zenblocks-menu-item-with-sync">
                  <MenuItem
                    onClick={() => {
                      openPanelExclusively("style", "border");
                      scrollToPanel("border");
                      onClose();
                    }}
                  >
                    <span className="zenblocks-menu-item-icon">
                      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style={{ fill: "none", stroke: "currentColor" }} strokeLinecap="round" strokeLinejoin="round">
                        <path strokeWidth="1.75" d="M4 18v.01" />
                        <path strokeWidth="1.75" d="M8 18v.01" />
                        <path strokeWidth="1.75" d="M12 18v.01" />
                        <path strokeWidth="1.75" d="M16 18v.01" />
                        <path strokeWidth="1.75" d="M20 18v.01" />
                        <path strokeWidth="1.75" d="M18 12h2" />
                        <path strokeWidth="1.75" d="M11 12h2" />
                        <path strokeWidth="1.75" d="M4 12h2" />
                        <path strokeWidth="1.75" d="M4 6h16" />
                      </svg>
                    </span>
                    {__("Border Settings", "zenblocks")}
                  </MenuItem>
                  <Button
                    className="zenblocks-toolbar-sync-button"
                    icon={update}
                    label={__("Sync Border to Hover", "zenblocks")}
                    showTooltip
                    tooltipPosition="top"
                    onClick={(e) => {
                      e.preventDefault();
                      e.stopPropagation();
                      createSyncHandler("border")();
                    }}
                  />
                </div>
                <div className="zenblocks-menu-item-with-sync">
                  <MenuItem
                    onClick={() => {
                      openPanelExclusively("style", "radius");
                      scrollToPanel("radius");
                      onClose();
                    }}
                  >
                    <span className="zenblocks-menu-item-icon">
                      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24">
                        <rect x="4" y="4" width="16" height="16" rx="4" ry="4" fill="none" stroke="currentColor" strokeWidth="1.75" />
                      </svg>
                    </span>
                    {__("Border Radius Settings", "zenblocks")}
                  </MenuItem>
                  <Button
                    className="zenblocks-toolbar-sync-button"
                    icon={update}
                    label={__("Sync Border Radius to Hover", "zenblocks")}
                    showTooltip
                    tooltipPosition="top"
                    onClick={(e) => {
                      e.preventDefault();
                      e.stopPropagation();
                      createSyncHandler("radius")();
                    }}
                  />
                </div>
                <div className="zenblocks-menu-item-with-sync">
                  <MenuItem
                    onClick={() => {
                      openPanelExclusively("style", ["innerShadow", "shadow"]);
                      scrollToPanel("innerShadow");
                      onClose();
                    }}
                  >
                    <span className="zenblocks-menu-item-icon">
                      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="currentColor" stroke="none">
                        <path d="M3 2C2.44772 2 2 2.44772 2 3V17C2 17.5523 2.44772 18 3 18H6V21C6 21.5523 6.44772 22 7 22H21C21.5523 22 22 21.5523 22 21V7C22 6.44772 21.5523 6 21 6H18V3C18 2.44772 17.5523 2 17 2H3ZM18 11.5607L20 13.5607V16.4393L18 14.4393V11.5607ZM18 9.43934V8H20V11.4393L18 9.43934ZM18 17V16.5607L20 18.5607V20H18.5607L16.5607 18H17C17.5523 18 18 17.5523 18 17ZM14.4393 18L16.4393 20H13.5607L11.5607 18H14.4393ZM9.43934 18L11.4393 20H8V18H9.43934ZM4 16V4H16V16H4Z" />
                      </svg>
                    </span>
                    {__("Shadow Settings", "zenblocks")}
                  </MenuItem>
                  <Button
                    className="zenblocks-toolbar-sync-button"
                    icon={update}
                    label={__("Sync Shadow to Hover", "zenblocks")}
                    showTooltip
                    tooltipPosition="top"
                    onClick={(e) => {
                      e.preventDefault();
                      e.stopPropagation();
                      createSyncHandler("innerShadow")();
                      createSyncHandler("shadow")();
                    }}
                  />
                </div>
                <div className="zenblocks-menu-item-with-sync">
                  <MenuItem
                    onClick={() => {
                      openPanelExclusively("background");
                      setPanelStates((prev) => {
                        const newStates = {
                          ...prev,
                          backgroundColor: false,
                          backgroundImage: false,
                          backgroundPattern: false,
                          backgroundBaseColor: false,
                          backgroundTransition: false,
                        };
                        savePanelStates(newStates);
                        return newStates;
                      });
                      scrollToPanel("background");
                      onClose();
                    }}
                  >
                    <span className="zenblocks-menu-item-icon">
                      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round">
                        <path d="M4 8l4 -4" />
                        <path d="M14 4l-10 10" />
                        <path d="M4 20l16 -16" />
                        <path d="M20 10l-10 10" />
                        <path d="M20 16l-4 4" />
                      </svg>
                    </span>
                    {__("Background Settings", "zenblocks")}
                  </MenuItem>
                  <Button
                    className="zenblocks-toolbar-sync-button"
                    icon={update}
                    label={__("Sync Background to Hover", "zenblocks")}
                    showTooltip
                    tooltipPosition="top"
                    onClick={(e) => {
                      e.preventDefault();
                      e.stopPropagation();
                      createSyncHandlerLevel1("background")();
                    }}
                  />
                </div>
                <div className="zenblocks-menu-item-with-sync">
                  <MenuItem
                    onClick={() => {
                      openPanelExclusively("icon", "iconSelect");
                      scrollToPanel("iconSelect");
                      onClose();
                    }}
                  >
                    <span className="zenblocks-menu-item-icon">
                      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style={{ fill: "none", stroke: "currentColor" }} strokeLinecap="round" strokeLinejoin="round">
                        <path strokeWidth="1.75" d="M16 7h.01" />
                        <path strokeWidth="1.75" d="M3.4 18H12a8 8 0 0 0 8-8V7a4 4 0 0 0-7.28-2.3L2 20" />
                        <path strokeWidth="1.75" d="m20 7 2 .5-2 .5" />
                        <path strokeWidth="1.75" d="M10 18v3" />
                        <path strokeWidth="1.75" d="M14 17.75V21" />
                        <path strokeWidth="1.75" d="M7 18a6 6 0 0 0 3.84-10.61" />
                      </svg>
                    </span>
                    {__("Icon Settings", "zenblocks")}
                  </MenuItem>
                  <Button
                    className="zenblocks-toolbar-sync-button"
                    icon={update}
                    label={__("Sync Icon to Hover", "zenblocks")}
                    showTooltip
                    tooltipPosition="top"
                    onClick={(e) => {
                      e.preventDefault();
                      e.stopPropagation();
                      createSyncHandlerLevel1("icon")();
                    }}
                  />
                </div>
                <div className="zenblocks-menu-item-with-sync">
                  <MenuItem
                    onClick={() => {
                      openPanelExclusively("thumbnail", "thumbnailImage");
                      scrollToPanel("thumbnailImage");
                      onClose();
                    }}
                  >
                    <span className="zenblocks-menu-item-icon">
                      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style={{ fill: "none", stroke: "currentColor" }} strokeLinecap="round" strokeLinejoin="round">
                        <path strokeWidth="1.75" d="M15 8h.01" />
                        <path strokeWidth="1.75" d="M3 6a3 3 0 0 1 3 -3h12a3 3 0 0 1 3 3v12a3 3 0 0 1 -3 3h-12a3 3 0 0 1 -3 -3v-12z" />
                        <path strokeWidth="1.75" d="M3 16l5 -5c.928 -.893 2.072 -.893 3 0l5 5" />
                        <path strokeWidth="1.75" d="M14 14l1 -1c.928 -.893 2.072 -.893 3 0l3 3" />
                      </svg>
                    </span>
                    {__("Thumbnail Settings", "zenblocks")}
                  </MenuItem>
                  <Button
                    className="zenblocks-toolbar-sync-button"
                    icon={update}
                    label={__("Sync Thumbnail to Hover", "zenblocks")}
                    showTooltip
                    tooltipPosition="top"
                    onClick={(e) => {
                      e.preventDefault();
                      e.stopPropagation();
                      createSyncHandlerLevel1("thumbnail")();
                    }}
                  />
                </div>
                <div className="zenblocks-menu-item-with-sync">
                  <MenuItem
                    onClick={() => {
                      openPanelExclusively("band", "bandImage");
                      scrollToPanel("bandImage");
                      onClose();
                    }}
                  >
                    <span className="zenblocks-menu-item-icon">
                      <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style={{ fill: "none", stroke: "currentColor" }} strokeLinecap="round" strokeLinejoin="round">
                        <path strokeWidth="1.75" d="M3 5h18" />
                        <path strokeWidth="1.75" d="M3 10h18" />
                        <path strokeWidth="1.75" d="M3 15h18" />
                        <path strokeWidth="1.75" d="M3 20h18" />
                      </svg>
                    </span>
                    {__("Band Settings", "zenblocks")}
                  </MenuItem>
                  <Button
                    className="zenblocks-toolbar-sync-button"
                    icon={update}
                    label={__("Sync Band to Hover", "zenblocks")}
                    showTooltip
                    tooltipPosition="top"
                    onClick={(e) => {
                      e.preventDefault();
                      e.stopPropagation();
                      createSyncHandlerLevel1("band")();
                    }}
                  />
                </div>
                <MenuItem
                  onClick={() => {
                    openPanelExclusively("layout");
                    scrollToPanel("layout");
                    onClose();
                  }}
                >
                  <span className="zenblocks-menu-item-icon">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style={{ fill: "none", stroke: "currentColor" }} strokeLinecap="round" strokeLinejoin="round">
                      <rect strokeWidth="1.75" width="7" height="9" x="3" y="3" rx="1" />
                      <rect strokeWidth="1.75" width="7" height="5" x="14" y="3" rx="1" />
                      <rect strokeWidth="1.75" width="7" height="9" x="14" y="12" rx="1" />
                      <rect strokeWidth="1.75" width="7" height="5" x="3" y="16" rx="1" />
                    </svg>
                  </span>
                  {__("Layout Settings", "zenblocks")}
                </MenuItem>
                <MenuItem
                  className="zenblocks-sync-hover-style"
                  onClick={() => {
                    setShowSyncConfirmModal(true);
                    onClose();
                  }}
                >
                  <span className="zenblocks-menu-item-icon">
                    <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" aria-hidden="true" focusable="false">
                      <path d="m11.3 17.2-5-5c-.1-.1-.1-.3 0-.4l2.3-2.3-1.1-1-2.3 2.3c-.7.7-.7 1.8 0 2.5l5 5H7.5v1.5h5.3v-5.2h-1.5v2.6zm7.5-6.4-5-5h2.7V4.2h-5.2v5.2h1.5V6.8l5 5c.1.1.1.3 0 .4l-2.3 2.3 1.1 1.1 2.3-2.3c.6-.7.6-1.9-.1-2.5z"></path>
                    </svg>
                  </span>
                  {__("Sync Hover Style", "zenblocks")}
                </MenuItem>
              </MenuGroup>
            )}
          />
        </ToolbarGroup>
        <ToolbarGroup>
          <ToolbarDropdownMenu
            icon={() => (
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style={{ fill: "none", stroke: "currentColor" }} strokeLinecap="round" strokeLinejoin="round">
                <path strokeWidth="1.75" d="M4 7h3a1 1 0 0 0 1 -1v-1a2 2 0 0 1 4 0v1a1 1 0 0 0 1 1h3a1 1 0 0 1 1 1v3a1 1 0 0 0 1 1h1a2 2 0 0 1 0 4h-1a1 1 0 0 0 -1 1v3a1 1 0 0 1 -1 1h-3a1 1 0 0 1 -1 -1v-1a2 2 0 0 0 -4 0v1a1 1 0 0 1 -1 1h-3a1 1 0 0 1 -1 -1v-3a1 1 0 0 1 1 -1h1a2 2 0 0 0 0 -4h-1a1 1 0 0 1 -1 -1v-3a1 1 0 0 1 1 -1" />
              </svg>
            )}
            label={__("Additional Settings", "zenblocks")}
            controls={[
              {
                icon: () => (
                  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#333333" stroke="none" strokeLinecap="round" strokeLinejoin="round" style={{ overflow: "visible" }}>
                    <path fill="currentColor" d="M12 2c5.523 0 10 4.477 10 10a10 10 0 0 1 -20 0c0 -5.523 4.477 -10 10 -10m-.293 6.293a1 1 0 0 0 -1.414 0l-.083 .094a1 1 0 0 0 .083 1.32l2.292 2.293l-2.292 2.293a1 1 0 0 0 1.414 1.414l3 -3a1 1 0 0 0 0 -1.414z" />
                  </svg>
                ),
                title: __("Micro Copy", "zenblocks"),
                onClick: () => {
                  setPanelStates((prev) => {
                    const newStates = {
                      ...prev,
                      tabPanel: false,
                      designPanel: false,
                      additionalPanel: true,
                      animationPanel: false,
                      copyMicroSettings: true,
                      copySubSettings: false,
                      microTextSettings: false,
                      subTextSettings: false,
                    };
                    savePanelStates(newStates);
                    return newStates;
                  });
                  scrollToPanel("copyMicroSettings");
                },
              },
              {
                icon: () => (
                  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#333333" stroke="none" strokeLinecap="round" strokeLinejoin="round" style={{ overflow: "visible" }}>
                    <path fill="currentColor" d="M12 2c5.523 0 10 4.477 10 10a10 10 0 0 1 -20 0c0 -5.523 4.477 -10 10 -10m-.293 6.293a1 1 0 0 0 -1.414 0l-.083 .094a1 1 0 0 0 .083 1.32l2.292 2.293l-2.292 2.293a1 1 0 0 0 1.414 1.414l3 -3a1 1 0 0 0 0 -1.414z" />
                  </svg>
                ),
                title: __("Sub Copy", "zenblocks"),
                onClick: () => {
                  setPanelStates((prev) => {
                    const newStates = {
                      ...prev,
                      tabPanel: false,
                      designPanel: false,
                      additionalPanel: true,
                      animationPanel: false,
                      copyMicroSettings: false,
                      copySubSettings: true,
                      microTextSettings: false,
                      subTextSettings: false,
                    };
                    savePanelStates(newStates);
                    return newStates;
                  });
                  scrollToPanel("copySubSettings");
                },
              },
              {
                icon: () => (
                  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#333333" stroke="none" strokeLinecap="round" strokeLinejoin="round" style={{ overflow: "visible" }}>
                    <path fill="currentColor" d="M12 2c5.523 0 10 4.477 10 10a10 10 0 0 1 -20 0c0 -5.523 4.477 -10 10 -10m-.293 6.293a1 1 0 0 0 -1.414 0l-.083 .094a1 1 0 0 0 .083 1.32l2.292 2.293l-2.292 2.293a1 1 0 0 0 1.414 1.414l3 -3a1 1 0 0 0 0 -1.414z" />
                  </svg>
                ),
                title: __("Micro Text", "zenblocks"),
                onClick: () => {
                  setPanelStates((prev) => {
                    const newStates = {
                      ...prev,
                      tabPanel: false,
                      designPanel: false,
                      additionalPanel: true,
                      animationPanel: false,
                      copyMicroSettings: false,
                      copySubSettings: false,
                      microTextSettings: true,
                      subTextSettings: false,
                    };
                    savePanelStates(newStates);
                    return newStates;
                  });
                  scrollToPanel("microTextSettings");
                },
              },
              {
                icon: () => (
                  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#333333" stroke="none" strokeLinecap="round" strokeLinejoin="round" style={{ overflow: "visible" }}>
                    <path fill="currentColor" d="M12 2c5.523 0 10 4.477 10 10a10 10 0 0 1 -20 0c0 -5.523 4.477 -10 10 -10m-.293 6.293a1 1 0 0 0 -1.414 0l-.083 .094a1 1 0 0 0 .083 1.32l2.292 2.293l-2.292 2.293a1 1 0 0 0 1.414 1.414l3 -3a1 1 0 0 0 0 -1.414z" />
                  </svg>
                ),
                title: __("Sub Text", "zenblocks"),
                onClick: () => {
                  setPanelStates((prev) => {
                    const newStates = {
                      ...prev,
                      tabPanel: false,
                      designPanel: false,
                      additionalPanel: true,
                      animationPanel: false,
                      copyMicroSettings: false,
                      copySubSettings: false,
                      microTextSettings: false,
                      subTextSettings: true,
                    };
                    savePanelStates(newStates);
                    return newStates;
                  });
                  scrollToPanel("subTextSettings");
                },
              },
            ]}
          />
        </ToolbarGroup>
        <ToolbarGroup>
          <ToolbarDropdownMenu
            icon={() => (
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style={{ fill: "none", stroke: "currentColor" }} strokeLinecap="round" strokeLinejoin="round">
                <path strokeWidth="1.75" d="M7 10h14l-4 -4" />
                <path strokeWidth="1.75" d="M17 14h-14l4 4" />
              </svg>
            )}
            label={__("Animation Settings", "zenblocks")}
            controls={[
              {
                icon: () => (
                  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#333333" stroke="none" strokeLinecap="round" strokeLinejoin="round" style={{ overflow: "visible" }}>
                    <path fill="currentColor" d="M12 2c5.523 0 10 4.477 10 10a10 10 0 0 1 -20 0c0 -5.523 4.477 -10 10 -10m-.293 6.293a1 1 0 0 0 -1.414 0l-.083 .094a1 1 0 0 0 .083 1.32l2.292 2.293l-2.292 2.293a1 1 0 0 0 1.414 1.414l3 -3a1 1 0 0 0 0 -1.414z" />
                  </svg>
                ),
                title: __("Text Animation", "zenblocks"),
                onClick: () => {
                  setPanelStates((prev) => {
                    const newStates = {
                      ...prev,
                      tabPanel: false,
                      designPanel: false,
                      additionalPanel: false,
                      animationPanel: true,
                      textAnimationSubPanel: true,
                      iconAnimationSubPanel: false,
                      frameAnimationSubPanel: false,
                      buttonAnimationSubPanel: false,
                    };
                    savePanelStates(newStates);
                    return newStates;
                  });
                  scrollToPanel("textAnimationSubPanel");
                },
              },
              {
                icon: () => (
                  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#333333" stroke="none" strokeLinecap="round" strokeLinejoin="round" style={{ overflow: "visible" }}>
                    <path fill="currentColor" d="M12 2c5.523 0 10 4.477 10 10a10 10 0 0 1 -20 0c0 -5.523 4.477 -10 10 -10m-.293 6.293a1 1 0 0 0 -1.414 0l-.083 .094a1 1 0 0 0 .083 1.32l2.292 2.293l-2.292 2.293a1 1 0 0 0 1.414 1.414l3 -3a1 1 0 0 0 0 -1.414z" />
                  </svg>
                ),
                title: __("Icon Animation", "zenblocks"),
                onClick: () => {
                  setPanelStates((prev) => {
                    const newStates = {
                      ...prev,
                      tabPanel: false,
                      designPanel: false,
                      additionalPanel: false,
                      animationPanel: true,
                      textAnimationSubPanel: false,
                      iconAnimationSubPanel: true,
                      frameAnimationSubPanel: false,
                      buttonAnimationSubPanel: false,
                    };
                    savePanelStates(newStates);
                    return newStates;
                  });
                  scrollToPanel("iconAnimationSubPanel");
                },
              },
              {
                icon: () => (
                  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#333333" stroke="none" strokeLinecap="round" strokeLinejoin="round" style={{ overflow: "visible" }}>
                    <path fill="currentColor" d="M12 2c5.523 0 10 4.477 10 10a10 10 0 0 1 -20 0c0 -5.523 4.477 -10 10 -10m-.293 6.293a1 1 0 0 0 -1.414 0l-.083 .094a1 1 0 0 0 .083 1.32l2.292 2.293l-2.292 2.293a1 1 0 0 0 1.414 1.414l3 -3a1 1 0 0 0 0 -1.414z" />
                  </svg>
                ),
                title: __("Frame Animation", "zenblocks"),
                onClick: () => {
                  setPanelStates((prev) => {
                    const newStates = {
                      ...prev,
                      tabPanel: false,
                      designPanel: false,
                      additionalPanel: false,
                      animationPanel: true,
                      textAnimationSubPanel: false,
                      iconAnimationSubPanel: false,
                      frameAnimationSubPanel: true,
                      buttonAnimationSubPanel: false,
                    };
                    savePanelStates(newStates);
                    return newStates;
                  });
                  scrollToPanel("frameAnimationSubPanel");
                },
              },
              {
                icon: () => (
                  <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="#333333" stroke="none" strokeLinecap="round" strokeLinejoin="round" style={{ overflow: "visible" }}>
                    <path fill="currentColor" d="M12 2c5.523 0 10 4.477 10 10a10 10 0 0 1 -20 0c0 -5.523 4.477 -10 10 -10m-.293 6.293a1 1 0 0 0 -1.414 0l-.083 .094a1 1 0 0 0 .083 1.32l2.292 2.293l-2.292 2.293a1 1 0 0 0 1.414 1.414l3 -3a1 1 0 0 0 0 -1.414z" />
                  </svg>
                ),
                title: __("Button Animation", "zenblocks"),
                onClick: () => {
                  setPanelStates((prev) => {
                    const newStates = {
                      ...prev,
                      tabPanel: false,
                      designPanel: false,
                      additionalPanel: false,
                      animationPanel: true,
                      textAnimationSubPanel: false,
                      iconAnimationSubPanel: false,
                      frameAnimationSubPanel: false,
                      buttonAnimationSubPanel: true,
                    };
                    savePanelStates(newStates);
                    return newStates;
                  });
                  scrollToPanel("buttonAnimationSubPanel");
                },
              },
            ]}
          />
        </ToolbarGroup>
        <ToolbarGroup>
          <ToolbarButton
            icon={() => (
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style={{ fill: "none", stroke: "currentColor" }} strokeLinecap="round" strokeLinejoin="round">
                <rect x="3" y="5" width="6" height="6" rx="1" strokeWidth="2" />
                <path strokeWidth="2" d="m3 17 2 2 4-4" />
                <path strokeWidth="2" d="M13 6h8" />
                <path strokeWidth="2" d="M13 12h8" />
                <path strokeWidth="2" d="M13 18h8" />
              </svg>
            )}
            label={__("Design Settings", "zenblocks")}
            isActive={panelStates.designPanel}
            onClick={() => openDesignPanelExclusively()}
          />
        </ToolbarGroup>
        <ToolbarGroup>
          <SavePatternButton
            blockType="buttonbasic"
            clientId={clientId}
            customIcon={() => (
              <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="24" height="24" style={{ fill: "none", stroke: "currentColor" }} strokeLinecap="round" strokeLinejoin="round">
                <path strokeWidth="2" d="M11 12H3" />
                <path strokeWidth="2" d="M16 6H3" />
                <path strokeWidth="2" d="M16 18H3" />
                <path strokeWidth="2" d="M18 9v6" />
                <path strokeWidth="2" d="M21 12h-6" />
              </svg>
            )}
          />
        </ToolbarGroup>
      </BlockControls>

      <InspectorControls>
        <ResponsiveTabProviderV2 onTabChange={setPreviewDevice} externalActiveTab={previewDevice}>
          <div className="zenblocks-buttonbasic-doc-link-wrap">
            <a
              href={buttonBasicDocsTopUrl}
              className="zenblocks-buttonbasic-doc-link"
              target="_blank"
              rel="noopener noreferrer"
            >
              {buttonBasicDocsLabel}
              <svg className="zenblocks-buttonbasic-doc-link-icon" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
                <path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"></path>
                <polyline points="15 3 21 3 21 9"></polyline>
                <line x1="10" y1="14" x2="21" y2="3"></line>
              </svg>
            </a>
          </div>
          <PreviewDeviceControl />

          {showProBadge && (
            <ProFeatureNotice
              proFeatures={proFeatures}
              isFreePreview={isFreePreview}
              onToggleFreePreview={() => setIsFreePreview(!isFreePreview)}
            />
          )}

          <div className="zenblocks-inspector-controls">
            {/* デザイン設定 */}
            <span id="panel-anchor-designPanel" style={{ display: "block", height: 0 }} />
            <StickyCollapsiblePanel title={__("Design Settings", "zenblocks")} isOpen={panelStates.designPanel} onToggle={() => togglePanel("designPanel")}>
              {/* カスタム（サブパネル） */}
              <PanelBody
                    title={__("Custom", "zenblocks")}
                    opened={panelStates.designCustomPanel}
                    onToggle={() => togglePanel("designCustomPanel")}
                    className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--parent zenblocks-panel--design-custom"
                  >
                    <PlusFeatureOverlay
                      featureName={__("Custom Pattern", "zenblocks")}
                      learnMorePath="/downloads/"
                    >
                      <div className="zenblocks-panel-body zenblocks-panel-body--design-custom">
                        <CustomPatternManager blockType="buttonbasic" setAttributes={setAttributes} PreviewComponent={ButtonPatternPreview} />
                      </div>
                    </PlusFeatureOverlay>
                  </PanelBody>
                  {/* プリセット（サブパネル） */}
                  <PanelBody
                    title={__("Preset", "zenblocks")}
                    opened={panelStates.designPresetPanel}
                    onToggle={() => togglePanel("designPresetPanel")}
                    className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--parent zenblocks-panel--design-preset"
                  >
                    <div className="zenblocks-panel-body zenblocks-panel-body--design-preset">
                      <ButtonPatternSelector
                        patterns={getProcessedPatterns()}
                        onSelectPattern={(pattern) => {
                          // createBlockでデフォルト値とマージし、完全なattributesセットを生成
                          // （カスタムパターンと同じ方式）
                          const block = createBlock("zenblocks/button-basic", pattern.attributes);

                          // block.jsonでdefaultが未定義のレガシー属性は、createBlockの結果に
                          // 含まれない。setAttributesはマージ操作のため、前のプリセットが設定
                          // した値がクリアされず残留する。detectProFeaturesが参照するキーを
                          // 明示的にリセットして、Pro判定の誤検出を防ぐ。
                          const legacyProResets = {
                            iconFrameWidthMD: 0,
                            iconFrameHeightMD: 0,
                            iconFrameBorderWidthMD: 0,
                            iconFrameRadiusMD: 0,
                          };

                          // 現在のブロック固有の設定を保持
                          const newAttributes = {
                            ...legacyProResets,
                            ...block.attributes,
                            uniqueId: attributes.uniqueId,
                            content: attributes.content,
                            contentHover: attributes.contentHover,
                            href: attributes.href,
                            target: attributes.target,
                            rel: attributes.rel,
                            tagName: attributes.tagName,
                          };

                          setAttributes(newAttributes);
                        }}
                      />
                    </div>
              </PanelBody>
            </StickyCollapsiblePanel>

            {/* カスタム折りたたみパネル - ボタン設定 */}
            <StickyCollapsiblePanel title={__("Button Settings", "zenblocks")} isOpen={panelStates.tabPanel} onToggle={() => togglePanel("tabPanel")}>
              <StickyHoverTab activeStateTab={activeStateTab} setActiveStateTab={setActiveStateTab} onSyncAll={createSyncHandlerLevel0("all")} />

              <div className={`state-tab-panel state-tab-panel-${activeStateTab}`}>
                {activeStateTab === "normal" ? (
                  <ResponsiveTabProvider>
                    <PanelBody
                      title={__("Basic Settings", "zenblocks")}
                      opened={panelStates.basic}
                      onToggle={() => togglePanel("basic")}
                      className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--parent zenblocks-panel--basic"
                    >
                      {/* テキスト設定（サブパネル） */}
                      <span id="panel-anchor-textSettings" style={{ display: "block", height: 0 }} />
                      <PanelBody
                        title={__("Text", "zenblocks")}
                        opened={panelStates.textSettings}
                        onToggle={() => togglePanel("textSettings")}
                        className="zenblocks-panel zenblocks-panel--level-2 zenblocks-panel--settings zenblocks-panel--text-settings"
                      >
                        <div className="zenblocks-inspector-text-setting">
                          <TextControl
                            label={__("Text", "zenblocks")}
                            value={content || ""}
                            onChange={(value) => {
                              const attrs = { content: value };
                              if (!isPlus()) {
                                attrs.contentHover = "";
                              }
                              setAttributes(attrs);
                            }}
                            help={__("Enter the text to display", "zenblocks")}
                          />
                        </div>
                      </PanelBody>

                      {/* タグ設定（サブパネル） */}
                      <PanelBody
                        title={__("Tag", "zenblocks")}
                        opened={panelStates.tagSettings}
                        onToggle={() => togglePanel("tagSettings")}
                        className="zenblocks-panel zenblocks-panel--level-2 zenblocks-panel--settings zenblocks-panel--tag-settings"
                      >
                        <div className="zenblocks-inspector-tag-setting">
                          <div className="zenblocks-tag-selector">
                            <span className="zenblocks-tag-selector__label">{__("HTML Tag", "zenblocks")}</span>
                            <div className="zenblocks-tag-selector__buttons">
                              <button
                                type="button"
                                className={`zenblocks-tag-selector__button${(tagName || "a") === "a" ? " is-active" : ""}`}
                                onClick={() => setAttributes({ tagName: "a" })}
                              >
                                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="currentColor">
                                  <path d="M15.6 7.2H14v1.5h1.6c2 0 3.7 1.7 3.7 3.7s-1.7 3.7-3.7 3.7H14v1.5h1.6c2.8 0 5.2-2.3 5.2-5.2 0-2.9-2.3-5.2-5.2-5.2zM10 15.1H8.4c-2 0-3.7-1.7-3.7-3.7s1.7-3.7 3.7-3.7H10V6.2H8.4c-2.9 0-5.2 2.3-5.2 5.2 0 2.9 2.3 5.2 5.2 5.2H10v-1.5zm-1.3-4.1h6.6v1.5H8.7V11z"/>
                                </svg>
                                <span>{__("Link", "zenblocks")}</span>
                              </button>
                              <button
                                type="button"
                                className={`zenblocks-tag-selector__button${tagName === "button" ? " is-active" : ""}`}
                                onClick={() => setAttributes({ tagName: "button" })}
                              >
                                <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" width="16" height="16" fill="currentColor">
                                  <path d="M19 6H5c-1.1 0-2 .9-2 2v8c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2zm.5 10c0 .3-.2.5-.5.5H5c-.3 0-.5-.2-.5-.5V8c0-.3.2-.5.5-.5h14c.3 0 .5.2.5.5v8z"/>
                                </svg>
                                <span>{__("Button", "zenblocks")}</span>
                              </button>
                            </div>
                          </div>
                          {tagName === "a" && (
                            <>
                              <TextControl
                                label={__("Link URL", "zenblocks")}
                                value={href || ""}
                                onChange={(value) => setAttributes({ href: value })}
                                help={__("Enter the link URL", "zenblocks")}
                              />
                              <SelectControl
                                label={__("Link Target", "zenblocks")}
                                value={target || ""}
                                options={targetOptions}
                                onChange={(value) => setAttributes({ target: value })}
                                help={__("Set how the link opens", "zenblocks")}
                              />
                              <SelectControl
                                label={__("rel Attribute", "zenblocks")}
                                value={rel || ""}
                                options={relOptions}
                                onChange={(value) => setAttributes({ rel: value })}
                                help={__("SEO and security settings", "zenblocks")}
                              />
                              <TextControl
                                label={__("Link Title", "zenblocks")}
                                value={linkTitle || ""}
                                onChange={(value) => setAttributes({ linkTitle: value })}
                                help={__("Tooltip displayed on hover", "zenblocks")}
                              />
                            </>
                          )}

                          {tagName === "button" && (
                            <SelectControl
                              label={__("Button Type", "zenblocks")}
                              value={buttonType || "button"}
                              options={buttonTypeOptions}
                              onChange={(value) => setAttributes({ buttonType: value })}
                              help={__("Set the button type", "zenblocks")}
                            />
                          )}

                          <TextControl
                            label={__("aria-label", "zenblocks")}
                            value={ariaLabel || ""}
                            onChange={(value) => setAttributes({ ariaLabel: value })}
                            help={__("Description text for screen readers", "zenblocks")}
                          />
                          <TextControl
                            label={__("Tracking ID", "zenblocks")}
                            value={attributes.trackingId || ""}
                            onChange={(value) => setAttributes({ trackingId: value })}
                            help={__("Click ID for GTM etc. (data-click-id)", "zenblocks")}
                          />
                          <TextControl
                            label={__("Button Location", "zenblocks")}
                            value={attributes.trackingLocation || ""}
                            onChange={(value) => setAttributes({ trackingLocation: value })}
                            help={__("Button placement location (data-button-location)", "zenblocks")}
                          />
                          <TextControl
                            label={__("ID", "zenblocks")}
                            value={attributes.anchor || ""}
                            onChange={(value) => setAttributes({ anchor: value })}
                            help={__("HTML element ID attribute (syncs with Advanced Settings HTML Anchor)", "zenblocks")}
                          />
                        </div>
                      </PanelBody>
                    </PanelBody>

                    <DisplaySettingV7
                      attributes={attributes}
                      setAttributes={setAttributes}
                      title={__("Display Settings", "zenblocks")}
                      opened={panelStates.display}
                      onToggle={() => togglePanel("display")}
                    />

                    <PanelBody
                      title={__("Style Settings", "zenblocks")}
                      opened={panelStates.style}
                      onToggle={() => togglePanel("style")}
                      className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--parent zenblocks-panel--has-subpanel zenblocks-panel--style"
                    >
                      {/* 文字色（サブパネル） */}
                      <span id="panel-anchor-textColor" style={{ display: "block", height: 0 }} />
                      <PanelBody
                        title={__("Text Color", "zenblocks")}
                        opened={panelStates.textColor}
                        onToggle={() => togglePanel("textColor")}
                        className="zenblocks-panel zenblocks-panel--level-2 zenblocks-panel--settings zenblocks-panel--font-color"
                      >
                        <FontColorSetting
                          colorValue={textColor}
                          alphaValue={attributes.textColorAlpha ?? 1}
                          onColorChange={(value) => setAttributes({ textColor: value })}
                          onAlphaChange={(value) => setAttributes({ textColorAlpha: value })}
                        />
                      </PanelBody>

                      {/* テキストシャドウ（サブパネル） */}
                      <PanelBody
                        title={__("Text Shadow", "zenblocks")}
                        opened={panelStates.textShadow}
                        onToggle={() => togglePanel("textShadow")}
                        className="zenblocks-panel zenblocks-panel--level-2 zenblocks-panel--settings zenblocks-panel--font-text-shadow"
                      >
                        <FontTextShadowSetting attributes={attributes} setAttributes={setAttributes} />
                      </PanelBody>

                      {/* ボーダー（サブパネル） */}
                      <span id="panel-anchor-border" style={{ display: "block", height: 0 }} />
                      <StylingBorderSettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Border", "zenblocks")}
                        opened={panelStates.border}
                        onToggle={() => togglePanel("border")}
                        attrName="borderV2"
                      />

                      {/* 角丸（サブパネル） */}
                      <span id="panel-anchor-radius" style={{ display: "block", height: 0 }} />
                      <StylingRadiusSettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Border Radius", "zenblocks")}
                        opened={panelStates.radius}
                        onToggle={() => togglePanel("radius")}
                        attrName="radiusV2"
                        responsiveAttrName="useResponsiveRadius"
                      />

                      {/* インナーシャドウ（サブパネル） */}
                      <span id="panel-anchor-innerShadow" style={{ display: "block", height: 0 }} />
                      <StylingInnerShadowSettingV5
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Inner Shadow", "zenblocks")}
                        opened={panelStates.innerShadow}
                        onToggle={() => togglePanel("innerShadow")}
                      />

                      {/* シャドウ（サブパネル） */}

                      <StylingShadowSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Shadow", "zenblocks")}
                        opened={panelStates.shadow}
                        onToggle={() => togglePanel("shadow")}
                      />

                      {/* 透明（サブパネル） */}

                      <StylingOpacitySettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Opacity", "zenblocks")}
                        opened={panelStates.opacity}
                        onToggle={() => togglePanel("opacity")}
                      />

                      {/* トランジション（サブパネル） */}

                      {applyFilters(
                        'zenblocks.buttonBasic.styleTransitionPanel',
                        <ProPanelShell
                          title={__("Transition", "zenblocks")}
                          opened={panelStates.styleTransition}
                          onToggle={() => togglePanel("styleTransition")}
                          className="zenblocks-panel zenblocks-panel--level-2 zenblocks-panel--settings zenblocks-panel--style-transition"
                          featureName="スタイルトランジション"
                          learnMorePath="/docs/block/element/buttonbasic/button/style/"
                        />,
                        { attributes, setAttributes, panelStates, togglePanel }
                      )}
                    </PanelBody>

                    <span id="panel-anchor-font" style={{ display: "block", height: 0 }} />
                    <PanelBody
                      title={__("Font Settings", "zenblocks")}
                      opened={panelStates.font}
                      onToggle={() => togglePanel("font")}
                      className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--parent zenblocks-panel--has-subpanel zenblocks-panel--font"
                    >
                      <FontFamilySettingV8 attributes={attributes} setAttributes={setAttributes} opened={panelStates.fontFamily} onToggle={() => togglePanel("fontFamily")} />

                      <FontSizeSettingV8 attributes={attributes} setAttributes={setAttributes} opened={panelStates.fontSize} onToggle={() => togglePanel("fontSize")} />

                      <FontLineHeightSettingV7 attributes={attributes} setAttributes={setAttributes} opened={panelStates.lineHeight} onToggle={() => togglePanel("lineHeight")} />

                      <FontLetterSpacingSettingV8 attributes={attributes} setAttributes={setAttributes} opened={panelStates.letterSpacing} onToggle={() => togglePanel("letterSpacing")} />
                    </PanelBody>

                    <PanelBody
                      title={__("Background Settings", "zenblocks")}
                      opened={panelStates.background}
                      onToggle={() => togglePanel("background")}
                      className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--parent zenblocks-panel--has-subpanel zenblocks-panel--background"
                      data-panel-id="background"
                    >
                      <span id="panel-anchor-background" style={{ display: "block", height: 0 }} />
                      <BackgroundColorSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Overlay", "zenblocks")}
                        opened={panelStates.backgroundColor}
                        onToggle={() => togglePanel("backgroundColor")}
                      />

                      <BackgroundPatternSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Pattern", "zenblocks")}
                        opened={panelStates.backgroundPattern}
                        onToggle={() => togglePanel("backgroundPattern")}
                      />

                      <BackgroundImageSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Image", "zenblocks")}
                        opened={panelStates.backgroundImage}
                        onToggle={() => togglePanel("backgroundImage")}
                        isVideoPro={true}
                        learnMorePath="/docs/block/element/buttonbasic/button/background/"
                      />

                      <BackgroundBaseColorSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Color", "zenblocks")}
                        opened={panelStates.backgroundBaseColor}
                        onToggle={() => togglePanel("backgroundBaseColor")}
                      />

                      {applyFilters(
                        'zenblocks.buttonBasic.backgroundTransitionPanel',
                        <ProPanelShell
                          title={__("Transition", "zenblocks")}
                          opened={panelStates.backgroundTransition}
                          onToggle={() => togglePanel("backgroundTransition")}
                          className="zenblocks-panel zenblocks-panel--level-2 zenblocks-panel--settings zenblocks-panel--background-transition"
                          featureName="背景トランジション"
                          learnMorePath="/docs/block/element/buttonbasic/button/background/"
                        />,
                        { attributes, setAttributes, panelStates, togglePanel }
                      )}
                    </PanelBody>

                    {/* アイコン設定 */}
                    <span id="panel-anchor-icon" style={{ display: "block", height: 0 }} />
                    <PanelBody
                      title={__("Icon Settings", "zenblocks")}
                      opened={panelStates.icon}
                      onToggle={() => togglePanel("icon")}
                      className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--parent zenblocks-panel--has-subpanel zenblocks-panel--icon"
                    >
                      <span id="panel-anchor-iconSelect" style={{ display: "block", height: 0 }} />
                      <IconSelectSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        icon={icon}
                        iconColor={iconColor}
                        iconStrokeWidth={iconStrokeWidth}
                        textColor={textColor}
                        getCurrentIconColor={() => getCurrentIconColor(icon, iconColor, textColor)}
                        title={__("Icon Select", "zenblocks")}
                        panelState={panelStates.iconSelect}
                        onTogglePanel={() => togglePanel("iconSelect")}
                        isHoverState={false}
                      />

                      <IconColorSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Icon Color", "zenblocks")}
                        opened={panelStates.iconColor}
                        onToggle={() => togglePanel("iconColor")}
                        isHoverState={false}
                      />

                      <IconSizeSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Icon Size", "zenblocks")}
                        opened={panelStates.iconSize}
                        onToggle={() => togglePanel("iconSize")}
                        isHoverState={false}
                      />

                      <IconPositionSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Icon Position", "zenblocks")}
                        opened={panelStates.iconPosition}
                        onToggle={() => togglePanel("iconPosition")}
                        isHoverState={false}
                      />

                      {applyFilters(
                        'zenblocks.buttonBasic.iconFramePanel',
                        <ProPanelShell
                          title={__("Icon Frame", "zenblocks")}
                          opened={panelStates.iconFrame}
                          onToggle={() => togglePanel("iconFrame")}
                          className="zenblocks-panel zenblocks-panel--level-2 zenblocks-panel--settings zenblocks-panel--has-subpanel zenblocks-panel--icon-frame"
                          featureName="アイコンフレーム"
                          learnMorePath="/docs/block/element/buttonbasic/button/icon/"
                        />,
                        { attributes, setAttributes, panelStates, togglePanel, isHoverState: false }
                      )}

                      {applyFilters(
                        'zenblocks.buttonBasic.iconTransitionPanel',
                        <ProPanelShell
                          title={__("Transition", "zenblocks")}
                          opened={panelStates.iconTransition}
                          onToggle={() => togglePanel("iconTransition")}
                          className="zenblocks-panel zenblocks-panel--level-2 zenblocks-panel--settings zenblocks-panel--icon-transition"
                          featureName="アイコントランジション"
                          learnMorePath="/docs/block/element/buttonbasic/button/icon/"
                        />,
                        { attributes, setAttributes, panelStates, togglePanel }
                      )}
                    </PanelBody>

                    {/* サムネイル設定 */}
                    <span id="panel-anchor-thumbnail" style={{ display: "block", height: 0 }} />
                    <span id="panel-anchor-thumbnailImage" style={{ display: "block", height: 0 }} />
                    {applyFilters(
                      'zenblocks.buttonBasic.thumbnailPanel',
                      <ProPanelShell
                        title={__("Thumbnail Settings", "zenblocks")}
                        opened={panelStates.thumbnail}
                        onToggle={() => togglePanel("thumbnail")}
                        className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--parent zenblocks-panel--has-subpanel zenblocks-panel--thumbnail"
                        featureName="サムネイル設定"
                        learnMorePath="/docs/block/element/buttonbasic/button/thumbnail/"
                      />,
                      { attributes, setAttributes, panelStates, togglePanel, isHoverState: false }
                    )}

                    {/* バンド設定 */}
                    <span id="panel-anchor-band" style={{ display: "block", height: 0 }} />
                    {applyFilters(
                      'zenblocks.buttonBasic.bandPanel',
                      <ProPanelShell
                        title={__("Band Settings", "zenblocks")}
                        opened={panelStates.band}
                        onToggle={() => togglePanel("band")}
                        className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--parent zenblocks-panel--has-subpanel zenblocks-panel--band"
                        featureName="バンド設定"
                        learnMorePath="/docs/block/element/buttonbasic/button/band/"
                      />,
                      { attributes, setAttributes, panelStates, togglePanel, isHoverState: false }
                    )}

                    {/* レイアウト設定 */}
                    <span id="panel-anchor-layout" style={{ display: "block", height: 0 }} />
                    <PanelBody
                      title={__("Layout Settings", "zenblocks")}
                      opened={panelStates.layout}
                      onToggle={() => togglePanel("layout")}
                      className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--parent zenblocks-panel--has-subpanel zenblocks-panel--layout"
                    >
                      <LayoutWidthSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Width", "zenblocks")}
                        opened={panelStates.width}
                        onToggle={() => togglePanel("width")}
                        maxWidth={1000}
                        maxMinWidth={1000}
                        maxMaxWidth={1000}
                      />
                      <LayoutHeightSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Height", "zenblocks")}
                        opened={panelStates.height}
                        onToggle={() => togglePanel("height")}
                      />
                      <SpacingMarginSettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Margin", "zenblocks")}
                        opened={panelStates.margin}
                        onToggle={() => togglePanel("margin")}
                      />
                      <SpacingPaddingSettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Padding", "zenblocks")}
                        opened={panelStates.padding}
                        onToggle={() => togglePanel("padding")}
                      />
                      <LayoutPositionSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Position", "zenblocks")}
                        opened={panelStates.position}
                        onToggle={() => togglePanel("position")}
                      />
                      {/* レイヤー順序 */}
                      <PanelBody
                        title={__("Layer Order", "zenblocks")}
                        opened={panelStates.layerOrder}
                        onToggle={() => togglePanel("layerOrder")}
                        className="zenblocks-panel zenblocks-panel--level-2 zenblocks-panel--settings zenblocks-panel--layer-order"
                      >
                        <div className="zenblocks-inspector-layer-order">
                          <RangeControl
                            label={__("Content", "zenblocks")}
                            value={attributes.layerZIndex?.content ?? 20}
                            onChange={(value) => setAttributes({ layerZIndex: { ...attributes.layerZIndex, content: value } })}
                            min={0}
                            max={99}
                          />
                          <RangeControl
                            label={__("Thumbnail", "zenblocks")}
                            value={attributes.layerZIndex?.thumbnail ?? 10}
                            onChange={(value) => setAttributes({ layerZIndex: { ...attributes.layerZIndex, thumbnail: value } })}
                            min={0}
                            max={99}
                          />
                          <RangeControl
                            label={__("Band", "zenblocks")}
                            value={attributes.layerZIndex?.band ?? 5}
                            onChange={(value) => setAttributes({ layerZIndex: { ...attributes.layerZIndex, band: value } })}
                            min={0}
                            max={99}
                          />
                          <RangeControl
                            label={__("Background", "zenblocks")}
                            value={attributes.layerZIndex?.bg ?? 0}
                            onChange={(value) => setAttributes({ layerZIndex: { ...attributes.layerZIndex, bg: value } })}
                            min={0}
                            max={99}
                          />
                        </div>
                      </PanelBody>
                    </PanelBody>
                  </ResponsiveTabProvider>
                ) : (
                  <ResponsiveTabProvider>
                    <PanelBodyWithSync
                      title={__("Basic Settings", "zenblocks")}
                      opened={panelStates.basic}
                      onToggle={() => togglePanel("basic")}
                      onSync={createSyncHandlerLevel1("basic")}
                      level={1}
                      panelType="parent"
                      hasSubpanel={true}
                      panelName="basic"
                    >
                      {/* テキスト設定（サブパネル） */}
                      <PanelBodyWithSync
                        title={__("Text", "zenblocks")}
                        opened={panelStates.textSettings}
                        onToggle={() => togglePanel("textSettings")}
                        onSync={createSyncHandler("content")}
                        level={2}
                        panelType="settings"
                        panelName="text-settings"
                      >
                        {applyFilters(
                          'zenblocks.buttonBasic.hoverTextPanel',
                          <PlusOverlayOnly
                            featureName="ホバーテキスト"
                            learnMorePath="/downloads/"
                          />,
                          { attributes, setAttributes }
                        )}
                      </PanelBodyWithSync>

                      {/* タグ設定（サブパネル） */}
                      <PanelBody
                        title={__("Tag", "zenblocks")}
                        opened={panelStates.tagSettings}
                        onToggle={() => togglePanel("tagSettings")}
                        className="zenblocks-panel zenblocks-panel--level-2 zenblocks-panel--settings zenblocks-panel--tag-settings"
                      >
                        <div className="zenblocks-inspector-tag-setting" style={{ color: "#757575", fontSize: "12px", textAlign: "center" }}>
                          {__("This item cannot be changed", "zenblocks")}
                        </div>
                      </PanelBody>
                    </PanelBodyWithSync>

                    <PanelBody title={__("Display Settings", "zenblocks")} opened={panelStates.display} onToggle={() => togglePanel("display")}>
                      <div className="zenblocks-inspector-display-setting" style={{ color: "#757575", fontSize: "12px", textAlign: "center" }}>
                        {__("This item cannot be changed", "zenblocks")}
                      </div>
                    </PanelBody>

                    <PanelBodyWithSync
                      title={__("Style Settings", "zenblocks")}
                      opened={panelStates.style}
                      onToggle={() => togglePanel("style")}
                      onSync={createSyncHandlerLevel1("style")}
                      level={1}
                      panelType="parent"
                      hasSubpanel={true}
                      panelName="style"
                    >
                      {/* 文字色（サブパネル） */}
                      <PanelBodyWithSync
                        title={__("Text Color", "zenblocks")}
                        opened={panelStates.textColor}
                        onToggle={() => togglePanel("textColor")}
                        onSync={createSyncHandler("textColor")}
                        className="zenblocks-nested-panel"
                        level={2}
                        panelType="settings"
                        panelName="font-color"
                      >
                        <FontColorSetting
                          colorValue={attributes.textColorHover}
                          alphaValue={attributes.textColorAlphaHover ?? 1}
                          onColorChange={(value) => setAttributes({ textColorHover: value })}
                          onAlphaChange={(value) => setAttributes({ textColorAlphaHover: value })}
                        />
                      </PanelBodyWithSync>

                      {/* テキストシャドウ（サブパネル） */}
                      <PanelBodyWithSync
                        title={__("Text Shadow", "zenblocks")}
                        opened={panelStates.textShadow}
                        onToggle={() => togglePanel("textShadow")}
                        onSync={createSyncHandler("textShadow")}
                        className="zenblocks-nested-panel"
                        level={2}
                        panelType="settings"
                        panelName="font-text-shadow"
                      >
                        <FontTextShadowSetting
                          attributes={{
                            textShadowEnabled: attributes.textShadowEnabledHover,
                            textShadowOffsetX: attributes.textShadowOffsetXHover,
                            textShadowOffsetXUnit: attributes.textShadowOffsetXUnitHover,
                            textShadowOffsetY: attributes.textShadowOffsetYHover,
                            textShadowOffsetYUnit: attributes.textShadowOffsetYUnitHover,
                            textShadowBlur: attributes.textShadowBlurHover,
                            textShadowBlurUnit: attributes.textShadowBlurUnitHover,
                            textShadowColor: attributes.textShadowColorHover,
                            textShadowColorAlpha: attributes.textShadowColorAlphaHover,
                            textShadowOpacity: attributes.textShadowOpacityHover,
                          }}
                          setAttributes={(newAttrs) => {
                            const hoverAttrs = {};
                            Object.keys(newAttrs).forEach((key) => {
                              hoverAttrs[key + "Hover"] = newAttrs[key];
                            });
                            setAttributes(hoverAttrs);
                          }}
                        />
                      </PanelBodyWithSync>

                      <StylingBorderSettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Border", "zenblocks")}
                        opened={panelStates.border}
                        onToggle={() => togglePanel("border")}
                        onSync={createSyncHandler("border")}
                        attrName="borderV2"
                        isHoverState={true}
                      />

                      <StylingRadiusSettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Border Radius", "zenblocks")}
                        opened={panelStates.radius}
                        onToggle={() => togglePanel("radius")}
                        onSync={createSyncHandler("radius")}
                        attrName="radiusV2"
                        responsiveAttrName="useResponsiveRadiusHover"
                        isHoverState={true}
                      />

                      <StylingInnerShadowSettingV5
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Inner Shadow", "zenblocks")}
                        opened={panelStates.innerShadow}
                        onToggle={() => togglePanel("innerShadow")}
                        onSync={createSyncHandler("innerShadow")}
                        isHoverState={true}
                      />

                      <StylingShadowSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Shadow", "zenblocks")}
                        opened={panelStates.shadow}
                        onToggle={() => togglePanel("shadow")}
                        onSync={createSyncHandler("shadow")}
                        isHoverState={true}
                      />

                      <StylingOpacitySettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Opacity", "zenblocks")}
                        opened={panelStates.opacity}
                        onToggle={() => togglePanel("opacity")}
                        isHoverState={true}
                        onSync={createSyncHandler("opacity")}
                      />
                    </PanelBodyWithSync>

                    <PanelBodyWithSync
                      title={__("Font Settings", "zenblocks")}
                      opened={panelStates.font}
                      onToggle={() => togglePanel("font")}
                      onSync={createSyncHandlerLevel1("font")}
                      level={1}
                      panelType="parent"
                      hasSubpanel={true}
                      panelName="font"
                    >
                      <FontFamilySettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        opened={panelStates.fontFamily}
                        onToggle={() => togglePanel("fontFamily")}
                        onSync={createSyncHandler("fontFamily")}
                        isHoverState={true}
                      />

                      <FontSizeSettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        opened={panelStates.fontSize}
                        onToggle={() => togglePanel("fontSize")}
                        onSync={createSyncHandler("fontSize")}
                        attrName="fontSizeV2Hover"
                        responsiveAttrName="useResponsiveFontSizeHover"
                      />

                      <FontLineHeightSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        opened={panelStates.lineHeight}
                        onToggle={() => togglePanel("lineHeight")}
                        isHoverState={true}
                        onSync={createSyncHandler("lineHeight")}
                      />

                      <FontLetterSpacingSettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        opened={panelStates.letterSpacing}
                        onToggle={() => togglePanel("letterSpacing")}
                        onSync={createSyncHandler("letterSpacing")}
                        attrName="letterSpacingV2Hover"
                        responsiveAttrName="useResponsiveLetterSpacingHover"
                      />
                    </PanelBodyWithSync>

                    <PanelBodyWithSync
                      title={__("Background Settings", "zenblocks")}
                      opened={panelStates.background}
                      onToggle={() => togglePanel("background")}
                      onSync={createSyncHandlerLevel1("background")}
                      level={1}
                      panelType="parent"
                      hasSubpanel={true}
                      panelName="background"
                    >
                      <BackgroundColorSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Overlay", "zenblocks")}
                        opened={panelStates.backgroundColor}
                        onToggle={() => togglePanel("backgroundColor")}
                        isHoverState={true}
                        onSync={createSyncHandler("backgroundColor")}
                      />

                      <BackgroundPatternSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Pattern", "zenblocks")}
                        opened={panelStates.backgroundPattern}
                        onToggle={() => togglePanel("backgroundPattern")}
                        isHoverState={true}
                        onSync={createSyncHandler("backgroundPattern")}
                      />

                      <BackgroundImageSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Image", "zenblocks")}
                        opened={panelStates.backgroundImage}
                        onToggle={() => togglePanel("backgroundImage")}
                        isHoverState={true}
                        onSync={createSyncHandler("backgroundImage")}
                        isVideoPro={true}
                        learnMorePath="/docs/block/element/buttonbasic/button/background/"
                      />

                      <BackgroundBaseColorSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Color", "zenblocks")}
                        opened={panelStates.backgroundBaseColor}
                        onToggle={() => togglePanel("backgroundBaseColor")}
                        isHoverState={true}
                        onSync={createSyncHandler("backgroundBaseColor")}
                      />
                    </PanelBodyWithSync>

                    <PanelBodyWithSync
                      title={__("Icon Settings", "zenblocks")}
                      opened={panelStates.icon}
                      onToggle={() => togglePanel("icon")}
                      onSync={createSyncHandlerLevel1("icon")}
                      level={1}
                      panelType="parent"
                      hasSubpanel={true}
                      panelName="icon"
                    >
                      <IconSelectSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        icon={icon}
                        iconColor={iconColor}
                        iconStrokeWidth={iconStrokeWidth}
                        textColor={textColor}
                        getCurrentIconColor={() => getCurrentIconColor(iconHover || icon, iconColorHover || iconColor, textColorHover || textColor)}
                        title={__("Icon Select", "zenblocks")}
                        panelState={panelStates.iconSelect}
                        onTogglePanel={() => togglePanel("iconSelect")}
                        isHoverState={true}
                        onSync={createSyncHandler("iconSelect")}
                      />

                      <IconColorSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Icon Color", "zenblocks")}
                        opened={panelStates.iconColor}
                        onToggle={() => togglePanel("iconColor")}
                        isHoverState={true}
                        onSync={createSyncHandler("iconColor")}
                      />

                      <IconSizeSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Icon Size", "zenblocks")}
                        opened={panelStates.iconSize}
                        onToggle={() => togglePanel("iconSize")}
                        isHoverState={true}
                        onSync={createSyncHandler("iconSize")}
                      />

                      <IconPositionSettingV7
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Icon Position", "zenblocks")}
                        opened={panelStates.iconPosition}
                        onToggle={() => togglePanel("iconPosition")}
                        isHoverState={true}
                        onSync={createSyncHandler("iconPosition")}
                      />

                      <PanelBodyWithSync
                        title={__("Icon Frame", "zenblocks")}
                        opened={panelStates.iconFrame}
                        onToggle={() => togglePanel("iconFrame")}
                        onSync={createSyncHandler("iconFrame")}
                        className="zenblocks-nested-panel"
                        level={2}
                        panelType="settings"
                        hasSubpanel={true}
                        panelName="icon-frame"
                      >
                        {applyFilters(
                          'zenblocks.buttonBasic.hoverIconFramePanel',
                          <ProOverlayOnly
                            featureName="アイコンフレーム"
                            learnMorePath="/docs/block/element/buttonbasic/button/icon/"
                          />,
                          { attributes, setAttributes, panelStates, togglePanel, isHoverState: true, createSyncHandler }
                        )}
                      </PanelBodyWithSync>
                    </PanelBodyWithSync>

                    {/* サムネイル設定 (ホバー) */}

                    {applyFilters(
                      'zenblocks.buttonBasic.hoverThumbnailPanel',
                      <ProPanelShell
                        title={__("Thumbnail Settings", "zenblocks")}
                        opened={panelStates.thumbnail}
                        onToggle={() => togglePanel("thumbnail")}
                        className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--parent zenblocks-panel--has-subpanel zenblocks-panel--thumbnail"
                        featureName="サムネイル設定"
                        learnMorePath="/docs/block/element/buttonbasic/button/thumbnail/"
                      />,
                      { attributes, setAttributes, panelStates, togglePanel, isHoverState: true, createSyncHandlerLevel1 }
                    )}

                    {/* バンド設定 (ホバー) */}

                    {applyFilters(
                      'zenblocks.buttonBasic.hoverBandPanel',
                      <ProPanelShell
                        title={__("Band Settings", "zenblocks")}
                        opened={panelStates.band}
                        onToggle={() => togglePanel("band")}
                        className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--parent zenblocks-panel--has-subpanel zenblocks-panel--band"
                        featureName="バンド設定"
                        learnMorePath="/docs/block/element/buttonbasic/button/band/"
                      />,
                      { attributes, setAttributes, panelStates, togglePanel, isHoverState: true, createSyncHandlerLevel1 }
                    )}

                    <PanelBody
                      title={__("Spacing Settings", "zenblocks")}
                      opened={panelStates.spacing}
                      onToggle={() => togglePanel("spacing")}
                      className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--parent zenblocks-panel--has-subpanel zenblocks-panel--spacing"
                    >
                      <div style={{ padding: "16px 0", color: "#757575", fontSize: "12px", textAlign: "center" }}>{__("This item cannot be changed", "zenblocks")}</div>
                    </PanelBody>

                    <PanelBody
                      title={__("Layout Settings", "zenblocks")}
                      opened={panelStates.layout}
                      onToggle={() => togglePanel("layout")}
                      className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--parent zenblocks-panel--has-subpanel zenblocks-panel--layout"
                    >
                      <div style={{ padding: "16px 0", color: "#757575", fontSize: "12px", textAlign: "center" }}>{__("This item cannot be changed", "zenblocks")}</div>
                    </PanelBody>
                  </ResponsiveTabProvider>
                )}
              </div>
            </StickyCollapsiblePanel>

            {/* カスタム折りたたみパネル - 追加設定 */}
            <span id="panel-anchor-additionalPanel" style={{ display: "block", height: 0 }} />
            <StickyCollapsiblePanel title={__("Additional Settings", "zenblocks")} isOpen={panelStates.additionalPanel} onToggle={() => togglePanel("additionalPanel")}>
              <ResponsiveTabProvider>
                {/* マイクロコピー設定 */}
                <span id="panel-anchor-copyMicroSettings" style={{ display: "block", height: 0 }} />
                <PanelBody
                  title={__("Micro Copy", "zenblocks")}
                  opened={panelStates.copyMicroSettings}
                  onToggle={() => togglePanel("copyMicroSettings")}
                  className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--settings zenblocks-panel--micro-copy-settings"
                >
                  <div className="zenblocks-inspector-micro-copy-setting">
                    <PanelBody
                      title={__("Text", "zenblocks")}
                      initialOpen={false}
                      className="zenblocks-panel zenblocks-panel--level-2 zenblocks-panel--settings zenblocks-panel--micro-copy-text zenblocks-panel--no-subpanel"
                    >
                      <TextareaControl
                        label={__("Text", "zenblocks")}
                        value={attributes.copyMicro || ""}
                        onChange={(value) => setAttributes({ copyMicro: value })}
                        help={__("Copy displayed above the button (outside button). Max 2 lines", "zenblocks")}
                        rows={2}
                      />
                    </PanelBody>
                    <PanelBody
                      title={__("Style", "zenblocks")}
                      initialOpen={false}
                      className="zenblocks-panel zenblocks-panel--level-2 zenblocks-panel--settings zenblocks-panel--micro-copy-style zenblocks-panel--no-subpanel"
                    >
                      <SelectControl
                        label={__("Style", "zenblocks")}
                        value={attributes.copyMicroDesign || "01"}
                        options={[
                          { label: __("01: Simple", "zenblocks"), value: "01" },
                          { label: __("02: Decorated Frame", "zenblocks"), value: "02" },
                          { label: __("03: Ribbon", "zenblocks"), value: "03" },
                          { label: __("04: Speech Bubble", "zenblocks"), value: "04" },
                          { label: __("05: Design", "zenblocks"), value: "05" },
                        ]}
                        onChange={(value) => setAttributes({ copyMicroDesign: value })}
                      />
                    </PanelBody>
                    <StylingBorderSettingV8
                      attributes={attributes}
                      setAttributes={setAttributes}
                      title={__("Border", "zenblocks")}
                      attrName="copyMicroBorderV2"
                      showBoxSizing={false}
                      showEnableToggle={false}
                      level={2}
                    />
                    <PanelBody
                      title={__("Border Radius", "zenblocks")}
                      initialOpen={false}
                      className="zenblocks-panel zenblocks-panel--level-2 zenblocks-panel--settings zenblocks-panel--micro-copy-radius zenblocks-panel--no-subpanel"
                    >
                      <StylingRadiusSimpleSettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        attrName="copyMicroBorderRadiusV2"
                      />
                    </PanelBody>
                    <PanelBody
                      title={__("Color", "zenblocks")}
                      initialOpen={false}
                      className="zenblocks-panel zenblocks-panel--level-2 zenblocks-panel--settings zenblocks-panel--micro-copy-color zenblocks-panel--no-subpanel"
                    >
                      <CustomColorPalette
                        color={attributes.copyMicroTextColor || ""}
                        alpha={attributes.copyMicroTextColorAlpha ?? 1}
                        enableGradient={false}
                        enableAlpha={true}
                        onColorChange={(value) => setAttributes({ copyMicroTextColor: value })}
                        onAlphaChange={(value) => setAttributes({ copyMicroTextColorAlpha: value })}
                        label={__("Text Color", "zenblocks")}
                      />
                      <CustomColorPalette
                        color={attributes.copyMicroBgColor || ""}
                        alpha={attributes.copyMicroBgColorAlpha ?? 1}
                        gradient={attributes.copyMicroBgGradient || ""}
                        useGradient={attributes.copyMicroBgUseGradient || false}
                        enableGradient={true}
                        enableAlpha={true}
                        onColorChange={(value) => setAttributes({ copyMicroBgColor: value })}
                        onAlphaChange={(value) => setAttributes({ copyMicroBgColorAlpha: value })}
                        onGradientChange={(value) => setAttributes({ copyMicroBgGradient: value })}
                        onUseGradientChange={(value) => setAttributes({ copyMicroBgUseGradient: value })}
                        label={__("Background Color", "zenblocks")}
                      />
                    </PanelBody>
                    <PanelBody
                      title={__("Font", "zenblocks")}
                      initialOpen={false}
                      className="zenblocks-panel zenblocks-panel--level-2 zenblocks-panel--settings zenblocks-panel--has-subpanel zenblocks-panel--micro-copy-font"
                    >
                      <FontFamilySettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Font Family", "zenblocks")}
                        attrName="copyMicroFontFamilyV2"
                        fontWeightAttrName="copyMicroFontWeightV2"
                        level={3}
                        supportsHover={false}
                      />
                      <FontSizeSettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Font Size", "zenblocks")}
                        attrName="copyMicroFontSizeV2"
                        level={3}
                      />
                      <FontLineHeightSettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Line Height", "zenblocks")}
                        attrName="copyMicroLineHeightV2"
                        level={3}
                      />
                      <FontLetterSpacingSettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Letter Spacing", "zenblocks")}
                        attrName="copyMicroLetterSpacingV2"
                        level={3}
                      />
                    </PanelBody>
                    <PanelBody
                      title={__("Text Shadow", "zenblocks")}
                      initialOpen={false}
                      className="zenblocks-panel zenblocks-panel--level-2 zenblocks-panel--settings zenblocks-panel--micro-copy-text-shadow zenblocks-panel--no-subpanel"
                    >
                      <FontTextShadowSettingV2
                        attributes={attributes}
                        setAttributes={setAttributes}
                        attrName="copyMicroTextShadowV2"
                      />
                    </PanelBody>
                    <PanelBody
                      title={__("Layout", "zenblocks")}
                      initialOpen={false}
                      className="zenblocks-panel zenblocks-panel--level-2 zenblocks-panel--settings zenblocks-panel--has-subpanel zenblocks-panel--micro-copy-layout"
                    >
                      <SpacingMarginSettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Margin", "zenblocks")}
                        initialOpen={false}
                        attrName="copyMicroMarginV2"
                        level={3}
                      />
                      <SpacingPaddingSettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Padding", "zenblocks")}
                        initialOpen={false}
                        attrName="copyMicroPaddingV2"
                        level={3}
                      />
                      <PanelBody
                        title={__("Transform", "zenblocks")}
                        initialOpen={false}
                        className="zenblocks-panel zenblocks-panel--level-3 zenblocks-panel--settings zenblocks-panel--micro-copy-transform"
                      >
                        <div className="zenblocks-inspector-micro-copy-transform" style={{ padding: "16px 0" }}>
                          <div className="spacing-margin-control">
                            <div className="spacing-margin-label">{__("Rotation (deg)", "zenblocks")}</div>
                            <div className="spacing-margin-controls">
                              <RangeControl
                                value={parseInt(attributes.copyMicroRotate) || 0}
                                onChange={(value) => setAttributes({ copyMicroRotate: value })}
                                min={-180}
                                max={180}
                              />
                            </div>
                          </div>
                        </div>
                      </PanelBody>
                    </PanelBody>
                  </div>
                </PanelBody>

                {/* サブコピー設定 */}
                <span id="panel-anchor-copySubSettings" style={{ display: "block", height: 0 }} />
                <PanelBody
                  title={__("Sub Copy", "zenblocks")}
                  opened={panelStates.copySubSettings}
                  onToggle={() => togglePanel("copySubSettings")}
                  className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--settings zenblocks-panel--sub-copy-settings"
                >
                  <div className="zenblocks-inspector-sub-copy-setting">
                    <PanelBody
                      title={__("Text", "zenblocks")}
                      initialOpen={false}
                      className="zenblocks-panel zenblocks-panel--level-2 zenblocks-panel--settings zenblocks-panel--sub-copy-text zenblocks-panel--no-subpanel"
                    >
                      <TextareaControl
                        label={__("Sub Copy", "zenblocks")}
                        value={attributes.copySub || ""}
                        onChange={(value) => setAttributes({ copySub: value })}
                        help={__("Copy displayed below the button (outside button). Max 2 lines", "zenblocks")}
                        rows={2}
                      />
                    </PanelBody>
                    <PanelBody
                      title={__("Color", "zenblocks")}
                      initialOpen={false}
                      className="zenblocks-panel zenblocks-panel--level-2 zenblocks-panel--settings zenblocks-panel--sub-copy-color zenblocks-panel--no-subpanel"
                    >
                      <CustomColorPalette
                        color={attributes.copySubTextColor || ""}
                        alpha={attributes.copySubTextColorAlpha ?? 1}
                        enableGradient={false}
                        enableAlpha={true}
                        onColorChange={(value) => setAttributes({ copySubTextColor: value })}
                        onAlphaChange={(value) => setAttributes({ copySubTextColorAlpha: value })}
                        label={__("Text Color", "zenblocks")}
                      />
                    </PanelBody>
                    <PanelBody
                      title={__("Font", "zenblocks")}
                      initialOpen={false}
                      className="zenblocks-panel zenblocks-panel--level-2"
                    >
                      <FontFamilySettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Font Family", "zenblocks")}
                        attrName="copySubFontFamilyV2"
                        fontWeightAttrName="copySubFontWeightV2"
                        level={3}
                        supportsHover={false}
                      />
                      <FontSizeSettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Font Size", "zenblocks")}
                        attrName="copySubFontSizeV2"
                        level={3}
                      />
                      <FontLineHeightSettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Line Height", "zenblocks")}
                        attrName="copySubLineHeightV2"
                        level={3}
                      />
                      <FontLetterSpacingSettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Letter Spacing", "zenblocks")}
                        attrName="copySubLetterSpacingV2"
                        level={3}
                      />
                    </PanelBody>
                    <PanelBody
                      title={__("Text Shadow", "zenblocks")}
                      initialOpen={false}
                      className="zenblocks-panel zenblocks-panel--level-2 zenblocks-panel--settings zenblocks-panel--sub-copy-text-shadow zenblocks-panel--no-subpanel"
                    >
                      <FontTextShadowSettingV2
                        attributes={attributes}
                        setAttributes={setAttributes}
                        attrName="copySubTextShadowV2"
                      />
                    </PanelBody>
                    <PanelBody
                      title={__("Layout", "zenblocks")}
                      initialOpen={false}
                      className="zenblocks-panel zenblocks-panel--level-2 zenblocks-panel--settings zenblocks-panel--has-subpanel zenblocks-panel--sub-copy-layout"
                    >
                      <SpacingMarginSettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Margin", "zenblocks")}
                        initialOpen={false}
                        attrName="copySubMarginV2"
                        level={3}
                      />
                      <SpacingPaddingSettingV8
                        attributes={attributes}
                        setAttributes={setAttributes}
                        title={__("Padding", "zenblocks")}
                        initialOpen={false}
                        attrName="copySubPaddingV2"
                        level={3}
                      />
                      <PanelBody
                        title={__("Transform", "zenblocks")}
                        initialOpen={false}
                        className="zenblocks-panel zenblocks-panel--level-3 zenblocks-panel--settings zenblocks-panel--sub-copy-transform"
                      >
                        <div className="zenblocks-inspector-sub-copy-transform" style={{ padding: "16px 0" }}>
                          <div className="spacing-margin-control">
                            <div className="spacing-margin-label">{__("Rotation (deg)", "zenblocks")}</div>
                            <div className="spacing-margin-controls">
                              <RangeControl
                                value={parseInt(attributes.copySubRotate) || 0}
                                onChange={(value) => setAttributes({ copySubRotate: value })}
                                min={-180}
                                max={180}
                              />
                            </div>
                          </div>
                        </div>
                      </PanelBody>
                    </PanelBody>
                  </div>
                </PanelBody>

                {/* マイクロテキスト設定 */}
                <span id="panel-anchor-microTextSettings" style={{ display: "block", height: 0 }} />
                {applyFilters(
                  'zenblocks.buttonBasic.microTextPanel',
                  <ProPanelShell
                    title={__("Micro Text", "zenblocks")}
                    opened={panelStates.microTextSettings}
                    onToggle={() => togglePanel("microTextSettings")}
                    className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--settings zenblocks-panel--micro-text-settings"
                    featureName="マイクロテキスト"
                    learnMorePath="/docs/block/element/buttonbasic/additional/microtext/"
                  />,
                  { attributes, setAttributes, panelStates, togglePanel }
                )}

                {/* サブテキスト設定 */}
                <span id="panel-anchor-subTextSettings" style={{ display: "block", height: 0 }} />
                {applyFilters(
                  'zenblocks.buttonBasic.subTextPanel',
                  <ProPanelShell
                    title={__("Sub Text", "zenblocks")}
                    opened={panelStates.subTextSettings}
                    onToggle={() => togglePanel("subTextSettings")}
                    className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--settings zenblocks-panel--sub-text-settings"
                    featureName="サブテキスト"
                    learnMorePath="/docs/block/element/buttonbasic/additional/subtext/"
                  />,
                  { attributes, setAttributes, panelStates, togglePanel }
                )}
              </ResponsiveTabProvider>
            </StickyCollapsiblePanel>

            {/* アニメーション設定 */}
            <span id="panel-anchor-animationPanel" style={{ display: "block", height: 0 }} />
            <StickyCollapsiblePanel title={__("Animation Settings", "zenblocks")} isOpen={panelStates.animationPanel} onToggle={() => togglePanel("animationPanel")}>
              {/* テキストアニメーション（サブパネル） */}
              <span id="panel-anchor-textAnimationSubPanel" style={{ display: "block", height: 0 }} />
              <PanelBody
                    title={__("Text Animation", "zenblocks")}
                    opened={panelStates.textAnimationSubPanel}
                    onToggle={() => togglePanel("textAnimationSubPanel")}
                    className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--parent zenblocks-panel--has-subpanel zenblocks-panel--text-animation"
                  >
                    {applyFilters(
                      'zenblocks.buttonBasic.textAnimationPanel',
                      <ProOverlayOnly
                        featureName="テキストアニメーション"
                        learnMorePath="/docs/block/element/buttonbasic/animation/textanimation/"
                      />,
                      { attributes, setAttributes, panelStates, togglePanel }
                    )}
                  </PanelBody>
                  {/* アイコンアニメーション（サブパネル） */}
                  <span id="panel-anchor-iconAnimationSubPanel" style={{ display: "block", height: 0 }} />
                  <PanelBody
                    title={__("Icon Animation", "zenblocks")}
                    opened={panelStates.iconAnimationSubPanel}
                    onToggle={() => togglePanel("iconAnimationSubPanel")}
                    className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--parent zenblocks-panel--has-subpanel zenblocks-panel--icon-animation"
                  >
                    {applyFilters(
                      'zenblocks.buttonBasic.iconAnimationPanel',
                      <ProOverlayOnly
                        featureName="アイコンアニメーション"
                        learnMorePath="/docs/block/element/buttonbasic/animation/iconanimation/"
                      />,
                      { attributes, setAttributes, panelStates, togglePanel }
                    )}
                  </PanelBody>
                  {/* フレームアニメーション（サブパネル） */}
                  <span id="panel-anchor-frameAnimationSubPanel" style={{ display: "block", height: 0 }} />
                  <PanelBody
                    title={__("Frame Animation", "zenblocks")}
                    opened={panelStates.frameAnimationSubPanel}
                    onToggle={() => togglePanel("frameAnimationSubPanel")}
                    className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--parent zenblocks-panel--has-subpanel zenblocks-panel--frame-animation"
                  >
                    {applyFilters(
                      'zenblocks.buttonBasic.frameAnimationPanel',
                      <ProOverlayOnly
                        featureName="フレームアニメーション"
                        learnMorePath="/docs/block/element/buttonbasic/animation/frameanimation/"
                      />,
                      { attributes, setAttributes, panelStates, togglePanel }
                    )}
                  </PanelBody>
                  {/* ボタンアニメーション（サブパネル） */}
                  <span id="panel-anchor-buttonAnimationSubPanel" style={{ display: "block", height: 0 }} />
                  <PanelBody
                    title={__("Button Animation", "zenblocks")}
                    opened={panelStates.buttonAnimationSubPanel}
                    onToggle={() => togglePanel("buttonAnimationSubPanel")}
                    className="zenblocks-panel zenblocks-panel--level-1 zenblocks-panel--parent zenblocks-panel--has-subpanel zenblocks-panel--button-animation"
                  >
                    {applyFilters(
                      'zenblocks.buttonBasic.buttonAnimationPanel',
                      <ProOverlayOnly
                        featureName="ボタンアニメーション"
                        learnMorePath="/docs/block/element/buttonbasic/animation/buttonanimation/"
                      />,
                      { attributes, setAttributes, panelStates, togglePanel }
                    )}
              </PanelBody>
            </StickyCollapsiblePanel>
          </div>
        </ResponsiveTabProviderV2>
      </InspectorControls>

      <div {...blockProps}>
        {attributes.copyMicro && <span className="wp-block-zenblocks-button-basic-copy-micro"><span className="wp-block-zenblocks-button-basic-copy-micro-contents">{attributes.copyMicro}</span></span>}
        {tagName === "a" ? (
          <a
            href={href || "#"}
            onClick={(e) => {
              e.preventDefault();
            }}
            target={target || undefined}
            rel={rel || undefined}
            className={
              (icon && icon !== "") || (attributes.iconFrameUseIndividualSize ? attributes.iconFrameWidth > 0 || attributes.iconFrameHeight > 0 : attributes.iconFrameSize > 0) ? "has-icon" : ""
            }
          >
            <div className="wp-block-zenblocks-button-basic-content">
              {((icon && icon !== "") || (attributes.iconFrameUseIndividualSize ? attributes.iconFrameWidth > 0 || attributes.iconFrameHeight > 0 : attributes.iconFrameSize > 0)) && (
                <span className="wp-block-zenblocks-button-basic-icon wrap_icon">
                  <span className="default" dangerouslySetInnerHTML={{ __html: icon ? renderSVGIcon(icon, getCurrentIconColor(icon, iconColor, textColor), iconStrokeWidth || 1.75) : "" }} />
                  <span
                    className="hover"
                    dangerouslySetInnerHTML={{
                      __html:
                        iconHover || icon
                          ? renderSVGIcon(
                              iconHover || icon,
                              getCurrentIconColor(iconHover || icon, iconColorHover || iconColor, textColorHover || textColor),
                              iconStrokeWidthHover !== undefined ? iconStrokeWidthHover : iconStrokeWidth || 1.75,
                            )
                          : "",
                    }}
                  />
                </span>
              )}
              <span className="wp-block-zenblocks-button-basic-text">
                {attributes.microText && <span className="wp-block-zenblocks-button-basic-text-micro">{attributes.microText}</span>}
                <span className="wp-block-zenblocks-button-basic-text-main">
                  <span className="default">{renderTextWithChars(content)}</span>
                  <span className="hover">{renderTextWithChars(hoverText)}</span>
                </span>
                {attributes.subText && <span className="wp-block-zenblocks-button-basic-text-sub">{attributes.subText}</span>}
              </span>
            </div>
            {hasThumbnailMedia(attributes) && (
              <span className="wp-block-zenblocks-button-basic-thumbnail">
                <span className="wp-block-zenblocks-button-basic-thumbnail-overlay default"></span>
                <span className="wp-block-zenblocks-button-basic-thumbnail-overlay hover"></span>
                {attributes.thumbnailMediaType === "video" && attributes.thumbnailVideoPoster && <span className="wp-block-zenblocks-button-basic-thumbnail-poster default" style={thumbnailPosterInlineStyle}></span>}
                {attributes.thumbnailMediaType !== "video" && <span className="wp-block-zenblocks-button-basic-thumbnail-image default"></span>}
                {attributes.thumbnailMediaType === "video" && !!attributes.thumbnailVideoUrl && (
                  <span className="wp-block-zenblocks-button-basic-thumbnail-movie default">
                    {thumbnailVideoConfig.type === "file" ? (
                      <video
                        src={thumbnailVideoConfig.fileUrl}
                        poster={attributes.thumbnailVideoPoster || undefined}
                        style={thumbnailVideoInlineStyle}
                        autoPlay
                        loop
                        muted
                        playsInline
                        preload="metadata"
                        aria-hidden="true"
                      />
                    ) : isEmbedThumbnailVideo && getEditorVideoThumbnailUrl(thumbnailVideoConfig) ? (
                      <img
                        src={getEditorVideoThumbnailUrl(thumbnailVideoConfig)}
                        alt=""
                        style={thumbnailVideoInlineStyle}
                        aria-hidden="true"
                      />
                    ) : null}
                  </span>
                )}
              </span>
            )}
            <span className="wp-block-zenblocks-button-basic-band">
              <span className="wp-block-zenblocks-button-basic-band-color default"></span>
              <span className="wp-block-zenblocks-button-basic-band-color hover"></span>
              {(getBandPatternType(attributes, "pc") !== "none" ||
                getBandPatternType(attributes, "md") !== "none" ||
                getBandPatternType(attributes, "tb") !== "none" ||
                getBandPatternType(attributes, "sp") !== "none") && (
                <span
                  className="wp-block-zenblocks-button-basic-band-pattern default"
                  data-pattern-pc={getBandPatternType(attributes, previewDevice || "pc")}
                ></span>
              )}
              {attributes.bandMediaType === "video" && attributes.bandVideoPoster && <span className="wp-block-zenblocks-button-basic-band-poster default" style={bandPosterInlineStyle}></span>}
              {attributes.bandMediaType !== "video" && <span className="wp-block-zenblocks-button-basic-band-image default"></span>}
              {attributes.bandMediaType === "video" && !!attributes.bandVideoUrl && (
                <span className="wp-block-zenblocks-button-basic-band-movie default">
                  {bandVideoConfig.type === "file" ? (
                    <video
                      src={bandVideoConfig.fileUrl}
                      poster={attributes.bandVideoPoster || undefined}
                      style={bandVideoInlineStyle}
                      autoPlay
                      loop
                      muted
                      playsInline
                      preload="metadata"
                      aria-hidden="true"
                    />
                  ) : isEmbedBandVideo && getEditorVideoThumbnailUrl(bandVideoConfig) ? (
                    <img
                      src={getEditorVideoThumbnailUrl(bandVideoConfig)}
                      alt=""
                      style={bandVideoInlineStyle}
                      aria-hidden="true"
                    />
                  ) : null}
                </span>
              )}
            </span>
            <span className="wp-block-zenblocks-button-basic-bg">
              <span className="wp-block-zenblocks-button-basic-bg-overlay default"></span>
              <span className="wp-block-zenblocks-button-basic-bg-overlay hover"></span>
              {attributes.backgroundMediaType !== "video" && <span className="wp-block-zenblocks-button-basic-bg-image default"></span>}
              {attributes.backgroundMediaType === "video" && attributes.backgroundVideoPoster && <span className="wp-block-zenblocks-button-basic-bg-poster default" style={posterInlineStyle}></span>}
              {hasBackgroundVideo(attributes) && (
                <span className="wp-block-zenblocks-button-basic-bg-movie default">
                  {backgroundVideoConfig.type === "file" ? (
                    <video
                      src={backgroundVideoConfig.fileUrl}
                      poster={attributes.backgroundVideoPoster || undefined}
                      style={videoInlineStyle}
                      autoPlay
                      loop
                      muted
                      playsInline
                      preload="metadata"
                      aria-hidden="true"
                    />
                  ) : isEmbedBackgroundVideo && getEditorVideoThumbnailUrl(backgroundVideoConfig) ? (
                    <img
                      src={getEditorVideoThumbnailUrl(backgroundVideoConfig)}
                      alt=""
                      style={videoInlineStyle}
                      aria-hidden="true"
                    />
                  ) : null}
                </span>
              )}
              <span className="wp-block-zenblocks-button-basic-bg-base-color default"></span>
              {(getBackgroundPatternType(attributes, "pc") !== "none" ||
                getBackgroundPatternType(attributes, "md") !== "none" ||
                getBackgroundPatternType(attributes, "tb") !== "none" ||
                getBackgroundPatternType(attributes, "sp") !== "none") && (
                <span
                  className="wp-block-zenblocks-button-basic-bg-pattern default"
                  data-pattern-pc={getBackgroundPatternType(attributes, previewDevice || "pc")}
                ></span>
              )}
            </span>
            {attributes.frameAnimation && attributes.frameAnimation !== "none" && <span className="wp-block-zenblocks-button-basic-frame"></span>}
          </a>
        ) : (
          <button
            type={buttonType || "button"}
            className={
              (icon && icon !== "") || (attributes.iconFrameUseIndividualSize ? attributes.iconFrameWidth > 0 || attributes.iconFrameHeight > 0 : attributes.iconFrameSize > 0) ? "has-icon" : ""
            }
          >
            <div className="wp-block-zenblocks-button-basic-content">
              {((icon && icon !== "") || (attributes.iconFrameUseIndividualSize ? attributes.iconFrameWidth > 0 || attributes.iconFrameHeight > 0 : attributes.iconFrameSize > 0)) && (
                <span className="wp-block-zenblocks-button-basic-icon wrap_icon">
                  <span className="default" dangerouslySetInnerHTML={{ __html: icon ? renderSVGIcon(icon, getCurrentIconColor(icon, iconColor, textColor), iconStrokeWidth || 1.75) : "" }} />
                  <span
                    className="hover"
                    dangerouslySetInnerHTML={{
                      __html:
                        iconHover || icon
                          ? renderSVGIcon(
                              iconHover || icon,
                              getCurrentIconColor(iconHover || icon, iconColorHover || iconColor, textColorHover || textColor),
                              iconStrokeWidthHover !== undefined ? iconStrokeWidthHover : iconStrokeWidth || 1.75,
                            )
                          : "",
                    }}
                  />
                </span>
              )}
              <span className="wp-block-zenblocks-button-basic-text">
                {attributes.microText && <span className="wp-block-zenblocks-button-basic-text-micro">{attributes.microText}</span>}
                <span className="wp-block-zenblocks-button-basic-text-main">
                  <span className="default">{renderTextWithChars(content)}</span>
                  <span className="hover">{renderTextWithChars(hoverText)}</span>
                </span>
                {attributes.subText && <span className="wp-block-zenblocks-button-basic-text-sub">{attributes.subText}</span>}
              </span>
            </div>
            {hasThumbnailMedia(attributes) && (
              <span className="wp-block-zenblocks-button-basic-thumbnail">
                <span className="wp-block-zenblocks-button-basic-thumbnail-overlay default"></span>
                <span className="wp-block-zenblocks-button-basic-thumbnail-overlay hover"></span>
                {attributes.thumbnailMediaType === "video" && attributes.thumbnailVideoPoster && <span className="wp-block-zenblocks-button-basic-thumbnail-poster default" style={thumbnailPosterInlineStyle}></span>}
                {attributes.thumbnailMediaType !== "video" && <span className="wp-block-zenblocks-button-basic-thumbnail-image default"></span>}
                {attributes.thumbnailMediaType === "video" && !!attributes.thumbnailVideoUrl && (
                  <span className="wp-block-zenblocks-button-basic-thumbnail-movie default">
                    {thumbnailVideoConfig.type === "file" ? (
                      <video
                        src={thumbnailVideoConfig.fileUrl}
                        poster={attributes.thumbnailVideoPoster || undefined}
                        style={thumbnailVideoInlineStyle}
                        autoPlay
                        loop
                        muted
                        playsInline
                        preload="metadata"
                        aria-hidden="true"
                      />
                    ) : isEmbedThumbnailVideo && getEditorVideoThumbnailUrl(thumbnailVideoConfig) ? (
                      <img
                        src={getEditorVideoThumbnailUrl(thumbnailVideoConfig)}
                        alt=""
                        style={thumbnailVideoInlineStyle}
                        aria-hidden="true"
                      />
                    ) : null}
                  </span>
                )}
              </span>
            )}
            <span className="wp-block-zenblocks-button-basic-band">
              <span className="wp-block-zenblocks-button-basic-band-color default"></span>
              <span className="wp-block-zenblocks-button-basic-band-color hover"></span>
              {(getBandPatternType(attributes, "pc") !== "none" ||
                getBandPatternType(attributes, "md") !== "none" ||
                getBandPatternType(attributes, "tb") !== "none" ||
                getBandPatternType(attributes, "sp") !== "none") && (
                <span
                  className="wp-block-zenblocks-button-basic-band-pattern default"
                  data-pattern-pc={getBandPatternType(attributes, previewDevice || "pc")}
                ></span>
              )}
              {attributes.bandMediaType === "video" && attributes.bandVideoPoster && <span className="wp-block-zenblocks-button-basic-band-poster default" style={bandPosterInlineStyle}></span>}
              {attributes.bandMediaType !== "video" && <span className="wp-block-zenblocks-button-basic-band-image default"></span>}
              {attributes.bandMediaType === "video" && !!attributes.bandVideoUrl && (
                <span className="wp-block-zenblocks-button-basic-band-movie default">
                  {bandVideoConfig.type === "file" ? (
                    <video
                      src={bandVideoConfig.fileUrl}
                      poster={attributes.bandVideoPoster || undefined}
                      style={bandVideoInlineStyle}
                      autoPlay
                      loop
                      muted
                      playsInline
                      preload="metadata"
                      aria-hidden="true"
                    />
                  ) : isEmbedBandVideo && getEditorVideoThumbnailUrl(bandVideoConfig) ? (
                    <img
                      src={getEditorVideoThumbnailUrl(bandVideoConfig)}
                      alt=""
                      style={bandVideoInlineStyle}
                      aria-hidden="true"
                    />
                  ) : null}
                </span>
              )}
            </span>
            <span className="wp-block-zenblocks-button-basic-bg">
              <span className="wp-block-zenblocks-button-basic-bg-overlay default"></span>
              <span className="wp-block-zenblocks-button-basic-bg-overlay hover"></span>
              {attributes.backgroundMediaType !== "video" && <span className="wp-block-zenblocks-button-basic-bg-image default"></span>}
              {attributes.backgroundMediaType === "video" && attributes.backgroundVideoPoster && <span className="wp-block-zenblocks-button-basic-bg-poster default" style={posterInlineStyle}></span>}
              {hasBackgroundVideo(attributes) && (
                <span className="wp-block-zenblocks-button-basic-bg-movie default">
                  {backgroundVideoConfig.type === "file" ? (
                    <video
                      src={backgroundVideoConfig.fileUrl}
                      poster={attributes.backgroundVideoPoster || undefined}
                      style={videoInlineStyle}
                      autoPlay
                      loop
                      muted
                      playsInline
                      preload="metadata"
                      aria-hidden="true"
                    />
                  ) : isEmbedBackgroundVideo && getEditorVideoThumbnailUrl(backgroundVideoConfig) ? (
                    <img
                      src={getEditorVideoThumbnailUrl(backgroundVideoConfig)}
                      alt=""
                      style={videoInlineStyle}
                      aria-hidden="true"
                    />
                  ) : null}
                </span>
              )}
              <span className="wp-block-zenblocks-button-basic-bg-base-color default"></span>
              {(getBackgroundPatternType(attributes, "pc") !== "none" ||
                getBackgroundPatternType(attributes, "md") !== "none" ||
                getBackgroundPatternType(attributes, "tb") !== "none" ||
                getBackgroundPatternType(attributes, "sp") !== "none") && (
                <span
                  className="wp-block-zenblocks-button-basic-bg-pattern default"
                  data-pattern-pc={getBackgroundPatternType(attributes, previewDevice || "pc")}
                ></span>
              )}
            </span>
            {attributes.frameAnimation && attributes.frameAnimation !== "none" && <span className="wp-block-zenblocks-button-basic-frame"></span>}
          </button>
        )}
        {attributes.copySub && <span className="wp-block-zenblocks-button-basic-copy-sub"><span className="wp-block-zenblocks-button-basic-copy-sub-contents">{attributes.copySub}</span></span>}
      </div>
      {showSyncConfirmModal && (
        <Modal
          title={__("Sync Hover Style", "zenblocks")}
          onRequestClose={() => setShowSyncConfirmModal(false)}
          className="zenblocks-sync-confirm-modal"
        >
          <p style={{ marginBottom: "16px" }}>
            {__("Copy default style settings to hover style.", "zenblocks")}
          </p>
          <p style={{ marginBottom: "16px", color: "#757575", fontSize: "12px" }}>
            {__("Note: Current hover style settings will be overwritten. This action cannot be undone.", "zenblocks")}
          </p>
          <div style={{ display: "flex", justifyContent: "flex-end", gap: "8px" }}>
            <Button variant="secondary" onClick={() => setShowSyncConfirmModal(false)}>
              {__("Cancel", "zenblocks")}
            </Button>
            <Button
              variant="primary"
              onClick={() => {
                createSyncHandlerLevel0("all")();
                setShowSyncConfirmModal(false);
              }}
            >
              {__("Sync", "zenblocks")}
            </Button>
          </div>
        </Modal>
      )}
    </>
  );
}

export default function ButtonBasicEdit(props) {
  return <ButtonBasicEditInner {...props} />;
}
