diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index c3c07d114df83ae2c2dc663da720cc5451914f31..78d9a7e7b59248e5b280835a47c7860b579061e2 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -15,10 +15,10 @@ jobs:
 
     steps:
     - uses: actions/checkout@v2
-    - name: Use Node.js 14.x for lint
+    - name: Use Node.js 16.x for lint
       uses: actions/setup-node@v1
       with:
-        node-version: '14.x'
+        node-version: '16.x'
     - run: npm i
     - run: npm run lint
 
@@ -28,7 +28,7 @@ jobs:
 
     strategy:
       matrix:
-        node-version: [12.x, 14.x, 16.x]
+        node-version: [16.x]
 
     env:
       NODE_ENV: test
@@ -47,7 +47,7 @@ jobs:
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        node-version: [12.x, 14.x, 16.x]
+        node-version: [16.x]
 
     env:
       NODE_ENV: test
diff --git a/common/constants.js b/common/constants.js
index cf56106555a3b26559711671e22fcc0e06494e86..94a42b81abf59142a3d50f5a175d64208e02fbbd 100644
--- a/common/constants.js
+++ b/common/constants.js
@@ -108,6 +108,7 @@ If you do not accept the Terms & Conditions you are not permitted to access or u
     CANNOT_DECIPHER_HEMISPHERE: 'Cannot decipher region hemisphere.',
     DOES_NOT_SUPPORT_MULTI_REGION_SELECTION: `Please only select a single region.`,
     MULTI_REGION_SELECTION: `Multi region selection`,
+    DESCRIPTION: 'Description',
     REGIONAL_FEATURES: 'Regional features',
     CONNECTIVITY: 'Connectivity',
     NO_ADDIONTAL_INFO_AVAIL: `Currently, no additional information is linked to this region.`,
diff --git a/deploy/bkwdCompat/urlState.js b/deploy/bkwdCompat/urlState.js
index 66f92c3dc4f6b375fcfe0c70f16a685b43c30e0d..64093f9e035e19fc95c9ee8eea8b2caa2303912b 100644
--- a/deploy/bkwdCompat/urlState.js
+++ b/deploy/bkwdCompat/urlState.js
@@ -114,8 +114,12 @@ const WARNING_STRINGS = {
   REGION_SELECT_ERROR: 'Region selected cannot be processed properly.',
   TEMPLATE_ERROR: 'Template not found.',
 }
