diff --git a/.github/workflows/deploy-helm.yml b/.github/workflows/deploy-helm.yml
index cce906fa41dbc87880596854a3ee34ff6b77db32..cf98e4d1b0a11fbe42b8cbc0f7dfb3f1ba90eafb 100644
--- a/.github/workflows/deploy-helm.yml
+++ b/.github/workflows/deploy-helm.yml
@@ -9,6 +9,10 @@ on:
       IMAGE_TAG:
         required: true
         type: string
+      IMAGE_DIGEST:
+        required: false
+        type: string
+        default: 'unknown-digest'
 
     secrets:
       KUBECONFIG:
@@ -32,12 +36,14 @@ jobs:
           helm --kubeconfig=$kubecfg_path \
             upgrade \
             --set image.tag=${{ inputs.IMAGE_TAG }} \
+            --set podLabels.image-digest=${{ inputs.IMAGE_DIGEST }} \
             ${{ inputs.DEPLOYMENT_NAME }} .helm/siibra-explorer/
         else
           echo "tag ${{ inputs.DEPLOYMENT_NAME }} not found. Install"
           helm --kubeconfig=$kubecfg_path \
             install \
             --set image.tag=${{ inputs.IMAGE_TAG }} \
+            --set podLabels.image-digest=${{ inputs.IMAGE_DIGEST }} \
             ${{ inputs.DEPLOYMENT_NAME }} .helm/siibra-explorer/
         fi
 
diff --git a/.github/workflows/docker_img.yml b/.github/workflows/docker_img.yml
index 0e60c8d7bd01804eb748c5dd97baefc83632fc06..f9a9b2d212b7b0ff404addabd6f5f4794f4956b3 100644
--- a/.github/workflows/docker_img.yml
+++ b/.github/workflows/docker_img.yml
@@ -25,6 +25,9 @@ jobs:
       SIIBRA_API_RC: 'https://siibra-api-rc.apps.hbp.eu/v3_0'
       SIIBRA_API_LATEST: 'https://siibra-api-latest.apps-dev.hbp.eu/v3_0'
 
+    outputs:
+      IMAGE_DIGEST: ${{ steps.build-docker-image.outputs.IMAGE_DIGEST }}
+
     steps:
     - uses: actions/checkout@v4
       with:
@@ -59,7 +62,8 @@ jobs:
         else
           echo "dev bulid, enable experimental features"
         fi
-    - name: 'Build docker image'
+    - id: 'build-docker-image'
+      name: 'Build docker image'
       run: |
         DOCKER_BUILT_TAG=${{ env.DOCKER_REGISTRY }}siibra-explorer:$BRANCH_NAME
         echo "Building $DOCKER_BUILT_TAG"
@@ -73,6 +77,10 @@ jobs:
         echo "Successfully built $DOCKER_BUILT_TAG"
         echo "DOCKER_BUILT_TAG=$DOCKER_BUILT_TAG" >> $GITHUB_ENV
 
+        IMAGE_DIGEST=$(docker inspect --format='{{ index .RepoDigests 0 }}' $DOCKER_BUILT_TAG)
+        echo "Built image digest: $IMAGE_DIGEST"
+        echo "IMAGE_DIGEST=$IMAGE_DIGEST" >> $GITHUB_OUTPUT
+
     - name: 'Push to docker registry'
       run: |
         echo "Login to docker registry"
@@ -138,6 +146,19 @@ jobs:
     secrets:
       okd_token: ${{ secrets.OKD_PROD_SECRET }}
 
+  trigger-deploy-rc-rancher:
+    if: ${{ needs.setting-vars.outputs.BRANCH_NAME == 'rc' && success() }}
+    needs:
+      - build-docker-img
+      - setting-vars
+    uses: ./.github/workflows/deploy-helm.yml
+    with:
+      DEPLOYMENT_NAME: rc
+      IMAGE_TAG: ${{ needs.setting-vars.outputs.SXPLR_VERSION }}
+      IMAGE_DIGEST: ${{ needs.build-docker-img.outputs.IMAGE_DIGEST }}
+    secrets:
+      KUBECONFIG: ${{ secrets.KUBECONFIG }}
+
   trigger-deploy-master-rancher:
     if: ${{ needs.setting-vars.outputs.BRANCH_NAME == 'master' && success() }}
     needs:
