<?php
/**
 * Mersal Suite — shell rendering (sidebar, topbar, switcher, hub, system pages).
 *
 * Provided as a trait consumed by Mersal_Suite so the controller file stays
 * focused on plumbing. All markup is inline-styled to mirror the prototype.
 *
 * @package Mersal_Suite
 */

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

if ( trait_exists( 'Mersal_Suite_Shell' ) ) {
	return;
}

/**
 * Shell rendering methods for Mersal_Suite.
 */
trait Mersal_Suite_Shell {

	/**
	 * Meta for a context ('suite' or a plugin id).
	 *
	 * @param string $id Context id.
	 * @return array
	 */
	private function meta( $id ) {
		if ( 'suite' === $id || ! isset( $this->plugins[ $id ] ) ) {
			$ar = 'ar' === $this->lang();
			return array(
				'name'   => $ar ? 'مرسال سويت' : 'Mersal Suite',
				'sub'    => $ar ? 'منصة المراسلة' : 'Messaging Suite',
				'icon'   => 'grid_view',
				'accent' => '#0f7a4a',
				'ver'    => self::VERSION,
			);
		}
		$p = $this->plugins[ $id ];
		return array(
			'name'   => $this->L( $p['name'] ),
			'sub'    => $this->L( $p['sub'] ),
			'icon'   => $p['icon'],
			'accent' => $p['accent'],
			'ver'    => $p['version'],
		);
	}

	/**
	 * Soft / solid colour pair for a tone name.
	 *
	 * @param string $tone Tone.
	 * @return array{0:string,1:string}
	 */
	public function tone( $tone ) {
		$m = array(
			'accent' => array( 'var(--accent-soft)', 'var(--accent)' ),
			'info'   => array( 'var(--info-soft)', 'var(--info)' ),
			'violet' => array( 'var(--violet-soft)', 'var(--violet)' ),
			'hi'     => array( 'var(--hi-soft)', 'var(--hi)' ),
			'danger' => array( 'var(--danger-soft)', 'var(--danger)' ),
			'warn'   => array( 'var(--warn-soft)', 'var(--warn)' ),
		);
		return isset( $m[ $tone ] ) ? $m[ $tone ] : $m['accent'];
	}

	/**
	 * Nav groups for the current context.
	 *
	 * @param string $cur Current plugin id.
	 * @return array
	 */
	private function nav_groups( $cur ) {
		$ar = 'ar' === $this->lang();
		if ( 'suite' === $cur ) {
			$plugin_items = array();
			if ( class_exists( 'Mersal_Suite_Catalog' ) ) {
				foreach ( Mersal_Suite_Catalog::ORDER as $id ) {
					$meta = Mersal_Suite_Catalog::meta( $id, $this );
					if ( ! $meta ) {
						continue;
					}
					$route = $meta['default_route'];
					$opts  = array();
					if ( ! Mersal_Suite_Catalog::is_active( $id ) ) {
						$opts['href'] = Mersal_Suite_Catalog::resolve_url( $id );
						if ( 'download' === Mersal_Suite_Catalog::status( $id ) ) {
							$opts['install'] = $id;
						}
					}
					$plugin_items[] = array( $route, $this->L( $meta['name'] ), $meta['icon'], $opts );
				}
			} else {
				foreach ( $this->plugins() as $id => $p ) {
					$plugin_items[] = array( $p['default_route'], $this->L( $p['name'] ), $p['icon'] );
				}
			}
			return array(
				array( $ar ? 'نظرة عامة' : 'Overview', array( array( 'hub', $ar ? 'الرئيسية' : 'Hub', 'grid_view' ) ) ),
				array( $ar ? 'الإضافات' : 'Plugins', $plugin_items ),
			);
		}
		return isset( $this->plugins[ $cur ]['nav'] ) ? $this->plugins[ $cur ]['nav'] : array();
	}

	/**
	 * Suite-wide system links.
	 *
	 * @return array
	 */
	private function system_nav() {
		$ar  = 'ar' === $this->lang();
		$upd = $this->updates_count();
		return array(
			array( 'updates', $ar ? 'التحديثات' : 'Updates', 'system_update_alt', $upd > 0 ? array( 'badge' => (string) $upd ) : array() ),
			array( 'integrations', $ar ? 'الربط والتكاملات' : 'Integrations', 'extension' ),
			array( 'settings', $ar ? 'الإعدادات العامة' : 'General Settings', 'tune' ),
			array( 'billing', $ar ? 'الباقة والفوترة' : 'Plan & Billing', 'workspace_premium' ),
		);
	}

	/**
	 * Build a flat route => label map (for breadcrumbs).
	 *
	 * @return array<string,array{0:string,1:string}> route => [rootLabel, leafLabel]
	 */
	private function route_labels() {
		$ar  = 'ar' === $this->lang();
		$map = array(
			'hub'           => array( '', $ar ? 'الرئيسية' : 'Hub' ),
			'otp.connect'   => array( $ar ? 'مرسال OTP' : 'Mersal OTP', $ar ? 'ربط مرسال' : 'Mersal account' ),
			'cm.connect'    => array( $ar ? 'مرسال للحملات' : 'Mersal Campaigns', $ar ? 'ربط مرسال' : 'Mersal account' ),
			'nt.connect'    => array( $ar ? 'مرسال للإشعارات' : 'Mersal Notifications', $ar ? 'ربط مرسال' : 'Mersal account' ),
			'otp.wizard'    => array( $ar ? 'مرسال OTP' : 'Mersal OTP', $ar ? 'معالج الإعداد' : 'Setup wizard' ),
			'cm.wizard'     => array( $ar ? 'مرسال للحملات' : 'Mersal Campaigns', $ar ? 'معالج الإعداد' : 'Setup wizard' ),
			'nt.wizard'     => array( $ar ? 'مرسال للإشعارات' : 'Mersal Notifications', $ar ? 'معالج الإعداد' : 'Setup wizard' ),
			'updates'       => array( $ar ? 'النظام' : 'System', $ar ? 'التحديثات' : 'Updates' ),
			'integrations'  => array( $ar ? 'النظام' : 'System', $ar ? 'الربط والتكاملات' : 'Integrations' ),
			'settings'      => array( $ar ? 'النظام' : 'System', $ar ? 'الإعدادات العامة' : 'General Settings' ),
			'billing'       => array( $ar ? 'النظام' : 'System', $ar ? 'الباقة والفوترة' : 'Plan & Billing' ),
		);
		foreach ( $this->plugins() as $id => $p ) {
			$root = $this->L( $p['name'] );
			foreach ( $p['nav'] as $group ) {
				$items = isset( $group[1] ) ? $group[1] : array();
				foreach ( $items as $it ) {
					if ( isset( $it[0], $it[1] ) ) {
						$map[ $it[0] ] = array( $root, $this->L( $it[1] ) );
					}
				}
			}
		}
		return $map;
	}

	/* ------------------------------------------------------------------ */
	/* Sidebar                                                            */
	/* ------------------------------------------------------------------ */