-
+const pliPreviewUrl = `/a:juelich:iav:atlas:v1.0.0:1/t:minds:core:referencespace:v1.0.0:a1655b99-82f1-420f-a3c2-fe80fd4c8588/p:juelich:iav:atlas:v1.0.0:4/@:0.0.0.-W000.._eCwg.2-FUe3._-s_W.2_evlu..7LIy..1qI1a.D31U~.i-Os~..HRE/f:siibra:features:voi:19c437087299dd62e7c507200f69aea6`
 module.exports = (query, _warningCb) => {
+
+  const HOST_PATHNAME = process.env.HOST_PATHNAME || ''
+  let redirectUrl = `${HOST_PATHNAME}/#`
+
   const {
     standaloneVolumes,
     niftiLayers, // deprecating - check if anyone calls this url
@@ -163,7 +167,17 @@ module.exports = (query, _warningCb) => {
       if (Array.isArray(parsedDsp)) {
         if (parsedDsp.length === 1) {
           const { datasetId, filename } = parsedDsp[0]
-          dsp = `/dsp:${encodeId(datasetId)}::${encodeURI(filename)}`
+          if (datasetId === "minds/core/dataset/v1.0.0/b08a7dbc-7c75-4ce7-905b-690b2b1e8957") {
+            /**
+             * if preview pli link, return hardcoded link
+             */
+            return `${HOST_PATHNAME}/#${pliPreviewUrl}`
+          } else {
+            /**
+             * TODO deprecate dsp
+             */
+            dsp = `/dsp:${encodeId(datasetId)}::${encodeURI(filename)}`
+          }
         } else {
           searchParam.set(`previewingDatasetFiles`, previewingDatasetFiles)
         }
@@ -206,8 +220,6 @@ module.exports = (query, _warningCb) => {
       // ignore region selected and move on
     }
   }
-  const HOST_PATHNAME = process.env.HOST_PATHNAME || ''
-  let redirectUrl = `${HOST_PATHNAME}/#`
   if (standaloneVolumes) {
     searchParam.set('standaloneVolumes', standaloneVolumes)
     if (nav) redirectUrl += nav
diff --git a/deploy/csp/index.js b/deploy/csp/index.js
index 7273c69b4e841bc5e0be5aa85d68fb8c10b15e09..898228ce845b95c747d027704c08ab96f8196c30 100644
--- a/deploy/csp/index.js
+++ b/deploy/csp/index.js
@@ -54,7 +54,9 @@ const connectSrc = [
   'object.cscs.ch',
 
   // required for dataset previews
-  'hbp-kg-dataset-previewer.apps.hbp.eu/v2/',
+
+  // spatial transform
+  "hbp-spatial-backend.apps.hbp.eu",
 
   // injected by env var
   ...CSP_CONNECT_SRC
@@ -102,7 +104,6 @@ module.exports = {
         ],
         imgSrc: [
           "'self'",
-          "hbp-kg-dataset-previewer.apps.hbp.eu/v2/"
         ],
         scriptSrc:[
           "'self'",
@@ -118,6 +119,9 @@ module.exports = {
           ...WHITE_LIST_SRC,
           ...defaultAllowedSites
         ],
+        frameSrc: [
+          "*"
+        ],
         reportUri: CSP_REPORT_URI || '/report-violation'
       },
       reportOnly
diff --git a/src/atlasComponents/annotations/annotation.service.ts b/src/atlasComponents/annotations/annotation.service.ts
index ec352e5fbd3707b63b4da42ca92e9157c36bfb0c..fd67601ee087cf32ddd230d7e42b3ca9fdaea421 100644
--- a/src/atlasComponents/annotations/annotation.service.ts
+++ b/src/atlasComponents/annotations/annotation.service.ts
@@ -146,7 +146,8 @@ export class AnnotationLayer {
     }
   }
   updateAnnotation(spec: AnnotationSpec) {
-    const localAnnotations = this.nglayer.layer.localAnnotations
+    const localAnnotations = this.nglayer?.layer?.localAnnotations
+    if (!localAnnotations) return
     const ref = localAnnotations.references.get(spec.id)
     const _spec = this.parseNgSpecType(spec)
     if (ref) {
diff --git a/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.component.ts b/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.component.ts
index 08bdb9d55bd85a616914cae076797142f3ff1026..88614d6194880e18d3e802de65c1660f75557b13 100644
--- a/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.component.ts
+++ b/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.component.ts
@@ -1,5 +1,8 @@
-import { Component, Input } from "@angular/core";
+import { Component, Input, OnChanges, SimpleChanges } from "@angular/core";
 import { SapiDatasetModel } from "src/atlasComponents/sapi";
+import { CONST } from "common/constants"
+
+const RESTRICTED_ACCESS_ID = "https://nexus.humanbrainproject.org/v0/data/minds/core/embargostatus/v1.0.0/3054f80d-96a8-4dce-9b92-55c68a8b5efd"
 
 @Component({
   selector: `sxplr-sapiviews-core-datasets-dataset`,
@@ -9,7 +12,17 @@ import { SapiDatasetModel } from "src/atlasComponents/sapi";
   ]
 })
 
-export class DatasetView {
+export class DatasetView implements OnChanges{
   @Input('sxplr-sapiviews-core-datasets-dataset-input')
   dataset: SapiDatasetModel
+
+  public isRestricted = false
+  public CONST = CONST
+
+  ngOnChanges(changes: SimpleChanges): void {
+    const { dataset } = changes
+    if (dataset) {
+      this.isRestricted = (dataset.currentValue as SapiDatasetModel)?.metadata?.accessibility?.["@id"] === RESTRICTED_ACCESS_ID
+    }
+  }
 }
diff --git a/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.template.html b/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.template.html
index 68ce4f9a8540b0c1154408328260ed2e00a07b5a..f9c37f9907d70750b2de1db334ac2c15949db7ca 100644
--- a/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.template.html
+++ b/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.template.html
@@ -24,6 +24,13 @@
     <span class="sxplr-m-a">
       EBRAINS dataset
     </span>
+
+    <button *ngIf="isRestricted"
+      [matTooltip]="CONST.GDPR_TEXT"
+      mat-icon-button color="warn">
+      <i class="fas fa-exclamation-triangle"></i>
+    </button>
+
     <mat-divider class="sxplr-pl-1" [vertical]="true"></mat-divider>
 
     <a mat-icon-button *ngFor="let url of dataset.urls" [href]="url.doi | parseDoi" target="_blank">
diff --git a/src/atlasComponents/sapiViews/core/index.ts b/src/atlasComponents/sapiViews/core/index.ts
index 6db4628176e571f0a50adca091dc02c5d51801de..cb3d0ffce18ea93d534e44866392f0fc819b0ae8 100644
--- a/src/atlasComponents/sapiViews/core/index.ts
+++ b/src/atlasComponents/sapiViews/core/index.ts
@@ -1,3 +1,7 @@
 export {
   SapiViewsCoreModule
-} from "./module"
\ No newline at end of file
+} from "./module"
+
+export {
+  SapiViewsCoreSpaceBoundingBox
+} from "./space"
\ No newline at end of file
diff --git a/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.component.ts b/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.component.ts
index 541b428be133981a956008ca640e2b2a67a52cf1..27d4a53cc941a95164407b86f61825c01df1527f 100644
--- a/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.component.ts
+++ b/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.component.ts
@@ -1,5 +1,5 @@
-import { Component, EventEmitter, Input, OnChanges, Output } from "@angular/core";
-import { concat, Observable, of, timer } from "rxjs";
+import { Component, EventEmitter, Input, OnChanges, Output, SimpleChange, SimpleChanges } from "@angular/core";
+import { BehaviorSubject, concat, Observable, of, timer } from "rxjs";
 import { SapiParcellationModel } from "src/atlasComponents/sapi/type";
 import { ParcellationVisibilityService } from "../parcellationVis.service";
 import { ARIA_LABELS } from "common/constants"
@@ -38,7 +38,11 @@ export class SapiViewsCoreParcellationParcellationSmartChip implements OnChanges
 
   otherVersions: SapiParcellationModel[]
 
-  ngOnChanges() {
+  ngOnChanges(changes: SimpleChanges) {
+    const { parcellation } = changes
+    if (parcellation) {
+      this.onDismissClicked$.next(false)
+    }
     this.otherVersions = []
     if (!this.parcellation) {
       return
@@ -82,6 +86,8 @@ export class SapiViewsCoreParcellationParcellationSmartChip implements OnChanges
   }
 
   dismiss(){
+    if (this.onDismissClicked$.value) return
+    this.onDismissClicked$.next(true)
     this.onDismiss.emit(this.parcellation)
   }
 
@@ -93,4 +99,6 @@ export class SapiViewsCoreParcellationParcellationSmartChip implements OnChanges
   trackByFn(parc: SapiParcellationModel){
     return parc["@id"]
   }
+
+  onDismissClicked$ = new BehaviorSubject<boolean>(false)
 }
diff --git a/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.style.css b/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.style.css
index 93caeb8c21b229a9d3a4efb5a9219e9f604163d3..e8d0ca357ccbfe577e65a2f9d78c1589227cbf33 100644
--- a/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.style.css
+++ b/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.style.css
@@ -5,20 +5,6 @@
   margin: 0.5rem;
 }
 
-.otherversion-wrapper.loading > sxplr-sapiviews-core-parcellation-chip
-{
-  animation: blink 500ms ease-in-out infinite alternate;
-}
-
-@keyframes blink {
-  0% {
-    opacity: 0.8;
-  }
-  100% {
-    opacity: 0.5;
-  }
-}
-
 .otherversion-wrapper.loading > .spinner-container
 {
   position: absolute;
diff --git a/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.template.html b/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.template.html
index b21af3c775b330b100c4aa8c3e877fdc88237dfd..e56b6b69b9fc9405c4efb29900f9a448921839cf 100644
--- a/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.template.html
+++ b/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.template.html
@@ -10,7 +10,10 @@
       }">
 
 
-      <sxplr-sapiviews-core-parcellation-chip 
+      <sxplr-sapiviews-core-parcellation-chip
+        [ngClass]="{
+          'sxplr-blink': (loadingParc$ | async) === parc
+        }"
         [sxplr-sapiviews-core-parcellation-chip-parcellation]="parc"
         [sxplr-sapiviews-core-parcellation-chip-color]="(parcellation | equality : parc : trackByFn) ? 'primary' : 'default'"
         (sxplr-sapiviews-core-parcellation-chip-onclick)="selectParcellation(parc)">
@@ -28,7 +31,8 @@
 
 <sxplr-sapiviews-core-parcellation-chip
   [ngClass]="{
-    'sxplr-muted': !(parcellationVisibility$ | async)
+    'sxplr-muted': !(parcellationVisibility$ | async),
+    'sxplr-blink': onDismissClicked$ | async
   }"
   class="sxplr-d-inline-block"
   [sxplr-sapiviews-core-parcellation-chip-parcellation]="parcellation"
@@ -63,7 +67,12 @@
       color="primary"
       iav-stop="mousedown click"
       (click)="dismiss()">
-      <i class="fas fa-times"></i>
+
+      <spinner-cmp class="sxplr-w-100 sxplr-h-100" *ngIf="onDismissClicked$ | async; else defaultDismissIcon"></spinner-cmp>
+      <ng-template #defaultDismissIcon>
+        <i class="fas fa-times"></i>
+      </ng-template>
+
     </button>
   </div>
 </sxplr-sapiviews-core-parcellation-chip>
diff --git a/src/atlasComponents/sapiViews/core/region/module.ts b/src/atlasComponents/sapiViews/core/region/module.ts
index f0e19a9bc9a82c83dc8e3501ce3f2b99ff51b7bd..6c30611aa3b4ce8494f21bc60501da87089b9bb6 100644
--- a/src/atlasComponents/sapiViews/core/region/module.ts
+++ b/src/atlasComponents/sapiViews/core/region/module.ts
@@ -1,5 +1,6 @@
 import { CommonModule } from "@angular/common";
 import { NgModule } from "@angular/core";
+import { MarkdownModule } from "src/components/markdown";
 import { SpinnerModule } from "src/components/spinner";
 import { AngularMaterialModule } from "src/sharedModules";
 import { SapiViewsFeaturesModule } from "../../features";
@@ -17,6 +18,7 @@ import { SapiViewsCoreRegionRegionRich } from "./region/rich/region.rich.compone
     SapiViewsUtilModule,
     SapiViewsFeaturesModule,
     SpinnerModule,
+    MarkdownModule,
   ],
   declarations: [
     SapiViewsCoreRegionRegionListItem,
diff --git a/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.template.html b/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.template.html
index 8884f0786d55340b4e389cd1b47ddaaec1d08f85..d4a9a79d17698288b49f115c83d895459327bd20 100644
--- a/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.template.html
+++ b/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.template.html
@@ -68,7 +68,7 @@
       <spinner-cmp *ngIf="rfDir.busy$ | async"></spinner-cmp>
 
       <sxplr-sapiviews-features-entry-list-item
-        *ngFor="let feat of rfDir.listOfFeatures$ | async"
+        *ngFor="let feat of rfDir.listOfFeatures$ | async | orderFilterFeatures"
         [sxplr-sapiviews-features-entry-list-item-feature]="feat"
         (click)="handleRegionalFeatureClicked(feat)">
       </sxplr-sapiviews-features-entry-list-item>
@@ -76,10 +76,23 @@
     
   </ng-template>
 
+  <ng-template #regionDesc>
+    <markdown-dom class="sxplr-muted" [markdown]="region?.versionInnovation || 'No description provided.'">
+    </markdown-dom>
+  </ng-template>
 
+  <mat-accordion class="d-block mt-2">
 
+    <ng-container *ngTemplateOutlet="ngMatAccordionTmpl; context: {
+      title: CONST.DESCRIPTION,
+      iconClass: 'fas fa-info',
+      content: regionDesc,
+      desc: '',
+      iconTooltip: 'Description',
+      iavNgIf: !!region?.versionInnovation
+    }">
 
-  <mat-accordion class="d-block mt-2">
+    </ng-container>
 
     <ng-container *ngTemplateOutlet="ngMatAccordionTmpl; context: {
       title: CONST.REGIONAL_FEATURES,
@@ -91,10 +104,6 @@
     }">
     </ng-container>
 
-  </mat-accordion>
-
-  <mat-accordion class="d-block mt-2">
-
     <!-- connectivity -->
     <ng-template #sxplrSapiviewsFeaturesConnectivityBrowser>
       <sxplr-sapiviews-features-connectivity-browser
diff --git a/src/atlasComponents/sapiViews/core/space/index.ts b/src/atlasComponents/sapiViews/core/space/index.ts
index 46f783b69e03bdae2ef01144ba731e0b264c1c12..26c7eed07b1e454d4eac3bcbdf0c77bb9fe4f162 100644
--- a/src/atlasComponents/sapiViews/core/space/index.ts
+++ b/src/atlasComponents/sapiViews/core/space/index.ts
@@ -1 +1,4 @@
-export { SapiViewsCoreSpaceModule } from "./module"
\ No newline at end of file
+export { SapiViewsCoreSpaceModule } from "./module"
+export {
+  SapiViewsCoreSpaceBoundingBox
+} from "./boundingBox.directive"
\ No newline at end of file
diff --git a/src/atlasComponents/sapiViews/features/entryListItem/entryListItem.component.ts b/src/atlasComponents/sapiViews/features/entryListItem/entryListItem.component.ts
index 3b915ff248a21b0cf19d3dc5fbac8131b2d21643..8008affe34a6b783fd1b93ed14ee527279e36d04 100644
--- a/src/atlasComponents/sapiViews/features/entryListItem/entryListItem.component.ts
+++ b/src/atlasComponents/sapiViews/features/entryListItem/entryListItem.component.ts
@@ -1,4 +1,4 @@
-import { Component, Input } from "@angular/core";
+import { ChangeDetectionStrategy, Component, Input } from "@angular/core";
 import { SapiFeatureModel } from "src/atlasComponents/sapi";
 import { CleanedIeegDataset, CLEANED_IEEG_DATASET_TYPE, SapiDatasetModel, SapiParcellationFeatureMatrixModel, SapiRegionalFeatureReceptorModel, SapiSerializationErrorModel, SapiVOIDataResponse, SxplrCleanedFeatureModel } from "src/atlasComponents/sapi/type";
 
@@ -7,7 +7,8 @@ import { CleanedIeegDataset, CLEANED_IEEG_DATASET_TYPE, SapiDatasetModel, SapiPa
   templateUrl: `./entryListItem.template.html`,
   styleUrls: [
     `./entryListItem.style.css`
-  ]
+  ],
+  changeDetection: ChangeDetectionStrategy.OnPush,
 })
 
 export class SapiViewsFeaturesEntryListItem{
diff --git a/src/atlasComponents/sapiViews/features/index.ts b/src/atlasComponents/sapiViews/features/index.ts
index 19e30dcb1873aa37868be5e8944eaad3a9b0ce05..89e1fafbad8108576c708d401326b2d5f4137f6d 100644
--- a/src/atlasComponents/sapiViews/features/index.ts
+++ b/src/atlasComponents/sapiViews/features/index.ts
@@ -1,3 +1,7 @@
 export {
   SapiViewsFeaturesModule
-} from "./module"
\ No newline at end of file
+} from "./module"
+
+export {
+  SapiViewsFeaturesVoiQuery
+} from "./voi"
diff --git a/src/atlasComponents/sapiViews/features/module.ts b/src/atlasComponents/sapiViews/features/module.ts
index cbf7aeacaeccaf721bb6ca55108b01366f3fa685..3df348c72f79be4b53c3050e30627c896e8b93f2 100644
--- a/src/atlasComponents/sapiViews/features/module.ts
+++ b/src/atlasComponents/sapiViews/features/module.ts
@@ -11,6 +11,7 @@ import * as ieeg from "./ieeg"
 import * as receptor from "./receptors"
 import {SapiViewsFeatureConnectivityModule} from "src/atlasComponents/sapiViews/features/connectivity";
 import * as voi from "./voi"
