<?php

/**
 * AnchorKit Elementor Widget Class
 *
 * @package AnchorKit
 * @since 1.0.0
 */

// Exit if accessed directly
if (!defined('ABSPATH')) {
	exit;
}

use Elementor\Widget_Base;
use Elementor\Controls_Manager;
use Elementor\Group_Control_Typography;
use Elementor\Group_Control_Border;
use Elementor\Group_Control_Box_Shadow;
use Elementor\Core\Schemes\Color;
use Elementor\Core\Schemes\Typography;

/**
 * AnchorKit Table of Contents Widget
 */
class AnchorKit_Elementor_Widget extends Widget_Base
{

	/**
	 * Cached global defaults sourced from auto-insert/Gutenberg settings.
	 *
	 * @var array|null
	 */
	protected $toc_defaults = null;

	/**
	 * Cached reset schema for this widget instance.
	 *
	 * @var array|null
	 */
	protected $reset_schema_cache = null;

	/**
	 * Cached reset schema for static requests (e.g. script localization).
	 *
	 * @var array|null
	 */
	protected static $static_reset_schema_cache = null;

	/**
	 * Get widget name
	 */
	public function get_name()
	{
		return 'anchorkit-toc';
	}

	/**
	 * Get widget title
	 */
	public function get_title()
	{
		$title = __('AnchorKit TOC', 'anchorkit-table-of-contents');
		return $title;
	}

	/**
	 * Get widget icon
	 */
	public function get_icon()
	{
		return 'anchorkit-elementor-icon';
	}

	/**
	 * Get widget categories
	 */
	public function get_categories()
	{
		return array('anchorkit', 'general');
	}

	/**
	 * Get widget keywords
	 */
	public function get_keywords()
	{
		return array('table of contents', 'toc', 'navigation', 'index', 'anchor', 'anchorkit');
	}

	/**
	 * Get script dependencies
	 *
	 * Retrieve the list of script dependencies the widget requires
	 */
	public function get_script_depends()
	{
		return array('anchorkit-toc-js');
	}

	/**
	 * Get style dependencies
	 *
	 * Retrieve the list of style dependencies the widget requires
	 */
	public function get_style_depends()
	{
		return array('anchorkit-toc-css');
	}

	/**
	 * Shared helper for pulling sanitized TOC defaults.
	 *
	 * @return array
	 */
	protected function get_toc_defaults()
	{
		if ($this->toc_defaults === null) {
			$this->toc_defaults = function_exists('anchorkit_get_toc_default_settings')
				? anchorkit_get_toc_default_settings()
				: array();
		}

		return $this->toc_defaults;
	}

	/**
	 * Get the reset schema for this widget instance.
	 *
	 * @return array
	 */
	protected function get_reset_schema_for_instance()
	{
		if ($this->reset_schema_cache === null) {
			$this->reset_schema_cache = self::compute_reset_schema($this->get_toc_defaults());
		}

		return $this->reset_schema_cache;
	}

	/**
	 * Provide reset schema data for consumers outside of the widget instance.
	 *
	 * @return array
	 */
	public static function get_reset_schema_static()
	{
		if (self::$static_reset_schema_cache === null) {
			$defaults = function_exists('anchorkit_get_toc_default_settings') ? anchorkit_get_toc_default_settings() : array();
			self::$static_reset_schema_cache = self::compute_reset_schema($defaults);
		}

		return self::$static_reset_schema_cache;
	}

	/**
	 * Build the reset schema describing default values per section.
	 *
	 * @param array $defaults
	 * @return array
	 */
	protected static function compute_reset_schema(array $defaults)
	{
		$switcher_default = static function ($value, $fallback = false) {
			if ($value === null) {
				$value = $fallback;
			}

			return $value ? 'yes' : '';
		};

		$slider_default = static function ($value, $unit = 'px', $fallback = 0) {
			if (!is_numeric($value)) {
				$value = $fallback;
			}

			return array(
				'unit' => $unit,
				'size' => (float) $value,
			);
		};

		$array_default = static function ($value, $fallback) {
			if (is_array($value) && !empty($value)) {
				return array_values($value);
			}

			return $fallback;
		};

		$sections = array();

		$sections['content'] = array(
			'label' => __('Content Settings', 'anchorkit-table-of-contents'),
			'controls' => array(
				'toc_title' => $defaults['title'] ?? __('Table of Contents', 'anchorkit-table-of-contents'),
				'show_title' => $switcher_default($defaults['showTitle'] ?? true, true),
				'heading_levels' => $array_default($defaults['headingLevels'] ?? null, array('h2', 'h3', 'h4')),
				'min_headings' => isset($defaults['minHeadingsToShow']) ? (int) $defaults['minHeadingsToShow'] : 2,
				'exclude_selectors' => $defaults['excludeSelectors'] ?? '',
				'aria_label' => $defaults['ariaLabel'] ?? '',
				'custom_css_class' => $defaults['customCssClass'] ?? '',
				'custom_id' => '',
				'anchor_format' => $defaults['anchorFormat'] ?? 'auto',
				'anchor_prefix' => $defaults['anchorPrefix'] ?? 'section',
				'custom_labels' => isset($defaults['customLabels']) ? (string) $defaults['customLabels'] : '',
			),
		);

		$sections['behavior'] = array(
			'label' => __('Behavior Settings', 'anchorkit-table-of-contents'),
			'controls' => array(
				'hierarchical' => $switcher_default($defaults['hierarchicalView'] ?? true, true),
				'collapsible' => $switcher_default($defaults['collapsible'] ?? true, true),
				'initial_state' => $defaults['initialState'] ?? 'expanded',
				'smooth_scroll' => $switcher_default($defaults['smoothScroll'] ?? true, true),
				'scroll_offset' => $slider_default($defaults['scrollOffset'] ?? 0, 'px', 0),
				'scroll_easing' => $defaults['scrollEasing'] ?? 'ease-in-out',
				'scroll_duration' => isset($defaults['scrollDuration']) ? (int) $defaults['scrollDuration'] : 500,
				'hide_on_mobile' => $switcher_default($defaults['hideOnMobile'] ?? false, false),
				'mobile_breakpoint' => isset($defaults['mobileBreakpoint']) ? (int) $defaults['mobileBreakpoint'] : 782,
				'toc_width' => $slider_default($defaults['tocWidth'] ?? 100, '%', 100),
				'alignment' => $defaults['tocAlignment'] ?? 'center',
			),
		);

		$sections['pro_features'] = array(
			'label' => __('Advanced Features', 'anchorkit-table-of-contents'),
			'controls' => array(
				'sticky' => $switcher_default($defaults['sticky'] ?? false, false),
				'sticky_position' => $defaults['stickyPosition'] ?? 'content',
				'sticky_offset' => $slider_default($defaults['stickyOffset'] ?? 20, 'px', 20),
				'scroll_spy' => $switcher_default($defaults['scrollSpy'] ?? false, false),
				'back_to_top_link' => $switcher_default($defaults['backToTopLink'] ?? false, false),
				'back_to_top_text' => $defaults['backToTopText'] ?? __('Back to Top', 'anchorkit-table-of-contents'),
				'back_to_top_font_size' => isset($defaults['backToTopFontSize']) ? (int) $defaults['backToTopFontSize'] : 14,
				'view_more_enabled' => $switcher_default($defaults['viewMoreEnabled'] ?? false, false),
				'initial_count' => isset($defaults['viewMoreInitialCount']) ? (int) $defaults['viewMoreInitialCount'] : 5,
				'view_more_text' => $defaults['viewMoreText'] ?? __('View More', 'anchorkit-table-of-contents'),
				'view_less_text' => $defaults['viewLessText'] ?? __('View Less', 'anchorkit-table-of-contents'),
				'entrance_animation' => $switcher_default($defaults['entranceAnimation'] ?? false, false),
				'animation_type' => $defaults['animationType'] ?? 'fade',
				'bullet_style' => $defaults['bulletStyle'] ?? 'disc',
				'bullet_character' => $defaults['bulletCharacter'] ?? '•',
				'show_numerals' => $switcher_default($defaults['showNumerals'] ?? false, false),
				'numbering_style' => $defaults['numberingStyle'] ?? 'hierarchical',
				'numbering_format' => $defaults['numberingFormat'] ?? 'decimal',
				'numbering_separator' => $defaults['numberingSeparator'] ?? '.',
				'exclude_keywords' => $defaults['excludeKeywords'] ?? '',
				'exclude_regex' => $defaults['excludeRegex'] ?? '',
				'show_reading_time' => $switcher_default($defaults['showReadingTime'] ?? false, false),
				'show_word_count' => $switcher_default($defaults['showWordCount'] ?? false, false),
				'reading_speed' => isset($defaults['readingSpeed']) ? (int) $defaults['readingSpeed'] : 200,
				'time_format' => $defaults['timeFormat'] ?? 'min_read',
				'schema_enabled' => $switcher_default($defaults['schemaEnabled'] ?? false, false),
				'schema_type' => $defaults['schemaType'] ?? 'Article',
			),
		);

		$sections['integrations'] = array(
			'label' => __('Integrations & Compatibility', 'anchorkit-table-of-contents'),
			'controls' => array(
				'acf_enabled' => $switcher_default($defaults['acfEnabled'] ?? false, false),
				'acf_field_names' => '',
				'acf_merge_mode' => $defaults['acfMergeMode'] ?? 'after',
				'amp_enabled' => $switcher_default($defaults['ampEnabled'] ?? false, false),
			),
		);

		$sections['style'] = array(
			'label' => __('Container Style', 'anchorkit-table-of-contents'),
			'controls' => array(
				'style_preset' => $defaults['stylePreset'] ?? 'minimal',
				'theme' => $defaults['theme'] ?? 'system',
				// Border controls
				'border_border' => '',
				'border_width' => array(
					'top' => '',
					'right' => '',
					'bottom' => '',
					'left' => '',
					'unit' => 'px',
					'isLinked' => true,
				),
				// Border Radius (Dimensions)
				'border_radius' => array(
					'top' => '',
					'right' => '',
					'bottom' => '',
					'left' => '',
					'unit' => 'px',
					'isLinked' => true,
				),
				// Padding (Dimensions)
				'padding' => array(
					'top' => '',
					'right' => '',
					'bottom' => '',
					'left' => '',
					'unit' => 'px',
					'isLinked' => true,
				),
			),
		);

		// Typography section (merged from typography and advanced_typography)
		$sections['typography'] = array(
			'label' => __('Typography', 'anchorkit-table-of-contents'),
			'controls' => array(
				// Title Typography group control defaults
				'title_typography_typography' => '',
				'title_typography_font_family' => '',
				'title_typography_font_size' => array(
					'size' => '',
					'unit' => 'px',
				),
				'title_typography_font_weight' => '',
				'title_typography_text_transform' => '',
				'title_typography_font_style' => '',
				'title_typography_text_decoration' => '',

				// Link Typography group control defaults
				'link_typography_typography' => '',
				'link_typography_font_family' => '',
				'link_typography_font_size' => array(
					'size' => '',
					'unit' => 'px',
				),
				'link_typography_font_weight' => '',
				'link_typography_text_transform' => '',
				'link_typography_font_style' => '',
				'link_typography_text_decoration' => '',

				// Advanced Typography controls
				'advanced_typography_override' => $switcher_default($defaults['advancedTypographyOverride'] ?? false, false),
				'title_font_size' => array(
					'size' => isset($defaults['titleFontSize']) ? (int) $defaults['titleFontSize'] : 20,
					'unit' => 'px',
				),
				'h2_font_size' => array(
					'size' => isset($defaults['h2FontSize']) ? (int) $defaults['h2FontSize'] : 18,
					'unit' => 'px',
				),
				'h3_font_size' => array(
					'size' => isset($defaults['h3FontSize']) ? (int) $defaults['h3FontSize'] : 16,
					'unit' => 'px',
				),
				'h4_font_size' => array(
					'size' => isset($defaults['h4FontSize']) ? (int) $defaults['h4FontSize'] : 14,
					'unit' => 'px',
				),
				'h5_font_size' => array(
					'size' => isset($defaults['h5FontSize']) ? (int) $defaults['h5FontSize'] : 13,
					'unit' => 'px',
				),
				'h6_font_size' => array(
					'size' => isset($defaults['h6FontSize']) ? (int) $defaults['h6FontSize'] : 12,
					'unit' => 'px',
				),
				'line_height' => isset($defaults['lineHeight']) ? (float) $defaults['lineHeight'] : 1.6,
				'letter_spacing' => isset($defaults['letterSpacing']) ? (float) $defaults['letterSpacing'] : 0,
				'text_transform' => $defaults['textTransform'] ?? 'none',
				'link_underline' => $defaults['linkUnderline'] ?? 'none',
			),
		);

		$sections['custom_style'] = array(
			'label' => __('Custom Styling', 'anchorkit-table-of-contents'),
			'controls' => array(
				'design_override' => '',
				'design_editor_mode' => 'light',
				'design_bg_color_light' => $defaults['bgColorLight'] ?? '#ffffff',
				'design_text_color_light' => $defaults['textColorLight'] ?? '#333333',
				'design_link_color_light' => $defaults['linkColorLight'] ?? '#0073AA',
				'design_link_hover_color_light' => $defaults['linkHoverColorLight'] ?? '#005177',
				'design_border_color_light' => $defaults['borderColorLight'] ?? '#dddddd',
				'design_bullet_color_light' => $defaults['bulletColorLight'] ?? '#0073AA',
				'design_active_link_color_light' => $defaults['activeLinkColorLight'] ?? '#00A0D2',
				'design_bg_color_dark' => $defaults['bgColorDark'] ?? '#1e1e1e',
				'design_text_color_dark' => $defaults['textColorDark'] ?? '#e0e0e0',
				'design_link_color_dark' => $defaults['linkColorDark'] ?? '#7ec4ee',
				'design_link_hover_color_dark' => $defaults['linkHoverColorDark'] ?? '#a8d8f0',
				'design_border_color_dark' => $defaults['borderColorDark'] ?? '#404040',
				'design_bullet_color_dark' => $defaults['bulletColorDark'] ?? '#7ec4ee',
				'design_active_link_color_dark' => $defaults['activeLinkColorDark'] ?? '#5ba3d0',
				'design_shadow_h_offset_light' => 0,
				'design_shadow_v_offset_light' => 4,
				'design_shadow_blur_light' => 6,
				'design_shadow_spread_light' => 0,
				'design_shadow_color_light' => '#000000',
				'design_shadow_opacity_light' => $slider_default(0.1, 'px', 0.1),
				'design_shadow_h_offset_dark' => 0,
				'design_shadow_v_offset_dark' => 2,
				'design_shadow_blur_dark' => 8,
				'design_shadow_spread_dark' => 0,
				'design_shadow_color_dark' => '#000000',
				'design_shadow_opacity_dark' => $slider_default(0.3, 'px', 0.3),
			),
		);

		$all_controls = array();
		foreach ($sections as $section) {
			$all_controls = array_merge($all_controls, $section['controls']);
		}

		return array(
			'sections' => $sections,
			'all_controls' => $all_controls,
		);
	}