	/**
	 * Render the dark sidebar.
	 *
	 * @param string $route Active route.
	 * @param string $cur   Current plugin id.
	 */
	private function sidebar( $route, $cur ) {
		$ar   = 'ar' === $this->lang();
		$meta = $this->meta( $cur );
		?>
		<aside style="background:#11201a; color:#92a89b; height:100%; min-height:0; display:flex; flex-direction:column; border-inline-end:1px solid #1c2e25;">
			<div style="padding:16px 16px 14px; display:flex; align-items:center; gap:10px; border-bottom:1px solid #1c2e25;">
				<div style="width:34px; height:34px; border-radius:10px; background:#fff; display:grid; place-items:center; flex:0 0 34px; box-shadow:0 2px 10px rgba(0,0,0,.35);">
					<span class="msym fill" style="font-size:22px; color:<?php echo esc_attr( $meta['accent'] ); ?>;"><?php echo esc_html( $meta['icon'] ); ?></span>
				</div>
				<div style="display:flex; flex-direction:column; line-height:1.2; min-width:0;">
					<b style="font-size:14.5px; color:#fff; font-weight:700; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;"><?php echo esc_html( $meta['name'] ); ?></b>
					<span style="font-size:10px; color:#6f8a7c; font-weight:600; letter-spacing:.04em; text-transform:uppercase;"><?php echo esc_html( $meta['sub'] ); ?></span>
				</div>
				<div style="margin-inline-start:auto; font-size:10px; color:#7d9a8b; padding:3px 7px; border-radius:99px; background:rgba(255,255,255,.05); border:1px solid #1c2e25; flex:0 0 auto;">v<?php echo esc_html( $meta['ver'] ); ?></div>
			</div>

			<div style="margin:12px 12px 4px; display:flex; align-items:center; gap:8px; padding:8px 10px; background:#0c1812; border:1px solid #1c2e25; border-radius:9px;">
				<span class="msym" style="font-size:16px; color:#6f8a7c;">search</span>
				<input data-ms-search placeholder="<?php echo esc_attr( $ar ? 'بحث في كل شيء…' : 'Search anything…' ); ?>" style="flex:1; background:transparent; border:0; outline:0; color:#e7f0ea; font-size:12.5px;">
				<kbd style="font-family:Inter,monospace; font-size:10px; padding:1px 6px; border-radius:4px; background:rgba(255,255,255,.05); border:1px solid #1c2e25; color:#6f8a7c;">⌘K</kbd>
			</div>

			<?php $this->plugin_strip( $cur, $route ); ?>

			<nav style="flex:1; overflow-y:auto; padding:6px 10px 16px;">
				<?php
				foreach ( $this->nav_groups( $cur ) as $group ) {
					$glabel = isset( $group[0] ) ? $this->L( $group[0] ) : '';
					$items  = isset( $group[1] ) ? $group[1] : array();
					echo '<div><div style="font-size:10px; letter-spacing:.1em; text-transform:uppercase; color:#5a7567; padding:15px 10px 6px; font-weight:800;">' . esc_html( $glabel ) . '</div>';
					foreach ( $items as $it ) {
						$this->nav_item( $it, $route );
					}
					echo '</div>';
				}
				if ( 'suite' === $cur ) :
					?>
				<div style="margin-top:8px;">
					<div style="font-size:10px; letter-spacing:.1em; text-transform:uppercase; color:#5a7567; padding:15px 10px 6px; font-weight:800;"><?php echo esc_html( $ar ? 'النظام' : 'System' ); ?></div>
					<?php
					foreach ( $this->system_nav() as $it ) {
						$this->nav_item( $it, $route );
					}
					?>
				</div>
				<?php endif; ?>
			</nav>

			<?php $this->sidebar_footer( $ar, $route, $cur ); ?>
		</aside>
		<?php
	}

	/**
	 * Render a single sidebar nav item (anchor).
	 *
	 * @param array  $it    [route, label, icon, opts].
	 * @param string $route Active route.
	 */
	private function nav_item( $it, $route ) {
		$rt     = isset( $it[0] ) ? $it[0] : '';
		$label  = isset( $it[1] ) ? $this->L( $it[1] ) : '';
		$icon   = isset( $it[2] ) ? $it[2] : 'chevron_right';
		$opts   = isset( $it[3] ) && is_array( $it[3] ) ? $it[3] : array();
		$active = ( $route === $rt );
		$href   = ! empty( $opts['href'] ) ? $opts['href'] : $this->url( $rt );
		$ar     = 'ar' === $this->lang();
		$weight = $active ? 700 : 500;
		$bg     = $active ? 'rgba(255,255,255,.10)' : 'transparent';
		$fg     = $active ? '#ffffff' : '#92a89b';
		$icofg  = $active ? '#ffffff' : '#6f8a7c';
		$fill   = $active ? 'fill' : '';
		?>
		<a class="ms-nav-item" href="<?php echo esc_url( $href ); ?>"<?php echo ! empty( $opts['install'] ) ? ' data-ms-install="' . esc_attr( $opts['install'] ) . '"' : ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> style="position:relative; width:100%; display:flex; align-items:center; gap:11px; padding:8px 11px; border-radius:9px; border:0; cursor:pointer; margin:1px 0; font-size:13px; text-align:start; font-weight:<?php echo (int) $weight; ?>; background:<?php echo esc_attr( $bg ); ?>; color:<?php echo esc_attr( $fg ); ?>; box-sizing:border-box;">
			<span style="position:absolute; inset-inline-start:0; top:7px; bottom:7px; width:3px; border-radius:0 3px 3px 0; background:var(--accent); opacity:<?php echo $active ? '1' : '0'; ?>;"></span>
			<span class="msym <?php echo esc_attr( $fill ); ?>" style="font-size:18px; color:<?php echo esc_attr( $icofg ); ?>;"><?php echo esc_html( $icon ); ?></span>
			<span style="flex:1;"><?php echo esc_html( $label ); ?></span>
			<?php if ( ! empty( $opts['dot'] ) && ! $active ) : ?>
				<span style="width:7px; height:7px; border-radius:50%; background:var(--hi); box-shadow:0 0 0 3px rgba(234,124,57,.22); margin-inline-start:auto;"></span>
			<?php endif; ?>
			<?php if ( ! empty( $opts['badge'] ) ) : ?>
				<span style="margin-inline-start:auto; font-size:9.5px; padding:2px 7px; border-radius:99px; background:rgba(255,255,255,.08); color:#cfe0d6; font-weight:700;"><?php echo esc_html( $opts['badge'] ); ?></span>
			<?php endif; ?>
			<?php if ( ! empty( $opts['pro'] ) ) : ?>
				<span style="margin-inline-start:auto; font-size:9px; padding:1px 5px; border-radius:4px; background:linear-gradient(135deg,var(--hi),#f0a76b); color:#fff; font-weight:800; letter-spacing:.04em;">PRO</span>
			<?php endif; ?>
		</a>
		<?php
	}