+import { OrderFilterFeaturesPipe } from "./orderFilterFeatureList.pipe"
 
 const {
   SxplrSapiViewsFeaturesIeegModule
@@ -35,6 +36,7 @@ const { SapiViewsFeaturesVoiModule } = voi
     FeatureBadgeColourPipe,
     FeatureBadgeFlagPipe,
     SapiViewsFeaturesEntryListItem,
+    OrderFilterFeaturesPipe,
   ],
   providers: [
     {
@@ -48,6 +50,7 @@ const { SapiViewsFeaturesVoiModule } = voi
     SapiViewsFeaturesEntryListItem,
     SapiViewsFeaturesVoiModule,
     SapiViewsFeatureConnectivityModule,
+    OrderFilterFeaturesPipe,
   ]
 })
 export class SapiViewsFeaturesModule{}
diff --git a/src/atlasComponents/sapiViews/features/orderFilterFeatureList.pipe.ts b/src/atlasComponents/sapiViews/features/orderFilterFeatureList.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..382862b0300f4bdaffadce20aeb4e28274a8bef6
--- /dev/null
+++ b/src/atlasComponents/sapiViews/features/orderFilterFeatureList.pipe.ts
@@ -0,0 +1,37 @@
+import { Pipe, PipeTransform } from "@angular/core";
+import { CLEANED_IEEG_DATASET_TYPE, SapiFeatureModel, SxplrCleanedFeatureModel } from "src/atlasComponents/sapi/type";
+import { environment } from "src/environments/environment"
+
+type PipableFeatureType = SapiFeatureModel | SxplrCleanedFeatureModel
+
+type ArrayOperation<T extends boolean | number> = (input: PipableFeatureType) => T
+
+const FILTER_FN: ArrayOperation<boolean> = feature => {
+  return feature["@type"] !== "siibra/features/cells"
+}
+
+const ORDER_LIST: ArrayOperation<number> = feature => {
+  if (feature["@type"] === "siibra/features/receptor") return -4
+  if (feature["@type"] === CLEANED_IEEG_DATASET_TYPE) return -3
+  if (feature['@type'] === "https://openminds.ebrains.eu/core/DatasetVersion") return 2
+  return 0
+}
+
+@Pipe({
+  name: 'orderFilterFeatures',
+  pure: true
+})
+
+export class OrderFilterFeaturesPipe implements PipeTransform{
+  public transform(inputFeatures: PipableFeatureType[]): PipableFeatureType[] {
+    return inputFeatures
+      .filter(f => {
+        /**
+         * if experimental flag is set, do not filter out anything
+         */
+        if (environment.EXPERIMENTAL_FEATURE_FLAG) return true
+        return FILTER_FN(f)
+      })
+      .sort((a, b) => ORDER_LIST(a) - ORDER_LIST(b))
+  }
+}
diff --git a/src/overwrite.scss b/src/overwrite.scss
index a6b3e9f55255d3080d58a94e7be6aedce47fc890..790e436d35acc4e970127548ec060fa796b6a650 100644
--- a/src/overwrite.scss
+++ b/src/overwrite.scss
@@ -264,4 +264,18 @@ $flex-directions: row,column;
 
 .#{$nsp}-flex-static {
   flex: 0 0 auto;
