<?php $this->start('body');
    $p    = $this->data['p'];
    $onb  = $this->data['onb']  ?? [];
    $ck   = $this->data['checklist'] ?? [];
    $appr = $this->data['approval'] ?? [];
    $done = 0; foreach ($ck as $it) if ((int)$it['is_complete']===1) $done++;
    $total = count($ck);
    $canSubmit = ($p['crm_status'] === 'NOT_STARTED' || $p['crm_status'] === 'IN_PROGRESS')
                 && $done === $total && $total > 0 && (int)$p['migrated_flag'] === 0
                 && empty($appr);
    $group = strtolower(trim($_SESSION['user_group_name'] ?? ''));
    // Slice 8Z-z-A · PC + Procurement never see revenue/margin (feedback rule).
    $canSeeRevenue    = !in_array($group, ['projects coordinator','procurement'], true);
    $canEditChecklist = in_array($group, ['crm','administrator'], true) && $p['crm_status'] !== 'APPROVED';
    $ws               = $this->data['workspace'] ?? ['type' => '', 'kpis' => [], 'actions' => [], 'note' => ''];
    $gatesOpen        = $p['crm_status'] === 'APPROVED' || (int)$p['migrated_flag'] === 1;
    $wsIcon           = ['goods' => 'fas fa-boxes', 'works' => 'fas fa-hard-hat', 'services' => 'fas fa-tools'][$ws['type']] ?? 'fas fa-cubes';
    // Slice 8g CRM authoring — only for non-migrated goods projects pre-approval
    $goodsPo    = $this->data['goods_po']    ?? [];
    $goodsItems = $this->data['goods_items'] ?? [];
    $goodsAppr  = $this->data['goods_appr']  ?? [];
    $seats      = $this->data['seats']       ?? [];
    $isGoodsCrmPhase = $p['project_type'] === 'goods'
                    && (int)$p['migrated_flag'] === 0
                    && in_array($p['crm_status'], ['PENDING','NOT_STARTED','IN_PROGRESS','SUBMITTED','DECLINED'], true);
    // Slice 8Y — item authoring is now PC-owned (was CRM). PM + Admin also authorised for edge cases.
    $canCrmEdit = in_array($group, ['crm','projects coordinator','project manager','administrator'], true)
                    && in_array($p['crm_status'], ['PENDING','NOT_STARTED','IN_PROGRESS','DECLINED'], true)
                    && empty($goodsAppr);
?>

<div class="d-flex align-items-center justify-content-between mb-3">
    <div>
        <h5 class="mb-0" style="font-weight:600;"><?= htmlspecialchars($p['project_no']); ?> · <?= htmlspecialchars($p['project_name']); ?></h5>
        <div class="text-muted" style="font-size:.72rem;">
            <span style="text-transform:capitalize;"><?= htmlspecialchars($p['project_type']); ?></span> ·
            <?= htmlspecialchars($p['project_customer']); ?> ·
            <?= htmlspecialchars(strtolower(str_replace('_',' ', $p['origin']))); ?>
        </div>
    </div>
    <div class="d-flex gap-2">
        <a href="<?= PROOT; ?>Projects/xlsx/<?= (int)$p['c0d']; ?>" class="btn btn-sm" style="background:#F8FAFC;border:1px solid #E2E8F0;color:#334155;">
            <i class="fas fa-file-excel me-1" style="color:#7A9E7E;"></i>Excel
        </a>
        <button type="button" id="btn_preview_project_pdf" class="btn btn-sm" style="background:#F8FAFC;border:1px solid #E2E8F0;color:#334155;">
            <i class="fas fa-file-pdf me-1" style="color:#C48579;"></i>PDF
        </button>
        <a href="<?= PROOT; ?>Projects" class="btn btn-sm btn-outline-secondary"><i class="fas fa-arrow-left me-1"></i> Back</a>
    </div>
</div>

<script>
// 8Y · Project handover PDF preview — iframe modal with newTab / download / close.
(function () {
    var $btn = document.getElementById('btn_preview_project_pdf');
    if (!$btn) return;
    var pid = <?= (int)$p['c0d']; ?>;
    var previewUrl  = '<?= PROOT; ?>Projects/pdf/' + pid;
    var downloadUrl = previewUrl + '?disposition=attachment';
    $btn.addEventListener('click', function () {
        $.confirm({
            title: '<i class="fas fa-file-pdf me-1" style="color:#C48579;"></i>Project handover pack',
            columnClass: 'col-lg-11 col-xl-10',
            boxWidth: '95%', useBootstrap: false,
            content:
                '<div style="height:78vh;background:#F8FAFC;border:1px solid #E2E8F0;border-radius:4px;overflow:hidden;">' +
                '  <iframe src="' + previewUrl + '" style="width:100%;height:100%;border:0;" title="Project handover PDF"></iframe>' +
                '</div>',
            buttons: {
                newTab:    { text: '<i class="fas fa-external-link-alt me-1"></i> Open in new tab', btnClass: 'btn-outline-secondary', action: function () { window.open(previewUrl, '_blank'); return false; } },
                download:  { text: '<i class="fas fa-download me-1"></i> Download',                  btnClass: 'btn-outline-primary',   action: function () { window.location.href = downloadUrl; return false; } },
                close:     { text: 'Close', btnClass: 'btn-secondary' }
            }
        });
    });
})();
</script>

<?php // Slice 8j — direct-award chip surfaces the justification for scrutiny
if ($p['origin'] === 'DIRECT_AWARD'):
    $daj = trim((string)($p['direct_award_justification'] ?? ''));
    $len = mb_strlen($daj);
    $isThin = $len < 20;
    $band   = $isThin ? ['#B87A5A','#F3E5D9','⚠ Direct Award · thin justification'] : ['#6B3F2A','#F3E5D9','Direct Award · commercial justification on file'];
?>
<div class="alert py-2 mb-3" style="background:<?= $band[1]; ?>;border:1px solid <?= $band[0]; ?>;color:<?= $band[0]; ?>;">
    <div class="d-flex justify-content-between align-items-start">
        <div>
            <strong><?= htmlspecialchars($band[2]); ?></strong>
            <div style="font-size:.82rem;color:#5B4F3C;margin-top:2px;">
                <?= htmlspecialchars(mb_strimwidth($daj, 0, 400, '…')); ?>
            </div>
        </div>
        <span class="badge" style="background:<?= $band[0]; ?>;color:#fff;"><?= $len; ?> chars</span>
    </div>
</div>
<?php endif; ?>

<div class="row g-3 mb-3">
    <?php if ($canSeeRevenue): ?>
    <div class="col-md-3"><div class="card border-0 shadow-sm"><div class="card-body p-2"><div class="text-muted small">Contract</div><div style="font-weight:600;"><?= htmlspecialchars($p['currency']); ?> <?= number_format((float)$p['contract_value']); ?></div></div></div></div>
    <div class="col-md-3"><div class="card border-0 shadow-sm"><div class="card-body p-2"><div class="text-muted small">Default Margin</div><div style="font-weight:600;"><?= number_format((float)$p['default_margin_pct'],2); ?>%</div></div></div></div>
    <?php endif; ?>
    <div class="col-md-<?= $canSeeRevenue ? 3 : 6; ?>"><div class="card border-0 shadow-sm"><div class="card-body p-2"><div class="text-muted small">Start / End</div><div style="font-weight:600;"><?= htmlspecialchars($p['project_start_date'] ?: '—'); ?> → <?= htmlspecialchars($p['project_end_date'] ?: '—'); ?></div></div></div></div>
    <div class="col-md-<?= $canSeeRevenue ? 3 : 6; ?>"><div class="card border-0 shadow-sm"><div class="card-body p-2"><div class="text-muted small">Location</div><div style="font-weight:600;"><?= htmlspecialchars(trim(($p['region'] ?? '') . ' · ' . ($p['district'] ?? ''), ' ·')) ?: '—'; ?></div></div></div></div>
</div>

<?php
    // Slice 8Y — Source tender · contract snapshot card (tender-origin projects only).
    // NOTE: outer `if` MUST stay `!empty($src) && !empty($src['tender'])` — this block
    // also wraps the Tender scope card (line ~269) and the Kickoff brief section, and
    // gates $srcItems/$srcPricing initialisation. The PC/Procurement revenue-hide is
    // applied at the visible HTML wrapper below (Slice 8Z-z-A).
    $src = $this->data['source_ctx'] ?? [];
    if (!empty($src) && !empty($src['tender'])):
        $srcT   = $src['tender'];
        $srcTid = (int)$srcT['c0d'];
        $srcTerms   = $src['terms']   ?? null;
        $srcSigning = $src['signing'] ?? null;
        $srcHist    = $src['history'] ?? [];
        $srcGoodsPo = (int)($src['goods_client_po_id'] ?? 0);
?>
<?php if ($canSeeRevenue): // 8Z-z-A · hide source-tender snapshot card from PC + Procurement ?>
<div class="card border-0 shadow-sm mb-3" style="border-left:3px solid #7A8BA1 !important;background:#F8FAFC;">
    <div class="card-header bg-white d-flex align-items-center justify-content-between" style="border-bottom:1px solid #E2E8F0;">
        <div>
            <strong style="color:#334155;"><i class="fas fa-scroll me-2" style="color:#7A8BA1;"></i>Source tender · contract snapshot</strong>
            <div class="text-muted small mt-1" style="color:#64748B;font-size:.72rem;">Everything the PM needs from the pre-award trail. Contract terms and signing details flow through unchanged from the tender file.</div>
        </div>
        <a href="<?= PROOT; ?>Tenders/view/<?= $srcTid; ?>" class="btn btn-sm" style="background:#F8FAFC;border:1px solid #7A8BA1;color:#334155;font-weight:600;">
            <i class="fas fa-external-link-alt me-1" style="color:#7A8BA1;"></i>Open source tender
        </a>
    </div>
    <div class="card-body p-3">

        <!-- Tender identity -->
        <div class="row g-2 mb-3">
            <div class="col-md-3">
                <div class="text-muted small" style="color:#64748B;font-size:.68rem;text-transform:uppercase;letter-spacing:.4px;">Tender no</div>
                <div style="font-weight:600;color:#334155;"><?= htmlspecialchars((string)$srcT['tender_no']); ?></div>
            </div>
            <div class="col-md-4">
                <div class="text-muted small" style="color:#64748B;font-size:.68rem;text-transform:uppercase;letter-spacing:.4px;">Title</div>
                <div style="font-weight:600;color:#334155;"><?= htmlspecialchars((string)$srcT['tender_title']); ?></div>
            </div>
            <div class="col-md-2">
                <div class="text-muted small" style="color:#64748B;font-size:.68rem;text-transform:uppercase;letter-spacing:.4px;">Buyer</div>
                <div style="font-weight:600;color:#334155;"><?= htmlspecialchars((string)$srcT['buyer_name']); ?></div>
            </div>
            <div class="col-md-3">
                <div class="text-muted small" style="color:#64748B;font-size:.68rem;text-transform:uppercase;letter-spacing:.4px;">Source</div>
                <div style="font-weight:500;color:#334155;font-size:.82rem;"><?= htmlspecialchars(ucwords(strtolower(str_replace('_',' ', (string)$srcT['source_type'])))); ?></div>
            </div>
        </div>

        <!-- Value timeline · pre-bid → submitted → signed. Clears up the "three numbers" confusion. -->
        <div class="row g-2 mb-3">
            <div class="col-md-4">
                <div class="p-2 rounded" style="background:#F1F5F9;border:1px solid #E2E8F0;">
                    <div class="text-muted small" style="color:#64748B;font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Buyer estimate <span style="color:#94A3B8;font-weight:400;text-transform:none;">· pre-bid</span></div>
                    <div style="font-weight:600;color:#334155;">TZS <?= number_format((float)($srcT['estimated_value'] ?? 0)); ?></div>
                </div>
            </div>
            <div class="col-md-4">
                <div class="p-2 rounded" style="background:#FEF3E7;border:1px solid #D4A574;">
                    <div class="text-muted small" style="color:#8B6914;font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Our bid <span style="color:#B78F52;font-weight:400;text-transform:none;">· submitted</span></div>
                    <div style="font-weight:600;color:#334155;">TZS <?= number_format((float)($srcT['submission_amount'] ?? 0)); ?></div>
                </div>
            </div>
            <div class="col-md-4">
                <div class="p-2 rounded" style="background:#EAF2E8;border:1px solid #7A9E7E;">
                    <div class="text-muted small" style="color:#3F5C43;font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Signed contract <span style="color:#5B7A5F;font-weight:400;text-transform:none;">· awarded</span></div>
                    <div style="font-weight:600;color:#334155;">TZS <?= number_format((float)($srcTerms['contract_value'] ?? 0)); ?></div>
                </div>
            </div>
        </div>

        <!-- Contract terms snapshot -->
        <?php if ($srcTerms): ?>
            <div class="mb-2" style="border-top:1px dashed #CBD5E1;padding-top:.6rem;"><strong style="color:#334155;font-size:.8rem;"><i class="fas fa-file-contract me-1" style="color:#7A9E7E;"></i>Contract terms</strong></div>
            <div class="row g-2 mb-3">
                <div class="col-md-2"><div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Contract no</div><div style="font-weight:600;color:#334155;"><?= htmlspecialchars((string)($srcTerms['contract_no'] ?? '—')); ?></div></div>
                <div class="col-md-2"><div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Contract date</div><div style="font-weight:600;color:#334155;"><?= htmlspecialchars((string)($srcTerms['contract_date'] ?? '—')); ?></div></div>
                <div class="col-md-2"><div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Contract value</div><div style="font-weight:600;color:#334155;">TZS <?= number_format((float)($srcTerms['contract_value'] ?? 0)); ?></div></div>
                <div class="col-md-2"><div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Payment basis</div><div style="font-weight:500;color:#334155;font-size:.82rem;text-transform:capitalize;"><?= htmlspecialchars(strtolower(str_replace('_',' ', (string)($srcTerms['payment_basis'] ?? '—')))); ?></div></div>
                <div class="col-md-2"><div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Delivery (days)</div><div style="font-weight:600;color:#334155;"><?= htmlspecialchars((string)($srcTerms['delivery_timeline_days'] ?? '—')); ?></div></div>
                <div class="col-md-2"><div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Warranty (months)</div><div style="font-weight:600;color:#334155;"><?= htmlspecialchars((string)($srcTerms['warranty_months'] ?? '—')); ?></div></div>
                <div class="col-md-2"><div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Advance %</div><div style="font-weight:600;color:#334155;"><?= number_format((float)($srcTerms['advance_pct'] ?? 0), 2); ?>%</div></div>
                <div class="col-md-2"><div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Retention %</div><div style="font-weight:600;color:#334155;"><?= number_format((float)($srcTerms['retention_pct'] ?? 0), 2); ?>%</div></div>
                <div class="col-md-2"><div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">WHT %</div><div style="font-weight:600;color:#334155;"><?= number_format((float)($srcTerms['wht_pct'] ?? 0), 2); ?>%</div></div>
                <div class="col-md-6"><div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Payment terms</div><div style="font-weight:500;color:#334155;font-size:.82rem;"><?= htmlspecialchars((string)($srcTerms['payment_terms'] ?? '—')); ?></div></div>
            </div>
        <?php else: ?>
            <div class="alert py-2 mb-3" style="background:#F1F5F9;border:1px dashed #CBD5E1;color:#64748B;font-size:.82rem;">
                <i class="fas fa-hourglass-half me-1"></i>Contract terms weren't captured on the source tender — signing details will be manual.
            </div>
        <?php endif; ?>

        <!-- Signing block -->
        <?php if ($srcSigning): ?>
            <div class="mb-2" style="border-top:1px dashed #CBD5E1;padding-top:.6rem;"><strong style="color:#334155;font-size:.8rem;"><i class="fas fa-signature me-1" style="color:#7A9E7E;"></i>Signing event</strong></div>
            <div class="row g-2 mb-3">
                <div class="col-md-2"><div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Signed date</div><div style="font-weight:600;color:#334155;"><?= htmlspecialchars((string)($srcSigning['signed_date'] ?? '—')); ?></div></div>
                <div class="col-md-4"><div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Venue</div><div style="font-weight:500;color:#334155;font-size:.82rem;"><?= htmlspecialchars((string)($srcSigning['signed_venue'] ?? '—')); ?></div></div>
                <div class="col-md-3"><div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Our signatories</div><div style="font-weight:500;color:#334155;font-size:.82rem;"><?= htmlspecialchars((string)($srcSigning['our_signatories'] ?? '—')); ?></div></div>
                <div class="col-md-3"><div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Their signatories</div><div style="font-weight:500;color:#334155;font-size:.82rem;"><?= htmlspecialchars((string)($srcSigning['their_signatories'] ?? '—')); ?></div></div>
                <?php if (!empty($srcSigning['notes'])): ?>
                    <div class="col-12"><div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Notes</div><div style="color:#334155;font-size:.82rem;"><?= htmlspecialchars((string)$srcSigning['notes']); ?></div></div>
                <?php endif; ?>
            </div>
        <?php else: ?>
            <div class="alert py-2 mb-3" style="background:#FEF3C7;border:1px solid #F59E0B;color:#78350F;font-size:.82rem;">
                <i class="fas fa-info-circle me-1"></i>Signing event not yet recorded on the source tender.
            </div>
        <?php endif; ?>

        <!-- Approval history (collapsed) -->
        <?php if (!empty($srcHist)): ?>
            <div class="mt-2" style="border-top:1px dashed #CBD5E1;padding-top:.6rem;">
                <div class="d-flex align-items-center justify-content-between" style="cursor:pointer;" data-bs-toggle="collapse" data-bs-target="#srcApprHist" aria-expanded="false">
                    <strong style="color:#334155;font-size:.8rem;"><i class="fas fa-history me-1" style="color:#7A9E7E;"></i>Approval history</strong>
                    <div class="d-flex align-items-center gap-2">
                        <span class="badge" style="background:#F1F5F9;color:#334155;font-size:.66rem;"><?= count($srcHist); ?> event<?= count($srcHist) === 1 ? '' : 's' ?></span>
                        <i class="fas fa-chevron-down" style="color:#94A3B8;font-size:.7rem;"></i>
                    </div>
                </div>
                <div class="collapse mt-2" id="srcApprHist">
                    <table class="table table-sm mb-0 align-middle" style="background:#fff;">
                        <thead style="background:#F1F5F9;">
                            <tr>
                                <th style="color:#334155;font-size:.7rem;">When</th>
                                <th style="color:#334155;font-size:.7rem;">Step</th>
                                <th style="color:#334155;font-size:.7rem;">Action</th>
                                <th style="color:#334155;font-size:.7rem;">By</th>
                                <th style="color:#334155;font-size:.7rem;">Comment</th>
                            </tr>
                        </thead>
                        <tbody>
                            <?php foreach ($srcHist as $h): ?>
                                <tr>
                                    <td class="small text-muted" style="color:#64748B;"><?= htmlspecialchars((string)$h['created_on']); ?></td>
                                    <td class="small" style="color:#334155;"><?= htmlspecialchars((string)($h['step_label'] ?? '')); ?></td>
                                    <td><span class="badge" style="background:#E2E8F0;color:#334155;font-size:.62rem;text-transform:capitalize;"><?= htmlspecialchars(strtolower((string)$h['action'])); ?></span></td>
                                    <td class="small text-muted" style="color:#64748B;"><?= htmlspecialchars((string)($h['actor_name'] ?? '')); ?></td>
                                    <td class="small text-muted" style="color:#64748B;"><?= htmlspecialchars((string)$h['comment']); ?></td>
                                </tr>
                            <?php endforeach; ?>
                        </tbody>
                    </table>
                </div>
            </div>
        <?php endif; ?>

        <!-- Goods PO baseline link -->
        <?php if ($srcGoodsPo > 0): ?>
            <div class="mt-2" style="border-top:1px dashed #CBD5E1;padding-top:.6rem;">
                <a href="<?= PROOT; ?>GoodsClientPos/view/<?= $srcGoodsPo; ?>" class="text-decoration-none" style="color:#7A9E7E;font-weight:600;font-size:.82rem;">
                    <i class="fas fa-file-contract me-1"></i>Open the sourcing baseline · Client PO snapshotted from tender pricing →
                </a>
            </div>
        <?php endif; ?>
    </div>
</div>
<?php endif; // /8Z-z-A source-tender snapshot revenue-hide ?>

<?php
    // Slice 8Y Cards A + B · goods PM sees tender scope + tender pricing lines.
    $srcItems       = $src['items']         ?? [];
    $srcPricing     = $src['pricing']       ?? null;
    $srcPriceLines  = $src['pricing_lines'] ?? [];
?>

<!-- Card A · Tender scope · what the buyer asked for -->
<?php if (!empty($srcItems)): ?>
<div class="card border-0 shadow-sm mb-3">
    <div class="card-header bg-white d-flex align-items-center justify-content-between" style="border-bottom:1px solid #E2E8F0;cursor:pointer;user-select:none;"
         data-bs-toggle="collapse" data-bs-target="#cardTenderScopeBody" aria-expanded="false" aria-controls="cardTenderScopeBody">
        <div>
            <strong style="color:#334155;"><i class="fas fa-list-ul me-2" style="color:#7A8BA1;"></i>Tender scope · what the buyer asked for</strong>
            <div class="text-muted small mt-1" style="color:#64748B;font-size:.72rem;">Read-only. Original RFP line items on the source tender.</div>
        </div>
        <div class="d-flex align-items-center gap-2">
            <span class="badge" style="background:#F1F5F9;color:#334155;font-size:.72rem;"><?= count($srcItems); ?> line<?= count($srcItems) === 1 ? '' : 's' ?></span>
            <i class="fas fa-chevron-down" style="color:#94A3B8;font-size:.7rem;"></i>
        </div>
    </div>
    <div class="collapse" id="cardTenderScopeBody">
    <div class="table-responsive">
        <table class="table table-sm mb-0 align-middle">
            <thead style="background:#F1F5F9;">
                <tr>
                    <th style="color:#334155;width:60px;">#</th>
                    <th style="color:#334155;">Item ref</th>
                    <th style="color:#334155;">Description</th>
                    <th style="color:#334155;text-align:right;">Qty</th>
                    <th style="color:#334155;">UoM</th>
                    <th style="color:#334155;">Kind</th>
                    <th style="color:#334155;">Spec / notes</th>
                </tr>
            </thead>
            <tbody>
                <?php foreach ($srcItems as $it): ?>
                    <tr>
                        <td class="small text-muted"><?= (int)$it['line_no']; ?></td>
                        <td class="small" style="color:#334155;font-weight:500;"><?= htmlspecialchars((string)($it['item_ref'] ?? '—')); ?></td>
                        <td style="color:#334155;font-size:.85rem;"><?= htmlspecialchars((string)$it['description']); ?></td>
                        <td class="text-end" style="color:#334155;font-weight:500;"><?= rtrim(rtrim(number_format((float)$it['qty'], 4, '.', ','), '0'), '.'); ?></td>
                        <td class="small text-muted"><?= htmlspecialchars((string)($it['uom'] ?? '—')); ?></td>
                        <td><span class="badge" style="background:#EAF2E8;color:#3F5C43;font-size:.62rem;text-transform:capitalize;"><?= htmlspecialchars(strtolower((string)$it['line_kind'])); ?></span></td>
                        <td class="small text-muted" style="color:#64748B;max-width:280px;"><?= htmlspecialchars((string)($it['spec_notes'] ?? '—')); ?></td>
                    </tr>
                <?php endforeach; ?>
            </tbody>
        </table>
    </div>
    </div> <!-- /#cardTenderScopeBody -->
</div>
<?php endif; ?>

<!-- ── Slice 8Z-u · PM's Kickoff Brief · read-only merged view of FM + Exec halves from the linked tender ── -->
<?php
    $kb        = $this->data['kickoff_brief']          ?? [];
    $kbCeiling = $this->data['kickoff_budget_ceiling'] ?? null;
    $kbTid     = (int)($this->data['kickoff_tender_id'] ?? 0);
    if (!empty($kb)):
        if (!class_exists('TenderExecKickoffBrief')) require_once ROOT . '/app/models/TenderExecKickoffBrief.php';
        $priorityColor = ['LOW' => '#94A3B8', 'NORMAL' => '#7A8BA1', 'HIGH' => '#C48579'];
        $priority      = strtoupper((string)($kb['priority'] ?? 'NORMAL'));
        // Group gates + risks so PM sees them at a glance
        $gateGroups = [
            'Financial pre-mobilization gates (FM)' => ['gate_insurance_activated','gate_advance_requested','gate_tra_efiscal_setup','gate_wcf_nssf_verified'],
            'Operational pre-mobilization gates (Executive)' => ['gate_site_visit','gate_mobilization','gate_long_lead','gate_permits','gate_osha_safety_plan'],
        ];
        $riskGroups = [
            'Financial risks (FM)' => ['risk_client_payment','risk_fx_exposure','risk_wcf_nssf_compliance'],
            'Strategic / operational risks (Executive)' => ['risk_tight_schedule','risk_site_access','risk_scope_ambiguity','risk_ppra_reporting'],
        ];
        // Total flagged risks so we can show a warning banner when non-zero
        $flaggedRisks = 0;
        foreach (['risk_client_payment','risk_fx_exposure','risk_wcf_nssf_compliance','risk_tight_schedule','risk_site_access','risk_scope_ambiguity','risk_ppra_reporting'] as $rk) {
            if (!empty($kb[$rk])) $flaggedRisks++;
        }