	/**
	 * Quick-switch strip for the three Mersal plugins.
	 *
	 * @param string $cur   Current plugin id.
	 * @param string $route Active route.
	 */
	private function plugin_strip( $cur, $route ) {
		if ( ! class_exists( 'Mersal_Suite_Catalog' ) ) {
			return;
		}
		$ar = 'ar' === $this->lang();
		echo '<div style="margin:4px 12px 8px; display:flex; gap:6px; justify-content:center;">';
		foreach ( Mersal_Suite_Catalog::ORDER as $id ) {
			$meta = Mersal_Suite_Catalog::meta( $id, $this );
			if ( ! $meta ) {
				continue;
			}
			$active   = ( $cur === $id );
			$status   = Mersal_Suite_Catalog::status( $id, $ar );
			$href     = Mersal_Suite_Catalog::resolve_url( $id );
			$bg       = $active ? 'rgba(255,255,255,.12)' : 'rgba(255,255,255,.04)';
			$border   = $active ? 'color-mix(in srgb, var(--accent) 40%, #1c2e25)' : '#1c2e25';
			$title    = $this->L( $meta['name'] );
			$tip      = 'active' === $status ? $title : ( $title . ' — ' . Mersal_Suite_Catalog::status_label( $id, $ar ) );
			$install  = ( 'download' === $status ) ? ' data-ms-install="' . esc_attr( $id ) . '"' : '';
			?>
			<a href="<?php echo esc_url( $href ); ?>"<?php echo $install; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> title="<?php echo esc_attr( $tip ); ?>" style="position:relative; flex:1; display:grid; place-items:center; height:38px; border-radius:10px; background:<?php echo esc_attr( $bg ); ?>; border:1px solid <?php echo esc_attr( $border ); ?>; color:<?php echo esc_attr( $active ? '#fff' : '#92a89b' ); ?>; text-decoration:none;">
				<span class="msym fill" style="font-size:20px; color:<?php echo esc_attr( $active ? '#fff' : $meta['accent'] ); ?>;"><?php echo esc_html( $meta['icon'] ); ?></span>
				<?php if ( 'active' !== $status ) : ?>
					<span style="position:absolute; top:-4px; inset-inline-end:-2px; font-size:8px; font-weight:800; padding:1px 4px; border-radius:99px; background:var(--hi); color:#fff; white-space:nowrap;"><?php echo esc_html( Mersal_Suite_Catalog::status_label( $id, $ar ) ); ?></span>
				<?php endif; ?>
			</a>
			<?php
		}
		echo '</div>';
	}

	/**
	 * The per-plugin Mersal account footer card.
	 *
	 * @param bool   $ar    Arabic flag.
	 * @param string $route Active route.
	 * @param string $cur   Current plugin id.
	 */
	private function sidebar_footer( $ar, $route = '', $cur = 'suite' ) {
		$footer_id = in_array( $cur, array( 'otp', 'cm', 'nt' ), true ) ? $cur : 'suite';
		if ( class_exists( 'Mersal_Suite_Account' ) ) {
			$conn = Mersal_Suite_Account::footer_for_plugin( $footer_id );
		} else {
			$conn = array(
				'connected' => false,
				'title'     => $ar ? 'ربط حساب مرسال' : 'Connect Mersal',
				'subtitle'  => $ar ? 'افتح صفحة الربط' : 'Open account settings',
				'initials'  => 'م',
				'url'       => $this->url( 'hub' ),
			);
		}
		$url       = ! empty( $conn['url'] ) ? $conn['url'] : $this->url( 'hub' );
		$connected = ! empty( $conn['connected'] );
		$title     = isset( $conn['title'] ) ? (string) $conn['title'] : ( $ar ? 'ربط حساب مرسال' : 'Connect Mersal' );
		$subtitle  = isset( $conn['subtitle'] ) ? (string) $conn['subtitle'] : ( $ar ? 'افتح صفحة الربط' : 'Open account settings' );
		$init      = isset( $conn['initials'] ) ? (string) $conn['initials'] : 'م';
		$connect_routes = array( 'otp.connect', 'cm.connect', 'nt.connect' );
		$active    = in_array( $route, $connect_routes, true );
		$dot       = $connected ? 'var(--accent)' : 'var(--warn)';
		$bg        = $active ? 'rgba(255,255,255,.08)' : '#0c1812';
		$border    = $active ? 'color-mix(in srgb, var(--accent) 35%, #1c2e25)' : '#1c2e25';
		?>
		<div style="border-top:1px solid #1c2e25; padding:12px;">
			<a href="<?php echo esc_url( $url ); ?>" style="display:flex; align-items:center; gap:10px; padding:8px 10px; border-radius:11px; background:<?php echo esc_attr( $bg ); ?>; border:1px solid <?php echo esc_attr( $border ); ?>; cursor:pointer; text-decoration:none;">
				<div style="width:32px; height:32px; border-radius:50%; background:linear-gradient(135deg,var(--accent),var(--accent-2)); display:grid; place-items:center; color:#fff; font-weight:700; font-size:12px; flex:0 0 32px;"><?php echo esc_html( $init ); ?></div>
				<div style="display:flex; flex-direction:column; line-height:1.3; min-width:0;">
					<b style="font-size:12.5px; color:#e7f0ea; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;"><?php echo esc_html( $title ); ?></b>
					<span style="font-size:10.5px; color:#6f8a7c; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;"><?php echo esc_html( $subtitle ); ?></span>
				</div>
				<span style="width:8px; height:8px; border-radius:50%; background:<?php echo esc_attr( $dot ); ?>; box-shadow:0 0 0 3px rgba(34,167,106,.2); margin-inline-start:auto; flex:0 0 8px;"></span>
			</a>
		</div>
		<?php
	}

	/* ------------------------------------------------------------------ */
	/* Topbar                                                             */
	/* ------------------------------------------------------------------ */

