diff --git a/Dockerfile b/Dockerfile
index fbd5608c10bb90eb79f5b6f24781cf4e8907c2ef..b3f6d6ba67345ea1183ec8f9db906d7573e5b8c4 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -3,9 +3,6 @@ FROM node:14 as builder
 ARG BACKEND_URL
 ENV BACKEND_URL=${BACKEND_URL}
 
-ARG DATASET_PREVIEW_URL
-ENV DATASET_PREVIEW_URL=${DATASET_PREVIEW_URL:-https://hbp-kg-dataset-previewer.apps.hbp.eu/v2}
-
 ARG BS_REST_URL
 ENV BS_REST_URL=${BS_REST_URL:-https://siibra-api-stable.apps.hbp.eu/v1_0}
 
diff --git a/build_env.md b/build_env.md
index 1582bcdb0a487e3a91a88ecdcec45df445a687b9..1c29ea98614c3a40dbe91d7c620f9e6a5356b4e8 100644
--- a/build_env.md
+++ b/build_env.md
@@ -8,7 +8,6 @@ As interactive atlas viewer uses [webpack define plugin](https://webpack.js.org/
 | `PRODUCTION` | if the build is for production, toggles optimisations such as minification | `undefined` | true |
 | `BACKEND_URL` | backend that the viewer calls to fetch available template spaces, parcellations, plugins, datasets | `null` | https://interactive-viewer.apps.hbp.eu/ |
 | `BS_REST_URL` | [siibra-api](https://github.com/FZJ-INM1-BDA/siibra-api) used to fetch different resources | https://siibra-api-stable.apps.hbp.eu/v1_0 |
-| `DATASET_PREVIEW_URL` | dataset preview url used by component <https://github.com/fzj-inm1-bda/kg-dataset-previewer>. Useful for diagnosing issues with dataset previews.| https://hbp-kg-dataset-previewer.apps.hbp.eu/datasetPreview | http://localhost:1234/datasetPreview |
 | `MATOMO_URL` | base url for matomo analytics | `null` | https://example.com/matomo/ |
 | `MATOMO_ID` | application id for matomo analytics | `null` | 6 |
 | `STRICT_LOCAL` | hides **Explore** and **Download** buttons. Useful for offline demo's | `false` | `true` |
diff --git a/common/constants.js b/common/constants.js
index 1527bc74e86405a3f23353e182103e9a7da31882..0a930c3b857d9b4db64300653fb716b8e0eed533 100644
--- a/common/constants.js
+++ b/common/constants.js
@@ -27,6 +27,7 @@
     NO_BULK_DOWNLOAD: `No datasets pinned`,
 
     // overlay/layout specific
+    TOGGLE_DELINEATION: `Toggle delineation [q]`,
     SELECT_ATLAS: 'Atlas',
     CONTEXT_MENU: `Viewer context menu`,
     TOGGLE_FRONTAL_OCTANT: `Toggle perspective view frontal octant`,
@@ -84,6 +85,24 @@
   }
 
   exports.CONST = {
+    KG_TOS: `The interactive viewer queries HBP Knowledge Graph Data Platform ("KG") for published datasets.
+
+
+Access to the data and metadata provided through KG requires that you cite and acknowledge said data and metadata according to the Terms and Conditions of the Platform.
+
+
+Citation requirements are outlined <https://www.humanbrainproject.eu/en/explore-the-brain/search-terms-of-use#citations> .
+
+
+Acknowledgement requirements are outlined <https://www.humanbrainproject.eu/en/explore-the-brain/search-terms-of-use#acknowledgements>
+
+
+These outlines are based on the authoritative Terms and Conditions are found <https://www.humanbrainproject.eu/en/explore-the-brain/search-terms-of-use>
+
+
+If you do not accept the Terms & Conditions you are not permitted to access or use the KG to search for, to submit, to post, or to download any materials found there-in.
+`,
+
     LOADING_TXT: `Loading ...`,
 
     CANNOT_DECIPHER_HEMISPHERE: 'Cannot decipher region hemisphere.',
diff --git a/src/atlasComponents/connectivity/connectivityBrowser/connectivityBrowser.component.spec.ts b/src/atlasComponents/connectivity/connectivityBrowser/connectivityBrowser.component.spec.ts
deleted file mode 100644
index d9ebdd9a94f5727043f4676bb3a433e1418a543b..0000000000000000000000000000000000000000
--- a/src/atlasComponents/connectivity/connectivityBrowser/connectivityBrowser.component.spec.ts
+++ /dev/null
@@ -1,112 +0,0 @@
-import {ConnectivityBrowserComponent} from "./connectivityBrowser.component";
-import {async, ComponentFixture, TestBed} from "@angular/core/testing";
-import {Action} from "@ngrx/store";
-import {HttpClientModule} from "@angular/common/http";
-import {CUSTOM_ELEMENTS_SCHEMA, Directive, Input} from "@angular/core";
-import {provideMockActions} from "@ngrx/effects/testing";
-import {MockStore, provideMockStore} from "@ngrx/store/testing";
-import {Observable, of} from "rxjs";
-import { viewerStateOverwrittenColorMapSelector } from "src/services/state/viewerState/selectors";
-import { ngViewerSelectorClearViewEntries } from "src/services/state/ngViewerState.store.helper";
-import {BS_ENDPOINT} from "src/util/constants";
-
-/**
- * injecting databrowser module is bad idea
- * since it relies on its own selectors
- * since the only reason why data browser is imported is to use show dataset dialogue
- * just use a dummy directive
- */
-const MOCK_BS_ENDPOINT = `http://localhost:1234`
-
-@Directive({
-    selector: '[iav-dataset-show-dataset-dialog]'
-})
-
-class DummyDirective{
-    @Input('iav-dataset-show-dataset-dialog-name')
-    name: string
-    @Input('iav-dataset-show-dataset-dialog-description')
-    description: string
-    @Input('iav-dataset-show-dataset-dialog-kgid')
-    kgId: string
-    @Input('iav-dataset-show-dataset-dialog-kgschema')
-    kgSchema: string
-}
-
-describe('ConnectivityComponent', () => {
-
-    let component: ConnectivityBrowserComponent;
-    let fixture: ComponentFixture<ConnectivityBrowserComponent>;
-    const actions$: Observable<Action> = of({type: 'TEST'})
-
-    let datasetList = [
-        {
-            ['@id']: 'id1',
-            src_name: 'id1',
-            src_info: 'd1',
-            kgId: 'kgId1',
-            kgschema: 'kgschema1'
-        }, {
-            ['@id']: 'id2',
-            src_name: 'id2',
-            src_info: 'd2',
-            kgId: 'kgId2',
-            kgschema: 'kgschema2'
-        }
-    ]
-
-    beforeEach(async (() => {
-        TestBed.configureTestingModule({
-            imports: [
-                HttpClientModule,
-            ],
-            providers: [
-                provideMockActions(() => actions$),
-                provideMockStore(),
-                {
-                    provide: BS_ENDPOINT,
-                    useValue: MOCK_BS_ENDPOINT
-                }
-            ],
-            declarations: [
-                ConnectivityBrowserComponent,
-                DummyDirective,
-            ],
-            schemas: [
-                CUSTOM_ELEMENTS_SCHEMA,
-            ],
-        }).compileComponents()
-
-    }));
-
-    beforeEach(() => {
-        const mockStore = TestBed.inject(MockStore)
-        mockStore.overrideSelector(viewerStateOverwrittenColorMapSelector, null)
-        mockStore.overrideSelector(ngViewerSelectorClearViewEntries, [])
-    })
-
-    it('> component can be created', async () => {
-        fixture = TestBed.createComponent(ConnectivityBrowserComponent)
-        component = fixture.componentInstance
-        expect(component).toBeTruthy()
-    })
-
-    // ToDo create test for kgId and kgSchema after it will work while viewing dataset
-    it('> change dataset changes name and description', () => {
-        fixture = TestBed.createComponent(ConnectivityBrowserComponent)
-        component = fixture.componentInstance
-
-        component.datasetList = datasetList
-
-        component.changeDataset({value: 'id1'})
-
-        expect(component.selectedDataset).toEqual('id1')
-        expect(component.selectedDatasetDescription).toEqual('d1')
-
-        component.changeDataset({value: 'id2'})
-
-        expect(component.selectedDataset).toEqual('id2')
-        expect(component.selectedDatasetDescription).toEqual('d2')
-    })
-
-});
diff --git a/src/atlasComponents/connectivity/connectivityBrowser/connectivityBrowser.component.ts b/src/atlasComponents/connectivity/connectivityBrowser/connectivityBrowser.component.ts
deleted file mode 100644
index 0458757bbf0bfe396386003660dfe7de83cdc37d..0000000000000000000000000000000000000000
--- a/src/atlasComponents/connectivity/connectivityBrowser/connectivityBrowser.component.ts
+++ /dev/null
@@ -1,450 +0,0 @@
-import {
-  AfterViewInit, ChangeDetectorRef,
-  Component,
-  ElementRef,
-  EventEmitter,
-  OnDestroy,
-  Output,
-  ViewChild,
-  Input,
-  OnInit, Inject,
-} from "@angular/core";
-import {select, Store} from "@ngrx/store";
-import {fromEvent, Observable, Subscription, Subject, combineLatest, of} from "rxjs";
-import {distinctUntilChanged, filter, map, switchMap, switchMapTo} from "rxjs/operators";
-import { ngViewerSelectorClearViewEntries, ngViewerActionClearView } from "src/services/state/ngViewerState.store.helper";
-import {HttpClient} from "@angular/common/http";
-import {BS_ENDPOINT} from "src/util/constants";
-import {getIdFromKgIdObj} from "common/util";
-import {OVERWRITE_SHOW_DATASET_DIALOG_TOKEN} from "src/util/interfaces";
-import { SAPI, SapiRegionModel } from "src/atlasComponents/sapi";
-import { actions } from "src/state/atlasSelection";
-import { atlasAppearance, atlasSelection } from "src/state";
-
-
-const CONNECTIVITY_NAME_PLATE = 'Connectivity'
-
-@Component({
-  selector: 'connectivity-browser',
-  templateUrl: './connectivityBrowser.template.html',
-  providers: [
-    {
-      provide: OVERWRITE_SHOW_DATASET_DIALOG_TOKEN,
-      useValue: null
-    }
-  ]
-})
-export class ConnectivityBrowserComponent implements OnInit, AfterViewInit, OnDestroy {
-
-    private setColorMap$: Subject<boolean> = new Subject()
-
-    /**
-     * accordion expansion should only toggle the clearviewqueue state
-     * which should be the single source of truth
-     * setcolormaps$ is set by the presence/absence of clearviewqueue[CONNECTIVITY_NAME_PLATE]
-     */
-    private _isFirstUpdate = true
-
-    public connectivityUrl: string
-
-    private accordionIsExpanded = false
-
-    @Input()
-    set accordionExpanded(flag: boolean) {
-      /**
-         * ignore first update
-         */
-      if (this._isFirstUpdate) {
-        this._isFirstUpdate = false
-        return
-      }
-      this.accordionIsExpanded = flag
-      this.store$.dispatch(
-        ngViewerActionClearView({
-          payload: {
-            [CONNECTIVITY_NAME_PLATE]: flag && !this.noDataReceived
-          }
-        })
-      )
-      this.store$.dispatch({
-        type: 'SET_OVERWRITTEN_COLOR_MAP',
-        payload: flag? CONNECTIVITY_NAME_PLATE : false,
-      })
-
-      if (flag) {
-        this.addNewColorMap()
-      } else {
-        this.restoreDefaultColormap()
-      }
-    }
-
-    @Output()
-    connectivityDataReceived = new EventEmitter<any>()
-
-    @Output()
-    setOpenState: EventEmitter<boolean> = new EventEmitter()
-
-    @Output()
-    connectivityLoadUrl: EventEmitter<string> = new EventEmitter()
-
-    @Output() connectivityNumberReceived: EventEmitter<string> = new EventEmitter()
-
-    @Input()
-    set region(val) {
-      const newRegionName = val && val.name
-
-      if (!val) {
-        this.store$.dispatch({
-          type: 'SET_OVERWRITTEN_COLOR_MAP',
-          payload: false,
-        })
-        return
-      }
-
-      if (newRegionName !== this.regionName && this.defaultColorMap) {
-        this.restoreDefaultColormap()
-      }
-
-      if (val.status
-          && !val.name.includes('left hemisphere')
-          && !val.name.includes('right hemisphere')) {
-        this.regionHemisphere = val.status
-      }
-
-      this.regionName = newRegionName
-      this.regionId = val.id? val.id.kg? getIdFromKgIdObj(val.id.kg) : val.id : null
-      this.atlasId = val.context.atlas['@id']
-      this.parcellationId = val.context.parcellation['@id']
-
-      if(this.selectedDataset) {
-        this.setConnectivityUrl()
-        this.setProfileLoadUrl()
-      }
-      // TODO may not be necessary
-      this.changeDetectionRef.detectChanges()
-    }
-    public atlasId: any
-    public parcellationId: any
-    public regionId: string
-    public regionName: string
-    public regionHemisphere: string = null
-    public datasetList: any[] = []
-    public selectedDataset: any
-    public selectedDatasetName: any
-    public selectedDatasetDescription: string = ''
-    public selectedDatasetKgId: string = ''
-    public selectedDatasetKgSchema: string = ''
-    public connectedAreas = []
-
-    // TODO this may be incompatible
-    private selectedParcellationFlatRegions$ = this.store$.pipe(
-      select(atlasSelection.selectors.selectedATP),
-      switchMap(({ atlas, template, parcellation }) => this.sapi.getParcRegions(atlas["@id"], parcellation["@id"], template["@id"])) 
-    )
-    public overwrittenColorMap$: Observable<any>
-
-    private subscriptions: Subscription[] = []
-    public expandMenuIndex = -1
-    public allRegions = []
-    public defaultColorMap: Map<string, Map<number, { red: number, green: number, blue: number }>>
-
-    public noDataReceived = false
-
-    @ViewChild('connectivityComponent', {read: ElementRef}) public connectivityComponentElement: ElementRef<any>
-    @ViewChild('fullConnectivityGrid') public fullConnectivityGridElement: ElementRef<any>
-
-    constructor(
-        private store$: Store<any>,
-        private changeDetectionRef: ChangeDetectorRef,
-        private httpClient: HttpClient,
-        @Inject(BS_ENDPOINT) private siibraApiUrl: string,
-        private sapi: SAPI
-    ) {
-
-      this.overwrittenColorMap$ = this.store$.pipe(
-        select(atlasAppearance.selectors.getOverwrittenColormap),
-        distinctUntilChanged()
-      )
-    }
-
-    public loadUrl: string
-    public fullConnectivityLoadUrl: string
-
-    ngOnInit(): void {
-      this.setConnectivityUrl()
-
-      this.httpClient.get<[]>(this.connectivityUrl).subscribe(res => {
-        this.datasetList = res
-        this.selectedDataset = this.datasetList[0]?.['@id']
-        this.selectedDatasetName = this.datasetList[0]?.['src_name']
-        this.selectedDatasetDescription = this.datasetList[0]?.['src_info']
-        // this.selectedDatasetKgId = this.datasetList[0]?.kgId || null
-        // this.selectedDatasetKgSchema = this.datasetList[0]?.kgSchema || null
-
-        this.changeDataset()
-      })
-    }
-
-    public ngAfterViewInit(): void {
-      this.subscriptions.push(
-        this.store$.pipe(
-          select(atlasAppearance.selectors.getOverwrittenColormap),
-        ).subscribe(value => {
-          if (this.accordionIsExpanded) {
-            this.setColorMap$.next(!!value)
-          }
-        })
-      )
-
-      /**
-       * Listen to of clear view entries
-       * can come from within the component (when connectivity is not available for the dataset)
-       * --> do not collapse
-       * or outside (user clicks x in chip)
-       * --> collapse
-       */
-      this.subscriptions.push(
-        this.store$.pipe(
-          select(ngViewerSelectorClearViewEntries),
-          map(arr => arr.filter(v => v === CONNECTIVITY_NAME_PLATE)),
-          filter(arr => arr.length ===0),
-          distinctUntilChanged()
-        ).subscribe(() => {
-          if (!this.noDataReceived) {
-            this.setOpenState.emit(false)
-          }
-        })
-      )
-
-
-      this.subscriptions.push(this.overwrittenColorMap$.subscribe(ocm => {
-        if (this.accordionIsExpanded && !ocm) {
-          this.setOpenState.emit(false)
-        }
-      }))
-
-      this.subscriptions.push(
-        this.selectedParcellationFlatRegions$.subscribe(flattenedRegions => {
-          this.defaultColorMap = null
-          this.allRegions = flattenedRegions
-        }),
-      )
-
-      /**
-         * setting/restoring colormap
-         */
-      this.subscriptions.push(
-        combineLatest(
-          this.setColorMap$.pipe(
-            distinctUntilChanged()
-          ),
-          fromEvent(this.connectivityComponentElement?.nativeElement, 'connectivityDataReceived').pipe(
-            map((e: CustomEvent) => {
-              if (e.detail !== 'No data') {
-                this.connectivityNumberReceived.emit(e.detail.length)
-              }
-              return e.detail
-            })
-          )
-        ).subscribe(([flag, connectedAreas]) => {
-          if (connectedAreas === 'No data') {
-            this.noDataReceived = true
-            return this.clearViewer()
-          } else {
-            this.store$.dispatch(
-              ngViewerActionClearView({
-                payload: {
-                  [CONNECTIVITY_NAME_PLATE]: true
-                }
-              })
-            )
-            this.noDataReceived = false
-            this.connectivityNumberReceived.emit(connectedAreas.length)
-            this.connectedAreas = connectedAreas
-
-            if (flag) {
-              this.addNewColorMap()
-              this.store$.dispatch({
-                type: 'SET_OVERWRITTEN_COLOR_MAP',
-                payload: 'connectivity',
-              })
-            } else {
-              this.restoreDefaultColormap()
-
-              this.store$.dispatch({type: 'SET_OVERWRITTEN_COLOR_MAP', payload: null})
-
-            }
-          }
-        })
-      )
-
-      this.subscriptions.push(
-        fromEvent(this.connectivityComponentElement?.nativeElement, 'customToolEvent', {capture: true})
-          .subscribe((e: CustomEvent) => {
-            if (e.detail.name === 'export csv') {
-              // ToDo Fix in future to use component
-              const a = document.querySelector('hbp-connectivity-matrix-row');
-              (a as any).downloadCSV()
-            }
-          }),
-        fromEvent(this.connectivityComponentElement?.nativeElement, 'connectedRegionClicked', {capture: true})
-          .subscribe((e: CustomEvent) => {
-            this.navigateToRegion(e.detail.name)
-          }),
-      )
-    }
-
-    public ngOnDestroy(): void {
-      this.connectivityNumberReceived.emit(null)
-      this.store$.dispatch(
-        ngViewerActionClearView({
-          payload: {
-            [CONNECTIVITY_NAME_PLATE]: false
-          }
-        })
-      )
-      this.restoreDefaultColormap()
-      this.subscriptions.forEach(s => s.unsubscribe())
-    }
-
-    private setConnectivityUrl() {
-      this.connectivityUrl = `${this.siibraApiUrl}/atlases/${encodeURIComponent(this.atlasId)}/parcellations/${encodeURIComponent(this.parcellationId)}/regions/${encodeURIComponent(this.regionName)}/features/ConnectivityProfile`
-    }
-
-    private setProfileLoadUrl() {
-      const url = `${this.connectivityUrl}/${encodeURIComponent(this.selectedDataset)}`
-      this.connectivityLoadUrl.emit(url)
-      this.loadUrl = url
-    }
-
-    clearViewer() {
-      this.store$.dispatch(
-        ngViewerActionClearView({
-          payload: {
-            [CONNECTIVITY_NAME_PLATE]: false
-          }
-        })
-      )
-      this.connectedAreas = []
-      this.connectivityNumberReceived.emit('0')
-
-      return this.restoreDefaultColormap()
-    }
-
-    // ToDo Affect on component
-    changeDataset(event = null) {
-      if (event) {
-        this.selectedDataset = event.value
-        const foundDataset = this.datasetList.find(d => d['@id'] === this.selectedDataset)
-        this.selectedDatasetName = foundDataset?.['src_name']
-        this.selectedDatasetDescription = foundDataset?.['src_info']
-        // this.selectedDatasetKgId = foundDataset?.kgId || null
-        // this.selectedDatasetKgSchema = foundDataset?.kgSchema || null
-      }
-      if (this.datasetList.length && this.selectedDataset) {
-        this.setProfileLoadUrl()
-
-        this.fullConnectivityLoadUrl = `${this.siibraApiUrl}/atlases/${encodeURIComponent(this.atlasId)}/parcellations/${encodeURIComponent(this.parcellationId)}/features/ConnectivityMatrix/${encodeURIComponent(this.selectedDatasetName)}`
-      }
-    }
-
-    navigateToRegion(region: SapiRegionModel) {
-      this.store$.dispatch(
-        atlasSelection.actions.navigateToRegion({
-          region
-        })
-      )
-    }
-
-    selectRegion(region: SapiRegionModel) {
-      this.store$.dispatch(
-        actions.selectRegions({
-          regions: [ region ]
-        })
-      )
-    }
-
-    getRegionWithName(region) {
-      return this.allRegions.find(ar => {
-        if (this.regionHemisphere) {
-          let regionName = region
-          let regionStatus = null
-          if (regionName.includes('left hemisphere')) {
-            regionStatus = 'left hemisphere'
-            regionName = regionName.replace(' - left hemisphere', '');
-          } else if (regionName.includes('right hemisphere')) {
-            regionStatus = 'right hemisphere'
-            regionName = regionName.replace(' - right hemisphere', '');
-          }
-          return ar.name === regionName && ar.status === regionStatus
-        }
-
-        return ar.name === region
-      })
-    }
-
-    public restoreDefaultColormap() {
-      if (!this.defaultColorMap) return
-      getWindow().interactiveViewer.viewerHandle.applyLayersColourMap(this.defaultColorMap)
-    }
-
-    public addNewColorMap() {
-      if (!this.defaultColorMap) {
-        this.defaultColorMap = getWindow().interactiveViewer.viewerHandle.getLayersSegmentColourMap()
-      }
-
-      const existingMap: Map<string, Map<number, { red: number, green: number, blue: number }>> = (getWindow().interactiveViewer.viewerHandle.getLayersSegmentColourMap())
-      const colorMap = new Map(existingMap)
-
-      this.allRegions.forEach(r => {
-        if (r.ngId) {
-          colorMap.get(r.ngId).set(r.labelIndex, {red: 255, green: 255, blue: 255})
-        }
-      })
-
-      this.connectedAreas.forEach(area => {
-        const areaAsRegion = this.allRegions
-          .filter(r => {
-
-            if (this.regionHemisphere) {
-              let regionName = area.name
-              let regionStatus = null
-              if (regionName.includes('left hemisphere')) {
-                regionStatus = 'left hemisphere'
-                regionName = regionName.replace(' - left hemisphere', '');
-              } else if (regionName.includes('right hemisphere')) {
-                regionStatus = 'right hemisphere'
-                regionName = regionName.replace(' - right hemisphere', '');
-              }
-              return r.name === regionName && r.status === regionStatus
-            }
-
-            return r.name === area.name
-          })
-          .map(r => r)
-
-        if (areaAsRegion && areaAsRegion.length && areaAsRegion[0].ngId) {
-          colorMap.get(areaAsRegion[0].ngId).set(areaAsRegion[0].labelIndex, {
-            red: area.color.r,
-            green: area.color.g,
-            blue: area.color.b
-          })
-        }
-      })
-      getWindow().interactiveViewer.viewerHandle.applyLayersColourMap(colorMap)
-    }
-
-    exportConnectivityProfile() {
-      const a = document.querySelector('hbp-connectivity-matrix-row');
-      (a as any).downloadCSV()
-    }
-
-    public exportFullConnectivity() {
-      this.fullConnectivityGridElement?.nativeElement['downloadCSV']()
-    }
-
-}
-
-function getWindow(): any {
-  return window
-}
diff --git a/src/atlasComponents/connectivity/connectivityBrowser/connectivityBrowser.template.html b/src/atlasComponents/connectivity/connectivityBrowser/connectivityBrowser.template.html
deleted file mode 100644
index 646d4b0abfeadec3cdc5c5c9675f2fb07580318e..0000000000000000000000000000000000000000
--- a/src/atlasComponents/connectivity/connectivityBrowser/connectivityBrowser.template.html
+++ /dev/null
@@ -1,88 +0,0 @@
-<div class="w-100 h-100 d-block d-flex flex-column sxplr-pb-2">
-    <hbp-connectivity-matrix-row
-            (connectivityDataReceived)="connectivityDataReceived.emit($event)"
-            #connectivityComponent
-            *ngIf="regionName"
-            [region]="regionName + (regionHemisphere? ' - ' + regionHemisphere : '')"
-            theme="dark"
-            [loadurl]="loadUrl"
-            show-export="true"
-            show-source="false"
-            show-title="false"
-            show-toolbar="false"
-            show-description="false"
-            show-dataset-name="false"
-            custom-dataset-selector="true"
-            tools_showlog="true"
-            [tools_custom]='[{"name": "exportslot", "type": "slot"}]'
-            hide-export-view="true">
-
-        <div slot="dataset">
-            <div *ngIf="datasetList.length && selectedDataset"  class=" flex-grow-0 flex-shrink-0 d-flex flex-row flex-nowrap">
-                    <mat-form-field class="flex-grow-1 flex-shrink-1 w-0">
-                        <mat-label>
-                            Dataset
-                        </mat-label>
-
-                        <mat-select
-                                panelClass="no-max-width"
-                                [value]="selectedDataset"
-                                (selectionChange)="changeDataset($event)">
-                            <mat-option
-                                    *ngFor="let dataset of datasetList"
-                                    [value]="dataset['@id']">
-                                {{ dataset['src_name'] }}
-                            </mat-option>
-                        </mat-select>
-                    </mat-form-field>
-                <ng-container *ngIf="selectedDataset && (selectedDatasetDescription || selectedDatasetKgId)" >
-                    TODO please reimplmenent button to explore KG dataset
-                    <button class="flex-grow-0 flex-shrink-0"
-                            mat-icon-button
-                            (click)="exportFullConnectivity()"
-                            matTooltip="Export full connectivity profile">
-                        <i class="fas fa-download"></i>
-                    </button>
-                </ng-container>
-                </div>
-            <div>
-                Connectivity Profile
-            </div>
-        </div>
-
-        <div slot="connectedRegionMenu">
-            <div class="d-flex flex-column sxplr-p-0 m-0" *ngIf="expandMenuIndex >= 0">
-                <mat-card-subtitle class="sxplr-pt-2 sxplr-pr-2 sxplr-pl-2 sxplr-pb-0">
-                    <div class="d-flex justify-content-between align-items-center">
-                      {{connectedAreas[expandMenuIndex].name}}
-                      <small class="d-flex align-items-center">
-                          <button mat-icon-button matTooltip="Navigate"
-                                  (click)="navigateToRegion(connectedAreas[expandMenuIndex].name)">
-                              <i class="fas fa-map-marked-alt"></i>
-                          </button>
-                          <button mat-icon-button matTooltip="Explore"
-                                  (click)="selectRegion(getRegionWithName(connectedAreas[expandMenuIndex].name))">
-                              <i class="fas fa-search-location"></i>
-                          </button>
-                      </small>
-                    </div>
-                </mat-card-subtitle>
-                <mat-divider></mat-divider>
-            </div>
-        </div>
-        <div slot="exportslot">
-            <button mat-icon-button
-                    [disabled]="noDataReceived"
-                    (click)="exportConnectivityProfile()"
-                    matTooltip="Export connectivity profile">
-                <i class="fas fa-download mb-2"></i>
-            </button>
-        </div>
-    </hbp-connectivity-matrix-row>
-    <full-connectivity-grid #fullConnectivityGrid
-                            [loadurl]="fullConnectivityLoadUrl"
-                            [name]="selectedDataset"
-                            [description]="selectedDatasetDescription"
-                            only-export="true">
-    </full-connectivity-grid>
-</div>
diff --git a/src/atlasComponents/connectivity/hasConnectivity.directive.ts b/src/atlasComponents/connectivity/hasConnectivity.directive.ts
deleted file mode 100644
index 8879de8c093488b90acd5fb81d57820f341da36e..0000000000000000000000000000000000000000
--- a/src/atlasComponents/connectivity/hasConnectivity.directive.ts
+++ /dev/null
@@ -1,62 +0,0 @@
-import {Directive, Inject, Input, OnDestroy, OnInit} from "@angular/core";
-import {of, Subscription} from "rxjs";
-import {switchMap} from "rxjs/operators";
-import {BS_ENDPOINT} from "src/util/constants";
-import {HttpClient} from "@angular/common/http";
-
-@Directive({
-  selector: '[has-connectivity]',
-  exportAs: 'hasConnectivityDirective'
-})
-
-export class HasConnectivity implements OnInit, OnDestroy {
-
-    private subscriptions: Subscription[] = []
-
-    @Input() region: any
-
-    public hasConnectivity = false
-    public connectivityNumber = 0
-
-    constructor(@Inject(BS_ENDPOINT) private siibraApiUrl: string,
-                private httpClient: HttpClient) {}
-
-    ngOnInit() {
-      this.checkConnectivity(this.region[0])
-    }
-
-    checkConnectivity(region) {
-      if (!region.context) {
-        this.hasConnectivity = false
-        return
-      }
-      const {atlas, parcellation, template} = region.context
-      if (region.name) {
-        const connectivityUrl = `${this.siibraApiUrl}/atlases/${encodeURIComponent(atlas['@id'])}/parcellations/${encodeURIComponent(parcellation['@id'])}/regions/${encodeURIComponent(region.name)}/features/ConnectivityProfile`
-
-        this.subscriptions.push(
-          this.httpClient.get<[]>(connectivityUrl).pipe(switchMap((res: any[]) => {
-            if (res && res.length) {
-              this.hasConnectivity = true
-              const url = `${connectivityUrl}/${encodeURIComponent(res[0]['@id'])}`
-              return this.httpClient.get(url)
-            } else {
-              this.hasConnectivity = false
-              this.connectivityNumber = 0
-            }
-            return of(null)
-          })).subscribe(res => {
-
-            if (res && res['__profile']) {
-              this.connectivityNumber = res['__profile'].filter(p => p > 0).length
-            }
-          })
-        )
-      }
-    }
-
-    ngOnDestroy(){
-      while (this.subscriptions.length > 0) this.subscriptions.pop().unsubscribe()
-    }
-
-}
diff --git a/src/atlasComponents/connectivity/index.ts b/src/atlasComponents/connectivity/index.ts
deleted file mode 100644
index c9a2e808fc6290283e77ea4bccff8f199eea3ca0..0000000000000000000000000000000000000000
--- a/src/atlasComponents/connectivity/index.ts
+++ /dev/null
@@ -1,2 +0,0 @@
-export { ConnectivityBrowserComponent } from "./connectivityBrowser/connectivityBrowser.component";
-export { AtlasCmptConnModule } from "./module";
\ No newline at end of file
diff --git a/src/atlasComponents/connectivity/module.ts b/src/atlasComponents/connectivity/module.ts
deleted file mode 100644
index c9231d4605589eeb8a7e5f2dd1f66a4a2b34089f..0000000000000000000000000000000000000000
--- a/src/atlasComponents/connectivity/module.ts
+++ /dev/null
@@ -1,25 +0,0 @@
-import { CommonModule } from "@angular/common";
-import { CUSTOM_ELEMENTS_SCHEMA, NgModule } from "@angular/core";
-import { AngularMaterialModule } from "src/sharedModules";
-import { ConnectivityBrowserComponent } from "./connectivityBrowser/connectivityBrowser.component";
-import {HasConnectivity} from "src/atlasComponents/connectivity/hasConnectivity.directive";
-
-@NgModule({
-  imports: [
-    CommonModule,
-    AngularMaterialModule
-  ],
-  declarations: [
-    ConnectivityBrowserComponent,
-    HasConnectivity
-  ],
-  exports: [
-    ConnectivityBrowserComponent,
-    HasConnectivity
-  ],
-  schemas: [
-    CUSTOM_ELEMENTS_SCHEMA,
-  ],
-})
-
-export class AtlasCmptConnModule{}
diff --git a/src/atlasComponents/sapi/core/sapiRegion.ts b/src/atlasComponents/sapi/core/sapiRegion.ts
index b353aed0283c41b5f983adcb01fed1ab0a1c131b..d8b1d2306ae27b9215fd7ca9ffa0f43c9208e0a3 100644
--- a/src/atlasComponents/sapi/core/sapiRegion.ts
+++ b/src/atlasComponents/sapi/core/sapiRegion.ts
@@ -1,19 +1,33 @@
 import { SAPI } from "..";
-import { SapiRegionalFeatureModel } from "../type";
+import { SapiRegionalFeatureModel, SapiRegionMapInfoModel, SapiRegionModel } from "../type";
+import { strToRgb, hexToRgb } from 'common/util'
 
 export class SAPIRegion{
+
+  static GetDisplayColor(region: SapiRegionModel){
+    if (!region) {
+      throw new Error(`region must be provided!`)
+    }
+    if (region.hasAnnotation?.displayColor) {
+      return hexToRgb(region.hasAnnotation.displayColor)
+    }
+    return strToRgb(JSON.stringify(region))
+  }
+
+  private prefix: string
+
   constructor(
     private sapi: SAPI,
     public atlasId: string,
     public parcId: string,
     public id: string,
   ){
-
+    this.prefix = `${this.sapi.bsEndpoint}/atlases/${encodeURIComponent(this.atlasId)}/parcellations/${encodeURIComponent(this.parcId)}/regions/${encodeURIComponent(this.id)}`
   }
 
   getFeatures(spaceId: string): Promise<SapiRegionalFeatureModel[]> {
     return this.sapi.http.get<SapiRegionalFeatureModel[]>(
-      `${this.sapi.bsEndpoint}/atlases/${encodeURIComponent(this.atlasId)}/parcellations/${encodeURIComponent(this.parcId)}/regions/${encodeURIComponent(this.id)}/features`,
+      `${this.prefix}/features`,
       {
         params: {
           space_id: spaceId
@@ -24,7 +38,33 @@ export class SAPIRegion{
 
   getFeatureInstance(instanceId: string, spaceId: string = null): Promise<SapiRegionalFeatureModel> {
     return this.sapi.http.get<SapiRegionalFeatureModel>(
-      `${this.sapi.bsEndpoint}/atlases/${encodeURIComponent(this.atlasId)}/parcellations/${encodeURIComponent(this.parcId)}/regions/${encodeURIComponent(this.id)}/features/${encodeURIComponent(instanceId)}`,
+      `${this.prefix}/features/${encodeURIComponent(instanceId)}`,
+      {
+        params: {
+          space_id: spaceId
+        }
+      }
+    ).toPromise()
+  }
+
+  getMapInfo(spaceId: string): Promise<SapiRegionMapInfoModel> {
+    return this.sapi.http.get<SapiRegionMapInfoModel>(
+      `${this.prefix}/regional_map/info`,
+      {
+        params: {
+          space_id: spaceId
+        }
+      }
+    ).toPromise()
+  }
+
+  getMapUrl(spaceId: string): string {
+    return `${this.prefix}/regional_map/map?space_id=${encodeURI(spaceId)}`
+  }
+
+  getDetail(spaceId: string): Promise<SapiRegionModel> {
+    return this.sapi.http.get<SapiRegionModel>(
+      `${this.prefix}/${this.id}`,
       {
         params: {
           space_id: spaceId
diff --git a/src/atlasComponents/sapi/stories.base.ts b/src/atlasComponents/sapi/stories.base.ts
index e3cd6f322117fed8ff26ec9c88227fee77b28ae7..86dddb2f0954bdc027087e35590a8c3452b9daaa 100644
--- a/src/atlasComponents/sapi/stories.base.ts
+++ b/src/atlasComponents/sapi/stories.base.ts
@@ -68,6 +68,9 @@ export async function getAtlas(id: string): Promise<SapiAtlasModel>{
 export async function getParc(atlasId: string, id: string): Promise<SapiParcellationModel>{
   return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId}/parcellations/${id}`)).json()
 }
+export async function getParcRegions(atlasId: string, id: string, spaceId: string): Promise<SapiRegionModel[]>{
+  return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId}/parcellations/${id}/regions?space_id=${encodeURIComponent(spaceId)}`)).json()
+}
 
 export async function getSpace(atlasId: string, id: string): Promise<SapiSpaceModel> {
   return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId}/spaces/${id}`)).json()
@@ -85,6 +88,10 @@ export async function getJba29(): Promise<SapiParcellationModel> {
   return await getParc(atlasId.human, parcId.human.jba29)
 }
 
+export async function getJba29Regions(): Promise<SapiRegionModel[]> {
+  return await getParcRegions(atlasId.human, parcId.human.jba29, spaceId.human.mni152)
+}
+
 export async function getHoc1Left(spaceId=null): Promise<SapiRegionModel> {
   if (!spaceId) {
     return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/hoc1%20left`)).json()
@@ -92,6 +99,13 @@ export async function getHoc1Left(spaceId=null): Promise<SapiRegionModel> {
   return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/hoc1%20left?space_id=${encodeURIComponent(spaceId)}`)).json()
 }
 
+export async function get44Left(spaceId=null): Promise<SapiRegionModel> {
+  if (!spaceId) {
+    return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/area%2044%20left`)).json()
+  }
+  return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/area%2044%20left?space_id=${encodeURIComponent(spaceId)}`)).json()
+}
+
 export async function getHoc1Features(): Promise<SapiRegionalFeatureModel[]> {
   return await (await fetch(`${SAPI.bsEndpoint}/atlases/${atlasId.human}/parcellations/${parcId.human.jba29}/regions/hoc1%20left/features`)).json()
 }
diff --git a/src/atlasComponents/sapi/type.ts b/src/atlasComponents/sapi/type.ts
index 8e645b34e2133b1973b4cea33663614d13d9b7c5..9de24016f86a548458f9fccf0c088b0bf6b7b529 100644
--- a/src/atlasComponents/sapi/type.ts
+++ b/src/atlasComponents/sapi/type.ts
@@ -15,6 +15,7 @@ export type SapiAtlasModel = components["schemas"]["SapiAtlasModel"]
 export type SapiSpaceModel = components["schemas"]["SapiSpaceModel"]
 export type SapiParcellationModel = components["schemas"]["SapiParcellationModel"]
 export type SapiRegionModel = components["schemas"]["siibra__openminds__SANDS__v3__atlas__parcellationEntityVersion__Model"]
+export type SapiRegionMapInfoModel = components["schemas"]["NiiMetadataModel"]
 
 export type SapiSpatialFeatureModel = components["schemas"]["VOIDataModel"]
 export type SapiVOIDataResponse = components["schemas"]["VOIDataModel"]
diff --git a/src/atlasComponents/sapiViews/core/atlas/dropdownAtlasSelector/dropdownAtlasSelector.component.ts b/src/atlasComponents/sapiViews/core/atlas/dropdownAtlasSelector/dropdownAtlasSelector.component.ts
index 0da41ae9de3a2d0a7274ab0849f604d26f261e9e..815a4d45ed29cad974c1465e8a8cca5a0af6bcee 100644
--- a/src/atlasComponents/sapiViews/core/atlas/dropdownAtlasSelector/dropdownAtlasSelector.component.ts
+++ b/src/atlasComponents/sapiViews/core/atlas/dropdownAtlasSelector/dropdownAtlasSelector.component.ts
@@ -1,8 +1,8 @@
-import { Component } from "@angular/core";
+import { Component, OnDestroy } from "@angular/core";
 import { Store, select } from "@ngrx/store";
-import { Observable } from "rxjs";
+import { Observable, Subscription } from "rxjs";
 import { ARIA_LABELS } from 'common/constants'
-import { atlasSelection } from "src/state"
+import { atlasSelection, generalActions } from "src/state"
 import { SAPI, SapiAtlasModel } from "src/atlasComponents/sapi";
 
 @Component({
@@ -13,8 +13,10 @@ import { SAPI, SapiAtlasModel } from "src/atlasComponents/sapi";
   ]
 })
 
-export class SapiViewsCoreAtlasAtlasDropdownSelector{
+export class SapiViewsCoreAtlasAtlasDropdownSelector implements OnDestroy{
 
+  private subs: Subscription[] = []
+  private fetchedAtlases: SapiAtlasModel[] = []
   public fetchedAtlases$: Observable<SapiAtlasModel[]> = this.sapi.atlases$
   public selectedAtlas$: Observable<SapiAtlasModel> = this.store$.pipe(
     select(atlasSelection.selectors.selectedAtlas)
@@ -26,14 +28,29 @@ export class SapiViewsCoreAtlasAtlasDropdownSelector{
     private store$: Store<any>,
     private sapi: SAPI,
   ){
+    this.subs.push(
+      this.fetchedAtlases$.subscribe(val => this.fetchedAtlases = val)
+    )
+  }
+
+  ngOnDestroy(): void {
+    this.subs.pop().unsubscribe()
   }
 
   handleChangeAtlas({ value }) {
-    this.store$.dispatch(
-      atlasSelection.actions.selectATPById({
-        atlasId: value
-      })
-    )
+    const found = this.fetchedAtlases.find(atlas => atlas["@id"] === value)
+    if (found) {
+      this.store$.dispatch(
+        atlasSelection.actions.selectAtlas({
+          atlas: found
+        })
+      )
+    } else {
+      this.store$.dispatch(
+        generalActions.generalActionError({
+          message: `Atlas with id ${value} not found.`
+        })
+      )
+    }
   }
 }
-
diff --git a/src/atlasComponents/sapiViews/core/atlas/tmplParcSelector/tmplParcSelector.component.ts b/src/atlasComponents/sapiViews/core/atlas/tmplParcSelector/tmplParcSelector.component.ts
index d3cbe274f4ba2194ebfacfc40837eed3c4eca20e..666ef5075c26f9d9fea5fa2f7ea6cde4560d9dac 100644
--- a/src/atlasComponents/sapiViews/core/atlas/tmplParcSelector/tmplParcSelector.component.ts
+++ b/src/atlasComponents/sapiViews/core/atlas/tmplParcSelector/tmplParcSelector.component.ts
@@ -62,10 +62,6 @@ export class SapiViewsCoreAtlasAtlasTmplParcSelector {
 
   public selectedTemplate$ = this.store$.pipe(
     select(atlasSelection.selectors.selectedTemplate),
-    withLatestFrom(this.availableTemplates$),
-    map(([selectedTmpl, fullInfoTemplates]) => {
-      return fullInfoTemplates.find(t => t['@id'] === selectedTmpl['@id'])
-    })
   )
 
   public selectedParcellation$ = this.store$.pipe(
@@ -107,6 +103,14 @@ export class SapiViewsCoreAtlasAtlasTmplParcSelector {
     this.selectorExpanded = !this.selectorExpanded
   }
 
+  closeSelector(){
+    this.selectorExpanded = false
+  }
+  
+  openSelector() {
+    this.selectorExpanded = true
+  }
+
   selectTemplate(tmpl: SapiSpaceModel) {
     this.showOverlayIntent$.next(true)
     
diff --git a/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.template.html b/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.template.html
index e5fba069a65e277955b1ac34bb736005b6aa9c96..68ce4f9a8540b0c1154408328260ed2e00a07b5a 100644
--- a/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.template.html
+++ b/src/atlasComponents/sapiViews/core/datasets/dataset/dataset.template.html
@@ -1,11 +1,22 @@
+<ng-template #headerTmpl>
+  <ng-content select="[header]"></ng-content>
+</ng-template>
+
 <mat-card *ngIf="!dataset">
-  Dataset not specified.
+
+  <ng-template [ngTemplateOutlet]="headerTmpl"></ng-template>
+  <span>
+    Dataset not specified.
+  </span>
 </mat-card>
 
 <mat-card *ngIf="dataset"
-  class="mat-elevation-z4 sxplr-z-index-4">
+  class="mat-elevation-z4 sxplr-z-4">
   <mat-card-title>
-    {{ dataset.metadata.fullName }}
+    <ng-template [ngTemplateOutlet]="headerTmpl"></ng-template>
+    <span>
+      {{ dataset.metadata.fullName }}
+    </span>
   </mat-card-title>
 
   <mat-card-subtitle class="sxplr-d-inline-flex sxplr-align-items-stretch">
@@ -21,7 +32,7 @@
   </mat-card-subtitle>
 </mat-card>
 
-<mat-card *ngIf="dataset" class="sxplr-z-index-0">
+<mat-card *ngIf="dataset" class="sxplr-z-0">
   <mat-card-content>
     <markdown-dom class="sxplr-muted" [markdown]="dataset?.metadata?.description">
     </markdown-dom>
diff --git a/src/atlasComponents/sapiViews/core/parcellation/filterUnsupportedParc.pipe.ts b/src/atlasComponents/sapiViews/core/parcellation/filterUnsupportedParc.pipe.ts
index 5d2412cdd76b13e568166f7c68ae0ecfc73b8b1e..3a9d1a30ec5a9bc9ed281cca3e44051cd7b5b163 100644
--- a/src/atlasComponents/sapiViews/core/parcellation/filterUnsupportedParc.pipe.ts
+++ b/src/atlasComponents/sapiViews/core/parcellation/filterUnsupportedParc.pipe.ts
@@ -24,7 +24,13 @@ export class FilterUnsupportedParcPipe implements PipeTransform{
       if (p instanceof GroupedParcellation) {
         return hideGroup.indexOf(p.name) < 0
       }
-      return unsupportedIds.indexOf(p["@id"]) < 0
+      if (unsupportedIds.includes(p["@id"])) {
+        return false
+      }
+      if (p.version) {
+        return !p.version.deprecated
+      }
+      return true
     })
   }
 }
diff --git a/src/atlasComponents/sapiViews/core/parcellation/parcellationVersion.pipe.ts b/src/atlasComponents/sapiViews/core/parcellation/parcellationVersion.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..506acc493479285eb4271aee38f5cd1798174fda
--- /dev/null
+++ b/src/atlasComponents/sapiViews/core/parcellation/parcellationVersion.pipe.ts
@@ -0,0 +1,84 @@
+import { Pipe, PipeTransform } from "@angular/core";
+import { SapiParcellationModel } from "src/atlasComponents/sapi/type";
+
+export function getTraverseFunctions(parcellations: SapiParcellationModel[]) {
+
+  const getTraverse = (key: 'prev' | 'next') => (parc: SapiParcellationModel) => {
+    if (!parc.version) {
+      throw new Error(`parcellation ${parc.name} does not have version defined!`)
+    }
+    if (!parc.version[key]) {
+      return null
+    }
+    const found = parcellations.find(p => p["@id"] === parc.version[key]["@id"])
+    if (!found) {
+      throw new Error(`parcellation ${parc.name} references ${parc.version[key]['@id']} as ${key} version, but it cannot be found.`)
+    }
+    return found
+  }
+  
+  const findNewer = getTraverse('next')
+  const findOlder = getTraverse('prev')
+
+  const getFindMostFn = (findNewest) => {
+    const useFn = findNewest
+      ? findNewer
+      : findOlder
+    return () => {
+      let cursor = parcellations[0]
+      let returnParc: SapiParcellationModel
+      while (cursor) {
+        returnParc = cursor
+        cursor = useFn(cursor)
+      }
+      return returnParc
+    }
+  }
+
+  return {
+    findNewer,
+    findOlder,
+    findNewest: getFindMostFn(true),
+    findOldest: getFindMostFn(false)
+  }
+  
+}
+
+
+@Pipe({
+  name: 'orderParcellationByVersion',
+  pure: true
+})
+
+export class OrderParcellationByVersionPipe implements PipeTransform{
+  public transform(parcellations: SapiParcellationModel[], newestFirst: boolean = true, index: number = 0) {
+    const {
+      findNewer,
+      findOlder
+    } = getTraverseFunctions(parcellations)
+
+    const findMostFn = newestFirst ? findNewer : findOlder
+    const tranverseFn = newestFirst ? findOlder : findNewer
+
+    const mostParc = (() => {
+      let cursor = parcellations[0]
+      let returnParc: SapiParcellationModel
+      while (cursor) {
+        returnParc = cursor
+        cursor = findMostFn(cursor)
+      }
+      return returnParc
+    })()
+
+    let idx = 0
+    let cursor = mostParc
+    while (idx < index) {
+      cursor = tranverseFn(cursor)
+      if (!cursor) {
+        throw new Error(`index out of bound`)
+      }
+      idx ++
+    }
+    return cursor
+  }
+}
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 e28c7bec05cde38553e4bc7417dc7418155327bc..f56ae3fdb4de939dad8b5ac6285f10a81e7cda8b 100644
--- a/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.component.ts
+++ b/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.component.ts
@@ -2,6 +2,8 @@ import { Component, EventEmitter, Input, OnChanges, Output, SimpleChanges } from
 import { Observable } from "rxjs";
 import { SapiParcellationModel } from "src/atlasComponents/sapi/type";
 import { ParcellationVisibilityService } from "../parcellationVis.service";
+import { ARIA_LABELS } from "common/constants"
+import { getTraverseFunctions } from "../parcellationVersion.pipe";
 
 @Component({
   selector: `sxplr-sapiviews-core-parcellation-smartchip`,
@@ -13,6 +15,8 @@ import { ParcellationVisibilityService } from "../parcellationVis.service";
 
 export class SapiViewsCoreParcellationParcellationSmartChip implements OnChanges{
 
+  public ARIA_LABELS = ARIA_LABELS
+
   @Input('sxplr-sapiviews-core-parcellation-smartchip-parcellation')
   parcellation: SapiParcellationModel
 
@@ -47,34 +51,13 @@ export class SapiViewsCoreParcellationParcellationSmartChip implements OnChanges
     }
 
     this.otherVersions = []
-    const getTraverse = (key: 'prev' | 'next') => (parc: SapiParcellationModel) => {
-      if (!parc.version) {
-        throw new Error(`parcellation ${parc.name} does not have version defined!`)
-      }
-      if (!parc.version[key]) {
-        return null
-      }
-      const found = this.parcellations.find(p => p["@id"] === parc.version[key]["@id"])
-      if (!found) {
-        throw new Error(`parcellation ${parc.name} references ${parc.version[key]['@id']} as ${key} version, but it cannot be found.`)
-      }
-      return found
-    }
 
-    const findNewer = getTraverse('next')
-    const findOlder = getTraverse('prev')
+    const {
+      findNewest,
+      findOlder
+    } = getTraverseFunctions(this.parcellations)
 
-    const newest = (() => {
-      let cursor = this.parcellation
-      let newest: SapiParcellationModel
-      while (cursor) {
-        newest = cursor
-        cursor = findNewer(cursor)
-      }
-      return newest
-    })()
-
-    let cursor: SapiParcellationModel = newest
+    let cursor: SapiParcellationModel = findNewest()
     while (cursor) {
       this.otherVersions.push(cursor)
       cursor = findOlder(cursor)
@@ -93,7 +76,6 @@ export class SapiViewsCoreParcellationParcellationSmartChip implements OnChanges
 
   selectParcellation(parc: SapiParcellationModel){
     if (parc === this.parcellation) return
-
-    console.log('select parcellation', parc)
+    this.onSelectParcellation.emit(parc)
   }
 }
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 0473218f9c475ea3b61c25bab951f88645e2f546..88cde95071e545574c543ef36c7cbfbe6223ebb1 100644
--- a/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.template.html
+++ b/src/atlasComponents/sapiViews/core/parcellation/smartChip/parcellation.smartChip.template.html
@@ -1,12 +1,12 @@
 <mat-menu #otherParcMenu="matMenu"
   [hasBackdrop]="false"
-  class="sxplr-bg-none sxplr-of-x-hidden sxplr-box-shadow-none overwrite-max-width-80vw">
+  class="sxplr-bg-none sxplr-of-x-hidden sxplr-box-shadow-none sxplr-mxw-80vw">
   <div (iav-outsideClick)="menuTrigger.closeMenu()">
 
     <sxplr-sapiviews-core-parcellation-chip *ngFor="let parc of otherVersions"
       [sxplr-sapiviews-core-parcellation-chip-parcellation]="parc"
       [sxplr-sapiviews-core-parcellation-chip-color]="parcellation === parc ? 'primary' : 'default'"
-      (click)="selectParcellation(parc)">
+      (sxplr-sapiviews-core-parcellation-chip-onclick)="selectParcellation(parc)">
 
     </sxplr-sapiviews-core-parcellation-chip>
   </div>
@@ -28,7 +28,10 @@
   <div prefix class="sxplr-scale-70">
     <button mat-mini-fab
       [color]="(parcellationVisibility$ | async) ? 'primary' : 'default'"
+      [matTooltip]="ARIA_LABELS.TOGGLE_DELINEATION"
       iav-stop="mousedown click"
+      [iav-key-listener]="[{'type': 'keydown', 'key': 'q', 'capture': true, 'target': 'document' }]"
+      (iav-key-event)="toggleParcellationVisibility()"
       (click)="toggleParcellationVisibility()">
       <i class="fas"
         [ngClass]="(parcellationVisibility$ | async) ? 'fa-eye': 'fa-eye-slash'">
diff --git a/src/atlasComponents/sapiViews/core/region/module.ts b/src/atlasComponents/sapiViews/core/region/module.ts
index 511a1fcb8c770c56dbd9e64de315c7c09b9d38c4..cdafe1bcd9779d40119f938b3c221c26865b24ae 100644
--- a/src/atlasComponents/sapiViews/core/region/module.ts
+++ b/src/atlasComponents/sapiViews/core/region/module.ts
@@ -1,8 +1,10 @@
 import { CommonModule } from "@angular/common";
 import { NgModule } from "@angular/core";
+import { SpinnerModule } from "src/components/spinner";
 import { AngularMaterialModule } from "src/sharedModules";
 import { SapiViewsFeaturesModule } from "../../features";
 import { SapiViewsUtilModule } from "../../util/module";
+import { SapiViewsCoreRegionRegionChip } from "./region/chip/region.chip.component";
 import { SapiViewsCoreRegionRegionListItem } from "./region/listItem/region.listItem.component";
 import { SapiViewsCoreRegionRegionBase } from "./region/region.base.directive";
 import { SapiViewsCoreRegionRegionalFeatureDirective } from "./region/region.features.directive";
@@ -13,17 +15,20 @@ import { SapiViewsCoreRegionRegionRich } from "./region/rich/region.rich.compone
     CommonModule,
     AngularMaterialModule,
     SapiViewsUtilModule,
-    SapiViewsFeaturesModule
+    SapiViewsFeaturesModule,
+    SpinnerModule,
   ],
   declarations: [
     SapiViewsCoreRegionRegionListItem,
     SapiViewsCoreRegionRegionRich,
+    SapiViewsCoreRegionRegionChip,
     SapiViewsCoreRegionRegionBase,
     SapiViewsCoreRegionRegionalFeatureDirective,
   ],
   exports: [
     SapiViewsCoreRegionRegionListItem,
     SapiViewsCoreRegionRegionRich,
+    SapiViewsCoreRegionRegionChip,
     SapiViewsCoreRegionRegionBase,
     SapiViewsCoreRegionRegionalFeatureDirective,
   ]
diff --git a/src/atlasComponents/sapiViews/core/region/region/chip/region.chip.component.ts b/src/atlasComponents/sapiViews/core/region/region/chip/region.chip.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1852f3e602a60d3739dc5bffa89a190b64fb33f7
--- /dev/null
+++ b/src/atlasComponents/sapiViews/core/region/region/chip/region.chip.component.ts
@@ -0,0 +1,20 @@
+import { Component, EventEmitter, Output } from "@angular/core";
+import { SapiViewsCoreRegionRegionBase } from "../region.base.directive";
+
+@Component({
+  selector: `sxplr-sapiviews-core-region-region-chip`,
+  templateUrl: `./region.chip.template.html`,
+  styleUrls: [
+    `./region.chip.style.css`
+  ]
+})
+
+export class SapiViewsCoreRegionRegionChip extends SapiViewsCoreRegionRegionBase {
+  shouldFetchDetail = true
+  @Output('sxplr-sapiviews-core-region-region-chip-clicked')
+  clickEmitter = new EventEmitter<MouseEvent>()
+
+  onClick(event: MouseEvent){
+    this.clickEmitter.emit(event)
+  }
+}
diff --git a/src/atlasComponents/sapiViews/core/region/region/chip/region.chip.stories.ts b/src/atlasComponents/sapiViews/core/region/region/chip/region.chip.stories.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1fc06697565f11e974950f757052ead015238ed6
--- /dev/null
+++ b/src/atlasComponents/sapiViews/core/region/region/chip/region.chip.stories.ts
@@ -0,0 +1,134 @@
+import { CommonModule } from "@angular/common"
+import { HttpClientModule } from "@angular/common/http"
+import { Meta, moduleMetadata, Story } from "@storybook/angular"
+import { SAPI, SapiParcellationModel } from "src/atlasComponents/sapi"
+import { atlasId, getAtlas, provideDarkTheme, getParc, getHumanAtlas, getJba29, getMni152, getHoc1Left, get44Left } from "src/atlasComponents/sapi/stories.base"
+import { AngularMaterialModule } from "src/sharedModules"
+import { SapiViewsCoreRegionModule } from "../../module"
+import { SapiViewsCoreRegionRegionChip } from "./region.chip.component"
+
+
+export default {
+  component: SapiViewsCoreRegionRegionChip,
+  decorators: [
+    moduleMetadata({
+      imports: [
+        CommonModule,
+        HttpClientModule,
+        SapiViewsCoreRegionModule,
+        AngularMaterialModule,
+      ],
+      providers: [
+        SAPI,
+        ...provideDarkTheme,
+      ],
+      declarations: []
+    })
+  ],
+} as Meta
+
+const Template: Story<SapiViewsCoreRegionRegionChip> = (args: SapiViewsCoreRegionRegionChip, { loaded, parameters }) => {
+  const { 
+    atlas,
+    parcellation,
+    template,
+    region,
+  } = loaded
+  const {
+    contentProjection
+  } = parameters
+
+  return ({
+    props: {
+      atlas,
+      parcellation,
+      template,
+      region,
+    },
+    template: `
+    <sxplr-sapiviews-core-region-region-chip>
+      ${contentProjection || ''}
+    </sxplr-sapiviews-core-region-region-chip>
+    `
+  })
+}
+Template.loaders = []
+
+const getContentProjection = ({ prefix = null, suffix = null }) => {
+  let returnVal = ``
+  if (prefix) {
+    returnVal += `<div prefix>${prefix}</div>`
+  }
+  if (suffix) {
+    returnVal += `<div suffix>${suffix}</div>`
+  }
+  return returnVal
+}
+
+export const Default = Template.bind({})
+Default.loaders = [
+  async () => {
+    
+    const atlas = await getHumanAtlas()
+    const parcellation = await getJba29()
+    const template = await getMni152()
+    const region = await getHoc1Left()
+
+    return {
+      atlas,
+      parcellation,
+      template,
+      region,
+    }
+  }
+]
+
+export const Dark = Template.bind({})
+Dark.loaders = [
+  async () => {
+    
+    const atlas = await getHumanAtlas()
+    const parcellation = await getJba29()
+    const template = await getMni152()
+    const region = await get44Left()
+
+    return {
+      atlas,
+      parcellation,
+      template,
+      region,
+    }
+  }
+]
+
+export const Prefix = Template.bind({})
+Prefix.loaders = [
+  ...Default.loaders
+]
+Prefix.parameters = {
+  contentProjection: getContentProjection({
+    prefix: `PREFIX`,
+  })
+}
+
+export const Suffix = Template.bind({})
+Suffix.loaders = [
+  ...Default.loaders
+]
+Suffix.parameters = {
+  contentProjection: getContentProjection({
+    suffix: `SUFFIX`,
+  })
+}
+
+
+export const PrefixSuffix = Template.bind({})
+PrefixSuffix.loaders = [
+  ...Default.loaders
+]
+PrefixSuffix.parameters = {
+  contentProjection: getContentProjection({
+    prefix: `PREFIX`,
+    suffix: `SUFFIX`,
+  })
+}
diff --git a/src/services/state/uiState/selectors.spec.ts b/src/atlasComponents/sapiViews/core/region/region/chip/region.chip.style.css
similarity index 100%
rename from src/services/state/uiState/selectors.spec.ts
rename to src/atlasComponents/sapiViews/core/region/region/chip/region.chip.style.css
diff --git a/src/atlasComponents/sapiViews/core/region/region/chip/region.chip.template.html b/src/atlasComponents/sapiViews/core/region/region/chip/region.chip.template.html
new file mode 100644
index 0000000000000000000000000000000000000000..03db372cf5c31f39529a87d07bf1efa8c4bdb9c6
--- /dev/null
+++ b/src/atlasComponents/sapiViews/core/region/region/chip/region.chip.template.html
@@ -0,0 +1,35 @@
+<ng-template #prefixTmpl>
+  <ng-content select="[prefix]"></ng-content>
+</ng-template>
+
+<ng-template #suffixTmpl>
+  <ng-content select="[suffix]"></ng-content>
+</ng-template>
+
+<div *ngIf="!region">
+  <div class="sxplr-d-inline-block">
+    <ng-template [ngTemplateOutlet]="prefixTmpl"></ng-template>
+  </div>
+  <spinner-cmp class="sxplr-d-inline-block"></spinner-cmp>
+  <div class="sxplr-d-inline-block">
+    <ng-template [ngTemplateOutlet]="suffixTmpl"></ng-template>
+  </div>
+</div>
+
+<mat-chip-list *ngIf="region"
+  [ngClass]="{
+    'darktheme': regionDarkmode,
+    'lighttheme': !regionDarkmode
+  }">
+  <mat-chip
+    (click)="onClick($event)"
+    class="iv-custom-comp text"
+    [style.backgroundColor]="regionRgbString"
+    >
+    <ng-template [ngTemplateOutlet]="prefixTmpl"></ng-template>
+    <span class="mat-body">
+      {{ region.name }}
+    </span>
+    <ng-template [ngTemplateOutlet]="suffixTmpl"></ng-template>
+  </mat-chip>
+</mat-chip-list>
diff --git a/src/atlasComponents/sapiViews/core/region/region/region.base.directive.ts b/src/atlasComponents/sapiViews/core/region/region/region.base.directive.ts
index a84edee486bcbde88230a3629a5a0738ccc8db6b..4ff63ab42055f5ab35e85618db311102a9719ccd 100644
--- a/src/atlasComponents/sapiViews/core/region/region/region.base.directive.ts
+++ b/src/atlasComponents/sapiViews/core/region/region/region.base.directive.ts
@@ -1,12 +1,20 @@
-import { Directive, Input } from "@angular/core";
+import { Directive, EventEmitter, Input, OnDestroy, Output } from "@angular/core";
 import { SapiAtlasModel, SapiParcellationModel, SapiRegionModel, SapiSpaceModel } from "src/atlasComponents/sapi";
-import { strToRgb, rgbToHsl, hexToRgb } from 'common/util'
+import { rgbToHsl } from 'common/util'
+import { SAPI } from "src/atlasComponents/sapi/sapi.service";
+import { Subject } from "rxjs";
+import { SAPIRegion } from "src/atlasComponents/sapi/core";
 
 @Directive({
-  selector: `sxplr-sapiviews-core-region`
+  selector: `[sxplr-sapiviews-core-region]`,
+  exportAs: "sapiViewsCoreRegion"
 })
 export class SapiViewsCoreRegionRegionBase {
 
+  @Input('sxplr-sapiviews-core-region-detail-flag')
+  shouldFetchDetail = false
+  public fetchInProgress = false
+
   @Input('sxplr-sapiviews-core-region-atlas')
   atlas: SapiAtlasModel
   @Input('sxplr-sapiviews-core-region-template')
@@ -14,11 +22,36 @@ export class SapiViewsCoreRegionRegionBase {
   @Input('sxplr-sapiviews-core-region-parcellation')
   parcellation: SapiParcellationModel
 
-  private _region: SapiRegionModel 
+  @Output('sxplr-sapiviews-core-region-navigate-to')
+  onNavigateTo = new EventEmitter<number[]>()
+
+  protected region$ = new Subject<SapiRegionModel>()
+  private _region: SapiRegionModel
   @Input('sxplr-sapiviews-core-region-region')
   set region(val: SapiRegionModel) {
-    this._region = val
-    this.setupRegionDarkmode()
+    
+    this.region$.next(val)
+
+    if (!this.shouldFetchDetail || !val) {
+      this._region = val
+      this.setupRegionDarkmode()
+      return
+    }
+    this.fetchInProgress = true
+    this._region = null
+    
+    this.fetchDetail(val)
+      .then(r => {
+        this._region = r
+      })
+      .catch(e => {
+        console.warn(`populating detail failed.`, e)
+        this._region = val
+      })
+      .finally(() => {
+        this.fetchInProgress = false
+        this.setupRegionDarkmode()
+      })
   }
   get region(){
     return this._region
@@ -42,12 +75,7 @@ export class SapiViewsCoreRegionRegionBase {
       /**
        * color
        */
-      let rgb = [255, 200, 200]
-      if (this.region.hasAnnotation?.displayColor) {
-        rgb = hexToRgb(this.region?.hasAnnotation?.displayColor)
-      } else {
-        rgb = strToRgb(JSON.stringify(this.region))
-      }
+      let rgb = SAPIRegion.GetDisplayColor(this.region)
       this.regionRgbString = `rgb(${rgb.join(',')})`
       const [_h, _s, l] = rgbToHsl(...rgb)
       this.regionDarkmode = l < 0.4
@@ -67,6 +95,14 @@ export class SapiViewsCoreRegionRegionBase {
   }
 
   navigateTo(position: number[]) {
-    console.log('navigate to region', position)
+    this.onNavigateTo.emit(position.map(v => v*1e6))
+  }
+
+  protected async fetchDetail(region: SapiRegionModel) {
+    return await this.sapi.getRegion(this.atlas["@id"],this.parcellation["@id"], region.name).getDetail(this.template["@id"])
+  }
+
+  constructor(protected sapi: SAPI){
+
   }
 }
diff --git a/src/atlasComponents/sapiViews/core/region/region/region.features.directive.ts b/src/atlasComponents/sapiViews/core/region/region/region.features.directive.ts
index c2e1d640fc4069217f533ca859a534c530c30235..d542fc05dd988f4f599b292633b20445402f8dea 100644
--- a/src/atlasComponents/sapiViews/core/region/region/region.features.directive.ts
+++ b/src/atlasComponents/sapiViews/core/region/region/region.features.directive.ts
@@ -1,6 +1,6 @@
 import { Directive, OnChanges, SimpleChanges } from "@angular/core";
-import { BehaviorSubject, Observable } from "rxjs";
-import { switchMap,  filter, startWith, shareReplay } from "rxjs/operators";
+import { BehaviorSubject, merge, Observable } from "rxjs";
+import { switchMap,  filter, startWith, shareReplay, mapTo, delay, tap } from "rxjs/operators";
 import { SAPI, SapiAtlasModel, SapiParcellationModel, SapiRegionalFeatureModel, SapiRegionModel, SapiSpaceModel } from "src/atlasComponents/sapi";
 import { SapiViewsCoreRegionRegionBase } from "./region.base.directive";
 
@@ -23,18 +23,30 @@ export class SapiViewsCoreRegionRegionalFeatureDirective extends SapiViewsCoreRe
     this.ATPR$.next({ atlas, template, parcellation, region })
   }
 
-  constructor(private sapi: SAPI){
-    super()
+  constructor(sapi: SAPI){
+    super(sapi)
   }
 
-  public listOfFeatures$: Observable<SapiRegionalFeatureModel[]> = this.ATPR$.pipe(
+  private features$: Observable<SapiRegionalFeatureModel[]> = this.ATPR$.pipe(
     filter(arg => {
       if (!arg) return false
       const { atlas, parcellation, region, template } = arg
       return !!atlas && !!parcellation && !!region && !!template 
     }),
     switchMap(({ atlas, parcellation, region, template }) => this.sapi.getRegionFeatures(atlas["@id"], parcellation["@id"], template["@id"], region.name)),
+  )
+
+  public listOfFeatures$: Observable<SapiRegionalFeatureModel[]> = this.features$.pipe(
     startWith([]),
     shareReplay(1),
   )
+
+  public busy$: Observable<boolean> = merge(
+    this.ATPR$.pipe(
+      mapTo(true)    
+    ),
+    this.features$.pipe(
+      mapTo(false)
+    )
+  )
 }
diff --git a/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.component.ts b/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.component.ts
index 1d44db4e8578b0aa7d5b9eb663e1979b5f5caaf8..cf2e067d1d147fee14456c7d8b31a6e6a3e153a2 100644
--- a/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.component.ts
+++ b/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.component.ts
@@ -1,9 +1,11 @@
-import { Component, EventEmitter, Inject, Output } from "@angular/core";
-import { Observable, Subject } from "rxjs";
+import { Component, EventEmitter, Inject, OnDestroy, Output } from "@angular/core";
+import { Observable, Subject, Subscription } from "rxjs";
+import { filter } from "rxjs/operators"
 import { DARKTHEME } from "src/util/injectionTokens";
 import { SapiViewsCoreRegionRegionBase } from "../region.base.directive";
 import { ARIA_LABELS, CONST } from 'common/constants'
 import { SapiRegionalFeatureModel } from "src/atlasComponents/sapi";
+import { SAPI } from "src/atlasComponents/sapi/sapi.service";
 
 @Component({
   selector: 'sxplr-sapiviews-core-region-region-rich',
@@ -13,23 +15,20 @@ import { SapiRegionalFeatureModel } from "src/atlasComponents/sapi";
   ]
 })
 
-export class SapiViewsCoreRegionRegionRich extends SapiViewsCoreRegionRegionBase{
+export class SapiViewsCoreRegionRegionRich extends SapiViewsCoreRegionRegionBase {
   
-  get ARIA_LABELS() {
-    return ARIA_LABELS
-  }
-
-  get CONST() {
-    return CONST
-  }
+  shouldFetchDetail = true
+  public ARIA_LABELS = ARIA_LABELS
+  public CONST = CONST
 
   @Output('sxplr-sapiviews-core-region-region-rich-feature-clicked')
   featureClicked = new EventEmitter<SapiRegionalFeatureModel>()
 
   constructor(
-    @Inject(DARKTHEME) public darktheme$: Observable<boolean>
+    sapi: SAPI,
+    @Inject(DARKTHEME) public darktheme$: Observable<boolean>,
   ){
-    super()
+    super(sapi)
   }
 
   handleRegionalFeatureClicked(feat: SapiRegionalFeatureModel) {
diff --git a/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.stories.ts b/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.stories.ts
index 818f0b227362e5ce9ac3a6035a09bc4e25b2818e..551ed5a081fb5536fc91ff2e2d4c2196aed3740f 100644
--- a/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.stories.ts
+++ b/src/atlasComponents/sapiViews/core/region/region/rich/region.rich.stories.ts
@@ -2,7 +2,7 @@ import { CommonModule } from "@angular/common"
 import { HttpClientModule } from "@angular/common/http"
 import { Meta, moduleMetadata, Story } from "@storybook/angular"
 import { SAPI } from "src/atlasComponents/sapi"
-import { getHoc1Left, getHumanAtlas, getJba29, getMni152, provideDarkTheme } from "src/atlasComponents/sapi/stories.base"
+import { atlasId, getHoc1Left, getHumanAtlas, getJba29, getJba29Regions, getMni152, provideDarkTheme } from "src/atlasComponents/sapi/stories.base"
 import { SapiViewsCoreRegionModule } from "../../module"
 import { SapiViewsCoreRegionRegionRich } from "./region.rich.component"
 import { action } from '@storybook/addon-actions';
@@ -41,7 +41,6 @@ const Template: Story<SapiViewsCoreRegionRegionRich> = (args: SapiViewsCoreRegio
   const { contentProjection } = parameters
   return ({
     props: {
-      ...args,
       atlas: human, 
       template: mni152, 
       parcellation: jba29, 
@@ -63,7 +62,6 @@ const loadRegions = async () => {
   const mni152 = await getMni152()
   const jba29 = await getJba29()
   const hoc1left = await getHoc1Left(mni152["@id"])
-
   return {
     human,
     mni152,
@@ -101,3 +99,15 @@ HeaderContentProjection.loaders = [
 HeaderContentProjection.parameters = {
   contentProjection: `<div header>HEADER CONTENT PROJECTED</div>`
 }
+
+export const InjectionSimpleRegion = Template.bind({})
+InjectionSimpleRegion.loaders = [
+  ...HumanMni152Jba29Hoc1Left.loaders,
+  async () => {
+    const regions = await getJba29Regions()
+    const hoc1left = regions.find(r => /left/i.test(r.name) && /hoc1/i.test(r.name))
+    return {
+      hoc1left
+    }
+  }
+]
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 453707e72d044d826f925a950116752e73782a5e..23d94a6cf393179dd4c553d54d23dc90a4facf24 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
@@ -1,3 +1,15 @@
+<ng-template #headerTmpl>
+  <ng-content select="[header]"></ng-content>
+</ng-template>
+
+<ng-template [ngIf]="!region">
+  
+  <ng-template [ngTemplateOutlet]="headerTmpl"></ng-template>
+
+  <spinner-cmp *ngIf="fetchInProgress"></spinner-cmp>
+  <span *ngIf="!fetchInProgress"> Region must be provided! </span>
+</ng-template>
+
 <ng-template [ngIf]="region">
 
 <mat-card class="mat-elevation-z4">
@@ -9,7 +21,7 @@
       'lighttheme': regionDarkmode === false
     }">
 
-    <ng-content [select]="[header]"></ng-content>
+    <ng-template [ngTemplateOutlet]="headerTmpl"></ng-template>
 
     <mat-card-title class="iv-custom-comp text">
       {{ region.name }}
@@ -61,6 +73,8 @@
     class="feature-list-container"
     >
 
+    <spinner-cmp *ngIf="rfDir.busy$ | async"></spinner-cmp>
+
     <sxplr-sapiviews-features-entry-list-item
       *ngFor="let feat of rfDir.listOfFeatures$ | async"
       [sxplr-sapiviews-features-entry-list-item-feature]="feat"
@@ -134,9 +148,3 @@
     </ng-template>
   </mat-expansion-panel>
 </ng-template>
-
-<!-- fall back if region is not provided -->
-
-<ng-template [ngIf]="!region">
-  Region must be provided!
-</ng-template>
\ No newline at end of file
diff --git a/src/atlasComponents/sapiViews/features/entry/entry.component.ts b/src/atlasComponents/sapiViews/features/entry/entry.component.ts
index cc5f8a396f61d4d2b63b8ad9c19afa197d15c332..79ee7640af146039fb2fc14d566c12daf7bef396 100644
--- a/src/atlasComponents/sapiViews/features/entry/entry.component.ts
+++ b/src/atlasComponents/sapiViews/features/entry/entry.component.ts
@@ -31,6 +31,6 @@ export class FeatureEntryCmp{
   feature: SapiFeatureModel
 
   featureType = {
-    receptor: "siibra/receptor"
+    receptor: "siibra/features/receptor"
   }
 }
diff --git a/src/atlasComponents/sapiViews/richDataset.stories.ts b/src/atlasComponents/sapiViews/richDataset.stories.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c49035dbe93ff1d54764413660bea9afd4bbef9e
--- /dev/null
+++ b/src/atlasComponents/sapiViews/richDataset.stories.ts
@@ -0,0 +1,121 @@
+import { CommonModule } from "@angular/common"
+import { HttpClientModule } from "@angular/common/http"
+import { Component } from "@angular/core"
+import { Meta, moduleMetadata, Story } from "@storybook/angular"
+import { SAPI } from "src/atlasComponents/sapi"
+import { getHoc1FeatureDetail, getHoc1Features, getHoc1Left, getHumanAtlas, getJba29, getMni152, provideDarkTheme } from "src/atlasComponents/sapi/stories.base"
+import { AngularMaterialModule } from "src/sharedModules"
+import { SapiAtlasModel, SapiFeatureModel, SapiParcellationModel, SapiRegionModel, SapiSpaceModel } from "../sapi/type"
+import { SapiViewsCoreDatasetModule } from "./core/datasets"
+import { SapiViewsFeaturesModule } from "./features"
+
+@Component({
+  selector: `rich-dataset-wrapper-cmp`,
+  template: `
+  <div *ngIf="!dataset">
+    Dataset must be provided
+  </div>
+  <mat-card *ngIf="dataset">
+    <sxplr-sapiviews-core-datasets-dataset
+      [sxplr-sapiviews-core-datasets-dataset-input]="dataset">
+    </sxplr-sapiviews-core-datasets-dataset>
+
+    <sxplr-sapiviews-features-entry
+      [sxplr-sapiviews-features-entry-atlas]="atlas"
+      [sxplr-sapiviews-features-entry-space]="template"
+      [sxplr-sapiviews-features-entry-parcellation]="parcellation"
+      [sxplr-sapiviews-features-entry-region]="region"
+      [sxplr-sapiviews-features-entry-feature]="dataset">
+    </sxplr-sapiviews-features-entry>
+  </mat-card>
+  
+  `,
+  styles: [
+    `mat-card { max-width: 40rem; }`
+  ]
+})
+
+class RichDatasetWrapperCmp {
+  atlas: SapiAtlasModel
+  parcellation: SapiParcellationModel
+  template: SapiSpaceModel
+  region: SapiRegionModel
+  dataset: SapiFeatureModel
+}
+
+export default {
+  component: RichDatasetWrapperCmp,
+  decorators: [
+    moduleMetadata({
+      imports: [
+        AngularMaterialModule,
+        CommonModule,
+        HttpClientModule,
+        SapiViewsCoreDatasetModule,
+        SapiViewsFeaturesModule,
+      ],
+      providers: [
+        SAPI,
+        ...provideDarkTheme,
+      ],
+      declarations: []
+    })
+  ],
+} as Meta
+
+const Template: Story<RichDatasetWrapperCmp> = (args: RichDatasetWrapperCmp, { loaded }) => {
+  const {
+    
+    atlas, 
+    parcellation, 
+    template, 
+    region, 
+    feature
+  } = loaded
+  return ({
+    props: {
+      atlas, 
+      parcellation, 
+      template, 
+      region, 
+      dataset: feature,
+    },
+  })
+}
+
+const loadRegionMetadata = async () => {
+
+  const atlas = await getHumanAtlas()
+  const parcellation = await getJba29()
+  const template = await getMni152()
+  const region = await getHoc1Left()
+  return {
+    atlas, 
+    parcellation, 
+    template, 
+    region, 
+  }
+}
+
+const loadFeat = async () => {
+  const features = await getHoc1Features()
+  return { features }
+}
+
+export const ReceptorDataset = Template.bind({})
+ReceptorDataset.args = {
+
+}
+ReceptorDataset.loaders = [
+  async () => {
+    return await loadRegionMetadata()
+  },
+  async () => {
+    const { features } = await loadFeat()
+    const receptorfeat = features.find(f => f.type === "siibra/features/receptor")
+    const feature = await getHoc1FeatureDetail(receptorfeat["@id"])
+    return {
+      feature
+    }
+  }
+]
diff --git a/src/atlasViewer/atlasViewer.component.ts b/src/atlasViewer/atlasViewer.component.ts
index cca817c6b626f6524ed2bb1afc454cd9ac42c939..7cf6952ae0c87594b243aa328f424e8731a15f44 100644
--- a/src/atlasViewer/atlasViewer.component.ts
+++ b/src/atlasViewer/atlasViewer.component.ts
@@ -211,12 +211,3 @@ If you have any comments or need further support, please contact us at [${this.p
   @HostBinding('attr.version')
   public _version: string = environment.VERSION
 }
-
-export interface INgLayerInterface {
-  name: string
-  visible: boolean
-  source: string
-  type: string // image | segmentation | etc ...
-  transform?: [[number, number, number, number], [number, number, number, number], [number, number, number, number], [number, number, number, number]] | null
-  // colormap : string
-}
diff --git a/src/databrowser.fallback.ts b/src/databrowser.fallback.ts
deleted file mode 100644
index 6d23e7fb4ec9d40e35c4b2c8cafed9578b68db64..0000000000000000000000000000000000000000
--- a/src/databrowser.fallback.ts
+++ /dev/null
@@ -1,111 +0,0 @@
-import { InjectionToken } from "@angular/core"
-import { Observable } from "rxjs"
-import { IHasId } from "./util/interfaces"
-
-/**
- * TODO gradually move to relevant.
- */
-
-export const kgTos = `The interactive viewer queries HBP Knowledge Graph Data Platform ("KG") for published datasets.
-
-
-Access to the data and metadata provided through KG requires that you cite and acknowledge said data and metadata according to the Terms and Conditions of the Platform.
-
-
-Citation requirements are outlined <https://www.humanbrainproject.eu/en/explore-the-brain/search-terms-of-use#citations> .
-
-
-Acknowledgement requirements are outlined <https://www.humanbrainproject.eu/en/explore-the-brain/search-terms-of-use#acknowledgements>
-
-
-These outlines are based on the authoritative Terms and Conditions are found <https://www.humanbrainproject.eu/en/explore-the-brain/search-terms-of-use>
-
-
-If you do not accept the Terms & Conditions you are not permitted to access or use the KG to search for, to submit, to post, or to download any materials found there-in.
-`
-
-export function getKgSchemaIdFromFullId(fullId: string): [string, string]{
-  if (!fullId) { return [null, null] }
-  const match = /([\w\-.]*\/[\w\-.]*\/[\w\-.]*\/[\w\-.]*)\/([\w\-.]*)$/.exec(fullId)
-  if (!match) { return [null, null] }
-  return [match[1], match[2]]
-}
-
-
-export interface IKgReferenceSpace {
-  name: string
-}
-
-export interface IKgPublication {
-  name: string
-  doi: string
-  cite: string
-}
-
-export interface IKgParcellationRegion {
-  id?: string
-  name: string
-}
-
-export interface IKgActivity {
-  methods: string[]
-  preparation: string[]
-  protocols: string[]
-}
-
-export interface IKgDataEntry {
-  activity: IKgActivity[]
-  name: string
-  description: string
-  license: string[]
-  licenseInfo: string[]
-  parcellationRegion: IKgParcellationRegion[]
-  formats: string[]
-  custodians: string[]
-  contributors: string[]
-  referenceSpaces: IKgReferenceSpace[]
-  files: File[]
-  publications: IKgPublication[]
-  embargoStatus: IHasId[]
-
-  methods: string[]
-  protocols: string[]
-
-  preview?: boolean
-
-  /**
-   * TODO typo, should be kgReferences
-   */
-  kgReference: string[]
-
-  id: string
-  fullId: string
-}
-
-export type TypePreviewDispalyed = (file, dataset) => Observable<boolean>
-
-
-export enum EnumPreviewFileTypes{
-  NIFTI,
-  IMAGE,
-  CHART,
-  OTHER,
-  VOLUMES,
-}
-
-export interface DatasetPreview {
-  datasetId: string
-  filename: string
-}
-
-export function determinePreviewFileType(previewFile: any): EnumPreviewFileTypes {
-  if (!previewFile) throw new Error(`previewFile is required to determine the file type`)
-  const { mimetype, data } = previewFile
-  const chartType = data && data['chart.js'] && data['chart.js'].type
-  const registerdVolumes = data && data['iav-registered-volumes']
-  if ( mimetype === 'application/nifti' ) { return EnumPreviewFileTypes.NIFTI }
-  if ( /^image/.test(mimetype)) { return EnumPreviewFileTypes.IMAGE }
-  if ( /application\/json/.test(mimetype) && (chartType === 'line' || chartType === 'radar')) { return EnumPreviewFileTypes.CHART }
-  if ( /application\/json/.test(mimetype) && !!registerdVolumes) { return EnumPreviewFileTypes.VOLUMES }
-  return EnumPreviewFileTypes.OTHER
-}
diff --git a/src/environments/environment.common.ts b/src/environments/environment.common.ts
index 7634811836054d36fb8d6c38e622993b4d2ca2df..764290062735cae7148fa2d534f69a11b422eb87 100644
--- a/src/environments/environment.common.ts
+++ b/src/environments/environment.common.ts
@@ -4,7 +4,6 @@ export const environment = {
   VERSION: 'unknown version',
   PRODUCTION: true,
   BACKEND_URL: null,
-  DATASET_PREVIEW_URL: 'https://hbp-kg-dataset-previewer.apps.hbp.eu/v2',
   BS_REST_URL: 'http://localhost:5000/v1_0',
   SPATIAL_TRANSFORM_BACKEND: 'https://hbp-spatial-backend.apps.hbp.eu',
   MATOMO_URL: null,
diff --git a/src/environments/parseEnv.js b/src/environments/parseEnv.js
index dbd985314dc0c472611870143293d584b95e1e11..b05909d596c85cc1875650602cafb8a5fa2fba3a 100644
--- a/src/environments/parseEnv.js
+++ b/src/environments/parseEnv.js
@@ -7,7 +7,6 @@ const main = async () => {
   const pathToEnvFile = path.join(__dirname, './environment.prod.ts')
   const {
     BACKEND_URL,
-    DATASET_PREVIEW_URL,
     STRICT_LOCAL,
     MATOMO_URL,
     MATOMO_ID,
@@ -19,7 +18,6 @@ const main = async () => {
   
   console.log(`[parseEnv.js] parse envvar:`, {
     BACKEND_URL,
-    DATASET_PREVIEW_URL,
     STRICT_LOCAL,
     MATOMO_URL,
     MATOMO_ID,
@@ -43,7 +41,6 @@ export const environment = {
   VERSION: ${version},
   BS_REST_URL: ${JSON.stringify(BS_REST_URL)},
   BACKEND_URL: ${JSON.stringify(BACKEND_URL)},
-  DATASET_PREVIEW_URL: ${JSON.stringify(DATASET_PREVIEW_URL)},
   STRICT_LOCAL: ${JSON.stringify(STRICT_LOCAL)},
   MATOMO_URL: ${JSON.stringify(MATOMO_URL)},
   MATOMO_ID: ${JSON.stringify(MATOMO_ID)},
diff --git a/src/extra_styles.css b/src/extra_styles.css
index 3c9598b3f5e22dde46926c806307f648026e824d..4dc17c826004add9df28f132625f4fd7b9f39d51 100644
--- a/src/extra_styles.css
+++ b/src/extra_styles.css
@@ -718,10 +718,6 @@ kg-dataset-previewer > img
   margin: 15px;
 }
 
-.m-1px
-{
-  margin:1px;
-}
 
 .ml-15px-n
 {
@@ -875,8 +871,3 @@ quick-tour-unit svg
   stroke-linecap: round;
   stroke-linejoin: round;
 }
-
-.overwrite-max-width-80vw
-{
-  max-width: 80vw!important;
-}
diff --git a/src/main.module.ts b/src/main.module.ts
index 329b27c1fd72db2f7131029db082a3a4dc706cb9..de2ee0525e1e189c01f619314f01534c69f1d377 100644
--- a/src/main.module.ts
+++ b/src/main.module.ts
@@ -41,19 +41,22 @@ import { MessagingGlue } from './messagingGlue';
 import { BS_ENDPOINT } from './util/constants';
 import { QuickTourModule } from './ui/quickTour';
 import { of } from 'rxjs';
-import { kgTos } from './databrowser.fallback'
 import { CANCELLABLE_DIALOG } from './util/interfaces';
 import { environment } from 'src/environments/environment' 
 import { NotSupportedCmp } from './notSupportedCmp/notSupported.component';
-
 import {
   atlasSelection,
-  RootEffecsModule,
   RootStoreModule,
+  getStoreEffects,
 } from "./state"
 import { DARKTHEME } from './util/injectionTokens';
 import { map } from 'rxjs/operators';
+import { EffectsModule } from '@ngrx/effects';
 
+// TODO check if there is a more logical place import put layerctrl effects ts
+import { LayerCtrlEffects } from './viewerModule/nehuba/layerCtrl.service/layerCtrl.effects';
+import { NehubaNavigationEffects } from './viewerModule/nehuba/navigation.service/navigation.effects';
+import { CONST } from "common/constants"
 
 @NgModule({
   imports : [
@@ -78,7 +81,11 @@ import { map } from 'rxjs/operators';
     AtlasViewerRouterModule,
     QuickTourModule,
     
-    RootEffecsModule,
+    EffectsModule.forRoot([
+      ...getStoreEffects(),
+      LayerCtrlEffects,
+      NehubaNavigationEffects,
+    ]),
     RootStoreModule,
     HttpClientModule,
   ],
@@ -143,7 +150,7 @@ import { map } from 'rxjs/operators';
     },
     {
       provide: TOS_OBS_INJECTION_TOKEN,
-      useValue: of(kgTos)
+      useValue: of(CONST.KG_TOS)
     },
 
     {
diff --git a/src/messagingGlue.ts b/src/messagingGlue.ts
index 96bce9f87b0a723b592abc5b8f78a03ffde7ee9d..edb76b0f769ee11e5dcf04210e4ec992d442b9b5 100644
--- a/src/messagingGlue.ts
+++ b/src/messagingGlue.ts
@@ -1,9 +1,7 @@
 import { Injectable, OnDestroy } from "@angular/core";
-import { select, Store } from "@ngrx/store";
+import { Store } from "@ngrx/store";
 import { IMessagingActionTmpl, IWindowMessaging } from "./messaging/types";
-import { ngViewerActionAddNgLayer, ngViewerActionRemoveNgLayer } from "./services/state/ngViewerState/actions";
-import { generalActionError } from "./services/stateStore.helper";
-import { atlasSelection } from "src/state"
+import { atlasAppearance, atlasSelection, generalActions } from "src/state"
 import { SAPI } from "./atlasComponents/sapi";
 
 @Injectable()
@@ -43,7 +41,7 @@ export class MessagingGlue implements IWindowMessaging, OnDestroy {
     const atlasId = this.tmplSpIdToAtlasId.get(payload['@id'])
     if (!atlasId) {
       return this.store.dispatch(
-        generalActionError({
+        generalActions.generalActionError({
           message: `atlas id with the corresponding templateId ${payload['@id']} not found.`
         })
       )
@@ -68,29 +66,26 @@ export class MessagingGlue implements IWindowMessaging, OnDestroy {
     if (type === 'swc') {
       const { transform } = resourceParam
       const layer = {
-        name: swcLayerUuid,
         id: swcLayerUuid,
         source: `swc://${url}`,
-        mixability: 'mixable',
-        type: "segmentation",
-        "segments": [
+        // type: "customlayer/nglayer",
+        segments: [
           "1"
         ],
-        transform,
+        transform: transform,
+        clType: 'customlayer/nglayer' as 'customlayer/nglayer'
       }
 
       this.store.dispatch(
-        ngViewerActionAddNgLayer({
-          layer
+        atlasAppearance.actions.addCustomLayer({
+          customLayer: layer
         })
       )
 
       this.mapIdUnload.set(swcLayerUuid, () => {
         this.store.dispatch(
-          ngViewerActionRemoveNgLayer({
-            layer: {
-              name: swcLayerUuid
-            }
+          atlasAppearance.actions.removeCustomLayer({
+            id: swcLayerUuid
           })
         )
         unload()
diff --git a/src/overwrite.scss b/src/overwrite.scss
index 7db898b3e7adf09e11919aa4996a15240e136d9f..69b68e49481fdbd5989c5e0bd196066ee98b3793 100644
--- a/src/overwrite.scss
+++ b/src/overwrite.scss
@@ -47,9 +47,12 @@ $media-map: (
 
 
 @for $i from 4 through 10 {
-  $maxheight: $i * 10;
-  .max-#{$maxheight}-vh {
-    max-height: $maxheight * 1vh;
+  $tensvar: $i * 10;
+  .#{$nsp}-mxh-#{$tensvar}vh {
+    max-height: $tensvar * 1vh;
+  }
+  .#{$nsp}-mxw-#{$tensvar}vw {
+    max-width: $tensvar * 1vw;
   }
 }
 
@@ -95,42 +98,42 @@ $transform-origin-maps: (
 }
 
 @for $zlvl from 0 through 10 {
-  .#{$nsp}-z-index-#{$zlvl} {
+  .#{$nsp}-z-#{$zlvl} {
     z-index: $zlvl;
   }
 }
 
-@for $unit from 0 through 8 {
-  .#{$nsp}-pt-#{$unit} {
-    padding-top: $unit * 0.5rem;
+@for $unit from 0 through 10 {
+  .#{$nsp}-pt-#{$unit}{
+    padding-top: $unit * 0.5rem!important;
   }
-  .#{$nsp}-pb-#{$unit} {
-    padding-bottom: $unit * 0.5rem;
+  .#{$nsp}-pb-#{$unit}{
+    padding-bottom: $unit * 0.5rem!important;
   }
-  .#{$nsp}-pl-#{$unit} {
-    padding-left: $unit * 0.5rem;
+  .#{$nsp}-pl-#{$unit}{
+    padding-left: $unit * 0.5rem!important;
   }
-  .#{$nsp}-pr-#{$unit} {
-    padding-right: $unit * 0.5rem;
+  .#{$nsp}-pr-#{$unit}{
+    padding-right: $unit * 0.5rem!important;
   }
-  .#{$nsp}-p-#{$unit} {
-    padding: $unit * 0.5rem;
+  .#{$nsp}-p-#{$unit}{
+    padding: $unit * 0.5rem!important;
   }
 
-  .#{$nsp}-mt-#{$unit} {
-    margin-top: $unit * 0.5rem;
+  .#{$nsp}-mt-#{$unit}{
+    margin-top: $unit * 0.5rem!important;
   }
-  .#{$nsp}-mb-#{$unit} {
-    margin-bottom: $unit * 0.5rem;
+  .#{$nsp}-mb-#{$unit}{
+    margin-bottom: $unit * 0.5rem!important;
   }
-  .#{$nsp}-ml-#{$unit} {
-    margin-left: $unit * 0.5rem;
+  .#{$nsp}-ml-#{$unit}{
+    margin-left: $unit * 0.5rem!important;
   }
-  .#{$nsp}-mr-#{$unit} {
-    margin-right: $unit * 0.5rem;
+  .#{$nsp}-mr-#{$unit}{
+    margin-right: $unit * 0.5rem!important;
   }
-  .#{$nsp}-m-#{$unit} {
-    margin: $unit * 0.5rem;
+  .#{$nsp}-m-#{$unit}{
+    margin: $unit * 0.5rem!important;
   }
 }
 
@@ -200,7 +203,7 @@ $white-space-vars: nowrap;
 
 $pointer-events-vars: all, none;
 @each $pointer-events-var in $pointer-events-vars {
-  .#{$nsp}-pointer-events-#{$pointer-events-var}
+  .#{$nsp}-pe-#{$pointer-events-var}
   {
     pointer-events: $pointer-events-var!important;
   }
@@ -217,3 +220,11 @@ $width-pc-vars: 100;
 {
   border-width: 1px;
 }
+
+// flex
+$flex-wrap-vars: nowrap, wrap, wrap-reverse;
+@each $flex-wrap-var in $flex-wrap-vars {
+  .#{$nsp}-flex-wrap-#{$flex-wrap-var} {
+    flex-wrap: $flex-wrap-var;
+  }
+}
diff --git a/src/plugin/atlasViewer.pluginService.service.spec.ts b/src/plugin/atlasViewer.pluginService.service.spec.ts
index 41e342b8bf77d8941eb731554972b71217e75b73..56d8cfc106502e2ee6cb9c5ff93f6c73d5eab619 100644
--- a/src/plugin/atlasViewer.pluginService.service.spec.ts
+++ b/src/plugin/atlasViewer.pluginService.service.spec.ts
@@ -1,18 +1,16 @@
 import { CommonModule } from "@angular/common"
 import { HttpClientTestingModule, HttpTestingController } from "@angular/common/http/testing"
-import { NgModule } from "@angular/core"
-import { async, fakeAsync, TestBed, tick } from "@angular/core/testing"
+import { fakeAsync, TestBed, tick } from "@angular/core/testing"
 import { MockStore, provideMockStore } from "@ngrx/store/testing"
 import { ComponentsModule } from "src/components"
 import { DialogService } from "src/services/dialogService.service"
-import { selectorPluginCspPermission } from "src/services/state/userConfigState.helper"
 import { AngularMaterialModule } from "src/sharedModules"
+import { userPreference } from "src/state"
 import { PureContantService } from "src/util"
 import { APPEND_SCRIPT_TOKEN, REMOVE_SCRIPT_TOKEN } from "src/util/constants"
 import { WidgetModule, WidgetServices } from "src/widget"
 import { PluginServices } from "./atlasViewer.pluginService.service"
 import { PluginModule } from "./plugin.module"
-import { PluginUnit } from "./pluginUnit/pluginUnit.component"
 
 const MOCK_PLUGIN_MANIFEST = {
   name: 'fzj.xg.MOCK_PLUGIN_MANIFEST',
@@ -33,8 +31,8 @@ describe('> atlasViewer.pluginService.service.ts', () => {
     let httpMock: HttpTestingController
     let mockStore: MockStore
     
-    beforeEach(async(() => {
-      TestBed.configureTestingModule({
+    beforeEach(async () => {
+      await TestBed.configureTestingModule({
         imports: [
           AngularMaterialModule,
           CommonModule,
@@ -67,38 +65,37 @@ describe('> atlasViewer.pluginService.service.ts', () => {
             }
           }
         ]
-      }).compileComponents().then(() => {
-        
-        httpMock = TestBed.inject(HttpTestingController)
-        pluginService = TestBed.inject(PluginServices)
-        mockStore = TestBed.inject(MockStore)
-        pluginService.pluginViewContainerRef = {
-          createComponent: () => {
-            return {
-              onDestroy: () => {},
-              instance: {
-                elementRef: {
-                  nativeElement: {
-                    append: () => {}
-                  }
+      }).compileComponents()
+      
+      httpMock = TestBed.inject(HttpTestingController)
+      pluginService = TestBed.inject(PluginServices)
+      mockStore = TestBed.inject(MockStore)
+      pluginService.pluginViewContainerRef = {
+        createComponent: () => {
+          return {
+            onDestroy: () => {},
+            instance: {
+              elementRef: {
+                nativeElement: {
+                  append: () => {}
                 }
               }
             }
           }
-        } as any
+        }
+      } as any
 
-        httpMock.expectOne('http://localhost:3000/plugins/manifests').flush('[]')
+      httpMock.expectOne('http://localhost:3000/plugins/manifests').flush('[]')
 
-        const widgetService = TestBed.inject(WidgetServices)
-        /**
-         * widget service floatingcontainer not inst in this circumstance
-         * TODO fix widget service tests importing widget service are not as flaky
-         */
-        widgetService.addNewWidget = () => {
-          return {} as any
-        }
-      })
-    }))
+      const widgetService = TestBed.inject(WidgetServices)
+      /**
+       * widget service floatingcontainer not inst in this circumstance
+       * TODO fix widget service tests importing widget service are not as flaky
+       */
+      widgetService.addNewWidget = () => {
+        return {} as any
+      }
+    })
 
     afterEach(() => {
       spyfn.appendSrc.calls.reset()
@@ -127,7 +124,7 @@ describe('> atlasViewer.pluginService.service.ts', () => {
     describe('#launchPlugin', () => {
 
       beforeEach(() => {
-        mockStore.overrideSelector(selectorPluginCspPermission, { value: false })
+        mockStore.overrideSelector(userPreference.selectors.userCsp, {})
       })
 
       describe('> basic fetching functionality', () => {
@@ -200,7 +197,7 @@ describe('> atlasViewer.pluginService.service.ts', () => {
 
           describe('> if user permission has been given', () => {
             beforeEach(fakeAsync(() => {
-              mockStore.overrideSelector(selectorPluginCspPermission, { value: true })
+              mockStore.overrideSelector(userPreference.selectors.userCsp, { 'fzj.xg.MOCK_PLUGIN_MANIFEST': {} })
               userConfirmSpy.and.callFake(() => Promise.reject())
               pluginService.launchPlugin({
                 ...cspManifest
@@ -222,7 +219,7 @@ describe('> atlasViewer.pluginService.service.ts', () => {
 
           describe('> if user permission has not yet been given', () => {
             beforeEach(() => {
-              mockStore.overrideSelector(selectorPluginCspPermission, { value: false })
+              mockStore.overrideSelector(userPreference.selectors.userCsp, {})
             })
             describe('> user permission', () => {
               beforeEach(fakeAsync(() => {
diff --git a/src/plugin/atlasViewer.pluginService.service.ts b/src/plugin/atlasViewer.pluginService.service.ts
index 3707c087d376b589ff673fe0482bf4a59b300046..a050e4312983d16e54aed95758ed118b3131177a 100644
--- a/src/plugin/atlasViewer.pluginService.service.ts
+++ b/src/plugin/atlasViewer.pluginService.service.ts
@@ -8,12 +8,12 @@ import { LoggingService } from 'src/logging';
 import { WidgetUnit, WidgetServices } from "src/widget";
 import { APPEND_SCRIPT_TOKEN, REMOVE_SCRIPT_TOKEN, getHttpHeader } from 'src/util/constants';
 import { PluginFactoryDirective } from './pluginFactory.directive';
-import { selectorPluginCspPermission } from 'src/services/state/userConfigState.helper';
 import { DialogService } from 'src/services/dialogService.service';
 import { DomSanitizer } from '@angular/platform-browser';
 import { MatSnackBar } from '@angular/material/snack-bar';
 import { PureContantService } from 'src/util';
 import { actions } from "src/state/plugins"
+import { userPreference } from 'src/state';
 
 const requiresReloadMd = `\n\n***\n\n**warning**: interactive atlas viewer **will** be reloaded in order for the change to take effect.`
 
@@ -229,10 +229,11 @@ export class PluginServices {
 
     await new Promise((rs, rj) => {
       this.store.pipe(
-        select(selectorPluginCspPermission, { key: pluginKey }),
+        select(userPreference.selectors.userCsp),
+        map(dict => !!dict[pluginKey]),
         take(1),
         switchMap(userAgreed => {
-          if (userAgreed.value) return of(true)
+          if (userAgreed) return of(true)
 
           /**
            * check if csp exists
diff --git a/src/routerModule/router.service.ts b/src/routerModule/router.service.ts
index 2837af008e31978422ba494aabdc8223f9d188ba..28a8c696bcf390011ca16244c2e6d30352a8da31 100644
--- a/src/routerModule/router.service.ts
+++ b/src/routerModule/router.service.ts
@@ -4,11 +4,11 @@ import { Inject } from "@angular/core";
 import { NavigationEnd, Router } from '@angular/router'
 import { Store } from "@ngrx/store";
 import { debounceTime, distinctUntilChanged, filter, map, shareReplay, startWith, switchMapTo, take, tap, withLatestFrom } from "rxjs/operators";
-import { generalApplyState } from "src/services/stateStore.helper";
 import { PureContantService } from "src/util";
 import { cvtStateToHashedRoutes, cvtFullRouteToState, encodeCustomState, decodeCustomState, verifyCustomState } from "./util";
 import { BehaviorSubject, combineLatest, merge, NEVER, Observable, of } from 'rxjs'
 import { scan } from 'rxjs/operators'
+import { generalActions } from "src/state"
 
 @Injectable({
   providedIn: 'root'
@@ -123,7 +123,7 @@ export class RouterService {
 
       if ( fullPath !== `/${routeFromState}`) {
         store$.dispatch(
-          generalApplyState({
+          generalActions.generalApplyState({
             state: stateFromRoute
           })
         )
diff --git a/src/services/state/ngViewerState.store.helper.ts b/src/services/state/ngViewerState.store.helper.ts
deleted file mode 100644
index 2898db9c78d9d39a26d23c8ba9c9e8a6bf3deef7..0000000000000000000000000000000000000000
--- a/src/services/state/ngViewerState.store.helper.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-// TODO to be merged with ng viewer state after refactor
-export { INgLayerInterface, PANELS } from './ngViewerState/constants'
-
-export {
-  ngViewerActionAddNgLayer,
-  ngViewerActionRemoveNgLayer,
-  
-  ngViewerActionToggleMax,
-  ngViewerActionClearView,
-  ngViewerActionSetPanelOrder,
-  ngViewerActionForceShowSegment,
-} from './ngViewerState/actions'
-
-export {
-  ngViewerSelectorClearView,
-  ngViewerSelectorClearViewEntries,
-  ngViewerSelectorNehubaReady,
-  ngViewerSelectorPanelOrder,
-  ngViewerSelectorLayers,
-} from './ngViewerState/selectors'
diff --git a/src/services/state/ngViewerState/actions.ts b/src/services/state/ngViewerState/actions.ts
deleted file mode 100644
index 858602e076a6c0d47a5ff339697971fa29c21924..0000000000000000000000000000000000000000
--- a/src/services/state/ngViewerState/actions.ts
+++ /dev/null
@@ -1,67 +0,0 @@
-import { createAction, props, createReducer } from "@ngrx/store"
-import { INgLayerInterface } from './constants'
-
-export const ngViewerActionAddNgLayer = createAction(
-  '[ngLayerAction] addNgLayer',
-  props<{ layer: INgLayerInterface|INgLayerInterface[] }>()
-)
-
-export const ngViewerActionRemoveNgLayer = createAction(
-  '[ngLayerAction] removeNgLayer',
-  props<{ layer: Partial<INgLayerInterface>|Partial<INgLayerInterface>[] }>()
-)
-
-export const ngViewerActionToggleMax = createAction(
-  `[ngViewerAction] toggleMax`,
-  props<{ payload: { index: number } }>()
-)
-
-export const ngViewerActionSetPanelOrder = createAction(
-  `[ngViewerAction] setPanelOrder`,
-  props<{ payload: { panelOrder: string } }>()
-)
-
-export const ngViewerActionSwitchPanelMode = createAction(
-  `[ngViewerAction] switchPanelMode`,
-  props<{ payload: { panelMode: string } }>()
-)
-
-export const ngViewerActionForceShowSegment = createAction(
-  `[ngViewerAction] forceShowSegment`,
-  props<{ forceShowSegment: boolean }>()
-)
-
-export const ngViewerActionNehubaReady = createAction(
-  `[ngViewerAction] nehubaReady`,
-  props<{ nehubaReady: boolean }>()
-)
-
-/**
- * Clear viewer view from additional layers such as PMap or connectivity
- * To request view to be cleared, call 
- * this.store$.dispatch(
- *  ngViewerActionClearView({ 
- *    payload: {
- *      ['my-unique-id']: true
- *    }
- *  })
- * )
- * 
- * When finished, call
- * 
- * this.store$.dispatch(
- *   ngViewerActionClearView({
- *    payload: {
- *      ['my-unique-id']: false
- *    }
- *   })
- * )
- */
-export const ngViewerActionClearView = createAction(
-  `[ngViewerAction] clearView`,
-  props<{ payload: { [key: string]: boolean }}>()
-)
-
-export const ngViewerActionCycleViews = createAction(
-  `[ngViewerAction] cycleView`
-)
\ No newline at end of file
diff --git a/src/services/state/ngViewerState/constants.ts b/src/services/state/ngViewerState/constants.ts
deleted file mode 100644
index 947d86c3eea81125f5ad99427f4988328fea3d16..0000000000000000000000000000000000000000
--- a/src/services/state/ngViewerState/constants.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-export interface INgLayerInterface {
-  name: string // displayName
-  source: string
-  mixability?: string //"base" | "mixable" | "nonmixable"
-  annotation?: string //
-  id?: string // unique identifier
-  visible?: boolean
-  shader?: string
-  transform?: any
-  opacity?: number
-}
-
-export enum PANELS {
-  FOUR_PANEL = 'FOUR_PANEL',
-  V_ONE_THREE = 'V_ONE_THREE',
-  H_ONE_THREE = 'H_ONE_THREE',
-  SINGLE_PANEL = 'SINGLE_PANEL',
-}
diff --git a/src/services/state/ngViewerState/selectors.spec.ts b/src/services/state/ngViewerState/selectors.spec.ts
deleted file mode 100644
index c44f676f86802ee790f4b7e291e7e79c50ccb849..0000000000000000000000000000000000000000
--- a/src/services/state/ngViewerState/selectors.spec.ts
+++ /dev/null
@@ -1,28 +0,0 @@
-import { ngViewerSelectorClearViewEntries } from './selectors'
-
-let clearViewQueue = {}
-
-describe('> ngViewerState/selectors.ts', () => {
-  describe('> ngViewerSelectorClearViewEntries', () => {
-    beforeEach(() => {
-      clearViewQueue = {}
-    })
-    describe('> when prop is not provided', () => {
-      it('> if clearViewQueue is empty (on startup)', () => {
-        const result = ngViewerSelectorClearViewEntries.projector(clearViewQueue)
-        expect(result).toEqual([])
-      })
-      it('> if clearViewQueue is non empty, but falsy, should return false', () => {
-        clearViewQueue['hello - world'] = null
-        clearViewQueue['oo bar'] = false
-        const result = ngViewerSelectorClearViewEntries.projector(clearViewQueue)
-        expect(result).toEqual([])
-      })
-      it('> if clearViewQueue is non empty and truthy, should return true', () => {
-        clearViewQueue['hello - world'] = 1
-        const result = ngViewerSelectorClearViewEntries.projector(clearViewQueue)
-        expect(result).toEqual(['hello - world'])
-      })
-    })
-  })
-})
\ No newline at end of file
diff --git a/src/services/state/ngViewerState/selectors.ts b/src/services/state/ngViewerState/selectors.ts
deleted file mode 100644
index e5940a77d769ebf5f4a0a6b47fa310988c07ec11..0000000000000000000000000000000000000000
--- a/src/services/state/ngViewerState/selectors.ts
+++ /dev/null
@@ -1,33 +0,0 @@
-import { createSelector } from "@ngrx/store";
-
-export const ngViewerSelectorClearViewEntries = createSelector(
-  (state: any) => state?.ngViewerState?.clearViewQueue,
-  (clearViewQueue = {}) => {
-    const returnKeys = []
-    for (const key in clearViewQueue) {
-      if (!!clearViewQueue[key]) returnKeys.push(key)
-    }
-    return returnKeys
-  }
-)
-
-export const ngViewerSelectorClearView = createSelector(
-  ngViewerSelectorClearViewEntries,
-  keys => keys.length > 0
-)
-
-export const ngViewerSelectorPanelOrder = createSelector(
-  state => state['ngViewerState'],
-  ngViewerState => ngViewerState.panelOrder
-)
-
-
-export const ngViewerSelectorNehubaReady = createSelector(
-  state => state['ngViewerState'],
-  ngViewerState => ngViewerState.nehubaReady
-)
-
-export const ngViewerSelectorLayers = createSelector(
-  state => state['ngViewerState'],
-  ngViewerState => ngViewerState?.layers || []
-)
\ No newline at end of file
diff --git a/src/services/state/uiState.store.helper.ts b/src/services/state/uiState.store.helper.ts
deleted file mode 100644
index b2201ef0b7ceb8419c52de5ca64a461e2dea0c1a..0000000000000000000000000000000000000000
--- a/src/services/state/uiState.store.helper.ts
+++ /dev/null
@@ -1,32 +0,0 @@
-// TODO merge with uiState.store.ts after refactor completes
-
-export {
-  uiActionSetPreviewingDatasetFiles,
-  uiActionShowSidePanelConnectivity,
-  uiStateCloseSidePanel,
-  uiStateCollapseSidePanel,
-  uiStateExpandSidePanel,
-  uiStateOpenSidePanel,
-  uiStateShowBottomSheet,
-  uiActionSnackbarMessage,
-  uiActionMouseoverLandmark,
-  uiActionMouseoverSegments,
-} from './uiState/actions'
-
-
-export enum EnumWidgetTypes{
-  DATASET_PREVIEW,
-}
-
-export interface IDatasetPreviewData{
-  datasetId: string
-  filename: string
-  datasetSchema?: string
-}
-
-export type TypeOpenedWidget = {
-  type: EnumWidgetTypes
-  data: IDatasetPreviewData
-}
-
-export const SHOW_KG_TOS = `SHOW_KG_TOS`
\ No newline at end of file
diff --git a/src/services/state/uiState/actions.ts b/src/services/state/uiState/actions.ts
deleted file mode 100644
index ae2fbc3bd9535428de9c3912a967ea71ee298c2c..0000000000000000000000000000000000000000
--- a/src/services/state/uiState/actions.ts
+++ /dev/null
@@ -1,49 +0,0 @@
-
-import { createAction, props } from '@ngrx/store'
-import { TemplateRef } from '@angular/core'
-import { MatBottomSheetConfig } from '@angular/material/bottom-sheet'
-
-export const uiStateCloseSidePanel = createAction(
-  '[uiState] closeSidePanel'
-)
-
-export const uiStateOpenSidePanel = createAction(
-  '[uiState] openSidePanel'
-)
-
-export const uiStateCollapseSidePanel = createAction(
-  '[uiState] collapseSidePanelCurrentView'
-)
-
-export const uiStateExpandSidePanel = createAction(
-  '[uiState] expandSidePanelCurrentView'
-)
-
-export const uiStateShowBottomSheet = createAction(
-  '[uiState] showBottomSheet',
-  props<{ bottomSheetTemplate: TemplateRef<unknown>, config?: MatBottomSheetConfig }>()
-)
-
-export const uiActionMouseoverLandmark = createAction(
-  `[uiState] mouseoverLandmark`,
-  props<{ landmark: string }>()
-)
-
-export const uiActionMouseoverSegments = createAction(
-  `[uiState] mouseoverSegments`,
-  props<{ segments: any[] }>()
-)
-
-export const uiActionSetPreviewingDatasetFiles = createAction(
-  `[uiState] setDatasetPreviews`,
-  props<{previewingDatasetFiles: {datasetId: string, filename: string}[]}>()
-)
-
-export const uiActionShowSidePanelConnectivity = createAction(
-  `[uiState] showSidePanelConnectivity`
-)
-
-export const uiActionSnackbarMessage = createAction(
-  `[uiState] snackbarMessage`,
-  props<{snackbarMessage: string}>()
-)
\ No newline at end of file
diff --git a/src/services/state/uiState/common.ts b/src/services/state/uiState/common.ts
deleted file mode 100644
index dd5da3140f280c9cef5c7cd29637c2577f47587f..0000000000000000000000000000000000000000
--- a/src/services/state/uiState/common.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-export interface IUiState{
-
-  previewingDatasetFiles: {datasetId: string, filename: string}[]
-
-  mouseOverSegments: Array<{
-    layer: {
-      name: string
-    }
-    segment: any | null
-  }>
-  sidePanelIsOpen: boolean
-  sidePanelExploreCurrentViewIsOpen: boolean
-  mouseOverSegment: any | number
-
-  mouseOverLandmark: string
-  mouseOverUserLandmark: any
-
-  focusedSidePanel: string | null
-
-  snackbarMessage: symbol
-
-  agreedCookies: boolean
-  agreedKgTos: boolean
-}
diff --git a/src/services/state/userConfigState.helper.spec.ts b/src/services/state/userConfigState.helper.spec.ts
deleted file mode 100644
index e007700e80d5b030b8d2d70cb41e71d64dfcd136..0000000000000000000000000000000000000000
--- a/src/services/state/userConfigState.helper.spec.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import { selectorPluginCspPermission } from "./userConfigState.helper"
-
-describe('> userConfigState.helper.ts', () => {
-  describe('> selectorPluginCspPermission', () => {
-    const expectedTrue = {
-      value: true
-    }
-    const expectedFalse = {
-      value: false
-    }
-    describe('> malformed init value', () => {
-      describe('> undefined userconfigstate', () => {
-        it('> return expected false val', () => {
-          const returnVal = selectorPluginCspPermission.projector(null, { key: 'foo-bar' })
-          expect(returnVal).toEqual(expectedFalse)
-        })
-      })
-      describe('> undefined pluginCsp property', () => {
-        it('> return expected false val', () => {
-          const returnVal = selectorPluginCspPermission.projector({}, { key: 'foo-bar' })
-          expect(returnVal).toEqual(expectedFalse)
-        })
-      })
-    })
-
-    describe('> well fored init valu', () => {
-
-      describe('> undefined key', () => {
-        it('> return expected false val', () => {
-          const returnVal = selectorPluginCspPermission.projector({
-            pluginCsp: {'yes-man': true}
-          }, { key: 'foo-bar' })
-          expect(returnVal).toEqual(expectedFalse)
-        })
-      })
-
-      describe('> truthly defined key', () => {
-        it('> return expected true val', () => {
-          const returnVal = selectorPluginCspPermission.projector({ pluginCsp:
-            { 'foo-bar': true }
-          }, { key: 'foo-bar' })
-          expect(returnVal).toEqual(expectedTrue)
-        })
-      })
-    })
-  })
-})
\ No newline at end of file
diff --git a/src/services/state/userConfigState.helper.ts b/src/services/state/userConfigState.helper.ts
deleted file mode 100644
index e71be024c1947ccf0fc3f3aca909cebbceeaf046..0000000000000000000000000000000000000000
--- a/src/services/state/userConfigState.helper.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-import { createSelector } from "@ngrx/store"
-
-export const selectorPluginCspPermission = createSelector(
-  (state: any) => state.userConfigState,
-  (userConfigState: any, props: any = {}) => {
-    const { key } = props as { key: string }
-    return {
-      value: !!userConfigState?.pluginCsp?.[key]
-    } 
-  }
-)
diff --git a/src/services/state/userConfigState.store.spec.ts b/src/services/state/userConfigState.store.spec.ts
deleted file mode 100644
index 4f1b078d5298d3850bdc07148314234eee216889..0000000000000000000000000000000000000000
--- a/src/services/state/userConfigState.store.spec.ts
+++ /dev/null
@@ -1,88 +0,0 @@
-import { HttpClientTestingModule, HttpTestingController } from "@angular/common/http/testing"
-import { fakeAsync, TestBed, tick } from "@angular/core/testing"
-import { provideMockActions } from "@ngrx/effects/testing"
-import { Action } from "@ngrx/store"
-import { MockStore, provideMockStore } from "@ngrx/store/testing"
-import { from, Observable } from "rxjs"
-import { AngularMaterialModule } from "src/sharedModules"
-import { PureContantService } from "src/util"
-import { DialogService } from "../dialogService.service"
-import { actionUpdatePluginCsp, UserConfigStateUseEffect } from "./userConfigState.store"
-import { viewerStateSelectedParcellationSelector, viewerStateSelectedRegionsSelector, viewerStateSelectedTemplateSelector } from "./viewerState/selectors"
-
-describe('> userConfigState.store.spec.ts', () => {
-  describe('> UserConfigStateUseEffect', () => {
-    let action$: Observable<Action>
-    beforeEach(() => {
-      TestBed.configureTestingModule({
-        imports: [
-          HttpClientTestingModule,
-          AngularMaterialModule,
-        ],
-        providers: [
-          provideMockActions(() => action$),
-          provideMockStore({
-            initialState: {
-              viewerConfigState: {
-                gpuLimit: 1e9,
-                animation: true
-              }
-            }
-          }),
-          DialogService,
-          {
-            provide: PureContantService,
-            useValue: {
-              backendUrl: 'http://localhost:3000/'
-            }
-          }
-        ]
-      })
-
-      const mockStore = TestBed.inject(MockStore)
-      mockStore.overrideSelector(viewerStateSelectedTemplateSelector, null)
-      mockStore.overrideSelector(viewerStateSelectedParcellationSelector, null)
-      mockStore.overrideSelector(viewerStateSelectedRegionsSelector, [])
-    })
-
-    it('> can be init', () => {
-      const useEffect = TestBed.inject(UserConfigStateUseEffect)
-      expect(useEffect).toBeTruthy()
-    })
-    describe('> setInitPluginPermission$', () => {
-      let mockHttp: HttpTestingController
-      let useEffect: UserConfigStateUseEffect
-      const mockpluginPer = {
-        'foo-bar': {
-          'script-src': [
-            '1',
-            '2',
-          ]
-        }
-      }
-      beforeEach(() => {
-        mockHttp = TestBed.inject(HttpTestingController)
-        useEffect = TestBed.inject(UserConfigStateUseEffect)
-      })
-      afterEach(() => {
-        mockHttp.verify()
-      })
-      it('> calls /GET user/pluginPermissions', fakeAsync(() => {
-        let val
-        useEffect.setInitPluginPermission$.subscribe(v => val = v)
-        tick(20)
-        const req = mockHttp.expectOne(`http://localhost:3000/user/pluginPermissions`)
-        req.flush(mockpluginPer)
-        expect(val).toEqual(actionUpdatePluginCsp({ payload: mockpluginPer }))
-      }))
-
-      it('> if get fn fails', fakeAsync(() => {
-        let val
-        useEffect.setInitPluginPermission$.subscribe(v => val = v)
-        const req = mockHttp.expectOne(`http://localhost:3000/user/pluginPermissions`)
-        req.error(null, { status: 500, statusText: 'Internal Error' })
-        expect(val).toEqual(actionUpdatePluginCsp({ payload: {} }))
-      }))
-    })
-  })
-})
\ No newline at end of file
diff --git a/src/services/state/viewerConfig.store.helper.ts b/src/services/state/viewerConfig.store.helper.ts
deleted file mode 100644
index 7dc4a3c6c184e0f56ea034d9990c5dff58e52825..0000000000000000000000000000000000000000
--- a/src/services/state/viewerConfig.store.helper.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-import { createSelector } from "@ngrx/store"
-
-export const VIEWER_CONFIG_FEATURE_KEY = 'viewerConfigState'
-export interface IViewerConfigState {
-  gpuLimit: number
-  animation: boolean
-  useMobileUI: boolean
-}
-
-// export const viewerConfigSelectorUseMobileUi = createSelector(
-//   state => state[VIEWER_CONFIG_FEATURE_KEY],
-//   viewerConfigState => viewerConfigState.useMobileUI
-// )
diff --git a/src/services/state/viewerState/actions.ts b/src/services/state/viewerState/actions.ts
deleted file mode 100644
index aa5b5aad286a38154a281d31ee58d489712f08d0..0000000000000000000000000000000000000000
--- a/src/services/state/viewerState/actions.ts
+++ /dev/null
@@ -1,26 +0,0 @@
-import { createAction, props } from "@ngrx/store"
-
-export const viewerStateNavigateToRegion = createAction(
-  `[viewerState] navigateToRegion`,
-  props<{ payload: { region: any } }>()
-)
-
-export const viewerStateSelectTemplateWithId = createAction(
-  `[viewerState] selectTemplateWithId`,
-  props<{ payload: { ['@id']: string }, config?: { selectParcellation: { ['@id']: string } } }>()
-)
-
-export const viewerStateAddUserLandmarks = createAction(
-  `[viewerState] addUserlandmark,`,
-  props<{ landmarks: any[] }>()
-)
-
-export const viewerStateMouseOverCustomLandmark = createAction(
-  '[viewerState] mouseOverCustomLandmark',
-  props<{ payload: { userLandmark: any } }>()
-)
-
-export const viewerStateMouseOverCustomLandmarkInPerspectiveView = createAction(
-  `[viewerState] mouseOverCustomLandmarkInPerspectiveView`,
-  props<{ payload: { label: string } }>()
-)
diff --git a/src/services/state/viewerState/constants.ts b/src/services/state/viewerState/constants.ts
deleted file mode 100644
index dbfa8c7800f0cc602fe1b1f942b7088552fe20ce..0000000000000000000000000000000000000000
--- a/src/services/state/viewerState/constants.ts
+++ /dev/null
@@ -1,4 +0,0 @@
-export interface IRegion{
-  name: string
-  [key: string]: string
-}
diff --git a/src/services/state/viewerState/selectors.spec.ts b/src/services/state/viewerState/selectors.spec.ts
deleted file mode 100644
index e5916b75e671cdb281508c796106e9de484ff7f3..0000000000000000000000000000000000000000
--- a/src/services/state/viewerState/selectors.spec.ts
+++ /dev/null
@@ -1,289 +0,0 @@
-import {
-  viewerStateGetOverlayingAdditionalParcellations,
-  viewerStateAtlasParcellationSelector,
-  viewerStateAtlasLatestParcellationSelector,
-  viewerStateParcVersionSelector,
-  selectorSelectedATP,
-  viewerStateGetSelectedAtlas,
-  viewerStateSelectedTemplateSelector,
-  viewerStateSelectedParcellationSelector,
-} from './selectors'
-
-
-const atlas1 = {
-  '@id': 'atlas-1',
-  name: 'atlas-1-name',
-  templateSpaces: [
-    {
-      '@id': 'atlas-1-tmpl-1',
-      name: 'atlas-1-tmpl-1',
-      availableIn: [
-        {
-          '@id': 'atlas-1-parc-1',
-          name: 'atlas-1-parc-1'
-        },
-        {
-          '@id': 'atlas-1-parc-2',
-          name: 'atlas-1-parc-2'
-        }
-      ]
-    }
-  ],
-  parcellations: [
-    {
-      '@id': 'atlas-1-parc-1',
-      name: 'atlas-1-parc-1',
-      baseLayer: true
-    },
-    {
-      '@id': 'atlas-1-parc-2',
-      name: 'atlas-1-parc-2'
-    }
-  ]
-}
-
-const tmpl1 = {
-  '@id': 'atlas-1-tmpl-1',
-  name: 'atlas-1-tmpl-1',
-  parcellations: [
-    {
-      '@id': 'atlas-1-parc-1',
-      name: 'atlas-1-parc-1'
-    },
-    {
-      '@id': 'atlas-1-parc-2',
-      name: 'atlas-1-parc-2'
-    }
-  ]
-}
-
-const atlas2 = {
-  '@id': 'atlas-2',
-  name: 'atlas-2-name',
-  templateSpaces: [
-    {
-      '@id': 'atlas-2-tmpl-1',
-      name: 'atlas-2-tmpl-1',
-      availableIn: [
-        {
-          '@id': 'atlas-2-parc-1',
-          name: 'atlas-2-parc-1'
-        },
-        {
-          '@id': 'atlas-2-parc-2',
-          name: 'atlas-2-parc-2'
-        }
-      ]
-    },
-    {
-      '@id': 'atlas-2-tmpl-2',
-      name: 'atlas-2-tmpl-2',
-      availableIn: [
-        {
-          '@id': 'atlas-2-parc-1',
-          name: 'atlas-2-parc-1'
-        },
-        {
-          '@id': 'atlas-2-parc-2',
-          name: 'atlas-2-parc-2'
-        }
-      ]
-    }
-  ],
-  parcellations: [
-    {
-      '@id': 'atlas-2-parc-1',
-      name: 'atlas-2-parc-1',
-      "@version": {
-        "@next": "atlas-2-parc-2",
-        "@this": "atlas-2-parc-1",
-        "name": "atlas-2-parc-1",
-        "@previous": null
-      }
-    },
-    {
-      '@id': 'atlas-2-parc-2',
-      name: 'atlas-2-parc-2',
-      "@version": {
-        "@next": null,
-        "@this": "atlas-2-parc-2",
-        "name": "atlas-2-parc-2",
-        "@previous": "atlas-2-parc-1"
-      }
-    }
-  ]
-}
-
-const tmpl2 = {
-  '@id': 'atlas-2-tmpl-1',
-  name: 'atlas-2-tmpl-1',
-  parcellations: [
-    {
-      '@id': 'atlas-2-parc-1',
-      name: 'atlas-2-parc-1'
-    },
-    {
-      '@id': 'atlas-2-parc-2',
-      name: 'atlas-2-parc-2'
-    }
-  ]
-}
-
-
-const tmpl2_2 = {
-  '@id': 'atlas-2-tmpl-2',
-  name: 'atlas-2-tmpl-2',
-  parcellations: [
-    {
-      '@id': 'atlas-2-parc-1',
-      name: 'atlas-2-parc-1'
-    },
-    {
-      '@id': 'atlas-2-parc-2',
-      name: 'atlas-2-parc-2'
-    }
-  ]
-}
-
-const fetchedAtlases = [
-  atlas1,
-  atlas2
-]
-
-const fetchedTemplates = [
-  tmpl1,
-  tmpl2,
-  tmpl2_2
-]
-
-describe('viewerState/selector.ts', () => {
-  // describe('> viewerStateGetOverlayingAdditionalParcellations', () => {
-  //   describe('> if atlas has no basic layer', () => {
-  //     it('> should return empty array', () => {
-
-  //       const parcs = viewerStateGetOverlayingAdditionalParcellations.projector({
-  //         fetchedAtlases,
-  //         selectedAtlasId: atlas2['@id']
-  //       }, {
-  //         parcellationSelected: tmpl2.parcellations[0]
-  //       })
-        
-  //       expect(parcs).toEqual([])
-  //     })
-  //   })
-
-  //   describe('> if atlas has basic layer', () => {
-  //     describe('> if non basiclayer is selected', () => {
-  //       it('> should return non empty array', () => {
-  //         const parc = atlas1.parcellations.find(p => !p['baseLayer'])
-  //         const parcs = viewerStateGetOverlayingAdditionalParcellations.projector({
-  //           fetchedAtlases,
-  //           selectedAtlasId: atlas1['@id']
-  //         }, {
-  //           parcellationSelected: parc
-  //         })
-  //         expect(parcs.length).toEqual(1)
-  //         expect(parcs[0]['@id']).toEqual(parc['@id'])
-  //       })
-  //     })
-
-  //     describe('> if basic layer is selected', () => {
-  //       it('> should return empty array', () => {
-  //         const parc = atlas1.parcellations.find(p => !!p['baseLayer'])
-  //         const parcs = viewerStateGetOverlayingAdditionalParcellations.projector({
-  //           fetchedAtlases,
-  //           selectedAtlasId: atlas1['@id']
-  //         }, {
-  //           parcellationSelected: parc
-  //         })
-  //         expect(parcs.length).toEqual(0)
-  //       })
-  //     })
-  //   })
-  // })
-
-  // describe('> viewerStateAtlasParcellationSelector', () => {
-  //   const check = (atlasJson, templates) => {
-
-  //     const parcs = viewerStateAtlasParcellationSelector.projector({
-  //       fetchedAtlases,
-  //       selectedAtlasId: atlasJson['@id']
-  //     }, {
-  //       fetchedTemplates
-  //     })
-  //     const templateParcs = []
-  //     for (const tmpl of templates) {
-  //       templateParcs.push(...tmpl.parcellations)
-  //     }
-  //     for (const parc of parcs) {
-  //       const firstHalf = templateParcs.find(p => p['@id'] === parc['@id'])
-  //       const secondHalf = atlasJson.parcellations.find(p => p['@id'] === parc['@id'])
-  //       expect(firstHalf).toBeTruthy()
-  //       expect(secondHalf).toBeTruthy()
-  //       //TODO compare strict equality of firsthalf+secondhalf with parc
-  //     }
-  //   }
-
-  //   it('> should work', () => {
-  //     check(atlas1, [tmpl1, tmpl2, tmpl2_2])
-  //     check(atlas2, [tmpl1, tmpl2, tmpl2_2])
-  //   })
-  // })
-
-  // describe('> viewerStateAtlasLatestParcellationSelector', () => {
-  //   it('> should only show 1 parc', () => {
-  //     const parcs = viewerStateAtlasLatestParcellationSelector.projector(atlas2.parcellations)
-  //     expect(parcs.length).toEqual(1)
-  //   })
-  // })
-
-  // describe('> viewerStateParcVersionSelector', () => {
-  //   it('> should work', () => {
-  //     const parcs = viewerStateParcVersionSelector.projector(atlas2.parcellations, {
-  //       parcellationSelected: atlas2.parcellations[0]
-  //     })
-  //     expect(parcs.length).toEqual(2)
-
-  //     expect(parcs[0]['@version']['@next']).toBeFalsy()
-  //     expect(parcs[parcs.length-1]['@version']['@previous']).toBeFalsy()
-  //   })
-  // })
-
-  describe("> viewerStateGetSelectedAtlas", () => {
-    it("> projects properly", () => {
-      const atlas1 = {
-        "@id": "atlas1"
-      }
-      const atlas2 = {
-        "@id": "atlas2"
-      }
-      const atlas3 = {
-        "@id": "atlas3"
-      }
-      const allAtlases = [ atlas1, atlas2, atlas3 ]
-      const result = viewerStateGetSelectedAtlas.projector({
-        fetchedAtlases: allAtlases,
-        overlayingAdditionalParcellations: [],
-        selectedAtlasId: atlas1["@id"]
-      })
-      expect(result).toEqual(atlas1 as any)
-    })
-  })
-
-  describe("> selectorSelectedATP", () => {
-    const mockAtlas = {
-      "@id": "mock atlas"
-    } as any
-    const mockTmpl = {
-      "@id": "mock Tmpl"
-    } as any
-    const mockParc = {
-      "@id": "mock Parc"
-    } as any
-
-    it("> transforms the selectors properly", () => {
-      const result = selectorSelectedATP.projector(mockAtlas,mockTmpl,mockParc)
-      expect(result).toEqual({ atlas: mockAtlas, template: mockTmpl, parcellation: mockParc })
-    })
-  })
-})
\ No newline at end of file
diff --git a/src/services/state/viewerState/selectors.ts b/src/services/state/viewerState/selectors.ts
deleted file mode 100644
index c752e8aeae91104be3fd789cf7829894361ff9e3..0000000000000000000000000000000000000000
--- a/src/services/state/viewerState/selectors.ts
+++ /dev/null
@@ -1,188 +0,0 @@
-// import { createSelector } from "@ngrx/store"
-// import { SapiAtlasModel, SapiParcellationModel, SapiSpaceModel } from "src/atlasComponents/sapi"
-// import { SapiRegionModel } from "src/atlasComponents/sapi/type"
-// import { viewerStateHelperStoreName, IViewerStateHelperStore } from "../viewerState.store.helper"
-// import { IViewerState } from "./type"
-
-// import {
-//   selectors as atlasSelectionSelectors
-// } from "src/state/atlasSelection"
-
-// const {
-//   selectedATP: selectorSelectedATP,
-//   selectedAtlas: viewerStateGetSelectedAtlas,
-//   selectedParcellation: viewerStateSelectedParcellationSelector,
-//   selectedTemplate: viewerStateSelectedTemplateSelector,
-// } = atlasSelectionSelectors
-
-
-// const viewerStateSelectedRegionsSelector = createSelector<any, any, SapiRegionModel[]>(
-//   state => state['viewerState'],
-//   viewerState => viewerState['regionsSelected']
-// )
-
-// const viewerStateCustomLandmarkSelector = createSelector(
-//   state => state['viewerState'],
-//   viewerState => viewerState['userLandmarks']
-// )
-
-// const flattenFetchedTemplatesIntoParcellationsReducer = (acc, curr) => {
-//   const parcelations = (curr['parcellations'] || []).map(p => {
-//     return {
-//       ...p,
-//       useTheme: curr['useTheme']
-//     }
-//   })
-
-//   return acc.concat( parcelations )
-// }
-
-// const viewerStateFetchedTemplatesSelector = createSelector(
-//   state => state['viewerState'],
-//   viewerState => viewerState['fetchedTemplates']
-// )
-
-// const viewerStateSelectorFeatureSelector = createSelector(
-//   (state: any) => state.viewerState as IViewerState,
-//   viewerState => viewerState.featureSelected
-// )
-
-// /**
-//  * viewerStateSelectedTemplateSelector may have it navigation mutated to allow for initiliasation of viewer at the correct navigation
-//  * in some circumstances, it may be required to get the original navigation object
-//  */
-// const viewerStateSelectedTemplatePureSelector = createSelector(
-//   viewerStateFetchedTemplatesSelector,
-//   viewerStateSelectedTemplateSelector,
-//   (fetchedTemplates, selectedTemplate) => {
-//     if (!selectedTemplate) return null
-//     return fetchedTemplates.find(t => t['@id'] === selectedTemplate['@id'])
-//   }
-// )
-
-// const viewerStateNavigationStateSelector = createSelector(
-//   state => state['viewerState'],
-//   viewerState => viewerState['navigation']
-// )
-
-// const viewerStateOverwrittenColorMapSelector = createSelector(
-//   state => state['viewerState'],
-//   viewerState => viewerState['overwrittenColorMap']
-// )
-
-// const viewerStateSelectorNavigation = createSelector(
-//   state => state['viewerState'],
-//   viewerState => viewerState['navigation']
-// )
-
-// const viewerStateViewerModeSelector = createSelector(
-//   state => state['viewerState'],
-//   viewerState => viewerState['viewerMode']
-// )
-
-// const viewerStateGetOverlayingAdditionalParcellations = createSelector(
-//   state => state[viewerStateHelperStoreName],
-//   state => state['viewerState'],
-//   (viewerHelperState, viewerState ) => {
-//     const { selectedAtlasId, fetchedAtlases } = viewerHelperState
-//     const { parcellationSelected } = viewerState
-//     const selectedAtlas = selectedAtlasId && fetchedAtlases.find(a => a['@id'] === selectedAtlasId)
-//     const hasBaseLayer = selectedAtlas?.parcellations.find(p => p.baseLayer)
-//     if (!hasBaseLayer) return []
-//     const atlasLayer =  selectedAtlas?.parcellations.find(p => p['@id'] === (parcellationSelected && parcellationSelected['@id']))
-//     const isBaseLayer = atlasLayer && atlasLayer.baseLayer
-//     return (!!atlasLayer && !isBaseLayer) ? [{
-//       ...(parcellationSelected || {} ),
-//       ...atlasLayer
-//     }] : []
-//   }
-// )
-
-// const viewerStateFetchedAtlasesSelector = createSelector<any, any, SapiAtlasModel[]>(
-//   state => state[viewerStateHelperStoreName],
-//   helperState => helperState['fetchedAtlases']
-// )
-
-
-// const viewerStateAtlasParcellationSelector = createSelector(
-//   state => state[viewerStateHelperStoreName],
-//   state => state['viewerState'],
-//   (viewerHelperState, viewerState) => {
-//     const { selectedAtlasId, fetchedAtlases } = viewerHelperState
-//     const { fetchedTemplates } = viewerState
-
-//     const allParcellations = fetchedTemplates.reduce(flattenFetchedTemplatesIntoParcellationsReducer, [])
-
-//     const selectedAtlas = selectedAtlasId && fetchedAtlases.find(a => a['@id'] === selectedAtlasId)
-//     const atlasLayers = selectedAtlas?.parcellations
-//       .map(p => {
-//         const otherHalfOfParc = allParcellations.find(parc => parc['@id'] === p['@id']) || {}
-//         return {
-//           ...p,
-//           ...otherHalfOfParc,
-//         }
-//       })
-//     return atlasLayers
-//   }
-// )
-
-// const viewerStateAtlasLatestParcellationSelector = createSelector(
-//   viewerStateAtlasParcellationSelector,
-//   parcs => (parcs && parcs.filter( p => !p['@version'] || !p['@version']['@next']) || [])
-// )
-
-// const viewerStateParcVersionSelector = createSelector(
-//   viewerStateAtlasParcellationSelector,
-//   state => state['viewerState'],
-//   (allAtlasParcellations, viewerState) => {
-//     if (!viewerState || !viewerState.parcellationSelected) return []
-//     const returnParc = []
-//     const foundParc = allAtlasParcellations.find(p => p['@id'] === viewerState.parcellationSelected['@id'])
-//     if (!foundParc) return []
-//     returnParc.push(foundParc)
-//     const traverseParc = parc => {
-//       if (!parc) return []
-//       if (!parc['@version']) return []
-//       if (parc['@version']['@next']) {
-//         const nextParc = allAtlasParcellations.find(p => p['@id'] === parc['@version']['@next'])
-//         if (nextParc) {
-//           const nextParcAlreadyIncluded = returnParc.find(p => p['@id'] === nextParc['@id'])
-//           if (!nextParcAlreadyIncluded) {
-//             returnParc.unshift(nextParc)
-//             traverseParc(nextParc)
-//           }
-//         }
-//       }
-
-//       if (parc['@version']['@previous']) {
-//         const previousParc = allAtlasParcellations.find(p => p['@id'] === parc['@version']['@previous'])
-//         if (previousParc) {
-//           const previousParcAlreadyIncluded = returnParc.find(p => p['@id'] === previousParc['@id'])
-//           if (!previousParcAlreadyIncluded) {
-//             returnParc.push(previousParc)
-//             traverseParc(previousParc)
-//           }
-//         }
-//       }
-//     }
-//     traverseParc(foundParc)
-//     return returnParc
-//   }
-// )
-
-// const viewerStateContextedSelectedRegionsSelector = createSelector(
-//   viewerStateSelectedRegionsSelector,
-//   viewerStateGetSelectedAtlas,
-//   viewerStateSelectedTemplatePureSelector,
-//   viewerStateSelectedParcellationSelector,
-//   (regions, atlas, template, parcellation) => regions.map(r => {
-//     return {
-//       ...r,
-//       context: {
-//         atlas,
-//         template,
-//         parcellation
-//       }
-//     }
-//   })
-// )
diff --git a/src/services/state/viewerState/type.ts b/src/services/state/viewerState/type.ts
deleted file mode 100644
index 58bf80a3e7abd4dbea84b24c1e41e96b268677c3..0000000000000000000000000000000000000000
--- a/src/services/state/viewerState/type.ts
+++ /dev/null
@@ -1,40 +0,0 @@
-import { IUserLandmark } from 'src/atlasViewer/atlasViewer.apiService.service';
-import { INgLayerInterface } from 'src/atlasViewer/atlasViewer.component';
-
-export interface IViewerState {
-  fetchedTemplates: any[]
-
-  templateSelected: any | null
-  parcellationSelected: any | null
-  regionsSelected: any[]
-
-  viewerMode: string
-
-  landmarksSelected: any[]
-  userLandmarks: IUserLandmark[]
-
-  navigation: any | null
-
-  loadedNgLayers: INgLayerInterface[]
-  connectivityRegion: string | null
-  overwrittenColorMap: string | null
-
-  standaloneVolumes: any[]
-}
-
-
-export const defaultViewerState: IViewerState = {
-
-  landmarksSelected : [],
-  fetchedTemplates : [],
-  loadedNgLayers: [],
-  regionsSelected: [],
-  viewerMode: null,
-  userLandmarks: [],
-  navigation: null,
-  parcellationSelected: null,
-  templateSelected: null,
-  connectivityRegion: '',
-  overwrittenColorMap: null,
-  standaloneVolumes: []
-}
diff --git a/src/services/stateStore.helper.ts b/src/services/stateStore.helper.ts
deleted file mode 100644
index 172c58258dec163d118529afe22aeb3ef4af1ce4..0000000000000000000000000000000000000000
--- a/src/services/stateStore.helper.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { createAction, props } from "@ngrx/store";
-
-export const GENERAL_ACTION_TYPES = {
-  APPLY_STATE: 'APPLY_STATE',
-}
-
-export const generalApplyState = createAction(
-  GENERAL_ACTION_TYPES.APPLY_STATE,
-  props<{ state: any }>()
-)
-
-export const generalActionError = createAction(
-  `[generalActionError]`,
-  props<{ message: string }>()
-)
diff --git a/src/services/stateStore.service.spec.ts b/src/services/stateStore.service.spec.ts
deleted file mode 100644
index 1fb8e0058c9d33c10a4fa249d435e9f84c84f7ce..0000000000000000000000000000000000000000
--- a/src/services/stateStore.service.spec.ts
+++ /dev/null
@@ -1,144 +0,0 @@
-import { getMultiNgIdsRegionsLabelIndexMap } from './stateStore.service'
-
-const getRandomDummyData = () => Math.round(Math.random() * 1000).toString(16)
-
-const region1 = {
-  name: 'region 1',
-  labelIndex: 15,
-  ngId: 'left',
-  dummydata: getRandomDummyData()
-}
-const region2 = {
-  name: 'region 2',
-  labelIndex: 16,
-  ngId: 'right',
-  dummydata: getRandomDummyData()
-}
-const region3 = {
-  name: 'region 3',
-  labelIndex: 17,
-  ngId: 'right',
-  dummydata: getRandomDummyData()
-}
-
-const dummyParcellationWithNgId = {
-  name: 'dummy parcellation name',
-  regions: [
-    region1,
-    region2,
-    region3
-  ]
-}
-
-const dummyParcellationWithoutNgId = {
-  name: 'dummy parcellation name',
-  ngId: 'toplevel',
-  regions: [
-    region1,
-    region2,
-    region3
-  ].map(({ ngId, ...rest }) => {
-    return {
-      ...rest,
-      ...(ngId === 'left' ? { ngId } : {})
-    }
-  })
-}
-
-describe('stateStore.service.ts', () => {
-  describe('getMultiNgIdsRegionsLabelIndexMap', () => {
-    describe('should not mutate original regions', () => {
-      
-    })
-
-    describe('should populate map properly', () => {
-      const map = getMultiNgIdsRegionsLabelIndexMap(dummyParcellationWithNgId)
-      it('populated map should have 2 top level', () => {
-        expect(map.size).toBe(2)
-      })
-
-      it('should container left and right top level', () => {
-        expect(map.get('left')).toBeTruthy()
-        expect(map.get('right')).toBeTruthy()
-      })
-
-      it('left top level should have 1 member', () => {
-        const leftMap = map.get('left')
-        expect(leftMap.size).toBe(1)
-      })
-
-      it('left top level should map 15 => region1', () => {
-        const leftMap = map.get('left')
-        expect(leftMap.get(15)).toEqual(region1)
-      })
-
-      it('right top level should have 2 member', () => {
-        const rightMap = map.get('right')
-        expect(rightMap.size).toBe(2)
-      })
-
-      it('right top level should map 16 => region2, 17 => region3', () => {
-        const rightMap = map.get('right')
-        expect(rightMap.get(16)).toEqual(region2)
-        expect(rightMap.get(17)).toEqual(region3)
-      })
-    })
-
-    describe('should allow inheritance of ngId', () => {
-
-      const map = getMultiNgIdsRegionsLabelIndexMap(dummyParcellationWithoutNgId)
-      it('populated map should have 2 top level', () => {
-        expect(map.size).toBe(2)
-      })
-
-      it('should container left and right top level', () => {
-        expect(map.get('left')).toBeTruthy()
-        expect(map.get('toplevel')).toBeTruthy()
-      })
-
-      it('left top level should have 1 member', () => {
-        const leftMap = map.get('left')
-        expect(leftMap.size).toBe(1)
-      })
-
-      it('left top level should map 15 => region1', () => {
-        const leftMap = map.get('left')
-        expect(leftMap.get(15)).toEqual(region1)
-      })
-
-      it('toplevel top level should have 2 member', () => {
-        const toplevelMap = map.get('toplevel')
-        expect(toplevelMap.size).toBe(2)
-      })
-
-      it('toplevel top level should map 16 => region2, 17 => region3', () => {
-        const toplevelMap = map.get('toplevel')
-        expect(toplevelMap.get(16).dummydata).toEqual(region2.dummydata)
-        expect(toplevelMap.get(17).dummydata).toEqual(region3.dummydata)
-      })
-    })
-
-    describe('should allow inheritance of attr when specified', () => {
-      const attr = {
-        dummyattr: 'default dummy attr'
-      }
-      const map = getMultiNgIdsRegionsLabelIndexMap({
-        ...dummyParcellationWithNgId,
-        dummyattr: 'p dummy attr'
-      }, attr)
-      it('every region should have dummyattr set properly', () => {
-        let regions = []
-        for (const [ _key1, mMap ] of Array.from(map)) {
-          for (const [_key2, rs] of Array.from(mMap)) {
-            regions = [...regions, rs]
-          }
-        }
-        
-        for (const r of regions) {
-          expect(r.dummyattr).toEqual('p dummy attr')
-        }
-      })
-
-    })
-  })
-})
\ No newline at end of file
diff --git a/src/services/stateStore.service.ts b/src/services/stateStore.service.ts
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/state/actions.ts b/src/state/actions.ts
index 2465c644ab5cd842e2e9f9f9537b10c1a51f155b..2b29757e099d292ee870c3115a26e906a814b7d2 100644
--- a/src/state/actions.ts
+++ b/src/state/actions.ts
@@ -1,13 +1,16 @@
 import { createAction, props } from "@ngrx/store";
-import { nameSpace } from "./const"
+import { MainState, nameSpace } from "./const"
 
-const generalActionError = createAction(
+export const generalActionError = createAction(
   `${nameSpace} generalActionError`,
   props<{
     message: string
   }>()
 )
 
-export const actions = {
-  generalActionError
-}
+export const generalApplyState = createAction(
+  `${nameSpace} generalApplyState`,
+  props<{
+    state: MainState
+  }>()
+)
diff --git a/src/state/atlasAppearance/action.ts b/src/state/atlasAppearance/action.ts
index 27461e622489e29cc7c4d85563a0a7331de092dc..6a4ce26e148d801c726ba23c3eee906e736aa510 100644
--- a/src/state/atlasAppearance/action.ts
+++ b/src/state/atlasAppearance/action.ts
@@ -1,12 +1,5 @@
 import { createAction, props } from "@ngrx/store";
-import { nameSpace } from "./const"
-
-export const overwriteColorMap = createAction(
-  `${nameSpace} overwriteColorMap`,
-  props<{
-    colormap: Record<string, number[]>
-  }>()
-)
+import { CustomLayer, nameSpace } from "./const"
 
 export const setOctantRemoval = createAction(
   `${nameSpace} setOctantRemoval`,
@@ -20,4 +13,18 @@ export const setShowDelineation = createAction(
   props<{
     flag: boolean
   }>()
-)
\ No newline at end of file
+)
+
+export const addCustomLayer = createAction(
+  `${nameSpace} addCustomLayer`,
+  props<{
+    customLayer: CustomLayer
+  }>()
+)
+
+export const removeCustomLayer = createAction(
+  `${nameSpace} removeCustomLayer`,
+  props<{
+    id: string
+  }>()
+)
diff --git a/src/state/atlasAppearance/const.ts b/src/state/atlasAppearance/const.ts
index ee9d2e45f3c36217015b6c2a18e7e6cd4721ea9e..17ebe814184485cbdc24dd05553f68c8397c1cf1 100644
--- a/src/state/atlasAppearance/const.ts
+++ b/src/state/atlasAppearance/const.ts
@@ -1 +1,39 @@
-export const nameSpace = `[state.atlasAppearance]`
\ No newline at end of file
+import { SAPIRegion } from "src/atlasComponents/sapi/core"
+export const nameSpace = `[state.atlasAppearance]`
+
+type CustomLayerBase = {
+  id: string
+}
+
+export type ColorMapCustomLayer = {
+  clType: 'customlayer/colormap' | 'baselayer/colormap'
+  colormap: WeakMap<SAPIRegion, number[]>
+} & CustomLayerBase
+
+export type NgLayerCustomLayer = {
+  clType: 'customlayer/nglayer' | 'baselayer/nglayer'
+  source: string
+  visible?: boolean
+  shader?: string
+  transform?: number[][]
+  opacity?: number
+  segments?: (number|string)[]
+  // type?: string
+
+  // annotation?: string // TODO what is this used for?
+} & CustomLayerBase
+
+/**
+ * custom layer is a catch all term that apply **any** special looks
+ * to an atlas. it could include:
+ * 
+ * - different colormap
+ * - different volume (pmap)
+ * - different indicies
+ * 
+ * It is up to the viewer on how to interprete these information.
+ * each instance **must** contain a clType and an id
+ * - clType facilitates viewer on how to interprete the custom layer
+ * - id allows custom layer to be removed, if necessary
+ */
+export type CustomLayer = ColorMapCustomLayer | NgLayerCustomLayer
diff --git a/src/state/atlasAppearance/index.ts b/src/state/atlasAppearance/index.ts
index bbbe62696bb68c5448b30b1aa3be6c2a55434658..6d95a7d9cbaf54679e0040637bda231b79003f1c 100644
--- a/src/state/atlasAppearance/index.ts
+++ b/src/state/atlasAppearance/index.ts
@@ -1,4 +1,4 @@
 export * as actions from "./action"
 export * as selectors from "./selector"
-export { nameSpace } from "./const"
-export { reducer } from "./store"
\ No newline at end of file
+export { nameSpace, ColorMapCustomLayer, CustomLayer, NgLayerCustomLayer } from "./const"
+export { reducer, AtlasAppearanceStore } from "./store"
\ No newline at end of file
diff --git a/src/state/atlasAppearance/selector.ts b/src/state/atlasAppearance/selector.ts
index 842d2db0f527eba5538a5bf34a06ed2ed3b58d40..b7eac7bc1701c6e490a6a72ccd9cf8412d4e7aeb 100644
--- a/src/state/atlasAppearance/selector.ts
+++ b/src/state/atlasAppearance/selector.ts
@@ -4,11 +4,6 @@ import { AtlasAppearanceStore } from "./store"
 
 const selectStore = state => state[nameSpace] as AtlasAppearanceStore
 
-export const getOverwrittenColormap = createSelector(
-  selectStore,
-  state => state.overwrittenColormap
-)
-
 export const octantRemoval = createSelector(
   selectStore,
   state => state.octantRemoval
@@ -17,4 +12,9 @@ export const octantRemoval = createSelector(
 export const showDelineation = createSelector(
   selectStore,
   state => state.showDelineation
-)
\ No newline at end of file
+)
+
+export const customLayers = createSelector(
+  selectStore,
+  state => state.customLayers
+)
diff --git a/src/state/atlasAppearance/store.ts b/src/state/atlasAppearance/store.ts
index 476da05585d4fe905386bbacbadf8ba16c6e5ff2..648104a70910a795d74c2de55c4bd12b5abe9b6e 100644
--- a/src/state/atlasAppearance/store.ts
+++ b/src/state/atlasAppearance/store.ts
@@ -1,45 +1,62 @@
 import { createReducer, on } from "@ngrx/store"
 import * as actions from "./action"
+import { CustomLayer } from "./const"
 
 export type AtlasAppearanceStore = {
-  overwrittenColormap: Record<string, number[]>
+
   octantRemoval: boolean
   showDelineation: boolean
+  customLayers: CustomLayer[]
 }
 
 const defaultState: AtlasAppearanceStore = {
-  overwrittenColormap: null,
   octantRemoval: true,
   showDelineation: true,
+  customLayers: []
 }
 
 export const reducer = createReducer(
   defaultState,
   on(
-    actions.overwriteColorMap,
-    (state, { colormap }) => {
+    actions.setOctantRemoval,
+    (state, { flag }) => {
       return {
         ...state,
-        overwrittenColormap: colormap
+        octantRemoval: flag
       }
     }
   ),
   on(
-    actions.setOctantRemoval,
+    actions.setShowDelineation,
     (state, { flag }) => {
       return {
         ...state,
-        octantRemoval: flag
+        showDelineation: flag
       }
     }
   ),
   on(
-    actions.setShowDelineation,
-    (state, { flag }) => {
+    actions.addCustomLayer,
+    (state, { customLayer }) => {
+      const { customLayers } = state
+
       return {
         ...state,
-        showDelineation: flag
+        customLayers: [
+          customLayer,
+          ...customLayers.filter(l => l.id !== customLayer.id)
+        ]
       }
     }
   ),
+  on(
+    actions.removeCustomLayer,
+    (state, { id }) => {
+      const { customLayers } = state
+      return {
+        ...state,
+        customLayers: customLayers.filter(l => l.id !== id)
+      }
+    }
+  )
 )
diff --git a/src/state/atlasSelection/actions.ts b/src/state/atlasSelection/actions.ts
index 7d114fa5cd3a2acb7811f3d8d08c594e9c0d5164..d3f4f7735abe19dbc087da3c849a428b102dcfe0 100644
--- a/src/state/atlasSelection/actions.ts
+++ b/src/state/atlasSelection/actions.ts
@@ -1,6 +1,6 @@
 import { createAction, props } from "@ngrx/store";
 import { SapiAtlasModel, SapiParcellationModel, SapiRegionModel, SapiSpaceModel } from "src/atlasComponents/sapi";
-import { nameSpace, ViewerMode } from "./const"
+import { BreadCrumb, nameSpace, ViewerMode } from "./const"
 
 export const selectAtlas = createAction(
   `${nameSpace} selectAtlas`,
@@ -23,6 +23,13 @@ export const selectParcellation = createAction(
   }>()
 )
 
+export const setSelectedParcellationAllRegions = createAction(
+  `${nameSpace} setSelectedParcellationAllRegions`,
+  props<{
+    regions: SapiRegionModel[]
+  }>()
+)
+
 export const selectRegions = createAction(
   `${nameSpace} selectRegions`,
   props<{
@@ -57,6 +64,20 @@ export const setViewerMode = createAction(
   }>()
 )
 
+export const showBreadCrumb = createAction(
+  `${nameSpace} showBreadCrumb`,
+  props<{
+    breadcrumb: BreadCrumb
+  }>()
+)
+
+export const dismissBreadCrumb = createAction(
+  `${nameSpace} dismissBreadCrumb`,
+  props<{
+    id: string
+  }>()
+)
+
 export const clearSelectedRegions = createAction(
   `${nameSpace} clearSelectedRegions`
 )
@@ -78,6 +99,9 @@ export const clearStandAloneVolumes = createAction(
   `${nameSpace} clearStandAloneVolumes`
 )
 
+/**
+ * n.b. position in nm!
+ */
 export const navigateTo = createAction(
   `${nameSpace} navigateTo`,
   props<{
@@ -124,4 +148,4 @@ export const viewSelRegionInNewSpace = createAction(
     region: SapiRegionModel
     template: SapiSpaceModel
   }>()
-)
\ No newline at end of file
+)
diff --git a/src/state/atlasSelection/const.ts b/src/state/atlasSelection/const.ts
index 7e26794f3173ebf6b97ce8ab614c963e32685548..5ae1942f7be037d174612e9dbbb9b229065bbad9 100644
--- a/src/state/atlasSelection/const.ts
+++ b/src/state/atlasSelection/const.ts
@@ -1,2 +1,6 @@
 export const nameSpace = `[state.atlasSelection]`
-export type ViewerMode = 'annotating' | 'key frame'
\ No newline at end of file
+export type ViewerMode = 'annotating' | 'key frame'
+export type BreadCrumb = {
+  id: string
+  name: string
+}
diff --git a/src/state/atlasSelection/effects.ts b/src/state/atlasSelection/effects.ts
index 1dbaf44a16567047161aa0687fb0bb08a93813e8..e3c8e15da99ed5552519337487a94c497895b2b4 100644
--- a/src/state/atlasSelection/effects.ts
+++ b/src/state/atlasSelection/effects.ts
@@ -1,12 +1,14 @@
 import { Injectable } from "@angular/core";
 import { Actions, createEffect, ofType } from "@ngrx/effects";
-import { forkJoin, merge, of } from "rxjs";
-import { filter, map, mapTo, switchMap, withLatestFrom } from "rxjs/operators";
+import { forkJoin, from, merge, of } from "rxjs";
+import { filter, map, mapTo, switchMap, switchMapTo, withLatestFrom } from "rxjs/operators";
 import { SAPI } from "src/atlasComponents/sapi";
-import * as actions from "./actions"
-import { actions as generalAction } from "../actions"
+import * as mainActions from "../actions"
 import { select, Store } from "@ngrx/store";
-import { selectors } from '.'
+import { selectors, actions } from '.'
+import { fromRootStore } from "./util";
+import { ParcellationIsBaseLayer } from "src/atlasComponents/sapiViews/core/parcellation/parcellationIsBaseLayer.pipe";
+import { OrderParcellationByVersionPipe } from "src/atlasComponents/sapiViews/core/parcellation/parcellationVersion.pipe";
 
 @Injectable()
 export class Effect {
@@ -47,6 +49,19 @@ export class Effect {
     }),
   ))
 
+  onATPSelectionGetAndSetAllRegions = createEffect(() => this.store.pipe(
+    select(selectors.selectedATP),
+    filter(({ atlas, template, parcellation }) => !!atlas && !!template && !!parcellation),
+    switchMap(({ atlas, template, parcellation }) => 
+      this.sapiSvc.getParcRegions(atlas["@id"], parcellation["@id"], template["@id"])
+    ),
+    map(regions => 
+      actions.setSelectedParcellationAllRegions({
+        regions
+      })
+    )
+  ))
+
   onAtlasSelClearStandAloneVolumes = createEffect(() => this.action.pipe(
     ofType(actions.selectAtlas),
     mapTo(actions.setStandAloneVolumes({
@@ -63,11 +78,23 @@ export class Effect {
 
   onNonBaseLayerRemoval = createEffect(() => this.action.pipe(
     ofType(actions.clearNonBaseParcLayer),
-    mapTo(generalAction.generalActionError({
-      message: `NYI`
-    }))
+    switchMapTo(
+      this.store.pipe(
+        fromRootStore.allAvailParcs(this.sapiSvc),
+        map(parcs => {
+          const baseLayers = parcs.filter(this.parcellationIsBaseLayerPipe.transform)
+          const newestLayer = this.orderParcellationByVersionPipe.transform(baseLayers)
+          return actions.selectParcellation({
+            parcellation: newestLayer
+          })
+        })  
+      )
+    )
   ))
 
+  private parcellationIsBaseLayerPipe = new ParcellationIsBaseLayer()
+  private orderParcellationByVersionPipe = new OrderParcellationByVersionPipe()
+
   onClearStandAloneVolumes = createEffect(() => this.action.pipe(
     ofType(actions.clearStandAloneVolumes),
     mapTo(actions.setStandAloneVolumes({
@@ -82,22 +109,11 @@ export class Effect {
    */
   onSelectATPById = createEffect(() => this.action.pipe(
     ofType(actions.selectATPById),
-    mapTo(generalAction.generalActionError({
-      message: `NYI`
-    }))
-  ))
-
-  /**
-   * consider what happens if it was nehuba viewer?
-   * what happens if it was three surfer viewer?
-   */
-  onNavigateTo = createEffect(() => this.action.pipe(
-    ofType(actions.navigateTo),
-    mapTo(generalAction.generalActionError({
-      message: `NYI`
+    mapTo(mainActions.generalActionError({
+      message: `NYI, onSelectATPById`
     }))
   ))
-
+  
   onClearViewerMode = createEffect(() => this.action.pipe(
     ofType(actions.clearViewerMode),
     mapTo(actions.setViewerMode({ viewerMode: null }))
@@ -105,15 +121,15 @@ export class Effect {
 
   onToggleRegionSelectById = createEffect(() => this.action.pipe(
     ofType(actions.toggleRegionSelectById),
-    mapTo(generalAction.generalActionError({
-      message: `NYI`
+    mapTo(mainActions.generalActionError({
+      message: `NYI onToggleRegionSelectById`
     }))
   ))
 
   onNavigateToRegion = createEffect(() => this.action.pipe(
     ofType(actions.navigateToRegion),
-    mapTo(generalAction.generalActionError({
-      message: `NYI`
+    mapTo(mainActions.generalActionError({
+      message: `NYI onNavigateToRegion`
     }))
   ))
 
@@ -128,9 +144,16 @@ export class Effect {
       ofType(actions.selectParcellation)
     )
   ).pipe(
-    mapTo(actions.selectRegions({
-      regions: []
-    }))
+    switchMapTo(
+      of(
+        actions.selectRegions({
+          regions: []
+        }),
+        actions.setSelectedParcellationAllRegions({
+          regions: []
+        })
+      )
+    )
   ))
 
   onRegionToggleSelect = createEffect(() => this.action.pipe(
diff --git a/src/state/atlasSelection/selectors.ts b/src/state/atlasSelection/selectors.ts
index a60c20225d382e20691a955a7f3010c4bb1a0dc0..7a6663b8b8489c6bb231db14fe50579fa3180b8d 100644
--- a/src/state/atlasSelection/selectors.ts
+++ b/src/state/atlasSelection/selectors.ts
@@ -21,6 +21,11 @@ export const selectedParcellation = createSelector(
   state => state.selectedParcellation
 )
 
+export const selectedParcAllRegions = createSelector(
+  selectStore,
+  state => state.selectedParcellationAllRegions
+)
+
 export const selectedRegions = createSelector(
   selectStore,
   state => state.selectedRegions
@@ -47,3 +52,8 @@ export const viewerMode = createSelector(
   selectStore,
   state => state.viewerMode
 )
+
+export const breadCrumbs = createSelector(
+  selectStore,
+  state => state.breadcrumbs
+)
\ No newline at end of file
diff --git a/src/state/atlasSelection/store.ts b/src/state/atlasSelection/store.ts
index f36738bf1febc95b28dc7b6b4dff47377298c28e..7332711b69be6094ca9708e0945f958627921b6f 100644
--- a/src/state/atlasSelection/store.ts
+++ b/src/state/atlasSelection/store.ts
@@ -1,12 +1,14 @@
 import { createReducer, on } from "@ngrx/store";
 import { SapiAtlasModel, SapiParcellationModel, SapiRegionModel, SapiSpaceModel } from "src/atlasComponents/sapi";
 import * as actions from "./actions"
-import { ViewerMode } from "./const"
+import { ViewerMode, BreadCrumb } from "./const"
 
 export type AtlasSelectionState = {
   selectedAtlas: SapiAtlasModel
   selectedTemplate: SapiSpaceModel
   selectedParcellation: SapiParcellationModel
+  selectedParcellationAllRegions: SapiRegionModel[]
+
   selectedRegions: SapiRegionModel[]
   standAloneVolumes: string[]
 
@@ -23,16 +25,19 @@ export type AtlasSelectionState = {
   }
 
   viewerMode: ViewerMode
+  breadcrumbs: BreadCrumb[]
 }
 
 export const defaultState: AtlasSelectionState = {
   selectedAtlas: null,
   selectedParcellation: null,
+  selectedParcellationAllRegions: [],
   selectedRegions: [],
   selectedTemplate: null,
   standAloneVolumes: [],
   navigation: null,
-  viewerMode: null
+  viewerMode: null,
+  breadcrumbs: []
 }
 
 const reducer = createReducer(
@@ -64,6 +69,15 @@ const reducer = createReducer(
       }
     }
   ),
+  on(
+    actions.setSelectedParcellationAllRegions,
+    (state, { regions }) => {
+      return {
+        ...state,
+        selectedParcellationAllRegions: regions
+      }
+    }
+  ),
   on(
     actions.selectRegions,
     (state, { regions }) => {
@@ -99,6 +113,27 @@ const reducer = createReducer(
         viewerMode
       }
     }
+  ),
+  on(
+    actions.showBreadCrumb,
+    (state, { breadcrumb }) => {
+      return {
+        ...state,
+        breadcrumbs: [
+          ...state.breadcrumbs.filter(bc => bc.id !== breadcrumb.id),
+          breadcrumb
+        ]
+      }
+    }
+  ),
+  on(
+    actions.dismissBreadCrumb,
+    (state, { id }) => {
+      return {
+        ...state,
+        breadcrumbs: state.breadcrumbs.filter(bc => bc.id !== id)
+      }
+    }
   )
 )
 
diff --git a/src/state/const.ts b/src/state/const.ts
index 60f4c38b8b2f0d9f9dd4f8db61c0bc42e37a6ac4..29172b656f7af7c04a4857bcb4b7c9f416cc6f22 100644
--- a/src/state/const.ts
+++ b/src/state/const.ts
@@ -1 +1,13 @@
-export const nameSpace = `[state]`
\ No newline at end of file
+import { annotation, atlasAppearance, atlasSelection, plugins, userInteraction, userInterface, userPreference } from "."
+
+export const nameSpace = `[state]`
+
+export type MainState = {
+  [userPreference.nameSpace]: userPreference.UserPreference,
+  [atlasSelection.nameSpace]: atlasSelection.AtlasSelectionState,
+  [userInterface.nameSpace]: userInterface.UiStore,
+  [userInteraction.nameSpace]: userInteraction.UserInteraction,
+  [annotation.nameSpace]: annotation.AnnotationState,
+  [plugins.nameSpace]: plugins.PluginStore,
+  [atlasAppearance.nameSpace]: atlasAppearance.AtlasAppearanceStore
+}
diff --git a/src/state/index.ts b/src/state/index.ts
index b8523aff300ecd5c0ff0987c4a99ae20a088e14f..18f568ae703038c5255550d238793bd7b267936a 100644
--- a/src/state/index.ts
+++ b/src/state/index.ts
@@ -9,7 +9,6 @@ import * as atlasAppearance from "./atlasAppearance"
 import * as plugins from "./plugins"
 import * as userInteraction from "./userInteraction"
 import * as userPreference from "./userPreference"
-import { EffectsModule } from "@ngrx/effects"
 
 export {
   atlasSelection,
@@ -21,7 +20,9 @@ export {
   userPreference,
 }
 
-export function debug(reducer: ActionReducer<any>): ActionReducer<any> {
+export * as generalActions from "./actions"
+
+function debug(reducer: ActionReducer<any>): ActionReducer<any> {
   return function(state, action) {
     console.log('state', state);
     console.log('action', action);
@@ -44,8 +45,19 @@ export const RootStoreModule = StoreModule.forRoot({
   ]
 })
 
-export const RootEffecsModule = EffectsModule.forRoot([
-  plugins.Effects,
-  atlasSelection.Effect,
-  userInterface.Effects,
-])
\ No newline at end of file
+/**
+ * 
+ * We have to use a function here. At import time, *.Effect(s) 
+ * would not yet be defined.
+ * 
+ * @returns Effects from state
+ */
+export function getStoreEffects() {
+  return [
+    plugins.Effects,
+    atlasSelection.Effect,
+    userInterface.Effects,
+  ]
+}
+
+export { MainState } from "./const"
diff --git a/src/state/plugins/index.ts b/src/state/plugins/index.ts
index bdca8a18cd994e4c61ac6588fe2052efd79e4634..11548c69ffd13af7819fb9c2a67c9fc189d725db 100644
--- a/src/state/plugins/index.ts
+++ b/src/state/plugins/index.ts
@@ -1,5 +1,5 @@
 export * as selectors from "./selectors"
 export * as actions from "./actions"
-export { reducer } from "./store"
+export { reducer, PluginStore } from "./store"
 export { Effects } from "./effects"
 export { nameSpace, INIT_MANIFEST_SRC } from "./const"
\ No newline at end of file
diff --git a/src/state/userInteraction/index.ts b/src/state/userInteraction/index.ts
index 2bad8f6b313c2a4a4f8c7afff8f5def60db6d43c..4903f7b16fe5d859f2a437fee17e2602de9081b9 100644
--- a/src/state/userInteraction/index.ts
+++ b/src/state/userInteraction/index.ts
@@ -2,4 +2,4 @@ export { Effect } from "./effects"
 export { nameSpace } from "./const"
 export * as actions from "./actions"
 export * as selectors from "./selectors"
-export { reducer } from "./store"
\ No newline at end of file
+export { reducer, UserInteraction } from "./store"
\ No newline at end of file
diff --git a/src/state/userInterface/effects.ts b/src/state/userInterface/effects.ts
index d1472dc5dd8fe1a61f8e9784e6f5aee5e11cf22a..aabfd36f14a0c0ff90b809d4f712fcca16798182 100644
--- a/src/state/userInterface/effects.ts
+++ b/src/state/userInterface/effects.ts
@@ -5,7 +5,7 @@ import { Actions, createEffect, ofType } from "@ngrx/effects";
 import { select, Store } from "@ngrx/store";
 import { of } from "rxjs";
 import { filter, map, mapTo, pairwise, startWith, switchMap, tap, withLatestFrom } from "rxjs/operators";
-import { generalActionError } from "src/services/stateStore.helper";
+import { generalActionError } from "../actions";
 import { userInterface } from "..";
 import { selectors } from "../atlasSelection"
 import * as actions from "./actions"
diff --git a/src/state/userInterface/index.ts b/src/state/userInterface/index.ts
index cff6971a4bc22aaf6bee13218fcf516f136bf774..2329de3b38bacb0d8a648ee9fe13a911c8b92bb4 100644
--- a/src/state/userInterface/index.ts
+++ b/src/state/userInterface/index.ts
@@ -1,5 +1,5 @@
 export * as actions from "./actions"
 export * as selectors from "./selectors"
 export { nameSpace, PanelMode } from "./const"
-export { reducer } from "./store"
+export { reducer, UiStore } from "./store"
 export { Effects } from "./effects"
diff --git a/src/ui/layerbrowser/index.ts b/src/ui/layerbrowser/index.ts
deleted file mode 100644
index e1c19e45596aa009b1c8a86a22b48628dceb991e..0000000000000000000000000000000000000000
--- a/src/ui/layerbrowser/index.ts
+++ /dev/null
@@ -1,11 +0,0 @@
-export { LayerBrowserModule } from './layerBrowser.module'
-
-
-export interface INgLayerInterface {
-  name: string
-  visible: boolean
-  source: string
-  type: string // image | segmentation | etc ...
-  transform?: [[number, number, number, number], [number, number, number, number], [number, number, number, number], [number, number, number, number]] | null
-  // colormap : string
-}
diff --git a/src/ui/layerbrowser/layerBrowser.module.ts b/src/ui/layerbrowser/layerBrowser.module.ts
deleted file mode 100644
index a634859a0ce3ed07d2d57b2471cc481bbe89e27b..0000000000000000000000000000000000000000
--- a/src/ui/layerbrowser/layerBrowser.module.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import {
-  GetInitialLayerOpacityPipe,
-  LayerBrowser,
-  LockedLayerBtnClsPipe
-} from './layerBrowserComponent/layerbrowser.component'
-import { NgModule } from '@angular/core';
-import { CommonModule } from '@angular/common';
-import { AngularMaterialModule } from 'src/sharedModules';
-import { LayerDetailComponent } from './layerDetail/layerDetail.component';
-import { FormsModule } from '@angular/forms';
-import { UtilModule } from 'src/util';
-
-@NgModule({
-  imports: [
-    CommonModule,
-    FormsModule,
-    AngularMaterialModule,
-    UtilModule,
-  ],
-  declarations: [
-    LayerBrowser,
-    LayerDetailComponent,
-
-    GetInitialLayerOpacityPipe,
-    LockedLayerBtnClsPipe,
-  ],
-  exports: [
-    GetInitialLayerOpacityPipe,
-    LayerBrowser,
-    LockedLayerBtnClsPipe
-  ]
-})
-
-export class LayerBrowserModule{}
\ No newline at end of file
diff --git a/src/ui/layerbrowser/layerBrowserComponent/layerbrowser.component.ts b/src/ui/layerbrowser/layerBrowserComponent/layerbrowser.component.ts
deleted file mode 100644
index 043e0005a7d84e5a99f7e3acf52a48410df73378..0000000000000000000000000000000000000000
--- a/src/ui/layerbrowser/layerBrowserComponent/layerbrowser.component.ts
+++ /dev/null
@@ -1,272 +0,0 @@
-import { Component,  EventEmitter, Input, OnDestroy, OnInit, Output, Pipe, PipeTransform } from "@angular/core";
-import { select, Store } from "@ngrx/store";
-import { combineLatest, Observable, Subscription } from "rxjs";
-import { debounceTime, distinctUntilChanged, map, shareReplay, startWith } from "rxjs/operators";
-import { MatSliderChange } from "@angular/material/slider";
-
-import { getViewer } from "src/util/fn";
-import { PureContantService } from "src/util";
-import { ngViewerActionRemoveNgLayer, ngViewerActionForceShowSegment } from "src/services/state/ngViewerState/actions";
-import { getNgIds } from 'src/util/fn'
-import { LoggingService } from "src/logging";
-import { ARIA_LABELS } from 'common/constants'
-
-import { INgLayerInterface } from "../index";
-
-const SHOW_LAYER_NAMES = [
-  'PLI Fiber Orientation Red Channel',
-  'PLI Fiber Orientation Green Channel',
-  'PLI Fiber Orientation Blue Channel',
-  'Blockface Image',
-  'PLI Transmittance',
-  'T2w MRI',
-  'MRI Labels'
-]
-
-@Component({
-  selector : 'layer-browser',
-  templateUrl : './layerbrowser.template.html',
-  styleUrls : [
-    './layerbrowser.style.css',
-  ],
-})
-
-export class LayerBrowser implements OnInit, OnDestroy {
-
-  public TOGGLE_SHOW_LAYER_CONTROL_ARIA_LABEL = ARIA_LABELS.TOGGLE_SHOW_LAYER_CONTROL
-
-  @Output() public nonBaseLayersChanged: EventEmitter<INgLayerInterface[]> = new EventEmitter()
-
-  /**
-   * TODO make untangle nglayernames and its dependency on ng
-   */
-  public loadedNgLayers$: Observable<INgLayerInterface[]>
-  public lockedLayers: string[] = []
-
-  public nonBaseNgLayers$: Observable<INgLayerInterface[]>
-
-  public forceShowSegmentCurrentState: boolean | null = null
-  public forceShowSegment$: Observable<boolean|null>
-
-  public ngLayers$: Observable<string[]>
-  public advancedMode: boolean = false
-
-  private subscriptions: Subscription[] = []
-  private disposeHandler: any
-
-  @Input()
-  public showPlaceholder: boolean = true
-
-  public darktheme$: Observable<boolean>
-
-  private customNgLayers: string[] = ['spatial landmark layer']
-
-  constructor(
-    private store: Store<any>,
-    private pureConstantSvc: PureContantService,
-    private log: LoggingService,
-  ) {
-    this.ngLayers$ = store.pipe(
-      select('viewerState'),
-      select('templateSelected'),
-      map(templateSelected => {
-        if (!templateSelected) { return [] }
-        if (this.advancedMode) { return [] }
-
-        const { ngId , otherNgIds = []} = templateSelected
-
-        return [
-          ngId,
-          ...this.customNgLayers,
-          ...otherNgIds,
-          ...templateSelected.parcellations.reduce((acc, curr) => {
-            return acc.concat([
-              curr.ngId,
-              ...getNgIds(curr.regions),
-            ])
-          }, []),
-        ]
-      }),
-      /**
-       * get unique array
-       */
-      map(nonUniqueArray => Array.from(new Set(nonUniqueArray))),
-      /**
-       * remove falsy values
-       */
-      map(arr => arr.filter(v => !!v)),
-    )
-
-    this.loadedNgLayers$ = this.store.pipe(
-      select('viewerState'),
-      select('loadedNgLayers'),
-    )
-
-    this.nonBaseNgLayers$ = combineLatest(
-      this.ngLayers$,
-      this.loadedNgLayers$,
-    ).pipe(
-      map(([baseNgLayerNames, loadedNgLayers]) => {
-        const baseNameSet = new Set(baseNgLayerNames)
-        return loadedNgLayers.filter(l => SHOW_LAYER_NAMES.includes(l.name))
-      }),
-      distinctUntilChanged()
-    )
-
-    this.forceShowSegment$ = this.store.pipe(
-      select('ngViewerState'),
-      select('forceShowSegment'),
-      startWith(false)
-    )
-
-    this.darktheme$ = this.pureConstantSvc.darktheme$.pipe(
-      shareReplay(1),
-    )
-
-  }
-
-  public ngOnInit() {
-    this.subscriptions.push(
-      this.nonBaseNgLayers$.pipe(
-        // on switching template, non base layer will fire
-        // debounce to ensure that the non base layer is indeed an extra layer
-        debounceTime(160),
-      ).subscribe(layers => this.nonBaseLayersChanged.emit(layers)),
-    )
-    this.subscriptions.push(
-      this.forceShowSegment$.subscribe(state => this.forceShowSegmentCurrentState = state),
-    )
-
-    this.viewer = getViewer()
-  }
-
-  public ngOnDestroy() {
-    this.subscriptions.forEach(s => s.unsubscribe())
-  }
-
-  public classVisible(layer: any): boolean {
-    return typeof layer.visible === 'undefined'
-      ? true
-      : layer.visible
-  }
-
-  public checkLocked(ngLayer: INgLayerInterface): boolean {
-    if (!this.lockedLayers) {
-      /* locked layer undefined. always return false */
-      return false
-    } else {
-      return this.lockedLayers.findIndex(l => l === ngLayer.name) >= 0
-    }
-  }
-
-  public viewer: any
-
-  public toggleVisibility(layer: any) {
-    const layerName = layer.name
-    if (!layerName) {
-      this.log.error('layer name not defined', layer)
-      return
-    }
-    const ngLayer = this.viewer.layerManager.getLayerByName(layerName)
-    if (!ngLayer) {
-      this.log.error('ngLayer could not be found', layerName, this.viewer.layerManager.managedLayers)
-    }
-    ngLayer.setVisible(!ngLayer.visible)
-  }
-
-  public toggleForceShowSegment(ngLayer: any) {
-    if (!ngLayer || ngLayer.type !== 'segmentation') {
-      /* toggle only on segmentation layer */
-      return
-    }
-
-    /**
-     * TODO perhaps useEffects ?
-     */
-    this.store.dispatch(
-      ngViewerActionForceShowSegment({
-        forceShowSegment : this.forceShowSegmentCurrentState === null
-          ? true
-          : this.forceShowSegmentCurrentState === true
-            ? false
-            : null,
-      })
-    )
-  }
-
-  public removeLayer(layer: any) {
-    if (this.checkLocked(layer)) {
-      this.log.warn('this layer is locked and cannot be removed')
-      return
-    }
-
-    this.store.dispatch(
-      ngViewerActionRemoveNgLayer({
-        layer
-      })
-    )
-  }
-
-  public changeOpacity(layerName: string, event: MatSliderChange){
-    const { value } = event
-    const l = this.viewer.layerManager.getLayerByName(layerName)
-    if (!l) return
-
-    if (typeof l.layer.opacity === 'object') {
-      l.layer.opacity.value = value
-    } else if (typeof l.layer.displayState === 'object') {
-      l.layer.displayState.selectedAlpha.value = value
-    } else {
-      this.log.warn({
-        msg: `layer does not belong anywhere`,
-        layerName,
-        layer: l
-      })
-    }
-  }
-
-  /**
-   * TODO use observable and pipe to make this more perf
-   */
-  public segmentationTooltip() {
-    return `toggle segments visibility:
-    ${this.forceShowSegmentCurrentState === true ? 'always show' : this.forceShowSegmentCurrentState === false ? 'always hide' : 'auto'}`
-  }
-
-  get segmentationAdditionalClass() {
-    return this.forceShowSegmentCurrentState === null
-      ? 'blue'
-      : this.forceShowSegmentCurrentState === true
-        ? 'normal'
-        : this.forceShowSegmentCurrentState === false
-          ? 'muted'
-          : 'red'
-  }
-
-  public matTooltipPosition: string = 'below'
-}
-
-@Pipe({
-  name: 'lockedLayerBtnClsPipe',
-})
-
-export class LockedLayerBtnClsPipe implements PipeTransform {
-  public transform(ngLayer: INgLayerInterface, lockedLayers?: string[]): boolean {
-    return (lockedLayers && new Set(lockedLayers).has(ngLayer.name)) || false
-  }
-}
-
-@Pipe({
-  name: 'getInitialLayerOpacityPipe'
-})
-
-export class GetInitialLayerOpacityPipe implements PipeTransform{
-  public transform(viewer: any, layerName: string): number{
-    if (!viewer) return 0
-    const l = viewer.layerManager.getLayerByName(layerName)
-    if (!l || !l.layer) return 0
-    if (typeof l.layer.opacity === 'object') return l.layer.opacity.value
-    else if (typeof l.layer.displayState === 'object') return l.layer.displayState.selectedAlpha.value
-    else return 0
-  }
-}
diff --git a/src/ui/layerbrowser/layerBrowserComponent/layerbrowser.style.css b/src/ui/layerbrowser/layerBrowserComponent/layerbrowser.style.css
deleted file mode 100644
index b38ff0ea019b33d7e8797092569c7cc865408ea2..0000000000000000000000000000000000000000
--- a/src/ui/layerbrowser/layerBrowserComponent/layerbrowser.style.css
+++ /dev/null
@@ -1,11 +0,0 @@
-:host
-{
-  padding: 0 0.2em;
-  display: flex;
-  flex-direction: column-reverse;
-}
-
-.noLayerPlaceHolder
-{
-  padding: 0.5em 1em;
-}
diff --git a/src/ui/layerbrowser/layerBrowserComponent/layerbrowser.template.html b/src/ui/layerbrowser/layerBrowserComponent/layerbrowser.template.html
deleted file mode 100644
index 43aa21f9f9784a690d238a2eec02b23be4994030..0000000000000000000000000000000000000000
--- a/src/ui/layerbrowser/layerBrowserComponent/layerbrowser.template.html
+++ /dev/null
@@ -1,106 +0,0 @@
-<!-- n.b. using mousedown for event trigger -->
-<!-- Chrome & FF exhibit different behaviours when using click/mouseup as a event handler -->
-<!-- in Chrome, it will complain that expression changed after change detection -->
-<!-- in FF, the element changes, and focusout event is never fired properly -->
-
-<ng-container *ngIf="nonBaseNgLayers$ | async as nonBaseNgLayers; else noLayerPlaceHolder">
-  <mat-accordion *ngIf="nonBaseNgLayers.length > 0; else noLayerPlaceHolder"
-    [multi]="true"
-    displayMode="flat">
-    <mat-expansion-panel
-      [disabled]="true"
-      *ngFor="let ngLayer of nonBaseNgLayers"
-      class="layer-expansion-unit"
-      #expansionPanel>
-      <mat-expansion-panel-header>
-        <div class="align-items-center d-flex flex-nowrap sxplr-pr-4 w-100">
-          <!-- toggle opacity -->
-          <div matTooltip="opacity">
-
-            <mat-slider
-              [disabled]="!ngLayer.visible"
-              min="0"
-              max="1"
-              (input)="changeOpacity(ngLayer.name, $event)"
-              [value]="viewer | getInitialLayerOpacityPipe: ngLayer.name"
-              step="0.01">
-
-            </mat-slider>
-          </div>
-
-          <!-- toggle visibility -->
-
-          <button
-            [matTooltipPosition]="matTooltipPosition"
-            [matTooltip]="(ngLayer | lockedLayerBtnClsPipe : lockedLayers) ? 'base layer cannot be hidden' : 'toggle visibility'"
-            (mousedown)="toggleVisibility(ngLayer)"
-            mat-icon-button
-            [disabled]="ngLayer | lockedLayerBtnClsPipe : lockedLayers"
-            [color]="ngLayer.visible ? 'primary' : null">
-            <i [ngClass]="(ngLayer | lockedLayerBtnClsPipe : lockedLayers) ? 'fas fa-lock muted' : ngLayer.visible ? 'far fa-eye' : 'far fa-eye-slash'">
-            </i>
-          </button>
-
-          <!-- advanced mode only: toggle force show segmentation -->
-          <button
-            *ngIf="advancedMode"
-            [matTooltipPosition]="matTooltipPosition"
-            [matTooltip]="ngLayer.type === 'segmentation' ? segmentationTooltip() : 'only segmentation layer can hide/show segments'"
-            (mousedown)="toggleForceShowSegment(ngLayer)"
-            mat-icon-button>
-            <i
-              class="fas"
-              [ngClass]="ngLayer.type === 'segmentation' ? ('fa-th-large ' + segmentationAdditionalClass) : 'fa-lock muted' ">
-
-            </i>
-          </button>
-
-          <!-- remove layer -->
-          <button
-            color="warn"
-            mat-icon-button
-            (mousedown)="removeLayer(ngLayer)"
-            [disabled]="ngLayer | lockedLayerBtnClsPipe : lockedLayers"
-            [matTooltip]="(ngLayer | lockedLayerBtnClsPipe : lockedLayers) ? 'base layers cannot be removed' : 'remove layer'">
-            <i [class]="(ngLayer | lockedLayerBtnClsPipe : lockedLayers) ? 'fas fa-lock muted' : 'fas fa-trash'">
-            </i>
-          </button>
-
-          <!-- layer description -->
-          <mat-label
-            [matTooltipPosition]="matTooltipPosition"
-            [matTooltip]="ngLayer.name | getFilenamePipe "
-            [class]="((darktheme$ | async) ? 'text-light' : 'text-dark') + ' text-truncate flex-grow-1 flex-shrink-1'">
-            {{ ngLayer.name | getFilenamePipe }}
-          </mat-label>
-
-          <button mat-icon-button
-            [attr.aria-label]="TOGGLE_SHOW_LAYER_CONTROL_ARIA_LABEL"
-            (click)="expansionPanel.toggle()">
-            <ng-container *ngIf="expansionPanel.expanded; else btnIconAlt">
-              <i class="fas fa-chevron-up"></i>
-            </ng-container>
-
-            <ng-template #btnIconAlt>
-              <i class="fas fa-chevron-down"></i>
-            </ng-template>
-          </button>
-
-        </div>
-      </mat-expansion-panel-header>
-
-      <ng-template matExpansionPanelContent>
-        <layer-detail-cmp [layerName]="ngLayer.name">
-        </layer-detail-cmp>
-      </ng-template>
-
-    </mat-expansion-panel>
-  </mat-accordion>
-</ng-container>
-
-<!-- fall back when no layers are showing -->
-<ng-template #noLayerPlaceHolder>
-  <small *ngIf="showPlaceholder" class="noLayerPlaceHolder text-muted">
-    No additional layers added.
-  </small>
-</ng-template>
diff --git a/src/ui/layerbrowser/layerDetail/layerDetail.component.spec.ts b/src/ui/layerbrowser/layerDetail/layerDetail.component.spec.ts
deleted file mode 100644
index 575f538b1b828342c9f290f37aab9bf2c2209556..0000000000000000000000000000000000000000
--- a/src/ui/layerbrowser/layerDetail/layerDetail.component.spec.ts
+++ /dev/null
@@ -1,300 +0,0 @@
-import { LayerDetailComponent, VIEWER_INJECTION_TOKEN } from './layerDetail.component'
-import { async, TestBed } from '@angular/core/testing'
-import { NgLayersService } from '../ngLayerService.service'
-import { By } from '@angular/platform-browser'
-import * as CONSTANT from 'src/util/constants'
-import { AngularMaterialModule } from 'src/sharedModules'
-import { CommonModule } from '@angular/common'
-import { FormsModule, ReactiveFormsModule } from '@angular/forms'
-
-const getSpies = (service: NgLayersService) => {
-  const lowThMapGetSpy = spyOn(service.lowThresholdMap, 'get').and.callThrough()
-  const highThMapGetSpy = spyOn(service.highThresholdMap, 'get').and.callThrough()
-  const brightnessMapGetSpy = spyOn(service.brightnessMap, 'get').and.callThrough()
-  const contractMapGetSpy = spyOn(service.contrastMap, 'get').and.callThrough()
-  const removeBgMapGetSpy = spyOn(service.removeBgMap, 'get').and.callThrough()
-
-  const lowThMapSetSpy = spyOn(service.lowThresholdMap, 'set').and.callThrough()
-  const highThMapSetSpy = spyOn(service.highThresholdMap, 'set').and.callThrough()
-  const brightnessMapSetSpy = spyOn(service.brightnessMap, 'set').and.callThrough()
-  const contrastMapSetSpy = spyOn(service.contrastMap, 'set').and.callThrough()
-  const removeBgMapSetSpy = spyOn(service.removeBgMap, 'set').and.callThrough()
-
-  return {
-    lowThMapGetSpy,
-    highThMapGetSpy,
-    brightnessMapGetSpy,
-    contractMapGetSpy,
-    removeBgMapGetSpy,
-    lowThMapSetSpy,
-    highThMapSetSpy,
-    brightnessMapSetSpy,
-    contrastMapSetSpy,
-    removeBgMapSetSpy,
-  }
-}
-
-const getCtrl = () => {
-  const lowThSlider = By.css('mat-slider[aria-label="Set lower threshold"]')
-  const highThSlider = By.css('mat-slider[aria-label="Set higher threshold"]')
-  const brightnessSlider = By.css('mat-slider[aria-label="Set brightness"]')
-  const contrastSlider = By.css('mat-slider[aria-label="Set contrast"]')
-  const removeBgSlideToggle = By.css('mat-slide-toggle[aria-label="Remove background"]')
-  return {
-    lowThSlider,
-    highThSlider,
-    brightnessSlider,
-    contrastSlider,
-    removeBgSlideToggle,
-  }
-}
-
-const getSliderChangeTest = ctrlName => describe(`testing: ${ctrlName}`, () => {
-
-  it('on change, calls window', () => {
-    const service = TestBed.inject(NgLayersService)
-    const spies = getSpies(service)
-    
-    const fixture = TestBed.createComponent(LayerDetailComponent)
-    const layerName = `hello-kitty`
-    fixture.componentInstance.layerName = layerName
-    const triggerChSpy = spyOn(fixture.componentInstance, 'triggerChange')
-    const ctrls = getCtrl()
-    
-    const sLower = fixture.debugElement.query( ctrls[`${ctrlName}Slider`] )
-    sLower.componentInstance.input.emit({ value: 0.5 })
-    expect(spies[`${ctrlName}MapSetSpy`]).toHaveBeenCalledWith(layerName, 0.5)
-    expect(triggerChSpy).toHaveBeenCalled()
-  })
-})
-
-const fragmentMainSpy = {
-  value: `test value`,
-  restoreState: () => {}
-}
-
-const defaultViewer = {
-  layerManager: {
-    getLayerByName: jasmine.createSpy('getLayerByName').and.returnValue({layer: {fragmentMain: fragmentMainSpy}})
-  }
-}
-
-describe('> layerDetail.component.ts', () => {
-  describe('> LayerDetailComponent', () => {
-
-    beforeEach(async(() => {
-      TestBed.configureTestingModule({
-        declarations: [
-          LayerDetailComponent
-        ],
-        imports: [
-          AngularMaterialModule,
-          CommonModule,
-          FormsModule,
-          ReactiveFormsModule,
-        ],
-        providers: [
-          NgLayersService,
-          {
-            provide: VIEWER_INJECTION_TOKEN,
-            useValue: defaultViewer
-          }
-        ]
-      }).compileComponents()
-    }))
-
-    describe('> basic funcitonalities', () => {
-
-      it('> it should be created', () => {
-        const fixture = TestBed.createComponent(LayerDetailComponent)
-        const element = fixture.debugElement.componentInstance
-        expect(element).toBeTruthy()
-      })
-  
-      it('> on bind input, if input is truthy, calls get on layerService maps', () => {
-        TestBed.overrideProvider(VIEWER_INJECTION_TOKEN, {
-          useValue: {}
-        })
-        const service = TestBed.inject(NgLayersService)
-        const {
-          brightnessMapGetSpy,
-          contractMapGetSpy,
-          highThMapGetSpy,
-          lowThMapGetSpy,
-          removeBgMapGetSpy
-        } = getSpies(service)
-  
-        const layerName = `hello-kitty`
-        const fixture = TestBed.createComponent(LayerDetailComponent)
-        fixture.componentInstance.layerName = layerName
-        fixture.componentInstance.ngOnChanges()
-        fixture.detectChanges()
-        expect(brightnessMapGetSpy).toHaveBeenCalledWith(layerName)
-        expect(contractMapGetSpy).toHaveBeenCalledWith(layerName)
-        expect(highThMapGetSpy).toHaveBeenCalledWith(layerName)
-        expect(lowThMapGetSpy).toHaveBeenCalledWith(layerName)
-        expect(removeBgMapGetSpy).toHaveBeenCalledWith(layerName)
-      })
-  
-      it('> on bind input, if input is falsy, does not call layerService map get', () => {
-        const service = TestBed.inject(NgLayersService)
-        const {
-          brightnessMapGetSpy,
-          contractMapGetSpy,
-          highThMapGetSpy,
-          lowThMapGetSpy,
-          removeBgMapGetSpy
-        } = getSpies(service)
-  
-        const layerName = null
-        const fixture = TestBed.createComponent(LayerDetailComponent)
-        fixture.componentInstance.layerName = layerName
-        fixture.componentInstance.ngOnChanges()
-        fixture.detectChanges()
-        expect(brightnessMapGetSpy).not.toHaveBeenCalled()
-        expect(contractMapGetSpy).not.toHaveBeenCalled()
-        expect(highThMapGetSpy).not.toHaveBeenCalled()
-        expect(lowThMapGetSpy).not.toHaveBeenCalled()
-        expect(removeBgMapGetSpy).not.toHaveBeenCalled()
-      })
-  
-    })
-
-    const testingSlidersCtrl = [
-      'lowTh',
-      'highTh',
-      'brightness',
-      'contrast',
-    ]
-
-    for (const sliderCtrl of testingSlidersCtrl ) {
-      getSliderChangeTest(sliderCtrl)
-    }
-
-    describe('testing: removeBG toggle', () => {
-      it('on change, calls window', () => {
-
-        const service = TestBed.inject(NgLayersService)
-        const { removeBgMapSetSpy } = getSpies(service)
-        
-        const fixture = TestBed.createComponent(LayerDetailComponent)
-        const triggerChSpy = spyOn(fixture.componentInstance, 'triggerChange')
-        const layerName = `hello-kitty`
-        fixture.componentInstance.layerName = layerName
-
-        const { removeBgSlideToggle } = getCtrl()
-        const bgToggle = fixture.debugElement.query( removeBgSlideToggle )
-        bgToggle.componentInstance.change.emit({ checked: true })
-        expect(removeBgMapSetSpy).toHaveBeenCalledWith('hello-kitty', true)
-        expect(triggerChSpy).toHaveBeenCalled()
-
-        removeBgMapSetSpy.calls.reset()
-        triggerChSpy.calls.reset()
-        expect(removeBgMapSetSpy).not.toHaveBeenCalled()
-        expect(triggerChSpy).not.toHaveBeenCalled()
-
-        bgToggle.componentInstance.change.emit({ checked: false })
-
-        expect(removeBgMapSetSpy).toHaveBeenCalledWith('hello-kitty', false)
-        expect(triggerChSpy).toHaveBeenCalled()
-      })
-    })
-
-    describe('triggerChange', () => {
-      it('should throw if viewer is not defined', () => {
-        TestBed.overrideProvider(VIEWER_INJECTION_TOKEN, {
-          useValue: null
-        })
-        const fixutre = TestBed.createComponent(LayerDetailComponent)
-        expect(function(){
-          fixutre.componentInstance.triggerChange()
-        }).toThrowError('viewer is not defined')
-      })
-
-      it('should throw if layer is not found', () => {
-        const fakeGetLayerByName = jasmine.createSpy().and.returnValue(undefined)
-        const fakeNgInstance = {
-          layerManager: {
-            getLayerByName: fakeGetLayerByName
-          }
-        }
-
-        TestBed.overrideProvider(VIEWER_INJECTION_TOKEN, {
-          useValue: fakeNgInstance
-        })
-
-        const fixutre = TestBed.createComponent(LayerDetailComponent)
-        const layerName = `test-kitty`
-
-        fixutre.componentInstance.layerName = layerName
-
-        expect(function(){
-          fixutre.componentInstance.triggerChange()
-        }).toThrowError(`layer with name: ${layerName}, not found.`)
-      })
-
-      it('should throw if layer.layer.fragmentMain is undefined', () => {
-        const layerName = `test-kitty`
-
-        const fakeLayer = {
-          hello: 'world'
-        }
-        const fakeGetLayerByName = jasmine.createSpy().and.returnValue(fakeLayer)
-        const fakeNgInstance = {
-          layerManager: {
-            getLayerByName: fakeGetLayerByName
-          }
-        }
-
-        TestBed.overrideProvider(VIEWER_INJECTION_TOKEN, {
-          useValue: fakeNgInstance
-        })
-
-        const fixutre = TestBed.createComponent(LayerDetailComponent)
-
-        fixutre.componentInstance.layerName = layerName
-
-        expect(function(){
-          fixutre.componentInstance.triggerChange()
-        }).toThrowError(`layer.fragmentMain is not defined... is this an image layer?`)
-      })
-
-      it('should call getShader and restoreState if all goes right', () => {
-
-        const replacementShader = `blabla ahder`
-        const getShaderSpy = jasmine.createSpy('getShader').and.returnValue(replacementShader)
-        spyOnProperty(CONSTANT, 'getShader').and.returnValue(getShaderSpy)
-        
-        const layerName = `test-kitty`
-
-        const fakeRestoreState = jasmine.createSpy('fakeGetLayerByName')
-        const fakeLayer = {
-          layer: {
-            fragmentMain: {
-              restoreState: fakeRestoreState
-            }
-          }
-        }
-        const fakeGetLayerByName = jasmine.createSpy('fakeGetLayerByName').and.returnValue(fakeLayer)
-        const fakeNgInstance = {
-          layerManager: {
-            getLayerByName: fakeGetLayerByName
-          }
-        }
-        TestBed.overrideProvider(VIEWER_INJECTION_TOKEN, {
-          useValue: fakeNgInstance
-        })
-        
-        const fixutre = TestBed.createComponent(LayerDetailComponent)
-        fixutre.componentInstance.layerName = layerName
-        fixutre.detectChanges()
-
-        fixutre.componentInstance.triggerChange()
-        
-        expect(fakeGetLayerByName).toHaveBeenCalledWith(layerName)
-        expect(getShaderSpy).toHaveBeenCalled()
-        expect(fakeRestoreState).toHaveBeenCalledWith(replacementShader)
-      })
-    })
-  })
-})
\ No newline at end of file
diff --git a/src/ui/layerbrowser/layerDetail/layerDetail.component.ts b/src/ui/layerbrowser/layerDetail/layerDetail.component.ts
deleted file mode 100644
index 414bab57e2f2ef11e8232a7405e8b206d5707cda..0000000000000000000000000000000000000000
--- a/src/ui/layerbrowser/layerDetail/layerDetail.component.ts
+++ /dev/null
@@ -1,100 +0,0 @@
-import { Component, Input, OnChanges, ChangeDetectionStrategy, Optional, Inject } from "@angular/core";
-import { NgLayersService } from "../ngLayerService.service";
-import { MatSliderChange } from "@angular/material/slider";
-import { MatSlideToggleChange } from "@angular/material/slide-toggle";
-import { getShader } from "src/util/constants";
-
-export const VIEWER_INJECTION_TOKEN = `VIEWER_INJECTION_TOKEN`
-
-@Component({
-  selector: 'layer-detail-cmp',
-  templateUrl: './layerDetail.template.html',
-  changeDetection: ChangeDetectionStrategy.OnPush
-})
-
-export class LayerDetailComponent implements OnChanges{
-  @Input() 
-  layerName: string
-
-  private colormap = null 
-
-  constructor(
-    private layersService: NgLayersService,
-    @Optional() @Inject(VIEWER_INJECTION_TOKEN) private injectedViewer
-  ){
-
-  }
-
-  ngOnChanges(){
-    if (!this.layerName) return
-
-    this.lowThreshold = this.layersService.lowThresholdMap.get(this.layerName) || this.lowThreshold
-    this.highThreshold = this.layersService.highThresholdMap.get(this.layerName) || this.highThreshold
-    this.brightness = this.layersService.brightnessMap.get(this.layerName) || this.brightness
-    this.contrast = this.layersService.contrastMap.get(this.layerName) || this.contrast
-    this.removeBg = this.layersService.removeBgMap.get(this.layerName) || this.removeBg
-    this.colormap = this.layersService.colorMapMap.get(this.layerName) || this.colormap
-  }
-
-  public lowThreshold: number = 0
-  public highThreshold: number = 1
-  public brightness: number = 0
-  public contrast: number = 0
-  public removeBg: boolean = false
-
-  handleChange(mode: 'low' | 'high' | 'brightness' | 'contrast', event: MatSliderChange){
-    switch(mode) {
-    case 'low':
-      this.layersService.lowThresholdMap.set(this.layerName, event.value)
-      this.lowThreshold = event.value
-      break;
-    case 'high':
-      this.layersService.highThresholdMap.set(this.layerName, event.value)
-      this.highThreshold = event.value
-      break;
-    case 'brightness':
-      this.layersService.brightnessMap.set(this.layerName, event.value)
-      this.brightness = event.value
-      break;
-    case 'contrast':
-      this.layersService.contrastMap.set(this.layerName, event.value)
-      this.contrast = event.value
-      break;
-    default: return
-    }
-    this.triggerChange()
-  }
-
-  handleToggleBg(event: MatSlideToggleChange){
-    this.layersService.removeBgMap.set(this.layerName, event.checked)
-    this.removeBg = event.checked
-    this.triggerChange()
-  }
-
-  triggerChange(){
-    const { lowThreshold, highThreshold, brightness, contrast, removeBg, colormap } = this
-    const shader = getShader({
-      lowThreshold,
-      highThreshold, 
-      colormap,
-      brightness,
-      contrast,
-      removeBg
-    })
-    this.fragmentMain.restoreState(shader)
-  }
-
-  private get viewer(){
-    return this.injectedViewer || (window as any).viewer
-  }
-
-  private get fragmentMain(){
-
-    if (!this.viewer) throw new Error(`viewer is not defined`)
-    const layer = this.viewer.layerManager.getLayerByName(this.layerName)
-    if (!layer) throw new Error(`layer with name: ${this.layerName}, not found.`)
-    if (! (layer.layer?.fragmentMain?.restoreState) ) throw new Error(`layer.fragmentMain is not defined... is this an image layer?`)
-
-    return layer.layer.fragmentMain
-  }
-}
diff --git a/src/ui/layerbrowser/layerDetail/layerDetail.template.html b/src/ui/layerbrowser/layerDetail/layerDetail.template.html
deleted file mode 100644
index 376b875c3ffd924a5a69166d2555104cae0c0390..0000000000000000000000000000000000000000
--- a/src/ui/layerbrowser/layerDetail/layerDetail.template.html
+++ /dev/null
@@ -1,79 +0,0 @@
-<div class="d-flex flex-column">
-  <div>
-    <mat-label>
-      Low threshold
-    </mat-label>
-    <mat-slider
-      aria-label="Set lower threshold"
-      (input)="handleChange('low', $event)"
-      [value]="lowThreshold"
-      min="0"
-      max="1"
-      step="0.001">
-    </mat-slider>
-    <mat-label>
-      {{ lowThreshold }}
-    </mat-label>
-  </div>
-
-  <div>
-    <mat-label>
-      High threshold
-    </mat-label>
-    <mat-slider
-      aria-label="Set higher threshold"
-      (input)="handleChange('high', $event)"
-      [value]="highThreshold"
-      min="0"
-      max="1"
-      step="0.001">
-    </mat-slider>  
-    <mat-label>
-      {{ highThreshold }}
-    </mat-label>
-  </div>
-  <div>
-    <mat-label>
-      Brightness
-    </mat-label>
-    <mat-slider
-      aria-label="Set brightness"
-      (input)="handleChange('brightness', $event)"
-      [value]="brightness"
-      min="-1"
-      max="1"
-      step="0.01">
-    </mat-slider>  
-    <mat-label>
-      {{ brightness }}
-    </mat-label>
-  </div>
-  <div>
-    <mat-label>
-      Contrast
-    </mat-label>
-    <mat-slider
-      aria-label="Set contrast"
-      (input)="handleChange('contrast', $event)"
-      [value]="contrast"
-      min="-1"
-      max="1"
-      step="0.01">
-    </mat-slider>  
-    <mat-label>
-      {{ contrast }}
-    </mat-label>
-  </div>
-
-  <div>
-    <mat-label>
-      Remove background
-    </mat-label>
-    <mat-slide-toggle
-      aria-label="Remove background"
-      (change)="handleToggleBg($event)"
-      [(ngModel)]="removeBg">
-
-    </mat-slide-toggle>
-  </div>
-</div>
\ No newline at end of file
diff --git a/src/ui/layerbrowser/ngLayerService.service.ts b/src/ui/layerbrowser/ngLayerService.service.ts
deleted file mode 100644
index 35bd949ba6885423862692dacdac94e35dc96a7b..0000000000000000000000000000000000000000
--- a/src/ui/layerbrowser/ngLayerService.service.ts
+++ /dev/null
@@ -1,15 +0,0 @@
-import { Injectable } from "@angular/core";
-import { EnumColorMapName } from "src/util/colorMaps";
-
-@Injectable({
-  providedIn: 'root'
-})
-
-export class NgLayersService{
-  public lowThresholdMap: Map<string, number> = new Map()
-  public highThresholdMap: Map<string, number> = new Map()
-  public brightnessMap: Map<string, number> = new Map()
-  public contrastMap: Map<string, number> = new Map()
-  public removeBgMap: Map<string, boolean> = new Map()
-  public colorMapMap: Map<string, EnumColorMapName> = new Map()
-}
diff --git a/src/ui/nehubaContainer/pipes/mobileControlNubStyle.pipe.ts b/src/ui/nehubaContainer/pipes/mobileControlNubStyle.pipe.ts
deleted file mode 100644
index 1f70f6b658cb27001bab3415c77aa0ec90d5be70..0000000000000000000000000000000000000000
--- a/src/ui/nehubaContainer/pipes/mobileControlNubStyle.pipe.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import { Pipe, PipeTransform } from "@angular/core";
-import { PANELS } from 'src/services/state/ngViewerState.store.helper'
-
-
-@Pipe({
-  name: 'mobileControlNubStylePipe',
-})
-
-export class MobileControlNubStylePipe implements PipeTransform {
-  public transform(panelMode: string): any {
-    switch (panelMode) {
-    case PANELS.SINGLE_PANEL:
-      return {
-        top: '80%',
-        left: '95%',
-      }
-    case PANELS.V_ONE_THREE:
-    case PANELS.H_ONE_THREE:
-      return {
-        top: '66.66%',
-        left: '66.66%',
-      }
-    case PANELS.FOUR_PANEL:
-    default:
-      return {
-        top: '50%',
-        left: '50%',
-      }
-    }
-  }
-}
diff --git a/src/ui/ui.module.ts b/src/ui/ui.module.ts
index 3e389e9585292b377ea1d1b16f87c43dad703425..1115cb7c6769c3831fe56eb6ecfbf7c514c585a5 100644
--- a/src/ui/ui.module.ts
+++ b/src/ui/ui.module.ts
@@ -12,7 +12,6 @@ import { DownloadDirective } from "../util/directives/download.directive";
 
 import { LogoContainer } from "./logoContainer/logoContainer.component";
 import { MobileOverlay } from "./nehubaContainer/mobileOverlay/mobileOverlay.component";
-import { MobileControlNubStylePipe } from "./nehubaContainer/pipes/mobileControlNubStyle.pipe";
 
 import { HumanReadableFileSizePipe } from "src/util/pipes/humanReadableFileSize.pipe";
 
@@ -56,7 +55,6 @@ import { DialogInfoModule } from "./dialogInfo"
     ActionDialog,
 
     /* pipes */
-    MobileControlNubStylePipe,
 
     HumanReadableFileSizePipe,
     ReorderPanelIndexPipe,
diff --git a/src/util/constants.ts b/src/util/constants.ts
index fadf5811251a20f5a4002fc37342e73d6f4ed536..5c4e7185743a1dca35e0523f076385b797fc21b5 100644
--- a/src/util/constants.ts
+++ b/src/util/constants.ts
@@ -14,7 +14,6 @@ export const LOCAL_STORAGE_CONST = {
 
 export const COOKIE_VERSION = '0.3.0'
 export const KG_TOS_VERSION = '0.3.0'
-export const DS_PREVIEW_URL = environment.DATASET_PREVIEW_URL
 export const BACKENDURL = (() => {
   const { BACKEND_URL } = environment
   if (!BACKEND_URL) return ``
@@ -83,7 +82,6 @@ export const getShader = ({
   removeBg = false
 } = {}): string => {
   const { header, main, premain } = mapKeyColorMap.get(colormap) || (() => {
-    console.warn(`colormap ${colormap} not found. Using default colormap instead`)
     return mapKeyColorMap.get(EnumColorMapName.GREYSCALE)
   })()
 
diff --git a/src/util/generator.ts b/src/util/generator.ts
index 9c9d14a9064fb6d113d7c648ae59c69575314c69..fcf39012ca428114ebe93974a5aa1951db8bef15 100644
--- a/src/util/generator.ts
+++ b/src/util/generator.ts
@@ -1,7 +1,7 @@
 export function* timedValues(ms: number = 500, mode: string = 'linear') {
   const startTime = Date.now()
 
-  const getValue = (fraction) => {
+  const getValue = (fraction: number) => {
     switch (mode) {
     case 'linear':
     default:
diff --git a/src/viewerModule/module.ts b/src/viewerModule/module.ts
index 1e12da494fea67d1ed6a68c526bfaca2269ec458..7516440907c6505b9479c826fde3452768bc0288 100644
--- a/src/viewerModule/module.ts
+++ b/src/viewerModule/module.ts
@@ -18,12 +18,10 @@ import { INJ_ANNOT_TARGET } from "src/atlasComponents/userAnnotations/tools/type
 import { NEHUBA_INSTANCE_INJTKN } from "./nehuba/util";
 import { map } from "rxjs/operators";
 import { TContextArg } from "./viewer.interface";
-import { ViewerStateBreadCrumbModule } from "./viewerStateBreadCrumb/module";
 import { API_SERVICE_SET_VIEWER_HANDLE_TOKEN, AtlasViewerAPIServices, setViewerHandleFactory } from "src/atlasViewer/atlasViewer.apiService.service";
 import { ILoadMesh, LOAD_MESH_TOKEN } from "src/messaging/types";
 import { KeyFrameModule } from "src/keyframesModule/module";
 import { ViewerInternalStateSvc } from "./viewerInternalState.service";
-import { LayerBrowserModule } from "src/ui/layerbrowser";
 import { SAPIModule } from 'src/atlasComponents/sapi';
 import { NehubaVCtxToBbox } from "./pipes/nehubaVCtxToBbox.pipe";
 import { SapiViewsModule, SapiViewsUtilModule } from "src/atlasComponents/sapiViews";
@@ -43,9 +41,7 @@ import { SapiViewsModule, SapiViewsUtilModule } from "src/atlasComponents/sapiVi
     UserAnnotationsModule,
     QuickTourModule,
     ContextMenuModule,
-    ViewerStateBreadCrumbModule,
     KeyFrameModule,
-    LayerBrowserModule,
     SAPIModule,
     SapiViewsModule,
     SapiViewsUtilModule
diff --git a/src/viewerModule/nehuba/constants.ts b/src/viewerModule/nehuba/constants.ts
index bbd36606525015fcd2f8e6315a061ea2a7f56a36..6537a7aef4ea762d6d38c85ac335011551b5767e 100644
--- a/src/viewerModule/nehuba/constants.ts
+++ b/src/viewerModule/nehuba/constants.ts
@@ -4,17 +4,6 @@ import { Observable } from 'rxjs'
 export { getNgIds } from 'src/util/fn'
 export const NEHUBA_VIEWER_FEATURE_KEY = 'ngViewerFeature'
 
-export interface INgLayerInterface {
-  name: string // displayName
-  source: string
-  mixability: string // base | mixable | nonmixable
-  annotation?: string //
-  id?: string // unique identifier
-  visible?: boolean
-  shader?: string
-  transform?: any
-}
-
 export interface IRegion {
   [key: string]: any
   ngId: string
diff --git a/src/viewerModule/nehuba/layerCtrl.service/index.ts b/src/viewerModule/nehuba/layerCtrl.service/index.ts
index 05cbb34fe0a5803c935749c2c45e6345bb467746..09065a46f416dd4373e98395f4cf985715718cce 100644
--- a/src/viewerModule/nehuba/layerCtrl.service/index.ts
+++ b/src/viewerModule/nehuba/layerCtrl.service/index.ts
@@ -7,5 +7,5 @@ export {
   SET_COLORMAP_OBS,
   SET_LAYER_VISIBILITY,
   getRgb,
-  INgLayerInterface,
+  
 } from './layerCtrl.util'
diff --git a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.effects.ts b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.effects.ts
new file mode 100644
index 0000000000000000000000000000000000000000..967472606b37e3b06775396db0ab353d63f90687
--- /dev/null
+++ b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.effects.ts
@@ -0,0 +1,66 @@
+import { Injectable } from "@angular/core";
+import { createEffect } from "@ngrx/effects";
+import { select, Store } from "@ngrx/store";
+import { of } from "rxjs";
+import { mapTo, switchMap, withLatestFrom, filter, catchError } from "rxjs/operators";
+import { SAPI } from "src/atlasComponents/sapi";
+import { atlasAppearance, atlasSelection } from "src/state";
+import { EnumColorMapName } from "src/util/colorMaps";
+import { getShader } from "src/util/constants";
+import { NehubaLayerControlService } from "./layerCtrl.service";
+
+@Injectable()
+export class LayerCtrlEffects {
+  onRegionSelectClearPmapLayer = createEffect(() => this.store.pipe(
+    select(atlasSelection.selectors.selectedRegions),
+    withLatestFrom(this.store.pipe(
+      select(atlasSelection.selectors.selectedATP)
+    )),
+    mapTo(
+      atlasAppearance.actions.removeCustomLayer({
+        id: NehubaLayerControlService.PMAP_LAYER_NAME
+      })
+    )
+  ))
+
+  onRegionSelectShowNewPmapLayer = createEffect(() => this.store.pipe(
+    select(atlasSelection.selectors.selectedRegions),
+    filter(regions => regions.length > 0),
+    withLatestFrom(
+      this.store.pipe(
+        select(atlasSelection.selectors.selectedATP)
+      )
+    ),
+    switchMap(([ regions, { atlas, parcellation, template } ]) => {
+      const sapiRegion = this.sapi.getRegion(atlas["@id"], parcellation["@id"], regions[0].name)
+      return sapiRegion.getMapInfo(template["@id"])
+        .then(val => 
+          atlasAppearance.actions.addCustomLayer({
+            customLayer: {
+              clType: "customlayer/nglayer",
+              id: NehubaLayerControlService.PMAP_LAYER_NAME,
+              source: `nifti://${sapiRegion.getMapUrl(template["@id"])}`,
+              shader: getShader({
+                colormap: EnumColorMapName.VIRIDIS,
+                highThreshold: val.max,
+                lowThreshold: val.min,
+                removeBg: true,
+              })
+            }
+          })
+        )
+    }),
+    catchError((err, obs) => of(
+      atlasAppearance.actions.removeCustomLayer({
+        id: NehubaLayerControlService.PMAP_LAYER_NAME
+      })
+    ))
+  ))
+
+  constructor(
+    private store: Store<any>,
+    private sapi: SAPI,  
+  ){
+
+  }
+}
\ No newline at end of file
diff --git a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.spec.ts b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.spec.ts
index 5ef1deb33b6fad50fa407239e64a83ad3b154793..8f6e2d64648bda49141346dbfbcb62bfeb72eaab 100644
--- a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.spec.ts
+++ b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.spec.ts
@@ -1,11 +1,7 @@
-import { fakeAsync, TestBed, tick } from "@angular/core/testing"
+import { fakeAsync, TestBed } from "@angular/core/testing"
 import { MockStore, provideMockStore } from "@ngrx/store/testing"
 import { NehubaLayerControlService } from "./layerCtrl.service"
 import * as layerCtrlUtil from '../constants'
-import { hot } from "jasmine-marbles"
-import { IColorMap } from "./layerCtrl.util"
-import { debounceTime } from "rxjs/operators"
-import { ngViewerSelectorClearView, ngViewerSelectorLayers } from "src/services/state/ngViewerState.store.helper"
 import {
   atlasSelection
 } from "src/state"
diff --git a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.ts b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.ts
index 8cb8fed1ea05c9334b107200ceba86828ae9d4de..5af33b5694d9c63e4d325f2ab5a00fe7a7e45193 100644
--- a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.ts
+++ b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.service.ts
@@ -1,14 +1,12 @@
 import { Injectable, OnDestroy } from "@angular/core";
 import { select, Store } from "@ngrx/store";
-import { BehaviorSubject, combineLatest, from, merge, Observable, Subject, Subscription } from "rxjs";
+import { BehaviorSubject, combineLatest, merge, Observable, Subject, Subscription } from "rxjs";
 import { debounceTime, distinctUntilChanged, filter, map, shareReplay, switchMap, withLatestFrom } from "rxjs/operators";
-import { IColorMap, INgLayerCtrl, INgLayerInterface, TNgLayerCtrl } from "./layerCtrl.util";
+import { IColorMap, INgLayerCtrl, TNgLayerCtrl } from "./layerCtrl.util";
 import { IAuxMesh } from '../store'
 import { IVolumeTypeDetail } from "src/util/siibraApiConstants/types";
-import { ngViewerActionAddNgLayer, ngViewerActionRemoveNgLayer, ngViewerSelectorClearView, ngViewerSelectorLayers } from "src/services/state/ngViewerState.store.helper";
-import { hexToRgb } from 'common/util'
 import { SAPI, SapiParcellationModel } from "src/atlasComponents/sapi";
-import { SAPISpace } from "src/atlasComponents/sapi/core";
+import { SAPISpace, SAPIRegion } from "src/atlasComponents/sapi/core";
 import { getParcNgId, fromRootStore as nehubaConfigSvcFromRootStore } from "../config.service"
 import { getRegionLabelIndex } from "../config.service/util";
 import { annotation, atlasAppearance, atlasSelection } from "src/state";
@@ -65,7 +63,8 @@ export class NehubaLayerControlService implements OnDestroy{
 
   public selectedATPR$ = this.selectedATP$.pipe(
     switchMap(({ atlas, template, parcellation }) => 
-      from(this.sapiSvc.getParcRegions(atlas["@id"], parcellation["@id"], template["@id"])).pipe(
+      this.store$.pipe(
+        select(atlasSelection.selectors.selectedParcAllRegions),
         map(regions => ({
           atlas, template, parcellation, regions
         })),
@@ -85,7 +84,7 @@ export class NehubaLayerControlService implements OnDestroy{
           if (!r.hasAnnotation.visualizedIn) continue
 
           const ngId = getParcNgId(atlas, template, parcellation, r)
-          const [ red, green, blue ] = hexToRgb(r.hasAnnotation.displayColor) || Object.keys(BACKUP_COLOR).map(key => BACKUP_COLOR[key])
+          const [ red, green, blue ] = SAPIRegion.GetDisplayColor(r)
           const labelIndex = getRegionLabelIndex(atlas, template, parcellation, r)
           if (!labelIndex) continue
 
@@ -181,99 +180,21 @@ export class NehubaLayerControlService implements OnDestroy{
           payload: layerObj
         })
       }),
-      this.store$.pipe(
-        select(atlasSelection.selectors.selectedRegions)
-      ).subscribe(() => {
-        /**
-         * TODO
-         * below is the original code, but can be refactored.
-         * essentially, new workflow will be like the following:
-         * - get SapiRegion
-         * - getRegionalMap info (min/max)
-         * - dispatch new layer call
-         */
-
-        // if (roi$) {
-
-        //   this.sub.push(
-        //     roi$.pipe(
-        //       switchMap(roi => {
-        //         if (!roi || !roi.hasRegionalMap) {
-        //           // clear pmap
-        //           return of(null)
-        //         }
-                
-        //         const { links } = roi
-        //         const { regional_map: regionalMapUrl, regional_map_info: regionalMapInfoUrl } = links
-        //         return from(fetch(regionalMapInfoUrl).then(res => res.json())).pipe(
-        //           map(regionalMapInfo => {
-        //             return {
-        //               roi,
-        //               regionalMapUrl,
-        //               regionalMapInfo
-        //             }
-        //           })
-        //         )
-        //       })
-        //     ).subscribe(processedRoi => {
-        //       if (!processedRoi) {
-        //         this.store$.dispatch(
-        //           ngViewerActionRemoveNgLayer({
-        //             layer: {
-        //               name: NehubaLayerControlService.PMAP_LAYER_NAME
-        //             }
-        //           })
-        //         )
-        //         return
-        //       }
-        //       const { 
-        //         roi,
-        //         regionalMapUrl,
-        //         regionalMapInfo
-        //       } = processedRoi
-        //       const { min, max, colormap = EnumColorMapName.VIRIDIS } = regionalMapInfo || {} as any
-
-        //       const shaderObj = {
-        //         ...PMAP_DEFAULT_CONFIG,
-        //         ...{ colormap },
-        //         ...( typeof min !== 'undefined' ? { lowThreshold: min } : {} ),
-        //         ...( max ? { highThreshold: max } : { highThreshold: 1 } )
-        //       }
-
-        //       const layer = {
-        //         name: NehubaLayerControlService.PMAP_LAYER_NAME,
-        //         source : `nifti://${regionalMapUrl}`,
-        //         mixability : 'nonmixable',
-        //         shader : getShader(shaderObj),
-        //       }
-
-        //       this.store$.dispatch(
-        //         ngViewerActionAddNgLayer({ layer })
-        //       )
-
-        //       // this.layersService.highThresholdMap.set(layerName, highThreshold)
-        //       // this.layersService.lowThresholdMap.set(layerName, lowThreshold)
-        //       // this.layersService.colorMapMap.set(layerName, cmap)
-        //       // this.layersService.removeBgMap.set(layerName, removeBg)
-        //     })
-        //   )
-        // }
-
-      })
     )
 
     this.sub.push(
-      this.ngLayers$.subscribe(({ ngLayers }) => {
-        this.ngLayersRegister.layers = ngLayers
+      this.ngLayers$.subscribe(({ customLayers }) => {
+        this.ngLayersRegister = customLayers
       })
     )
 
     this.sub.push(
       this.store$.pipe(
-        select(ngViewerSelectorClearView),
+        select(atlasAppearance.selectors.customLayers),
+        map(cl => cl.filter(l => l.clType === "customlayer/colormap").length > 0),
         distinctUntilChanged()
       ).subscribe(flag => {
-        const pmapLayer = this.ngLayersRegister.layers.find(l => l.name === NehubaLayerControlService.PMAP_LAYER_NAME)
+        const pmapLayer = this.ngLayersRegister.find(l => l.id === NehubaLayerControlService.PMAP_LAYER_NAME)
         if (!pmapLayer) return
         const payload = {
           type: 'update',
@@ -369,21 +290,13 @@ export class NehubaLayerControlService implements OnDestroy{
      * if layer contains non mixable layer
      */
     this.store$.pipe(
-      select(ngViewerSelectorLayers),
-      map(layers => layers.findIndex(l => l.mixability === 'nonmixable') >= 0),
+      select(atlasAppearance.selectors.customLayers),
+      map(layers => layers.filter(l => l.clType === "customlayer/nglayer").length > 0),
     ),
-    /**
-     * clearviewqueue, indicating something is controlling colour map
-     * show all seg
-     */
-    this.store$.pipe(
-      select(ngViewerSelectorClearView),
-      distinctUntilChanged()
-    )
   ]).pipe(
     withLatestFrom(this.selectedATP$),
-    map(([[ regions, nonmixableLayerExists, clearViewFlag ], { atlas, parcellation, template }]) => {
-      if (nonmixableLayerExists && !clearViewFlag) {
+    map(([[ regions, nonmixableLayerExists ], { atlas, parcellation, template }]) => {
+      if (nonmixableLayerExists) {
         return null
       }
   
@@ -395,7 +308,7 @@ export class NehubaLayerControlService implements OnDestroy{
           return serializeSegment(ngId, label)
         })
       )
-      if (selectedRegionIndexSet.size > 0 && !clearViewFlag) {
+      if (selectedRegionIndexSet.size > 0) {
         return [...selectedRegionIndexSet]
       } else {
         return []
@@ -407,38 +320,33 @@ export class NehubaLayerControlService implements OnDestroy{
    * ngLayers controller
    */
 
-  private ngLayersRegister: {layers: INgLayerInterface[]} = {
-    layers: []
-  }
+  private ngLayersRegister: atlasAppearance.NgLayerCustomLayer[] = []
   public removeNgLayers(layerNames: string[]) {
-    this.ngLayersRegister.layers
-      .filter(layer => layerNames?.findIndex(l => l === layer.name) >= 0)
-      .map(l => l.name)
+    this.ngLayersRegister
+      .filter(layer => layerNames?.findIndex(l => l === layer.id) >= 0)
+      .map(l => l.id)
       .forEach(layerName => {
-        this.store$.dispatch(ngViewerActionRemoveNgLayer({
-          layer: {
-            name: layerName
-          }
-        }))
+        this.store$.dispatch(
+          atlasAppearance.actions.removeCustomLayer({
+            id: layerName
+          })
+        )
       })
   }
-  public addNgLayer(layers: INgLayerInterface[]){
-    this.store$.dispatch(ngViewerActionAddNgLayer({
-      layer: layers
-    }))
-  }
+
   private ngLayers$ = this.store$.pipe(
-    select(ngViewerSelectorLayers),
-    map((ngLayers: INgLayerInterface[]) => {
-      const newLayers = ngLayers.filter(l => {
-        const registeredLayerNames = this.ngLayersRegister.layers.map(l => l.name)
-        return !registeredLayerNames.includes(l.name)
+    select(atlasAppearance.selectors.customLayers),
+    map(customLayers => customLayers.filter(l => l.clType === "customlayer/nglayer") as atlasAppearance.NgLayerCustomLayer[]),
+    map(customLayers => {
+      const newLayers = customLayers.filter(l => {
+        const registeredLayerNames = this.ngLayersRegister.map(l => l.id)
+        return !registeredLayerNames.includes(l.id)
       })
-      const removeLayers = this.ngLayersRegister.layers.filter(l => {
-        const stateLayerNames = ngLayers.map(l => l.name)
-        return !stateLayerNames.includes(l.name)
+      const removeLayers = this.ngLayersRegister.filter(l => {
+        const stateLayerNames = customLayers.map(l => l.id)
+        return !stateLayerNames.includes(l.id)
       })
-      return { newLayers, removeLayers, ngLayers }
+      return { newLayers, removeLayers, customLayers }
     }),
     shareReplay(1)
   )
@@ -450,11 +358,9 @@ export class NehubaLayerControlService implements OnDestroy{
       map(newLayers => {
 
         const newLayersObj: any = {}
-        newLayers.forEach(({ name, source, ...rest }) => newLayersObj[name] = {
+        newLayers.forEach(({ id, source, ...rest }) => newLayersObj[id] = {
           ...rest,
           source,
-          // source: getProxyUrl(source),
-          // ...getProxyOther({source})
         })
   
         return {
@@ -467,7 +373,7 @@ export class NehubaLayerControlService implements OnDestroy{
       map(({ removeLayers }) => removeLayers),
       filter(layers => layers.length > 0),
       map(removeLayers => {
-        const removeLayerNames = removeLayers.map(v => v.name)
+        const removeLayerNames = removeLayers.map(v => v.id)
         return {
           type: 'remove',
           payload: { names: removeLayerNames }
diff --git a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.util.ts b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.util.ts
index 0b76bb2700889156b617dc49d3c091a474dce4df..d5a743d67ee5dfe7ab13521b7ae0383d2e9a7524 100644
--- a/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.util.ts
+++ b/src/viewerModule/nehuba/layerCtrl.service/layerCtrl.util.ts
@@ -1,6 +1,7 @@
 import { InjectionToken } from '@angular/core'
 import { strToRgb } from 'common/util'
 import { Observable } from 'rxjs'
+import { atlasAppearance } from 'src/state'
 
 export interface IColorMap {
   [key: string]: {
@@ -42,10 +43,10 @@ export interface INgLayerCtrl {
     names: string[]
   }
   add: {
-    [key: string]: INgLayerInterface
+    [key: string]: atlasAppearance.NgLayerCustomLayer
   }
   update: {
-    [key: string]: Partial<INgLayerInterface>
+    [key: string]: Partial<atlasAppearance.NgLayerCustomLayer>
   }
   setLayerTransparency: {
     [key: string]: number
@@ -61,14 +62,3 @@ export const SET_COLORMAP_OBS = new InjectionToken<Observable<IColorMap>>('SET_C
 export const SET_LAYER_VISIBILITY = new InjectionToken<Observable<string[]>>('SET_LAYER_VISIBILITY')
 export const SET_SEGMENT_VISIBILITY = new InjectionToken<Observable<string[]>>('SET_SEGMENT_VISIBILITY')
 export const NG_LAYER_CONTROL = new InjectionToken<TNgLayerCtrl<keyof INgLayerCtrl>>('NG_LAYER_CONTROL')
-
-export interface INgLayerInterface {
-  name: string // displayName
-  source: string
-  mixability: string // base | mixable | nonmixable
-  annotation?: string //
-  id?: string // unique identifier
-  visible?: boolean
-  shader?: string
-  transform?: any
-}
diff --git a/src/viewerModule/nehuba/maximisePanelButton/maximisePanelButton.component.ts b/src/viewerModule/nehuba/maximisePanelButton/maximisePanelButton.component.ts
index 16cecc54bea2b3191ecd6b3b4b227fdcd7144778..2838f216817ce253062339deb59b635826ab607b 100644
--- a/src/viewerModule/nehuba/maximisePanelButton/maximisePanelButton.component.ts
+++ b/src/viewerModule/nehuba/maximisePanelButton/maximisePanelButton.component.ts
@@ -1,8 +1,6 @@
 import { Component, Input } from "@angular/core";
 import { select, Store } from "@ngrx/store";
-import { Observable } from "rxjs";
 import { distinctUntilChanged, map } from "rxjs/operators";
-import { PANELS } from 'src/services/state/ngViewerState.store.helper'
 import { ARIA_LABELS } from 'common/constants'
 import { userInterface } from "src/state"
 
diff --git a/src/viewerModule/nehuba/mesh.service/mesh.service.ts b/src/viewerModule/nehuba/mesh.service/mesh.service.ts
index 552af17c944f40a27e8b6ec1427e7b29ad6f88ac..db85e917b8a64feeb28ec279d6c0d61f10243877 100644
--- a/src/viewerModule/nehuba/mesh.service/mesh.service.ts
+++ b/src/viewerModule/nehuba/mesh.service/mesh.service.ts
@@ -35,8 +35,7 @@ export class NehubaMeshService implements OnDestroy {
   }
 
   private allRegions$ = this.store$.pipe(
-    select(atlasSelection.selectors.selectedATP),
-    switchMap(({ atlas, template, parcellation }) => this.sapiSvc.getParcRegions(atlas["@id"], parcellation["@id"], template["@id"]))
+    select(atlasSelection.selectors.selectedParcAllRegions),
   )
 
   private selectedRegions$ = this.store$.pipe(
diff --git a/src/viewerModule/nehuba/navigation.service/navigation.effects.ts b/src/viewerModule/nehuba/navigation.service/navigation.effects.ts
new file mode 100644
index 0000000000000000000000000000000000000000..65db6b37735fdadb2d10f68cfd3aed28702c7969
--- /dev/null
+++ b/src/viewerModule/nehuba/navigation.service/navigation.effects.ts
@@ -0,0 +1,102 @@
+import { Inject, Injectable, OnDestroy } from "@angular/core";
+import { Actions, createEffect, ofType } from "@ngrx/effects";
+import { select, Store } from "@ngrx/store";
+import { Observable, Subscription } from "rxjs";
+import { filter, tap, withLatestFrom } from "rxjs/operators";
+import { atlasSelection, MainState, userPreference } from "src/state"
+import { timedValues } from "src/util/generator";
+import { NehubaViewerUnit } from "../nehubaViewer/nehubaViewer.component";
+import { NEHUBA_INSTANCE_INJTKN } from "../util";
+import { navAdd, navMul } from "./navigation.util";
+
+@Injectable()
+export class NehubaNavigationEffects implements OnDestroy{
+
+  private subscription: Subscription[] = []
+  private nehubaInst: NehubaViewerUnit
+  private rafRef: number
+
+  /**
+   * This is an implementation which reconciles local state with the global navigation state.
+   * - it should **never** set global state.
+   * - there exist two (potential) source of navigation state change
+   *    - directly set via global state (with statuscard, url, etc)
+   *    - via viewer (mostly through user interaction)
+   *   if the latter were emitted, it is the local's responsibility to check the (debounced) diff between local/global state,
+   *   and update global state accordingly.
+   * - This effect updates the internal navigation state. It should leave reporting any diff to the local viewer's native implementation.
+   */
+  onNavigateTo = createEffect(() => this.action.pipe(
+    ofType(atlasSelection.actions.navigateTo),
+    filter(() => !!this.nehubaInst),
+    withLatestFrom(
+      this.store.pipe(
+        select(userPreference.selectors.useAnimation)
+      ),
+      this.store.pipe(
+        select(atlasSelection.selectors.navigation)
+      )
+    ),
+    tap(([{ navigation, animation, physical }, globalAnimationFlag, currentNavigation]) => {
+      if (!animation || !globalAnimationFlag) {
+        this.nehubaInst.setNavigationState({
+          ...navigation,
+          positionReal: physical
+        })
+        return
+      }
+
+      const gen = timedValues()
+      const src = currentNavigation
+
+      const dest = {
+        ...src,
+        ...navigation
+      }
+
+      const delta = navAdd(dest, navMul(src, -1))
+
+      const animate = () => {
+        
+        /**
+         * if nehubaInst becomes nullish whilst animation is running
+         */  
+        if (!this.nehubaInst) {
+          this.rafRef = null
+          return
+        }
+
+        const next = gen.next()
+        const d =  next.value
+
+        const n = navAdd(src, navMul(delta, d))
+        this.nehubaInst.setNavigationState({
+          ...n,
+          positionReal: true
+        })
+
+        if ( !next.done ) {
+          this.rafRef = requestAnimationFrame(() => animate())
+        } else {
+          this.rafRef = null
+        }
+      }
+      this.rafRef = requestAnimationFrame(() => animate())
+
+    })
+  ), { dispatch: false })
+
+  constructor(
+    private action: Actions,
+    private store: Store<MainState>,
+    @Inject(NEHUBA_INSTANCE_INJTKN) nehubaInst$: Observable<NehubaViewerUnit>,
+  ){
+    this.subscription.push(
+      nehubaInst$.subscribe(val => this.nehubaInst = val),
+    )
+  }
+
+  ngOnDestroy(){
+    while(this.subscription.length > 0) this.subscription.pop().unsubscribe()
+  }
+}
\ No newline at end of file
diff --git a/src/viewerModule/nehuba/navigation.service/navigation.service.ts b/src/viewerModule/nehuba/navigation.service/navigation.service.ts
index 17dd917898fe30761c9ab3f6e8c2ac8bb43b7d92..59ef98c02b7a82fa3850040170ae23608d1ea3e6 100644
--- a/src/viewerModule/nehuba/navigation.service/navigation.service.ts
+++ b/src/viewerModule/nehuba/navigation.service/navigation.service.ts
@@ -101,7 +101,7 @@ export class NehubaNavigationService implements OnDestroy{
         
         if (!navEql) {
           this.store$.dispatch(
-            actions.navigateTo({
+            actions.setNavigation({
               navigation: roundedNav
             })
           )
diff --git a/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts b/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts
index 9627bd89b60ebeb6efb6ddcc576bcc665f474c41..625be54ba3d759ae203c3928a465e79c0f841909 100644
--- a/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts
+++ b/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts
@@ -85,6 +85,7 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
 
   private subscriptions: Subscription[] = []
 
+  private _nehubaReady = false
   @Output() public nehubaReady: EventEmitter<null> = new EventEmitter()
   @Output() public layersChanged: EventEmitter<null> = new EventEmitter()
   private layersChangedHandler: any
@@ -181,8 +182,19 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
         this.patchNG()
         this.loadNehuba()
 
-        this.layersChangedHandler = this.nehubaViewer.ngviewer.layerManager.layersChanged.add(() => this.layersChanged.emit(null))
-        this.nehubaViewer.ngviewer.registerDisposer(this.layersChangedHandler)
+        const viewer = this.nehubaViewer.ngviewer
+        this.layersChangedHandler = viewer.layerManager.layersChanged.add(() => {
+          this.layersChanged.emit(null)
+          const readiedLayerNames: string[] = viewer.layerManager.managedLayers.filter(l => l.layer).map(l => l.name)
+          for (const layerName in this.ngIdSegmentsMap) {
+            if (!readiedLayerNames.includes(layerName)) {
+              return
+            }
+            this._nehubaReady = true
+            this.nehubaReady.emit(null)
+          }
+        })
+        viewer.registerDisposer(this.layersChangedHandler)
       })
       .then(() => {
         // all mutation to this.nehubaViewer should await createNehubaPromise
@@ -255,7 +267,7 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
       this.ondestroySubscriptions.push(
         this.setColormap$.pipe(
           switchMap(switchMapWaitFor({
-            condition: () => !!(this.nehubaViewer?.ngviewer)
+            condition: () => this._nehubaReady
           })),
           debounceTime(160),
         ).subscribe(v => {
@@ -277,7 +289,9 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
     if (this.layerVis$) {
       this.ondestroySubscriptions.push(
         this.layerVis$.pipe(
-          switchMap(switchMapWaitFor({ condition: () => !!(this.nehubaViewer?.ngviewer) })),
+          switchMap(switchMapWaitFor({
+            condition: () => this._nehubaReady
+          })),
           distinctUntilChanged(arrayOrderedEql),
           debounceTime(160),
         ).subscribe((layerNames: string[]) => {
@@ -307,12 +321,11 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
         this.segVis$.pipe(
           switchMap(
             switchMapWaitFor({
-              condition: () => this.nehubaViewer?.ngviewer,
+              condition: () => this._nehubaReady,
               leading: true,
             })
           )
         ).subscribe(val => {
-          console.log(val)
           // null === hide all seg
           if (val === null) {
             this.hideAllSeg()
@@ -335,7 +348,7 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
       this.ondestroySubscriptions.push(
         this.layerCtrl$.pipe(
           bufferUntil(({
-            condition: () => !!this.nehubaViewer?.ngviewer
+            condition: () => this._nehubaReady
           }))
         ).subscribe(messages => {
           for (const message of messages) {
@@ -430,6 +443,7 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
   public loadNehuba() {
     this.nehubaViewer = this.exportNehuba.createNehubaViewer(this.config, (err) => {
       /* print in debug mode */
+      debugger
       this.log.error(err)
     })
 
@@ -443,7 +457,6 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
     /* creation of the layout is done on next frame, hence the settimeout */
     setTimeout(() => {
       getViewer().display.panels.forEach(patchSliceViewPanel)
-      this.nehubaReady.emit(null)
     })
 
     this.newViewerInit()
@@ -691,7 +704,6 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
   public showAllSeg() {
     if (!this.nehubaViewer) { return }
     for (const ngId in this.ngIdSegmentsMap) {
-      console.log(ngId)
       for (const idx of this.ngIdSegmentsMap[ngId]) {
         this.nehubaViewer.showSegment(idx, {
           name: ngId,
@@ -964,7 +976,6 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
     this._s$.forEach(_s$ => {
       if (_s$) { _s$.unsubscribe() }
     })
-
   }
 
   private setColorMap(map: Map<string, Map<number, {red: number, green: number, blue: number}>>) {
diff --git a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts
index 66d4e77a72026a7e9eb033aa37662087f07733e6..4b941c8a3593f20bf03ba4c8dd74ba5537332dfa 100644
--- a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts
+++ b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts
@@ -1,12 +1,9 @@
 import { AfterViewInit, Component, ElementRef, EventEmitter, Inject, Input, OnDestroy, Optional, Output, TemplateRef, ViewChild } from "@angular/core";
 import { select, Store } from "@ngrx/store";
 import { asyncScheduler, BehaviorSubject, combineLatest, fromEvent, merge, Observable, of, Subject, Subscription } from "rxjs";
-import { ngViewerActionCycleViews, ngViewerActionToggleMax } from "src/services/state/ngViewerState/actions";
 import { ClickInterceptor, CLICK_INTERCEPTOR_INJECTOR } from "src/util";
 import { debounceTime, distinctUntilChanged, filter, map, mapTo, scan, shareReplay, startWith, switchMap, switchMapTo, take, tap, throttleTime } from "rxjs/operators";
-import { viewerStateAddUserLandmarks, viewerStateMouseOverCustomLandmark } from "src/services/state/viewerState/actions";
 import { ARIA_LABELS, IDS, QUICKTOUR_DESC } from 'common/constants'
-import { PANELS } from "src/services/state/ngViewerState/constants";
 import { LoggingService } from "src/logging";
 import { EnumViewerEvt, IViewer, TViewerEvent } from "../../viewer.interface";
 import { NehubaViewerUnit } from "../nehubaViewer/nehubaViewer.component";
@@ -27,10 +24,8 @@ import { MatDialog } from "@angular/material/dialog";
 import { AtlasWorkerService } from "src/atlasViewer/atlasViewer.workerService.service";
 import { SAPI, SapiAtlasModel, SapiParcellationModel, SapiRegionModel, SapiSpaceModel } from "src/atlasComponents/sapi";
 import { NehubaConfig, getNehubaConfig, fromRootStore, NgLayerSpec, NgPrecompMeshSpec, NgSegLayerSpec, getParcNgId, getRegionLabelIndex } from "../config.service";
-import { generalActionError } from "src/services/stateStore.helper";
 import { SET_MESHES_TO_LOAD } from "../constants";
-import { actions } from "src/state/atlasSelection";
-import { annotation, atlasSelection, userInteraction, userInterface } from "src/state";
+import { annotation, atlasAppearance, atlasSelection, userInteraction, userInterface, generalActions } from "src/state";
 
 export const INVALID_FILE_INPUT = `Exactly one (1) nifti file is required!`
 
@@ -79,7 +74,7 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnDestroy, AfterViewIni
   public ARIA_LABELS = ARIA_LABELS
   public IDS = IDS
 
-  private currentPanelMode: PANELS
+  private currentPanelMode: userInterface.PanelMode
 
   @ViewChild(NehubaViewerContainerDirective, { static: true })
   public nehubaContainerDirective: NehubaViewerContainerDirective
@@ -266,13 +261,21 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnDestroy, AfterViewIni
 
     /* on selecting of new template, remove additional nglayers */
     if (this.nehubaConfig) {
-      const baseLayerNames = Object.keys(this.nehubaConfig.dataset.initialNgState.layers)
-      this.layerCtrlService.removeNgLayers(baseLayerNames)
+      
+      const initialSpec = this.nehubaConfig.dataset.initialNgState
+      const { layers } = initialSpec
+
+      for (const layerName in layers) {
+        this.store$.dispatch(
+          atlasAppearance.actions.removeCustomLayer({
+            id: layerName
+          })
+        )
+      }
     }
   }
 
   private async loadTmpl(atlas: SapiAtlasModel, _template: SapiSpaceModel, parcellation: SapiParcellationModel, ngLayers: Record<string, NgLayerSpec | NgPrecompMeshSpec | NgSegLayerSpec>) {
-
     if (!_template) return
     /**
      * recalcuate zoom
@@ -285,9 +288,11 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnDestroy, AfterViewIni
       /**
        * selected parc does not have space as a valid output
        */
-      this.store$.dispatch(generalActionError({
-        message: `space ${_template.fullName} is not defined in parcellation ${parcellation.brainAtlasVersions[0].fullName}`
-      }))
+      this.store$.dispatch(
+        generalActions.generalActionError({
+          message: `space ${_template.fullName} is not defined in parcellation ${parcellation.brainAtlasVersions[0].fullName}`
+        })
+      )
       template = await this.sapiSvc.getSpaceDetail(this.selectedAtlas["@id"], parcellation.brainAtlasVersions[0].coordinateSpace["@id"] as string)
     }
     const config = getNehubaConfig(template)
@@ -303,7 +308,7 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnDestroy, AfterViewIni
 
     this.nehubaConfig = config
 
-    this.nehubaContainerDirective.createNehubaInstance(config)
+    await this.nehubaContainerDirective.createNehubaInstance(config)
     this.viewerUnit = this.nehubaContainerDirective.nehubaViewerInstance
     this.sliceRenderEvent$.pipe(
       takeOnePipe()
@@ -321,26 +326,25 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnDestroy, AfterViewIni
     await this.loadParc(atlas, parcellation, template, ngLayers)
 
     const initialSpec = config.dataset.initialNgState
-    const {layers} = initialSpec
-
-    const dispatchLayers = Object.keys(layers).map((key, idx) => {
-      const layer = {
-        name : key,
-        source : layers[key].source,
-        mixability : idx === 0
-          ? 'base'
-          : 'mixable',
-        visible : typeof layers[key].visible === 'undefined'
-          ? true
-          : layers[key].visible,
-        transform : typeof layers[key].transform === 'undefined'
-          ? null
-          : layers[key].transform,
+    const { layers } = initialSpec
+
+    for (const layerName in layers) {
+      const l = layers[layerName]
+      const customLayer: atlasAppearance.NgLayerCustomLayer = {
+        id: layerName,
+        source: l.source,
+        visible: l.visible,
+        transform: l.transform,
+        clType: 'baselayer/nglayer'
       }
-      return layer
-    })
 
-    this.layerCtrlService.addNgLayer(dispatchLayers)
+      this.store$.dispatch(
+        atlasAppearance.actions.addCustomLayer({
+          customLayer
+        })
+      )
+    }
+
     this.newViewer$.next(true)
   }
 
@@ -400,7 +404,7 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnDestroy, AfterViewIni
       switchMap(this.waitForNehuba.bind(this))
     ).subscribe(([mode, panelOrder]) => {
       
-      this.currentPanelMode = mode
+      this.currentPanelMode = mode as userInterface.PanelMode
 
       const viewPanels = panelOrder.split('').map(v => Number(v)).map(idx => this.viewPanels[idx]) as [HTMLElement, HTMLElement, HTMLElement, HTMLElement]
 
@@ -412,26 +416,26 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnDestroy, AfterViewIni
         return
       }
 
-      switch (mode) {
-      case PANELS.H_ONE_THREE: {
+      switch (this.currentPanelMode) {
+      case "H_ONE_THREE": {
         const element = this.removeExistingPanels()
         const newEl = getHorizontalOneThree(viewPanels)
         element.appendChild(newEl)
         break;
       }
-      case PANELS.V_ONE_THREE: {
+      case "V_ONE_THREE": {
         const element = this.removeExistingPanels()
         const newEl = getVerticalOneThree(viewPanels)
         element.appendChild(newEl)
         break;
       }
-      case PANELS.FOUR_PANEL: {
+      case "FOUR_PANEL": {
         const element = this.removeExistingPanels()
         const newEl = getFourPanel(viewPanels)
         element.appendChild(newEl)
         break;
       }
-      case PANELS.SINGLE_PANEL: {
+      case "SINGLE_PANEL": {
         const element = this.removeExistingPanels()
         const newEl = getSinglePanel(viewPanels)
         element.appendChild(newEl)
@@ -586,7 +590,7 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnDestroy, AfterViewIni
         }),
         moveToNavigationLoc : (coord, _realSpace?) => {
           this.store$.dispatch(
-            actions.navigateTo({
+            atlasSelection.actions.navigateTo({
               navigation: {
                 position: coord
               },
@@ -618,10 +622,10 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnDestroy, AfterViewIni
           if (!landmarks.every(l => l.position.constructor === Array) || !landmarks.every(l => l.position.every(v => !isNaN(v))) || !landmarks.every(l => l.position.length == 3)) {
             throw new Error('position needs to be a length 3 tuple of numbers ')
           }
-
-          this.store$.dispatch(viewerStateAddUserLandmarks({
-            landmarks
-          }))
+          /**
+           * add implementation to user landmarks
+           */
+          console.warn(`adding landmark not yet implemented`)
         },
         remove3DLandmarks : landmarkIds => {
           this.store$.dispatch(
@@ -719,9 +723,9 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnDestroy, AfterViewIni
   }
 
   handleCycleViewEvent(){
-    if (this.currentPanelMode !== PANELS.SINGLE_PANEL) return
+    if (this.currentPanelMode !== "SINGLE_PANEL") return
     this.store$.dispatch(
-      ngViewerActionCycleViews()
+      userInterface.actions.cyclePanelMode()
     )
   }
 
@@ -740,7 +744,7 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnDestroy, AfterViewIni
     const trueOnhoverSegments = this.onhoverSegments && this.onhoverSegments.filter(v => typeof v === 'object')
     if (!trueOnhoverSegments || (trueOnhoverSegments.length === 0)) return true
     this.store$.dispatch(
-      actions.selectRegions({
+      atlasSelection.actions.selectRegions({
         regions: trueOnhoverSegments.slice(0, 1)
       })
     )
@@ -752,9 +756,11 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnDestroy, AfterViewIni
   }) 
 
   public toggleMaximiseMinimise(index: number) {
-    this.store$.dispatch(ngViewerActionToggleMax({
-      payload: { index }
-    }))
+    this.store$.dispatch(
+      userInterface.actions.toggleMaximiseView({
+        targetIndex: index
+      })
+    )
   }
 
   public zoomNgView(panelIndex: number, factor: number) {
@@ -789,7 +795,12 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnDestroy, AfterViewIni
   private dismissAllAddedLayers(){
     while (this.droppedLayerNames.length) {
       const { resourceUrl, layerName } = this.droppedLayerNames.pop()
-      this.layerCtrlService.removeNgLayers([ layerName ])
+      this.store$.dispatch(
+        atlasAppearance.actions.removeCustomLayer({
+          id: layerName
+        })
+      )
+      
       URL.revokeObjectURL(resourceUrl)
     }
   }
@@ -835,17 +846,21 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnDestroy, AfterViewIni
         layerName: randomUuid,
         resourceUrl: url
       })
-      this.layerCtrlService.addNgLayer([{
-        name: randomUuid,
-        mixability: 'mixable',
-        source: `nifti://${url}`,
-        shader: getShader({
-          colormap: EnumColorMapName.MAGMA,
-          lowThreshold: meta.min || 0,
-          highThreshold: meta.max || 1
-        })
-      }])
 
+      this.store$.dispatch(
+        atlasAppearance.actions.addCustomLayer({
+          customLayer: {
+            id: randomUuid,
+            source: `nifti://${url}`,
+            shader: getShader({
+              colormap: EnumColorMapName.MAGMA,
+              lowThreshold: meta.min || 0,
+              highThreshold: meta.max || 1
+            }),
+            clType: 'customlayer/nglayer'
+          }
+        })
+      )
       this.dialog.open(
         this.layerCtrlTmpl,
         {
@@ -900,19 +915,13 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnDestroy, AfterViewIni
   }
 
   public handleMouseEnterCustomLandmark(lm) {
-    this.store$.dispatch(
-      viewerStateMouseOverCustomLandmark({
-        payload: { userLandmark: lm }
-      })
-    )
+    console.log('handle enter custom landmark')
+
   }
 
   public handleMouseLeaveCustomLandmark(_lm) {
-    this.store$.dispatch(
-      viewerStateMouseOverCustomLandmark({
-        payload: { userLandmark: null }
-      })
-    )
+    console.log("handle leave custom landmark")
+
   }
 
   public quickTourOverwritingPos = {
diff --git a/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.spec.ts b/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.spec.ts
index baab9f9d27b4d65801c5944541e54c899ecf69b0..49dbb2e31e9a663981ed69f059c2a2085d5d6ebb 100644
--- a/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.spec.ts
+++ b/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.spec.ts
@@ -5,8 +5,6 @@ import { MockStore, provideMockStore } from "@ngrx/store/testing"
 import { NehubaViewerUnit } from "../nehubaViewer/nehubaViewer.component"
 import { NehubaViewerContainerDirective } from "./nehubaViewerInterface.directive"
 import { Subject } from "rxjs"
-import { ngViewerActionNehubaReady } from "src/services/state/ngViewerState/actions"
-import { viewerStateMouseOverCustomLandmarkInPerspectiveView } from "src/services/state/viewerState/actions"
 import { userPreference, atlasSelection, atlasAppearance } from "src/state"
 
 describe('> nehubaViewerInterface.directive.ts', () => {
@@ -130,16 +128,7 @@ describe('> nehubaViewerInterface.directive.ts', () => {
     
       describe('> on clear called', () => {
         it('> dispatches nehubaReady: false action', () => {
-          const mockStore = TestBed.inject(MockStore)
-          const mockStoreDispatchSpy = spyOn(mockStore, 'dispatch')
-          directiveInstance.clear()
-          expect(
-            mockStoreDispatchSpy
-          ).toHaveBeenCalledWith(
-            ngViewerActionNehubaReady({
-              nehubaReady: false
-            })
-          )
+
         })
 
         it('> iavNehubaViewerContainerViewerLoading emits false', () => {
@@ -206,82 +195,25 @@ describe('> nehubaViewerInterface.directive.ts', () => {
         })
         it('> single null emits null', fakeAsync(() => {
 
-          directiveInstance.createNehubaInstance(template, lifecycle)
-          spyNehubaViewerInstance.mouseoverUserlandmarkEmitter.next(null)
-
-          tick(200)
-          expect(dispatchSpy).toHaveBeenCalledWith(
-            viewerStateMouseOverCustomLandmarkInPerspectiveView({
-              payload: { label: null }
-            })
-          )
         }))
 
         it('> single value emits value', fakeAsync(() => {
 
-          directiveInstance.createNehubaInstance(template, lifecycle)
-          spyNehubaViewerInstance.mouseoverUserlandmarkEmitter.next("24")
-
-          tick(200)
-          expect(dispatchSpy).toHaveBeenCalledWith(
-            viewerStateMouseOverCustomLandmarkInPerspectiveView({
-              payload: { label: "24" }
-            })
-          )
         }))
 
         describe('> double value in 140ms emits last value', () => {
 
           it('> null - 24 emits 24', fakeAsync(() => {
 
-            directiveInstance.createNehubaInstance(template, lifecycle)
-            spyNehubaViewerInstance.mouseoverUserlandmarkEmitter.next(null)
-            spyNehubaViewerInstance.mouseoverUserlandmarkEmitter.next("24")
-  
-            tick(200)
-            expect(dispatchSpy).toHaveBeenCalledWith(
-              viewerStateMouseOverCustomLandmarkInPerspectiveView({
-                payload: { label: "24" }
-              })
-            )
           }))
           it('> 24 - null emits null', fakeAsync(() => {
 
-            directiveInstance.createNehubaInstance(template, lifecycle)
-            spyNehubaViewerInstance.mouseoverUserlandmarkEmitter.next("24")
-            spyNehubaViewerInstance.mouseoverUserlandmarkEmitter.next(null)
-  
-            tick(200)
-            expect(dispatchSpy).toHaveBeenCalledWith(
-              viewerStateMouseOverCustomLandmarkInPerspectiveView({
-                payload: { label: null }
-              })
-            )
+
           }))
         })
       
         it('> single value outside 140 ms emits separately', fakeAsync(() => {
 
-          directiveInstance.createNehubaInstance(template, lifecycle)
-          spyNehubaViewerInstance.mouseoverUserlandmarkEmitter.next(null)
-          tick(200)
-          spyNehubaViewerInstance.mouseoverUserlandmarkEmitter.next("24")
-
-          tick(200)
-          expect(
-            dispatchSpy.calls.allArgs()
-          ).toEqual([
-            [
-              viewerStateMouseOverCustomLandmarkInPerspectiveView({
-                payload: { label: null }
-              })
-            ],
-            [
-              viewerStateMouseOverCustomLandmarkInPerspectiveView({
-                payload: { label: "24" }
-              })
-            ]
-          ])
         }))
       })
     })
diff --git a/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.ts b/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.ts
index e476b805551731e9f691a7b28937b4de1203c53a..04c087b6ea103f661035837108e876a9aae51334 100644
--- a/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.ts
+++ b/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerInterface.directive.ts
@@ -4,9 +4,7 @@ import { Store, select } from "@ngrx/store";
 import { Subscription, Observable, fromEvent, asyncScheduler, combineLatest } from "rxjs";
 import { distinctUntilChanged, filter, debounceTime, scan, map, throttleTime, switchMapTo } from "rxjs/operators";
 import { serializeSegment, takeOnePipe } from "../util";
-import { ngViewerActionNehubaReady } from "src/services/state/ngViewerState/actions";
 import { LoggingService } from "src/logging";
-import { uiActionMouseoverLandmark } from "src/services/state/uiState/actions";
 import { arrayOfPrimitiveEqual } from 'src/util/fn'
 import { INavObj, NehubaNavigationService } from "../navigation.service";
 import { NehubaConfig, defaultNehubaConfig } from "../config.service";
@@ -204,7 +202,7 @@ export class NehubaViewerContainerDirective implements OnInit, OnDestroy{
         function onInit() {
           this.overrideShowLayers = forceShowLayerNames
         }
-        this.createNehubaInstance(copiedNehubaConfig, { onInit })
+        await this.createNehubaInstance(copiedNehubaConfig, { onInit })
       }),
 
       this.gpuLimit$.pipe(
@@ -235,8 +233,11 @@ export class NehubaViewerContainerDirective implements OnInit, OnDestroy{
     this.nehubaViewerInstance.toggleOctantRemoval(flag)
   }
 
-  createNehubaInstance(nehubaConfig: NehubaConfig, lifeCycle: INehubaLifecycleHook = {}){
+  async createNehubaInstance(nehubaConfig: NehubaConfig, lifeCycle: INehubaLifecycleHook = {}){
     this.clear()
+
+    await new Promise((rs, rj) => setTimeout(rs, 0))
+
     this.iavNehubaViewerContainerViewerLoading.emit(true)
     this.cr = this.el.createComponent(this.nehubaViewerFactory)
 
@@ -273,11 +274,6 @@ export class NehubaViewerContainerDirective implements OnInit, OnDestroy{
         /**
          * TODO when user selects new template, window.viewer
          */
-        this.store$.dispatch(
-          ngViewerActionNehubaReady({
-            nehubaReady: true,
-          })
-        )
       }),
 
       this.nehubaViewerInstance.mouseoverSegmentEmitter.pipe(
@@ -288,11 +284,7 @@ export class NehubaViewerContainerDirective implements OnInit, OnDestroy{
       this.nehubaViewerInstance.mouseoverLandmarkEmitter.pipe(
         distinctUntilChanged()
       ).subscribe(label => {
-        this.store$.dispatch(
-          uiActionMouseoverLandmark({
-            landmark: label
-          })
-        )
+        console.warn(`mouseover landmark`, label)
       }),
 
       this.nehubaViewerInstance.mouseoverUserlandmarkEmitter.pipe(
@@ -327,12 +319,6 @@ export class NehubaViewerContainerDirective implements OnInit, OnDestroy{
       this.nehubaViewerSubscriptions.pop().unsubscribe()
     }
 
-    this.store$.dispatch(
-      ngViewerActionNehubaReady({
-        nehubaReady: false,
-      })
-    )
-
     this.iavNehubaViewerContainerViewerLoading.emit(false)
     if(this.cr) this.cr.destroy()
     this.el.clear()
diff --git a/src/viewerModule/nehuba/ngLayerCtl/ngLayerCtrl.component.ts b/src/viewerModule/nehuba/ngLayerCtl/ngLayerCtrl.component.ts
index 2b2db1dc27a6a2e7add85ee09f106ffdc85ff2cb..bc85f84690053f7b765fe7f317552086d39e448f 100644
--- a/src/viewerModule/nehuba/ngLayerCtl/ngLayerCtrl.component.ts
+++ b/src/viewerModule/nehuba/ngLayerCtl/ngLayerCtrl.component.ts
@@ -1,8 +1,8 @@
-import { ChangeDetectionStrategy, Component, Inject, Input, OnChanges, OnDestroy, SimpleChanges } from "@angular/core";
+import { ChangeDetectionStrategy, Component, Inject, Input, OnChanges, OnDestroy } from "@angular/core";
 import { Store } from "@ngrx/store";
 import { isMat4 } from "common/util"
 import { Observable } from "rxjs";
-import { ngViewerActionAddNgLayer, ngViewerActionRemoveNgLayer } from "src/services/state/ngViewerState.store.helper";
+import { atlasAppearance } from "src/state";
 import { NehubaViewerUnit } from "..";
 import { NEHUBA_INSTANCE_INJTKN } from "../util";
 
@@ -120,20 +120,21 @@ export class NgLayerCtrlCmp implements OnChanges, OnDestroy{
         this.removeLayer = null
       }
       this.store.dispatch(
-        ngViewerActionAddNgLayer({
-          layer: [{
-            name: name,
+        atlasAppearance.actions.addCustomLayer({
+          customLayer: {
+            id: name,
             shader: this.shader,
             transform: this.transform,
+            clType: 'customlayer/nglayer',
             source: `precomputed://${this.source}`,
-            opacity: this.opacity
-          }]
+            opacity: this.opacity,
+          }
         })
       )
       this.removeLayer = () => {
         this.store.dispatch(
-          ngViewerActionRemoveNgLayer({
-            layer: [{ name }]
+          atlasAppearance.actions.removeCustomLayer({
+            id: name
           })
         )
       }
diff --git a/src/viewerModule/nehuba/store/actions.ts b/src/viewerModule/nehuba/store/actions.ts
index 03e4821f5b8b26ec5e29464dfc07f15c0f7377b3..c8392e03b7fa423286c416c9c67fc83ad2cb4dfd 100644
--- a/src/viewerModule/nehuba/store/actions.ts
+++ b/src/viewerModule/nehuba/store/actions.ts
@@ -3,13 +3,6 @@ import { createAction, props } from "@ngrx/store";
 import { NEHUBA_VIEWER_FEATURE_KEY } from "../constants";
 import { IAuxMesh } from "./type";
 
-export const actionAddNgLayer = createAction(
-  `[${NEHUBA_VIEWER_FEATURE_KEY}] [addNgLayer]`,
-  props<{
-    layers: any[]
-  }>()
-)
-
 export const actionSetAuxMesh = createAction(
   `[${NEHUBA_VIEWER_FEATURE_KEY}] [setAuxMesh]`,
   props<{
@@ -30,7 +23,3 @@ export const actionSetAuxMeshes = createAction(
     payload: IAuxMesh[]
   }>()
 )
-
-export const actionClearAuxMeshes = createAction(
-  `[${NEHUBA_VIEWER_FEATURE_KEY}] [clearAuxMeshes]`
-)
diff --git a/src/viewerModule/nehuba/store/index.ts b/src/viewerModule/nehuba/store/index.ts
index bfaa5f424408a852f371a4abddc152bae202d81d..70ad438c394fc79d2a59ba9b21497adedc825548 100644
--- a/src/viewerModule/nehuba/store/index.ts
+++ b/src/viewerModule/nehuba/store/index.ts
@@ -1,8 +1,6 @@
 export {
-  actionAddNgLayer,
   actionRemoveAuxMesh,
   actionSetAuxMesh,
-  actionClearAuxMeshes,
   actionSetAuxMeshes,
 } from './actions'
 export {
@@ -14,7 +12,6 @@ export {
 export {
   IAuxMesh,
   INehubaFeature,
-  INgLayerInterface
 } from './type'
 
 export { fromRootStore } from './util'
\ No newline at end of file
diff --git a/src/viewerModule/nehuba/store/type.ts b/src/viewerModule/nehuba/store/type.ts
index 4b1d4d3d69ab657aa67edbd18512397cda07d495..d45347a166b1630d9ecc47cebbfaa48a3a95985b 100644
--- a/src/viewerModule/nehuba/store/type.ts
+++ b/src/viewerModule/nehuba/store/type.ts
@@ -1,3 +1,5 @@
+import { atlasAppearance } from "src/state"
+
 export interface IAuxMesh {
   ['@id']: string
   name: string
@@ -8,19 +10,9 @@ export interface IAuxMesh {
   visible: boolean
 }
 
-export interface INgLayerInterface {
-  name: string // displayName
-  source: string
-  mixability: string // base | mixable | nonmixable
-  annotation?: string //
-  id?: string // unique identifier
-  visible?: boolean
-  shader?: string
-  transform?: any
-}
 
 export interface INehubaFeature {
-  layers: INgLayerInterface[]
+  layers: atlasAppearance.NgLayerCustomLayer[]
   panelMode: string
   panelOrder: string
   octantRemoval: boolean
diff --git a/src/viewerModule/nehuba/util.ts b/src/viewerModule/nehuba/util.ts
index fcec9aa50df3f4a6147b1fb124a343bd52226b92..049f647b533d02527a978bf2d48eeff02806c56a 100644
--- a/src/viewerModule/nehuba/util.ts
+++ b/src/viewerModule/nehuba/util.ts
@@ -1,11 +1,11 @@
 import { InjectionToken } from '@angular/core'
 import { Observable, pipe } from 'rxjs'
 import { filter, scan, take } from 'rxjs/operators'
-import { PANELS } from 'src/services/state/ngViewerState.store.helper'
 import { getExportNehuba, getViewer } from 'src/util/fn'
 import { NehubaViewerUnit } from './nehubaViewer/nehubaViewer.component'
 import { NgConfigViewerState } from "./config.service"
 import { RecursivePartial } from './config.service/type'
+import { userInterface } from 'src/state'
 
 const flexContCmnCls = ['w-100', 'h-100', 'd-flex', 'justify-content-center', 'align-items-stretch']
 
@@ -39,30 +39,37 @@ const left = true
 const right = true
 const bottom = true
 
-const mapModeIdxClass = new Map()
+const mapModeIdxClass = new Map<
+  userInterface.PanelMode, Map<number,{
+    top?: boolean
+    bottom?: boolean
+    left?: boolean
+    right?: boolean
+  }>
+>()
 
-mapModeIdxClass.set(PANELS.FOUR_PANEL, new Map([
+mapModeIdxClass.set("FOUR_PANEL", new Map([
   [0, { top, left }],
   [1, { top, right }],
   [2, { bottom, left }],
   [3, { right, bottom }],
 ]))
 
-mapModeIdxClass.set(PANELS.SINGLE_PANEL, new Map([
+mapModeIdxClass.set("SINGLE_PANEL", new Map([
   [0, { top, left, right, bottom }],
   [1, {}],
   [2, {}],
   [3, {}],
 ]))
 
-mapModeIdxClass.set(PANELS.H_ONE_THREE, new Map([
+mapModeIdxClass.set("H_ONE_THREE", new Map([
   [0, { top, left, bottom }],
   [1, { top, right }],
   [2, { right }],
   [3, { bottom, right }],
 ]))
 
-mapModeIdxClass.set(PANELS.V_ONE_THREE, new Map([
+mapModeIdxClass.set("V_ONE_THREE", new Map([
   [0, { top, left, right }],
   [1, { bottom, left }],
   [2, { bottom }],
@@ -89,7 +96,7 @@ export const panelTouchSide = (panel: HTMLElement, { top: touchTop, left: touchL
   return panel
 }
 
-export const addTouchSideClasses = (panel: HTMLElement, actualOrderIndex: number, panelMode: string) => {
+export const addTouchSideClasses = (panel: HTMLElement, actualOrderIndex: number, panelMode: userInterface.PanelMode) => {
 
   if (actualOrderIndex < 0) { return panel }
 
@@ -105,7 +112,7 @@ export const addTouchSideClasses = (panel: HTMLElement, actualOrderIndex: number
 export const getHorizontalOneThree = (panels: [HTMLElement, HTMLElement, HTMLElement, HTMLElement]) => {
   washPanels(panels)
 
-  panels.forEach((panel, idx) => addTouchSideClasses(panel, idx, PANELS.H_ONE_THREE))
+  panels.forEach((panel, idx) => addTouchSideClasses(panel, idx, "H_ONE_THREE"))
 
   const majorContainer = makeCol(panels[0])
   const minorContainer = makeCol(panels[1], panels[2], panels[3])
@@ -119,7 +126,7 @@ export const getHorizontalOneThree = (panels: [HTMLElement, HTMLElement, HTMLEle
 export const getVerticalOneThree = (panels: [HTMLElement, HTMLElement, HTMLElement, HTMLElement]) => {
   washPanels(panels)
 
-  panels.forEach((panel, idx) => addTouchSideClasses(panel, idx, PANELS.V_ONE_THREE))
+  panels.forEach((panel, idx) => addTouchSideClasses(panel, idx, "V_ONE_THREE"))
 
   const majorContainer = makeRow(panels[0])
   const minorContainer = makeRow(panels[1], panels[2], panels[3])
@@ -133,7 +140,7 @@ export const getVerticalOneThree = (panels: [HTMLElement, HTMLElement, HTMLEleme
 export const getFourPanel = (panels: [HTMLElement, HTMLElement, HTMLElement, HTMLElement]) => {
   washPanels(panels)
 
-  panels.forEach((panel, idx) => addTouchSideClasses(panel, idx, PANELS.FOUR_PANEL))
+  panels.forEach((panel, idx) => addTouchSideClasses(panel, idx, "FOUR_PANEL"))
 
   const majorContainer = makeRow(panels[0], panels[1])
   const minorContainer = makeRow(panels[2], panels[3])
@@ -147,7 +154,7 @@ export const getFourPanel = (panels: [HTMLElement, HTMLElement, HTMLElement, HTM
 export const getSinglePanel = (panels: [HTMLElement, HTMLElement, HTMLElement, HTMLElement]) => {
   washPanels(panels)
 
-  panels.forEach((panel, idx) => addTouchSideClasses(panel, idx, PANELS.SINGLE_PANEL))
+  panels.forEach((panel, idx) => addTouchSideClasses(panel, idx, "SINGLE_PANEL"))
 
   const majorContainer = makeRow(panels[0])
   const minorContainer = makeRow(panels[1], panels[2], panels[3])
diff --git a/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.spec.ts b/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.spec.ts
index b9476bf4f2c384cc7925f8334bb50dbc3c4e8989..b9c8b3737adda7bdb3f0aee902f9cb52caad9391 100644
--- a/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.spec.ts
+++ b/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.spec.ts
@@ -12,7 +12,7 @@ import { ViewerCtrlCmp } from "./viewerCtrlCmp.component"
 import { TestbedHarnessEnvironment } from '@angular/cdk/testing/testbed'
 import { HarnessLoader } from "@angular/cdk/testing"
 import { MatSlideToggleHarness } from '@angular/material/slide-toggle/testing'
-import { atlasAppearance } from "src/state"
+import { atlasAppearance, atlasSelection } from "src/state"
 
 
 describe('> viewerCtrlCmp.component.ts', () => {
@@ -80,9 +80,8 @@ describe('> viewerCtrlCmp.component.ts', () => {
     })
     beforeEach(() => {
       mockStore = TestBed.inject(MockStore)
-      mockStore.overrideSelector(viewerStateSelectedTemplatePureSelector, {})
+      mockStore.overrideSelector(atlasSelection.selectors.selectedTemplate, {} as any)
       mockStore.overrideSelector(atlasAppearance.selectors.octantRemoval, true)
-      mockStore.overrideSelector(viewerStateCustomLandmarkSelector, [])
       mockStore.overrideSelector(selectorAuxMeshes, [])
     })
 
@@ -236,120 +235,5 @@ describe('> viewerCtrlCmp.component.ts', () => {
         )
       })
     })
-
-    describe('> flagDelin', () => {
-      let toggleParcVsblSpy: jasmine.Spy
-      beforeEach(() => {
-        fixture = TestBed.createComponent(ViewerCtrlCmp)
-        toggleParcVsblSpy = spyOn(fixture.componentInstance as any, 'toggleParcVsbl')
-        fixture.detectChanges()
-      })
-      it('> calls toggleParcVsbl', () => {
-        toggleParcVsblSpy.and.callFake(() => {})
-        fixture.componentInstance.flagDelin = false
-        expect(toggleParcVsblSpy).toHaveBeenCalled()
-      })
-    })
-    describe('> toggleParcVsbl', () => {
-      let getViewerConfigSpy: jasmine.Spy
-      let getLayerByNameSpy: jasmine.Spy
-      beforeEach(() => {
-        const pureCstSvc = TestBed.inject(PureContantService)
-        getLayerByNameSpy = mockNehubaViewer.nehubaViewer.ngviewer.layerManager.getLayerByName
-        getViewerConfigSpy = pureCstSvc.getViewerConfig as jasmine.Spy
-        fixture = TestBed.createComponent(ViewerCtrlCmp)
-        fixture.detectChanges()
-      })
-
-      it('> calls pureSvc.getViewerConfig', async () => {
-        getViewerConfigSpy.and.returnValue({})
-        await fixture.componentInstance['toggleParcVsbl']()
-        expect(getViewerConfigSpy).toHaveBeenCalled()
-      })
-
-      describe('> if _flagDelin is true', () => {
-        beforeEach(() => {
-          fixture.componentInstance['_flagDelin'] = true
-          fixture.componentInstance['hiddenLayerNames'] = [
-            'foo',
-            'bar',
-            'baz'
-          ]
-        })
-        it('> go through all hideen layer names and set them to true', async () => {
-          const setVisibleSpy = jasmine.createSpy('setVisible')
-          getLayerByNameSpy.and.returnValue({
-            setVisible: setVisibleSpy
-          })
-          await fixture.componentInstance['toggleParcVsbl']()
-          expect(getLayerByNameSpy).toHaveBeenCalledTimes(3)
-          for (const arg of ['foo', 'bar', 'baz']) {
-            expect(getLayerByNameSpy).toHaveBeenCalledWith(arg)
-          }
-          expect(setVisibleSpy).toHaveBeenCalledTimes(3)
-          expect(setVisibleSpy).toHaveBeenCalledWith(true)
-          expect(setVisibleSpy).not.toHaveBeenCalledWith(false)
-        })
-        it('> hiddenLayerNames resets', async () => {
-          await fixture.componentInstance['toggleParcVsbl']()
-          expect(fixture.componentInstance['hiddenLayerNames']).toEqual([])
-        })
-      })
-
-      describe('> if _flagDelin is false', () => {
-        let managedLayerSpyProp: jasmine.Spy
-        let setVisibleSpy: jasmine.Spy
-        beforeEach(() => {
-          fixture.componentInstance['_flagDelin'] = false
-          setVisibleSpy = jasmine.createSpy('setVisible')
-          getLayerByNameSpy.and.returnValue({
-            setVisible: setVisibleSpy
-          })
-          getViewerConfigSpy.and.resolveTo({
-            'foo': {},
-            'bar': {},
-            'baz': {}
-          })
-          managedLayerSpyProp = spyOnProperty(mockNehubaViewer.nehubaViewer.ngviewer.layerManager, 'managedLayers')
-          managedLayerSpyProp.and.returnValue([{
-            visible: true,
-            name: 'foo'
-          }, {
-            visible: false,
-            name: 'bar'
-          }, {
-            visible: true,
-            name: 'baz'
-          }])
-        })
-
-        afterEach(() => {
-          managedLayerSpyProp.calls.reset()
-        })
-
-        it('> calls schedulRedraw', async () => {
-          await fixture.componentInstance['toggleParcVsbl']()
-          await new Promise(rs => requestAnimationFrame(rs))
-          expect(mockNehubaViewer.nehubaViewer.ngviewer.display.scheduleRedraw).toHaveBeenCalled()
-        })
-
-        it('> only calls setVisible false on visible layers', async () => {
-          await fixture.componentInstance['toggleParcVsbl']()
-          expect(getLayerByNameSpy).toHaveBeenCalledTimes(2)
-          
-          for (const arg of ['foo', 'baz']) {
-            expect(getLayerByNameSpy).toHaveBeenCalledWith(arg)
-          }
-          expect(setVisibleSpy).toHaveBeenCalledTimes(2)
-          expect(setVisibleSpy).toHaveBeenCalledWith(false)
-          expect(setVisibleSpy).not.toHaveBeenCalledWith(true)
-        })
-
-        it('> sets hiddenLayerNames correctly', async () => {
-          await fixture.componentInstance['toggleParcVsbl']()
-          expect(fixture.componentInstance['hiddenLayerNames']).toEqual(['foo', 'baz'])
-        })
-      })
-    })
   })
 })
diff --git a/src/viewerModule/viewerCmp/viewerCmp.component.ts b/src/viewerModule/viewerCmp/viewerCmp.component.ts
index 14ae775e5ea9c5584b3de8c149bc32f1de3122b5..4c7fdce6fc2cdfd80a7302c76e13aca4f898f69a 100644
--- a/src/viewerModule/viewerCmp/viewerCmp.component.ts
+++ b/src/viewerModule/viewerCmp/viewerCmp.component.ts
@@ -287,7 +287,6 @@ export class ViewerCmp implements OnDestroy {
       if (context.viewerType === 'threeSurfer') {
         hoveredRegions = (context as TContextArg<'threeSurfer'>).payload._mouseoverRegion
       }
-      console.log('hoveredRegions', hoveredRegions)
 
       if (hoveredRegions.length > 0) {
         append({
@@ -313,6 +312,12 @@ export class ViewerCmp implements OnDestroy {
     while (this.onDestroyCb.length > 0) this.onDestroyCb.pop()()
   }
 
+  public clearRoi(){
+    this.store$.dispatch(
+      actions.clearSelectedRegions()
+    )
+  }
+
   public selectRoi(roi: SapiRegionModel) {
     this.store$.dispatch(
       actions.selectRegions({
@@ -389,9 +394,25 @@ export class ViewerCmp implements OnDestroy {
   }
 
   onDismissNonbaseLayer(){
-    
+    this.store$.dispatch(
+      atlasSelection.actions.clearNonBaseParcLayer()
+    )
   }
-  onSelectParcellation(parc: SapiParcellationModel){
-
+  onSelectParcellation(parcellation: SapiParcellationModel){
+    this.store$.dispatch(
+      atlasSelection.actions.selectParcellation({
+        parcellation
+      })
+    )
+  }
+  navigateTo(position: number[]) {
+    this.store$.dispatch(
+      atlasSelection.actions.navigateTo({
+        navigation: {
+          position
+        },
+        animation: true,
+      })
+    )
   }
 }
diff --git a/src/viewerModule/viewerCmp/viewerCmp.style.css b/src/viewerModule/viewerCmp/viewerCmp.style.css
index 3e85ab331101bd7a6e2215d37e9e710031bc0cd3..e30172096bd62fc52a359af3c20131c6c517d261 100644
--- a/src/viewerModule/viewerCmp/viewerCmp.style.css
+++ b/src/viewerModule/viewerCmp/viewerCmp.style.css
@@ -3,11 +3,6 @@
   position: relative;
 }
 
-.explore-btn
-{
-  margin-top: 4.5rem;
-}
-
 .region-text-search-autocomplete-position
 {
   z-index: 10;
@@ -59,3 +54,13 @@ mat-drawer
 {
   padding-top: 5rem;
 }
+
+sxplr-sapiviews-core-region-region-chip
+{
+  margin-left:-5rem;
+}
+
+sxplr-sapiviews-core-region-region-chip [prefix]
+{
+  padding-left:5rem;
+}
\ No newline at end of file
diff --git a/src/viewerModule/viewerCmp/viewerCmp.template.html b/src/viewerModule/viewerCmp/viewerCmp.template.html
index 103d28ebc59212e559b68ce3c5788c55184e90f6..d1531cab26aae829c616c2f10c9458c3c2046c4d 100644
--- a/src/viewerModule/viewerCmp/viewerCmp.template.html
+++ b/src/viewerModule/viewerCmp/viewerCmp.template.html
@@ -204,19 +204,26 @@
 
     <!-- such a gross implementation -->
     <!-- TODO fix this -->
-    <div class="mt-1-n w-100 sxplr-pl-2 sxplr-pr-2 m-1px">
+    <div class="sxplr-mt-1-n w-100 sxplr-pl-1 sxplr-pr-1"
+      sxplr-sapiviews-core-region
+      [sxplr-sapiviews-core-region-atlas]="selectedAtlas$ | async"
+      [sxplr-sapiviews-core-region-template]="templateSelected$ | async"
+      [sxplr-sapiviews-core-region-parcellation]="parcellationSelected$ | async"
+      [sxplr-sapiviews-core-region-region]="(selectedRegions$ | async)[0]"
+      [sxplr-sapiviews-core-region-detail-flag]="true"
+      #sapiRegion="sapiViewsCoreRegion">
 
       <!-- TODO use sapiViews/core/region/base and fix the rest -->
       <button mat-raised-button
         *ngIf="!(onlyShowMiniTray$ | async)"
         [attr.aria-label]="ARIA_LABELS.EXPAND"
         (click)="showFullSidenav()"
-        class="explore-btn pe-all w-100"
+        class="sxplr-mt-9 sxplr-pe-all w-100"
         [ngClass]="{
-          'darktheme': true,
-          'lighttheme': false
+          'darktheme': sapiRegion.regionDarkmode,
+          'lighttheme': !sapiRegion.regionDarkmode
         }"
-        [style.backgroundColor]="'accent'">
+        [style.backgroundColor]="sapiRegion.regionRgbString">
         <span class="text iv-custom-comp">
           Explore
         </span>
@@ -355,26 +362,55 @@
 <ng-template #bottomLeftTmpl let-showFullSideNav="showFullSideNav">
 
   <!-- atlas selector -->
-  <sxplr-sapiviews-core-atlas-tmplparcselector *ngIf="viewerLoaded && !(isStandaloneVolumes$ | async)">
+  <sxplr-sapiviews-core-atlas-tmplparcselector
+    *ngIf="viewerLoaded && !(isStandaloneVolumes$ | async)"
+    [iav-key-listener]="[{'type': 'keydown', 'key': 'Escape'}]"
+    (iav-key-event)="tmplParcSelector.closeSelector()"
+    (iav-outsideClick)="tmplParcSelector.closeSelector()"
+    #tmplParcSelector="sxplrSapiViewsCoreAtlasTmplparcselector">
   </sxplr-sapiviews-core-atlas-tmplparcselector>
 
-  <!-- selected parcellation chip -->
-  <sxplr-sapiviews-core-parcellation-smartchip
-    class="sxplr-pointer-events-all"
-    [sxplr-sapiviews-core-parcellation-smartchip-parcellation]="parcellationSelected$ | async"
-    [sxplr-sapiviews-core-parcellation-smartchip-all-parcellations]="allAvailableParcellations$ | async"
-    (sxplr-sapiviews-core-parcellation-smartchip-dismiss-nonbase-layer)="onDismissNonbaseLayer()"
-    (sxplr-sapiviews-core-parcellation-smartchip-select-parcellation)="onSelectParcellation($event)"
-    >
-  </sxplr-sapiviews-core-parcellation-smartchip>
-
-  <!-- chips -->
-  <!-- <div *ngIf="parcellationSelected$ | async"
-    class="d-inline-block flex-grow-1 flex-shrink-1 pe-none overflow-x-auto overflow-y-hidden">
+  <!-- scroll container -->
+  <div class="sxplr-d-inline-flex
+    sxplr-flex-wrap-nowrap
+    sxplr-mxw-80vw
+    sxplr-pe-all
+    sxplr-of-x-auto
+    sxplr-of-y-hidden">
+
+    <!-- selected parcellation chip -->
+    <sxplr-sapiviews-core-parcellation-smartchip
+      class="sxplr-z-2 sxplr-mr-1"
+      [sxplr-sapiviews-core-parcellation-smartchip-parcellation]="parcellationSelected$ | async"
+      [sxplr-sapiviews-core-parcellation-smartchip-all-parcellations]="allAvailableParcellations$ | async"
+      (sxplr-sapiviews-core-parcellation-smartchip-dismiss-nonbase-layer)="onDismissNonbaseLayer()"
+      (sxplr-sapiviews-core-parcellation-smartchip-select-parcellation)="onSelectParcellation($event)"
+      >
+    </sxplr-sapiviews-core-parcellation-smartchip>
+
+    <!-- selected region chip -->
+    <sxplr-sapiviews-core-region-region-chip
+      *ngFor="let region of selectedRegions$ | async"
+      class="sxplr-pe-all sxplr-z-1 sxplr-mr-1"
+      (sxplr-sapiviews-core-region-region-chip-clicked)="showFullSideNav()"
+      [sxplr-sapiviews-core-region-atlas]="selectedAtlas$ | async"
+      [sxplr-sapiviews-core-region-template]="templateSelected$ | async"
+      [sxplr-sapiviews-core-region-parcellation]="parcellationSelected$ | async"
+      [sxplr-sapiviews-core-region-region]="region">
+
+      <div prefix>
+      </div>
 
-    <viewer-state-breadcrumb class="d-inline-block pe-all" (on-item-click)="showFullSideNav()">
-    </viewer-state-breadcrumb>
-  </div> -->
+      <div suffix class="sxplr-scale-70">
+        <button mat-mini-fab
+          color="primary"
+          iav-stop="mousedown click"
+          (click)="clearRoi()">
+          <i class="fas fa-times"></i>
+        </button>
+      </div>
+    </sxplr-sapiviews-core-region-region-chip>
+  </div>
 
 </ng-template>
 
@@ -472,18 +508,27 @@
       <!-- if region selected > 0 -->
       <ng-template [ngIf]="regionSelected?.length > 0" [ngIfElse]="tabTmpl_nothingSelected">
 
+        <div sxplr-sapiviews-core-region
+          [sxplr-sapiviews-core-region-detail-flag]="true"
+          [sxplr-sapiviews-core-region-atlas]="selectedAtlas$ | async"
+          [sxplr-sapiviews-core-region-template]="templateSelected$ | async"
+          [sxplr-sapiviews-core-region-parcellation]="parcellationSelected$ | async"
+          [sxplr-sapiviews-core-region-region]="regionSelected[0]"
+          #tabTmpl_iavRegion="sapiViewsCoreRegion">
+
+        </div>
 
         <!-- TODO fix with sapiView/core/region directive -->
-        <!-- <ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
+        <ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
           matColor: 'accent',
-          customColor: tabTmpl_iavRegion.rgbString,
-          customColorDarkmode: tabTmpl_iavRegion.rgbDarkmode,
+          customColor: tabTmpl_iavRegion.regionRgbString,
+          customColorDarkmode: tabTmpl_iavRegion.regionDarkmode,
           fontIcon: 'fa-brain',
-          tooltip: 'Explore ' + tabTmpl_iavRegion.region.name,
+          tooltip: 'Explore ' + regionSelected[0].name,
           click: click
         }">
 
-        </ng-container> -->
+        </ng-container>
       </ng-template>
 
       <!-- nothing is selected -->
@@ -562,6 +607,7 @@
           [sxplr-sapiviews-core-region-parcellation]="parcellationSelected$ | async"
           [sxplr-sapiviews-core-region-region]="selectedRegions[0]"
           (sxplr-sapiviews-core-region-region-rich-feature-clicked)="showDataset($event)"
+          (sxplr-sapiviews-core-region-navigate-to)="navigateTo($event)"
         >
           <div class="sapi-container" header></div>
         </sxplr-sapiviews-core-region-region-rich>
@@ -798,20 +844,24 @@
   let-backCb="backCb"
   let-feature="feature">
 
-  <!-- back btn -->
-  <button mat-button
-    *ngIf="backCb"
-    (click)="backCb()"
-    [attr.aria-label]="ARIA_LABELS.CLOSE"
-    class="position-absolute z-index-10 m-2">
-    <i class="fas fa-chevron-left"></i>
-    <span class="ml-1">
-      Back
-    </span>
-  </button>
-
-  <sxplr-sapiviews-core-datasets-dataset class="sxplr-mt-8 sxplr-z-index-2 mat-elevation-z2"
+  <sxplr-sapiviews-core-datasets-dataset class="sxplr-z-2 mat-elevation-z2"
     [sxplr-sapiviews-core-datasets-dataset-input]="feature">
+
+    <div header>
+      <!-- back btn -->
+      <button mat-button
+        *ngIf="backCb"
+        (click)="backCb()"
+        [attr.aria-label]="ARIA_LABELS.CLOSE"
+        class="sxplr-mb-2"
+        >
+        <i class="fas fa-chevron-left"></i>
+        <span class="ml-1">
+          Back
+        </span>
+      </button>
+    </div>
+
   </sxplr-sapiviews-core-datasets-dataset>
   
   <sxplr-sapiviews-features-entry
diff --git a/src/viewerModule/viewerStateBreadCrumb/breadcrumb/breadcrumb.component.ts b/src/viewerModule/viewerStateBreadCrumb/breadcrumb/breadcrumb.component.ts
deleted file mode 100644
index a2b0b594b3ab0e2f002e2ab140aefe54f289d3da..0000000000000000000000000000000000000000
--- a/src/viewerModule/viewerStateBreadCrumb/breadcrumb/breadcrumb.component.ts
+++ /dev/null
@@ -1,103 +0,0 @@
-import { Component, EventEmitter, Output } from "@angular/core";
-import { IQuickTourData } from "src/ui/quickTour";
-import { CONST, ARIA_LABELS, QUICKTOUR_DESC } from 'common/constants'
-import { select, Store } from "@ngrx/store";
-import { distinctUntilChanged, map } from "rxjs/operators";
-import { ngViewerActionClearView, ngViewerSelectorClearViewEntries } from "src/services/state/ngViewerState.store.helper";
-import { OVERWRITE_SHOW_DATASET_DIALOG_TOKEN } from "src/util/interfaces";
-import { atlasSelection } from "src/state"
-import { NEVER, of } from "rxjs";
-import { SapiParcellationModel } from "src/atlasComponents/sapi";
-
-@Component({
-  selector: 'viewer-state-breadcrumb',
-  templateUrl: './breadcrumb.template.html',
-  styleUrls: [
-    './breadcrumb.style.css'
-  ],
-  providers: [
-    {
-      provide: OVERWRITE_SHOW_DATASET_DIALOG_TOKEN,
-      useValue: null
-    }
-  ]
-})
-
-export class ViewerStateBreadCrumb {
-
-  public CONST = CONST
-  public ARIA_LABELS = ARIA_LABELS
-
-  @Output('on-item-click')
-  onChipClick = new EventEmitter()
-
-  public quickTourChips: IQuickTourData = {
-    order: 5,
-    description: QUICKTOUR_DESC.CHIPS,
-  }
-
-  public clearViewKeys$ = this.store$.pipe(
-    select(ngViewerSelectorClearViewEntries)
-  )
-
-  // TODO what is this observable anyway?
-  public selectedAdditionalLayers$ = of([])
-
-  public parcellationSelected$ = this.store$.pipe(
-    select(atlasSelection.selectors.selectedParcellation),
-    distinctUntilChanged(),
-    
-  )
-
-  public selectedRegions$ = this.store$.pipe(
-    select(atlasSelection.selectors.selectedRegions),
-    distinctUntilChanged(),
-  )
-
-  // TODO add version info in siibra-api/siibra-python
-  public selectedLayerVersions$ = NEVER
-
-  constructor(private store$: Store<any>){
-  }
-
-  handleChipClick(){
-    this.onChipClick.emit(null)
-  }
-
-  public clearSelectedRegions(){
-    this.store$.dispatch(
-      atlasSelection.actions.clearSelectedRegions()
-    )
-  }
-
-  public unsetClearViewByKey(key: string){
-    this.store$.dispatch(
-      ngViewerActionClearView({ payload: {
-        [key]: false
-      }})
-    )
-  }
-
-  public clearAdditionalLayer(layer: { ['@id']: string }){
-    this.store$.dispatch(
-      atlasSelection.actions.clearNonBaseParcLayer()
-    )
-  }
-
-  public selectParcellationWithId(parcId: string) {
-    this.store$.dispatch(
-      atlasSelection.actions.selectATPById({
-        parcellationId: parcId
-      })
-    )
-  }
-
-  public bindFns(fns){
-    return () => {
-      for (const [ fn, ...arg] of fns) {
-        fn(...arg)
-      }
-    }
-  }
-
-}
diff --git a/src/viewerModule/viewerStateBreadCrumb/breadcrumb/breadcrumb.style.css b/src/viewerModule/viewerStateBreadCrumb/breadcrumb/breadcrumb.style.css
deleted file mode 100644
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000
diff --git a/src/viewerModule/viewerStateBreadCrumb/breadcrumb/breadcrumb.template.html b/src/viewerModule/viewerStateBreadCrumb/breadcrumb/breadcrumb.template.html
deleted file mode 100644
index d1338f81bbd2ab900e4a6d66f1c6d2e9d74c4a09..0000000000000000000000000000000000000000
--- a/src/viewerModule/viewerStateBreadCrumb/breadcrumb/breadcrumb.template.html
+++ /dev/null
@@ -1,187 +0,0 @@
-<mat-chip-list
-  quick-tour
-  [quick-tour-description]="quickTourChips.description"
-  [quick-tour-order]="quickTourChips.order">
-
-  <!-- additional layer -->
-
-  <ng-container>
-    <ng-container *ngTemplateOutlet="currParcellationTmpl; context: {
-      addParc: (selectedAdditionalLayers$ | async),
-      parc: (parcellationSelected$ | async)
-    }">
-    </ng-container>
-  </ng-container>
-
-  <!-- any selected region(s) -->
-  <ng-container>
-    <ng-container *ngTemplateOutlet="selectedRegionTmpl">
-    </ng-container>
-  </ng-container>
-</mat-chip-list>
-
-
-<!-- parcellation chip / region chip -->
-<ng-template #currParcellationTmpl let-parc="parc" let-addParc="addParc">
-  <div [matMenuTriggerFor]="layerVersionMenu"
-    [matMenuTriggerData]="{ layerVersionMenuTrigger: layerVersionMenuTrigger }"
-    #layerVersionMenuTrigger="matMenuTrigger">
-
-    <ng-template [ngIf]="addParc && addParc.length > 0" [ngIfElse]="defaultParcTmpl">
-      <ng-container *ngFor="let p of addParc">
-        <ng-container *ngTemplateOutlet="chipTmpl; context: {
-          parcel: p,
-          selected: true,
-          dismissable: true,
-          ariaLabel: ARIA_LABELS.PARC_VER_SELECT,
-          onclick: layerVersionMenuTrigger.toggleMenu.bind(layerVersionMenuTrigger)
-        }">
-        </ng-container>
-      </ng-container>
-    </ng-template>
-    <ng-template #defaultParcTmpl>
-      <ng-template [ngIf]="parc">
-
-        <ng-container *ngTemplateOutlet="chipTmpl; context: {
-          parcel: parc,
-          selected: false,
-          dismissable: false,
-          ariaLabel: ARIA_LABELS.PARC_VER_SELECT,
-          onclick: layerVersionMenuTrigger.toggleMenu.bind(layerVersionMenuTrigger)
-        }">
-        </ng-container>
-      </ng-template>
-    </ng-template>
-  </div>
-</ng-template>
-
-
-<ng-template #selectedRegionTmpl>
-
-  <!-- regions chip -->
-  <ng-template [ngIf]="selectedRegions$ | async" let-selectedRegions="ngIf">
-    <!-- if regions.length > 1 -->
-    <!-- use group chip -->
-    <ng-template [ngIf]="selectedRegions.length > 1" [ngIfElse]="singleRegionChipTmpl">
-      <mat-chip
-        color="primary"
-        selected
-        (click)="handleChipClick()"
-        class="pe-all position-relative z-index-1 ml-8-n">
-        <span class="iv-custom-comp text text-truncate d-inline sxplr-pl-4">
-          {{ CONST.MULTI_REGION_SELECTION }}
-        </span>
-        <mat-icon
-          (click)="clearSelectedRegions()"
-          fontSet="fas"
-          iav-stop="click"
-          fontIcon="fa-times">
-        </mat-icon>
-      </mat-chip>
-    </ng-template>
-
-    <!-- if reginos.lengt === 1 -->
-    <!-- use single region chip -->
-    <ng-template #singleRegionChipTmpl>
-      <ng-container *ngFor="let r of selectedRegions">
-
-        <!-- region chip for discrete map -->
-
-        <!-- TODO use actual region chip -->
-        <mat-chip>REGION PLACE HOLDER</mat-chip>
-
-        <!-- chips for previewing origin datasets/continous map -->
-        <ng-container *ngFor="let originDataset of (r.originDatasets || []); let index = index">
-
-          <mat-chip *ngFor="let key of clearViewKeys$ | async"
-            (click)="handleChipClick()"
-            class="pe-all position-relative ml-8-n">
-            <span class="sxplr-pl-4">
-              {{ key }}
-            </span>
-            <mat-icon (click)="unsetClearViewByKey(key)"
-              fontSet="fas"
-              iav-stop="click"
-              fontIcon="fa-times">
-
-            </mat-icon>
-          </mat-chip>
-        </ng-container>
-
-      </ng-container>
-    </ng-template>
-  </ng-template>
-
-</ng-template>
-
-<!-- layer version selector -->
-<mat-menu #layerVersionMenu
-  class="bg-none box-shadow-none"
-  [aria-label]="ARIA_LABELS.PARC_VER_CONTAINER"
-  [hasBackdrop]="false">
-  <ng-template matMenuContent let-layerVersionMenuTrigger="layerVersionMenuTrigger">
-    <div (iav-outsideClick)="layerVersionMenuTrigger.closeMenu()">
-      <ng-container *ngFor="let parcVer of selectedLayerVersions$ | async">
-        <ng-container *ngIf="parcellationSelected$ | async as selectedParcellation">
-
-          <ng-container *ngTemplateOutlet="chipTmpl; context: {
-            parcel: parcVer,
-            selected: selectedParcellation['@id'] === parcVer['@id'],
-            dismissable: false,
-            class: 'w-100',
-            ariaLabel: parcVer.displayName || parcVer.name,
-            onclick: bindFns([
-              [ selectParcellationWithId.bind(this), parcVer['@id'] ],
-              [ layerVersionMenuTrigger.closeMenu.bind(layerVersionMenuTrigger) ]
-            ])
-          }">
-          </ng-container>
-        </ng-container>
-        <div class="mt-1"></div>
-      </ng-container>
-    </div>
-  </ng-template>
-</mat-menu>
-
-
-<ng-template #chipTmpl
-  let-parcel="parcel"
-  let-selected="selected"
-  let-dismissable="dismissable"
-  let-chipClass="class"
-  let-ariaLabel="ariaLabel"
-  let-onclick="onclick">
-  <mat-chip class="pe-all position-relative z-index-2 d-inline-flex justify-content-between"
-    [ngClass]="chipClass"
-    [attr.aria-label]="ariaLabel"
-    (click)="onclick && onclick()"
-    [selected]="selected">
-
-    <span class="ws-no-wrap">
-      {{ parcel?.groupName ? (parcel?.groupName + ' - ') : '' }}{{ parcel && (parcel.displayName || parcel.name) }}
-    </span>
-
-    <!-- info icon -->
-    <ng-container *ngFor="let originDatainfo of (parcel | originDatainfoPipe)">
-      
-      <mat-icon
-        fontSet="fas"
-        fontIcon="fa-info-circle"
-        iav-stop="click"
-        iav-dataset-show-dataset-dialog
-        [iav-dataset-show-dataset-dialog-name]="originDatainfo.metadata.fullName"
-        [iav-dataset-show-dataset-dialog-description]="originDatainfo.metadata.description"
-        [iav-dataset-show-dataset-dialog-urls]="originDatainfo.urls">
-      </mat-icon>
-
-    </ng-container>
-
-    <!-- dismiss icon -->
-    <mat-icon
-      *ngIf="dismissable"
-      (click)="clearAdditionalLayer(parcel); $event.stopPropagation()"
-      fontSet="fas"
-      fontIcon="fa-times">
-    </mat-icon>
-  </mat-chip>
-</ng-template>
diff --git a/src/viewerModule/viewerStateBreadCrumb/module.ts b/src/viewerModule/viewerStateBreadCrumb/module.ts
deleted file mode 100644
index c331dbbaed2dce17f35c48ebdc9aa4f662ca8a6d..0000000000000000000000000000000000000000
--- a/src/viewerModule/viewerStateBreadCrumb/module.ts
+++ /dev/null
@@ -1,29 +0,0 @@
-import { CommonModule } from "@angular/common";
-import { NgModule } from "@angular/core";
-import { QuickTourModule } from "src/ui/quickTour";
-import { AngularMaterialModule } from "src/sharedModules";
-import { UtilModule } from "src/util";
-import { ViewerStateBreadCrumb } from "./breadcrumb/breadcrumb.component";
-import { OriginalDatainfoPipe } from "./pipes/originDataInfo.pipe"
-import { DialogInfoModule } from "src/ui/dialogInfo";
-
-@NgModule({
-  imports: [
-    CommonModule,
-    AngularMaterialModule,
-    QuickTourModule,
-    UtilModule,
-    DialogInfoModule,
-  ],
-  declarations: [
-    ViewerStateBreadCrumb,
-    OriginalDatainfoPipe,
-  ],
-  exports: [
-    ViewerStateBreadCrumb,
-  ],
-  providers:[
-  ]
-})
-
-export class ViewerStateBreadCrumbModule{}
\ No newline at end of file
diff --git a/src/viewerModule/viewerStateBreadCrumb/pipes/originDataInfo.pipe.ts b/src/viewerModule/viewerStateBreadCrumb/pipes/originDataInfo.pipe.ts
deleted file mode 100644
index 3c8676554dd7c1b766878d579b42b9a2bdbfc2ce..0000000000000000000000000000000000000000
--- a/src/viewerModule/viewerStateBreadCrumb/pipes/originDataInfo.pipe.ts
+++ /dev/null
@@ -1,24 +0,0 @@
-import { Pipe, PipeTransform } from "@angular/core"
-import {
-  SapiDatasetModel,
-  SapiParcellationModel,
-  SapiRegionModel,
-} from "src/atlasComponents/sapi"
-
-@Pipe({
-  name: 'originDatainfoPipe'
-})
-
-export class OriginalDatainfoPipe implements PipeTransform{
-  public transform(obj: SapiParcellationModel | SapiRegionModel): SapiDatasetModel[]{
-    
-    if (obj["@type"] === "minds/core/parcellationatlas/v1.0.0") {
-      const ds = (obj as SapiParcellationModel).datasets[0]
-      return (obj as SapiParcellationModel).datasets
-    }
-    if (obj["@type"] === "https://openminds.ebrains.eu/sands/ParcellationEntityVersion") {
-      (obj as SapiRegionModel)
-      return []
-    }
-  }
-}