<?php

declare(strict_types=1);

require_once dirname(__DIR__, 3) . '/system/bootstrap.php';
require_once dirname(__DIR__) . '/shared/section-content-field-controls.php';
// DesignSystemRegistry is loaded by bootstrap's app-local JSONM runtime.

$currentUser = myronRequireDesignAccess();
$registry = myronSiteTypeRegistryRepository();
$templateRepository = myronTemplateDefinitionRepository();
$bundleRepository = myronBundleActivationRepository();
$previewFactory = myronTemplatePreviewFactory();
$renderer = myronDefinitionTemplateRenderer();
$contentRepository = myronContentRepository();
$pdo = myronDatabase();
$entitlementPresentation = myronEntitlementPresentationPolicy();
$footerDesignRepository = myronFooterDesignRepository();
$navigationDesignRepository = myronNavigationDesignRepository();
$railDesignRepository = myronRailDesignRepository();
$chromeAssignmentRepository = myronTemplateChromeAssignmentRepository();
$footerVariantLabels = myronFooterVariantCompositionService()->variantLabels();
$designSystemRegistry = new DesignSystemRegistry();
$currentLayoutTokens = $designSystemRegistry->currentLayoutTokens();
$studioBreakpointSm = trim((string) (($currentLayoutTokens['breakpoints'] ?? [])['sm'] ?? '640px'));
if (!preg_match('/^\d+px$/', $studioBreakpointSm)) {
    $studioBreakpointSm = '640px';
}

$templateStudioBasePath = '/design/template-studio';
$legacySiteTypeStudioBasePath = '/design/site-type-studio';
$requestPath = myronResolveAppRequestPath((string) ($_SERVER['REQUEST_URI'] ?? myronBuildAdminUrl('design.templateStudio')));
$isTemplateStudioRoute = $requestPath === $templateStudioBasePath || str_starts_with($requestPath, $templateStudioBasePath . '/');
$relativePath = $isTemplateStudioRoute
    ? trim(substr($requestPath, strlen($templateStudioBasePath)), '/')
    : trim(substr($requestPath, strlen($legacySiteTypeStudioBasePath)), '/');
$routeParts = $relativePath === '' ? [] : array_map('urldecode', explode('/', $relativePath));
$selectedCode = '';
// STN-012-015: Two distinct Design context surfaces aligned with the four-class taxonomy:
//   /site-templates/...  → 'templates' selectedView → READ-ONLY inspection of the
//      platform-shipped architectural definition (section structure, guidance, preview).
//      Site Templates are platform-shipped and not editable by the Designer.
//   /page-templates/...  → 'pages' selectedView    → EDITABLE customization of the
//      Designer's editorialized Page Templates (the brand-voice version of each Site
//      Template). Designer edits defaultContent which flows into Real Pages when Content
//      operators create them.
$selectedView = '';
$selectedRef = '';
if ($isTemplateStudioRoute && in_array((string) ($routeParts[0] ?? ''), ['site-templates', 'page-templates'], true)) {
    $selectedView = (string) ($routeParts[0] === 'page-templates' ? 'pages' : 'templates');
    $selectedCode = strtolower(trim((string) ($routeParts[1] ?? '')));
    $selectedRef = trim((string) ($routeParts[2] ?? ''));
} else {
    $selectedCode = strtolower(trim((string) ($routeParts[0] ?? '')));
    $selectedView = strtolower(trim((string) ($routeParts[1] ?? '')));
    $selectedRef = trim((string) ($routeParts[2] ?? ''));
}
$showEnabledOnly = in_array($selectedView, ['templates', 'pages'], true) && $selectedRef === '' && trim((string) ($_GET['enabled'] ?? '')) === '1';

$siteTypes = $entitlementPresentation->visibleSiteTypes(array_values(array_filter(
    $registry->listSiteTypes('primary'),
    static fn (array $siteType): bool => trim((string) ($siteType['code'] ?? '')) !== ''
)));
$siteTypesByCode = [];
foreach ($siteTypes as $siteType) {
    $siteTypesByCode[strtolower((string) ($siteType['code'] ?? ''))] = $siteType;
}

$studioUrl = static function (?string $code = null, ?string $view = null, ?string $ref = null, array $query = []): string {
    $normalizedView = trim((string) $view);
    $path = 'design/template-studio';
    if ($normalizedView === 'templates') {
        $path .= '/site-templates';
    } elseif ($normalizedView === 'pages') {
        $path .= '/page-templates';
    }
    if ($code !== null && trim($code) !== '') {
        $path .= '/' . strtolower(trim($code));
    }
    if ($ref !== null && trim($ref) !== '') {
        $path .= '/' . rawurlencode(trim($ref));
    }

    return myronBuildAdminUrl($path, $query);
};