	/**
	 * Render the topbar.
	 *
	 * @param string $route Active route.
	 * @param string $cur   Current plugin id.
	 */
	private function topbar( $route, $cur ) {
		$ar       = 'ar' === $this->lang();
		$meta     = $this->meta( $cur );
		$labels   = $this->route_labels();
		$crumb    = isset( $labels[ $route ] ) ? $labels[ $route ] : array( $meta['name'], '' );
		$leaf     = $crumb[1];
		$chevron  = $ar ? 'chevron_left' : 'chevron_right';
		?>
		<header style="position:relative; z-index:30; background:var(--bg); border-bottom:1px solid var(--border); padding:0 22px; height:62px; flex:0 0 62px; display:flex; align-items:center; gap:12px;">
			<?php $this->switcher( $cur, $meta ); ?>

			<div style="display:flex; align-items:center; gap:6px; color:var(--fg-2); font-size:13px; min-width:0; overflow:hidden;">
				<span class="msym" style="font-size:16px; color:var(--fg-3);"><?php echo esc_html( $chevron ); ?></span>
				<b style="color:var(--fg-1); font-weight:700; white-space:nowrap; overflow:hidden; text-overflow:ellipsis;"><?php echo esc_html( $leaf ); ?></b>
			</div>

			<div style="margin-inline-start:auto; display:flex; align-items:center; gap:8px;">
				<div style="display:flex; align-items:center; gap:5px; padding:5px 8px; border-radius:99px; background:var(--surface); border:1px solid var(--border); font-size:12px; font-weight:700; box-shadow:var(--shadow);">
					<span class="msym" style="font-size:16px; color:var(--fg-3);">language</span>
					<span data-ms-lang="en" style="padding:2px 9px; border-radius:99px; cursor:pointer; background:<?php echo $ar ? 'transparent' : 'var(--fg-1)'; ?>; color:<?php echo $ar ? 'var(--fg-2)' : '#fff'; ?>;">EN</span>
					<span data-ms-lang="ar" style="padding:2px 9px; border-radius:99px; cursor:pointer; background:<?php echo $ar ? 'var(--fg-1)' : 'transparent'; ?>; color:<?php echo $ar ? '#fff' : 'var(--fg-2)'; ?>;">عربي</span>
				</div>

				<?php $this->updates_button( $ar ); ?>
				<?php $this->notif_bell( $ar ); ?>

				<a href="<?php echo esc_url( $this->url( 'billing' ) ); ?>" style="display:inline-flex; align-items:center; gap:6px; background:var(--hi); color:#fff; border:none; border-radius:10px; padding:9px 14px; font-weight:800; font-size:13px; cursor:pointer;">
					<span class="msym fill" style="font-size:17px;">workspace_premium</span><?php echo esc_html( $ar ? 'خطط مرسال' : 'Mersal Plans' ); ?>
				</a>
			</div>
		</header>
		<?php
	}

	/**
	 * Suite switcher button + dropdown.
	 *
	 * @param string $cur  Current plugin id.
	 * @param array  $meta Current meta.
	 */
	private function switcher( $cur, $meta ) {
		$ar = 'ar' === $this->lang();
		?>
		<div style="position:relative;">
			<div data-ms-backdrop="switch" style="display:none; position:fixed; inset:0; z-index:35;"></div>
			<button data-ms-toggle="switch" style="display:flex; align-items:center; gap:8px; background:var(--surface); border:1px solid var(--border); border-radius:11px; padding:8px 12px; cursor:pointer; color:var(--fg-1); font-weight:700; font-size:13px; box-shadow:var(--shadow);">
				<span style="width:22px; height:22px; border-radius:7px; background:<?php echo esc_attr( $meta['accent'] ); ?>; color:#fff; display:grid; place-items:center; flex:0 0 22px;"><span class="msym fill" style="font-size:15px;"><?php echo esc_html( $meta['icon'] ); ?></span></span>
				<?php echo esc_html( $meta['name'] ); ?>
				<span class="msym" style="font-size:18px; color:var(--fg-3);">expand_more</span>
			</button>
			<div data-ms-panel="switch" style="display:none; position:absolute; inset-inline-start:0; top:calc(100% + 6px); width:262px; background:var(--surface); border:1px solid var(--border); border-radius:11px; box-shadow:var(--shadow-lg); z-index:40; padding:6px; animation:msPop .16s ease;">
				<div style="font-size:10px; font-weight:800; letter-spacing:.1em; text-transform:uppercase; color:var(--fg-3); padding:8px 10px 5px;"><?php echo esc_html( $ar ? 'مرسال سويت' : 'Mersal Suite' ); ?></div>
				<?php
				$rows = array( 'suite' => $this->meta( 'suite' ) );
				if ( class_exists( 'Mersal_Suite_Catalog' ) ) {
					foreach ( Mersal_Suite_Catalog::ORDER as $id ) {
						$cmeta = Mersal_Suite_Catalog::meta( $id, $this );
						if ( $cmeta ) {
							$rows[ $id ] = array(
								'name'   => $this->L( $cmeta['name'] ),
								'icon'   => $cmeta['icon'],
								'accent' => $cmeta['accent'],
							);
						}
					}
				} else {
					foreach ( $this->plugins() as $id => $p ) {
						$rows[ $id ] = $this->meta( $id );
					}
				}
				foreach ( $rows as $id => $m ) {
					$sel    = ( $id === $cur );
					if ( 'suite' === $id ) {
						$target = 'hub';
						$href   = $this->url( $target );
					} elseif ( class_exists( 'Mersal_Suite_Catalog' ) ) {
						$href = Mersal_Suite_Catalog::resolve_url( $id );
						if ( Mersal_Suite_Catalog::is_active( $id ) ) {
							$cmeta  = Mersal_Suite_Catalog::meta( $id, $this );
							$target = $cmeta ? $cmeta['default_route'] : $id . '.dash';
							$href   = $this->url( $target );
						}
					} else {
						$target = $this->plugins[ $id ]['default_route'];
						$href   = $this->url( $target );
					}
					$rowbg  = $sel ? 'var(--accent-soft)' : 'transparent';
					$tilebg = $sel ? $m['accent'] : 'var(--surface-3)';
					$tilefg = $sel ? '#fff' : 'var(--fg-2)';
					$badge  = class_exists( 'Mersal_Suite_Catalog' ) && 'suite' !== $id && 'active' !== Mersal_Suite_Catalog::status( $id, $ar )
						? Mersal_Suite_Catalog::status_label( $id, $ar )
						: '';
					$install = ( class_exists( 'Mersal_Suite_Catalog' ) && 'suite' !== $id && 'download' === Mersal_Suite_Catalog::status( $id, $ar ) )
						? ' data-ms-install="' . esc_attr( $id ) . '"'
						: '';
					?>
					<a href="<?php echo esc_url( $href ); ?>"<?php echo $install; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> style="width:100%; display:flex; align-items:center; gap:11px; padding:9px 10px; border-radius:9px; cursor:pointer; background:<?php echo esc_attr( $rowbg ); ?>; color:var(--fg-1); text-align:start; margin:1px 0; box-sizing:border-box;">
						<span style="width:28px; height:28px; border-radius:8px; background:<?php echo esc_attr( $tilebg ); ?>; color:<?php echo esc_attr( $tilefg ); ?>; display:grid; place-items:center; flex:0 0 28px;"><span class="msym fill" style="font-size:17px;"><?php echo esc_html( $m['icon'] ); ?></span></span>
						<span style="flex:1; font-weight:600; font-size:13px;"><?php echo esc_html( $m['name'] ); ?></span>
						<?php if ( $badge ) : ?>
							<span style="font-size:9px; font-weight:800; padding:2px 6px; border-radius:99px; background:var(--hi-soft); color:var(--hi);"><?php echo esc_html( $badge ); ?></span>
						<?php elseif ( $sel ) : ?>
							<span class="msym" style="font-size:18px; color:var(--accent);">check</span>
						<?php endif; ?>
					</a>
					<?php
				}
				?>
			</div>
		</div>
		<?php
	}

