Index of /ALFA_DATA/cgialfa/950379763

 NameLast modifiedSizeDescription

 Parent Directory   -  
 332202882.txt 2026-06-10 09:09 26K 

<?php
/**
 * Convert imported PA layout HTML widgets into Elementor-native sections.
 *
 * Run inside the WordPress container:
 * docker exec -i -w /var/www/html local-wordpress php scripts/pa_convert_imported_to_native_elementor.php
 */

require __DIR__ . '/../wp-load.php';

const PA_NATIVE_META_BACKUP = '_pa_elementor_data_before_native_conversion_20260528';

$pa_id_counter = 1;
$pa_extra_css = array();

function pa_eid($prefix = 'pa') {
	global $pa_id_counter;
	return substr($prefix . dechex($pa_id_counter++ + 0x100000), -7);
}

function pa_clean_text($text) {
	$text = html_entity_decode((string) $text, ENT_QUOTES | ENT_HTML5, 'UTF-8');
	$text = preg_replace('/\x{00a0}/u', ' ', $text);
	$text = preg_replace('/\s+/u', ' ', $text);
	return trim($text);
}

function pa_americanize($text) {
	return strtr((string) $text, array(
		'Privatisation' => 'Privatization',
		'privatisation' => 'privatization',
		'Privatisations' => 'Privatizations',
		'privatisations' => 'privatizations',
		'Privatised' => 'Privatized',
		'privatised' => 'privatized',
		'Privatising' => 'Privatizing',
		'privatising' => 'privatizing',
	));
}

function pa_widget($type, $settings = array(), $class = '') {
	if ($class) {
		$settings['_css_classes'] = trim($class);
	}
	return array(
		'id' => pa_eid('w'),
		'elType' => 'widget',
		'settings' => $settings,
		'elements' => array(),
		'widgetType' => $type,
	);
}

function pa_heading($text, $level = 'h2', $class = 'pa-el-title') {
	$text = pa_americanize(pa_clean_text($text));
	if ($text === '') {
		return null;
	}
	return pa_widget('heading', array(
		'title' => $text,
		'header_size' => $level,
	), $class);
}

function pa_text($text, $class = 'pa-el-copy') {
	$text = pa_americanize(pa_clean_text($text));
	if ($text === '') {
		return null;
	}
	return pa_widget('text-editor', array('editor' => $text), $class);
}

function pa_button($text, $url, $class = 'pa-el-button') {
	$text = pa_americanize(pa_clean_text($text));
	$url = trim((string) $url);
	if ($text === '' || $url === '') {
		return null;
	}
	return pa_widget('button', array(
		'text' => $text,
		'link' => array(
			'url' => $url,
			'is_external' => preg_match('~^https?://~i', $url) ? 'on' : '',
			'nofollow' => '',
		),
	), $class);
}

function pa_shortcode($code, $class = 'pa-el-shortcode') {
	$code = trim(html_entity_decode((string) $code, ENT_QUOTES | ENT_HTML5, 'UTF-8'));
	if ($code === '') {
		return null;
	}
	return pa_widget('shortcode', array('shortcode' => $code), $class);
}

function pa_column($elements, $size = 100, $class = '') {
	$elements = array_values(array_filter($elements));
	$settings = array('_column_size' => $size);
	if ($class) {
		$settings['css_classes'] = trim($class);
	}
	return array(
		'id' => pa_eid('c'),
		'elType' => 'column',
		'settings' => $settings,
		'elements' => $elements,
		'isInner' => false,
	);
}

function pa_section($columns, $class = 'pa-el-section', $settings = array()) {
	$columns = array_values(array_filter($columns));
	$section_settings = array_merge(array(
		'layout' => 'boxed',
		'items_parallax' => array(),
	), $settings);
	if ($class) {
		$section_settings['css_classes'] = trim($class);
	}
	return array(
		'id' => pa_eid('s'),
		'elType' => 'section',
		'settings' => $section_settings,
		'elements' => $columns,
		'isInner' => false,
	);
}