@@ -147,6 +168,7 @@ jobs:
     with:
       DEPLOYMENT_NAME: master
       IMAGE_TAG: ${{ needs.setting-vars.outputs.SXPLR_VERSION }}
+      IMAGE_DIGEST: ${{ needs.build-docker-img.outputs.IMAGE_DIGEST }}
     secrets:
       KUBECONFIG: ${{ secrets.KUBECONFIG }}
 
diff --git a/.helm/siibra-explorer/Chart.yaml b/.helm/siibra-explorer/Chart.yaml
index 301a17e4237e3c63762161df8c7bb7eed1d8904d..6cdf72464347e040f030ff28f7c1a5b4a036f457 100644
--- a/.helm/siibra-explorer/Chart.yaml
+++ b/.helm/siibra-explorer/Chart.yaml
@@ -15,7 +15,7 @@ type: application
 # This is the chart version. This version number should be incremented each time you make changes
 # to the chart and its templates, including the app version.
 # Versions are expected to follow Semantic Versioning (https://semver.org/)
-version: 0.1.1
+version: 0.1.2
 
 # This is the version number of the application being deployed. This version number should be
 # incremented each time you make changes to the application. Versions are not expected to
diff --git a/src/atlasViewer/onhoverSegment.pipe.ts b/src/atlasViewer/onhoverSegment.pipe.ts
deleted file mode 100644
index 5199a582a1ba2e5084d7097996652a492211a342..0000000000000000000000000000000000000000
--- a/src/atlasViewer/onhoverSegment.pipe.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { Pipe, PipeTransform, SecurityContext } from "@angular/core";
-import { DomSanitizer, SafeHtml } from "@angular/platform-browser";
-
-@Pipe({
-  name: 'transformOnhoverSegment',
-})
-
-export class TransformOnhoverSegmentPipe implements PipeTransform {
-  constructor(private sanitizer: DomSanitizer) {
-
-  }
-
-  private sanitizeHtml(inc: string): SafeHtml {
-    return this.sanitizer.sanitize(SecurityContext.HTML, inc)
-  }
-
-  private getStatus(text: string) {
-    return ` <span class="text-muted">(${this.sanitizeHtml(text)})</span>`
-  }
-
-  public transform(segment: any | number): SafeHtml {
-    return this.sanitizer.bypassSecurityTrustHtml((
-      ( this.sanitizeHtml(segment.name) || segment) +
-      (segment.status
-        ? this.getStatus(segment.status)
-        : '')
-    ))
-  }
-}
diff --git a/src/features/compoundFeatureIndices/compoundFeatureIndices.template.html b/src/features/compoundFeatureIndices/compoundFeatureIndices.template.html
index 727aa06aebfeeb3f05ee0f19501ee34e29a297db..2cf12729686a4c940269ec9bb8ef80df03ebd417 100644
--- a/src/features/compoundFeatureIndices/compoundFeatureIndices.template.html
+++ b/src/features/compoundFeatureIndices/compoundFeatureIndices.template.html
@@ -23,6 +23,7 @@
     </table>
     
     <pointcloud-intents [points]="view.indices | filterForPoints"
+        (point-clicked)="handleOnClick($event)"
         [selected-template]="view.selectedTemplate">
     </pointcloud-intents>
 </ng-template>
diff --git a/src/features/compoundFeatureIndices/module.ts b/src/features/compoundFeatureIndices/module.ts
index 387b0081f501bc3d03ce6debac1f802e52e208c1..1f0174e0e7ade54b49176c86b98f9f1e822ee132 100644
--- a/src/features/compoundFeatureIndices/module.ts
+++ b/src/features/compoundFeatureIndices/module.ts
@@ -5,6 +5,8 @@ import { CompoundFeatureIndices } from "./compoundFeatureIndices.component";
 import { IndexToStrPipe } from "./idxToText.pipe";
 import { IndexToIconPipe } from "./idxToIcon.pipe";
 import { PointCloudIntents, FilterPointTransformer } from "src/features/pointcloud-intents";