	/**
	 * Topbar updates shortcut: opens the Updates tab, badge = available updates.
	 *
	 * @param bool $ar Arabic flag.
	 */
	private function updates_button( $ar ) {
		$upd = $this->updates_count();
		?>
		<a href="<?php echo esc_url( $this->url( 'updates' ) ); ?>" title="<?php echo esc_attr( $ar ? 'التحديثات' : 'Updates' ); ?>" style="position:relative; display:grid; place-items:center; width:32px; height:32px; background:var(--surface); border:1px solid var(--border); border-radius:10px; cursor:pointer; color:var(--fg-2); box-shadow:var(--shadow);">
			<span class="msym" style="font-size:19px;">system_update_alt</span>
			<?php if ( $upd > 0 ) : ?>
				<span style="position:absolute; top:-5px; inset-inline-end:-5px; min-width:17px; height:17px; padding:0 4px; border-radius:99px; background:var(--hi); color:#fff; font-size:10px; font-weight:800; display:grid; place-items:center; border:2px solid var(--bg);"><?php echo esc_html( (string) $upd ); ?></span>
			<?php endif; ?>
		</a>
		<?php
	}

	/**
	 * Dismissible remote announcement (announcement.json on the Mersal site),
	 * shown on every Suite tab until the user dismisses it.
	 */
	private function announcement_banner() {
		if ( ! class_exists( 'Mersal_Suite_Remote' ) ) {
			return;
		}
		$n = Mersal_Suite_Remote::announcement();
		if ( ! $n ) {
			return;
		}
		$ar    = 'ar' === $this->lang();
		$title = $this->L( $n['title'] );
		$body  = isset( $n['body'] ) ? $this->L( $n['body'] ) : '';
		$icon  = ! empty( $n['icon'] ) ? (string) $n['icon'] : 'campaign';
		list( $bg, $fg ) = $this->tone( isset( $n['tone'] ) ? (string) $n['tone'] : 'accent' );
		$url       = ! empty( $n['url'] ) ? (string) $n['url'] : '';
		$url_label = isset( $n['url_label'] ) ? $this->L( $n['url_label'] ) : ( $ar ? 'المزيد' : 'Learn more' );
		?>
		<div data-ms-notice style="display:flex; align-items:flex-start; gap:10px; background:var(--surface); border:1px solid var(--border); border-inline-start:4px solid <?php echo esc_attr( $fg ); ?>; border-radius:11px; padding:14px 16px; box-shadow:var(--shadow); margin-bottom:18px; animation:msFade .3s ease;">
			<div style="width:32px; height:32px; border-radius:11px; display:grid; place-items:center; background:<?php echo esc_attr( $bg ); ?>; color:<?php echo esc_attr( $fg ); ?>; flex:0 0 32px;"><span class="msym fill" style="font-size:20px;"><?php echo esc_html( $icon ); ?></span></div>
			<div style="flex:1; min-width:0;">
				<b style="font-size:13.5px; color:var(--fg-1);"><?php echo esc_html( $title ); ?></b>
				<?php if ( $body ) : ?>
					<p style="margin:3px 0 0; font-size:12.5px; color:var(--fg-2); line-height:1.6;"><?php echo esc_html( $body ); ?></p>
				<?php endif; ?>
				<?php if ( $url ) : ?>
					<a href="<?php echo esc_url( $url ); ?>" target="_blank" rel="noopener" style="display:inline-flex; align-items:center; gap:4px; margin-top:7px; font-size:12px; font-weight:700; color:<?php echo esc_attr( $fg ); ?>;"><span class="msym" style="font-size:15px;">open_in_new</span><?php echo esc_html( $url_label ); ?></a>
				<?php endif; ?>
			</div>
			<button data-ms-notice-dismiss="<?php echo esc_attr( (string) $n['id'] ); ?>" title="<?php echo esc_attr( $ar ? 'إخفاء' : 'Dismiss' ); ?>" style="border:none; background:transparent; color:var(--fg-3); cursor:pointer; padding:2px; flex:0 0 auto;"><span class="msym" style="font-size:19px;">close</span></button>
		</div>
		<?php
	}

	/**
	 * Notifications bell + dropdown (data via the mersal_suite_notifications filter).
	 *
	 * @param bool $ar Arabic flag.
	 */
	private function notif_bell( $ar ) {
		$items  = $this->notifications();
		$unread = 0;
		foreach ( $items as $n ) {
			if ( ! empty( $n['unread'] ) ) {
				$unread++;
			}
		}
		?>
		<div data-ms-backdrop="notif" style="display:none; position:fixed; inset:0; z-index:35;"></div>
		<div style="position:relative;">
			<button data-ms-toggle="notif" style="position:relative; display:grid; place-items:center; width:32px; height:32px; background:var(--surface); border:1px solid var(--border); border-radius:10px; cursor:pointer; color:var(--fg-2); box-shadow:var(--shadow);">
				<span class="msym fill" style="font-size:19px;">notifications</span>
				<?php if ( $unread > 0 ) : ?>
					<span style="position:absolute; top:-5px; inset-inline-end:-5px; min-width:17px; height:17px; padding:0 4px; border-radius:99px; background:var(--hi); color:#fff; font-size:10px; font-weight:800; display:grid; place-items:center; border:2px solid var(--bg);"><?php echo esc_html( (string) $unread ); ?></span>
				<?php endif; ?>
			</button>
			<div data-ms-panel="notif" style="display:none; position:absolute; inset-inline-end:0; top:48px; width:340px; background:var(--surface); border:1px solid var(--border); border-radius:12px; box-shadow:var(--shadow-lg); z-index:40; overflow:hidden; animation:msPop .18s ease;">
				<div style="display:flex; align-items:center; justify-content:space-between; padding:14px 16px; border-bottom:1px solid var(--border);">
					<b style="font-size:14px; color:var(--fg-1);"><?php echo esc_html( $ar ? 'الإشعارات' : 'Notifications' ); ?></b>
				</div>
				<div style="max-height:340px; overflow-y:auto;">
					<?php if ( empty( $items ) ) : ?>
						<div style="padding:26px 16px; text-align:center; font-size:12.5px; color:var(--fg-3);"><?php echo esc_html( $ar ? 'لا توجد إشعارات' : 'No notifications' ); ?></div>
					<?php else : ?>
						<?php
						foreach ( $items as $n ) {
							list( $bg, $fg ) = $this->tone( isset( $n['tone'] ) ? $n['tone'] : 'accent' );
							if ( ! empty( $n['href'] ) ) {
								$href = $n['href'];
							} else {
								$href = isset( $n['route'] ) ? $this->url( $n['route'] ) : '#';
							}
							?>
							<a href="<?php echo esc_url( $href ); ?>" style="display:flex; gap:12px; padding:13px 16px; border-bottom:1px solid var(--border); cursor:pointer;">
								<div style="width:36px; height:36px; border-radius:10px; display:grid; place-items:center; background:<?php echo esc_attr( $bg ); ?>; color:<?php echo esc_attr( $fg ); ?>; flex:0 0 36px;"><span class="msym fill" style="font-size:19px;"><?php echo esc_html( isset( $n['icon'] ) ? $n['icon'] : 'info' ); ?></span></div>
								<div style="flex:1; min-width:0;">
									<div style="font-size:12.5px; font-weight:700; color:var(--fg-1); line-height:1.4;"><?php echo esc_html( isset( $n['title'] ) ? $n['title'] : '' ); ?></div>
									<div style="font-size:11.5px; color:var(--fg-2); margin-top:2px; line-height:1.4;"><?php echo esc_html( isset( $n['sub'] ) ? $n['sub'] : '' ); ?></div>
									<div style="font-size:10.5px; color:var(--fg-3); margin-top:3px;"><?php echo esc_html( isset( $n['time'] ) ? $n['time'] : '' ); ?></div>
								</div>
								<?php if ( ! empty( $n['unread'] ) ) : ?><span style="width:8px; height:8px; border-radius:50%; background:var(--hi); flex:0 0 8px; margin-top:4px;"></span><?php endif; ?>
							</a>
							<?php
						}
						?>
					<?php endif; ?>
				</div>
				<a href="<?php echo esc_url( $this->url( 'updates' ) ); ?>" style="display:flex; align-items:center; justify-content:center; gap:6px; padding:13px; font-size:12.5px; font-weight:700; color:var(--accent); cursor:pointer; background:var(--surface-2);">
					<span class="msym" style="font-size:17px;">system_update_alt</span><?php echo esc_html( $ar ? 'فتح مركز التحديثات' : 'Open update center' ); ?>
				</a>
			</div>
		</div>
		<?php
	}