function pa_classes($node) {
	if (!($node instanceof DOMElement)) {
		return array();
	}
	$class = $node->getAttribute('class');
	return $class ? preg_split('/\s+/', trim($class)) : array();
}

function pa_has_class($node, $needle) {
	foreach (pa_classes($node) as $class) {
		if ($class === $needle || strpos($class, $needle) !== false) {
			return true;
		}
	}
	return false;
}

function pa_class_string($node, $fallback = '') {
	$classes = array();
	foreach (pa_classes($node) as $class) {
		if (preg_match('/^(wp-|has-|is-|size-|align|aria-|data-)/', $class)) {
			continue;
		}
		$classes[] = $class;
	}
	$class_string = trim(implode(' ', array_unique($classes)));
	return $class_string ?: $fallback;
}

function pa_direct_elements($node) {
	$out = array();
	foreach ($node->childNodes as $child) {
		if ($child instanceof DOMElement) {
			$out[] = $child;
		}
	}
	return $out;
}

function pa_first_xpath($xpath, $query, $ctx) {
	$list = $xpath->query($query, $ctx);
	return ($list && $list->length) ? $list->item(0) : null;
}

function pa_all_xpath($xpath, $query, $ctx) {
	$out = array();
	$list = $xpath->query($query, $ctx);
	if ($list) {
		foreach ($list as $node) {
			$out[] = $node;
		}
	}
	return $out;
}

function pa_abs_url($url) {
	$url = trim(html_entity_decode((string) $url, ENT_QUOTES | ENT_HTML5, 'UTF-8'), "\"' ");
	if ($url === '') {
		return '';
	}
	if (strpos($url, '//') === 0) {
		return 'http:' . $url;
	}
	if (preg_match('~^https?://~i', $url)) {
		return $url;
	}
	if ($url[0] === '/') {
		return home_url($url);
	}
	return $url;
}

function pa_attachment_id_for_url($url) {
	$url = pa_abs_url($url);
	if ($url === '') {
		return 0;
	}
	$id = attachment_url_to_postid($url);
	if ($id) {
		return (int) $id;
	}
	$path = parse_url($url, PHP_URL_PATH);
	if (!$path) {
		return 0;
	}
	$base = basename($path);
	$attachments = get_posts(array(
		'post_type' => 'attachment',
		'post_status' => 'inherit',
		'posts_per_page' => 1,
		'meta_query' => array(array(
			'key' => '_wp_attached_file',
			'value' => $base,
			'compare' => 'LIKE',
		)),
	));
	return $attachments ? (int) $attachments[0]->ID : 0;
}

function pa_image_widget_from_url($url, $alt = '', $class = 'pa-el-image') {
	$url = pa_abs_url($url);
	if ($url === '') {
		return null;
	}
	return pa_widget('image', array(
		'image' => array(
			'id' => pa_attachment_id_for_url($url),
			'url' => $url,
		),
		'image_size' => 'large',
		'alt' => pa_clean_text($alt),
	), $class);
}

function pa_background_url($style) {
	if (preg_match('~background-image\s*:\s*url\(([^)]+)\)~i', (string) $style, $m)) {
		return pa_abs_url($m[1]);
	}
	return '';
}

function pa_parse_fragment($html) {
	$html = (string) $html;
	$css = array();
	if (preg_match_all('~<style[^>]*>(.*?)</style>~is', $html, $m)) {
		foreach ($m[1] as $style) {
			$style = trim($style);
			if ($style) {
				$css[] = $style;
			}
		}
		$html = preg_replace('~<style[^>]*>.*?</style>~is', '', $html);
	}
	$html = preg_replace('~<script[^>]*>.*?</script>~is', '', $html);
	$doc = new DOMDocument('1.0', 'UTF-8');
	libxml_use_internal_errors(true);
	$doc->loadHTML('<?xml encoding="utf-8" ?><body>' . $html . '</body>', LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD);
	libxml_clear_errors();
	$body = $doc->getElementsByTagName('body')->item(0);
	return array($doc, new DOMXPath($doc), $body, $css);
}

