<?php
if (!defined('ABSPATH')) exit;

if (!current_user_can('manage_options')) {
    wp_die('Unauthorized');
}

global $wpdb;

$field_config  = get_option('afb_project_field_config', []);
$account_table = $wpdb->prefix . 'asana_accounts';
$accounts      = $wpdb->get_results("SELECT * FROM $account_table", ARRAY_A);

$projects = [];
$seen_project_gids = [];
foreach ((array) $accounts as $account) {
    $pat           = $account['pat'];
    $portfolio_gid = $account['portfolio_gid'] ?? null;

    $items = $portfolio_gid
        ? afb_get_portfolio_projects($portfolio_gid, $pat)
        : afb_fetch_asana('projects', $pat);

    foreach ((array) $items as $project) {
        $project_gid = (string) ($project['gid'] ?? '');
        if ($project_gid === '' || isset($seen_project_gids[$project_gid])) {
            continue;
        }

        $seen_project_gids[$project_gid] = true;
        $project['__pat'] = $pat;
        $projects[] = $project;
    }
}

usort($projects, static function ($a, $b) {
    return strcasecmp((string) ($a['name'] ?? ''), (string) ($b['name'] ?? ''));
});

$projects_by_gid = [];
foreach ((array) $projects as $project) {
    $gid = (string) ($project['gid'] ?? '');
    if ($gid !== '') {
        $projects_by_gid[$gid] = $project;
    }
}

$selected_gid = '';
if (!empty($_GET['project_gid'])) {
    $selected_gid = sanitize_text_field(wp_unslash($_GET['project_gid']));
} elseif (!empty($_POST['afb_project_to_configure'])) {
    $selected_gid = sanitize_text_field(wp_unslash($_POST['afb_project_to_configure']));
}

if ($selected_gid !== '' && !isset($projects_by_gid[$selected_gid])) {
    echo '<div class="notice notice-error is-dismissible"><p>That project could not be found. Please choose a project from the list.</p></div>';
    $selected_gid = '';
}