$templateIdsForSiteType = static function (array $siteType): array {
    $templateIds = [];
    foreach (is_array($siteType['defaultTemplates'] ?? null) ? $siteType['defaultTemplates'] : [] as $templateId) {
        $normalized = trim((string) $templateId);
        if ($normalized !== '') {
            $templateIds[] = $normalized;
        }
    }

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

$optionalTemplateIdsForSiteType = static function (array $siteType): array {
    $templateIds = [];
    foreach (is_array($siteType['optionalTemplates'] ?? null) ? $siteType['optionalTemplates'] : [] as $templateId) {
        $normalized = trim((string) $templateId);
        if ($normalized !== '') {
            $templateIds[] = $normalized;
        }
    }

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

$parentBundleIdsForSubtype = static function (array $siteType): array {
    $parents = [];
    $addParent = static function (mixed $parentBundle) use (&$parents): void {
        $normalized = trim((string) $parentBundle);
        if ($normalized !== '') {
            $parents[$normalized] = true;
        }
    };

    $legacyParent = $siteType['parentBundle'] ?? null;
    if (is_array($legacyParent)) {
        foreach ($legacyParent as $parentBundle) {
            $addParent($parentBundle);
        }
    } else {
        $addParent($legacyParent);
    }

    foreach (is_array($siteType['parentBundles'] ?? null) ? $siteType['parentBundles'] : [] as $parentBundle) {
        $addParent($parentBundle);
    }

    if ($parents === []) {
        $addParent(($siteType['_registry'] ?? [])['parentBundleId'] ?? '');
    }

    return array_keys($parents);
};

$subtypeDisplayName = static function (array $siteType): string {
    $name = trim((string) ($siteType['name'] ?? $siteType['id'] ?? 'Subtype'));
    $name = (string) preg_replace('/\s*\(subtype\)\s*$/i', '', $name);

    return $name !== '' ? $name : 'Subtype';
};

$subtypeTemplateGroupsForSiteType = static function (array $siteType) use (
    $registry,
    $parentBundleIdsForSubtype,
    $subtypeDisplayName
): array {
    $parentBundleId = trim((string) ($siteType['id'] ?? ''));
    if ($parentBundleId === '') {
        return [];
    }

    $groups = [];
    foreach ($registry->listSiteTypes('subtype') as $subtype) {
        if (!in_array($parentBundleId, $parentBundleIdsForSubtype($subtype), true)) {
            continue;
        }

        $templateIds = [];
        foreach (is_array($subtype['defaultTemplates'] ?? null) ? $subtype['defaultTemplates'] : [] as $templateId) {
            $normalized = trim((string) $templateId);
            if ($normalized !== '') {
                $templateIds[] = $normalized;
            }
        }
        $templateIds = array_values(array_unique($templateIds));
        if ($templateIds === []) {
            continue;
        }

        $code = trim((string) ($subtype['code'] ?? ''));
        $groups[] = [
            'id' => trim((string) ($subtype['id'] ?? '')),
            'code' => $code,
            'name' => $subtypeDisplayName($subtype),
            'label' => ($code !== '' ? $code . ' - ' : '') . $subtypeDisplayName($subtype),
            'templateIds' => $templateIds,
        ];
    }

    return $groups;
};

$subtypeTemplateIdsForSiteType = static function (array $siteType) use ($subtypeTemplateGroupsForSiteType): array {
    $templateIds = [];
    foreach ($subtypeTemplateGroupsForSiteType($siteType) as $group) {
        foreach (is_array($group['templateIds'] ?? null) ? $group['templateIds'] : [] as $templateId) {
            $normalized = trim((string) $templateId);
            if ($normalized !== '') {
                $templateIds[] = $normalized;
            }
        }
    }

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

$manageableTemplateIdsForSiteType = static function (array $siteType) use ($templateIdsForSiteType, $optionalTemplateIdsForSiteType, $subtypeTemplateIdsForSiteType): array {
    return array_values(array_unique(array_merge(
        $templateIdsForSiteType($siteType),
        $optionalTemplateIdsForSiteType($siteType),
        $subtypeTemplateIdsForSiteType($siteType)
    )));
};

$allTemplateDefinitions = $templateRepository->listTemplates();
$templateAvailability = $bundleRepository->templateAvailabilityIndex($allTemplateDefinitions);
$selectionState = myronOnboardingStateRepository()->getState();
$selectionManifest = is_array($selectionState['selection_manifest'] ?? null) ? $selectionState['selection_manifest'] : [];
$selectedTemplateLookup = array_fill_keys(array_values(array_map(
    static fn (mixed $templateId): string => trim((string) $templateId),
    is_array($selectionManifest['selected_template_ids'] ?? null) ? $selectionManifest['selected_template_ids'] : []
)), true);
$templateEnabled = static function (string $templateId) use ($selectedTemplateLookup, $templateAvailability): bool {
    $normalized = trim($templateId);
    if ($normalized === '') {
        return false;
    }

    return isset($selectedTemplateLookup[$normalized]) || !empty($templateAvailability[$normalized]['available']);
};

$templateEnabledLabel = static fn (string $templateId): string => $templateEnabled($templateId) ? 'Enabled' : 'Disabled';

$baseSourceTemplateId = static function (string $sourceTemplateId): string {
    $customMarker = '::custom::';
    $markerPosition = strpos($sourceTemplateId, $customMarker);

    return $markerPosition === false ? $sourceTemplateId : substr($sourceTemplateId, 0, $markerPosition);
};

$supportsBlogRail = static function (string $sourceTemplateId) use ($baseSourceTemplateId, $railDesignRepository): bool {
    return $railDesignRepository->supportsTemplate($baseSourceTemplateId($sourceTemplateId));
};

$runtimeSchemaForDefinition = static function (array $definition): array {
    $chrome = MyronTemplateDefinitionRepository::chromeForTemplateRecord($definition);
    $bodySections = MyronTemplateDefinitionRepository::bodySectionsForRecord($definition);
    $schema = [
        'sourceTemplateId' => (string) ($definition['id'] ?? ''),
        'sourceBundleId' => (string) ($definition['bundleId'] ?? ''),
        'chrome' => $chrome,
        'headerCapabilities' => MyronTemplateDefinitionRepository::headerCapabilitiesForTemplateRecord($definition, $chrome),
        'bridge' => [
            'normalizedBodySections' => true,
            'legacyChromeSectionCount' => count(is_array($definition['sections'] ?? null) ? $definition['sections'] : []),
            'bodySectionCount' => count($bodySections),
        ],
        'regions' => [
                ['key' => 'eyebrow', 'label' => 'Eyebrow', 'type' => 'text', 'richtext' => true],
                ['key' => 'headline', 'label' => 'Headline', 'type' => 'text', 'richtext' => true],
                ['key' => 'intro', 'label' => 'Intro', 'type' => 'textarea', 'richtext' => true],
                ['key' => 'body', 'label' => 'Body', 'type' => 'textarea', 'richtext' => true],
                ['key' => 'ctaLabel', 'label' => 'CTA label', 'type' => 'text', 'richtext' => true],
            ['key' => 'ctaHref', 'label' => 'CTA href', 'type' => 'text'],
        ],
        'sections' => $bodySections,
    ];
    if (is_array($definition['blogRail'] ?? null)) {
        $schema['blogRail'] = $definition['blogRail'];
    }

    return $schema;
};

$pageIdentityForTemplate = static function (array $definition): array {
    $sourceTemplateId = (string) ($definition['id'] ?? '');
    $name = trim((string) ($definition['name'] ?? $sourceTemplateId)) ?: $sourceTemplateId;
    $routeMap = [
        'template.blog-index.mkt.v1' => ['Blog', '/blog'],
        'template.post-single.mkt.v1' => ['Post', '/blog/post'],
        'template.resources.mkt.v1' => ['Resources', '/resources'],
        'template.featured-offers.mkt.v1' => ['Featured Offers', '/featured-offers'],
        'template.funnel.squeeze.mkt.v1' => ['Squeeze', '/squeeze'],
        'template.funnel.bridge.mkt.v1' => ['Bridge', '/bridge'],
        'template.funnel.sales-long-form.mkt.v1' => ['Sales', '/sales'],
        'template.funnel.checkout.mkt.v1' => ['Checkout', '/checkout'],
        'template.funnel.upsell.mkt.v1' => ['Upsell', '/upsell'],
        'template.funnel.downsell.mkt.v1' => ['Downsell', '/downsell'],
        'template.funnel.confirmation.mkt.v1' => ['Confirmation', '/confirmation'],
        'template.funnel.expired.mkt.v1' => ['Expired', '/expired'],
        'template.funnel.reverse-squeeze.mkt.v1' => ['Reverse Squeeze', '/reverse-squeeze'],
        'template.funnel.quiz.mkt.v1' => ['Quiz', '/quiz'],
        'template.funnel.vsl.mkt.v1' => ['Video Sales Letter', '/vsl'],
        'template.funnel.application.mkt.v1' => ['Application', '/application'],
        'template.funnel.webinar-registration.mkt.v1' => ['Webinar Registration', '/webinar-registration'],
        'template.funnel.webinar-confirmation.mkt.v1' => ['Webinar Confirmation', '/webinar-confirmation'],
        'template.funnel.webinar-broadcast.mkt.v1' => ['Webinar Broadcast', '/webinar-broadcast'],
        'template.funnel.webinar-replay.mkt.v1' => ['Webinar Replay', '/webinar-replay'],
        'template.funnel.free-plus-shipping-checkout.mkt.v1' => ['Free Plus Shipping Checkout', '/free-plus-shipping-checkout'],
        'template.funnel.summit-hub.mkt.v1' => ['Summit Hub', '/summit-hub'],
        'template.funnel.challenge-enrollment.mkt.v1' => ['Challenge Enrollment', '/challenge-enrollment'],
        'template.funnel.cancellation-retention.mkt.v1' => ['Cancellation Retention', '/cancellation-retention'],
    ];
    $route = trim((string) ($definition['route'] ?? ''));
    $title = trim((string) ($definition['pageTitle'] ?? ''));

    if (isset($routeMap[$sourceTemplateId]) || $route !== '') {
        $mapped = $routeMap[$sourceTemplateId] ?? [$title, $route];
        $resolvedTitle = $title !== '' ? $title : (string) $mapped[0];

        return [
            'title' => $resolvedTitle,
            'path' => myronNormalizePath($route !== '' ? $route : (string) $mapped[1]),
        ];
    }

    $parts = explode('.', $sourceTemplateId);
    $role = (string) ($parts[1] ?? myronNormalizeSlug($name));
    $titleMap = [
        'home' => 'Home',
        'about' => 'About',
        'services' => 'Services',
        'contact' => 'Contact',
        'legal' => 'Legal',
        '404' => '404',
        'search' => 'Search',
        'coming-soon' => 'Coming Soon',
    ];
    $resolvedTitle = $title !== '' ? $title : ($titleMap[$role] ?? ucwords(str_replace('-', ' ', $role)));

    return [
        'title' => $resolvedTitle,
        'path' => $role === 'home' ? '/' : '/' . myronNormalizeSlug($resolvedTitle),
    ];
};

$runtimeTemplateByRef = static function (string $ref) use ($contentRepository): ?array {
    $normalizedRef = trim($ref);
    if ($normalizedRef === '') {
        return null;
    }

    foreach ($contentRepository->listTemplates() as $template) {
        if (
            trim((string) ($template['id'] ?? '')) === $normalizedRef
            || trim((string) ($template['source_template_id'] ?? '')) === $normalizedRef
        ) {
            return $template;
        }
    }

    return null;
};

$customTemplatesForSiteType = static function (array $siteType) use ($contentRepository, $manageableTemplateIdsForSiteType, $baseSourceTemplateId): array {
    $defaultLookup = array_fill_keys($manageableTemplateIdsForSiteType($siteType), true);
    $customTemplates = [];

    foreach ($contentRepository->listTemplates() as $template) {
        $sourceTemplateId = trim((string) ($template['source_template_id'] ?? ''));
        if ($sourceTemplateId === '' || !str_contains($sourceTemplateId, '::custom::')) {
            continue;
        }
        if (!isset($defaultLookup[$baseSourceTemplateId($sourceTemplateId)])) {
            continue;
        }
        $customTemplates[] = $template;
    }

    return $customTemplates;
};

$templateContextForRef = static function (array $siteType, string $ref) use (
    $templateRepository,
    $contentRepository,
    $templateIdsForSiteType,
    $manageableTemplateIdsForSiteType,
    $baseSourceTemplateId,
    $runtimeSchemaForDefinition,
    $runtimeTemplateByRef
): ?array {
    $defaultLookup = array_fill_keys($manageableTemplateIdsForSiteType($siteType), true);
    $duplicableLookup = array_fill_keys($templateIdsForSiteType($siteType), true);
    $runtimeTemplate = $runtimeTemplateByRef($ref);

    if (is_array($runtimeTemplate)) {
        $sourceTemplateId = trim((string) ($runtimeTemplate['source_template_id'] ?? ''));
        $baseTemplateId = $baseSourceTemplateId($sourceTemplateId);
        if (!isset($defaultLookup[$baseTemplateId])) {
            return null;
        }
        $definition = $templateRepository->findTemplateById($baseTemplateId);
        if (!is_array($definition)) {
            return null;
        }
        $schema = is_array($runtimeTemplate['schema'] ?? null) ? $runtimeTemplate['schema'] : $runtimeSchemaForDefinition($definition);

        return [
            'isCustom' => str_contains($sourceTemplateId, '::custom::'),
            'lifecycle' => is_array($runtimeTemplate['template_lifecycle'] ?? null) ? $runtimeTemplate['template_lifecycle'] : [],
            'definition' => $definition,
            'runtimeTemplate' => $runtimeTemplate,
            'sourceTemplateId' => $sourceTemplateId,
            'baseTemplateId' => $baseTemplateId,
            'displayId' => (string) ($runtimeTemplate['id'] ?? $sourceTemplateId),
            'canDuplicate' => isset($duplicableLookup[$baseTemplateId]),
            'name' => trim((string) ($runtimeTemplate['name'] ?? '')) ?: trim((string) ($definition['name'] ?? $baseTemplateId)),
            'schema' => $schema,
            'sections' => array_values(array_filter(
                is_array($schema['sections'] ?? null) ? $schema['sections'] : [],
                static fn (mixed $section): bool => is_array($section)
            )),
            'defaultContent' => is_array($schema['defaultContent'] ?? null) ? $schema['defaultContent'] : [],
        ];
    }

    $templateId = trim($ref);
    if ($templateId === '' || !isset($defaultLookup[$templateId])) {
        return null;
    }
    $definition = $templateRepository->findTemplateById($templateId);
    if (!is_array($definition)) {
        return null;
    }
    $runtimeTemplate = $contentRepository->findRuntimeTemplateBySourceTemplateId($templateId);
    $schema = is_array($runtimeTemplate['schema'] ?? null) ? $runtimeTemplate['schema'] : $runtimeSchemaForDefinition($definition);

    return [
        'isCustom' => false,
        'lifecycle' => is_array($runtimeTemplate['template_lifecycle'] ?? null) ? $runtimeTemplate['template_lifecycle'] : [],
        'definition' => $definition,
        'runtimeTemplate' => $runtimeTemplate,
        'sourceTemplateId' => $templateId,
        'baseTemplateId' => $templateId,
        'displayId' => $templateId,
        'canDuplicate' => isset($duplicableLookup[$templateId]),
        'name' => trim((string) ($definition['name'] ?? $templateId)) ?: $templateId,
        'schema' => $schema,
        'sections' => array_values(array_filter(
            is_array($schema['sections'] ?? null) ? $schema['sections'] : [],
            static fn (mixed $section): bool => is_array($section)
        )),
        'defaultContent' => is_array($schema['defaultContent'] ?? null) ? $schema['defaultContent'] : [],
    ];
};

$contentAuthoredCount = static function (array $content, array $sections): int {
    $sectionContent = is_array($content['sections'] ?? null) ? $content['sections'] : [];
    $count = 0;
    foreach ($sections as $position => $section) {
        if (!is_array($section)) {
            continue;
        }
        $instanceKey = myronSectionInstanceKey($section, (int) $position);
        $values = is_array($sectionContent[$instanceKey] ?? null) ? $sectionContent[$instanceKey] : [];
        if ($values !== []) {
            $count++;
        }
    }

    return $count;
};

// STN-012-015: The studio-page-default seed-record helpers and their accompanying view
// have been removed. They wrote orphan data (no consumer in app/modules/* or app/system/*
// reads bundle_seed_records WHERE seed_type = 'studio-page-default'). The Page Templates
// editor now lives in the single 'templates' view above and writes to
// page_template_versions.schema_json.defaultContent via updateRuntimeTemplateDefaultContent().

$createCustomTemplate = static function (array $definition, string $name) use ($pdo, $runtimeSchemaForDefinition): array {
    $sourceTemplateId = trim((string) ($definition['id'] ?? ''));
    $sourceBundleId = trim((string) ($definition['bundleId'] ?? ''));
    $displayName = trim($name);
    if ($sourceTemplateId === '' || $displayName === '') {
        throw new InvalidArgumentException('A source template and template name are required.');
    }

    $slug = substr(myronNormalizeSlug($displayName), 0, 72) ?: 'custom';
    $candidateSourceTemplateId = $sourceTemplateId . '::custom::' . $slug;
    $counter = 2;
    while (true) {
        $exists = $pdo->prepare('SELECT id FROM page_templates WHERE source_template_id = :source_template_id LIMIT 1');
        $exists->execute([':source_template_id' => $candidateSourceTemplateId]);
        if ($exists->fetchColumn() === false) {
            break;
        }
        $candidateSourceTemplateId = $sourceTemplateId . '::custom::' . $slug . '-' . $counter;
        $counter++;
    }

    $templateId = myronGenerateId('tpl');
    $versionId = myronGenerateId('tplver');
    $now = myronNow();
    $schema = $runtimeSchemaForDefinition($definition);
    $schema['sourceTemplateId'] = $candidateSourceTemplateId;
    $schema['sourceTemplateBaseId'] = $sourceTemplateId;
    $schema['defaultContent'] = [];

    $pdo->beginTransaction();
    try {
        $insertTemplate = $pdo->prepare(
            'INSERT INTO page_templates (
                id, template_key, name, description, source_template_id, source_bundle_id,
                chrome_json, header_capabilities_json, current_version_id, created_at, updated_at
             ) VALUES (
                :id, :template_key, :name, :description, :source_template_id, :source_bundle_id,
                :chrome_json, :header_capabilities_json, :current_version_id, :created_at, :updated_at
             )'
        );
        $insertTemplate->execute([
            ':id' => $templateId,
            ':template_key' => myronNormalizeSlug(str_replace(['template.', '.v1'], ['', ''], $sourceTemplateId)) . '-' . $slug,
            ':name' => $displayName,
            ':description' => 'Custom named template derived from ' . $sourceTemplateId . '.',
            ':source_template_id' => $candidateSourceTemplateId,
            ':source_bundle_id' => $sourceBundleId,
            ':chrome_json' => json_encode($schema['chrome'] ?? [], JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES),
            ':header_capabilities_json' => json_encode($schema['headerCapabilities'] ?? [], JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES),
            ':current_version_id' => $versionId,
            ':created_at' => $now,
            ':updated_at' => $now,
        ]);

        $insertVersion = $pdo->prepare(
            'INSERT INTO page_template_versions (
                id, template_id, version_number, view_name, schema_json, created_at
             ) VALUES (
                :id, :template_id, :version_number, :view_name, :schema_json, :created_at
             )'
        );
        $insertVersion->execute([
            ':id' => $versionId,
            ':template_id' => $templateId,
            ':version_number' => 1,
            ':view_name' => 'default',
            ':schema_json' => json_encode($schema, JSON_THROW_ON_ERROR | JSON_UNESCAPED_SLASHES),
            ':created_at' => $now,
        ]);

        $pdo->commit();
    } catch (Throwable $exception) {
        $pdo->rollBack();
        throw $exception;
    }

    return [
        'id' => $templateId,
        'source_template_id' => $candidateSourceTemplateId,
    ];
};

$previewPageForTemplateContext = static function (array $context, array $contentOverride = []) use ($previewFactory): array {
    $definition = is_array($context['definition'] ?? null) ? $context['definition'] : [];
    $page = $previewFactory->buildPreviewPage($definition);
    $schema = is_array($context['schema'] ?? null) ? $context['schema'] : [];
    $defaultContent = is_array($context['defaultContent'] ?? null) ? $context['defaultContent'] : [];

    if ($schema !== []) {
        $page['template_schema'] = $schema;
    }
    if ($defaultContent !== [] || $contentOverride !== []) {
        $page['content'] = array_replace(
            is_array($page['content'] ?? null) ? $page['content'] : [],
            $defaultContent,
            $contentOverride
        );
    }
    $page['source_template_id'] = (string) ($context['sourceTemplateId'] ?? $page['source_template_id'] ?? '');
    $page['source_bundle_id'] = (string) ($definition['bundleId'] ?? $page['source_bundle_id'] ?? '');

    return $page;
};

$selectedSiteType = $selectedCode !== '' ? ($siteTypesByCode[$selectedCode] ?? null) : null;
$knownView = in_array($selectedView, ['templates', 'pages'], true);
if ($selectedCode !== '' && (!is_array($selectedSiteType) || !$knownView)) {
    http_response_code(404);
}

if ($_SERVER['REQUEST_METHOD'] === 'POST' && !is_array($selectedSiteType)) {
    if (!myronUserCanManageDesign($currentUser)) {
        myronRenderForbidden('Creating Custom Site Templates requires Designer or Administrator access.');
    }
    myronRequireCsrf($_POST['csrf_token'] ?? null);
    $action = trim((string) ($_POST['action'] ?? ''));
    try {
        if ($action === 'create-custom-site-template') {
            $postedSiteTypeCode = strtolower(trim((string) ($_POST['site_type_code'] ?? '')));
            if ($postedSiteTypeCode !== '' && !isset($siteTypesByCode[$postedSiteTypeCode])) {
                throw new InvalidArgumentException('That site type classification is not available for the current license.');
            }
            $callerCtx = myronActionCallerContextForUser($currentUser);
            $created = myronTemplateDuplicationActionService()->createBlank(
                (string) ($_POST['template_name'] ?? ''),
                (string) ($_POST['template_description'] ?? ''),
                $postedSiteTypeCode,
                $callerCtx
            );
            myronRedirectWithFlash(
                myronBuildAdminUrl('design.templatesManager', ['usage' => 'library', 'template' => (string) $created['source_template_id']]),
                'Custom Site Template created.',
                'success'
            );
        }
    } catch (Throwable $exception) {
        myronRedirectWithFlash($studioUrl(), $exception->getMessage(), 'error');
    }
}

if ($_SERVER['REQUEST_METHOD'] === 'POST' && is_array($selectedSiteType) && $knownView) {
    // STN-012-015 AFP: Read access opens the Studio; writes require myronUserCanManageDesign().
    if (!myronUserCanManageDesign($currentUser)) {
        myronRenderForbidden('Editing Page Templates requires Designer or Administrator access.');
    }
    myronRequireCsrf($_POST['csrf_token'] ?? null);
    $action = trim((string) ($_POST['action'] ?? ''));
    $siteTypeCode = (string) ($selectedSiteType['code'] ?? $selectedCode);

    try {
        if ($action === 'duplicate-template') {
            // APO-194 Card 2 — admin form path + POST /api/v1/design/templates/duplicate
            // share MyronTemplateDuplicationActionService::duplicate. The service uses a
            // schema resolver passed in bootstrap; the admin path's gating (template is
            // available for the selected site type) stays here as a pre-call check.
            $sourceTemplateId = trim((string) ($_POST['source_template_id'] ?? ''));
            $definition = $templateRepository->findTemplateById($sourceTemplateId);
            $defaultLookup = array_fill_keys($templateIdsForSiteType($selectedSiteType), true);
            if (!is_array($definition) || !isset($defaultLookup[$sourceTemplateId])) {
                throw new InvalidArgumentException('The source template is not available for this site type.');
            }
            $callerCtx = myronActionCallerContextForUser($currentUser);
            $created = myronTemplateDuplicationActionService()->duplicate($definition, (string) ($_POST['template_name'] ?? ''), $callerCtx);
            myronRedirectWithFlash(
                $studioUrl($siteTypeCode, 'templates', (string) $created['id']),
                'Custom template created.',
                'success'
            );
        }

        if ($action === 'make-custom-template-available') {
            $templateRef = trim((string) ($_POST['template_ref'] ?? $selectedRef));
            $context = $templateContextForRef($selectedSiteType, $templateRef);
            if (!is_array($context) || empty($context['isCustom']) || !is_array($context['runtimeTemplate'] ?? null)) {
                throw new InvalidArgumentException('Choose a valid Custom Site Template.');
            }
            $callerCtx = myronActionCallerContextForUser($currentUser);
            myronTemplateDuplicationActionService()->makeAvailableAsPageTemplate((string) $context['runtimeTemplate']['id'], $callerCtx);
            myronRedirectWithFlash(
                $studioUrl($siteTypeCode, 'templates', $templateRef),
                'Custom Site Template is now available as a Page Template.',
                'success'
            );
        }

        if ($action === 'update-template-chrome-assignment') {
            if ($selectedView !== 'pages') {
                throw new InvalidArgumentException('Chrome assignments are managed from the Page Templates surface.');
            }
            $templateRef = trim((string) ($_POST['template_ref'] ?? $selectedRef));
            $context = $templateContextForRef($selectedSiteType, $templateRef);
            if (!is_array($context)) {
                throw new InvalidArgumentException('The selected Page Template could not be found.');
            }
            $sourceTemplateId = trim((string) ($context['sourceTemplateId'] ?? ''));
            if ($sourceTemplateId === '') {
                throw new InvalidArgumentException('The selected Page Template is missing a source template id.');
            }

            $navigationDesignId = trim((string) ($_POST['navigation_design_id'] ?? ''));
            $footerVariantId = trim((string) ($_POST['footer_variant_id'] ?? ''));
            $chromeAssignmentRepository->setForTemplate($sourceTemplateId, [
                'navigation_design_id' => $navigationDesignId,
                'footer_variant_id' => in_array($footerVariantId, ['inherit_site', 'inherit_seed', 'inherit'], true) ? null : $footerVariantId,
            ], (string) ($currentUser['id'] ?? ''));
            myronRedirectWithFlash(
                $studioUrl($siteTypeCode, 'pages', $templateRef),
                'Updated Chrome Assignment.',
                'success'
            );
        }

        if ($action === 'update-template-section-content') {
            $templateRef = trim((string) ($_POST['template_ref'] ?? $selectedRef));
            $context = $templateContextForRef($selectedSiteType, $templateRef);
            if (!is_array($context)) {
                throw new InvalidArgumentException('The selected template could not be found.');
            }
            $runtimeTemplate = is_array($context['runtimeTemplate'] ?? null) ? $context['runtimeTemplate'] : null;
            if (!is_array($runtimeTemplate)) {
                $runtimeTemplate = myronTemplateInstantiationService()->instantiateTemplate((array) $context['definition']);
            }
            $content = myronContentPayloadFromInput($_POST, (array) $context['sections']);
            $contentRepository->updateRuntimeTemplateDefaultContent((string) $runtimeTemplate['id'], $content);
            // STN-012-015: defaultContent editing is the Page Templates surface — redirect there.
            myronRedirectWithFlash(
                $studioUrl($siteTypeCode, 'pages', $templateRef),
                'Page Template content saved.',
                'success'
            );
        }

        if ($action === 'update-template-blog-rail') {
            if ($selectedView !== 'pages') {
                throw new InvalidArgumentException('Blog rail placement is managed from the Page Templates surface.');
            }
            $templateRef = trim((string) ($_POST['template_ref'] ?? $selectedRef));
            $context = $templateContextForRef($selectedSiteType, $templateRef);
            if (!is_array($context)) {
                throw new InvalidArgumentException('The selected Page Template could not be found.');
            }
            $sourceTemplateId = trim((string) ($context['sourceTemplateId'] ?? ''));
            if (!$supportsBlogRail($sourceTemplateId)) {
                throw new InvalidArgumentException('This Page Template does not support a blog rail.');
            }
            $runtimeTemplate = is_array($context['runtimeTemplate'] ?? null) ? $context['runtimeTemplate'] : null;
            if (!is_array($runtimeTemplate)) {
                $runtimeTemplate = myronTemplateInstantiationService()->instantiateTemplate((array) $context['definition']);
            }
            $contentRepository->updateRuntimeTemplateBlogRailPlacement(
                (string) ($runtimeTemplate['id'] ?? ''),
                (string) ($_POST['blog_rail_placement'] ?? 'right')
            );
            myronRedirectWithFlash(
                $studioUrl($siteTypeCode, 'pages', $templateRef),
                'Blog rail placement updated.',
                'success'
            );
        }

        // STN-012-015: The orphan 'update-page-section-content' action handler that wrote to
        // bundle_seed_records was removed in favor of the unified 'update-template-section-content'
        // handler above, which writes to the four-class storage at
        // page_template_versions.schema_json.defaultContent.
    } catch (Throwable $exception) {
        myronRedirectWithFlash(
            $studioUrl($siteTypeCode, $selectedView, $selectedRef !== '' ? $selectedRef : null),
            $exception->getMessage(),
            'error'
        );
    }
}

$title = is_array($selectedSiteType)
    ? MyronSiteTypeRegistryRepository::displayLabelForSiteType($selectedSiteType) . ' Template Studio'
    : 'Template Studio';
// STN-012-015: Two distinct Design context surfaces — Site Templates (architectural,
// read-only) and Page Templates (editorial, Designer-editable). Index chrome reflects which
// surface is active.
$activeItem = $selectedView === 'pages' ? 'template-studio-page-templates' : 'template-studio-site-templates';
$indexTitle = $selectedView === 'pages' ? 'Page Templates' : 'Site Templates';
$indexSubtitle = $selectedView === 'pages'
    ? 'Customize the editorial content of page templates that content operators will use to create new pages.'
    : 'Inspect the platform-shipped architectural definition of each template — section structure, design notes, editorial intent.';

myronRenderAdminShellStart($currentUser, [
    'title' => $title,
    'titleContext' => 'Template Studio',
    'activeItem' => $activeItem,
]);
?>
<div class="mc-workspace__header">
  <?php
    $templateStudioHref = $selectedView === 'pages'
        ? myronBuildAdminUrl('design.templateStudioPageTemplates')
        : myronBuildAdminUrl('design.templateStudioSiteTemplates');
    $templateStudioCrumbs = [
        ['label' => 'Design', 'href' => myronBuildAdminUrl('design.primitives')],
        ['label' => 'Template Studio', 'href' => $templateStudioHref],
    ];
    if (is_array($selectedSiteType)) {
        $templateStudioCrumbs[] = [
            'label' => MyronSiteTypeRegistryRepository::displayLabelForSiteType($selectedSiteType),
            'href' => $knownView ? $studioUrl($siteTypeCode ?? $selectedCode, $selectedView) : '',
        ];
        if ($knownView) {
            $templateStudioCrumbs[] = ['label' => $selectedView === 'pages' ? 'Page Templates' : 'Site Templates'];
        }
    } else {
        $templateStudioCrumbs[] = ['label' => $indexTitle];
    }
    myronRenderAdminBreadcrumbs($templateStudioCrumbs);
  ?>
  <div class="mc-workspace__title-row">
    <h1 class="mc-workspace__title"><?= myronEscape(is_array($selectedSiteType) ? MyronSiteTypeRegistryRepository::displayLabelForSiteType($selectedSiteType) : 'Template Studio') ?></h1>
  </div>
  <p class="mc-workspace__subtitle"><?= $selectedView === 'pages'
      ? 'Customize the editorial content of page templates that content operators will use to create new pages.'
      : 'Inspect the platform-shipped architectural definition of each template — section structure, design notes, editorial intent.' ?></p>
</div>

<div class="mc-page-canvas mc-page-canvas--site">
  <div class="sg-main">
    <?php if (!is_array($selectedSiteType)): ?>
      <?php if ($selectedCode !== ''): ?>
      <div class="sg-status sg-status--error" role="status">The requested site type could not be found.</div>
      <?php endif; ?>
      <section class="sg-section" aria-labelledby="template-studio-index-title">
        <div class="sg-section__header">
          <h2 class="sg-section__title" id="template-studio-index-title"><?= myronEscape($indexTitle) ?></h2>
          <p class="sg-section__subtitle"><?= myronEscape($indexSubtitle) ?></p>
        </div>
        <?php if ($selectedView !== 'pages'): ?>
        <?php
          $customSiteTemplates = $contentRepository->listCustomSiteTemplates();
          ob_start();
        ?>
        <form class="sg-form-grid" method="post">
          <input type="hidden" name="csrf_token" value="<?= myronEscape(myronCsrfToken()) ?>">
          <input type="hidden" name="action" value="create-custom-site-template">
          <label class="sg-field">
            <span class="sg-field__label">Template name</span>
            <input class="sg-field__control" type="text" name="template_name" required>
          </label>
          <label class="sg-field">
            <span class="sg-field__label">Site type classification</span>
            <select class="sg-field__control" name="site_type_code">
              <option value="">Custom</option>
              <?php foreach ($siteTypes as $siteType): ?>
              <?php $code = (string) ($siteType['code'] ?? ''); ?>
              <option value="<?= myronEscape($code) ?>"><?= myronEscape(MyronSiteTypeRegistryRepository::displayLabelForSiteType($siteType)) ?></option>
              <?php endforeach; ?>
            </select>
          </label>
          <label class="sg-field sg-field--full">
            <span class="sg-field__label">Description</span>
            <textarea class="sg-field__control" name="template_description" rows="4"></textarea>
          </label>
          <button class="sg-button sg-button--primary" type="submit">Create Custom Site Template</button>
        </form>
        <?php $createCustomSiteTemplateBody = (string) ob_get_clean(); ?>
        <div class="sg-section__header">
          <h3 class="sg-section__title">Custom Site Templates</h3>
          <p class="sg-section__subtitle">Operator-owned architectural templates. Duplicate a packaged Site Template or create one from scratch, then make it available as a Page Template when it is ready for design defaults and Content page creation.</p>
        </div>
        <div class="mc-editor-toolbar">
          <div class="mc-editor-toolbar__summary">
            <span class="sg-pill"><?= myronEscape((string) count($customSiteTemplates)) ?> custom templates</span>
          </div>
          <div class="mc-editor-toolbar__actions">
            <button class="sg-button sg-button--secondary" type="button" data-mc-sidesheet-open="create-custom-site-template-sheet">Create Custom Site Template</button>
          </div>
        </div>
        <div class="mc-page-grid mc-page-grid--studio-template-list" role="table" aria-label="Custom Site Templates" data-myron-custom-site-template-list>
          <div class="mc-page-grid__row mc-page-grid__row--head" role="row">
            <span role="columnheader">Template Name</span>
            <span role="columnheader">Source</span>
            <span role="columnheader">Sections</span>
            <span role="columnheader">Page Template</span>
            <span role="columnheader">Actions</span>
          </div>
          <?php if ($customSiteTemplates === []): ?>
          <div class="mc-page-grid__row" role="row">
            <span class="mc-page-grid__cell" role="cell">No custom Site Templates yet. Duplicate a packaged template or create one from scratch.</span>
            <span class="mc-page-grid__cell" role="cell">-</span>
            <span class="mc-page-grid__cell" role="cell">-</span>
            <span class="mc-page-grid__cell" role="cell">Not available</span>
            <span class="mc-page-grid__cell" role="cell">-</span>
          </div>
          <?php endif; ?>
          <?php foreach ($customSiteTemplates as $template): ?>
          <?php
            $schema = is_array($template['schema'] ?? null) ? $template['schema'] : [];
            $lifecycle = is_array($template['template_lifecycle'] ?? null) ? $template['template_lifecycle'] : [];
            $sourceTemplateId = (string) ($template['source_template_id'] ?? '');
            $sections = array_values(array_filter(is_array($schema['sections'] ?? null) ? $schema['sections'] : [], 'is_array'));
          ?>
          <div class="mc-page-grid__row" role="row">
            <span class="mc-page-grid__cell mc-page-grid__cell--name" role="cell">
              <span class="mc-page-grid__name"><?= myronEscape((string) ($template['name'] ?? $sourceTemplateId)) ?></span>
              <span class="mc-page-grid__subtle"><code><?= myronEscape($sourceTemplateId) ?></code></span>
            </span>
            <span class="mc-page-grid__cell" role="cell"><?= myronEscape((string) ($lifecycle['createdFrom'] ?? 'custom')) ?></span>
            <span class="mc-page-grid__cell" role="cell"><span class="sg-pill"><?= myronEscape((string) count($sections)) ?> sections</span></span>
            <span class="mc-page-grid__cell" role="cell"><span class="sg-pill <?= !empty($lifecycle['availableAsPageTemplate']) ? 'sg-pill--active' : 'sg-pill--secondary' ?>"><?= !empty($lifecycle['availableAsPageTemplate']) ? 'Available' : 'Not available' ?></span></span>
            <span class="mc-page-grid__cell mc-page-grid__cell--actions" role="cell">
              <a class="sg-button sg-button--secondary" href="<?= myronEscape(myronBuildAdminUrl('design.templatesManager', ['usage' => 'library', 'template' => $sourceTemplateId])) ?>">Manage Architecture</a>
            </span>
          </div>
          <?php endforeach; ?>
        </div>
        <?php myronRenderAdminSidesheet('create-custom-site-template-sheet', 'Create Custom Site Template', $createCustomSiteTemplateBody, ['size' => 'md']); ?>
        <?php endif; ?>
        <div class="mc-page-grid mc-page-grid--site-type-studio" role="table" aria-label="Template Studio site types" data-myron-template-studio-index data-myron-site-type-studio-index>
          <div class="mc-page-grid__row mc-page-grid__row--head" role="row">
            <span role="columnheader">Site Type</span>
            <span role="columnheader">Code</span>
            <span role="columnheader">Bundle Description</span>
            <span role="columnheader">Defaults</span>
            <span role="columnheader">Enabled</span>
            <span role="columnheader">Actions</span>
          </div>
          <?php foreach ($siteTypes as $siteType): ?>
          <?php
            $code = (string) ($siteType['code'] ?? '');
            $label = MyronSiteTypeRegistryRepository::displayLabelForSiteType($siteType);
            $description = trim((string) ($siteType['description'] ?? ''));
            $templateCount = count($templateIdsForSiteType($siteType));
            $enabledCount = count(array_values(array_filter(
                $manageableTemplateIdsForSiteType($siteType),
                static fn (string $templateId): bool => $templateEnabled($templateId)
            )));
          ?>
          <div class="mc-page-grid__row" role="row" data-site-type-code="<?= myronEscape($code) ?>">
            <span class="mc-page-grid__cell mc-page-grid__cell--name" role="cell">
              <span class="mc-page-grid__name"><?= myronEscape($label) ?></span>
              <span class="mc-page-grid__subtle"><?= myronEscape((string) ($siteType['name'] ?? $label)) ?></span>
            </span>
            <span class="mc-page-grid__cell" role="cell"><code><?= myronEscape($code) ?></code></span>
            <span class="mc-page-grid__cell" role="cell"><?= myronEscape($description !== '' ? $description : 'No description available.') ?></span>
            <span class="mc-page-grid__cell" role="cell"><span class="sg-pill"><?= myronEscape((string) $templateCount) ?> defaults</span></span>
            <span class="mc-page-grid__cell" role="cell"><span class="sg-pill"><?= myronEscape((string) $enabledCount) ?> enabled</span></span>
            <span class="mc-page-grid__cell mc-page-grid__cell--actions" role="cell">
              <a class="sg-button sg-button--secondary" href="<?= myronEscape($studioUrl($code, $selectedView !== '' ? $selectedView : 'templates')) ?>">Manage</a>
            </span>
          </div>
          <?php endforeach; ?>
        </div>
      </section>
    <?php else: ?>
      <?php
        $siteTypeCode = (string) ($selectedSiteType['code'] ?? $selectedCode);
        $siteTypeLabel = MyronSiteTypeRegistryRepository::displayLabelForSiteType($selectedSiteType);
        $templateIds = $templateIdsForSiteType($selectedSiteType);
        $optionalTemplateIds = $optionalTemplateIdsForSiteType($selectedSiteType);
        $subtypeTemplateGroups = $subtypeTemplateGroupsForSiteType($selectedSiteType);
        $subtypeTemplateCount = count($subtypeTemplateIdsForSiteType($selectedSiteType));
        $customTemplates = $customTemplatesForSiteType($selectedSiteType);
        if ($selectedView === 'pages') {
            $customTemplates = array_values(array_filter(
                $customTemplates,
                static fn (array $template): bool => (bool) ($template['is_available_page_template'] ?? true)
            ));
        }
        $enabledTemplateRows = [];
        foreach ($templateIds as $templateId) {
            if ($templateEnabled($templateId)) {
                $enabledTemplateRows[] = ['id' => $templateId, 'source' => 'Default'];
            }
        }
        foreach ($optionalTemplateIds as $templateId) {
            if ($templateEnabled($templateId)) {
                $enabledTemplateRows[] = ['id' => $templateId, 'source' => 'Optional'];
            }
        }
        foreach ($subtypeTemplateGroups as $subtypeGroup) {
            foreach (is_array($subtypeGroup['templateIds'] ?? null) ? $subtypeGroup['templateIds'] : [] as $templateId) {
                $templateId = (string) $templateId;
                if ($templateEnabled($templateId)) {
                    $enabledTemplateRows[] = [
                        'id' => $templateId,
                        'source' => 'Subtype' . (trim((string) ($subtypeGroup['code'] ?? '')) !== '' ? ': ' . (string) $subtypeGroup['code'] : ''),
                    ];
                }
            }
        }
        foreach ($customTemplates as $template) {
            $templateId = (string) ($template['id'] ?? '');
            if ($templateId !== '' && $templateEnabled($templateId)) {
                $enabledTemplateRows[] = ['id' => $templateId, 'source' => 'Custom'];
            }
        }
      ?>
      <section class="sg-section" aria-label="Template Studio controls">
        <div class="mc-editor-toolbar">
          <div class="mc-editor-toolbar__summary">
            <span class="sg-pill"><?= myronEscape($siteTypeLabel) ?></span>
            <span class="mc-editor-toolbar__meta"><?= myronEscape((string) count($templateIds)) ?> default templates</span>
            <?php if ($optionalTemplateIds !== []): ?>
            <span class="mc-editor-toolbar__meta"><?= myronEscape((string) count($optionalTemplateIds)) ?> optional templates</span>
            <?php endif; ?>
            <?php if ($subtypeTemplateCount > 0): ?>
            <span class="mc-editor-toolbar__meta"><?= myronEscape((string) $subtypeTemplateCount) ?> subtype templates</span>
            <?php endif; ?>
          </div>
          <div class="mc-editor-toolbar__actions">
            <?php
              // STN-012-020 hotfix: surface nav buttons removed from the toolbar. Both surfaces
              // are already labelled in the page heading and breadcrumbs, and there are clear
              // sidebar menu items for switching between Site Templates and Page Templates.
              // The toolbar now focuses on per-surface actions (filters, back-link, etc.).
            ?>
            <?php if ($selectedRef === '' && in_array($selectedView, ['templates', 'pages'], true)): ?>
            <?php
              // STN-012-020 hotfix: button text disambiguates the filter target by surface
              // ("Site Templates" vs "Page Templates"), e.g. "View Enabled Agency Site Templates".
              $toggleFriendlyLabel = MyronSiteTypeRegistryRepository::friendlyLabelForCode($siteTypeCode);
              $toggleSurfaceWord = $selectedView === 'pages' ? 'Page' : 'Site';
              $toggleHref = $showEnabledOnly
                  ? $studioUrl($siteTypeCode, $selectedView)
                  : $studioUrl($siteTypeCode, $selectedView, null, ['enabled' => '1']);
              $toggleLabel = $showEnabledOnly
                  ? 'View All ' . $toggleFriendlyLabel . ' ' . $toggleSurfaceWord . ' Templates'
                  : 'View Enabled ' . $toggleFriendlyLabel . ' ' . $toggleSurfaceWord . ' Templates';
            ?>
            <a class="sg-button <?= $showEnabledOnly ? 'sg-button--primary' : 'sg-button--secondary' ?>" href="<?= myronEscape($toggleHref) ?>"><?= myronEscape($toggleLabel) ?></a>
            <?php endif; ?>
            <a class="sg-button sg-button--secondary" href="<?= myronEscape($selectedRef === '' ? $studioUrl() : $studioUrl($siteTypeCode, $selectedView)) ?>">Back to <?= $selectedRef === '' ? 'Site Types' : ($selectedView === 'pages' ? 'Page Templates' : 'Site Templates') ?></a>
          </div>
        </div>
      </section>

      <?php if (in_array($selectedView, ['templates', 'pages'], true) && $selectedRef === ''): ?>
      <section class="sg-section" data-myron-site-type-studio-templates>
        <div class="sg-section__header">
          <h2 class="sg-section__title"><?= myronEscape($siteTypeLabel) ?> <?= $selectedView === 'pages' ? 'Page Templates' : 'Site Templates' ?></h2>
          <p class="sg-section__subtitle"><?= $selectedView === 'pages'
              ? 'Customize the editorial content of each page template — these are what content operators select when creating new pages.'
              : 'Inspect the platform-shipped architectural definition of each template.' ?></p>
        </div>
        <?php if ($showEnabledOnly): ?>
        <div class="mc-page-grid mc-page-grid--studio-template-list" role="table" aria-label="Enabled Page Templates" data-myron-template-studio-enabled-list>
          <div class="mc-page-grid__row mc-page-grid__row--head" role="row">
            <span role="columnheader">Template Name</span>
            <span role="columnheader">Template ID</span>
            <span role="columnheader">Source</span>
            <span role="columnheader">Enabled</span>
            <span role="columnheader">Action</span>
          </div>
          <?php if ($enabledTemplateRows === []): ?>
          <div class="mc-page-grid__row" role="row">
            <span class="mc-page-grid__cell" role="cell">No enabled templates found for this site type.</span>
            <span class="mc-page-grid__cell" role="cell">-</span>
            <span class="mc-page-grid__cell" role="cell">-</span>
            <span class="mc-page-grid__cell" role="cell">Disabled</span>
            <span class="mc-page-grid__cell" role="cell">-</span>
          </div>
          <?php endif; ?>
          <?php foreach ($enabledTemplateRows as $enabledTemplate): ?>
          <?php
            $templateId = (string) ($enabledTemplate['id'] ?? '');
            $context = $templateContextForRef($selectedSiteType, $templateId);
            if (!is_array($context)) {
                continue;
            }
          ?>
          <div class="mc-page-grid__row" role="row">
            <span class="mc-page-grid__cell mc-page-grid__cell--name" role="cell"><span class="mc-page-grid__name"><?= myronEscape((string) $context['name']) ?></span></span>
            <span class="mc-page-grid__cell" role="cell"><code><?= myronEscape($templateId) ?></code></span>
            <span class="mc-page-grid__cell" role="cell"><?= myronEscape((string) ($enabledTemplate['source'] ?? 'Template')) ?></span>
            <span class="mc-page-grid__cell" role="cell"><span class="sg-pill"><?= myronEscape($templateEnabledLabel($templateId)) ?></span></span>
            <span class="mc-page-grid__cell mc-page-grid__cell--actions" role="cell"><a class="sg-button sg-button--secondary" href="<?= myronEscape($studioUrl($siteTypeCode, $selectedView, $templateId)) ?>"><?= $selectedView === 'pages' ? 'Customize' : 'Inspect' ?></a></span>
          </div>
          <?php endforeach; ?>
        </div>
        <?php else: ?>
        <div class="mc-page-grid mc-page-grid--studio-template-list" role="table" aria-label="Default Templates" data-myron-site-type-studio-template-table="default">
          <div class="mc-page-grid__row mc-page-grid__row--head" role="row">
            <span role="columnheader">Template Name</span>
            <span role="columnheader">Template ID</span>
            <span role="columnheader">Section Count</span>
            <span role="columnheader">Enabled</span>
            <span role="columnheader">Action</span>
          </div>
          <?php foreach ($templateIds as $templateId): ?>
          <?php
            $context = $templateContextForRef($selectedSiteType, $templateId);
            if (!is_array($context)) {
                continue;
            }
          ?>
          <div class="mc-page-grid__row" role="row">
            <span class="mc-page-grid__cell mc-page-grid__cell--name" role="cell"><span class="mc-page-grid__name"><?= myronEscape((string) $context['name']) ?></span></span>
            <span class="mc-page-grid__cell" role="cell"><code><?= myronEscape($templateId) ?></code></span>
            <span class="mc-page-grid__cell" role="cell"><span class="sg-pill"><?= myronEscape((string) count((array) $context['sections'])) ?> sections</span></span>
            <span class="mc-page-grid__cell" role="cell"><span class="sg-pill"><?= myronEscape($templateEnabledLabel($templateId)) ?></span></span>
            <span class="mc-page-grid__cell mc-page-grid__cell--actions" role="cell"><a class="sg-button sg-button--secondary" href="<?= myronEscape($studioUrl($siteTypeCode, $selectedView, $templateId)) ?>"><?= $selectedView === 'pages' ? 'Customize' : 'Inspect' ?></a></span>
          </div>
          <?php endforeach; ?>
        </div>
        <?php if ($optionalTemplateIds !== []): ?>
        <div class="sg-section__header">
          <h3 class="sg-section__title">Optional Templates</h3>
          <p class="sg-section__subtitle">Supported by this site type but not included in the default bootstrap. Activate in Site Setup to add to your site.</p>
        </div>
        <div class="mc-page-grid mc-page-grid--studio-template-list" role="table" aria-label="Optional Templates" data-myron-site-type-studio-template-table="optional">
          <div class="mc-page-grid__row mc-page-grid__row--head" role="row">
            <span role="columnheader">Template Name</span>
            <span role="columnheader">Template ID</span>
            <span role="columnheader">Section Count</span>
            <span role="columnheader">Enabled</span>
            <span role="columnheader">Action</span>
          </div>
          <?php foreach ($optionalTemplateIds as $templateId): ?>
          <?php
            $context = $templateContextForRef($selectedSiteType, $templateId);
            if (!is_array($context)) {
                continue;
            }
          ?>
          <div class="mc-page-grid__row" role="row">
            <span class="mc-page-grid__cell mc-page-grid__cell--name" role="cell"><span class="mc-page-grid__name"><?= myronEscape((string) $context['name']) ?></span></span>
            <span class="mc-page-grid__cell" role="cell"><code><?= myronEscape($templateId) ?></code></span>
            <span class="mc-page-grid__cell" role="cell"><span class="sg-pill"><?= myronEscape((string) count((array) $context['sections'])) ?> sections</span></span>
            <span class="mc-page-grid__cell" role="cell"><span class="sg-pill"><?= myronEscape($templateEnabledLabel($templateId)) ?></span></span>
            <span class="mc-page-grid__cell mc-page-grid__cell--actions" role="cell"><a class="sg-button sg-button--secondary" href="<?= myronEscape($studioUrl($siteTypeCode, $selectedView, $templateId)) ?>"><?= $selectedView === 'pages' ? 'Customize' : 'Inspect' ?></a></span>
          </div>
          <?php endforeach; ?>
        </div>
        <?php endif; ?>
        <?php if ($subtypeTemplateGroups !== []): ?>
        <div class="sg-section__header">
          <h3 class="sg-section__title">Subtype Templates</h3>
          <p class="sg-section__subtitle">Templates supplied by subtype bundles associated with this site type.</p>
        </div>
        <?php foreach ($subtypeTemplateGroups as $subtypeGroup): ?>
        <div class="sg-section__header">
          <h4 class="sg-section__title"><?= myronEscape((string) ($subtypeGroup['label'] ?? 'Subtype')) ?></h4>
        </div>
        <div class="mc-page-grid mc-page-grid--studio-template-list" role="table" aria-label="Subtype Templates - <?= myronEscape((string) ($subtypeGroup['label'] ?? 'Subtype')) ?>" data-myron-site-type-studio-template-table="subtype" data-myron-site-type-studio-subtype="<?= myronEscape((string) ($subtypeGroup['code'] ?? '')) ?>">
          <div class="mc-page-grid__row mc-page-grid__row--head" role="row">
            <span role="columnheader">Template Name</span>
            <span role="columnheader">Template ID</span>
            <span role="columnheader">Section Count</span>
            <span role="columnheader">Enabled</span>
            <span role="columnheader">Action</span>
          </div>
          <?php foreach (is_array($subtypeGroup['templateIds'] ?? null) ? $subtypeGroup['templateIds'] : [] as $templateId): ?>
          <?php
            $context = $templateContextForRef($selectedSiteType, (string) $templateId);
            if (!is_array($context)) {
                continue;
            }
          ?>
          <div class="mc-page-grid__row" role="row">
            <span class="mc-page-grid__cell mc-page-grid__cell--name" role="cell"><span class="mc-page-grid__name"><?= myronEscape((string) $context['name']) ?></span></span>
            <span class="mc-page-grid__cell" role="cell"><code><?= myronEscape((string) $templateId) ?></code></span>
            <span class="mc-page-grid__cell" role="cell"><span class="sg-pill"><?= myronEscape((string) count((array) $context['sections'])) ?> sections</span></span>
            <span class="mc-page-grid__cell" role="cell"><span class="sg-pill"><?= myronEscape($templateEnabledLabel((string) $templateId)) ?></span></span>
            <span class="mc-page-grid__cell mc-page-grid__cell--actions" role="cell"><a class="sg-button sg-button--secondary" href="<?= myronEscape($studioUrl($siteTypeCode, $selectedView, (string) $templateId)) ?>"><?= $selectedView === 'pages' ? 'Customize' : 'Inspect' ?></a></span>
          </div>
          <?php endforeach; ?>
        </div>
        <?php endforeach; ?>
        <?php endif; ?>
        <div class="sg-section__header">
          <h3 class="sg-section__title">Custom Site Templates</h3>
          <p class="sg-section__subtitle"><?= $selectedView === 'pages'
              ? 'Custom Site Templates that have been made available as Page Templates.'
              : 'Operator-owned architectural templates derived from this site type.' ?></p>
        </div>
        <div class="mc-page-grid mc-page-grid--studio-template-list" role="table" aria-label="Custom Site Templates" data-myron-site-type-studio-template-table="custom">
          <div class="mc-page-grid__row mc-page-grid__row--head" role="row">
            <span role="columnheader">Template Name</span>
            <span role="columnheader">Template ID</span>
            <span role="columnheader">Section Count</span>
            <span role="columnheader">Page Template</span>
            <span role="columnheader">Action</span>
          </div>
          <?php if ($customTemplates === []): ?>
          <div class="mc-page-grid__row" role="row"><span class="mc-page-grid__cell" role="cell"><?= $selectedView === 'pages'
              ? 'No custom Site Templates have been made available as Page Templates yet.'
              : 'No custom Site Templates yet. Use Inspect > Duplicate as Custom Site Template on any default template, or create one from the main Site Templates view.' ?></span></div>
          <?php endif; ?>
          <?php foreach ($customTemplates as $template): ?>
          <?php
            $schema = is_array($template['schema'] ?? null) ? $template['schema'] : [];
            $sections = is_array($schema['sections'] ?? null) ? $schema['sections'] : [];
            $templateId = (string) ($template['id'] ?? '');
            $lifecycle = is_array($template['template_lifecycle'] ?? null) ? $template['template_lifecycle'] : [];
            $availableAsPageTemplate = (bool) ($lifecycle['availableAsPageTemplate'] ?? true);
          ?>
          <div class="mc-page-grid__row" role="row">
            <span class="mc-page-grid__cell mc-page-grid__cell--name" role="cell"><span class="mc-page-grid__name"><?= myronEscape((string) ($template['name'] ?? $templateId)) ?></span></span>
            <span class="mc-page-grid__cell" role="cell"><code><?= myronEscape($templateId) ?></code></span>
            <span class="mc-page-grid__cell" role="cell"><span class="sg-pill"><?= myronEscape((string) count($sections)) ?> sections</span></span>
            <span class="mc-page-grid__cell" role="cell"><span class="sg-pill <?= $availableAsPageTemplate ? 'sg-pill--active' : 'sg-pill--secondary' ?>"><?= $availableAsPageTemplate ? 'Available' : 'Not available' ?></span></span>
            <span class="mc-page-grid__cell mc-page-grid__cell--actions" role="cell"><a class="sg-button sg-button--secondary" href="<?= myronEscape($studioUrl($siteTypeCode, $selectedView, $templateId)) ?>"><?= $selectedView === 'pages' ? 'Customize' : 'Manage' ?></a></span>
          </div>
          <?php endforeach; ?>
        </div>
        <?php endif; ?>
      </section>
      <?php elseif (in_array($selectedView, ['templates', 'pages'], true)): ?>
      <?php
        // STN-012-015: Detail view serves both Site Templates (read-only inspection) and
        // Page Templates (Designer-editable customization). Conditional toolbar buttons,
        // sidesheets, and subtitle copy reflect the difference; the shared rendering of
        // Template Details + Architectural Guidance + Preview lives in both surfaces.
        $context = $templateContextForRef($selectedSiteType, $selectedRef);
        if (!is_array($context)) {
            http_response_code(404);
        }
      ?>
      <?php if (is_array($context)): ?>
      <?php
        $sections = (array) $context['sections'];
        $defaultContent = (array) $context['defaultContent'];
        $lifecycle = is_array($context['lifecycle'] ?? null) ? $context['lifecycle'] : [];
        $isCustomSiteTemplate = !empty($context['isCustom']) && (($lifecycle['kind'] ?? '') === 'custom_site_template');
        $isAvailablePageTemplate = (bool) ($lifecycle['availableAsPageTemplate'] ?? false);
        $authoredCount = $contentAuthoredCount($defaultContent, $sections);
        $unsetCount = max(0, count($sections) - $authoredCount);
        $page = $previewPageForTemplateContext($context);
        $blogRailSupported = $supportsBlogRail((string) ($context['sourceTemplateId'] ?? ''));
        $blogRailSourceTemplateId = $baseSourceTemplateId((string) ($context['sourceTemplateId'] ?? ''));
        $blogRail = is_array($context['schema']['blogRail'] ?? null) ? $context['schema']['blogRail'] : [];
        $resolvedBlogRail = $blogRailSupported ? $railDesignRepository->resolveForTemplate($blogRailSourceTemplateId, is_array($context['schema'] ?? null) ? $context['schema'] : []) : [];
        $blogRailPlacement = (string) ($resolvedBlogRail['placement'] ?? myronNormalizeSlug((string) ($blogRail['placement'] ?? 'right')));
        $blogRailName = (string) ($resolvedBlogRail['rail_name'] ?? 'Standard Blog Rail');
        $blogRailSource = (string) ($resolvedBlogRail['source'] ?? 'legacy-blogRail');

        // Section Content editor body (used only on Page Templates / 'pages' view).
        // STN-012-015: Use the EditorSurfaceReadModel templateSurface to render the same
        // editableFields shape the operator-side page editor uses — giving the Designer
        // parity with what a Content operator sees. Each section exposes its full set
        // of editable fields (eyebrow, headline, intro, body, ctaLabel, ctaHref + any
        // section-specific fields like image or repeatable items), backed by the section
        // content schema service.
        $sectionSheetBody = '';
        if ($selectedView === 'pages') {
            $designerSurface = myronEditorSurfaceReadModel()->templateSurface((string) $context['baseTemplateId']);
            $surfaceSections = is_array($designerSurface['sections'] ?? null) ? $designerSurface['sections'] : [];

            // Image-asset options for any section field of type=image (matches the picker
            // shape the operator-side page editor uses).
            $availableImageFiles = array_values(array_filter(
                myronFileRepository()->listFiles(),
                static fn (array $file): bool => (bool) ($file['is_image'] ?? false)
            ));

            // Index the platform-shipped (definition) defaultContent so we can flag any
            // section that has Designer-edited content diverging from the seed.
            $platformDefaultContent = is_array($context['definition']['defaultContent'] ?? null)
                ? $context['definition']['defaultContent']
                : [];
            $platformSections = is_array($platformDefaultContent['sections'] ?? null) ? $platformDefaultContent['sections'] : [];

            // Index the section guidance from the architectural guidance JSON so we can
            // surface inline editorial intent next to each section's editor.
            $guidanceSectionsIndex = [];
            $guidanceData = is_array($context['definition']['guidance'] ?? null) ? $context['definition']['guidance'] : null;
            if (is_array($guidanceData) && is_array($guidanceData['sections'] ?? null)) {
                foreach ($guidanceData['sections'] as $guidedSection) {
                    if (!is_array($guidedSection)) {
                        continue;
                    }
                    $sectionKey = trim((string) ($guidedSection['sectionKey'] ?? ''));
                    if ($sectionKey !== '') {
                        $guidanceSectionsIndex[$sectionKey] = $guidedSection;
                    }
                }
            }

            ob_start();
            ?>
            <form class="sg-form-grid" method="post" data-myron-template-section-content>
              <input type="hidden" name="csrf_token" value="<?= myronEscape(myronCsrfToken()) ?>">
              <input type="hidden" name="action" value="update-template-section-content">
              <input type="hidden" name="template_ref" value="<?= myronEscape($selectedRef) ?>">
              <p class="sg-card__text">Customize the editorial content for each section. Content operators see this content when they create a new page from this template — they can edit it on their pages without changing the template.</p>
              <div class="mc-visual-section-panels" data-mc-visual-section-panels>
                <?php foreach ($surfaceSections as $position => $sectionNode): ?>
                <?php
                  if (!is_array($sectionNode)) { continue; }
                  $instanceKey = (string) ($sectionNode['instanceKey'] ?? '');
                  $sectionKey = (string) ($sectionNode['sectionKey'] ?? '');
                  $sectionLabel = (string) ($sectionNode['label'] ?? ($sectionKey ?: $instanceKey));
                  $editableFields = is_array($sectionNode['editableFields'] ?? null) ? $sectionNode['editableFields'] : [];
                  $isEditable = (string) ($sectionNode['editability'] ?? '') === 'editable';
                  $sectionGuidance = $guidanceSectionsIndex[$sectionKey] ?? null;
                  $guidanceExcerpt = '';
                  if (is_array($sectionGuidance)) {
                      $bits = [];
                      foreach (['intent', 'editorialNote', 'guidance', 'note'] as $candidateKey) {
                          $candidate = trim((string) ($sectionGuidance[$candidateKey] ?? ''));
                          if ($candidate !== '') {
                              $bits[] = $candidate;
                          }
                      }
                      $guidanceExcerpt = implode(' · ', array_unique($bits));
                  }
                  // "Modified" detection: any current field value that differs from the
                  // platform-shipped section default (per-instance match).
                  $platformValues = is_array($platformSections[$instanceKey] ?? null) ? $platformSections[$instanceKey] : [];
                  $isModified = false;
                  if ($platformValues !== []) {
                      foreach ($editableFields as $checkField) {
                          if (!is_array($checkField)) { continue; }
                          $cKey = (string) ($checkField['key'] ?? '');
                          $cVal = trim((string) ($checkField['value'] ?? ''));
                          $platformVal = trim((string) ($platformValues[$cKey] ?? ''));
                          if ($cKey !== '' && $cVal !== '' && $cVal !== $platformVal) {
                              $isModified = true;
                              break;
                          }
                      }
                  }
                ?>
                <section class="sg-card" data-mc-visual-section-panel data-section-instance-key="<?= myronEscape($instanceKey) ?>">
                  <h3 class="sg-card__title">
                    <?= myronEscape($sectionLabel) ?>
                    <?php if (!$isEditable): ?><span class="sg-pill sg-pill--secondary">Inspect only</span><?php endif; ?>
                    <?php if ($isModified): ?><span class="sg-pill sg-pill--active" title="This section's content has been customized away from the platform-shipped seed.">Modified</span><?php endif; ?>
                  </h3>
                  <?php if ($guidanceExcerpt !== ''): ?>
                  <p class="sg-card__text mc-page-grid__subtle"><strong>Editorial intent:</strong> <?= myronEscape($guidanceExcerpt) ?></p>
                  <?php endif; ?>
                  <?php if (!$isEditable || $editableFields === []): ?>
                  <p class="sg-section__subtitle">This section has no editorial fields — its content is governed by the template structure.</p>
                  <?php else: ?>
                  <div class="sg-form-grid">
                    <?php foreach ($editableFields as $field): ?>
                    <?php
                      if (!is_array($field)) { continue; }
                      $fieldKey = (string) ($field['key'] ?? '');
                      if ($fieldKey === '') { continue; }
                      $fieldType = (string) ($field['type'] ?? 'text');
                      $fieldLabel = (string) ($field['label'] ?? $fieldKey);
                      $fieldValue = (string) ($field['value'] ?? '');
                      $inputName = 'section_content[' . $instanceKey . '][' . $fieldKey . ']';
                      $richtextAttribute = function_exists('myronSectionContentFieldRichtextAttribute')
                          ? myronSectionContentFieldRichtextAttribute($field, $fieldType)
                          : '';
                    ?>
                    <label class="sg-field<?= $fieldType === 'textarea' ? ' sg-field--full' : '' ?>">
                      <span class="sg-field__label"><?= myronEscape($fieldLabel) ?></span>
                      <?php if ($fieldType === 'textarea'): ?>
                      <textarea class="sg-field__control sg-field__control--textarea" name="<?= myronEscape($inputName) ?>" rows="<?= $fieldKey === 'body' ? '6' : '3' ?>"<?= $richtextAttribute ?>><?= myronEscape($fieldValue) ?></textarea>
                      <?php elseif ($fieldType === 'image'): ?>
                      <select class="sg-field__control" name="<?= myronEscape($inputName) ?>">
                        <option value="">Use section default</option>
                        <?php foreach ($availableImageFiles as $file): ?>
                        <option value="<?= myronEscape((string) ($file['id'] ?? '')) ?>"<?= $fieldValue === (string) ($file['id'] ?? '') ? ' selected' : '' ?>>
                          <?= myronEscape((string) (($file['title'] ?? '') ?: ($file['original_filename'] ?? 'Image asset'))) ?>
                        </option>
                        <?php endforeach; ?>
                      </select>
                      <span class="sg-field__hint">Choose an existing Files asset.</span>
                      <?php elseif ($fieldType === 'url'): ?>
                      <input class="sg-field__control" type="text" inputmode="url" name="<?= myronEscape($inputName) ?>" value="<?= myronEscape($fieldValue) ?>">
                      <?php else: ?>
                      <input class="sg-field__control" type="text" name="<?= myronEscape($inputName) ?>" value="<?= myronEscape($fieldValue) ?>"<?= $richtextAttribute ?>>
                      <?php endif; ?>
                    </label>
                    <?php endforeach; ?>
                  </div>
                  <?php endif; ?>
                </section>
                <?php endforeach; ?>
              </div>
              <button class="sg-button sg-button--primary" type="submit">Save Page Template content</button>
            </form>
            <?php
            $sectionSheetBody = (string) ob_get_clean();
        }

        // Template Details body (read-only structure inspection — same on both surfaces).
        ob_start();
        $chromeAssignment = $chromeAssignmentRepository->getForTemplate((string) ($context['sourceTemplateId'] ?? ''));
        $assignedNavigationId = is_array($chromeAssignment) ? trim((string) ($chromeAssignment['navigation_design_id'] ?? '')) : '';
        $assignedFooterVariant = is_array($chromeAssignment) ? trim((string) ($chromeAssignment['footer_variant_id'] ?? '')) : '';
        $templateChrome = is_array($context['schema']['chrome'] ?? null) ? $context['schema']['chrome'] : [];
        $footerChrome = is_array($templateChrome['footer'] ?? null) ? $templateChrome['footer'] : [];
        $selectedFooterChromeSeed = trim((string) ($footerChrome['variant'] ?? ''));
        $footerSelectedValue = $assignedFooterVariant !== ''
            ? $assignedFooterVariant
            : ($selectedFooterChromeSeed !== '' ? 'inherit_seed' : 'inherit_site');
        $defaultNavigationDesign = $navigationDesignRepository->getDefault();
        $activatedNavigationVersions = $navigationDesignRepository->listActivatedSorted();
        $defaultFooterDesign = $footerDesignRepository->getDefault();
        $activatedFooterVariants = $footerDesignRepository->listActivatedSorted();
      ?>
      <?php if ($selectedView === 'pages'): ?>
      <?php if (myronUserCanManageDesign($currentUser)): ?>
      <form method="post" class="sg-form-grid mc-template-chrome-assignment-form" data-myron-page-template-chrome-assignment>
        <input type="hidden" name="csrf_token" value="<?= myronEscape(myronCsrfToken()) ?>">
        <input type="hidden" name="action" value="update-template-chrome-assignment">
        <input type="hidden" name="template_ref" value="<?= myronEscape($selectedRef) ?>">
        <section class="sg-card mc-template-chrome-assignment-slot">
          <h3 class="sg-card__title">Navigation</h3>
          <label class="sg-field">
            <span class="sg-field__label">Navigation version</span>
            <select class="sg-field__control" name="navigation_design_id">
              <option value=""<?= $assignedNavigationId === '' ? ' selected' : '' ?>>Use site default (<?= myronEscape((string) ($defaultNavigationDesign['name'] ?? 'Primary')) ?>)</option>
              <?php foreach ($activatedNavigationVersions as $version): ?>
              <?php $versionId = (string) ($version['id'] ?? ''); ?>
              <option value="<?= myronEscape($versionId) ?>"<?= $assignedNavigationId === $versionId ? ' selected' : '' ?>><?= myronEscape((string) ($version['name'] ?? 'Navigation')) ?></option>
              <?php endforeach; ?>
            </select>
            <span class="mc-footer-chrome-seed-hint">When set to a specific version, this Page Template overrides the site default.</span>
          </label>
        </section>
        <section class="sg-card mc-template-chrome-assignment-slot">
          <h3 class="sg-card__title">Footer</h3>
          <label class="sg-field">
            <span class="sg-field__label">Footer variant</span>
            <select class="sg-field__control" name="footer_variant_id">
              <option value="inherit_site"<?= $footerSelectedValue === 'inherit_site' ? ' selected' : '' ?>>Use site default (<?= myronEscape((string) ($defaultFooterDesign['variant_id'] ?? 'footer.standard')) ?>)</option>
              <?php if ($selectedFooterChromeSeed !== ''): ?>
              <option value="inherit_seed"<?= $footerSelectedValue === 'inherit_seed' ? ' selected' : '' ?>>Use template chrome (<?= myronEscape($selectedFooterChromeSeed) ?>)</option>
              <?php endif; ?>
              <?php foreach ($activatedFooterVariants as $footer): ?>
              <?php $variantId = (string) ($footer['variant_id'] ?? ''); ?>
              <option value="<?= myronEscape($variantId) ?>"<?= $footerSelectedValue === $variantId ? ' selected' : '' ?>><?= myronEscape($footerVariantLabels[$variantId] ?? $variantId) ?></option>
              <?php endforeach; ?>
            </select>
            <?php if ($selectedFooterChromeSeed !== ''): ?>
            <span class="mc-footer-chrome-seed-hint">Use template chrome preserves the packaged chrome.footer.variant seed until a specific override is selected.</span>
            <?php endif; ?>
            <span class="mc-footer-chrome-seed-hint">When set to a specific variant, this Page Template overrides the site default.</span>
          </label>
        </section>
        <div class="sg-card__actions">
          <button class="sg-button sg-button--primary" type="submit">Update Chrome Assignment</button>
        </div>
      </form>
      <?php else: ?>
      <section class="sg-card mc-template-chrome-assignment-slot">
        <h3 class="sg-card__title">Chrome Assignment</h3>
        <p class="sg-card__text">You have read access to this surface. Editing navigation and footer overrides requires Designer or Administrator access.</p>
      </section>
      <?php endif; ?>
      <?php endif; ?>
      <?php if ($selectedView === 'pages' && $blogRailSupported): ?>
      <?php if (myronUserCanManageDesign($currentUser)): ?>
      <form method="post" class="sg-form-grid mc-template-blog-rail-form" data-myron-page-template-blog-rail>
        <input type="hidden" name="csrf_token" value="<?= myronEscape(myronCsrfToken()) ?>">
        <input type="hidden" name="action" value="update-template-blog-rail">
        <input type="hidden" name="template_ref" value="<?= myronEscape($selectedRef) ?>">
        <section class="sg-card mc-template-chrome-assignment-slot">
          <h3 class="sg-card__title">Blog Rail</h3>
          <label class="sg-field">
            <span class="sg-field__label">Rail placement</span>
            <select class="sg-field__control" name="blog_rail_placement">
              <option value="right"<?= $blogRailPlacement === 'right' ? ' selected' : '' ?>>Right</option>
              <option value="left"<?= $blogRailPlacement === 'left' ? ' selected' : '' ?>>Left</option>
              <option value="none"<?= $blogRailPlacement === 'none' ? ' selected' : '' ?>>None</option>
            </select>
            <span class="mc-footer-chrome-seed-hint">Assigned rail: <?= myronEscape($blogRailName) ?>. This writes the same Rails assignment used by the public runtime.</span>
            <span class="mc-footer-chrome-seed-hint">Source: <?= myronEscape($blogRailSource) ?>. Rails Design is the primary management surface.</span>
          </label>
        </section>
        <div class="sg-card__actions">
          <button class="sg-button sg-button--primary" type="submit">Update Blog Rail</button>
        </div>
      </form>
      <?php else: ?>
      <section class="sg-card mc-template-chrome-assignment-slot">
        <h3 class="sg-card__title">Blog Rail</h3>
        <p class="sg-card__text">You have read access to this surface. Editing the blog rail requires Designer or Administrator access.</p>
      </section>
      <?php endif; ?>
      <?php endif; ?>
      <div class="mc-page-grid mc-page-grid--studio-template-list" role="table" aria-label="Template structure">
        <div class="mc-page-grid__row mc-page-grid__row--head" role="row"><span role="columnheader">Section Key</span><span role="columnheader">Component ID</span><span role="columnheader">Editability</span></div>
        <?php foreach ($sections as $position => $section): ?>
        <div class="mc-page-grid__row" role="row">
          <span class="mc-page-grid__cell" role="cell"><code><?= myronEscape((string) ($section['sectionKey'] ?? myronSectionInstanceKey($section, (int) $position))) ?></code></span>
          <span class="mc-page-grid__cell" role="cell"><code><?= myronEscape((string) ($section['componentId'] ?? '')) ?></code></span>
          <span class="mc-page-grid__cell" role="cell"><?= !empty(($section['editing'] ?? [])['contentEditable']) ? 'Content editable' : 'Design editable' ?></span>
        </div>
        <?php endforeach; ?>
      </div>
      <?php
        $attributesBody = (string) ob_get_clean();
        // Shared Architectural Guidance sidesheet body — read-only on both surfaces (same
        // helper used by content/templates.php).
        $guidanceBody = myronRenderTemplateGuidanceSidesheetBody(
            is_array($context['definition']['guidance'] ?? null) ? $context['definition']['guidance'] : null
        );

        // Duplicate modal body (only for packaged Site Templates / 'templates' view — Designer can
        // fork a Site Template into a Custom Site Template before changing architecture).
        $duplicateBody = '';
        if ($selectedView === 'templates' && empty($context['isCustom']) && !empty($context['canDuplicate'])) {
            ob_start();
            ?>
            <form class="sg-form-grid" method="post">
              <input type="hidden" name="csrf_token" value="<?= myronEscape(myronCsrfToken()) ?>">
              <input type="hidden" name="action" value="duplicate-template">
              <input type="hidden" name="source_template_id" value="<?= myronEscape((string) $context['baseTemplateId']) ?>">
              <div class="sg-field">
                <label class="sg-field__label" for="duplicate-template-name">Custom Site Template name</label>
                <input class="sg-field__control" type="text" id="duplicate-template-name" name="template_name" required>
              </div>
              <button class="sg-button sg-button--primary" type="submit">Create Custom Site Template</button>
            </form>
            <?php
            $duplicateBody = (string) ob_get_clean();
        }
      ?>
      <section class="sg-section" data-myron-site-type-studio-manage-template data-myron-studio-surface="<?= myronEscape($selectedView) ?>">
        <div class="mc-editor-toolbar">
          <div class="mc-editor-toolbar__summary">
            <span class="mc-editor-toolbar__title"><?= myronEscape((string) $context['name']) ?></span>
            <?php if ($selectedView === 'pages'): ?>
              <?php if ($unsetCount > 0): ?>
              <span class="sg-pill"><?= myronEscape((string) $unsetCount) ?> section<?= $unsetCount === 1 ? '' : 's' ?> need content</span>
              <?php else: ?>
              <span class="sg-pill sg-pill--active">All sections have content</span>
              <?php endif; ?>
            <?php else: ?>
              <span class="sg-pill <?= $isCustomSiteTemplate ? 'sg-pill--active' : '' ?>"><?= $isCustomSiteTemplate ? 'Custom Site Template' : 'Read only' ?></span>
              <?php if ($isCustomSiteTemplate): ?>
              <span class="sg-pill <?= $isAvailablePageTemplate ? 'sg-pill--active' : 'sg-pill--secondary' ?>"><?= $isAvailablePageTemplate ? 'Available as Page Template' : 'Not available as Page Template' ?></span>
              <?php endif; ?>
            <?php endif; ?>
          </div>
          <div class="mc-editor-toolbar__breakpoint" role="group" aria-label="Preview breakpoint" data-mc-studio-breakpoint-toggle>
            <?php foreach ([
                'mobile' => 'Mobile',
                'tablet' => 'Tablet',
                'desktop' => 'Desktop',
            ] as $breakpointValue => $breakpointLabel): ?>
            <button
              class="sg-button <?= $breakpointValue === 'desktop' ? 'sg-button--primary' : 'sg-button--secondary' ?>"
              type="button"
              aria-pressed="<?= $breakpointValue === 'desktop' ? 'true' : 'false' ?>"
              data-mc-studio-breakpoint-button="<?= myronEscape($breakpointValue) ?>"
            ><?= myronEscape($breakpointLabel) ?></button>
            <?php endforeach; ?>
          </div>
          <div class="mc-editor-toolbar__actions">
            <button class="sg-button sg-button--secondary" type="button" data-mc-sidesheet-open="template-attributes-sheet">Template Details</button>
            <?php if ($guidanceBody !== ''): ?>
            <button class="sg-button sg-button--secondary" type="button" data-mc-sidesheet-open="template-guidance-sheet">Architectural Guidance</button>
            <?php endif; ?>
            <?php if ($selectedView === 'templates' && empty($context['isCustom']) && !empty($context['canDuplicate'])): ?>
            <button class="sg-button sg-button--secondary" type="button" data-mc-sidesheet-open="duplicate-template-modal">Duplicate as Custom Site Template</button>
            <?php endif; ?>
            <?php if ($selectedView === 'templates' && $isCustomSiteTemplate): ?>
            <a class="sg-button sg-button--secondary" href="<?= myronEscape(myronBuildAdminUrl('design.templatesManager', ['usage' => 'library', 'template' => (string) $context['sourceTemplateId']])) ?>">Manage Architecture</a>
            <?php if (!$isAvailablePageTemplate && myronUserCanManageDesign($currentUser)): ?>
            <form method="post" class="sg-inline-form">
              <input type="hidden" name="csrf_token" value="<?= myronEscape(myronCsrfToken()) ?>">
              <input type="hidden" name="action" value="make-custom-template-available">
              <input type="hidden" name="template_ref" value="<?= myronEscape($selectedRef) ?>">
              <button class="sg-button sg-button--primary" type="submit">Make Available as Page Template</button>
            </form>
            <?php endif; ?>
            <?php endif; ?>
            <a class="sg-button sg-button--secondary" href="<?= myronEscape(myronBuildAdminUrl('design.templatePreview', ['id' => (string) $context['baseTemplateId']])) ?>" target="_blank" rel="noreferrer">Open Full Preview</a>
          </div>
        </div>
        <?php if ($selectedView === 'pages'): ?>
        <p class="sg-section__subtitle">Edit the editorial content that ships with this Page Template. Content operators will see this when they create a new page from this template.</p>
        <?php if (myronUserCanManageDesign($currentUser)): ?>
        <button class="sg-button sg-button--primary" type="button" data-mc-sidesheet-open="template-section-content-sheet" data-mc-visual-section-editor-trigger>Edit Editorial Content</button>
        <?php else: ?>
        <p class="sg-section__subtitle">You have read access to this surface. Editing the Editorial Content requires Designer or Administrator access.</p>
        <?php endif; ?>
        <?php else: ?>
        <p class="sg-section__subtitle"><?= $isCustomSiteTemplate
            ? 'Manage the architectural structure of this Custom Site Template, then make it available as a Page Template when it is ready for design defaults and Content page creation.'
            : 'Inspect the architectural definition of this packaged template. Duplicate it as a Custom Site Template before changing structure.' ?></p>
        <?php endif; ?>
        <div
          class="mc-editor-viewer__canvas mc-template-manager-viewer__canvas mc-studio-preview__canvas"
          style="--studio-breakpoint-sm: <?= myronEscape($studioBreakpointSm) ?>;"
          data-mc-visual-editor-canvas
          data-mc-studio-preview-canvas
          data-myron-site-type-studio-rendered
          data-breakpoint="desktop"
        >
          <div class="mc-studio-preview__viewport" data-mc-studio-preview-viewport data-breakpoint="desktop">
            <?= $renderer->renderPublishedPage($page, myronPublicBasePath(), []) . "\n" ?>
          </div>
        </div>
      </section>
      <?php
        myronRenderAdminSidesheet('template-attributes-sheet', 'Template Details', $attributesBody, ['size' => 'lg', 'description' => 'Section structure of this template.']);
        if ($selectedView === 'pages' && $sectionSheetBody !== '') {
            myronRenderAdminSidesheet('template-section-content-sheet', 'Editorial Content', $sectionSheetBody, ['size' => 'lg', 'description' => 'Customize what content operators see when they create a new page from this template.']);
        }
        if ($guidanceBody !== '') {
            myronRenderAdminSidesheet('template-guidance-sheet', 'Architectural Guidance', $guidanceBody, ['size' => 'lg', 'description' => 'How this template is structured and the editorial intent behind each section.']);
        }
        if ($selectedView === 'templates' && $duplicateBody !== '') {
            myronRenderAdminSidesheet('duplicate-template-modal', 'Duplicate as Custom Site Template', $duplicateBody, ['size' => 'sm']);
        }
      ?>
      <?php endif; ?>
      <?php endif; ?>
    <?php endif; ?>
  </div>
</div>
<?php
myronRenderAdminShellEnd();