?>
<div class="card border-0 shadow-sm mb-3" style="border-left:3px solid #7A9E7E !important;">
    <div class="card-header bg-white d-flex align-items-center justify-content-between" style="border-bottom:1px solid #E2E8F0;">
        <div>
            <strong style="color:#334155;"><i class="fas fa-flag-checkered me-2" style="color:#7A9E7E;"></i>Your kickoff brief</strong>
            <div class="text-muted small mt-1" style="color:#64748B;font-size:.72rem;">
                Mandate + guardrails + gates + risks captured by FM and Executive on the linked tender.
                <?php if ($kbTid > 0): ?>
                    <a href="<?= PROOT; ?>Tenders/view/<?= $kbTid; ?>#tab-contract" style="color:#7A8BA1;font-weight:600;">Open tender source →</a>
                <?php endif; ?>
            </div>
        </div>
        <span class="badge" style="background:<?= $priorityColor[$priority] ?? '#7A8BA1'; ?>;color:#fff;font-size:.7rem;font-weight:600;padding:.25rem .55rem;">
            <i class="fas fa-bolt me-1"></i><?= htmlspecialchars($priority); ?> priority
        </span>
    </div>
    <div class="card-body p-3">
        <?php if ($flaggedRisks > 0): ?>
            <div class="alert py-2 mb-3" style="background:#FEF3C7;border:1px solid #F59E0B;color:#78350F;font-size:.78rem;">
                <i class="fas fa-exclamation-triangle me-1"></i>
                <strong><?= $flaggedRisks; ?> risk flag<?= $flaggedRisks === 1 ? '' : 's'; ?></strong> raised on this contract — see below.
            </div>
        <?php endif; ?>

        <!-- ── Kickoff essentials + Guardrails · top row (large kpi tiles) ── -->
        <div class="row g-2 mb-3">
            <div class="col-md-3">
                <div class="p-2" style="background:#F8FAFC;border:1px solid #E2E8F0;border-radius:4px;">
                    <div class="text-muted small" style="color:#64748B;font-size:.62rem;text-transform:capitalize;">Target kickoff</div>
                    <div style="color:#334155;font-weight:600;font-size:.9rem;"><?= htmlspecialchars((string)($kb['target_kickoff_date'] ?? '—')) ?: '—'; ?></div>
                </div>
            </div>
            <div class="col-md-3">
                <div class="p-2" style="background:#F8FAFC;border:1px solid #E2E8F0;border-radius:4px;">
                    <div class="text-muted small" style="color:#64748B;font-size:.62rem;text-transform:capitalize;">Reporting cadence</div>
                    <div style="color:#334155;font-weight:600;font-size:.9rem;"><?= htmlspecialchars((string)($kb['reporting_cadence'] ?? '—')) ?: '—'; ?></div>
                </div>
            </div>
            <div class="col-md-3">
                <div class="p-2" style="background:#F8FAFC;border:1px solid #E2E8F0;border-radius:4px;">
                    <div class="text-muted small" style="color:#64748B;font-size:.62rem;text-transform:capitalize;">Margin floor · escalate if lower</div>
                    <div style="color:#334155;font-weight:600;font-size:.9rem;">
                        <?php if ($kb['margin_floor_pct'] !== null && $kb['margin_floor_pct'] !== ''): ?>
                            <?= number_format((float)$kb['margin_floor_pct'], 2); ?> %
                        <?php else: ?>—<?php endif; ?>
                    </div>
                </div>
            </div>
            <div class="col-md-3">
                <div class="p-2" style="background:#F8FAFC;border:1px solid #E2E8F0;border-radius:4px;">
                    <div class="text-muted small" style="color:#64748B;font-size:.62rem;text-transform:capitalize;">Budget ceiling (auto)</div>
                    <div style="color:#334155;font-weight:600;font-size:.9rem;"><?= $kbCeiling !== null ? number_format((float)$kbCeiling) . ' TZS' : '—'; ?></div>
                </div>
            </div>
        </div>

        <!-- ── Instructions to PM · headline mandate ── -->
        <?php if (!empty($kb['instructions_to_pm'])): ?>
            <div class="mb-3">
                <div class="text-muted small mb-1" style="color:#64748B;font-size:.66rem;text-transform:capitalize;">Instructions from Executive</div>
                <div class="p-2" style="background:#FDF7EC;border-left:3px solid #D4A574;color:#78350F;font-size:.86rem;line-height:1.4;white-space:pre-wrap;"><?= nl2br(htmlspecialchars((string)$kb['instructions_to_pm'])); ?></div>
            </div>
        <?php endif; ?>

        <!-- ── Gates: two-column layout ── -->
        <div class="row g-3 mb-3">
            <?php foreach ($gateGroups as $grpTitle => $grpFields):
                $done = 0; $total = 0;
                foreach ($grpFields as $f) { $total++; if (!empty($kb[$f])) $done++; }
            ?>
                <div class="col-md-6">
                    <div class="p-2" style="background:#F8FAFC;border:1px solid #E2E8F0;border-radius:4px;">
                        <div class="d-flex align-items-center justify-content-between mb-1">
                            <strong style="color:#334155;font-size:.78rem;"><?= htmlspecialchars($grpTitle); ?></strong>
                            <span class="badge" style="background:<?= ($done === $total && $total > 0) ? '#7A9E7E' : '#D4A574'; ?>;color:#fff;font-size:.62rem;font-weight:600;"><?= $done; ?> / <?= $total; ?></span>
                        </div>
                        <?php foreach ($grpFields as $f):
                            $ok  = !empty($kb[$f]);
                            $lbl = TenderExecKickoffBrief::LABELS[$f] ?? $f;
                        ?>
                            <div style="font-size:.76rem;color:<?= $ok ? '#3F5C43' : '#78350F'; ?>;line-height:1.6;">
                                <i class="<?= $ok ? 'fas fa-check-circle' : 'far fa-circle'; ?> me-1" style="color:<?= $ok ? '#7A9E7E' : '#D4A574'; ?>;font-size:.72rem;"></i>
                                <?= htmlspecialchars($lbl); ?>
                            </div>
                        <?php endforeach; ?>
                    </div>
                </div>
            <?php endforeach; ?>
        </div>

        <!-- ── Risk flags: two-column layout ── -->
        <div class="row g-3 mb-3">
            <?php foreach ($riskGroups as $grpTitle => $grpFields):
                $raised = 0; $total = 0;
                foreach ($grpFields as $f) { $total++; if (!empty($kb[$f])) $raised++; }
            ?>
                <div class="col-md-6">
                    <div class="p-2" style="background:#F8FAFC;border:1px solid #E2E8F0;border-radius:4px;">
                        <div class="d-flex align-items-center justify-content-between mb-1">
                            <strong style="color:#334155;font-size:.78rem;"><?= htmlspecialchars($grpTitle); ?></strong>
                            <?php if ($raised > 0): ?>
                                <span class="badge" style="background:#C48579;color:#fff;font-size:.62rem;font-weight:600;"><?= $raised; ?> raised</span>
                            <?php else: ?>
                                <span class="badge" style="background:#F1F5F9;color:#64748B;font-size:.62rem;font-weight:500;">none</span>
                            <?php endif; ?>
                        </div>
                        <?php foreach ($grpFields as $f):
                            $flagged = !empty($kb[$f]);
                            $lbl     = TenderExecKickoffBrief::LABELS[$f] ?? $f;
                        ?>
                            <?php if ($flagged): ?>
                                <div style="font-size:.76rem;color:#8B2727;line-height:1.6;">
                                    <i class="fas fa-exclamation-triangle me-1" style="color:#C48579;font-size:.72rem;"></i>
                                    <?= htmlspecialchars($lbl); ?>
                                </div>
                            <?php else: ?>
                                <div style="font-size:.72rem;color:#94A3B8;line-height:1.6;">
                                    <i class="far fa-check-circle me-1" style="font-size:.7rem;"></i>
                                    <?= htmlspecialchars($lbl); ?>
                                </div>
                            <?php endif; ?>
                        <?php endforeach; ?>
                    </div>
                </div>
            <?php endforeach; ?>
        </div>

        <!-- ── Change-order threshold + escalation contact · footer row ── -->
        <div class="row g-2">
            <?php if ($kb['change_order_threshold_pct'] !== null && $kb['change_order_threshold_pct'] !== ''): ?>
                <div class="col-md-6">
                    <div class="text-muted small" style="color:#64748B;font-size:.66rem;text-transform:capitalize;">Change-order threshold</div>
                    <div style="color:#334155;font-size:.82rem;">Variance ≥ <?= number_format((float)$kb['change_order_threshold_pct'], 2); ?> % of contract requires re-approval.</div>
                </div>
            <?php endif; ?>
            <?php if (!empty($kb['escalation_contact_name'])): ?>
                <div class="col-md-6">
                    <div class="text-muted small" style="color:#64748B;font-size:.66rem;text-transform:capitalize;">Escalation contact</div>
                    <div style="color:#334155;font-size:.82rem;"><i class="fas fa-phone-alt me-1" style="color:#7A8BA1;font-size:.72rem;"></i><?= htmlspecialchars((string)$kb['escalation_contact_name']); ?></div>
                </div>
            <?php endif; ?>
        </div>
    </div>
    <?php if (!empty($kb['fm_edited_on']) || !empty($kb['exec_edited_on'])): ?>
        <div class="card-footer bg-white text-muted small d-flex flex-wrap gap-3" style="border-top:1px solid #E2E8F0;font-size:.66rem;color:#94A3B8;">
            <?php if (!empty($kb['fm_edited_on'])): ?>
                <div><i class="fas fa-university me-1" style="color:#7A8BA1;"></i>FM: <?= htmlspecialchars((string)($kb['fm_edited_by_name'] ?? '')); ?> · <?= htmlspecialchars(date('d M · H:i', strtotime((string)$kb['fm_edited_on']))); ?></div>
            <?php endif; ?>
            <?php if (!empty($kb['exec_edited_on'])): ?>
                <div><i class="fas fa-user-tie me-1" style="color:#7A9E7E;"></i>Exec: <?= htmlspecialchars((string)($kb['exec_edited_by_name'] ?? '')); ?> · <?= htmlspecialchars(date('d M · H:i', strtotime((string)$kb['exec_edited_on']))); ?></div>
            <?php endif; ?>
        </div>
    <?php endif; ?>
</div>
<?php endif; ?>

<!-- ═══════════════════════════════════════════════════════════════════
     Slice 8Z-v · Services PM Workspace (6 cards, only for project_type = services)
     A · Bid answers · confirm
     E · Overheads · carry-over + PM annotations
     B · Coverage register · Sites + Assets
     C · SLA matrix
     F · PM → PC structured instructions
     G · Operational Documents library
     ═══════════════════════════════════════════════════════════════════ -->
<?php if (($p['project_type'] ?? '') === 'services'):
    if (!class_exists('ProjectOpsDocuments')) require_once ROOT . '/app/models/ProjectOpsDocuments.php';
    $svcSpec        = $this->data['svc_spec']          ?? [];
    $svcEquip       = $this->data['svc_equipment']     ?? [];
    $svcContract    = $this->data['svc_contract']      ?? null;
    $svcSites       = $this->data['svc_sites']         ?? [];
    $svcAssets      = $this->data['svc_assets']        ?? [];
    $svcSlas        = $this->data['svc_slas']          ?? [];
    $svcOverheads   = $this->data['svc_overheads']     ?? [];
    $svcOhNotes     = $this->data['svc_oh_notes']      ?? [];
    $svcOpsDocs     = $this->data['svc_ops_docs']      ?? [];
    $svcOpsMand     = $this->data['svc_ops_mandatory'] ?? ['ok'=>false,'missing'=>[],'labels'=>[]];
    $userGroupUpper = strtoupper((string)($_SESSION['user_group_name'] ?? ''));
    $isPm           = (int)($p['project_manager_id'] ?? 0) === (int)($_SESSION['user_id'] ?? -1);
    $isPc           = (int)($p['pc_id']              ?? 0) === (int)($_SESSION['user_id'] ?? -1);
    $isAdmin        = $userGroupUpper === 'ADMINISTRATOR';
    $canPmEdit      = $isPm || $isAdmin;
    $canPcEdit      = $isPc || $isPm || $isAdmin;   // PM can also do PC work if PC unassigned
    $canOpsUpload   = $canPmEdit || $canPcEdit;
    $contractId     = (int)($svcContract['c0d'] ?? 0);
    $specConfirmed  = !empty($svcContract['pm_spec_confirmed_on']);
?>

<!-- ─── A · Bid answers · confirm ─── -->
<div class="card border-0 shadow-sm mb-3" style="border-left:3px solid #7A8BA1 !important;">
    <div class="card-header bg-white d-flex align-items-center justify-content-between" style="border-bottom:1px solid #E2E8F0;">
        <div>
            <strong style="color:#334155;"><i class="fas fa-clipboard-check me-2" style="color:#7A8BA1;"></i>Bid answers &mdash; carried across from tender</strong>
            <div class="text-muted small mt-1" style="color:#64748B;font-size:.72rem;">
                Read-only snapshot of the 10 CRM checklist answers. PM confirms these match execution reality before contract activation.
            </div>
        </div>
        <?php if ($specConfirmed): ?>
            <span class="badge" style="background:#7A9E7E;color:#fff;font-size:.7rem;font-weight:600;padding:.25rem .55rem;"><i class="fas fa-check-circle me-1"></i>Confirmed <?= htmlspecialchars(date('d M · H:i', strtotime((string)$svcContract['pm_spec_confirmed_on']))); ?><?php if (!empty($svcContract['pm_spec_confirmed_by_name'])): ?> · <?= htmlspecialchars((string)$svcContract['pm_spec_confirmed_by_name']); ?><?php endif; ?></span>
        <?php elseif ($canPmEdit && $contractId > 0): ?>
            <button type="button" id="btn_svc_confirm_spec" data-contract-id="<?= $contractId; ?>" class="btn btn-sm" style="background:#7A9E7E;border-color:#7A9E7E;color:#fff;font-weight:600;"><i class="fas fa-check me-1"></i>Confirm spec for execution</button>
        <?php endif; ?>
    </div>
    <div class="card-body p-3">
        <?php if (empty($svcSpec)): ?>
            <div class="alert py-2 mb-0" style="background:#FEF3C7;border:1px solid #F59E0B;color:#78350F;font-size:.78rem;"><i class="fas fa-exclamation-triangle me-1"></i>No tender spec on file — this project may have been created outside the tender flow. PM should refine the contract terms directly.</div>
        <?php else:
            $fmt = function ($v, $suffix = '') { return ($v === null || $v === '') ? '<span style="color:#94A3B8;">—</span>' : htmlspecialchars((string)$v) . $suffix; };
        ?>
            <div class="row g-3">
                <div class="col-md-6">
                    <div class="p-2" style="background:#F8FAFC;border:1px solid #E2E8F0;border-radius:4px;">
                        <div class="text-muted small mb-1" style="color:#64748B;font-size:.62rem;text-transform:capitalize;">Sites &amp; Equipment</div>
                        <div style="font-size:.86rem;color:#334155;"><strong><?= (int)($svcSpec['no_of_sites'] ?? 0); ?></strong> sites <span style="color:#64748B;">·</span> <?= $fmt($svcSpec['sites_notes'] ?? ''); ?></div>
                        <?php if (!empty($svcEquip)): ?>
                            <div class="mt-1" style="font-size:.74rem;color:#334155;">
                                <?php foreach ($svcEquip as $eq): ?>
                                    <span class="badge me-1" style="background:#EEF2F6;color:#334155;font-size:.62rem;border:1px solid #E2E8F0;text-transform:capitalize;font-weight:500;"><?= htmlspecialchars($eq['type']); ?> <?= htmlspecialchars($eq['size']); ?> × <?= (int)$eq['count']; ?></span>
                                <?php endforeach; ?>
                            </div>
                        <?php endif; ?>
                    </div>
                </div>
                <div class="col-md-6">
                    <div class="p-2" style="background:#F8FAFC;border:1px solid #E2E8F0;border-radius:4px;">
                        <div class="text-muted small mb-1" style="color:#64748B;font-size:.62rem;text-transform:capitalize;">PM programme &amp; SLA</div>
                        <div style="font-size:.78rem;color:#334155;">Cadence: <strong><?= $fmt($svcSpec['pm_cadence']); ?></strong> · paid <?= $fmt($svcSpec['pm_payment_structure']); ?></div>
                        <div style="font-size:.78rem;color:#334155;">SLA hrs — EMR <strong><?= $fmt($svcSpec['sla_emergency_hrs']); ?></strong> · URG <strong><?= $fmt($svcSpec['sla_urgent_hrs']); ?></strong> · ROU <strong><?= $fmt($svcSpec['sla_routine_hrs']); ?></strong></div>
                    </div>
                </div>
                <div class="col-md-6">
                    <div class="p-2" style="background:#F8FAFC;border:1px solid #E2E8F0;border-radius:4px;">
                        <div class="text-muted small mb-1" style="color:#64748B;font-size:.62rem;text-transform:capitalize;">Callouts</div>
                        <div style="font-size:.78rem;color:#334155;"><?= !empty($svcSpec['has_callouts']) ? 'Included' : 'Excluded'; ?> · <?= $fmt($svcSpec['callout_payment_structure']); ?></div>
                        <div style="font-size:.78rem;color:#334155;">Fee <strong><?= isset($svcSpec['callout_fee']) ? number_format((float)$svcSpec['callout_fee']) : '—'; ?></strong> TZS · emergency ×<strong><?= $fmt($svcSpec['emergency_multiplier']); ?></strong> · free <strong><?= $fmt($svcSpec['free_callouts_per_month']); ?></strong>/month</div>
                    </div>
                </div>
                <div class="col-md-6">
                    <div class="p-2" style="background:#F8FAFC;border:1px solid #E2E8F0;border-radius:4px;">
                        <div class="text-muted small mb-1" style="color:#64748B;font-size:.62rem;text-transform:capitalize;">Spare policy &amp; pack</div>
                        <div style="font-size:.78rem;color:#334155;"><strong><?= $fmt($svcSpec['spare_policy']); ?></strong> · <?= $fmt($svcSpec['spare_policy_notes'] ?? ''); ?></div>
                        <div style="font-size:.74rem;color:#64748B;"><?= !empty($svcSpec['client_supplied_pack']) ? 'Client-supplied pack' : 'Company-supplied pack'; ?></div>
                    </div>
                </div>
                <div class="col-md-6">
                    <div class="p-2" style="background:#F8FAFC;border:1px solid #E2E8F0;border-radius:4px;">
                        <div class="text-muted small mb-1" style="color:#64748B;font-size:.62rem;text-transform:capitalize;">Invoicing</div>
                        <div style="font-size:.78rem;color:#334155;"><strong><?= $fmt($svcSpec['invoicing_cadence']); ?></strong> · terms <strong><?= $fmt($svcSpec['payment_terms_days']); ?></strong>d</div>
                    </div>
                </div>
                <div class="col-md-6">
                    <div class="p-2" style="background:#F8FAFC;border:1px solid #E2E8F0;border-radius:4px;">
                        <div class="text-muted small mb-1" style="color:#64748B;font-size:.62rem;text-transform:capitalize;">Pricing model</div>
                        <div style="font-size:.78rem;color:#334155;">Labour <strong><?= isset($svcSpec['labour_rate_per_hr']) ? number_format((float)$svcSpec['labour_rate_per_hr']) : '—'; ?></strong>/hr · Mileage <strong><?= isset($svcSpec['mileage_rate_per_km']) ? number_format((float)$svcSpec['mileage_rate_per_km']) : '—'; ?></strong>/km · Parts markup <strong><?= $fmt($svcSpec['parts_markup_pct'], ' %'); ?></strong></div>
                    </div>
                </div>
                <?php if (!empty($svcSpec['general_notes'])): ?>
                    <div class="col-12">
                        <div class="p-2" style="background:#FDF7EC;border-left:3px solid #D4A574;font-size:.78rem;color:#78350F;white-space:pre-wrap;"><i class="fas fa-comment me-1"></i><?= htmlspecialchars((string)$svcSpec['general_notes']); ?></div>
                    </div>
                <?php endif; ?>
            </div>
        <?php endif; ?>
    </div>
</div>

<!-- ─── E · Overheads · carry-over + PM annotations ─── -->
<div class="card border-0 shadow-sm mb-3" style="border-left:3px solid #7A8BA1 !important;">
    <div class="card-header bg-white" style="border-bottom:1px solid #E2E8F0;">
        <strong style="color:#334155;"><i class="fas fa-coins me-2" style="color:#7A8BA1;"></i>Overheads &mdash; carried across from tender bid</strong>
        <div class="text-muted small mt-1" style="color:#64748B;font-size:.72rem;">Bid overhead pool. PM annotates actuals vs bid per line — flags budget slippage early.</div>
    </div>
    <div class="card-body p-0">
        <?php if (empty($svcOverheads)): ?>
            <div class="p-3 text-center text-muted" style="color:#94A3B8;font-size:.78rem;">No tender overhead pool on file.</div>
        <?php else:
            $poolTotal = 0.0; foreach ($svcOverheads as $oh) $poolTotal += (float)$oh['amount'];
        ?>
            <div class="table-responsive">
                <table class="table table-sm mb-0 align-middle">
                    <thead style="background:#F1F5F9;font-size:.68rem;color:#334155;">
                        <tr>
                            <th>Category</th><th>Label</th><th style="width:110px;">Display mode</th>
                            <th class="text-end" style="width:130px;">Bid TZS</th>
                            <th class="text-end" style="width:130px;">PM projected TZS</th>
                            <th>PM notes</th>
                            <?php if ($canPmEdit): ?><th style="width:70px;"></th><?php endif; ?>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach ($svcOverheads as $oh):
                            $tohId  = (int)$oh['c0d'];
                            $note   = $svcOhNotes[$tohId] ?? [];
                            $actual = $note['actual_amount'] ?? '';
                        ?>
                            <tr style="font-size:.78rem;" data-oh-id="<?= $tohId; ?>">
                                <td style="color:#334155;font-weight:500;"><?= htmlspecialchars((string)$oh['category']); ?></td>
                                <td style="color:#334155;"><?= htmlspecialchars((string)$oh['label']); ?></td>
                                <td><span class="badge" style="background:#EEF2F6;color:#334155;font-size:.6rem;font-weight:500;border:1px solid #E2E8F0;text-transform:capitalize;"><?= htmlspecialchars((string)$oh['display_mode']); ?></span></td>
                                <td class="text-end" style="font-family:monospace;color:#334155;"><?= number_format((float)$oh['amount']); ?></td>
                                <td>
                                    <input type="number" step="0.01" class="form-control form-control-sm oh-actual text-end" style="font-family:monospace;" value="<?= htmlspecialchars((string)$actual); ?>" <?= $canPmEdit ? '' : 'disabled'; ?>>
                                </td>
                                <td><input type="text" class="form-control form-control-sm oh-notes" value="<?= htmlspecialchars((string)($note['notes'] ?? '')); ?>" placeholder="Variance reason · actuals so far" <?= $canPmEdit ? '' : 'disabled'; ?>></td>
                                <?php if ($canPmEdit): ?>
                                    <td class="text-end"><button type="button" class="btn btn-sm btn-oh-save" style="background:#7A8BA1;border-color:#7A8BA1;color:#fff;font-weight:600;padding:.15rem .45rem;font-size:.68rem;"><i class="fas fa-save"></i></button></td>
                                <?php endif; ?>
                            </tr>
                        <?php endforeach; ?>
                    </tbody>
                    <tfoot style="background:#F8FAFC;">
                        <tr style="font-size:.76rem;color:#334155;font-weight:600;">
                            <td colspan="3">Pool total</td>
                            <td class="text-end" style="font-family:monospace;"><?= number_format($poolTotal); ?></td>
                            <td colspan="<?= $canPmEdit ? 3 : 2; ?>"></td>
                        </tr>
                    </tfoot>
                </table>
            </div>
        <?php endif; ?>
    </div>
</div>

<!-- ─── B · Coverage register · Sites + Assets ─── -->
<div class="card border-0 shadow-sm mb-3" style="border-left:3px solid #7A8BA1 !important;">
    <div class="card-header bg-white d-flex align-items-center justify-content-between" style="border-bottom:1px solid #E2E8F0;">
        <div>
            <strong style="color:#334155;"><i class="fas fa-map-marked-alt me-2" style="color:#7A8BA1;"></i>Coverage register &mdash; Sites &amp; Assets</strong>
            <div class="text-muted small mt-1" style="color:#64748B;font-size:.72rem;">PC populates the actual site + asset register. Target from bid: <strong><?= (int)($svcSpec['no_of_sites'] ?? 0); ?></strong> sites.</div>
        </div>
        <?php if ($canPcEdit && $contractId > 0): ?>
            <div class="d-flex gap-2">
                <button type="button" id="btn_svc_add_site"  data-contract-id="<?= $contractId; ?>" class="btn btn-sm" style="background:#7A8BA1;border-color:#7A8BA1;color:#fff;font-weight:600;"><i class="fas fa-plus me-1"></i>Add site</button>
                <button type="button" id="btn_svc_add_asset" data-contract-id="<?= $contractId; ?>" class="btn btn-sm" style="background:#7A9E7E;border-color:#7A9E7E;color:#fff;font-weight:600;" <?= empty($svcSites) ? 'disabled title="Add a site first"' : ''; ?>><i class="fas fa-plus me-1"></i>Add asset</button>
            </div>
        <?php endif; ?>
    </div>
    <div class="card-body p-0">
        <?php if ($contractId === 0): ?>
            <div class="p-3 text-center text-muted" style="color:#94A3B8;font-size:.78rem;">No service contract on file — cannot register sites/assets yet.</div>
        <?php else: ?>
            <div class="row g-0">
                <div class="col-md-6" style="border-right:1px solid #E2E8F0;">
                    <div class="p-2" style="background:#F8FAFC;border-bottom:1px solid #E2E8F0;font-size:.72rem;color:#334155;font-weight:600;">Sites <span style="color:#94A3B8;font-weight:400;">(<?= count($svcSites); ?>)</span></div>
                    <?php if (empty($svcSites)): ?>
                        <div class="p-3 text-center text-muted" style="color:#94A3B8;font-size:.74rem;">No sites yet.</div>
                    <?php else: ?>
                        <div class="list-group list-group-flush">
                            <?php foreach ($svcSites as $s): ?>
                                <div class="list-group-item p-2" style="border-color:#E2E8F0;font-size:.78rem;">
                                    <div class="d-flex align-items-start justify-content-between">
                                        <div>
                                            <strong style="color:#334155;"><?= htmlspecialchars((string)$s['name']); ?></strong>
                                            <?php if (!empty($s['site_code'])): ?><span class="badge ms-1" style="background:#EEF2F6;color:#334155;font-size:.6rem;font-family:monospace;border:1px solid #E2E8F0;"><?= htmlspecialchars((string)$s['site_code']); ?></span><?php endif; ?>
                                            <div class="small" style="color:#64748B;font-size:.68rem;"><?= htmlspecialchars(trim(($s['region'] ?? '') . ' · ' . ($s['physical_address'] ?? ''), ' ·')); ?></div>
                                        </div>
                                        <?php if ($canPcEdit): ?><button type="button" class="btn btn-sm btn-svc-site-del" data-site-id="<?= (int)$s['c0d']; ?>" style="background:transparent;border:none;color:#C48579;padding:0;font-size:.72rem;"><i class="fas fa-times"></i></button><?php endif; ?>
                                    </div>
                                </div>
                            <?php endforeach; ?>
                        </div>
                    <?php endif; ?>
                </div>
                <div class="col-md-6">
                    <div class="p-2" style="background:#F8FAFC;border-bottom:1px solid #E2E8F0;font-size:.72rem;color:#334155;font-weight:600;">Assets <span style="color:#94A3B8;font-weight:400;">(<?= count($svcAssets); ?>)</span></div>
                    <?php if (empty($svcAssets)): ?>
                        <div class="p-3 text-center text-muted" style="color:#94A3B8;font-size:.74rem;">No assets yet.</div>
                    <?php else: ?>
                        <div class="list-group list-group-flush">
                            <?php foreach ($svcAssets as $a): ?>
                                <div class="list-group-item p-2" style="border-color:#E2E8F0;font-size:.78rem;">
                                    <div class="d-flex align-items-start justify-content-between">
                                        <div>
                                            <strong style="color:#334155;"><?= htmlspecialchars((string)($a['name'] ?? $a['asset_type'] ?? 'Asset')); ?></strong>
                                            <?php if (!empty($a['serial_no'])): ?><span class="badge ms-1" style="background:#EEF2F6;color:#334155;font-size:.6rem;font-family:monospace;border:1px solid #E2E8F0;"><?= htmlspecialchars((string)$a['serial_no']); ?></span><?php endif; ?>
                                            <div class="small" style="color:#64748B;font-size:.68rem;"><?= htmlspecialchars(trim(($a['make'] ?? '') . ' ' . ($a['model'] ?? ''))); ?><?php if (!empty($a['rating'])): ?> · <?= htmlspecialchars((string)$a['rating']); ?><?php endif; ?></div>
                                        </div>
                                        <?php if ($canPcEdit): ?><button type="button" class="btn btn-sm btn-svc-asset-del" data-asset-id="<?= (int)$a['c0d']; ?>" style="background:transparent;border:none;color:#C48579;padding:0;font-size:.72rem;"><i class="fas fa-times"></i></button><?php endif; ?>
                                    </div>
                                </div>
                            <?php endforeach; ?>
                        </div>
                    <?php endif; ?>
                </div>
            </div>
        <?php endif; ?>
    </div>
</div>

<!-- ─── C · SLA matrix ─── -->
<div class="card border-0 shadow-sm mb-3" style="border-left:3px solid #7A8BA1 !important;">
    <div class="card-header bg-white d-flex align-items-center justify-content-between" style="border-bottom:1px solid #E2E8F0;">
        <div>
            <strong style="color:#334155;"><i class="fas fa-stopwatch me-2" style="color:#7A8BA1;"></i>SLA matrix</strong>
            <div class="text-muted small mt-1" style="color:#64748B;font-size:.72rem;">Response &amp; resolve targets per severity. Pre-fill from bid, refine per signed terms.</div>
        </div>
        <?php if ($canPcEdit && $contractId > 0 && empty($svcSlas) && !empty($svcSpec)): ?>
            <button type="button" id="btn_svc_seed_slas" data-contract-id="<?= $contractId; ?>" data-tender-id="<?= (int)($svcSpec['tender_id'] ?? 0); ?>" class="btn btn-sm" style="background:#7A9E7E;border-color:#7A9E7E;color:#fff;font-weight:600;"><i class="fas fa-magic me-1"></i>Seed from bid</button>
        <?php endif; ?>
    </div>
    <div class="card-body p-0">
        <?php if ($contractId === 0): ?>
            <div class="p-3 text-center text-muted" style="color:#94A3B8;font-size:.78rem;">No service contract on file.</div>
        <?php elseif (empty($svcSlas)): ?>
            <div class="p-3 text-center text-muted" style="color:#94A3B8;font-size:.78rem;">No SLA rows yet. <?= empty($svcSpec) ? '' : 'Use <strong>Seed from bid</strong> to populate from the tender answers.'; ?></div>
        <?php else: ?>
            <div class="table-responsive">
                <table class="table table-sm mb-0 align-middle">
                    <thead style="background:#F1F5F9;font-size:.68rem;color:#334155;">
                        <tr><th>Severity</th><th class="text-end">Response (hrs)</th><th class="text-end">Resolve (hrs)</th><th>Notes</th></tr>
                    </thead>
                    <tbody>
                        <?php foreach ($svcSlas as $sla): ?>
                            <tr style="font-size:.78rem;">
                                <td><strong style="color:#334155;"><?= htmlspecialchars((string)$sla['severity']); ?></strong></td>
                                <td class="text-end" style="font-family:monospace;color:#334155;"><?= (int)$sla['response_target_hrs']; ?></td>
                                <td class="text-end" style="font-family:monospace;color:#334155;"><?= (int)$sla['resolve_target_hrs']; ?></td>
                                <td style="color:#64748B;font-size:.74rem;"><?= htmlspecialchars((string)($sla['notes'] ?? '')); ?></td>
                            </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            </div>
        <?php endif; ?>
    </div>