if (!empty($_POST['config_project_gid'])) {
    check_admin_referer('afb_field_flow_save', 'afb_field_flow_nonce');

    $gid                    = sanitize_text_field($_POST['config_project_gid']);
    $used_fields            = isset($_POST['used_fields']) ? array_map('sanitize_text_field', (array) $_POST['used_fields']) : [];
    $field_order            = isset($_POST['field_order']) ? array_map('sanitize_text_field', (array) $_POST['field_order']) : [];
    $required_fields        = isset($_POST['required_fields']) ? array_map('sanitize_text_field', (array) $_POST['required_fields']) : [];
    $hidden_fields          = isset($_POST['hidden_fields']) ? array_map('sanitize_text_field', (array) $_POST['hidden_fields']) : [];
    $readonly_fields        = isset($_POST['readonly_fields']) ? array_map('sanitize_text_field', (array) $_POST['readonly_fields']) : [];
    $paragraph_fields       = isset($_POST['paragraph_fields']) ? array_map('sanitize_text_field', (array) $_POST['paragraph_fields']) : [];
    $custom_paragraphs      = [];
    if (!empty($_POST['custom_paragraphs']) && is_array($_POST['custom_paragraphs'])) {
        foreach ($_POST['custom_paragraphs'] as $paragraph_id => $paragraph_html) {
            $paragraph_id = sanitize_text_field((string) $paragraph_id);
            if ($paragraph_id === '') continue;
            $custom_paragraphs[$paragraph_id] = wp_kses_post(wp_unslash((string) $paragraph_html));
        }
    }
    $custom_paragraph_titles = isset($_POST['custom_paragraph_titles']) ? array_map('sanitize_text_field', $_POST['custom_paragraph_titles']) : [];

    $custom_sections       = isset($_POST['custom_sections']) ? array_map('sanitize_textarea_field', $_POST['custom_sections']) : [];
    $custom_section_titles = isset($_POST['custom_section_titles']) ? array_map('sanitize_text_field', $_POST['custom_section_titles']) : [];
    $submit_block_fields   = isset($_POST['submit_block_fields'])
        ? array_map('sanitize_text_field', (array) $_POST['submit_block_fields'])
        : [];
    $custom_agreement_labels = isset($_POST['custom_agreement_labels']) ? array_map('sanitize_text_field', $_POST['custom_agreement_labels']) : [];
    $custom_agreement_details = isset($_POST['custom_agreement_details']) ? array_map('sanitize_textarea_field', $_POST['custom_agreement_details']) : [];
    $agreement_required_fields = isset($_POST['agreement_required_fields']) ? array_map('sanitize_text_field', (array) $_POST['agreement_required_fields']) : [];
    $agreement_description_fields = isset($_POST['agreement_description_fields']) ? array_map('sanitize_text_field', (array) $_POST['agreement_description_fields']) : [];
    $custom_upload_titles   = isset($_POST['custom_upload_titles']) ? array_map('sanitize_text_field', $_POST['custom_upload_titles']) : [];
    $custom_upload_details  = isset($_POST['custom_upload_details']) ? array_map('sanitize_textarea_field', $_POST['custom_upload_details']) : [];
    $custom_upload_min_files = isset($_POST['custom_upload_min_files']) ? array_map('absint', $_POST['custom_upload_min_files']) : [];
    $custom_upload_private_modes = [];
    if (!empty($_POST['custom_upload_private_modes']) && is_array($_POST['custom_upload_private_modes'])) {
        foreach ($_POST['custom_upload_private_modes'] as $upload_id_raw => $upload_mode_raw) {
            $upload_id = sanitize_text_field((string) $upload_id_raw);
            if ($upload_id === '' || strpos($upload_id, 'upload_') !== 0) {
                continue;
            }

            $upload_mode = sanitize_text_field((string) $upload_mode_raw);
            if (!in_array($upload_mode, ['main_only', 'copy_to_companion', 'companion_only'], true)) {
                continue;
            }

            $custom_upload_private_modes[$upload_id] = $upload_mode;
        }
    }
    $custom_upload_accept_types = [];
    if (!empty($_POST['custom_upload_accept_types']) && is_array($_POST['custom_upload_accept_types'])) {
        foreach ($_POST['custom_upload_accept_types'] as $upload_id_raw => $upload_accept_raw) {
            $upload_id = sanitize_text_field((string) $upload_id_raw);
            if ($upload_id === '' || strpos($upload_id, 'upload_') !== 0) {
                continue;
            }

            $accept_parts = preg_split('/\s*,\s*/', strtolower((string) $upload_accept_raw));
            if (!is_array($accept_parts)) {
                continue;
            }

            $accept_tokens = [];
            foreach ($accept_parts as $accept_part) {
                $accept_token = trim((string) $accept_part);
                if ($accept_token === '') {
                    continue;
                }

                $accept_token = preg_replace('/\s+/', '', $accept_token);
                if ($accept_token === '') {
                    continue;
                }

                if (strpos($accept_token, '.') === 0) {
                    $ext = preg_replace('/[^a-z0-9]/', '', substr($accept_token, 1));
                    if ($ext === '') {
                        continue;
                    }

                    $accept_token = '.' . $ext;
                } elseif (preg_match('/^[a-z0-9!#$&^_.+-]+\/(?:[a-z0-9!#$&^_.+-]+|\*)$/', $accept_token)) {
                    // MIME token is valid as-is.
                } elseif (preg_match('/^[a-z0-9]{1,16}$/', $accept_token)) {
                    $accept_token = '.' . $accept_token;
                } else {
                    continue;
                }

                $accept_tokens[$accept_token] = true;
            }

            if (!empty($accept_tokens)) {
                $custom_upload_accept_types[$upload_id] = implode(',', array_keys($accept_tokens));
            }
        }
    }
    $custom_upload_compress_images = isset($_POST['custom_upload_compress_images'])
        ? array_values(array_unique(array_filter(array_map('sanitize_text_field', (array) $_POST['custom_upload_compress_images']), static function ($upload_id) {
            return $upload_id !== '' && strpos($upload_id, 'upload_') === 0;
        })))
        : [];
    $custom_upload_max_file_mb = [];
    if (!empty($_POST['custom_upload_max_file_mb']) && is_array($_POST['custom_upload_max_file_mb'])) {
        foreach ($_POST['custom_upload_max_file_mb'] as $upload_id_raw => $max_file_mb_raw) {
            $upload_id = sanitize_text_field((string) $upload_id_raw);
            if ($upload_id === '' || strpos($upload_id, 'upload_') !== 0) {
                continue;
            }

            $max_file_mb_text = str_replace(',', '.', trim((string) $max_file_mb_raw));
            if ($max_file_mb_text === '' || !is_numeric($max_file_mb_text)) {
                continue;
            }

            $max_file_mb = (float) $max_file_mb_text;
            if ($max_file_mb <= 0) {
                continue;
            }

            $custom_upload_max_file_mb[$upload_id] = min(512, round($max_file_mb, 2));
        }
    }
    $custom_upload_max_width_px = [];
    if (!empty($_POST['custom_upload_max_width_px']) && is_array($_POST['custom_upload_max_width_px'])) {
        foreach ($_POST['custom_upload_max_width_px'] as $upload_id_raw => $max_width_raw) {
            $upload_id = sanitize_text_field((string) $upload_id_raw);
            if ($upload_id === '' || strpos($upload_id, 'upload_') !== 0) {
                continue;
            }

            $max_width_text = str_replace(',', '.', trim((string) $max_width_raw));
            if ($max_width_text === '' || !is_numeric($max_width_text)) {
                continue;
            }

            $max_width = (int) round((float) $max_width_text);
            if ($max_width <= 0) {
                continue;
            }

            $custom_upload_max_width_px[$upload_id] = max(100, min(4000, $max_width));
        }
    }
    $custom_upload_compress_quality = [];
    if (!empty($_POST['custom_upload_compress_quality']) && is_array($_POST['custom_upload_compress_quality'])) {
        foreach ($_POST['custom_upload_compress_quality'] as $upload_id_raw => $quality_raw) {
            $upload_id = sanitize_text_field((string) $upload_id_raw);
            if ($upload_id === '' || strpos($upload_id, 'upload_') !== 0) {
                continue;
            }

            $quality_text = trim((string) $quality_raw);
            if ($quality_text === '' || !is_numeric($quality_text)) {
                continue;
            }

            $custom_upload_compress_quality[$upload_id] = max(1, min(100, (int) round((float) $quality_text)));
        }
    }
    $custom_single_input_labels = isset($_POST['custom_single_input_labels']) ? array_map('sanitize_text_field', $_POST['custom_single_input_labels']) : [];
    $custom_single_input_descriptions = isset($_POST['custom_single_input_descriptions']) ? array_map('sanitize_textarea_field', $_POST['custom_single_input_descriptions']) : [];
    $custom_single_input_placeholders = isset($_POST['custom_single_input_placeholders']) ? array_map('sanitize_text_field', $_POST['custom_single_input_placeholders']) : [];
    $custom_single_input_sync_fields = isset($_POST['custom_single_input_sync_fields']) ? array_map('sanitize_text_field', $_POST['custom_single_input_sync_fields']) : [];
    $custom_single_input_modes = [];
    if (!empty($_POST['custom_single_input_modes']) && is_array($_POST['custom_single_input_modes'])) {
        foreach ($_POST['custom_single_input_modes'] as $single_id => $single_mode_raw) {
            $single_id = sanitize_text_field((string) $single_id);
            if ($single_id === '') {
                continue;
            }

            $single_mode = sanitize_text_field((string) $single_mode_raw);
            if (!in_array($single_mode, ['text', 'textarea'], true)) {
                $single_mode = 'text';
            }

            $custom_single_input_modes[$single_id] = $single_mode;
        }
    }
    $custom_single_input_max_words_enabled = isset($_POST['custom_single_input_max_words_enabled'])
        ? array_values(array_unique(array_filter(array_map('sanitize_text_field', (array) $_POST['custom_single_input_max_words_enabled']), static function ($val) {
            return $val !== '';
        })))
        : [];
    $custom_single_input_max_words = [];
    if (!empty($_POST['custom_single_input_max_words']) && is_array($_POST['custom_single_input_max_words'])) {
        foreach ($_POST['custom_single_input_max_words'] as $single_id => $max_words_raw) {
            $single_id = sanitize_text_field((string) $single_id);
            if ($single_id === '') {
                continue;
            }

            $custom_single_input_max_words[$single_id] = max(0, absint($max_words_raw));
        }
    }
    $custom_single_input_ai_enabled = isset($_POST['custom_single_input_ai_enabled'])
        ? array_values(array_unique(array_filter(array_map('sanitize_text_field', (array) $_POST['custom_single_input_ai_enabled']), static function ($val) {
            return $val !== '';
        })))
        : [];
    $custom_dropdown_labels = isset($_POST['custom_dropdown_labels']) ? array_map('sanitize_text_field', $_POST['custom_dropdown_labels']) : [];
    $custom_dropdown_descriptions = isset($_POST['custom_dropdown_descriptions']) ? array_map('sanitize_textarea_field', $_POST['custom_dropdown_descriptions']) : [];
    $custom_dropdown_placeholders = isset($_POST['custom_dropdown_placeholders']) ? array_map('sanitize_text_field', $_POST['custom_dropdown_placeholders']) : [];
    $custom_dropdown_options = isset($_POST['custom_dropdown_options']) ? array_map('sanitize_textarea_field', $_POST['custom_dropdown_options']) : [];
    $custom_dropdown_selection_modes = isset($_POST['custom_dropdown_selection_modes']) ? array_map('sanitize_text_field', $_POST['custom_dropdown_selection_modes']) : [];
    $custom_dropdown_sync_fields = isset($_POST['custom_dropdown_sync_fields']) ? array_map('sanitize_text_field', $_POST['custom_dropdown_sync_fields']) : [];
    $custom_calendar_labels = isset($_POST['custom_calendar_labels']) ? array_map('sanitize_text_field', $_POST['custom_calendar_labels']) : [];
    $custom_calendar_descriptions = isset($_POST['custom_calendar_descriptions']) ? array_map('sanitize_textarea_field', $_POST['custom_calendar_descriptions']) : [];
    $custom_calendar_placeholders = isset($_POST['custom_calendar_placeholders']) ? array_map('sanitize_text_field', $_POST['custom_calendar_placeholders']) : [];
    $custom_calendar_sync_modes = isset($_POST['custom_calendar_sync_modes']) ? array_map('sanitize_text_field', $_POST['custom_calendar_sync_modes']) : [];
    $custom_calendar_sync_fields = isset($_POST['custom_calendar_sync_fields']) ? array_map('sanitize_text_field', $_POST['custom_calendar_sync_fields']) : [];
    $custom_repeater_labels = isset($_POST['custom_repeater_labels']) ? array_map('sanitize_text_field', $_POST['custom_repeater_labels']) : [];
    $custom_repeater_descriptions = isset($_POST['custom_repeater_descriptions']) ? array_map('sanitize_textarea_field', $_POST['custom_repeater_descriptions']) : [];
    $custom_repeater_save_mode = [];
    if (!empty($_POST['custom_repeater_save_mode']) && is_array($_POST['custom_repeater_save_mode'])) {
        foreach ($_POST['custom_repeater_save_mode'] as $repeater_id_raw => $save_mode_raw) {
            $repeater_id = sanitize_text_field((string) $repeater_id_raw);
            if ($repeater_id === '') {
                continue;
            }

            $save_mode = sanitize_text_field((string) $save_mode_raw);
            $custom_repeater_save_mode[$repeater_id] = ($save_mode === 'description') ? 'description' : 'subtasks';
        }
    }
    $custom_repeater_columns = [];
    if (!empty($_POST['custom_repeater_columns']) && is_array($_POST['custom_repeater_columns'])) {
        foreach ($_POST['custom_repeater_columns'] as $repeater_id_raw => $repeater_columns_raw) {
            $repeater_id = sanitize_text_field((string) $repeater_id_raw);
            if ($repeater_id === '') {
                continue;
            }

            $repeater_columns = sanitize_textarea_field((string) $repeater_columns_raw);
            if ($repeater_columns === '') {
                continue;
            }

            $custom_repeater_columns[$repeater_id] = $repeater_columns;
        }
    }
    $custom_repeater_min_rows = [];
    if (!empty($_POST['custom_repeater_min_rows']) && is_array($_POST['custom_repeater_min_rows'])) {
        foreach ($_POST['custom_repeater_min_rows'] as $repeater_id_raw => $min_rows_raw) {
            $repeater_id = sanitize_text_field((string) $repeater_id_raw);
            if ($repeater_id === '') {
                continue;
            }

            $custom_repeater_min_rows[$repeater_id] = max(0, min(250, absint($min_rows_raw)));
        }
    }
    $custom_repeater_max_rows = [];
    if (!empty($_POST['custom_repeater_max_rows']) && is_array($_POST['custom_repeater_max_rows'])) {
        foreach ($_POST['custom_repeater_max_rows'] as $repeater_id_raw => $max_rows_raw) {
            $repeater_id = sanitize_text_field((string) $repeater_id_raw);
            if ($repeater_id === '') {
                continue;
            }

            $max_rows = max(0, min(250, absint($max_rows_raw)));
            if ($max_rows <= 0) {
                continue;
            }

            $custom_repeater_max_rows[$repeater_id] = $max_rows;
        }
    }
    foreach ($custom_repeater_min_rows as $repeater_id => $min_rows) {
        if (!isset($custom_repeater_max_rows[$repeater_id])) {
            continue;
        }

        if ((int) $custom_repeater_max_rows[$repeater_id] < (int) $min_rows) {
            $custom_repeater_max_rows[$repeater_id] = (int) $min_rows;
        }
    }
    $custom_repeater_field_map = [];
    if (!empty($_POST['custom_repeater_field_map']) && is_array($_POST['custom_repeater_field_map'])) {
        foreach ($_POST['custom_repeater_field_map'] as $repeater_id_raw => $mapped_field_ids_raw) {
            $repeater_id = sanitize_text_field((string) $repeater_id_raw);
            if ($repeater_id === '') {
                continue;
            }

            $mapped_field_ids = is_array($mapped_field_ids_raw)
                ? $mapped_field_ids_raw
                : [$mapped_field_ids_raw];

            $seen_mapped = [];
            $cleaned_mapped = [];
            foreach ($mapped_field_ids as $mapped_gid_raw) {
                $mapped_gid = sanitize_text_field((string) $mapped_gid_raw);
                if ($mapped_gid === '' || !ctype_digit($mapped_gid) || isset($seen_mapped[$mapped_gid])) {
                    continue;
                }

                $seen_mapped[$mapped_gid] = true;
                $cleaned_mapped[] = $mapped_gid;
            }

            if (!empty($cleaned_mapped)) {
                $custom_repeater_field_map[$repeater_id] = $cleaned_mapped;
            }
        }
    }
    $custom_text_sync_fields = [];
    if (!empty($_POST['custom_text_sync_fields']) && is_array($_POST['custom_text_sync_fields'])) {
        foreach ($_POST['custom_text_sync_fields'] as $source_gid_raw => $target_gid_raw) {
            $source_gid = sanitize_text_field((string) $source_gid_raw);
            $target_gid = sanitize_text_field((string) $target_gid_raw);
            if ($source_gid === '' || $target_gid === '' || !ctype_digit($source_gid) || !ctype_digit($target_gid) || $source_gid === $target_gid) {
                continue;
            }

            $custom_text_sync_fields[$source_gid] = $target_gid;
        }
    }
    $custom_calendar_preset_modes = isset($_POST['custom_calendar_preset_modes']) ? array_map('sanitize_text_field', $_POST['custom_calendar_preset_modes']) : [];
    $custom_task_name_labels = isset($_POST['custom_task_name_labels']) ? array_map('sanitize_text_field', $_POST['custom_task_name_labels']) : [];
    $custom_task_name_templates = [];
    if (!empty($_POST['custom_task_name_templates']) && is_array($_POST['custom_task_name_templates'])) {
        foreach ($_POST['custom_task_name_templates'] as $task_name_id => $task_name_template) {
            $task_name_id = sanitize_text_field((string) $task_name_id);
            if ($task_name_id === '') {
                continue;
            }

            $custom_task_name_templates[$task_name_id] = sanitize_text_field((string) $task_name_template);
        }
    }
    // Ensure task_name IDs are included in the conditions processing below
    // (they're already processed in the $conditions array by the main condition handler)
    $private_companion_task_name_template = sanitize_text_field((string) ($_POST['private_companion_task_name_template'] ?? ''));
    $private_companion_task_name_mode = sanitize_text_field((string) ($_POST['private_companion_task_name_mode'] ?? 'use_main'));
    if (!in_array($private_companion_task_name_mode, ['use_main', 'use_job_number', 'use_template'], true)) {
        $private_companion_task_name_mode = 'use_main';
    }
    $private_data_companion_enabled = !empty($_POST['private_data_companion_enabled']) ? 1 : 0;
    $private_companion_depends_on_main = !empty($_POST['private_companion_depends_on_main']) ? 1 : 0;
    $private_data_project_gid = sanitize_text_field((string) ($_POST['private_data_project_gid'] ?? ''));
    if (!ctype_digit($private_data_project_gid)) {
        $private_data_project_gid = '';
    }
    $private_companion_upload_mode = sanitize_text_field((string) ($_POST['private_companion_upload_mode'] ?? 'main_only'));
    if (!in_array($private_companion_upload_mode, ['main_only', 'copy_to_companion', 'companion_only'], true)) {
        $private_companion_upload_mode = 'main_only';
    }
    $private_companion_field_targets = [];
    if (!empty($_POST['private_companion_field_targets']) && is_array($_POST['private_companion_field_targets'])) {
        foreach ($_POST['private_companion_field_targets'] as $source_id => $target_gid_raw) {
            $source_id = sanitize_text_field((string) $source_id);
            $target_gid = sanitize_text_field((string) $target_gid_raw);
            if ($source_id === '' || $target_gid === '' || !ctype_digit($target_gid)) {
                continue;
            }

            $private_companion_field_targets[$source_id] = $target_gid;
        }
    }

    $custom_due_date_default_base = isset($_POST['custom_due_date_default_base']) && is_array($_POST['custom_due_date_default_base'])
        ? array_map('sanitize_text_field', $_POST['custom_due_date_default_base'])
        : [];
    $custom_due_date_default_base_field = isset($_POST['custom_due_date_default_base_field']) && is_array($_POST['custom_due_date_default_base_field'])
        ? array_map('sanitize_text_field', $_POST['custom_due_date_default_base_field'])
        : [];
    $custom_due_date_default_offset = isset($_POST['custom_due_date_default_offset']) && is_array($_POST['custom_due_date_default_offset'])
        ? $_POST['custom_due_date_default_offset']
        : [];
    $custom_due_date_default_mode = isset($_POST['custom_due_date_default_mode']) && is_array($_POST['custom_due_date_default_mode'])
        ? array_map('sanitize_text_field', $_POST['custom_due_date_default_mode'])
        : [];
    $custom_due_date_default_allow_weekends = isset($_POST['custom_due_date_default_allow_weekends'])
        ? array_values(array_unique(array_filter(array_map('sanitize_text_field', (array) $_POST['custom_due_date_default_allow_weekends']), static function ($val) {
            return $val !== '';
        })))
        : [];
    $custom_due_date_override_manual = isset($_POST['custom_due_date_override_manual'])
        ? array_values(array_unique(array_filter(array_map('sanitize_text_field', (array) $_POST['custom_due_date_override_manual']), static function ($val) {
            return $val !== '';
        })))
        : [];
    $custom_due_date_rules_raw = isset($_POST['custom_due_date_rules']) && is_array($_POST['custom_due_date_rules'])
        ? $_POST['custom_due_date_rules']
        : [];

    $custom_due_date_configs = [];
    $due_date_block_ids = array_values(array_unique(array_filter(array_merge(
        array_map('strval', array_keys((array) $custom_due_date_default_base)),
        array_map('strval', array_keys((array) $custom_due_date_default_base_field)),
        array_map('strval', array_keys((array) $custom_due_date_default_offset)),
        array_map('strval', array_keys((array) $custom_due_date_default_mode)),
        array_map('strval', array_keys((array) $custom_due_date_rules_raw)),
        array_map('strval', (array) $custom_due_date_default_allow_weekends),
        array_map('strval', (array) $custom_due_date_override_manual),
        array_values(array_filter((array) $field_order, static function ($id) {
            return is_string($id) && strpos($id, 'due_date_') === 0;
        }))
    ), static function ($id) {
        return is_string($id) && strpos($id, 'due_date_') === 0;
    })));

    foreach ($due_date_block_ids as $due_id) {
        $default_base_raw = (string) ($custom_due_date_default_base[$due_id] ?? 'today');
        $default_base = in_array($default_base_raw, ['today', 'field'], true) ? $default_base_raw : 'today';
        $default_base_field = sanitize_text_field((string) ($custom_due_date_default_base_field[$due_id] ?? ''));
        $default_offset = (int) ($custom_due_date_default_offset[$due_id] ?? 0);
        if ($default_offset > 3650) {
            $default_offset = 3650;
        } elseif ($default_offset < -3650) {
            $default_offset = -3650;
        }

        $default_mode_raw = (string) ($custom_due_date_default_mode[$due_id] ?? 'business');
        $default_mode = in_array($default_mode_raw, ['business', 'calendar'], true) ? $default_mode_raw : 'business';
        $default_allow_weekends = in_array($due_id, $custom_due_date_default_allow_weekends, true) ? 1 : 0;
        $override_manual = in_array($due_id, $custom_due_date_override_manual, true) ? 1 : 0;

        $rules = [];
        $rules_json_raw = wp_unslash((string) ($custom_due_date_rules_raw[$due_id] ?? '[]'));
        $decoded_rules = json_decode($rules_json_raw, true);
        if (is_array($decoded_rules)) {
            foreach ($decoded_rules as $rule) {
                if (!is_array($rule)) {
                    continue;
                }

                $depends_on = sanitize_text_field((string) ($rule['depends_on'] ?? ''));
                if ($depends_on === '') {
                    continue;
                }

                $posted_vals = $rule['values'] ?? [];
                $rule_vals = is_array($posted_vals)
                    ? $posted_vals
                    : (($posted_vals !== '' && $posted_vals !== null) ? [$posted_vals] : []);
                $rule_vals = array_values(array_unique(array_filter(array_map('sanitize_text_field', $rule_vals), static function ($val) {
                    return $val !== '';
                })));
                if (empty($rule_vals)) {
                    continue;
                }

                $rule_base_raw = sanitize_text_field((string) ($rule['base'] ?? 'today'));
                $rule_base = in_array($rule_base_raw, ['today', 'field'], true) ? $rule_base_raw : 'today';
                $rule_base_field = sanitize_text_field((string) ($rule['base_field'] ?? ''));
                $rule_offset = (int) ($rule['offset'] ?? 0);
                if ($rule_offset > 3650) {
                    $rule_offset = 3650;
                } elseif ($rule_offset < -3650) {
                    $rule_offset = -3650;
                }

                $rule_mode_raw = sanitize_text_field((string) ($rule['mode'] ?? 'business'));
                $rule_mode = in_array($rule_mode_raw, ['business', 'calendar'], true) ? $rule_mode_raw : 'business';
                $rule_allow_weekends = !empty($rule['allow_weekends']) ? 1 : 0;

                $rules[] = [
                    'depends_on'      => $depends_on,
                    'value'           => $rule_vals[0],
                    'values'          => $rule_vals,
                    'base'            => $rule_base,
                    'base_field'      => $rule_base_field,
                    'offset'          => $rule_offset,
                    'mode'            => $rule_mode,
                    'allow_weekends'  => $rule_allow_weekends,
                ];
            }
        }

        $custom_due_date_configs[$due_id] = [
            'rules' => $rules,
            'default' => [
                'base'           => $default_base,
                'base_field'     => $default_base_field,
                'offset'         => $default_offset,
                'mode'           => $default_mode,
                'allow_weekends' => $default_allow_weekends,
            ],
            'override_manual' => $override_manual,
        ];
    }

    $custom_assignee_labels = isset($_POST['custom_assignee_labels']) && is_array($_POST['custom_assignee_labels'])
        ? array_map('sanitize_text_field', $_POST['custom_assignee_labels'])
        : [];
    $custom_assignee_default = isset($_POST['custom_assignee_default']) && is_array($_POST['custom_assignee_default'])
        ? array_map('sanitize_text_field', $_POST['custom_assignee_default'])
        : [];
    $custom_assignee_default_fallbacks_raw = isset($_POST['custom_assignee_default_fallbacks']) && is_array($_POST['custom_assignee_default_fallbacks'])
        ? $_POST['custom_assignee_default_fallbacks']
        : [];
    $custom_assignee_rules_raw = isset($_POST['custom_assignee_rules']) && is_array($_POST['custom_assignee_rules'])
        ? $_POST['custom_assignee_rules']
        : [];
    $custom_assignee_check_ooo = isset($_POST['custom_assignee_check_ooo'])
        ? array_values(array_unique(array_filter(array_map('sanitize_text_field', (array) $_POST['custom_assignee_check_ooo']), static function ($val) {
            return $val !== '';
        })))
        : [];

    $normalize_assignee_gid = static function ($raw_gid) {
        $gid = sanitize_text_field((string) $raw_gid);
        $gid = preg_replace('/\D+/', '', $gid);
        return is_string($gid) ? $gid : '';
    };

    $custom_assignee_configs = [];
    $assignee_block_ids = array_values(array_unique(array_filter(array_merge(
        array_map('strval', array_keys((array) $custom_assignee_default)),
        array_map('strval', array_keys((array) $custom_assignee_default_fallbacks_raw)),
        array_map('strval', array_keys((array) $custom_assignee_rules_raw)),
        array_map('strval', (array) $custom_assignee_check_ooo),
        array_values(array_filter((array) $field_order, static function ($id) {
            return is_string($id) && strpos($id, 'assignee_') === 0;
        }))
    ), static function ($id) {
        return is_string($id) && strpos($id, 'assignee_') === 0;
    })));

    foreach ($assignee_block_ids as $assignee_id) {
        $default_assignee = $normalize_assignee_gid($custom_assignee_default[$assignee_id] ?? '');

        $default_fallback_vals = isset($custom_assignee_default_fallbacks_raw[$assignee_id]) && is_array($custom_assignee_default_fallbacks_raw[$assignee_id])
            ? $custom_assignee_default_fallbacks_raw[$assignee_id]
            : [];
        $default_fallbacks = array_values(array_unique(array_filter(array_map($normalize_assignee_gid, $default_fallback_vals), static function ($gid) use ($default_assignee) {
            return $gid !== '' && $gid !== $default_assignee;
        })));

        $rules = [];
        $rules_json_raw = wp_unslash((string) ($custom_assignee_rules_raw[$assignee_id] ?? '[]'));
        $decoded_rules = json_decode($rules_json_raw, true);
        if (is_array($decoded_rules)) {
            foreach ($decoded_rules as $rule) {
                if (!is_array($rule)) {
                    continue;
                }

                $depends_on = sanitize_text_field((string) ($rule['depends_on'] ?? ''));
                if ($depends_on === '') {
                    continue;
                }

                $posted_vals = $rule['values'] ?? [];
                $rule_vals = is_array($posted_vals)
                    ? $posted_vals
                    : (($posted_vals !== '' && $posted_vals !== null) ? [$posted_vals] : []);
                $rule_vals = array_values(array_unique(array_filter(array_map('sanitize_text_field', $rule_vals), static function ($val) {
                    return $val !== '';
                })));
                if (empty($rule_vals)) {
                    continue;
                }

                $rule_assignee = $normalize_assignee_gid($rule['assignee'] ?? '');
                if ($rule_assignee === '') {
                    continue;
                }

                $raw_rule_fallbacks = [];
                if (isset($rule['fallback_assignees']) && is_array($rule['fallback_assignees'])) {
                    $raw_rule_fallbacks = $rule['fallback_assignees'];
                } elseif (isset($rule['fallback']) && $rule['fallback'] !== '') {
                    $raw_rule_fallbacks = [$rule['fallback']];
                }

                $rule_fallbacks = array_values(array_unique(array_filter(array_map($normalize_assignee_gid, $raw_rule_fallbacks), static function ($gid) use ($rule_assignee) {
                    return $gid !== '' && $gid !== $rule_assignee;
                })));

                $rules[] = [
                    'depends_on'         => $depends_on,
                    'value'              => $rule_vals[0],
                    'values'             => $rule_vals,
                    'assignee'           => $rule_assignee,
                    'fallback_assignees' => $rule_fallbacks,
                ];
            }
        }

        $custom_assignee_configs[$assignee_id] = [
            'default_assignee'         => $default_assignee,
            'default_fallback_assignees' => $default_fallbacks,
            'rules'                    => $rules,
            'check_ooo_today'          => in_array($assignee_id, $custom_assignee_check_ooo, true) ? 1 : 0,
            'all_ooo_action'           => 'leave_unassigned',
            'ooo_unavailable_action'   => 'continue_normal',
        ];
    }

    $custom_recipient_labels = isset($_POST['custom_recipient_labels']) && is_array($_POST['custom_recipient_labels'])
        ? array_map('sanitize_text_field', $_POST['custom_recipient_labels'])
        : [];
    $custom_recipient_enabled = isset($_POST['custom_recipient_enabled'])
        ? array_values(array_unique(array_filter(array_map('sanitize_text_field', (array) $_POST['custom_recipient_enabled']), static function ($val) {
            return $val !== '';
        })))
        : [];
    $custom_recipient_include_submitter = isset($_POST['custom_recipient_include_submitter'])
        ? array_values(array_unique(array_filter(array_map('sanitize_text_field', (array) $_POST['custom_recipient_include_submitter']), static function ($val) {
            return $val !== '';
        })))
        : [];
    $custom_recipient_mode = isset($_POST['custom_recipient_mode']) && is_array($_POST['custom_recipient_mode'])
        ? array_map('sanitize_text_field', $_POST['custom_recipient_mode'])
        : [];
    $custom_recipient_subject_templates = isset($_POST['custom_recipient_subject_templates']) && is_array($_POST['custom_recipient_subject_templates'])
        ? array_map('sanitize_text_field', $_POST['custom_recipient_subject_templates'])
        : [];
    $custom_recipient_body_templates = isset($_POST['custom_recipient_body_templates']) && is_array($_POST['custom_recipient_body_templates'])
        ? array_map('wp_kses_post', wp_unslash($_POST['custom_recipient_body_templates']))
        : [];
    $custom_recipient_source_fields_raw = isset($_POST['custom_recipient_source_fields']) && is_array($_POST['custom_recipient_source_fields'])
        ? $_POST['custom_recipient_source_fields']
        : [];
    $custom_recipient_manual_emails_raw = isset($_POST['custom_recipient_manual_emails']) && is_array($_POST['custom_recipient_manual_emails'])
        ? $_POST['custom_recipient_manual_emails']
        : [];

    $extract_recipient_manual_emails = static function ($raw_value) {
        if (is_array($raw_value)) {
            $raw_value = implode("\n", array_map('strval', $raw_value));
        }

        $text = wp_unslash((string) $raw_value);
        if ($text === '') {
            return [];
        }

        $emails = [];
        if (preg_match_all('/[A-Z0-9._%+\-]+@[A-Z0-9.\-]+\.[A-Z]{2,}/i', $text, $matches) && !empty($matches[0])) {
            foreach ($matches[0] as $candidate) {
                $email = sanitize_email((string) $candidate);
                if (is_email($email)) {
                    $emails[] = $email;
                }
            }
        } else {
            $email = sanitize_email($text);
            if (is_email($email)) {
                $emails[] = $email;
            }
        }

        return array_values(array_unique($emails));
    };

    $custom_recipient_configs = [];
    $recipient_block_ids = array_values(array_unique(array_filter(array_merge(
        array_map('strval', array_keys((array) $custom_recipient_mode)),
        array_map('strval', array_keys((array) $custom_recipient_subject_templates)),
        array_map('strval', array_keys((array) $custom_recipient_body_templates)),
        array_map('strval', array_keys((array) $custom_recipient_source_fields_raw)),
        array_map('strval', array_keys((array) $custom_recipient_manual_emails_raw)),
        array_map('strval', (array) $custom_recipient_enabled),
        array_map('strval', (array) $custom_recipient_include_submitter),
        array_values(array_filter((array) $field_order, static function ($id) {
            return is_string($id) && strpos($id, 'recipient_') === 0;
        }))
    ), static function ($id) {
        return is_string($id) && strpos($id, 'recipient_') === 0;
    })));

    foreach ($recipient_block_ids as $recipient_id) {
        $mode_raw = sanitize_text_field((string) ($custom_recipient_mode[$recipient_id] ?? 'separate'));
        $mode = in_array($mode_raw, ['separate', 'cc'], true) ? $mode_raw : 'separate';

        $source_vals = isset($custom_recipient_source_fields_raw[$recipient_id]) && is_array($custom_recipient_source_fields_raw[$recipient_id])
            ? $custom_recipient_source_fields_raw[$recipient_id]
            : [];
        $source_fields = array_values(array_unique(array_filter(array_map('sanitize_text_field', $source_vals), static function ($val) {
            return $val !== '';
        })));
        $manual_emails = $extract_recipient_manual_emails($custom_recipient_manual_emails_raw[$recipient_id] ?? '');

        $subject_tpl = sanitize_text_field((string) ($custom_recipient_subject_templates[$recipient_id] ?? ''));
        $body_tpl = wp_kses_post((string) ($custom_recipient_body_templates[$recipient_id] ?? ''));

        $custom_recipient_configs[$recipient_id] = [
            'enabled'           => in_array($recipient_id, $custom_recipient_enabled, true) ? 1 : 0,
            'include_submitter' => in_array($recipient_id, $custom_recipient_include_submitter, true) ? 1 : 0,
            'mode'              => $mode,
            'source_fields'     => $source_fields,
            'manual_emails'     => $manual_emails,
            'subject_template'  => $subject_tpl,
            'body_template'     => $body_tpl,
        ];
    }

    $visible_enum_options = [];
    if (!empty($_POST['visible_enum_options']) && is_array($_POST['visible_enum_options'])) {
        foreach ($_POST['visible_enum_options'] as $field_gid => $option_gids) {
            $field_gid = sanitize_text_field((string) $field_gid);
            if ($field_gid === '') {
                continue;
            }

            $vals = is_array($option_gids) ? $option_gids : [];
            $vals = array_values(array_unique(array_filter(array_map('sanitize_text_field', $vals), static function ($val) {
                return $val !== '';
            })));

            if (!empty($vals)) {
                $visible_enum_options[$field_gid] = $vals;
            }
        }
    }

    $option_visibility_rules = [];
    if (!empty($_POST['option_filter_depends_on']) && is_array($_POST['option_filter_depends_on'])) {
        foreach ($_POST['option_filter_depends_on'] as $target_gid => $source_gid) {
            $target_gid = sanitize_text_field((string) $target_gid);
            $source_gid = sanitize_text_field((string) $source_gid);
            if ($target_gid === '' || $source_gid === '') {
                continue;
            }

            $raw_map = '';
            if (!empty($_POST['option_filter_map']) && is_array($_POST['option_filter_map'])) {
                $raw_map = wp_unslash((string) ($_POST['option_filter_map'][$target_gid] ?? ''));
            }

            $decoded_map = json_decode($raw_map, true);
            if (!is_array($decoded_map)) {
                continue;
            }

            $sanitized_map = [];
            foreach ($decoded_map as $source_value_gid => $target_values) {
                $source_value_gid = sanitize_text_field((string) $source_value_gid);
                if ($source_value_gid === '') {
                    continue;
                }

                $vals = is_array($target_values) ? $target_values : [];
                $vals = array_values(array_unique(array_filter(array_map('sanitize_text_field', $vals), static function ($val) {
                    return $val !== '';
                })));

                if (!empty($vals)) {
                    $sanitized_map[$source_value_gid] = $vals;
                }
            }

            if (!empty($sanitized_map)) {
                $option_visibility_rules[$target_gid] = [
                    'depends_on' => $source_gid,
                    'map'        => $sanitized_map,
                ];
            }
        }
    }

    // Deprecated: uploads are now configured through upload blocks only.
    $allow_uploads = false;
    $form_title    = isset($_POST['form_title']) ? sanitize_text_field($_POST['form_title']) : '';

    $half_width_fields = isset($_POST['half_width_fields'])
        ? array_map('sanitize_text_field', (array) $_POST['half_width_fields'])
        : [];
    $third_width_fields = isset($_POST['third_width_fields'])
        ? array_map('sanitize_text_field', (array) $_POST['third_width_fields'])
        : [];
    if (!empty($half_width_fields) && !empty($third_width_fields)) {
        $half_width_fields = array_values(array_diff($half_width_fields, $third_width_fields));
    }

    $conditions = [];
    if (!empty($_POST['condition_rules']) && is_array($_POST['condition_rules'])) {
        $posted_logic = isset($_POST['condition_logic']) && is_array($_POST['condition_logic'])
            ? $_POST['condition_logic']
            : [];

        foreach ($_POST['condition_rules'] as $target => $rules_json) {
            $target = sanitize_text_field((string) $target);
            if ($target === '') continue;

            $raw = wp_unslash((string) $rules_json);
            $decoded = json_decode($raw, true);
            if (!is_array($decoded)) continue;

            $rules = [];
            foreach ($decoded as $rule) {
                if (!is_array($rule)) continue;
                $source = sanitize_text_field((string) ($rule['depends_on'] ?? ''));
                if ($source === '') continue;

                $posted_vals = $rule['values'] ?? [];
                $vals = is_array($posted_vals)
                    ? $posted_vals
                    : (($posted_vals !== '' && $posted_vals !== null) ? [$posted_vals] : []);
                $vals = array_values(array_unique(array_filter(array_map('sanitize_text_field', $vals), static function ($val) {
                    return $val !== '';
                })));

                if (!empty($vals)) {
                    $rules[] = [
                        'depends_on' => $source,
                        'value'      => $vals[0],
                        'values'     => $vals,
                    ];
                }
            }

            if (!empty($rules)) {
                $logic = sanitize_text_field((string) ($posted_logic[$target] ?? 'all'));
                if (!in_array($logic, ['all', 'any'], true)) {
                    $logic = 'all';
                }

                $conditions[$target] = [
                    'logic'     => $logic,
                    'rules'     => $rules,
                    // Legacy single-rule compatibility keys.
                    'depends_on'=> $rules[0]['depends_on'],
                    'value'     => $rules[0]['value'],
                    'values'    => $rules[0]['values'],
                ];
            }
        }
    }

    // Backward compatibility for legacy single-condition form posts.
    if (!empty($_POST['depends_on']) && is_array($_POST['depends_on'])) {
        foreach ($_POST['depends_on'] as $target => $source) {
            $target = sanitize_text_field((string) $target);
            if ($target === '' || isset($conditions[$target])) continue;

            $source = sanitize_text_field((string) $source);
            if ($source === '') continue;

            $posted = $_POST['expected_value'][$target] ?? [];
            $vals   = is_array($posted) ? $posted : (($posted !== '' && $posted !== null) ? [$posted] : []);
            $vals   = array_values(array_unique(array_filter(array_map('sanitize_text_field', $vals), static function ($val) {
                return $val !== '';
            })));

            if (!empty($vals)) {
                $rule = [
                    'depends_on' => $source,
                    'value'      => $vals[0],
                    'values'     => $vals,
                ];
                $conditions[$target] = [
                    'logic'      => 'all',
                    'rules'      => [$rule],
                    'depends_on' => $source,
                    'value'      => $vals[0],
                    'values'     => $vals,
                ];
            }
        }
    }

    $labels       = isset($_POST['labels']) ? array_map('sanitize_text_field', $_POST['labels']) : [];
    $descriptions = isset($_POST['descriptions']) ? array_map('sanitize_text_field', $_POST['descriptions']) : [];

    $field_config[$gid] = [
        'used_fields'             => $used_fields,
        'field_order'             => $field_order,
        'conditions'              => $conditions,
        'required_fields'         => $required_fields,
        'hidden_fields'           => $hidden_fields,
        'readonly_fields'         => $readonly_fields,
        'labels'                  => $labels,
        'descriptions'            => $descriptions,
        'paragraph_fields'        => $paragraph_fields,
        'custom_paragraphs'       => $custom_paragraphs,
        'custom_paragraph_titles' => $custom_paragraph_titles,
        'custom_sections'         => $custom_sections,
        'custom_section_titles'   => $custom_section_titles,
        'submit_block_fields'     => $submit_block_fields,
        'custom_agreement_labels' => $custom_agreement_labels,
        'custom_agreement_details'=> $custom_agreement_details,
        'agreement_required_fields' => $agreement_required_fields,
        'agreement_description_fields' => $agreement_description_fields,
        'custom_upload_titles'    => $custom_upload_titles,
        'custom_upload_details'   => $custom_upload_details,
        'custom_upload_min_files' => $custom_upload_min_files,
        'custom_upload_private_modes' => $custom_upload_private_modes,
        'custom_upload_accept_types' => $custom_upload_accept_types,
        'custom_upload_compress_images' => $custom_upload_compress_images,
        'custom_upload_max_file_mb' => $custom_upload_max_file_mb,
        'custom_upload_max_width_px' => $custom_upload_max_width_px,
        'custom_upload_compress_quality' => $custom_upload_compress_quality,
        'custom_single_input_labels' => $custom_single_input_labels,
        'custom_single_input_descriptions' => $custom_single_input_descriptions,
        'custom_single_input_placeholders' => $custom_single_input_placeholders,
        'custom_single_input_sync_fields' => $custom_single_input_sync_fields,
        'custom_single_input_modes' => $custom_single_input_modes,
        'custom_single_input_max_words_enabled' => $custom_single_input_max_words_enabled,
        'custom_single_input_max_words' => $custom_single_input_max_words,
        'custom_single_input_ai_enabled' => $custom_single_input_ai_enabled,
        'custom_dropdown_labels' => $custom_dropdown_labels,
        'custom_dropdown_descriptions' => $custom_dropdown_descriptions,
        'custom_dropdown_placeholders' => $custom_dropdown_placeholders,
        'custom_dropdown_options' => $custom_dropdown_options,
        'custom_dropdown_selection_modes' => $custom_dropdown_selection_modes,
        'custom_dropdown_sync_fields' => $custom_dropdown_sync_fields,
        'custom_calendar_labels' => $custom_calendar_labels,
        'custom_calendar_descriptions' => $custom_calendar_descriptions,
        'custom_calendar_placeholders' => $custom_calendar_placeholders,
        'custom_calendar_sync_modes' => $custom_calendar_sync_modes,
        'custom_calendar_sync_fields' => $custom_calendar_sync_fields,
        'custom_repeater_labels' => $custom_repeater_labels,
        'custom_repeater_descriptions' => $custom_repeater_descriptions,
        'custom_repeater_save_mode' => $custom_repeater_save_mode,
        'custom_repeater_columns' => $custom_repeater_columns,
        'custom_repeater_min_rows' => $custom_repeater_min_rows,
        'custom_repeater_max_rows' => $custom_repeater_max_rows,
        'custom_repeater_field_map' => $custom_repeater_field_map,
        'custom_text_sync_fields' => $custom_text_sync_fields,
        'custom_calendar_preset_modes' => $custom_calendar_preset_modes,
        'custom_task_name_labels' => $custom_task_name_labels,
        'custom_task_name_templates' => $custom_task_name_templates,
        'private_companion_task_name_mode' => $private_companion_task_name_mode,
        'private_companion_task_name_template' => $private_companion_task_name_template,
        'private_data_companion_enabled' => $private_data_companion_enabled,
        'private_companion_depends_on_main' => $private_companion_depends_on_main,
        'private_data_project_gid'    => $private_data_project_gid,
        'private_companion_upload_mode' => $private_companion_upload_mode,
        'private_companion_field_targets' => $private_companion_field_targets,
        'custom_due_date_configs'  => $custom_due_date_configs,
        'custom_assignee_labels'   => $custom_assignee_labels,
        'custom_assignee_configs'  => $custom_assignee_configs,
        'custom_recipient_labels'  => $custom_recipient_labels,
        'custom_recipient_configs' => $custom_recipient_configs,
        'visible_enum_options'    => $visible_enum_options,
        'option_visibility_rules' => $option_visibility_rules,
        'allow_uploads'           => $allow_uploads,
        'form_title'              => $form_title,
        'half_width_fields'       => $half_width_fields,
        'third_width_fields'      => $third_width_fields,
    ];

    update_option('afb_project_field_config', $field_config);
    echo '<div class="notice notice-success is-dismissible"><p>Field flow saved.</p></div>';
}
?>