-}
\ No newline at end of file
+}
+
+.#{$nsp}-blink
+{
+  animation: blink 500ms ease-in-out infinite alternate;
+}
+
+@keyframes blink {
+  0% {
+    opacity: 0.8;
+  }
+  100% {
+    opacity: 0.5;
+  }
+}
diff --git a/src/viewerModule/nehuba/constants.ts b/src/viewerModule/nehuba/constants.ts
index 6537a7aef4ea762d6d38c85ac335011551b5767e..ca5ae4be810af998f93318a6348f751555fabff3 100644
--- a/src/viewerModule/nehuba/constants.ts
+++ b/src/viewerModule/nehuba/constants.ts
@@ -64,3 +64,5 @@ export interface IMeshesToLoad {
 }
 
 export const SET_MESHES_TO_LOAD = new InjectionToken<Observable<IMeshesToLoad>>('SET_MESHES_TO_LOAD')
+
+export const PMAP_LAYER_NAME = 'regional-pmap'
diff --git a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.effects.ts b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.effects.ts
index 6f6d708876773bd84a484d73226fab01066f731a..579f7fb79ab3e65547cc420391f2097587eeff18 100644
--- a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.effects.ts
+++ b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.effects.ts
@@ -11,7 +11,7 @@ import { EnumColorMapName } from "src/util/colorMaps";
 import { getShader } from "src/util/constants";
 import { getNgLayersFromVolumesATP, getRegionLabelIndex } from "../config.service";
 import { ParcVolumeSpec } from "../store/util";