</div>

<!-- ─── Slice 8Z-y · Service Scope Configuration · Vue 3 Options API root (no page reloads) ─── -->
<?php
    $svcBindings   = $this->data['svc_bindings']       ?? [];
    $svcPacks      = $this->data['svc_packs']          ?? [];
    $svcTplFlat    = $this->data['svc_templates_flat'] ?? [];
    // Seed the equipment mix from confirmed scope OR fall back to bid spec
    $confirmedEquipJson = (string)($svcContract['equipment_scope_confirmed_json'] ?? '');
    $confirmedEquip     = $confirmedEquipJson !== '' ? (json_decode($confirmedEquipJson, true) ?: []) : [];
    $effectiveEquip     = !empty($confirmedEquip) ? $confirmedEquip : $svcEquip;
    $sitesTarget        = ($svcContract['sites_target_confirmed'] ?? null);
    if ($sitesTarget === null || $sitesTarget === '') $sitesTarget = (int)($svcSpec['no_of_sites'] ?? 0);
    $CID                = (int)($svcContract['c0d'] ?? 0);

    // Slice 8Z-z-A · Sites & installed-equipment counts for the summary strip.
    $equipTarget = 0;
    foreach ($effectiveEquip as $eq) $equipTarget += (int)($eq['count'] ?? 0);
    $sitesActual = 0; $sitesConfirmed = 0; $assetsActual = 0;
    if ($CID > 0) {
        $__db = new DB();
        $rS = $__db->mySelect(
            "SELECT COUNT(*) AS n_total, SUM(poc_confirmed_on IS NOT NULL) AS n_conf
               FROM service_contract_sites WHERE contract_id = :c AND is_active = 1",
            [':c' => $CID]
        );
        $sitesActual    = (int)($rS[0]['n_total'] ?? 0);
        $sitesConfirmed = (int)($rS[0]['n_conf']  ?? 0);
        $rA = $__db->mySelect(
            "SELECT COUNT(*) AS n FROM service_contract_assets WHERE contract_id = :c AND is_active = 1",
            [':c' => $CID]
        );
        $assetsActual = (int)($rA[0]['n'] ?? 0);
    }
?>

<!-- ── 8Z-z-A · Sites & installed-equipment summary strip ── -->
<div class="card border-0 shadow-sm mb-3" style="border-left:3px solid #D4A574 !important;">
    <div class="card-body py-2 px-3 d-flex align-items-center flex-wrap">
        <div class="me-4">
            <div style="color:#94A3B8;font-size:.6rem;letter-spacing:.4px;text-transform:uppercase;font-weight:600;">Sites &amp; installed equipment</div>
            <div style="color:#334155;font-weight:600;font-size:.86rem;">
                <i class="fas fa-map-marked-alt me-1" style="color:#D4A574;"></i>
                <?= $sitesActual; ?><?= $sitesTarget ? '<span style="color:#94A3B8;font-weight:500;font-size:.72rem;"> of ' . (int)$sitesTarget . '</span>' : ''; ?> sites
                &nbsp;·&nbsp;
                <?= $sitesConfirmed; ?> POC confirmed
                &nbsp;·&nbsp;
                <?= $assetsActual; ?><?= $equipTarget ? '<span style="color:#94A3B8;font-weight:500;font-size:.72rem;"> of ' . (int)$equipTarget . '</span>' : ''; ?> equipment units
            </div>
        </div>
        <div class="ms-auto">
            <a href="<?= PROOT; ?>Projects/sites/<?= (int)$p['c0d']; ?>" class="btn btn-sm" style="background:#D4A574;border-color:#D4A574;color:#fff;font-weight:600;">
                <i class="fas fa-map-pin me-1"></i>Manage sites
            </a>
        </div>
    </div>
</div>
<div id="svc_scope_root" v-cloak class="card border-0 shadow-sm mb-3" style="border-left:3px solid #7A9E7E !important;">
    <div class="card-header bg-white" style="border-bottom:1px solid #E2E8F0;">
        <strong style="color:#334155;"><i class="fas fa-tasks me-2" style="color:#7A9E7E;"></i>Service scope configuration &mdash; PM to PC</strong>
        <div class="text-muted small mt-1" style="color:#64748B;font-size:.72rem;">Confirm scope from bid · bind templates per equipment class · define the spare-part schedule · additional notes.</div>
    </div>
    <div class="card-body p-0">

        <!-- ── Y-A · Confirm scope (Vue) ───────────────────────────── -->
        <div class="p-3" style="background:#F8FAFC;border-bottom:1px solid #E2E8F0;">
            <div class="d-flex align-items-center justify-content-between mb-2">
                <div>
                    <strong style="color:#334155;font-size:.86rem;">A · Confirm scope from bid</strong>
                    <span v-if="scopeConfirmedOn" class="badge ms-2" style="background:#7A9E7E;color:#fff;font-size:.62rem;font-weight:600;">
                        <i class="fas fa-check-circle me-1"></i>Confirmed {{ fmtConfirmed }}<span v-if="scopeConfirmedByName"> · {{ scopeConfirmedByName }}</span>
                    </span>
                </div>
                <button v-if="canPmEdit && CID > 0" type="button" @click="saveScope" :disabled="savingScope"
                        class="btn btn-sm" style="background:#7A9E7E;border-color:#7A9E7E;color:#fff;font-weight:600;">
                    <i class="fas" :class="savingScope ? 'fa-spinner fa-spin' : 'fa-save'"></i>
                    <span class="ms-1">{{ savingScope ? 'Saving…' : 'Save scope' }}</span>
                </button>
            </div>
            <div class="row g-3">
                <div class="col-md-3">
                    <label class="form-label" style="color:#64748B;font-size:.68rem;text-transform:capitalize;font-weight:600;">Sites target</label>
                    <input type="number" min="0" v-model.number="sitesTarget" :disabled="!canPmEdit" class="form-control form-control-sm">
                    <div v-if="bidSites" class="small mt-1" style="color:#94A3B8;font-size:.62rem;">Bid stated {{ bidSites }} sites</div>
                </div>
                <div class="col-md-9">
                    <label class="form-label" style="color:#64748B;font-size:.68rem;text-transform:capitalize;font-weight:600;">Equipment mix (confirmed)</label>
                    <div class="mb-1">
                        <span v-if="!equipMix.length" class="small" style="color:#94A3B8;font-size:.72rem;">No equipment on file — click Edit to add.</span>
                        <span v-for="(eq, i) in equipMix" :key="'eq_'+i" class="badge me-1 mb-1" style="background:#EEF2F6;color:#334155;font-size:.66rem;border:1px solid #E2E8F0;padding:.15rem .5rem;font-weight:500;text-transform:capitalize;">
                            {{ eq.type }} {{ eq.size }} × {{ eq.count }}
                        </span>
                    </div>
                    <button v-if="canPmEdit" type="button" @click="openEditEquipMix"
                            class="btn btn-sm" style="background:transparent;border:1px dashed #7A8BA1;color:#7A8BA1;font-size:.66rem;padding:.15rem .5rem;font-weight:500;">
                        <i class="fas fa-pencil-alt me-1"></i>Edit equipment mix
                    </button>
                </div>
            </div>
        </div>

        <!-- ── Y-B · Template bindings per equipment class (Vue) ──── -->
        <div class="p-3" style="border-bottom:1px solid #E2E8F0;">
            <div class="d-flex align-items-center justify-content-between mb-2">
                <div>
                    <strong style="color:#334155;font-size:.86rem;">B · Templates per equipment class</strong>
                    <span class="text-muted ms-2" style="color:#94A3B8;font-size:.68rem;">Coverage matrix — feeds PM schedule generation.</span>
                </div>
                <button v-if="canPmEdit && CID > 0 && equipMix.length" type="button" @click="bindingAutoSuggestAll"
                        class="btn btn-sm" style="background:#7A8BA1;border-color:#7A8BA1;color:#fff;font-weight:600;">
                    <i class="fas fa-magic me-1"></i>Auto-suggest defaults
                </button>
            </div>
            <div v-if="CID === 0" class="p-3 text-center" style="color:#94A3B8;font-size:.72rem;">No service contract on file — cannot bind templates.</div>
            <div v-else-if="!equipMix.length" class="p-3 text-center" style="color:#94A3B8;font-size:.72rem;">Confirm equipment mix in section A first.</div>
            <template v-else>
                <div v-for="(eq, i) in equipMix" :key="'cls_'+i" class="mb-2 p-2" style="background:#F8FAFC;border:1px solid #E2E8F0;border-radius:4px;">
                    <div class="d-flex align-items-center justify-content-between mb-1">
                        <div>
                            <strong style="color:#334155;font-size:.78rem;text-transform:capitalize;">{{ classLabel(eq) }}</strong>
                            <span class="text-muted ms-1" style="color:#94A3B8;font-size:.66rem;">{{ eq.count }} unit(s)</span>
                        </div>
                        <div v-if="canPmEdit">
                            <button type="button" @click="openBindingAdd(classLabel(eq), eq.count)"
                                    class="btn btn-sm" style="background:transparent;border:1px solid #7A8BA1;color:#7A8BA1;font-size:.62rem;padding:.1rem .4rem;">
                                <i class="fas fa-plus me-1"></i>Add template
                            </button>
                            <button type="button" @click="openBindingSuggest(classLabel(eq), eq.count)"
                                    class="btn btn-sm" style="background:transparent;border:1px solid #7A9E7E;color:#7A9E7E;font-size:.62rem;padding:.1rem .4rem;">
                                <i class="fas fa-magic me-1"></i>Suggest
                            </button>
                        </div>
                    </div>
                    <div v-if="!bindingsByClass(classLabel(eq)).length" class="small" style="color:#94A3B8;font-size:.7rem;">
                        No templates bound. Click <strong>Suggest</strong> to auto-add matching templates from the catalog.
                    </div>
                    <div v-else>
                        <span v-for="b in bindingsByClass(classLabel(eq))" :key="'b_'+b.c0d"
                              class="badge me-1 mb-1" style="background:#fff;color:#334155;border:1px solid #E2E8F0;font-size:.68rem;font-weight:500;padding:.2rem .55rem;">
                            <code style="color:#7A8BA1;font-size:.66rem;background:#EEF2F6;padding:.05rem .25rem;border-radius:2px;">{{ b.slug }}</code>
                            <span class="ms-1" style="color:#64748B;font-size:.66rem;">{{ b.template_label }}</span>
                            <span v-if="cadenceNote(b)" class="ms-1" style="color:#94A3B8;font-size:.6rem;">· {{ cadenceNote(b) }}</span>
                            <button v-if="canPmEdit" type="button" @click="removeBinding(b)"
                                    class="btn btn-sm ms-1" style="background:transparent;border:none;color:#C48579;padding:0;font-size:.62rem;">
                                <i class="fas fa-times"></i>
                            </button>
                        </span>
                    </div>
                </div>
            </template>
        </div>

        <!-- ── Y-C · Spare part schedule (Vue) ─────────────────────── -->
        <div class="p-3" style="border-bottom:1px solid #E2E8F0;">
            <div class="d-flex align-items-center justify-content-between mb-2">
                <div>
                    <strong style="color:#334155;font-size:.86rem;">C · Spare part schedule</strong>
                    <span class="text-muted ms-2" style="color:#94A3B8;font-size:.68rem;">Contract-level policy: <strong>{{ sparePolicy || '—' }}</strong>. Per-pack supply model may differ.</span>
                </div>
                <button v-if="canPmEdit && CID > 0" type="button" @click="openPackAdd"
                        class="btn btn-sm" style="background:#7A8BA1;border-color:#7A8BA1;color:#fff;font-weight:600;">
                    <i class="fas fa-plus me-1"></i>Add pack
                </button>
            </div>
            <div v-if="CID === 0" class="p-3 text-center" style="color:#94A3B8;font-size:.72rem;">No service contract on file — cannot register packs.</div>
            <div v-else-if="!packs.length" class="p-3 text-center" style="color:#94A3B8;font-size:.72rem;">No packs defined yet. Click <strong>Add pack</strong> to start.</div>
            <template v-else>
                <div v-for="pk in packs" :key="'pk_'+pk.c0d" class="mb-2 p-2" style="background:#F8FAFC;border:1px solid #E2E8F0;border-radius:4px;">
                    <div class="d-flex align-items-center justify-content-between mb-1">
                        <div>
                            <strong style="color:#334155;font-size:.78rem;">{{ pk.name }}</strong>
                            <span class="badge ms-1" :style="'background:' + supplyColor(pk.supply_model) + ';color:#fff;font-size:.6rem;font-weight:600;padding:.1rem .35rem;text-transform:capitalize;'">
                                {{ pk.supply_model }}
                            </span>
                            <code v-if="pk.linked_template_slug" class="ms-1" style="color:#7A8BA1;font-size:.66rem;">{{ pk.linked_template_slug }}</code>
                        </div>
                        <div v-if="canPmEdit">
                            <button type="button" @click="openItemAdd(pk.c0d)"
                                    class="btn btn-sm" style="background:transparent;border:1px solid #7A9E7E;color:#7A9E7E;font-size:.62rem;padding:.1rem .4rem;">
                                <i class="fas fa-plus me-1"></i>Add item
                            </button>
                            <button type="button" @click="openPackEdit(pk)"
                                    class="btn btn-sm" style="background:transparent;border:none;color:#7A8BA1;font-size:.62rem;padding:.1rem .3rem;">
                                <i class="fas fa-pencil-alt"></i>
                            </button>
                            <button type="button" @click="removePack(pk)"
                                    class="btn btn-sm" style="background:transparent;border:none;color:#C48579;font-size:.62rem;padding:.1rem .3rem;">
                                <i class="fas fa-times"></i>
                            </button>
                        </div>
                    </div>
                    <div v-if="!pk.items || !pk.items.length" class="small ps-2" style="color:#94A3B8;font-size:.7rem;">No items yet.</div>
                    <table v-else class="table table-sm mb-0" style="font-size:.74rem;background:transparent;">
                        <tbody>
                            <tr v-for="it in pk.items" :key="'it_'+it.c0d">
                                <td style="width:130px;color:#64748B;font-size:.68rem;">{{ it.interval_label }}</td>
                                <td style="color:#334155;">{{ it.item_name }}</td>
                                <td style="width:80px;text-align:right;color:#334155;font-family:monospace;">{{ fmtQty(it.qty) }}</td>
                                <td style="width:60px;color:#64748B;font-size:.68rem;">{{ it.uom }}</td>
                                <td style="color:#64748B;font-size:.66rem;">{{ it.notes }}</td>
                                <td v-if="canPmEdit" style="width:60px;text-align:right;">
                                    <button type="button" @click="openItemEdit(it)" class="btn btn-sm" style="background:transparent;border:none;color:#7A8BA1;font-size:.62rem;padding:0;"><i class="fas fa-pencil-alt"></i></button>
                                    <button type="button" @click="removeItem(it)" class="btn btn-sm" style="background:transparent;border:none;color:#C48579;font-size:.62rem;padding:0;"><i class="fas fa-times"></i></button>
                                </td>
                            </tr>
                        </tbody>
                    </table>
                </div>
            </template>
        </div>

        <!-- ── Y-E · Additional PC instructions ────────────────────── -->
        <div class="p-3">
            <div class="d-flex align-items-center justify-content-between mb-2">
                <strong style="color:#334155;font-size:.86rem;">E · Additional PC instructions</strong>
                <?php if ($canPmEdit): ?><button type="button" id="btn_svc_instr_save" class="btn btn-sm" style="background:#7A9E7E;border-color:#7A9E7E;color:#fff;font-weight:600;"><i class="fas fa-save me-1"></i>Save instructions</button><?php endif; ?>
            </div>
            <fieldset <?= $canPmEdit ? '' : 'disabled'; ?> id="svc_instr_form">
                <div class="mb-2">
                    <label class="form-label" style="color:#64748B;font-size:.68rem;text-transform:capitalize;font-weight:600;">Site onboarding priority &amp; batching</label>
                    <textarea name="sites_instructions" rows="2" class="form-control form-control-sm" placeholder="e.g. Batch 1: 10 Coast sites first (highest revenue). Batch 2: Dar. Batch 3: Morogoro. Photograph every genset serial."><?= htmlspecialchars((string)($p['pm_svc_sites_instructions'] ?? '')); ?></textarea>
                </div>
                <div class="mb-2">
                    <label class="form-label" style="color:#64748B;font-size:.68rem;text-transform:capitalize;font-weight:600;">Team &amp; resources to assemble</label>
                    <textarea name="team_instructions" rows="2" class="form-control form-control-sm" placeholder="e.g. 2 FS techs (basic + advanced elec cert). 2 pickups. Toolbox with IR thermometer + torque wrench. NOC coverage 8-5 weekdays."><?= htmlspecialchars((string)($p['pm_svc_team_instructions'] ?? '')); ?></textarea>
                </div>
                <div>
                    <label class="form-label" style="color:#64748B;font-size:.68rem;text-transform:capitalize;font-weight:600;">Other notes for PC</label>
                    <textarea name="templates_needed" rows="2" class="form-control form-control-sm" placeholder="Anything else PC needs to know — special reporting cadence, client preferences, edge cases."><?= htmlspecialchars((string)($p['pm_svc_templates_needed'] ?? '')); ?></textarea>
                </div>
            </fieldset>
        </div>
    </div>
</div>

<!-- ─── G · Operational Documents library ─── -->
<div class="card border-0 shadow-sm mb-3" style="border-left:3px solid #D4A574 !important;">
    <div class="card-header bg-white d-flex align-items-center justify-content-between" style="border-bottom:1px solid #E2E8F0;">
        <div>
            <strong style="color:#334155;"><i class="fas fa-folder-open me-2" style="color:#D4A574;"></i>Operational documents</strong>
            <div class="text-muted small mt-1" style="color:#64748B;font-size:.72rem;">
                Signed contract · CAR / Workers Comp / vehicle insurance · WCF · NSSF · OSHA method statement · TRA e-fiscal cert · site permits · HSE plan.
                <strong>Mandatory for activation:</strong> the 7 starred subtypes.
            </div>
        </div>
        <?php
            $mCnt = 0; foreach (ProjectOpsDocuments::SUBTYPES as $m) if (!empty($m['mandatory'])) $mCnt++;
            $done = max(0, $mCnt - count($svcOpsMand['missing'] ?? []));
        ?>
        <div class="d-flex align-items-center gap-2">
            <span class="badge" style="background:<?= !empty($svcOpsMand['ok']) ? '#7A9E7E' : '#D4A574'; ?>;color:#fff;font-size:.66rem;font-weight:600;padding:.25rem .55rem;"><?= $done; ?> / <?= $mCnt; ?> mandatory</span>
            <?php if ($canOpsUpload): ?><button type="button" id="btn_ops_upload" data-project-id="<?= (int)$p['c0d']; ?>" class="btn btn-sm" style="background:#7A8BA1;border-color:#7A8BA1;color:#fff;font-weight:600;"><i class="fas fa-upload me-1"></i>Upload</button><?php endif; ?>
        </div>
    </div>
    <div class="card-body p-0">
        <?php if (empty($svcOpsMand['ok'])): ?>
            <div class="p-2" style="background:#FDF7EC;border-bottom:1px solid #F0DEBB;color:#8B6914;font-size:.74rem;">
                <i class="fas fa-exclamation-triangle me-1" style="color:#D4A574;"></i>
                Missing before contract activation: <strong><?= htmlspecialchars(implode(', ', $svcOpsMand['labels'] ?? [])); ?></strong>
            </div>
        <?php endif; ?>
        <?php if (empty($svcOpsDocs)): ?>
            <div class="p-3 text-center text-muted" style="color:#94A3B8;font-size:.78rem;">Nothing uploaded yet.</div>
        <?php else: ?>
            <div class="table-responsive">
                <table class="table table-sm mb-0 align-middle">
                    <thead style="background:#F1F5F9;font-size:.68rem;color:#334155;">
                        <tr><th>Subtype</th><th>File</th><th style="width:110px;">Valid until</th><th>Uploaded</th><th style="width:100px;"></th></tr>
                    </thead>
                    <tbody>
                        <?php foreach ($svcOpsDocs as $d):
                            $sub  = (string)$d['subtype'];
                            $mand = !empty(ProjectOpsDocuments::SUBTYPES[$sub]['mandatory'] ?? false);
                            $lbl  = (string)(ProjectOpsDocuments::SUBTYPES[$sub]['label'] ?? $sub);
                        ?>
                            <tr style="font-size:.78rem;">
                                <td>
                                    <span class="badge" style="background:<?= $mand ? '#EEF2F6' : '#F1F5F9'; ?>;color:#334155;border:1px solid <?= $mand ? '#7A8BA1' : '#E2E8F0'; ?>;font-size:.62rem;text-transform:capitalize;"><?= htmlspecialchars($lbl); ?><?php if ($mand): ?> <i class="fas fa-star ms-1" style="color:#D4A574;font-size:.56rem;" title="Mandatory"></i><?php endif; ?></span>
                                </td>
                                <td>
                                    <a href="<?= PROOT; ?>Projects/opsDocPreview/<?= (int)$d['c0d']; ?>" target="_blank" style="color:#7A8BA1;text-decoration:none;font-size:.72rem;"><i class="fas fa-file me-1"></i><?= htmlspecialchars((string)$d['original_filename']); ?></a>
                                    <span class="small ms-1" style="color:#94A3B8;font-size:.62rem;">(<?= number_format((int)$d['size_bytes'] / 1024, 1); ?> KB)</span>
                                </td>
                                <td style="color:<?= !empty($d['validity_until']) ? '#334155' : '#94A3B8'; ?>;font-size:.72rem;"><?= htmlspecialchars((string)($d['validity_until'] ?? '')) ?: '—'; ?></td>
                                <td style="color:#64748B;font-size:.66rem;"><?= htmlspecialchars((string)($d['uploaded_by_name'] ?? '')); ?><br><span style="font-size:.6rem;color:#94A3B8;"><?= htmlspecialchars(date('d M · H:i', strtotime((string)$d['uploaded_on']))); ?></span></td>
                                <td class="text-end">
                                    <a href="<?= PROOT; ?>Projects/opsDocDownload/<?= (int)$d['c0d']; ?>" class="btn btn-sm" style="background:transparent;border:none;color:#7A8BA1;padding:.15rem;" title="Download"><i class="fas fa-download"></i></a>
                                    <?php if ($canOpsUpload): ?><button type="button" class="btn btn-sm btn-ops-del" data-doc-id="<?= (int)$d['c0d']; ?>" style="background:transparent;border:none;color:#C48579;padding:.15rem;" title="Remove"><i class="fas fa-times"></i></button><?php endif; ?>
                                </td>
                            </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            </div>
        <?php endif; ?>
    </div>
</div>

<!-- ─── Slice 8Z-x · Service templates catalog · reference library (visible to ALL viewers) ─── -->
<?php
    $svcTplGroupedFull = $this->data['svc_templates_grouped']  ?? [];
    $svcCalloutRes     = $this->data['svc_callout_res_grouped'] ?? [];
    $totalTemplates    = 0; foreach ($svcTplGroupedFull as $rows) $totalTemplates += count($rows);
    $totalItemsAllTpl  = 0; foreach ($svcTplGroupedFull as $rows) foreach ($rows as $r) $totalItemsAllTpl += (int)($r['item_count'] ?? 0);
    $totalCallouts     = 0; foreach ($svcCalloutRes as $rows) $totalCallouts += count($rows);
?>
<div class="card border-0 shadow-sm mb-3" style="border-left:3px solid #7A8BA1 !important;">
    <div class="card-header bg-white d-flex align-items-center justify-content-between" style="border-bottom:1px solid #E2E8F0;">
        <div>
            <strong style="color:#334155;"><i class="fas fa-book me-2" style="color:#7A8BA1;"></i>Service templates catalog &mdash; reference library</strong>
            <div class="text-muted small mt-1" style="color:#64748B;font-size:.72rem;">
                Proven PM / callout / resolution templates ported from sitetracker16 production.
                <strong><?= $totalTemplates; ?></strong> templates &middot; <strong><?= $totalItemsAllTpl; ?></strong> checklist items &middot; <strong><?= $totalCallouts; ?></strong> callout closure patterns.
                Click any row for the full item list.
            </div>
        </div>
        <span class="badge" style="background:#EEF2F6;color:#334155;font-size:.66rem;font-weight:600;border:1px solid #E2E8F0;">Read-only reference</span>
    </div>
    <div class="card-body p-0">
        <?php if (empty($svcTplGroupedFull)): ?>
            <div class="p-3 text-center text-muted" style="color:#94A3B8;font-size:.78rem;">Catalog is empty. Ask Admin to seed it.</div>
        <?php else: ?>
            <?php foreach ($svcTplGroupedFull as $grpLbl => $grpRows): ?>
                <div class="p-2" style="background:#F8FAFC;border-bottom:1px solid #E2E8F0;font-size:.68rem;color:#334155;font-weight:600;text-transform:capitalize;letter-spacing:.3px;"><?= htmlspecialchars($grpLbl); ?></div>
                <div class="table-responsive">
                    <table class="table table-sm mb-0 align-middle">
                        <tbody>
                            <?php foreach ($grpRows as $tpl): ?>
                                <tr style="font-size:.78rem;cursor:pointer;" class="tpl-cat-row" data-tpl-id="<?= (int)$tpl['c0d']; ?>">
                                    <td style="width:160px;">
                                        <code style="color:#7A8BA1;font-size:.72rem;background:#EEF2F6;padding:.1rem .35rem;border-radius:2px;"><?= htmlspecialchars((string)$tpl['slug']); ?></code>
                                    </td>
                                    <td>
                                        <div style="color:#334155;font-weight:500;"><?= htmlspecialchars((string)$tpl['label']); ?></div>
                                        <div class="small" style="color:#64748B;font-size:.68rem;line-height:1.35;"><?= htmlspecialchars((string)$tpl['description']); ?></div>
                                    </td>
                                    <td style="width:100px;color:#64748B;font-size:.68rem;"><?= htmlspecialchars((string)$tpl['scope']); ?></td>
                                    <td style="width:140px;color:#64748B;font-size:.68rem;"><?= htmlspecialchars((string)($tpl['cadence_note'] ?? '')); ?></td>
                                    <td class="text-end" style="width:110px;">
                                        <span class="badge" style="background:#F1F5F9;color:#334155;font-size:.62rem;border:1px solid #E2E8F0;font-weight:500;"><?= (int)$tpl['item_count']; ?> items</span>
                                    </td>
                                    <td class="text-end" style="width:80px;">
                                        <button type="button" class="btn btn-sm btn-tpl-view" data-tpl-id="<?= (int)$tpl['c0d']; ?>" style="background:transparent;border:1px solid #7A8BA1;color:#7A8BA1;font-size:.66rem;padding:.1rem .5rem;font-weight:600;"><i class="fas fa-eye me-1"></i>View</button>
                                    </td>
                                </tr>
                            <?php endforeach; ?>
                        </tbody>
                    </table>
                </div>
            <?php endforeach; ?>

            <?php if (!empty($svcCalloutRes)): ?>
                <div class="p-2" style="background:#F8FAFC;border-top:1px solid #E2E8F0;border-bottom:1px solid #E2E8F0;font-size:.68rem;color:#334155;font-weight:600;text-transform:capitalize;letter-spacing:.3px;">
                    Callout resolution patterns · pick a closure recipe when logging a callout
                </div>
                <div class="table-responsive">
                    <table class="table table-sm mb-0 align-middle">
                        <thead style="background:#FAFBFC;font-size:.62rem;color:#64748B;text-transform:capitalize;">
                            <tr><th style="width:110px;">Category</th><th style="width:180px;">Code</th><th>Title</th><th>Root cause</th><th>Action taken</th><th style="width:120px;">Fault status</th></tr>
                        </thead>
                        <tbody>
                            <?php foreach ($svcCalloutRes as $cat => $rows):
                                foreach ($rows as $r):
                                    $statusColor = ['FIXED'=>'#7A9E7E','MONITORING'=>'#D4A574','PENDING_FOLLOWUP'=>'#D4A574','PENDING_SPARES'=>'#C48579','ESCALATED'=>'#C48579'][$r['fault_status']] ?? '#94A3B8';
                            ?>
                                <tr style="font-size:.76rem;">
                                    <td><span class="badge" style="background:#EEF2F6;color:#334155;border:1px solid #E2E8F0;font-size:.6rem;font-weight:500;"><?= htmlspecialchars((string)$cat); ?></span></td>
                                    <td><code style="color:#7A8BA1;font-size:.7rem;"><?= htmlspecialchars((string)$r['code']); ?></code></td>
                                    <td style="color:#334155;font-weight:500;"><?= htmlspecialchars((string)$r['title']); ?></td>
                                    <td style="color:#64748B;font-size:.72rem;"><?= htmlspecialchars((string)($r['root_cause'] ?? '')); ?></td>
                                    <td style="color:#64748B;font-size:.72rem;"><?= htmlspecialchars((string)($r['action_taken'] ?? '')); ?></td>
                                    <td><span class="badge" style="background:<?= $statusColor; ?>;color:#fff;font-size:.6rem;font-weight:600;"><?= htmlspecialchars((string)$r['fault_status']); ?></span></td>
                                </tr>
                            <?php endforeach; endforeach; ?>
                        </tbody>
                    </table>
                </div>
            <?php endif; ?>
        <?php endif; ?>
    </div>