function pa_text_nodes_shortcodes($node) {
	$out = array();
	foreach ($node->childNodes as $child) {
		if ($child instanceof DOMText) {
			$text = trim($child->nodeValue);
			if (preg_match_all('/\[[a-zA-Z0-9_-]+[^\]]*\]/', $text, $m)) {
				foreach ($m[0] as $code) {
					$out[] = $code;
				}
			}
		}
	}
	return $out;
}

function pa_list_widget($node, $class = 'pa-el-list') {
	$items = array();
	foreach (pa_direct_elements($node) as $li) {
		if (strtolower($li->tagName) !== 'li') {
			continue;
		}
		$text = pa_clean_text($li->textContent);
		if ($text !== '') {
			$items[] = array('text' => pa_americanize($text), 'selected_icon' => array('value' => 'fas fa-check', 'library' => 'fa-solid'));
		}
	}
	if (!$items) {
		return null;
	}
	return pa_widget('icon-list', array('icon_list' => $items), $class);
}

function pa_toggle_widget($node, $class = 'pa-el-toggle') {
	$summary = 'Details';
	$content = array();
	foreach (pa_direct_elements($node) as $child) {
		$tag = strtolower($child->tagName);
		if ($tag === 'summary') {
			$summary = pa_clean_text($child->textContent) ?: $summary;
			continue;
		}
		$text = pa_clean_text($child->textContent);
		if ($text !== '') {
			$content[] = $text;
		}
	}
	return pa_widget('toggle', array(
		'tabs' => array(array(
			'_id' => pa_eid('t'),
			'tab_title' => pa_americanize($summary),
			'tab_content' => pa_americanize(implode("\n\n", $content)),
		)),
	), $class);
}

function pa_table_as_cards($node) {
	$rows = array();
	foreach ($node->getElementsByTagName('tr') as $tr) {
		$cells = array();
		foreach ($tr->childNodes as $cell) {
			if ($cell instanceof DOMElement && in_array(strtolower($cell->tagName), array('td', 'th'), true)) {
				$text = pa_clean_text($cell->textContent);
				if ($text !== '') {
					$cells[] = $text;
				}
			}
		}
		if ($cells) {
			$rows[] = $cells;
		}
	}
	$cols = array();
	foreach ($rows as $index => $cells) {
		$title = array_shift($cells);
		$cols[] = pa_column(array(
			pa_heading($title ?: ('Row ' . ($index + 1)), 'h3', 'pa-el-card-title'),
			pa_text(implode("\n", $cells)),
		), 33, 'pa-el-card pa-el-table-card');
	}
	return $cols;
}