+import { RENDER_CF_POINT, RenderCfPoint } from "../pointcloud-intents/intents.component";
+
 
 @NgModule({
   imports: [
@@ -20,6 +22,16 @@ import { PointCloudIntents, FilterPointTransformer } from "src/features/pointclo
   ],
   exports: [
     CompoundFeatureIndices,
+  ],
+  providers: [
+    {
+      provide: RENDER_CF_POINT,
+      useFactory: () => {
+        const pipe = new IndexToStrPipe()
+        const renderCfPoint: RenderCfPoint = cfIndex => pipe.transform(cfIndex.index)
+        return renderCfPoint
+      }
+    }
   ]
 })
 
diff --git a/src/features/pointcloud-intents/intents.component.ts b/src/features/pointcloud-intents/intents.component.ts
index 3df8d06bf00401c4a5716cdd1a1a3e26c2cbc7c4..c0c5af5bbf18d19d9c9d20676772943c4443c3eb 100644
--- a/src/features/pointcloud-intents/intents.component.ts
+++ b/src/features/pointcloud-intents/intents.component.ts
@@ -1,5 +1,5 @@
 import { CommonModule } from "@angular/common";
-import { Component, EventEmitter, Input, Output, inject } from "@angular/core";
+import { Component, EventEmitter, Inject, InjectionToken, Input, Optional, Output, inject } from "@angular/core";
 import { BehaviorSubject, Observable, combineLatest } from "rxjs";
 import { Point, SxplrTemplate } from "src/atlasComponents/sapi/sxplrTypes";
 import { PathReturn } from "src/atlasComponents/sapi/typeV3";
@@ -7,7 +7,8 @@ import { AngularMaterialModule } from "src/sharedModules";
 import { DestroyDirective } from "src/util/directives/destroy.directive";
 import { CFIndex } from "./util";
 import { AnnotationLayer } from "src/atlasComponents/annotations";
-import { map, takeUntil } from "rxjs/operators";
+import { map, takeUntil, withLatestFrom } from "rxjs/operators";
+import { CLICK_INTERCEPTOR_INJECTOR, ClickInterceptor, HOVER_INTERCEPTOR_INJECTOR, HoverInterceptor, THoverConfig } from "src/util/injectionTokens";
 
 type Intent = PathReturn<"/feature/{feature_id}/intents">['items'][number]
 
@@ -61,33 +62,104 @@ export class PointCloudIntents {
     this.#selectedTemplate$.next(tmpl)
   }
 
-  spaceMatchedPoints$ = combineLatest([
+  #spaceMatchedCfIndices$ = combineLatest([
     this.#points$,
     this.#selectedTemplate$
   ]).pipe(
-    map(([ points, selectedTemplate ]) => points.filter(p => p.index.spaceId === selectedTemplate?.id).map(v => v.index))
+    map(([ points, selectedTemplate ]) => points.filter(p => p.index.spaceId === selectedTemplate?.id))
   )
 
+  #spaceMatchedAnnIdToCfIdx$ = this.#spaceMatchedCfIndices$.pipe(
+    map(indices => {
+      const idToIndexMap = new Map<string, CFIndex<Point>>()
+      for (const idx of indices){
+        idToIndexMap.set(
+          serializeToId(idx.index).id,
+          idx
+        )
+      }
+      return idToIndexMap
+    })
+  )
 
-  @Output('on-click')
-  onClick = new EventEmitter<Point>()
+  @Output('point-clicked')
+  pointClicked = new EventEmitter<CFIndex<Point>>()
 
   annLayer: AnnotationLayer
