@eric-emg/symphiq-components 1.2.411 → 1.2.414

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -540,9 +540,30 @@ class ModalService {
540
540
  };
541
541
  this.modalState.next(newState);
542
542
  }
543
- openStrategyRecommendationsModal(strategy, objectiveTitle, goalTitle, viewMode, expandedRecommendationId) {
543
+ openStrategyRecommendationsModal(strategy, objectiveTitle, goalTitle, viewMode, expandedRecommendationId, goal, objective) {
544
544
  const data = { strategy, objectiveTitle, goalTitle, viewMode, expandedRecommendationId };
545
- this.modalState.next({ type: 'strategy-recommendations', data, charts: [], previousState: null, navigationStack: [] });
545
+ const navigationStack = [];
546
+ if (goal) {
547
+ const goalObjectivesData = { goal, viewMode };
548
+ navigationStack.push({
549
+ type: 'goal-objectives',
550
+ data: goalObjectivesData,
551
+ charts: [],
552
+ previousState: null,
553
+ navigationStack: []
554
+ });
555
+ }
556
+ if (objective && goalTitle) {
557
+ const objectiveStrategiesData = { objective, goalTitle, viewMode };
558
+ navigationStack.push({
559
+ type: 'objective-strategies',
560
+ data: objectiveStrategiesData,
561
+ charts: [],
562
+ previousState: null,
563
+ navigationStack: []
564
+ });
565
+ }
566
+ this.modalState.next({ type: 'strategy-recommendations', data, charts: [], previousState: null, navigationStack });
546
567
  }
547
568
  openCategoryDetailModal(category, viewMode, scrollToSection) {
548
569
  const data = { category, viewMode, scrollToSection };
@@ -14423,19 +14444,18 @@ class RecommendationCardComponent {
14423
14444
  this.strategyTitle = input(undefined, ...(ngDevMode ? [{ debugName: "strategyTitle" }] : []));
14424
14445
  this.cardNavigate = output();
14425
14446
  this._isExpanded = signal(false, ...(ngDevMode ? [{ debugName: "_isExpanded" }] : []));
14426
- this._forceExpanded = signal(false, ...(ngDevMode ? [{ debugName: "_forceExpanded" }] : []));
14427
14447
  this._hasAnimated = signal(false, ...(ngDevMode ? [{ debugName: "_hasAnimated" }] : []));
14428
14448
  this.profileContextService = inject(ProfileContextService);
14429
14449
  this.navigationService = inject(NavigationStateService);
14430
14450
  this.modalService = inject(ModalService);
14431
14451
  this.viewModeService = inject(ViewModeService);
14432
- this.isExpanded = computed(() => this._forceExpanded() || this._isExpanded() || this.viewModeService.isExpanded(), ...(ngDevMode ? [{ debugName: "isExpanded" }] : []));
14452
+ this.isExpanded = computed(() => this.forceExpanded() || this._isExpanded() || this.viewModeService.isExpanded(), ...(ngDevMode ? [{ debugName: "isExpanded" }] : []));
14433
14453
  this.isDark = computed(() => this.viewMode() === ViewModeEnum.DARK, ...(ngDevMode ? [{ debugName: "isDark" }] : []));
14434
14454
  this.isActuallyExpanded = computed(() => this.isExpanded(), ...(ngDevMode ? [{ debugName: "isActuallyExpanded" }] : []));
14435
- this.forceExpandedValue = computed(() => this._forceExpanded(), ...(ngDevMode ? [{ debugName: "forceExpandedValue" }] : []));
14455
+ this.forceExpandedValue = computed(() => this.forceExpanded(), ...(ngDevMode ? [{ debugName: "forceExpandedValue" }] : []));
14436
14456
  this.shouldAnimateExpand = computed(() => this.isActuallyExpanded() && this._hasAnimated(), ...(ngDevMode ? [{ debugName: "shouldAnimateExpand" }] : []));
14437
14457
  this.iconSize = computed(() => this.isActuallyExpanded() ? 'w-6 h-6' : 'w-5 h-5', ...(ngDevMode ? [{ debugName: "iconSize" }] : []));
14438
- this.shouldBeClickable = computed(() => !this._forceExpanded() || !this.inModalContext, ...(ngDevMode ? [{ debugName: "shouldBeClickable" }] : []));
14458
+ this.shouldBeClickable = computed(() => !this.forceExpanded() || !this.inModalContext, ...(ngDevMode ? [{ debugName: "shouldBeClickable" }] : []));
14439
14459
  this.displayItem = computed(() => {
14440
14460
  let displayItem;
14441
14461
  if (this.recommendation()) {
@@ -14750,7 +14770,7 @@ class RecommendationCardComponent {
14750
14770
  this.toggleExpanded();
14751
14771
  }
14752
14772
  toggleExpanded() {
14753
- if (!this._forceExpanded() && !this.viewModeService.isExpanded()) {
14773
+ if (!this.forceExpanded() && !this.viewModeService.isExpanded()) {
14754
14774
  const wasExpanded = this._isExpanded();
14755
14775
  this._isExpanded.update(v => !v);
14756
14776
  if (!wasExpanded && !this._hasAnimated()) {
@@ -67651,9 +67671,9 @@ class SymphiqBusinessAnalysisDashboardComponent {
67651
67671
  }, 500);
67652
67672
  }
67653
67673
  openRecommendationDetailsModal(recommendation) {
67654
- // Create an adapter to match ProfileItemInterface structure
67655
67674
  const itemAdapter = {
67656
67675
  ...recommendation,
67676
+ type: 'RECOMMENDATION',
67657
67677
  label: recommendation.title,
67658
67678
  value: recommendation.description
67659
67679
  };
@@ -68068,259 +68088,259 @@ class SymphiqBusinessAnalysisDashboardComponent {
68068
68088
  }
68069
68089
  (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(SymphiqBusinessAnalysisDashboardComponent, [{
68070
68090
  type: Component,
68071
- args: [{ selector: 'symphiq-business-analysis-dashboard', standalone: true, imports: [CommonModule, ProfileSectionComponent, SectionNavigationComponent, FloatingTocComponent, FloatingBackButtonComponent, TooltipContainerComponent, SectionDividerComponent, BusinessAnalysisModalComponent, SearchButtonComponent, SearchModalComponent, ViewModeSwitcherModalComponent, JourneyProgressIndicatorComponent, WelcomeBannerComponent, RecommendationsTiledGridComponent, CollapsibleSectionGroupComponent, ContentGenerationProgressWithConfettiComponent, IndeterminateSpinnerComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `
68072
- <div [ngClass]="getContainerClasses()">
68073
- <!-- Scroll Progress Bar (fixed at top) -->
68074
- <div [class]="embedded() ? 'sticky top-0 left-0 right-0 h-1 z-[60] bg-slate-200/30' : 'fixed top-0 left-0 right-0 h-1 z-[60] bg-slate-200/30'">
68075
- <div
68076
- [style.width.%]="scrollProgress()"
68077
- [ngClass]="isLightMode() ? 'bg-gradient-to-r from-blue-500 to-purple-500' : 'bg-gradient-to-r from-blue-400 to-purple-400'"
68078
- class="h-full transition-all duration-200 ease-out">
68079
- </div>
68080
- </div>
68081
-
68082
- <div class="animated-bubbles" [class.light-mode]="isLightMode()" style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; width: 100vw; height: 100vh; z-index: 1; pointer-events: none;"></div>
68083
-
68084
- <div class="relative z-[51]">
68085
- <header [ngClass]="getHeaderClasses()" class="sticky top-0 z-50">
68086
- <!-- Expanded Header (default state) -->
68087
- <div
68088
- class="transition-all duration-300 ease-in-out overflow-hidden"
68089
- [class.max-h-0]="headerScrollService.isScrolled()"
68090
- [class.opacity-0]="headerScrollService.isScrolled()"
68091
- [class.max-h-96]="!headerScrollService.isScrolled()"
68092
- [class.opacity-100]="!headerScrollService.isScrolled()">
68093
- <div
68094
- class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8"
68095
- [class.pointer-events-none]="headerScrollService.isScrolled()"
68096
- [class.pointer-events-auto]="!headerScrollService.isScrolled()">
68097
- <div class="flex items-center justify-between">
68098
- <div>
68099
- <h1 [ngClass]="getMainTitleClasses()">
68100
- {{ currentProfile()?.profileStructured?.businessName || 'Business Analysis' }}
68101
- </h1>
68102
- <p [ngClass]="getSubtitleClasses()">
68103
- Business Profile & Analysis
68104
- </p>
68105
- </div>
68106
- @if (profile()?.selfContentStatus === AiDynamicContentStatusEnum.GENERATED) {
68107
- <div class="flex items-center gap-2">
68108
- <symphiq-search-button
68109
- [isLightMode]="isLightMode()"
68110
- (searchClick)="openSearch()"
68111
- />
68112
- <button
68113
- type="button"
68114
- (click)="openViewModeSwitcher()"
68115
- [ngClass]="getViewModeButtonClasses()"
68116
- class="cursor-pointer flex items-center gap-2 px-3 py-1.5 rounded-lg text-xs font-medium transition-all duration-200 hover:scale-105">
68117
- <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
68118
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
68119
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
68120
- </svg>
68121
- <span>{{ displayModeLabel() }}</span>
68122
- </button>
68123
- </div>
68124
- }
68125
- </div>
68126
- </div>
68127
- </div>
68128
-
68129
- <!-- Condensed Header (scrolled state) -->
68130
- <div
68131
- class="transition-all duration-300 ease-in-out overflow-hidden"
68132
- [class.max-h-0]="!headerScrollService.isScrolled()"
68133
- [class.opacity-0]="!headerScrollService.isScrolled()"
68134
- [class.max-h-20]="headerScrollService.isScrolled()"
68135
- [class.opacity-100]="headerScrollService.isScrolled()">
68136
- <div
68137
- class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-3"
68138
- [class.pointer-events-none]="!headerScrollService.isScrolled()"
68139
- [class.pointer-events-auto]="headerScrollService.isScrolled()">
68140
- <div class="flex items-center justify-between">
68141
- <div class="flex-1 min-w-0 mr-4">
68142
- <h1 [ngClass]="isLightMode() ? 'text-xl font-bold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent truncate' : 'text-xl font-bold bg-gradient-to-r from-blue-400 to-purple-400 bg-clip-text text-transparent truncate'">
68143
- {{ currentProfile()?.profileStructured?.businessName || 'Business Analysis' }}
68144
- </h1>
68145
- </div>
68146
- <div class="flex items-center gap-4">
68147
- @if (!isSimplifiedView()) {
68148
- <div class="flex items-center gap-2 text-sm flex-shrink-0">
68149
- <span [ngClass]="isLightMode() ? 'text-slate-600 font-medium' : 'text-slate-400 font-medium'" class="transition-opacity duration-300" [class.opacity-0]="sectionTitleFading()" [class.opacity-100]="!sectionTitleFading()">
68150
- {{ currentSectionTitle() }}
68151
- </span>
68152
- @if (currentSubsectionTitle()) {
68153
- <span [ngClass]="isLightMode() ? 'text-slate-400' : 'text-slate-500'" class="transition-opacity duration-300" [class.opacity-0]="subsectionTitleFading()" [class.opacity-100]="!subsectionTitleFading()">›</span>
68154
- <span [ngClass]="isLightMode() ? 'text-slate-500' : 'text-slate-500'" class="transition-opacity duration-300" [class.opacity-0]="subsectionTitleFading()" [class.opacity-100]="!subsectionTitleFading()">
68155
- {{ currentSubsectionTitle() }}
68156
- </span>
68157
- }
68158
- </div>
68159
- }
68160
- @if (profile()?.selfContentStatus === AiDynamicContentStatusEnum.GENERATED) {
68161
- <symphiq-search-button
68162
- [isLightMode]="isLightMode()"
68163
- [minimized]="true"
68164
- (searchClick)="openSearch()"
68165
- />
68166
- <button
68167
- type="button"
68168
- (click)="openViewModeSwitcher()"
68169
- [ngClass]="getViewModeButtonClasses()"
68170
- class="cursor-pointer flex items-center gap-2 px-2 py-1.5 rounded-lg text-xs font-medium transition-all duration-200 hover:scale-105">
68171
- <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
68172
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
68173
- <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
68174
- </svg>
68175
- </button>
68176
- }
68177
- </div>
68178
- </div>
68179
- </div>
68180
- </div>
68181
- </header>
68182
-
68183
- <main class="relative">
68184
- @if (isLoading()) {
68185
- <!-- Pure Loading State -->
68186
- <div class="flex items-center justify-center min-h-[60vh]">
68187
- <symphiq-indeterminate-spinner
68188
- [viewMode]="viewMode()"
68189
- size="large"
68190
- />
68191
- </div>
68192
- } @else if (isContentGenerating()) {
68193
- <!-- Journey Progress Banner (always show when not onboarded) -->
68194
- @if (!isOnboarded()) {
68195
- <symphiq-journey-progress-indicator
68196
- [viewMode]="viewMode()"
68197
- [currentStepId]="JourneyStepIdEnum.BUSINESS_ANALYSIS"
68198
- [showNextStepAction]="false"
68199
- [forDemo]="forDemo()"
68200
- [maxAccessibleStepId]="maxAccessibleStepId()"
68201
- (stepClick)="stepClick.emit($event)"
68202
- (nextStepClick)="nextStepClick.emit()"
68203
- />
68204
- }
68205
-
68206
- <!-- Content Generation Progress Component -->
68207
- <symphiq-content-generation-progress-with-confetti
68208
- [viewMode]="viewMode()"
68209
- [itemStatus]="itemStatus()"
68210
- [currentStatus]="profile()?.selfContentStatus"
68211
- [confettiIntensity]="'celebration'"
68212
- [title]="'We are generating a new Business Analysis for ' + (currentProfile()?.profileStructured?.businessName || 'your business') + '.'"
68213
- [subtitle]="'It will appear here when ready. You can check back later as this will take a few minutes to complete.'"
68214
- />
68215
- } @else {
68216
- @if (isSimplifiedView()) {
68217
- <!-- Journey Progress Banner - Full Width Sticky (only show when not onboarded) -->
68218
- @if (!isOnboarded()) {
68219
- <symphiq-journey-progress-indicator
68220
- [viewMode]="viewMode()"
68221
- [currentStepId]="JourneyStepIdEnum.BUSINESS_ANALYSIS"
68222
- [showNextStepAction]="showNextStepAction()"
68223
- [forDemo]="forDemo()"
68224
- [maxAccessibleStepId]="maxAccessibleStepId()"
68225
- (stepClick)="stepClick.emit($event)"
68226
- (nextStepClick)="nextStepClick.emit()"
68227
- />
68228
- }
68229
-
68230
- <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
68231
- <div class="mb-8">
68232
- <symphiq-welcome-banner
68233
- [viewMode]="viewMode()"
68234
- [businessName]="currentProfile()?.profileStructured?.businessName || 'your business'"
68235
- [isOnboarded]="isOnboarded()"
68236
- />
68237
- </div>
68238
-
68239
- <div class="mb-8">
68240
- <symphiq-recommendations-tiled-grid
68241
- [recommendations]="recommendationItems()"
68242
- [viewMode]="viewMode()"
68243
- (viewMoreClick)="openRecommendationDetailsModal($event)"
68244
- />
68245
- </div>
68246
-
68247
- <div>
68248
- <symphiq-collapsible-section-group
68249
- [sections]="nonRecommendationSections()"
68250
- [viewMode]="viewMode()"
68251
- />
68252
- </div>
68253
- </div>
68254
- } @else {
68255
- @for (section of sections(); track trackBySectionId($index, section); let idx = $index; let last = $last) {
68256
- <symphiq-profile-section
68257
- [section]="section"
68258
- [viewMode]="viewMode()"
68259
- [forceExpanded]="!isCompactView()"
68260
- />
68261
- @if (!last) {
68262
- <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
68263
- <symphiq-section-divider
68264
- [viewMode]="viewMode()"
68265
- [subsections]="sections()[idx + 1].subsections || []" />
68266
- </div>
68267
- }
68268
- }
68269
- }
68270
- }
68271
- </main>
68272
-
68273
- @if (!isSimplifiedView()) {
68274
- <symphiq-section-navigation
68275
- [sections]="sections()"
68276
- [viewMode]="viewMode()"
68277
- [embedded]="embedded()"
68278
- [scrollElement]="scrollElement() ?? undefined"
68279
- />
68280
- }
68281
-
68282
- @if (!isSimplifiedView()) {
68283
- <symphiq-floating-toc
68284
- [sections]="sections()"
68285
- [viewMode]="viewMode()"
68286
- [embedded]="embedded()"
68287
- [scrollElement]="scrollElement() ?? undefined"
68288
- />
68289
- }
68290
-
68291
- <symphiq-floating-back-button
68292
- [viewMode]="viewMode()"
68293
- [embedded]="embedded()"
68294
- />
68295
- </div>
68296
-
68297
- <symphiq-tooltip-container />
68298
- <symphiq-business-analysis-modal
68299
- [isLightMode]="isLightMode()"
68300
- (viewInContextRequested)="handleViewInContext($event)" />
68301
-
68302
- <symphiq-search-modal
68303
- [isLightMode]="isLightMode()"
68304
- [isOpen]="searchService.isSearchOpen()"
68305
- [searchQuery]="searchService.getSearchQuery()"
68306
- [results]="searchService.searchResults()"
68307
- [hasResults]="searchService.hasResults()"
68308
- [selectedIndex]="selectedSearchIndex()"
68309
- [placeholder]="'Search sections, items, and analysis...'"
68310
- (searchChange)="onSearchChange($event)"
68311
- (resultSelected)="onSearchResultSelected($event)"
68312
- (close)="closeSearch()"
68313
- />
68314
-
68315
- <symphiq-view-mode-switcher-modal
68316
- [isOpen]="isViewModeSwitcherOpen()"
68317
- [currentMode]="displayMode()"
68318
- [viewMode]="viewMode()"
68319
- [isLoading]="isViewModeSwitching()"
68320
- (close)="closeViewModeSwitcher()"
68321
- (modeSelected)="handleDisplayModeChange($event)"
68322
- />
68323
- </div>
68091
+ args: [{ selector: 'symphiq-business-analysis-dashboard', standalone: true, imports: [CommonModule, ProfileSectionComponent, SectionNavigationComponent, FloatingTocComponent, FloatingBackButtonComponent, TooltipContainerComponent, SectionDividerComponent, BusinessAnalysisModalComponent, SearchButtonComponent, SearchModalComponent, ViewModeSwitcherModalComponent, JourneyProgressIndicatorComponent, WelcomeBannerComponent, RecommendationsTiledGridComponent, CollapsibleSectionGroupComponent, ContentGenerationProgressWithConfettiComponent, IndeterminateSpinnerComponent], changeDetection: ChangeDetectionStrategy.OnPush, template: `
68092
+ <div [ngClass]="getContainerClasses()">
68093
+ <!-- Scroll Progress Bar (fixed at top) -->
68094
+ <div [class]="embedded() ? 'sticky top-0 left-0 right-0 h-1 z-[60] bg-slate-200/30' : 'fixed top-0 left-0 right-0 h-1 z-[60] bg-slate-200/30'">
68095
+ <div
68096
+ [style.width.%]="scrollProgress()"
68097
+ [ngClass]="isLightMode() ? 'bg-gradient-to-r from-blue-500 to-purple-500' : 'bg-gradient-to-r from-blue-400 to-purple-400'"
68098
+ class="h-full transition-all duration-200 ease-out">
68099
+ </div>
68100
+ </div>
68101
+
68102
+ <div class="animated-bubbles" [class.light-mode]="isLightMode()" style="position: fixed; top: 0; left: 0; right: 0; bottom: 0; width: 100vw; height: 100vh; z-index: 1; pointer-events: none;"></div>
68103
+
68104
+ <div class="relative z-[51]">
68105
+ <header [ngClass]="getHeaderClasses()" class="sticky top-0 z-50">
68106
+ <!-- Expanded Header (default state) -->
68107
+ <div
68108
+ class="transition-all duration-300 ease-in-out overflow-hidden"
68109
+ [class.max-h-0]="headerScrollService.isScrolled()"
68110
+ [class.opacity-0]="headerScrollService.isScrolled()"
68111
+ [class.max-h-96]="!headerScrollService.isScrolled()"
68112
+ [class.opacity-100]="!headerScrollService.isScrolled()">
68113
+ <div
68114
+ class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8"
68115
+ [class.pointer-events-none]="headerScrollService.isScrolled()"
68116
+ [class.pointer-events-auto]="!headerScrollService.isScrolled()">
68117
+ <div class="flex items-center justify-between">
68118
+ <div>
68119
+ <h1 [ngClass]="getMainTitleClasses()">
68120
+ {{ currentProfile()?.profileStructured?.businessName || 'Business Analysis' }}
68121
+ </h1>
68122
+ <p [ngClass]="getSubtitleClasses()">
68123
+ Business Profile & Analysis
68124
+ </p>
68125
+ </div>
68126
+ @if (profile()?.selfContentStatus === AiDynamicContentStatusEnum.GENERATED) {
68127
+ <div class="flex items-center gap-2">
68128
+ <symphiq-search-button
68129
+ [isLightMode]="isLightMode()"
68130
+ (searchClick)="openSearch()"
68131
+ />
68132
+ <button
68133
+ type="button"
68134
+ (click)="openViewModeSwitcher()"
68135
+ [ngClass]="getViewModeButtonClasses()"
68136
+ class="cursor-pointer flex items-center gap-2 px-3 py-1.5 rounded-lg text-xs font-medium transition-all duration-200 hover:scale-105">
68137
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
68138
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
68139
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
68140
+ </svg>
68141
+ <span>{{ displayModeLabel() }}</span>
68142
+ </button>
68143
+ </div>
68144
+ }
68145
+ </div>
68146
+ </div>
68147
+ </div>
68148
+
68149
+ <!-- Condensed Header (scrolled state) -->
68150
+ <div
68151
+ class="transition-all duration-300 ease-in-out overflow-hidden"
68152
+ [class.max-h-0]="!headerScrollService.isScrolled()"
68153
+ [class.opacity-0]="!headerScrollService.isScrolled()"
68154
+ [class.max-h-20]="headerScrollService.isScrolled()"
68155
+ [class.opacity-100]="headerScrollService.isScrolled()">
68156
+ <div
68157
+ class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-3"
68158
+ [class.pointer-events-none]="!headerScrollService.isScrolled()"
68159
+ [class.pointer-events-auto]="headerScrollService.isScrolled()">
68160
+ <div class="flex items-center justify-between">
68161
+ <div class="flex-1 min-w-0 mr-4">
68162
+ <h1 [ngClass]="isLightMode() ? 'text-xl font-bold bg-gradient-to-r from-blue-600 to-purple-600 bg-clip-text text-transparent truncate' : 'text-xl font-bold bg-gradient-to-r from-blue-400 to-purple-400 bg-clip-text text-transparent truncate'">
68163
+ {{ currentProfile()?.profileStructured?.businessName || 'Business Analysis' }}
68164
+ </h1>
68165
+ </div>
68166
+ <div class="flex items-center gap-4">
68167
+ @if (!isSimplifiedView()) {
68168
+ <div class="flex items-center gap-2 text-sm flex-shrink-0">
68169
+ <span [ngClass]="isLightMode() ? 'text-slate-600 font-medium' : 'text-slate-400 font-medium'" class="transition-opacity duration-300" [class.opacity-0]="sectionTitleFading()" [class.opacity-100]="!sectionTitleFading()">
68170
+ {{ currentSectionTitle() }}
68171
+ </span>
68172
+ @if (currentSubsectionTitle()) {
68173
+ <span [ngClass]="isLightMode() ? 'text-slate-400' : 'text-slate-500'" class="transition-opacity duration-300" [class.opacity-0]="subsectionTitleFading()" [class.opacity-100]="!subsectionTitleFading()">›</span>
68174
+ <span [ngClass]="isLightMode() ? 'text-slate-500' : 'text-slate-500'" class="transition-opacity duration-300" [class.opacity-0]="subsectionTitleFading()" [class.opacity-100]="!subsectionTitleFading()">
68175
+ {{ currentSubsectionTitle() }}
68176
+ </span>
68177
+ }
68178
+ </div>
68179
+ }
68180
+ @if (profile()?.selfContentStatus === AiDynamicContentStatusEnum.GENERATED) {
68181
+ <symphiq-search-button
68182
+ [isLightMode]="isLightMode()"
68183
+ [minimized]="true"
68184
+ (searchClick)="openSearch()"
68185
+ />
68186
+ <button
68187
+ type="button"
68188
+ (click)="openViewModeSwitcher()"
68189
+ [ngClass]="getViewModeButtonClasses()"
68190
+ class="cursor-pointer flex items-center gap-2 px-2 py-1.5 rounded-lg text-xs font-medium transition-all duration-200 hover:scale-105">
68191
+ <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">
68192
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z"></path>
68193
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M2.458 12C3.732 7.943 7.523 5 12 5c4.478 0 8.268 2.943 9.542 7-1.274 4.057-5.064 7-9.542 7-4.477 0-8.268-2.943-9.542-7z"></path>
68194
+ </svg>
68195
+ </button>
68196
+ }
68197
+ </div>
68198
+ </div>
68199
+ </div>
68200
+ </div>
68201
+ </header>
68202
+
68203
+ <main class="relative">
68204
+ @if (isLoading()) {
68205
+ <!-- Pure Loading State -->
68206
+ <div class="flex items-center justify-center min-h-[60vh]">
68207
+ <symphiq-indeterminate-spinner
68208
+ [viewMode]="viewMode()"
68209
+ size="large"
68210
+ />
68211
+ </div>
68212
+ } @else if (isContentGenerating()) {
68213
+ <!-- Journey Progress Banner (always show when not onboarded) -->
68214
+ @if (!isOnboarded()) {
68215
+ <symphiq-journey-progress-indicator
68216
+ [viewMode]="viewMode()"
68217
+ [currentStepId]="JourneyStepIdEnum.BUSINESS_ANALYSIS"
68218
+ [showNextStepAction]="false"
68219
+ [forDemo]="forDemo()"
68220
+ [maxAccessibleStepId]="maxAccessibleStepId()"
68221
+ (stepClick)="stepClick.emit($event)"
68222
+ (nextStepClick)="nextStepClick.emit()"
68223
+ />
68224
+ }
68225
+
68226
+ <!-- Content Generation Progress Component -->
68227
+ <symphiq-content-generation-progress-with-confetti
68228
+ [viewMode]="viewMode()"
68229
+ [itemStatus]="itemStatus()"
68230
+ [currentStatus]="profile()?.selfContentStatus"
68231
+ [confettiIntensity]="'celebration'"
68232
+ [title]="'We are generating a new Business Analysis for ' + (currentProfile()?.profileStructured?.businessName || 'your business') + '.'"
68233
+ [subtitle]="'It will appear here when ready. You can check back later as this will take a few minutes to complete.'"
68234
+ />
68235
+ } @else {
68236
+ @if (isSimplifiedView()) {
68237
+ <!-- Journey Progress Banner - Full Width Sticky (only show when not onboarded) -->
68238
+ @if (!isOnboarded()) {
68239
+ <symphiq-journey-progress-indicator
68240
+ [viewMode]="viewMode()"
68241
+ [currentStepId]="JourneyStepIdEnum.BUSINESS_ANALYSIS"
68242
+ [showNextStepAction]="showNextStepAction()"
68243
+ [forDemo]="forDemo()"
68244
+ [maxAccessibleStepId]="maxAccessibleStepId()"
68245
+ (stepClick)="stepClick.emit($event)"
68246
+ (nextStepClick)="nextStepClick.emit()"
68247
+ />
68248
+ }
68249
+
68250
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
68251
+ <div class="mb-8">
68252
+ <symphiq-welcome-banner
68253
+ [viewMode]="viewMode()"
68254
+ [businessName]="currentProfile()?.profileStructured?.businessName || 'your business'"
68255
+ [isOnboarded]="isOnboarded()"
68256
+ />
68257
+ </div>
68258
+
68259
+ <div class="mb-8">
68260
+ <symphiq-recommendations-tiled-grid
68261
+ [recommendations]="recommendationItems()"
68262
+ [viewMode]="viewMode()"
68263
+ (viewMoreClick)="openRecommendationDetailsModal($event)"
68264
+ />
68265
+ </div>
68266
+
68267
+ <div>
68268
+ <symphiq-collapsible-section-group
68269
+ [sections]="nonRecommendationSections()"
68270
+ [viewMode]="viewMode()"
68271
+ />
68272
+ </div>
68273
+ </div>
68274
+ } @else {
68275
+ @for (section of sections(); track trackBySectionId($index, section); let idx = $index; let last = $last) {
68276
+ <symphiq-profile-section
68277
+ [section]="section"
68278
+ [viewMode]="viewMode()"
68279
+ [forceExpanded]="!isCompactView()"
68280
+ />
68281
+ @if (!last) {
68282
+ <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
68283
+ <symphiq-section-divider
68284
+ [viewMode]="viewMode()"
68285
+ [subsections]="sections()[idx + 1].subsections || []" />
68286
+ </div>
68287
+ }
68288
+ }
68289
+ }
68290
+ }
68291
+ </main>
68292
+
68293
+ @if (!isSimplifiedView()) {
68294
+ <symphiq-section-navigation
68295
+ [sections]="sections()"
68296
+ [viewMode]="viewMode()"
68297
+ [embedded]="embedded()"
68298
+ [scrollElement]="scrollElement() ?? undefined"
68299
+ />
68300
+ }
68301
+
68302
+ @if (!isSimplifiedView()) {
68303
+ <symphiq-floating-toc
68304
+ [sections]="sections()"
68305
+ [viewMode]="viewMode()"
68306
+ [embedded]="embedded()"
68307
+ [scrollElement]="scrollElement() ?? undefined"
68308
+ />
68309
+ }
68310
+
68311
+ <symphiq-floating-back-button
68312
+ [viewMode]="viewMode()"
68313
+ [embedded]="embedded()"
68314
+ />
68315
+ </div>
68316
+
68317
+ <symphiq-tooltip-container />
68318
+ <symphiq-business-analysis-modal
68319
+ [isLightMode]="isLightMode()"
68320
+ (viewInContextRequested)="handleViewInContext($event)" />
68321
+
68322
+ <symphiq-search-modal
68323
+ [isLightMode]="isLightMode()"
68324
+ [isOpen]="searchService.isSearchOpen()"
68325
+ [searchQuery]="searchService.getSearchQuery()"
68326
+ [results]="searchService.searchResults()"
68327
+ [hasResults]="searchService.hasResults()"
68328
+ [selectedIndex]="selectedSearchIndex()"
68329
+ [placeholder]="'Search sections, items, and analysis...'"
68330
+ (searchChange)="onSearchChange($event)"
68331
+ (resultSelected)="onSearchResultSelected($event)"
68332
+ (close)="closeSearch()"
68333
+ />
68334
+
68335
+ <symphiq-view-mode-switcher-modal
68336
+ [isOpen]="isViewModeSwitcherOpen()"
68337
+ [currentMode]="displayMode()"
68338
+ [viewMode]="viewMode()"
68339
+ [isLoading]="isViewModeSwitching()"
68340
+ (close)="closeViewModeSwitcher()"
68341
+ (modeSelected)="handleDisplayModeChange($event)"
68342
+ />
68343
+ </div>
68324
68344
  `, styles: [":host{display:block}@keyframes spin{to{transform:rotate(360deg)}}@keyframes pulse-highlight{0%,to{transform:scale(1);box-shadow:0 0 #3b82f6b3}50%{transform:scale(1.02);box-shadow:0 0 20px 8px #3b82f64d}}:host ::ng-deep .search-highlight-pulse{animation:pulse-highlight 2s ease-in-out;border-color:#3b82f6!important}\n"] }]
68325
68345
  }], () => [], { embedded: [{ type: i0.Input, args: [{ isSignal: true, alias: "embedded", required: false }] }], profile: [{ type: i0.Input, args: [{ isSignal: true, alias: "profile", required: false }] }], parentHeaderOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "parentHeaderOffset", required: false }] }], requestedByUser: [{ type: i0.Input, args: [{ isSignal: true, alias: "requestedByUser", required: false }] }], viewMode: [{ type: i0.Input, args: [{ isSignal: true, alias: "viewMode", required: false }] }], scrollEvent: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollEvent", required: false }] }], scrollElement: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollElement", required: false }] }], isLoading: [{ type: i0.Input, args: [{ isSignal: true, alias: "isLoading", required: false }] }], isOnboarded: [{ type: i0.Input, args: [{ isSignal: true, alias: "isOnboarded", required: false }] }], forDemo: [{ type: i0.Input, args: [{ isSignal: true, alias: "forDemo", required: false }] }], maxAccessibleStepId: [{ type: i0.Input, args: [{ isSignal: true, alias: "maxAccessibleStepId", required: false }] }], itemStatus: [{ type: i0.Input, args: [{ isSignal: true, alias: "itemStatus", required: false }] }], stepClick: [{ type: i0.Output, args: ["stepClick"] }], nextStepClick: [{ type: i0.Output, args: ["nextStepClick"] }], onScroll: [{
68326
68346
  type: HostListener,
@@ -73796,7 +73816,7 @@ class PhaseTimelineCardComponent {
73796
73816
  }
73797
73817
  const hierarchy = this.findRecommendationHierarchy(recommendation.id);
73798
73818
  if (hierarchy) {
73799
- this.modalService.openStrategyRecommendationsModal(hierarchy.strategy, hierarchy.objective?.title, hierarchy.goal?.title, this.viewMode(), recommendation.id);
73819
+ this.modalService.openStrategyRecommendationsModal(hierarchy.strategy, hierarchy.objective?.title, hierarchy.goal?.title, this.viewMode(), recommendation.id, hierarchy.goal, hierarchy.objective);
73800
73820
  }
73801
73821
  }
73802
73822
  findRecommendationHierarchy(recommendationId) {
@@ -81804,6 +81824,7 @@ function StrategyRecommendationsModalContentComponent_For_8_Template(rf, ctx) {
81804
81824
  const ctx_r0 = i0.ɵɵnextContext();
81805
81825
  i0.ɵɵclassProp("cursor-pointer", ctx_r0.hasExpandableContent(recommendation_r4));
81806
81826
  i0.ɵɵproperty("ngClass", ctx_r0.cardClasses());
81827
+ i0.ɵɵattribute("id", "recommendation-" + (recommendation_r4.id || $index_r5));
81807
81828
  i0.ɵɵadvance(2);
81808
81829
  i0.ɵɵproperty("ngClass", ctx_r0.iconContainerClasses());
81809
81830
  i0.ɵɵadvance(5);
@@ -81874,6 +81895,12 @@ class StrategyRecommendationsModalContentComponent {
81874
81895
  const recId = this.expandedRecommendationId();
81875
81896
  if (recId) {
81876
81897
  this.expandedRecommendations.set(new Set([recId]));
81898
+ setTimeout(() => {
81899
+ const element = document.getElementById('recommendation-' + recId);
81900
+ if (element) {
81901
+ element.scrollIntoView({ behavior: 'smooth', block: 'start' });
81902
+ }
81903
+ }, 100);
81877
81904
  }
81878
81905
  }, ...(ngDevMode ? [{ debugName: "expandRecommendationEffect", allowSignalWrites: true }] : [{ allowSignalWrites: true }]));
81879
81906
  this.cardClasses = computed(() => {
@@ -82708,7 +82735,7 @@ class StrategyRecommendationsModalContentComponent {
82708
82735
  i0.ɵɵconditionalCreate(5, StrategyRecommendationsModalContentComponent_Conditional_5_Template, 2, 2, "span", 4);
82709
82736
  i0.ɵɵconditionalCreate(6, StrategyRecommendationsModalContentComponent_Conditional_6_Template, 2, 2, "span", 4);
82710
82737
  i0.ɵɵelementEnd()();
82711
- i0.ɵɵrepeaterCreate(7, StrategyRecommendationsModalContentComponent_For_8_Template, 35, 31, "div", 5, _forTrack0$b);
82738
+ i0.ɵɵrepeaterCreate(7, StrategyRecommendationsModalContentComponent_For_8_Template, 35, 32, "div", 5, _forTrack0$b);
82712
82739
  i0.ɵɵelementEnd();
82713
82740
  } if (rf & 2) {
82714
82741
  let tmp_1_0;
@@ -82775,7 +82802,7 @@ class StrategyRecommendationsModalContentComponent {
82775
82802
 
82776
82803
  <!-- Recommendations Section -->
82777
82804
  @for (recommendation of strategy()?.recommendations; track recommendation.id || $index) {
82778
- <div [ngClass]="cardClasses()" class="rounded p-5 transition-all duration-200 hover:shadow-lg" [class.cursor-pointer]="hasExpandableContent(recommendation)" (click)="hasExpandableContent(recommendation) ? toggleRecommendation($event, recommendation.id || $index) : null">
82805
+ <div [attr.id]="'recommendation-' + (recommendation.id || $index)" [ngClass]="cardClasses()" class="rounded p-5 transition-all duration-200 hover:shadow-lg" [class.cursor-pointer]="hasExpandableContent(recommendation)" (click)="hasExpandableContent(recommendation) ? toggleRecommendation($event, recommendation.id || $index) : null">
82779
82806
  <div class="flex items-start gap-3">
82780
82807
  <div [ngClass]="iconContainerClasses()">
82781
82808
  <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24">