	/* ------------------------------------------------------------------ */
	/* Data helpers (filter-driven, real data injected by plugins)        */
	/* ------------------------------------------------------------------ */

	/**
	 * Store / brand name (Suite setting overrides the WP blog name).
	 *
	 * @return string
	 */
	public function store_name() {
		$n = $this->opt( 'store_name', '' );
		return $n ? $n : get_bloginfo( 'name' );
	}

	/**
	 * Notifications shown in the bell: real Suite events (updates available,
	 * remote announcement) + anything plugins add through the filter.
	 *
	 * @return array
	 */
	private function notifications() {
		$ar    = 'ar' === $this->lang();
		$items = array();

		if ( class_exists( 'Mersal_Suite_Remote' ) ) {
			$upd = $this->updates_count();
			if ( $upd > 0 ) {
				$items[] = array(
					'icon'   => 'system_update_alt',
					'tone'   => 'hi',
					'title'  => $ar ? sprintf( '%d تحديث متاح لإضافات مرسال', $upd ) : sprintf( '%d Mersal plugin update(s) available', $upd ),
					'sub'    => $ar ? 'ثبّت أحدث إصدار من مركز التحديثات' : 'Install the latest versions from the update center',
					'route'  => 'updates',
					'unread' => true,
				);
			}
			$n = Mersal_Suite_Remote::announcement();
			if ( $n ) {
				$items[] = array(
					'icon'   => ! empty( $n['icon'] ) ? (string) $n['icon'] : 'campaign',
					'tone'   => ! empty( $n['tone'] ) ? (string) $n['tone'] : 'accent',
					'title'  => $this->L( $n['title'] ),
					'sub'    => isset( $n['body'] ) ? $this->L( $n['body'] ) : '',
					'href'   => ! empty( $n['url'] ) ? (string) $n['url'] : '',
					'unread' => true,
				);
			}
		}

		$extra  = apply_filters( 'mersal_suite_notifications', array() );
		$merged = array_merge( $items, is_array( $extra ) ? $extra : array() );

		// De-dupe by id: several Mersal plugins may each fetch the same account
		// broadcast list from mersal.it, so the same notification arrives more
		// than once. Items without an id (Suite-native events) are always kept.
		$seen = array();
		$out  = array();
		foreach ( $merged as $n ) {
			$id = isset( $n['id'] ) ? (string) $n['id'] : '';
			if ( '' !== $id ) {
				if ( isset( $seen[ $id ] ) ) {
					continue;
				}
				$seen[ $id ] = true;
			}
			$out[] = $n;
		}
		return $out;
	}

	/**
	 * Number of plugin updates available (real, filterable on top).
	 *
	 * @return int
	 */
	private function updates_count() {
		$count = class_exists( 'Mersal_Suite_Remote' ) ? Mersal_Suite_Remote::updates_count() : 0;
		return (int) apply_filters( 'mersal_suite_updates_count', $count );
	}

	/* ------------------------------------------------------------------ */
	/* Hub                                                                */
	/* ------------------------------------------------------------------ */