	/**
	 * Generate the reset button markup used in Elementor sections.
	 *
	 * @param string $section_key
	 * @param string $section_label
	 * @param bool   $include_global
	 * @return string
	 */
	protected function get_reset_button_markup($section_key, $section_label, $include_global = false)
	{
		$buttons = array();

		// If include_global is true, we ONLY show the global button (legacy support or specific use case)
		// But based on new requirements, we want to separate them.
		// Let's adapt: if $section_key is 'all', show global button.
		// Otherwise show section button.

		if ($section_key === 'all') {
			$buttons[] = sprintf(
				'<button type="button" class="anchorkit-el-reset-button anchorkit-el-reset-button--global" data-reset-target="all" data-reset-label="%1$s">%2$s</button>',
				esc_attr__('Entire Widget', 'anchorkit-table-of-contents'),
				esc_html__('Reset All Settings', 'anchorkit-table-of-contents')
			);
		} else {
			// translators: %s is the section name being reset (e.g., "Title", "Container")
			$reset_text = sprintf(__('Reset %s', 'anchorkit-table-of-contents'), $section_label);
			$buttons[] = sprintf(
				'<button type="button" class="anchorkit-el-reset-button" data-reset-target="%1$s" data-reset-label="%2$s">%3$s</button>',
				esc_attr($section_key),
				esc_attr($section_label),
				esc_html($reset_text)
			);
		}

		return '<div class="anchorkit-el-reset-buttons">' . implode('', $buttons) . '</div>';
	}

	/**
	 * PERFORMANCE ENHANCEMENT - Widget Inner Wrapper
	 * ===============================================
	 *
	 * Elementor wraps each widget in two nested <div> elements by default.
	 * For performance optimization, we can reduce this to one wrapper.
	 *
	 * BENEFIT: Reduces DOM size and improves rendering performance
	 * RISK: May affect layout in some edge cases
	 *
	 * IMPLEMENTATION:
	 *   Uncomment the method below to enable this optimization.
	 *   Test thoroughly with all widget configurations before deploying.
	 *
	 * @since 1.0.0
	 * @return bool False to disable inner wrapper (one less div)
	 */
	// public function has_widget_inner_wrapper() {
	// return false;
	// }