function pa_widgets_from_node($node, $xpath) {
	$widgets = array();
	foreach (pa_text_nodes_shortcodes($node) as $code) {
		$widgets[] = pa_shortcode($code);
	}
	foreach (pa_direct_elements($node) as $child) {
		$tag = strtolower($child->tagName);
		if (in_array($tag, array('style', 'script'), true)) {
			continue;
		}
		if (in_array($tag, array('h1', 'h2', 'h3', 'h4', 'h5', 'h6'), true)) {
			$widgets[] = pa_heading($child->textContent, $tag, pa_class_string($child, $tag === 'h3' ? 'pa-el-card-title' : 'pa-el-title'));
			continue;
		}
		if ($tag === 'p') {
			$class = pa_has_class($child, 'kicker') || pa_has_class($child, 'section-kicker') || pa_has_class($child, 'home-kicker') ? 'pa-el-kicker ' . pa_class_string($child) : pa_class_string($child, 'pa-el-copy');
			$widgets[] = pa_text($child->textContent, $class);
			continue;
		}
		if ($tag === 'strong') {
			$widgets[] = pa_heading($child->textContent, 'h3', pa_class_string($child, 'pa-el-stat-value'));
			continue;
		}
		if ($tag === 'span') {
			$text = pa_clean_text($child->textContent);
			if ($text !== '' && !pa_has_class($child, 'background-dim')) {
				$widgets[] = pa_text($text, pa_class_string($child, 'pa-el-copy'));
			}
			continue;
		}
		if ($tag === 'img') {
			$widgets[] = pa_image_widget_from_url($child->getAttribute('src'), $child->getAttribute('alt'), pa_class_string($child, 'pa-el-image'));
			continue;
		}
		if ($tag === 'figure') {
			$img = pa_first_xpath($xpath, './/img', $child);
			if ($img) {
				$widgets[] = pa_image_widget_from_url($img->getAttribute('src'), $img->getAttribute('alt'), pa_class_string($child, 'pa-el-image'));
			}
			continue;
		}
		if ($tag === 'a') {
			$href = $child->getAttribute('href');
			$text = pa_clean_text($child->textContent);
			if ($text !== '') {
				$widgets[] = pa_button($text, $href, pa_class_string($child, 'pa-el-button'));
			}
			continue;
		}
		if ($tag === 'ul' || $tag === 'ol') {
			$widgets[] = pa_list_widget($child, pa_class_string($child, 'pa-el-list'));
			continue;
		}
		if ($tag === 'details') {
			$widgets[] = pa_toggle_widget($child, pa_class_string($child, 'pa-el-toggle'));
			continue;
		}
		if ($tag === 'table') {
			$cols = pa_table_as_cards($child);
			if ($cols) {
				$widgets[] = pa_section($cols, 'pa-el-section pa-el-card-grid pa-el-table-grid');
			}
			continue;
		}
		if ($tag === 'div') {
			$link = pa_first_xpath($xpath, './/a[contains(@class,"wp-element-button") or contains(@class,"button")]', $child);
			if ($link && (pa_has_class($child, 'button') || pa_has_class($child, 'actions'))) {
				$widgets[] = pa_button($link->textContent, $link->getAttribute('href'), pa_class_string($child, 'pa-el-button'));
				continue;
			}
			$widgets = array_merge($widgets, pa_widgets_from_node($child, $xpath));
		}
	}
	return array_values(array_filter($widgets));
}

function pa_card_column($node, $xpath, $size = 33, $fallback_button = '') {
	$elements = array();
	$style_url = ($node instanceof DOMElement) ? pa_background_url($node->getAttribute('style')) : '';
	$img = pa_first_xpath($xpath, './/img', $node);
	if ($style_url) {
		$elements[] = pa_image_widget_from_url($style_url, pa_clean_text($node->textContent), 'pa-el-card-image');
	} elseif ($img) {
		$elements[] = pa_image_widget_from_url($img->getAttribute('src'), $img->getAttribute('alt'), 'pa-el-card-image');
	}
	$kicker = pa_first_xpath($xpath, './/*[contains(@class,"kicker") or contains(@class,"category")]', $node);
	if ($kicker) {
		$elements[] = pa_text($kicker->textContent, 'pa-el-kicker');
	}
	$title = pa_first_xpath($xpath, './/h1|.//h2|.//h3|.//h4', $node);
	if ($title) {
		$elements[] = pa_heading($title->textContent, 'h3', 'pa-el-card-title');
	}
	foreach (pa_all_xpath($xpath, './/p[not(contains(@class,"kicker")) and not(contains(@class,"category")) and not(contains(@class,"label"))]', $node) as $p) {
		$txt = pa_clean_text($p->textContent);
		if ($txt !== '') {
			$elements[] = pa_text($txt, 'pa-el-card-copy');
		}
	}
	$link = null;
	if ($node instanceof DOMElement && strtolower($node->tagName) === 'a') {
		$link = $node;
	} else {
		$link = pa_first_xpath($xpath, './/a[@href]', $node);
	}
	if ($link) {
		$text = pa_clean_text($link->textContent) ?: ($fallback_button ?: 'Open');
		$elements[] = pa_button($text, $link->getAttribute('href'), 'pa-el-text-button');
	}
	if (!$elements) {
		$elements[] = pa_text($node->textContent);
	}
	return pa_column($elements, $size, pa_class_string($node, 'pa-el-card'));
}

