diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 04f5a9d4cd45690589842a134d2985614ed62403..c3c07d114df83ae2c2dc663da720cc5451914f31 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -2,10 +2,6 @@ name: '[ci]'
 
 on:
   push:
-    branches-ignore:
-    - 'dev'
-    - 'staging'
-    - 'master'
 
     # ignore changes to docs and mkdocs.yml
     paths-ignore:
@@ -66,4 +62,4 @@ jobs:
         cd deploy
         npm i
         npm run test
-  
\ No newline at end of file
+  
diff --git a/.github/workflows/docker_img.yml b/.github/workflows/docker_img.yml
index daa098e920be68ce850beb81fd1450505dbfc1cd..3366bae8a3fcb7db4160d5c103970f0ae56d39e2 100644
--- a/.github/workflows/docker_img.yml
+++ b/.github/workflows/docker_img.yml
@@ -1,6 +1,13 @@
 name: '[docker image]'
 
-on: [ 'push' ]
+on:
+  push:
+    # do not rebuild if...
+    paths-ignore:
+      # changes to .openshift directory... mostly devops config
+      - '.openshift/*'
+      # docs (docs are built on readthedocs any way)
+      - 'docs/*'
 
 jobs:
   build-docker-img:
diff --git a/.gitignore b/.gitignore
index 4a28d67aecc150bc9b509a5abf305128d1784839..05ba580503a02c6b0557b29836fa8bc2a42b4295 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,3 +11,4 @@ site
 
 *.log
 cachedKgDataset.json