<div class="wrap">
    <h1 class="afb-hide-default-title">Field Flow Config</h1>

    <div class="afb-admin-shell">
        <?php if ($selected_gid === ''): ?>
        <section class="afb-admin-hero-light w-100">
            <div class="flex flex-col gap-3 md:flex-row md:items-center md:justify-between">
                <div class="flex items-start gap-3">
                    <span class="afb-admin-hero-icon" aria-hidden="true">&#9881;</span>
                    <div>
                        <h2 class="text-2xl font-semibold m-0 text-slate-900">Field Flow Builder</h2>
                        <p class="text-sm text-slate-600 mt-1 mb-0">Open a project below to manage its dedicated field flow configuration page.</p>
                    </div>
                </div>
                <div class="text-xs text-slate-500">One page per project</div>
            </div>
        </section>
        <?php endif; ?>

        <section class="afb-admin-card mt-4">
            <div class="afb-admin-card-pad">
                <?php if ($selected_gid === ''): ?>
                    <div class="flex items-center justify-between gap-3 mb-3">
                        <div>
                            <h3 class="text-base font-semibold text-slate-900 m-0">Projects</h3>
                            <p class="text-xs text-slate-500 mt-1 mb-0">Choose a project to open its dedicated field flow config page.</p>
                        </div>
                        <span class="text-xs text-slate-500"><?= esc_html((string) count($projects)) ?> total</span>
                    </div>

                    <?php if (empty($projects)): ?>
                        <p class="text-sm text-slate-600 m-0">No projects found. Check your Asana account connection and portfolio settings.</p>
                    <?php else: ?>
                        <table class="widefat striped">
                            <thead>
                                <tr>
                                    <th scope="col">Project</th>
                                    <th scope="col">Project ID</th>
                                    <th scope="col" class="text-right">Action</th>
                                </tr>
                            </thead>
                            <tbody>
                                <?php foreach ((array) $projects as $project):
                                    $project_gid = (string) ($project['gid'] ?? '');
                                    if ($project_gid === '') continue;
                                    $edit_url = add_query_arg(
                                        [
                                            'page' => 'asana-field-flow',
                                            'project_gid' => $project_gid,
                                        ],
                                        admin_url('admin.php')
                                    );
                                ?>
                                    <tr>
                                        <td>
                                            <strong><?= esc_html($project['name'] ?? '(Unnamed project)') ?></strong>
                                        </td>
                                        <td><code><?= esc_html($project_gid) ?></code></td>
                                        <td class="text-right">
                                            <a href="<?= esc_url($edit_url) ?>" class="button button-primary">Edit Field Flow</a>
                                        </td>
                                    </tr>
                                <?php endforeach; ?>
                            </tbody>
                        </table>
                    <?php endif; ?>
                <?php else:
                    $back_url = add_query_arg(
                        [
                            'page' => 'asana-field-flow',
                        ],
                        admin_url('admin.php')
                    );
                ?>
                    <?php $preview_url = home_url('/asana-form/' . rawurlencode($selected_gid) . '/'); ?>
                    <div class="flex items-center justify-between gap-3">
                        <div>
                            <h3 class="text-base font-semibold text-slate-900 m-0">Project Config Page</h3>
                            <p class="text-xs text-slate-500 mt-1 mb-0">This URL is dedicated to one project and can be bookmarked.</p>
                        </div>
                        <div class="flex items-center gap-2">
                            <a href="<?= esc_url($preview_url) ?>" class="button button-primary" target="_blank" rel="noopener noreferrer">Preview Form</a>
                            <a href="<?= esc_url($back_url) ?>" class="button">Back to all projects</a>
                        </div>
                    </div>
                <?php endif; ?>
            </div>
        </section>

<?php if ($selected_gid !== ''):
    $cfg          = $field_config[$selected_gid] ?? [];

    $allow_uploads            = $cfg['allow_uploads'] ?? false;
    $form_title               = $cfg['form_title'] ?? '';
    $private_data_companion_enabled = !empty($cfg['private_data_companion_enabled']);
    $private_companion_depends_on_main = !empty($cfg['private_companion_depends_on_main']);
    $private_data_project_gid = sanitize_text_field((string) ($cfg['private_data_project_gid'] ?? ''));
    $private_companion_upload_mode = sanitize_text_field((string) ($cfg['private_companion_upload_mode'] ?? 'main_only'));
    if (!in_array($private_companion_upload_mode, ['main_only', 'copy_to_companion', 'companion_only'], true)) {
        $private_companion_upload_mode = 'main_only';
    }
    $private_companion_field_targets = [];
    if (!empty($cfg['private_companion_field_targets']) && is_array($cfg['private_companion_field_targets'])) {
        foreach ($cfg['private_companion_field_targets'] as $source_id => $target_gid_raw) {
            $source_id = sanitize_text_field((string) $source_id);
            $target_gid = sanitize_text_field((string) $target_gid_raw);
            if ($source_id === '' || $target_gid === '' || !ctype_digit($target_gid)) {
                continue;
            }

            $private_companion_field_targets[$source_id] = $target_gid;
        }
    }

    $used_fields              = $cfg['used_fields'] ?? [];
    $required_fields          = $cfg['required_fields'] ?? [];
    $hidden_fields            = $cfg['hidden_fields'] ?? [];
    $readonly_fields          = $cfg['readonly_fields'] ?? [];
    $paragraph_fields         = $cfg['paragraph_fields'] ?? [];
    $custom_paragraphs        = $cfg['custom_paragraphs'] ?? [];
    $custom_paragraph_titles  = $cfg['custom_paragraph_titles'] ?? [];

    $custom_sections          = $cfg['custom_sections'] ?? [];
    $custom_section_titles    = $cfg['custom_section_titles'] ?? [];
    $submit_block_fields      = is_array($cfg['submit_block_fields'] ?? null)
        ? $cfg['submit_block_fields']
        : [];
    $custom_agreement_labels  = $cfg['custom_agreement_labels'] ?? [];
    $custom_agreement_details = $cfg['custom_agreement_details'] ?? [];
    $agreement_required_configured = array_key_exists('agreement_required_fields', $cfg);
    $agreement_required_fields = $agreement_required_configured && is_array($cfg['agreement_required_fields'])
        ? $cfg['agreement_required_fields']
        : [];
    $agreement_description_fields = is_array($cfg['agreement_description_fields'] ?? null)
        ? $cfg['agreement_description_fields']
        : [];
    $custom_upload_titles     = $cfg['custom_upload_titles'] ?? [];
    $custom_upload_details    = $cfg['custom_upload_details'] ?? [];
    $custom_upload_min_files  = $cfg['custom_upload_min_files'] ?? [];
    $custom_upload_private_modes = is_array($cfg['custom_upload_private_modes'] ?? null)
        ? $cfg['custom_upload_private_modes']
        : [];
    $custom_upload_accept_types = is_array($cfg['custom_upload_accept_types'] ?? null)
        ? $cfg['custom_upload_accept_types']
        : [];
    $custom_upload_compress_images_raw = is_array($cfg['custom_upload_compress_images'] ?? null)
        ? $cfg['custom_upload_compress_images']
        : [];
    $custom_upload_compress_images = [];
    foreach ($custom_upload_compress_images_raw as $key => $value) {
        if (is_string($value) && $value !== '') {
            $custom_upload_compress_images[] = $value;
            continue;
        }

        if (is_string($key) && $key !== '' && !is_int($key)) {
            $custom_upload_compress_images[] = $key;
        }
    }
    $custom_upload_compress_images = array_values(array_unique($custom_upload_compress_images));
    $custom_upload_compress_images_configured = array_key_exists('custom_upload_compress_images', $cfg);
    $custom_upload_max_file_mb_raw = is_array($cfg['custom_upload_max_file_mb'] ?? null)
        ? $cfg['custom_upload_max_file_mb']
        : [];
    $custom_upload_max_file_mb = [];
    foreach ($custom_upload_max_file_mb_raw as $upload_id_raw => $max_file_mb_raw) {
        $upload_id = sanitize_text_field((string) $upload_id_raw);
        if ($upload_id === '' || strpos($upload_id, 'upload_') !== 0) {
            continue;
        }

        $max_file_mb = (float) $max_file_mb_raw;
        if ($max_file_mb <= 0) {
            continue;
        }

        $custom_upload_max_file_mb[$upload_id] = min(512, round($max_file_mb, 2));
    }
    $custom_upload_max_width_px_raw = is_array($cfg['custom_upload_max_width_px'] ?? null)
        ? $cfg['custom_upload_max_width_px']
        : [];
    $custom_upload_max_width_px = [];
    foreach ($custom_upload_max_width_px_raw as $upload_id_raw => $max_width_raw) {
        $upload_id = sanitize_text_field((string) $upload_id_raw);
        if ($upload_id === '' || strpos($upload_id, 'upload_') !== 0) {
            continue;
        }

        $max_width = (int) round((float) $max_width_raw);
        if ($max_width <= 0) {
            continue;
        }

        $custom_upload_max_width_px[$upload_id] = max(100, min(4000, $max_width));
    }
    $custom_upload_compress_quality_raw = is_array($cfg['custom_upload_compress_quality'] ?? null)
        ? $cfg['custom_upload_compress_quality']
        : [];
    $custom_upload_compress_quality = [];
    foreach ($custom_upload_compress_quality_raw as $upload_id_raw => $quality_raw) {
        $upload_id = sanitize_text_field((string) $upload_id_raw);
        if ($upload_id === '' || strpos($upload_id, 'upload_') !== 0) {
            continue;
        }

        $quality = (float) $quality_raw;
        if ($quality <= 0) {
            continue;
        }

        $custom_upload_compress_quality[$upload_id] = max(1, min(100, (int) round($quality)));
    }
    $custom_single_input_labels = $cfg['custom_single_input_labels'] ?? [];
    $custom_single_input_descriptions = $cfg['custom_single_input_descriptions'] ?? [];
    $custom_single_input_placeholders = $cfg['custom_single_input_placeholders'] ?? [];
    $custom_single_input_sync_fields = $cfg['custom_single_input_sync_fields'] ?? [];
    $custom_single_input_modes = is_array($cfg['custom_single_input_modes'] ?? null)
        ? $cfg['custom_single_input_modes']
        : [];
    $custom_single_input_max_words_enabled_raw = is_array($cfg['custom_single_input_max_words_enabled'] ?? null)
        ? $cfg['custom_single_input_max_words_enabled']
        : [];
    $custom_single_input_max_words_enabled = [];
    foreach ($custom_single_input_max_words_enabled_raw as $key => $value) {
        if (is_string($value) && $value !== '') {
            $custom_single_input_max_words_enabled[] = $value;
            continue;
        }

        if (is_string($key) && $key !== '' && !is_int($key)) {
            $custom_single_input_max_words_enabled[] = $key;
        }
    }
    $custom_single_input_max_words_enabled = array_values(array_unique($custom_single_input_max_words_enabled));

    $custom_single_input_max_words_raw = is_array($cfg['custom_single_input_max_words'] ?? null)
        ? $cfg['custom_single_input_max_words']
        : [];
    $custom_single_input_max_words = [];
    foreach ($custom_single_input_max_words_raw as $single_id => $max_words_raw) {
        $single_id = sanitize_text_field((string) $single_id);
        if ($single_id === '') {
            continue;
        }

        $custom_single_input_max_words[$single_id] = max(0, absint($max_words_raw));
    }
    $custom_single_input_ai_enabled_raw = is_array($cfg['custom_single_input_ai_enabled'] ?? null)
        ? $cfg['custom_single_input_ai_enabled']
        : [];
    $custom_single_input_ai_enabled = [];
    foreach ($custom_single_input_ai_enabled_raw as $key => $value) {
        if (is_string($value) && $value !== '') {
            $custom_single_input_ai_enabled[] = $value;
            continue;
        }

        if (is_string($key) && $key !== '' && !is_int($key)) {
            $custom_single_input_ai_enabled[] = $key;
        }
    }
    $custom_single_input_ai_enabled = array_values(array_unique($custom_single_input_ai_enabled));
    $custom_dropdown_labels = $cfg['custom_dropdown_labels'] ?? [];
    $custom_dropdown_descriptions = $cfg['custom_dropdown_descriptions'] ?? [];
    $custom_dropdown_placeholders = $cfg['custom_dropdown_placeholders'] ?? [];
    $custom_dropdown_options = $cfg['custom_dropdown_options'] ?? [];
    $custom_dropdown_selection_modes = $cfg['custom_dropdown_selection_modes'] ?? [];
    $custom_dropdown_sync_fields = $cfg['custom_dropdown_sync_fields'] ?? [];
    $custom_calendar_labels = $cfg['custom_calendar_labels'] ?? [];
    $custom_calendar_descriptions = $cfg['custom_calendar_descriptions'] ?? [];
    $custom_calendar_placeholders = $cfg['custom_calendar_placeholders'] ?? [];
    $custom_calendar_sync_modes = $cfg['custom_calendar_sync_modes'] ?? [];
    $custom_calendar_sync_fields = $cfg['custom_calendar_sync_fields'] ?? [];
    $custom_repeater_labels = $cfg['custom_repeater_labels'] ?? [];
    $custom_repeater_descriptions = $cfg['custom_repeater_descriptions'] ?? [];
    $custom_repeater_save_mode_raw = is_array($cfg['custom_repeater_save_mode'] ?? null)
        ? $cfg['custom_repeater_save_mode']
        : [];
    $custom_repeater_save_mode = [];
    foreach ($custom_repeater_save_mode_raw as $repeater_id_raw => $save_mode_raw) {
        $repeater_id = sanitize_text_field((string) $repeater_id_raw);
        if ($repeater_id === '') {
            continue;
        }

        $save_mode = sanitize_text_field((string) $save_mode_raw);
        $custom_repeater_save_mode[$repeater_id] = ($save_mode === 'description') ? 'description' : 'subtasks';
    }
    $custom_repeater_columns = is_array($cfg['custom_repeater_columns'] ?? null)
        ? $cfg['custom_repeater_columns']
        : [];
    $custom_repeater_min_rows_raw = is_array($cfg['custom_repeater_min_rows'] ?? null)
        ? $cfg['custom_repeater_min_rows']
        : [];
    $custom_repeater_min_rows = [];
    foreach ($custom_repeater_min_rows_raw as $repeater_id => $min_rows_raw) {
        $repeater_id = sanitize_text_field((string) $repeater_id);
        if ($repeater_id === '') {
            continue;
        }

        $custom_repeater_min_rows[$repeater_id] = max(0, min(250, absint($min_rows_raw)));
    }
    $custom_repeater_max_rows_raw = is_array($cfg['custom_repeater_max_rows'] ?? null)
        ? $cfg['custom_repeater_max_rows']
        : [];
    $custom_repeater_max_rows = [];
    foreach ($custom_repeater_max_rows_raw as $repeater_id => $max_rows_raw) {
        $repeater_id = sanitize_text_field((string) $repeater_id);
        if ($repeater_id === '') {
            continue;
        }

        $max_rows = max(0, min(250, absint($max_rows_raw)));
        if ($max_rows <= 0) {
            continue;
        }

        $custom_repeater_max_rows[$repeater_id] = $max_rows;
    }
    foreach ($custom_repeater_min_rows as $repeater_id => $min_rows) {
        if (!isset($custom_repeater_max_rows[$repeater_id])) {
            continue;
        }

        if ((int) $custom_repeater_max_rows[$repeater_id] < (int) $min_rows) {
            $custom_repeater_max_rows[$repeater_id] = (int) $min_rows;
        }
    }
    $custom_repeater_field_map_raw = is_array($cfg['custom_repeater_field_map'] ?? null)
        ? $cfg['custom_repeater_field_map']
        : [];
    $custom_repeater_field_map = [];
    foreach ($custom_repeater_field_map_raw as $repeater_id => $mapped_gids_raw) {
        $repeater_id = sanitize_text_field((string) $repeater_id);
        if ($repeater_id === '') {
            continue;
        }

        $mapped_gids = is_array($mapped_gids_raw)
            ? $mapped_gids_raw
            : [$mapped_gids_raw];

        $cleaned = [];
        $seen = [];
        foreach ($mapped_gids as $mapped_gid_raw) {
            $mapped_gid = sanitize_text_field((string) $mapped_gid_raw);
            if ($mapped_gid === '' || !ctype_digit($mapped_gid) || isset($seen[$mapped_gid])) {
                continue;
            }

            $seen[$mapped_gid] = true;
            $cleaned[] = $mapped_gid;
        }

        if (!empty($cleaned)) {
            $custom_repeater_field_map[$repeater_id] = $cleaned;
        }
    }
    $custom_text_sync_fields = is_array($cfg['custom_text_sync_fields'] ?? null)
        ? $cfg['custom_text_sync_fields']
        : [];
    $custom_calendar_preset_modes = $cfg['custom_calendar_preset_modes'] ?? [];
    $custom_task_name_labels = $cfg['custom_task_name_labels'] ?? [];
    $custom_task_name_templates = $cfg['custom_task_name_templates'] ?? [];
    $private_companion_task_name_mode = sanitize_text_field((string) ($cfg['private_companion_task_name_mode'] ?? 'use_main'));
    if (!in_array($private_companion_task_name_mode, ['use_main', 'use_job_number', 'use_template'], true)) {
        $private_companion_task_name_mode = 'use_main';
    }
    $private_companion_task_name_template = sanitize_text_field((string) ($cfg['private_companion_task_name_template'] ?? ''));
    $custom_due_date_configs = is_array($cfg['custom_due_date_configs'] ?? null)
        ? $cfg['custom_due_date_configs']
        : [];
    $custom_assignee_labels = is_array($cfg['custom_assignee_labels'] ?? null)
        ? $cfg['custom_assignee_labels']
        : [];
    $custom_assignee_configs = is_array($cfg['custom_assignee_configs'] ?? null)
        ? $cfg['custom_assignee_configs']
        : [];
    $custom_recipient_labels = is_array($cfg['custom_recipient_labels'] ?? null)
        ? $cfg['custom_recipient_labels']
        : [];
    $custom_recipient_configs = is_array($cfg['custom_recipient_configs'] ?? null)
        ? $cfg['custom_recipient_configs']
        : [];
    $visible_enum_options     = $cfg['visible_enum_options'] ?? [];
    $option_visibility_rules  = $cfg['option_visibility_rules'] ?? [];

    $conditions               = $cfg['conditions'] ?? [];
    $labels                   = $cfg['labels'] ?? [];
    $descriptions             = $cfg['descriptions'] ?? [];
    $half_width_fields        = $cfg['half_width_fields'] ?? [];
    $third_width_fields       = $cfg['third_width_fields'] ?? [];
    if (!empty($half_width_fields) && !empty($third_width_fields)) {
        $half_width_fields = array_values(array_diff((array) $half_width_fields, (array) $third_width_fields));
    }

    $project_pat = null;
    $project_name = '';

    foreach ((array) $projects as $proj) {
        if (($proj['gid'] ?? '') === $selected_gid) {
            $project_pat = $proj['__pat'] ?? null;
            $project_name = $proj['name'] ?? '';
            break;
        }
    }

    $fields_raw = afb_get_project_fields($selected_gid, $project_pat);

    $field_map = [];
    foreach ((array) $fields_raw as $setting) {
        $f = $setting['custom_field'] ?? null;
        if (!$f || empty($f['gid'])) continue;
        $field_map[(string) $f['gid']] = $setting;
    }

    $notes_id = '__NOTES_HTML__';
    if (!isset($field_map[$notes_id])) {
        $field_map[$notes_id] = [
            'custom_field' => [
                'gid'          => $notes_id,
                'name'         => $labels[$notes_id] ?? 'Notes',
                'type'         => 'notes_html',
                'enum_options' => [],
            ]
        ];
    }

    $text_sync_targets = [];
    foreach ((array) $field_map as $sync_gid => $sync_setting) {
        $sync_field = $sync_setting['custom_field'] ?? [];
        $sync_type = (string) ($sync_field['type'] ?? '');
        if ($sync_gid === $notes_id || $sync_type !== 'text') {
            continue;
        }

        $text_sync_targets[$sync_gid] = (string) ($sync_field['name'] ?? $sync_gid);
    }

    $private_field_targets = [];
    $private_text_field_targets = [];
    $private_calendar_field_targets = [];
    $private_target_project_name = '';

    if ($private_data_project_gid !== '') {
        $private_project_pat = '';
        foreach ((array) $projects as $proj) {
            $proj_gid = (string) ($proj['gid'] ?? '');
            if ($proj_gid !== $private_data_project_gid) {
                continue;
            }

            $private_project_pat = (string) ($proj['__pat'] ?? '');
            $private_target_project_name = (string) ($proj['name'] ?? '');
            break;
        }

        if ($private_project_pat !== '') {
            $private_fields_raw = afb_get_project_fields($private_data_project_gid, $private_project_pat);
            foreach ((array) $private_fields_raw as $private_setting) {
                $private_field = $private_setting['custom_field'] ?? [];
                $private_gid = (string) ($private_field['gid'] ?? '');
                if ($private_gid === '') {
                    continue;
                }

                $private_name = (string) ($private_field['name'] ?? $private_gid);
                $private_type = strtolower((string) ($private_field['type'] ?? 'text'));
                if ($private_type === '') {
                    $private_type = 'text';
                }

                $private_field_targets[$private_gid] = [
                    'name' => $private_name,
                    'type' => $private_type,
                    'label' => $private_name . ' (' . $private_gid . ') [' . $private_type . ']',
                ];

                if ($private_type === 'text') {
                    $private_text_field_targets[$private_gid] = $private_field_targets[$private_gid];
                }

                if (in_array($private_type, ['text', 'date'], true)) {
                    $private_calendar_field_targets[$private_gid] = $private_field_targets[$private_gid];
                }
            }
        }
    }

    $fields = [];
    $ordered_ids_raw = $cfg['field_order'] ?? [];
    $ordered_ids = [];
    if (is_array($ordered_ids_raw)) {
        foreach ($ordered_ids_raw as $key => $value) {
            if (is_string($value) && $value !== '') {
                $ordered_ids[] = $value;
                continue;
            }
            if (is_string($key) && $key !== '' && !is_int($key)) {
                $ordered_ids[] = $key;
            }
        }
    }
    if (empty($ordered_ids)) {
        $ordered_ids = array_values(array_unique(array_filter(array_merge(
            array_keys((array) $custom_paragraph_titles),
            array_keys((array) $custom_section_titles),
            array_keys((array) $custom_agreement_labels),
            array_keys((array) $custom_upload_titles),
            array_keys((array) $custom_single_input_labels),
            array_keys((array) $custom_dropdown_labels),
            array_keys((array) $custom_calendar_labels),
            array_keys((array) $custom_repeater_labels),
            array_keys((array) $custom_repeater_field_map),
            array_keys((array) $custom_task_name_labels),
            array_keys((array) $custom_task_name_templates),
            array_keys((array) $custom_due_date_configs),
            array_keys((array) $custom_assignee_labels),
            array_keys((array) $custom_assignee_configs),
            array_keys((array) $custom_recipient_labels),
            array_keys((array) $custom_recipient_configs),
            array_map('strval', (array) $used_fields)
        ), static function ($id) {
            return is_string($id) && $id !== '';
        })));
    }

    // Legacy migration: old configs used allow_uploads without upload_* entries.
    // Surface this as a normal upload block so the admin UI only has one upload model.
    $has_upload_block = false;
    foreach ((array) $ordered_ids as $ordered_id) {
        if (is_string($ordered_id) && strpos($ordered_id, 'upload_') === 0) {
            $has_upload_block = true;
            break;
        }
    }
    if ($allow_uploads && !$has_upload_block) {
        $legacy_upload_id = 'upload_legacy_optional';
        $legacy_suffix = 1;
        while (in_array($legacy_upload_id, $ordered_ids, true)) {
            $legacy_upload_id = 'upload_legacy_optional_' . $legacy_suffix;
            $legacy_suffix++;
        }

        $ordered_ids[] = $legacy_upload_id;

        if (!isset($custom_upload_titles[$legacy_upload_id]) || trim((string) $custom_upload_titles[$legacy_upload_id]) === '') {
            $custom_upload_titles[$legacy_upload_id] = 'File Uploads';
        }
        if (!isset($custom_upload_details[$legacy_upload_id]) || trim((string) $custom_upload_details[$legacy_upload_id]) === '') {
            $custom_upload_details[$legacy_upload_id] = 'Please upload any relevant documents to this request. We have a maximum upload size of 64MB.';
        }
        if (!isset($custom_upload_min_files[$legacy_upload_id])) {
            $custom_upload_min_files[$legacy_upload_id] = 0;
        }
    }

    $seen_ordered_ids = [];
    $used_field_map_ids = [];

    foreach ((array) $ordered_ids as $id) {
        if (!is_string($id) || $id === '' || isset($seen_ordered_ids[$id])) {
            continue;
        }
        $seen_ordered_ids[$id] = true;

        if (strpos($id, 'para_') === 0) {
            $fields[] = [
                'type'    => 'paragraph',
                'id'      => $id,
                'title'   => $custom_paragraph_titles[$id] ?? '',
                'content' => $custom_paragraphs[$id] ?? '',
            ];
            continue;
        }

        if (strpos($id, 'section_') === 0) {
            $fields[] = [
                'type' => 'section',
                'id'   => $id,
            ];
            continue;
        }

        if (strpos($id, 'agree_') === 0) {
            $agreement_is_required = $agreement_required_configured
                ? in_array($id, $agreement_required_fields, true)
                : true;
            $fields[] = [
                'type'        => 'agreement',
                'id'          => $id,
                'label'       => $custom_agreement_labels[$id] ?? '',
                'description' => $custom_agreement_details[$id] ?? '',
                'required'    => $agreement_is_required,
            ];
            continue;
        }

        if (strpos($id, 'upload_') === 0) {
            $upload_private_mode = sanitize_text_field((string) ($custom_upload_private_modes[$id] ?? 'use_project_default'));
            if (!in_array($upload_private_mode, ['use_project_default', 'main_only', 'copy_to_companion', 'companion_only'], true)) {
                $upload_private_mode = 'use_project_default';
            }

            $upload_accept_types = sanitize_text_field((string) ($custom_upload_accept_types[$id] ?? ''));
            $upload_compress_images = $custom_upload_compress_images_configured
                ? in_array($id, $custom_upload_compress_images, true)
                : true;
            $upload_max_file_mb = max(0.0, (float) ($custom_upload_max_file_mb[$id] ?? 0));
            $upload_max_width_px = max(100, min(4000, (int) ($custom_upload_max_width_px[$id] ?? 1200)));
            $upload_compress_quality = max(1, min(100, (int) ($custom_upload_compress_quality[$id] ?? 60)));

            $fields[] = [
                'type'        => 'upload',
                'id'          => $id,
                'title'       => $custom_upload_titles[$id] ?? '',
                'description' => $custom_upload_details[$id] ?? '',
                'min_files'   => (int) ($custom_upload_min_files[$id] ?? 0),
                'private_upload_mode' => $upload_private_mode,
                'accept_types' => $upload_accept_types,
                'compress_images' => $upload_compress_images,
                'max_file_mb' => $upload_max_file_mb,
                'compress_max_width' => $upload_max_width_px,
                'compress_quality' => $upload_compress_quality,
            ];
            continue;
        }

        if (strpos($id, 'single_') === 0) {
            $single_mode = (string) ($custom_single_input_modes[$id] ?? 'text');
            if (!in_array($single_mode, ['text', 'textarea'], true)) {
                $single_mode = 'text';
            }

            $single_max_words_enabled = in_array($id, (array) $custom_single_input_max_words_enabled, true);
            $single_max_words = max(0, (int) ($custom_single_input_max_words[$id] ?? 0));

            $fields[] = [
                'type'        => 'single_input',
                'id'          => $id,
                'label'       => $custom_single_input_labels[$id] ?? '',
                'description' => $custom_single_input_descriptions[$id] ?? '',
                'placeholder' => $custom_single_input_placeholders[$id] ?? '',
                'sync_field'  => $custom_single_input_sync_fields[$id] ?? '',
                'input_mode'  => $single_mode,
                'max_words_enabled' => $single_max_words_enabled,
                'max_words'   => $single_max_words,
            ];
            continue;
        }

        if (strpos($id, 'dropdown_') === 0) {
            $fields[] = [
                'type'        => 'dropdown',
                'id'          => $id,
                'label'       => $custom_dropdown_labels[$id] ?? '',
                'description' => $custom_dropdown_descriptions[$id] ?? '',
                'placeholder' => $custom_dropdown_placeholders[$id] ?? '',
                'options'     => $custom_dropdown_options[$id] ?? '',
                'selection_mode' => $custom_dropdown_selection_modes[$id] ?? '',
                'sync_field'  => $custom_dropdown_sync_fields[$id] ?? '',
            ];
            continue;
        }

        if (strpos($id, 'calendar_') === 0) {
            $fields[] = [
                'type'        => 'calendar',
                'id'          => $id,
                'label'       => $custom_calendar_labels[$id] ?? '',
                'description' => $custom_calendar_descriptions[$id] ?? '',
                'placeholder' => $custom_calendar_placeholders[$id] ?? '',
                'sync_mode'   => $custom_calendar_sync_modes[$id] ?? '',
                'sync_field'  => $custom_calendar_sync_fields[$id] ?? '',
                'preset_mode' => $custom_calendar_preset_modes[$id] ?? '',
            ];
            continue;
        }

        if (strpos($id, 'repeater_') === 0) {
            $fields[] = [
                'type'        => 'repeater',
                'id'          => $id,
                'label'       => $custom_repeater_labels[$id] ?? '',
                'description' => $custom_repeater_descriptions[$id] ?? '',
                'save_mode'   => $custom_repeater_save_mode[$id] ?? 'subtasks',
                'columns'     => $custom_repeater_columns[$id] ?? '',
                'min_rows'    => (int) ($custom_repeater_min_rows[$id] ?? 0),
                'max_rows'    => (int) ($custom_repeater_max_rows[$id] ?? 0),
                'field_map'   => $custom_repeater_field_map[$id] ?? [],
            ];
            continue;
        }

        if (strpos($id, 'task_name_') === 0) {
            $fields[] = [
                'type'     => 'task_name',
                'id'       => $id,
                'label'    => $custom_task_name_labels[$id] ?? '',
                'template' => $custom_task_name_templates[$id] ?? '',
            ];
            continue;
        }

        if (strpos($id, 'due_date_') === 0) {
            $fields[] = [
                'type'   => 'due_date_tool',
                'id'     => $id,
                'config' => $custom_due_date_configs[$id] ?? [],
            ];
            continue;
        }

        if (strpos($id, 'assignee_') === 0) {
            $fields[] = [
                'type'   => 'assignee_tool',
                'id'     => $id,
                'label'  => $custom_assignee_labels[$id] ?? '',
                'config' => $custom_assignee_configs[$id] ?? [],
            ];
            continue;
        }

        if (strpos($id, 'recipient_') === 0) {
            $fields[] = [
                'type'   => 'recipient_tool',
                'id'     => $id,
                'label'  => $custom_recipient_labels[$id] ?? '',
                'config' => $custom_recipient_configs[$id] ?? [],
            ];
            continue;
        }

        if (isset($field_map[$id])) {
            $fields[] = $field_map[$id];
            $used_field_map_ids[$id] = true;
        }
    }

    foreach ($field_map as $gid => $setting) {
        if (isset($used_field_map_ids[$gid])) {
            continue;
        }
        $fields[] = $setting;
    }

    $afb_normalize_condition = static function ($cond) {
        $logic = 'all';
        $rules = [];

        if (is_array($cond) && isset($cond['logic']) && in_array((string) $cond['logic'], ['all', 'any'], true)) {
            $logic = (string) $cond['logic'];
        }

        if (is_array($cond) && !empty($cond['rules']) && is_array($cond['rules'])) {
            foreach ($cond['rules'] as $rule) {
                if (!is_array($rule)) continue;
                $source = (string) ($rule['depends_on'] ?? '');
                if ($source === '') continue;

                $vals = [];
                if (!empty($rule['values']) && is_array($rule['values'])) {
                    $vals = array_map('strval', $rule['values']);
                } elseif (isset($rule['value']) && $rule['value'] !== '') {
                    $vals = [(string) $rule['value']];
                }

                $vals = array_values(array_unique(array_filter($vals, static function ($val) {
                    return $val !== '';
                })));

                if (!empty($vals)) {
                    $rules[] = [
                        'depends_on' => $source,
                        'value'      => $vals[0],
                        'values'     => $vals,
                    ];
                }
            }
        } elseif (is_array($cond) && !empty($cond['depends_on'])) {
            $source = (string) $cond['depends_on'];
            $vals = [];
            if (!empty($cond['values']) && is_array($cond['values'])) {
                $vals = array_map('strval', $cond['values']);
            } elseif (!empty($cond['value'])) {
                $vals = [(string) $cond['value']];
            }
            $vals = array_values(array_unique(array_filter($vals, static function ($val) {
                return $val !== '';
            })));

            if ($source !== '' && !empty($vals)) {
                $rules[] = [
                    'depends_on' => $source,
                    'value'      => $vals[0],
                    'values'     => $vals,
                ];
            }
        }

        return [
            'logic' => $logic,
            'rules' => $rules,
        ];
    };

    $afb_render_condition_editor = static function ($target_id, $cond) use ($afb_normalize_condition) {
        $target_id = (string) $target_id;
        if ($target_id === '') return;

        $normalized = $afb_normalize_condition($cond);
        $logic = (string) ($normalized['logic'] ?? 'all');
        if (!in_array($logic, ['all', 'any'], true)) {
            $logic = 'all';
        }
        $rules_json = wp_json_encode($normalized['rules'] ?? []);
        if (!is_string($rules_json)) {
            $rules_json = '[]';
        }
        ?>
        <div class="afb-cond-editor afb-cond-section afb-collapsible-section is-collapsed" data-target="<?= esc_attr($target_id) ?>">
            <div class="afb-cond-header">
                <div class="afb-cond-header-title">
                    <svg fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor"><path stroke-linecap="round" stroke-linejoin="round" d="M12 3c2.755 0 5.455.232 8.083.678.533.09.917.556.917 1.096v1.044a2.25 2.25 0 0 1-.659 1.591l-5.432 5.432a2.25 2.25 0 0 0-.659 1.591v2.927a2.25 2.25 0 0 1-1.244 2.013L9.75 21v-6.568a2.25 2.25 0 0 0-.659-1.591L3.659 7.409A2.25 2.25 0 0 1 3 5.818V4.774c0-.54.384-1.006.917-1.096A48.32 48.32 0 0 1 12 3Z" /></svg>
                    <span>Conditions</span>
                </div>
                <div class="afb-cond-header-controls">
                    <button type="button" class="afb-admin-btn afb-section-toggle" aria-expanded="false">Show</button>
                    <select name="condition_logic[<?= esc_attr($target_id) ?>]" class="afb-cond-logic afb-cond-logic-select">
                        <option value="all" <?= selected($logic, 'all', false) ?>>Match all</option>
                        <option value="any" <?= selected($logic, 'any', false) ?>>Match any</option>
                    </select>
                    <button type="button" class="afb-cond-add-btn afb-cond-add">Add rule</button>
                </div>
            </div>
            <div class="afb-cond-body afb-collapsible-body">
                <div class="afb-cond-rules space-y-2"></div>
                <input
                    type="hidden"
                    name="condition_rules[<?= esc_attr($target_id) ?>]"
                    class="afb-cond-rules-input"
                    value='<?= esc_attr($rules_json) ?>'
                />
                <p class="text-xs text-slate-400 mt-3 mb-0">Each rule uses a source field and expected value(s).</p>
            </div>
        </div>
        <?php
    };

    $due_date_base_field_targets = [];
    $recipient_source_targets = [];
    foreach ((array) $fields as $candidate_setting) {
        if (!is_array($candidate_setting)) {
            continue;
        }

        $candidate_type = sanitize_text_field((string) ($candidate_setting['type'] ?? ''));
        $candidate_id = sanitize_text_field((string) ($candidate_setting['id'] ?? ''));
        if ($candidate_id !== '' && in_array($candidate_type, ['single_input', 'dropdown', 'calendar', 'agreement'], true)) {
            $candidate_label = '';
            if ($candidate_type === 'single_input') {
                $candidate_label = sanitize_text_field((string) ($custom_single_input_labels[$candidate_id] ?? ($candidate_setting['label'] ?? '')));
                if ($candidate_label === '') {
                    $candidate_label = 'Single Input Text';
                }
            } elseif ($candidate_type === 'dropdown') {
                $candidate_label = sanitize_text_field((string) ($custom_dropdown_labels[$candidate_id] ?? ($candidate_setting['label'] ?? '')));
                if ($candidate_label === '') {
                    $candidate_label = 'Dropdown';
                }
            } elseif ($candidate_type === 'calendar') {
                $candidate_label = sanitize_text_field((string) ($custom_calendar_labels[$candidate_id] ?? ($candidate_setting['label'] ?? '')));
                if ($candidate_label === '') {
                    $candidate_label = 'Calendar Picker';
                }
            } else {
                $candidate_label = sanitize_text_field((string) ($custom_agreement_labels[$candidate_id] ?? ($candidate_setting['label'] ?? '')));
                if ($candidate_label === '') {
                    $candidate_label = 'Agreement Checkbox';
                }
            }

            $recipient_source_targets[$candidate_id] = $candidate_label . ' (' . $candidate_id . ')';
        }

        if (($candidate_setting['type'] ?? '') === 'calendar') {
            $calendar_id = sanitize_text_field((string) ($candidate_setting['id'] ?? ''));
            if ($calendar_id === '') {
                continue;
            }

            $calendar_label = sanitize_text_field((string) ($custom_calendar_labels[$calendar_id] ?? ($candidate_setting['label'] ?? '')));
            if ($calendar_label === '') {
                $calendar_label = 'Calendar Picker';
            }

            $due_date_base_field_targets[$calendar_id] = $calendar_label . ' (' . $calendar_id . ')';
            continue;
        }

        if (!empty($candidate_setting['custom_field']) && is_array($candidate_setting['custom_field'])) {
            $cf = $candidate_setting['custom_field'];
            $cf_gid = sanitize_text_field((string) ($cf['gid'] ?? ''));
            $cf_type = strtolower((string) ($cf['type'] ?? ''));
            $cf_name = sanitize_text_field((string) ($cf['name'] ?? $cf_gid));
            if ($cf_gid !== '' && in_array($cf_type, ['text', 'number'], true)) {
                $recipient_source_targets[$cf_gid] = $cf_name . ' (' . $cf_gid . ')';
            }
            if ($cf_gid === '' || $cf_type !== 'date') {
                continue;
            }
            $due_date_base_field_targets[$cf_gid] = $cf_name . ' (' . $cf_gid . ')';
        }
    }

    $assignee_member_map = [];
    if ($selected_gid !== '' && is_string($project_pat) && $project_pat !== '') {
        $memberships = afb_fetch_asana(
            'memberships?parent=' . rawurlencode($selected_gid) . '&limit=100&opt_fields=member.gid,member.name,member.resource_type',
            $project_pat
        );

        foreach ((array) $memberships as $membership) {
            if (!is_array($membership) || empty($membership['member']) || !is_array($membership['member'])) {
                continue;
            }

            $member = $membership['member'];
            $member_gid = sanitize_text_field((string) ($member['gid'] ?? ''));
            $member_gid = preg_replace('/\D+/', '', $member_gid);
            if (!is_string($member_gid) || $member_gid === '' || isset($assignee_member_map[$member_gid])) {
                continue;
            }

            $member_name = sanitize_text_field((string) ($member['name'] ?? ''));
            if ($member_name === '') {
                $member_name = 'User ' . $member_gid;
            }

            $assignee_member_map[$member_gid] = [
                'gid'  => $member_gid,
                'name' => $member_name,
            ];
        }
    }

    foreach ((array) $custom_assignee_configs as $assignee_cfg) {
        if (!is_array($assignee_cfg)) {
            continue;
        }

        $config_gids = [];
        $default_gid = sanitize_text_field((string) ($assignee_cfg['default_assignee'] ?? ''));
        if ($default_gid !== '') {
            $config_gids[] = $default_gid;
        }

        $default_fallbacks = [];
        if (!empty($assignee_cfg['default_fallback_assignees']) && is_array($assignee_cfg['default_fallback_assignees'])) {
            $default_fallbacks = $assignee_cfg['default_fallback_assignees'];
        } elseif (!empty($assignee_cfg['fallback_assignees']) && is_array($assignee_cfg['fallback_assignees'])) {
            $default_fallbacks = $assignee_cfg['fallback_assignees'];
        }
        $config_gids = array_merge($config_gids, $default_fallbacks);

        $rules = isset($assignee_cfg['rules']) && is_array($assignee_cfg['rules'])
            ? $assignee_cfg['rules']
            : [];
        foreach ($rules as $rule) {
            if (!is_array($rule)) {
                continue;
            }

            $rule_gid = sanitize_text_field((string) ($rule['assignee'] ?? ''));
            if ($rule_gid !== '') {
                $config_gids[] = $rule_gid;
            }

            $rule_fallbacks = isset($rule['fallback_assignees']) && is_array($rule['fallback_assignees'])
                ? $rule['fallback_assignees']
                : [];
            $config_gids = array_merge($config_gids, $rule_fallbacks);
        }

        foreach ($config_gids as $raw_gid) {
            $clean_gid = sanitize_text_field((string) $raw_gid);
            $clean_gid = preg_replace('/\D+/', '', $clean_gid);
            if (!is_string($clean_gid) || $clean_gid === '' || isset($assignee_member_map[$clean_gid])) {
                continue;
            }

            $assignee_member_map[$clean_gid] = [
                'gid'  => $clean_gid,
                'name' => 'User ' . $clean_gid,
            ];
        }
    }

    $assignee_member_options = array_values($assignee_member_map);
    usort($assignee_member_options, static function ($a, $b) {
        return strcasecmp((string) ($a['name'] ?? ''), (string) ($b['name'] ?? ''));
    });

    $assignee_member_options_json = wp_json_encode($assignee_member_options);
    if (!is_string($assignee_member_options_json)) {
        $assignee_member_options_json = '[]';
    }