</div>

<script>
(function () {
    var PROOT = <?= json_encode(PROOT); ?>;

    // Slice 8Z-x · click a template row → fetch item schema → render in a jquery-confirm modal
    function typeBadge(t) {
        var col = { CHECK:'#7A9E7E', NUMBER:'#7A8BA1', PHOTO:'#D4A574', LONG_TEXT:'#94A3B8',
                    TEXT:'#94A3B8', DATE:'#94A3B8', DROPDOWN:'#7A8BA1', GPS:'#C48579', SCAN:'#7A8BA1' };
        return '<span style="background:' + (col[t] || '#94A3B8') + ';color:#fff;font-size:.58rem;padding:.08rem .3rem;border-radius:2px;font-weight:600;">' + t + '</span>';
    }
    function esc(s) { return String(s || '').replace(/&/g,'&amp;').replace(/</g,'&lt;').replace(/>/g,'&gt;').replace(/"/g,'&quot;'); }

    function openTemplateModal(tid) {
        console.log('[tpl-catalog] fetching template', tid);
        $.ajax({
            url: PROOT + 'Projects/templateItemsAj',
            type: 'POST',
            data: { template_id: tid },
            dataType: 'json'
        }).done(function (res) {
            console.log('[tpl-catalog] response', res);
            if (!res || !res.ok) {
                var msg = 'Failed to load template' + (res && res.msg ? ': ' + res.msg : '');
                if (window.rsToast) rsToast(msg, 'error', 5000); else alert(msg);
                return;
            }
            var t = res.template, items = res.items || [];
            // Group items by section preserving order of appearance
            var sections = []; var byCatIdx = {};
            items.forEach(function (it) {
                var s = it.section;
                if (byCatIdx[s] === undefined) { byCatIdx[s] = sections.length; sections.push({ name: s, items: [] }); }
                sections[byCatIdx[s]].items.push(it);
            });
            var html = '<div class="small text-muted mb-2" style="font-size:.72rem;">'
                     + '<code style="color:#7A8BA1;font-size:.7rem;">' + esc(t.slug) + '</code>'
                     + ' · ' + esc(t.category) + ' · scope ' + esc(t.scope)
                     + (t.cadence_note ? ' · ' + esc(t.cadence_note) : '')
                     + ' · <strong>' + items.length + '</strong> items across <strong>' + sections.length + '</strong> section(s)'
                     + '</div>';
            html += '<div class="mb-2" style="font-size:.78rem;color:#334155;">' + esc(t.description) + '</div>';
            sections.forEach(function (sec) {
                html += '<div class="mt-3 mb-1" style="font-size:.66rem;color:#334155;font-weight:600;text-transform:capitalize;letter-spacing:.5px;background:#F1F5F9;padding:.25rem .5rem;border-radius:2px;">' + esc(sec.name) + '</div>';
                html += '<table class="table table-sm mb-0" style="font-size:.72rem;"><tbody>';
                sec.items.forEach(function (it) {
                    var req = it.is_required == 1 ? '<span style="color:#C48579;font-weight:600;">*</span>' : '';
                    var dep = it.depends_on_slug ? ' <span style="color:#94A3B8;font-size:.62rem;">[gated on <code>' + esc(it.depends_on_slug) + '</code>=' + esc(it.depends_on_value) + ']</span>' : '';
                    var unit = it.unit_or_note ? ' <span style="color:#94A3B8;font-size:.62rem;">' + esc(it.unit_or_note) + '</span>' : '';
                    var cfg = '';
                    if (it.config_json) {
                        try { var j = JSON.parse(it.config_json); if (j.choices) cfg = ' <span style="color:#94A3B8;font-size:.62rem;">choices: ' + esc(j.choices.join(' · ')) + '</span>'; }
                        catch (e) {}
                    }
                    html += '<tr>'
                          + '<td style="width:24px;">' + req + '</td>'
                          + '<td style="width:64px;">' + typeBadge(it.field_type) + '</td>'
                          + '<td><code style="color:#7A8BA1;font-size:.68rem;">' + esc(it.field_slug) + '</code></td>'
                          + '<td style="color:#334155;">' + esc(it.field_label) + unit + cfg + dep + '</td>'
                          + '</tr>';
                });
                html += '</tbody></table>';
            });
            if (typeof $.confirm === 'function') {
                $.confirm({
                    title: t.label,
                    content: html,
                    columnClass: 'large',
                    type: 'blue',
                    buttons: { close: { text: 'Close', btnClass: 'btn-light' } }
                });
            } else {
                // Fallback if jquery-confirm didn't load
                var w = window.open('', '_blank');
                w.document.write('<html><head><title>' + esc(t.label) + '</title></head><body>' + html + '</body></html>');
            }
        }).fail(function (xhr, status, err) {
            console.error('[tpl-catalog] AJAX failed', status, err, xhr && xhr.status, xhr && xhr.responseText && xhr.responseText.slice(0, 200));
            var msg = 'Could not load template (HTTP ' + (xhr && xhr.status || '?') + '). Check console.';
            if (window.rsToast) rsToast(msg, 'error', 5000); else alert(msg);
        });
    }
    // Bind ONCE — click either the row OR the View button; both use the row's tpl-id.
    // Handler is delegated so it survives future re-renders.
    $(document).on('click', '.tpl-cat-row', function (e) {
        var tid = parseInt($(this).data('tpl-id'), 10);
        console.log('[tpl-catalog] row clicked, tid=', tid);
        if (tid > 0) openTemplateModal(tid);
    });
})();
</script>

<script>
(function () {
    var PID = <?= (int)$p['c0d']; ?>;
    var CID = <?= (int)$contractId; ?>;
    var PROOT = <?= json_encode(PROOT); ?>;

    /* A · Confirm spec */
    $('#btn_svc_confirm_spec').on('click', function () {
        var $btn = $(this).prop('disabled', true).html('<i class="fas fa-spinner fa-spin me-1"></i>Confirming…');
        $.post(PROOT + 'Projects/confirmSpecAj', { contract_id: CID }, 'json').done(function (res) {
            if (res && res.ok) { rsToast('Spec confirmed.', 'success'); setTimeout(function () { location.reload(); }, 400); }
            else { rsToast('Failed: ' + (res && res.msg || 'unknown'), 'error'); $btn.prop('disabled', false).html('<i class="fas fa-check me-1"></i>Confirm spec for execution'); }
        });
    });

    /* E · Save overhead annotation (per-row) */
    $(document).on('click', '.btn-oh-save', function () {
        var $tr = $(this).closest('tr');
        var payload = {
            project_id:         PID,
            tender_overhead_id: parseInt($tr.data('oh-id'), 10),
            actual_amount:      $tr.find('.oh-actual').val(),
            notes:              $tr.find('.oh-notes').val()
        };
        var $btn = $(this).prop('disabled', true);
        $.post(PROOT + 'Projects/svcOverheadNoteSaveAj', payload, 'json').done(function (res) {
            $btn.prop('disabled', false);
            if (res && res.ok) rsToast('Saved.', 'success');
            else rsToast('Save failed: ' + (res && res.msg || 'unknown'), 'error');
        });
    });

    /* B · Sites CRUD */
    $('#btn_svc_add_site').on('click', function () {
        $.confirm({
            title: 'Add site', columnClass: 'medium', type: 'blue',
            content:
              '<div class="mb-2"><label class="form-label small text-muted">Site name *</label><input type="text" id="site_name" class="form-control form-control-sm"></div>'
            + '<div class="mb-2"><label class="form-label small text-muted">Site code</label><input type="text" id="site_code" class="form-control form-control-sm" placeholder="e.g. VOD-DAR-042"></div>'
            + '<div class="mb-2"><label class="form-label small text-muted">Region</label><input type="text" id="site_region" class="form-control form-control-sm"></div>'
            + '<div class="mb-2"><label class="form-label small text-muted">Physical address</label><input type="text" id="site_addr" class="form-control form-control-sm"></div>',
            buttons: {
                save: { text: 'Add', btnClass: 'btn-primary', action: function () {
                    var name = ($('#site_name').val() || '').trim();
                    if (!name) { rsToast('Site name required.', 'warning'); return false; }
                    $.post(PROOT + 'Projects/svcSiteSaveAj', {
                        contract_id: CID, name: name,
                        site_code: $('#site_code').val(), region: $('#site_region').val(), physical_address: $('#site_addr').val()
                    }, 'json').done(function (res) {
                        if (res && res.ok) { rsToast('Site added.', 'success'); setTimeout(function () { location.reload(); }, 350); }
                        else rsToast('Failed: ' + (res && res.msg || 'unknown'), 'error');
                    });
                }},
                cancel: { text: 'Cancel', btnClass: 'btn-light' }
            }
        });
    });
    $(document).on('click', '.btn-svc-site-del', function () {
        var sid = parseInt($(this).data('site-id'), 10);
        $.confirm({ title: 'Remove site?', content: 'All assets on this site will be affected.', type: 'orange',
            buttons: {
                yes: { text: 'Remove', btnClass: 'btn-warning', action: function () {
                    $.post(PROOT + 'Projects/svcSiteRemoveAj', { site_id: sid }, 'json').done(function (res) {
                        if (res && res.ok) { rsToast('Removed.', 'success'); setTimeout(function () { location.reload(); }, 300); }
                        else rsToast('Failed: ' + (res && res.msg || 'unknown'), 'error');
                    });
                }},
                cancel: { text: 'Cancel', btnClass: 'btn-light' }
            }
        });
    });

    /* B · Assets CRUD */
    $('#btn_svc_add_asset').on('click', function () {
        $.confirm({ title: 'Add asset', columnClass: 'medium', type: 'blue',
            content:
              '<div class="mb-2"><label class="form-label small text-muted">Asset type *</label><input type="text" id="a_type" class="form-control form-control-sm" placeholder="e.g. Genset · AC · UPS"></div>'
            + '<div class="mb-2"><label class="form-label small text-muted">Name / description</label><input type="text" id="a_name" class="form-control form-control-sm"></div>'
            + '<div class="mb-2"><label class="form-label small text-muted">Make · Model</label><input type="text" id="a_mm" class="form-control form-control-sm"></div>'
            + '<div class="mb-2"><label class="form-label small text-muted">Serial no</label><input type="text" id="a_sn" class="form-control form-control-sm"></div>'
            + '<div class="mb-2"><label class="form-label small text-muted">Rating (kVA / BTU / etc.)</label><input type="text" id="a_rt" class="form-control form-control-sm"></div>',
            buttons: {
                save: { text: 'Add', btnClass: 'btn-primary', action: function () {
                    var type = ($('#a_type').val() || '').trim();
                    if (!type) { rsToast('Asset type required.', 'warning'); return false; }
                    var mm = ($('#a_mm').val() || '').trim().split(/\s+/);
                    $.post(PROOT + 'Projects/svcAssetSaveAj', {
                        contract_id: CID, asset_type: type,
                        name: $('#a_name').val(),
                        make: (mm[0] || ''), model: (mm.slice(1).join(' ') || ''),
                        serial_no: $('#a_sn').val(), rating: $('#a_rt').val()
                    }, 'json').done(function (res) {
                        if (res && res.ok) { rsToast('Asset added.', 'success'); setTimeout(function () { location.reload(); }, 350); }
                        else rsToast('Failed: ' + (res && res.msg || 'unknown'), 'error');
                    });
                }},
                cancel: { text: 'Cancel', btnClass: 'btn-light' }
            }
        });
    });
    $(document).on('click', '.btn-svc-asset-del', function () {
        var aid = parseInt($(this).data('asset-id'), 10);
        $.confirm({ title: 'Remove asset?', content: 'Asset row will be removed.', type: 'orange',
            buttons: {
                yes: { text: 'Remove', btnClass: 'btn-warning', action: function () {
                    $.post(PROOT + 'Projects/svcAssetRemoveAj', { asset_id: aid }, 'json').done(function (res) {
                        if (res && res.ok) { rsToast('Removed.', 'success'); setTimeout(function () { location.reload(); }, 300); }
                        else rsToast('Failed: ' + (res && res.msg || 'unknown'), 'error');
                    });
                }},
                cancel: { text: 'Cancel', btnClass: 'btn-light' }
            }
        });
    });

    /* C · SLA seed */
    $('#btn_svc_seed_slas').on('click', function () {
        var $btn = $(this).prop('disabled', true).html('<i class="fas fa-spinner fa-spin me-1"></i>Seeding…');
        var tid = parseInt($(this).data('tender-id'), 10);
        $.post(PROOT + 'Projects/svcSlaSeedFromSpecAj', { contract_id: CID, tender_id: tid }, 'json').done(function (res) {
            if (res && res.ok) { rsToast('Seeded ' + (res.seeded || 0) + ' SLA row(s).', 'success'); setTimeout(function () { location.reload(); }, 400); }
            else { $btn.prop('disabled', false).html('<i class="fas fa-magic me-1"></i>Seed from bid'); rsToast('Failed: ' + (res && res.msg || 'unknown'), 'error'); }
        });
    });

    /* F · Templates catalog picker — chip click appends slug to the textarea */
    $(document).on('click', '.btn-tpl-chip', function () {
        var slug = ($(this).data('slug') || '').toString().trim();
        if (!slug) return;
        var $ta  = $('#svc_instr_form [name=templates_needed]');
        var cur  = ($ta.val() || '').trim();
        // De-dup: don't append if slug is already present (word-boundary match)
        var re = new RegExp('(^|[^A-Z0-9_-])' + slug.replace(/[-]/g, '\\-') + '($|[^A-Z0-9_-])', 'i');
        if (re.test(cur)) { if (window.rsToast) rsToast('Already in the list.', 'info'); return; }
        $ta.val((cur ? cur + ' · ' : '') + slug).focus();
        if (window.rsToast) rsToast('Added ' + slug + ' — remember to Save.', 'success', 2500);
    });

    /* F · PM instructions save */
    $('#btn_svc_instr_save').on('click', function () {
        var $btn = $(this).prop('disabled', true).html('<i class="fas fa-spinner fa-spin me-1"></i>Saving…');
        $.post(PROOT + 'Projects/svcInstructionsSaveAj', {
            project_id: PID,
            templates_needed:   $('#svc_instr_form [name=templates_needed]').val(),
            sites_instructions: $('#svc_instr_form [name=sites_instructions]').val(),
            team_instructions:  $('#svc_instr_form [name=team_instructions]').val()
        }, 'json').done(function (res) {
            $btn.prop('disabled', false).html('<i class="fas fa-save me-1"></i>Save instructions');
            if (res && res.ok) rsToast('Instructions saved.', 'success');
            else rsToast('Failed: ' + (res && res.msg || 'unknown'), 'error');
        });
    });

    /* ── Slice 8Z-y · Y-A/B/C · MOVED to Vue 3 Options API root
       (see <div id="svc_scope_root"> earlier in this file + createApp at end).
       No page reloads. TPL_FLAT is redefined inside the Vue mount. ── */

    /* G · Ops docs upload/remove */
    var OPS_SUBTYPES = [
        ['SIGNED_CONTRACT',       'Signed contract',              true],
        ['CAR_INSURANCE',         "Contractor's All-Risk (CAR)",  true],
        ['WORKERS_COMP',          'Workers Compensation policy',  true],
        ['WCF_PROOF',             'WCF proof',                    true],
        ['NSSF_PROOF',            'NSSF proof',                   true],
        ['OSHA_METHOD_STATEMENT', 'OSHA method statement',        true],
        ['TRA_EFISCAL_CERT',      'TRA e-fiscal certificate',     true],
        ['SITE_ACCESS_PERMIT',    'Site access permit',           false],
        ['HSE_PLAN',              'HSE plan',                     false],
        ['VEHICLE_INSURANCE',     'Vehicle insurance',            false],
        ['OTHER',                 'Other',                        false]
    ];
    $('#btn_ops_upload').on('click', function () {
        var opts = OPS_SUBTYPES.map(function (s) { return '<option value="' + s[0] + '">' + s[1] + (s[2] ? ' *' : '') + '</option>'; }).join('');
        $.confirm({ title: 'Upload operational document', columnClass: 'medium', type: 'blue',
            content:
              '<div class="mb-2"><label class="form-label small text-muted">Subtype (starred = mandatory)</label><select id="ops_sub" class="form-select form-select-sm">' + opts + '</select></div>'
            + '<div class="mb-2"><label class="form-label small text-muted">Label (optional)</label><input type="text" id="ops_lbl" class="form-control form-control-sm"></div>'
            + '<div class="mb-2"><label class="form-label small text-muted">Valid until (insurance / permits)</label><input type="date" id="ops_vu" class="form-control form-control-sm"></div>'
            + '<div class="mb-2"><input type="file" id="ops_file" class="form-control form-control-sm" accept=".pdf,.jpg,.jpeg,.png,.doc,.docx,.xls,.xlsx,.zip"></div>'
            + '<div class="small text-muted" style="font-size:.66rem;">PDF, image, DOC/DOCX, XLS/XLSX, ZIP. Max 10 MB.</div>',
            buttons: {
                upload: { text: 'Upload', btnClass: 'btn-primary', action: function () {
                    var f = document.getElementById('ops_file');
                    if (!f || !f.files || !f.files[0]) { rsToast('Pick a file first.', 'warning'); return false; }
                    var fd = new FormData();
                    fd.append('project_id',     PID);
                    fd.append('subtype',        $('#ops_sub').val());
                    fd.append('label',          $('#ops_lbl').val());
                    fd.append('validity_until', $('#ops_vu').val());
                    fd.append('ops_file',       f.files[0]);
                    $.ajax({ url: PROOT + 'Projects/opsDocUploadAj', type: 'POST',
                             data: fd, contentType: false, processData: false, dataType: 'json'
                    }).done(function (res) {
                        if (res && res.ok) { rsToast('Uploaded.', 'success'); setTimeout(function () { location.reload(); }, 400); }
                        else rsToast('Upload failed: ' + (res && res.msg || 'unknown'), 'error');
                    });
                }},
                cancel: { text: 'Cancel', btnClass: 'btn-light' }
            }
        });
    });
    $(document).on('click', '.btn-ops-del', function () {
        var did = parseInt($(this).data('doc-id'), 10);
        $.confirm({ title: 'Remove document?', content: 'File is removed from disk. Audit row survives.', type: 'orange',
            buttons: {
                yes: { text: 'Remove', btnClass: 'btn-warning', action: function () {
                    $.post(PROOT + 'Projects/opsDocRemoveAj', { doc_id: did }, 'json').done(function (res) {
                        if (res && res.ok) { rsToast('Removed.', 'success'); setTimeout(function () { location.reload(); }, 300); }
                        else rsToast('Failed: ' + (res && res.msg || 'unknown'), 'error');
                    });
                }},
                cancel: { text: 'Cancel', btnClass: 'btn-light' }
            }
        });
    });
})();
</script>

<?php endif; /* end services-only PM workspace block */ ?>

<!-- Card B · Tender pricing · what we quoted (full detail — sections, overheads, procurement mode, margin) -->
<?php if ($srcPricing !== null): ?>
    <?php
        $srcSections   = $src['pricing_sections']  ?? [];
        $srcOverheads  = $src['pricing_overheads'] ?? [];
        $statusColor   = ['APPROVED'=>'#7A9E7E','DRAFT'=>'#94A3B8','SUBMITTED'=>'#7A8BA1','DECLINED'=>'#C48579'][$srcPricing['status']] ?? '#94A3B8';
        $sumPrice      = (float)($srcPricing['sum_price']    ?? 0);
        $sumCost       = (float)($srcPricing['sum_cost']     ?? 0);
        $sumOverhead   = (float)($srcPricing['sum_overhead'] ?? 0);
        $sumMargin     = (float)($srcPricing['sum_margin']   ?? 0);
        $marginPct     = (float)($srcPricing['margin_pct']   ?? 0);
        $procMode      = strtoupper((string)($srcPricing['procurement_mode'] ?? ''));
        $procChip = ['LOCAL'=>['#EAF2E8','#3F5C43','Local'], 'IMPORT'=>['#FEF3E7','#8B6914','Import'], 'MIXED'=>['#F1F5F9','#334155','Mixed'], 'MANUFACTURE'=>['#EAF2E8','#3F5C43','Manufacture']][$procMode] ?? ['#F1F5F9','#94A3B8', ($procMode ?: '—')];

        // Group lines by section (fallback to a synthetic "Uncategorised" bucket).
        $linesBySection = [];
        foreach ($srcPriceLines as $pl) {
            $sid = (int)($pl['section_id'] ?? 0);
            $linesBySection[$sid][] = $pl;
        }
    ?>
<div class="card border-0 shadow-sm mb-3">
    <div class="card-header bg-white d-flex align-items-center justify-content-between" style="border-bottom:1px solid #E2E8F0;cursor:pointer;user-select:none;"
         data-bs-toggle="collapse" data-bs-target="#cardTenderPricingBody" aria-expanded="false" aria-controls="cardTenderPricingBody">
        <div>
            <strong style="color:#334155;"><i class="fas fa-tags me-2" style="color:#7A8BA1;"></i>Tender pricing · what we quoted</strong>
            <div class="text-muted small mt-1" style="color:#64748B;font-size:.72rem;">
                v<?= (int)$srcPricing['version_no']; ?>
                <?php if (!empty($srcPricing['version_label'])): ?>· <?= htmlspecialchars((string)$srcPricing['version_label']); ?><?php endif; ?>
                · <?= count($srcPriceLines); ?> line<?= count($srcPriceLines) === 1 ? '' : 's' ?>
                · <?= count($srcSections); ?> section<?= count($srcSections) === 1 ? '' : 's' ?>
                · <?= count($srcOverheads); ?> overhead<?= count($srcOverheads) === 1 ? '' : 's' ?>
            </div>
        </div>
        <div class="d-flex align-items-center gap-2">
            <span class="badge" style="background:<?= $statusColor; ?>;color:#fff;font-size:.72rem;text-transform:capitalize;"><?= htmlspecialchars(strtolower((string)$srcPricing['status'])); ?></span>
            <?php if (!empty($src['tender']['c0d'])): ?>
                <a href="<?= PROOT; ?>Tenders/view/<?= (int)$src['tender']['c0d']; ?>#tab-pricing" class="btn btn-sm" style="background:#F8FAFC;border:1px solid #E2E8F0;color:#334155;font-size:.72rem;" onclick="event.stopPropagation();">
                    <i class="fas fa-external-link-alt me-1" style="color:#7A8BA1;"></i>Full pricing tab
                </a>
            <?php endif; ?>
            <i class="fas fa-chevron-down" style="color:#94A3B8;font-size:.7rem;"></i>
        </div>
    </div>
    <div class="collapse" id="cardTenderPricingBody">

    <!-- Meta strip: pricing mode, procurement mode, defaults -->
    <div class="card-body p-3" style="background:#F8FAFC;border-bottom:1px solid #E2E8F0;">
        <div class="row g-2">
            <div class="col-md-2">
                <div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Pricing mode</div>
                <div style="font-weight:500;color:#334155;font-size:.82rem;text-transform:capitalize;"><?= htmlspecialchars(strtolower(str_replace('_',' ', (string)($srcPricing['pricing_mode'] ?? '—')))); ?></div>
            </div>
            <div class="col-md-2">
                <div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Procurement</div>
                <span class="badge" style="background:<?= $procChip[0]; ?>;color:<?= $procChip[1]; ?>;font-size:.72rem;font-weight:600;"><i class="fas fa-globe-africa me-1"></i><?= htmlspecialchars($procChip[2]); ?></span>
            </div>
            <div class="col-md-2">
                <div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Currency</div>
                <div style="font-weight:600;color:#334155;"><?= htmlspecialchars((string)($srcPricing['currency'] ?? 'TZS')); ?></div>
            </div>
            <div class="col-md-2">
                <div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Default markup</div>
                <div style="font-weight:600;color:#334155;"><?= number_format((float)($srcPricing['default_markup_pct'] ?? 0), 2); ?>%</div>
            </div>
            <div class="col-md-2">
                <div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Contingency</div>
                <div style="font-weight:600;color:#334155;"><?= number_format((float)($srcPricing['contingency_pct'] ?? 0), 2); ?>%</div>
            </div>
            <div class="col-md-2">
                <div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">VAT</div>
                <div style="font-weight:600;color:#334155;"><?= number_format((float)($srcPricing['vat_pct'] ?? 0), 2); ?>%</div>
            </div>
        </div>
    </div>

    <!-- Lines grouped by section -->
    <?php if (!empty($srcPriceLines)): ?>
        <div class="table-responsive">
            <table class="table table-sm mb-0 align-middle">
                <thead style="background:#F1F5F9;">
                    <tr>
                        <th style="color:#334155;">Description</th>
                        <th style="color:#334155;text-align:right;">Qty</th>
                        <th style="color:#334155;">UoM</th>
                        <th style="color:#334155;text-align:right;">Unit cost</th>
                        <th style="color:#334155;text-align:right;">Markup %</th>
                        <th style="color:#334155;text-align:right;">Unit sell</th>
                        <th style="color:#334155;text-align:right;">Line cost</th>
                        <th style="color:#334155;text-align:right;">Line sell</th>
                    </tr>
                </thead>
                <?php
                    // Emit each section as its own tbody with a header row + line rows + section total.
                    $sectionOrder = [];
                    foreach ($srcSections as $s) $sectionOrder[(int)$s['c0d']] = $s;
                    foreach ($linesBySection as $sid => $_) if ($sid > 0 && !isset($sectionOrder[$sid])) $sectionOrder[$sid] = ['c0d'=>$sid, 'section_no'=>0, 'section_name'=>'Section #' . $sid, 'sum_cost'=>0, 'sum_price'=>0];
                    if (isset($linesBySection[0])) $sectionOrder[0] = ['c0d'=>0, 'section_no'=>0, 'section_name'=>'Uncategorised', 'sum_cost'=>0, 'sum_price'=>0];
                ?>
                <?php foreach ($sectionOrder as $sid => $sec):
                    $lines = $linesBySection[$sid] ?? [];
                    if (empty($lines) && (int)($sec['sum_price'] ?? 0) === 0) continue;
                    $secCost  = 0; $secPrice = 0;
                    foreach ($lines as $pl) { $secCost += (float)$pl['line_cost']; $secPrice += (float)$pl['line_price']; }
                ?>
                    <tbody>
                        <tr style="background:#EEF2F6;">
                            <td colspan="8" style="color:#334155;font-weight:600;font-size:.82rem;">
                                <i class="fas fa-folder-open me-1" style="color:#7A8BA1;"></i>
                                <?= htmlspecialchars((string)$sec['section_name']); ?>
                                <span class="text-muted small ms-1" style="font-weight:400;">· <?= count($lines); ?> line<?= count($lines) === 1 ? '' : 's' ?></span>
                            </td>
                        </tr>
                        <?php foreach ($lines as $pl): ?>
                            <tr>
                                <td style="color:#334155;font-size:.85rem;padding-left:1.4rem;"><?= htmlspecialchars((string)$pl['description']); ?>
                                    <?php if (!empty($pl['notes'])): ?><div class="small text-muted" style="font-size:.7rem;"><?= htmlspecialchars((string)$pl['notes']); ?></div><?php endif; ?>
                                </td>
                                <td class="text-end" style="color:#334155;"><?= rtrim(rtrim(number_format((float)$pl['qty'], 4, '.', ','), '0'), '.'); ?></td>
                                <td class="small text-muted"><?= htmlspecialchars((string)($pl['uom'] ?? '—')); ?></td>
                                <td class="text-end" style="color:#64748B;"><?= number_format((float)$pl['unit_cost'], 2); ?></td>
                                <td class="text-end" style="color:#64748B;"><?= number_format((float)$pl['markup_pct'], 2); ?>%</td>
                                <td class="text-end" style="color:#334155;font-weight:500;"><?= number_format((float)$pl['unit_price'], 2); ?></td>
                                <td class="text-end" style="color:#64748B;"><?= number_format((float)$pl['line_cost']); ?></td>
                                <td class="text-end" style="color:#334155;font-weight:600;"><?= number_format((float)$pl['line_price']); ?></td>
                            </tr>
                        <?php endforeach; ?>
                        <tr style="background:#F8FAFC;">
                            <td colspan="6" class="text-end small text-muted" style="font-weight:500;">Section subtotal</td>
                            <td class="text-end" style="color:#64748B;font-weight:600;"><?= number_format($secCost); ?></td>
                            <td class="text-end" style="color:#334155;font-weight:600;"><?= number_format($secPrice); ?></td>
                        </tr>
                    </tbody>
                <?php endforeach; ?>
            </table>
        </div>
    <?php endif; ?>

    <!-- Overheads block (collapsible if long) -->
    <?php if (!empty($srcOverheads)): ?>
        <div class="p-3" style="border-top:1px solid #E2E8F0;background:#FDF7EC;">
            <div class="d-flex align-items-center justify-content-between mb-2">
                <strong style="color:#8B6914;font-size:.86rem;"><i class="fas fa-layer-group me-1"></i>Overheads pool</strong>
                <span class="badge" style="background:#FEF3E7;color:#8B6914;font-size:.68rem;"><?= count($srcOverheads); ?> line<?= count($srcOverheads) === 1 ? '' : 's' ?> · TZS <?= number_format($sumOverhead); ?></span>
            </div>
            <div class="table-responsive">
                <table class="table table-sm mb-0 align-middle" style="background:#fff;">
                    <thead style="background:#F1F5F9;">
                        <tr>
                            <th style="color:#334155;">Category</th>
                            <th style="color:#334155;">Label</th>
                            <th style="color:#334155;">Mode</th>
                            <th style="color:#334155;text-align:right;">Amount</th>
                            <th style="color:#334155;">Notes</th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach ($srcOverheads as $oh): ?>
                            <tr>
                                <td class="small" style="color:#334155;text-transform:capitalize;"><?= htmlspecialchars(strtolower(str_replace('_',' ', (string)$oh['category']))); ?></td>
                                <td style="color:#334155;font-size:.85rem;"><?= htmlspecialchars((string)$oh['label']); ?></td>
                                <td><span class="badge" style="background:#F1F5F9;color:#334155;font-size:.62rem;text-transform:capitalize;"><?= htmlspecialchars(strtolower(str_replace('_',' ', (string)($oh['display_mode'] ?? '—')))); ?></span></td>
                                <td class="text-end" style="color:#334155;font-weight:500;"><?= number_format((float)$oh['amount']); ?></td>
                                <td class="small text-muted" style="color:#64748B;max-width:280px;"><?= htmlspecialchars((string)($oh['notes'] ?? '—')); ?></td>
                            </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            </div>
        </div>
    <?php endif; ?>

    <!-- Grand totals strip -->
    <div class="p-3" style="border-top:2px solid #7A9E7E;background:#F8FAFC;">
        <div class="row g-2 align-items-end">
            <div class="col-md-2">
                <div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Cost of goods</div>
                <div style="font-weight:600;color:#334155;">TZS <?= number_format($sumCost); ?></div>
            </div>
            <div class="col-md-2">
                <div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Overhead</div>
                <div style="font-weight:600;color:#334155;">TZS <?= number_format($sumOverhead); ?></div>
            </div>
            <div class="col-md-2">
                <div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Margin</div>
                <div style="font-weight:600;color:#334155;">TZS <?= number_format($sumMargin); ?></div>
            </div>
            <div class="col-md-2">
                <div class="text-muted small" style="font-size:.66rem;text-transform:uppercase;letter-spacing:.3px;">Sell price</div>
                <div style="font-weight:700;color:#334155;font-size:1.05rem;">TZS <?= number_format($sumPrice); ?></div>
            </div>
            <div class="col-md-4 text-end">
                <span class="badge" style="background:<?= $marginPct >= 20 ? '#EAF2E8' : '#FEF3C7'; ?>;color:<?= $marginPct >= 20 ? '#3F5C43' : '#78350F'; ?>;font-size:1rem;padding:.55rem 1rem;font-weight:600;">
                    <i class="fas fa-percentage me-1"></i>Margin <?= number_format($marginPct, 2); ?>%
                </span>
            </div>
        </div>
    </div>

    </div> <!-- /#cardTenderPricingBody -->
</div>
<?php endif; ?>

<?php
    // Cards T + C + D · Team + PM inputs + Reassign PM. Only for tender-origin projects with a PM assigned.
    $viewerId       = (int)($_SESSION['user_id'] ?? 0);
    $viewerGroup    = strtoupper((string)($_SESSION['user_group_name'] ?? ''));
    $pmId           = (int)($p['project_manager_id'] ?? 0);
    $pcId           = (int)($p['pc_id'] ?? 0);
    $accId          = (int)($p['accountant_id'] ?? 0);
    $procId         = (int)($p['procurement_id'] ?? 0);
    $isPm           = ($pmId > 0 && $pmId === $viewerId);
    $isAdmin        = ($viewerGroup === 'ADMINISTRATOR');
    $isExec         = ($viewerGroup === 'EXECUTIVE');
    $isPmRole       = ($viewerGroup === 'PROJECT MANAGER'); // Any PM in the org can view; only the assigned one can write.
    // Slice 8Y fix: Card C is visible to *everyone* (read-only for non-PM/Admin so PC/Proc/Exec can see the briefing).
    // Writes are still gated on $canPmEdit inside the card body.
    $showPmCard     = ($pmId > 0 || $isAdmin);
    $canPmEdit      = ($isPm || $isAdmin);
    $showReassign   = ($isExec || $isAdmin) && $pmId > 0;
    $showAssignPc   = ($isPm || $isAdmin);
    $pmCandidates   = $this->data['pm_candidates'] ?? [];
    $pcCandidates   = $this->data['pc_candidates'] ?? [];
    $roleChanges    = $this->data['role_changes']  ?? [];
    $pmConfirmedAt  = $p['pm_confirmed_at']    ?? null;
    $pmConfirmedBy  = (int)($p['pm_confirmed_by'] ?? 0);
    $pmConfirmedNote= (string)($p['pm_confirmation_notes'] ?? '');
    $pmNotesPc      = (string)($p['pm_notes_pc']            ?? '');
    $pmNotesProc    = (string)($p['pm_notes_procurement']   ?? '');
    $pmSuggested    = (string)($p['pm_suggested_items']     ?? '');
?>

<!-- Card T · Assigned team (visible to everyone) -->
<?php
    $seatChip = function (string $label, string $roleWho, int $uid, string $name, string $icon) {
        $filled = $uid > 0 && trim($name) !== '';
        echo '<div class="col-md-3">';
        echo '  <div class="p-2 rounded d-flex align-items-center gap-2" style="background:' . ($filled ? '#EAF2E8' : '#F1F5F9') . ';border:1px solid ' . ($filled ? '#7A9E7E33' : '#CBD5E1') . ';min-height:56px;">';
        echo '    <div class="d-flex align-items-center justify-content-center" style="width:32px;height:32px;border-radius:50%;background:' . ($filled ? '#7A9E7E' : '#CBD5E1') . ';color:#fff;font-size:.8rem;flex-shrink:0;">';
        echo '      <i class="fas ' . $icon . '"></i>';
        echo '    </div>';
        echo '    <div style="line-height:1.15;flex:1;overflow:hidden;">';
        echo '      <div class="text-muted small" style="font-size:.62rem;text-transform:uppercase;letter-spacing:.4px;">' . htmlspecialchars($label) . '</div>';
        if ($filled) {
            echo '      <div style="font-weight:600;color:#334155;font-size:.85rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;" title="' . htmlspecialchars($name) . '">' . htmlspecialchars($name) . '</div>';
        } else {
            echo '      <div style="color:#94A3B8;font-style:italic;font-size:.82rem;">Awaiting ' . htmlspecialchars($roleWho) . '</div>';
        }
        echo '    </div>';
        echo '  </div>';
        echo '</div>';
    };
?>
<div class="card border-0 shadow-sm mb-3">
    <div class="card-header bg-white" style="border-bottom:1px solid #E2E8F0;">
        <strong style="color:#334155;"><i class="fas fa-users me-2" style="color:#7A8BA1;"></i>Assigned team</strong>
        <div class="text-muted small mt-1" style="color:#64748B;font-size:.72rem;">Seats hydrated at Executive approval + updates as the PM assigns their PC.</div>
    </div>
    <div class="card-body p-3">
        <div class="row g-2">
            <?php
                $seatChip('Project Manager',      'Executive', $pmId,   (string)($p['project_manager_name'] ?? ''), 'fa-user-tie');
                $seatChip('Projects Coordinator', 'PM',        $pcId,   (string)($p['pc_name']               ?? ''), 'fa-user-check');
                $seatChip('Accountant',           'FM',        $accId,  (string)($p['accountant_name']       ?? ''), 'fa-calculator');
                $seatChip('Procurement',          'FM',        $procId, (string)($p['procurement_name']      ?? ''), 'fa-truck-loading');
            ?>
        </div>
    </div>
</div>

<!-- Card C · PM briefing — readiness stamp + notes to PC + notes to Procurement + suggested extras + PC assign -->
<?php if ($showPmCard): ?>
<div class="card border-0 shadow-sm mb-3" style="border-left:3px solid #7A9E7E !important;">
    <div class="card-header bg-white d-flex align-items-center justify-content-between" style="border-bottom:1px solid #E2E8F0;">
        <div>
            <strong style="color:#334155;"><i class="fas fa-user-check me-2" style="color:#7A9E7E;"></i>Project Manager briefing</strong>
            <div class="text-muted small mt-1" style="color:#64748B;font-size:.72rem;">Assign the PC, brief them + Procurement, flag scope gaps, then stamp the record as reviewed.</div>
        </div>
        <?php if ($pmConfirmedAt): ?>
            <span class="badge" style="background:#EAF2E8;color:#3F5C43;font-size:.72rem;">
                <i class="fas fa-check me-1"></i>Reviewed <?= htmlspecialchars((string)$pmConfirmedAt); ?>
            </span>
        <?php endif; ?>
    </div>
    <div class="card-body p-3">
        <?php if ($pmConfirmedAt): ?>
            <div class="alert py-2 mb-3" style="background:#EAF2E8;border:1px solid #7A9E7E;color:#3F5C43;font-size:.82rem;">
                <i class="fas fa-check-circle me-1"></i>
                Marked reviewed on <strong><?= htmlspecialchars((string)$pmConfirmedAt); ?></strong>
                by <strong><?= htmlspecialchars((string)($p['project_manager_name'] ?? 'PM')); ?></strong>.
                You can update the briefing and stamp again — last write wins.
            </div>
        <?php endif; ?>

        <!-- Assign PC row (only when PM/Admin viewing). Includes project start/end dates. -->
        <?php if ($showAssignPc):
            $curStart = (string)($p['project_start_date'] ?? '');
            $curEnd   = (string)($p['project_end_date']   ?? '');
        ?>
            <div class="mb-3 p-2 rounded" style="background:#F8FAFC;border:1px dashed #CBD5E1;">
                <div class="row g-2 align-items-end">
                    <div class="col-md-3">
                        <label class="form-label" style="color:#334155;font-size:.72rem;font-weight:600;"><i class="fas fa-user-check me-1" style="color:#7A8BA1;"></i>Projects Coordinator</label>
                        <?php if ($pcId > 0): ?>
                            <div style="font-weight:600;color:#334155;font-size:.85rem;"><?= htmlspecialchars((string)($p['pc_name'] ?? '—')); ?></div>
                            <div class="small text-muted" style="font-size:.68rem;">Currently assigned</div>
                        <?php else: ?>
                            <div style="color:#94A3B8;font-style:italic;font-size:.85rem;">Not assigned yet</div>
                        <?php endif; ?>
                    </div>
                    <div class="col-md-3">
                        <label class="form-label" style="color:#334155;font-size:.72rem;"><?= $pcId > 0 ? 'Reassign to' : 'Assign' ?></label>
                        <select id="pm_pick_pc" class="form-select form-select-sm">
                            <option value="">— Pick a Projects Coordinator —</option>
                            <?php foreach ($pcCandidates as $c): ?>
                                <?php if ((int)$c['c0d'] === $pcId) continue; ?>
                                <option value="<?= (int)$c['c0d']; ?>"><?= htmlspecialchars((string)$c['full_name']); ?></option>
                            <?php endforeach; ?>
                        </select>
                    </div>
                    <div class="col-md-2">
                        <label class="form-label" style="color:#334155;font-size:.72rem;"><i class="fas fa-play me-1" style="color:#7A9E7E;"></i>Start</label>
                        <input type="date" id="pc_start_date" class="form-control form-control-sm" value="<?= htmlspecialchars($curStart); ?>">
                    </div>
                    <div class="col-md-2">
                        <label class="form-label" style="color:#334155;font-size:.72rem;"><i class="fas fa-flag-checkered me-1" style="color:#C48579;"></i>End</label>
                        <input type="date" id="pc_end_date" class="form-control form-control-sm" value="<?= htmlspecialchars($curEnd); ?>">
                    </div>
                    <div class="col-md-2">
                        <button type="button" id="btn_assign_pc" class="btn btn-sm w-100" style="background:#7A8BA1;border-color:#7A8BA1;color:#fff;font-weight:600;">
                            <i class="fas fa-user-check me-1"></i><?= $pcId > 0 ? 'Reassign' : 'Assign'; ?>
                        </button>
                    </div>
                </div>
                <?php if ($curStart || $curEnd): ?>
                    <div class="small text-muted mt-1" style="font-size:.68rem;">Project window: <?= htmlspecialchars($curStart ?: '—'); ?> → <?= htmlspecialchars($curEnd ?: '—'); ?></div>
                <?php endif; ?>
            </div>
        <?php endif; ?>

        <?php $ro = $canPmEdit ? '' : 'readonly'; ?>
        <?php if (!$canPmEdit): ?>
            <div class="alert py-1 mb-2 small" style="background:#F1F5F9;color:#64748B;font-size:.72rem;">
                <i class="fas fa-info-circle me-1"></i>Read-only — only <strong><?= htmlspecialchars((string)($p['project_manager_name'] ?? 'the assigned PM')); ?></strong> or an Administrator can edit this briefing.
            </div>
        <?php endif; ?>

        <!-- PM readiness notes -->
        <label class="form-label" style="color:#334155;font-size:.78rem;font-weight:600;"><i class="fas fa-clipboard-check me-1" style="color:#7A9E7E;"></i>PM readiness notes</label>
        <textarea id="pm_review_notes" rows="2" class="form-control form-control-sm mb-3" <?= $ro; ?>
                  placeholder="Overall feasibility, concerns, price lines that need renegotiation, mobilisation risks…"><?= htmlspecialchars($pmConfirmedNote); ?></textarea>

        <!-- Briefing to PC + Procurement side by side -->
        <div class="row g-3 mb-3">
            <div class="col-md-6">
                <label class="form-label" style="color:#334155;font-size:.78rem;font-weight:600;">
                    <i class="fas fa-user-check me-1" style="color:#7A8BA1;"></i>Notes to Projects Coordinator
                </label>
                <textarea id="pm_notes_pc" rows="4" class="form-control form-control-sm" <?= $ro; ?>
                          placeholder="Kick-off cadence, sub-contractor references, HSE bulletins, sequencing across sites, mobilisation timeline, site access constraints, client stakeholders…"><?= htmlspecialchars($pmNotesPc); ?></textarea>
                <div class="text-muted small mt-1" style="font-size:.68rem;color:#94A3B8;">Shown to the PC on their onboarding surface. Free-form.</div>
            </div>
            <div class="col-md-6">
                <label class="form-label" style="color:#334155;font-size:.78rem;font-weight:600;">
                    <i class="fas fa-truck-loading me-1" style="color:#7A8BA1;"></i>Notes to Procurement
                </label>
                <textarea id="pm_notes_procurement" rows="4" class="form-control form-control-sm" <?= $ro; ?>
                          placeholder="Preferred suppliers, brand/quality standards, local vs imported preferences per line, warranty asks, spare part expectations, freight/insurance considerations, delivery windows…"><?= htmlspecialchars($pmNotesProc); ?></textarea>
                <div class="text-muted small mt-1" style="font-size:.68rem;color:#94A3B8;">Shown on the sourcing surface. Guides supplier LPO drafting.</div>
            </div>
        </div>

        <!-- Suggested extra scope items PM thinks are missing from tender -->
        <label class="form-label" style="color:#334155;font-size:.78rem;font-weight:600;">
            <i class="fas fa-plus-circle me-1" style="color:#D4A574;"></i>Suggested extras &mdash; scope items PM thinks are missing from tender
        </label>
        <textarea id="pm_suggested_items" rows="3" class="form-control form-control-sm" <?= $ro; ?>
                  placeholder="One item per line. e.g. &#10;· Rack-to-rack fibre patch cords (24 · SM)&#10;· Aux transformer &mdash; not on RFP but needed on-site&#10;· Bonding wire kit for cabinet earth"><?= htmlspecialchars($pmSuggested); ?></textarea>
        <div class="text-muted small mt-1" style="font-size:.68rem;color:#94A3B8;">Not automatically added to the buyer scope &mdash; PC + Procurement decide whether to raise a variation / CR.</div>

        <?php if ($canPmEdit): ?>
            <div class="text-end mt-3">
                <button type="button" id="btn_pm_review" class="btn btn-sm"
                        style="background:#7A9E7E;border-color:#7A9E7E;color:#fff;font-weight:600;">
                    <i class="fas fa-check me-1"></i><?= $pmConfirmedAt ? 'Update briefing + review' : 'Mark scope + pricing reviewed'; ?>
                </button>
            </div>
        <?php endif; ?>
    </div>
</div>
<script>
(function () {
    var $btn      = document.getElementById('btn_pm_review');
    var $assignPc = document.getElementById('btn_assign_pc');
    if ($btn) $btn.addEventListener('click', function () {
        var payload = {
            project_id:         <?= (int)$p['c0d']; ?>,
            confirmation_notes: (document.getElementById('pm_review_notes').value       || '').trim(),
            notes_pc:           (document.getElementById('pm_notes_pc').value           || '').trim(),
            notes_procurement:  (document.getElementById('pm_notes_procurement').value  || '').trim(),
            suggested_items:    (document.getElementById('pm_suggested_items').value    || '').trim()
        };
        $.confirm({
            title: 'Mark project reviewed?',
            content: 'This stamps your PM briefing on the record and shares your notes with PC + Procurement.',
            type: 'green',
            buttons: {
                confirm: { text: 'Confirm', btnClass: 'btn-success', action: function () {
                    $.post('<?= PROOT; ?>Projects/pmReviewAj', payload, function (r) {
                        if (r && r.ok) { rsToast(r.msg || 'Reviewed.', 'success'); setTimeout(function(){ location.reload(); }, 600); }
                        else { $.alert({title:'Could not stamp', content:(r && r.msg) || 'Server error', type:'red'}); }
                    }, 'json');
                }},
                cancel: function () {}
            }
        });
    });
    if ($assignPc) $assignPc.addEventListener('click', function () {
        var uid = document.getElementById('pm_pick_pc').value;
        var sd  = (document.getElementById('pc_start_date').value || '').trim();
        var ed  = (document.getElementById('pc_end_date').value   || '').trim();
        if (!uid) { $.alert({title:'Pick a PC', content:'Select the new Projects Coordinator.', type:'orange'}); return; }
        if (sd && ed && ed < sd) { $.alert({title:'Dates invalid', content:'End date cannot be before start date.', type:'orange'}); return; }
        var windowLine = (sd || ed) ? ('<div class="small text-muted mt-1">Window: ' + (sd || '—') + ' → ' + (ed || '—') + '</div>') : '';
        $.confirm({
            title: 'Assign Projects Coordinator?',
            content: 'The PC will be notified and can pick up the onboarding checklist.' + windowLine,
            type: 'blue',
            buttons: {
                confirm: { text: 'Assign', btnClass: 'btn-primary', action: function () {
                    $.post('<?= PROOT; ?>Projects/assignPcAj', {
                        project_id: <?= (int)$p['c0d']; ?>, new_pc_id: uid, reason: 'PM handover',
                        start_date: sd, end_date: ed
                    }, function (r) {
                        if (r && r.ok) { rsToast(r.msg || 'PC assigned.', 'success'); setTimeout(function(){ location.reload(); }, 600); }
                        else { $.alert({title:'Could not assign', content:(r && r.msg) || 'Server error', type:'red'}); }
                    }, 'json');
                }},
                cancel: function () {}
            }
        });
    });
})();
</script>
<?php endif; ?>

<!-- Card D · Reassign PM (Executive + Administrator) -->
<?php if ($showReassign): ?>
<div class="card border-0 shadow-sm mb-3" style="border-left:3px solid #D4A574 !important;">
    <div class="card-header bg-white d-flex align-items-center justify-content-between" style="border-bottom:1px solid #E2E8F0;">
        <div>
            <strong style="color:#334155;"><i class="fas fa-user-tag me-2" style="color:#8B6914;"></i>Reassign Project Manager</strong>
            <div class="text-muted small mt-1" style="color:#64748B;font-size:.72rem;">Only Executive or Administrator. Changes the PM seat + logs the reason. New PM is notified.</div>
        </div>
        <?php if (!empty($roleChanges)): ?>
            <span class="badge" style="background:#FEF3E7;color:#8B6914;font-size:.72rem;"><?= count($roleChanges); ?> change<?= count($roleChanges) === 1 ? '' : 's' ?></span>
        <?php endif; ?>
    </div>
    <div class="card-body p-3">
        <div class="row g-2 align-items-end">
            <div class="col-md-4">
                <label class="form-label" style="color:#334155;font-size:.78rem;">Current PM</label>
                <input type="text" class="form-control form-control-sm" value="<?= htmlspecialchars((string)($p['project_manager_name'] ?? '—')); ?>" disabled>
            </div>
            <div class="col-md-4">
                <label class="form-label" style="color:#334155;font-size:.78rem;">New PM <span style="color:#C48579;">*</span></label>
                <select id="reassign_pm_pick" class="form-select form-select-sm">
                    <option value="">— Pick —</option>
                    <?php foreach ($pmCandidates as $c): ?>
                        <?php if ((int)$c['c0d'] === $pmId) continue; ?>
                        <option value="<?= (int)$c['c0d']; ?>"><?= htmlspecialchars((string)$c['full_name']); ?></option>
                    <?php endforeach; ?>
                </select>
            </div>
            <div class="col-md-4">
                <label class="form-label" style="color:#334155;font-size:.78rem;">Reason <span style="color:#C48579;">*</span></label>
                <input type="text" id="reassign_pm_reason" class="form-control form-control-sm" placeholder="Why (audit-worthy — required)">
            </div>
        </div>
        <div class="text-end mt-2">
            <button type="button" id="btn_reassign_pm" class="btn btn-sm"
                    style="background:#D4A574;border-color:#D4A574;color:#fff;font-weight:600;">
                <i class="fas fa-exchange-alt me-1"></i>Reassign PM
            </button>
        </div>

        <?php if (!empty($roleChanges)): ?>
            <div class="mt-3" style="border-top:1px dashed #CBD5E1;padding-top:.6rem;">
                <div class="d-flex align-items-center justify-content-between mb-1" style="cursor:pointer;user-select:none;" data-bs-toggle="collapse" data-bs-target="#roleChangesBody">
                    <strong style="color:#334155;font-size:.8rem;"><i class="fas fa-history me-1" style="color:#7A9E7E;"></i>PM change history</strong>
                    <i class="fas fa-chevron-down" style="color:#94A3B8;font-size:.7rem;"></i>
                </div>
                <div class="collapse" id="roleChangesBody">
                    <table class="table table-sm mb-0 align-middle" style="background:#fff;">
                        <thead style="background:#F1F5F9;">
                            <tr>
                                <th style="color:#334155;font-size:.7rem;">When</th>
                                <th style="color:#334155;font-size:.7rem;">Slot</th>
                                <th style="color:#334155;font-size:.7rem;">From</th>
                                <th style="color:#334155;font-size:.7rem;">To</th>
                                <th style="color:#334155;font-size:.7rem;">By</th>
                                <th style="color:#334155;font-size:.7rem;">Reason</th>
                            </tr>
                        </thead>
                        <tbody>
                            <?php foreach ($roleChanges as $rc): ?>
                                <tr>
                                    <td class="small text-muted"><?= htmlspecialchars((string)$rc['changed_on']); ?></td>
                                    <td class="small" style="color:#334155;"><?= htmlspecialchars(ucwords(strtolower(str_replace('_',' ', (string)$rc['role_slot'])))); ?></td>
                                    <td class="small text-muted"><?= htmlspecialchars((string)($rc['old_user_name'] ?: '—')); ?></td>
                                    <td class="small" style="color:#334155;font-weight:500;"><?= htmlspecialchars((string)$rc['new_user_name']); ?></td>
                                    <td class="small text-muted"><?= htmlspecialchars((string)$rc['changed_by_name']); ?></td>
                                    <td class="small text-muted"><?= htmlspecialchars((string)$rc['reason']); ?></td>
                                </tr>
                            <?php endforeach; ?>
                        </tbody>
                    </table>
                </div>
            </div>
        <?php endif; ?>
    </div>
</div>
<script>
(function () {
    var $btn = document.getElementById('btn_reassign_pm');
    if (!$btn) return;
    $btn.addEventListener('click', function () {
        var uid = document.getElementById('reassign_pm_pick').value;
        var r   = (document.getElementById('reassign_pm_reason').value || '').trim();
        if (!uid) { $.alert({title:'Pick a PM', content:'Select the new Project Manager.', type:'orange'}); return; }
        if (!r)   { $.alert({title:'Reason required', content:'Explain why the reassignment is needed.', type:'orange'}); return; }
        $.confirm({
            title: 'Reassign PM?',
            content: 'The current PM seat will be replaced. This is logged.',
            type: 'orange',
            buttons: {
                confirm: { text: 'Reassign', btnClass: 'btn-warning', action: function () {
                    $.post('<?= PROOT; ?>Projects/reassignPmAj', {
                        project_id: <?= (int)$p['c0d']; ?>, new_pm_id: uid, reason: r
                    }, function (resp) {
                        if (resp && resp.ok) { rsToast(resp.msg || 'Reassigned.', 'success'); setTimeout(function(){ location.reload(); }, 600); }
                        else { $.alert({title:'Could not reassign', content:(resp && resp.msg) || 'Server error', type:'red'}); }
                    }, 'json');
                }},
                cancel: function () {}
            }
        });
    });
})();
</script>
<?php endif; ?>

<?php endif; ?>

<?php
    // Slice 8Y · Client PO document card + Timelines card. Visible for ALL projects (not gated on tender origin).
    $docs           = $this->data['documents']   ?? [];
    $milestones     = $this->data['milestones']  ?? [];
    $viewerId       = $viewerId       ?? (int)($_SESSION['user_id'] ?? 0);
    $viewerGroup    = $viewerGroup    ?? strtoupper((string)($_SESSION['user_group_name'] ?? ''));
    $pmId           = $pmId           ?? (int)($p['project_manager_id'] ?? 0);
    $pcId           = $pcId           ?? (int)($p['pc_id'] ?? 0);
    $isPm           = ($pmId > 0 && $pmId === $viewerId);
    $isPc           = ($pcId > 0 && $pcId === $viewerId);
    $isAdmin        = ($viewerGroup === 'ADMINISTRATOR');
    $canUploadDoc   = ($isPm || $isAdmin);
    $canEditMilestone = ($isPm || $isPc || $isAdmin || $viewerGroup === 'PROJECTS COORDINATOR');
    $docKindLabel = [
        'CLIENT_PO' => ['Client PO',  '#7A9E7E'],
        'BOQ'       => ['BOQ',        '#7A8BA1'],
        'DRAWING'   => ['Drawing',    '#8B6914'],
        'SPEC'      => ['Spec',       '#7A8BA1'],
        'WARRANTY'  => ['Warranty',   '#D4A574'],
        'OTHER'     => ['Other',      '#94A3B8'],
    ];
?>

<!-- Card Docs · Client PO + supporting attachments -->
<div class="card border-0 shadow-sm mb-3">
    <div class="card-header bg-white d-flex align-items-center justify-content-between" style="border-bottom:1px solid #E2E8F0;">
        <div>
            <strong style="color:#334155;"><i class="fas fa-paperclip me-2" style="color:#7A8BA1;"></i>Client PO &amp; attachments</strong>
            <div class="text-muted small mt-1" style="color:#64748B;font-size:.72rem;">Signed Client PO, BOQ, drawings, specs — the artefacts PC + Procurement need to work from. PDF / image / xlsx / docx up to 15 MB.</div>
        </div>
        <span class="badge" style="background:#F1F5F9;color:#334155;font-size:.68rem;"><?= count($docs); ?> attached</span>
    </div>
    <div class="card-body p-3">
        <?php if ($canUploadDoc): ?>
            <form id="proj_doc_form" enctype="multipart/form-data" class="mb-3 p-2 rounded" style="background:#F8FAFC;border:1px dashed #CBD5E1;">
                <input type="hidden" name="project_id" value="<?= (int)$p['c0d']; ?>">
                <div class="row g-2 align-items-end">
                    <div class="col-md-2">
                        <label class="form-label" style="color:#334155;font-size:.72rem;">Kind</label>
                        <select name="doc_kind" class="form-select form-select-sm">
                            <?php foreach ($docKindLabel as $k => $lbl): ?>
                                <option value="<?= $k; ?>"><?= htmlspecialchars($lbl[0]); ?></option>
                            <?php endforeach; ?>
                        </select>
                    </div>
                    <div class="col-md-4">
                        <label class="form-label" style="color:#334155;font-size:.72rem;">File</label>
                        <input type="file" name="file" class="form-control form-control-sm"
                               accept=".pdf,.jpg,.jpeg,.png,.webp,.gif,.xlsx,.xls,.doc,.docx,.csv,.txt">
                    </div>
                    <div class="col-md-4">
                        <label class="form-label" style="color:#334155;font-size:.72rem;">Notes (optional)</label>
                        <input type="text" name="notes" class="form-control form-control-sm" placeholder="e.g. signed 2026-08-20 by TTCL Ltd">
                    </div>
                    <div class="col-md-2">
                        <button type="button" id="btn_upload_doc" class="btn btn-sm w-100" style="background:#7A9E7E;border-color:#7A9E7E;color:#fff;font-weight:600;"><i class="fas fa-upload me-1"></i>Upload</button>
                    </div>
                </div>
            </form>
        <?php endif; ?>

        <?php if (empty($docs)): ?>
            <div class="text-center text-muted small py-3" style="color:#94A3B8;">
                <i class="fas fa-inbox me-1"></i>No documents yet. <?php if ($canUploadDoc): ?>Upload the signed Client PO above.<?php endif; ?>
            </div>
        <?php else: ?>
            <div class="table-responsive">
                <table class="table table-sm mb-0 align-middle">
                    <thead style="background:#F1F5F9;">
                        <tr>
                            <th style="color:#334155;">Kind</th>
                            <th style="color:#334155;">File</th>
                            <th style="color:#334155;">Notes</th>
                            <th style="color:#334155;">Uploaded by</th>
                            <th style="color:#334155;">When</th>
                            <th style="color:#334155;text-align:right;">Size</th>
                            <th></th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach ($docs as $d):
                            $lbl = $docKindLabel[$d['doc_kind']] ?? ['—', '#94A3B8'];
                            $canDelete = ((int)$d['uploaded_by'] === $viewerId) || $isAdmin;
                        ?>
                            <tr>
                                <td><span class="badge" style="background:<?= $lbl[1]; ?>;color:#fff;font-size:.68rem;text-transform:capitalize;"><?= htmlspecialchars($lbl[0]); ?></span></td>
                                <td>
                                    <a href="<?= PROOT; ?>Projects/documentDownload/<?= (int)$d['c0d']; ?>" target="_blank" style="color:#7A8BA1;font-weight:600;text-decoration:none;font-size:.85rem;">
                                        <i class="fas fa-file me-1" style="color:#94A3B8;"></i><?= htmlspecialchars((string)$d['original_name']); ?>
                                    </a>
                                </td>
                                <td class="small text-muted" style="max-width:220px;color:#64748B;"><?= htmlspecialchars((string)($d['notes'] ?? '')); ?></td>
                                <td class="small text-muted" style="color:#64748B;"><?= htmlspecialchars((string)$d['uploaded_by_name']); ?></td>
                                <td class="small text-muted" style="color:#64748B;"><?= htmlspecialchars((string)$d['created_on']); ?></td>
                                <td class="text-end small text-muted" style="color:#64748B;">
                                    <?= number_format((int)$d['size_bytes'] / 1024, 1); ?> KB
                                </td>
                                <td class="text-end">
                                    <a href="<?= PROOT; ?>Projects/documentDownload/<?= (int)$d['c0d']; ?>?disposition=attachment" class="btn btn-sm btn-outline-secondary" title="Download"><i class="fas fa-download"></i></a>
                                    <?php if ($canDelete): ?>
                                        <button type="button" class="btn btn-sm btn-outline-danger btn-del-doc" data-id="<?= (int)$d['c0d']; ?>" title="Remove"><i class="fas fa-times"></i></button>
                                    <?php endif; ?>
                                </td>
                            </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            </div>
        <?php endif; ?>
    </div>
</div>

<?php if ($canUploadDoc): ?>
<script>
(function () {
    var $btn = document.getElementById('btn_upload_doc');
    if (!$btn) return;
    $btn.addEventListener('click', function () {
        var form = document.getElementById('proj_doc_form');
        var fd = new FormData(form);
        var fileEl = form.querySelector('input[type="file"]');
        if (!fileEl || !fileEl.files || fileEl.files.length === 0) {
            $.alert({title:'Pick a file', content:'Choose a file to upload first.', type:'orange'}); return;
        }
        $btn.disabled = true;
        fetch('<?= PROOT; ?>Projects/documentUploadAj', { method: 'POST', body: fd })
            .then(function (r) { return r.json(); })
            .then(function (r) {
                if (r && r.ok) { rsToast('Uploaded.', 'success'); setTimeout(function(){ location.reload(); }, 500); }
                else { $btn.disabled = false; $.alert({title:'Upload failed', content:(r && r.msg) || 'Server error', type:'red'}); }
            })
            .catch(function () { $btn.disabled = false; $.alert({title:'Upload failed', content:'Network error', type:'red'}); });
    });
})();
</script>
<?php endif; ?>
<script>
document.querySelectorAll('.btn-del-doc').forEach(function (b) {
    b.addEventListener('click', function () {
        var id = b.getAttribute('data-id');
        $.confirm({
            title: 'Remove document?', content: 'The file stays on disk but no longer shows here.', type: 'orange',
            buttons: {
                confirm: { text: 'Remove', btnClass: 'btn-warning', action: function () {
                    $.post('<?= PROOT; ?>Projects/documentDeleteAj', { doc_id: id }, function (r) {
                        if (r && r.ok) { rsToast('Removed.', 'success'); setTimeout(function(){ location.reload(); }, 500); }
                        else { $.alert({title:'Could not remove', content:(r && r.msg) || 'Server error', type:'red'}); }
                    }, 'json');
                }},
                cancel: function () {}
            }
        });
    });
});
</script>

<!-- Card Milestones · timeline -->
<?php
    $statusChip = [
        'NOT_STARTED' => ['#94A3B8', '#F1F5F9', 'Not started'],
        'IN_PROGRESS' => ['#7A8BA1', '#E8EEF3', 'In progress'],
        'DONE'        => ['#7A9E7E', '#EAF2E8', 'Done'],
        'BLOCKED'     => ['#C48579', '#F5EAE1', 'Blocked'],
        'CANCELLED'   => ['#94A3B8', '#F1F5F9', 'Cancelled'],
    ];
    $today = date('Y-m-d');
?>
<div class="card border-0 shadow-sm mb-3">
    <div class="card-header bg-white d-flex align-items-center justify-content-between" style="border-bottom:1px solid #E2E8F0;">
        <div>
            <strong style="color:#334155;"><i class="fas fa-route me-2" style="color:#7A8BA1;"></i>Timelines &amp; milestones</strong>
            <div class="text-muted small mt-1" style="color:#64748B;font-size:.72rem;">Checkpoints the team must hit. Owners can flip status; PM/PC/Admin can add / edit / remove.</div>
        </div>
        <span class="badge" style="background:#F1F5F9;color:#334155;font-size:.68rem;"><?= count($milestones); ?> milestone<?= count($milestones) === 1 ? '' : 's' ?></span>
    </div>
    <div class="card-body p-3">
        <?php if ($canEditMilestone): ?>
            <div class="mb-3 p-2 rounded" style="background:#F8FAFC;border:1px dashed #CBD5E1;">
                <div class="row g-2 align-items-end">
                    <div class="col-md-4">
                        <label class="form-label" style="color:#334155;font-size:.72rem;">Title</label>
                        <input type="text" id="ms_title" class="form-control form-control-sm" placeholder="e.g. Kick-off meeting held">
                    </div>
                    <div class="col-md-2">
                        <label class="form-label" style="color:#334155;font-size:.72rem;">Target date</label>
                        <input type="date" id="ms_target" class="form-control form-control-sm">
                    </div>
                    <div class="col-md-3">
                        <label class="form-label" style="color:#334155;font-size:.72rem;">Owner</label>
                        <select id="ms_owner_slot" class="form-select form-select-sm">
                            <option value="">— Any / TBD —</option>
                            <?php foreach (['PROJECT_MANAGER'=>'Project Manager','PROJECTS_COORDINATOR'=>'Projects Coordinator','ACCOUNTANT'=>'Accountant','PROCUREMENT'=>'Procurement','FIELD_SUPERVISOR'=>'Field Supervisor','CRM'=>'CRM','EXECUTIVE'=>'Executive'] as $k => $lbl): ?>
                                <option value="<?= $k; ?>"><?= htmlspecialchars($lbl); ?></option>
                            <?php endforeach; ?>
                        </select>
                    </div>
                    <div class="col-md-3">
                        <button type="button" id="btn_add_ms" class="btn btn-sm w-100" style="background:#7A8BA1;border-color:#7A8BA1;color:#fff;font-weight:600;">
                            <i class="fas fa-plus me-1"></i>Add milestone
                        </button>
                    </div>
                    <div class="col-12">
                        <input type="text" id="ms_desc" class="form-control form-control-sm" placeholder="Description (optional)">
                    </div>
                </div>
            </div>
        <?php endif; ?>

        <?php if (empty($milestones)): ?>
            <div class="text-center text-muted small py-3" style="color:#94A3B8;">
                <i class="fas fa-hourglass-half me-1"></i>No milestones yet. <?php if ($canEditMilestone): ?>Add the first one above.<?php endif; ?>
            </div>
        <?php else: ?>
            <div class="table-responsive">
                <table class="table table-sm mb-0 align-middle">
                    <thead style="background:#F1F5F9;">
                        <tr>
                            <th style="color:#334155;width:40px;">#</th>
                            <th style="color:#334155;">Milestone</th>
                            <th style="color:#334155;">Target</th>
                            <th style="color:#334155;">Owner</th>
                            <th style="color:#334155;">Status</th>
                            <th></th>
                        </tr>
                    </thead>
                    <tbody>
                        <?php foreach ($milestones as $m):
                            $chip = $statusChip[$m['status']] ?? $statusChip['NOT_STARTED'];
                            $overdue = $m['target_date'] && $m['target_date'] < $today && $m['status'] !== 'DONE' && $m['status'] !== 'CANCELLED';
                        ?>
                            <tr>
                                <td class="small text-muted"><?= (int)$m['sequence']; ?></td>
                                <td>
                                    <div style="color:#334155;font-weight:500;font-size:.85rem;"><?= htmlspecialchars((string)$m['title']); ?></div>
                                    <?php if (!empty($m['description'])): ?>
                                        <div class="text-muted small" style="font-size:.7rem;color:#94A3B8;"><?= htmlspecialchars((string)$m['description']); ?></div>
                                    <?php endif; ?>
                                </td>
                                <td class="small" style="color:<?= $overdue ? '#C48579' : '#334155'; ?>;">
                                    <?= htmlspecialchars((string)($m['target_date'] ?? '—')); ?>
                                    <?php if ($overdue): ?><span class="badge ms-1" style="background:#C48579;color:#fff;font-size:.58rem;">overdue</span><?php endif; ?>
                                </td>
                                <td class="small text-muted"><?= htmlspecialchars(ucwords(strtolower(str_replace('_',' ', (string)($m['owner_slot'] ?? '—'))))); ?></td>
                                <td>
                                    <?php if ($canEditMilestone): ?>
                                        <select class="form-select form-select-sm ms-status" data-id="<?= (int)$m['c0d']; ?>" style="background:<?= $chip[1]; ?>;color:<?= $chip[0]; ?>;border:1px solid <?= $chip[0]; ?>;font-weight:600;font-size:.72rem;padding:.15rem .3rem;height:auto;">
                                            <?php foreach ($statusChip as $sk => $sc): ?>
                                                <option value="<?= $sk; ?>" <?= $m['status'] === $sk ? 'selected' : ''; ?>><?= htmlspecialchars($sc[2]); ?></option>
                                            <?php endforeach; ?>
                                        </select>
                                    <?php else: ?>
                                        <span class="badge" style="background:<?= $chip[1]; ?>;color:<?= $chip[0]; ?>;border:1px solid <?= $chip[0]; ?>;font-size:.68rem;"><?= htmlspecialchars($chip[2]); ?></span>
                                    <?php endif; ?>
                                </td>
                                <td class="text-end">
                                    <?php if ($canEditMilestone): ?>
                                        <button type="button" class="btn btn-sm btn-outline-danger btn-del-ms" data-id="<?= (int)$m['c0d']; ?>" title="Remove"><i class="fas fa-times"></i></button>
                                    <?php endif; ?>
                                </td>
                            </tr>
                        <?php endforeach; ?>
                    </tbody>
                </table>
            </div>
        <?php endif; ?>
    </div>
</div>

<?php if ($canEditMilestone): ?>
<script>
(function () {
    var $add = document.getElementById('btn_add_ms');
    if ($add) $add.addEventListener('click', function () {
        var t = (document.getElementById('ms_title').value || '').trim();
        if (!t) { $.alert({title:'Title required', content:'Give the milestone a title.', type:'orange'}); return; }
        $.post('<?= PROOT; ?>Projects/milestoneAddAj', {
            project_id: <?= (int)$p['c0d']; ?>,
            title: t,
            description: (document.getElementById('ms_desc').value || '').trim(),
            target_date: (document.getElementById('ms_target').value || '').trim(),
            owner_slot: document.getElementById('ms_owner_slot').value
        }, function (r) {
            if (r && r.ok) { rsToast('Added.', 'success'); setTimeout(function(){ location.reload(); }, 400); }
            else { $.alert({title:'Could not add', content:(r && r.msg) || 'Server error', type:'red'}); }
        }, 'json');
    });

    document.querySelectorAll('.ms-status').forEach(function (sel) {
        sel.addEventListener('change', function () {
            var id = sel.getAttribute('data-id');
            $.post('<?= PROOT; ?>Projects/milestoneUpdateAj', { id: id, status: sel.value }, function (r) {
                if (r && r.ok) { rsToast('Updated.', 'success'); setTimeout(function(){ location.reload(); }, 400); }
                else { $.alert({title:'Could not update', content:(r && r.msg) || 'Server error', type:'red'}); }
            }, 'json');
        });
    });

    document.querySelectorAll('.btn-del-ms').forEach(function (b) {
        b.addEventListener('click', function () {
            var id = b.getAttribute('data-id');
            $.confirm({
                title: 'Remove milestone?', content: 'This is a soft delete — audit trail preserved.', type: 'orange',
                buttons: {
                    confirm: { text: 'Remove', btnClass: 'btn-warning', action: function () {
                        $.post('<?= PROOT; ?>Projects/milestoneDeleteAj', { id: id }, function (r) {
                            if (r && r.ok) { rsToast('Removed.', 'success'); setTimeout(function(){ location.reload(); }, 400); }
                            else { $.alert({title:'Could not remove', content:(r && r.msg) || 'Server error', type:'red'}); }
                        }, 'json');
                    }},
                    cancel: function () {}
                }
            });
        });
    });
})();
</script>
<?php endif; ?>

<div class="card border-0 shadow-sm mb-3">
    <div class="card-header bg-white d-flex align-items-center justify-content-between">
        <strong><i class="fas fa-clipboard-check me-2 text-muted"></i>CRM Onboarding</strong>
        <div>
            <?php
                $crmClass = [
                    'APPROVED'    => 'bg-success',
                    'SUBMITTED'   => 'bg-info text-white',
                    'IN_PROGRESS' => 'bg-warning text-dark',
                    'MIGRATED'    => 'bg-secondary',
                    'NOT_STARTED' => 'bg-light text-muted',
                    'DECLINED'    => 'bg-danger',
                ][$p['crm_status']] ?? 'bg-light text-muted';
            ?>
            <span class="badge <?= $crmClass; ?>" style="text-transform:capitalize;"><?= htmlspecialchars(strtolower(str_replace('_',' ',$p['crm_status']))); ?></span>
            <?php if ((int)$p['migrated_flag'] === 1): ?><span class="badge bg-warning text-dark ms-1">⚠ Migrated</span><?php endif; ?>
        </div>
    </div>
    <div class="card-body p-3">
        <div class="mb-3">
            <div class="d-flex justify-content-between align-items-center mb-1">
                <div class="text-muted small">Checklist</div>
                <div class="d-flex align-items-center gap-2">
                    <?php if (strtolower((string)($p['project_type'] ?? '')) === 'services' && $canEditChecklist): ?>
                        <button type="button" class="btn btn-sm btn-link p-0" style="font-size:.72rem;" onclick="rsRefreshServicesChecks(<?= (int)$p['c0d']; ?>)" title="Auto-tick items that match live service-contract data">
                            <i class="fas fa-sync-alt me-1"></i>Refresh checks
                        </button>
                    <?php endif; ?>
                    <div class="text-muted small"><?= $done; ?> / <?= $total; ?> complete</div>
                </div>
            </div>
            <div class="progress" style="height:6px;">
                <div class="progress-bar" role="progressbar" style="width:<?= $total>0?round($done*100/$total):0; ?>%;background:<?= BRAND_COLOR; ?>;"></div>
            </div>
        </div>

        <div class="row g-2">
            <?php foreach ($ck as $it): ?>
                <div class="col-md-6 col-lg-4">
                    <label class="d-flex align-items-center gap-2 p-2 rounded" style="border:1px solid var(--rs-border,#e2e8f0);cursor:<?= $canEditChecklist?'pointer':'default'; ?>;<?= (int)$it['is_complete']===1?'background:#f0faf3;':''; ?>">
                        <input type="checkbox"
                               <?= (int)$it['is_complete']===1?'checked':''; ?>
                               <?= $canEditChecklist?'':'disabled'; ?>
                               onchange="rsToggleChecklist(<?= (int)$it['c0d']; ?>, this)">
                        <span style="font-size:.82rem;"><?= htmlspecialchars($it['checklist_label']); ?></span>
                    </label>
                </div>
            <?php endforeach; ?>
        </div>

        <?php if (!empty($appr)): ?>
            <div class="alert alert-info mt-3 mb-0 py-2">
                <i class="fas fa-hourglass-half me-1"></i>
                Approval in progress · Step <strong><?= htmlspecialchars($appr['current_step_label'] ?? ''); ?></strong> · Role gate: <code><?= htmlspecialchars($appr['current_step_role'] ?? ''); ?></code>.
                <a href="<?= PROOT; ?>FinChains/view/<?= (int)$appr['c0d']; ?>" class="btn btn-sm btn-outline-primary ms-2">Open approval</a>
            </div>
        <?php elseif ($canSubmit): ?>
            <div class="mt-3 text-end">
                <button type="button" class="btn btn-sm btn-primary" style="background:<?= BRAND_COLOR; ?>;border-color:<?= BRAND_COLOR; ?>;" onclick="rsSubmitOnboarding(<?= (int)$p['c0d']; ?>)">
                    <i class="fas fa-paper-plane me-1"></i> Submit for CRM Approval
                </button>
            </div>
        <?php elseif ($p['crm_status'] === 'APPROVED'): ?>
            <div class="alert alert-success mt-3 mb-0 py-2"><i class="fas fa-check-circle me-1"></i> Project is onboarded and Ops gates are open.</div>
        <?php elseif ((int)$p['migrated_flag'] === 1): ?>
            <div class="alert alert-warning mt-3 mb-0 py-2"><i class="fas fa-exclamation-triangle me-1"></i> Legacy project · onboarding bypassed. Ops gates are open but flagged in every report.</div>
        <?php elseif ($total > 0): ?>
            <div class="alert alert-secondary mt-3 mb-0 py-2 small text-muted">Complete all checklist items to enable submission.</div>
        <?php endif; ?>
    </div>
</div>

<!-- ── Slice 8g · Goods PC authoring surface (was CRM) ──────────────────── -->
<?php if ($isGoodsCrmPhase):
    // Slice 8Z: role-aware — PC/Proc do NOT see margin/cost internals; PM/FM/Exec/Admin do.
    $poIsHandedOver = !empty($goodsPo['handover_at']);
    $poStatus       = (string)($goodsPo['status'] ?? '');
    $hideMargin     = in_array($group, ['projects coordinator','procurement'], true);
    $priceLabel     = $hideMargin ? 'Sourcing ceiling' : 'Unit sell';
    // Confirm-progress counters for header chip + handover gate
    $itemsCount     = count($goodsItems);
    $confirmedCount = 0; foreach ($goodsItems as $it) if (($it['item_status'] ?? 'PENDING') === 'CONFIRMED') $confirmedCount++;
    $allConfirmed   = $itemsCount > 0 && $confirmedCount === $itemsCount;
?>
<div class="card border-0 shadow-sm mb-3" style="border-left:3px solid #7A9E7E !important;">
    <div class="card-header bg-white d-flex align-items-center justify-content-between" style="cursor:pointer;user-select:none;"
         data-bs-toggle="collapse" data-bs-target="#cardGoodsAuthoringBody" aria-expanded="true" aria-controls="cardGoodsAuthoringBody">
        <div>
            <i class="fas fa-boxes me-2 text-muted"></i>
            <strong>Items to Supply · PC authoring</strong>
            <span class="text-muted small ms-2">Every item the customer expects — spec, brand, sourcing ceiling, delivery. Locked once handed over.</span>
        </div>
        <div class="d-flex align-items-center gap-2">
            <?php if ($poIsHandedOver): ?>
                <span class="badge" style="background:#7A8BA1;color:#fff;font-size:.68rem;"><i class="fas fa-truck me-1"></i>Handed over · Sourcing</span>
            <?php elseif ($itemsCount > 0): ?>
                <span class="badge" style="background:<?= $allConfirmed ? '#EAF2E8' : '#F1F5F9'; ?>;color:<?= $allConfirmed ? '#3F5C43' : '#334155'; ?>;font-size:.68rem;">
                    <?= $confirmedCount; ?> / <?= $itemsCount; ?> confirmed
                </span>
            <?php endif; ?>
            <?php if (!empty($goodsAppr)): ?>
                <span class="badge bg-info text-white" onclick="event.stopPropagation();"><i class="fas fa-hourglass-half me-1"></i> Chain step: <?= htmlspecialchars($goodsAppr['current_step_label'] ?? '—'); ?></span>
                <a href="<?= PROOT; ?>FinChains/view/<?= (int)$goodsAppr['c0d']; ?>" class="btn btn-sm btn-outline-primary ms-2" onclick="event.stopPropagation();">Open approval</a>
            <?php elseif ($p['crm_status'] === 'DECLINED'): ?>
                <span class="badge bg-danger" onclick="event.stopPropagation();">Declined — edit + resubmit</span>
            <?php endif; ?>
            <i class="fas fa-chevron-down" style="color:#94A3B8;font-size:.7rem;"></i>
        </div>
    </div>
    <div class="collapse show" id="cardGoodsAuthoringBody">
    <div class="card-body p-3" style="background:#FAF8F4;">

    <!-- 8Z-Vue · PC scrub Vue root. Hydrates from window.__pcScrubData; all CRUD is reactive. -->
    <div id="pc-scrub-root" v-cloak>

        <!-- Handover banner (Vue-driven) -->
        <div v-if="isHandedOver" class="alert py-2 mb-3 d-flex align-items-start justify-content-between" style="background:#E8EEF3;border:1px solid #7A8BA1;color:#334155;font-size:.82rem;">
            <div>
                <i class="fas fa-truck me-1"></i>
                <strong>PO in Sourcing</strong> &mdash; handed over to <strong>{{ procUserName || 'Procurement' }}</strong>
                <span v-if="po.handover_at"> on {{ po.handover_at }}</span>
                <span v-if="po.handover_by_name"> by {{ po.handover_by_name }}</span>.
                Items are locked; Procurement is drafting supplier LPOs.
                <div v-if="po.handover_notes" class="small mt-1" style="color:#64748B;">
                    Handover note: <em>&ldquo;{{ po.handover_notes }}&rdquo;</em>
                </div>
            </div>
            <a v-if="po.c0d" :href="'<?= PROOT; ?>GoodsClientPos/view/' + po.c0d" class="btn btn-sm text-decoration-none ms-2 flex-shrink-0" style="background:#7A8BA1;border-color:#7A8BA1;color:#fff;font-weight:600;">
                Open Procurement workspace <i class="fas fa-arrow-right ms-1"></i>
            </a>
        </div>

        <!-- Three item-authoring paths -->
        <div v-if="canEdit && !isHandedOver" class="mb-3 p-2 rounded" style="background:#FFF;border:1px solid #E2E8F0;">
            <div class="d-flex align-items-center gap-2 mb-2">
                <strong style="color:#334155;font-size:.82rem;"><i class="fas fa-magic me-1" style="color:#7A9E7E;"></i>Add items three ways</strong>
                <span class="text-muted small" style="font-size:.7rem;color:#94A3B8;">PC's authoring surface &mdash; pick whichever fits the source data.</span>
            </div>
            <div class="row g-2">
                <!-- Path 1: Convert from tender -->
                <div class="col-md-4">
                    <div class="p-2 rounded h-100" style="background:#F8FAFC;border:1px dashed #7A9E7E;">
                        <div class="mb-1"><strong style="color:#3F5C43;font-size:.78rem;"><i class="fas fa-clone me-1"></i>1. Convert from tender</strong></div>
                        <div class="small text-muted mb-2" style="font-size:.68rem;color:#64748B;">
                            Clone every tender scope line into this PO. Existing lines with the same description are skipped.
                        </div>
                        <button type="button" class="btn btn-sm w-100" :disabled="!tenderId || busy" @click="convertScope" style="background:#7A9E7E;border-color:#7A9E7E;color:#fff;font-weight:600;">
                            <i class="fas fa-clone me-1"></i>Convert tender scope
                        </button>
                    </div>
                </div>
                <!-- Path 2: Import XLSX -->
                <div class="col-md-4">
                    <div class="p-2 rounded h-100" style="background:#F8FAFC;border:1px dashed #7A8BA1;">
                        <div class="mb-1"><strong style="color:#334155;font-size:.78rem;"><i class="fas fa-file-import me-1"></i>2. Import XLSX / CSV</strong></div>
                        <div class="small text-muted mb-2" style="font-size:.68rem;color:#64748B;">
                            Pick a spreadsheet &mdash; parsed in your browser via SheetJS. Preview before insert.
                            <a :href="endpoints.template" style="color:#7A8BA1;text-decoration:underline;">Download template</a>
                        </div>
                        <div class="d-flex gap-1">
                            <input type="file" ref="importFile" class="form-control form-control-sm" accept=".xlsx,.xls,.csv" style="font-size:.7rem;">
                            <button type="button" class="btn btn-sm" @click="importXlsx" style="background:#7A8BA1;border-color:#7A8BA1;color:#fff;font-weight:600;white-space:nowrap;">
                                <i class="fas fa-upload"></i>
                            </button>
                        </div>
                    </div>
                </div>
                <!-- Path 3: Manual (form below) -->
                <div class="col-md-4">
                    <div class="p-2 rounded h-100" style="background:#F8FAFC;border:1px dashed #D4A574;">
                        <div class="mb-1"><strong style="color:#8B6914;font-size:.78rem;"><i class="fas fa-keyboard me-1"></i>3. Manual entry</strong></div>
                        <div class="small text-muted" style="font-size:.68rem;color:#64748B;">Use the form below for one line at a time.</div>
                    </div>
                </div>
            </div>
        </div>

        <!-- Manual add-item form -->
        <div v-if="canEdit && !isHandedOver" class="row g-2 mb-3 align-items-end">
            <div class="col-md-3">
                <label class="form-label" style="font-size:.78rem;">Description</label>
                <input v-model.trim="newItem.description" class="form-control form-control-sm" placeholder="e.g. Surgical gloves size M">
            </div>
            <div class="col-md-2">
                <label class="form-label" style="font-size:.78rem;">Brand</label>
                <input v-model.trim="newItem.brand" class="form-control form-control-sm" placeholder="e.g. Ansell">
            </div>
            <div class="col-md-1">
                <label class="form-label" style="font-size:.78rem;">Qty</label>
                <input type="number" step="0.01" v-model.number="newItem.qty" class="form-control form-control-sm">
            </div>
            <div class="col-md-1">
                <label class="form-label" style="font-size:.78rem;">Unit</label>
                <input v-model.trim="newItem.unit" class="form-control form-control-sm" placeholder="box">
            </div>
            <div class="col-md-2">
                <label class="form-label" style="font-size:.78rem;">{{ priceLabel }}</label>
                <input type="number" step="0.01" v-model.number="newItem.unit_price_sell" class="form-control form-control-sm">
            </div>
            <div class="col-md-1" v-if="!hideMargin">
                <label class="form-label" style="font-size:.78rem;">Margin %</label>
                <input type="number" step="0.01" v-model.number="newItem.margin_pct" class="form-control form-control-sm">
            </div>
            <div class="col-md-1">
                <label class="form-label" style="font-size:.78rem;">Source</label>
                <select v-model="newItem.source_pref" class="form-select form-select-sm">
                    <option value="ANY">Any</option>
                    <option value="LOCAL">Local</option>
                    <option value="IMPORT">Import</option>
                </select>
            </div>
            <div class="col-md-1">
                <label class="form-label" style="font-size:.78rem;">Delivery</label>
                <input v-model.trim="newItem.delivery_method" class="form-control form-control-sm" placeholder="courier">
            </div>
            <div class="col-12 text-end">
                <button type="button" @click="addItem" :disabled="busy" class="btn btn-sm btn-primary" style="background:#7A9E7E;border-color:#7A9E7E;">
                    <i class="fas fa-plus me-1"></i> Add item
                </button>
            </div>
        </div>

        <!-- Items table -->
        <div v-if="items.length" class="table-responsive">
            <table class="table table-sm mb-0 align-middle">
                <thead class="table-light">
                    <tr>
                        <th style="width:36px;">#</th>
                        <th>Item</th>
                        <th style="width:110px;">Brand</th>
                        <th style="width:80px;">Source</th>
                        <th class="text-end" style="width:70px;">Qty</th>
                        <th style="width:60px;">Unit</th>
                        <th class="text-end" style="width:130px;">{{ priceLabel }}</th>
                        <th v-if="!hideMargin" class="text-end" style="width:100px;">Margin</th>
                        <th class="text-end" style="width:130px;">{{ hideMargin ? 'Line ceiling' : 'Line total' }}</th>
                        <th style="width:110px;">Status</th>
                        <th v-if="canEdit && !isHandedOver" style="width:90px;"></th>
                    </tr>
                </thead>
                <tbody>
                    <template v-for="it in items" :key="it.c0d">
                        <tr>
                            <td class="text-muted">{{ it.item_no }}</td>
                            <td class="small">
                                <a v-if="canEdit && !isHandedOver" href="#" @click.prevent="toggleExpand(it)" style="text-decoration:none;color:#334155;">
                                    <i class="fas" :class="it._expanded ? 'fa-caret-down' : 'fa-caret-right'" style="color:#94A3B8;"></i>
                                    {{ it.description }}
                                </a>
                                <template v-else>{{ it.description }}</template>
                                <div v-if="it.notes" class="text-muted small" style="font-size:.7rem;">{{ it.notes }}</div>
                                <span v-if="it.priority && it.priority !== 'MED'" class="badge ms-1" :style="'background:' + priorityColor[it.priority] + ';color:#fff;font-size:.58rem;'">{{ it.priority }}</span>
                                <span v-if="it.deliver_by" class="badge ms-1" style="background:#F1F5F9;color:#64748B;font-size:.58rem;"><i class="fas fa-calendar-day me-1"></i>{{ it.deliver_by }}</span>
                            </td>
                            <td class="small">{{ it.brand || '—' }}</td>
                            <td><span class="badge" :style="'background:' + sourcePill[it.source_pref].bg + ';color:' + sourcePill[it.source_pref].fg + ';'">{{ sourcePill[it.source_pref].label }}</span></td>
                            <td class="text-end small">{{ fmtQty(it.qty) }}</td>
                            <td class="small text-muted">{{ it.unit }}</td>
                            <td class="text-end">{{ fmt(it.unit_price_sell) }}</td>
                            <td v-if="!hideMargin" class="text-end small text-muted">{{ Number(it.margin_pct || 0).toFixed(2) }}%</td>
                            <td class="text-end"><strong>{{ fmt(it.line_total_sell) }}</strong></td>
                            <td>
                                <span class="badge" :style="'background:' + statusChip[it.item_status].bg + ';color:' + statusChip[it.item_status].fg + ';border:1px solid ' + statusChip[it.item_status].fg + ';font-size:.62rem;'">{{ statusChip[it.item_status].label }}</span>
                            </td>
                            <td v-if="canEdit && !isHandedOver" class="text-end">
                                <button v-if="it.item_status === 'CONFIRMED'" class="btn btn-sm btn-outline-warning" @click="unconfirmItem(it)" title="Un-confirm"><i class="fas fa-undo"></i></button>
                                <button v-else class="btn btn-sm btn-outline-success" @click="confirmItem(it)" title="Confirm"><i class="fas fa-check"></i></button>
                                <button class="btn btn-sm btn-outline-secondary" @click="removeItem(it)" title="Remove"><i class="fas fa-times"></i></button>
                            </td>
                        </tr>
                        <tr v-if="canEdit && !isHandedOver && it._expanded" style="background:#FDF7EC;">
                            <td :colspan="hideMargin ? 10 : 11" class="p-3">
                                <div class="row g-2 align-items-end">
                                    <div class="col-md-2">
                                        <label class="form-label" style="font-size:.7rem;color:#334155;">Brand / model</label>
                                        <input type="text" class="form-control form-control-sm" v-model.trim="it.brand">
                                    </div>
                                    <div class="col-md-2">
                                        <label class="form-label" style="font-size:.7rem;color:#334155;">Priority</label>
                                        <select class="form-select form-select-sm" v-model="it.priority">
                                            <option value="LOW">Low</option>
                                            <option value="MED">Medium</option>
                                            <option value="HIGH">High</option>
                                            <option value="CRITICAL">Critical</option>
                                        </select>
                                    </div>
                                    <div class="col-md-2">
                                        <label class="form-label" style="font-size:.7rem;color:#334155;">Alternates?</label>
                                        <select class="form-select form-select-sm" v-model.number="it.alt_ok">
                                            <option :value="1">Equivalent brands OK</option>
                                            <option :value="0">Exact brand only</option>
                                        </select>
                                    </div>
                                    <div class="col-md-3">
                                        <label class="form-label" style="font-size:.7rem;color:#334155;">Alt notes</label>
                                        <input type="text" class="form-control form-control-sm" v-model.trim="it.alt_note" placeholder="e.g. Cisco / Juniper / HPE equivalents OK">
                                    </div>
                                    <div class="col-md-3">
                                        <label class="form-label" style="font-size:.7rem;color:#334155;">{{ priceLabel }} (max cost)</label>
                                        <input type="number" step="0.01" class="form-control form-control-sm" v-model.number="it.unit_price_sell">
                                    </div>
                                    <div class="col-md-2">
                                        <label class="form-label" style="font-size:.7rem;color:#334155;">Deliver by</label>
                                        <input type="date" class="form-control form-control-sm" v-model="it.deliver_by">
                                    </div>
                                    <div class="col-md-4">
                                        <label class="form-label" style="font-size:.7rem;color:#334155;">Deliver to</label>
                                        <input type="text" class="form-control form-control-sm" v-model.trim="it.deliver_to" placeholder="e.g. Site A · Dodoma warehouse">
                                    </div>
                                    <div class="col-md-6">
                                        <label class="form-label" style="font-size:.7rem;color:#334155;">Scrub remarks (visible to Procurement)</label>
                                        <input type="text" class="form-control form-control-sm" v-model.trim="it.scrub_remarks" placeholder="Quality standard, warranty, spares…">
                                    </div>
                                    <div class="col-12 text-end">
                                        <button class="btn btn-sm" :disabled="it._saving" @click="saveDetails(it)" style="background:#7A9E7E;border-color:#7A9E7E;color:#fff;font-weight:600;">
                                            <i class="fas fa-save me-1"></i>{{ it._saving ? 'Saving…' : 'Save detail' }}
                                        </button>
                                    </div>
                                </div>
                            </td>
                        </tr>
                    </template>
                    <tr class="table-light">
                        <td :colspan="hideMargin ? 7 : 8" class="text-end small text-muted">{{ hideMargin ? 'Sourcing ceiling total' : 'Subtotal' }}</td>
                        <td class="text-end"><strong>{{ fmt(subtotalSell) }}</strong></td>
                        <td></td>
                        <td v-if="canEdit && !isHandedOver"></td>
                    </tr>
                </tbody>
            </table>
        </div>
        <div v-else class="text-muted small py-3 text-center">No items yet — add the first one above.</div>

        <!-- Submit for approval -->
        <div v-if="canEdit && items.length && po.crm_status !== 'SUBMITTED'" class="mt-3 text-end">
            <button type="button" @click="submitForApproval" class="btn btn-sm btn-primary" style="background:#3D5B44;border-color:#3D5B44;">
                <i class="fas fa-paper-plane me-1"></i> Submit for approval (FM → Exec → PM)
            </button>
        </div>

        <!-- Delivery block (PC-editable) -->
        <div v-if="canEdit && !isHandedOver && items.length" class="mt-3 p-3 rounded" style="background:#F0F6FA;border:1px solid #7A8BA1;">
            <div class="d-flex align-items-center justify-content-between mb-2">
                <strong style="color:#334155;font-size:.9rem;"><i class="fas fa-map-marker-alt me-1" style="color:#7A8BA1;"></i>Delivery details</strong>
                <span class="badge" :style="'background:' + (deliveryComplete ? '#EAF2E8' : '#FEF3C7') + ';color:' + (deliveryComplete ? '#3F5C43' : '#78350F') + ';font-size:.68rem;'">
                    {{ deliveryComplete ? '✓ Ready' : 'Needs Incoterm + location' }}
                </span>
            </div>
            <div class="row g-2">
                <div class="col-md-2">
                    <label class="form-label" style="font-size:.7rem;color:#334155;">Delivery mode</label>
                    <select v-model="po.delivery_mode" class="form-select form-select-sm">
                        <option value="SINGLE_LOCATION">Single location</option>
                        <option value="MULTI_LOCATION">Multiple locations (per-line)</option>
                    </select>
                </div>
                <div class="col-md-2">
                    <label class="form-label" style="font-size:.7rem;color:#334155;">
                        Incoterm <span style="color:#C48579;">*</span>
                        <a href="#" @click.prevent="showIncotermHelp" style="color:#7A8BA1;text-decoration:none;" title="What do these mean?">
                            <i class="fas fa-info-circle ms-1" style="font-size:.7rem;"></i>
                        </a>
                    </label>
                    <select v-model="po.incoterm" class="form-select form-select-sm">
                        <option value="">— Pick —</option>
                        <option v-for="i in incoterms" :key="i" :value="i">{{ i }}</option>
                    </select>
                    <div class="small mt-1" style="font-size:.62rem;line-height:1.15;">
                        <span style="color:#94A3B8;">Local → <strong style="color:#3F5C43;">DAP</strong> · Import → <strong style="color:#8B6914;">CIP</strong></span>
                        <span v-if="po.incoterm && po.incoterm !== suggestedIncoterm" class="d-block mt-1">
                            <a href="#" @click.prevent="po.incoterm = suggestedIncoterm" style="color:#7A8BA1;text-decoration:underline;">
                                <i class="fas fa-magic me-1"></i>Apply suggestion ({{ suggestedIncoterm }})
                            </a>
                        </span>
                    </div>
                </div>
                <div class="col-md-2">
                    <label class="form-label" style="font-size:.7rem;color:#334155;">Delivery deadline</label>
                    <input type="date" v-model="po.delivery_deadline" class="form-control form-control-sm">
                </div>
                <div class="col-md-6" v-if="po.delivery_mode === 'SINGLE_LOCATION'">
                    <label class="form-label" style="font-size:.7rem;color:#334155;">Primary delivery location <span style="color:#C48579;">*</span></label>
                    <input type="text" v-model.trim="po.primary_delivery_location" class="form-control form-control-sm" placeholder="e.g. TTCL HQ · Kijitonyama · Dar es Salaam">
                </div>
                <div class="col-md-6" v-else>
                    <label class="form-label" style="font-size:.7rem;color:#334155;">Multi-site note</label>
                    <div class="p-1 rounded small" style="background:#FEF3E7;border:1px dashed #D4A574;color:#8B6914;font-size:.72rem;">
                        <i class="fas fa-info-circle me-1"></i>Per-line <code>deliver_to</code> values on each item become authoritative.
                    </div>
                </div>
                <div class="col-md-3">
                    <label class="form-label" style="font-size:.7rem;color:#334155;">Site contact name</label>
                    <input type="text" v-model.trim="po.delivery_contact_name" class="form-control form-control-sm" placeholder="Receiver on site">
                </div>
                <div class="col-md-3">
                    <label class="form-label" style="font-size:.7rem;color:#334155;">Site contact phone</label>
                    <input type="text" v-model.trim="po.delivery_contact_phone" class="form-control form-control-sm" placeholder="+255 ...">
                </div>
                <div class="col-md-6">
                    <label class="form-label" style="font-size:.7rem;color:#334155;">Special instructions</label>
                    <input type="text" v-model.trim="po.delivery_special_instructions" class="form-control form-control-sm" placeholder="Gate access, forklift needed, HSE badge, weekend restrictions…">
                </div>
                <div class="col-12 text-end">
                    <button type="button" @click="saveDelivery" :disabled="savingDelivery" class="btn btn-sm" style="background:#7A8BA1;border-color:#7A8BA1;color:#fff;font-weight:600;">
                        <i class="fas fa-save me-1"></i>{{ savingDelivery ? 'Saving…' : 'Save delivery' }}
                    </button>
                </div>
            </div>
        </div>

        <!-- Overheads carry-over card -->
        <div v-if="canEdit && !isHandedOver" class="mt-3 p-3 rounded" style="background:#FDF7EC;border:1px solid #D4A574;">
            <div class="d-flex align-items-center justify-content-between mb-2">
                <div>
                    <strong style="color:#8B6914;font-size:.9rem;"><i class="fas fa-layer-group me-1"></i>Overheads carry-over</strong>
                    <div class="text-muted small mt-1" style="color:#8B6914;font-size:.7rem;">
                        Confirm which tender-time overheads apply on this project. Add anything discovered during site walk-through.
                    </div>
                </div>
                <div class="d-flex align-items-center gap-2">
                    <span v-if="overheads.length" class="badge" style="background:#FEF3E7;color:#8B6914;font-size:.68rem;">
                        {{ activeOverheadCount }} / {{ overheads.length }} active
                    </span>
                    <button v-if="tenderId" type="button" @click="seedOverheads" class="btn btn-sm" style="background:#F8FAFC;border:1px solid #D4A574;color:#8B6914;font-weight:600;">
                        <i class="fas fa-clone me-1"></i>Seed from tender
                    </button>
                </div>
            </div>

            <!-- Add-overhead row -->
            <div class="row g-2 align-items-end mb-2 p-2 rounded" style="background:#FFF;border:1px dashed #D4A574;">
                <div class="col-md-2">
                    <label class="form-label" style="font-size:.7rem;color:#334155;">Category</label>
                    <select v-model="newOverhead.category" class="form-select form-select-sm">
                        <option v-for="c in overheadCategories" :key="c" :value="c">{{ c.charAt(0) + c.slice(1).toLowerCase() }}</option>
                    </select>
                </div>
                <div class="col-md-4">
                    <label class="form-label" style="font-size:.7rem;color:#334155;">Label</label>
                    <input type="text" v-model.trim="newOverhead.label" class="form-control form-control-sm" placeholder="e.g. Site freight — Dodoma to Dar">
                </div>
                <div class="col-md-2">
                    <label class="form-label" style="font-size:.7rem;color:#334155;">Amount (initial)</label>
                    <input type="number" step="0.01" v-model.number="newOverhead.amount" class="form-control form-control-sm">
                    <div class="small text-muted" style="font-size:.6rem;color:#94A3B8;">Seeds both Estimate + Actual</div>
                </div>
                <div class="col-md-3">
                    <label class="form-label" style="font-size:.7rem;color:#334155;">Notes</label>
                    <input type="text" v-model.trim="newOverhead.notes" class="form-control form-control-sm" placeholder="Optional">
                </div>
                <div class="col-md-1">
                    <button type="button" @click="addOverhead" class="btn btn-sm w-100" style="background:#D4A574;border-color:#D4A574;color:#fff;font-weight:600;">
                        <i class="fas fa-plus"></i>
                    </button>
                </div>
            </div>

            <div v-if="overheads.length" class="table-responsive">
                <table class="table table-sm mb-0 align-middle" style="background:#fff;">
                    <thead style="background:#F1F5F9;">
                        <tr>
                            <th style="width:32px;"></th>
                            <th style="width:130px;">Category</th>
                            <th>Label</th>
                            <th class="text-end" style="width:120px;" title="Tender-time estimate (frozen)">Estimate</th>
                            <th class="text-end" style="width:130px;" title="Live committed amount — PC refines as quotes come in">Actual</th>
                            <th class="text-end" style="width:90px;" title="Actual minus Estimate">Δ</th>
                            <th>Notes</th>
                            <th style="width:100px;">Source</th>
                            <th style="width:80px;"></th>
                        </tr>
                    </thead>
                    <tbody>
                        <tr v-for="oh in overheads" :key="oh.c0d" :style="oh.active == 0 ? 'opacity:.5;' : ''">
                            <td>
                                <input type="checkbox" :checked="oh.active == 1" @change="toggleOverhead(oh, $event.target.checked)">
                            </td>
                            <td>
                                <select v-model="oh.category" @change="saveOverhead(oh)" class="form-select form-select-sm" style="font-size:.72rem;">
                                    <option v-for="c in overheadCategories" :key="c" :value="c">{{ c.charAt(0) + c.slice(1).toLowerCase() }}</option>
                                </select>
                            </td>
                            <td>
                                <input type="text" v-model.trim="oh.label" @blur="saveOverhead(oh)" class="form-control form-control-sm" style="font-size:.78rem;">
                            </td>
                            <td class="text-end text-muted" style="font-size:.78rem;" :title="'Tender-time estimate — frozen. Original value: ' + fmt(oh.amount)">
                                {{ fmt(oh.amount) }}
                            </td>
                            <td class="text-end">
                                <input type="number" step="0.01" v-model.number="oh.amount_actual" @blur="saveOverhead(oh)" class="form-control form-control-sm text-end" style="font-size:.78rem;" placeholder="—">
                            </td>
                            <td class="text-end small" :style="overheadDelta(oh) > 0 ? 'color:#C48579;font-weight:600;' : (overheadDelta(oh) < 0 ? 'color:#3F5C43;font-weight:600;' : 'color:#94A3B8;')">
                                <span v-if="oh.amount_actual !== null && oh.amount_actual !== undefined && oh.amount_actual !== ''">
                                    {{ overheadDelta(oh) > 0 ? '+' : '' }}{{ fmt(overheadDelta(oh)) }}
                                </span>
                                <span v-else>—</span>
                            </td>
                            <td>
                                <input type="text" v-model.trim="oh.notes" @blur="saveOverhead(oh)" class="form-control form-control-sm" style="font-size:.72rem;">
                            </td>
                            <td>
                                <span class="badge" :style="'background:' + (oh.source === 'TENDER_CARRY_OVER' ? '#EAF2E8' : '#FEF3E7') + ';color:' + (oh.source === 'TENDER_CARRY_OVER' ? '#3F5C43' : '#8B6914') + ';font-size:.6rem;'">
                                    {{ oh.source === 'TENDER_CARRY_OVER' ? 'Tender' : 'PC added' }}
                                </span>
                            </td>
                            <td class="text-end">
                                <button class="btn btn-sm btn-outline-danger" @click="removeOverhead(oh)" title="Remove"><i class="fas fa-times"></i></button>
                            </td>
                        </tr>
                    </tbody>
                </table>
            </div>
            <div v-else class="text-center small py-2" style="color:#8B6914;">
                <i class="fas fa-inbox me-1"></i>No overheads yet.
                <span v-if="tenderId">Click <strong>Seed from tender</strong> to import PM's overheads,</span>
                or add one manually above.
            </div>
        </div>

        <!-- Handover panel (PC/Admin only) — checks up top, note + button on their own row below -->
        <div v-if="canHandover && !isHandedOver && items.length" class="mt-3 p-3 rounded" style="background:#EEF2F6;border:1px solid #7A8BA1;">
            <div class="mb-2">
                <strong style="color:#334155;font-size:.9rem;"><i class="fas fa-truck me-1" style="color:#7A8BA1;"></i>Handover to Procurement</strong>
                <div class="text-muted small mt-1" style="color:#64748B;font-size:.75rem;">
                    Locks the items + fires a bell notification to <strong>{{ procUserName || 'the Procurement group' }}</strong>.
                </div>
            </div>
            <ul class="mb-3 small" style="font-size:.72rem;padding-left:1.2rem;">
                <li :style="'color:' + (allConfirmed ? '#3F5C43' : '#8B6914') + ';'">
                    <i class="fas" :class="allConfirmed ? 'fa-check-circle' : 'fa-exclamation-triangle'"></i>
                    All items confirmed &mdash; {{ confirmedCount }} / {{ itemsCount }}
                </li>
                <li :style="'color:' + (deliveryComplete ? '#3F5C43' : '#8B6914') + ';'">
                    <i class="fas" :class="deliveryComplete ? 'fa-check-circle' : 'fa-exclamation-triangle'"></i>
                    Delivery block complete &mdash; Incoterm{{ po.incoterm ? ' ' + po.incoterm : '' }}{{ deliveryLocationOk ? '' : ' · location missing' }}
                </li>
                <li :style="'color:' + (activeOverheadCount > 0 ? '#3F5C43' : '#8B6914') + ';'">
                    <i class="fas" :class="activeOverheadCount > 0 ? 'fa-check-circle' : 'fa-exclamation-triangle'"></i>
                    Overheads reviewed &mdash; {{ activeOverheadCount }} active
                </li>
            </ul>
            <div class="row g-2 align-items-end">
                <div class="col-md-9">
                    <label class="form-label" style="color:#334155;font-size:.72rem;">Operational note to Procurement <span class="text-muted" style="font-weight:400;">(optional)</span></label>
                    <input type="text" v-model.trim="handoverNotes" class="form-control form-control-sm" placeholder="e.g. Priority items ship first · negotiate hard on freight · pre-approved suppliers preferred">
                </div>
                <div class="col-md-3">
                    <button type="button" @click="handover" :disabled="!readyForHandover" class="btn btn-sm w-100" style="background:#7A8BA1;border-color:#7A8BA1;color:#fff;font-weight:600;">
                        <i class="fas fa-paper-plane me-1"></i>Hand over to Procurement
                    </button>
                </div>
            </div>
        </div>
    </div>
    <!-- /#pc-scrub-root -->

    <script>
    window.__pcScrubData = {
        po:                <?= json_encode($goodsPo ?: (object)[]) ?>,
        items:             <?= json_encode(array_values($goodsItems ?: [])) ?>,
        overheads:         <?= json_encode(array_values($this->data['project_overheads'] ?? [])) ?>,
        project_id:        <?= (int)$p['c0d'] ?>,
        tender_id:         <?= (int)($src['tender']['c0d'] ?? 0) ?>,
        hide_margin:       <?= $hideMargin ? 'true' : 'false' ?>,
        can_edit:          <?= $canCrmEdit && !$poIsHandedOver ? 'true' : 'false' ?>,
        is_handed_over:    <?= $poIsHandedOver ? 'true' : 'false' ?>,
        can_handover:      <?= in_array($group, ['projects coordinator','administrator'], true) && !$poIsHandedOver ? 'true' : 'false' ?>,
        proc_user_name:    <?= json_encode((string)($p['procurement_name'] ?? '')) ?>,
        price_label:       <?= json_encode($priceLabel) ?>,
        current_user_name: <?= json_encode((string)($_SESSION['full_name'] ?? '')) ?>,
        endpoints: {
            add:            '<?= PROOT ?>Projects/goodsAddItemAj',
            remove:         '<?= PROOT ?>Projects/goodsRemoveItemAj',
            update:         '<?= PROOT ?>Projects/goodsUpdateItemAj',
            confirm:        '<?= PROOT ?>Projects/goodsConfirmItemAj',
            unconfirm:      '<?= PROOT ?>Projects/goodsUnconfirmItemAj',
            convert:        '<?= PROOT ?>Projects/goodsConvertScopeAj',
            import:         '<?= PROOT ?>Projects/goodsImportItemsAj',
            handover:       '<?= PROOT ?>Projects/goodsHandoverToProcurementAj',
            submit:         '<?= PROOT ?>Projects/goodsSubmitOnboardingAj',
            template:       '<?= PROOT ?>Projects/goodsItemsTemplate',
            saveDelivery:   '<?= PROOT ?>Projects/savePoDeliveryAj',
            overheadSeed:   '<?= PROOT ?>Projects/overheadsSeedFromTenderAj',
            overheadAdd:    '<?= PROOT ?>Projects/overheadAddAj',
            overheadUpdate: '<?= PROOT ?>Projects/overheadUpdateAj',
            overheadDelete: '<?= PROOT ?>Projects/overheadDeleteAj'
        }
    };
    </script>
    <script src="<?= PROOT ?>js/Olibs/vue.global.prod.js"></script>
    <script src="<?= PROOT ?>js/Olibs/xlsx.full.min.js"></script>
    <script src="<?= PROOT ?>js/Projects/pc-scrub.js"></script>

    </div>
</div> <!-- /#cardGoodsAuthoringBody -->
</div>
<?php endif; ?>

<!-- ── Assigned seats strip (post-onboarding) ─────────────────────────── -->
<?php if ($p['crm_status'] === 'APPROVED' && (int)$p['migrated_flag'] === 0 && $p['project_type'] === 'goods'): ?>
<?php $seatCells = [
    ['label' => 'Project Manager', 'uid' => (int)($p['project_manager_id'] ?? 0), 'icon' => 'fas fa-user-tie'],
    ['label' => 'Projects Coordinator', 'uid' => (int)($p['pc_id'] ?? 0), 'icon' => 'fas fa-user-check'],
    ['label' => 'Accountant', 'uid' => (int)($p['accountant_id'] ?? 0), 'icon' => 'fas fa-calculator'],
    ['label' => 'Procurement', 'uid' => (int)($p['procurement_id'] ?? 0), 'icon' => 'fas fa-shopping-cart'],
]; ?>
<div class="card border-0 shadow-sm mb-3" style="background:#EAF2E8;">
    <div class="card-body p-3">
        <div class="row g-2">
            <?php foreach ($seatCells as $sc):
                $u = $seats[$sc['uid']] ?? null;
            ?>
                <div class="col-md-3">
                    <div class="text-muted small" style="text-transform:uppercase;letter-spacing:.4px;font-size:.6rem;">
                        <i class="<?= $sc['icon']; ?> me-1"></i> <?= htmlspecialchars($sc['label']); ?>
                    </div>
                    <div style="font-weight:600;color:#3D5B44;">
                        <?= $u ? htmlspecialchars($u['full_name']) : '<span class="text-muted">— unassigned —</span>'; ?>
                    </div>
                </div>
            <?php endforeach; ?>
        </div>
    </div>
</div>
<?php endif; ?>

<!-- ── Type-aware workspace (Goods / Works / Services) ─────────────────── -->
<?php if (!empty($ws['type'])): ?>
<div class="card border-0 shadow-sm mb-3">
    <div class="card-header bg-white d-flex align-items-center justify-content-between">
        <div>
            <i class="<?= $wsIcon; ?> me-2 text-muted"></i>
            <strong><?= htmlspecialchars(ucfirst($ws['type'])); ?> workspace</strong>
            <?php if (!$gatesOpen): ?>
                <span class="badge bg-warning text-dark ms-2">Ops gates closed until CRM approves</span>
            <?php endif; ?>
        </div>
    </div>
    <div class="card-body p-3" style="background:#FAF8F4;">
        <?php if (!empty($ws['note'])): ?>
            <div class="mb-3" style="font-size:.82rem;color:#5B4F3C;">
                <i class="fas fa-info-circle me-1"></i> <?= $ws['note']; /* trusted static copy from controller */ ?>
            </div>
        <?php endif; ?>

        <?php if (!empty($ws['kpis'])): ?>
        <div class="row g-2 mb-3">
            <?php foreach ($ws['kpis'] as $label => $meta): ?>
                <div class="col-md">
                    <a href="<?= PROOT; ?><?= htmlspecialchars($meta['url']); ?>" class="d-block p-2 border rounded text-decoration-none" style="background:#fff;color:#334155;">
                        <div class="text-muted small" style="text-transform:uppercase;letter-spacing:.4px;font-size:.6rem;"><?= htmlspecialchars($label); ?></div>
                        <div style="font-weight:700;font-size:1rem;"><?= htmlspecialchars((string)$meta['value']); ?></div>
                    </a>
                </div>
            <?php endforeach; ?>
        </div>
        <?php endif; ?>

        <?php if (!empty($ws['actions'])): ?>
        <div>
            <?php foreach ($ws['actions'] as $a):
                $btn = !empty($a['primary']) ? 'btn-primary' : 'btn-outline-secondary';
                $style = !empty($a['primary']) ? 'background:#7A9E7E;border-color:#7A9E7E;' : '';
                $disabled = !$gatesOpen ? 'disabled aria-disabled="true" style="pointer-events:none;opacity:.5;' . $style . '"' : 'style="' . $style . '"';
            ?>
                <a href="<?= $gatesOpen ? PROOT . htmlspecialchars($a['url']) : '#'; ?>" class="btn btn-sm <?= $btn; ?> me-1 mb-1" <?= $disabled; ?>>
                    <i class="<?= htmlspecialchars($a['icon']); ?> me-1"></i> <?= htmlspecialchars($a['label']); ?>
                </a>
            <?php endforeach; ?>
        </div>
        <?php endif; ?>
    </div>
</div>
<?php endif; ?>

<script>
function rsToggleChecklist(id, el) {
    fetch('<?= PROOT; ?>Onboarding/toggleAj', {
        method: 'POST',
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        body: 'item_id=' + encodeURIComponent(id) + '&is_complete=' + (el.checked ? 1 : 0)
    }).then(r => r.json()).then(j => {
        if (!j.ok) { alert(j.msg || 'Save failed'); el.checked = !el.checked; return; }
        location.reload();
    }).catch(() => { alert('Network error'); el.checked = !el.checked; });
}
function rsSubmitOnboarding(pid) {
    if (!confirm('Submit this project for CRM onboarding approval? PC will accept first, then Executive signs off.')) return;
    fetch('<?= PROOT; ?>Onboarding/submitAj', {
        method: 'POST',
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        body: 'project_id=' + encodeURIComponent(pid)
    }).then(r => r.json()).then(j => {
        alert(j.msg || (j.ok?'Submitted':'Failed'));
        if (j.ok) location.reload();
    });
}
// Slice 8S-9 · Auto-tick Services checklist against live contract data
function rsRefreshServicesChecks(pid) {
    fetch('<?= PROOT; ?>Onboarding/syncServicesChecklistAj', {
        method: 'POST',
        headers: {'Content-Type': 'application/x-www-form-urlencoded'},
        body: 'project_id=' + encodeURIComponent(pid)
    }).then(r => r.json()).then(j => {
        if (!j.ok) { alert(j.msg || 'Refresh failed'); return; }
        var on  = (j.flipped_on  || []).length;
        var off = (j.flipped_off || []).length;
        if (on === 0 && off === 0) {
            if (typeof rsToast === 'function') rsToast('Checklist already in sync.', 'info');
            else alert('Checklist already in sync.');
            return;
        }
        var msg = 'Auto-ticked ' + on + ', un-ticked ' + off + '.';
        if (typeof rsToast === 'function') rsToast(msg, 'success');
        else alert(msg);
        setTimeout(function(){ location.reload(); }, 350);
    }).catch(function(){ alert('Network error'); });
}

// Slice 8g · Goods CRM authoring — item add / remove / submit
$('#gi_add').on('click', function () {
    var payload = {
        project_id:      <?= (int)$p['c0d']; ?>,
        description:     $('#gi_desc').val().trim(),
        brand:           $('#gi_brand').val().trim(),
        source_pref:     $('#gi_src').val(),
        delivery_method: $('#gi_del').val(),
        qty:             $('#gi_qty').val(),
        unit:            $('#gi_unit').val(),
        unit_price_sell: $('#gi_px').val(),
        margin_pct:      $('#gi_mp').val(),
    };
    if (!payload.description) { rsToast('Description required.', 'error'); return; }
    $.post('<?= PROOT; ?>Projects/goodsAddItemAj', payload, 'json')
        .done(function (r) {
            if (r && r.ok) location.reload();
            else            rsToast('Failed: ' + (r.msg || 'unknown'), 'error');
        });
});

$('.btn-gi-del').on('click', function () {
    var itemId = $(this).data('id');
    var poId   = $(this).data('po');
    $.confirm({
        title: 'Remove this item?', content: '', boxWidth: '360px', useBootstrap: false,
        buttons: {
            confirm: { text: 'Remove', btnClass: 'btn-danger', action: function () {
                $.post('<?= PROOT; ?>Projects/goodsRemoveItemAj', { po_id: poId, item_id: itemId }, 'json')
                    .done(function (r) {
                        if (r && r.ok) location.reload();
                        else            rsToast('Failed: ' + (r.msg || 'unknown'), 'error');
                    });
            }},
            cancel: { text: 'Cancel' }
        }
    });
});

$('#gi_submit').on('click', function () {
    $.confirm({
        title: 'Submit for approval?',
        content: '<p style="font-size:.85rem;color:#5B4F3C;">Chain will walk <strong>FM → Exec → PM</strong>. FM assigns Accountant + Procurement; Exec assigns PM; PM assigns PC. Ops gates open on PM terminal.</p>',
        boxWidth: '440px', useBootstrap: false,
        buttons: {
            confirm: { text: 'Submit', btnClass: 'btn-primary', action: function () {
                $.post('<?= PROOT; ?>Projects/goodsSubmitOnboardingAj', { project_id: <?= (int)$p['c0d']; ?> }, 'json')
                    .done(function (r) {
                        if (r && r.ok) { rsToast('Submitted for approval.', 'success'); location.reload(); }
                        else            rsToast('Failed: ' + (r.msg || 'unknown'), 'error');
                    });
            }},
            cancel: { text: 'Cancel' }
        }
    });
});
</script>

<!-- ─── Slice 8Z-y · Vue 3 Options API root for #svc_scope_root · no reloads ─── -->
<?php if (($p['project_type'] ?? '') === 'services' && ($CID ?? 0) > 0): ?>
<style>[v-cloak]{display:none !important;}</style>
<script src="<?= PROOT ?>js/Olibs/vue.global.prod.js"></script>
<script>
(function () {
    var CID   = <?= (int)$CID; ?>;
    var PID   = <?= (int)$p['c0d']; ?>;
    var PROOT = <?= json_encode(PROOT); ?>;
    var canPmEdit = <?= !empty($canPmEdit) ? 'true' : 'false'; ?>;
    var bootContract = <?= json_encode($svcContract ?? [], JSON_UNESCAPED_SLASHES); ?>;
    var bootBindings = <?= json_encode($svcBindings ?? [], JSON_UNESCAPED_SLASHES); ?>;
    var bootPacks    = <?= json_encode($svcPacks    ?? [], JSON_UNESCAPED_SLASHES); ?>;
    var bootEquip    = <?= json_encode(array_values($effectiveEquip ?? []), JSON_UNESCAPED_SLASHES); ?>;
    var bootSites    = <?= (int)$sitesTarget; ?>;
    var bidSites     = <?= (int)($svcSpec['no_of_sites'] ?? 0); ?>;
    var TPL_FLAT     = <?= json_encode(array_map(fn($t) => ['c0d'=>(int)$t['c0d'], 'slug'=>$t['slug'], 'label'=>$t['label'], 'scope'=>$t['scope'], 'category'=>$t['category']], $svcTplFlat), JSON_UNESCAPED_SLASHES); ?>;

    if (typeof Vue === 'undefined') {
        $('#svc_scope_root').removeAttr('v-cloak').css('display','block');
        $('#svc_scope_root').prepend('<div class="alert alert-warning small m-3">Scope UI could not initialise (Vue failed to load).</div>');
        return;
    }

    var esc = function (s) { return String(s == null ? '' : s).replace(/&/g,'&amp;').replace(/"/g,'&quot;').replace(/</g,'&lt;'); };

    var app = Vue.createApp({
        data: function () {
            return {
                CID: CID, PID: PID, PROOT: PROOT, canPmEdit: canPmEdit,
                sitesTarget: bootSites, bidSites: bidSites,
                equipMix:  (bootEquip    || []).slice(),
                bindings:  (bootBindings || []).slice(),
                packs:     (bootPacks    || []).slice(),
                scopeConfirmedOn:     bootContract.scope_confirmed_on     || '',
                scopeConfirmedByName: bootContract.scope_confirmed_by_name || '',
                sparePolicy:          bootContract.spare_policy           || '',
                savingScope: false,
                supplyColors: { 'CLIENT':'#7A9E7E','COMPANY':'#7A8BA1','CONSIGNMENT':'#D4A574','FIXED_PACK':'#94A3B8' }
            };
        },
        computed: {
            fmtConfirmed: function () {
                if (!this.scopeConfirmedOn) return '';
                var d = new Date(String(this.scopeConfirmedOn).replace(' ', 'T'));
                if (isNaN(d.getTime())) return this.scopeConfirmedOn;
                var M = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
                return d.getDate() + ' ' + M[d.getMonth()] + ' · ' + String(d.getHours()).padStart(2,'0') + ':' + String(d.getMinutes()).padStart(2,'0');
            }
        },
        methods: {
            classLabel:  function (eq) { return ((eq.type || '') + ' ' + (eq.size || '')).trim(); },
            bindingsByClass: function (cls) { return this.bindings.filter(function (b) { return String(b.equipment_class || '') === cls; }); },
            cadenceNote: function (b) {
                if (b.cadence_override_days) return b.cadence_override_days + ' days (override)';
                return b.cadence_note || '';
            },
            fmtQty: function (q) {
                var v = parseFloat(q); if (!isFinite(v)) return '';
                var s = v.toFixed(4); return s.replace(/\.?0+$/, '');
            },
            supplyColor: function (sm) { return this.supplyColors[sm] || '#94A3B8'; },

            refresh: function () {
                var self = this;
                $.post(PROOT + 'Projects/svcScopeSnapshotAj', { contract_id: self.CID }, 'json').done(function (res) {
                    if (!res || !res.ok) return;
                    self.bindings = res.bindings || [];
                    self.packs    = res.packs    || [];
                    var c = res.contract || {};
                    self.scopeConfirmedOn     = c.scope_confirmed_on     || '';
                    self.scopeConfirmedByName = c.scope_confirmed_by_name || '';
                    self.sparePolicy          = c.spare_policy           || self.sparePolicy;
                    if (c.sites_target_confirmed !== null && c.sites_target_confirmed !== undefined) {
                        self.sitesTarget = parseInt(c.sites_target_confirmed, 10) || 0;
                    }
                    var eqJson = c.equipment_scope_confirmed_json;
                    if (eqJson) {
                        try { var parsed = JSON.parse(eqJson); if (Array.isArray(parsed)) self.equipMix = parsed; } catch (e) {}
                    }
                });
            },

            /* ── Y-A · Scope ─────────────────────────────────────────── */
            saveScope: function () {
                var self = this; self.savingScope = true;
                $.post(PROOT + 'Projects/saveScopeConfirmAj', {
                    contract_id:    self.CID,
                    sites_target:   self.sitesTarget,
                    equipment_json: JSON.stringify(self.equipMix)
                }, 'json').done(function (res) {
                    self.savingScope = false;
                    if (res && res.ok) { if (window.rsToast) rsToast('Scope confirmed.', 'success'); self.refresh(); }
                    else if (window.rsToast) rsToast('Failed: ' + (res && res.msg || 'unknown'), 'error');
                }).fail(function (xhr) {
                    self.savingScope = false;
                    if (window.rsToast) rsToast('Network error saving scope (HTTP ' + xhr.status + ')', 'error');
                });
            },
            openEditEquipMix: function () {
                var self = this;
                var current = self.equipMix.slice();
                function rowHtml(r) {
                    r = r || {};
                    return '<div class="row g-1 mb-1 eq-row">'
                         + '<div class="col-4"><input type="text" class="form-control form-control-sm eq-type" placeholder="Type (GEN/AC/UPS)" value="' + esc(r.type) + '"></div>'
                         + '<div class="col-5"><input type="text" class="form-control form-control-sm eq-size" placeholder="Size / rating" value="' + esc(r.size) + '"></div>'
                         + '<div class="col-2"><input type="number" min="0" class="form-control form-control-sm eq-count text-end" placeholder="Qty" value="' + esc(r.count) + '"></div>'
                         + '<div class="col-1"><button type="button" class="btn btn-sm eq-del" style="background:transparent;border:none;color:#C48579;"><i class="fas fa-times"></i></button></div>'
                         + '</div>';
                }
                var rowsHtml = current.length ? current.map(rowHtml).join('') : rowHtml({});
                $.confirm({
                    title: 'Edit equipment mix', columnClass: 'medium', type: 'blue',
                    content: '<div id="eq_rows">' + rowsHtml + '</div>'
                           + '<button type="button" id="eq_add_row" class="btn btn-sm mt-2" style="background:transparent;border:1px dashed #7A8BA1;color:#7A8BA1;font-size:.7rem;"><i class="fas fa-plus me-1"></i>Add row</button>',
                    onContentReady: function () {
                        var dlg = this;
                        dlg.$content.on('click', '#eq_add_row', function () { dlg.$content.find('#eq_rows').append(rowHtml({})); });
                        dlg.$content.on('click', '.eq-del',    function () { $(this).closest('.eq-row').remove(); });
                    },
                    buttons: {
                        apply: { text: 'Apply', btnClass: 'btn-primary', action: function () {
                            var rows = [];
                            this.$content.find('.eq-row').each(function () {
                                var t = $(this).find('.eq-type').val() || '';
                                var s = $(this).find('.eq-size').val() || '';
                                var c = parseInt($(this).find('.eq-count').val(), 10) || 0;
                                if (t.trim() || c) rows.push({ type: t.trim(), size: s.trim(), count: c });
                            });
                            self.equipMix = rows;
                            if (window.rsToast) rsToast('Equipment updated. Click Save scope to persist.', 'info', 4000);
                        }},
                        cancel: { text: 'Cancel', btnClass: 'btn-light' }
                    }
                });
            },

            /* ── Y-B · Bindings ──────────────────────────────────────── */
            openBindingAdd: function (cls, qty) {
                var self = this;
                var opts = TPL_FLAT.map(function (t) { return '<option value="' + t.c0d + '">' + esc(t.slug) + ' · ' + esc(t.label) + '</option>'; }).join('');
                $.confirm({
                    title: 'Bind template to ' + cls, type: 'blue',
                    content: '<div class="mb-2"><label class="form-label small text-muted">Template</label><select id="bind_tpl" class="form-select form-select-sm">' + opts + '</select></div>'
                           + '<div class="mb-2"><label class="form-label small text-muted">Cadence override (days) — leave blank to use template default</label><input type="number" min="0" id="bind_cad" class="form-control form-control-sm"></div>'
                           + '<div class="mb-2"><label class="form-label small text-muted">Notes</label><input type="text" id="bind_note" class="form-control form-control-sm"></div>',
                    buttons: {
                        save: { text: 'Bind', btnClass: 'btn-primary', action: function () {
                            $.post(PROOT + 'Projects/bindingSaveAj', {
                                contract_id: self.CID, equipment_class: cls, equipment_qty: qty,
                                template_id: $('#bind_tpl').val(), cadence_override_days: $('#bind_cad').val(), notes: $('#bind_note').val()
                            }, 'json').done(function (res) {
                                if (res && res.ok) { if (window.rsToast) rsToast('Template bound.', 'success'); self.refresh(); }
                                else if (window.rsToast) rsToast('Failed: ' + (res && res.msg || 'unknown'), 'error');
                            });
                        }},
                        cancel: { text: 'Cancel', btnClass: 'btn-light' }
                    }
                });
            },
            openBindingSuggest: function (cls, qty) {
                var self = this;
                $.post(PROOT + 'Projects/bindingSuggestDefaultsAj', {
                    contract_id: self.CID, equipment_class: cls, equipment_qty: qty
                }, 'json').done(function (res) {
                    if (res && res.ok) {
                        if (window.rsToast) rsToast('Suggested ' + (res.added || 0) + ' template(s). Skipped ' + (res.skipped || 0) + '.', 'success');
                        self.refresh();
                    } else if (window.rsToast) rsToast('Failed: ' + (res && res.msg || 'unknown'), 'error');
                });
            },
            bindingAutoSuggestAll: function () {
                var self = this;
                var mix = self.equipMix.slice();
                if (!mix.length) { if (window.rsToast) rsToast('Confirm equipment mix first.', 'warning'); return; }
                $.confirm({
                    title: 'Auto-suggest templates for every equipment class?', type: 'blue',
                    content: 'The templates catalog will be scanned for each of your ' + mix.length + ' equipment class(es). Existing bindings are preserved.',
                    buttons: {
                        go: { text: 'Suggest all', btnClass: 'btn-primary', action: function () {
                            var pending = mix.length; var totalAdded = 0;
                            mix.forEach(function (eq) {
                                var label = self.classLabel(eq);
                                $.post(PROOT + 'Projects/bindingSuggestDefaultsAj', {
                                    contract_id: self.CID, equipment_class: label, equipment_qty: eq.count
                                }, 'json').done(function (res) {
                                    if (res && res.ok) totalAdded += (res.added || 0);
                                }).always(function () {
                                    pending--;
                                    if (pending <= 0) {
                                        if (window.rsToast) rsToast('Suggested ' + totalAdded + ' binding(s) across ' + mix.length + ' class(es).', 'success');
                                        self.refresh();
                                    }
                                });
                            });
                        }},
                        cancel: { text: 'Cancel', btnClass: 'btn-light' }
                    }
                });
            },
            removeBinding: function (b) {
                var self = this;
                $.confirm({
                    title: 'Remove template binding?', type: 'orange',
                    content: 'PM schedule generation will exclude this template on the next run.',
                    buttons: {
                        yes: { text: 'Remove', btnClass: 'btn-warning', action: function () {
                            $.post(PROOT + 'Projects/bindingRemoveAj', { binding_id: b.c0d }, 'json').done(function (res) {
                                if (res && res.ok) {
                                    if (window.rsToast) rsToast('Removed.', 'success');
                                    self.bindings = self.bindings.filter(function (x) { return x.c0d !== b.c0d; });
                                } else if (window.rsToast) rsToast('Failed: ' + (res && res.msg || 'unknown'), 'error');
                            });
                        }},
                        cancel: { text: 'Cancel', btnClass: 'btn-light' }
                    }
                });
            },

            /* ── Y-C · Packs + items ─────────────────────────────────── */
            packFormHtml: function (pk) {
                pk = pk || {};
                var models = ['CLIENT','COMPANY','CONSIGNMENT','FIXED_PACK'];
                var opts = models.map(function (m) { return '<option value="' + m + '"' + ((pk.supply_model || 'CLIENT') === m ? ' selected' : '') + '>' + m + '</option>'; }).join('');
                var tplOpts = '<option value="">— none —</option>' + TPL_FLAT.map(function (t) {
                    return '<option value="' + esc(t.slug) + '"' + ((pk.linked_template_slug || '') === t.slug ? ' selected' : '') + '>' + esc(t.slug) + ' · ' + esc(t.label) + '</option>';
                }).join('');
                return ''
                     + '<div class="mb-2"><label class="form-label small text-muted">Pack name *</label><input type="text" id="pk_name" class="form-control form-control-sm" value="' + esc(pk.name) + '"></div>'
                     + '<div class="row g-2"><div class="col-6"><label class="form-label small text-muted">Code</label><input type="text" id="pk_code" class="form-control form-control-sm" value="' + esc(pk.code) + '"></div>'
                     + '<div class="col-6"><label class="form-label small text-muted">Supply model</label><select id="pk_sm" class="form-select form-select-sm">' + opts + '</select></div></div>'
                     + '<div class="mb-2 mt-2"><label class="form-label small text-muted">Linked template (optional)</label><select id="pk_lt" class="form-select form-select-sm">' + tplOpts + '</select></div>'
                     + '<div><label class="form-label small text-muted">Notes</label><textarea id="pk_notes" class="form-control form-control-sm" rows="2">' + esc(pk.notes) + '</textarea></div>';
            },
            collectPackPayload: function () {
                return { name: $('#pk_name').val(), code: $('#pk_code').val(),
                         supply_model: $('#pk_sm').val(), linked_template_slug: $('#pk_lt').val(),
                         notes: $('#pk_notes').val() };
            },
            openPackAdd: function () {
                var self = this;
                $.confirm({
                    title: 'Add spare-part pack', content: self.packFormHtml({}), columnClass: 'medium', type: 'blue',
                    buttons: {
                        save: { text: 'Add', btnClass: 'btn-primary', action: function () {
                            var payload = self.collectPackPayload(); payload.contract_id = self.CID;
                            $.post(PROOT + 'Projects/packSaveAj', payload, 'json').done(function (res) {
                                if (res && res.ok) { if (window.rsToast) rsToast('Pack added.', 'success'); self.refresh(); }
                                else if (window.rsToast) rsToast('Failed: ' + (res && res.msg || 'unknown'), 'error');
                            });
                        }},
                        cancel: { text: 'Cancel', btnClass: 'btn-light' }
                    }
                });
            },
            openPackEdit: function (pk) {
                var self = this;
                $.confirm({
                    title: 'Edit pack', content: self.packFormHtml(pk), columnClass: 'medium', type: 'blue',
                    buttons: {
                        save: { text: 'Save', btnClass: 'btn-primary', action: function () {
                            var payload = self.collectPackPayload(); payload.contract_id = self.CID; payload.c0d = pk.c0d;
                            $.post(PROOT + 'Projects/packSaveAj', payload, 'json').done(function (res) {
                                if (res && res.ok) { if (window.rsToast) rsToast('Saved.', 'success'); self.refresh(); }
                                else if (window.rsToast) rsToast('Failed: ' + (res && res.msg || 'unknown'), 'error');
                            });
                        }},
                        cancel: { text: 'Cancel', btnClass: 'btn-light' }
                    }
                });
            },
            removePack: function (pk) {
                var self = this;
                $.confirm({
                    title: 'Remove this pack?', type: 'orange',
                    content: 'The pack and all its items will be soft-deleted.',
                    buttons: {
                        yes: { text: 'Remove', btnClass: 'btn-warning', action: function () {
                            $.post(PROOT + 'Projects/packRemoveAj', { pack_id: pk.c0d }, 'json').done(function (res) {
                                if (res && res.ok) {
                                    if (window.rsToast) rsToast('Removed.', 'success');
                                    self.packs = self.packs.filter(function (x) { return x.c0d !== pk.c0d; });
                                } else if (window.rsToast) rsToast('Failed: ' + (res && res.msg || 'unknown'), 'error');
                            });
                        }},
                        cancel: { text: 'Cancel', btnClass: 'btn-light' }
                    }
                });
            },
            itemFormHtml: function (it) {
                it = it || {};
                return ''
                     + '<div class="row g-2"><div class="col-4"><label class="form-label small text-muted">Interval</label><input type="text" id="it_lbl" class="form-control form-control-sm" placeholder="Per visit · Every 250h" value="' + esc(it.interval_label) + '"></div>'
                     + '<div class="col-8"><label class="form-label small text-muted">Item name *</label><input type="text" id="it_nm" class="form-control form-control-sm" value="' + esc(it.item_name) + '"></div></div>'
                     + '<div class="row g-2 mt-1"><div class="col-4"><label class="form-label small text-muted">Qty</label><input type="number" step="0.0001" id="it_q" class="form-control form-control-sm text-end" value="' + esc(it.qty || 1) + '"></div>'
                     + '<div class="col-4"><label class="form-label small text-muted">UOM</label><input type="text" id="it_u" class="form-control form-control-sm" placeholder="ea · L · kg" value="' + esc(it.uom) + '"></div>'
                     + '<div class="col-4"><label class="form-label small text-muted">Notes</label><input type="text" id="it_nt" class="form-control form-control-sm" value="' + esc(it.notes) + '"></div></div>';
            },
            collectItemPayload: function () {
                return { interval_label: $('#it_lbl').val(), item_name: $('#it_nm').val(),
                         qty: $('#it_q').val(), uom: $('#it_u').val(), notes: $('#it_nt').val() };
            },
            openItemAdd: function (packId) {
                var self = this;
                $.confirm({
                    title: 'Add pack item', content: self.itemFormHtml({}), columnClass: 'medium', type: 'blue',
                    buttons: {
                        save: { text: 'Add', btnClass: 'btn-primary', action: function () {
                            var payload = self.collectItemPayload(); payload.pack_id = packId;
                            $.post(PROOT + 'Projects/packItemSaveAj', payload, 'json').done(function (res) {
                                if (res && res.ok) { if (window.rsToast) rsToast('Item added.', 'success'); self.refresh(); }
                                else if (window.rsToast) rsToast('Failed: ' + (res && res.msg || 'unknown'), 'error');
                            });
                        }},
                        cancel: { text: 'Cancel', btnClass: 'btn-light' }
                    }
                });
            },
            openItemEdit: function (it) {
                var self = this;
                $.confirm({
                    title: 'Edit item', content: self.itemFormHtml(it), columnClass: 'medium', type: 'blue',
                    buttons: {
                        save: { text: 'Save', btnClass: 'btn-primary', action: function () {
                            var payload = self.collectItemPayload(); payload.pack_id = it.pack_id; payload.c0d = it.c0d;
                            $.post(PROOT + 'Projects/packItemSaveAj', payload, 'json').done(function (res) {
                                if (res && res.ok) { if (window.rsToast) rsToast('Saved.', 'success'); self.refresh(); }
                                else if (window.rsToast) rsToast('Failed: ' + (res && res.msg || 'unknown'), 'error');
                            });
                        }},
                        cancel: { text: 'Cancel', btnClass: 'btn-light' }
                    }
                });
            },
            removeItem: function (it) {
                var self = this;
                $.confirm({
                    title: 'Remove item?', type: 'orange',
                    content: 'Pack item will be soft-deleted.',
                    buttons: {
                        yes: { text: 'Remove', btnClass: 'btn-warning', action: function () {
                            $.post(PROOT + 'Projects/packItemRemoveAj', { item_id: it.c0d }, 'json').done(function (res) {
                                if (res && res.ok) {
                                    if (window.rsToast) rsToast('Removed.', 'success');
                                    self.packs.forEach(function (pk) {
                                        if ((pk.items || []).length && pk.c0d === it.pack_id) {
                                            pk.items = pk.items.filter(function (x) { return x.c0d !== it.c0d; });
                                        }
                                    });
                                } else if (window.rsToast) rsToast('Failed: ' + (res && res.msg || 'unknown'), 'error');
                            });
                        }},
                        cancel: { text: 'Cancel', btnClass: 'btn-light' }
                    }
                });
            }
        }
    });

    $(function () {
        if (!document.getElementById('svc_scope_root')) return;
        try { app.mount('#svc_scope_root'); }
        catch (e) {
            console.error('[svc-scope-vue] mount threw:', e);
            $('#svc_scope_root').removeAttr('v-cloak').css('display','block');
            $('#svc_scope_root').prepend('<div class="alert alert-danger small m-3">Scope UI failed to mount: ' + (e && e.message || e) + ' — see console.</div>');
        }
    });
})();
</script>
<?php endif; ?>

<?php $this->end(); ?>