+tmp
diff --git a/angular.json b/angular.json
index 8e887675e54154cb46b0eac5e871ce64c6079695..68b6001b6a2bd6b197221bcf374c11f378bff086 100644
--- a/angular.json
+++ b/angular.json
@@ -1,5 +1,8 @@
 {
   "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
+  "cli": {
+    "analytics": false
+  },
   "version": 1,
   "newProjectRoot": "projects",
   "projects": {
diff --git a/common/constants.js b/common/constants.js
index a4880c3a454d1d505182126643a24fab6c197a79..1527bc74e86405a3f23353e182103e9a7da31882 100644
--- a/common/constants.js
+++ b/common/constants.js
@@ -112,7 +112,10 @@
     QUICKTOUR_CANCEL: `Dismiss`,
 
     DELETE_ALL_ANNOTATION_CONFIRMATION_MSG: `Are you sure you want to delete all annotations?`,
-    LOADING_ANNOTATION_MSG: `Loading annotations... Please wait...`
+    LOADING_ANNOTATION_MSG: `Loading annotations... Please wait...`,
+
+    ATLAS_SELECTOR_LABEL_SPACES: `Spaces`,
+    ATLAS_SELECTOR_LABEL_PARC_MAPS: `Parcellation maps`
   }
 
   exports.QUICKTOUR_DESC ={
diff --git a/deploy/app.js b/deploy/app.js
index 0a9aaa02df174ea5d934dddc6c7d998bd647f220..3fa93a530fe2ea7076fe7978d00654afc0ab7bc4 100644
--- a/deploy/app.js
+++ b/deploy/app.js
@@ -197,9 +197,6 @@ app.get('/', (req, res, next) => {
   }
 })
 
-
-app.use('/logo', require('./logo'))
-
 app.get('/ready', async (req, res) => {
   const authIsReady = authReady ? await authReady() : false
 
diff --git a/deploy/csp/index.js b/deploy/csp/index.js
index b7e07519626b1a0b3cf8f8f86728a1c6d7d333fd..b3e439e8160c050734f23307341d71b782705dc2 100644
--- a/deploy/csp/index.js
+++ b/deploy/csp/index.js
@@ -116,8 +116,8 @@ module.exports = {
           'unpkg.com/kg-dataset-previewer@1.2.0/', // preview component
           'cdnjs.cloudflare.com/ajax/libs/mathjax/', // math jax
           'https://unpkg.com/three-surfer@0.0.10/dist/bundle.js', // for threeSurfer (freesurfer support in browser)
-          'https://unpkg.com/ng-layer-tune@0.0.2/dist/ng-layer-tune/', // needed for ng layer control
-          (req, res) => res.locals.nonce ? [`'nonce-${res.locals.nonce}'`] : [],
+          'https://unpkg.com/ng-layer-tune@0.0.5/dist/ng-layer-tune/', // needed for ng layer control
+          (req, res) => res.locals.nonce ? `'nonce-${res.locals.nonce}'` : null,
           ...SCRIPT_SRC,
           ...WHITE_LIST_SRC,
           ...defaultAllowedSites
diff --git a/deploy/logo/index.js b/deploy/logo/index.js
deleted file mode 100644
index d4750d225f9d0a09510db3fa40175544670c2969..0000000000000000000000000000000000000000
--- a/deploy/logo/index.js
+++ /dev/null
@@ -1,40 +0,0 @@
-const fs = require('fs')
-const path = require('path')
-const { getHandleErrorFn } = require('../util/streamHandleError')
-const router = require('express').Router()
-
-const map = new Map([
-  ['hbp', {
-    mimetype: 'image/png',
-    light: 'HBP_Primary_RGB_BlackText.png',
-    dark: 'HBP_Primary_RGB_WhiteText.png'
-  }],
-  ['ebrains', {
-    mimetype: 'image/svg+xml',
-    light: 'ebrains-logo-dark.svg',
-    dark: 'ebrains-logo-light.svg'
-  }],
-  ['fzj', {
-    mimetype: 'image/svg+xml',
-    light: 'fzj_black_transparent_svg.svg',
-    dark: 'fzj_white_transparent_svg.svg'
-  }]
-])
-
-router.get('/', (req, res) => {
-  
-  const USE_LOGO = process.env.USE_LOGO || 'hbp'
-  const { mimetype, light, dark } = map.get(USE_LOGO) || map.get('hbp')
-  const darktheme = !!req.query.darktheme
-  try {
-    res.setHeader('Content-type', mimetype)
-    fs.createReadStream(
-      path.join(__dirname, `assets/${darktheme ? dark : light}`)
-    ).pipe(res).on('error', getHandleErrorFn(req, res))
-  } catch (e) {
-    console.error(`Fetching logo error ${e.toString()}`)
-    res.status(500).end()
-  }
-})
-
-module.exports = router
\ No newline at end of file
diff --git a/deploy/plugins/index.js b/deploy/plugins/index.js
index 929f19499786e69b7dc1461a27ae96972e32b8a0..8d6bee52dadaf45913c133479a42142b3c2a4a3e 100644
--- a/deploy/plugins/index.js
+++ b/deploy/plugins/index.js
@@ -7,6 +7,16 @@ const express = require('express')
 const lruStore = require('../lruStore')
 const got = require('got')
 const router = express.Router()
+const DEV_PLUGINS = (() => {
+  try {
+    return JSON.parse(
+      process.env.DEV_PLUGINS || `[]`
+    )
+  } catch (e) {
+    console.warn(`Parsing DEV_PLUGINS failed: ${e}`)
+    return []
+  }
+})()
 const PLUGIN_URLS = (process.env.PLUGIN_URLS && process.env.PLUGIN_URLS.split(';')) || []
 const STAGING_PLUGIN_URLS = (process.env.STAGING_PLUGIN_URLS && process.env.STAGING_PLUGIN_URLS.split(';')) || []
 
@@ -44,7 +54,7 @@ router.get('/manifests', async (_req, res) => {
   }))
 
   res.status(200).json(
-    allManifests.filter(v => !!v)
+    [...DEV_PLUGINS, ...allManifests.filter(v => !!v)]
   )
 })
 
diff --git a/deploy/saneUrl/index.js b/deploy/saneUrl/index.js
index 72d0f9f9e2a8a13f98f96b7989c167ae61e2f47a..010f28e87db03d0f143fd78e961f3182d766af20 100644
--- a/deploy/saneUrl/index.js
+++ b/deploy/saneUrl/index.js
@@ -7,7 +7,12 @@ const RedisStore = require('rate-limit-redis')
 const { redisURL } = require('../lruStore')
 const { ProxyStore, NotExactlyPromiseAny } = require('./util')
 
-const store = new Store()
+let store
+try {
+  store = new Store()
+} catch (e) {
+  console.error(`Failed to new store.`, e)
+}
 const depStore = new DepcStore()
 
 const proxyStore = new ProxyStore(store)
diff --git a/deploy/saneUrl/util.js b/deploy/saneUrl/util.js
index 949025cdc76bbf6b8794222bc67e2995ae1da482..12fce0a38ac846600110d638b1ea7a96cb6fd3cd 100644
--- a/deploy/saneUrl/util.js
+++ b/deploy/saneUrl/util.js
@@ -2,6 +2,7 @@ const { NotFoundError } = require('./store')
 
 class ProxyStore {
   static async StaticGet(store, req, name) {
+    if (!store) throw new Error(`store is falsy`)
     const payload = JSON.parse(await store.get(name))
     const { expiry, value, ...rest } = payload
     if (expiry && (Date.now() > expiry)) {
@@ -21,6 +22,7 @@ class ProxyStore {
   }
 
   async set(req, name, value) {
+    if (!this.store) throw new Error(`store is falsy`)
     const supplementary = req.user
     ? {
         userId: req.user.id,
diff --git a/docs/releases/v2.6.0.md b/docs/releases/v2.6.0.md
new file mode 100644
index 0000000000000000000000000000000000000000..90f139cfc720729684972e5cc609ea6bc8be60ea
--- /dev/null
+++ b/docs/releases/v2.6.0.md
@@ -0,0 +1,14 @@
+# v2.6.0
+
+## New features
+
+- add the capability of add 3rd party plugins (experimental)
+
+## Under the hood stuff
+
+- refactor: simplify DOM, remove unused functions
+- reworked logo path
+- added visual indication when a new template is being loaded
+- reworked visual for `supported template` in region side panel
+- improve performance by disabling `zone.js` patch of `requestAnimationFrame` and change detection strategy of nehuba viewer
+- added message when no regional features found (#1111)
diff --git a/e2e/checklist.md b/e2e/checklist.md
index 8434c5cbb39ae3f35be8fbd72d6ad4bfe48fb37a..3c0cbe0a538168ea49aeff84877386c05826459b 100644
--- a/e2e/checklist.md
+++ b/e2e/checklist.md
@@ -54,4 +54,11 @@
 - [ ] Waxholm
   - [ ] v4 are visible
   - [ ] on hover, show correct region name(s)
-  - [ ] whole mesh loads
\ No newline at end of file
+  - [ ] whole mesh loads
+## saneURL
+- [ ] [saneUrl](https://siibra-explorer.apps.hbp.eu/staging/saneUrl/bigbrainGreyWhite) redirects to big brain
+- [ ] [saneUrl](https://siibra-explorer.apps.hbp.eu/staging/saneUrl/julichbrain) redirects to julich brain (colin 27)
+- [ ] [saneUrl](https://siibra-explorer.apps.hbp.eu/staging/saneUrl/whs4) redirects to waxholm v4
+- [ ] [saneUrl](https://siibra-explorer.apps.hbp.eu/staging/saneUrl/allen2017) redirects to allen 2017
+- [ ] [saneUrl](https://siibra-explorer.apps.hbp.eu/staging/saneUrl/mebrains) redirects to monkey
+
diff --git a/mkdocs.yml b/mkdocs.yml
index a2ade830ee78908a40bb8dcd9ee1b7b489753329..95827211ee2faac6753b6dae9b4d023d6e716530 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -40,6 +40,7 @@ pages:
     - Fetching datasets: 'advanced/datasets.md'
     - Display non-atlas volumes: 'advanced/otherVolumes.md'
   - Release notes:
+    - v2.6.0: 'releases/v2.6.0.md'
     - v2.5.8: 'releases/v2.5.8.md'
     - v2.5.7: 'releases/v2.5.7.md'
     - v2.5.6: 'releases/v2.5.6.md'
diff --git a/package.json b/package.json
index b538486fe3ccd90b081f90e8e2d462f80acbf90f..c9e41e939e48afb2cd1edaa045ce9fc801eb10ad 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "interactive-viewer",
-  "version": "2.5.8",
+  "version": "2.6.0",
   "description": "HBP interactive atlas viewer. Integrating KG query, dataset previews & more. Based on humanbrainproject/nehuba & google/neuroglancer. Built with angular",
   "scripts": {
     "build-aot": "ng build && node ./third_party/matomo/processMatomo.js",
diff --git a/deploy/logo/assets/HBP_Primary_RGB_BlackText.png b/src/assets/logo/HBP_Primary_RGB_BlackText.png
similarity index 100%
rename from deploy/logo/assets/HBP_Primary_RGB_BlackText.png
rename to src/assets/logo/HBP_Primary_RGB_BlackText.png
diff --git a/deploy/logo/assets/HBP_Primary_RGB_WhiteText.png b/src/assets/logo/HBP_Primary_RGB_WhiteText.png
similarity index 100%
rename from deploy/logo/assets/HBP_Primary_RGB_WhiteText.png
rename to src/assets/logo/HBP_Primary_RGB_WhiteText.png
diff --git a/deploy/logo/assets/ebrains-logo-dark.svg b/src/assets/logo/ebrains-logo-dark.svg
similarity index 100%
rename from deploy/logo/assets/ebrains-logo-dark.svg
rename to src/assets/logo/ebrains-logo-dark.svg
diff --git a/deploy/logo/assets/ebrains-logo-light.svg b/src/assets/logo/ebrains-logo-light.svg
similarity index 100%
rename from deploy/logo/assets/ebrains-logo-light.svg
rename to src/assets/logo/ebrains-logo-light.svg
diff --git a/deploy/logo/assets/fzj_black_transparent_svg.svg b/src/assets/logo/fzj_black_transparent_svg.svg
similarity index 100%
rename from deploy/logo/assets/fzj_black_transparent_svg.svg
rename to src/assets/logo/fzj_black_transparent_svg.svg
diff --git a/deploy/logo/assets/fzj_white_transparent_svg.svg b/src/assets/logo/fzj_white_transparent_svg.svg
similarity index 100%
rename from deploy/logo/assets/fzj_white_transparent_svg.svg
rename to src/assets/logo/fzj_white_transparent_svg.svg
diff --git a/src/atlasComponents/parcellation/getParcPreviewUrl.pipe.ts b/src/atlasComponents/parcellation/getParcPreviewUrl.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3f70d60e90bdb1645d44f74edbe86ce7b6aec463
--- /dev/null
+++ b/src/atlasComponents/parcellation/getParcPreviewUrl.pipe.ts
@@ -0,0 +1,49 @@
+import { Pipe, PipeTransform } from "@angular/core"
+
+const previewImgMap = new Map([
+  
+  ['minds/core/parcellationatlas/v1.0.0/94c1125b-b87e-45e4-901c-00daee7f2579', 'cytoarchitectonic-maps.png'],
+  ['juelich/iav/atlas/v1.0.0/3', 'cortical-layers.png'],
+  ['juelich/iav/atlas/v1.0.0/4', 'grey-white-matter.png'],
+  ['juelich/iav/atlas/v1.0.0/5', 'firbe-long.png'],
+  ['juelich/iav/atlas/v1.0.0/6', 'firbe-short.png'],
+  ['minds/core/parcellationatlas/v1.0.0/d80fbab2-ce7f-4901-a3a2-3c8ef8a3b721', 'difumo-64.png'],
+  ['minds/core/parcellationatlas/v1.0.0/73f41e04-b7ee-4301-a828-4b298ad05ab8', 'difumo-128.png'],
+  ['minds/core/parcellationatlas/v1.0.0/141d510f-0342-4f94-ace7-c97d5f160235', 'difumo-256.png'],
+  ['minds/core/parcellationatlas/v1.0.0/63b5794f-79a4-4464-8dc1-b32e170f3d16', 'difumo-512.png'],
+  ['minds/core/parcellationatlas/v1.0.0/12fca5c5-b02c-46ce-ab9f-f12babf4c7e1', 'difumo-1024.png'],
+  
+  
+  ['minds/core/parcellationatlas/v1.0.0/05655b58-3b6f-49db-b285-64b5a0276f83', 'allen-mouse-2017.png'],
+  ['minds/core/parcellationatlas/v1.0.0/39a1384b-8413-4d27-af8d-22432225401f', 'allen-mouse-2015.png'],
+  
+
+  ['minds/core/parcellationatlas/v1.0.0/ebb923ba-b4d5-4b82-8088-fa9215c2e1fe', 'waxholm-v3.png'],
+  ['minds/core/parcellationatlas/v1.0.0/2449a7f0-6dd0-4b5a-8f1e-aec0db03679d', 'waxholm-v2.png'],
+  ['minds/core/parcellationatlas/v1.0.0/11017b35-7056-4593-baad-3934d211daba', 'waxholm-v1.png'],
+  ['juelich/iav/atlas/v1.0.0/79cbeaa4ee96d5d3dfe2876e9f74b3dc3d3ffb84304fb9b965b1776563a1069c', 'short-bundle-hcp.png'],
+
+  ['minds/core/parcellationatlas/v1.0.0/mebrains-tmp-id', 'primate-parc.png'],
+])
+
+/**
+ * used for directories
+ */
+const previewNameToPngMap = new Map([
+  ['fibre architecture', 'firbe-long.png'],
+  ['functional modes', 'difumo-128.png']
+])
+
+@Pipe({
+  name: 'getParcPreviewUrl',
+  pure: true
+})
+
+export class GetParcPreviewUrlPipe implements PipeTransform{
+  public transform(tile: any){
+    const filename = tile['@id']
+      ? previewImgMap.get(tile['@id'])
+      : previewNameToPngMap.get(tile['name'])
+    return filename && `assets/images/atlas-selection/${filename}`
+  }
+}
diff --git a/src/atlasComponents/parcellation/index.ts b/src/atlasComponents/parcellation/index.ts
index 4af8252e223c89fce580454087e7038563e1fab4..f49438e683dafb818113eb571433a364854eb24b 100644
--- a/src/atlasComponents/parcellation/index.ts
+++ b/src/atlasComponents/parcellation/index.ts
@@ -1,3 +1,4 @@
+export { GetParcPreviewUrlPipe } from "./getParcPreviewUrl.pipe";
 export { FilterNameBySearch } from "./regionHierachy/filterNameBySearch.pipe";
 export { AtlasCmpParcellationModule } from "./module";
 export { RegionHierarchy } from "./regionHierachy/regionHierarchy.component";
diff --git a/src/atlasComponents/parcellation/module.ts b/src/atlasComponents/parcellation/module.ts
index 7763c155a14babdc53f3d81c2c8466410066d5e0..c3e101c3a1d4bf3b2a6384723d79414e59a76429 100644
--- a/src/atlasComponents/parcellation/module.ts
+++ b/src/atlasComponents/parcellation/module.ts
@@ -8,6 +8,7 @@ import { FilterNameBySearch } from "./regionHierachy/filterNameBySearch.pipe";
 import { UtilModule } from "src/util";
 import { FormsModule, ReactiveFormsModule } from "@angular/forms";
 import { ComponentsModule } from "src/components";
+import { GetParcPreviewUrlPipe } from "./getParcPreviewUrl.pipe";
 
 @NgModule({
   imports: [
@@ -24,11 +25,13 @@ import { ComponentsModule } from "src/components";
     RegionTextSearchAutocomplete,
 
     FilterNameBySearch,
+    GetParcPreviewUrlPipe,
   ],
   exports: [
     RegionHierarchy,
     RegionTextSearchAutocomplete,
     FilterNameBySearch,
+    GetParcPreviewUrlPipe,
   ]
 })
 export class AtlasCmpParcellationModule{}
\ No newline at end of file
diff --git a/src/atlasComponents/parcellationRegion/module.ts b/src/atlasComponents/parcellationRegion/module.ts
index d4507dcaa7e390cbeb96d0a1519c3070bb6ee1d8..03aceeb2d6353c60a3bdb08a634fbbd87a4199d8 100644
--- a/src/atlasComponents/parcellationRegion/module.ts
+++ b/src/atlasComponents/parcellationRegion/module.ts
@@ -11,6 +11,9 @@ import { BSFeatureModule } from "../regionalFeatures/bsFeatures";
 import { RegionAccordionTooltipTextPipe } from "./regionAccordionTooltipText.pipe";
 import { AtlasCmptConnModule } from "../connectivity";
 import { HttpClientModule } from "@angular/common/http";
+import { RegionInOtherTmplPipe } from "./regionInOtherTmpl.pipe";
+import { SiibraExplorerTemplateModule } from "../template";
+import { KgDatasetModule } from "../regionalFeatures/bsFeatures/kgDataset";
 
 @NgModule({
   imports: [
@@ -21,6 +24,8 @@ import { HttpClientModule } from "@angular/common/http";
     BSFeatureModule,
     AtlasCmptConnModule,
     HttpClientModule,
+    SiibraExplorerTemplateModule,
+    KgDatasetModule,
   ],
   declarations: [
     RegionMenuComponent,
@@ -29,6 +34,7 @@ import { HttpClientModule } from "@angular/common/http";
     RegionDirective,
     RenderViewOriginDatasetLabelPipe,
     RegionAccordionTooltipTextPipe,
+    RegionInOtherTmplPipe,
   ],
   exports: [
     RegionMenuComponent,
diff --git a/src/atlasComponents/parcellationRegion/region.base.spec.ts b/src/atlasComponents/parcellationRegion/region.base.spec.ts
index df343917f7bb050a4a0b3553c1fabd7f918bfaa1..3e4085c70e1df483bd89f47e31dda4c3d167f1da 100644
--- a/src/atlasComponents/parcellationRegion/region.base.spec.ts
+++ b/src/atlasComponents/parcellationRegion/region.base.spec.ts
@@ -1,7 +1,8 @@
 import { TestBed } from '@angular/core/testing'
 import { MockStore, provideMockStore } from '@ngrx/store/testing'
 import { viewerStateSelectTemplateWithId } from 'src/services/state/viewerState/actions'
-import { RegionBase, regionInOtherTemplateSelector, getRegionParentParcRefSpace } from './region.base'
+import { RegionBase, getRegionParentParcRefSpace } from './region.base'
+import { TSiibraExRegion } from './type'
 
 // eslint-disable-next-line @typescript-eslint/no-var-requires
 const util = require('common/util')
@@ -27,430 +28,7 @@ enum EnumParcRegVersion{
   V2_4 = "V2_4"
 }
 
-const getRegionInOtherTemplateSelectorBundle = (version: EnumParcRegVersion) => {
-  switch (version) {
-    case EnumParcRegVersion.V1_18: {
-      /**
-       * regions
-       */
-
-      const mr1wrong = {
-        labelIndex: 1,
-        name: 'mr1',
-        id: {
-          kg: {
-            kgSchema: 'fzj/mock/pr',
-            kgId: 'fff-bbb'
-          }
-        }
-      }
-
-      const mr0wrong = {
-        labelIndex: 1,
-        name: 'mr0',
-        id: {
-          kg: {
-            kgSchema: 'fzj/mock/pr',
-            kgId: 'aaa-fff'
-          }
-        }
-      }
-
-
-      const mr1lh = {
-        labelIndex: 1,
-        name: 'mr1 left',
-        id: {
-          kg: {
-            kgSchema: 'fzj/mock/pr',
-            kgId: 'ccc-bbb'
-          }
-        }
-      }
-
-      const mr1rh = {
-        labelIndex: 1,
-        name: 'mr1 right',
-        id: {
-          kg: {
-            kgSchema: 'fzj/mock/pr',
-            kgId: 'ccc-bbb'
-          }
-        }
-      }
-
-      const mr0nh = {
-        labelIndex: 11,
-        name: 'mr0',
-      }
-
-      const mr0lh = {
-        labelIndex: 1,
-        name: 'mr0 left',
-        availableIn: [{id: 'fzj/mock/rs/v0.0.0/aaa-bbb'}, {id: 'fzj/mock/rs/v0.0.0/bbb-bbb'}, {id: 'fzj/mock/rs/v0.0.0/ccc-bbb'}],
-        id: {
-          kg: {
-            kgSchema: 'fzj/mock/pr',
-            kgId: 'aaa-bbb'
-          }
-        }
-      }
-
-      const mr0rh = {
-        labelIndex: 1,
-        name: 'mr0 right',
-        id: {
-          kg: {
-            kgSchema: 'fzj/mock/pr',
-            kgId: 'aaa-bbb'
-          }
-        }
-      }
-
-      const mr1 = {
-        labelIndex: 1,
-        name: 'mr1',
-        id: {
-          kg: {
-            kgSchema: 'fzj/mock/pr',
-            kgId: 'ccc-bbb'
-          }
-        }
-      }
-
-      // parcellations
-
-      const mp1h = {
-        name: 'mp1h',
-        '@id': 'parcellation/id',
-        regions: [ mr0nh, mr1lh, mr0lh,  mr0rh, mr1rh ]
-      }
-
-      const mpWrong = {
-        name: 'mp1h',
-        '@id': 'parcellation/id',
-        regions: [ mr1wrong, mr0wrong ]
-      }
-
-      const mp0 = {
-        name: 'mp0',
-        '@id': 'parcellation/id',
-        regions: [ mr1, mr0 ]
-      }
-
-      // templates
-
-      const mt0 = {
-        name: 'mt0',
-        '@id': 'fzj/mock/rs/v0.0.0/aaa-bbb',
-        parcellations: [ mp0 ]
-      }
-
-      const mt1 = {
-        name: 'mt1',
-        '@id': 'fzj/mock/rs/v0.0.0/bbb-bbb',
-        parcellations: [ mp0 ]
-      }
-
-      const mt2 = {
-        name: 'mt2',
-        '@id': 'fzj/mock/rs/v0.0.0/ccc-bbb',
-        parcellations: [ mp1h ]
-      }
-
-      const mt3 = {
-        name: 'mt3',
-        '@id': 'fzj/mock/rs/v0.0.0/ddd-bbb',
-        parcellations: [ mp1h ]
-      }
-
-      const mtWrong = {
-        name: 'mtWrong',
-        '@id': 'fzj/mock/rs/v0.0.0/ddd-bbb',
-        parcellations: [ mpWrong ]
-      }
-
-      const mockFetchedTemplates = [ mt0, mt1, mt2, mt3, mtWrong ]
-      return {
-        mockFetchedTemplates,
-        mt2,
-        mt0,
-        mp0,
-        mt1,
-        mp1h,
-        mr0lh,
-        mt3,
-        mr0,
-        mr0rh,
-        mr0nh
-      }
-
-    }
-    case EnumParcRegVersion.V2_4: {
-      /**
-       * regions
-       */
-
-      const mr1wrong = {
-        labelIndex: 1,
-        name: 'mr1',
-        id: {
-          kg: {
-            kgSchema: 'fzj/mock/pr',
-            kgId: 'fff-bbb'
-          }
-        }
-      }
-
-      const mr0wrong = {
-        labelIndex: 1,
-        name: 'mr0',
-        id: {
-          kg: {
-            kgSchema: 'fzj/mock/pr',
-            kgId: 'aaa-fff'
-          }
-        }
-      }
-
-
-      const mr1lh = {
-        labelIndex: 1,
-        name: 'mr1',
-        status: 'left',
-        id: {
-          kg: {
-            kgSchema: 'fzj/mock/pr',
-            kgId: 'ccc-bbb'
-          }
-        }
-      }
-
-      const mr1rh = {
-        labelIndex: 1,
-        name: 'mr1',
-        status: 'right',
-        id: {
-          kg: {
-            kgSchema: 'fzj/mock/pr',
-            kgId: 'ccc-bbb'
-          }
-        }
-      }
-
-      const mr0nh = {
-        labelIndex: 11,
-        name: 'mr0',
-      }
-
-      const mr0lh = {
-        labelIndex: 1,
-        name: 'mr0 left',
-        availableIn: [{id: 'fzj/mock/rs/v0.0.0/aaa-bbb'}, {id: 'fzj/mock/rs/v0.0.0/bbb-bbb'}, {id: 'fzj/mock/rs/v0.0.0/ccc-bbb'}],
-        id: {
-          kg: {
-            kgSchema: 'fzj/mock/pr',
-            kgId: 'aaa-bbb'
-          }
-        }
-      }
-
-      const mr0rh = {
-        labelIndex: 1,
-        name: 'mr0 right',
-        id: {
-          kg: {
-            kgSchema: 'fzj/mock/pr',
-            kgId: 'aaa-bbb'
-          }
-        }
-      }
-
-      const mr1 = {
-        labelIndex: 1,
-        name: 'mr1',
-        id: {
-          kg: {
-            kgSchema: 'fzj/mock/pr',
-            kgId: 'ccc-bbb'
-          }
-        }
-      }
-
-      // parcellations
-
-      const mp1h = {
-        name: 'mp1h',
-        '@id': 'parcellation/id',
-        regions: [ mr0nh, mr1lh, mr0lh,  mr0rh, mr1rh ]
-      }
-
-      const mpWrong = {
-        name: 'mp1h',
-        '@id': 'parcellation/id',
-        regions: [ mr1wrong, mr0wrong ]
-      }
-
-      const mp0 = {
-        name: 'mp0',
-        '@id': 'parcellation/id',
-        regions: [ mr1, mr0 ]
-      }
-
-      // templates
-
-      const mt0 = {
-        name: 'mt0',
-        '@id': 'fzj/mock/rs/v0.0.0/aaa-bbb',
-        parcellations: [ mp0 ]
-      }
-
-      const mt1 = {
-        name: 'mt1',
-        '@id': 'fzj/mock/rs/v0.0.0/bbb-bbb',
-        parcellations: [ mp0 ]
-      }
-
-      const mt2 = {
-        name: 'mt2',
-        '@id': 'fzj/mock/rs/v0.0.0/ccc-bbb',
-        parcellations: [ mp1h ]
-      }
-
-      const mt3 = {
-        name: 'mt3',
-        '@id': 'fzj/mock/rs/v0.0.0/ddd-bbb',
-        parcellations: [ mp1h ]
-      }
-
-      const mtWrong = {
-        name: 'mtWrong',
-        '@id': 'fzj/mock/rs/v0.0.0/ddd-bbb',
-        parcellations: [ mpWrong ]
-      }
-
-      const mockFetchedTemplates = [ mt0, mt1, mt2, mt3, mtWrong ]
-      return {
-        mockFetchedTemplates,
-        mt2,
-        mt0,
-        mp0,
-        mt1,
-        mp1h,
-        mr0lh,
-        mr0nh,
-        mt3,
-        mr0,
-        mr0rh
-      }
-    }
-    default: throw new Error(`version needs to be v1.18 or v2.4`)
-  }
-}
-
 describe('> region.base.ts', () => {
-  describe('> regionInOtherTemplateSelector', () => {
-
-    // TODO
-    it('> only selects region in the template specified by selected atlas')
-
-    for (const enumKey of Object.keys(EnumParcRegVersion)) {
-      describe(`> selector version for ${enumKey}`, () => {
-
-        const { mockFetchedTemplates, mr0, mt2, mt0, mp0, mt1, mp1h, mr0lh, mt3, mr0rh, mr0nh } = getRegionInOtherTemplateSelectorBundle(enumKey as EnumParcRegVersion)
-
-        let selectedAtlas = {
-          templateSpaces: mockFetchedTemplates
-        }
-        describe('> no hemisphere selected, simulates big brain cyto map', () => {
-
-          let result: any[]
-          beforeAll(() => {
-            result = regionInOtherTemplateSelector.projector(selectedAtlas, mockFetchedTemplates, { region: {...mr0, context: {template: mt0, parcellation: mp0} }})
-          })
-
-          it('> length checks out', () => {
-            expect(result.length).toEqual(4)
-          })
-
-          it('> does not contain itself', () => {
-            expect(result).not.toContain(
-              jasmine.objectContaining({
-                template: mt0,
-                parcellation: mp0,
-                region: mr0
-              })
-            )
-          })
-
-          it('> no hemisphere result has no hemisphere meta data', () => {
-            expect(result).toContain(
-              jasmine.objectContaining({
-                template: mt1,
-                parcellation: mp0,
-                region: mr0
-              })
-            )
-          })
-
-          it('> hemisphere result has hemisphere metadata # 1', () => {
-            expect(result).toContain(
-              jasmine.objectContaining({
-                template: mt2,
-                parcellation: mp1h,
-                region: mr0lh,
-                hemisphere: 'left'
-              })
-            )
-          })
-          it('> hemisphere result has hemisphere metadata # 2', () => {
-            expect(result).toContain(
-              jasmine.objectContaining({
-                template: mt2,
-                parcellation: mp1h,
-                region: mr0rh,
-                hemisphere: 'right'
-              })
-            )
-          })
-        })
-
-        describe('> hemisphere data selected (left), simulates julich-brain in mni152', () => {
-          let result
-          beforeAll(() => {
-            result = regionInOtherTemplateSelector.projector(selectedAtlas, mockFetchedTemplates, { region: {...mr0lh, context: {template: mt0, parcellation: mp1h} }})
-          })
-
-          it('> length checks out', () => {
-            expect(result.length).toEqual(3)
-          })
-
-          it('> does not select wrong hemisphere (right)', () => {
-            expect(result).not.toContain(
-              jasmine.objectContaining({
-                template: mt2,
-                parcellation: mp1h,
-                region: mr0rh,
-              })
-            )
-          })
-
-          it('> select the region with correct hemisphere', () => {
-            expect(result).toContain(
-              jasmine.objectContaining({
-                template: mt2,
-                parcellation: mp1h,
-                region: mr0lh
-              })
-            )
-          })
-        })
-
-      })
-    }
-
-  })
-
   describe('> RegionBase', () => {
     let regionBase: RegionBase
     let mockStore: MockStore
@@ -461,7 +39,6 @@ describe('> region.base.ts', () => {
         ]
       })
       mockStore = TestBed.inject(MockStore)
-      mockStore.overrideSelector(regionInOtherTemplateSelector, [])
       mockStore.overrideSelector(getRegionParentParcRefSpace, { template: null, parcellation: null })
     })
     describe('> position', () => {
@@ -539,7 +116,6 @@ describe('> region.base.ts', () => {
       beforeEach(() => {
         strToRgbSpy = spyOn(util, 'strToRgb')
         mockStore = TestBed.inject(MockStore)
-        mockStore.overrideSelector(regionInOtherTemplateSelector, [])
         mockStore.overrideSelector(getRegionParentParcRefSpace, { template: null, parcellation: null })
       })
 
@@ -647,10 +223,20 @@ describe('> region.base.ts', () => {
 
         it('> calls viewerStateSelectTemplateWithId', () => {
 
-          regionBase.changeView({
-            template: fakeTmpl,
-            parcellation: fakeParc,
-          })
+          const partialRegion = {
+            context: {
+              parcellation: fakeParc,
+              atlas: {
+                "@id": '',
+                name: '',
+                parcellations: [],
+                templateSpaces: [fakeTmpl]
+              },
+              template: null
+            }
+          } as Partial<TSiibraExRegion>
+          regionBase.region = partialRegion as any
+          regionBase.changeView(fakeTmpl)
 
           expect(dispatchSpy).toHaveBeenCalledWith(
             viewerStateSelectTemplateWithId({
diff --git a/src/atlasComponents/parcellationRegion/region.base.ts b/src/atlasComponents/parcellationRegion/region.base.ts
index f596afe76f7cfbffc7e83a39c24993e0b52e7530..5f4b7d327e4e1432abb128187ec7c738b6a1bd29 100644
--- a/src/atlasComponents/parcellationRegion/region.base.ts
+++ b/src/atlasComponents/parcellationRegion/region.base.ts
@@ -1,15 +1,16 @@
 import { Directive, EventEmitter, Input, Output, Pipe, PipeTransform } from "@angular/core";
 import { select, Store, createSelector } from "@ngrx/store";
 import { uiStateOpenSidePanel, uiStateExpandSidePanel, uiActionShowSidePanelConnectivity } from 'src/services/state/uiState.store.helper'
-import { distinctUntilChanged, switchMap, filter, map, withLatestFrom, tap } from "rxjs/operators";
+import { map, tap } from "rxjs/operators";
 import { Observable, BehaviorSubject, combineLatest } from "rxjs";
-import { flattenRegions, getIdFromKgIdObj, rgbToHsl } from 'common/util'
-import { viewerStateSetConnectivityRegion, viewerStateNavigateToRegion, viewerStateToggleRegionSelect, viewerStateNewViewer, isNewerThan, viewerStateSelectTemplateWithId } from "src/services/state/viewerState.store.helper";
-import { viewerStateFetchedTemplatesSelector, viewerStateGetSelectedAtlas, viewerStateSelectedTemplateFullInfoSelector, viewerStateSelectedTemplateSelector } from "src/services/state/viewerState/selectors";
-import { strToRgb, verifyPositionArg, getRegionHemisphere } from 'common/util'
+import { rgbToHsl } from 'common/util'
+import { viewerStateSetConnectivityRegion, viewerStateNavigateToRegion, viewerStateToggleRegionSelect, viewerStateSelectTemplateWithId } from "src/services/state/viewerState.store.helper";
+import { viewerStateGetSelectedAtlas, viewerStateSelectedTemplatePureSelector } from "src/services/state/viewerState/selectors";
+import { strToRgb, verifyPositionArg } from 'common/util'
 import { getPosFromRegion } from "src/util/siibraApiConstants/fn";
 import { TRegionDetail } from "src/util/siibraApiConstants/types";
 import { IHasId } from "src/util/interfaces";
+import { TSiibraExTemplate } from "./type";
 
 @Directive()
 export class RegionBase {
@@ -83,75 +84,16 @@ export class RegionBase {
 
   @Output() public closeRegionMenu: EventEmitter<boolean> = new EventEmitter()
 
-  public sameRegionTemplate: any[] = []
-  public regionInOtherTemplates$: Observable<any[]>
   public regionOriginDatasetLabels$: Observable<{ name: string }[]>
   public selectedAtlas$: Observable<any> = this.store$.pipe(
     select(viewerStateGetSelectedAtlas)
   )
 
-  public selectedTemplateFullInfo$: Observable<any[]>
 
   constructor(
     private store$: Store<any>,
   ) {
 
-    this.selectedTemplateFullInfo$ = this.store$.pipe(
-      select(viewerStateSelectedTemplateFullInfoSelector),
-    )
-
-    this.regionInOtherTemplates$ = this.region$.pipe(
-      distinctUntilChanged(),
-      filter(v => !!v && !!v.context),
-      switchMap(region => this.store$.pipe(
-        select(
-          regionInOtherTemplateSelector,
-          { region }
-        ),
-        withLatestFrom(
-          this.store$.pipe(
-            select(viewerStateGetSelectedAtlas)
-          )
-        ),
-        map(([ regionsInOtherTemplates, selectedatlas ]) => {
-          const { parcellations } = selectedatlas
-          const filteredRsInOtherTmpls = []
-          for (const bundledObj of regionsInOtherTemplates) {
-            const { template, parcellation, region } = bundledObj
-
-            /**
-             * trying to find duplicate region
-             * with same templateId, and same hemisphere
-             */
-            const sameEntityIdx = filteredRsInOtherTmpls.findIndex(({ template: _template, region: _region }) => {
-              return _template['@id'] === template['@id']
-                && getRegionHemisphere(_region) === getRegionHemisphere(region)
-            })
-            /**
-             * if doesn't exist, just push to output
-             */
-            if ( sameEntityIdx < 0 ) {
-              filteredRsInOtherTmpls.push(bundledObj)
-            } else {
-
-              /**
-               * if exists, only append the latest version
-               */
-              const { parcellation: currentParc } = filteredRsInOtherTmpls[sameEntityIdx]
-              /**
-               * if the new element is newer than existing item
-               */
-              if (isNewerThan(parcellations, parcellation, currentParc)) {
-                filteredRsInOtherTmpls.splice(sameEntityIdx, 1)
-                filteredRsInOtherTmpls.push(bundledObj)
-              }
-            }
-          }
-          return filteredRsInOtherTmpls
-        })
-      ))
-    )
-
     this.regionOriginDatasetLabels$ = combineLatest([
       this.store$,
       this.region$
@@ -161,6 +103,9 @@ export class RegionBase {
     )
   }
 
+  public selectedTemplate$ = this.store$.pipe(
+    select(viewerStateSelectedTemplatePureSelector),
+  )
 
   public navigateToRegion() {
     this.closeRegionMenu.emit()
@@ -190,13 +135,14 @@ export class RegionBase {
     )
   }
 
-  changeView(sameRegion) {
-    const {
-      template,
-      parcellation,
-    } = sameRegion
+  changeView(template: TSiibraExTemplate) {
+
     this.closeRegionMenu.emit()
 
+    const {
+      parcellation
+    } = (this.region?.context || {})
+    
     /**
      * TODO use createAction in future
      * for now, not importing const because it breaks tests
@@ -280,81 +226,3 @@ export class RenderViewOriginDatasetLabelPipe implements PipeTransform{
     return `origin dataset`
   }
 }
-
-export const regionInOtherTemplateSelector = createSelector(
-  viewerStateGetSelectedAtlas,
-  viewerStateFetchedTemplatesSelector,
-  (atlas, fetchedTemplates, prop) => {
-    const atlasTemplateSpacesIds = atlas.templateSpaces.map(a => a['@id'])
-    const { region: regionOfInterest } = prop
-    const returnArr = []
-
-    const regionOfInterestHemisphere = getRegionHemisphere(regionOfInterest)
-
-    // need to ensure that the templates are defined in atlas definition
-    // atlas is the single source of truth
-
-    const otherTemplates = fetchedTemplates
-      .filter(({ ['@id']: id }) => id !== regionOfInterest.context.template['@id']
-          && atlasTemplateSpacesIds.includes(id)
-          && (regionOfInterest.availableIn || []).map(ai => ai.id).includes(id))
-
-    for (const template of otherTemplates) {
-      const parcellation = template.parcellations.find(p => p['@id'] === regionOfInterest.context.parcellation['@id'])
-
-      const flattenedRegions = flattenRegions(parcellation.regions)
-      const selectableRegions = flattenedRegions.filter(({ labelIndex }) => !!labelIndex)
-
-      for (const region of selectableRegions) {
-        if (regionsEqual(regionOfInterest, region)) {
-
-          const regionHemisphere = getRegionHemisphere(region)
-
-          /**
-             * if both hemisphere metadatas are defined
-             */
-          if (
-            !!regionOfInterestHemisphere &&
-              !!regionHemisphere
-          ) {
-            if (regionHemisphere === regionOfInterestHemisphere) {
-              returnArr.push({
-                template,
-                parcellation,
-                region,
-              })
-            }
-          } else {
-            returnArr.push({
-              template,
-              parcellation,
-              region,
-              hemisphere: regionHemisphere
-            })
-          }
-        }
-      }
-
-    }
-    return returnArr
-  }
-)
-
-const regionsEqual = (region1, region2) => {
-  const region1Hemisphere = getRegionHemisphere(region1)
-  const region2Hemisphere = getRegionHemisphere(region2)
-
-  if (region1.id && region1.id.kg && region2.id && region2.id.kg) {
-    return getIdFromKgIdObj(region1.id.kg) === getIdFromKgIdObj(region2.id.kg)
-        // If both has hemispheres, they should be equal
-        && (!(region1Hemisphere && region2Hemisphere) || region1Hemisphere === region2Hemisphere)
-  }
-
-  if (region1Hemisphere && region2Hemisphere) {
-    return region1.name === region2.name
-  } else {
-    const region1NameBasis = region1Hemisphere? region1.name.substring(0, region1.name.lastIndexOf(' ')) : region1.name
-    const region2NameBasis = region2Hemisphere? region2.name.substring(0, region2.name.lastIndexOf(' ')) : region2.name
-    return region1NameBasis === region2NameBasis
-  }
-}
diff --git a/src/atlasComponents/parcellationRegion/regionInOtherTmpl.pipe.ts b/src/atlasComponents/parcellationRegion/regionInOtherTmpl.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..3a0e81dc8ee756aa29b6112e1ebab77987f33ed5
--- /dev/null
+++ b/src/atlasComponents/parcellationRegion/regionInOtherTmpl.pipe.ts
@@ -0,0 +1,14 @@
+import { Pipe, PipeTransform } from "@angular/core";
+import { TSiibraExRegion } from "./type";
+
+@Pipe({
+  name: 'regionInOtherTmpl',
+  pure: true
+})
+
+export class RegionInOtherTmplPipe implements PipeTransform{
+  public transform(region: TSiibraExRegion){
+    const { templateSpaces: allTmpl = [] } = region?.context?.atlas || {}
+    return allTmpl.filter(t => (region?.availableIn || []).find(availTmpl => availTmpl['id'] === t["@id"]))
+  }
+}
diff --git a/src/atlasComponents/parcellationRegion/regionMenu/regionMenu.component.ts b/src/atlasComponents/parcellationRegion/regionMenu/regionMenu.component.ts
index 879815ee4ae1d4a510927cde5193522dd5178aa9..f6456eba6b90135ae35ea96b110834093b46a4f8 100644
--- a/src/atlasComponents/parcellationRegion/regionMenu/regionMenu.component.ts
+++ b/src/atlasComponents/parcellationRegion/regionMenu/regionMenu.component.ts
@@ -1,9 +1,10 @@
 import { Component, OnDestroy } from "@angular/core";
 import { Store } from "@ngrx/store";
-import { Observable, Subscription } from "rxjs";
+import { merge, Observable, Subject, Subscription } from "rxjs";
 import { RegionBase } from '../region.base'
 import { CONST, ARIA_LABELS } from 'common/constants'
 import { ComponentStore } from "src/viewerModule/componentStore";
+import { distinctUntilChanged, mapTo } from "rxjs/operators";
 
 @Component({
   selector: 'region-menu',
@@ -19,6 +20,19 @@ export class RegionMenuComponent extends RegionBase implements OnDestroy {
 
   public activePanelTitles$: Observable<string[]>
   private activePanelTitles: string[] = []
+
+  public intentToChgTmpl$ = new Subject()
+  public lockOtherTmpl$ = merge(
+    this.selectedTemplate$.pipe(
+      mapTo(false)
+    ),
+    this.intentToChgTmpl$.pipe(
+      mapTo(true)
+    )
+  ).pipe(
+    distinctUntilChanged()
+  )
+
   constructor(
     store$: Store<any>,
     private viewerCmpLocalUiStore: ComponentStore<{ activePanelsTitle: string[] }>,
diff --git a/src/atlasComponents/parcellationRegion/regionMenu/regionMenu.style.css b/src/atlasComponents/parcellationRegion/regionMenu/regionMenu.style.css
index 34d152c481193d92a7b78b2fc6c0901f955556f9..386e688cd8e1adc6489f109fbadf71148c4d5ccc 100644
--- a/src/atlasComponents/parcellationRegion/regionMenu/regionMenu.style.css
+++ b/src/atlasComponents/parcellationRegion/regionMenu/regionMenu.style.css
@@ -20,3 +20,35 @@ mat-icon
   font-size: 95%;
   line-height: normal;
 }
+
+:host-context([darktheme="true"]) .loading-overlay
+{
+    background-color: rgba(10, 10, 10, 0.8);
+}
+
+.loading-overlay
+{
+    background-color: rgba(250, 250, 250, 0.8);
+}
+
+.loading-overlay
+{
+    position: absolute;
+    width: 100%;
+    height: 100%;
+    top: 0;
+    left: 0;
+    font-size: 200%;
+
+    display: grid;
+    grid-template-columns: auto;
+    grid-template-rows: 1fr auto 1fr;
+    grid-template-columns: 1fr auto 1fr;
+    grid-template-areas: "." "vertical-center" ".";
+}
+
+.loading-overlay > .spinner
+{
+    grid-column: 2;
+    grid-row: 2;
+}
diff --git a/src/atlasComponents/parcellationRegion/regionMenu/regionMenu.template.html b/src/atlasComponents/parcellationRegion/regionMenu/regionMenu.template.html
index db607952a6369db63f42fc4bbf83d7d965c4d711..06aac677565c2f5f7f4f169710bdcf64b39cb915 100644
--- a/src/atlasComponents/parcellationRegion/regionMenu/regionMenu.template.html
+++ b/src/atlasComponents/parcellationRegion/regionMenu/regionMenu.template.html
@@ -74,32 +74,53 @@
 
 
   <!-- Explore in other template -->
-  <ng-container *ngIf="regionInOtherTemplates$ | async as regionInOtherTemplates">
-
+  <ng-template [ngIf]="region$ | async | regionInOtherTmpl" let-otherTmpls>
     <ng-template #exploreInOtherTmpl>
-      <mat-card *ngFor="let sameRegion of regionInOtherTemplates"
-        class="p-0 border-0 box-shadow-none mt-1 tb-1 cursor-pointer"
-        (click)="changeView(sameRegion)"
-        [matTooltip]="sameRegion.template.name + (sameRegion.hemisphere ? (' - ' + sameRegion.hemisphere) : '')"
-        mat-ripple>
-        <small>
-          {{ sameRegion.template.name + (sameRegion.hemisphere ? (' - ' + sameRegion.hemisphere) : '') }}
-        </small>
-      </mat-card>
+      <mat-grid-list cols="3"
+        rowHeight="2:3"
+        gutterSize="16"
+        class="position-relative">
+        <mat-grid-tile *ngFor="let otherTmpl of otherTmpls">
+          
+          <div [hidden]
+              iav-dataset-show-dataset-dialog
+              [iav-dataset-show-dataset-dialog-name]="otherTmpl.originDatainfos[0]?.name"
+              [iav-dataset-show-dataset-dialog-description]="otherTmpl.originDatainfos[0]?.description"
+              [iav-dataset-show-dataset-dialog-urls]="otherTmpl.originDatainfos[0]?.urls"
+              [iav-dataset-show-dataset-dialog-ignore-overwrite]="true"
+              #kgInfo="iavDatasetShowDatasetDialog">
+          </div>
+          <tile-cmp [tile-image-src]="otherTmpl | getTemplatePreviewUrl"
+              class="cursor-pointer pe-all"
+              tile-image-alt="Preview of this tile"
+              [tile-text]="otherTmpl.displayName || otherTmpl.name"
+              [tile-show-info]="otherTmpl.originDatainfos?.length > 0"
+              [tile-image-darktheme]="otherTmpl | templateIsDarkTheme"
+              [tile-selected]="(selectedTemplate$ | async | getProperty : '@id') === otherTmpl['@id']"
+              (tile-on-click)="(tileCmp.selected || changeView(otherTmpl)); (tileCmp.selected || intentToChgTmpl$.next(true))"
+              (tile-on-info-click)="kgInfo && kgInfo.onClick()"
+              #tileCmp="tileCmp">
+          </tile-cmp>
+        </mat-grid-tile>
+      </mat-grid-list>
+
+      <div *ngIf="lockOtherTmpl$ | async" class="loading-overlay">
+        <spinner-cmp class="spinner"></spinner-cmp>
+      </div>
+
     </ng-template>
 
     <ng-container *ngTemplateOutlet="ngMatAccordionTmpl; context: {
       title: 'Explore in other templates',
-      desc: regionInOtherTemplates.length,
+      desc: otherTmpls.length,
       iconClass: 'fas fa-brain',
-      iconTooltip: regionInOtherTemplates.length | regionAccordionTooltipTextPipe : 'regionInOtherTmpl',
-      iavNgIf: regionInOtherTemplates.length,
+      iconTooltip: otherTmpls.length | regionAccordionTooltipTextPipe : 'regionInOtherTmpl',
+      iavNgIf: otherTmpls.length > 0,
       content: exploreInOtherTmpl
     }">
-
-
     </ng-container>
-  </ng-container>
+  </ng-template>
+
 
   <!-- kg regional features list -->
   <ng-template #kgRegionalFeatureList>
diff --git a/src/atlasComponents/parcellationRegion/type.ts b/src/atlasComponents/parcellationRegion/type.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e5c40a75fc1c63e88c92e4e388c56603feef1625
--- /dev/null
+++ b/src/atlasComponents/parcellationRegion/type.ts
@@ -0,0 +1,24 @@
+import { IHasId } from "src/util/interfaces";
+import { TRegionSummary } from "src/util/siibraApiConstants/types";
+
+type TAny = {
+  [key: string]: any
+}
+
+export type TSiibraExTemplate = IHasId & TAny
+export type TSiibraExParcelation = IHasId & TAny
+
+export type TSiibraExAtlas = {
+  name: string
+  '@id': string
+  parcellations: TSiibraExParcelation[]
+  templateSpaces: TSiibraExTemplate[]
+}
+
+export type TSiibraExRegion = TRegionSummary & {
+  context: {
+    atlas: TSiibraExAtlas
+    template: TSiibraExTemplate
+    parcellation: TSiibraExParcelation
+  }
+}
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/genericInfo/genericInfoCmp/genericInfo.component.ts b/src/atlasComponents/regionalFeatures/bsFeatures/genericInfo/genericInfoCmp/genericInfo.component.ts
index 4b911265407de5f74d5615cfe2eae2e7a14b6b6b..ca0d7c57c1c17a4fe011b05d05bd5d1cea13f6f5 100644
--- a/src/atlasComponents/regionalFeatures/bsFeatures/genericInfo/genericInfoCmp/genericInfo.component.ts
+++ b/src/atlasComponents/regionalFeatures/bsFeatures/genericInfo/genericInfoCmp/genericInfo.component.ts
@@ -1,4 +1,4 @@
-import { AfterViewInit, Component, Inject, Input, OnChanges, OnDestroy, Optional, TemplateRef, ViewChild, ViewContainerRef, ViewRef } from "@angular/core";
+import { AfterViewInit, ChangeDetectorRef, Component, Inject, Input, OnChanges, OnDestroy, Optional, TemplateRef, ViewChild, ViewContainerRef, ViewRef } from "@angular/core";
 import { BsRegionInputBase } from "../../bsRegionInputBase";
 import { KG_REGIONAL_FEATURE_KEY, TBSDetail, UNDER_REVIEW } from "../../kgRegionalFeature/type";
 import { ARIA_LABELS, CONST } from 'common/constants'
@@ -69,6 +69,7 @@ export class GenericInfoCmp extends BsRegionInputBase implements OnChanges, Afte
 
   constructor(
     svc: BsFeatureService,
+    private cdr: ChangeDetectorRef,
     @Optional() @Inject(MAT_DIALOG_DATA) data: TInjectableData
   ){
     super(svc)
@@ -76,7 +77,7 @@ export class GenericInfoCmp extends BsRegionInputBase implements OnChanges, Afte
       const { dataType, description, name, urls, useClassicUi, view, region, summary, isGdprProtected } = data
       this.description = description
       this.name = name
-      this.urls = urls
+      this.urls = urls || []
       this.doiUrls = this.urls.filter(d => !!d.doi)
       this.useClassicUi = useClassicUi
       if (dataType) this.dataType = dataType
@@ -130,6 +131,7 @@ export class GenericInfoCmp extends BsRegionInputBase implements OnChanges, Afte
       },
       () => {
         this.loadingFlag = false
+        this.cdr.markForCheck()
       }
     )
   }
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/ieegCmp/ieeg.component.ts b/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/ieegCmp/ieeg.component.ts
index 338ce1fc1ec372dba80a5a68a7e862b3febae770..1694e857d446519312a46d43254edd66323627ee 100644
--- a/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/ieegCmp/ieeg.component.ts
+++ b/src/atlasComponents/regionalFeatures/bsFeatures/ieeg/ieegCmp/ieeg.component.ts
@@ -35,7 +35,6 @@ export class BsFeatureIEEGCmp extends BsRegionInputBase implements OnDestroy{
     this.subs.push(
       this.results$.subscribe(results => {
         this.results = results
-        console.log(results)
         this.loadLandmarks()
       })
     )
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/showDataset/showDataset.directive.ts b/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/showDataset/showDataset.directive.ts
index 5aeb3c1eb2310b954ae6346ca97fe78d67afeb85..d4b02e120d85776b02b0db606da5aa059cd46113 100644
--- a/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/showDataset/showDataset.directive.ts
+++ b/src/atlasComponents/regionalFeatures/bsFeatures/kgDataset/showDataset/showDataset.directive.ts
@@ -39,6 +39,9 @@ export class ShowDatasetDialogDirective{
     doi: string
   }[] = []
 
+  @Input('iav-dataset-show-dataset-dialog-ignore-overwrite')
+  ignoreOverwrite = false
+
   @Input('iav-dataset-show-dataset-dialog-contexted-region')
   region: TSiibraRegion & TContextRegion
 
@@ -67,7 +70,7 @@ export class ShowDatasetDialogDirective{
       return this.snackbar.open(`Cannot show dataset. Neither fullId nor kgId provided.`)
     }
 
-    if (this.overwriteFn) {
+    if (!this.ignoreOverwrite && this.overwriteFn) {
       return this.overwriteFn(data)
     }
 
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/entry/entry.component.ts b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/entry/entry.component.ts
index 8acaa8e680f108574e319b3eb5d032b69f70de24..33bc2bbde0ce20039d5bcf33de72782da242cc21 100644
--- a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/entry/entry.component.ts
+++ b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/entry/entry.component.ts
@@ -1,12 +1,11 @@
-import { Component, Inject, OnDestroy, Optional } from "@angular/core";
-import { Observable, of, Subject, Subscription } from "rxjs";
+import { ChangeDetectorRef, Component, Inject, OnDestroy, Optional } from "@angular/core";
+import { BehaviorSubject, Observable, of, Subscription } from "rxjs";
 import { filter, map, shareReplay, startWith, switchMap, tap } from "rxjs/operators";
 import { BsRegionInputBase } from "../../bsRegionInputBase";
 import { REGISTERED_FEATURE_INJECT_DATA } from "../../constants";
 import { BsFeatureService, TFeatureCmpInput } from "../../service";
 import { TBSDetail } from "../type";
 import { ARIA_LABELS } from 'common/constants'
-import { isPr } from "../profile/profile.component";
 
 @Component({
   selector: 'bs-features-receptor-entry',
@@ -21,7 +20,7 @@ export class BsFeatureReceptorEntry extends BsRegionInputBase implements OnDestr
   private sub: Subscription[] = []
   public ARIA_LABELS = ARIA_LABELS
 
-  private selectedREntryId$ = new Subject<string>()
+  private selectedREntryId$ = new BehaviorSubject<string>(null)
   private _selectedREntryId: string
   set selectedREntryId(id: string){
     this.selectedREntryId$.next(id)
@@ -50,13 +49,6 @@ export class BsFeatureReceptorEntry extends BsRegionInputBase implements OnDestr
   public receptorsSummary$ = this.region$.pipe(
     filter(v => !!v),
     switchMap(() => this.getFeatureInstancesList('ReceptorDistribution')),
-    tap(arr => {
-      if (arr && arr.length > 0) {
-        this.selectedREntryId = arr[0]['@id']
-      } else {
-        this.selectedREntryId = null
-      }
-    }),
     startWith([]),
     shareReplay(1),
   )
@@ -75,11 +67,21 @@ export class BsFeatureReceptorEntry extends BsRegionInputBase implements OnDestr
 
   constructor(
     svc: BsFeatureService,
+    cdr: ChangeDetectorRef,
     @Optional() @Inject(REGISTERED_FEATURE_INJECT_DATA) data: TFeatureCmpInput
   ){
     super(svc, data)
     this.sub.push(
-      this.selectedReceptor$.subscribe()
+      this.selectedReceptor$.subscribe(() => {
+        cdr.markForCheck()
+      }),
+      this.receptorsSummary$.subscribe(arr => {
+        if (arr && arr.length > 0) {
+          this.selectedREntryId = arr[0]['@id']
+        } else {
+          this.selectedREntryId = null
+        }
+      })
     )
   }
 }
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/entry/entry.template.html b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/entry/entry.template.html
index 813c489a6f2e2e054ed1019ebc36d5dc6ef2388c..48a24c834f0ef7e943434a6242c12fe49b0f5b91 100644
--- a/src/atlasComponents/regionalFeatures/bsFeatures/receptor/entry/entry.template.html
+++ b/src/atlasComponents/regionalFeatures/bsFeatures/receptor/entry/entry.template.html
@@ -8,8 +8,11 @@
   </mat-option>
 </mat-select>
 
-<ng-container *ngIf="selectedReceptor$ | async as selectedRec">
+<ng-template [ngIf]="!(selectedReceptor$ | async)">
+  <spinner-cmp></spinner-cmp>
+</ng-template>
 
+<ng-template let-selectedRec [ngIf]="selectedReceptor$ | async">
   <bs-features-receptor-fingerprint
     (onSelectReceptor)="onSelectReceptor($event)"
     [bsFeature]="selectedRec">
@@ -44,4 +47,4 @@
     </bs-features-receptor-autoradiograph>
   </ng-template>
 
-</ng-container>
+</ng-template>
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/regionalFeatureWrapper/regionalFeatureWrapper.component.ts b/src/atlasComponents/regionalFeatures/bsFeatures/regionalFeatureWrapper/regionalFeatureWrapper.component.ts
index 72d4595fade4fec861614188df507ba3d5a42b56..76a2ad1f2f9bdffbbb598992d542989a48127279 100644
--- a/src/atlasComponents/regionalFeatures/bsFeatures/regionalFeatureWrapper/regionalFeatureWrapper.component.ts
+++ b/src/atlasComponents/regionalFeatures/bsFeatures/regionalFeatureWrapper/regionalFeatureWrapper.component.ts
@@ -2,7 +2,7 @@ import { Component, ComponentFactory, ComponentFactoryResolver, Inject, Injector
 import { IBSSummaryResponse, TContextedFeature, TRegion } from "../type";
 import { BsFeatureService, TFeatureCmpInput } from "../service";
 import { combineLatest, Observable, Subject } from "rxjs";
-import { debounceTime, map, shareReplay, startWith, tap } from "rxjs/operators";
+import { debounceTime, map, shareReplay, startWith } from "rxjs/operators";
 import { REGISTERED_FEATURE_INJECT_DATA } from "../constants";
 import { ARIA_LABELS } from 'common/constants'
 import {
diff --git a/src/atlasComponents/regionalFeatures/bsFeatures/regionalFeatureWrapper/regionalFeatureWrapper.template.html b/src/atlasComponents/regionalFeatures/bsFeatures/regionalFeatureWrapper/regionalFeatureWrapper.template.html
index adecf93c84ab9c417168b4588e1aef63e4bb55e0..020145c3c36c406a74c3575422068d0b43700892 100644
--- a/src/atlasComponents/regionalFeatures/bsFeatures/regionalFeatureWrapper/regionalFeatureWrapper.template.html
+++ b/src/atlasComponents/regionalFeatures/bsFeatures/regionalFeatureWrapper/regionalFeatureWrapper.template.html
@@ -33,9 +33,17 @@
       [attr.aria-label]="ARIA_LABELS.LIST_OF_DATASETS_ARIA_LABEL">
 
       <!-- if busy, show spinner -->
-      <ng-template [ngIf]="busy$ | async">
+      <ng-template [ngIf]="busy$ | async" [ngIfElse]="notBusyTmpl">
         <ng-template [ngTemplateOutlet]="busyTmpl"></ng-template>
       </ng-template>
+
+      <ng-template #notBusyTmpl>
+        <ng-template [ngIf]="registeredFeatures.length === 0">
+          <span class="text-muted">
+            No regional features found.
+          </span>
+        </ng-template>
+      </ng-template>
       <div *ngFor="let feature of registeredFeatures; let index = index"
         class="overflow-hidden">
 
diff --git a/src/atlasComponents/splashScreen/splashScreen/splashScreen.component.ts b/src/atlasComponents/splashScreen/splashScreen/splashScreen.component.ts
index 3d4ed603f7586a8395df2c4daf06949f4b68802c..3df8c71c099444e4be81158e3093c8c9e6d3dcde 100644
--- a/src/atlasComponents/splashScreen/splashScreen/splashScreen.component.ts
+++ b/src/atlasComponents/splashScreen/splashScreen/splashScreen.component.ts
@@ -1,4 +1,4 @@
-import { Component, ElementRef, Pipe, PipeTransform, ViewChild } from "@angular/core";
+import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ElementRef, Pipe, PipeTransform, ViewChild } from "@angular/core";
 import { MatSnackBar } from "@angular/material/snack-bar";
 import { select, Store } from "@ngrx/store";
 import { Observable, Subject, Subscription } from "rxjs";
@@ -13,6 +13,7 @@ import { CONST } from 'common/constants'
   styleUrls : [
     `./splashScreen.style.css`,
   ],
+  changeDetection: ChangeDetectionStrategy.OnPush,
 })
 
 export class SplashScreen {
@@ -33,10 +34,14 @@ export class SplashScreen {
   constructor(
     private store: Store<any>,
     private snack: MatSnackBar,
-    private pureConstantService: PureContantService
+    private pureConstantService: PureContantService,
+    private cdr: ChangeDetectorRef,
   ) {
     this.subscriptions.push(
-      this.pureConstantService.allFetchingReady$.subscribe(flag => this.finishedLoading = flag)
+      this.pureConstantService.allFetchingReady$.subscribe(flag => {
+        this.finishedLoading = flag
+        this.cdr.markForCheck()
+      })
     )
 
     this.loadedAtlases$ = this.store.pipe(
diff --git a/src/atlasComponents/template/getTemplatePreviewUrl.pipe.ts b/src/atlasComponents/template/getTemplatePreviewUrl.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..c2071c8af1b686baee241c47608695b7a709667d
--- /dev/null
+++ b/src/atlasComponents/template/getTemplatePreviewUrl.pipe.ts
@@ -0,0 +1,30 @@
+import { Pipe, PipeTransform } from "@angular/core"
+
+const previewImgMap = new Map([
+  ['minds/core/referencespace/v1.0.0/a1655b99-82f1-420f-a3c2-fe80fd4c8588', 'bigbrain.png'],
+  ['minds/core/referencespace/v1.0.0/dafcffc5-4826-4bf1-8ff6-46b8a31ff8e2', 'icbm2009c.png'],
+  ['minds/core/referencespace/v1.0.0/7f39f7be-445b-47c0-9791-e971c0b6d992', 'colin27.png'],
+
+  ['minds/core/referencespace/v1.0.0/265d32a0-3d84-40a5-926f-bf89f68212b9', 'allen-mouse.png'],
+  
+  ['minds/core/referencespace/v1.0.0/d5717c4a-0fa1-46e6-918c-b8003069ade8', 'waxholm.png'],
+
+  ['minds/core/referencespace/v1.0.0/tmp-fsaverage', 'freesurfer.png'],
+  ['minds/core/referencespace/v1.0.0/tmp-fsaverage6', 'freesurfer.png'],
+
+  ['minds/core/referencespace/v1.0.0/tmp-hcp32k', 'freesurfer.png'],
+  ['minds/core/referencespace/v1.0.0/MEBRAINS_T1.masked', 'primate.png'],
+  
+])
+
+@Pipe({
+  name: 'getTemplatePreviewUrl',
+  pure: true
+})
+
+export class GetTemplatePreviewUrlPipe implements PipeTransform{
+  public transform(tile: any){
+    const filename = previewImgMap.get(tile['@id'])
+    return filename && `assets/images/atlas-selection/${filename}`
+  }
+}
diff --git a/src/atlasComponents/template/index.ts b/src/atlasComponents/template/index.ts
new file mode 100644
index 0000000000000000000000000000000000000000..38cd6578cc518656abb1303d11557b86529cc996
--- /dev/null
+++ b/src/atlasComponents/template/index.ts
@@ -0,0 +1,2 @@
+export { GetTemplatePreviewUrlPipe } from "./getTemplatePreviewUrl.pipe";
+export { SiibraExplorerTemplateModule } from './module'
diff --git a/src/atlasComponents/template/module.ts b/src/atlasComponents/template/module.ts
new file mode 100644
index 0000000000000000000000000000000000000000..9f1a49646b274dc7936b24800f99a4bf12e152c7
--- /dev/null
+++ b/src/atlasComponents/template/module.ts
@@ -0,0 +1,17 @@
+import { NgModule } from "@angular/core";
+import { GetTemplatePreviewUrlPipe } from "./getTemplatePreviewUrl.pipe";
+import { TemplateIsDarkThemePipe } from "./templateIsDarkTheme.pipe";
+
+@NgModule({
+  imports: [],
+  declarations: [
+    GetTemplatePreviewUrlPipe,
+    TemplateIsDarkThemePipe,
+  ],
+  exports: [
+    GetTemplatePreviewUrlPipe,
+    TemplateIsDarkThemePipe,
+  ]
+})
+
+export class SiibraExplorerTemplateModule{}
\ No newline at end of file
diff --git a/src/atlasComponents/template/templateIsDarkTheme.pipe.ts b/src/atlasComponents/template/templateIsDarkTheme.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..8454fd96e81e9815f8ab0bb627eb1e01d18b95b0
--- /dev/null
+++ b/src/atlasComponents/template/templateIsDarkTheme.pipe.ts
@@ -0,0 +1,33 @@
+import { OnDestroy, Pipe, PipeTransform } from "@angular/core";
+import { select, Store } from "@ngrx/store";
+import { Subscription } from "rxjs";
+import { viewerStateSelectedTemplateFullInfoSelector } from "src/services/state/viewerState/selectors";
+import { IHasId } from "src/util/interfaces";
+
+@Pipe({
+  name: 'templateIsDarkTheme',
+  pure: true,
+})
+
+export class TemplateIsDarkThemePipe implements OnDestroy, PipeTransform{
+
+  private templateFullInfo: any[] = []
+  constructor(store: Store<any>){
+    this.sub.push(
+      store.pipe(
+        select(viewerStateSelectedTemplateFullInfoSelector)
+      ).subscribe(val => this.templateFullInfo = val)
+    )
+  }
+
+  private sub: Subscription[] = []
+
+  ngOnDestroy(){
+    while(this.sub.length) this.sub.pop().unsubscribe()
+  }
+
+  public transform(template: IHasId): boolean{
+    const found = this.templateFullInfo.find(t => t['@id'] === template["@id"])
+    return found && found.darktheme
+  }
+}
\ No newline at end of file
diff --git a/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.component.ts b/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.component.ts
index 84c42160985d551a495cf6a2713aa25738578b36..1752a7d5f686fbd441993f3a33898f9b194b0744 100644
--- a/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.component.ts
+++ b/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.component.ts
@@ -1,13 +1,15 @@
-import { Component, OnInit, ViewChildren, QueryList, HostBinding, ViewChild, TemplateRef, ElementRef, Pipe, PipeTransform } from "@angular/core";
+import { Component, OnInit, ViewChildren, QueryList, HostBinding, ViewChild, ElementRef, OnDestroy } from "@angular/core";
 import { select, Store } from "@ngrx/store";
-import { distinctUntilChanged, map, withLatestFrom, shareReplay, groupBy, mergeMap, toArray, switchMap, scan, filter, tap } from "rxjs/operators";
-import { Observable, Subscription, from, zip, of, combineLatest } from "rxjs";
+import { distinctUntilChanged, map, withLatestFrom, shareReplay, mapTo } from "rxjs/operators";
+import { merge, Observable, Subject, Subscription } from "rxjs";
 import { viewerStateSelectTemplateWithId, viewerStateToggleLayer } from "src/services/state/viewerState.store.helper";
 import { MatMenuTrigger } from "@angular/material/menu";
 import { viewerStateGetSelectedAtlas, viewerStateAtlasLatestParcellationSelector, viewerStateSelectedTemplateFullInfoSelector, viewerStateSelectedTemplatePureSelector, viewerStateSelectedParcellationSelector } from "src/services/state/viewerState/selectors";
-import { ARIA_LABELS, QUICKTOUR_DESC } from 'common/constants'
+import { ARIA_LABELS, CONST, QUICKTOUR_DESC } from 'common/constants'
 import { IQuickTourData } from "src/ui/quickTour/constrants";
 import { animate, state, style, transition, trigger } from "@angular/animations";
+import { IHasId, OVERWRITE_SHOW_DATASET_DIALOG_TOKEN } from "src/util/interfaces";
+import { CurrentTmplSupportsParcPipe } from "../pipes/currTmplSupportsParc.pipe";
 
 @Component({
   selector: 'atlas-layer-selector',
@@ -41,275 +43,124 @@ import { animate, state, style, transition, trigger } from "@angular/animations"
     }
   ]
 })
-export class AtlasLayerSelector implements OnInit {
-
-    public TOGGLE_ATLAS_LAYER_SELECTOR = ARIA_LABELS.TOGGLE_ATLAS_LAYER_SELECTOR
-
-    @ViewChildren(MatMenuTrigger) matMenuTriggers: QueryList<MatMenuTrigger>
-    public atlas: any
-
-    @ViewChild('selectorPanelTmpl', { read: ElementRef })
-    selectorPanelTemplateRef: ElementRef
-
-    public selectedAtlas$: Observable<any> = this.store$.pipe(
-      select(viewerStateGetSelectedAtlas),
-      distinctUntilChanged(),
-      shareReplay(1)
-    )
-    private layersGroupBy$ = this.selectedAtlas$.pipe(
-      switchMap(selectedAtlas => from((selectedAtlas?.parcellations) || []).pipe(
-        /**
-         * do not show base layers
-         */
-        filter(p => !(p as any).baseLayer),
-        groupBy((parcellation: any) => parcellation.groupName, p => p),
-        mergeMap(group => zip(
-          of(group.key),
-          group.pipe(toArray()))
-        ),
-        scan((acc, curr) => acc.concat([ curr ]), []),
-        shareReplay(1),
-      ))
-    )
-
-
-    private atlasLayersLatest$ = this.store$.pipe(
-      select(viewerStateAtlasLatestParcellationSelector),
-      shareReplay(1),
+export class AtlasLayerSelector implements OnInit, OnDestroy {
+
+  public ARIA_LABELS = ARIA_LABELS
+  public CONST = CONST
+
+  @ViewChildren(MatMenuTrigger)
+  matMenuTriggers: QueryList<MatMenuTrigger>
+
+  @ViewChild('selectorPanelTmpl', { read: ElementRef })
+  selectorPanelTemplateRef: ElementRef
+
+  public selectedAtlas$: Observable<any> = this.store$.pipe(
+    select(viewerStateGetSelectedAtlas),
+    distinctUntilChanged(),
+    shareReplay(1)
+  )
+
+  public atlasLayersLatest$ = this.store$.pipe(
+    select(viewerStateAtlasLatestParcellationSelector),
+    shareReplay(1),
+  )
+
+  public availableTemplates$ = this.store$.pipe<any[]>(
+    select(viewerStateSelectedTemplateFullInfoSelector),
+  )
+
+  private selectedTemplate: any
+  public selectedTemplate$ = this.store$.pipe(
+    select(viewerStateSelectedTemplatePureSelector),
+    withLatestFrom(this.availableTemplates$),
+    map(([selectedTmpl, fullInfoTemplates]) => {
+      return fullInfoTemplates.find(t => t['@id'] === selectedTmpl['@id'])
+    })
+  )
+  private showOverlayIntent$ = new Subject()
+  public showLoadingOverlay$ = merge(
+    this.showOverlayIntent$.pipe(
+      mapTo(true)
+    ),
+    this.selectedTemplate$.pipe(
+      mapTo(false)
     )
+  ).pipe(
+    distinctUntilChanged(),
+  )
+
+  public selectedParcellation$ = this.store$.pipe(
+    select(viewerStateSelectedParcellationSelector),
+  )
+
+  private subscriptions: Subscription[] = []
+
+  @HostBinding('attr.data-opened')
+  public selectorExpanded: boolean = false
+      
+  public quickTourData: IQuickTourData = {
+    order: 4,
+    description: QUICKTOUR_DESC.LAYER_SELECTOR,
+  }
 
-    public nonGroupedLayers$: Observable<any[]> = this.atlasLayersLatest$.pipe(
-      map(allParcellations =>
-        allParcellations
-          .filter(p => !p['groupName'])
-          .filter(p => !p['baseLayer'])
-      ),
-    )
+  constructor(private store$: Store<any>) {}
 
-    public groupedLayers$: Observable<any[]> = combineLatest([
-      this.atlasLayersLatest$.pipe(
-        map(allParcellations =>
-          allParcellations.filter(p => !p['baseLayer'])
-        ),
-      ),
-      this.layersGroupBy$
-    ]).pipe(
-      map(([ allParcellations, arr]) => arr
-        .filter(([ key ]) => !!key )
-        .map(([key, parcellations]) => ({
-          name: key,
-          previewUrl: parcellations[0].previewUrl,
-          parcellations: parcellations.map(p => {
-            const fullInfo = allParcellations.find(fullP => fullP['@id'] === p['@id']) || {}
-            return {
-              ...fullInfo,
-              ...p,
-              darktheme: (fullInfo || {}).useTheme === 'dark'
-            }
-          })
-        }))
-      ),
+  ngOnInit(): void {
+    this.subscriptions.push(
+      this.selectedTemplate$.subscribe(st => {
+        this.selectedTemplate = st
+      }),
     )
-    public selectedTemplateSpaceId: string
-    public selectedLayers = []
-
-    public selectedTemplate$: Observable<any>
-    private selectedParcellation$: Observable<any>
-
-    private subscriptions: Subscription[] = []
-
-    @HostBinding('attr.data-opened')
-    public selectorExpanded: boolean = false
-    public selectedTemplatePreviewUrl: string = ''
-        
-    public quickTourData: IQuickTourData = {
-      order: 4,
-      description: QUICKTOUR_DESC.LAYER_SELECTOR,
-    }
+  }
 
-    public availableTemplates$ = this.store$.pipe<any[]>(
-      select(viewerStateSelectedTemplateFullInfoSelector),
-    )
+  ngOnDestroy() {
+    while(this.subscriptions.length) this.subscriptions.pop().unsubscribe()
+  }
 
-    public containerMaxWidth: number
 
-    public shouldShowRenderPlaceHolder$ = combineLatest([
-      this.availableTemplates$,
-      this.groupedLayers$,
-      this.nonGroupedLayers$,
-    ]).pipe(
-      map(([ availTmpl, grpL, ungrpL ]) => {
-        return availTmpl?.length > 0 || (grpL?.length || 0) + (ungrpL?.length || 0) > 0
-      })
-    )
-
-    constructor(private store$: Store<any>) {
+  toggleSelector() {
+    this.selectorExpanded = !this.selectorExpanded
+  }
 
-      this.selectedTemplate$ = this.store$.pipe(
-        select(viewerStateSelectedTemplatePureSelector),
-        withLatestFrom(this.selectedAtlas$),
-        map(([templateSelected, templateFromAtlas]) => {
-          return {
-            ...templateFromAtlas,
-            ...templateSelected
-          }
-        })
-      )
-      this.selectedParcellation$ = this.store$.pipe(
-        select(viewerStateSelectedParcellationSelector)
-      )
+  selectTemplatewithId(templateId: string) {
+    this.showOverlayIntent$.next(true)
+    this.store$.dispatch(viewerStateSelectTemplateWithId({
+      payload: {
+        '@id': templateId
+      }
+    }))
+  }
 
-    }
+  private currTmplSupportParcPipe = new CurrentTmplSupportsParcPipe()
 
-    ngOnInit(): void {
-      this.subscriptions.push(
-        this.selectedTemplate$.subscribe(st => {
-          this.selectedTemplatePreviewUrl = st.templateSpaces?.find(t => t['@id'] === st['@id']).previewUrl
-          this.selectedTemplateSpaceId = st['@id']
-        }),
-      )
-      this.subscriptions.push(
-        this.selectedParcellation$.subscribe(ps => {
-          this.selectedLayers = (this.atlas && [this.atlas.parcellations.find(l => l['@id'] === ps['@id'])['@id']]) || []
-        })
-      )
-      this.subscriptions.push(
-        this.selectedAtlas$.subscribe(sa => {
-          this.atlas = sa
-        })
+  selectParcellationWithName(layer: any) {
+    const tmplChangeReq = this.currTmplSupportParcPipe.transform(this.selectedTemplate, layer)
+    if (!tmplChangeReq) {
+      this.store$.dispatch(
+        viewerStateToggleLayer({ payload: layer })
       )
-    }
-
-    toggleSelector() {
-      this.selectorExpanded = !this.selectorExpanded
-    }
-
-    selectTemplateWithName(template) {
+    } else {
       this.store$.dispatch(
-        viewerStateSelectTemplateWithId({ payload: template })
+        viewerStateSelectTemplateWithId({
+          payload: layer.availableIn[0],
+          config: {
+            selectParcellation: layer
+          }
+        })
       )
     }
+  }
 
-    selectParcellationWithName(layer) {
-      const templateChangeRequired = !this.currentTemplateIncludesLayer(layer)
-      if (!templateChangeRequired) {
-        this.store$.dispatch(
-          viewerStateToggleLayer({ payload: layer })
-        )
-      } else {
-        this.store$.dispatch(
-          viewerStateSelectTemplateWithId({ payload: layer.availableIn[0], config: { selectParcellation: layer } })
-        )
-      }
-    }
-
-    currentTemplateIncludesLayer(layer) {
-      return layer && layer.availableIn.map(a => a['@id']).includes(this.selectedTemplateSpaceId)
-    }
-
-    templateIncludesGroup(group) {
-      return group.parcellations.some(v => v.availableIn.map(t => t['@id']).includes(this.selectedTemplateSpaceId))
-    }
-
-    selectedOneOfTheLayers(layers) {
-      const includes = layers.map(l=>l['@id']).some(id=> this.selectedLayers.includes(id))
-      return includes
-    }
-
-    selectedLayersIncludes(id) {
-      return this.selectedLayers.includes(id)
-    }
-
-    collapseExpandedGroup(){
-      this.matMenuTriggers.forEach(t => t.menuOpen && t.closeMenu())
-    }
-
-    getTileTmplClickFnAsCtx(fn: (...arg) => void, param: any) {
-      return () => fn.call(this, param)
-    }
-
-    getTooltipText(layer) {
-      if (!this.atlas) return
-      if (this.atlas.templateSpaces.map(tmpl => tmpl['@id']).includes(layer['@id'])) return layer.name
-      if (layer.availableIn) {
-        if (this.currentTemplateIncludesLayer(layer)) return layer.name
-        else {
-          const firstAvailableRefSpaceId = layer && Array.isArray(layer.availableIn) && layer.availableIn.length > 0 && layer.availableIn[0]['@id']
-          const firstAvailableRefSpace = firstAvailableRefSpaceId && this.atlas.templateSpaces.find(t => t['@id'] === firstAvailableRefSpaceId)
-          return `${layer.name} 🔄 ${(firstAvailableRefSpace && firstAvailableRefSpace.name) || ''}`
-        }
-      }
-
-      if (layer.parcellations) {
-        if (this.templateIncludesGroup(layer)) return layer.name
-        else return `${layer.name} 🔄`
-      }
-
-      return layer.name
-    }
-
-    trackbyAtId(t){
-      return t['@id']
-    }
-
-    trackbyName(t) {
-      return t['name']
-    }
-}
-
-import { OVERWRITE_SHOW_DATASET_DIALOG_TOKEN } from "src/util/interfaces";
-
-const previewImgMap = new Map([
-  ['minds/core/referencespace/v1.0.0/a1655b99-82f1-420f-a3c2-fe80fd4c8588', 'bigbrain.png'],
-  ['minds/core/referencespace/v1.0.0/dafcffc5-4826-4bf1-8ff6-46b8a31ff8e2', 'icbm2009c.png'],
-  ['minds/core/referencespace/v1.0.0/7f39f7be-445b-47c0-9791-e971c0b6d992', 'colin27.png'],
-  ['minds/core/parcellationatlas/v1.0.0/94c1125b-b87e-45e4-901c-00daee7f2579', 'cytoarchitectonic-maps.png'],
-  ['juelich/iav/atlas/v1.0.0/3', 'cortical-layers.png'],
-  ['juelich/iav/atlas/v1.0.0/4', 'grey-white-matter.png'],
-  ['juelich/iav/atlas/v1.0.0/5', 'firbe-long.png'],
-  ['juelich/iav/atlas/v1.0.0/6', 'firbe-short.png'],
-  ['minds/core/parcellationatlas/v1.0.0/d80fbab2-ce7f-4901-a3a2-3c8ef8a3b721', 'difumo-64.png'],
-  ['minds/core/parcellationatlas/v1.0.0/73f41e04-b7ee-4301-a828-4b298ad05ab8', 'difumo-128.png'],
-  ['minds/core/parcellationatlas/v1.0.0/141d510f-0342-4f94-ace7-c97d5f160235', 'difumo-256.png'],
-  ['minds/core/parcellationatlas/v1.0.0/63b5794f-79a4-4464-8dc1-b32e170f3d16', 'difumo-512.png'],
-  ['minds/core/parcellationatlas/v1.0.0/12fca5c5-b02c-46ce-ab9f-f12babf4c7e1', 'difumo-1024.png'],
-  ['minds/core/referencespace/v1.0.0/265d32a0-3d84-40a5-926f-bf89f68212b9', 'allen-mouse.png'],
-  ['minds/core/parcellationatlas/v1.0.0/05655b58-3b6f-49db-b285-64b5a0276f83', 'allen-mouse-2017.png'],
-  ['minds/core/parcellationatlas/v1.0.0/39a1384b-8413-4d27-af8d-22432225401f', 'allen-mouse-2015.png'],
-  ['minds/core/referencespace/v1.0.0/d5717c4a-0fa1-46e6-918c-b8003069ade8', 'waxholm.png'],
-  ['minds/core/parcellationatlas/v1.0.0/ebb923ba-b4d5-4b82-8088-fa9215c2e1fe-v4', 'waxholm-v4.png'],
-  ['minds/core/parcellationatlas/v1.0.0/ebb923ba-b4d5-4b82-8088-fa9215c2e1fe', 'waxholm-v3.png'],
-  ['minds/core/parcellationatlas/v1.0.0/2449a7f0-6dd0-4b5a-8f1e-aec0db03679d', 'waxholm-v2.png'],
-  ['minds/core/parcellationatlas/v1.0.0/11017b35-7056-4593-baad-3934d211daba', 'waxholm-v1.png'],
-  ['juelich/iav/atlas/v1.0.0/79cbeaa4ee96d5d3dfe2876e9f74b3dc3d3ffb84304fb9b965b1776563a1069c', 'short-bundle-hcp.png'],
-  ['minds/core/referencespace/v1.0.0/tmp-fsaverage', 'freesurfer.png'],
-  ['minds/core/referencespace/v1.0.0/tmp-fsaverage6', 'freesurfer.png'],
-  ['minds/core/referencespace/v1.0.0/tmp-hcp32k', 'freesurfer.png'],
-  ['minds/core/referencespace/v1.0.0/MEBRAINS_T1.masked', 'primate.png'],
-  ['minds/core/parcellationatlas/v1.0.0/mebrains-tmp-id', 'primate-parc.png'],
-])
+  collapseExpandedGroup(){
+    this.matMenuTriggers.forEach(t => t.menuOpen && t.closeMenu())
+  }
 
-/**
- * used for directories
- */
-const previewNameToPngMap = new Map([
-  ['fibre architecture', 'firbe-long.png'],
-  ['functional modes', 'difumo-128.png']
-])
 
-@Pipe({
-  name: 'getPreviewUrlPipe',
-  pure: true
-})
+  trackbyAtId(t: IHasId){
+    return t['@id']
+  }
 
-export class GetPreviewUrlPipe implements PipeTransform{
-  public transform(tile: any){
-    const filename = tile['@id']
-      ? previewImgMap.get(tile['@id'])
-      : previewNameToPngMap.get(tile['name'])
-    if (!filename) {
-      console.log(tile)
-    }
-    return filename && `assets/images//atlas-selection/${filename}`
+  trackKeyVal(obj: {key: string, value: any}) {
+    return obj.key
   }
 }
diff --git a/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.style.css b/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.style.css
index 56cfffcf79c4db7ee31690dbe90d44a4016ad97f..425a45a5e252f904956712930e5996740733d60f 100644
--- a/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.style.css
+++ b/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.style.css
@@ -1,41 +1,3 @@
-.singleLayerImageContainer img {
-    flex-shrink: 0;
-    width: 70px;
-    height: 70px;
-    border-radius: 10px;
-    -webkit-border-radius: 10px;
-    -moz-border-radius: 10px;
-}
-
-
-.selectedTemplateDefaultContainer {
-    width: 100px;
-    height: 100px;
-    border-radius: 10px;
-}
-.selectedTemplateDefaultContainer img {
-    border-radius: 10px;
-    min-width: 100%;
-    min-height: 100%;
-    width: 100%;
-}
-
-.selectedLayerBorder {
-    border: 2px solid #FED363;
-}
-
-.folder-container
-{
-    margin-right:0.5rem;
-    margin-bottom:-0.5rem;
-}
-
-.info-container
-{
-    margin-right:-0.5rem;
-    margin-top:-0.25rem;
-}
-
 .selector-container
 {
     overflow-y:scroll;
@@ -45,15 +7,34 @@
     z-index: 5;
 }
 
-.single-column-tile
+:host-context([darktheme="true"]) .loading-overlay
+{
+    background-color: rgba(10, 10, 10, 0.8);
+}
+
+.loading-overlay
 {
-    width: calc((28rem - 32px)/3);
+    background-color: rgba(250, 250, 250, 0.8);
 }
 
-.infoButton {
-    height: 18px;
-    width: 18px;
-    margin-top: 10px;
-    margin-right: 12px;
-    border-radius: 50%;
+.loading-overlay
+{
+    position: absolute;
+    width: 100%;
+    height: 100%;
+    top: 0;
+    left: 0;
+    font-size: 200%;
+
+    display: grid;
+    grid-template-columns: auto;
+    grid-template-rows: 1fr auto 1fr;
+    grid-template-columns: 1fr auto 1fr;
+    grid-template-areas: "." "vertical-center" ".";
+}
+
+.loading-overlay > .spinner
+{
+    grid-column: 2;
+    grid-row: 2;
 }
diff --git a/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.template.html b/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.template.html
index e7b687d28f0262123213da9f38d0aaf77e36a2f6..ed78029cd9c644c84e4c809e9498ff21a5eece81 100644
--- a/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.template.html
+++ b/src/atlasComponents/uiSelectors/atlasLayerSelector/atlasLayerSelector.template.html
@@ -1,192 +1,169 @@
-<div class="position-relative d-flex flex-column justify-content-start">
-
-    <!-- selector panel when expanded -->
-
-    <mat-card class="selector-container position-absolute"
-        [ngClass]="{'pe-all': selectorExpanded}"
-        [@toggleAtlasLayerSelector]="selectorExpanded"
-        (@toggleAtlasLayerSelector.done)="atlasSelectorTour?.attachTo(selectorExpanded ? selectorPanelTemplateRef : null)"
-        #selectorPanelTmpl>
-        <mat-card-content>
-
-            <!-- templates -->
-            <mat-card-subtitle>
-                Templates
-            </mat-card-subtitle>
-            <mat-grid-list cols="3" rowHeight="3:4">
-                <!-- template tiles -->
-                <mat-grid-tile *ngFor="let template of availableTemplates$ | async; trackBy: trackbyAtId"
-                    [attr.aria-checked]="selectedTemplateSpaceId === template['@id']">
-                    <ng-container *ngTemplateOutlet="tileTmpl; context: {
-                        tileSrc: template,
-                        selected: selectedTemplateSpaceId === template['@id'],
-                        onClick: getTileTmplClickFnAsCtx(selectTemplateWithName, template)
-                    }">
-                    </ng-container>
-                </mat-grid-tile>
-            </mat-grid-list>
-
-            <mat-divider></mat-divider>
-
-            <!-- levels/maps/segregations -->
-            <mat-card-subtitle class="mt-2">
-                Levels
-            </mat-card-subtitle>
-
-            <mat-grid-list cols="3" rowHeight="3:4">
-
-                <!-- non grouped layers -->
-                <mat-grid-tile *ngFor="let layer of (nonGroupedLayers$ | async); trackBy: trackbyAtId"
-                    [attr.aria-checked]="selectedLayersIncludes(layer['@id'])">
-                    <ng-container *ngTemplateOutlet="tileTmpl; context: {
-                        tileSrc: layer,
-                        selected: selectedLayersIncludes(layer['@id']),
-                        onClick: getTileTmplClickFnAsCtx(selectParcellationWithName, layer),
-                        disabled: !currentTemplateIncludesLayer(layer)
-                    }">
-
-                    </ng-container>
-                </mat-grid-tile>
-
-                <!-- grouped layers -->
-                <mat-grid-tile *ngFor="let group of (groupedLayers$ | async); trackBy: trackbyName"
-                    [attr.aria-checked]="selectedOneOfTheLayers(group.parcellations)">
-                    <ng-container *ngTemplateOutlet="tileTmpl; context: {
-                        tileSrc: group,
-                        selected: selectedOneOfTheLayers(group.parcellations),
-                        disabled: !templateIncludesGroup(group),
-                        menuTriggerFor: layerGroupMenu,
-                        menuTriggerData: { layerGroupItems: group.parcellations },
-                        isDirectory: true
-                    }">
-
-                    </ng-container>
-                </mat-grid-tile>
-            </mat-grid-list>
-        </mat-card-content>
-    </mat-card>
-
-    <!-- place holder when not expanded -->
-    <div class="position-relative m-2 cursor-pointer scale-up-bl pe-all"
-        quick-tour
-        [quick-tour-description]="quickTourData.description"
-        [quick-tour-order]="quickTourData.order"
-        #atlasSelectorTour="quickTour">
-        <button color="primary"
-            matTooltip="Select layer"
-            mat-mini-fab
-            *ngIf="shouldShowRenderPlaceHolder$ | async"
-            [attr.aria-label]="TOGGLE_ATLAS_LAYER_SELECTOR"
-            (click)="toggleSelector()">
-            <i class="fas fa-layer-group"></i>
-        </button>
-    </div>
+<!-- selector panel when expanded -->
+
+<mat-card class="selector-container m-2 position-absolute"
+    [ngClass]="{'pe-all': selectorExpanded}"
+    [@toggleAtlasLayerSelector]="selectorExpanded"
+    (@toggleAtlasLayerSelector.done)="atlasSelectorTour?.attachTo(selectorExpanded ? selectorPanelTemplateRef : null)"
+    #selectorPanelTmpl>
+    <mat-card-content>
+
+        <!-- templates -->
+        <mat-card-subtitle>
+            {{ CONST.ATLAS_SELECTOR_LABEL_SPACES }}
+        </mat-card-subtitle>
+
+        <!-- template grid and tiles -->
+        <mat-grid-list cols="3"
+            rowHeight="2:3"
+            gutterSize="16">
+
+            <mat-grid-tile *ngFor="let template of availableTemplates$ | async; trackBy: trackbyAtId"
+                [attr.aria-checked]="(selectedTemplate$ | async | getProperty : '@id')  === template['@id']">
+                
+                <div [hidden]
+                    iav-dataset-show-dataset-dialog
+                    [iav-dataset-show-dataset-dialog-name]="template.originDatainfos[0]?.name"
+                    [iav-dataset-show-dataset-dialog-description]="template.originDatainfos[0]?.description"
+                    [iav-dataset-show-dataset-dialog-urls]="template.originDatainfos[0]?.urls"
+                    #kgInfo="iavDatasetShowDatasetDialog">
+                </div>
+                <tile-cmp [tile-image-src]="template | getPreviewUrlPipe"
+                    class="cursor-pointer pe-all"
+                    tile-image-alt="Preview of this tile"
+                    [tile-text]="template.displayName || template.name"
+                    [tile-show-info]="template.originDatainfos?.length > 0"
+                    [tile-disabled]="!(selectedParcellation$ | async | currParcSupportsTmpl : template)"
+                    [tile-image-darktheme]="template.darktheme"
+                    [tile-selected]="(selectedTemplate$ | async | getProperty : '@id')  === template['@id']"
+                    (tile-on-click)="selectTemplatewithId(template['@id'])"
+                    (tile-on-info-click)="kgInfo && kgInfo.onClick()">
+                </tile-cmp>
+            </mat-grid-tile>
+        </mat-grid-list>
 
-</div>
+        <mat-divider></mat-divider>
 
-<!-- image tile tmpl -->
-<ng-template #tileTmpl
-    let-tileSrc="tileSrc"
-    let-selected="selected"
-    let-onClick="onClick"
-    let-disabled="disabled"
-    let-isDirectory="isDirectory"
-    let-menuTriggerFor="menuTriggerFor"
-    let-menuTriggerData="menuTriggerData">
-    <div *ngIf="menuTriggerFor; else noMatMenuTriggerTmpl"
-        iav-stop="click"
-        class="d-flex flex-column justify-content-start w-100 h-100 mb-1 mt-1 overflow-hidden cursor-pointer singleLayerImageContainer"
-        [matMenuTriggerFor]="menuTriggerFor"
-        [matMenuTriggerData]="menuTriggerData">
-
-        <ng-container *ngTemplateOutlet="tileContent">
-        </ng-container>
-    </div>
+        <!-- parcellations -->
+        <mat-card-subtitle class="mt-2">
+            {{ CONST.ATLAS_SELECTOR_LABEL_PARC_MAPS }}
+        </mat-card-subtitle>
 
-    <ng-template #noMatMenuTriggerTmpl>
-        <div class="d-flex flex-column justify-content-start w-100 h-100 mb-1 mt-1 overflow-hidden cursor-pointer singleLayerImageContainer">
-            <ng-container *ngTemplateOutlet="tileContent">
-            </ng-container>
-        </div>
-    </ng-template>
+        <mat-grid-list cols="3"
+            rowHeight="2:3"
+            gutterSize="16">
+
+            <!-- non grouped layers -->
+            <mat-grid-tile *ngFor="let layer of (atlasLayersLatest$ | async | getNonbaseParc | getIndividualParc); trackBy: trackbyAtId"
+                [attr.aria-checked]="selectedParcellation$ | async | groupParcSelected : layer">
 
-    <ng-template #tileContent>
-        <div class="d-flex flex-column justify-content-start w-100 mb-1 mt-1 overflow-hidden cursor-pointer singleLayerImageContainer"
-            [matTooltip]="getTooltipText(tileSrc)"
-            matTooltipPosition="above"
-            (click)="onClick && onClick()"
-            [ngStyle]="{opacity: disabled ? '0.2': '1' }">
-
-            <div class="position-relative d-flex flex-column align-items-center">
-                <div class="position-relative">
-                    <!-- info icon btn -->
-                    <div class="position-absolute top-0 right-0 info-container"
-                        [ngClass]="{ 'darktheme': tileSrc.darktheme, 'lighttheme': !tileSrc.darktheme }">
-                        <ng-container *ngTemplateOutlet="infoBtn; context: { tileSrc: tileSrc}">
-
-                        </ng-container>
-                    </div>
-
-                    <!-- preview image -->
-                    <img [src]="tileSrc | getPreviewUrlPipe"
-                        alt="Preview of this tile"
-                        class="layer-image align-self-center"
-                        [ngClass]="{ 'selectedLayerBorder': selected }"
-                        draggable="false">
-
-                    <!-- if is directory, show directory icon -->
-                    <div *ngIf="isDirectory" class="position-absolute bottom-0 right-0">
-                        <i class="fas fa-folder folder-container fa-2x"></i>
-                    </div>
+                <div [hidden]
+                    iav-dataset-show-dataset-dialog
+                    [iav-dataset-show-dataset-dialog-name]="layer.originDatainfos[0]?.name"
+                    [iav-dataset-show-dataset-dialog-description]="layer.originDatainfos[0]?.description"
+                    [iav-dataset-show-dataset-dialog-urls]="layer.originDatainfos[0]?.urls"
+                    #kgInfo="iavDatasetShowDatasetDialog">
                 </div>
-            </div>
+                <tile-cmp [tile-image-src]="layer | getPreviewUrlPipe"
+                    class="cursor-pointer pe-all"
+                    tile-image-alt="Preview of this tile"
+                    [tile-text]="layer.displayName || layer.name"
+                    [tile-show-info]="layer.originDatainfos?.length > 0"
+                    [tile-disabled]="!(selectedTemplate$ | async | currentTemplateSupportsParcellation : layer)"
+                    [tile-image-darktheme]="layer.darktheme"
 
-            <!-- text container -->
-            <div class="d-flex justify-content-center">
-                <small class="iv-custom-comp text ml-1 mr-1 mt-2 text-break text-center">{{ tileSrc.displayName || tileSrc.name }}</small>
-            </div>
-        </div>
-    </ng-template>
-</ng-template>
+                    [tile-selected]="selectedParcellation$ | async | groupParcSelected : layer"
 
-<ng-template #infoBtn let-tileSrc="tileSrc">
-    <ng-container *ngFor="let originDatainfo of tileSrc.originDatainfos">
-        <div mat-icon-button
-            iav-stop="click"
-            class="iv-custom-comp d-flex justify-content-center align-items-center infoButton"
-            [ngStyle]="{backgroundColor: tileSrc.darktheme ? 'white': 'black', color: tileSrc.darktheme ? 'black': 'white' }"
-            iav-dataset-show-dataset-dialog
-            [iav-dataset-show-dataset-dialog-name]="originDatainfo.name"
-            [iav-dataset-show-dataset-dialog-description]="originDatainfo.description"
-            [iav-dataset-show-dataset-dialog-urls]="originDatainfo.urls">
-            <small><i class="fas fa-info"></i></small>
-        </div>
-    </ng-container>
-
-</ng-template>
+                    (tile-on-click)="selectParcellationWithName(layer)"
+                    (tile-on-info-click)="kgInfo && kgInfo.onClick()">
+                </tile-cmp>
+
+            </mat-grid-tile>
+
+            <!-- grouped layers -->
+            <mat-grid-tile *ngFor="let groupKeyVal of (atlasLayersLatest$ | async | getNonbaseParc | getGroupedParc | keyvalue); trackBy: trackKeyVal"
+                [attr.aria-checked]="false">
+
+                <!-- prevent click bubbling to document is necessary -->
+                <!-- or else, the outsideclick directive will fire immediately -->
+                <!-- resulting in immediate opening and closing of mat menu -->
+                <tile-cmp [tile-image-src]="groupKeyVal['value'][0] | getPreviewUrlPipe"
+                    class="cursor-pointer pe-all"
+                    tile-image-alt="Preview of this tile"
+                    [tile-text]="groupKeyVal['key']"
+                    [tile-show-info]="false"
+                    [tile-disabled]="!(selectedTemplate$ | async | currentTemplateSupportsParcellation : groupKeyVal['value'])"
+                    [tile-image-darktheme]="groupKeyVal['value'][0].darktheme"
+                    [tile-is-dir]="true"
+                    [matMenuTriggerFor]=layerGroupMenu
+                    [matMenuTriggerData]="{
+                        layerGroupItems: groupKeyVal['value']
+                    }"
+                    [tile-selected]="selectedParcellation$ | async | groupParcSelected : groupKeyVal['value']"
+                    iav-stop="click">
+                </tile-cmp>
+            </mat-grid-tile>
+        </mat-grid-list>
+    </mat-card-content>
+
+    <div [hidden]="!(showLoadingOverlay$ | async)"
+        class="loading-overlay">
+        <spinner-cmp class="spinner"></spinner-cmp>
+    </div>
+</mat-card>
+
+<!-- place holder when not expanded -->
+<div class="position-relative m-2 cursor-pointer scale-up-bl pe-all"
+    quick-tour
+    [quick-tour-description]="quickTourData.description"
+    [quick-tour-order]="quickTourData.order"
+    #atlasSelectorTour="quickTour">
+    <!-- TODO check when do we disable atlas selector -->
+    <button color="primary"
+        *ngIf="true"
+        matTooltip="Select layer"
+        mat-mini-fab
+        [attr.aria-label]="ARIA_LABELS.TOGGLE_ATLAS_LAYER_SELECTOR"
+        (click)="toggleSelector()">
+        <i class="fas fa-layer-group"></i>
+    </button>
+</div>
 
 <!-- mat menu for grouped layer -->
 <mat-menu
     #layerGroupMenu="matMenu"
-    class="layerGroupMenu"
     hasBackdrop="false">
 
     <ng-template matMenuContent let-layerGroupItems="layerGroupItems">
         <mat-grid-list cols="1"
-            rowHeight="1:1"
+            rowHeight="6:7"
+            gutterSize="8"
             iav-stop="click"
             (iav-outsideClick)="collapseExpandedGroup()">
             <mat-grid-tile *ngFor="let layer of layerGroupItems"
-                [attr.aria-checked]="selectedLayersIncludes(layer['@id'])">
+                [attr.aria-checked]="selectedParcellation$ | async | groupParcSelected : layer">
+
+                <div [hidden]
+                    iav-dataset-show-dataset-dialog
+                    [iav-dataset-show-dataset-dialog-name]="layer.originDatainfos[0]?.name"
+                    [iav-dataset-show-dataset-dialog-description]="layer.originDatainfos[0]?.description"
+                    [iav-dataset-show-dataset-dialog-urls]="layer.originDatainfos[0]?.urls"
+                    #kgInfo="iavDatasetShowDatasetDialog">
+                </div>
+
+                <tile-cmp [tile-image-src]="layer | getPreviewUrlPipe"
+                    class="iv-custom-comp text m-3 cursor-pointer pe-all"
+                    tile-image-alt="Preview of this tile"
+                    [tile-text]="layer.displayName || layer.name"
+                    [tile-show-info]="layer.originDatainfos?.length > 0"
+                    [tile-disabled]="!(selectedTemplate$ | async | currentTemplateSupportsParcellation : layer)"
+                    [tile-image-darktheme]="layer.darktheme"
+
+                    [tile-selected]="selectedParcellation$ | async | groupParcSelected : layer"
 
-                <ng-container *ngTemplateOutlet="tileTmpl; context: {
-                    tileSrc: layer,
-                    onClick: getTileTmplClickFnAsCtx(selectParcellationWithName, layer),
-                    selected: selectedLayersIncludes(layer['@id']),
-                    disabled: !currentTemplateIncludesLayer(layer)
-                } ">
+                    (tile-on-click)="selectParcellationWithName(layer)"
+                    (tile-on-info-click)="kgInfo && kgInfo.onClick()">
+                </tile-cmp>
 
-                </ng-container>
             </mat-grid-tile>
         </mat-grid-list>
 
diff --git a/src/atlasComponents/uiSelectors/module.ts b/src/atlasComponents/uiSelectors/module.ts
index d655e9887d960671c3c02ceb798647d7691d67ef..384dc294ca684560a8d8b0cf7f71d85b7fb488f4 100644
--- a/src/atlasComponents/uiSelectors/module.ts
+++ b/src/atlasComponents/uiSelectors/module.ts
@@ -3,9 +3,20 @@ import { NgModule } from "@angular/core";
 import { AngularMaterialModule } from "src/sharedModules";
 import { UtilModule } from "src/util";
 import { AtlasDropdownSelector } from "./atlasDropdown/atlasDropdown.component";
-import { AtlasLayerSelector, GetPreviewUrlPipe } from "./atlasLayerSelector/atlasLayerSelector.component";
+import { AtlasLayerSelector } from "./atlasLayerSelector/atlasLayerSelector.component";
 import {QuickTourModule} from "src/ui/quickTour/module";
 import { KgDatasetModule } from "../regionalFeatures/bsFeatures/kgDataset";
+import { AtlaslayerTooltipPipe } from "./pipes/atlasLayerTooltip.pipe";
+import { ComponentsModule } from "src/components";
+import { GetNonbaseParcPipe } from "./pipes/getNonBaseParc.pipe";
+import { GetIndividualParcPipe } from "./pipes/getIndividualParc.pipe";
+import { getGroupedParcPipe } from "./pipes/getGroupedParc.pipe";
+import { CurrentTmplSupportsParcPipe } from "./pipes/currTmplSupportsParc.pipe";
+import { GroupParcSelectedPipe } from "./pipes/groupParcSelected.pipe";
+import { GetPreviewUrlPipe } from "./pipes/getPreviewUrl.pipe";
+import { CurrParcSupportsTmplPipe } from "./pipes/currParcSupportsTmpl.pipe";
+import { AtlasCmpParcellationModule } from "../parcellation";
+import { SiibraExplorerTemplateModule } from "../template";
 
 @NgModule({
   imports: [
@@ -14,11 +25,21 @@ import { KgDatasetModule } from "../regionalFeatures/bsFeatures/kgDataset";
     UtilModule,
     QuickTourModule,
     KgDatasetModule,
+    ComponentsModule,
+    AtlasCmpParcellationModule,
+    SiibraExplorerTemplateModule,
   ],
   declarations: [
     AtlasDropdownSelector,
     AtlasLayerSelector,
     GetPreviewUrlPipe,
+    AtlaslayerTooltipPipe,
+    GetNonbaseParcPipe,
+    GetIndividualParcPipe,
+    getGroupedParcPipe,
+    CurrentTmplSupportsParcPipe,
+    GroupParcSelectedPipe,
+    CurrParcSupportsTmplPipe,
   ],
   exports: [
     AtlasDropdownSelector,
diff --git a/src/atlasComponents/uiSelectors/pipes/atlasLayerTooltip.pipe.ts b/src/atlasComponents/uiSelectors/pipes/atlasLayerTooltip.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..285f134543afa5151de4627fe2f507515e5f81de
--- /dev/null
+++ b/src/atlasComponents/uiSelectors/pipes/atlasLayerTooltip.pipe.ts
@@ -0,0 +1,12 @@
+import { Pipe, PipeTransform } from "@angular/core";
+
+@Pipe({
+  name: 'atlasLayerTooltip',
+  pure: true
+})
+
+export class AtlaslayerTooltipPipe implements PipeTransform{
+  public transform(layer: any){
+    return layer.name
+  }
+}
diff --git a/src/atlasComponents/uiSelectors/pipes/currParcSupportsTmpl.pipe.ts b/src/atlasComponents/uiSelectors/pipes/currParcSupportsTmpl.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..77fd66327ee0a4fa5bd004d46474d9ff5a95fb0a
--- /dev/null
+++ b/src/atlasComponents/uiSelectors/pipes/currParcSupportsTmpl.pipe.ts
@@ -0,0 +1,20 @@
+import { Pipe, PipeTransform } from "@angular/core";
+
+@Pipe({
+  name: 'currParcSupportsTmpl',
+  pure: true
+})
+
+export class CurrParcSupportsTmplPipe implements PipeTransform{
+  public transform(parc: any, tmpl: any){
+    /**
+     * TODO
+     * buggy. says julich brain v290 is not supported in fsaverage
+     * related to https://github.com/FZJ-INM1-BDA/siibra-python/issues/98 
+     */
+    const parcSupportTmpl = (p: any) => !!(tmpl.availableIn || []).find(tmplP => tmplP['@id'] === p['@id'])
+    return Array.isArray(parc)
+      ? parc.some(parcSupportTmpl)
+      : parcSupportTmpl(parc)
+  }
+}
diff --git a/src/atlasComponents/uiSelectors/pipes/currTmplSupportsParc.pipe.ts b/src/atlasComponents/uiSelectors/pipes/currTmplSupportsParc.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6d1ed06bd92acea21148e64bc6815c5d4345aa73
--- /dev/null
+++ b/src/atlasComponents/uiSelectors/pipes/currTmplSupportsParc.pipe.ts
@@ -0,0 +1,15 @@
+import { Pipe, PipeTransform } from "@angular/core";
+
+@Pipe({
+  name: 'currentTemplateSupportsParcellation',
+  pure: true
+})
+
+export class CurrentTmplSupportsParcPipe implements PipeTransform{
+  public transform(tmpl: any, parc: any): boolean {
+    const testParc = (p: any) => !!(p?.availableIn || []).find((availTmpl: any) => availTmpl['@id'] === tmpl['@id'])
+    return Array.isArray(parc)
+      ? parc.some(testParc)
+      : testParc(parc)
+  }
+}
diff --git a/src/atlasComponents/uiSelectors/pipes/getGroupedParc.pipe.ts b/src/atlasComponents/uiSelectors/pipes/getGroupedParc.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..683d9d7904e588d64d734118723b60f577f20b7b
--- /dev/null
+++ b/src/atlasComponents/uiSelectors/pipes/getGroupedParc.pipe.ts
@@ -0,0 +1,22 @@
+import { Pipe, PipeTransform } from "@angular/core";
+
+type TReturn = {
+  [key: string]: any[]
+}
+
+@Pipe({
+  name: 'getGroupedParc',
+  pure: true
+})
+export class getGroupedParcPipe implements PipeTransform{
+
+  public transform(arr: any[]):TReturn{
+    const returnObj: TReturn = {}
+    const filteredArr = arr.filter(p => p['groupName'])
+    for (const obj of filteredArr) {
+      const groupName: string = obj['groupName']
+      returnObj[groupName] = (returnObj[groupName] || []).concat(obj)
+    }
+    return returnObj
+  }
+}
diff --git a/src/atlasComponents/uiSelectors/pipes/getIndividualParc.pipe.ts b/src/atlasComponents/uiSelectors/pipes/getIndividualParc.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..1e7b155b258819a4490ed41083aa0f55f6051ee4
--- /dev/null
+++ b/src/atlasComponents/uiSelectors/pipes/getIndividualParc.pipe.ts
@@ -0,0 +1,12 @@
+import { Pipe, PipeTransform } from "@angular/core";
+
+@Pipe({
+  name: 'getIndividualParc',
+  pure: true
+})
+export class GetIndividualParcPipe implements PipeTransform{
+
+  public transform(arr: any[]){
+    return arr.filter(p => !p['groupName'])
+  }
+}
diff --git a/src/atlasComponents/uiSelectors/pipes/getNonBaseParc.pipe.ts b/src/atlasComponents/uiSelectors/pipes/getNonBaseParc.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..e0b7997bfa191ee6e790fc935a541e7c8d9a5bb1
--- /dev/null
+++ b/src/atlasComponents/uiSelectors/pipes/getNonBaseParc.pipe.ts
@@ -0,0 +1,12 @@
+import { Pipe, PipeTransform } from "@angular/core";
+
+@Pipe({
+  name: 'getNonbaseParc',
+  pure: true
+})
+export class GetNonbaseParcPipe implements PipeTransform{
+
+  public transform(arr: any[]){
+    return arr.filter(p => !p['baseLayer'])
+  }
+}
diff --git a/src/atlasComponents/uiSelectors/pipes/getPreviewUrl.pipe.ts b/src/atlasComponents/uiSelectors/pipes/getPreviewUrl.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7826f44e267119a0cab9c848f0dd368280629b95
--- /dev/null
+++ b/src/atlasComponents/uiSelectors/pipes/getPreviewUrl.pipe.ts
@@ -0,0 +1,18 @@
+import { Pipe, PipeTransform } from "@angular/core";
+import { GetParcPreviewUrlPipe } from "src/atlasComponents/parcellation";
+import { GetTemplatePreviewUrlPipe } from "src/atlasComponents/template";
+
+const templateUrlPipe = new GetTemplatePreviewUrlPipe()
+const parcUrlPipe = new GetParcPreviewUrlPipe()
+
+@Pipe({
+  name: 'getPreviewUrlPipe',
+  pure: true
+})
+
+export class GetPreviewUrlPipe implements PipeTransform{
+  public transform(tile: any){
+    const filename = templateUrlPipe.transform(tile) || parcUrlPipe.transform(tile)
+    return filename
+  }
+}
diff --git a/src/atlasComponents/uiSelectors/pipes/groupParcSelected.pipe.ts b/src/atlasComponents/uiSelectors/pipes/groupParcSelected.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6beb302be626272f72e62f23b722ce1ce7411015
--- /dev/null
+++ b/src/atlasComponents/uiSelectors/pipes/groupParcSelected.pipe.ts
@@ -0,0 +1,15 @@
+import { Pipe, PipeTransform } from "@angular/core";
+
+@Pipe({
+  name: 'groupParcSelected',
+  pure: true
+})
+
+export class GroupParcSelectedPipe implements PipeTransform{
+  public transform(selectedParc: any, parc: any){
+    const isSelected = (p: any) => p['@id'] === selectedParc['@id']
+    return Array.isArray(parc)
+      ? parc.some(isSelected)
+      : isSelected(parc)
+  }
+}
diff --git a/src/atlasComponents/userAnnotations/tools/line.ts b/src/atlasComponents/userAnnotations/tools/line.ts
index bea53cdf42b49e494e9f3419813f4b9178dc3b99..3d01d57dc41678c9958d1c52b41e734fce28ae28 100644
--- a/src/atlasComponents/userAnnotations/tools/line.ts
+++ b/src/atlasComponents/userAnnotations/tools/line.ts
@@ -12,7 +12,7 @@ import {
   TCallbackFunction,
 } from "./type";
 import { Point, TPointJsonSpec } from './point'
-import { Directive, Injectable, OnDestroy } from "@angular/core";
+import { Directive, OnDestroy } from "@angular/core";
 import { Observable, Subject, Subscription } from "rxjs";
 import { filter, switchMapTo, takeUntil } from "rxjs/operators";
 import { getUuid } from "src/util/fn";
@@ -24,6 +24,7 @@ export type TLineJsonSpec = {
 
 export class Line extends IAnnotationGeometry{
   public id: string
+  public annotationType = 'Line'
 
   public points: Point[] = []
 
diff --git a/src/atlasComponents/userAnnotations/tools/point.ts b/src/atlasComponents/userAnnotations/tools/point.ts
index 1db473a6713ed78b82c0d12c4a34acf65f13bb84..f69baf0e4045e8300de93c42a086b57ceee7292e 100644
--- a/src/atlasComponents/userAnnotations/tools/point.ts
+++ b/src/atlasComponents/userAnnotations/tools/point.ts
@@ -16,6 +16,7 @@ export class Point extends IAnnotationGeometry {
   y: number
   z: number
 
+  public annotationType = 'Point'
   static threshold = 1e-6
   static eql(p1: Point, p2: Point) {
     return Math.abs(p1.x - p2.x) < Point.threshold
diff --git a/src/atlasComponents/userAnnotations/tools/poly.ts b/src/atlasComponents/userAnnotations/tools/poly.ts
index b7929b5dfe77e378ae6a52c2f5c67d5333547025..47dd27c7dc56924a1be4911045523577e7e9d1ad 100644
--- a/src/atlasComponents/userAnnotations/tools/poly.ts
+++ b/src/atlasComponents/userAnnotations/tools/poly.ts
@@ -13,6 +13,7 @@ export type TPolyJsonSpec = {
 
 export class Polygon extends IAnnotationGeometry{
   public id: string
+  public annotationType = 'Polygon'
 
   public points: Point[] = []
   public edges: [number, number][] = []
diff --git a/src/atlasComponents/userAnnotations/tools/service.ts b/src/atlasComponents/userAnnotations/tools/service.ts
index 196d77ec0563fa57183f10fb2c7d865e462f6d00..dccdc60427a025b8c0e9fc974e03bc6e23f959ee 100644
--- a/src/atlasComponents/userAnnotations/tools/service.ts
+++ b/src/atlasComponents/userAnnotations/tools/service.ts
@@ -3,7 +3,7 @@ import { ARIA_LABELS } from 'common/constants'
 import { Inject, Optional } from "@angular/core";
 import { select, Store } from "@ngrx/store";
 import { BehaviorSubject, combineLatest, fromEvent, merge, Observable, of, Subject, Subscription } from "rxjs";
-import { map, switchMap, filter, shareReplay, pairwise } from "rxjs/operators";
+import {map, switchMap, filter, shareReplay, pairwise } from "rxjs/operators";
 import { viewerStateSelectedTemplatePureSelector, viewerStateViewerModeSelector } from "src/services/state/viewerState/selectors";
 import { NehubaViewerUnit } from "src/viewerModule/nehuba";
 import { NEHUBA_INSTANCE_INJTKN } from "src/viewerModule/nehuba/util";
@@ -135,6 +135,18 @@ export class ModularUserAnnotationToolService implements OnDestroy{
     map(mann => mann.length > 0 ? mann.length : null)
   )
 
+  public hoveringAnnotations$ = this.annotnEvSubj.pipe(
+    filter<TAnnotationEvent<'hoverAnnotation'>>(ev => ev.type === 'hoverAnnotation'),
+    map(ev => {
+      if (!(ev?.detail)) return null
+      const { pickedAnnotationId } = ev.detail
+      const annId = (pickedAnnotationId || '').split('_')[0]
+      const foundAnn = this.managedAnnotations.find(ann => ann.id === annId)
+      if (!foundAnn) return null
+      return foundAnn
+    })
+  )
+
   private registeredTools: {
     name: string
     iconClass: string
@@ -467,6 +479,7 @@ export class ModularUserAnnotationToolService implements OnDestroy{
             this.deleteNgAnnotationById(annotation.id)
             continue
           }
+          if (!this.ngAnnotationLayer) continue
           const localAnnotations = this.ngAnnotationLayer.layer.localAnnotations
           const annRef = localAnnotations.references.get(annotation.id)
           const annSpec = parseNgAnnotation(annotation)
diff --git a/src/atlasComponents/userAnnotations/tools/type.spec.ts b/src/atlasComponents/userAnnotations/tools/type.spec.ts
index f4b28738913465c7eda8ee898f28fdc724dbf016..599f20eabb8289dc975b501c876418df055e7d57 100644
--- a/src/atlasComponents/userAnnotations/tools/type.spec.ts
+++ b/src/atlasComponents/userAnnotations/tools/type.spec.ts
@@ -2,6 +2,7 @@ import { Subject, Subscription } from "rxjs"
 import { AbsToolClass, IAnnotationEvents, IAnnotationGeometry, TAnnotationEvent } from "./type"
 
 class TmpCls extends IAnnotationGeometry{
+  annotationType: 'tmpl-cls'
   getNgAnnotationIds(){
     return []
   }
@@ -110,6 +111,7 @@ describe('> types.ts', () => {
 
     describe('> updateSignal$', () => {
       class TmpCls extends IAnnotationGeometry{
+        annotationType = 'tmp-cls'
         getNgAnnotationIds(){
           return []
         }
diff --git a/src/atlasComponents/userAnnotations/tools/type.ts b/src/atlasComponents/userAnnotations/tools/type.ts
index 85a4c2e0f6783a024017a34fc0b50588a89ccfcd..8e33221b9bdf575fd3e2a196711236dce78b6d3b 100644
--- a/src/atlasComponents/userAnnotations/tools/type.ts
+++ b/src/atlasComponents/userAnnotations/tools/type.ts
@@ -313,6 +313,7 @@ export abstract class IAnnotationGeometry extends Highlightable {
 
   public space: TBaseAnnotationGeomtrySpec['space']
 
+  abstract annotationType: string
   abstract getNgAnnotationIds(): string[]
   abstract toNgAnnotation(): INgAnnotationTypes[keyof INgAnnotationTypes][]
   abstract toJSON(): TRecord
diff --git a/src/atlasViewer/atlasViewer.apiService.service.ts b/src/atlasViewer/atlasViewer.apiService.service.ts
index 9ee73c58689f765e94e54829a1b9138e43f38f86..ad6d2fb7e7057784edadb8b227f015f4e83f74ac 100644
--- a/src/atlasViewer/atlasViewer.apiService.service.ts
+++ b/src/atlasViewer/atlasViewer.apiService.service.ts
@@ -455,7 +455,7 @@ export interface IVIewerHandle {
   mouseEvent: Observable<{eventName: string, event: MouseEvent}>
   mouseOverNehuba: Observable<{labelIndex: number, foundRegion: any | null}>
   mouseOverNehubaLayers: Observable<Array<{layer: {name: string}, segment: any | number }>>
-  mouseOverNehubaUI: Observable<{ segments: any, landmark: any, customLandmark: any }>
+  mouseOverNehubaUI: Observable<{ annotation: any, segments: any, landmark: any, customLandmark: any }>
   getNgHash: () => string
 }
 
diff --git a/src/atlasViewer/atlasViewer.component.ts b/src/atlasViewer/atlasViewer.component.ts
index f866c771f21c42422f72bc7c32a9c9938146d7de..f407f68944dad36fb049901fcc59e9e91fc77f47 100644
--- a/src/atlasViewer/atlasViewer.component.ts
+++ b/src/atlasViewer/atlasViewer.component.ts
@@ -8,10 +8,11 @@ import {
   TemplateRef,
   ViewChild,
   ElementRef,
+  Inject,
 } from "@angular/core";
-import { Store, select, ActionsSubject } from "@ngrx/store";
-import { Observable, Subscription, interval, merge, of, timer, fromEvent } from "rxjs";
-import { map, filter, distinctUntilChanged, delay, withLatestFrom, switchMapTo, take, startWith } from "rxjs/operators";
+import { Store, select } from "@ngrx/store";
+import { Observable, Subscription, merge, timer, fromEvent } from "rxjs";
+import { map, filter, distinctUntilChanged, delay, switchMapTo, take, startWith } from "rxjs/operators";
 
 import {
   IavRootStoreInterface,
@@ -21,8 +22,7 @@ import {
 import { WidgetServices } from "src/widget";
 
 import { LocalFileService } from "src/services/localFile.service";
-import { AGREE_COOKIE, AGREE_KG_TOS } from "src/services/state/uiState.store";
-import { SHOW_KG_TOS } from 'src/services/state/uiState.store.helper'
+import { AGREE_COOKIE } from "src/services/state/uiState.store";
 import { isSame } from "src/util/fn";
 import { colorAnimation } from "./atlasViewer.animation"
 import { MouseHoverDirective } from "src/mouseoverModule";
@@ -34,6 +34,7 @@ import { SlServiceService } from "src/spotlight/sl-service.service";
 import { PureContantService } from "src/util";
 import { ClickInterceptorService } from "src/glue";
 import { environment } from 'src/environments/environment'
+import { DOCUMENT } from "@angular/common";
 
 /**
  * TODO
@@ -61,8 +62,6 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
 
   @ViewChild('cookieAgreementComponent', {read: TemplateRef}) public cookieAgreementComponent: TemplateRef<any>
 
-  @ViewChild('kgToS', {read: TemplateRef}) public kgTosComponent: TemplateRef<any>
-
   @ViewChild(MouseHoverDirective) private mouseOverNehuba: MouseHoverDirective
 
   @ViewChild('idleOverlay', {read: TemplateRef}) idelTmpl: TemplateRef<any>
@@ -85,20 +84,19 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
   public selectedParcellation: any
 
   private cookieDialogRef: MatDialogRef<any>
-  private kgTosDialogRef: MatDialogRef<any>
 
   constructor(
     private store: Store<IavRootStoreInterface>,
     private widgetServices: WidgetServices,
     private pureConstantService: PureContantService,
     private matDialog: MatDialog,
-    private dispatcher$: ActionsSubject,
     private rd: Renderer2,
     public localFileService: LocalFileService,
     private snackbar: MatSnackBar,
     private el: ElementRef,
     private slService: SlServiceService,
-    private clickIntService: ClickInterceptorService
+    private clickIntService: ClickInterceptorService,
+    @Inject(DOCUMENT) private document,
   ) {
 
     this.snackbarMessage$ = this.store.pipe(
@@ -147,7 +145,7 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
 
       this.subscriptions.push(
         merge(
-          fromEvent(window.document, 'mouseup'),
+          fromEvent(this.document, 'mouseup'),
           this.slService.onClick
         ).pipe(
           startWith(true),
@@ -196,7 +194,7 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
 
     this.subscriptions.push(
       this.pureConstantService.darktheme$.subscribe(flag => {
-        this.rd.setAttribute(document.body, 'darktheme', this.meetsRequirement && flag.toString())
+        this.rd.setAttribute(this.document.body, 'darktheme', this.meetsRequirement && flag.toString())
       }),
     )
   }
@@ -212,13 +210,9 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
       prefecthMainBundle.rel = 'preload'
       prefecthMainBundle.as = 'script'
       prefecthMainBundle.href = 'main.bundle.js'
-      this.rd.appendChild(document.head, prefecthMainBundle)
+      this.rd.appendChild(this.document.head, prefecthMainBundle)
     }
 
-    // this.onhoverLandmark$ = this.mouseOverNehuba.currentOnHoverObs$.pipe(
-    //   select('landmark')
-    // )
-
     /**
      * Show Cookie disclaimer if not yet agreed
      */
@@ -234,18 +228,6 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
       this.cookieDialogRef = this.matDialog.open(this.cookieAgreementComponent)
     })
 
-    this.dispatcher$.pipe(
-      filter(({type}) => type === SHOW_KG_TOS),
-      withLatestFrom(this.store.pipe(
-        select('uiState'),
-        select('agreedKgTos'),
-      )),
-      map(([_, agreed]) => agreed),
-      filter(flag => !flag),
-      delay(0),
-    ).subscribe(() => {
-      this.kgTosDialogRef = this.matDialog.open(this.kgTosComponent)
-    })
   }
 
   /**
@@ -264,7 +246,7 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
    */
   public meetsRequirements(): boolean {
 
-    const canvas = document.createElement('canvas')
+    const canvas = this.document.createElement('canvas')
     const gl = canvas.getContext('webgl2') as WebGLRenderingContext
 
     if (!gl) {
@@ -280,13 +262,6 @@ export class AtlasViewer implements OnDestroy, OnInit, AfterViewInit {
     return true
   }
 
-  public kgTosClickedOk() {
-    if (this.kgTosDialogRef) { this.kgTosDialogRef.close() }
-    this.store.dispatch({
-      type: AGREE_KG_TOS,
-    })
-  }
-
   public cookieClickedOk() {
     if (this.cookieDialogRef) { this.cookieDialogRef.close() }
     this.store.dispatch({
diff --git a/src/atlasViewer/atlasViewer.style.css b/src/atlasViewer/atlasViewer.style.css
index c6c87ac87da646244f55ce6654b404763ee369c8..0f938ac6632a634a35ee793318a408c0e70248fd 100644
--- a/src/atlasViewer/atlasViewer.style.css
+++ b/src/atlasViewer/atlasViewer.style.css
@@ -34,17 +34,13 @@ layout-floating-container > *
   top: 0;
 }
 
-[signinWrapper]
-{
-  margin: 0.8em 0.4em;
-}
-
-[contextualBlock]
+mat-list[dense].contextual-block
 {
+  display: inline-block;
   background-color:rgba(200,200,200,0.8);
 }
 
-:host-context([darktheme="true"]) [contextualBlock]
+:host-context([darktheme="true"]) mat-list[dense].contextual-block
 {
   background-color : rgba(30,30,30,0.8);
 }
diff --git a/src/atlasViewer/atlasViewer.template.html b/src/atlasViewer/atlasViewer.template.html
index fbaa8bf4c5dee3f37516c8d928c4c1a008897130..5549a8e38914948e7157fcfc6cde6a4f63bd9153 100644
--- a/src/atlasViewer/atlasViewer.template.html
+++ b/src/atlasViewer/atlasViewer.template.html
@@ -1,26 +1,14 @@
+
+<!-- required for manufacturing plugin templates -->
+<div pluginFactoryDirective>
+</div>
+
 <ng-container *ngIf="meetsRequirement; else doesNotMeetReqTemplate">
 
   <ng-container *ngTemplateOutlet="viewerBody">
   </ng-container>
 </ng-container>
 
-<!-- kg tos -->
-<ng-template #kgToS>
-  <h2 mat-dialog-title>Knowledge Graph ToS</h2>
-  <mat-dialog-content>
-    <small>
-      <kgtos-component>
-      </kgtos-component>
-    </small>
-  </mat-dialog-content>
-
-  <mat-dialog-actions class="justify-content-end">
-    <button color="primary" mat-raised-button (click)="kgTosClickedOk()" cdkFocusInitial>
-      Ok
-    </button>
-  </mat-dialog-actions>
-</ng-template>
-
 <!-- cookie -->
 <ng-template #cookieAgreementComponent>
   <h2 mat-dialog-title>Privacy Policy</h2>
@@ -40,7 +28,7 @@
 
 <!-- atlas template -->
 <ng-template #viewerBody>
-  <div class="atlas-container w-100 h-100"
+  <div class="w-100 h-100"
     iav-media-query
     quick-tour
     [quick-tour-position]="quickTourFinale.position"
@@ -65,41 +53,33 @@
       <div floatingContainerDirective>
       </div>
 
-      <div
-        *ngIf="(media.mediaBreakPoint$ | async) < 3"
+      <div *ngIf="(media.mediaBreakPoint$ | async) < 3"
         class="fixed-bottom pe-none mb-2 d-flex justify-content-center">
         <ng-container *ngTemplateOutlet="logoTmpl">
         </ng-container>
       </div>
 
-      <div floatingMouseContextualContainerDirective>
+      <div *ngIf="!ismobile" floatingMouseContextualContainerDirective>
 
-        <div *ngIf="!ismobile"
-          class="d-inline-block"
+        <div class="h-0"
           iav-mouse-hover
-          #iavMouseHoverContextualBlock="iavMouseHover"
-          contextualBlock>
-
-          <ng-container
-            *ngFor="let labelText of iavMouseHoverContextualBlock.currentOnHoverObs$ | async | mouseOverTextPipe">
-
-            <mat-list dense>
-
-              <mat-list-item class="h-auto">
+          #iavMouseHoverContextualBlock="iavMouseHover">
+        </div>
+        <mat-list dense class="contextual-block">
 
-                <mat-icon
-                  [fontSet]="(labelText.label | mouseOverIconPipe).fontSet"
-                  [fontIcon]="(labelText.label | mouseOverIconPipe).fontIcon"
-                  mat-list-icon>
+          <mat-list-item *ngFor="let cvtOutput of iavMouseHoverContextualBlock.currentOnHoverObs$ | async | mouseoverCvt"
+            class="h-auto">
 
-                </mat-icon>
+            <mat-icon
+              [fontSet]="cvtOutput.icon.fontSet"
+              [fontIcon]="cvtOutput.icon.fontIcon"
+              mat-list-icon>
+            </mat-icon>
 
-                <div matLine *ngFor="let text of labelText.text" [innerHTML]="text"></div>
+            <div matLine>{{ cvtOutput.text }}</div>
 
-              </mat-list-item>
-            </mat-list>
-          </ng-container>
-        </div>
+          </mat-list-item>
+        </mat-list>
         <!-- TODO Potentially implementing plugin contextual info -->
       </div>
 
@@ -113,10 +93,6 @@
       </div>
 
     </layout-floating-container>
-
-    <!-- required for manufacturing plugin templates -->
-    <div pluginFactoryDirective>
-    </div>
   </div>
 </ng-template>
 
diff --git a/src/components/components.module.ts b/src/components/components.module.ts
index 1eafa1a3db4056567b6d554b6dbc1ffa65e89355..c8d9ff210b5530a6e001dcd983a3fb8487c560cf 100644
--- a/src/components/components.module.ts
+++ b/src/components/components.module.ts
@@ -25,6 +25,7 @@ import { IAVVerticalButton } from './vButton/vButton.component';
 import { DynamicMaterialBtn } from './dynamicMaterialBtn/dynamicMaterialBtn.component';
 import { SpinnerCmp } from './spinner/spinner.component';
 import { ReadmoreModule } from './readmore';
+import { TileCmp } from './tile/tile.component';
 
 @NgModule({
   imports : [
@@ -46,6 +47,7 @@ import { ReadmoreModule } from './readmore';
     IAVVerticalButton,
     DynamicMaterialBtn,
     SpinnerCmp,
+    TileCmp,
 
     /* directive */
     TreeBaseDirective,
@@ -72,6 +74,7 @@ import { ReadmoreModule } from './readmore';
     IAVVerticalButton,
     DynamicMaterialBtn,
     SpinnerCmp,
+    TileCmp,
 
     TreeSearchPipe,
     TreeBaseDirective,
diff --git a/src/components/markdown/markdown.component.ts b/src/components/markdown/markdown.component.ts
index e48f409c0cbd604c5be32c424a491552cedaa0a5..bd5ea00320923c15e4517232021822b91fd8e630 100644
--- a/src/components/markdown/markdown.component.ts
+++ b/src/components/markdown/markdown.component.ts
@@ -1,4 +1,4 @@
-import { ChangeDetectionStrategy, Component, ElementRef, Input, ViewChild, ChangeDetectorRef, AfterViewChecked } from '@angular/core'
+import { ChangeDetectionStrategy, Component, ElementRef, Input, ViewChild, ChangeDetectorRef, AfterViewChecked, OnChanges } from '@angular/core'
 import * as showdown from 'showdown'
 
 @Component({
@@ -10,7 +10,7 @@ import * as showdown from 'showdown'
   changeDetection : ChangeDetectionStrategy.OnPush,
 })
 
-export class MarkdownDom implements AfterViewChecked {
+export class MarkdownDom implements OnChanges {
 
   @Input() public markdown: string = ``
   public innerHtml: string = ``
@@ -21,6 +21,7 @@ export class MarkdownDom implements AfterViewChecked {
   constructor(
     private cdr: ChangeDetectorRef
   ) {
+    this.cdr.detach()
     this.converter.setFlavor('github')
   }
 
@@ -30,7 +31,7 @@ export class MarkdownDom implements AfterViewChecked {
     return ''
   }
 
-  public ngAfterViewChecked(){
+  ngOnChanges(){
     this.innerHtml = this.converter.makeHtml(
       this.getMarkdown()
     )
diff --git a/src/components/tile/tile.component.ts b/src/components/tile/tile.component.ts
new file mode 100644
index 0000000000000000000000000000000000000000..fcab669508d12e06852675c41e7a20e38bc72843
--- /dev/null
+++ b/src/components/tile/tile.component.ts
@@ -0,0 +1,55 @@
+import { Component, EventEmitter, HostBinding, HostListener, Input, OnChanges, Output } from "@angular/core";
+
+@Component({
+  selector: 'tile-cmp',
+  templateUrl: './tile.template.html',
+  styleUrls: [
+    './tile.style.css'
+  ],
+  exportAs: 'tileCmp'
+})
+
+export class TileCmp implements OnChanges{
+  @Input('tile-image-src')
+  tileImgSrc: string
+
+  @Input('tile-image-alt')
+  tileImgAlt: string = 'Thumbnail of this tile.'
+
+  @Input('tile-text')
+  tileText: string = 'Tile'
+
+  @Input('tile-show-info')
+  tileShowInfo: boolean = false
+
+  @Input('tile-disabled')
+  tileDisabled: boolean = false
+
+  @Input('tile-image-darktheme')
+  darktheme: boolean = false
+
+  @Input('tile-selected')
+  selected: boolean = false
+
+  @Output('tile-on-click')
+  onClick: EventEmitter<MouseEvent> = new EventEmitter()
+
+  @Input('tile-is-dir')
+  isDir: boolean = false
+
+  @Output('tile-on-info-click')
+  onInfoClick: EventEmitter<MouseEvent> = new EventEmitter()
+
+  @HostBinding('class')
+  hostBindingClass = ''
+
+  @HostListener('click', ['$event'])
+  protected _onClick(event: MouseEvent) {
+    this.onClick.emit(event)
+  }
+
+  ngOnChanges(){
+    if (this.tileDisabled) this.hostBindingClass = 'muted'
+    else this.hostBindingClass = ''
+  }
+}
diff --git a/src/components/tile/tile.style.css b/src/components/tile/tile.style.css
new file mode 100644
index 0000000000000000000000000000000000000000..e877c720820a2a9b6fbf6a0d988fad5b90385054
--- /dev/null
+++ b/src/components/tile/tile.style.css
@@ -0,0 +1,39 @@
+.info-button {
+  height: 20px;
+  width: 20px;
+  margin-top: 10px;
+  margin-right: 12px;
+  border-radius: 50%;
+  text-align: center;
+}
+
+.tile-selected {
+  border: 2px solid #FED363;
+}
+
+:host,
+img
+{
+  display: block;
+  width: 100%;
+  height: 100%;
+}
+
+img
+{
+  border-radius: 10px;
+}
+
+.tile-text
+{
+  margin-top: 0.5rem;
+  text-align: center;
+  white-space: normal;
+  font-size: 80%;
+}
+
+.folder-container
+{
+    margin-right:0.5rem;
+    margin-bottom:-0.5rem;
+}
diff --git a/src/components/tile/tile.template.html b/src/components/tile/tile.template.html
new file mode 100644
index 0000000000000000000000000000000000000000..44cc134d2a135d88ad24d04c1631cb68ed827b5e
--- /dev/null
+++ b/src/components/tile/tile.template.html
@@ -0,0 +1,35 @@
+<div class="position-relative">
+  <!-- info icon -->
+  <div *ngIf="tileShowInfo"
+    class="position-absolute right-0">
+    <div mat-icon-button
+      iav-stop="click"
+      (click)="onInfoClick.emit($event)"
+      [ngStyle]="{
+        backgroundColor: darktheme ? 'white' : 'black',
+        color: darktheme ? 'black': 'white'
+      }"
+      class="mat-elevation-z2 iv-custom-comp info-button">
+      <small>
+        <i class="fas fa-info"></i>
+      </small>
+    </div>
+  </div>
+
+
+  <!-- directory icon -->
+  <div *ngIf="isDir" class="position-absolute bottom-0 right-0">
+    <i class="fas fa-folder folder-container fa-2x"></i>
+  </div>
+
+  <img [src]="tileImgSrc"
+    [alt]="tileImgAlt"
+    [ngClass]="{
+      'tile-selected': selected
+    }"
+    draggable="false">
+</div>
+
+<div class="tile-text">
+  {{ tileText }}
+</div>
diff --git a/src/extra_styles.css b/src/extra_styles.css
index ae2f870b0e9158e1b3032959d203fca162c9c4bd..928bcf43c3700cef7c1b006cc7b85ae1bedda609 100644
--- a/src/extra_styles.css
+++ b/src/extra_styles.css
@@ -320,6 +320,11 @@ markdown-dom p
   width: 20em!important;
 }
 
+.w-100vw
+{
+  width: 100vw!important;
+}
+
 .mw-100
 {
   max-width: 100%!important;
@@ -758,6 +763,16 @@ kg-dataset-previewer > img
   opacity: 1.0;
 }
 
+.m-15
+{
+  margin: 15px;
+}
+
+.m-1px
+{
+  margin:1px;
+}
+
 .ml-15px-n
 {
   margin-left: -15px!important;
@@ -805,6 +820,10 @@ kg-dataset-previewer > img
 {
   margin-top: -1rem!important;
 }
+.mt-1-n
+{
+  margin-top: -0.5rem!important;
+}
 
 .mb-6
 {
@@ -828,11 +847,6 @@ kg-dataset-previewer > img
   bottom: unset!important;
 }
 
-.layerGroupMenu > .mat-menu-content
-{
-  width: 100%;
-}
-
 mat-list.sm mat-list-item
 {
   height:2rem!important;
@@ -886,3 +900,8 @@ mat-list.sm mat-list-item
   margin-top: auto;
   margin-bottom: auto;
 }
+
+.v-align-top
+{
+  vertical-align: top;
+}
\ No newline at end of file
diff --git a/src/index.html b/src/index.html
index 5701618243131618751f45ef96644368a9baf333..8fd23a5d9027b1514df06dc820b766c9b0027af7 100644
--- a/src/index.html
+++ b/src/index.html
@@ -11,11 +11,14 @@
   <link rel="stylesheet" href="main.css">
   <link rel="stylesheet" href="version.css">
   <link rel="icon" type="image/png" href="res/favicons/favicon-128-light.png"/>
-  
+  <script>
+    // disable zone patching of raf. This hampers NG performance significantly
+    window['__Zone_disable_requestAnimationFrame'] = true
+  </script>
   <script src="https://unpkg.com/kg-dataset-previewer@1.2.0/dist/kg-dataset-previewer/kg-dataset-previewer.js" defer>
   </script>
   <script src="https://unpkg.com/three-surfer@0.0.10/dist/bundle.js" defer></script>
-  <script type="module" src="https://unpkg.com/ng-layer-tune@0.0.2/dist/ng-layer-tune/ng-layer-tune.esm.js"></script>
+  <script type="module" src="https://unpkg.com/ng-layer-tune@0.0.4/dist/ng-layer-tune/ng-layer-tune.esm.js"></script>
   
   <title>Interactive Atlas Viewer</title>
 </head>
diff --git a/src/layouts/currentLayout/currentLayout.component.ts b/src/layouts/currentLayout/currentLayout.component.ts
index 313f1cd93467cb08955bd92f2dc728568427bf62..be31bf00347ec1bee75eba254c3ff866b7ac4304 100644
--- a/src/layouts/currentLayout/currentLayout.component.ts
+++ b/src/layouts/currentLayout/currentLayout.component.ts
@@ -4,7 +4,6 @@ import { Observable } from "rxjs";
 import { startWith } from "rxjs/operators";
 import { SUPPORTED_PANEL_MODES } from "src/services/state/ngViewerState.store";
 import { ngViewerSelectorPanelMode } from "src/services/state/ngViewerState/selectors";
-import { IavRootStoreInterface } from "src/services/stateStore.service";
 
 @Component({
   selector: 'current-layout',
@@ -20,7 +19,7 @@ export class CurrentLayout {
   public panelMode$: Observable<string>
 
   constructor(
-    private store$: Store<IavRootStoreInterface>,
+    private store$: Store<any>,
   ) {
     this.panelMode$ = this.store$.pipe(
       select(ngViewerSelectorPanelMode),
diff --git a/src/layouts/currentLayout/currentLayout.style.css b/src/layouts/currentLayout/currentLayout.style.css
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..a633460dc9cd04a4e563a2a926b4d486cba421d4 100644
--- a/src/layouts/currentLayout/currentLayout.style.css
+++ b/src/layouts/currentLayout/currentLayout.style.css
@@ -0,0 +1,6 @@
+:host
+{
+  width: 100%;
+  height: 100%;
+  display: block;
+}
\ No newline at end of file
diff --git a/src/layouts/currentLayout/currentLayout.template.html b/src/layouts/currentLayout/currentLayout.template.html
index f3d04c104239b9e81f3ff0552c892e86c444ba0d..9575932ed1de52ea23341d6570a48b32225c9160 100644
--- a/src/layouts/currentLayout/currentLayout.template.html
+++ b/src/layouts/currentLayout/currentLayout.template.html
@@ -1,72 +1,72 @@
-<div [ngSwitch]="panelMode$ | async" class="w-100 h-100 d-flex flex-row">
+<ng-container [ngSwitch]="panelMode$ | async">
   <layout-four-panel
     *ngSwitchCase="supportedPanelModes[0]"
     class="d-block w-100 h-100">
-    <div class="w-100 h-100" cell-i>
+    <ng-container cell-i>
       <ng-content *ngTemplateOutlet="celli"></ng-content>
-    </div>
-    <div class="w-100 h-100" cell-ii>
+    </ng-container>
+    <ng-container cell-ii>
       <ng-content *ngTemplateOutlet="cellii"></ng-content>
-    </div>
-    <div class="w-100 h-100" cell-iii>
+    </ng-container>
+    <ng-container cell-iii>
       <ng-content *ngTemplateOutlet="celliii"></ng-content>
-    </div>
-    <div class="w-100 h-100" cell-iv>
+    </ng-container>
+    <ng-container cell-iv>
       <ng-content *ngTemplateOutlet="celliv"></ng-content>
-    </div>
+    </ng-container>
   </layout-four-panel>
   <layout-horizontal-one-three
     *ngSwitchCase="supportedPanelModes[1]"
     class="d-block w-100 h-100">
-    <div class="w-100 h-100" cell-i>
+    <ng-container cell-i>
       <ng-content *ngTemplateOutlet="celli"></ng-content>
-    </div>
-    <div class="w-100 h-100" cell-ii>
+    </ng-container>
+    <ng-container cell-ii>
       <ng-content *ngTemplateOutlet="cellii"></ng-content>
-    </div>
-    <div class="w-100 h-100" cell-iii>
+    </ng-container>
+    <ng-container cell-iii>
       <ng-content *ngTemplateOutlet="celliii"></ng-content>
-    </div>
-    <div class="w-100 h-100" cell-iv>
+    </ng-container>
+    <ng-container cell-iv>
       <ng-content *ngTemplateOutlet="celliv"></ng-content>
-    </div>
+    </ng-container>
   </layout-horizontal-one-three>
   <layout-vertical-one-three
     *ngSwitchCase="supportedPanelModes[2]"
     class="d-block w-100 h-100">
-    <div class="w-100 h-100" cell-i>
+    <ng-container cell-i>
       <ng-content *ngTemplateOutlet="celli"></ng-content>
-    </div>
-    <div class="w-100 h-100" cell-ii>
+    </ng-container>
+    <ng-container cell-ii>
       <ng-content *ngTemplateOutlet="cellii"></ng-content>
-    </div>
-    <div class="w-100 h-100" cell-iii>
+    </ng-container>
+    <ng-container cell-iii>
       <ng-content *ngTemplateOutlet="celliii"></ng-content>
-    </div>
-    <div class="w-100 h-100" cell-iv>
+    </ng-container>
+    <ng-container cell-iv>
       <ng-content *ngTemplateOutlet="celliv"></ng-content>
-    </div>
+    </ng-container>
   </layout-vertical-one-three>
   <layout-single-panel
     *ngSwitchCase="supportedPanelModes[3]"
     class="d-block w-100 h-100">
-    <div class="w-100 h-100" cell-i>
+    <ng-container cell-i>
       <ng-content *ngTemplateOutlet="celli"></ng-content>
-    </div>
-    <div class="w-100 h-100" cell-ii>
+    </ng-container>
+    <ng-container cell-ii>
       <ng-content *ngTemplateOutlet="cellii"></ng-content>
-    </div>
-    <div class="w-100 h-100" cell-iii>
+    </ng-container>
+    <ng-container cell-iii>
       <ng-content *ngTemplateOutlet="celliii"></ng-content>
-    </div>
-    <div class="w-100 h-100" cell-iv>
+    </ng-container>
+    <ng-container cell-iv>
       <ng-content *ngTemplateOutlet="celliv"></ng-content>
-    </div>
+    </ng-container>
   </layout-single-panel>
   <div *ngSwitchDefault>
     A panel mode which I have never seen before ...
   </div>
-</div>
+</ng-container>
 
 <ng-template #celli>
   <ng-content select="[cell-i]"></ng-content>
diff --git a/src/layouts/fourCorners/fourCorners.style.css b/src/layouts/fourCorners/fourCorners.style.css
index 352b490b2acf42d4d92344bdc0be28d4f8cf80da..e81a3cd69216d94cb228f602acf732f72a0dd44b 100644
--- a/src/layouts/fourCorners/fourCorners.style.css
+++ b/src/layouts/fourCorners/fourCorners.style.css
@@ -9,5 +9,33 @@
 
 .corner-container
 {
-  z-index: 5;
-}
\ No newline at end of file
+  max-width: 100%;
+}
+
+.grid-container
+{
+  height: 50%;
+  display: grid;
+  grid-template-columns: minmax(auto, 100%) minmax(auto, 100%);
+}
+
+.top-left
+{
+  place-self: start start;
+  z-index: 2;
+}
+.top-right
+{
+  place-self: start end;
+  z-index: 1;
+}
+.bottom-left
+{
+  place-self: end start;
+  z-index: 2;
+}
+.bottom-right
+{
+  place-self: end end;
+  z-index: 1;
+}
diff --git a/src/layouts/fourCorners/fourCorners.template.html b/src/layouts/fourCorners/fourCorners.template.html
index 96cfe86cdb46e296f4b44fa92adfb377dec010fd..c0e98df279d32db83b96227fa439642ff79175cc 100644
--- a/src/layouts/fourCorners/fourCorners.template.html
+++ b/src/layouts/fourCorners/fourCorners.template.html
@@ -2,19 +2,24 @@
   <ng-content select="[iavLayoutFourCornersContent]"></ng-content>
 </div>
 
-<div [ngClass]="cornerContainerClasses"
-  class="corner-container position-absolute top-0 left-0">
-  <ng-content select="[iavLayoutFourCornersTopLeft]"></ng-content>  
+<div class="grid-container">
+  <div [ngClass]="cornerContainerClasses"
+    class="corner-container top-left">
+    <ng-content select="[iavLayoutFourCornersTopLeft]"></ng-content>  
+  </div>
+  <div [ngClass]="cornerContainerClasses"
+    class="corner-container top-right">
+    <ng-content select="[iavLayoutFourCornersTopRight]"></ng-content>  
+  </div>
 </div>
-<div [ngClass]="cornerContainerClasses"
-  class="corner-container position-absolute top-0 right-0">
-  <ng-content select="[iavLayoutFourCornersTopRight]"></ng-content>  
-</div>
-<div [ngClass]="cornerContainerClasses"
-  class="corner-container position-absolute bottom-0 left-0">
-  <ng-content select="[iavLayoutFourCornersBottomLeft]"></ng-content>  
+
+<div class="grid-container">
+  <div [ngClass]="cornerContainerClasses"
+    class="corner-container bottom-left">
+    <ng-content select="[iavLayoutFourCornersBottomLeft]"></ng-content>  
+  </div>
+  <div [ngClass]="cornerContainerClasses"
+    class="corner-container bottom-right">
+    <ng-content select="[iavLayoutFourCornersBottomRight]"></ng-content>  
+  </div>
 </div>
-<div [ngClass]="cornerContainerClasses"
-  class="corner-container position-absolute bottom-0 right-0">
-  <ng-content select="[iavLayoutFourCornersBottomRight]"></ng-content>  
-</div>
\ No newline at end of file
diff --git a/src/layouts/layouts/fourPanel/fourPanel.style.css b/src/layouts/layouts/fourPanel/fourPanel.style.css
index 03169dfb4b9564f62c86ca9250303c5337927861..c967cad95281436e99d2fe073018148ae818c4bd 100644
--- a/src/layouts/layouts/fourPanel/fourPanel.style.css
+++ b/src/layouts/layouts/fourPanel/fourPanel.style.css
@@ -1,4 +1,12 @@
 .four-panel-cell
 {
   flex: 0 0 50%;
+}
+
+.four-panel-container
+{
+  display: grid;
+  grid-template-columns: 50% 50%;
+  grid-template-rows: 50% 50%;
+  height: 100%;
 }
\ No newline at end of file
diff --git a/src/layouts/layouts/fourPanel/fourPanel.template.html b/src/layouts/layouts/fourPanel/fourPanel.template.html
index ddb10f1f6a34adda68f578625dd843baf536dfa0..9e747c2a9cf43469711a520b225b92353090c523 100644
--- a/src/layouts/layouts/fourPanel/fourPanel.template.html
+++ b/src/layouts/layouts/fourPanel/fourPanel.template.html
@@ -1,18 +1,14 @@
-<div class="w-100 h-100 d-flex flex-column justify-content-center align-items-stretch">
-  <div class="d-flex flex-row flex-grow-1 flex-shrink-1">
-    <div class="d-flex flex-row four-panel-cell align-items-center justify-content-center">
-      <ng-content select="[cell-i]"></ng-content>
-    </div>
-    <div class="d-flex flex-row four-panel-cell align-items-center justify-content-center">
-      <ng-content select="[cell-ii]"></ng-content>
-    </div>
+<div class="four-panel-container">
+  <div>
+    <ng-content select="[cell-i]"></ng-content>
   </div>
-  <div class="d-flex flex-row flex-grow-1 flex-shrink-1">
-    <div class="d-flex flex-row four-panel-cell align-items-center justify-content-center">
-      <ng-content select="[cell-iii]"></ng-content>
-    </div>
-    <div class="d-flex flex-row four-panel-cell align-items-center justify-content-center">
-      <ng-content select="[cell-iv]"></ng-content>
-    </div>
+  <div>
+    <ng-content select="[cell-ii]"></ng-content>
+  </div>
+  <div>
+    <ng-content select="[cell-iii]"></ng-content>
+  </div>
+  <div>
+    <ng-content select="[cell-iv]"></ng-content>
   </div>
 </div>
diff --git a/src/layouts/layouts/single/single.template.html b/src/layouts/layouts/single/single.template.html
index 561a6363b701518ec5d27b1f0d78507e02afe30a..fcf3a11e33d91bac185b09150761e7487b3e7ae5 100644
--- a/src/layouts/layouts/single/single.template.html
+++ b/src/layouts/layouts/single/single.template.html
@@ -1,18 +1,3 @@
-<div class="w-100 h-100 d-flex flex-row justify-content-center align-items-stretch">
-    <div class="d-flex flex-column major-column">
-      <div class="overflow-hidden flex-grow-1 d-flex align-items-center justify-content-center">
-        <ng-content select="[cell-i]"></ng-content>
-      </div>
-    </div>
-    <div class="d-flex flex-column minor-column">
-      <div class="overflow-hidden layout-31-cell d-flex align-items-center justify-content-center">
-          <ng-content select="[cell-ii]"></ng-content>
-        </div>
-        <div class="overflow-hidden layout-31-cell d-flex align-items-center justify-content-center">
-          <ng-content select="[cell-iii]"></ng-content>
-        </div>
-        <div class="overflow-hidden layout-31-cell d-flex align-items-center justify-content-center">
-          <ng-content select="[cell-iv]"></ng-content>
-        </div>
-    </div>
-  </div>
\ No newline at end of file
+<div class="w-100 h-100">
+  <ng-content select="[cell-i]"></ng-content>
+</div>
diff --git a/src/mouseoverModule/index.ts b/src/mouseoverModule/index.ts
index 6e9cd09486d0a2da56b1f28f86dce2cc6382d78d..8dea7b959fa47feda07047ca34a1fa0d6e204cec 100644
--- a/src/mouseoverModule/index.ts
+++ b/src/mouseoverModule/index.ts
@@ -1,5 +1,3 @@
-export { MouseOverIconPipe } from './mouseOverIcon.pipe'
-export { MouseOverTextPipe } from './mouseOverText.pipe'
 export { MouseHoverDirective } from './mouseover.directive'
 export { MouseoverModule } from './mouseover.module'
 export { TransformOnhoverSegmentPipe } from './transformOnhoverSegment.pipe'
\ No newline at end of file
diff --git a/src/mouseoverModule/mouseOverCvt.pipe.ts b/src/mouseoverModule/mouseOverCvt.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..b0a86234237ad87ab895e70575e8dd1964ba5d51
--- /dev/null
+++ b/src/mouseoverModule/mouseOverCvt.pipe.ts
@@ -0,0 +1,89 @@
+import { Pipe, PipeTransform } from "@angular/core";
+import { TOnHoverObj } from "./util";
+
+function render<T extends keyof TOnHoverObj>(key: T, value: TOnHoverObj[T]){
+  if (!value) return []
+  switch (key) {
+  case 'segments': {
+    return (value as TOnHoverObj['segments']).map(seg => {
+      return {
+        icon: {
+          fontSet: 'fas',
+          fontIcon: 'fa-brain'
+        },
+        text: typeof seg.segment === 'string'
+          ? seg.segment
+          : seg.segment.name
+      }
+    })
+  }
+  case 'landmark': {
+    return [{
+      icon: {
+        fontSet: 'fas',
+        fontIcon: 'fa-map-marker-alt',
+      },
+      text: (value as TOnHoverObj['landmark']).landmarkName
+    }]
+  }
+  case 'userLandmark': {
+    return [{
+      icon: {
+        fontSet: 'fas',
+        fontIcon: 'fa-map-marker-alt',
+      },
+      text: value as TOnHoverObj['userLandmark']
+    }]
+  }
+  case 'annotation': {
+    const { annotationType, name } = (value as TOnHoverObj['annotation'])
+    let fontIcon: string
+    if (annotationType === 'Point') fontIcon = 'fa-circle'
+    if (annotationType === 'Line') fontIcon = 'fa-slash'
+    if (annotationType === 'Polygon') fontIcon = 'fa-draw-polygon'
+    if (!annotationType) fontIcon = 'fa-file'
+    return [{
+      icon: {
+        fontSet: 'fas',
+        fontIcon
+      },
+      text: name || `Unnamed ${annotationType}`
+    }]
+  }
+  default: {
+    return [{
+      icon: {
+        fontSet: 'fas',
+        fontIcon: 'fa-file',
+      },
+      text: `Unknown hovered object`
+    }]
+  }
+  }
+}
+
+type TCvtOutput = {
+  icon: {
+    fontSet: string
+    fontIcon: string
+  }
+  text: string
+}
+
+@Pipe({
+  name: 'mouseoverCvt',
+  pure: true
+})
+
+export class MouseOverConvertPipe implements PipeTransform{
+
+  public transform(dict: TOnHoverObj){
+    const output: TCvtOutput[] = []
+    for (const key in dict) {
+      output.push(
+        ...render(key as keyof TOnHoverObj, dict[key])
+      )
+    }
+    return output
+  }
+}
\ No newline at end of file
diff --git a/src/mouseoverModule/mouseOverIcon.pipe.ts b/src/mouseoverModule/mouseOverIcon.pipe.ts
deleted file mode 100644
index ba5f7686798d9417eb365580a84f16955cdf53d7..0000000000000000000000000000000000000000
--- a/src/mouseoverModule/mouseOverIcon.pipe.ts
+++ /dev/null
@@ -1,34 +0,0 @@
-import { Pipe, PipeTransform } from "@angular/core"
-
-@Pipe({
-  name: 'mouseOverIconPipe',
-})
-
-export class MouseOverIconPipe implements PipeTransform {
-
-  public transform(type: string): {fontSet: string, fontIcon: string} {
-
-    switch (type) {
-    case 'landmark':
-      return {
-        fontSet: 'fas',
-        fontIcon: 'fa-map-marker-alt',
-      }
-    case 'segments':
-      return {
-        fontSet: 'fas',
-        fontIcon: 'fa-brain',
-      }
-    case 'userLandmark':
-      return {
-        fontSet: 'fas',
-        fontIcon: 'fa-map-marker-alt',
-      }
-    default:
-      return {
-        fontSet: 'fas',
-        fontIcon: 'fa-file',
-      }
-    }
-  }
-}
diff --git a/src/mouseoverModule/mouseOverText.pipe.ts b/src/mouseoverModule/mouseOverText.pipe.ts
deleted file mode 100644
index 5ba11425c0e78eb8dee14e9a25ba02a0ed0f9adf..0000000000000000000000000000000000000000
--- a/src/mouseoverModule/mouseOverText.pipe.ts
+++ /dev/null
@@ -1,54 +0,0 @@
-import { Pipe, PipeTransform, SecurityContext } from "@angular/core"
-import { DomSanitizer, SafeHtml } from "@angular/platform-browser"
-import { TransformOnhoverSegmentPipe } from "./transformOnhoverSegment.pipe"
-
-@Pipe({
-  name: 'mouseOverTextPipe',
-})
-
-export class MouseOverTextPipe implements PipeTransform {
-
-  private transformOnHoverSegmentPipe: TransformOnhoverSegmentPipe
-  constructor(private sanitizer: DomSanitizer) {
-    this.transformOnHoverSegmentPipe = new TransformOnhoverSegmentPipe(this.sanitizer)
-  }
-
-  private renderText = ({ label, obj }): SafeHtml[] => {
-    switch (label) {
-    case 'landmark': {
-      const { dataset = [] } = obj
-      return [
-        this.sanitizer.sanitize(SecurityContext.HTML, obj.landmarkName),
-        ...(dataset.map(ds => this.sanitizer.bypassSecurityTrustHtml(`
-<span class="text-muted">
-  ${this.sanitizer.sanitize(SecurityContext.HTML, ds.name)}
-</span>
-`)))
-      ]
-    }
-    case 'segments':
-      return obj.map(({ segment }) => this.transformOnHoverSegmentPipe.transform(segment))
-    case 'userLandmark':
-      return [this.sanitizer.sanitize(SecurityContext.HTML, obj.name)]
-    default:
-      // ts-lint:disable-next-line
-      console.warn(`mouseOver.directive.ts#mouseOverTextPipe: Cannot be displayed: label: ${label}`)
-      return [this.sanitizer.bypassSecurityTrustHtml(`Cannot be displayed: label: ${label}`)]
-    }
-  }
-
-  public transform(inc: {segments: any, landmark: any, userLandmark: any}): Array<{label: string, text: SafeHtml[]}> {
-    const keys = Object.keys(inc)
-    return keys
-      // if is segments, filter out if lengtth === 0
-      .filter(key => Array.isArray(inc[key]) ? inc[key].length > 0 : true )
-      // for other properties, check if value is defined
-      .filter(key => !!inc[key])
-      .map(key => {
-        return {
-          label: key,
-          text: this.renderText({ label: key, obj: inc[key] })
-        }
-      })
-  }
-}
diff --git a/src/mouseoverModule/mouseover.directive.ts b/src/mouseoverModule/mouseover.directive.ts
index 25f33743ce536d91150185cfab6c2e52e3764c8e..cc4ae00872d32f4463aeb4d6a9ce7fbdee37ebe3 100644
--- a/src/mouseoverModule/mouseover.directive.ts
+++ b/src/mouseoverModule/mouseover.directive.ts
@@ -1,12 +1,11 @@
 import { Directive } from "@angular/core"
 import { select, Store } from "@ngrx/store"
 import { merge, Observable } from "rxjs"
-import { distinctUntilChanged, filter, map, scan, shareReplay, startWith, withLatestFrom } from "rxjs/operators"
+import { distinctUntilChanged, map, scan, shareReplay } from "rxjs/operators"
 import { LoggingService } from "src/logging"
-import { uiStateMouseOverSegmentsSelector, uiStateMouseoverUserLandmark } from "src/services/state/uiState/selectors"
-import { viewerStateSelectedParcellationSelector } from "src/services/state/viewerState/selectors"
-import { deserialiseParcRegionId } from "common/util"
-import { temporalPositveScanFn } from "./util"
+import { uiStateMouseOverLandmarkSelector, uiStateMouseOverSegmentsSelector, uiStateMouseoverUserLandmark } from "src/services/state/uiState/selectors"
+import { TOnHoverObj, temporalPositveScanFn } from "./util"
+import { ModularUserAnnotationToolService } from "src/atlasComponents/userAnnotations/tools/service";
 
 @Directive({
   selector: '[iav-mouse-hover]',
@@ -15,12 +14,12 @@ import { temporalPositveScanFn } from "./util"
 
 export class MouseHoverDirective {
 
-  public onHoverObs$: Observable<{segments: any, landmark: any, userLandmark: any}>
-  public currentOnHoverObs$: Observable<{segments: any, landmark: any, userLandmark: any}>
+  public currentOnHoverObs$: Observable<TOnHoverObj>
 
   constructor(
     private store$: Store<any>,
     private log: LoggingService,
+    private annotSvc: ModularUserAnnotationToolService,
   ) {
 
     // TODO consider moving these into a single obs serviced by a DI service
@@ -31,11 +30,10 @@ export class MouseHoverDirective {
     )
 
     const onHoverLandmark$ = this.store$.pipe(
-      select('uiState'),
-      select('mouseOverLandmark'),
+      select(uiStateMouseOverLandmarkSelector)
     ).pipe(
       map(landmark => {
-        if (landmark === null) { return landmark }
+        if (landmark === null) { return null }
         const idx = Number(landmark.replace('label=', ''))
         if (isNaN(idx)) {
           this.log.warn(`Landmark index could not be parsed as a number: ${landmark}`)
@@ -48,27 +46,27 @@ export class MouseHoverDirective {
 
     const onHoverSegments$ = this.store$.pipe(
       select(uiStateMouseOverSegmentsSelector),
-      filter(v => !!v),
-      withLatestFrom(
-        this.store$.pipe(
-          select(viewerStateSelectedParcellationSelector),
-          startWith(null),
-        ),
-      ),
-      map(([ arr, parcellationSelected ]) => parcellationSelected && parcellationSelected.auxillaryMeshIndices
-        ? arr.filter(({ segment }) => {
-          // if segment is not a string (i.e., not labelIndexId) return true
-          if (typeof segment !== 'string') { return true }
-          const { labelIndex } = deserialiseParcRegionId(segment)
-          return parcellationSelected.auxillaryMeshIndices.indexOf(labelIndex) < 0
-        })
-        : arr),
-      distinctUntilChanged((o, n) => o.length === n.length
-        && n.every(segment =>
-          o.find(oSegment => oSegment.layer.name === segment.layer.name
-            && oSegment.segment === segment.segment))),
+
+      // TODO fix aux mesh filtering
+
+      // withLatestFrom(
+      //   this.store$.pipe(
+      //     select(viewerStateSelectedParcellationSelector),
+      //     startWith(null as any),
+      //   ),
+      // ),
+      // map(([ arr, parcellationSelected ]) => parcellationSelected && parcellationSelected.auxillaryMeshIndices
+      //   ? arr.filter(({ segment }) => {
+      //     // if segment is not a string (i.e., not labelIndexId) return true
+      //     if (typeof segment !== 'string') { return true }
+      //     const { labelIndex } = deserialiseParcRegionId(segment)
+      //     return parcellationSelected.auxillaryMeshIndices.indexOf(labelIndex) < 0
+      //   })
+      //   : arr),
     )
 
+    const onHoverAnnotation$ = this.annotSvc.hoveringAnnotations$
+
     const mergeObs = merge(
       onHoverSegments$.pipe(
         distinctUntilChanged(),
@@ -76,6 +74,12 @@ export class MouseHoverDirective {
           return { segments }
         }),
       ),
+      onHoverAnnotation$.pipe(
+        distinctUntilChanged(),
+        map(annotation => {
+          return { annotation }
+        }),
+      ),
       onHoverLandmark$.pipe(
         distinctUntilChanged(),
         map(landmark => {
@@ -92,22 +96,13 @@ export class MouseHoverDirective {
       shareReplay(1),
     )
 
-    this.onHoverObs$ = mergeObs.pipe(
-      scan((acc, curr) => {
-        return {
-          ...acc,
-          ...curr,
-        }
-      }, { segments: null, landmark: null, userLandmark: null }),
-      shareReplay(1),
-    )
-
     this.currentOnHoverObs$ = mergeObs.pipe(
       scan(temporalPositveScanFn, []),
       map(arr => {
 
         let returnObj = {
           segments: null,
+          annotation: null,
           landmark: null,
           userLandmark: null,
         }
diff --git a/src/mouseoverModule/mouseover.module.ts b/src/mouseoverModule/mouseover.module.ts
index 476fc900a2a6a3731b5bae0d7f6a2f60d836dd8a..b5fbcc9feb9f04b1336d1df7209445144e569cc5 100644
--- a/src/mouseoverModule/mouseover.module.ts
+++ b/src/mouseoverModule/mouseover.module.ts
@@ -2,8 +2,8 @@ import { CommonModule } from "@angular/common";
 import { NgModule } from "@angular/core";
 import { TransformOnhoverSegmentPipe } from "src/atlasViewer/onhoverSegment.pipe";
 import { MouseHoverDirective } from "./mouseover.directive";
-import { MouseOverIconPipe } from "./mouseOverIcon.pipe";
-import { MouseOverTextPipe } from "./mouseOverText.pipe";
+import { MouseOverConvertPipe } from "./mouseOverCvt.pipe";
+
 
 @NgModule({
   imports: [
@@ -11,15 +11,13 @@ import { MouseOverTextPipe } from "./mouseOverText.pipe";
   ],
   declarations: [
     MouseHoverDirective,
-    MouseOverTextPipe,
     TransformOnhoverSegmentPipe,
-    MouseOverIconPipe,
+    MouseOverConvertPipe,
   ],
   exports: [
     MouseHoverDirective,
-    MouseOverTextPipe,
     TransformOnhoverSegmentPipe,
-    MouseOverIconPipe,
+    MouseOverConvertPipe,
   ]
 })
 
diff --git a/src/mouseoverModule/type.ts b/src/mouseoverModule/type.ts
new file mode 100644
index 0000000000000000000000000000000000000000..07c4312fa7896c53a7f4a8ca58b842e3cd88dc59
--- /dev/null
+++ b/src/mouseoverModule/type.ts
@@ -0,0 +1,13 @@
+import { TRegionSummary } from "src/util/siibraApiConstants/types";
+
+export type TMouseOverSegment = {
+  layer: {
+    name: string
+  }
+  segmentId: number
+  segment: TRegionSummary | string // if cannot decode, then segment will be {ngId}#{labelIndex}
+}
+
+export type TMouseOverVtkLandmark = {
+  landmarkName: string
+}
\ No newline at end of file
diff --git a/src/mouseoverModule/util.spec..ts b/src/mouseoverModule/util.spec.ts
similarity index 91%
rename from src/mouseoverModule/util.spec..ts
rename to src/mouseoverModule/util.spec.ts
index 07453e0343eb31d5e6b1279b3a249a19b5301c2c..31920019b049537cadb4df833acc11a8d8faf20c 100644
--- a/src/mouseoverModule/util.spec..ts
+++ b/src/mouseoverModule/util.spec.ts
@@ -50,11 +50,12 @@ describe('temporalPositveScanFn', () => {
     ]).pipe(
       take(1),
     ).subscribe(([ arr1, arr2, arr3, arr4 ]) => {
-      expect(arr1).toEqual([ segmentsPositive ])
-      expect(arr2).toEqual([ userLandmarkPostive, segmentsPositive ])
-      expect(arr3).toEqual([ userLandmarkPostive ])
+      expect(arr1).toEqual([ segmentsPositive ] as any)
+      expect(arr2).toEqual([ userLandmarkPostive, segmentsPositive ] as any)
+      expect(arr3).toEqual([ userLandmarkPostive ] as any)
       expect(arr4).toEqual([])
-    }, null, () => done() )
+      done()
+    })
 
     source.next(segmentsPositive)
     source.next(userLandmarkPostive)
diff --git a/src/mouseoverModule/util.ts b/src/mouseoverModule/util.ts
index 519202f8878440faf249ad3da41b163e5c66fd4b..ed4fbe50f42c9580f554e19b6e98678438c1b038 100644
--- a/src/mouseoverModule/util.ts
+++ b/src/mouseoverModule/util.ts
@@ -1,3 +1,14 @@
+import { IAnnotationGeometry } from "src/atlasComponents/userAnnotations/tools/type"
+import { TMouseOverSegment } from "./type"
+
+export type TOnHoverObj = {
+  segments: TMouseOverSegment[]
+  annotation: IAnnotationGeometry
+  landmark: {
+    landmarkName: number
+  }
+  userLandmark: any
+}
 
 /**
  * Scan function which prepends newest positive (i.e. defined) value
@@ -10,7 +21,7 @@
  *
  *
  */
-export const temporalPositveScanFn = (acc: Array<{segments: any, landmark: any, userLandmark: any}>, curr: {segments: any, landmark: any, userLandmark: any}) => {
+export const temporalPositveScanFn = (acc: Array<TOnHoverObj>, curr: Partial<TOnHoverObj>) => {
 
   const keys = Object.keys(curr)
 
@@ -21,6 +32,6 @@ export const temporalPositveScanFn = (acc: Array<{segments: any, landmark: any,
   )
 
   return isPositive
-    ? [curr, ...(acc.filter(item => !keys.some(key => !!item[key])))] as Array<{segments?: any, landmark?: any, userLandmark?: any}>
+    ? [curr, ...(acc.filter(item => !keys.some(key => !!item[key])))] as Array<TOnHoverObj>
     : acc.filter(item => !keys.some(key => !!item[key]))
-}
\ No newline at end of file
+}
diff --git a/src/overwrite.scss b/src/overwrite.scss
index 9aa3141ed73802f6b6b75ecc85cade85afdbcbae..c8e7e12e46e899f162b3085f1cd523be12835d24 100644
--- a/src/overwrite.scss
+++ b/src/overwrite.scss
@@ -1,3 +1,5 @@
+@use 'sass:math';
+
 iav-cmp-viewer-container
 {
 
@@ -33,4 +35,39 @@ kg-ds-prv-regional-feature-view
   {
     min-height: 20em;
   }
-}
\ No newline at end of file
+}
+
+// no prefix
+@for $i from 1 through 12 {
+  $vw: math.div(100vw * $i, 12);
+  .vw-col-#{$i} {
+    width: $vw;
+  }
+  .vw-col-#{$i}-nm {
+    margin-left: -1 * $vw;
+  }
+}
+
+$medias: "-sm","-md","-lg","-xl","-xxl";
+$media-map: (
+  "-sm": 576px,
+  "-md": 768px,
+  "-lg": 992px,
+  "-xl": 1200px,
+  "-xxl": 2000px,
+);
+
+@each $media in $medias {
+  $size: map-get($media-map, $media);
+  @media (min-width: $size) {
+    @for $i from 1 through 12 {
+      $vw: math.div(100vw * $i, 12);
+      .vw-col#{$media}-#{$i} {
+        width: $vw;
+      }
+      .vw-col#{$media}-#{$i}-nm {
+        margin-left: -1 * $vw;
+      }
+    }
+  }
+}
diff --git a/src/plugin/atlasViewer.pluginService.service.ts b/src/plugin/atlasViewer.pluginService.service.ts
index 1c83a6d28b92622728c9653cf0562846cd28e2cb..668027764cf639fe3be327119a12fb4140352f08 100644
--- a/src/plugin/atlasViewer.pluginService.service.ts
+++ b/src/plugin/atlasViewer.pluginService.service.ts
@@ -375,6 +375,18 @@ export class PluginServices {
 
     return handler
   }
+
+  public async addPluginViaManifestUrl(manifestUrl: string){
+    try {
+      const json = await this.fetch(manifestUrl)
+      this.fetchedPluginManifests = [
+        ...this.fetchedPluginManifests,
+        json
+      ]
+    } catch (e) {
+      throw new Error(e.statusText)
+    }
+  }
 }
 
 export interface IPluginManifest {
diff --git a/src/plugin/pluginBanner/pluginBanner.component.ts b/src/plugin/pluginBanner/pluginBanner.component.ts
index 59de1360d44b7db00fc1f9e5567371debf03b650..689f0aa32bfc4a7c16442bbc22e56c95d44a2b0d 100644
--- a/src/plugin/pluginBanner/pluginBanner.component.ts
+++ b/src/plugin/pluginBanner/pluginBanner.component.ts
@@ -1,6 +1,8 @@
 import { Component, ViewChild, TemplateRef } from "@angular/core";
 import { IPluginManifest, PluginServices } from "../atlasViewer.pluginService.service";
 import { MatDialog } from "@angular/material/dialog";
+import { environment } from 'src/environments/environment';
+import { MatSnackBar } from "@angular/material/snack-bar";
 
 @Component({
   selector : 'plugin-banner',
@@ -12,12 +14,15 @@ import { MatDialog } from "@angular/material/dialog";
 
 export class PluginBannerUI {
 
+  EXPERIMENTAL_FEATURE_FLAG = environment.EXPERIMENTAL_FEATURE_FLAG
+
   @ViewChild('pluginInfoTmpl', { read: TemplateRef })
   private pluginInfoTmpl: TemplateRef<any>
 
   constructor(
     public pluginServices: PluginServices,
     private matDialog: MatDialog,
+    private matSnackbar: MatSnackBar,
   ) {
   }
 
@@ -34,4 +39,28 @@ export class PluginBannerUI {
       }
     )
   }
+
+  public showTmpl(tmpl: TemplateRef<any>){
+    this.matDialog.open(tmpl, {
+      minWidth: '60vw'
+    })
+  }
+
+  public loadingThirdpartyPlugin = false
+
+  public async addThirdPartyPlugin(manifestUrl: string) {
+    this.loadingThirdpartyPlugin = true
+    try {
+      await this.pluginServices.addPluginViaManifestUrl(manifestUrl)
+      this.loadingThirdpartyPlugin = false
+      this.matSnackbar.open(`Adding plugin successful`, 'Dismiss', {
+        duration: 5000
+      })
+    } catch (e) {
+      this.loadingThirdpartyPlugin = false
+      this.matSnackbar.open(`Error adding plugin: ${e.toString()}`, 'Dismiss', {
+        duration: 5000
+      })
+    }
+  }
 }
diff --git a/src/plugin/pluginBanner/pluginBanner.template.html b/src/plugin/pluginBanner/pluginBanner.template.html
index 6216ee8247a5ac011f3ec41acf7f58cb7e52d0d3..3e452612ebef6347181b825c02c22c5ba2ce8c74 100644
--- a/src/plugin/pluginBanner/pluginBanner.template.html
+++ b/src/plugin/pluginBanner/pluginBanner.template.html
@@ -15,8 +15,46 @@
       {{ plugin.displayName ? plugin.displayName : plugin.name }}
     </span>
   </button>
+
+  <button mat-menu-item *ngIf="EXPERIMENTAL_FEATURE_FLAG"
+    (click)="showTmpl(thirdPartyPluginTmpl)">
+    <span>
+      Add third party plugin
+    </span>
+  </button>
 </mat-action-list>
 
+<ng-template #thirdPartyPluginTmpl>
+  <h2 mat-dialog-title>
+    Add thirdparty plugin
+  </h2>
+
+  <mat-dialog-content>
+    <form>
+      <mat-form-field class="d-block">
+        <mat-label>
+          manifest.json URL
+        </mat-label>
+        <input type="text" matInput placeholder="https://example.com/manifest.json" #urlInput>
+      </mat-form-field>
+    </form>
+  </mat-dialog-content>
+
+  <mat-dialog-actions align="end">
+    <button (click)="addThirdPartyPlugin(urlInput.value)"
+      mat-raised-button
+      [disabled]="loadingThirdpartyPlugin"
+      color="primary">
+      Load
+    </button>
+    <button mat-dialog-close
+      mat-button>
+      cancel
+    </button>
+  </mat-dialog-actions>
+
+</ng-template>
+
 <ng-template #pluginInfoTmpl let-manifest>
   <h1 mat-dialog-title>
     About {{ manifest.displayName || manifest.name }}
diff --git a/src/routerModule/router.service.spec.ts b/src/routerModule/router.service.spec.ts
index 2b933c6f1a5711b8503776d082203e684299f563..a06a700ff5c0d726381c0ecb9e3de24d08170bc7 100644
--- a/src/routerModule/router.service.spec.ts
+++ b/src/routerModule/router.service.spec.ts
@@ -267,27 +267,56 @@ describe('> router.service.ts', () => {
             discardPeriodicTasks()
           }))
 
-          it('> ... returns same value, does not dispatches', fakeAsync(() => {
-            const fakeParsedState = {
-              bizz: 'buzz'
-            }
-            cvtFullRouteToStateSpy.and.callFake(() => fakeParsedState)
-            cvtStateToHashedRoutesSpy.and.callFake(() => {
-              return `foo/bar`
-            })
-            router = TestBed.inject(Router)
-            router.navigate(['foo', 'bar'])
-    
-            const service = TestBed.inject(RouterService)
-            const store = TestBed.inject(MockStore)
-            const dispatchSpy = spyOn(store, 'dispatch')
+          describe('> returns the same value', () => {
+            it('> ... returns same value, does not dispatches', fakeAsync(() => {
+              const fakeParsedState = {
+                bizz: 'buzz'
+              }
+              cvtFullRouteToStateSpy.and.callFake(() => fakeParsedState)
+              cvtStateToHashedRoutesSpy.and.callFake(() => {
+                return `foo/bar`
+              })
+              router = TestBed.inject(Router)
+              router.navigate(['foo', 'bar'])
+      
+              const service = TestBed.inject(RouterService)
+              const store = TestBed.inject(MockStore)
+              const dispatchSpy = spyOn(store, 'dispatch')
+              
+              tick(320)
+
+              expect(dispatchSpy).not.toHaveBeenCalled()
+      
+              discardPeriodicTasks()
+            }))
             
-            tick(320)
+            it('> takes into account of customRoute', fakeAsync(() => {
+              const fakeParsedState = {
+                bizz: 'buzz'
+              }
+              cvtFullRouteToStateSpy.and.callFake(() => fakeParsedState)
+              cvtStateToHashedRoutesSpy.and.callFake(() => {
+                return `foo/bar`
+              })
+      
+              const service = TestBed.inject(RouterService)
+              service.customRoute$ = of({
+                'x-foo': 'hello'
+              })
 
-            expect(dispatchSpy).not.toHaveBeenCalled()
-    
-            discardPeriodicTasks()
-          }))
+              router = TestBed.inject(Router)
+              router.navigate(['foo', 'bar', 'x-foo:hello'])
+
+              const store = TestBed.inject(MockStore)
+              const dispatchSpy = spyOn(store, 'dispatch')
+              
+              tick(320)
+
+              expect(dispatchSpy).not.toHaveBeenCalled()
+      
+              discardPeriodicTasks()
+            }))
+          })
         })
       })
     })
diff --git a/src/routerModule/router.service.ts b/src/routerModule/router.service.ts
index ee0246f79302d60fae4c9caa8477c65120929d52..a17b554adcc8d430c279d7c241f8f96438ca018d 100644
--- a/src/routerModule/router.service.ts
+++ b/src/routerModule/router.service.ts
@@ -7,7 +7,7 @@ import { debounceTime, distinctUntilChanged, filter, map, shareReplay, startWith
 import { generalApplyState } from "src/services/stateStore.helper";
 import { PureContantService } from "src/util";
 import { cvtStateToHashedRoutes, cvtFullRouteToState, encodeCustomState, decodeCustomState, verifyCustomState } from "./util";
-import { BehaviorSubject, combineLatest, merge, Observable } from 'rxjs'
+import { BehaviorSubject, combineLatest, merge, Observable, of } from 'rxjs'
 import { scan } from 'rxjs/operators'
 
 @Injectable({
@@ -45,7 +45,7 @@ export class RouterService {
     // could be navigation (history api)
     // could be on init
     const navEnd$ = router.events.pipe(
-      filter(ev => ev instanceof NavigationEnd),
+      filter<NavigationEnd>(ev => ev instanceof NavigationEnd),
       shareReplay(1)
     )
 
@@ -94,10 +94,17 @@ export class RouterService {
     ready$.pipe(
       switchMapTo(
         navEnd$.pipe(
-          withLatestFrom(store$)
+          withLatestFrom(
+            store$,
+            this.customRoute$.pipe(
+              startWith({})
+            )
+          )
         )
       )
-    ).subscribe(([ev, state]: [NavigationEnd, any]) => {
+    ).subscribe(arg => {
+      const [ev, state, customRoutes] = arg
+      
       const fullPath = ev.urlAfterRedirects
       const stateFromRoute = cvtFullRouteToState(router.parseUrl(fullPath), state, this.logError)
       let routeFromState: string
@@ -107,6 +114,12 @@ export class RouterService {
         routeFromState = ``
       }
 
+      for (const key in customRoutes) {
+        const customStatePath = encodeCustomState(key, customRoutes[key])
+        if (!customStatePath) continue
+        routeFromState += `/${customStatePath}`
+      }
+
       if ( fullPath !== `/${routeFromState}`) {
         store$.dispatch(
           generalApplyState({
@@ -135,10 +148,10 @@ export class RouterService {
           ),
           this.customRoute$,
         ]).pipe(
-          map(([ routePath, customPath ]) => {
+          map(([ routePath, customRoutes ]) => {
             let returnPath = routePath
-            for (const key in customPath) {
-              const customStatePath = encodeCustomState(key, customPath[key])
+            for (const key in customRoutes) {
+              const customStatePath = encodeCustomState(key, customRoutes[key])
               if (!customStatePath) continue
               returnPath += `/${customStatePath}`
             }
diff --git a/src/services/state/uiState/actions.ts b/src/services/state/uiState/actions.ts
index 7f3f864483c29e791532642da6351cfd42e0b395..ae2fbc3bd9535428de9c3912a967ea71ee298c2c 100644
--- a/src/services/state/uiState/actions.ts
+++ b/src/services/state/uiState/actions.ts
@@ -26,7 +26,7 @@ export const uiStateShowBottomSheet = createAction(
 
 export const uiActionMouseoverLandmark = createAction(
   `[uiState] mouseoverLandmark`,
-  props<{ landmark: any }>()
+  props<{ landmark: string }>()
 )
 
 export const uiActionMouseoverSegments = createAction(
diff --git a/src/services/state/uiState/common.ts b/src/services/state/uiState/common.ts
index 1ba2e621ec2db19bc0f24bcae524ba33a847c326..dd5da3140f280c9cef5c7cd29637c2577f47587f 100644
--- a/src/services/state/uiState/common.ts
+++ b/src/services/state/uiState/common.ts
@@ -12,7 +12,7 @@ export interface IUiState{
   sidePanelExploreCurrentViewIsOpen: boolean
   mouseOverSegment: any | number
 
-  mouseOverLandmark: any
+  mouseOverLandmark: string
   mouseOverUserLandmark: any
 
   focusedSidePanel: string | null
diff --git a/src/services/state/uiState/selectors.spec.ts b/src/services/state/uiState/selectors.spec.ts
index 8f26ad8b2ade3ba0d0e9cc4d6873738fbc3fefc7..2464c9c8a1a4770a1e1c14afd28cb7c3dd4a3833 100644
--- a/src/services/state/uiState/selectors.spec.ts
+++ b/src/services/state/uiState/selectors.spec.ts
@@ -2,26 +2,6 @@ import { uiStateMouseOverSegmentsSelector } from './selectors'
 
 describe('> uiState/selectors.ts', () => {
   describe('> mouseOverSegments', () => {
-    it('> should filter out regions explicitly designated as unselectable', () => {
-      const unSelSeg = {
-        segment: {
-          unselectable: true
-        }
-      }
 
-      const selSeg0 = {
-        segment: 1
-      }
-
-      const selSeg1 = {
-        segment: {
-          name: 'hello world',
-          unselectable: false
-        }
-      }
-      const filteredResult = uiStateMouseOverSegmentsSelector.projector([unSelSeg, selSeg0, selSeg1])
-
-      expect(filteredResult).toEqual([selSeg0, selSeg1])
-    })
   })
 })
diff --git a/src/services/state/uiState/selectors.ts b/src/services/state/uiState/selectors.ts
index f72757b436adbf77e19becde70cff55213484504..483539b2d784f567564bc2963233b8dd91dabcb1 100644
--- a/src/services/state/uiState/selectors.ts
+++ b/src/services/state/uiState/selectors.ts
@@ -1,4 +1,5 @@
 import { createSelector } from "@ngrx/store";
+import { TMouseOverSegment } from "src/mouseoverModule/type";
 import { IUiState } from './common'
 
 export const uiStatePreviewingDatasetFilesSelector = createSelector(
@@ -7,19 +8,13 @@ export const uiStatePreviewingDatasetFilesSelector = createSelector(
 )
 
 export const uiStateMouseOverSegmentsSelector = createSelector(
-  state => state['uiState']['mouseOverSegments'],
-  mouseOverSegments => {
-    /**
-     * filter out the regions explicitly declared `unselectable`
-     */
-    return mouseOverSegments
-      .filter(({ segment }) => {
-        if (typeof segment === 'object' && segment !== null) {
-          if (segment.unselectable) return false
-        }
-        return true
-      })
-  }
+  state => state['uiState'],
+  uiState => uiState['mouseOverSegments'] as TMouseOverSegment[]
+)
+
+export const uiStateMouseOverLandmarkSelector = createSelector(
+  state => state['uiState'],
+  uiState => uiState['mouseOverLandmark'] as string
 )
 
 export const uiStateMouseoverUserLandmark = createSelector(
diff --git a/src/services/state/viewerState/actions.ts b/src/services/state/viewerState/actions.ts
index 74d44f9b86e3c5bf2327f00b64a3581f9317e436..d20ff0cd29af5855535d0ca27fc519e9204aa360 100644
--- a/src/services/state/viewerState/actions.ts
+++ b/src/services/state/viewerState/actions.ts
@@ -98,7 +98,7 @@ export const viewerStateSetViewerMode = createAction(
 
 export const viewerStateDblClickOnViewer = createAction(
   `[viewerState] dblClickOnViewer`,
-  props<{ payload: { segments: any, landmark: any, userLandmark: any } }>()
+  props<{ payload: { annotation: any, segments: any, landmark: any, userLandmark: any } }>()
 )
 
 export const viewerStateAddUserLandmarks = createAction(
diff --git a/src/ui/logoContainer/logoContainer.component.ts b/src/ui/logoContainer/logoContainer.component.ts
index 6b3ce834c7ae34d1459fc1965ab51dec8c14b3a1..105e0726251a75522bc2d747767c0fe7b3eb50c2 100644
--- a/src/ui/logoContainer/logoContainer.component.ts
+++ b/src/ui/logoContainer/logoContainer.component.ts
@@ -3,6 +3,9 @@ import { PureContantService } from "src/util";
 import { Subscription } from "rxjs";
 import { distinctUntilChanged } from "rxjs/operators";
 
+const imageDark = 'assets/logo/ebrains-logo-dark.svg'
+const imageLight = 'assets/logo/ebrains-logo-light.svg'
+
 @Component({
   selector : 'logo-container',
   templateUrl : './logoContainer.template.html',
@@ -13,10 +16,10 @@ import { distinctUntilChanged } from "rxjs/operators";
 
 export class LogoContainer {
   // only used to define size
-  public imgSrc = `${this.pureConstantService.backendUrl}logo`
+  public imgSrc = imageDark
   
   public containerStyle = {
-    backgroundImage: `url('${this.pureConstantService.backendUrl}logo')`
+    backgroundImage: `url('${this.imgSrc}')`
   }
 
   private subscriptions: Subscription[] = []
@@ -28,7 +31,7 @@ export class LogoContainer {
         distinctUntilChanged()
       ).subscribe(flag => {
         this.containerStyle = {
-          backgroundImage: `url('${this.pureConstantService.backendUrl}logo${!!flag ? '?darktheme=true' : ''}')`
+          backgroundImage: `url('${flag ? imageLight : imageDark}')`
         }
       })
     )
diff --git a/src/util/directives/switch.directive.ts b/src/util/directives/switch.directive.ts
index eb582253a951b061958c69ff19dd1317c97ab30f..89dd445186afe7d49e2ee8c7b7d50a27429edff7 100644
--- a/src/util/directives/switch.directive.ts
+++ b/src/util/directives/switch.directive.ts
@@ -1,16 +1,28 @@
 import { Directive, Input, Output, EventEmitter } from "@angular/core";
+import { BehaviorSubject } from "rxjs";
 
 @Directive({
   selector: '[iav-switch]',
   exportAs: 'iavSwitch'
 })
 export class SwitchDirective{
-  @Input('iav-switch-initstate') switchState: boolean = false
+
+  switchState: boolean = false
+
   @Input('iav-switch-delay') delay: number = 0
   @Output('iav-switch-event') eventemitter: EventEmitter<boolean> = new EventEmitter()
   
-  emit(flag){
+  @Input('iav-switch-state')
+  set setSwitchState(val: boolean) {
+    this.switchState = val
+    this.emit()
+  }
+
+  public switchState$ = new BehaviorSubject(this.switchState)
+
+  emit(){
     this.eventemitter.emit(this.switchState)
+    this.switchState$.next(this.switchState)
   }
 
   toggle(){
diff --git a/src/util/pipes/combineFn.pipe.ts b/src/util/pipes/combineFn.pipe.ts
new file mode 100644
index 0000000000000000000000000000000000000000..cfd98e4e11c293cfbb7fd09541312ccc2b97e4b3
--- /dev/null
+++ b/src/util/pipes/combineFn.pipe.ts
@@ -0,0 +1,13 @@
+import { Pipe, PipeTransform } from "@angular/core";
+
+@Pipe({
+  name: 'combineFn',
+  pure: true
+})
+export class CombineFnPipe implements PipeTransform{
+  public transform(fns: CallableFunction[]): CallableFunction{
+    return () => {
+      for (const fn of fns) fn()
+    }
+  }
+}
diff --git a/src/util/pureConstant.service.ts b/src/util/pureConstant.service.ts
index ba33d3b9388d8acbde91776d3826230be0074487..5d69b140153b700a2d76e35070602b6fba98dc23 100644
--- a/src/util/pureConstant.service.ts
+++ b/src/util/pureConstant.service.ts
@@ -56,6 +56,20 @@ type TIAVAtlas = {
   } & THasId)[]
 } & THasId
 
+type TNehubaConfig = Record<string, {
+  source: string
+  transform: number[][]
+  type: 'segmentation' | 'image'
+}>
+
+type TViewerConfig = TNehubaConfig
+
+/**
+ * key value pair of
+ * atlasId -> templateId -> viewerConfig
+ */
+type TAtlasTmplViewerConfig = Record<string, Record<string, TViewerConfig>>
+
 export const spaceMiscInfoMap = new Map([
   ['minds/core/referencespace/v1.0.0/a1655b99-82f1-420f-a3c2-fe80fd4c8588', {
     name: 'bigbrain',
@@ -514,12 +528,20 @@ Raise/track issues at github repo: <a target = "_blank" href = "${this.repoUrl}"
     shareReplay(1)
   )
 
+  private atlasTmplConfig: TAtlasTmplViewerConfig = {}
+
+  async getViewerConfig(atlasId: string, templateId: string, parcId: string) {
+    const atlasLayers = this.atlasTmplConfig[atlasId]
+    const templateLayers = atlasLayers && atlasLayers[templateId]
+    return templateLayers || {}
+  }
+
   public initFetchTemplate$ = this.fetchedAtlases$.pipe(
     switchMap(atlases => {
       return forkJoin(
         atlases.map(atlas => this.getSpacesAndParc(atlas['@id']).pipe(
           switchMap(({ templateSpaces, parcellations }) => {
-            const ngLayerObj = {}
+            this.atlasTmplConfig[atlas["@id"]] = {}
             return forkJoin(
               templateSpaces.map(
                 tmpl => {
@@ -534,7 +556,7 @@ Raise/track issues at github repo: <a target = "_blank" href = "${this.repoUrl}"
                       name: 'Julich-Brain Probabilistic Cytoarchitectonic Maps (v2.9)'
                     })
                   }
-                  ngLayerObj[tmpl.id] = {}
+                  this.atlasTmplConfig[atlas["@id"]][tmpl.id] = {}
                   return tmpl.availableParcellations.map(
                     parc => this.getRegions(atlas['@id'], parc.id, tmpl.id).pipe(
                       tap(regions => {
@@ -557,7 +579,7 @@ Raise/track issues at github repo: <a target = "_blank" href = "${this.repoUrl}"
                               const ngId = getNgId(atlas['@id'], tmpl.id, parc.id, dedicatedMap[0]['@id'])
                               region['ngId'] = ngId
                               region['labelIndex'] = dedicatedMap[0].detail['neuroglancer/precomputed'].labelIndex
-                              ngLayerObj[tmpl.id][ngId] = {
+                              this.atlasTmplConfig[atlas["@id"]][tmpl.id][ngId] = {
                                 source: `precomputed://${dedicatedMap[0].url}`,
                                 type: "segmentation",
                                 transform: dedicatedMap[0].detail['neuroglancer/precomputed'].transform
@@ -602,7 +624,7 @@ Raise/track issues at github repo: <a target = "_blank" href = "${this.repoUrl}"
                             const key = 'whole brain'
 
                             const ngIdKey = getNgId(atlas['@id'], tmpl.id, parseId(parc.id), key)
-                            ngLayerObj[tmpl.id][ngIdKey] = {
+                            this.atlasTmplConfig[atlas["@id"]][tmpl.id][ngIdKey] = {
                               source: `precomputed://${vol.url}`,
                               type: "segmentation",
                               transform: vol.detail['neuroglancer/precomputed'].transform
@@ -619,7 +641,7 @@ Raise/track issues at github repo: <a target = "_blank" href = "${this.repoUrl}"
                             }]
                             for (const { key, mapIndex } of mapIndexKey) {
                               const ngIdKey = getNgId(atlas['@id'], tmpl.id, parseId(parc.id), key)
-                              ngLayerObj[tmpl.id][ngIdKey] = {
+                              this.atlasTmplConfig[atlas["@id"]][tmpl.id][ngIdKey] = {
                                 source: `precomputed://${precomputedVols[mapIndex].url}`,
                                 type: "segmentation",
                                 transform: precomputedVols[mapIndex].detail['neuroglancer/precomputed'].transform
@@ -640,7 +662,7 @@ Raise/track issues at github repo: <a target = "_blank" href = "${this.repoUrl}"
                 }
               ).reduce(flattenReducer, [])
             ).pipe(
-              mapTo({ templateSpaces, parcellations, ngLayerObj })
+              mapTo({ templateSpaces, parcellations, ngLayerObj: this.atlasTmplConfig })
             )
           }),
           map(({ templateSpaces, parcellations, ngLayerObj }) => {
@@ -779,8 +801,8 @@ Raise/track issues at github repo: <a target = "_blank" href = "${this.repoUrl}"
                 }
               }
 
-              for (const key in (ngLayerObj[tmpl.id] || {})) {
-                initialLayers[key] = ngLayerObj[tmpl.id][key]
+              for (const key in (ngLayerObj[atlas["@id"]][tmpl.id] || {})) {
+                initialLayers[key] = ngLayerObj[atlas["@id"]][tmpl.id][key]
               }
 
               return {
diff --git a/src/util/util.module.ts b/src/util/util.module.ts
index bde4b907f1d01f911d5d9886ed967ba5b4698f3f..f128cf3fd266a1851d2951bf21c78ffffd4cedfd 100644
--- a/src/util/util.module.ts
+++ b/src/util/util.module.ts
@@ -20,6 +20,7 @@ import { GetPropertyPipe } from "./pipes/getProperty.pipe";
 import { FilterArrayPipe } from "./pipes/filterArray.pipe";
 import { DoiParserPipe } from "./pipes/doiPipe.pipe";
 import { GetFilenamePipe } from "./pipes/getFilename.pipe";
+import { CombineFnPipe } from "./pipes/combineFn.pipe";
 import { MergeObjPipe } from "./mergeObj.pipe";
 
 @NgModule({
@@ -46,6 +47,7 @@ import { MergeObjPipe } from "./mergeObj.pipe";
     FilterArrayPipe,
     DoiParserPipe,
     GetFilenamePipe,
+    CombineFnPipe,
     MergeObjPipe,
   ],
   exports: [
@@ -68,6 +70,7 @@ import { MergeObjPipe } from "./mergeObj.pipe";
     FilterArrayPipe,
     DoiParserPipe,
     GetFilenamePipe,
+    CombineFnPipe,
     MergeObjPipe,
   ]
 })
diff --git a/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts b/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts
index 248b72fe0285b2e5510e948bebbe5f23da1d1f07..8281c6565f4f6c717e8586877285781f631a1069 100644
--- a/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts
+++ b/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts
@@ -1,4 +1,4 @@
-import { Component, ElementRef, EventEmitter, OnDestroy, OnInit, Output, Inject, Optional } from "@angular/core";
+import { Component, ElementRef, EventEmitter, OnDestroy, OnInit, Output, Inject, Optional, ChangeDetectionStrategy } from "@angular/core";
 import { fromEvent, Subscription, ReplaySubject, BehaviorSubject, Observable, race, timer, Subject } from 'rxjs'
 import { debounceTime, filter, map, scan, startWith, mapTo, switchMap, take, skip, tap, distinctUntilChanged } from "rxjs/operators";
 import { AtlasWorkerService } from "src/atlasViewer/atlasViewer.workerService.service";
@@ -62,6 +62,8 @@ export const scanFn = (acc: LayerLabelIndex[], curr: LayerLabelIndex) => {
   styleUrls : [
     './nehubaViewer.style.css',
   ],
+  // OnPush seems to improve performance significantly
+  changeDetection: ChangeDetectionStrategy.OnPush
 })
 
 export class NehubaViewerUnit implements OnInit, OnDestroy {
@@ -94,7 +96,7 @@ export class NehubaViewerUnit implements OnInit, OnDestroy {
         url?: string
       }
     }> = new EventEmitter()
-  @Output() public mouseoverLandmarkEmitter: EventEmitter<number | null> = new EventEmitter()
+  @Output() public mouseoverLandmarkEmitter: EventEmitter<string> = new EventEmitter()
   @Output() public mouseoverUserlandmarkEmitter: EventEmitter<string> = new EventEmitter()
   @Output() public regionSelectionEmitter: EventEmitter<{segment: number, layer: {name?: string, url?: string}}> = new EventEmitter()
   @Output() public errorEmitter: EventEmitter<any> = new EventEmitter()
diff --git a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.spec.ts b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.spec.ts
index 4b081a97abd78533d6ab06c6202fb587453b23b9..8aa04373cf3c7d7a8c145d221d30c3d4f1b15a3e 100644
--- a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.spec.ts
+++ b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.spec.ts
@@ -183,9 +183,10 @@ describe('> nehubaViewerGlue.component.ts', () => {
       const testObj0 = {
         segment: 'hello world'
       }
+      const testObj1 = 'hello world'
       beforeEach(() => {
         fallbackSpy = spyOn(clickIntServ, 'fallback')
-        mockStore.overrideSelector(uiStateMouseOverSegmentsSelector, ['hello world', testObj0])
+        mockStore.overrideSelector(uiStateMouseOverSegmentsSelector, [testObj1, testObj0] as any)
         TestBed.createComponent(NehubaGlueCmp)
         clickIntServ.callRegFns(null)
       })
@@ -214,7 +215,7 @@ describe('> nehubaViewerGlue.component.ts', () => {
       }
       beforeEach(() => {
         fallbackSpy = spyOn(clickIntServ, 'fallback')
-        mockStore.overrideSelector(uiStateMouseOverSegmentsSelector, [testObj0, testObj1, testObj2])
+        mockStore.overrideSelector(uiStateMouseOverSegmentsSelector, [testObj0, testObj1, testObj2] as any)
 
       })
       afterEach(() => {
diff --git a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts
index 15504851b024378aeb96c8c96ef2f04d73489842..f8df7f66789021d41fe5f0435e6b24ae83a27c39 100644
--- a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts
+++ b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.component.ts
@@ -642,7 +642,7 @@ export class NehubaGlueCmp implements IViewer<'nehuba'>, OnChanges, OnDestroy, A
           map(({ segments }) => segments)
         ),
         mouseOverNehubaUI: this.mouseoverDirective.currentOnHoverObs$.pipe(
-          map(({ landmark, segments, userLandmark: customLandmark }) => ({ segments, landmark, customLandmark })),
+          map(({annotation, landmark, segments, userLandmark: customLandmark }) => ({annotation, segments, landmark, customLandmark })),
           shareReplay(1),
         ),
         getNgHash : this.nehubaContainerDirective.nehubaViewerInstance.getNgHash,
diff --git a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.style.css b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.style.css
index a03d05dd199a30e712eb7062ee253473ae894552..c859c65655905d25cd4f65fe332d3c3567cc6868 100644
--- a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.style.css
+++ b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.style.css
@@ -29,3 +29,13 @@
 {
   background-color: rgba(0, 0, 0, 0.7);
 }
+
+.nehuba-viewer-container-parent
+{
+  z-index: 1;
+}
+
+current-layout
+{
+  z-index: 2;
+}
diff --git a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html
index 73aeec9212a1f91a1fa8c16ce1c047e655a0177d..104c5add581a8bcb216d1afe8d15b42002657938 100644
--- a/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html
+++ b/src/viewerModule/nehuba/nehubaViewerGlue/nehubaViewerGlue.template.html
@@ -1,4 +1,4 @@
-<div class="d-block w-100 h-100"
+<div class="d-block w-100 h-100 nehuba-viewer-container-parent"
   (touchmove)="$event.preventDefault()"
   (drag-drop-file)="handleFileDrop($event)"
   iav-viewer-touch-interface
@@ -122,7 +122,7 @@
   let-panelIndex="panelIndex"
   let-visible="visible">
 
-  <div class="opacity-crossfade always-show-touchdevice pe-all overlay-btn-container"
+  <div class="ws-no-wrap opacity-crossfade always-show-touchdevice pe-all overlay-btn-container"
     [ngClass]="{ onHover: visible }"
     [attr.data-viewer-controller-visible]="visible"
     [attr.data-viewer-controller-index]="panelIndex">
@@ -220,6 +220,7 @@
     <div *ngIf="data.moreInfoFlag"
       class="iv-custom-comp darker-bg overflow-hidden grid-wide-3">
       <ng-layer-tune
+        advanced-control="true"
         [ngLayerName]="data.layerName"
         [thresholdMin]="data.min"
         [thresholdMax]="data.max">
diff --git a/src/viewerModule/nehuba/statusCard/statusCard.component.ts b/src/viewerModule/nehuba/statusCard/statusCard.component.ts
index a6daa233d6acdc5197d19d4a9dbc284c3e26f329..6ac175a1d93dba044ed00e3a7d5e09bc6857dd31 100644
--- a/src/viewerModule/nehuba/statusCard/statusCard.component.ts
+++ b/src/viewerModule/nehuba/statusCard/statusCard.component.ts
@@ -11,7 +11,7 @@ import { select, Store } from "@ngrx/store";
 import { LoggingService } from "src/logging";
 import { NehubaViewerUnit } from "../nehubaViewer/nehubaViewer.component";
 import { Observable, Subscription, of, combineLatest } from "rxjs";
-import { map, filter, startWith } from "rxjs/operators";
+import { map, filter, startWith, throttleTime } from "rxjs/operators";
 import { MatBottomSheet } from "@angular/material/bottom-sheet";
 import { MatDialog } from "@angular/material/dialog";
 import { ARIA_LABELS, QUICKTOUR_DESC } from 'common/constants'
@@ -50,7 +50,6 @@ export class StatusCardComponent implements OnInit, OnChanges{
   public navVal$: Observable<string>
   public mouseVal$: Observable<string>
 
-  public useTouchInterface$: Observable<boolean>
 
   public quickTourData: IQuickTourData = {
     description: QUICKTOUR_DESC.STATUS_CARD,
@@ -70,7 +69,6 @@ export class StatusCardComponent implements OnInit, OnChanges{
     private dialog: MatDialog,
     @Optional() @Inject(NEHUBA_INSTANCE_INJTKN) nehubaViewer$: Observable<NehubaViewerUnit>
   ) {
-    this.useTouchInterface$ = of(true) //this.pureConstantService.useTouchUI$
 
     if (nehubaViewer$) {
       this.subscriptions.push(
@@ -128,10 +126,12 @@ export class StatusCardComponent implements OnInit, OnChanges{
       this.mouseVal$ = combineLatest([
         this.statusPanelRealSpace$,
         this.nehubaViewer.mousePosInReal$.pipe(
-          filter(v => !!v)
+          filter(v => !!v),
+          throttleTime(16)
         ),
         this.nehubaViewer.mousePosInVoxel$.pipe(
-          filter(v => !!v)
+          filter(v => !!v),
+          throttleTime(16)
         )
       ]).pipe(
         map(([realFlag, real, voxel]) => realFlag
diff --git a/src/viewerModule/nehuba/statusCard/statusCard.template.html b/src/viewerModule/nehuba/statusCard/statusCard.template.html
index 69d2a44547d2761e2c20c96f5a7d1bb155dcf535..d3086513b1c12eb6207f9b142a66777cb59cde88 100644
--- a/src/viewerModule/nehuba/statusCard/statusCard.template.html
+++ b/src/viewerModule/nehuba/statusCard/statusCard.template.html
@@ -89,7 +89,7 @@
       </div>
 
       <!-- cursor pos -->
-      <mat-form-field *ngIf="!(useTouchInterface$ | async)"
+      <mat-form-field
         class="w-100">
         <mat-label>
           Cursor Position
@@ -115,17 +115,6 @@
       {{ navVal$ | async }}
     </span>
 
-    <!-- only show cursor if touch interface is not on -->
-    <span *ngIf="false && !(useTouchInterface$ | async)">
-      <!-- padding -->
-      <span class="pl-4"></span>
-
-      <i aria-label="cursor location" class="fas fa-mouse-pointer"></i>
-      <span class="pl2">
-        {{ mouseVal$ | async }}
-      </span>
-    </span>
-
     <mat-divider [vertical]="true"></mat-divider>
 
     <button mat-icon-button
diff --git a/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.spec.ts b/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.spec.ts
index 44a1fb490ccdfeb69020a48fa9a25154ef92a9dd..54b6e08fa3d70dea75042b7372251e8be51e2de7 100644
--- a/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.spec.ts
+++ b/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.spec.ts
@@ -7,7 +7,7 @@ import { ComponentsModule } from "src/components"
 import { ngViewerSelectorOctantRemoval } from "src/services/state/ngViewerState.store.helper"
 import { viewerStateCustomLandmarkSelector, viewerStateSelectedTemplatePureSelector } from "src/services/state/viewerState/selectors"
 import { AngularMaterialModule } from "src/sharedModules"
-import { UtilModule } from "src/util"
+import {PureContantService, UtilModule} from "src/util"
 import { actionSetAuxMeshes, selectorAuxMeshes } from "../../store"
 import { NEHUBA_INSTANCE_INJTKN } from "../../util"
 import { ViewerCtrlCmp } from "./viewerCtrlCmp.component"
@@ -20,12 +20,31 @@ describe('> viewerCtrlCmp.component.ts', () => {
     let fixture: ComponentFixture<ViewerCtrlCmp>
     let loader: HarnessLoader
     let mockStore: MockStore
+
     let mockNehubaViewer = {
-      updateUserLandmarks: jasmine.createSpy()
+      updateUserLandmarks: jasmine.createSpy(),
+      nehubaViewer: {
+        ngviewer: {
+          layerManager: {
+            getLayerByName: jasmine.createSpy('getLayerByName'),
+            get managedLayers() {
+              return []
+            },
+            set managedLayers(val) {
+              return
+            }
+          },
+          display: {
+            scheduleRedraw: jasmine.createSpy('scheduleRedraw')
+          }
+        }
+      }
     }
 
     afterEach(() => {
       mockNehubaViewer.updateUserLandmarks.calls.reset()
+      mockNehubaViewer.nehubaViewer.ngviewer.layerManager.getLayerByName.calls.reset()
+      mockNehubaViewer.nehubaViewer.ngviewer.display.scheduleRedraw.calls.reset()
     })
 
     beforeEach( async () => {
@@ -43,7 +62,17 @@ describe('> viewerCtrlCmp.component.ts', () => {
           provideMockStore(),
           {
             provide: NEHUBA_INSTANCE_INJTKN,
-            useValue: new BehaviorSubject(mockNehubaViewer)
+            useFactory: () => {
+              return new BehaviorSubject(mockNehubaViewer).asObservable()
+            }
+          },
+          {
+            provide: PureContantService,
+            useFactory: () => {
+              return {
+                getViewerConfig: jasmine.createSpy('getViewerConfig')
+              }
+            }
           }
         ]
       }).compileComponents()
@@ -54,12 +83,12 @@ describe('> viewerCtrlCmp.component.ts', () => {
       mockStore.overrideSelector(viewerStateSelectedTemplatePureSelector, {})
       mockStore.overrideSelector(ngViewerSelectorOctantRemoval, true)
       mockStore.overrideSelector(viewerStateCustomLandmarkSelector, [])
+      mockStore.overrideSelector(selectorAuxMeshes, [])
     })
 
     describe('> can be init', () => {
 
       beforeEach(() => {
-        mockStore.overrideSelector(selectorAuxMeshes, [])
         fixture = TestBed.createComponent(ViewerCtrlCmp)
         fixture.detectChanges()
         loader = TestbedHarnessEnvironment.loader(fixture)
@@ -207,5 +236,120 @@ 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/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.ts b/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.ts
index cbe0380a6c5a06350b7ec29287072094343a25c2..d46a84cfab7d129e94d0c542fd718fa7390e0b6c 100644
--- a/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.ts
+++ b/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.component.ts
@@ -1,15 +1,16 @@
 import { Component, HostBinding, Inject, Optional } from "@angular/core";
 import { select, Store } from "@ngrx/store";
 import { combineLatest, merge, Observable, of, Subscription } from "rxjs";
-import { filter, map, pairwise, withLatestFrom } from "rxjs/operators";
+import {filter, map, pairwise, withLatestFrom} from "rxjs/operators";
 import { ngViewerActionSetPerspOctantRemoval } from "src/services/state/ngViewerState/actions";
 import { ngViewerSelectorOctantRemoval } from "src/services/state/ngViewerState/selectors";
-import { viewerStateCustomLandmarkSelector, viewerStateSelectedTemplatePureSelector } from "src/services/state/viewerState/selectors";
+import { viewerStateCustomLandmarkSelector, viewerStateGetSelectedAtlas, viewerStateSelectedTemplatePureSelector } from "src/services/state/viewerState/selectors";
 import { NehubaViewerUnit } from "src/viewerModule/nehuba";
 import { NEHUBA_INSTANCE_INJTKN } from "src/viewerModule/nehuba/util";
 import { ARIA_LABELS } from 'common/constants'
 import { actionSetAuxMeshes, selectorAuxMeshes } from "../../store";
 import { FormBuilder, FormControl, FormGroup } from "@angular/forms";
+import {PureContantService} from "src/util";
 
 @Component({
   selector: 'viewer-ctrl-component',
@@ -27,6 +28,9 @@ export class ViewerCtrlCmp{
   @HostBinding('attr.darktheme')
   darktheme = false
 
+  private selectedAtlasId: string
+  private selectedTemplateId: string
+
   private _flagDelin = true
   get flagDelin(){
     return this._flagDelin
@@ -44,6 +48,7 @@ export class ViewerCtrlCmp{
     return this._removeOctantFlag
   }
   set removeOctantFlag(val){
+    if (val === this._removeOctantFlag) return
     this._removeOctantFlag = val
     this.setOctantRemoval(this._removeOctantFlag)
   }
@@ -68,9 +73,16 @@ export class ViewerCtrlCmp{
     select(selectorAuxMeshes),
   )
 
+  private nehubaInst: NehubaViewerUnit
+
+  get ngViewer() {
+    return this.nehubaInst?.nehubaViewer.ngviewer || (window as any).viewer
+  }
+
   constructor(
     private store$: Store<any>,
     formBuilder: FormBuilder,
+    private pureConstantService: PureContantService,
     @Optional() @Inject(NEHUBA_INSTANCE_INJTKN) private nehubaInst$: Observable<NehubaViewerUnit>,
   ){
 
@@ -83,20 +95,25 @@ export class ViewerCtrlCmp{
           this.customLandmarks$,
           this.nehubaInst$,
         ]).pipe(
-          filter(([_, neubaInst]) => !!neubaInst),
+          filter(([_, nehubaInst]) => !!nehubaInst),
         ).subscribe(([landmarks, nehubainst]) => {
           this.setOctantRemoval(landmarks.length === 0)
           nehubainst.updateUserLandmarks(landmarks)
-        })
+        }),
+        this.nehubaInst$.subscribe(nehubaInst => this.nehubaInst = nehubaInst)
       )
     } else {
       console.warn(`NEHUBA_INSTANCE_INJTKN not provided`)
     }
 
     this.sub.push(
+      this.store$.select(viewerStateGetSelectedAtlas)
+        .pipe(filter(a => !!a))
+        .subscribe(sa => this.selectedAtlasId = sa['@id']),
       this.store$.pipe(
         select(viewerStateSelectedTemplatePureSelector)
       ).subscribe(tmpl => {
+        this.selectedTemplateId = tmpl['@id']
         const { useTheme } = tmpl || {}
         this.darktheme = useTheme === 'dark'
       }),
@@ -152,29 +169,32 @@ export class ViewerCtrlCmp{
     )
   }
 
-  private toggleParcVsbl(){
-    const visibleParcLayers = ((window as any).viewer.layerManager.managedLayers)
-      .slice(1)
-      .filter(({ visible }) => visible)
-      .filter(layer => !this.auxMeshesNamesSet.has(layer.name))
+  private async toggleParcVsbl(){
+    const viewerConfig = await this.pureConstantService.getViewerConfig(this.selectedAtlasId, this.selectedTemplateId, null)
 
     if (this.flagDelin) {
       for (const name of this.hiddenLayerNames) {
-        const l = (window as any).viewer.layerManager.getLayerByName(name)
+        const l = this.ngViewer.layerManager.getLayerByName(name)
         l && l.setVisible(true)
       }
       this.hiddenLayerNames = []
     } else {
       this.hiddenLayerNames = []
-      for (const { name } of visibleParcLayers) {
-        const l = (window as any).viewer.layerManager.getLayerByName(name)
+      const segLayerNames: string[] = []
+      for (const layer of this.ngViewer.layerManager.managedLayers) {
+        if (layer.visible && layer.name in viewerConfig) {
+          segLayerNames.push(layer.name)
+        }
+      }
+      for (const name of segLayerNames) {
+        const l = this.ngViewer.layerManager.getLayerByName(name)
         l && l.setVisible(false)
         this.hiddenLayerNames.push( name )
       }
     }
-    
-    setTimeout(() => {
-      (window as any).viewer.display.scheduleRedraw()
+
+    requestAnimationFrame(() => {
+      this.ngViewer.display.scheduleRedraw()
     })
   }
 
diff --git a/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.template.html b/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.template.html
index 60a004bbd682af81cecb8244ce2207d42a85c55e..76aa348a8f659039b6c0ece363db4a79921be756 100644
--- a/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.template.html
+++ b/src/viewerModule/nehuba/viewerCtrl/viewerCtrlCmp/viewerCtrlCmp.template.html
@@ -8,8 +8,8 @@
   (iav-key-event)="delinToggle.toggle()"
   name="toggle-delineation">
 
-  <markdown-dom class="d-inline-block iv-custom-comp text">
-    Show delineations `[q]`
+  <markdown-dom class="d-inline-block iv-custom-comp text"
+    markdown="Show delineations `[q]`">
   </markdown-dom>
 </mat-slide-toggle>
 
diff --git a/src/viewerModule/threeSurfer/threeSurferGlue/threeSurfer.template.html b/src/viewerModule/threeSurfer/threeSurferGlue/threeSurfer.template.html
index c1981ce4f144361f24e86026bf15de4d063f89fc..31f59c7293be5be213c6634d42722f4cb852bf45 100644
--- a/src/viewerModule/threeSurfer/threeSurferGlue/threeSurfer.template.html
+++ b/src/viewerModule/threeSurfer/threeSurferGlue/threeSurfer.template.html
@@ -42,8 +42,8 @@
       {{ mode.name }}
     </span>
     <markdown-dom *ngIf="mode.name === selectedMode"
-      class="d-inline-block">
-      `[q]`
+      class="d-inline-block"
+      markdown="`[q]`">
     </markdown-dom>
   </button>
 </mat-menu>
diff --git a/src/viewerModule/viewerCmp/viewerCmp.component.ts b/src/viewerModule/viewerCmp/viewerCmp.component.ts
index fc946ca3f2a946852d1a19093fb35a359d5dd2b7..68b8a93746f8cc72d2c29750e8b73aee581f12eb 100644
--- a/src/viewerModule/viewerCmp/viewerCmp.component.ts
+++ b/src/viewerModule/viewerCmp/viewerCmp.component.ts
@@ -1,7 +1,7 @@
-import { Component, ComponentFactory, ComponentFactoryResolver, ElementRef, Inject, Injector, Input, OnDestroy, Optional, TemplateRef, ViewChild, ViewContainerRef } from "@angular/core";
+import { ChangeDetectionStrategy, ChangeDetectorRef, Component, ComponentFactory, ComponentFactoryResolver, Inject, Injector, Input, OnDestroy, Optional, TemplateRef, ViewChild, ViewContainerRef } from "@angular/core";
 import { select, Store } from "@ngrx/store";
-import {combineLatest, merge, NEVER, Observable, of, Subject, Subscription} from "rxjs";
-import {catchError, debounceTime, distinctUntilChanged, filter, map, shareReplay, startWith, switchMap } from "rxjs/operators";
+import { combineLatest, merge, NEVER, Observable, of, Subscription } from "rxjs";
+import {catchError, debounceTime, distinctUntilChanged, map, shareReplay, startWith, switchMap } from "rxjs/operators";
 import { viewerStateSetSelectedRegions } from "src/services/state/viewerState/actions";
 import {
   viewerStateContextedSelectedRegionsSelector,
@@ -14,9 +14,7 @@ import {
 import { CONST, ARIA_LABELS, QUICKTOUR_DESC } from 'common/constants'
 import { OVERWRITE_SHOW_DATASET_DIALOG_TOKEN, REGION_OF_INTEREST } from "src/util/interfaces";
 import { animate, state, style, transition, trigger } from "@angular/animations";
-import { SwitchDirective } from "src/util/directives/switch.directive";
-import { QuickTourThis, IQuickTourData } from "src/ui/quickTour";
-import { MatDrawer } from "@angular/material/sidenav";
+import { IQuickTourData } from "src/ui/quickTour";
 import { PureContantService } from "src/util";
 import { EnumViewerEvt, TContextArg, TSupportedViewers, TViewerEvent } from "../viewer.interface";
 import { getGetRegionFromLabelIndexId, switchMapWaitFor } from "src/util/fn";
@@ -26,6 +24,7 @@ import { MAT_DIALOG_DATA } from "@angular/material/dialog";
 import { GenericInfoCmp } from "src/atlasComponents/regionalFeatures/bsFeatures/genericInfo";
 import { _PLI_VOLUME_INJ_TOKEN, _TPLIVal } from "src/glue";
 import { uiActionSetPreviewingDatasetFiles } from "src/services/state/uiState.store.helper";
+import { viewerStateSetViewerMode } from "src/services/state/viewerState.store.helper";
 import { DialogService } from "src/services/dialogService.service";
 
 type TCStoreViewerCmp = {
@@ -116,7 +115,8 @@ export function ROIFactory(store: Store<any>, svc: PureContantService){
     },
     ComponentStore,
     DialogService
-  ]
+  ],
+  changeDetection: ChangeDetectionStrategy.OnPush
 })
 
 export class ViewerCmp implements OnDestroy {
@@ -127,12 +127,6 @@ export class ViewerCmp implements OnDestroy {
   public CONST = CONST
   public ARIA_LABELS = ARIA_LABELS
 
-  @ViewChild('sideNavTopSwitch', { static: true })
-  private sidenavTopSwitch: SwitchDirective
-
-  @ViewChild('sideNavFullLeftSwitch', { static: true })
-  private sidenavLeftSwitch: SwitchDirective
-
   @ViewChild('genericInfoVCR', { read: ViewContainerRef })
   genericInfoVCR: ViewContainerRef
 
@@ -172,6 +166,7 @@ export class ViewerCmp implements OnDestroy {
 
   public viewerMode$: Observable<string> = this.store$.pipe(
     select(viewerStateViewerModeSelector),
+    shareReplay(1),
   )
 
   public overlaySidenav$ = this.cStore.select(s => s.overlaySideNav).pipe(
@@ -190,12 +185,8 @@ export class ViewerCmp implements OnDestroy {
       return 'notsupported'
     })
   )
-
-  /**
-   * TODO may need to be deprecated
-   * in favour of regional feature/data feature
-   */
-  public iavAdditionalLayers$ = new Subject<any[]>()
+  
+  public pliVol$ = this._pliVol$ || NEVER
 
   /**
    * if no regions are selected, nor any additional layers (being deprecated)
@@ -203,13 +194,16 @@ export class ViewerCmp implements OnDestroy {
    * and the full left side bar should not be expandable
    * if it is already expanded, it should collapse
    */
-  public alwaysHideMinorPanel$: Observable<boolean> = combineLatest([
+  public onlyShowMiniTray$: Observable<boolean> = combineLatest([
     this.selectedRegions$,
-    this.iavAdditionalLayers$.pipe(
+    this.pliVol$.pipe(
       startWith([])
-    )
+    ),
+    this.viewerMode$.pipe(
+      startWith(null as string)
+    ),
   ]).pipe(
-    map(([ regions, layers ]) => regions.length === 0 && layers.length === 0)
+    map(([ regions, layers, viewerMode ]) => regions.length === 0 && layers.length === 0 && !viewerMode)
   )
 
   @ViewChild('viewerStatusCtxMenu', { read: TemplateRef })
@@ -224,7 +218,6 @@ export class ViewerCmp implements OnDestroy {
 
   private genericInfoCF: ComponentFactory<GenericInfoCmp>
 
-  public pliVol$ = this._pliVol$ || NEVER
   public clearVoi(){
     this.store$.dispatch(
       uiActionSetPreviewingDatasetFiles({
@@ -238,6 +231,7 @@ export class ViewerCmp implements OnDestroy {
     private cStore: ComponentStore<TCStoreViewerCmp>,
     cfr: ComponentFactoryResolver,
     private dialogSvc: DialogService,
+    private cdr: ChangeDetectorRef,
     @Optional() @Inject(_PLI_VOLUME_INJ_TOKEN) private _pliVol$: Observable<_TPLIVal[]>,
     @Optional() @Inject(REGION_OF_INTEREST) public regionOfInterest$: Observable<any>
   ){
@@ -245,24 +239,9 @@ export class ViewerCmp implements OnDestroy {
     this.genericInfoCF = cfr.resolveComponentFactory(GenericInfoCmp)
 
     this.subscriptions.push(
-      this.pliVol$.subscribe(val => {
-        if (val.length > 0) {
-          this.sidenavTopSwitch && this.sidenavTopSwitch.open()
-          this.sidenavLeftSwitch && this.sidenavLeftSwitch.open()
-        } else {
-          this.sidenavTopSwitch && this.sidenavTopSwitch.close()
-          this.sidenavLeftSwitch && this.sidenavLeftSwitch.close()
-        }
-      }),
       this.selectedRegions$.subscribe(() => {
         this.clearPreviewingDataset()
       }),
-      this.alwaysHideMinorPanel$.pipe(
-        distinctUntilChanged(),
-        filter(flag => !flag),
-      ).subscribe(() => {
-        this.openSideNavs()
-      }),
       this.viewerModuleSvc.context$.subscribe(
         (ctx: any) => this.context = ctx
       ),
@@ -397,7 +376,7 @@ export class ViewerCmp implements OnDestroy {
 
         this.genericInfoVCR.clear()
         this.genericInfoVCR.createComponent(this.genericInfoCF, null, injector)
-
+        this.cdr.markForCheck()
       })
     )
   }
@@ -415,13 +394,12 @@ export class ViewerCmp implements OnDestroy {
     )
   }
 
-  public handleChipClick(){
-    this.openSideNavs()
-  }
-
-  private openSideNavs() {
-    this.sidenavLeftSwitch && this.sidenavLeftSwitch.open()
-    this.sidenavTopSwitch && this.sidenavTopSwitch.open()
+  public exitSpecialViewMode(){
+    this.store$.dispatch(
+      viewerStateSetViewerMode({
+        payload: null
+      })
+    )
   }
 
   public clearPreviewingDataset(){
@@ -433,21 +411,6 @@ export class ViewerCmp implements OnDestroy {
     })
   }
 
-  @ViewChild('regionSelRef', { read: ElementRef })
-  regionSelRef: ElementRef<any>
-
-  @ViewChild('regionSearchQuickTour', { read: QuickTourThis })
-  regionSearchQuickTour: QuickTourThis
-
-  @ViewChild('matDrawerLeft', { read: MatDrawer })
-  matDrawerLeft: MatDrawer
-
-  handleSideNavAnimationDone(sideNavExpanded: boolean) {
-    this.regionSearchQuickTour?.attachTo(
-      !sideNavExpanded ? null : this.regionSelRef
-    )
-  }
-
   public handleViewerEvent(event: TViewerEvent<'nehuba' | 'threeSurfer'>){
     switch(event.type) {
     case EnumViewerEvt.VIEWERLOADED:
diff --git a/src/viewerModule/viewerCmp/viewerCmp.style.css b/src/viewerModule/viewerCmp/viewerCmp.style.css
index 19b64d6b88116e5954dd0fb2226e6fc79b3dcc01..6633b28f8ec233a078953ba66fbb6c73877b2274 100644
--- a/src/viewerModule/viewerCmp/viewerCmp.style.css
+++ b/src/viewerModule/viewerCmp/viewerCmp.style.css
@@ -49,3 +49,13 @@ mat-drawer
 {
   overflow-x: hidden;
 }
+
+.transition-margin-left
+{
+  transition: margin-left 200ms cubic-bezier(0.35, 0, 0.25, 1);
+}
+
+._pli-container
+{
+  padding-top: 5rem;
+}
diff --git a/src/viewerModule/viewerCmp/viewerCmp.template.html b/src/viewerModule/viewerCmp/viewerCmp.template.html
index b77622c13103c80c4ccc5e2c938ccd1bca2a97d1..abb3c1c34715215fae7f6d98ed850d1804436bbd 100644
--- a/src/viewerModule/viewerCmp/viewerCmp.template.html
+++ b/src/viewerModule/viewerCmp/viewerCmp.template.html
@@ -3,133 +3,221 @@
   </ng-container>
 </div>
 
-<layout-floating-container [zIndex]="10">
-
-  <!-- Annotation mode -->
-    <mat-drawer-container *ngIf="viewerMode$ | async as viewerMode"
-      class="mat-drawer-content-overflow-visible w-100 h-100 position-absolute invisible"
-      [hasBackdrop]="false">
-      
-      <mat-drawer #viewerModeDrawer="matDrawer"
-        mode="side"
-        (annotation-event-directive)="viewerModeDrawer.open()"
-        [annotation-event-directive-filter]="['showList']"
-        [autoFocus]="false"
-        [disableClose]="true"
-        class="p-0 pe-all col-10 col-sm-10 col-md-5 col-lg-4 col-xl-3 col-xxl-2">
-
-        <!-- annotation -->
-        <ng-template [ngIf]="viewerMode === ARIA_LABELS.VIEWER_MODE_ANNOTATING">
-          <annotation-list></annotation-list>
-        </ng-template>
 
-        <ng-template [ngIf]="viewerMode === ARIA_LABELS.VIEWER_MODE_KEYFRAME">
-          <key-frame-controller></key-frame-controller>
+<!-- master draw container -->
+<mat-drawer-container
+  *ngIf="viewerLoaded"
+  iav-switch
+  [iav-switch-state]="!(onlyShowMiniTray$ | async)"
+  #showFullSidenavSwitch="iavSwitch"
+  class="position-absolute w-100 h-100 mat-drawer-content-overflow-visible invisible"
+  [hasBackdrop]="false">
+  
+  <!-- master drawer -->
+  <mat-drawer
+    mode="side"
+    #drawer="matDrawer"
+    [opened]="!(onlyShowMiniTray$ | async)"
+    [@openClose]="showFullSidenavSwitch && (showFullSidenavSwitch.switchState$ | async) ? 'open' : 'closed'"
+    (@openClose.start)="$event.toState === 'open' && drawer.open()"
+    (@openClose.done)="$event.toState === 'closed' && drawer.close()"
+    [autoFocus]="false"
+    [disableClose]="true"
+    class="iv-custom-comp darker-bg p-0 pe-all col-10 col-sm-10 col-md-5 col-lg-4 col-xl-3 col-xxl-2 z-index-10">
+
+    <!-- entry template -->
+    <ng-template [ngIf]="viewerMode$ | async" let-mode [ngIfElse]="regularTmpl">
+      <ng-template [ngTemplateOutlet]="alternateModeDrawerTmpl"
+        [ngTemplateOutletContext]="{
+          mode: mode
+        }"></ng-template>
+    </ng-template>
+
+    <!-- regular mode  -->
+    <ng-template #regularTmpl>
+      <ng-template
+        [ngTemplateOutlet]="regularModeDrawerTmpl"
+        [ngTemplateOutletContext]="{
+          drawer: drawer,
+          showFullSidenavSwitch: showFullSidenavSwitch
+        }">
+      </ng-template>
+    </ng-template>
+  </mat-drawer>
+
+  <!-- master content -->
+  <mat-drawer-content class="visible pe-none position-relative">
+    <iav-layout-fourcorners>
+
+      <!-- top left -->
+      <div iavLayoutFourCornersTopLeft class="ws-no-wrap">
+
+        <!-- special mode -->
+        <ng-template [ngIf]="viewerMode$ | async" let-mode [ngIfElse]="defaultTopLeftTmpl">
+          <ng-template [ngTemplateOutlet]="specialModeTopLeftTmpl"
+            [ngTemplateOutletContext]="{
+              mode: mode,
+              toggleMatDrawer: drawer.toggle.bind(drawer)
+            }">
+          </ng-template>
         </ng-template>
 
-      </mat-drawer>
-      <mat-drawer-content class="visible position-relative pe-none">
+        <!-- default mode top left tmpl -->
+        <ng-template #defaultTopLeftTmpl>
+          <ng-template [ngTemplateOutlet]="defaultMainContentTopLeft"
+            [ngTemplateOutletContext]="{
+              isOpen: drawer.opened,
+              drawer: drawer,
+              showFullSidenavSwitch: showFullSidenavSwitch
+            }">
+          </ng-template>
+        </ng-template>
+      </div>
 
-        <!-- annotation specific -->
-        <iav-layout-fourcorners *ngIf="viewerMode === ARIA_LABELS.VIEWER_MODE_ANNOTATING">
-          <!-- pullable tab top right corner -->
-          <div iavLayoutFourCornersTopLeft class="tab-toggle-container">
+      <!-- top right -->
+      <div iavLayoutFourCornersTopRight class="ws-no-wrap">
 
-            <ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
-              matColor: 'primary',
-              fontIcon: 'fa-list',
-              tooltip: 'Annotation list',
-              click: viewerModeDrawer.toggle.bind(viewerModeDrawer),
-              badge: toolPanel?.annBadges$ | async
+        <!-- exit special mode -->
+        <ng-template [ngIf]="viewerMode$ | async" let-mode [ngIfElse]="defaultTopRightTmpl">
+          <ng-template [ngTemplateOutlet]="specialTopRightTmpl"
+            [ngTemplateOutletContext]="{
+              mode: mode
             }">
-            </ng-container>
-
-            <annotating-tools-panel class="z-index-10"
-              #toolPanel="annoToolsPanel">
-            </annotating-tools-panel>
-          </div>
-
-          <div iavLayoutFourCornersTopRight>
-            <mat-card class="mat-card-sm pe-all m-4">
-              <span>
-                Annotating
-              </span>
-              <button mat-icon-button
-                [matTooltip]="ARIA_LABELS.EXIT_ANNOTATION_MODE"
-                color="warn"
-                annotation-switch
-                annotation-switch-mode="off">
-                <i class="fas fa-times"></i>
-              </button>
-            </mat-card>
-          </div>
-
-        </iav-layout-fourcorners>
-
-
-        <!-- key frame specific -->
-        <iav-layout-fourcorners *ngIf="viewerMode === ARIA_LABELS.VIEWER_MODE_KEYFRAME">
-          <!-- pullable tab top right corner -->
-          <div iavLayoutFourCornersTopLeft class="tab-toggle-container">
-
-            <ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
-              matColor: 'primary',
-              fontIcon: 'fa-play',
-              tooltip: 'Annotation list',
-              click: viewerModeDrawer.toggle.bind(viewerModeDrawer)
+          </ng-template>
+        </ng-template>
+        
+        <!-- default mode top right tmpl -->
+        <ng-template #defaultTopRightTmpl>
+          <ng-template [ngTemplateOutlet]="minDefaultMainContentTopRight">
+          </ng-template>
+        </ng-template>
+      </div>
+
+
+      <!-- bottom left -->
+      <div iavLayoutFourCornersBottomLeft class="ws-no-wrap d-inline-flex w-100vw pe-none align-items-center mb-4">
+
+        <!-- special bottom left -->
+        <ng-template [ngIf]="viewerMode$ | async" let-mode [ngIfElse]="localBottomLeftTmpl"></ng-template>
+        
+        <!-- default mode bottom left tmpl -->
+        <ng-template #localBottomLeftTmpl>
+
+          <!-- not the most elegant, but it's a hard problem to solve -->
+          <!-- on the one hand, showFullSidenavSwitch can be of two states -->
+          <!-- and drawer.opened can be of two states -->
+          <ng-template [ngTemplateOutlet]="bottomLeftTmpl"
+            [ngTemplateOutletContext]="{
+              showFullSideNav: (showFullSidenavSwitch.switchState$ | async)
+                ? drawer.open.bind(drawer)
+                : showFullSidenavSwitch.open.bind(showFullSidenavSwitch)
             }">
-            </ng-container>
-          </div>
-
-          <div iavLayoutFourCornersTopRight>
-            <mat-card class="mat-card-sm pe-all m-4">
-              <span>
-                Key Frame
-              </span>
-              <button mat-icon-button
-                color="warn"
-                key-frame-play-now="off">
-                <i class="fas fa-times"></i>
-              </button>
-            </mat-card>
-          </div>
-
-        </iav-layout-fourcorners>
-      </mat-drawer-content>
-
-    </mat-drawer-container>
-
-  <!-- top drawer -->
-  <mat-drawer-container
-    [hidden]="viewerMode$ | async"
-    [iav-switch-initstate]="false"
-    iav-switch
-    #sideNavTopSwitch="iavSwitch"
-    class="mat-drawer-content-overflow-visible w-100 h-100 position-absolute invisible"
-    [hasBackdrop]="false">
-
-    <!-- sidenav-content -->
-
-    <!-- (closedStart)="sideNavwFullLeftSwitch.switchState && matDrawerLeft.close()"
-    (openedStart)="sideNavFullLeftSwitch.switchState && matDrawerLeft.open()" -->
-    <mat-drawer class="box-shadow-none border-0 pe-none bg-none col-10 col-sm-10 col-md-5 col-lg-4 col-xl-3 col-xxl-2"
-      mode="side"
-      [attr.data-mat-drawer-top-open]="matDrawerTop.opened"
-      [opened]="sideNavTopSwitch.switchState"
-      [autoFocus]="false"
-      [disableClose]="true"
-      (openedChange)="handleSideNavAnimationDone($event)"
-      #matDrawerTop="matDrawer">
-
-      <div class="h-0 w-100 region-text-search-autocomplete-position">
-        <ng-container *ngTemplateOutlet="autocompleteTmpl; context: { showTour: true }">
-        </ng-container>
+          </ng-template>
+        </ng-template>
+        
       </div>
+    </iav-layout-fourcorners>
+  </mat-drawer-content>
+</mat-drawer-container>
+
+<!-- alternate mode drawer tmpl -->
+<ng-template #alternateModeDrawerTmpl let-mode="mode">
+  <ng-container [ngSwitch]="mode">
+    <annotation-list *ngSwitchCase="ARIA_LABELS.VIEWER_MODE_ANNOTATING">
+    </annotation-list>
+    <key-frame-controller *ngSwitchCase="ARIA_LABELS.VIEWER_MODE_KEYFRAME">
+    </key-frame-controller>
+    <span *ngSwitchDefault>View mode {{ mode }} does not have side nav registered.</span>
+  </ng-container>
+</ng-template>
+
+
+<!-- regular mode drawer tmpl -->
+<ng-template #regularModeDrawerTmpl
+  let-drawer="drawer"
+  let-showFullSidenavSwitch="showFullSidenavSwitch">
+
+  <!-- check if preview volume -->
+  <ng-template [ngIf]="overlaySidenav$ | async" let-overlaySideNav>
+    
+    <!-- back btn -->
+    <button mat-button
+      (click)="clearPreviewingDataset()"
+      [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>
+
+    <ng-template #genericInfoVCR>
+    </ng-template>
+  </ng-template>
+
+  <div [ngClass]="{
+    'invisible overflow-hidden h-0': overlaySidenav$ | async,
+    'h-100': !(overlaySidenav$ | async)
+  }" class="pe-all position-relative d-flex flex-column">
+    
+
+  <!-- if pli voi is visible, show pli template
+  otherwise show region tmpl -->
+  <ng-template
+    [ngTemplateOutlet]="(pliVol$ | async)?.[0]
+      ? voiTmpl
+      : sidenavRegionTmpl"
+    [ngTemplateOutletContext]="{
+      drawer: drawer,
+      showFullSidenavSwitch: showFullSidenavSwitch
+    }">
+  </ng-template>
+
+    <!-- <ng-template let-pliVol [ngIf]="pliVol$ | async" [ngIfElse]="sidenavRegionTmpl">
+      <ng-template [ngIf]="pliVol.length > 0" [ngIfElse]="sidenavRegionTmpl">
+        <ng-template [ngTemplateOutlet]="voiTmpl">
+
+        </ng-template>
+      </ng-template>
+    </ng-template> -->
+
+    <!-- TODO dataset preview will become deprecated in the future.
+    Regional feature/data feature will replace it -->
+    <!-- <div class="hidden"
+      iav-shown-dataset
+      #iavShownDataset="iavShownDataset">
+    </div> -->
+
+  </div>
+</ng-template>
+
 
+<!-- minimal default drawer content -->
+<ng-template #minSearchTray
+  let-showFullSidenav="showFullSidenav"
+  let-drawer="drawer">
+
+  <div class="mt-2 d-inline-block vw-col-10 vw-col-sm-10 vw-col-md-5 vw-col-lg-4 vw-col-xl-3 vw-col-xxl-2"
+    iav-switch
+    [iav-switch-state]="true"
+    #minTrayVisSwitch="iavSwitch"
+    [ngClass]="{
+      'vw-col-10-nm vw-col-sm-10-nm vw-col-md-5-nm vw-col-lg-4-nm vw-col-xl-3-nm vw-col-xxl-2-nm': !(minTrayVisSwitch.switchState$ | async),
+      'transition-margin-left': !drawer.opened
+    }">
+
+    <div class="h-0 w-100 region-text-search-autocomplete-position">
+      <ng-container *ngTemplateOutlet="autocompleteTmpl; context: { showTour: true }">
+      </ng-container>
+    </div>
+
+    <!-- such a gross implementation -->
+    <!-- TODO fix this -->
+    <div class="mt-1-n w-100 pl-2 pr-2 m-1px">
       <button mat-raised-button
-        *ngIf="!(alwaysHideMinorPanel$ | async)"
+        *ngIf="!(onlyShowMiniTray$ | async)"
         [attr.aria-label]="ARIA_LABELS.EXPAND"
-        (click)="sideNavFullLeftSwitch && sideNavFullLeftSwitch.open()"
+        (click)="showFullSidenav()"
         class="explore-btn pe-all w-100"
         [ngClass]="{
           'darktheme': iavRegion.rgbDarkmode === true,
@@ -145,215 +233,205 @@
           [region]="(selectedRegions$ | async) && (selectedRegions$ | async)[0]"
           #iavRegion="iavRegion">
         </div>
-
       </button>
-    </mat-drawer>
-
-    <mat-drawer-content class="visible position-relative pe-none">
-
-      <iav-layout-fourcorners [iav-layout-fourcorners-cnr-cntr-ngclass]="{'w-100': true}">
-
-        <!-- pullable tab top left corner -->
-        <div iavLayoutFourCornersTopLeft class="d-flex flex-nowrap w-100">
-
-          <!-- top left -->
-          <div class="flex-grow-1 d-flex flex-nowrap align-items-start">
-
-            <div *ngIf="viewerLoaded"
-              class="pe-all tab-toggle-container"
-              (click)="sideNavTopSwitch && sideNavTopSwitch.toggle()"
-              quick-tour
-              [quick-tour-description]="quickTourRegionSearch.description"
-              [quick-tour-order]="quickTourRegionSearch.order"
-              #regionSearchQuickTour="quickTour">
-              <ng-container *ngTemplateOutlet="tabTmpl; context: {
-                isOpen: sideNavTopSwitch.switchState,
-                regionSelected: selectedRegions$ | async,
-                iavAdditionallayers: iavAdditionalLayers$ | async
-              }">
-              </ng-container>
-            </div>
-
-            <iav-cmp-viewer-nehuba-status *ngIf="(useViewer$ | async) === 'nehuba'"
-              class="pe-all mt-2 muted-7">
-            </iav-cmp-viewer-nehuba-status>
-          </div>
-
-          <!-- top right -->
-          <div class="flex-grow-0 d-inline-flex align-items-start">
-
-            <!-- signin banner at top right corner -->
-
-
-            <top-menu-cmp class="mt-3 mr-2 d-inline-block"
-              [ismobile]="ismobile"
-              [viewerLoaded]="viewerLoaded">
-            </top-menu-cmp>
-
-            <div *ngIf="viewerLoaded"
-              class="iv-custom-comp bg card m-2 mat-elevation-z2"
-              quick-tour
-              [quick-tour-description]="quickTourAtlasSelector.description"
-              [quick-tour-order]="quickTourAtlasSelector.order">
-              <atlas-dropdown-selector class="pe-all mt-2">
-              </atlas-dropdown-selector>
-            </div>
-          </div>
-        </div>
+    </div>
+  
+  </div>
 
-      </iav-layout-fourcorners>
+  <!-- tab toggling hide/show of min search tray -->
+  <div class="tab-toggle-container d-inline-block v-align-top">
+    <ng-container *ngTemplateOutlet="tabTmpl; context: {
+      isOpen: minTrayVisSwitch.switchState$ | async,
+      regionSelected: selectedRegions$ | async,
+      click: minTrayVisSwitch.toggle.bind(minTrayVisSwitch)
+    }">
+    </ng-container>
+  </div>
 
-    </mat-drawer-content>
-  </mat-drawer-container>
+</ng-template>
 
-  <!-- full left drawer -->
-  <mat-drawer-container
-    [hidden]="viewerMode$ | async"
-    [iav-switch-initstate]="!(alwaysHideMinorPanel$ | async)"
-    iav-switch
-    #sideNavFullLeftSwitch="iavSwitch"
-    class="mat-drawer-content-overflow-visible w-100 h-100 position-absolute invisible"
-    [hasBackdrop]="false">
-
-    <!-- sidenav-content -->
-    <mat-drawer class="darker-bg iv-custom-comp visible col-10 col-sm-10 col-md-5 col-lg-4 col-xl-3 col-xxl-2 d-flex flex-column pe-all"
-      mode="push"
-      [opened]="sideNavTopSwitch.switchState && sideNavFullLeftSwitch.switchState"
-      [attr.data-mat-drawer-fullleft-open]="matDrawerLeft.opened"
-      [autoFocus]="false"
-      #matDrawerLeft="matDrawer"
-      (openedChange)="$event && sideNavFullLeftSwitch.open()"
-      [@openClose]="sideNavTopSwitch.switchState && sideNavFullLeftSwitch.switchState ? 'open' : 'closed'"
-      (@openClose.done)="$event.toState === 'closed' && matDrawerLeft.close()"
-      [disableClose]="true">
-
-      <!-- check if preview volume -->
-      <div *ngIf="overlaySidenav$ | async as overlaySideNav" class="position-relative d-flex flex-column h-100">
-        <div class="position-relative ml-15px-n mr-15px-n">
-
-          <!-- back btn -->
-          <button mat-button
-            (click)="clearPreviewingDataset()"
-            [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>
 
-          <ng-template #genericInfoVCR>
-          </ng-template>
-        </div>
-      </div>
+<!-- top left -->
+<!-- default top left -->
+<ng-template #defaultMainContentTopLeft
+  let-isOpen="isOpen"
+  let-drawer="drawer"
+  let-showFullSidenavSwitch="showFullSidenavSwitch">
+
+  <!-- min search tray -->
+  <ng-template [ngIf]="!(showFullSidenavSwitch.switchState$ | async)">
+    <ng-template
+      [ngTemplateOutlet]="minSearchTray"
+      [ngTemplateOutletContext]="{
+        showFullSidenav: showFullSidenavSwitch.open.bind(showFullSidenavSwitch),
+        drawer: drawer
+      }">
+    </ng-template>
+  </ng-template>
 
-      <div [ngClass]="{
-        'invisible overflow-hidden h-0': overlaySidenav$ | async,
-        'h-100': !(overlaySidenav$ | async)
-      }" class="position-relative d-flex flex-column">
-        
-        <ng-template let-pliVol [ngIf]="pliVol$ | async" [ngIfElse]="sidenavRegionTmpl">
-          <ng-template [ngIf]="pliVol.length > 0" [ngIfElse]="sidenavRegionTmpl">
-            <ng-template [ngTemplateOutlet]="voiTmpl">
+  <!-- pullable tab top left corner -->
+  <div *ngIf="showFullSidenavSwitch.switchState$ | async"
+    class="v-align-top pe-all tab-toggle-container d-inline-block"
+    (click)="drawer.toggle()"
+    quick-tour
+    [quick-tour-description]="quickTourRegionSearch.description"
+    [quick-tour-order]="quickTourRegionSearch.order">
+    <ng-container *ngTemplateOutlet="tabTmpl; context: {
+      isOpen: isOpen,
+      regionSelected: selectedRegions$ | async
+    }">
+    </ng-container>
+  </div>
 
-            </ng-template>
-          </ng-template>
-        </ng-template>
+  <!-- status panel for (for nehuba viewer) -->
+  <iav-cmp-viewer-nehuba-status *ngIf="(useViewer$ | async) === 'nehuba'"
+    class="pe-all mt-2 muted-7 d-inline-block v-align-top">
+  </iav-cmp-viewer-nehuba-status>
+</ng-template>
 
-        <!-- TODO dataset preview will become deprecated in the future.
-        Regional feature/data feature will replace it -->
-        <!-- <div class="hidden"
-          iav-shown-dataset
-          #iavShownDataset="iavShownDataset">
-        </div> -->
 
-      </div>
-    </mat-drawer>
+<!-- special mode top left -->
+<ng-template #specialModeTopLeftTmpl
+  let-mode="mode"
+  let-toggleMatDrawer="toggleMatDrawer">
 
-    <!-- main-content -->
-    <mat-drawer-content class="visible position-relative" [hidden]="viewerMode$ | async">
+  <div class="tab-toggle-container">
 
-      <iav-layout-fourcorners [iav-layout-fourcorners-cnr-cntr-ngclass]="{'w-100': true}">
+    <ng-container [ngSwitch]="mode">
+      <!-- annotating top left -->
+      <ng-template [ngSwitchCase]="ARIA_LABELS.VIEWER_MODE_ANNOTATING">
+        <ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
+          matColor: 'primary',
+          fontIcon: 'fa-list',
+          tooltip: 'Annotation list',
+          click: toggleMatDrawer,
+          badge: toolPanel?.annBadges$ | async
+        }">
+        </ng-container>
+  
+        <annotating-tools-panel class="z-index-10 d-block"
+          #toolPanel="annoToolsPanel">
+        </annotating-tools-panel>
+      </ng-template>
 
-        <!-- bottom left corner (atlas selector and currently selected) -->
-        <div iavLayoutFourCornersBottomLeft class="d-inline-flex align-items-center mb-4 ml-2 w-100">
+      <ng-template [ngSwitchCase]="ARIA_LABELS.VIEWER_MODE_KEYFRAME">
 
-          <!-- atlas selector -->
-          <atlas-layer-selector *ngIf="viewerLoaded && !(isStandaloneVolumes$ | async)"
-            #alSelector="atlasLayerSelector"
-            (iav-outsideClick)="alSelector.selectorExpanded = false">
-          </atlas-layer-selector>
+        <ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
+          matColor: 'primary',
+          fontIcon: 'fa-play',
+          tooltip: 'Annotation list',
+          click: toggleMatDrawer
+        }">
+        </ng-container>
+      </ng-template>
+    </ng-container>
+  </div>
+</ng-template>
 
-          <!-- chips -->
-          <div *ngIf="parcellationSelected$ | async" class="flex-grow-0 p-1 pr-2 flex-shrink-1 overflow-y-hidden overflow-x-auto pe-all">
 
-            <viewer-state-breadcrumb
-              (on-item-click)="handleChipClick()">
-            </viewer-state-breadcrumb>
-          </div>
-        </div>
+<!-- top right -->
+<!-- default top right -->
+<ng-template #minDefaultMainContentTopRight>
 
-      </iav-layout-fourcorners>
+  <!-- signin banner at top right corner -->
+  <top-menu-cmp class="mt-3 mr-2 d-inline-block"
+    [ismobile]="ismobile"
+    [viewerLoaded]="viewerLoaded">
+  </top-menu-cmp>
 
-    </mat-drawer-content>
-  </mat-drawer-container>
+  <atlas-dropdown-selector
+    class="v-align-top pt-2 pe-all mt-2 iv-custom-comp bg card m-2 mat-elevation-z2 d-inline-block"
+    quick-tour
+    [quick-tour-description]="quickTourAtlasSelector.description"
+    [quick-tour-order]="quickTourAtlasSelector.order">
+  </atlas-dropdown-selector>
 
-</layout-floating-container>
+</ng-template>
 
-<!-- viewer tmpl -->
-<ng-template #viewerTmpl>
 
-  <iav-layout-fourcorners>
-    <div iavLayoutFourCornersContent
-      class="w-100 h-100 position-absolute">
-      <div class="h-100 w-100 overflow-hidden position-relative"
-        ctx-menu-host
-        [ctx-menu-host-tmpl]="viewerCtxMenuTmpl">
-
-        <ng-container [ngSwitch]="useViewer$ | async">
-
-          <!-- nehuba viewer -->
-          <iav-cmp-viewer-nehuba-glue class="d-block w-100 h-100 position-absolute left-0 top-0"
-            *ngSwitchCase="'nehuba'"
-            (viewerEvent)="handleViewerEvent($event)"
-            [selectedTemplate]="templateSelected$ | async"
-            [selectedParcellation]="parcellationSelected$ | async"
-            #iavCmpViewerNehubaGlue="iavCmpViewerNehubaGlue">
-          </iav-cmp-viewer-nehuba-glue>
-
-          <!-- three surfer (free surfer viewer) -->
-          <three-surfer-glue-cmp class="d-block w-100 h-100 position-absolute left-0 top-0"
-            *ngSwitchCase="'threeSurfer'"
-            (viewerEvent)="handleViewerEvent($event)"
-            [selectedTemplate]="templateSelected$ | async"
-            [selectedParcellation]="parcellationSelected$ | async">
-          </three-surfer-glue-cmp>
-
-          <!-- if not supported, show not supported message -->
-          <div *ngSwitchCase="'notsupported'">Template not supported by any of the viewers</div>
-
-          <!-- by default, show splash screen -->
-          <div *ngSwitchDefault>
-            <ui-splashscreen class="position-absolute left-0 top-0">
-            </ui-splashscreen>
-          </div>
-        </ng-container>
+<!-- special mode top right -->
+<ng-template #specialTopRightTmpl let-mode="mode">
+  <mat-card class="mat-card-sm pe-all m-4">
+    <span>
+      {{ mode }}
+    </span>
+    <button mat-icon-button
+      color="warn"
+      (click)="exitSpecialViewMode()">
+      <i class="fas fa-times"></i>
+    </button>
+  </mat-card>
+</ng-template>
+
+<!-- bottom left -->
+<ng-template #bottomLeftTmpl let-showFullSideNav="showFullSideNav">
+
+  <!-- atlas selector -->
+  <atlas-layer-selector *ngIf="viewerLoaded && !(isStandaloneVolumes$ | async)"
+    #alSelector="atlasLayerSelector"
+    class="d-inline-block flex-grow-0 flex-shrink-0 pe-all"
+    (iav-outsideClick)="alSelector.selectorExpanded = false">
+  </atlas-layer-selector>
+
+  <!-- chips -->
+  <div *ngIf="parcellationSelected$ | async"
+    class="d-inline-block flex-grow-1 flex-shrink-1 pe-none overflow-x-auto overflow-y-hidden">
+
+    <viewer-state-breadcrumb class="d-inline-block pe-all" (on-item-click)="showFullSideNav()">
+    </viewer-state-breadcrumb>
+  </div>
 
+</ng-template>
+
+
+<!-- viewer tmpl -->
+<ng-template #viewerTmpl>
+  <div class="position-absolute w-100 h-100 z-index-1">
+    
+    <ng-container [ngSwitch]="useViewer$ | async">
+
+      <!-- nehuba viewer -->
+      <iav-cmp-viewer-nehuba-glue class="d-block w-100 h-100 position-absolute left-0 top-0"
+        *ngSwitchCase="'nehuba'"
+        (viewerEvent)="handleViewerEvent($event)"
+        [selectedTemplate]="templateSelected$ | async"
+        [selectedParcellation]="parcellationSelected$ | async"
+        #iavCmpViewerNehubaGlue="iavCmpViewerNehubaGlue">
+      </iav-cmp-viewer-nehuba-glue>
+
+      <!-- three surfer (free surfer viewer) -->
+      <three-surfer-glue-cmp class="d-block w-100 h-100 position-absolute left-0 top-0"
+        *ngSwitchCase="'threeSurfer'"
+        (viewerEvent)="handleViewerEvent($event)"
+        [selectedTemplate]="templateSelected$ | async"
+        [selectedParcellation]="parcellationSelected$ | async">
+      </three-surfer-glue-cmp>
+
+      <!-- if not supported, show not supported message -->
+      <div *ngSwitchCase="'notsupported'">Template not supported by any of the viewers</div>
+
+      <!-- by default, show splash screen -->
+      <div *ngSwitchDefault>
+        <ui-splashscreen class="position-absolute left-0 top-0">
+        </ui-splashscreen>
       </div>
-    </div>
-  </iav-layout-fourcorners>
+    </ng-container>
+
+    <!-- <div class="h-100 w-100 overflow-hidden position-relative"
+      ctx-menu-host
+      [ctx-menu-host-tmpl]="viewerCtxMenuTmpl">
+    </div> -->
+  </div>
 </ng-template>
 
-<!-- auto complete search box -->
 
+<!-- auto complete search box -->
 <ng-template #autocompleteTmpl let-showTour="showTour">
-  <div class="iv-custom-comp bg card w-100 mat-elevation-z8 pe-all">
+  <div class="iv-custom-comp bg card ml-2 mr-2 mat-elevation-z8 pe-all">
     <region-text-search-autocomplete class="w-100 pt-2 flex-shrink-0 flex-grow-0">
     </region-text-search-autocomplete>
 
-    <div class="w-100 h-100 position-absolute pe-none"
-      *ngIf="showTour"
-      #regionSelRef>
+    <div class="w-100 h-100 position-absolute pe-none" *ngIf="showTour">
     </div>
   </div>
 </ng-template>
@@ -362,15 +440,18 @@
 <ng-template #tabTmpl
   let-isOpen="isOpen"
   let-regionSelected="regionSelected"
-  let-iavAdditionallayers="iavAdditionallayers">
+  let-iavAdditionallayers="iavAdditionallayers"
+  let-click="click">
 
   <!-- if mat drawer is open -->
   <ng-template [ngIf]="isOpen" [ngIfElse]="tabTmpl_closedTmpl">
-    <ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
-      matColor: 'basic',
-      fontIcon: 'fa-chevron-left'
-    }">
-    </ng-container>
+    <ng-template [ngTemplateOutlet]="tabTmpl_defaultTmpl"
+      [ngTemplateOutletContext]="{
+        matColor: 'basic',
+        fontIcon: 'fa-chevron-left',
+        click: click
+      }">
+    </ng-template>
   </ng-template>
 
   <!-- if matdrawer is closed -->
@@ -381,7 +462,8 @@
       <ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
         matColor: 'accent',
         fontIcon: 'fa-database',
-        tooltip: 'Explore dataset preview'
+        tooltip: 'Explore dataset preview',
+        click: click
       }">
       </ng-container>
     </ng-template>
@@ -402,7 +484,8 @@
           customColor: tabTmpl_iavRegion.rgbString,
           customColorDarkmode: tabTmpl_iavRegion.rgbDarkmode,
           fontIcon: 'fa-brain',
-          tooltip: 'Explore ' + tabTmpl_iavRegion.region.name
+          tooltip: 'Explore ' + tabTmpl_iavRegion.region.name,
+          click: click
         }">
 
         </ng-container>
@@ -413,7 +496,8 @@
         <ng-container *ngTemplateOutlet="tabTmpl_defaultTmpl; context: {
           matColor: 'primary',
           fontIcon: 'fa-sitemap',
-          tooltip: 'Explore regions'
+          tooltip: 'Explore regions',
+          click: click
         }">
         </ng-container>
       </ng-template>
@@ -422,6 +506,7 @@
 
 
 </ng-template>
+
 <ng-template #tabTmpl_defaultTmpl
   let-matColor="matColor"
   let-fontIcon="fontIcon"
@@ -466,31 +551,29 @@
     </span>
   </button>
 
-  <mat-card class="sidenav-cover-header-container">
-    <div class="sidenav-cover-header-container">
-      <mat-card-title>
-        {{ _pliTitle }}
-      </mat-card-title>
+  <mat-card class="_pli-container">
+    <mat-card-title>
+      {{ _pliTitle }}
+    </mat-card-title>
 
-      <mat-card-subtitle class="d-inline-flex align-items-center flex-wrap">
-        <mat-icon fontSet="fas" fontIcon="fa-database"></mat-icon>
-        <span>
-          Dataset preview
-        </span>
+    <mat-card-subtitle class="d-inline-flex align-items-center flex-wrap">
+      <mat-icon fontSet="fas" fontIcon="fa-database"></mat-icon>
+      <span>
+        Dataset preview
+      </span>
 
-        <mat-divider vertical="true" class="ml-2 h-2rem"></mat-divider>
+      <mat-divider vertical="true" class="ml-2 h-2rem"></mat-divider>
 
-        <a [href]="_pliLink"
-          mat-icon-button
-          matTooltip="Explore in EBRAINS Knowledge Graph"
-          target="_blank">
-          <i class="fas fa-external-link-alt"></i>
-        </a>
+      <a [href]="_pliLink"
+        mat-icon-button
+        matTooltip="Explore in EBRAINS Knowledge Graph"
+        target="_blank">
+        <i class="fas fa-external-link-alt"></i>
+      </a>
 
-      </mat-card-subtitle>
-    </div>
+    </mat-card-subtitle>
 
-    <small class="text-muted iv-custom-comp darker-bg">
+    <small class="d-block text-muted iv-custom-comp darker-bg">
       {{ _pliDesc }}
     </small>
 
@@ -506,7 +589,9 @@
 </ng-template>
 
 <!-- region sidenav tmpl -->
-<ng-template #sidenavRegionTmpl>
+<ng-template #sidenavRegionTmpl
+  let-drawer="drawer"
+  let-showFullSidenavSwitch="showFullSidenavSwitch">
 
   <!-- region search autocomplete  -->
   <!-- [@openCloseAnchor]="sideNavFullLeftSwitch.switchState ? 'open' : 'closed'" -->
@@ -549,8 +634,11 @@
   </div>
 
   <!-- collapse btn -->
-  <ng-container *ngTemplateOutlet="collapseBtn">
-  </ng-container>
+  <ng-template [ngTemplateOutlet]="collapseBtn"
+    [ngTemplateOutletContext]="{
+      collapse: showFullSidenavSwitch.close.bind(showFullSidenavSwitch)
+    }">
+  </ng-template>
 </ng-template>
 
 
@@ -559,7 +647,7 @@
   <!-- region detail -->
   <region-menu
     [region]="region"
-    class="flex-grow-1 bs-border-box ml-15px-n mr-15px-n mat-elevation-z4">
+    class="flex-grow-1 bs-border-box mat-elevation-z4">
   </region-menu>
 </ng-template>
 
@@ -666,13 +754,13 @@
 </ng-template>
 
 <!-- collapse btn -->
-<ng-template #collapseBtn>
+<ng-template #collapseBtn let-collapse="collapse">
 
   <div class="h-0 w-100 collapse-position d-flex flex-column justify-content-end align-items-center">
 
     <button mat-raised-button class="mat-elevation-z8"
       [attr.aria-label]="ARIA_LABELS.COLLAPSE"
-      (click)="sideNavFullLeftSwitch.close()"
+      (click)="collapse()"
       color="basic">
       <i class="fas fa-chevron-up"></i>
       <span>