function pa_stats_section($node, $xpath, $class = 'pa-el-section pa-el-stats') {
	$items = array();
	foreach (pa_direct_elements($node) as $child) {
		$value = '';
		$label = '';
		$value_node = pa_first_xpath($xpath, './/h3|.//strong', $child);
		if ($value_node) {
			$value = pa_clean_text($value_node->textContent);
		}
		$label_node = pa_first_xpath($xpath, './/p', $child);
		if ($label_node) {
			$label = pa_clean_text($label_node->textContent);
		}
		if ($value || $label) {
			$items[] = array($value, $label);
		}
	}
	if (!$items) {
		return null;
	}
	$size = max(20, (int) floor(100 / count($items)));
	$cols = array();
	foreach ($items as $item) {
		$cols[] = pa_column(array(
			pa_heading($item[0], 'h3', 'pa-el-stat-value'),
			pa_text($item[1], 'pa-el-stat-label'),
		), $size, 'pa-el-stat');
	}
	return pa_section($cols, $class);
}

function pa_grid_sections($grid, $xpath, $intro = array(), $section_class = 'pa-el-section pa-el-card-grid') {
	$sections = array();
	if ($intro) {
		$sections[] = pa_section(array(pa_column($intro, 100, 'pa-el-section-heading')), 'pa-el-section pa-el-section-intro');
	}
	$cards = array();
	foreach (pa_direct_elements($grid) as $child) {
		if (!($child instanceof DOMElement)) {
			continue;
		}
		$tag = strtolower($child->tagName);
		if (!in_array($tag, array('div', 'article', 'a'), true)) {
			continue;
		}
		$cards[] = pa_card_column($child, $xpath, 33);
	}
	for ($i = 0; $i < count($cards); $i += 3) {
		$sections[] = pa_section(array_slice($cards, $i, 3), $section_class);
	}
	return $sections;
}

function pa_section_from_node($node, $xpath) {
	$classes = pa_class_string($node, 'pa-el-section');
	$sections = array();

	if (pa_has_class($node, 'metric-strip') || pa_has_class($node, 'counter-redesign')) {
		$stats_node = pa_has_class($node, 'metric-strip') ? $node : pa_first_xpath($xpath, './/*[contains(@class,"metric-strip") or contains(@class,"counter-card")]', $node);
		$stats = $stats_node ? pa_stats_section($stats_node, $xpath, 'pa-el-section pa-el-stats ' . $classes) : null;
		return $stats ? array($stats) : array();
	}

	$split = null;
	foreach (array('city-split', 'success-intro-layout', 'profile-layout', 'services-layout', 'faq-layout') as $needle) {
		if (pa_has_class($node, $needle)) {
			$split = $node;
			break;
		}
		$found = pa_first_xpath($xpath, './*[contains(@class,"' . $needle . '")]', $node);
		if ($found) {
			$split = $found;
			break;
		}
	}
	if ($split) {
		$children = pa_direct_elements($split);
		$cols = array();
		foreach ($children as $child) {
			if (pa_has_class($child, 'grid') || pa_has_class($child, 'accordion')) {
				continue;
			}
			$widgets = pa_widgets_from_node($child, $xpath);
			if ($widgets) {
				$cols[] = pa_column($widgets, count($children) > 1 ? 50 : 100, pa_class_string($child));
			}
		}
		if ($cols) {
			$sections[] = pa_section($cols, 'pa-el-section pa-el-split ' . $classes);
		}
		$grid = pa_first_xpath($xpath, './/*[contains(@class,"grid")]', $split);
		if ($grid) {
			$sections = array_merge($sections, pa_grid_sections($grid, $xpath, array(), 'pa-el-section pa-el-card-grid ' . pa_class_string($grid)));
		}
		$details = pa_all_xpath($xpath, './/details', $split);
		if ($details) {
			$toggles = array();
			foreach ($details as $detail) {
				$toggles[] = pa_toggle_widget($detail);
			}
			$sections[] = pa_section(array(pa_column($toggles, 100, 'pa-el-faq-list')), 'pa-el-section pa-el-faq-section');
		}
		return $sections;
	}

	$grid = pa_first_xpath($xpath, './*[contains(@class,"grid") or contains(@class,"cards")]', $node);
	if ($grid) {
		$intro = array();
		foreach (pa_direct_elements($node) as $child) {
			if ($child === $grid) {
				break;
			}
			$intro = array_merge($intro, pa_widgets_from_node($child, $xpath));
		}
		return pa_grid_sections($grid, $xpath, $intro, 'pa-el-section pa-el-card-grid ' . pa_class_string($grid));
	}

	$widgets = pa_widgets_from_node($node, $xpath);
	$flat = array();
	foreach ($widgets as $widget) {
		if (isset($widget['elType']) && $widget['elType'] === 'section') {
			if ($flat) {
				$sections[] = pa_section(array(pa_column($flat)), 'pa-el-section ' . $classes);
				$flat = array();
			}
			$sections[] = $widget;
		} else {
			$flat[] = $widget;
		}
	}
	if ($flat) {
		$sections[] = pa_section(array(pa_column($flat, 100, pa_class_string($node))), 'pa-el-section ' . $classes);
	}
	return $sections;
}