-  constructor(){
+  constructor(
+    @Inject(RENDER_CF_POINT) render: RenderCfPoint,
+    @Optional() @Inject(CLICK_INTERCEPTOR_INJECTOR) clickInterceptor: ClickInterceptor,
+    @Optional() @Inject(HOVER_INTERCEPTOR_INJECTOR) hoverInterceptor: HoverInterceptor,
+  ){
     this.annLayer = new AnnotationLayer("intents", "#ff0000")
-    this.spaceMatchedPoints$.pipe(
+    this.#spaceMatchedCfIndices$.pipe(
       takeUntil(this.#destroy$)
-    ).subscribe(pts => {
-      const anns = pts.map(serializeToId)
+    ).subscribe(indices => {
+      const anns = indices.map(idx => serializeToId(idx.index))
       this.annLayer.addAnnotation(anns)
     },
     e => {
       console.error("error", e)
     },
     () => {
-      console.log("dismissing!")
       this.annLayer.dispose()
     })
+
+    this.annLayer.onHover.pipe(
+      takeUntil(this.#destroy$),
+      withLatestFrom(this.#spaceMatchedAnnIdToCfIdx$),
+    ).subscribe(([hover, map]) => {
+
+      if (hoverInterceptor && !!this.#hoveredMessage){
+        const { remove } = hoverInterceptor
+        remove(this.#hoveredMessage)
+        this.#hoveredMessage = null
+      }
+
+      this.#hoveredCfIndex = null
+
+      if (!hover) {
+        return
+      }
+
+      const idx = map.get(hover.id)
+      if (!idx) {
+        console.error(`Couldn't find AnnId: ${hover.id}`)
+        return
+      }
+
+      this.#hoveredCfIndex = idx
+
+      if (hoverInterceptor) {
+        const { append } = hoverInterceptor
+        const text = render(idx)
+        this.#hoveredMessage = {
+          message: `Hovering ${text}`
+        }
+        append(this.#hoveredMessage)
+      }
+    })
+
+    if (clickInterceptor) {
+      const { register, deregister } = clickInterceptor
+      const onClickHandler = this.onViewerClick.bind(this)
+      register(onClickHandler)
+      this.#destroy$.subscribe(() => deregister(onClickHandler))
+    }
   }
 
+  onViewerClick(){
+    if (this.#hoveredCfIndex) {
+      this.pointClicked.next(this.#hoveredCfIndex)
+      return false
+    }
+    return true
+  }
+
+  #hoveredCfIndex: CFIndex<Point> = null
+  #hoveredMessage: THoverConfig = null
+
 }
+
+export const RENDER_CF_POINT = new InjectionToken("RENDER_CF_POINT")
+export type RenderCfPoint = (cfIndex: CFIndex<Point>) => string
diff --git a/src/mouseoverModule/mouseover.directive.ts b/src/mouseoverModule/mouseover.directive.ts
index fad1fbf852e3cadd9983ffdab1009fd6c6cbafde..a69fccd7630c0be2a35d7ec73d2dd1f0ed7a6d53 100644
--- a/src/mouseoverModule/mouseover.directive.ts
+++ b/src/mouseoverModule/mouseover.directive.ts
@@ -6,6 +6,7 @@ import { TOnHoverObj, temporalPositveScanFn } from "./util"
 import { ModularUserAnnotationToolService } from "src/atlasComponents/userAnnotations/tools/service";
 import { userInteraction } from "src/state"
 import { arrayEqual } from "src/util/array"
+import { MouseOverSvc } from "./service"
 
 @Directive({
   selector: '[iav-mouse-hover]',
@@ -14,6 +15,13 @@ import { arrayEqual } from "src/util/array"
 
 export class MouseHoverDirective {
 
+  /**
+   * TODO move
+   * - mousing over regions
+   * - hovering annotation
+   * - hovering voi feature
+   * to use hover interceptor
+   */
   public currentOnHoverObs$: Observable<TOnHoverObj> = merge(
     this.store$.pipe(
       select(userInteraction.selectors.mousingOverRegions),
@@ -58,6 +66,9 @@ export class MouseHoverDirective {
   constructor(
     private store$: Store<any>,
     private annotSvc: ModularUserAnnotationToolService,
+    private svc: MouseOverSvc,
   ) {
   }
+
+  messages$ = this.svc.messages$
 }
diff --git a/src/mouseoverModule/mouseover.module.ts b/src/mouseoverModule/mouseover.module.ts
index b5fbcc9feb9f04b1336d1df7209445144e569cc5..f4c54934842b01a3b656136c63d0706603a178c5 100644
--- a/src/mouseoverModule/mouseover.module.ts
+++ b/src/mouseoverModule/mouseover.module.ts
@@ -1,8 +1,10 @@
 import { CommonModule } from "@angular/common";
 import { NgModule } from "@angular/core";
-import { TransformOnhoverSegmentPipe } from "src/atlasViewer/onhoverSegment.pipe";
+import { TransformOnhoverSegmentPipe } from "./transformOnhoverSegment.pipe";
 import { MouseHoverDirective } from "./mouseover.directive";
 import { MouseOverConvertPipe } from "./mouseOverCvt.pipe";
+import { HOVER_INTERCEPTOR_INJECTOR } from "src/util/injectionTokens";
+import { MouseOverSvc } from "./service";
 
 
 @NgModule({
@@ -18,7 +20,20 @@ import { MouseOverConvertPipe } from "./mouseOverCvt.pipe";
     MouseHoverDirective,
     TransformOnhoverSegmentPipe,
     MouseOverConvertPipe,
+  ],
+  providers: [
+    MouseOverSvc,
+    {
+      provide: HOVER_INTERCEPTOR_INJECTOR,
+      useFactory: (svc: MouseOverSvc) => {
+        return {
+          append: svc.append.bind(svc),
+          remove: svc.remove.bind(svc),
+        }
+      },
+      deps: [ MouseOverSvc ]
+    }
   ]
 })
 
-export class MouseoverModule{}
\ No newline at end of file
+export class MouseoverModule{}
diff --git a/src/mouseoverModule/service.ts b/src/mouseoverModule/service.ts
new file mode 100644
index 0000000000000000000000000000000000000000..eba057bcca83fab20a3e4afebee18de5c8d54efe
--- /dev/null
+++ b/src/mouseoverModule/service.ts
@@ -0,0 +1,27 @@
+import { Injectable } from "@angular/core";
+import { BehaviorSubject } from "rxjs";
+import { THoverConfig } from "src/util/injectionTokens";
+
+@Injectable()
+export class MouseOverSvc {
+
+  #messages: THoverConfig[] = []
+
+  messages$ = new BehaviorSubject(this.#messages)
+
+  set messages(messages: THoverConfig[]){
+    this.#messages = messages
+    this.messages$.next(this.#messages)
+  }
+
+  get messages(): THoverConfig[]{
+    return this.#messages
+  }
+
+  append(message: THoverConfig){
+    this.messages = this.messages.concat(message)
+  }
+  remove(message: THoverConfig){
+    this.messages = this.messages.filter(v => v !== message)
+  }
+}
diff --git a/src/util/injectionTokens.ts b/src/util/injectionTokens.ts
index 250a8cce50b1279b6c4d63fbb3e8bcd517b96a33..3b62ed171a53a512307599c7bf28a79eed677a59 100644
--- a/src/util/injectionTokens.ts
+++ b/src/util/injectionTokens.ts
@@ -19,6 +19,19 @@ export interface ClickInterceptor{
   deregister: (interceptorFunction: (ev: any) => any) => void
 }
 
+export const HOVER_INTERCEPTOR_INJECTOR = new InjectionToken<HoverInterceptor>("HOVER_INTERCEPTOR_INJECTOR")
+
+export type THoverConfig = {
+  fontSet?: string
+  fontIcon?: string
+  message: string
+}
+
+export interface HoverInterceptor {
+  append(message: THoverConfig): void
+  remove(message: THoverConfig): void
+}
+
 export const CONTEXT_MENU_ITEM_INJECTOR = new InjectionToken('CONTEXT_MENU_ITEM_INJECTOR')
 
 export type TContextMenu<T> = {
diff --git a/src/viewerModule/viewerCmp/viewerCmp.template.html b/src/viewerModule/viewerCmp/viewerCmp.template.html
index 2526996c85a8c178080fecf32942ad40deafbefb..7530460b3b4dcac8387ef68bc6634575dbde595f 100644
--- a/src/viewerModule/viewerCmp/viewerCmp.template.html
+++ b/src/viewerModule/viewerCmp/viewerCmp.template.html
@@ -22,6 +22,17 @@
           <span class="centered" matListItemIcon [class]="cvtOutput.icon.cls"></span>
           <span matListItemTitle>{{ cvtOutput.text }}</span>
         </mat-list-item>
+
+        <mat-list-item *ngFor="let message of iavMouseHoverContextualBlock.messages$ | async"
+          class="h-auto">
+          <ng-template [ngIf]="message.fontIcon && message.fontSet">
+            <mat-icon matListItemIcon
+              [fontSet]="message.fontSet"
+              [fontIcon]="message.fontIcon">
+            </mat-icon>
+          </ng-template>
+          <span matListItemTitle>{{ message.message }}</span>
+        </mat-list-item>
       </mat-list>
     </div>