?>

        <section class="afb-admin-card mt-4">
            <form method="post">
                <?php wp_nonce_field('afb_field_flow_save', 'afb_field_flow_nonce'); ?>
                <input type="hidden" name="config_project_gid" value="<?= esc_attr($selected_gid) ?>" />

                <div class="afb-page-toolbar">
                    <div class="afb-toolbar-project">
                        <p class="afb-toolbar-label">Editing project</p>
                        <h3 class="afb-toolbar-title"><?= esc_html($project_name) ?></h3>
                    </div>
                    <div class="afb-toolbar-form-title">
                        <label class="afb-toolbar-input-label" for="afb-form-title">Form title</label>
                        <input id="afb-form-title" type="text" name="form_title" value="<?= esc_attr($form_title) ?>" class="afb-admin-input" placeholder="Public form title">
                    </div>
                    <div class="afb-toolbar-actions">
                        <span class="afb-toolbar-count"><strong><?= count($fields) ?></strong> blocks</span>
                        <button type="button" class="afb-admin-btn afb-collapse-all">Collapse All</button>
                        <button type="button" class="afb-admin-btn afb-expand-all">Expand All</button>
                        <button type="submit" class="afb-admin-btn-primary">Save Field Flow</button>
                    </div>
                </div>

                <div class="p-4 md:p-5">
                <div class="afb-admin-card afb-admin-card-pad mb-4">
                    <div class="flex items-start justify-between gap-3">
                        <div>
                            <h4 class="text-sm font-semibold text-slate-900 m-0">Private Data Companion Task</h4>
                            <p class="text-xs text-slate-500 mt-1 mb-0">When enabled, each submission creates an additional companion task in your private project. You can point multiple source projects at the same private destination.</p>
                            <p class="text-xs text-slate-500 mt-1 mb-0">Per-field destination mapping is configured inside each field/block editor below.</p>
                        </div>
                    </div>

                    <div class="grid gap-3 md:grid-cols-2 mt-3">
                        <label class="afb-flag-toggle">
                            <input type="checkbox" class="afb-admin-check" name="private_data_companion_enabled" value="1" <?= $private_data_companion_enabled ? 'checked' : '' ?> />
                            Create private companion task for each submission
                        </label>

                        <div>
                            <label class="afb-flag-toggle">
                                <input type="checkbox" class="afb-admin-check" name="private_companion_depends_on_main" value="1" <?= $private_companion_depends_on_main ? 'checked' : '' ?> />
                                Make companion task dependent on main task
                            </label>
                            <p class="text-xs text-slate-400 mt-1 mb-0">When enabled, the companion task waits on the main task via Asana dependency linking.</p>
                        </div>

                        <div>
                            <label class="block text-xs text-slate-600 mb-1">Private destination project</label>
                            <select name="private_data_project_gid" class="afb-admin-select">
                                <option value="">Select destination project</option>
                                <?php foreach ((array) $projects as $private_project):
                                    $private_gid = (string) ($private_project['gid'] ?? '');
                                    if ($private_gid === '' || $private_gid === $selected_gid) {
                                        continue;
                                    }
                                ?>
                                    <option value="<?= esc_attr($private_gid) ?>" <?= selected($private_data_project_gid, $private_gid, false) ?>>
                                        <?= esc_html(($private_project['name'] ?? $private_gid) . ' (' . $private_gid . ')') ?>
                                    </option>
                                <?php endforeach; ?>
                            </select>
                            <p class="text-xs text-slate-400 mt-1 mb-0">Choose your dedicated private project. Leave blank to disable companion routing for this source project. After changing this project, save and reload before setting per-field targets.</p>
                            <?php if ($private_data_project_gid !== '' && empty($private_field_targets)): ?>
                                <p class="text-xs text-amber-700 mt-1 mb-0">No custom fields were loaded from the selected private project yet. Save and reload, or confirm project access.</p>
                            <?php endif; ?>
                        </div>

                        <div>
                            <label class="block text-xs text-slate-600 mb-1">Default upload destination</label>
                            <select name="private_companion_upload_mode" class="afb-admin-select">
                                <option value="main_only" <?= selected($private_companion_upload_mode, 'main_only', false) ?>>Main task only (default)</option>
                                <option value="copy_to_companion" <?= selected($private_companion_upload_mode, 'copy_to_companion', false) ?>>Main + companion task</option>
                                <option value="companion_only" <?= selected($private_companion_upload_mode, 'companion_only', false) ?>>Companion task only</option>
                            </select>
                            <p class="text-xs text-slate-400 mt-1 mb-0">This is the fallback for upload blocks. You can override destination per upload block below.</p>
                        </div>
                        <div>
                            <label class="block text-xs text-slate-600 mb-1">Companion task name mode</label>
                            <select name="private_companion_task_name_mode" class="afb-admin-select">
                                <option value="use_main" <?= selected($private_companion_task_name_mode, 'use_main', false) ?>>Use main task name</option>
                                <option value="use_job_number" <?= selected($private_companion_task_name_mode, 'use_job_number', false) ?>>Use job number</option>
                                <option value="use_template" <?= selected($private_companion_task_name_mode, 'use_template', false) ?>>Use template (below)</option>
                            </select>
                            <p class="text-xs text-slate-400 mt-1 mb-0">Choose how companion task names are constructed. Select "Use template" to supply a template below.</p>
                        </div>
                        <div>
                            <label class="block text-xs text-slate-600 mb-1">Companion task name template (optional)</label>
                            <input type="text" name="private_companion_task_name_template" value="<?= esc_attr($private_companion_task_name_template) ?>" class="afb-admin-input" placeholder="e.g. {{job_number}} or Confidential - {{job_number}}">
                            <p class="text-xs text-slate-400 mt-1 mb-0">Use placeholders like {{job_number}} and {{task_name}}. Leave blank to use the main task name.</p>
                        </div>
                    </div>
                </div>

                <div class="afb-flow-grid">
                    <div class="afb-admin-card afb-admin-card-pad">
                        <div class="flex items-center justify-between mb-2">
                            <h4 class="text-sm font-semibold text-slate-900 m-0">Available Fields</h4>
                            <span class="text-xs text-slate-500">Not in form</span>
                        </div>
                        <p class="text-xs text-slate-500 mt-0 mb-3">Click + or drag into the selected area.</p>

                        <div class="afb-available-tools mb-3 space-y-2">
                            <button type="button" class="afb-add-block" data-block-type="paragraph">
                                <span class="afb-add-block-title">Paragraph Block</span>
                                <span class="afb-add-block-sub">Static helper copy</span>
                                <span class="afb-add-block-action">Add</span>
                            </button>
                            <button type="button" class="afb-add-block" data-block-type="section">
                                <span class="afb-add-block-title">Section Break</span>
                                <span class="afb-add-block-sub">Creates new frontend step</span>
                                <span class="afb-add-block-action">Add</span>
                            </button>
                            <button type="button" class="afb-add-block" data-block-type="agreement">
                                <span class="afb-add-block-title">Agreement Checkbox</span>
                                <span class="afb-add-block-sub">Required checkbox not sent to Asana</span>
                                <span class="afb-add-block-action">Add</span>
                            </button>
                            <button type="button" class="afb-add-block" data-block-type="upload">
                                <span class="afb-add-block-title">Upload Area</span>
                                <span class="afb-add-block-sub">Optional or required upload block; add multiple as needed</span>
                                <span class="afb-add-block-action">Add</span>
                            </button>
                            <button type="button" class="afb-add-block" data-block-type="single_input">
                                <span class="afb-add-block-title">Single Input Text</span>
                                <span class="afb-add-block-sub">Single-line or textarea input; optional sync to Asana text field</span>
                                <span class="afb-add-block-action">Add</span>
                            </button>
                            <button type="button" class="afb-add-block" data-block-type="dropdown">
                                <span class="afb-add-block-title">Dropdown</span>
                                <span class="afb-add-block-sub">Single-select dropdown or multi-select checkboxes; optional sync to Asana text field</span>
                                <span class="afb-add-block-action">Add</span>
                            </button>
                            <button type="button" class="afb-add-block" data-block-type="calendar">
                                <span class="afb-add-block-title">Calendar Picker</span>
                                <span class="afb-add-block-sub">Date picker or eAlert Wednesdays; sync to text field or task due date</span>
                                <span class="afb-add-block-action">Add</span>
                            </button>
                            <button type="button" class="afb-add-block" data-block-type="repeater">
                                <span class="afb-add-block-title">Repeater List</span>
                                <span class="afb-add-block-sub">Collect multiple rows and save as subtasks or task description content</span>
                                <span class="afb-add-block-action">Add</span>
                            </button>
                            <button type="button" class="afb-add-block" data-block-type="task_name">
                                <span class="afb-add-block-title">Task Name Builder</span>
                                <span class="afb-add-block-sub">Build Asana task title with variables from submitted form values</span>
                                <span class="afb-add-block-action">Add</span>
                            </button>
                            <button type="button" class="afb-add-block" data-block-type="due_date">
                                <span class="afb-add-block-title">Due Date Tool</span>
                                <span class="afb-add-block-sub">Rule-driven due date formulas from today or date fields</span>
                                <span class="afb-add-block-action">Add</span>
                            </button>
                            <button type="button" class="afb-add-block" data-block-type="assignee">
                                <span class="afb-add-block-title">Assignee Tool</span>
                                <span class="afb-add-block-sub">Rule-driven assignment with OOO-aware fallback chain</span>
                                <span class="afb-add-block-action">Add</span>
                            </button>
                            <button type="button" class="afb-add-block" data-block-type="recipient">
                                <span class="afb-add-block-title">Recipients Tool</span>
                                <span class="afb-add-block-sub">Send submission copy to emails from selected fields or manual addresses</span>
                                <span class="afb-add-block-action">Add</span>
                            </button>
                        </div>

                        <ul id="field-available" class="space-y-3 min-h-[120px]"></ul>
                    </div>

                    <div class="afb-admin-card afb-admin-card-pad">
                        <div class="flex items-center justify-between mb-2">
                            <h4 class="text-sm font-semibold text-slate-900 m-0">Selected Form Flow</h4>
                            <span class="text-xs text-slate-500">Rendered on frontend</span>
                        </div>
                        <ul id="field-sortable" class="space-y-3 min-h-[220px]" data-assignee-options='<?= esc_attr($assignee_member_options_json) ?>'>
                    <?php foreach ((array) $fields as $setting): ?>
                        <?php if (isset($setting['type']) && $setting['type'] === 'paragraph'):
                            $pid = $setting['id'];
                            $paragraph_chk_block = in_array($pid, $submit_block_fields, true) ? 'checked' : '';
                            $paragraph_cond = $conditions[$pid] ?? ['depends_on' => '', 'value' => '', 'values' => []];
                        ?>
                            <li data-id="<?= esc_attr($pid) ?>" class="afb-builder-item afb-paragraph-block is-collapsed" data-kind="paragraph">
                                <input type="hidden" name="field_order[]" value="<?= esc_attr($pid) ?>" />
                                <div class="afb-builder-item-header">
                                    <span class="afb-handle" aria-hidden="true">::</span>
                                    <div class="min-w-0 flex-1">
                                        <div class="afb-item-title">Paragraph Block</div>
                                        <div class="afb-item-subtitle">Rich helper text between inputs</div>
                                    </div>
                                    <span class="afb-chip afb-chip-paragraph">Paragraph</span>
                                    <button type="button" class="afb-admin-btn afb-collapse-toggle">Expand</button>
                                    <button type="button" class="afb-admin-btn afb-duplicate-item">Duplicate</button>
                                    <button type="button" class="afb-admin-btn remove-builder-item">Remove</button>
                                </div>
                                <div class="afb-builder-item-body">
                                    <div class="grid gap-3 md:grid-cols-2 lg:grid-cols-3">
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="submit_block_fields[]" value="<?= esc_attr($pid) ?>" <?= $paragraph_chk_block ?> />
                                            Block submit when visible
                                        </label>
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Internal title</label>
                                        <input type="text" name="custom_paragraph_titles[<?= esc_attr($pid) ?>]" value="<?= esc_attr($custom_paragraph_titles[$pid] ?? '') ?>" class="afb-admin-input" placeholder="Paragraph title (not shown on frontend)">
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Paragraph content</label>
                                        <?php $paragraph_content = (string) ($setting['content'] ?? ''); ?>
                                        <div class="afb-paragraph-editor-wrap">
                                            <div class="flex items-center gap-2 mb-2">
                                                <button type="button" class="afb-admin-btn afb-para-insert" data-format="heading">Heading</button>
                                                <button type="button" class="afb-admin-btn afb-para-insert" data-format="bold">Bold</button>
                                                <button type="button" class="afb-admin-btn afb-para-insert" data-format="list">List</button>
                                                <button type="button" class="afb-admin-btn afb-para-insert" data-format="link">Link</button>
                                            </div>
                                            <div class="afb-admin-textarea afb-paragraph-wysiwyg" contenteditable="true" style="min-height: 150px; max-height: 280px; overflow: auto; white-space: pre-wrap;"><?= wp_kses_post($paragraph_content) ?></div>
                                            <textarea name="custom_paragraphs[<?= esc_attr($pid) ?>]" rows="6" class="afb-paragraph-editor" style="display:none;" aria-hidden="true"><?= esc_textarea($paragraph_content) ?></textarea>
                                            <p class="text-xs text-slate-400 mt-2 mb-0">Basic formatting only. Use toolbar buttons to insert heading, bold text, and bullet lists.</p>
                                        </div>
                                    </div>
                                    <?php $afb_render_condition_editor($pid, $paragraph_cond); ?>
                                </div>
                            </li>

                        <?php elseif (isset($setting['type']) && $setting['type'] === 'section'):
                            $sid = $setting['id'];
                            $section_cond = $conditions[$sid] ?? ['depends_on' => '', 'value' => '', 'values' => []];
                        ?>
                            <li data-id="<?= esc_attr($sid) ?>" class="afb-builder-item is-collapsed" data-kind="section">
                                <input type="hidden" name="field_order[]" value="<?= esc_attr($sid) ?>" />
                                <div class="afb-builder-item-header">
                                    <span class="afb-handle" aria-hidden="true">::</span>
                                    <div class="min-w-0 flex-1">
                                        <div class="afb-item-title"><?= esc_html(($custom_section_titles[$sid] ?? '') ?: 'Section Break') ?></div>
                                        <div class="afb-item-subtitle">Starts a new frontend step</div>
                                    </div>
                                    <span class="afb-chip afb-chip-section">Step</span>
                                    <button type="button" class="afb-admin-btn afb-collapse-toggle">Expand</button>
                                    <button type="button" class="afb-admin-btn afb-move-section-up">Up</button>
                                    <button type="button" class="afb-admin-btn afb-move-section-down">Down</button>
                                    <button type="button" class="afb-admin-btn afb-duplicate-item">Duplicate</button>
                                    <button type="button" class="afb-admin-btn remove-builder-item">Remove</button>
                                </div>
                                <div class="afb-builder-item-body">
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Step title</label>
                                        <input type="text" name="custom_section_titles[<?= esc_attr($sid) ?>]" value="<?= esc_attr($custom_section_titles[$sid] ?? '') ?>" class="afb-admin-input" placeholder="Example: Contact Details">
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Step helper text</label>
                                        <textarea name="custom_sections[<?= esc_attr($sid) ?>]" rows="3" class="afb-admin-textarea" placeholder="Optional instructions for this step"><?= esc_textarea($custom_sections[$sid] ?? '') ?></textarea>
                                    </div>
                                    <?php $afb_render_condition_editor($sid, $section_cond); ?>
                                    <p class="text-xs text-slate-500 mt-1 mb-0">Tip: Hidden steps are skipped automatically in frontend navigation.</p>
                                </div>
                            </li>

                        <?php elseif (isset($setting['type']) && $setting['type'] === 'agreement'):
                            $aid = $setting['id'];
                            $agreement_label = (string) ($custom_agreement_labels[$aid] ?? ($setting['label'] ?? ''));
                            $agreement_desc = (string) ($custom_agreement_details[$aid] ?? ($setting['description'] ?? ''));
                            $agreement_is_required = $agreement_required_configured
                                ? in_array($aid, $agreement_required_fields, true)
                                : true;
                            $agreement_chk_required = $agreement_is_required ? 'checked' : '';
                            $agreement_chk_block = in_array($aid, $submit_block_fields, true) ? 'checked' : '';
                            $agreement_chk_description = in_array($aid, $agreement_description_fields, true) ? 'checked' : '';
                            $agreement_cond = $conditions[$aid] ?? ['depends_on' => '', 'value' => '', 'values' => []];
                        ?>
                            <li data-id="<?= esc_attr($aid) ?>" class="afb-builder-item is-collapsed" data-kind="agreement">
                                <input type="hidden" name="field_order[]" value="<?= esc_attr($aid) ?>" />
                                <div class="afb-builder-item-header">
                                    <span class="afb-handle" aria-hidden="true">::</span>
                                    <div class="min-w-0 flex-1">
                                        <div class="afb-item-title"><?= esc_html($agreement_label !== '' ? $agreement_label : 'Agreement Checkbox') ?></div>
                                        <div class="afb-item-subtitle">Must be ticked before submit</div>
                                    </div>
                                    <span class="afb-chip afb-chip-paragraph">Agreement</span>
                                    <span class="afb-chip afb-agreement-required-chip" style="<?= $agreement_is_required ? '' : 'display:none;' ?>">Req</span>
                                    <button type="button" class="afb-admin-btn afb-collapse-toggle">Expand</button>
                                    <button type="button" class="afb-admin-btn afb-duplicate-item">Duplicate</button>
                                    <button type="button" class="afb-admin-btn remove-builder-item">Remove</button>
                                </div>
                                <div class="afb-builder-item-body">
                                    <div class="grid gap-3 md:grid-cols-2 lg:grid-cols-3">
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="agreement_required_fields[]" value="<?= esc_attr($aid) ?>" <?= $agreement_chk_required ?> />
                                            Required
                                        </label>
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="submit_block_fields[]" value="<?= esc_attr($aid) ?>" <?= $agreement_chk_block ?> />
                                            Block submit when visible
                                        </label>
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="agreement_description_fields[]" value="<?= esc_attr($aid) ?>" <?= $agreement_chk_description ?> />
                                            Append checked state to task description
                                        </label>
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Agreement label</label>
                                        <input type="text" name="custom_agreement_labels[<?= esc_attr($aid) ?>]" value="<?= esc_attr($agreement_label) ?>" class="afb-admin-input" placeholder="Example: I agree to the terms and privacy policy">
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Helper text</label>
                                        <textarea name="custom_agreement_details[<?= esc_attr($aid) ?>]" rows="3" class="afb-admin-textarea" placeholder="Optional short explanation shown below the agreement label"><?= esc_textarea($agreement_desc) ?></textarea>
                                    </div>
                                    <?php $afb_render_condition_editor($aid, $agreement_cond); ?>
                                </div>
                            </li>

                        <?php elseif (isset($setting['type']) && $setting['type'] === 'upload'):
                            $uid = $setting['id'];
                            $upload_title = (string) ($custom_upload_titles[$uid] ?? ($setting['title'] ?? ''));
                            $upload_desc = (string) ($custom_upload_details[$uid] ?? ($setting['description'] ?? ''));
                            $upload_min = (int) ($custom_upload_min_files[$uid] ?? ($setting['min_files'] ?? 0));
                            $upload_private_mode = sanitize_text_field((string) ($custom_upload_private_modes[$uid] ?? ($setting['private_upload_mode'] ?? 'use_project_default')));
                            if (!in_array($upload_private_mode, ['use_project_default', 'main_only', 'copy_to_companion', 'companion_only'], true)) {
                                $upload_private_mode = 'use_project_default';
                            }
                            $upload_accept_types = sanitize_text_field((string) ($custom_upload_accept_types[$uid] ?? ($setting['accept_types'] ?? '')));
                            $upload_compress_images_default = array_key_exists('compress_images', $setting)
                                ? !empty($setting['compress_images'])
                                : true;
                            $upload_compress_images = $custom_upload_compress_images_configured
                                ? in_array($uid, $custom_upload_compress_images, true)
                                : $upload_compress_images_default;
                            $upload_max_file_mb = max(0.0, (float) ($custom_upload_max_file_mb[$uid] ?? ($setting['max_file_mb'] ?? 0)));
                            $upload_max_file_mb_value = $upload_max_file_mb > 0
                                ? rtrim(rtrim(number_format($upload_max_file_mb, 2, '.', ''), '0'), '.')
                                : '';
                            $upload_max_width_px = max(100, min(4000, (int) ($custom_upload_max_width_px[$uid] ?? ($setting['compress_max_width'] ?? 1200))));
                            $upload_compress_quality = max(1, min(100, (int) ($custom_upload_compress_quality[$uid] ?? ($setting['compress_quality'] ?? 60))));
                            $upload_chk_required = $upload_min > 0 ? 'checked' : '';
                            $upload_chk_block = in_array($uid, $submit_block_fields, true) ? 'checked' : '';
                            $upload_cond = $conditions[$uid] ?? ['depends_on' => '', 'value' => '', 'values' => []];
                        ?>
                            <li data-id="<?= esc_attr($uid) ?>" class="afb-builder-item is-collapsed" data-kind="upload">
                                <input type="hidden" name="field_order[]" value="<?= esc_attr($uid) ?>" />
                                <div class="afb-builder-item-header">
                                    <span class="afb-handle" aria-hidden="true">::</span>
                                    <div class="min-w-0 flex-1">
                                        <div class="afb-item-title"><?= esc_html($upload_title !== '' ? $upload_title : 'Upload Area') ?></div>
                                        <div class="afb-item-subtitle">Files stay local to the request and are sent together</div>
                                    </div>
                                    <span class="afb-chip">Upload</span>
                                    <button type="button" class="afb-admin-btn afb-collapse-toggle">Expand</button>
                                    <button type="button" class="afb-admin-btn afb-duplicate-item">Duplicate</button>
                                    <button type="button" class="afb-admin-btn remove-builder-item">Remove</button>
                                </div>
                                <div class="afb-builder-item-body">
                                    <div class="grid gap-3 md:grid-cols-2 lg:grid-cols-3">
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check afb-upload-required-toggle" <?= $upload_chk_required ?> />
                                            Required
                                        </label>
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="submit_block_fields[]" value="<?= esc_attr($uid) ?>" <?= $upload_chk_block ?> />
                                            Block submit when visible
                                        </label>
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Upload title</label>
                                        <input type="text" name="custom_upload_titles[<?= esc_attr($uid) ?>]" value="<?= esc_attr($upload_title) ?>" class="afb-admin-input" placeholder="Example: Supporting documents">
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Helper text</label>
                                        <textarea name="custom_upload_details[<?= esc_attr($uid) ?>]" rows="3" class="afb-admin-textarea" placeholder="Explain what files to upload here"><?= esc_textarea($upload_desc) ?></textarea>
                                    </div>
                                    <div class="max-w-xs">
                                        <label class="block text-xs text-slate-600 mb-1">Minimum files required</label>
                                        <input type="number" min="0" step="1" name="custom_upload_min_files[<?= esc_attr($uid) ?>]" value="<?= esc_attr((string) max(0, $upload_min)) ?>" class="afb-admin-input" placeholder="0">
                                        <p class="text-xs text-slate-400 mt-1 mb-0">Tick Required for at least one file, or set a higher number for multi-file minimums.</p>
                                    </div>

                                    <div class="max-w-sm">
                                        <label class="block text-xs text-slate-600 mb-1">Accepted file types (optional)</label>
                                        <input type="text" name="custom_upload_accept_types[<?= esc_attr($uid) ?>]" value="<?= esc_attr($upload_accept_types) ?>" class="afb-admin-input" placeholder="Examples: image/*, .pdf, .jpg">
                                        <p class="text-xs text-slate-400 mt-1 mb-0">Leave blank to allow any file type. Use commas to separate multiple file extensions or MIME types.</p>
                                    </div>

                                    <div class="max-w-sm">
                                        <label class="afb-flag-toggle mt-1">
                                            <input type="checkbox" class="afb-admin-check" name="custom_upload_compress_images[]" value="<?= esc_attr($uid) ?>" <?= $upload_compress_images ? 'checked' : '' ?> />
                                            Compress image files on upload
                                        </label>
                                        <p class="text-xs text-slate-400 mt-1 mb-0">Compression happens as users pick files, before task submission starts.</p>
                                    </div>

                                    <div class="max-w-xs">
                                        <label class="block text-xs text-slate-600 mb-1">Max file size per file (MB, optional)</label>
                                        <input type="number" min="0" step="0.1" name="custom_upload_max_file_mb[<?= esc_attr($uid) ?>]" value="<?= esc_attr($upload_max_file_mb_value) ?>" class="afb-admin-input" placeholder="Example: 10">
                                        <p class="text-xs text-slate-400 mt-1 mb-0">Leave blank for no extra limit. Limit is checked after image compression.</p>
                                    </div>

                                    <div class="max-w-sm">
                                        <label class="block text-xs text-slate-600 mb-1">Image max width (px)</label>
                                        <div class="flex items-center gap-3">
                                            <input type="range" min="100" max="2400" step="50" name="custom_upload_max_width_px[<?= esc_attr($uid) ?>]" value="<?= esc_attr((string) $upload_max_width_px) ?>" class="afb-admin-range flex-1" oninput="this.nextElementSibling.textContent = this.value + 'px'">
                                            <span class="text-xs text-slate-500 min-w-[56px] text-right"><?= esc_html((string) $upload_max_width_px) ?>px</span>
                                        </div>
                                        <p class="text-xs text-slate-400 mt-1 mb-0">Large images are resized to this width before upload. 1200px is the default.</p>
                                    </div>

                                    <div class="max-w-sm">
                                        <label class="block text-xs text-slate-600 mb-1">Image compression quality (%)</label>
                                        <div class="flex items-center gap-3">
                                            <input type="range" min="1" max="100" step="1" name="custom_upload_compress_quality[<?= esc_attr($uid) ?>]" value="<?= esc_attr((string) $upload_compress_quality) ?>" class="afb-admin-range flex-1" oninput="this.nextElementSibling.textContent = this.value + '%'">
                                            <span class="text-xs text-slate-500 min-w-[44px] text-right"><?= esc_html((string) $upload_compress_quality) ?>%</span>
                                        </div>
                                        <p class="text-xs text-slate-400 mt-1 mb-0">Lower values reduce file size more aggressively. 60% is the default.</p>
                                    </div>

                                    <div class="max-w-sm">
                                        <label class="block text-xs text-slate-600 mb-1">Upload destination for this block</label>
                                        <select name="custom_upload_private_modes[<?= esc_attr($uid) ?>]" class="afb-admin-select">
                                            <option value="use_project_default" <?= selected($upload_private_mode, 'use_project_default', false) ?>>Use project default</option>
                                            <option value="main_only" <?= selected($upload_private_mode, 'main_only', false) ?>>Main task only</option>
                                            <option value="copy_to_companion" <?= selected($upload_private_mode, 'copy_to_companion', false) ?>>Main + companion task</option>
                                            <option value="companion_only" <?= selected($upload_private_mode, 'companion_only', false) ?>>Companion task only</option>
                                        </select>
                                        <p class="text-xs text-slate-400 mt-1 mb-0">Use this when some uploads are confidential and should only be attached to the private companion task.</p>
                                    </div>

                                    <?php $afb_render_condition_editor($uid, $upload_cond); ?>
                                </div>
                            </li>

                        <?php elseif (isset($setting['type']) && $setting['type'] === 'single_input'):
                            $single_id = $setting['id'];
                            $single_label = (string) ($custom_single_input_labels[$single_id] ?? ($setting['label'] ?? ''));
                            $single_desc = (string) ($custom_single_input_descriptions[$single_id] ?? ($setting['description'] ?? ''));
                            $single_placeholder = (string) ($custom_single_input_placeholders[$single_id] ?? ($setting['placeholder'] ?? ''));
                            $single_sync_field = (string) ($custom_single_input_sync_fields[$single_id] ?? ($setting['sync_field'] ?? ''));
                            $single_private_target = (string) ($private_companion_field_targets[$single_id] ?? '');
                            $single_input_mode_raw = (string) ($custom_single_input_modes[$single_id] ?? ($setting['input_mode'] ?? 'text'));
                            $single_input_mode = in_array($single_input_mode_raw, ['text', 'textarea'], true)
                                ? $single_input_mode_raw
                                : 'text';
                            $single_max_words_enabled = in_array($single_id, (array) $custom_single_input_max_words_enabled, true)
                                || (!empty($setting['max_words_enabled']) && (int) ($setting['max_words'] ?? 0) > 0);
                            $single_max_words = max(0, (int) ($custom_single_input_max_words[$single_id] ?? ($setting['max_words'] ?? 0)));
                            $single_ai_enabled = in_array($single_id, (array) $custom_single_input_ai_enabled, true)
                                || !empty($setting['ai_enabled']);
                            $single_chk_required = in_array($single_id, $required_fields, true) ? 'checked' : '';
                            $single_chk_half = in_array($single_id, $half_width_fields, true) ? 'checked' : '';
                            $single_chk_third = in_array($single_id, $third_width_fields, true) ? 'checked' : '';
                            $single_chk_block = in_array($single_id, $submit_block_fields, true) ? 'checked' : '';
                            $single_cond = $conditions[$single_id] ?? ['depends_on' => '', 'value' => '', 'values' => []];
                        ?>
                            <li data-id="<?= esc_attr($single_id) ?>" class="afb-builder-item is-collapsed" data-kind="single_input">
                                <input type="hidden" name="field_order[]" value="<?= esc_attr($single_id) ?>" />
                                <div class="afb-builder-item-header">
                                    <span class="afb-handle" aria-hidden="true">::</span>
                                    <div class="min-w-0 flex-1">
                                        <div class="afb-item-title"><?= esc_html($single_label !== '' ? $single_label : 'Single Input Text') ?></div>
                                        <div class="afb-item-subtitle">Single-line or textarea answer; optionally synced to Asana text field</div>
                                    </div>
                                    <span class="afb-chip">Text</span>
                                    <span class="afb-chip afb-single-half-chip" style="<?= ($single_chk_half || $single_chk_third) ? '' : 'display:none;' ?>"><?= $single_chk_third ? '1/3' : '1/2' ?></span>
                                    <span class="afb-chip afb-single-ai-chip" style="<?= $single_ai_enabled ? '' : 'display:none;' ?>">AI</span>
                                    <button type="button" class="afb-admin-btn afb-collapse-toggle">Expand</button>
                                    <button type="button" class="afb-admin-btn afb-duplicate-item">Duplicate</button>
                                    <button type="button" class="afb-admin-btn remove-builder-item">Remove</button>
                                </div>
                                <div class="afb-builder-item-body">
                                    <div class="grid gap-3 md:grid-cols-2 lg:grid-cols-3">
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="required_fields[]" value="<?= esc_attr($single_id) ?>" <?= $single_chk_required ?> />
                                            Required
                                        </label>
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="half_width_fields[]" value="<?= esc_attr($single_id) ?>" <?= $single_chk_half ?> />
                                            1/2 width
                                        </label>
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="third_width_fields[]" value="<?= esc_attr($single_id) ?>" <?= $single_chk_third ?> />
                                            1/3 width
                                        </label>
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="custom_single_input_ai_enabled[]" value="<?= esc_attr($single_id) ?>" <?= $single_ai_enabled ? 'checked' : '' ?> />
                                            Enable AI help
                                        </label>
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="submit_block_fields[]" value="<?= esc_attr($single_id) ?>" <?= $single_chk_block ?> />
                                            Block submit when visible
                                        </label>
                                    </div>
                                    <p class="text-xs text-slate-500 mt-1 mb-0">Shows a "Rewrite with AI" helper button on this field in the frontend form.</p>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Field label</label>
                                        <input type="text" name="custom_single_input_labels[<?= esc_attr($single_id) ?>]" value="<?= esc_attr($single_label) ?>" class="afb-admin-input" placeholder="Example: Preferred call-back number">
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Helper text</label>
                                        <textarea name="custom_single_input_descriptions[<?= esc_attr($single_id) ?>]" rows="3" class="afb-admin-textarea" placeholder="Optional short context shown below the label"><?= esc_textarea($single_desc) ?></textarea>
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Placeholder</label>
                                        <input type="text" name="custom_single_input_placeholders[<?= esc_attr($single_id) ?>]" value="<?= esc_attr($single_placeholder) ?>" class="afb-admin-input" placeholder="Example: Enter a short answer">
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Input type</label>
                                        <select name="custom_single_input_modes[<?= esc_attr($single_id) ?>]" class="afb-admin-select afb-single-input-mode">
                                            <option value="text" <?= selected($single_input_mode, 'text', false) ?>>Single-line input</option>
                                            <option value="textarea" <?= selected($single_input_mode, 'textarea', false) ?>>Textarea (multi-line)</option>
                                        </select>
                                    </div>
                                    <div class="afb-single-max-words-controls" style="<?= $single_input_mode === 'textarea' ? '' : 'display:none;' ?>">
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check afb-single-max-words-toggle" name="custom_single_input_max_words_enabled[]" value="<?= esc_attr($single_id) ?>" <?= $single_max_words_enabled ? 'checked' : '' ?> />
                                            Enable max word limit
                                        </label>
                                    </div>
                                    <div class="afb-single-max-words-wrap max-w-xs" style="<?= ($single_input_mode === 'textarea' && $single_max_words_enabled) ? '' : 'display:none;' ?>">
                                        <label class="block text-xs text-slate-600 mb-1">Max words</label>
                                        <input type="number" min="1" step="1" name="custom_single_input_max_words[<?= esc_attr($single_id) ?>]" value="<?= esc_attr($single_max_words > 0 ? (string) $single_max_words : '') ?>" class="afb-admin-input afb-single-max-words-input" placeholder="Example: 120">
                                        <p class="text-xs text-slate-400 mt-1 mb-0">Only applies when input type is textarea. Users will see live over/under word feedback.</p>
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Sync to Asana text field (optional)</label>
                                        <select name="custom_single_input_sync_fields[<?= esc_attr($single_id) ?>]" class="afb-admin-select">
                                            <option value="">Do not sync (append to task description)</option>
                                            <?php foreach ((array) $text_sync_targets as $sync_gid => $sync_name): ?>
                                                <option value="<?= esc_attr($sync_gid) ?>" <?= selected($single_sync_field, $sync_gid, false) ?>>
                                                    <?= esc_html($sync_name . ' (' . $sync_gid . ')') ?>
                                                </option>
                                            <?php endforeach; ?>
                                        </select>
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Private companion target field (optional)</label>
                                        <select name="private_companion_field_targets[<?= esc_attr($single_id) ?>]" class="afb-admin-select">
                                            <option value="">Do not map to private project</option>
                                            <?php foreach ((array) $private_text_field_targets as $private_target_gid => $private_target): ?>
                                                <option value="<?= esc_attr($private_target_gid) ?>" <?= selected($single_private_target, $private_target_gid, false) ?>>
                                                    <?= esc_html((string) ($private_target['label'] ?? $private_target_gid)) ?>
                                                </option>
                                            <?php endforeach; ?>
                                        </select>
                                    </div>

                                    <?php $afb_render_condition_editor($single_id, $single_cond); ?>
                                    <p class="text-xs text-slate-500 mt-1 mb-0">When synced, the submitted value writes to the selected Asana text field only. Without sync, it is appended to the task description.</p>
                                </div>
                            </li>

                        <?php elseif (isset($setting['type']) && $setting['type'] === 'dropdown'):
                            $dropdown_id = $setting['id'];
                            $dropdown_label = (string) ($custom_dropdown_labels[$dropdown_id] ?? ($setting['label'] ?? ''));
                            $dropdown_desc = (string) ($custom_dropdown_descriptions[$dropdown_id] ?? ($setting['description'] ?? ''));
                            $dropdown_placeholder = (string) ($custom_dropdown_placeholders[$dropdown_id] ?? ($setting['placeholder'] ?? ''));
                            $dropdown_options = (string) ($custom_dropdown_options[$dropdown_id] ?? ($setting['options'] ?? ''));
                            $dropdown_selection_mode_raw = (string) ($custom_dropdown_selection_modes[$dropdown_id] ?? ($setting['selection_mode'] ?? 'single'));
                            $dropdown_selection_mode = in_array($dropdown_selection_mode_raw, ['single', 'multi'], true)
                                ? $dropdown_selection_mode_raw
                                : 'single';
                            $dropdown_sync_field = (string) ($custom_dropdown_sync_fields[$dropdown_id] ?? ($setting['sync_field'] ?? ''));
                            $dropdown_private_target = (string) ($private_companion_field_targets[$dropdown_id] ?? '');
                            $dropdown_chk_required = in_array($dropdown_id, $required_fields, true) ? 'checked' : '';
                            $dropdown_chk_half = in_array($dropdown_id, $half_width_fields, true) ? 'checked' : '';
                            $dropdown_chk_third = in_array($dropdown_id, $third_width_fields, true) ? 'checked' : '';
                            $dropdown_chk_block = in_array($dropdown_id, $submit_block_fields, true) ? 'checked' : '';
                            $dropdown_cond = $conditions[$dropdown_id] ?? ['depends_on' => '', 'value' => '', 'values' => []];
                        ?>
                            <li data-id="<?= esc_attr($dropdown_id) ?>" class="afb-builder-item is-collapsed" data-kind="dropdown">
                                <input type="hidden" name="field_order[]" value="<?= esc_attr($dropdown_id) ?>" />
                                <div class="afb-builder-item-header">
                                    <span class="afb-handle" aria-hidden="true">::</span>
                                    <div class="min-w-0 flex-1">
                                        <div class="afb-item-title"><?= esc_html($dropdown_label !== '' ? $dropdown_label : 'Dropdown') ?></div>
                                        <div class="afb-item-subtitle">Single-select dropdown or multi-select checkboxes; optional text-field sync</div>
                                    </div>
                                    <span class="afb-chip">Dropdown</span>
                                    <span class="afb-chip afb-dropdown-half-chip" style="<?= ($dropdown_chk_half || $dropdown_chk_third) ? '' : 'display:none;' ?>"><?= $dropdown_chk_third ? '1/3' : '1/2' ?></span>
                                    <button type="button" class="afb-admin-btn afb-collapse-toggle">Expand</button>
                                    <button type="button" class="afb-admin-btn afb-duplicate-item">Duplicate</button>
                                    <button type="button" class="afb-admin-btn remove-builder-item">Remove</button>
                                </div>
                                <div class="afb-builder-item-body">
                                    <div class="grid gap-3 md:grid-cols-2 lg:grid-cols-3">
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="required_fields[]" value="<?= esc_attr($dropdown_id) ?>" <?= $dropdown_chk_required ?> />
                                            Required
                                        </label>
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="half_width_fields[]" value="<?= esc_attr($dropdown_id) ?>" <?= $dropdown_chk_half ?> />
                                            1/2 width
                                        </label>
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="third_width_fields[]" value="<?= esc_attr($dropdown_id) ?>" <?= $dropdown_chk_third ?> />
                                            1/3 width
                                        </label>
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="submit_block_fields[]" value="<?= esc_attr($dropdown_id) ?>" <?= $dropdown_chk_block ?> />
                                            Block submit when visible
                                        </label>
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Field label</label>
                                        <input type="text" name="custom_dropdown_labels[<?= esc_attr($dropdown_id) ?>]" value="<?= esc_attr($dropdown_label) ?>" class="afb-admin-input" placeholder="Example: Preferred contact method">
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Helper text</label>
                                        <textarea name="custom_dropdown_descriptions[<?= esc_attr($dropdown_id) ?>]" rows="3" class="afb-admin-textarea" placeholder="Optional short context shown below the label"><?= esc_textarea($dropdown_desc) ?></textarea>
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Placeholder</label>
                                        <input type="text" name="custom_dropdown_placeholders[<?= esc_attr($dropdown_id) ?>]" value="<?= esc_attr($dropdown_placeholder) ?>" class="afb-admin-input" placeholder="Example: Select an option">
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Selection type</label>
                                        <select name="custom_dropdown_selection_modes[<?= esc_attr($dropdown_id) ?>]" class="afb-admin-select">
                                            <option value="single" <?= selected($dropdown_selection_mode, 'single', false) ?>>Single select (dropdown)</option>
                                            <option value="multi" <?= selected($dropdown_selection_mode, 'multi', false) ?>>Multi select (checkboxes)</option>
                                        </select>
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Options (one per line)</label>
                                        <textarea name="custom_dropdown_options[<?= esc_attr($dropdown_id) ?>]" rows="6" class="afb-admin-textarea" placeholder="Option A&#10;Option B&#10;Option C"><?= esc_textarea($dropdown_options) ?></textarea>
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Sync to Asana text field (optional)</label>
                                        <select name="custom_dropdown_sync_fields[<?= esc_attr($dropdown_id) ?>]" class="afb-admin-select">
                                            <option value="">Do not sync (append to task description)</option>
                                            <?php foreach ((array) $text_sync_targets as $sync_gid => $sync_name): ?>
                                                <option value="<?= esc_attr($sync_gid) ?>" <?= selected($dropdown_sync_field, $sync_gid, false) ?>>
                                                    <?= esc_html($sync_name . ' (' . $sync_gid . ')') ?>
                                                </option>
                                            <?php endforeach; ?>
                                        </select>
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Private companion target field (optional)</label>
                                        <select name="private_companion_field_targets[<?= esc_attr($dropdown_id) ?>]" class="afb-admin-select">
                                            <option value="">Do not map to private project</option>
                                            <?php foreach ((array) $private_text_field_targets as $private_target_gid => $private_target): ?>
                                                <option value="<?= esc_attr($private_target_gid) ?>" <?= selected($dropdown_private_target, $private_target_gid, false) ?>>
                                                    <?= esc_html((string) ($private_target['label'] ?? $private_target_gid)) ?>
                                                </option>
                                            <?php endforeach; ?>
                                        </select>
                                    </div>

                                    <?php $afb_render_condition_editor($dropdown_id, $dropdown_cond); ?>
                                    <p class="text-xs text-slate-500 mt-1 mb-0">When synced, the selected value(s) write to the selected Asana text field only. Without sync, selection(s) are appended to the task description.</p>
                                </div>
                            </li>

                        <?php elseif (isset($setting['type']) && $setting['type'] === 'calendar'):
                            $calendar_id = $setting['id'];
                            $calendar_label = (string) ($custom_calendar_labels[$calendar_id] ?? ($setting['label'] ?? ''));
                            $calendar_desc = (string) ($custom_calendar_descriptions[$calendar_id] ?? ($setting['description'] ?? ''));
                            $calendar_placeholder = (string) ($custom_calendar_placeholders[$calendar_id] ?? ($setting['placeholder'] ?? ''));
                            $calendar_sync_mode_raw = (string) ($custom_calendar_sync_modes[$calendar_id] ?? ($setting['sync_mode'] ?? 'text'));
                            $calendar_sync_mode = in_array($calendar_sync_mode_raw, ['none', 'text', 'due_date'], true)
                                ? $calendar_sync_mode_raw
                                : ((string) ($custom_calendar_sync_fields[$calendar_id] ?? '') !== '' ? 'text' : 'none');
                            $calendar_sync_field = (string) ($custom_calendar_sync_fields[$calendar_id] ?? ($setting['sync_field'] ?? ''));
                            $calendar_private_target = (string) ($private_companion_field_targets[$calendar_id] ?? '');
                            $calendar_preset_mode_raw = (string) ($custom_calendar_preset_modes[$calendar_id] ?? ($setting['preset_mode'] ?? 'none'));
                            $calendar_preset_mode = in_array($calendar_preset_mode_raw, ['none', 'ealert_next_4_wednesdays'], true)
                                ? $calendar_preset_mode_raw
                                : 'none';
                            $calendar_chk_required = in_array($calendar_id, $required_fields, true) ? 'checked' : '';
                            $calendar_chk_half = in_array($calendar_id, $half_width_fields, true) ? 'checked' : '';
                            $calendar_chk_third = in_array($calendar_id, $third_width_fields, true) ? 'checked' : '';
                            $calendar_chk_block = in_array($calendar_id, $submit_block_fields, true) ? 'checked' : '';
                            $calendar_cond = $conditions[$calendar_id] ?? ['depends_on' => '', 'value' => '', 'values' => []];
                        ?>
                            <li data-id="<?= esc_attr($calendar_id) ?>" class="afb-builder-item is-collapsed" data-kind="calendar">
                                <input type="hidden" name="field_order[]" value="<?= esc_attr($calendar_id) ?>" />
                                <div class="afb-builder-item-header">
                                    <span class="afb-handle" aria-hidden="true">::</span>
                                    <div class="min-w-0 flex-1">
                                        <div class="afb-item-title"><?= esc_html($calendar_label !== '' ? $calendar_label : 'Calendar Picker') ?></div>
                                        <div class="afb-item-subtitle">Date picker with optional eAlert Wednesdays preset</div>
                                    </div>
                                    <span class="afb-chip">Calendar</span>
                                    <span class="afb-chip afb-calendar-half-chip" style="<?= ($calendar_chk_half || $calendar_chk_third) ? '' : 'display:none;' ?>"><?= $calendar_chk_third ? '1/3' : '1/2' ?></span>
                                    <button type="button" class="afb-admin-btn afb-collapse-toggle">Expand</button>
                                    <button type="button" class="afb-admin-btn afb-duplicate-item">Duplicate</button>
                                    <button type="button" class="afb-admin-btn remove-builder-item">Remove</button>
                                </div>
                                <div class="afb-builder-item-body">
                                    <div class="grid gap-3 md:grid-cols-2 lg:grid-cols-3">
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="required_fields[]" value="<?= esc_attr($calendar_id) ?>" <?= $calendar_chk_required ?> />
                                            Required
                                        </label>
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="half_width_fields[]" value="<?= esc_attr($calendar_id) ?>" <?= $calendar_chk_half ?> />
                                            1/2 width
                                        </label>
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="third_width_fields[]" value="<?= esc_attr($calendar_id) ?>" <?= $calendar_chk_third ?> />
                                            1/3 width
                                        </label>
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="submit_block_fields[]" value="<?= esc_attr($calendar_id) ?>" <?= $calendar_chk_block ?> />
                                            Block submit when visible
                                        </label>
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Field label</label>
                                        <input type="text" name="custom_calendar_labels[<?= esc_attr($calendar_id) ?>]" value="<?= esc_attr($calendar_label) ?>" class="afb-admin-input" placeholder="Example: Requested publish date">
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Helper text</label>
                                        <textarea name="custom_calendar_descriptions[<?= esc_attr($calendar_id) ?>]" rows="3" class="afb-admin-textarea" placeholder="Optional short context shown below the label"><?= esc_textarea($calendar_desc) ?></textarea>
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Placeholder</label>
                                        <input type="text" name="custom_calendar_placeholders[<?= esc_attr($calendar_id) ?>]" value="<?= esc_attr($calendar_placeholder) ?>" class="afb-admin-input" placeholder="Example: Select a date">
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Date source</label>
                                        <select name="custom_calendar_preset_modes[<?= esc_attr($calendar_id) ?>]" class="afb-admin-select">
                                            <option value="none" <?= selected($calendar_preset_mode, 'none', false) ?>>Manual date picker</option>
                                            <option value="ealert_next_4_wednesdays" <?= selected($calendar_preset_mode, 'ealert_next_4_wednesdays', false) ?>>Next 4 Wednesdays (eAlert)</option>
                                        </select>
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Sync destination</label>
                                        <select name="custom_calendar_sync_modes[<?= esc_attr($calendar_id) ?>]" class="afb-admin-select afb-calendar-sync-mode">
                                            <option value="none" <?= selected($calendar_sync_mode, 'none', false) ?>>Do not sync (append to task description)</option>
                                            <option value="text" <?= selected($calendar_sync_mode, 'text', false) ?>>Asana text field</option>
                                            <option value="due_date" <?= selected($calendar_sync_mode, 'due_date', false) ?>>Task due date</option>
                                        </select>
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Sync to Asana text field (when destination is text)</label>
                                        <select name="custom_calendar_sync_fields[<?= esc_attr($calendar_id) ?>]" class="afb-admin-select">
                                            <option value="">Select text field</option>
                                            <?php foreach ((array) $text_sync_targets as $sync_gid => $sync_name): ?>
                                                <option value="<?= esc_attr($sync_gid) ?>" <?= selected($calendar_sync_field, $sync_gid, false) ?>>
                                                    <?= esc_html($sync_name . ' (' . $sync_gid . ')') ?>
                                                </option>
                                            <?php endforeach; ?>
                                        </select>
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Private companion target field (optional)</label>
                                        <select name="private_companion_field_targets[<?= esc_attr($calendar_id) ?>]" class="afb-admin-select">
                                            <option value="">Do not map to private project</option>
                                            <?php foreach ((array) $private_calendar_field_targets as $private_target_gid => $private_target): ?>
                                                <option value="<?= esc_attr($private_target_gid) ?>" <?= selected($calendar_private_target, $private_target_gid, false) ?>>
                                                    <?= esc_html((string) ($private_target['label'] ?? $private_target_gid)) ?>
                                                </option>
                                            <?php endforeach; ?>
                                        </select>
                                    </div>

                                    <?php $afb_render_condition_editor($calendar_id, $calendar_cond); ?>
                                    <p class="text-xs text-slate-500 mt-1 mb-0">When using the eAlert preset, choices are generated from triage Wednesday logic if available. Sync can target a text custom field or the Asana task due date.</p>
                                </div>
                            </li>

                        <?php elseif (isset($setting['type']) && $setting['type'] === 'repeater'):
                            $repeater_id = $setting['id'];
                            $repeater_label = (string) ($custom_repeater_labels[$repeater_id] ?? ($setting['label'] ?? ''));
                            $repeater_desc = (string) ($custom_repeater_descriptions[$repeater_id] ?? ($setting['description'] ?? ''));
                            $repeater_columns = (string) ($custom_repeater_columns[$repeater_id] ?? ($setting['columns'] ?? "Name\nSurname\nEmail\nPhone\nAgreement"));
                            if ($repeater_columns === '') {
                                $repeater_columns = "Name\nSurname\nEmail\nPhone\nAgreement";
                            }
                            $repeater_min_rows = max(0, min(250, (int) ($custom_repeater_min_rows[$repeater_id] ?? ($setting['min_rows'] ?? 0))));
                            $repeater_max_rows = max(0, min(250, (int) ($custom_repeater_max_rows[$repeater_id] ?? ($setting['max_rows'] ?? 0))));
                            if ($repeater_max_rows > 0 && $repeater_max_rows < $repeater_min_rows) {
                                $repeater_max_rows = $repeater_min_rows;
                            }
                            $repeater_save_mode = sanitize_text_field((string) ($custom_repeater_save_mode[$repeater_id] ?? ($setting['save_mode'] ?? 'subtasks')));
                            if ($repeater_save_mode !== 'description') {
                                $repeater_save_mode = 'subtasks';
                            }
                            $repeater_chk_required = in_array($repeater_id, $required_fields, true) ? 'checked' : '';
                            $repeater_chk_half = in_array($repeater_id, $half_width_fields, true) ? 'checked' : '';
                            $repeater_chk_third = in_array($repeater_id, $third_width_fields, true) ? 'checked' : '';
                            $repeater_chk_block = in_array($repeater_id, $submit_block_fields, true) ? 'checked' : '';
                            $repeater_cond = $conditions[$repeater_id] ?? ['depends_on' => '', 'value' => '', 'values' => []];
                            $repeater_field_map = [];
                            $repeater_field_map_raw = $custom_repeater_field_map[$repeater_id] ?? ($setting['field_map'] ?? []);
                            if (is_array($repeater_field_map_raw)) {
                                foreach ($repeater_field_map_raw as $mapped_gid_raw) {
                                    $mapped_gid = sanitize_text_field((string) $mapped_gid_raw);
                                    if ($mapped_gid === '' || !ctype_digit($mapped_gid) || in_array($mapped_gid, $repeater_field_map, true)) {
                                        continue;
                                    }

                                    $repeater_field_map[] = $mapped_gid;
                                }
                            }

                            // Legacy compatibility: numeric column labels act as mapped Asana field gids.
                            $repeater_column_lines = preg_split('/\r\n|\r|\n/', (string) $repeater_columns);
                            if (is_array($repeater_column_lines)) {
                                foreach ($repeater_column_lines as $column_line_raw) {
                                    $column_gid = sanitize_text_field((string) $column_line_raw);
                                    if ($column_gid === '' || !ctype_digit($column_gid) || in_array($column_gid, $repeater_field_map, true)) {
                                        continue;
                                    }

                                    $repeater_field_map[] = $column_gid;
                                }
                            }
                        ?>
                            <li data-id="<?= esc_attr($repeater_id) ?>" class="afb-builder-item is-collapsed" data-kind="repeater">
                                <input type="hidden" name="field_order[]" value="<?= esc_attr($repeater_id) ?>" />
                                <div class="afb-builder-item-header">
                                    <span class="afb-handle" aria-hidden="true">::</span>
                                    <div class="min-w-0 flex-1">
                                        <div class="afb-item-title\"><?= esc_html($repeater_label !== '' ? $repeater_label : 'Repeater List') ?></div>
                                        <div class="afb-item-subtitle"><?= $repeater_save_mode === 'description' ? 'Rows append to the main task description' : 'One row per entry; each row creates a subtask' ?></div>
                                    </div>
                                    <span class="afb-chip">Repeater</span>
                                    <span class="afb-chip afb-repeater-half-chip" style="<?= ($repeater_chk_half || $repeater_chk_third) ? '' : 'display:none;' ?>"><?= $repeater_chk_third ? '1/3' : '1/2' ?></span>
                                    <button type="button" class="afb-admin-btn afb-collapse-toggle">Expand</button>
                                    <button type="button" class="afb-admin-btn afb-duplicate-item">Duplicate</button>
                                    <button type="button" class="afb-admin-btn remove-builder-item">Remove</button>
                                </div>
                                <div class="afb-builder-item-body">
                                    <div class="grid gap-3 md:grid-cols-2 lg:grid-cols-3">
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="required_fields[]" value="<?= esc_attr($repeater_id) ?>" <?= $repeater_chk_required ?> />
                                            Required
                                        </label>
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="half_width_fields[]" value="<?= esc_attr($repeater_id) ?>" <?= $repeater_chk_half ?> />
                                            1/2 width
                                        </label>
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="third_width_fields[]" value="<?= esc_attr($repeater_id) ?>" <?= $repeater_chk_third ?> />
                                            1/3 width
                                        </label>
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="submit_block_fields[]" value="<?= esc_attr($repeater_id) ?>" <?= $repeater_chk_block ?> />
                                            Block submit when visible
                                        </label>
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Field label</label>
                                        <input type="text" name="custom_repeater_labels[<?= esc_attr($repeater_id) ?>]" value="<?= esc_attr($repeater_label) ?>" class="afb-admin-input" placeholder="Example: People on this shoot">
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Helper text</label>
                                        <textarea name="custom_repeater_descriptions[<?= esc_attr($repeater_id) ?>]" rows="3" class="afb-admin-textarea" placeholder="Optional short context shown below the label"><?= esc_textarea($repeater_desc) ?></textarea>
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Save repeater rows as</label>
                                        <select name="custom_repeater_save_mode[<?= esc_attr($repeater_id) ?>]" class="afb-admin-select afb-repeater-save-mode">
                                            <option value="subtasks" <?= $repeater_save_mode === 'subtasks' ? 'selected' : '' ?>>Asana subtasks (one per row)</option>
                                            <option value="description" <?= $repeater_save_mode === 'description' ? 'selected' : '' ?>>Task description content</option>
                                        </select>
                                        <p class="text-xs text-slate-500 mt-1 mb-0 afb-repeater-mode-note"><?= $repeater_save_mode === 'description' ? 'Rows are appended to the main task Notes/Description.' : 'Rows create child subtasks under the main task.' ?></p>
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Columns (one per line)</label>
                                        <textarea name="custom_repeater_columns[<?= esc_attr($repeater_id) ?>]" rows="7" class="afb-admin-textarea" placeholder="Name&#10;Surname&#10;Email&#10;Phone&#10;Agreement"><?= esc_textarea($repeater_columns) ?></textarea>
                                    </div>
                                    <div class="afb-repeater-map-wrap" data-repeater-id="<?= esc_attr($repeater_id) ?>" data-repeater-save-mode="<?= esc_attr($repeater_save_mode) ?>">
                                        <label class="block text-xs text-slate-600 mb-1">Asana field mapping (subtask mode)</label>
                                        <p class="text-xs text-slate-500 mt-0 mb-2 afb-repeater-map-hint">Drag Asana fields from the left into this list. The order here controls each repeater row layout and the custom fields written on subtasks.</p>
                                        <ul class="afb-repeater-map-list space-y-2" data-repeater-id="<?= esc_attr($repeater_id) ?>">
                                            <?php foreach ($repeater_field_map as $mapped_gid):
                                                $mapped_gid = sanitize_text_field((string) $mapped_gid);
                                                if ($mapped_gid === '' || !ctype_digit($mapped_gid)) {
                                                    continue;
                                                }

                                                $mapped_setting = $field_map[$mapped_gid] ?? [];
                                                $mapped_field = is_array($mapped_setting) ? ($mapped_setting['custom_field'] ?? []) : [];
                                                $mapped_type = sanitize_text_field((string) ($mapped_field['type'] ?? 'text'));
                                                $mapped_label = sanitize_text_field((string) ($labels[$mapped_gid] ?? ($mapped_field['name'] ?? ('Field ' . $mapped_gid))));
                                                if ($mapped_label === '') {
                                                    $mapped_label = 'Field ' . $mapped_gid;
                                                }
                                            ?>
                                                <li class="afb-repeater-map-item flex items-center gap-2 rounded border border-slate-200 bg-white px-2 py-2" data-field-gid="<?= esc_attr($mapped_gid) ?>" data-field-type="<?= esc_attr($mapped_type !== '' ? $mapped_type : 'text') ?>">
                                                    <input type="hidden" name="custom_repeater_field_map[<?= esc_attr($repeater_id) ?>][]" value="<?= esc_attr($mapped_gid) ?>">
                                                    <span class="afb-repeater-map-handle" aria-hidden="true">::</span>
                                                    <div class="min-w-0 flex-1">
                                                        <div class="afb-repeater-map-name text-sm text-slate-800"><?= esc_html($mapped_label) ?></div>
                                                        <div class="afb-item-subtitle"><?= esc_html(($mapped_type !== '' ? $mapped_type : 'text') . ' - ' . $mapped_gid) ?></div>
                                                    </div>
                                                    <button type="button" class="afb-admin-btn afb-repeater-map-remove">Remove</button>
                                                </li>
                                            <?php endforeach; ?>
                                        </ul>
                                        <p class="text-xs text-slate-400 mt-2 mb-0 afb-repeater-map-empty" style="<?= empty($repeater_field_map) ? '' : 'display:none;' ?>">No mapped Asana fields yet. Drag a field from the left list into this area.</p>
                                        <p class="text-xs text-slate-500 mt-2 mb-0">When mapped fields are present, the repeater uses them instead of the plain column list.</p>
                                    </div>
                                    <div class="grid gap-3 md:grid-cols-2">
                                        <div>
                                            <label class="block text-xs text-slate-600 mb-1">Minimum rows</label>
                                            <input type="number" min="0" max="250" step="1" name="custom_repeater_min_rows[<?= esc_attr($repeater_id) ?>]" value="<?= esc_attr((string) $repeater_min_rows) ?>" class="afb-admin-input" placeholder="0">
                                        </div>
                                        <div>
                                            <label class="block text-xs text-slate-600 mb-1">Maximum rows</label>
                                            <input type="number" min="0" max="250" step="1" name="custom_repeater_max_rows[<?= esc_attr($repeater_id) ?>]" value="<?= esc_attr((string) $repeater_max_rows) ?>" class="afb-admin-input" placeholder="0 (unlimited)">
                                        </div>
                                    </div>

                                    <?php $afb_render_condition_editor($repeater_id, $repeater_cond); ?>
                                    <p class="text-xs text-slate-500 mt-1 mb-0 afb-repeater-output-hint"><?= $repeater_save_mode === 'description' ? 'Rows are appended to the main task description when this block is visible and has content.' : 'Each repeater row becomes one Asana subtask under the main task when this block is visible and has content.' ?></p>
                                </div>
                            </li>

                        <?php elseif (isset($setting['type']) && $setting['type'] === 'task_name'):
                            $task_name_id = $setting['id'];
                            $task_name_label = sanitize_text_field((string) ($custom_task_name_labels[$task_name_id] ?? ($setting['label'] ?? '')));
                            $task_name_title = $task_name_label !== '' ? $task_name_label : 'Task Name Builder';
                            $task_name_template = (string) ($custom_task_name_templates[$task_name_id] ?? ($setting['template'] ?? ''));
                            $task_name_cond = $conditions[$task_name_id] ?? ['depends_on' => '', 'value' => '', 'values' => []];
                        ?>
                            <li data-id="<?= esc_attr($task_name_id) ?>" class="afb-builder-item is-collapsed" data-kind="task_name">
                                <input type="hidden" name="field_order[]" value="<?= esc_attr($task_name_id) ?>" />
                                <div class="afb-builder-item-header">
                                    <span class="afb-handle" aria-hidden="true">::</span>
                                    <div class="min-w-0 flex-1">
                                        <div class="afb-item-title"><?= esc_html($task_name_title) ?></div>
                                        <div class="afb-item-subtitle">Build task titles from submitted form values</div>
                                    </div>
                                    <span class="afb-chip">Task Name</span>
                                    <button type="button" class="afb-admin-btn afb-collapse-toggle">Expand</button>
                                    <button type="button" class="afb-admin-btn afb-duplicate-item">Duplicate</button>
                                    <button type="button" class="afb-admin-btn remove-builder-item">Remove</button>
                                </div>
                                <div class="afb-builder-item-body">
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Builder label</label>
                                        <input type="text" name="custom_task_name_labels[<?= esc_attr($task_name_id) ?>]" class="afb-admin-input" placeholder="Example: Campaign task title" value="<?= esc_attr($task_name_label) ?>">
                                    </div>
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Template</label>
                                        <textarea name="custom_task_name_templates[<?= esc_attr($task_name_id) ?>]" rows="3" class="afb-admin-textarea afb-task-name-template" placeholder="Example: {{submitter_name}} {{field:calendar_12345678}}"><?= esc_textarea($task_name_template) ?></textarea>
                                        <p class="text-xs text-slate-500 mt-1 mb-0">If the template resolves to a blank value, the job number remains the task title.</p>
                                    </div>
                                    <div class="grid gap-3 md:grid-cols-[minmax(0,1fr)_auto] items-end">
                                        <div>
                                            <label class="block text-xs text-slate-600 mb-1">Insert variable</label>
                                            <select class="afb-admin-select afb-task-name-variable-select">
                                                <option value="">Choose variable</option>
                                            </select>
                                        </div>
                                        <div>
                                            <button type="button" class="afb-admin-btn afb-task-name-insert-variable">Insert</button>
                                        </div>
                                    </div>
                                    <p class="text-xs text-slate-400 mt-2 mb-0">Built-ins: {{job_number}}, {{submitter_name}}, {{submitter_email}}, {{due_date}}. Field tokens use {{field:...}}.</p>
                                    <?php $afb_render_condition_editor($task_name_id, $task_name_cond); ?>
                                </div>
                            </li>

                        <?php elseif (isset($setting['type']) && $setting['type'] === 'due_date_tool'):
                            $due_id = $setting['id'];
                            $due_cfg = is_array($custom_due_date_configs[$due_id] ?? null)
                                ? $custom_due_date_configs[$due_id]
                                : ((is_array($setting['config'] ?? null)) ? $setting['config'] : []);
                            $due_default = is_array($due_cfg['default'] ?? null) ? $due_cfg['default'] : [];
                            $due_default_base_raw = (string) ($due_default['base'] ?? 'today');
                            $due_default_base = in_array($due_default_base_raw, ['today', 'field'], true) ? $due_default_base_raw : 'today';
                            $due_default_base_field = sanitize_text_field((string) ($due_default['base_field'] ?? ''));
                            $due_default_offset = (int) ($due_default['offset'] ?? 0);
                            $due_default_mode_raw = (string) ($due_default['mode'] ?? 'business');
                            $due_default_mode = in_array($due_default_mode_raw, ['business', 'calendar'], true) ? $due_default_mode_raw : 'business';
                            $due_default_allow_weekends = !empty($due_default['allow_weekends']);
                            $due_override_manual = !empty($due_cfg['override_manual']);
                            $due_rules = is_array($due_cfg['rules'] ?? null) ? $due_cfg['rules'] : [];
                            $due_rules_json = wp_json_encode($due_rules);
                            if (!is_string($due_rules_json)) {
                                $due_rules_json = '[]';
                            }
                        ?>
                            <li data-id="<?= esc_attr($due_id) ?>" class="afb-builder-item is-collapsed" data-kind="due_date_tool">
                                <input type="hidden" name="field_order[]" value="<?= esc_attr($due_id) ?>" />
                                <div class="afb-builder-item-header">
                                    <span class="afb-handle" aria-hidden="true">::</span>
                                    <div class="min-w-0 flex-1">
                                        <div class="afb-item-title">Due Date Tool</div>
                                        <div class="afb-item-subtitle">Rule-driven due date formulas (business days by default)</div>
                                    </div>
                                    <span class="afb-chip">Due Date</span>
                                    <button type="button" class="afb-admin-btn afb-collapse-toggle">Expand</button>
                                    <button type="button" class="afb-admin-btn afb-duplicate-item">Duplicate</button>
                                    <button type="button" class="afb-admin-btn remove-builder-item">Remove</button>
                                </div>
                                <div class="afb-builder-item-body">
                                    <div class="grid gap-3 md:grid-cols-2 lg:grid-cols-3">
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="custom_due_date_override_manual[]" value="<?= esc_attr($due_id) ?>" <?= $due_override_manual ? 'checked' : '' ?> />
                                            Override manual due date input
                                        </label>
                                    </div>

                                    <div class="afb-collapsible-section afb-due-date-default-section is-expanded">
                                        <div class="afb-cond-header">
                                            <div class="afb-cond-header-title">
                                                <span>Default Formula</span>
                                            </div>
                                            <div class="afb-cond-header-controls">
                                                <button type="button" class="afb-admin-btn afb-section-toggle" aria-expanded="true">Hide</button>
                                            </div>
                                        </div>
                                        <div class="afb-collapsible-body">
                                            <div class="grid gap-3 md:grid-cols-2 lg:grid-cols-3">
                                                <div>
                                                    <label class="block text-xs text-slate-600 mb-1">Base date</label>
                                                    <select name="custom_due_date_default_base[<?= esc_attr($due_id) ?>]" class="afb-admin-select afb-due-default-base">
                                                        <option value="today" <?= selected($due_default_base, 'today', false) ?>>Today</option>
                                                        <option value="field" <?= selected($due_default_base, 'field', false) ?>>Date field from form</option>
                                                    </select>
                                                </div>
                                                <div class="afb-due-default-base-field-wrap" style="<?= $due_default_base === 'field' ? '' : 'display:none;' ?>">
                                                    <label class="block text-xs text-slate-600 mb-1">Base date field</label>
                                                    <select name="custom_due_date_default_base_field[<?= esc_attr($due_id) ?>]" class="afb-admin-select afb-due-default-base-field">
                                                        <option value="">Select date field</option>
                                                        <?php foreach ((array) $due_date_base_field_targets as $target_gid => $target_label): ?>
                                                            <option value="<?= esc_attr($target_gid) ?>" <?= selected($due_default_base_field, $target_gid, false) ?>><?= esc_html($target_label) ?></option>
                                                        <?php endforeach; ?>
                                                    </select>
                                                </div>
                                                <div>
                                                    <label class="block text-xs text-slate-600 mb-1">Offset days</label>
                                                    <input type="number" step="1" name="custom_due_date_default_offset[<?= esc_attr($due_id) ?>]" value="<?= esc_attr((string) $due_default_offset) ?>" class="afb-admin-input" placeholder="Example: 7 or -3">
                                                </div>
                                                <div>
                                                    <label class="block text-xs text-slate-600 mb-1">Offset mode</label>
                                                    <select name="custom_due_date_default_mode[<?= esc_attr($due_id) ?>]" class="afb-admin-select">
                                                        <option value="business" <?= selected($due_default_mode, 'business', false) ?>>Business days (default)</option>
                                                        <option value="calendar" <?= selected($due_default_mode, 'calendar', false) ?>>Calendar days</option>
                                                    </select>
                                                </div>
                                                <div>
                                                    <label class="afb-flag-toggle">
                                                        <input type="checkbox" class="afb-admin-check" name="custom_due_date_default_allow_weekends[]" value="<?= esc_attr($due_id) ?>" <?= $due_default_allow_weekends ? 'checked' : '' ?> />
                                                        Allow weekends in result
                                                    </label>
                                                </div>
                                            </div>
                                        </div>
                                    </div>

                                    <div class="afb-collapsible-section afb-due-date-rules-section is-expanded">
                                        <div class="afb-cond-header">
                                            <div class="afb-cond-header-title">
                                                <span>Rules</span>
                                            </div>
                                            <div class="afb-cond-header-controls">
                                                <button type="button" class="afb-admin-btn afb-section-toggle" aria-expanded="true">Hide</button>
                                                <button type="button" class="afb-admin-btn afb-due-rule-add">Add rule</button>
                                            </div>
                                        </div>
                                        <div class="afb-collapsible-body">
                                            <div class="afb-due-date-rules space-y-2"></div>
                                            <input
                                                type="hidden"
                                                name="custom_due_date_rules[<?= esc_attr($due_id) ?>]"
                                                class="afb-due-date-rules-input"
                                                value='<?= esc_attr($due_rules_json) ?>'
                                            />
                                            <p class="text-xs text-slate-400 mt-3 mb-0">Rules are evaluated top-to-bottom. First match wins.</p>
                                            <p class="text-xs text-slate-500 mt-1 mb-0">Each rule can use today or a selected date field as a base, then apply + or - day offsets.</p>
                                        </div>
                                    </div>
                                </div>
                            </li>

                        <?php elseif (isset($setting['type']) && $setting['type'] === 'assignee_tool'):
                            $assignee_id = $setting['id'];
                            $assignee_label = sanitize_text_field((string) ($custom_assignee_labels[$assignee_id] ?? ($setting['label'] ?? '')));
                            $assignee_title = $assignee_label !== '' ? $assignee_label : 'Assignee Tool';
                            $assignee_cfg = is_array($custom_assignee_configs[$assignee_id] ?? null)
                                ? $custom_assignee_configs[$assignee_id]
                                : ((is_array($setting['config'] ?? null)) ? $setting['config'] : []);

                            $assignee_default = sanitize_text_field((string) ($assignee_cfg['default_assignee'] ?? ''));
                            $assignee_default = preg_replace('/\D+/', '', $assignee_default);
                            if (!is_string($assignee_default)) {
                                $assignee_default = '';
                            }

                            $assignee_default_fallbacks_raw = [];
                            if (isset($assignee_cfg['default_fallback_assignees']) && is_array($assignee_cfg['default_fallback_assignees'])) {
                                $assignee_default_fallbacks_raw = $assignee_cfg['default_fallback_assignees'];
                            } elseif (isset($assignee_cfg['fallback_assignees']) && is_array($assignee_cfg['fallback_assignees'])) {
                                $assignee_default_fallbacks_raw = $assignee_cfg['fallback_assignees'];
                            }

                            $assignee_default_fallbacks = [];
                            foreach ($assignee_default_fallbacks_raw as $raw_fallback_gid) {
                                $fallback_gid = sanitize_text_field((string) $raw_fallback_gid);
                                $fallback_gid = preg_replace('/\D+/', '', $fallback_gid);
                                if (!is_string($fallback_gid) || $fallback_gid === '' || $fallback_gid === $assignee_default || in_array($fallback_gid, $assignee_default_fallbacks, true)) {
                                    continue;
                                }
                                $assignee_default_fallbacks[] = $fallback_gid;
                            }

                            $assignee_rules_raw = isset($assignee_cfg['rules']) && is_array($assignee_cfg['rules'])
                                ? $assignee_cfg['rules']
                                : [];
                            $assignee_rules = [];
                            foreach ($assignee_rules_raw as $assignee_rule) {
                                if (!is_array($assignee_rule)) {
                                    continue;
                                }

                                $depends_on = sanitize_text_field((string) ($assignee_rule['depends_on'] ?? ''));
                                if ($depends_on === '') {
                                    continue;
                                }

                                $rule_values_raw = [];
                                if (isset($assignee_rule['values']) && is_array($assignee_rule['values'])) {
                                    $rule_values_raw = $assignee_rule['values'];
                                } elseif (isset($assignee_rule['value']) && $assignee_rule['value'] !== '') {
                                    $rule_values_raw = [$assignee_rule['value']];
                                }

                                $rule_values = array_values(array_unique(array_filter(array_map('sanitize_text_field', $rule_values_raw), static function ($val) {
                                    return $val !== '';
                                })));
                                if (empty($rule_values)) {
                                    continue;
                                }

                                $rule_assignee = sanitize_text_field((string) ($assignee_rule['assignee'] ?? ''));
                                $rule_assignee = preg_replace('/\D+/', '', $rule_assignee);
                                if (!is_string($rule_assignee) || $rule_assignee === '') {
                                    continue;
                                }

                                $rule_fallbacks_raw = isset($assignee_rule['fallback_assignees']) && is_array($assignee_rule['fallback_assignees'])
                                    ? $assignee_rule['fallback_assignees']
                                    : [];
                                $rule_fallbacks = [];
                                foreach ($rule_fallbacks_raw as $raw_rule_fallback_gid) {
                                    $rule_fallback_gid = sanitize_text_field((string) $raw_rule_fallback_gid);
                                    $rule_fallback_gid = preg_replace('/\D+/', '', $rule_fallback_gid);
                                    if (!is_string($rule_fallback_gid) || $rule_fallback_gid === '' || $rule_fallback_gid === $rule_assignee || in_array($rule_fallback_gid, $rule_fallbacks, true)) {
                                        continue;
                                    }
                                    $rule_fallbacks[] = $rule_fallback_gid;
                                }

                                $assignee_rules[] = [
                                    'depends_on'         => $depends_on,
                                    'value'              => $rule_values[0],
                                    'values'             => $rule_values,
                                    'assignee'           => $rule_assignee,
                                    'fallback_assignees' => $rule_fallbacks,
                                ];
                            }

                            $assignee_rules_json = wp_json_encode($assignee_rules);
                            if (!is_string($assignee_rules_json)) {
                                $assignee_rules_json = '[]';
                            }

                            $assignee_check_ooo = array_key_exists('check_ooo_today', $assignee_cfg)
                                ? !empty($assignee_cfg['check_ooo_today'])
                                : true;
                        ?>
                            <li data-id="<?= esc_attr($assignee_id) ?>" class="afb-builder-item is-collapsed" data-kind="assignee_tool">
                                <input type="hidden" name="field_order[]" value="<?= esc_attr($assignee_id) ?>" />
                                <div class="afb-builder-item-header">
                                    <span class="afb-handle" aria-hidden="true">::</span>
                                    <div class="min-w-0 flex-1">
                                        <div class="afb-item-title"><?= esc_html($assignee_title) ?></div>
                                        <div class="afb-item-subtitle">Rule-driven assignment with OOO-aware fallback chain</div>
                                    </div>
                                    <span class="afb-chip">Assignee</span>
                                    <button type="button" class="afb-admin-btn afb-collapse-toggle">Expand</button>
                                    <button type="button" class="afb-admin-btn afb-duplicate-item">Duplicate</button>
                                    <button type="button" class="afb-admin-btn remove-builder-item">Remove</button>
                                </div>
                                <div class="afb-builder-item-body">
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Builder label</label>
                                        <input type="text" name="custom_assignee_labels[<?= esc_attr($assignee_id) ?>]" class="afb-admin-input" placeholder="Example: Campaign assignee" value="<?= esc_attr($assignee_label) ?>">
                                    </div>
                                    <div class="grid gap-3 md:grid-cols-2 lg:grid-cols-3">
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="custom_assignee_check_ooo[]" value="<?= esc_attr($assignee_id) ?>" <?= $assignee_check_ooo ? 'checked' : '' ?> />
                                            Check out-of-office status (today)
                                        </label>
                                    </div>

                                    <div class="grid gap-3 md:grid-cols-2">
                                        <div>
                                            <label class="block text-xs text-slate-600 mb-1">Default assignee</label>
                                            <select name="custom_assignee_default[<?= esc_attr($assignee_id) ?>]" class="afb-admin-select afb-assignee-default">
                                                <option value="">Leave unassigned by default</option>
                                                <?php foreach ((array) $assignee_member_options as $member_opt):
                                                    $member_gid = sanitize_text_field((string) ($member_opt['gid'] ?? ''));
                                                    if ($member_gid === '') continue;
                                                    $member_name = sanitize_text_field((string) ($member_opt['name'] ?? $member_gid));
                                                ?>
                                                    <option value="<?= esc_attr($member_gid) ?>" <?= selected($assignee_default, $member_gid, false) ?>>
                                                        <?= esc_html($member_name . ' (' . $member_gid . ')') ?>
                                                    </option>
                                                <?php endforeach; ?>
                                            </select>
                                        </div>
                                        <div>
                                            <label class="block text-xs text-slate-600 mb-1">Default fallback assignees</label>
                                            <select name="custom_assignee_default_fallbacks[<?= esc_attr($assignee_id) ?>][]" class="afb-admin-select afb-assignee-default-fallbacks" multiple size="6">
                                                <?php foreach ((array) $assignee_member_options as $member_opt):
                                                    $member_gid = sanitize_text_field((string) ($member_opt['gid'] ?? ''));
                                                    if ($member_gid === '') continue;
                                                    $member_name = sanitize_text_field((string) ($member_opt['name'] ?? $member_gid));
                                                ?>
                                                    <option value="<?= esc_attr($member_gid) ?>" <?= in_array($member_gid, $assignee_default_fallbacks, true) ? 'selected' : '' ?>>
                                                        <?= esc_html($member_name . ' (' . $member_gid . ')') ?>
                                                    </option>
                                                <?php endforeach; ?>
                                            </select>
                                            <p class="text-xs text-slate-400 mt-1 mb-0">Hold Ctrl / Cmd to choose multiple fallback assignees.</p>
                                        </div>
                                    </div>

                                    <div class="afb-collapsible-section afb-assignee-rules-section is-expanded">
                                        <div class="afb-cond-header">
                                            <div class="afb-cond-header-title">
                                                <span>Rules</span>
                                            </div>
                                            <div class="afb-cond-header-controls">
                                                <button type="button" class="afb-admin-btn afb-section-toggle" aria-expanded="true">Hide</button>
                                                <button type="button" class="afb-admin-btn afb-assignee-rule-add">Add rule</button>
                                            </div>
                                        </div>
                                        <div class="afb-collapsible-body">
                                            <div class="afb-assignee-rules space-y-2"></div>
                                            <input
                                                type="hidden"
                                                name="custom_assignee_rules[<?= esc_attr($assignee_id) ?>]"
                                                class="afb-assignee-rules-input"
                                                value='<?= esc_attr($assignee_rules_json) ?>'
                                            />
                                            <p class="text-xs text-slate-400 mt-3 mb-0">Rules are evaluated top-to-bottom. First match wins.</p>
                                            <p class="text-xs text-slate-500 mt-1 mb-0">If all candidates are out-of-office, the task is left unassigned. If OOO lookup is unavailable, assignment continues with the normal candidate order.</p>
                                        </div>
                                    </div>
                                </div>
                            </li>

                        <?php elseif (isset($setting['type']) && $setting['type'] === 'recipient_tool'):
                            $recipient_id = $setting['id'];
                            $recipient_label = sanitize_text_field((string) ($custom_recipient_labels[$recipient_id] ?? ($setting['label'] ?? '')));
                            $recipient_title = $recipient_label !== '' ? $recipient_label : 'Recipients Tool';
                            $recipient_cfg = is_array($custom_recipient_configs[$recipient_id] ?? null)
                                ? $custom_recipient_configs[$recipient_id]
                                : ((is_array($setting['config'] ?? null)) ? $setting['config'] : []);
                            $recipient_cond = $conditions[$recipient_id] ?? ['depends_on' => '', 'value' => '', 'values' => []];

                            $recipient_enabled = !empty($recipient_cfg['enabled']);
                            $recipient_include_submitter = !empty($recipient_cfg['include_submitter']);
                            $recipient_mode_raw = sanitize_text_field((string) ($recipient_cfg['mode'] ?? 'separate'));
                            $recipient_mode = in_array($recipient_mode_raw, ['separate', 'cc'], true)
                                ? $recipient_mode_raw
                                : 'separate';
                            $recipient_subject_template = sanitize_text_field((string) ($recipient_cfg['subject_template'] ?? ''));
                            $recipient_body_template = wp_kses_post((string) ($recipient_cfg['body_template'] ?? ''));
                            $recipient_source_fields_raw = isset($recipient_cfg['source_fields']) && is_array($recipient_cfg['source_fields'])
                                ? $recipient_cfg['source_fields']
                                : [];
                            $recipient_source_fields = array_values(array_unique(array_filter(array_map('sanitize_text_field', $recipient_source_fields_raw), static function ($val) {
                                return $val !== '';
                            })));
                            $recipient_manual_emails_raw = $recipient_cfg['manual_emails'] ?? [];
                            $recipient_manual_emails = [];
                            if (is_array($recipient_manual_emails_raw)) {
                                foreach ($recipient_manual_emails_raw as $manual_email_raw) {
                                    $manual_email = sanitize_email((string) $manual_email_raw);
                                    if (is_email($manual_email)) {
                                        $recipient_manual_emails[] = $manual_email;
                                    }
                                }
                            } else {
                                $manual_text = (string) $recipient_manual_emails_raw;
                                if (preg_match_all('/[A-Z0-9._%+\-]+@[A-Z0-9.\-]+\.[A-Z]{2,}/i', $manual_text, $matches) && !empty($matches[0])) {
                                    foreach ($matches[0] as $candidate) {
                                        $manual_email = sanitize_email((string) $candidate);
                                        if (is_email($manual_email)) {
                                            $recipient_manual_emails[] = $manual_email;
                                        }
                                    }
                                } else {
                                    $manual_email = sanitize_email($manual_text);
                                    if (is_email($manual_email)) {
                                        $recipient_manual_emails[] = $manual_email;
                                    }
                                }
                            }
                            $recipient_manual_emails = array_values(array_unique($recipient_manual_emails));
                            $recipient_manual_emails_text = implode("\n", $recipient_manual_emails);
                        ?>
                            <li data-id="<?= esc_attr($recipient_id) ?>" class="afb-builder-item is-collapsed" data-kind="recipient_tool">
                                <input type="hidden" name="field_order[]" value="<?= esc_attr($recipient_id) ?>" />
                                <div class="afb-builder-item-header">
                                    <span class="afb-handle" aria-hidden="true">::</span>
                                    <div class="min-w-0 flex-1">
                                        <div class="afb-item-title"><?= esc_html($recipient_title) ?></div>
                                        <div class="afb-item-subtitle">Send submission copy to emails from selected fields or manual addresses</div>
                                    </div>
                                    <span class="afb-chip">Recipients</span>
                                    <button type="button" class="afb-admin-btn afb-collapse-toggle">Expand</button>
                                    <button type="button" class="afb-admin-btn afb-duplicate-item">Duplicate</button>
                                    <button type="button" class="afb-admin-btn remove-builder-item">Remove</button>
                                </div>
                                <div class="afb-builder-item-body">
                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Builder label</label>
                                        <input type="text" name="custom_recipient_labels[<?= esc_attr($recipient_id) ?>]" class="afb-admin-input" placeholder="Example: Internal recipients" value="<?= esc_attr($recipient_label) ?>">
                                    </div>
                                    <div class="grid gap-3 md:grid-cols-2 lg:grid-cols-3">
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="custom_recipient_enabled[]" value="<?= esc_attr($recipient_id) ?>" <?= $recipient_enabled ? 'checked' : '' ?> />
                                            Enabled
                                        </label>
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="custom_recipient_include_submitter[]" value="<?= esc_attr($recipient_id) ?>" <?= $recipient_include_submitter ? 'checked' : '' ?> />
                                            Include submitter email
                                        </label>
                                    </div>

                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Recipient source fields</label>
                                        <select name="custom_recipient_source_fields[<?= esc_attr($recipient_id) ?>][]" class="afb-admin-select afb-recipient-source-fields" multiple size="7">
                                            <?php foreach ((array) $recipient_source_targets as $source_gid => $source_label): ?>
                                                <option value="<?= esc_attr($source_gid) ?>" <?= in_array($source_gid, $recipient_source_fields, true) ? 'selected' : '' ?>>
                                                    <?= esc_html($source_label) ?>
                                                </option>
                                            <?php endforeach; ?>
                                        </select>
                                        <p class="text-xs text-slate-400 mt-1 mb-0">Fields can contain one email or multiple emails separated by commas.</p>
                                    </div>

                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Manual recipient emails (optional)</label>
                                        <textarea name="custom_recipient_manual_emails[<?= esc_attr($recipient_id) ?>]" rows="3" class="afb-admin-textarea" placeholder="name@example.com&#10;second@example.com"><?= esc_textarea($recipient_manual_emails_text) ?></textarea>
                                        <p class="text-xs text-slate-400 mt-1 mb-0">Add fixed addresses separated by commas or new lines. These are combined with source-field emails.</p>
                                    </div>

                                    <div class="max-w-sm">
                                        <label class="block text-xs text-slate-600 mb-1">Delivery mode</label>
                                        <select name="custom_recipient_mode[<?= esc_attr($recipient_id) ?>]" class="afb-admin-select">
                                            <option value="separate" <?= selected($recipient_mode, 'separate', false) ?>>Send separate email to each recipient</option>
                                            <option value="cc" <?= selected($recipient_mode, 'cc', false) ?>>Send one email with recipients in CC</option>
                                        </select>
                                    </div>

                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Subject template (optional)</label>
                                        <input type="text" name="custom_recipient_subject_templates[<?= esc_attr($recipient_id) ?>]" value="<?= esc_attr($recipient_subject_template) ?>" class="afb-admin-input" placeholder="Defaults to Submission Copy email subject">
                                    </div>

                                    <div class="grid gap-3 md:grid-cols-[minmax(0,1fr)_auto_auto] items-end">
                                        <div>
                                            <label class="block text-xs text-slate-600 mb-1">Insert variable</label>
                                            <select class="afb-admin-select afb-recipient-variable-select">
                                                <option value="">Choose variable</option>
                                            </select>
                                        </div>
                                        <div>
                                            <button type="button" class="afb-admin-btn afb-recipient-insert-variable" data-target-template="subject">Insert in Subject</button>
                                        </div>
                                        <div>
                                            <button type="button" class="afb-admin-btn afb-recipient-insert-variable" data-target-template="body">Insert in Body</button>
                                        </div>
                                    </div>

                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Body template (optional)</label>
                                        <textarea name="custom_recipient_body_templates[<?= esc_attr($recipient_id) ?>]" rows="5" class="afb-admin-textarea" placeholder="Defaults to Submission Copy email body"><?= esc_textarea($recipient_body_template) ?></textarea>
                                        <p class="text-xs text-slate-500 mt-1 mb-0">Tokens: {{task_name}}, {{request_number}}, {{comms_link}}, {{fields_html}}, {{job_number}}, {{submitter_name}}, {{submitter_email}}, {{due_date}}, {{field:...}}</p>
                                    </div>

                                    <?php $afb_render_condition_editor($recipient_id, $recipient_cond); ?>
                                    <p class="text-xs text-slate-400 mt-1 mb-0">Only send this recipient email when the condition rules match.</p>
                                </div>
                            </li>

                        <?php else:
                            $f = $setting['custom_field'] ?? [];
                            $gid = (string) ($f['gid'] ?? '');
                            if ($gid === '') continue;

                            $chk_used     = in_array($gid, $used_fields, true) ? 'checked' : '';
                            $chk_required = in_array($gid, $required_fields, true) ? 'checked' : '';
                            $chk_hidden   = in_array($gid, $hidden_fields, true) ? 'checked' : '';
                            $chk_ro       = in_array($gid, $readonly_fields, true) ? 'checked' : '';
                            $chk_para     = in_array($gid, $paragraph_fields, true) ? 'checked' : '';
                            $chk_half     = in_array($gid, $half_width_fields, true) ? 'checked' : '';
                            $chk_third    = in_array($gid, $third_width_fields, true) ? 'checked' : '';
                            $chk_block    = in_array($gid, $submit_block_fields, true) ? 'checked' : '';

                            $cond = $conditions[$gid] ?? ['depends_on' => '', 'value' => '', 'values' => []];
                            $cond_norm = $afb_normalize_condition($cond);

                            $label_val = $labels[$gid] ?? '';
                            $desc_val  = $descriptions[$gid] ?? '';
                            $field_text_sync_target = '';
                            if (($f['type'] ?? '') === 'text') {
                                $candidate_sync_target = sanitize_text_field((string) ($custom_text_sync_fields[$gid] ?? ''));
                                if ($candidate_sync_target !== '' && ctype_digit($candidate_sync_target) && $candidate_sync_target !== $gid) {
                                    $field_text_sync_target = $candidate_sync_target;
                                }
                            }
                            $field_private_target = (string) ($private_companion_field_targets[$gid] ?? '');
                            $visible_option_values = [];
                            if (!empty($visible_enum_options[$gid]) && is_array($visible_enum_options[$gid])) {
                                $visible_option_values = array_values(array_unique(array_map('strval', $visible_enum_options[$gid])));
                            }
                            $supports_option_filter = in_array(($f['type'] ?? ''), ['enum', 'multi_enum'], true);
                            $target_enum_options = [];
                            foreach ((array) ($f['enum_options'] ?? []) as $enum_opt) {
                                if (!$enum_opt) continue;
                                if (isset($enum_opt['enabled']) && $enum_opt['enabled'] === false) continue;
                                $opt_gid = (string) ($enum_opt['gid'] ?? '');
                                if ($opt_gid === '') continue;
                                $target_enum_options[] = [
                                    'gid'  => $opt_gid,
                                    'name' => (string) ($enum_opt['name'] ?? $opt_gid),
                                ];
                            }

                            $option_rule_depends_on = '';
                            $option_rule_map = [];
                            if (!empty($option_visibility_rules[$gid]) && is_array($option_visibility_rules[$gid])) {
                                $option_rule_depends_on = (string) ($option_visibility_rules[$gid]['depends_on'] ?? '');
                                $raw_map = $option_visibility_rules[$gid]['map'] ?? [];
                                if (is_array($raw_map)) {
                                    foreach ($raw_map as $source_value_gid => $target_values) {
                                        $source_value_gid = (string) $source_value_gid;
                                        if ($source_value_gid === '') continue;
                                        $vals = is_array($target_values) ? $target_values : [];
                                        $vals = array_values(array_unique(array_filter(array_map('strval', $vals), static function ($val) {
                                            return $val !== '';
                                        })));
                                        if (!empty($vals)) {
                                            $option_rule_map[$source_value_gid] = $vals;
                                        }
                                    }
                                }
                            }
                            $option_rule_map_json = wp_json_encode($option_rule_map);
                        ?>
                            <li data-id="<?= esc_attr($gid) ?>" data-field-type="<?= esc_attr((string) ($f['type'] ?? '')) ?>" data-options='<?= esc_attr(json_encode($f['enum_options'] ?? [])) ?>' class="afb-builder-item is-collapsed" data-kind="field">
                                <input type="hidden" name="field_order[]" value="<?= esc_attr($gid) ?>" class="afb-order-input" />

                                <div class="afb-builder-item-header">
                                    <span class="afb-handle" aria-hidden="true">::</span>
                                    <div class="min-w-0 flex-1">
                                        <div class="afb-item-title"><?= esc_html($f['name'] ?? '') ?></div>
                                        <div class="afb-item-subtitle">
                                            <?= esc_html($f['type'] ?? 'text') ?>
                                            <?php if ($gid === '__NOTES_HTML__'): ?>
                                                <span class="text-slate-400">- writes to Asana task description</span>
                                            <?php endif; ?>
                                        </div>
                                        <div class="afb-item-flags">
                                            <?php
                                                $flags = [];
                                                if ($chk_required) $flags[] = 'Req';
                                                if ($chk_hidden) $flags[] = 'Hidden';
                                                if ($chk_ro) $flags[] = 'RO';
                                                if ($chk_half) $flags[] = '1/2';
                                                if ($chk_third) $flags[] = '1/3';
                                                if ($chk_para) $flags[] = 'Para';
                                                if ($chk_block) $flags[] = 'Block';
                                                if (!empty($cond_norm['rules'])) $flags[] = 'Cond';
                                                if ($supports_option_filter && !empty($visible_option_values)) $flags[] = 'Opts';
                                                if ($supports_option_filter && $option_rule_depends_on !== '' && !empty($option_rule_map)) $flags[] = 'Map';
                                                if ($field_text_sync_target !== '') $flags[] = 'Sync';
                                                if ($label_val !== '') $flags[] = 'Label';
                                            ?>
                                            <?php if (!empty($flags)): ?>
                                                <?= esc_html(implode(' • ', $flags)) ?>
                                            <?php else: ?>
                                                <span class="is-empty">Default</span>
                                            <?php endif; ?>
                                        </div>
                                    </div>
                                    <span class="afb-chip afb-chip-field">Field</span>
                                    <button type="button" class="afb-admin-btn afb-add-to-form">Add</button>
                                    <button type="button" class="afb-admin-btn afb-collapse-toggle">Expand</button>
                                    <button type="button" class="afb-admin-btn remove-builder-item">Remove</button>
                                </div>

                                <div class="afb-builder-item-body">
                                    <input type="checkbox" class="afb-used-toggle" name="used_fields[]" value="<?= esc_attr($gid) ?>" <?= $chk_used ?> style="display:none;" />
                                    <div class="grid gap-3 md:grid-cols-2 lg:grid-cols-3">
                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="required_fields[]" value="<?= esc_attr($gid) ?>" <?= $chk_required ?> />
                                            Required
                                        </label>

                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="hidden_fields[]" value="<?= esc_attr($gid) ?>" <?= $chk_hidden ?> />
                                            Hidden
                                        </label>

                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="readonly_fields[]" value="<?= esc_attr($gid) ?>" <?= $chk_ro ?> />
                                            Read-only
                                        </label>

                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="half_width_fields[]" value="<?= esc_attr($gid) ?>" <?= $chk_half ?> />
                                            1/2 width
                                        </label>

                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="third_width_fields[]" value="<?= esc_attr($gid) ?>" <?= $chk_third ?> />
                                            1/3 width
                                        </label>

                                        <label class="afb-flag-toggle">
                                            <input type="checkbox" class="afb-admin-check" name="submit_block_fields[]" value="<?= esc_attr($gid) ?>" <?= $chk_block ?> />
                                            Block submit when visible
                                        </label>

                                        <?php if (($f['type'] ?? '') === 'text'): ?>
                                            <label class="afb-flag-toggle">
                                                <input type="checkbox" class="afb-admin-check" name="paragraph_fields[]" value="<?= esc_attr($gid) ?>" <?= $chk_para ?> />
                                                Paragraph input
                                            </label>
                                        <?php endif; ?>
                                    </div>

                                    <div class="grid gap-3 md:grid-cols-2">
                                        <div>
                                            <label class="block text-xs text-slate-600 mb-1">Custom label</label>
                                            <input type="text" name="labels[<?= esc_attr($gid) ?>]" value="<?= esc_attr($label_val) ?>" class="afb-admin-input" placeholder="Optional replacement label">
                                        </div>
                                        <div>
                                            <label class="block text-xs text-slate-600 mb-1">Description</label>
                                            <input type="text" name="descriptions[<?= esc_attr($gid) ?>]" value="<?= esc_attr($desc_val) ?>" class="afb-admin-input" placeholder="Optional helper text">
                                        </div>
                                    </div>

                                    <?php if (($f['type'] ?? '') === 'text'): ?>
                                        <div>
                                            <label class="block text-xs text-slate-600 mb-1">Sync to Asana text field (optional)</label>
                                            <select name="custom_text_sync_fields[<?= esc_attr($gid) ?>]" class="afb-admin-select">
                                                <option value="">Use this field (default)</option>
                                                <?php foreach ((array) $text_sync_targets as $sync_gid => $sync_name):
                                                    if ((string) $sync_gid === $gid) {
                                                        continue;
                                                    }
                                                ?>
                                                    <option value="<?= esc_attr($sync_gid) ?>" <?= selected($field_text_sync_target, $sync_gid, false) ?>>
                                                        <?= esc_html($sync_name . ' (' . $sync_gid . ')') ?>
                                                    </option>
                                                <?php endforeach; ?>
                                            </select>
                                            <p class="text-xs text-slate-500 mt-1 mb-0">When set, this input writes to the selected Asana text field instead of its own field ID.</p>
                                        </div>
                                    <?php endif; ?>

                                    <div>
                                        <label class="block text-xs text-slate-600 mb-1">Private companion target field (optional)</label>
                                        <select name="private_companion_field_targets[<?= esc_attr($gid) ?>]" class="afb-admin-select">
                                            <option value="">Use default match by same field ID</option>
                                            <?php foreach ((array) $private_field_targets as $private_target_gid => $private_target): ?>
                                                <option value="<?= esc_attr($private_target_gid) ?>" <?= selected($field_private_target, $private_target_gid, false) ?>>
                                                    <?= esc_html((string) ($private_target['label'] ?? $private_target_gid)) ?>
                                                </option>
                                            <?php endforeach; ?>
                                        </select>
                                    </div>

                                    <?php if ($supports_option_filter): ?>
                                        <div class="afb-visible-options-wrap afb-collapsible-section is-collapsed">
                                            <div class="afb-visible-options-toolbar">
                                                <span class="afb-visible-options-label">Visible options</span>
                                                <div class="afb-visible-options-actions">
                                                    <button type="button" class="afb-visible-options-btn afb-section-toggle" aria-expanded="false">Show</button>
                                                </div>
                                            </div>
                                            <div class="afb-visible-options-body afb-collapsible-body">
                                                <div class="afb-visible-options-actions afb-visible-options-actions-body">
                                                    <button type="button" class="afb-visible-options-btn afb-select-all-options">Select all</button>
                                                    <button type="button" class="afb-visible-options-btn afb-clear-all-options">Clear</button>
                                                </div>
                                                <select name="visible_enum_options[<?= esc_attr($gid) ?>][]" class="afb-visible-options-select" multiple size="6">
                                                    <?php foreach ((array) $target_enum_options as $enum_opt):
                                                        $opt_gid = (string) ($enum_opt['gid'] ?? '');
                                                        if ($opt_gid === '') continue;
                                                    ?>
                                                        <option value="<?= esc_attr($opt_gid) ?>" <?= in_array($opt_gid, $visible_option_values, true) ? 'selected' : '' ?>>
                                                            <?= esc_html((string) ($enum_opt['name'] ?? $opt_gid)) ?>
                                                        </option>
                                                    <?php endforeach; ?>
                                                </select>
                                                <p class="text-xs text-slate-400 mt-2 mb-0">Leave empty to show all available Asana options. Hold Ctrl / Cmd to pick multiple.</p>
                                            </div>
                                        </div>

                                        <div class="afb-optmap-section afb-collapsible-section is-collapsed" data-target="<?= esc_attr($gid) ?>" data-target-options='<?= esc_attr(wp_json_encode($target_enum_options)) ?>'>
                                            <div class="afb-optmap-toolbar">
                                                <label class="block text-xs text-slate-600 mb-0">Option mapping source field</label>
                                                <button type="button" class="afb-visible-options-btn afb-section-toggle" aria-expanded="false">Show</button>
                                            </div>
                                            <div class="afb-optmap-body afb-collapsible-body">
                                                <select name="option_filter_depends_on[<?= esc_attr($gid) ?>]" class="afb-admin-select afb-option-filter-source" data-target="<?= esc_attr($gid) ?>">
                                                    <option value="">Disabled (show all visible options)</option>
                                                    <?php foreach ((array) $fields as $src):
                                                        if (!isset($src['custom_field'])) continue;
                                                        $src_field = $src['custom_field'];
                                                        $src_gid = (string) ($src_field['gid'] ?? '');
                                                        $src_type = (string) ($src_field['type'] ?? '');
                                                        if ($src_gid === '' || $src_gid === $gid) continue;
                                                        if (!in_array($src_type, ['enum', 'multi_enum'], true)) continue;
                                                    ?>
                                                        <option value="<?= esc_attr($src_gid) ?>" <?= selected($option_rule_depends_on, $src_gid, false) ?>>
                                                            <?= esc_html((string) ($src_field['name'] ?? $src_gid)) ?>
                                                        </option>
                                                    <?php endforeach; ?>
                                                </select>
                                                <input type="hidden" name="option_filter_map[<?= esc_attr($gid) ?>]" class="afb-option-filter-map" value='<?= esc_attr($option_rule_map_json ?: '{}') ?>'>
                                                <div class="afb-option-filter-rows mt-2"></div>
                                                <p class="text-xs text-slate-400 mt-2 mb-0">Map each source value to the option(s) users are allowed to see in this field.</p>
                                            </div>
                                        </div>
                                    <?php endif; ?>

                                    <?php if ($gid !== '__NOTES_HTML__'): ?>
                                        <?php $afb_render_condition_editor($gid, $cond); ?>
                                    <?php endif; ?>
                                </div>
                            </li>
                        <?php endif; ?>
                    <?php endforeach; ?>
                        </ul>
                    </div>
                </div>

                </div><!-- /afb-flow-grid -->
                </div><!-- /p-4 -->
            </form>
        </section>
<?php endif; ?>
    </div>
</div>