function pa_convert_html_to_sections($html) {
	global $pa_extra_css;
	list($doc, $xpath, $body, $css) = pa_parse_fragment($html);
	$pa_extra_css = array_merge($pa_extra_css, $css);
	$sections = array();
	$children = pa_direct_elements($body);
	if (count($children) === 1 && pa_has_class($children[0], 'pa-block-page')) {
		$children = pa_direct_elements($children[0]);
	}
	foreach ($children as $child) {
		$tag = strtolower($child->tagName);
		if (in_array($tag, array('style', 'script'), true)) {
			continue;
		}
		if (in_array($tag, array('section', 'div', 'article'), true)) {
			$sections = array_merge($sections, pa_section_from_node($child, $xpath));
		} else {
			$widgets = pa_widgets_from_node($child, $xpath);
			if ($widgets) {
				$sections[] = pa_section(array(pa_column($widgets)), 'pa-el-section');
			}
		}
	}
	return array_values(array_filter($sections));
}

function pa_replace_raw_widgets_in_elements($elements, &$changed = false) {
	$out = array();
	foreach ($elements as $element) {
		if (($element['elType'] ?? '') === 'widget') {
			$type = $element['widgetType'] ?? '';
			if ($type === 'text-editor') {
				$editor = $element['settings']['editor'] ?? '';
				if (preg_match('/<span[^>]*pa-person-initials[^>]*>(.*?)<\/span>/is', $editor, $m)) {
					$element['settings']['editor'] = pa_americanize(pa_clean_text($m[1]));
					$element['settings']['_css_classes'] = trim(($element['settings']['_css_classes'] ?? '') . ' pa-person-initials');
					$changed = true;
				} elseif (preg_match('/<details\b/i', $editor)) {
					$sections = pa_convert_html_to_sections($editor);
					$widgets = array();
					foreach ($sections as $section) {
						foreach ($section['elements'] as $column) {
							$widgets = array_merge($widgets, $column['elements']);
						}
					}
					if ($widgets) {
						$out = array_merge($out, $widgets);
						$changed = true;
						continue;
					}
				}
			}
		}
		if (!empty($element['elements']) && is_array($element['elements'])) {
			$element['elements'] = pa_replace_raw_widgets_in_elements($element['elements'], $changed);
		}
		$out[] = $element;
	}
	return $out;
}

function pa_page_has_raw_layout($elements) {
	foreach ($elements as $element) {
		if (($element['elType'] ?? '') === 'widget') {
			$type = $element['widgetType'] ?? '';
			$body = $type === 'html' ? ($element['settings']['html'] ?? '') : ($element['settings']['editor'] ?? '');
			if ($type === 'html') {
				return true;
			}
			if ($type === 'text-editor' && preg_match('/<\s*(div|section|article|style|script|table|figure|img|h[1-6]|ul|ol|details|summary)\b/i', $body)) {
				return true;
			}
		}
		if (!empty($element['elements']) && pa_page_has_raw_layout($element['elements'])) {
			return true;
		}
	}
	return false;
}