	/**
	 * Register widget controls
	 */
	protected function register_controls()
	{
		$defaults = $this->get_toc_defaults();
		$switcher_default = static function ($value) {
			return $value ? 'yes' : '';
		};
		$slider_default = static function ($value, $unit = 'px') {
			$size = is_numeric($value) ? (float) $value : 0;
			return array(
				'unit' => $unit,
				'size' => $size,
			);
		};

		// ============================================================
		// CONTENT TAB
		// ============================================================

		$this->start_controls_section(
			'content_section',
			array(
				'label' => __('Content Settings', 'anchorkit-table-of-contents'),
				'tab' => Controls_Manager::TAB_CONTENT,
			)
		);

		// Removed top reset controls

		// TOC Title
		$this->add_control(
			'toc_title',
			array(
				'label' => __('TOC Title', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::TEXT,
				'default' => $defaults['title'] ?? __('Table of Contents', 'anchorkit-table-of-contents'),
				'placeholder' => __('Enter TOC title', 'anchorkit-table-of-contents'),
				'label_block' => true,
			)
		);

		// Show Title Toggle
		$this->add_control(
			'show_title',
			array(
				'label' => __('Show Title', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SWITCHER,
				'label_on' => __('Yes', 'anchorkit-table-of-contents'),
				'label_off' => __('No', 'anchorkit-table-of-contents'),
				'return_value' => 'yes',
				'default' => $switcher_default($defaults['showTitle'] ?? true),
			)
		);

		// Heading Levels
		$this->add_control(
			'heading_levels',
			array(
				'label' => __('Include Heading Levels', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SELECT2,
				'multiple' => true,
				'options' => array(
					'h1' => __('H1', 'anchorkit-table-of-contents'),
					'h2' => __('H2', 'anchorkit-table-of-contents'),
					'h3' => __('H3', 'anchorkit-table-of-contents'),
					'h4' => __('H4', 'anchorkit-table-of-contents'),
					'h5' => __('H5', 'anchorkit-table-of-contents'),
					'h6' => __('H6', 'anchorkit-table-of-contents'),
				),
				'default' => $defaults['headingLevels'] ?? array('h2', 'h3', 'h4'),
				'label_block' => true,
			)
		);

		// Minimum Headings
		$this->add_control(
			'min_headings',
			array(
				'label' => __('Minimum Headings', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::NUMBER,
				'min' => 1,
				'max' => 10,
				'step' => 1,
				'default' => $defaults['minHeadingsToShow'] ?? 2,
				'description' => __('Minimum number of headings required to display TOC', 'anchorkit-table-of-contents'),
			)
		);

		// Exclude Selectors
		$this->add_control(
			'exclude_selectors',
			array(
				'label' => __('Exclude Headings (CSS Selectors)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::TEXTAREA,
				'rows' => 3,
				'default' => $defaults['excludeSelectors'] ?? '',
				'placeholder' => __('.toc-exclude, .no-toc', 'anchorkit-table-of-contents'),
				'description' => __('Comma-separated CSS selectors. Example: .toc-exclude, #skip-heading', 'anchorkit-table-of-contents'),
			)
		);

		// ARIA Label (Accessibility)
		$this->add_control(
			'aria_label',
			array(
				'label' => __('ARIA Label', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::TEXT,
				'default' => $defaults['ariaLabel'] ?? '',
				'placeholder' => __('Table of Contents', 'anchorkit-table-of-contents'),
				'description' => __('Accessible label for screen readers. Defaults to TOC title if empty.', 'anchorkit-table-of-contents'),
				'separator' => 'before',
			)
		);

		// Additional CSS Class(es)
		$this->add_control(
			'custom_css_class',
			array(
				'label' => __('Additional CSS Class(es)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::TEXT,
				'default' => $defaults['customCssClass'] ?? '',
				'placeholder' => __('my-toc custom-design', 'anchorkit-table-of-contents'),
				'description' => __('Space-separated class names for custom styling.', 'anchorkit-table-of-contents'),
			)
		);

		// Custom TOC ID
		$this->add_control(
			'custom_id',
			array(
				'label' => __('Custom TOC ID', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::TEXT,
				'default' => '',
				'placeholder' => __('my-custom-toc', 'anchorkit-table-of-contents'),
				'description' => __('Custom ID for the TOC container (for CSS/JavaScript targeting).', 'anchorkit-table-of-contents'),
			)
		);

		// Anchor Format
		$this->add_control(
			'anchor_format',
			array(
				'label' => __('Anchor ID Format', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SELECT,
				'options' => array(
					'auto' => __('Auto (from heading text)', 'anchorkit-table-of-contents'),
					'sequential' => __('Sequential numbers (toc-1, toc-2...)', 'anchorkit-table-of-contents'),
					'prefixed' => __('Custom prefix + sanitized heading', 'anchorkit-table-of-contents'),
				),
				'default' => $defaults['anchorFormat'] ?? 'auto',
				'description' => __('How anchor IDs are generated for headings.', 'anchorkit-table-of-contents'),
			)
		);

		// Anchor Prefix (for prefixed format)
		$this->add_control(
			'anchor_prefix',
			array(
				'label' => __('Custom Anchor Prefix', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::TEXT,
				'default' => $defaults['anchorPrefix'] ?? 'section',
				'placeholder' => __('section', 'anchorkit-table-of-contents'),
				'description' => __('Prefix for anchor IDs. Example result: section-introduction', 'anchorkit-table-of-contents'),
				'condition' => array(
					'anchor_format' => 'prefixed',
				),
			)
		);

		// Custom Heading Labels (JSON)
		$this->add_control(
			'custom_labels',
			array(
				'label' => __('Custom Heading Labels (JSON)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::TEXTAREA,
				'rows' => 4,
				'default' => $defaults['customLabels'] ?? '',
				'placeholder' => __('{"Introduction": "Start Here", "FAQ": "Questions"}', 'anchorkit-table-of-contents'),
				'description' => __('Replace heading text in TOC only. Format: {"Original": "New Label"}', 'anchorkit-table-of-contents'),
			)
		);

		$this->add_control(
			'content_reset_controls',
			array(
				'type' => Controls_Manager::RAW_HTML,
				'raw' => $this->get_reset_button_markup('content', __('Content Settings', 'anchorkit-table-of-contents')),
				'content_classes' => 'anchorkit-el-reset-control',
				'separator' => 'before',
			)
		);

		$this->end_controls_section();

		// ============================================================
		// BEHAVIOR SECTION
		// ============================================================

		$this->start_controls_section(
			'behavior_section',
			array(
				'label' => __('Behavior Settings', 'anchorkit-table-of-contents'),
				'tab' => Controls_Manager::TAB_CONTENT,
			)
		);

		// Removed top reset controls

		// Hierarchical View
		$this->add_control(
			'hierarchical',
			array(
				'label' => __('Hierarchical View', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SWITCHER,
				'label_on' => __('Yes', 'anchorkit-table-of-contents'),
				'label_off' => __('No', 'anchorkit-table-of-contents'),
				'return_value' => 'yes',
				'default' => $switcher_default($defaults['hierarchicalView'] ?? true),
				'description' => __('Indent sub-headings to show hierarchy', 'anchorkit-table-of-contents'),
			)
		);

		// Collapsible
		$this->add_control(
			'collapsible',
			array(
				'label' => __('Collapsible', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SWITCHER,
				'label_on' => __('Yes', 'anchorkit-table-of-contents'),
				'label_off' => __('No', 'anchorkit-table-of-contents'),
				'return_value' => 'yes',
				'default' => $switcher_default($defaults['collapsible'] ?? true),
				'description' => __('Allow users to collapse/expand TOC', 'anchorkit-table-of-contents'),
			)
		);

		// Initial State
		$this->add_control(
			'initial_state',
			array(
				'label' => __('Initial State', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SELECT,
				'options' => array(
					'expanded' => __('Expanded', 'anchorkit-table-of-contents'),
					'collapsed' => __('Collapsed', 'anchorkit-table-of-contents'),
				),
				'default' => $defaults['initialState'] ?? 'expanded',
				'condition' => array(
					'collapsible' => 'yes',
				),
			)
		);

		// Smooth Scroll
		$this->add_control(
			'smooth_scroll',
			array(
				'label' => __('Smooth Scrolling', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SWITCHER,
				'label_on' => __('Yes', 'anchorkit-table-of-contents'),
				'label_off' => __('No', 'anchorkit-table-of-contents'),
				'return_value' => 'yes',
				'default' => $switcher_default($defaults['smoothScroll'] ?? true),
			)
		);

		// Scroll Offset
		$this->add_control(
			'scroll_offset',
			array(
				'label' => __('Scroll Offset (px)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SLIDER,
				'size_units' => array('px'),
				'range' => array(
					'px' => array(
						'min' => 0,
						'max' => 200,
						'step' => 1,
					),
				),
				'default' => $slider_default($defaults['scrollOffset'] ?? 0, 'px'),
				'condition' => array(
					'smooth_scroll' => 'yes',
				),
				'description' => __('Distance from top when scrolling to headings (useful for fixed headers).', 'anchorkit-table-of-contents'),
			)
		);

		$this->add_control(
			'scroll_easing',
			array(
				'label' => __('Smooth Scroll Easing', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SELECT,
				'options' => array(
					'ease-in-out' => __('Ease In-Out', 'anchorkit-table-of-contents'),
					'ease-in' => __('Ease In', 'anchorkit-table-of-contents'),
					'ease-out' => __('Ease Out', 'anchorkit-table-of-contents'),
					'ease' => __('Ease', 'anchorkit-table-of-contents'),
					'linear' => __('Linear', 'anchorkit-table-of-contents'),
					'cubic-bezier(0.68, -0.55, 0.265, 1.55)' => __('Bouncy', 'anchorkit-table-of-contents'),
				),
				'default' => $defaults['scrollEasing'] ?? 'ease-in-out',
				'condition' => array(
					'smooth_scroll' => 'yes',
				),
				'description' => __('Easing curve for smooth scroll animation.', 'anchorkit-table-of-contents'),
			)
		);

		$this->add_control(
			'scroll_duration',
			array(
				'label' => __('Smooth Scroll Duration (ms)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::NUMBER,
				'min' => 100,
				'max' => 2000,
				'step' => 50,
				'default' => $defaults['scrollDuration'] ?? 500,
				'condition' => array(
					'smooth_scroll' => 'yes',
				),
				'description' => __('Duration of smooth scroll animation in milliseconds.', 'anchorkit-table-of-contents'),
			)
		);

		// Hide on Mobile
		$this->add_control(
			'hide_on_mobile',
			array(
				'label' => __('Hide on Mobile', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SWITCHER,
				'label_on' => __('Yes', 'anchorkit-table-of-contents'),
				'label_off' => __('No', 'anchorkit-table-of-contents'),
				'return_value' => 'yes',
				'default' => $switcher_default($defaults['hideOnMobile'] ?? false),
				'description' => __('Hide TOC on small screens', 'anchorkit-table-of-contents'),
				'separator' => 'before',
			)
		);

		// Mobile Breakpoint
		$this->add_control(
			'mobile_breakpoint',
			array(
				'label' => __('Mobile Breakpoint (px)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::NUMBER,
				'min' => 320,
				'max' => 1200,
				'step' => 1,
				'default' => $defaults['mobileBreakpoint'] ?? 782,
				'description' => __('Screen width below which TOC will be hidden', 'anchorkit-table-of-contents'),
				'condition' => array(
					'hide_on_mobile' => 'yes',
				),
			)
		);

		// TOC Width
		$this->add_control(
			'toc_width',
			array(
				'label' => __('TOC Width (%)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SLIDER,
				'size_units' => array('%'),
				'range' => array(
					'%' => array(
						'min' => 20,
						'max' => 100,
						'step' => 5,
					),
				),
				'default' => $slider_default($defaults['tocWidth'] ?? 100, '%'),
				// Remove selector here as it's handled in render() to support max-width logic logic better
				// 'selectors' => [
				// '{{WRAPPER}} .anchorkit-toc-container' => 'width: {{SIZE}}{{UNIT}} !important;',
				// ],
				'description' => __('Width as percentage of container', 'anchorkit-table-of-contents'),
			)
		);

		// Alignment (when not floating)
		$this->add_control(
			'alignment',
			array(
				'label' => __('Alignment', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SELECT,
				'options' => array(
					'left' => __('Left', 'anchorkit-table-of-contents'),
					'center' => __('Center', 'anchorkit-table-of-contents'),
					'right' => __('Right', 'anchorkit-table-of-contents'),
				),
				'default' => $defaults['tocAlignment'] ?? 'center',
				'description' => __('Control horizontal alignment when the TOC is narrower than the content area.', 'anchorkit-table-of-contents'),
				'condition' => array(
					'sticky_position!' => array('left', 'right'),
				),
				'selectors_dictionary' => array(
					'left' => '20px auto 20px 0',
					'center' => '20px auto',
					'right' => '20px 0 20px auto',
				),
				'selectors' => array(
					'{{WRAPPER}} .anchorkit-toc-container' => 'margin: {{VALUE}} !important;',
				),
			)
		);

		$this->add_control(
			'behavior_reset_controls',
			array(
				'type' => Controls_Manager::RAW_HTML,
				'raw' => $this->get_reset_button_markup('behavior', __('Behavior Settings', 'anchorkit-table-of-contents')),
				'content_classes' => 'anchorkit-el-reset-control',
				'separator' => 'before',
			)
		);

		$this->end_controls_section();

		// ============================================================
		// ADVANCED FEATURES SECTION
		// ============================================================

		$this->start_controls_section(
			'pro_features_section',
			array(
				'label' => __('Advanced Features', 'anchorkit-table-of-contents'),
				'tab' => Controls_Manager::TAB_CONTENT,
			)
		);

		// Sticky TOC
		$this->add_control(
			'sticky',
			array(
				'label' => __('Sticky Position', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SWITCHER,
				'label_on' => __('Yes', 'anchorkit-table-of-contents'),
				'label_off' => __('No', 'anchorkit-table-of-contents'),
				'return_value' => 'yes',
				'default' => $switcher_default($defaults['sticky'] ?? false),
				'description' => __('Keep TOC visible while scrolling', 'anchorkit-table-of-contents'),
			)
		);

		// Sticky Position Type
		$this->add_control(
			'sticky_position',
			array(
				'label' => __('Sticky Position Type', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SELECT,
				'options' => array(
					'content' => __('In Content (Default)', 'anchorkit-table-of-contents'),
					'left' => __('Floating Left Sidebar', 'anchorkit-table-of-contents'),
					'right' => __('Floating Right Sidebar', 'anchorkit-table-of-contents'),
				),
				'default' => $defaults['stickyPosition'] ?? 'content',
				'condition' => array(
					'sticky' => 'yes',
				),
			)
		);

		// Sticky Offset
		$this->add_control(
			'sticky_offset',
			array(
				'label' => __('Sticky Offset from Top (px)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SLIDER,
				'size_units' => array('px'),
				'range' => array(
					'px' => array(
						'min' => 0,
						'max' => 200,
						'step' => 1,
					),
				),
				'default' => $slider_default($defaults['stickyOffset'] ?? 20, 'px'),
				'condition' => array(
					'sticky' => 'yes',
				),
			)
		);

		// Scroll Spy (requires sticky)
		$this->add_control(
			'scroll_spy',
			array(
				'label' => __('Scroll Spy', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SWITCHER,
				'label_on' => __('Yes', 'anchorkit-table-of-contents'),
				'label_off' => __('No', 'anchorkit-table-of-contents'),
				'return_value' => 'yes',
				'default' => $switcher_default($defaults['scrollSpy'] ?? false),
				'description' => __('Highlight active section as user scrolls', 'anchorkit-table-of-contents'),
				'condition' => array(
					'sticky' => 'yes',
				),
			)
		);

		// Back to Top Link (requires sticky)
		$this->add_control(
			'back_to_top_link',
			array(
				'label' => __('Back to Top Link', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SWITCHER,
				'label_on' => __('Yes', 'anchorkit-table-of-contents'),
				'label_off' => __('No', 'anchorkit-table-of-contents'),
				'return_value' => 'yes',
				'default' => $switcher_default($defaults['backToTopLink'] ?? false),
				'description' => __('Add a "Back to Top" link at the end of the sticky TOC', 'anchorkit-table-of-contents'),
				'condition' => array(
					'sticky' => 'yes',
				),
			)
		);

		$this->add_control(
			'back_to_top_text',
			array(
				'label' => __('Back to Top Text', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::TEXT,
				'default' => $defaults['backToTopText'] ?? __('Back to Top', 'anchorkit-table-of-contents'),
				'condition' => array(
					'sticky' => 'yes',
					'back_to_top_link' => 'yes',
				),
			)
		);

		$this->add_control(
			'back_to_top_font_size',
			array(
				'label' => __('Back to Top Font Size (px)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::NUMBER,
				'default' => $defaults['backToTopFontSize'] ?? 14,
				'min' => 10,
				'max' => 24,
				'step' => 1,
				'condition' => array(
					'sticky' => 'yes',
					'back_to_top_link' => 'yes',
				),
			)
		);

		// View More Feature
		$this->add_control(
			'view_more_enabled',
			array(
				'label' => __('View More Feature', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SWITCHER,
				'label_on' => __('Yes', 'anchorkit-table-of-contents'),
				'label_off' => __('No', 'anchorkit-table-of-contents'),
				'return_value' => 'yes',
				'default' => $switcher_default($defaults['viewMoreEnabled'] ?? false),
				'description' => __('Limit visible items with expand/collapse button', 'anchorkit-table-of-contents'),
				'separator' => 'before',
			)
		);

		// Initial Count
		$this->add_control(
			'initial_count',
			array(
				'label' => __('Initial Item Count', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::NUMBER,
				'min' => 1,
				'max' => 50,
				'step' => 1,
				'default' => $defaults['viewMoreInitialCount'] ?? 5,
				'condition' => array(
					'view_more_enabled' => 'yes',
				),
			)
		);

		// View More Text
		$this->add_control(
			'view_more_text',
			array(
				'label' => __('"View More" Text', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::TEXT,
				'default' => $defaults['viewMoreText'] ?? __('View More', 'anchorkit-table-of-contents'),
				'condition' => array(
					'view_more_enabled' => 'yes',
				),
			)
		);

		// View Less Text
		$this->add_control(
			'view_less_text',
			array(
				'label' => __('"View Less" Text', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::TEXT,
				'default' => $defaults['viewLessText'] ?? __('View Less', 'anchorkit-table-of-contents'),
				'condition' => array(
					'view_more_enabled' => 'yes',
				),
			)
		);

		// Entrance Animation
		$this->add_control(
			'entrance_animation',
			array(
				'label' => __('Entrance Animation', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SWITCHER,
				'label_on' => __('Yes', 'anchorkit-table-of-contents'),
				'label_off' => __('No', 'anchorkit-table-of-contents'),
				'return_value' => 'yes',
				'default' => $switcher_default($defaults['entranceAnimation'] ?? false),
				'separator' => 'before',
			)
		);

		// Animation Type
		$this->add_control(
			'animation_type',
			array(
				'label' => __('Animation Type', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SELECT,
				'options' => array(
					'fade' => __('Fade', 'anchorkit-table-of-contents'),
					'slide' => __('Slide', 'anchorkit-table-of-contents'),
					'zoom' => __('Zoom', 'anchorkit-table-of-contents'),
				),
				'default' => $defaults['animationType'] ?? 'fade',
				'condition' => array(
					'entrance_animation' => 'yes',
				),
			)
		);

		// ============================================================
		// BULLETS & NUMBERING
		// ============================================================

		$this->add_control(
			'bullets_heading',
			array(
				'label' => __('Bullets & Numbering', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::HEADING,
				'separator' => 'before',
			)
		);

		// Bullet Style
		$this->add_control(
			'bullet_style',
			array(
				'label' => __('Bullet Style', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SELECT,
				'options' => array(
					'none' => __('None (no bullets)', 'anchorkit-table-of-contents'),
					'disc' => __('Disc (•)', 'anchorkit-table-of-contents'),
					'circle' => __('Circle (○)', 'anchorkit-table-of-contents'),
					'square' => __('Square (▪)', 'anchorkit-table-of-contents'),
					'arrow' => __('Arrow (→)', 'anchorkit-table-of-contents'),
					'chevron' => __('Chevron (›)', 'anchorkit-table-of-contents'),
					'check' => __('Check (✓)', 'anchorkit-table-of-contents'),
					'star' => __('Star (★)', 'anchorkit-table-of-contents'),
					'custom_character' => __('Custom Character', 'anchorkit-table-of-contents'),
				),
				'default' => $defaults['bulletStyle'] ?? 'disc',
				'description' => __('Choose a bullet or numbering style for TOC items', 'anchorkit-table-of-contents'),
			)
		);

		// Custom Bullet Character
		$this->add_control(
			'bullet_character',
			array(
				'label' => __('Custom Bullet Character', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::TEXT,
				'default' => $defaults['bulletCharacter'] ?? '•',
				'placeholder' => '►',
				'description' => __('Enter your custom bullet character (1-3 characters)', 'anchorkit-table-of-contents'),
				'condition' => array(
					'bullet_style' => 'custom_character',
				),
			)
		);

		// Bullet Color - Note about global settings
		$this->add_control(
			'bullet_color_note',
			array(
				'type' => Controls_Manager::RAW_HTML,
				'raw' => __('<p><strong>Note:</strong> Bullet colors are controlled globally in the AnchorKit settings page under <strong>Appearance & Behavior > Bullets & Numbering</strong>. This allows you to set different colors for light and dark modes.</p>', 'anchorkit-table-of-contents'),
				'content_classes' => 'elementor-panel-alert elementor-panel-alert-info',
			)
		);

		// Show Numerals
		$this->add_control(
			'show_numerals',
			array(
				'label' => __('Show Numerals', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SWITCHER,
				'label_on' => __('Yes', 'anchorkit-table-of-contents'),
				'label_off' => __('No', 'anchorkit-table-of-contents'),
				'return_value' => 'yes',
				'default' => $switcher_default($defaults['showNumerals'] ?? false),
				'description' => __('Display numbers for each TOC item (works with hierarchical view)', 'anchorkit-table-of-contents'),
			)
		);

		// Numbering Style
		$this->add_control(
			'numbering_style',
			array(
				'label' => __('Numbering Style', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SELECT,
				'options' => array(
					'hierarchical' => __('Hierarchical (1.2.3)', 'anchorkit-table-of-contents'),
					'flat' => __('Flat (1, 2, 3, 4...)', 'anchorkit-table-of-contents'),
				),
				'default' => $defaults['numberingStyle'] ?? 'hierarchical',
				'description' => __('Choose between hierarchical or flat numbering', 'anchorkit-table-of-contents'),
				'condition' => array(
					'show_numerals' => 'yes',
				),
			)
		);

		// Numbering Format
		$this->add_control(
			'numbering_format',
			array(
				'label' => __('Numbering Format', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SELECT,
				'options' => array(
					'decimal' => __('Decimal', 'anchorkit-table-of-contents'),
					'decimal_leading_zero' => __('Decimal (01)', 'anchorkit-table-of-contents'),
					'upper_roman' => __('Upper Roman (I)', 'anchorkit-table-of-contents'),
					'lower_roman' => __('Lower Roman (i)', 'anchorkit-table-of-contents'),
					'upper_alpha' => __('Upper Alpha (A)', 'anchorkit-table-of-contents'),
					'lower_alpha' => __('Lower Alpha (a)', 'anchorkit-table-of-contents'),
				),
				'default' => $defaults['numberingFormat'] ?? 'decimal',
				'condition' => array(
					'show_numerals' => 'yes',
				),
			)
		);

		// Numbering Separator
		$this->add_control(
			'numbering_separator',
			array(
				'label' => __('Separator', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SELECT,
				'options' => array(
					'.' => __('Dot (.)', 'anchorkit-table-of-contents'),
					'-' => __('Dash (-)', 'anchorkit-table-of-contents'),
					'·' => __('Middle dot (·)', 'anchorkit-table-of-contents'),
				),
				'default' => $defaults['numberingSeparator'] ?? '.',
				'condition' => array(
					'show_numerals' => 'yes',
				),
			)
		);

		// ============================================================
		// ADVANCED CONTENT FILTERING
		// ============================================================

		$this->add_control(
			'filtering_heading',
			array(
				'label' => __('Advanced Content Filtering', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::HEADING,
				'separator' => 'before',
			)
		);

		// Exclude Keywords
		$this->add_control(
			'exclude_keywords',
			array(
				'label' => __('Exclude Words', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::TEXTAREA,
				'rows' => 2,
				'default' => $defaults['excludeKeywords'] ?? '',
				'placeholder' => __('sponsored, advertisement', 'anchorkit-table-of-contents'),
				'description' => __('Comma-separated keywords. Headings containing these words will be excluded.', 'anchorkit-table-of-contents'),
			)
		);

		// Exclude Patterns
		$this->add_control(
			'exclude_regex',
			array(
				'label' => __('Trim Heading Prefixes', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::TEXTAREA,
				'rows' => 2,
				'default' => $defaults['excludeRegex'] ?? '',
				'placeholder' => __('step, chapter, section', 'anchorkit-table-of-contents'),
				'description' => __('Remove words from TOC labels. Example: "Step 1: Title" becomes "Title"', 'anchorkit-table-of-contents'),
			)
		);

		// ============================================================
		// READING TIME & METADATA
		// ============================================================

		$this->add_control(
			'reading_time_heading',
			array(
				'label' => __('Reading Time & Metadata', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::HEADING,
				'separator' => 'before',
			)
		);

		// Show Reading Time
		$this->add_control(
			'show_reading_time',
			array(
				'label' => __('Show Reading Time per Section', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SWITCHER,
				'label_on' => __('Yes', 'anchorkit-table-of-contents'),
				'label_off' => __('No', 'anchorkit-table-of-contents'),
				'return_value' => 'yes',
				'default' => $switcher_default($defaults['showReadingTime'] ?? false),
				'description' => __('Display estimated reading time for each TOC section', 'anchorkit-table-of-contents'),
			)
		);

		// Show Word Count
		$this->add_control(
			'show_word_count',
			array(
				'label' => __('Show Word Count', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SWITCHER,
				'label_on' => __('Yes', 'anchorkit-table-of-contents'),
				'label_off' => __('No', 'anchorkit-table-of-contents'),
				'return_value' => 'yes',
				'default' => $switcher_default($defaults['showWordCount'] ?? false),
				'description' => __('Display the number of words detected for each heading.', 'anchorkit-table-of-contents'),
			)
		);

		// Reading Speed (WPM)
		$this->add_control(
			'reading_speed',
			array(
				'label' => __('Reading Speed (WPM)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::NUMBER,
				'min' => 50,
				'max' => 1000,
				'step' => 10,
				'default' => $defaults['readingSpeed'] ?? 200,
				'description' => __('Words per minute for reading time calculation', 'anchorkit-table-of-contents'),
				'condition' => array(
					'show_reading_time' => 'yes',
				),
			)
		);

		// Time Format
		$this->add_control(
			'time_format',
			array(
				'label' => __('Time Format', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SELECT,
				'options' => array(
					'min_read' => __('“5 min read”', 'anchorkit-table-of-contents'),
					'minutes' => __('“~5 minutes”', 'anchorkit-table-of-contents'),
					'short' => __('“5m”', 'anchorkit-table-of-contents'),
				),
				'default' => $defaults['timeFormat'] ?? 'min_read',
				'condition' => array(
					'show_reading_time' => 'yes',
				),
			)
		);

		// ============================================================
		// SCHEMA.ORG & SEO
		// ============================================================

		$this->add_control(
			'schema_heading',
			array(
				'label' => __('Schema.org & SEO', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::HEADING,
				'separator' => 'before',
			)
		);

		// Enable Schema
		$this->add_control(
			'schema_enabled',
			array(
				'label' => __('Enable Schema.org Markup', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SWITCHER,
				'label_on' => __('Yes', 'anchorkit-table-of-contents'),
				'label_off' => __('No', 'anchorkit-table-of-contents'),
				'return_value' => 'yes',
				'default' => $switcher_default($defaults['schemaEnabled'] ?? false),
				'description' => __('Add structured data to help search engines understand your content', 'anchorkit-table-of-contents'),
			)
		);

		// Schema Type
		$this->add_control(
			'schema_type',
			array(
				'label' => __('Schema Type', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SELECT,
				'options' => array(
					'Article' => __('Article', 'anchorkit-table-of-contents'),
					'BlogPosting' => __('Blog Posting', 'anchorkit-table-of-contents'),
					'WebPage' => __('Web Page', 'anchorkit-table-of-contents'),
					'HowTo' => __('How-To Guide', 'anchorkit-table-of-contents'),
					'FAQPage' => __('FAQ Page', 'anchorkit-table-of-contents'),
					'NewsArticle' => __('News Article', 'anchorkit-table-of-contents'),
					'TechArticle' => __('Tech Article', 'anchorkit-table-of-contents'),
					'Course' => __('Course', 'anchorkit-table-of-contents'),
				),
				'default' => $defaults['schemaType'] ?? 'Article',
				'condition' => array(
					'schema_enabled' => 'yes',
				),
			)
		);

		// Schema Header Text
		$this->add_control(
			'schema_header',
			array(
				'label' => __('Schema Markup', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::RAW_HTML,
				'raw' => '<p>' . __('Structured data output follows your selected schema type for the TOC.', 'anchorkit-table-of-contents') . '</p>',
				'content_classes' => 'anchorkit-control-note',
			)
		);

		$this->add_control(
			'pro_features_reset_controls',
			array(
				'type' => Controls_Manager::RAW_HTML,
				'raw' => $this->get_reset_button_markup('pro_features', __('Advanced Features', 'anchorkit-table-of-contents')),
				'content_classes' => 'anchorkit-el-reset-control',
				'separator' => 'before',
			)
		);

		$this->end_controls_section();

		// ============================================================
		// Integrations & Compatibility
		// ============================================================

		$this->start_controls_section(
			'integrations_section',
			array(
				'label' => __('Integrations & Compatibility', 'anchorkit-table-of-contents'),
				'tab' => Controls_Manager::TAB_CONTENT,
			)
		);

		$this->add_control(
			'integrations_note',
			array(
				'type' => Controls_Manager::RAW_HTML,
				'raw' => '<p>' . __('Configure ACF merging and AMP-safe output for this widget.', 'anchorkit-table-of-contents') . '</p>',
				'content_classes' => 'anchorkit-control-note',
			)
		);

		// ACF Integration
		$this->add_control(
			'acf_enabled',
			array(
				'label' => __('ACF Integration', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SWITCHER,
				'label_on' => __('Yes', 'anchorkit-table-of-contents'),
				'label_off' => __('No', 'anchorkit-table-of-contents'),
				'return_value' => 'yes',
				'default' => $switcher_default($defaults['acfEnabled'] ?? false),
				'description' => __('Merge headings stored in Advanced Custom Fields with the main content.', 'anchorkit-table-of-contents'),
			)
		);

		$this->add_control(
			'acf_field_names',
			array(
				'label' => __('ACF Field Names', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::TEXT,
				'default' => '',
				'placeholder' => __('hero_content, body_sections', 'anchorkit-table-of-contents'),
				'description' => __('Comma-separated ACF field names whose content should be scanned for headings. Note: Click "Update" and preview the page to see ACF field changes reflected in the TOC.', 'anchorkit-table-of-contents'),
				'condition' => array(
					'acf_enabled' => 'yes',
				),
			)
		);

		$this->add_control(
			'acf_merge_mode',
			array(
				'label' => __('ACF Merge Mode', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SELECT,
				'options' => array(
					'before' => __('Before main content', 'anchorkit-table-of-contents'),
					'after' => __('After main content', 'anchorkit-table-of-contents'),
					'replace' => __('Replace main content', 'anchorkit-table-of-contents'),
				),
				'default' => $defaults['acfMergeMode'] ?? 'after',
				'condition' => array(
					'acf_enabled' => 'yes',
				),
				'description' => __('Control how ACF headings are combined with the primary content when building the TOC.', 'anchorkit-table-of-contents'),
			)
		);

		// AMP Compatibility
		$this->add_control(
			'amp_enabled',
			array(
				'label' => __('AMP Compatibility', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SWITCHER,
				'label_on' => __('Yes', 'anchorkit-table-of-contents'),
				'label_off' => __('No', 'anchorkit-table-of-contents'),
				'return_value' => 'yes',
				'default' => $switcher_default($defaults['ampEnabled'] ?? false),
				'description' => __('Render a simplified AMP-friendly TOC when viewing AMP endpoints.', 'anchorkit-table-of-contents'),
			)
		);

		$this->add_control(
			'integrations_reset_controls',
			array(
				'type' => Controls_Manager::RAW_HTML,
				'raw' => $this->get_reset_button_markup('integrations', __('Integrations & Compatibility', 'anchorkit-table-of-contents')),
				'content_classes' => 'anchorkit-el-reset-control',
				'separator' => 'before',
			)
		);

		$this->end_controls_section();

		// ============================================================
		// RESET SECTION (Global)
		// ============================================================

		$this->start_controls_section(
			'reset_section',
			array(
				'label' => __('Reset', 'anchorkit-table-of-contents'),
				'tab' => Controls_Manager::TAB_CONTENT,
			)
		);

		$this->add_control(
			'global_reset_controls',
			array(
				'type' => Controls_Manager::RAW_HTML,
				'raw' => $this->get_reset_button_markup('all', __('Entire Widget', 'anchorkit-table-of-contents')),
				'content_classes' => 'anchorkit-el-reset-control',
			)
		);

		$this->end_controls_section();

		// ============================================================
		// STYLE TAB - Appearance
		// ============================================================

		$this->start_controls_section(
			'style_section',
			array(
				'label' => __('Container Style', 'anchorkit-table-of-contents'),
				'tab' => Controls_Manager::TAB_STYLE,
			)
		);

		// Style Preset
		$this->add_control(
			'style_preset',
			array(
				'label' => __('Style Preset', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SELECT,
				'options' => array(
					'minimal' => __('Minimal', 'anchorkit-table-of-contents'),
					'classic' => __('Classic', 'anchorkit-table-of-contents'),
					'modern' => __('Modern', 'anchorkit-table-of-contents'),
				),
				'default' => $defaults['stylePreset'] ?? 'minimal',
				'description' => __('Choose a pre-designed style.', 'anchorkit-table-of-contents'),
			)
		);

		// Theme
		$this->add_control(
			'theme',
			array(
				'label' => __('Theme', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SELECT,
				'options' => array(
					'system' => __('System (auto)', 'anchorkit-table-of-contents'),
					'light' => __('Light', 'anchorkit-table-of-contents'),
					'dark' => __('Dark', 'anchorkit-table-of-contents'),
				),
				'default' => $defaults['theme'] ?? 'system',
				'description' => __('Choose a base theme. "System" follows the visitor preference.', 'anchorkit-table-of-contents'),
			)
		);

		// Border Type
		$this->add_control(
			'border_border',
			array(
				'label' => __('Border Type', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SELECT,
				'options' => array(
					'' => __('None', 'anchorkit-table-of-contents'),
					'solid' => __('Solid', 'anchorkit-table-of-contents'),
					'dashed' => __('Dashed', 'anchorkit-table-of-contents'),
					'dotted' => __('Dotted', 'anchorkit-table-of-contents'),
					'double' => __('Double', 'anchorkit-table-of-contents'),
				),
				'default' => '',
				'selectors' => array(
					'{{WRAPPER}} .anchorkit-toc-container' => 'border-style: {{VALUE}};',
				),
			)
		);

		// Border Width
		$this->add_control(
			'border_width',
			array(
				'label' => __('Border Width', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::DIMENSIONS,
				'size_units' => array('px', 'em', 'rem'),
				'selectors' => array(
					'{{WRAPPER}} .anchorkit-toc-container' => 'border-width: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}};',
				),
				'condition' => array(
					'border_border!' => '',
				),
			)
		);

		// Border Radius
		$this->add_control(
			'border_radius',
			array(
				'label' => __('Border Radius', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::DIMENSIONS,
				'size_units' => array('px', '%', 'em'),
				'selectors' => array(
					'{{WRAPPER}} .anchorkit-toc-container' => 'border-radius: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}} !important;',
				),
			)
		);

		// Padding
		$this->add_control(
			'padding',
			array(
				'label' => __('Padding', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::DIMENSIONS,
				'size_units' => array('px', '%', 'em'),
				'selectors' => array(
					'{{WRAPPER}} .anchorkit-toc-container' => 'padding: {{TOP}}{{UNIT}} {{RIGHT}}{{UNIT}} {{BOTTOM}}{{UNIT}} {{LEFT}}{{UNIT}} !important;',
				),
			)
		);

		$this->add_control(
			'style_section_reset_controls',
			array(
				'type' => Controls_Manager::RAW_HTML,
				'raw' => $this->get_reset_button_markup('style', __('Container Style', 'anchorkit-table-of-contents')),
				'content_classes' => 'anchorkit-el-reset-control',
				'separator' => 'before',
			)
		);

		$this->end_controls_section();

		// ============================================================
		// Custom Styling Overrides
		// ============================================================

		$this->start_controls_section(
			'custom_style_section',
			array(
				'label' => __('Custom Styling', 'anchorkit-table-of-contents'),
				'tab' => Controls_Manager::TAB_STYLE,
			)
		);

		$this->add_control(
			'design_override',
			array(
				'label' => __('Override Global Styling', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SWITCHER,
				'label_on' => __('Yes', 'anchorkit-table-of-contents'),
				'label_off' => __('No', 'anchorkit-table-of-contents'),
				'return_value' => 'yes',
				'default' => '',
				'description' => __('Enable to customize colors, spacing, and shadows per widget. Leave off to inherit the global design.', 'anchorkit-table-of-contents'),
			)
		);

		$light_mode_conditions = array(
			'relation' => 'and',
			'terms' => array(
				array(
					'name' => 'design_override',
					'operator' => '==',
					'value' => 'yes',
				),
				array(
					'name' => 'design_editor_mode',
					'operator' => '==',
					'value' => 'light',
				),
			),
		);
		$dark_mode_conditions = array(
			'relation' => 'and',
			'terms' => array(
				array(
					'name' => 'design_override',
					'operator' => '==',
					'value' => 'yes',
				),
				array(
					'name' => 'design_editor_mode',
					'operator' => '==',
					'value' => 'dark',
				),
			),
		);
		$override_enabled_conditions = array(
			'terms' => array(
				array(
					'name' => 'design_override',
					'operator' => '==',
					'value' => 'yes',
				),
			),
		);

		$this->add_control(
			'design_editor_mode',
			array(
				'label' => __('Editor Preview Mode', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::CHOOSE,
				'options' => array(
					'light' => array(
						'title' => __('Light Mode', 'anchorkit-table-of-contents'),
						'icon' => 'anchorkit-mode-icon--light',
					),
					'dark' => array(
						'title' => __('Dark Mode', 'anchorkit-table-of-contents'),
						'icon' => 'anchorkit-mode-icon--dark',
					),
				),
				'default' => 'light',
				'toggle' => false,
				'description' => __('Switch between Light and Dark to edit each variant. This also updates the preview.', 'anchorkit-table-of-contents'),
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_colors_light_heading',
			array(
				'label' => __('Light Mode Colors', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::HEADING,
				'separator' => 'before',
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_bg_color_light',
			array(
				'label' => __('Background', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::COLOR,
				'default' => $defaults['bgColorLight'] ?? '#ffffff',
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_text_color_light',
			array(
				'label' => __('Text', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::COLOR,
				'default' => $defaults['textColorLight'] ?? '#333333',
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_link_color_light',
			array(
				'label' => __('Link', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::COLOR,
				'default' => $defaults['linkColorLight'] ?? '#0073AA',
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_link_hover_color_light',
			array(
				'label' => __('Link Hover', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::COLOR,
				'default' => $defaults['linkHoverColorLight'] ?? '#005177',
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_border_color_light',
			array(
				'label' => __('Border', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::COLOR,
				'default' => $defaults['borderColorLight'] ?? '#dddddd',
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_bullet_color_light',
			array(
				'label' => __('Bullet', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::COLOR,
				'default' => $defaults['bulletColorLight'] ?? '#0073AA',
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_active_link_color_light',
			array(
				'label' => __('Active Link', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::COLOR,
				'default' => $defaults['activeLinkColorLight'] ?? '#00A0D2',
				'conditions' => $override_enabled_conditions,
			)
		);



		$this->add_control(
			'design_colors_dark_heading',
			array(
				'label' => __('Dark Mode Colors', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::HEADING,
				'separator' => 'before',
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_bg_color_dark',
			array(
				'label' => __('Background', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::COLOR,
				'default' => $defaults['bgColorDark'] ?? '#1e1e1e',
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_text_color_dark',
			array(
				'label' => __('Text', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::COLOR,
				'default' => $defaults['textColorDark'] ?? '#e0e0e0',
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_link_color_dark',
			array(
				'label' => __('Link', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::COLOR,
				'default' => $defaults['linkColorDark'] ?? '#7ec4ee',
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_link_hover_color_dark',
			array(
				'label' => __('Link Hover', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::COLOR,
				'default' => $defaults['linkHoverColorDark'] ?? '#a8d8f0',
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_border_color_dark',
			array(
				'label' => __('Border', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::COLOR,
				'default' => $defaults['borderColorDark'] ?? '#404040',
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_bullet_color_dark',
			array(
				'label' => __('Bullet', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::COLOR,
				'default' => $defaults['bulletColorDark'] ?? '#7ec4ee',
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_active_link_color_dark',
			array(
				'label' => __('Active Link', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::COLOR,
				'default' => $defaults['activeLinkColorDark'] ?? '#5ba3d0',
				'conditions' => $override_enabled_conditions,
			)
		);



		$this->add_control(
			'design_shadow_heading_light',
			array(
				'label' => __('Light Mode Shadow', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::HEADING,
				'separator' => 'before',
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_shadow_h_offset_light',
			array(
				'label' => __('Horizontal Offset (px)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::NUMBER,
				'min' => -100,
				'max' => 100,
				'default' => 0,
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_shadow_v_offset_light',
			array(
				'label' => __('Vertical Offset (px)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::NUMBER,
				'min' => -100,
				'max' => 100,
				'default' => 4,
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_shadow_blur_light',
			array(
				'label' => __('Blur (px)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::NUMBER,
				'min' => 0,
				'max' => 200,
				'default' => 6,
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_shadow_spread_light',
			array(
				'label' => __('Spread (px)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::NUMBER,
				'min' => -50,
				'max' => 50,
				'default' => 0,
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_shadow_color_light',
			array(
				'label' => __('Shadow Color', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::COLOR,
				'default' => '#000000',
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_shadow_opacity_light',
			array(
				'label' => __('Shadow Opacity', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SLIDER,
				'size_units' => array('px'),
				'range' => array(
					'px' => array(
						'min' => 0,
						'max' => 1,
						'step' => 0.05,
					),
				),
				'default' => array(
					'unit' => 'px',
					'size' => 0.1,
				),
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_shadow_heading_dark',
			array(
				'label' => __('Dark Mode Shadow', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::HEADING,
				'separator' => 'before',
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_shadow_h_offset_dark',
			array(
				'label' => __('Horizontal Offset (px)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::NUMBER,
				'min' => -100,
				'max' => 100,
				'default' => 0,
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_shadow_v_offset_dark',
			array(
				'label' => __('Vertical Offset (px)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::NUMBER,
				'min' => -100,
				'max' => 100,
				'default' => 2,
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_shadow_blur_dark',
			array(
				'label' => __('Blur (px)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::NUMBER,
				'min' => 0,
				'max' => 200,
				'default' => 8,
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_shadow_spread_dark',
			array(
				'label' => __('Spread (px)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::NUMBER,
				'min' => -50,
				'max' => 50,
				'default' => 0,
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_shadow_color_dark',
			array(
				'label' => __('Shadow Color', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::COLOR,
				'default' => '#000000',
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'design_shadow_opacity_dark',
			array(
				'label' => __('Shadow Opacity', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SLIDER,
				'size_units' => array('px'),
				'range' => array(
					'px' => array(
						'min' => 0,
						'max' => 1,
						'step' => 0.05,
					),
				),
				'default' => array(
					'unit' => 'px',
					'size' => 0.3,
				),
				'conditions' => $override_enabled_conditions,
			)
		);

		$this->add_control(
			'custom_style_reset_controls',
			array(
				'type' => Controls_Manager::RAW_HTML,
				'raw' => $this->get_reset_button_markup('custom_style', __('Custom Styling', 'anchorkit-table-of-contents')),
				'content_classes' => 'anchorkit-el-reset-control',
				'separator' => 'before',
			)
		);

		$this->end_controls_section();

		// ============================================================
		// STYLE TAB - Typography
		// ============================================================

		$this->start_controls_section(
			'typography_section',
			array(
				'label' => __('Typography', 'anchorkit-table-of-contents'),
				'tab' => Controls_Manager::TAB_STYLE,
			)
		);

		// Title Typography
		$this->add_group_control(
			Group_Control_Typography::get_type(),
			array(
				'name' => 'title_typography',
				'label' => __('Title Typography', 'anchorkit-table-of-contents'),
				'selector' => '{{WRAPPER}} .anchorkit-toc-title',
				'exclude' => array('line_height', 'letter_spacing', 'word_spacing', 'font_size'), // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude -- Elementor control config, not a WP_Query parameter.
				'fields_options' => array(
					'typography' => array(
						'default' => '',
					),
					'font_family' => array(
						'selectors' => array(
							'{{WRAPPER}} .anchorkit-toc-title' => 'font-family: {{VALUE}} !important;',
						),
					),
					'font_weight' => array(
						'selectors' => array(
							'{{WRAPPER}} .anchorkit-toc-title' => 'font-weight: {{VALUE}} !important;',
						),
					),
					'text_transform' => array(
						'selectors' => array(
							'{{WRAPPER}} .anchorkit-toc-title' => 'text-transform: {{VALUE}} !important;',
						),
					),
					'font_style' => array(
						'selectors' => array(
							'{{WRAPPER}} .anchorkit-toc-title' => 'font-style: {{VALUE}} !important;',
						),
					),
					'text_decoration' => array(
						'selectors' => array(
							'{{WRAPPER}} .anchorkit-toc-title' => 'text-decoration: {{VALUE}} !important;',
						),
					),
				),
			)
		);

		// Link Typography
		$this->add_group_control(
			Group_Control_Typography::get_type(),
			array(
				'name' => 'link_typography',
				'label' => __('Link Typography', 'anchorkit-table-of-contents'),
				'selector' => '{{WRAPPER}} .anchorkit-toc-link',
				'separator' => 'before',
				'exclude' => array('line_height', 'letter_spacing', 'word_spacing', 'text_decoration', 'font_size'), // phpcs:ignore WordPressVIPMinimum.Performance.WPQueryParams.PostNotIn_exclude -- Elementor control config, not a WP_Query parameter.
				'fields_options' => array(
					'typography' => array(
						'default' => '',
					),
					'font_family' => array(
						'selectors' => array(
							'{{WRAPPER}} .anchorkit-toc-link' => 'font-family: {{VALUE}} !important;',
						),
					),
					'font_weight' => array(
						'selectors' => array(
							'{{WRAPPER}} .anchorkit-toc-link' => 'font-weight: {{VALUE}} !important;',
						),
					),
					'text_transform' => array(
						'selectors' => array(
							'{{WRAPPER}} .anchorkit-toc-link' => 'text-transform: {{VALUE}} !important;',
						),
					),
					'font_style' => array(
						'selectors' => array(
							'{{WRAPPER}} .anchorkit-toc-link' => 'font-style: {{VALUE}} !important;',
						),
					),
					'text_decoration' => array(
						'selectors' => array(
							'{{WRAPPER}} .anchorkit-toc-link' => 'text-decoration: {{VALUE}} !important;',
						),
					),
				),
			)
		);

		$this->add_control(
			'typography_heading_levels_separator',
			array(
				'type' => Controls_Manager::DIVIDER,
				'style' => 'thick',
			)
		);

		// Advanced Typography Override Toggle
		$this->add_control(
			'advanced_typography_override',
			array(
				'label' => __('Override Base Font Size', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SWITCHER,
				'label_on' => __('Yes', 'anchorkit-table-of-contents'),
				'label_off' => __('No', 'anchorkit-table-of-contents'),
				'return_value' => 'yes',
				'default' => $switcher_default($defaults['advancedTypographyOverride'] ?? false),
				'description' => __('Enable to set custom font sizes for each heading level', 'anchorkit-table-of-contents'),
			)
		);

		// Title Font Size
		$this->add_control(
			'title_font_size',
			array(
				'label' => __('Title Font Size (px)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SLIDER,
				'size_units' => array('px'),
				'range' => array(
					'px' => array(
						'min' => 12,
						'max' => 32,
						'step' => 1,
					),
				),
				'default' => array(
					'unit' => 'px',
					'size' => $defaults['titleFontSize'] ?? 20,
				),
				'condition' => array(
					'advanced_typography_override' => 'yes',
				),
				'selectors' => array(
					'{{WRAPPER}} .anchorkit-toc-container .anchorkit-toc-title' => 'font-size: {{SIZE}}{{UNIT}} !important;',
				),
			)
		);

		// H2 Font Size
		$this->add_control(
			'h2_font_size',
			array(
				'label' => __('H2 Items Font Size (px)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SLIDER,
				'size_units' => array('px'),
				'range' => array(
					'px' => array(
						'min' => 10,
						'max' => 24,
						'step' => 1,
					),
				),
				'default' => array(
					'unit' => 'px',
					'size' => $defaults['h2FontSize'] ?? 18,
				),
				'condition' => array(
					'advanced_typography_override' => 'yes',
				),
				'selectors' => array(
					'{{WRAPPER}} .anchorkit-toc-container .anchorkit-toc-heading-level-2 > .anchorkit-toc-link' => 'font-size: {{SIZE}}{{UNIT}} !important;',
				),
			)
		);

		// H3 Font Size
		$this->add_control(
			'h3_font_size',
			array(
				'label' => __('H3 Items Font Size (px)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SLIDER,
				'size_units' => array('px'),
				'range' => array(
					'px' => array(
						'min' => 10,
						'max' => 24,
						'step' => 1,
					),
				),
				'default' => array(
					'unit' => 'px',
					'size' => $defaults['h3FontSize'] ?? 16,
				),
				'condition' => array(
					'advanced_typography_override' => 'yes',
				),
				'selectors' => array(
					'{{WRAPPER}} .anchorkit-toc-container .anchorkit-toc-heading-level-3 > .anchorkit-toc-link' => 'font-size: {{SIZE}}{{UNIT}} !important;',
				),
			)
		);

		// H4 Font Size
		$this->add_control(
			'h4_font_size',
			array(
				'label' => __('H4 Items Font Size (px)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SLIDER,
				'size_units' => array('px'),
				'range' => array(
					'px' => array(
						'min' => 10,
						'max' => 24,
						'step' => 1,
					),
				),
				'default' => array(
					'unit' => 'px',
					'size' => $defaults['h4FontSize'] ?? 14,
				),
				'condition' => array(
					'advanced_typography_override' => 'yes',
				),
				'selectors' => array(
					'{{WRAPPER}} .anchorkit-toc-container .anchorkit-toc-heading-level-4 > .anchorkit-toc-link' => 'font-size: {{SIZE}}{{UNIT}} !important;',
				),
			)
		);

		// H5 Font Size
		$this->add_control(
			'h5_font_size',
			array(
				'label' => __('H5 Items Font Size (px)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SLIDER,
				'size_units' => array('px'),
				'range' => array(
					'px' => array(
						'min' => 10,
						'max' => 24,
						'step' => 1,
					),
				),
				'default' => array(
					'unit' => 'px',
					'size' => $defaults['h5FontSize'] ?? 13,
				),
				'condition' => array(
					'advanced_typography_override' => 'yes',
				),
				'selectors' => array(
					'{{WRAPPER}} .anchorkit-toc-container .anchorkit-toc-heading-level-5 > .anchorkit-toc-link' => 'font-size: {{SIZE}}{{UNIT}} !important;',
				),
			)
		);

		// H6 Font Size
		$this->add_control(
			'h6_font_size',
			array(
				'label' => __('H6 Items Font Size (px)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SLIDER,
				'size_units' => array('px'),
				'range' => array(
					'px' => array(
						'min' => 10,
						'max' => 24,
						'step' => 1,
					),
				),
				'default' => array(
					'unit' => 'px',
					'size' => $defaults['h6FontSize'] ?? 12,
				),
				'condition' => array(
					'advanced_typography_override' => 'yes',
				),
				'selectors' => array(
					'{{WRAPPER}} .anchorkit-toc-container .anchorkit-toc-heading-level-6 > .anchorkit-toc-link' => 'font-size: {{SIZE}}{{UNIT}} !important;',
				),
			)
		);

		// Line Height
		$this->add_control(
			'line_height',
			array(
				'label' => __('Line Height', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::NUMBER,
				'default' => $defaults['lineHeight'] ?? 1.6,
				'min' => 1.0,
				'max' => 3.0,
				'step' => 0.1,
				'description' => __('Controls vertical spacing for multi-line TOC entries. Range: 1.0 - 3.0', 'anchorkit-table-of-contents'),
			)
		);

		// Letter Spacing
		$this->add_control(
			'letter_spacing',
			array(
				'label' => __('Letter Spacing (px)', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::NUMBER,
				'default' => $defaults['letterSpacing'] ?? 0,
				'min' => -2,
				'max' => 5,
				'step' => 0.1,
				'description' => __('Add or reduce spacing between letters in TOC links.', 'anchorkit-table-of-contents'),
			)
		);

		// Text Transform
		$this->add_control(
			'text_transform',
			array(
				'label' => __('Text Transform', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SELECT,
				'options' => array(
					'none' => __('None', 'anchorkit-table-of-contents'),
					'uppercase' => __('UPPERCASE', 'anchorkit-table-of-contents'),
					'lowercase' => __('lowercase', 'anchorkit-table-of-contents'),
					'capitalize' => __('Capitalize Each Word', 'anchorkit-table-of-contents'),
				),
				'default' => $defaults['textTransform'] ?? 'none',
				'description' => __('Control casing for TOC item labels.', 'anchorkit-table-of-contents'),
			)
		);

		// Link Underline
		$this->add_control(
			'link_underline',
			array(
				'label' => __('Link Underline', 'anchorkit-table-of-contents'),
				'type' => Controls_Manager::SELECT,
				'options' => array(
					'none' => __('None', 'anchorkit-table-of-contents'),
					'always' => __('Always Underlined', 'anchorkit-table-of-contents'),
					'hover' => __('Underline on Hover', 'anchorkit-table-of-contents'),
					'hover_none' => __('No Underline on Hover', 'anchorkit-table-of-contents'),
				),
				'default' => $defaults['linkUnderline'] ?? 'none',
				'description' => __('Choose when to display underlines on TOC links.', 'anchorkit-table-of-contents'),
			)
		);

		$this->add_control(
			'typography_reset_controls',
			array(
				'type' => Controls_Manager::RAW_HTML,
				'raw' => $this->get_reset_button_markup('typography', __('Typography', 'anchorkit-table-of-contents')),
				'content_classes' => 'anchorkit-el-reset-control',
				'separator' => 'before',
			)
		);

		$this->end_controls_section();
	}

	/**
	 * Render widget output on the frontend
	 */
	protected function render()
	{
		// Check if user has pro access - this block is stripped by Freemius in free version
		if (anchorkit_fs() && anchorkit_fs()->is__premium_only()) {
			if (!anchorkit_fs()->can_use_premium_code()) {
				return;
			}
		}

		$settings = $this->get_settings_for_display();
		$defaults = $this->get_toc_defaults();
		$elementor_instance = class_exists('\Elementor\Plugin') ? \Elementor\Plugin::$instance : null;
		$is_edit_mode = $elementor_instance && isset($elementor_instance->editor) && is_object($elementor_instance->editor) && method_exists($elementor_instance->editor, 'is_edit_mode')
			? $elementor_instance->editor->is_edit_mode()
			: false;
		$is_preview_mode = $elementor_instance && isset($elementor_instance->preview) && is_object($elementor_instance->preview) && method_exists($elementor_instance->preview, 'is_preview_mode')
			? $elementor_instance->preview->is_preview_mode()
			: false;
		$rendering_in_editor = $is_edit_mode || $is_preview_mode;
		/**
		 * Helper to check if a setting value was explicitly set at the widget level.
		 * Returns true only if the key exists in $settings (even if value is empty/null).
		 * This distinguishes between "user set this field" vs "field never touched".
		 */
		$is_explicitly_set = static function ($field_name) use ($settings) {
			return array_key_exists($field_name, $settings);
		};

		/**
		 * Convert Elementor switcher/boolean values to PHP boolean.
		 * IMPORTANT: This function only interprets the value when it's explicitly set.
		 * Caller must check $is_explicitly_set() first to determine if fallback to default is needed.
		 */
		$bool_from_setting = static function ($value, $default = false) {
			// Elementor switchers return 'yes' when on, '' when off. Treat any empty string/falsey (except null) as explicit off.
			if ($value === 'yes' || $value === true || $value === 1 || $value === '1') {
				return true;
			}
			if ($value === 'no' || $value === false || $value === 0 || $value === '0' || $value === '') {
				return false;
			}
			if ($value === null) {
				return (bool) $default;
			}
			return (bool) $value;
		};
		$slider_value = static function ($value, $default) {
			if (is_array($value) && isset($value['size']) && $value['size'] !== '') {
				return is_numeric($value['size']) ? (float) $value['size'] : $default;
			}
			if (is_numeric($value)) {
				return (float) $value;
			}
			return $default;
		};

		// For boolean fields, only use defaults when field was never set by user
		// If user explicitly toggled a field (even to OFF), use that value instead of global default
		$acf_enabled = $is_explicitly_set('acf_enabled')
			? $bool_from_setting($settings['acf_enabled'], false)
			: ($defaults['acfEnabled'] ?? false);
		$amp_enabled = $is_explicitly_set('amp_enabled')
			? $bool_from_setting($settings['amp_enabled'], false)
			: ($defaults['ampEnabled'] ?? false);
		$sticky_enabled = $is_explicitly_set('sticky')
			? $bool_from_setting($settings['sticky'], false)
			: ($defaults['sticky'] ?? false);
		$view_more_enabled = $is_explicitly_set('view_more_enabled')
			? $bool_from_setting($settings['view_more_enabled'], false)
			: ($defaults['viewMoreEnabled'] ?? false);
		$entrance_animation = $is_explicitly_set('entrance_animation')
			? $bool_from_setting($settings['entrance_animation'], false)
			: ($defaults['entranceAnimation'] ?? false);
		$show_numerals = $is_explicitly_set('show_numerals')
			? $bool_from_setting($settings['show_numerals'], false)
			: ($defaults['showNumerals'] ?? false);
		$show_reading_time = $is_explicitly_set('show_reading_time')
			? $bool_from_setting($settings['show_reading_time'], false)
			: ($defaults['showReadingTime'] ?? false);
		$show_word_count = $is_explicitly_set('show_word_count')
			? $bool_from_setting($settings['show_word_count'], false)
			: ($defaults['showWordCount'] ?? false);
		$advanced_typography = $is_explicitly_set('advanced_typography_override')
			? $bool_from_setting($settings['advanced_typography_override'], false)
			: ($defaults['advancedTypographyOverride'] ?? false);
		$back_to_top = $is_explicitly_set('back_to_top_link')
			? $bool_from_setting($settings['back_to_top_link'], false)
			: ($defaults['backToTopLink'] ?? false);
		$schema_enabled = $is_explicitly_set('schema_enabled')
			? $bool_from_setting($settings['schema_enabled'], false)
			: ($defaults['schemaEnabled'] ?? false);
		$design_override_val = $settings['design_override'] ?? '';
		// Check for multiple "truthy" values as Elementor/DB might store it differently
		$design_override_enabled = $design_override_val === 'yes' || $design_override_val === '1' || $design_override_val === true;

		// REMOVED: $use_global_custom_style logic - widgets with their own design_override OFF
		// should NOT inherit global custom styling. They should use preset styling only.
		$theme_setting = $settings['theme'] ?? ($defaults['theme'] ?? 'system');

		// Separate theme for rendering preview vs data persistence
		$theme_setting_for_render = $theme_setting;
		if ($rendering_in_editor && $design_override_enabled) {
			$editor_mode_theme = $settings['design_editor_mode'] ?? '';
			if ($editor_mode_theme === 'light' || $editor_mode_theme === 'dark') {
				// CRITICAL: Only change the preview theme, NOT the data theme
				// This ensures both colors are saved while preview shows the correct mode
				$theme_setting_for_render = $editor_mode_theme;
			}
		}
		$sanitize_color = static function ($value) {
			if (!is_string($value) || $value === '') {
				return '';
			}
			$color = sanitize_hex_color($value);
			if ($color) {
				return $color;
			}
			if (preg_match('/^[0-9a-fA-F]{6}$/', $value)) {
				$candidate = '#' . strtolower($value);
				$color = sanitize_hex_color($candidate);
				if ($color) {
					return $color;
				}
			}
			return '';
		};
		$slider_simple_value = static function ($value, $default = 0) {
			if (is_array($value) && isset($value['size']) && $value['size'] !== '') {
				return (float) $value['size'];
			}
			if ($value === '' || $value === null) {
				return $default;
			}
			return is_numeric($value) ? (float) $value : $default;
		};
		$clamp_number = static function ($value, $min = 0, $max = null) {
			if ($value === '' || $value === null) {
				return null;
			}
			if (!is_numeric($value)) {
				return null;
			}
			$number = (float) $value;
			if ($max !== null && $number > $max) {
				$number = $max;
			}
			if ($number < $min) {
				$number = $min;
			}
			return $number;
		};
		$color_token_map = array(
			'bg_color' => '--anchorkit-toc-bg',
			'text_color' => '--anchorkit-toc-text-color',
			'link_color' => '--anchorkit-toc-link-color',
			'link_hover_color' => '--anchorkit-toc-link-hover-color',
			'border_color' => '--anchorkit-toc-border-color',
			'bullet_color' => '--anchorkit-toc-bullet-color',
			'active_link_color' => '--anchorkit-toc-active-link-color',
		);

		$shadow_defaults = array(
			'light' => array(
				'h' => 0,
				'v' => 4,
				'blur' => 6,
				'spread' => 0,
				'color' => '#000000',
				'opacity' => 0.1,
			),
			'dark' => array(
				'h' => 0,
				'v' => 2,
				'blur' => 8,
				'spread' => 0,
				'color' => '#000000',
				'opacity' => 0.3,
			),
		);
		$hex_to_rgb = static function ($hex) {
			$hex = trim((string) $hex);
			if ($hex === '') {
				return array(0, 0, 0);
			}
			$hex = ltrim($hex, '#');
			if (strlen($hex) === 3) {
				return array(
					hexdec(str_repeat($hex[0], 2)),
					hexdec(str_repeat($hex[1], 2)),
					hexdec(str_repeat($hex[2], 2)),
				);
			}
			if (strlen($hex) === 6) {
				return array(
					hexdec(substr($hex, 0, 2)),
					hexdec(substr($hex, 2, 2)),
					hexdec(substr($hex, 4, 2)),
				);
			}
			return array(0, 0, 0);
		};
		$build_box_shadow = static function ($settings, $variant, $shadow_defaults, $sanitize_color, $slider_simple_value, $hex_to_rgb) {
			$suffix = $variant === 'dark' ? '_dark' : '_light';
			$defaults = $shadow_defaults[$variant];
			$h = $settings['design_shadow_h_offset' . $suffix] ?? $defaults['h'];
			$v = $settings['design_shadow_v_offset' . $suffix] ?? $defaults['v'];
			$blur = $settings['design_shadow_blur' . $suffix] ?? $defaults['blur'];
			$spread = $settings['design_shadow_spread' . $suffix] ?? $defaults['spread'];
			// CRITICAL FIX: Use explicit empty check, not just null coalescing.
			// Elementor sends empty strings for unset color values, which ?? doesn't handle.
			$color_setting = isset($settings['design_shadow_color' . $suffix]) && $settings['design_shadow_color' . $suffix] !== ''
				? $settings['design_shadow_color' . $suffix]
				: $defaults['color'];
			$color = $sanitize_color($color_setting);
			$opacity = $slider_simple_value($settings['design_shadow_opacity' . $suffix] ?? $defaults['opacity'], $defaults['opacity']);
			// Use default color if sanitization failed
			if ($color === '') {
				$color = $defaults['color'];
			}
			$rgb = $hex_to_rgb($color);
			$result = sprintf(
				'%1$spx %2$spx %3$spx %4$spx rgba(%5$d, %6$d, %7$d, %8$.3f)',
				(float) $h,
				(float) $v,
				(float) $blur,
				(float) $spread,
				$rgb[0],
				$rgb[1],
				$rgb[2],
				max(0, min(1, (float) $opacity))
			);
			return $result;
		};
		$design_tokens_light = array();
		$design_tokens_dark = array();
		$container_padding_override = null;
		$container_border_width_override = null;
		$container_border_radius_override = null;
		$box_shadow_light = '';
		$box_shadow_dark = '';
		if ($design_override_enabled) {
			foreach ($color_token_map as $key => $token) {
				$field_light = 'design_' . $key . '_light';
				$field_dark = 'design_' . $key . '_dark';
				if (!empty($settings[$field_light])) {
					$color = $sanitize_color($settings[$field_light]);
					if ($color !== '') {
						$design_tokens_light[$token] = $color;
					}
				}
				if (!empty($settings[$field_dark])) {
					$color = $sanitize_color($settings[$field_dark]);
					if ($color !== '') {
						$design_tokens_dark[$token] = $color;
					}
				}
			}
			// CRITICAL: Only set container overrides when user EXPLICITLY sets them to NON-ZERO values.
			// Do NOT fall back to $defaults - that would trigger $has_container_overrides in
			// elementor.php, adding .anchorkit-toc-custom-styling class which applies font-size
			// from CSS variables and overrides preset font sizes.
			//
			// IMPORTANT: Check that value is meaningful (not empty/null/0).
			// When Elementor shows these controls (because design override is ON), it may send 0 as
			// default value, which should NOT trigger custom-styling class.
			$container_padding_override = (array_key_exists('design_padding', $settings) && $settings['design_padding'] !== '' && $settings['design_padding'] !== null && $settings['design_padding'] > 0)
				? $clamp_number($settings['design_padding'], 0)
				: null;
			$container_border_width_override = (array_key_exists('design_border_width', $settings) && $settings['design_border_width'] !== '' && $settings['design_border_width'] !== null && $settings['design_border_width'] > 0)
				? $clamp_number($settings['design_border_width'], 0)
				: null;
			$container_border_radius_override = (array_key_exists('design_border_radius', $settings) && $settings['design_border_radius'] !== '' && $settings['design_border_radius'] !== null && $settings['design_border_radius'] > 0)
				? $clamp_number($settings['design_border_radius'], 0)
				: null;
			// Build box shadows when design override is enabled.
			// The $build_box_shadow function uses $shadow_defaults as fallbacks for values
			// not explicitly set by the user, so shadows will always be generated with
			// sensible defaults (e.g., black color with appropriate opacity).
			$box_shadow_light = $build_box_shadow($settings, 'light', $shadow_defaults, $sanitize_color, $slider_simple_value, $hex_to_rgb);
			$box_shadow_dark = $build_box_shadow($settings, 'dark', $shadow_defaults, $sanitize_color, $slider_simple_value, $hex_to_rgb);
		}
		// REMOVED: The elseif ($use_global_custom_style) branch that inherited global custom styling.
		// Widgets with design_override OFF should use preset styling from CSS, not global custom colors.

		// If no widget-specific box shadow was set, check for global box shadow setting.
		// Box shadow can be enabled globally via anchorkit_toc_box_shadow_enabled independently
		// from the "Custom Styling" option, so we need to check for it separately.
		if (empty($box_shadow_light) && empty($box_shadow_dark)) {
			if (function_exists('anchorkit_get_option') && anchorkit_get_option('anchorkit_toc_box_shadow_enabled', false)) {
				if (function_exists('anchorkit_collect_toc_tokens')) {
					$global_tokens = anchorkit_collect_toc_tokens();
					$light_tokens = isset($global_tokens['light']) ? $global_tokens['light'] : array();
					$dark_tokens = isset($global_tokens['dark']) ? $global_tokens['dark'] : array();

					if (isset($light_tokens['--anchorkit-toc-shadow-light'])) {
						$box_shadow_light = $light_tokens['--anchorkit-toc-shadow-light'];
					}
					if (isset($dark_tokens['--anchorkit-toc-shadow-dark'])) {
						$box_shadow_dark = $dark_tokens['--anchorkit-toc-shadow-dark'];
					}
				}
			}
		}

		$scroll_easing_value = isset($settings['scroll_easing']) && $settings['scroll_easing'] !== '' ? $settings['scroll_easing'] : ($defaults['scrollEasing'] ?? 'ease-in-out');
		$scroll_duration_value = isset($settings['scroll_duration']) && $settings['scroll_duration'] !== '' ? (int) $settings['scroll_duration'] : ($defaults['scrollDuration'] ?? 500);

		// Process font sizes from slider controls
		$title_font_size_processed = $slider_value($settings['title_font_size'] ?? null, $defaults['titleFontSize'] ?? 20);
		$h2_font_size_processed = $slider_value($settings['h2_font_size'] ?? null, $defaults['h2FontSize'] ?? 18);
		$h3_font_size_processed = $slider_value($settings['h3_font_size'] ?? null, $defaults['h3FontSize'] ?? 16);
		$h4_font_size_processed = $slider_value($settings['h4_font_size'] ?? null, $defaults['h4FontSize'] ?? 14);
		$h5_font_size_processed = $slider_value($settings['h5_font_size'] ?? null, $defaults['h5FontSize'] ?? 13);
		$h6_font_size_processed = $slider_value($settings['h6_font_size'] ?? null, $defaults['h6FontSize'] ?? 12);

		// Build settings array to pass to TOC generator
		// CRITICAL: For each field, check if it was explicitly set at widget level.
		// Only fall back to global defaults when field was never touched by user.
		$toc_settings = array(
			'context' => 'elementor',
			// Content settings
			'title' => $is_explicitly_set('toc_title') && $settings['toc_title'] !== ''
				? $settings['toc_title']
				: ($defaults['title'] ?? 'Table of Contents'),
			'show_title' => $is_explicitly_set('show_title')
				? $bool_from_setting($settings['show_title'], true)
				: ($defaults['showTitle'] ?? true),
			'heading_levels' => $is_explicitly_set('heading_levels') && !empty($settings['heading_levels'])
				? $settings['heading_levels']
				: ($defaults['headingLevels'] ?? array('h2', 'h3', 'h4')),
			'min_headings' => $is_explicitly_set('min_headings') && $settings['min_headings'] !== ''
				? (int) $settings['min_headings']
				: ($defaults['minHeadingsToShow'] ?? 2),
			'exclude_selectors' => $is_explicitly_set('exclude_selectors')
				? $settings['exclude_selectors']
				: ($defaults['excludeSelectors'] ?? ''),
			'aria_label' => $is_explicitly_set('aria_label') && $settings['aria_label'] !== ''
				? $settings['aria_label']
				: ($defaults['ariaLabel'] ?? ''),
			'custom_css_class' => $is_explicitly_set('custom_css_class')
				? $settings['custom_css_class']
				: ($defaults['customCssClass'] ?? ''),
			'custom_id' => $is_explicitly_set('custom_id') && !empty($settings['custom_id'])
				? $settings['custom_id']
				: '',
			'custom_labels' => $is_explicitly_set('custom_labels')
				? $settings['custom_labels']
				: ($defaults['customLabels'] ?? ''),
			'anchor_format' => $is_explicitly_set('anchor_format')
				? $settings['anchor_format']
				: ($defaults['anchorFormat'] ?? 'auto'),
			'anchor_prefix' => $is_explicitly_set('anchor_prefix')
				? $settings['anchor_prefix']
				: ($defaults['anchorPrefix'] ?? 'section'),
			'acf_enabled' => $acf_enabled,
			// CRITICAL FIX: Use isset instead of !empty so empty string overrides defaults
			// When user clears ACF field names, we want empty string (no ACF), not fallback to global settings
			'acf_field_names' => $is_explicitly_set('acf_field_names')
				? $settings['acf_field_names']
				: (!empty($defaults['acfFieldNames']) ? $defaults['acfFieldNames'] : null),
			'acf_merge_mode' => $is_explicitly_set('acf_merge_mode') && !empty($settings['acf_merge_mode'])
				? $settings['acf_merge_mode']
				: ($defaults['acfMergeMode'] ?? 'after'),
			'amp_enabled' => $amp_enabled,

			// Behavior settings
			'hierarchical' => $is_explicitly_set('hierarchical')
				? $bool_from_setting($settings['hierarchical'], true)
				: ($defaults['hierarchicalView'] ?? true),
			'collapsible' => $is_explicitly_set('collapsible')
				? $bool_from_setting($settings['collapsible'], true)
				: ($defaults['collapsible'] ?? true),
			'initial_state' => $is_explicitly_set('initial_state')
				? $settings['initial_state']
				: ($defaults['initialState'] ?? 'expanded'),
			'smooth_scroll' => $is_explicitly_set('smooth_scroll')
				? $bool_from_setting($settings['smooth_scroll'], true)
				: ($defaults['smoothScroll'] ?? true),
			'scroll_offset' => $is_explicitly_set('scroll_offset')
				? (int) $slider_value($settings['scroll_offset'], 0)
				: ($defaults['scrollOffset'] ?? 0),
			'scroll_easing' => $scroll_easing_value,
			'scroll_duration' => max(0, (int) $scroll_duration_value),
			'scroll_spy' => $is_explicitly_set('scroll_spy')
				? $bool_from_setting($settings['scroll_spy'], false)
				: ($defaults['scrollSpy'] ?? false),
			'hide_on_mobile' => $is_explicitly_set('hide_on_mobile')
				? $bool_from_setting($settings['hide_on_mobile'], false)
				: ($defaults['hideOnMobile'] ?? false),
			'mobile_breakpoint' => $is_explicitly_set('mobile_breakpoint') && $settings['mobile_breakpoint'] !== ''
				? (int) $settings['mobile_breakpoint']
				: ($defaults['mobileBreakpoint'] ?? 782),
			'toc_width' => $is_explicitly_set('toc_width')
				? (int) $slider_value($settings['toc_width'], 100)
				: ($defaults['tocWidth'] ?? 100),

			'alignment' => $is_explicitly_set('alignment')
				? $settings['alignment']
				: ($defaults['tocAlignment'] ?? 'center'),
			'float' => 'none',

			// Style settings
			'style_preset' => $is_explicitly_set('style_preset')
				? $settings['style_preset']
				: ($defaults['stylePreset'] ?? 'minimal'),
			'theme' => isset($theme_setting_for_render) ? $theme_setting_for_render : ($theme_setting ?? ($settings['theme'] ?? ($defaults['theme'] ?? 'system'))),

			// Advanced features - Sticky
			'sticky' => $sticky_enabled,
			'sticky_position' => $is_explicitly_set('sticky_position')
				? $settings['sticky_position']
				: ($defaults['stickyPosition'] ?? 'content'),
			'sticky_offset' => $is_explicitly_set('sticky_offset')
				? (int) $slider_value($settings['sticky_offset'], 20)
				: ($defaults['stickyOffset'] ?? 20),

			// Advanced features - View More
			'view_more_enabled' => $view_more_enabled,
			'initial_count' => $is_explicitly_set('initial_count') && $settings['initial_count'] !== ''
				? (int) $settings['initial_count']
				: ($defaults['viewMoreInitialCount'] ?? 5),
			'view_more_text' => $is_explicitly_set('view_more_text') && $settings['view_more_text'] !== ''
				? $settings['view_more_text']
				: ($defaults['viewMoreText'] ?? 'View More'),
			'view_less_text' => $is_explicitly_set('view_less_text') && $settings['view_less_text'] !== ''
				? $settings['view_less_text']
				: ($defaults['viewLessText'] ?? 'View Less'),

			// Advanced features - Animations
			'entrance_animation' => $entrance_animation,
			'animation_type' => $is_explicitly_set('animation_type')
				? $settings['animation_type']
				: ($defaults['animationType'] ?? 'fade'),

			// Advanced features - Bullets & Numbering
			'bullet_style' => $is_explicitly_set('bullet_style')
				? $settings['bullet_style']
				: ($defaults['bulletStyle'] ?? 'disc'),
			'bullet_character' => $is_explicitly_set('bullet_character')
				? $settings['bullet_character']
				: ($defaults['bulletCharacter'] ?? '•'),
			'bullet_color' => $is_explicitly_set('bullet_color')
				? $settings['bullet_color']
				: '',
			// Bullet colors now use global theme-aware settings (bullet_color_light/dark)
			'show_numerals' => $show_numerals,
			'numbering_style' => $is_explicitly_set('numbering_style')
				? $settings['numbering_style']
				: ($defaults['numberingStyle'] ?? 'hierarchical'),
			'numbering_format' => $is_explicitly_set('numbering_format')
				? $settings['numbering_format']
				: ($defaults['numberingFormat'] ?? 'decimal'),
			'numbering_separator' => $is_explicitly_set('numbering_separator')
				? $settings['numbering_separator']
				: ($defaults['numberingSeparator'] ?? '.'),

			// Advanced features - Advanced Filtering
			'exclude_keywords' => $is_explicitly_set('exclude_keywords')
				? $settings['exclude_keywords']
				: ($defaults['excludeKeywords'] ?? ''),
			'exclude_regex' => $is_explicitly_set('exclude_regex')
				? $settings['exclude_regex']
				: ($defaults['excludeRegex'] ?? ''),
			// Hardcode depth to full range (1-6) so "Include Heading Levels" is the only filter
			'min_heading_depth' => 1,
			'max_heading_depth' => 6,

			// Advanced features - Reading Time
			'show_reading_time' => $show_reading_time,
			'reading_speed' => $is_explicitly_set('reading_speed') && $settings['reading_speed'] !== ''
				? (int) $settings['reading_speed']
				: ($defaults['readingSpeed'] ?? 200),
			'show_word_count' => $show_word_count,
			'time_format' => $is_explicitly_set('time_format')
				? $settings['time_format']
				: ($defaults['timeFormat'] ?? 'min_read'),

			// Advanced features - Advanced Typography
			'advanced_typography_override' => $advanced_typography,
			'title_font_size' => $title_font_size_processed,
			'h2_font_size' => $h2_font_size_processed,
			'h3_font_size' => $h3_font_size_processed,
			'h4_font_size' => $h4_font_size_processed,
			'h5_font_size' => $h5_font_size_processed,
			'h6_font_size' => $h6_font_size_processed,
			'line_height' => $is_explicitly_set('line_height') && $settings['line_height'] !== ''
				? (float) $settings['line_height']
				: ($defaults['lineHeight'] ?? 1.6),
			'letter_spacing' => $is_explicitly_set('letter_spacing') && $settings['letter_spacing'] !== ''
				? (float) $settings['letter_spacing']
				: ($defaults['letterSpacing'] ?? 0),
			'text_transform' => $is_explicitly_set('text_transform')
				? $settings['text_transform']
				: ($defaults['textTransform'] ?? 'none'),
			'link_underline' => $is_explicitly_set('link_underline')
				? $settings['link_underline']
				: ($defaults['linkUnderline'] ?? 'none'),

			// Advanced features - Back to Top
			'back_to_top_link' => $back_to_top,
			'back_to_top_text' => $is_explicitly_set('back_to_top_text') && $settings['back_to_top_text'] !== ''
				? $settings['back_to_top_text']
				: ($defaults['backToTopText'] ?? 'Back to Top'),
			'back_to_top_font_size' => $is_explicitly_set('back_to_top_font_size') && $settings['back_to_top_font_size'] !== ''
				? (int) $settings['back_to_top_font_size']
				: ($defaults['backToTopFontSize'] ?? 14),

			// Advanced features - Schema
			'schema_enabled' => $schema_enabled,
			'schema_type' => $is_explicitly_set('schema_type')
				? $settings['schema_type']
				: ($defaults['schemaType'] ?? 'Article'),
		);
		// Only set design_override when the user explicitly enabled it for this widget
		if ($design_override_enabled) {
			$toc_settings['design_override'] = true;
		}
		if (!empty($design_tokens_light)) {
			$toc_settings['override_tokens_light'] = $design_tokens_light;
		}
		if (!empty($design_tokens_dark)) {
			$toc_settings['override_tokens_dark'] = $design_tokens_dark;
		}
		if ($container_padding_override !== null) {
			$toc_settings['container_padding'] = (int) $container_padding_override;
		}
		if ($container_border_width_override !== null) {
			$toc_settings['container_border_width'] = (int) $container_border_width_override;
		}
		if ($container_border_radius_override !== null) {
			$toc_settings['container_border_radius'] = (int) $container_border_radius_override;
		}
		if (!empty($box_shadow_light)) {
			$toc_settings['box_shadow_light'] = $box_shadow_light;
		}
		if (!empty($box_shadow_dark)) {
			$toc_settings['box_shadow_dark'] = $box_shadow_dark;
		}

		$toc_settings['return_parts'] = true;
		$parts = anchorkit_generate_elementor_toc($toc_settings);

		if (is_array($parts)) {
			// Late Escaping: Manually construct container to preserve complex styles (shadows) via esc_attr,
			// while using wp_kses on the inner content.
			$container_tag = $parts['container_tag'];

			// Hooks output (generally trusted as they may contain scripts/styles from other plugins)
			if (!empty($parts['before_html'])) {
				// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Hook output from do_action, may contain trusted third-party HTML
				echo wp_kses_post($parts['before_html']);
			}

			// Container opening tag - tag_escape ensures only valid tag names
			echo '<' . tag_escape($container_tag);
			foreach ($parts['container_attributes'] as $attr => $value) {
				echo ' ' . esc_attr($attr) . '="' . esc_attr($value) . '"';
			}
			// Data attributes are pre-assembled strings in the generator with esc_attr() applied internally
			if (!empty($parts['extra_attributes_string'])) {
				// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Pre-escaped with esc_attr() during generation in elementor.php
				echo ' ' . $parts['extra_attributes_string'];
			}
			echo '>';

			// Plugin-generated HTML for header (title + toggle button with SVG icon)
			if (!empty($parts['header_html'])) {
				echo wp_kses($parts['header_html'], anchorkit_get_allowed_html_tags());
			}

			// Strict content sanitization for list
			echo wp_kses($parts['inner_html'], anchorkit_get_allowed_html_tags());

			// Plugin-generated HTML for footer (View More/Back to Top)
			if (!empty($parts['footer_html'])) {
				echo wp_kses($parts['footer_html'], anchorkit_get_allowed_html_tags());
			}

			// Container closing tag
			echo '</' . tag_escape($container_tag) . '>';
		} else {
			// Fallback if array not returned (safety measure)
			echo wp_kses_post($parts);
		}
	}
}