-import { NehubaLayerControlService } from "./layerCtrl.service";
+import { PMAP_LAYER_NAME } from "../constants";
 
 @Injectable()
 export class LayerCtrlEffects {
@@ -22,7 +22,7 @@ export class LayerCtrlEffects {
     ),
     mapTo(
       atlasAppearance.actions.removeCustomLayer({
-        id: NehubaLayerControlService.PMAP_LAYER_NAME
+        id: PMAP_LAYER_NAME
       })
     )
   ))
@@ -42,7 +42,7 @@ export class LayerCtrlEffects {
           atlasAppearance.actions.addCustomLayer({
             customLayer: {
               clType: "customlayer/nglayer",
-              id: NehubaLayerControlService.PMAP_LAYER_NAME,
+              id: PMAP_LAYER_NAME,
               source: `nifti://${sapiRegion.getMapUrl(template["@id"])}`,
               shader: getShader({
                 colormap: EnumColorMapName.VIRIDIS,
@@ -55,7 +55,7 @@ export class LayerCtrlEffects {
         ),
         catchError(() => of(
           atlasAppearance.actions.removeCustomLayer({
-            id: NehubaLayerControlService.PMAP_LAYER_NAME
+            id: PMAP_LAYER_NAME
           })
         ))
       )
diff --git a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.ts b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.ts
index ba8b1d0adbe40c1c00fb794cac66a0b1890c25ae..5980c76d634265b8d20acac43b548da7d0f293e6 100644
--- a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.ts
+++ b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.ts
@@ -13,6 +13,7 @@ import { arrayEqual } from "src/util/array";
 import { ColorMapCustomLayer } from "src/state/atlasAppearance";
 import { SapiRegionModel } from "src/atlasComponents/sapi";
 import { AnnotationLayer } from "src/atlasComponents/annotations";
+import { PMAP_LAYER_NAME } from "../constants"
 
 export const BACKUP_COLOR = {
   red: 255,
@@ -25,8 +26,6 @@ export const BACKUP_COLOR = {
 })
 export class NehubaLayerControlService implements OnDestroy{
 
-  static PMAP_LAYER_NAME = 'regional-pmap'
-
   private selectedRegion$ = this.store$.pipe(
     select(atlasSelection.selectors.selectedRegions),
     shareReplay(1),
@@ -367,7 +366,7 @@ export class NehubaLayerControlService implements OnDestroy{
          */
         return customLayers
           .map(l => l.id)
-          .filter(name => name !== NehubaLayerControlService.PMAP_LAYER_NAME)
+          .filter(name => name !== PMAP_LAYER_NAME)
       })
     ),
     this.customLayers$.pipe(
@@ -378,7 +377,7 @@ export class NehubaLayerControlService implements OnDestroy{
       }),
       distinctUntilChanged(),
       map(flag => flag
-        ? [ NehubaLayerControlService.PMAP_LAYER_NAME ]
+        ? [ PMAP_LAYER_NAME ]
         : []
       )
     )
diff --git a/src/viewerModule/nehuba/mesh.service/mesh.service.spec.ts b/src/viewerModule/nehuba/mesh.service/mesh.service.spec.ts
index 62a4ce09eb3d14682498812aee8e9e90dd01b253..ef3ac53320fbfa6ee86ec80ac140c105a2534af8 100644
--- a/src/viewerModule/nehuba/mesh.service/mesh.service.spec.ts
+++ b/src/viewerModule/nehuba/mesh.service/mesh.service.spec.ts
@@ -7,7 +7,7 @@ import { SapiRegionModel } from "src/atlasComponents/sapi"
 import * as configSvc from "../config.service"
 import { LayerCtrlEffects } from "../layerCtrl.service/layerCtrl.effects"
 import { NEVER, of, pipe } from "rxjs"
-import { mapTo } from "rxjs/operators"
+import { mapTo, take } from "rxjs/operators"
 import { selectorAuxMeshes } from "../store"
 
 
@@ -51,6 +51,12 @@ describe('> mesh.service.ts', () => {
       )
     )
   })
+
+  afterEach(() => {
+    getParcNgIdSpy.calls.reset()
+    getRegionLabelIndexSpy.calls.reset()
+    getATPSpy.calls.reset()
+  })
   describe('> NehubaMeshService', () => {
     beforeEach(() => {
       TestBed.configureTestingModule({
@@ -72,37 +78,106 @@ describe('> mesh.service.ts', () => {
       expect(service).toBeTruthy()
     })
 
-    it('> mixes in auxillaryMeshIndices', () => {
-      const mockStore = TestBed.inject(MockStore)
-      mockStore.overrideSelector(atlasSelection.selectors.selectedRegions, [ fits1 ])
-      mockStore.overrideSelector(atlasSelection.selectors.selectedParcAllRegions, [])
-      mockStore.overrideSelector(selectorAuxMeshes, [auxMesh])
+    describe("> loadMeshes$", () => {
 
-      const ngId = 'blabla'
-      const labelIndex = 12
-      getParcNgIdSpy.and.returnValue(ngId)
-      getRegionLabelIndexSpy.and.returnValue(labelIndex)
+      describe("> auxMesh defined", () => {
+
+        const ngId = 'blabla'
+        const labelIndex = 12
+
+        beforeEach(() => {
+
+          const mockStore = TestBed.inject(MockStore)
+          mockStore.overrideSelector(atlasSelection.selectors.selectedRegions, [ fits1 ])
+          mockStore.overrideSelector(atlasSelection.selectors.selectedParcAllRegions, [])
+          mockStore.overrideSelector(selectorAuxMeshes, [auxMesh])
+    
+          getParcNgIdSpy.and.returnValue(ngId)
+          getRegionLabelIndexSpy.and.returnValue(labelIndex)
 
-      const service = TestBed.inject(NehubaMeshService)
-      
-      expect(
-        service.loadMeshes$
-      ).toBeObservable(
-        hot('(ab)', {
-          a: {
-            layer: {
-              name: ngId
-            },
-            labelIndicies: [ labelIndex ]
-          },
-          b: {
-            layer: {
-              name: auxMesh.ngId,
-            },
-            labelIndicies: auxMesh.labelIndicies
-          }
         })
-      )
+
+        it("> auxMesh ngId labelIndex emitted", () => {
+
+          const service = TestBed.inject(NehubaMeshService)
+          expect(
+            service.loadMeshes$
+          ).toBeObservable(
+            hot('(ab)', {
+              a: {
+                layer: {
+                  name: ngId
+                },
+                labelIndicies: [ labelIndex ]
+              },
+              b: {
+                layer: {
+                  name: auxMesh.ngId,
+                },
+                labelIndicies: auxMesh.labelIndicies
+              }
+            })
+          )
+        })
+      })
+
+      describe("> if multiple ngid and labelindicies are present", () => {
+
+        const ngId1 = 'blabla'
+        const labelIndex1 = 12
+
+        const ngId2 = 'foobar'
+        const labelIndex2 = 13
+
+        beforeEach(() => {
+
+          const mockStore = TestBed.inject(MockStore)
+          mockStore.overrideSelector(atlasSelection.selectors.selectedRegions, [ fits1 ])
+          mockStore.overrideSelector(atlasSelection.selectors.selectedParcAllRegions, [fits1, fits1])
+          mockStore.overrideSelector(selectorAuxMeshes, [])
+    
+          getParcNgIdSpy.and.returnValues(ngId1, ngId2, ngId2)
+          getRegionLabelIndexSpy.and.returnValues(labelIndex1, labelIndex2, labelIndex2)
+        })
+
+        it('> should call getParcNgIdSpy and getRegionLabelIndexSpy thrice', () => {
+          const service = TestBed.inject(NehubaMeshService)
+          service.loadMeshes$.pipe(
+            take(1)
+          ).subscribe(() => {
+
+            expect(getParcNgIdSpy).toHaveBeenCalledTimes(3)
+            expect(getRegionLabelIndexSpy).toHaveBeenCalledTimes(3)
+          })
+        })
+
+        /**
+         * in the case of julich brain 2.9 in colin 27, we expect selecting a region will hide meshes from all relevant ngIds (both left and right)
+         */
+        it('> expect the emitted value to be incl all ngIds', () => {
+          const service = TestBed.inject(NehubaMeshService)
+          expect(
+            service.loadMeshes$
+          ).toBeObservable(
+            hot('(ab)', {
+              a: {
+                layer: {
+                  name: ngId1
+                },
+                labelIndicies: []
+              },
+              b: {
+                layer: {
+                  name: ngId2
+                },
+                labelIndicies: [ labelIndex2 ]
+              }
+            })
+          )
+
+        })
+      })
+
     })
   })
 })
diff --git a/src/viewerModule/nehuba/mesh.service/mesh.service.ts b/src/viewerModule/nehuba/mesh.service/mesh.service.ts
index 2585f00224e8729a4434afa568e127a486e66fcb..d372ce460746d01c5cf560518e1532f38616b882 100644
--- a/src/viewerModule/nehuba/mesh.service/mesh.service.ts
+++ b/src/viewerModule/nehuba/mesh.service/mesh.service.ts
@@ -47,7 +47,40 @@ export class NehubaMeshService implements OnDestroy {
     ]).pipe(
       switchMap(([{ atlas, template, parcellation }, regions, selectedRegions]) => {
         const ngIdRecord: Record<string, number[]> = {}
+        
+        const tree = new Tree(
+          regions,
+          (c, p) => (c.hasParent || []).some(_p => _p["@id"] === p["@id"])
+        )
+
+        for (const r of regions) {
+          const regionLabelIndex = getRegionLabelIndex( atlas, template, parcellation, r )
+          if (!regionLabelIndex) {
+            continue
+          }
+          if (
+            tree.someAncestor(r, anc => !!getRegionLabelIndex(atlas, template, parcellation, anc))
+          ) {
+            continue
+          }
+          const ngId = getParcNgId(atlas, template, parcellation, r)
+          if (!ngIdRecord[ngId]) {
+            ngIdRecord[ngId] = []
+          }
+          ngIdRecord[ngId].push(regionLabelIndex)
+        }
+
         if (selectedRegions.length > 0) {
+          /**
+           * If regions are selected, reset the meshes
+           */
+          for (const key in ngIdRecord) {
+            ngIdRecord[key] = []
+          }
+
+          /**
+           * only show selected region
+           */
           for (const r of selectedRegions) {
             const ngId = getParcNgId(atlas, template, parcellation, r)
             const regionLabelIndex = getRegionLabelIndex( atlas, template, parcellation, r )
@@ -56,28 +89,6 @@ export class NehubaMeshService implements OnDestroy {
             }
             ngIdRecord[ngId].push(regionLabelIndex)
           }
-        } else {
-          const tree = new Tree(
-            regions,
-            (c, p) => (c.hasParent || []).some(_p => _p["@id"] === p["@id"])
-          )
-  
-          for (const r of regions) {
-            const regionLabelIndex = getRegionLabelIndex( atlas, template, parcellation, r )
-            if (!regionLabelIndex) {
-              continue
-            }
-            if (
-              tree.someAncestor(r, (anc) => !!getRegionLabelIndex(atlas, template, parcellation, anc))
-            ) {
-              continue
-            }
-            const ngId = getParcNgId(atlas, template, parcellation, r)
-            if (!ngIdRecord[ngId]) {
-              ngIdRecord[ngId] = []
-            }
-            ngIdRecord[ngId].push(regionLabelIndex)
-          }  
         }
         const arr: IMeshesToLoad[] = []
 
diff --git a/src/viewerModule/nehuba/ngLayerCtl/ngLayerCtrl.component.ts b/src/viewerModule/nehuba/ngLayerCtl/ngLayerCtrl.component.ts
index fd216151b9bbbf14d3b498eae8ffc98b2501ba05..f2e75e77f501517ac2f166f44a1b851042458489 100644
--- a/src/viewerModule/nehuba/ngLayerCtl/ngLayerCtrl.component.ts
+++ b/src/viewerModule/nehuba/ngLayerCtl/ngLayerCtrl.component.ts
@@ -54,6 +54,10 @@ export class NgLayerCtrlCmp implements OnChanges, OnDestroy{
   private onDestroyCb: (() => void)[] = []
   private removeLayer: () => void
 
+  public showOpacityCtrl = false
+  public hideNgTuneCtrl = 'lower_threshold,higher_threshold,brightness,contrast,colormap,hide-threshold-checkbox'
+  public defaultOpacity = 1
+
   @Input('ng-layer-ctl-name')
   name: string
 
diff --git a/src/viewerModule/nehuba/ngLayerCtl/ngLayerCtrl.template.html b/src/viewerModule/nehuba/ngLayerCtl/ngLayerCtrl.template.html
index 2188b17d9f57f496928a0b40f2ba78e3508be9d5..e3442c7b4323dac373e0b9110549b8c97a206a3e 100644
--- a/src/viewerModule/nehuba/ngLayerCtl/ngLayerCtrl.template.html
+++ b/src/viewerModule/nehuba/ngLayerCtl/ngLayerCtrl.template.html
@@ -7,4 +7,16 @@
   <span>
     {{ name }}
   </span>
+
+  <button mat-icon-button (click)="showOpacityCtrl = !showOpacityCtrl">
+    <i class="fas fa-cog"></i>
+  </button>
+
+  <ng-template [ngIf]="showOpacityCtrl">
+    <ng-layer-tune
+      [ngLayerName]="name"
+      [hideCtrl]="hideNgTuneCtrl"
+      [opacity]="defaultOpacity">
+    </ng-layer-tune>
+  </ng-template>
 </div>
diff --git a/src/viewerModule/threeSurfer/threeSurferGlue/threeSurfer.component.ts b/src/viewerModule/threeSurfer/threeSurferGlue/threeSurfer.component.ts
index a194176aa6d83027be793d3ebe1d098aa75f8c8d..f04ad6cc1b0a5b85875c6bc247150b737eb5605c 100644
--- a/src/viewerModule/threeSurfer/threeSurferGlue/threeSurfer.component.ts
+++ b/src/viewerModule/threeSurfer/threeSurferGlue/threeSurfer.component.ts
@@ -328,7 +328,8 @@ export class ThreeSurferGlueCmp implements IViewer<'threeSurfer'>, AfterViewInit
      * subscribe to main store and negotiate with relay to set camera
      */
     const navSub = this.store$.pipe(
-      select(atlasSelection.selectors.navigation)
+      select(atlasSelection.selectors.navigation),
+      filter(v => !!v),
     ).subscribe(nav => {
       const { perspectiveOrientation, perspectiveZoom } = nav
       this.mainStoreCameraNav = {
diff --git a/src/viewerModule/viewerCmp/viewerCmp.component.ts b/src/viewerModule/viewerCmp/viewerCmp.component.ts
index c01b335222d6ed39caf95183524d7d4c7aae2fac..f0b32efea3c8233a648e0277bfd38ddeaebe2074 100644
--- a/src/viewerModule/viewerCmp/viewerCmp.component.ts
+++ b/src/viewerModule/viewerCmp/viewerCmp.component.ts
@@ -12,6 +12,9 @@ import { SAPI, SapiRegionModel } from "src/atlasComponents/sapi";
 import { atlasSelection, userInteraction, } from "src/state";
 import { SapiSpatialFeatureModel, SapiFeatureModel, SapiParcellationModel, SapiSpaceModel } from "src/atlasComponents/sapi/type";
 import { getUuid } from "src/util/fn";
+import { environment } from "src/environments/environment"
+import { SapiViewsFeaturesVoiQuery } from "src/atlasComponents/sapiViews/features";
+import { SapiViewsCoreSpaceBoundingBox } from "src/atlasComponents/sapiViews/core";
 
 @Component({
   selector: 'iav-cmp-viewer-container',
@@ -62,10 +65,17 @@ export class ViewerCmp implements OnDestroy {
 
   public CONST = CONST
   public ARIA_LABELS = ARIA_LABELS
+  public VOI_QUERY_FLAG = environment.EXPERIMENTAL_FEATURE_FLAG
 
   @ViewChild('genericInfoVCR', { read: ViewContainerRef })
   genericInfoVCR: ViewContainerRef
 
+  @ViewChild('voiFeatures', { read: SapiViewsFeaturesVoiQuery })
+  voiQueryDirective: SapiViewsFeaturesVoiQuery
+
+  @ViewChild('bbox', { read: SapiViewsCoreSpaceBoundingBox })
+  boundingBoxDirective: SapiViewsCoreSpaceBoundingBox
+
   public quickTourRegionSearch: IQuickTourData = {
     order: 7,
     description: QUICKTOUR_DESC.REGION_SEARCH,
diff --git a/src/viewerModule/viewerCmp/viewerCmp.template.html b/src/viewerModule/viewerCmp/viewerCmp.template.html
index 2012afcff01d3121e46f30ddca9ceff8faebb46d..90d6d4a3810ecb35d68f616af533a3579493d78a 100644
--- a/src/viewerModule/viewerCmp/viewerCmp.template.html
+++ b/src/viewerModule/viewerCmp/viewerCmp.template.html
@@ -29,7 +29,7 @@
 
         </mat-list-item>
 
-        <ng-template [ngIf]="voiFeatures.onhover | async" let-feat>
+        <ng-template [ngIf]="voiQueryDirective && (voiQueryDirective.onhover | async)" let-feat>
           <mat-list-item>
             <mat-icon
               fontSet="fas"
@@ -223,9 +223,11 @@
       <ng-container *ngTemplateOutlet="autocompleteTmpl; context: { showTour: true }">
       </ng-container>
       
-      <div *ngIf="!((selectedRegions$ | async)[0])" class="sxplr-p-2 w-100">
-        <ng-container *ngTemplateOutlet="spatialFeatureListViewTmpl"></ng-container>
-      </div>
+      <ng-template [ngIf]="VOI_QUERY_FLAG">
+        <div *ngIf="!((selectedRegions$ | async)[0])" class="sxplr-p-2 w-100">
+          <ng-container *ngTemplateOutlet="spatialFeatureListViewTmpl"></ng-container>
+        </div>
+      </ng-template>
     </div>
 
     <!-- such a gross implementation -->
@@ -264,7 +266,7 @@
       isOpen: minTrayVisSwitch.switchState$ | async,
       regionSelected: selectedRegions$ | async,
       click: minTrayVisSwitch.toggle.bind(minTrayVisSwitch),
-      badge: (voiFeatures.features$ | async).length || null
+      badge: voiQueryDirective && (voiQueryDirective.features$ | async).length || null
     }">
     </ng-container>
   </div>
@@ -983,18 +985,18 @@
 </ng-template>
 
 <ng-template #spatialFeatureListViewTmpl>
-  <div *ngIf="voiFeatures.busy$ | async; else notBusyTmpl" class="fs-200">
+  <div *ngIf="voiQueryDirective && (voiQueryDirective.busy$ | async); else notBusyTmpl" class="fs-200">
     <spinner-cmp></spinner-cmp>
   </div>
 
   <ng-template #notBusyTmpl>
-    <mat-card *ngIf="(voiFeatures.features$ | async).length > 0" class="pe-all mat-elevation-z4">
+    <mat-card *ngIf="voiQueryDirective && (voiQueryDirective.features$ | async).length > 0" class="pe-all mat-elevation-z4">
       <mat-card-title>
         Volumes of interest
       </mat-card-title>
       <mat-card-subtitle class="overflow-hidden">
         <!-- TODO in future, perhaps encapsulate this as a component? seems like a nature fit in sapiView/space/boundingbox -->
-        <ng-template let-bbox [ngIf]="bbox.bbox$ | async | getProperty : 'bbox'" [ngIfElse]="bboxFallbackTmpl">
+        <ng-template let-bbox [ngIf]="boundingBoxDirective && (boundingBoxDirective.bbox$ | async | getProperty : 'bbox')" [ngIfElse]="bboxFallbackTmpl">
           Bounding box: {{ bbox[0] | numbers | json }} - {{ bbox[1] | numbers | json }} mm
         </ng-template>
         <ng-template #bboxFallbackTmpl>
@@ -1005,17 +1007,21 @@
 
       <mat-divider></mat-divider>
 
-      <div *ngFor="let feature of voiFeatures.features$ | async"
-        mat-ripple
-        (click)="showDataset(feature)"
-        class="sxplr-custom-cmp hoverable w-100 overflow-hidden text-overflow-ellipses">
-        {{ feature.metadata.fullName }}
-      </div>
+      <ng-template [ngIf]="voiQueryDirective">
+
+        <div *ngFor="let feature of voiQueryDirective.features$ | async"
+          mat-ripple
+          (click)="showDataset(feature)"
+          class="sxplr-custom-cmp hoverable w-100 overflow-hidden text-overflow-ellipses">
+          {{ feature.metadata.fullName }}
+        </div>
+      </ng-template>
     </mat-card>
   </ng-template>
 </ng-template>
 
 <div class="d-none"
+  *ngIf="VOI_QUERY_FLAG"
   sxplr-sapiviews-core-space-boundingbox
   [sxplr-sapiviews-core-space-boundingbox-atlas]="selectedAtlas$ | async"
   [sxplr-sapiviews-core-space-boundingbox-space]="templateSelected$ | async"