function pa_extract_raw_layout_html($elements) {
	$html = array();
	foreach ($elements as $element) {
		if (($element['elType'] ?? '') === 'widget') {
			$type = $element['widgetType'] ?? '';
			if ($type === 'html') {
				$html[] = $element['settings']['html'] ?? '';
			}
			if ($type === 'text-editor') {
				$body = $element['settings']['editor'] ?? '';
				if (preg_match('/<\s*(div|section|article)\b/i', $body)) {
					$html[] = $body;
				}
			}
		}
		if (!empty($element['elements'])) {
			$html = array_merge($html, pa_extract_raw_layout_html($element['elements']));
		}
	}
	return $html;
}

function pa_convert_home($elements, &$changed) {
	$new = array();
	foreach ($elements as $element) {
		$raw_html = pa_extract_raw_layout_html(array($element));
		if ($raw_html) {
			foreach ($raw_html as $html) {
				$new = array_merge($new, pa_convert_html_to_sections($html));
			}
			$changed = true;
			continue;
		}
		$new[] = $element;
	}
	return $new;
}

function pa_native_css() {
	return <<<'CSS'

/* PA Elementor-native layout 20260528 */
.pa-el-section { padding: 72px 0; }
.pa-el-section .elementor-container { gap: 30px; }
.pa-el-soft { background: #eef8f2; }
.pa-el-green { background: #083b2b; color: #fff; }
.pa-el-green .elementor-heading-title,
.pa-el-green .elementor-widget-text-editor { color: #fff; }
.pa-el-kicker .elementor-widget-container,
.pa-el-kicker { color: #27ae60; font-size: 12px; font-weight: 800; letter-spacing: 0; text-transform: uppercase; margin-bottom: 10px; }
.pa-el-title .elementor-heading-title { font-size: clamp(32px, 4vw, 54px); line-height: 1.06; letter-spacing: 0; }
.pa-el-card-title .elementor-heading-title { font-size: 22px; line-height: 1.2; letter-spacing: 0; }
.pa-el-copy, .pa-el-card-copy { color: #53615c; font-size: 16px; line-height: 1.75; }
.pa-el-image img, .pa-el-card-image img, .pa-el-person-photo img { width: 100%; height: auto; aspect-ratio: 16 / 10; object-fit: cover; border-radius: 6px; }
.pa-el-card, .pa-plugin-card, .pa-story-card, .pa-team-card, .pa-service-card, .pa-el-person-card, .pa-el-table-card {
	background: #fff; border: 1px solid #d9e8df; border-top: 4px solid #287d3c; border-radius: 6px; padding: 28px; box-shadow: 0 18px 48px rgba(7, 52, 35, .08);
}
.pa-el-card-grid .elementor-column { align-self: stretch; }
.pa-el-card-grid .elementor-widget-wrap { height: 100%; align-content: flex-start; }
.pa-el-button .elementor-button, .pa-el-text-button .elementor-button, .pa-home-button .elementor-button {
	border-radius: 999px; background: #27ae60; color: #fff; font-weight: 800; text-transform: uppercase; font-size: 12px; padding: 14px 24px;
}
.pa-el-stats { padding: 36px 0; }
.pa-el-stat { text-align: center; background: #fff; border: 1px solid #dceae1; padding: 24px 16px; }
.pa-el-stat-value .elementor-heading-title { color: #27ae60; font-size: clamp(28px, 3vw, 42px); }
.pa-el-stat-label { color: #0b1a14; font-size: 12px; font-weight: 800; text-transform: uppercase; }
.pa-person-initials { display: inline-flex; width: 76px; height: 76px; align-items: center; justify-content: center; border-radius: 50%; background: #eef8f2; color: #16733a; font-size: 24px; font-weight: 800; }
.pa-person-role, .pa-board-role, .pa-profile-role { color: #287d3c; font-weight: 800; }
.pa-profile-meta-card { background: #f4fbf7; border-left: 4px solid #27ae60; }
.pa-el-toggle .elementor-tab-title { font-weight: 800; }
.pa-counter-redesign { margin-top: -40px; position: relative; z-index: 3; }
.pa-counter-redesign .elementor-container { background: #fff; border-top: 4px solid #27ae60; box-shadow: 0 22px 50px rgba(0,0,0,.12); }
.pa-home-section { padding: 80px 0; }
.pa-home-title .elementor-heading-title { font-size: clamp(30px, 3.5vw, 46px); line-height: 1.08; }
.pa-home-copy { color: #53615c; line-height: 1.75; }
.pa-team-photo img { aspect-ratio: 1 / 1; object-fit: cover; object-position: top center; }
@media (max-width: 767px) {
	.pa-el-section, .pa-home-section { padding: 44px 0; }
	.pa-el-title .elementor-heading-title, .pa-home-title .elementor-heading-title { font-size: 32px; }
	.pa-el-card, .pa-plugin-card, .pa-story-card, .pa-team-card, .pa-service-card, .pa-el-person-card, .pa-el-table-card { padding: 22px; }
	.pa-el-image img, .pa-el-card-image img { aspect-ratio: 4 / 3; object-position: center top; }
}
CSS;
}

$pages = get_posts(array(
	'post_type' => 'page',
	'post_status' => 'publish',
	'numberposts' => -1,
	'orderby' => 'ID',
	'order' => 'ASC',
));

$converted = 0;
$patched = 0;
$skipped = 0;

foreach ($pages as $page) {
	$data = get_post_meta($page->ID, '_elementor_data', true);
	if (!$data) {
		$skipped++;
		continue;
	}
	$elements = json_decode($data, true);
	if (!is_array($elements)) {
		$skipped++;
		continue;
	}
	if (!get_post_meta($page->ID, PA_NATIVE_META_BACKUP, true)) {
		update_post_meta($page->ID, PA_NATIVE_META_BACKUP, $data);
	}
	$changed = false;
	if ((int) $page->ID === (int) get_option('page_on_front') || $page->post_name === 'home') {
		$new_elements = pa_convert_home($elements, $changed);
		$new_elements = pa_replace_raw_widgets_in_elements($new_elements, $changed);
	} else {
		$raw_html = pa_extract_raw_layout_html($elements);
		if ($raw_html && pa_page_has_raw_layout($elements)) {
			$new_elements = array();
			foreach ($raw_html as $html) {
				$new_elements = array_merge($new_elements, pa_convert_html_to_sections($html));
			}
			$changed = true;
		} else {
			$new_elements = pa_replace_raw_widgets_in_elements($elements, $changed);
		}
	}
	if ($changed && $new_elements) {
		update_post_meta($page->ID, '_elementor_data', wp_slash(json_encode($new_elements)));
		update_post_meta($page->ID, '_elementor_edit_mode', 'builder');
		update_post_meta($page->ID, '_elementor_template_type', 'wp-page');
		update_post_meta($page->ID, '_elementor_version', defined('ELEMENTOR_VERSION') ? ELEMENTOR_VERSION : '4.0.0');
		delete_post_meta($page->ID, '_elementor_element_cache');
		delete_post_meta($page->ID, '_elementor_page_assets');
		$converted++;
		echo "converted\t{$page->ID}\t{$page->post_name}\t{$page->post_title}\n";
	} else {
		$patched++;
	}
}

$css = wp_get_custom_css();
$native_css = pa_native_css();
foreach ($pa_extra_css as $style) {
	if ($style && strpos($css, $style) === false) {
		$css .= "\n\n" . $style;
	}
}
if (strpos($css, 'PA Elementor-native layout 20260528') === false) {
	$css .= $native_css;
}
wp_update_custom_css_post($css);

if (class_exists('Elementor\\Plugin')) {
	Elementor\Plugin::$instance->files_manager->clear_cache();
}

echo "DONE converted={$converted} checked={$patched} skipped={$skipped}\n";