{{-- Stakeholder Report — 4-page deck shell. Reused by both StrategyPro (strategy scope) and PgmPro (program scope). Data passed in via @include vars; this partial owns: - persistent header (subject, period, updated, status verdict) - global controls (period picker, print) - deck navigation (4 tabs + swipe + arrow keys + arrow buttons) - the 4 page containers (Overview / Logic Model / Resources & Coverage / Programs) - scoped CSS with `minmax(0,1fr)` discipline (§2 layout constraint) - print stylesheet expanding the deck (§7) Vars in: $scope 'strategy' | 'program' $subject string — displayed in the header $period ReportPeriod $updatedAt string $verdict 'ontrack' | 'atrisk' | 'off' | 'unknown' $verdictLabel string — the visible verdict $verdictSource string — provenance line (never hidden, per §3) $report ReportEngine::buildReport() output $stats $report['stats'] $deltas $report['deltas'] $needsAttn $report['needsAttention'] $logicModel null | {canvasId, narrative, stageProgress, healthBadges, coverageMatrix} $goalsGroup {goals, byProject, counts} — strategy: strategyGoals; program: programGoals $programRows array — strategy only, empty at program scope $programUpdates array — strategy only, empty at program scope --}} @php use Leantime\Domain\Reports\Models\ReportPeriod; $verdictDotColor = match ($verdict) { 'ontrack' => '#3E937A', 'inprogress' => '#3F72B0', 'atrisk' => '#C09035', 'off' => '#C2295B', default => '#9CA3AF', }; $completedCount = (int) ($stats['completed'] ?? 0); $overdueCount = (int) ($stats['overdue'] ?? 0); $goalsOnTrack = (int) ($stats['goalsOnTrack'] ?? 0); $goalsTotal = (int) ($stats['goalsTotal'] ?? 0); $hoursLogged = (float) ($stats['hoursLogged'] ?? 0); $completedDelta = (int) ($deltas['completedDelta'] ?? 0); $hasLM = $logicModel !== null; // Semantic period label — the "why this period" chip in the header sub-line. // Board audiences care WHY the report is showing this range (because it's // last closed) more than the raw dates, which appear separately in the picker. $periodMeaning = match ($period->preset) { ReportPeriod::PRESET_LAST_QUARTER => __('stakeholder.period.last_closed'), ReportPeriod::PRESET_THIS_QUARTER => __('stakeholder.period.in_progress'), ReportPeriod::PRESET_NEXT_QUARTER => __('stakeholder.period.upcoming'), ReportPeriod::PRESET_CUSTOM => __('stakeholder.period.custom'), default => '', }; // Preset name for the picker button — matches what the user selects in the // dropdown ("Last quarter" / "This quarter" / "Next quarter"). Deliberately // NOT "Q2 2026" — Leantime doesn't let companies define fiscal quarters, so // a calendar Q# label would be a lie for anyone whose fiscal year isn't // calendar-aligned. The literal date range is shown next to it. $presetName = match ($period->preset) { ReportPeriod::PRESET_LAST_QUARTER => __('label.period_last_quarter'), ReportPeriod::PRESET_THIS_QUARTER => __('label.period_this_quarter'), ReportPeriod::PRESET_NEXT_QUARTER => __('label.period_next_quarter'), ReportPeriod::PRESET_CUSTOM => __('label.period_custom'), default => __('label.period_this_quarter'), }; // Reload URL bases for the period picker preset links. $reportUrl = BASE_URL.'/'.($scope === 'strategy' ? 'strategyPro' : 'pgmPro').'/report'; @endphp @php // Prefer a $rdDark boolean passed by the caller/composer; fall back to the // Theme service only when it isn't supplied, so the view isn't required to // do a container lookup. $rdDark = $rdDark ?? (app()->make(\Leantime\Core\UI\Theme::class)->getColorMode() === 'dark'); @endphp