	/**
	 * Render the unified hub.
	 */
	private function page_hub() {
		$ar         = 'ar' === $this->lang();
		$store      = $this->store_name();
		$catalog    = class_exists( 'Mersal_Suite_Catalog' ) ? Mersal_Suite_Catalog::all() : array();
		$count      = class_exists( 'Mersal_Suite_Catalog' ) ? count( Mersal_Suite_Catalog::ORDER ) : count( $this->plugins );
		$active_cnt = 0;
		if ( class_exists( 'Mersal_Suite_Catalog' ) ) {
			foreach ( Mersal_Suite_Catalog::ORDER as $pid ) {
				if ( Mersal_Suite_Catalog::is_active( $pid ) ) {
					$active_cnt++;
				}
			}
		} else {
			$active_cnt = count( $this->plugins );
		}
		?>
		<div style="animation:msFade .3s ease;">
			<div style="position:relative; overflow:hidden; border-radius:16px; padding:20px 22px; background:linear-gradient(125deg,#0f7a4a 0%, #0c6740 55%, #0a5436 100%); color:#fff; box-shadow:0 14px 40px var(--accent-glow); margin-bottom:14px;">
				<div style="position:absolute; inset-inline-end:-40px; top:-40px; width:240px; height:240px; border-radius:50%; background:rgba(255,255,255,.06);"></div>
				<div style="position:absolute; inset-inline-end:60px; bottom:-70px; width:160px; height:160px; border-radius:50%; background:rgba(234,124,57,.18);"></div>
				<div style="position:relative; display:flex; align-items:flex-start; gap:24px; flex-wrap:wrap;">
					<div style="flex:1; min-width:280px;">
						<span style="display:inline-flex; align-items:center; gap:6px; font-size:11.5px; font-weight:700; background:rgba(255,255,255,.16); padding:5px 11px; border-radius:999px; margin-bottom:14px;">
							<span class="msym fill" style="font-size:15px;">bolt</span><?php echo esc_html( $ar ? 'كل الإضافات تعمل بكفاءة' : 'All plugins healthy' ); ?>
						</span>
						<h2 style="font-size:20px; font-weight:800; margin:0 0 8px; color:#fff;"><?php echo esc_html( $ar ? ( 'أهلاً، ' . $store . ' 👋' ) : ( 'Welcome, ' . $store . ' 👋' ) ); ?></h2>
						<p style="margin:0; font-size:14px; color:rgba(255,255,255,.82); max-width:520px; line-height:1.6;"><?php echo esc_html( $ar ? 'تحقّق OTP، إشعارات تلقائية، وحملات تسويقية — من نفس اللوحة وبنفس الهوية. كل إضافة تثبتها تضيف أدواتها هنا.' : 'OTP verification, automated notifications, and marketing campaigns — one dashboard, one identity. Each plugin you install plugs its tools in right here.' ); ?></p>
						<div style="display:flex; gap:10px; margin-top:18px; flex-wrap:wrap;">
							<?php
							$cm = isset( $this->plugins['cm'] ) ? $this->plugins['cm']['default_route'] : null;
							$otp = isset( $this->plugins['otp'] ) ? ( $this->plugins['otp']['default_route'] ) : null;
							if ( $cm ) :
								?>
								<a href="<?php echo esc_url( $this->url( 'cm.builder' ) ); ?>" style="display:inline-flex; align-items:center; gap:7px; background:#fff; color:#0c6740; border:none; border-radius:11px; padding:11px 18px; font-weight:800; font-size:13.5px; cursor:pointer;">
									<span class="msym fill" style="font-size:18px;">add</span><?php echo esc_html( $ar ? 'إنشاء حملة جديدة' : 'Create a campaign' ); ?>
								</a>
							<?php endif; ?>
							<?php if ( $otp ) : ?>
								<a href="<?php echo esc_url( $this->url( 'otp.channels' ) ); ?>" style="display:inline-flex; align-items:center; gap:7px; background:rgba(255,255,255,.14); color:#fff; border:1px solid rgba(255,255,255,.25); border-radius:11px; padding:11px 18px; font-weight:700; font-size:13.5px; cursor:pointer;">
									<span class="msym" style="font-size:18px;">settings</span><?php echo esc_html( $ar ? 'إعداد القنوات' : 'Configure channels' ); ?>
								</a>
							<?php endif; ?>
						</div>
					</div>
					<div style="display:flex; gap:22px; padding:6px 4px;">
						<div style="text-align:center;">
							<div style="font-size:23px; font-weight:800; line-height:1;"><?php echo esc_html( (string) $active_cnt ); ?></div>
							<div style="font-size:11px; color:rgba(255,255,255,.78); margin-top:5px;"><?php echo esc_html( $ar ? 'إضافات مُفعّلة' : 'active plugins' ); ?></div>
						</div>
						<div style="text-align:center;">
							<div style="font-size:23px; font-weight:800; line-height:1;"><?php echo esc_html( (string) $count ); ?></div>
							<div style="font-size:11px; color:rgba(255,255,255,.78); margin-top:5px;"><?php echo esc_html( $ar ? 'في المنصة' : 'in suite' ); ?></div>
						</div>
					</div>
				</div>
			</div>

			<?php
			$stats = apply_filters( 'mersal_suite_hub_stats', array() );
			if ( ! empty( $stats ) ) :
				?>
				<div style="display:grid; grid-template-columns:repeat(<?php echo (int) min( 4, max( 1, count( $stats ) ) ); ?>,1fr); gap:10px; margin-bottom:14px;">
					<?php
					foreach ( array_slice( $stats, 0, 4 ) as $s ) {
						list( $bg, $fg ) = $this->tone( isset( $s['tone'] ) ? $s['tone'] : 'accent' );
						?>
						<div style="background:var(--surface); border:1px solid var(--border); border-radius:12px; padding:13px; box-shadow:var(--shadow);">
							<div style="display:flex; align-items:center; justify-content:space-between;">
								<div style="width:32px; height:32px; border-radius:11px; display:grid; place-items:center; background:<?php echo esc_attr( $bg ); ?>; color:<?php echo esc_attr( $fg ); ?>;">
									<span class="msym fill" style="font-size:20px;"><?php echo esc_html( isset( $s['icon'] ) ? $s['icon'] : 'insights' ); ?></span>
								</div>
								<?php if ( ! empty( $s['delta'] ) ) : ?>
									<span style="display:inline-flex; align-items:center; gap:2px; font-size:11.5px; font-weight:700; color:var(--accent); background:var(--accent-soft); padding:3px 8px; border-radius:999px;">
										<span class="msym" style="font-size:14px;"><?php echo esc_html( ! empty( $s['up'] ) ? 'trending_up' : 'trending_down' ); ?></span><?php echo esc_html( $s['delta'] ); ?>
									</span>
								<?php endif; ?>
							</div>
							<div style="font-size:19px; font-weight:800; margin-top:13px; color:var(--fg-1);"><?php echo esc_html( isset( $s['val'] ) ? $s['val'] : '—' ); ?></div>
							<div style="font-size:12px; color:var(--fg-2); margin-top:2px;"><?php echo esc_html( isset( $s['label'] ) ? $s['label'] : '' ); ?></div>
						</div>
						<?php
					}
					?>
				</div>
			<?php endif; ?>

			<div style="display:grid; grid-template-columns:1.6fr 1fr; gap:12px; align-items:start;">
				<div>
					<div style="display:flex; align-items:center; gap:8px; margin-bottom:12px;">
						<h3 style="font-size:14px; font-weight:800; margin:0; color:var(--fg-1);"><?php echo esc_html( $ar ? 'إضافاتك' : 'Your plugins' ); ?></h3>
						<span style="font-size:12px; color:var(--fg-3); font-weight:600;"><?php echo esc_html( $count . ' ' . ( $ar ? 'في المنصة' : 'in suite' ) ); ?></span>
					</div>
					<div style="display:flex; flex-direction:column; gap:12px;">
						<?php
						$hub_plugins = class_exists( 'Mersal_Suite_Catalog' ) ? Mersal_Suite_Catalog::ORDER : array_keys( $this->plugins() );
						foreach ( $hub_plugins as $id ) {
							if ( class_exists( 'Mersal_Suite_Catalog' ) ) {
								$p      = Mersal_Suite_Catalog::meta( $id, $this );
								$status = Mersal_Suite_Catalog::status( $id, $ar );
								$href   = Mersal_Suite_Catalog::resolve_url( $id );
								$stat   = apply_filters( 'mersal_suite_plugin_stat', '', $id );
							} else {
								$p      = $this->plugins[ $id ];
								$status = 'active';
								$href   = $this->url( $p['default_route'] );
								$stat   = apply_filters( 'mersal_suite_plugin_stat', '', $id );
							}
							if ( ! $p ) {
								continue;
							}
							$is_active = ( 'active' === $status );
							$badge_txt = class_exists( 'Mersal_Suite_Catalog' ) ? Mersal_Suite_Catalog::status_label( $id, $ar ) : ( $ar ? 'مُثبّتة' : 'Installed' );
							$badge_col = $is_active ? 'var(--accent)' : 'var(--hi)';
							$badge_bg  = $is_active ? 'var(--accent-soft)' : 'var(--hi-soft)';
							$icon      = is_array( $p ) && isset( $p['icon'] ) ? $p['icon'] : 'extension';
							$accent    = is_array( $p ) && isset( $p['accent'] ) ? $p['accent'] : '#0f7a4a';
							$name      = $this->L( $p['name'] );
							$sub       = $this->L( $p['sub'] );
							$install   = ( 'download' === $status ) ? ' data-ms-install="' . esc_attr( $id ) . '"' : '';
							?>
							<a class="ms-card-link" href="<?php echo esc_url( $href ); ?>"<?php echo $install; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?> style="display:flex; align-items:center; gap:16px; background:var(--surface); border:1px solid var(--border); border-radius:12px; padding:13px; box-shadow:var(--shadow); cursor:pointer;">
								<div style="width:40px; height:40px; border-radius:11px; display:grid; place-items:center; background:color-mix(in srgb, <?php echo esc_attr( $accent ); ?> 16%, transparent); color:<?php echo esc_attr( $accent ); ?>; flex:0 0 40px;">
									<span class="msym fill" style="font-size:26px;"><?php echo esc_html( $icon ); ?></span>
								</div>
								<div style="flex:1; min-width:0;">
									<div style="display:flex; align-items:center; gap:8px; flex-wrap:wrap;">
										<b style="font-size:15px; color:var(--fg-1);"><?php echo esc_html( $name ); ?></b>
										<span style="display:inline-flex; align-items:center; gap:3px; font-size:10.5px; font-weight:700; color:<?php echo esc_attr( $badge_col ); ?>; background:<?php echo esc_attr( $badge_bg ); ?>; padding:2px 8px; border-radius:999px;">
											<?php if ( $is_active ) : ?><span class="msym fill" style="font-size:13px;">check_circle</span><?php endif; ?>
											<?php echo esc_html( $badge_txt ); ?>
										</span>
									</div>
									<p style="margin:4px 0 0; font-size:12.5px; color:var(--fg-2); line-height:1.5;"><?php echo esc_html( $sub ); ?></p>
									<?php if ( $stat ) : ?><div style="font-size:11.5px; color:var(--fg-3); margin-top:6px; font-weight:600;"><?php echo esc_html( $stat ); ?></div><?php endif; ?>
								</div>
								<span class="msym" style="font-size:22px; color:var(--fg-3);"><?php echo esc_html( $ar ? 'chevron_left' : 'chevron_right' ); ?></span>
							</a>
							<?php
						}
						?>
						<a href="https://mersal.it/Wordpress-Plugins/" target="_blank" rel="noopener" style="display:flex; align-items:center; justify-content:center; gap:8px; border:1.5px dashed var(--border-strong); border-radius:12px; padding:16px; color:var(--fg-3); font-weight:700; font-size:13px; cursor:pointer;">
							<span class="msym" style="font-size:19px;">add_circle</span><?php echo esc_html( $ar ? 'تصفّح إضافات مرسال الأخرى' : 'Browse more Mersal plugins' ); ?>
						</a>
					</div>
				</div>

				<div style="background:var(--surface); border:1px solid var(--border); border-radius:12px; padding:13px; box-shadow:var(--shadow);">
					<h3 style="font-size:13.5px; font-weight:800; margin:0 0 4px; color:var(--fg-1);"><?php echo esc_html( $ar ? 'أحدث النشاط' : 'Recent activity' ); ?></h3>
					<p style="margin:0 0 14px; font-size:12px; color:var(--fg-3);"><?php echo esc_html( $ar ? 'عبر كل الإضافات' : 'across all plugins' ); ?></p>
					<div style="display:flex; flex-direction:column;">
						<?php
						$activity = apply_filters( 'mersal_suite_hub_activity', array() );
						if ( empty( $activity ) ) {
							echo '<div style="padding:13px 0; font-size:12.5px; color:var(--fg-3);">' . esc_html( $ar ? 'لا يوجد نشاط بعد.' : 'No activity yet.' ) . '</div>';
						}
						foreach ( array_slice( (array) $activity, 0, 6 ) as $a ) {
							list( $bg, $fg ) = $this->tone( isset( $a['tone'] ) ? $a['tone'] : 'accent' );
							?>
							<div style="display:flex; gap:12px; padding:11px 0; border-bottom:1px solid var(--border);">
								<div style="width:34px; height:34px; border-radius:10px; display:grid; place-items:center; background:<?php echo esc_attr( $bg ); ?>; color:<?php echo esc_attr( $fg ); ?>; flex:0 0 34px;">
									<span class="msym fill" style="font-size:18px;"><?php echo esc_html( isset( $a['icon'] ) ? $a['icon'] : 'bolt' ); ?></span>
								</div>
								<div style="flex:1; min-width:0;">
									<p style="margin:0; font-size:12.5px; color:var(--fg-1); line-height:1.5;"><?php echo esc_html( isset( $a['txt'] ) ? $a['txt'] : '' ); ?></p>
									<span style="font-size:11px; color:var(--fg-3);"><?php echo esc_html( isset( $a['time'] ) ? $a['time'] : '' ); ?></span>
								</div>
							</div>
							<?php
						}
						?>
					</div>
				</div>
			</div>
		</div>
		<?php
	}

	/* ------------------------------------------------------------------ */
	/* System pages + placeholder                                         */
	/* ------------------------------------------------------------------ */

	/**
	 * Render a page header block.
	 *
	 * @param string $title Title.
	 * @param string $sub   Subtitle.
	 */
	public function page_head( $title, $sub = '' ) {
		echo '<div style="display:flex; align-items:flex-end; gap:16px; margin-bottom:13px;"><div style="display:flex; flex-direction:column; gap:3px;">';
		echo '<h1 style="margin:0; font-size:22px; font-weight:800; color:var(--fg-1); letter-spacing:-.01em;">' . esc_html( $title ) . '</h1>';
		if ( $sub ) {
			echo '<p style="margin:0; color:var(--fg-2); font-size:13.5px;">' . esc_html( $sub ) . '</p>';
		}
		echo '</div></div>';
	}

	/**
	 * Render a system page.
	 *
	 * @param string $route Route id.
	 */
	private function system_page( $route ) {
		$ar = 'ar' === $this->lang();
		// Allow a plugin to fully own a system page if it wants to.
		if ( has_action( 'mersal_suite_render_' . $route ) ) {
			do_action( 'mersal_suite_render_' . $route, $this );
			return;
		}
		switch ( $route ) {
			case 'settings':
				$this->page_settings();
				break;
			case 'updates':
				$this->page_updates();
				break;
			case 'integrations':
				$this->page_integrations();
				break;
			case 'billing':
				$this->page_billing();
				break;
			default:
				$this->page_placeholder( $route );
		}
	}

	/**
	 * Friendly placeholder for routes still being wired.
	 *
	 * @param string $route Route id.
	 */
	private function page_placeholder( $route ) {
		$ar = 'ar' === $this->lang();
		echo '<div style="background:var(--surface); border:1px solid var(--border); border-radius:12px; padding:48px; box-shadow:var(--shadow); text-align:center;">';
		echo '<div style="width:56px; height:56px; border-radius:12px; background:var(--accent-soft); color:var(--accent); display:grid; place-items:center; margin:0 auto 16px;"><span class="msym fill" style="font-size:23px;">construction</span></div>';
		echo '<h3 style="margin:0 0 6px; font-size:16px; color:var(--fg-1);">' . esc_html( $ar ? 'هذه الشاشة قيد التجهيز' : 'This screen is being prepared' ) . '</h3>';
		echo '<p style="margin:0; font-size:13px; color:var(--fg-2);">' . esc_html( $route ) . '</p>';
		echo '</div>';
	}
}
