diff --git a/.eslintrc.js b/.eslintrc.js
index 54af39fd8e639934ed7c4c2658f668a4facc8536..0e79e8f287d1ef96ada9140ca7aeb51938fdbec3 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -7,7 +7,6 @@ module.exports = {
     "@typescript-eslint/no-empty-interface": "off",
     "@typescript-eslint/no-inferrable-types": "off",
     "@typescript-eslint/interface-name-prefix": [0],
-    // "no-unused-vars": "off",
     "semi": "off",
     "indent": "off",
     "@typescript-eslint/member-delimiter-style": [2, {
diff --git a/deploy/csp/index.js b/deploy/csp/index.js
index 92ee364fd5cd7691811cf45956712bf98fd184c6..5f04bbcd2144b19ca15ba1acc765c4fba7afb45c 100644
--- a/deploy/csp/index.js
+++ b/deploy/csp/index.js
@@ -115,7 +115,7 @@ module.exports = {
           'https://unpkg.com/d3@6.2.0/', // required for preview component
           'https://unpkg.com/mathjax@3.1.2/', // math jax
           'https://unpkg.com/three-surfer@0.0.13/dist/bundle.js', // for threeSurfer (freesurfer support in browser)
-          'https://unpkg.com/ng-layer-tune@0.0.14/dist/ng-layer-tune/', // needed for ng layer control
+          'https://unpkg.com/ng-layer-tune@0.0.16/dist/ng-layer-tune/', // needed for ng layer control
           'https://unpkg.com/hbp-connectivity-component@0.6.6/', // needed for connectivity component
           (req, res) => res.locals.nonce ? `'nonce-${res.locals.nonce}'` : null,
           ...SCRIPT_SRC,
diff --git a/docs/releases/v2.12.1.md b/docs/releases/v2.12.1.md
new file mode 100644
index 0000000000000000000000000000000000000000..0d9308e1ec98b17cd2e785314cb3b25259b01323
--- /dev/null
+++ b/docs/releases/v2.12.1.md
@@ -0,0 +1,10 @@
+# v2.12.1
+
+# Feature
+
+- added the option to use red/green/blue colormaps (#1366)
+
+## Bugfix
+
+- fixed touch devices unable to navigate viewer
+- fixed some volume controls not working
diff --git a/mkdocs.yml b/mkdocs.yml
index a43dc55650094669690740ca9fe1e1fb13acc07b..207b2580cd9132c87e0721534a3a192cbbfd4711 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -33,6 +33,7 @@ nav:
     - Fetching datasets: 'advanced/datasets.md'
     - Display non-atlas volumes: 'advanced/otherVolumes.md'
   - Release notes:
+    - v2.12.1: 'releases/v2.12.1.md'
     - v2.12.0: 'releases/v2.12.0.md'
     - v2.11.4: 'releases/v2.11.4.md'
     - v2.11.3: 'releases/v2.11.3.md'
diff --git a/package-lock.json b/package-lock.json
index c6e536b6eb6532373f96bd0d1c06c34e690ec417..988893d143b1661bf6bca7685e244e46e87c2898 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
 {
   "name": "siibra-explorer",
-  "version": "2.12.0",
+  "version": "2.12.1",
   "lockfileVersion": 3,
   "requires": true,
   "packages": {
diff --git a/src/index.html b/src/index.html
index 625cc65955195124a32d39c78486382edb8a9737..b1c5716a7c0ffaa17c6da0b9c126f82f9b8532a2 100644
--- a/src/index.html
+++ b/src/index.html
@@ -14,7 +14,7 @@
   <script src="extra_js.js"></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.13/dist/bundle.js" defer></script>
-  <script type="module" src="https://unpkg.com/ng-layer-tune@0.0.14/dist/ng-layer-tune/ng-layer-tune.esm.js"></script>
+  <script type="module" src="https://unpkg.com/ng-layer-tune@0.0.16/dist/ng-layer-tune/ng-layer-tune.esm.js"></script>
   <script type="module" src="https://unpkg.com/hbp-connectivity-component@0.6.6/dist/connectivity-component/connectivity-component.js" ></script>
   <script defer src="https://unpkg.com/mathjax@3.1.2/es5/tex-svg.js"></script>
   <script defer src="https://unpkg.com/d3@6.2.0/dist/d3.min.js"></script>
diff --git a/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts b/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts
index 0bee1941f311aee0df808e66678299649bcc6128..94d1cc93950caa1c85a8850b485ebb9bba51e1f8 100644
--- a/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts
+++ b/src/viewerModule/nehuba/nehubaViewer/nehubaViewer.component.ts
@@ -847,7 +847,7 @@ const patchSliceViewPanel = (sliceViewPanel: any) => {
       const viewportToDataEv = new CustomEvent('viewportToData', {
         bubbles: true,
         detail: {
-          viewportToData : this.sliceView.viewportToData,
+          viewportToData : this.sliceView.invViewMatrix,
         },
       })
       this.element.dispatchEvent(viewportToDataEv)
diff --git a/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerTouch.directive.ts b/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerTouch.directive.ts
index 6223e187fe07f0bd19f2f5774c793594ff17851f..371cc99e778aaa79ac3ba7d7ec645a27bb2c4f60 100644
--- a/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerTouch.directive.ts
+++ b/src/viewerModule/nehuba/nehubaViewerInterface/nehubaViewerTouch.directive.ts
@@ -66,12 +66,12 @@ export class NehubaViewerTouchDirective implements OnDestroy{
      * Touchend also needs to be listened to, as user could start
      * with multitouch, and end up as single touch
      */
-    const touchStart$ = fromEvent(this.el.nativeElement, 'touchstart').pipe(
+    const touchStart$ = fromEvent(this.el.nativeElement, 'touchstart', { capture: true }).pipe(
       shareReplay(1),
     )
     this.singleTouchStart$ = merge(
       touchStart$,
-      fromEvent(this.el.nativeElement, 'touchend')
+      fromEvent(this.el.nativeElement, 'touchend', { capture: true })
     ).pipe(
       filter((ev: TouchEvent) => ev.touches.length === 1),
       shareReplay(1),
@@ -81,18 +81,18 @@ export class NehubaViewerTouchDirective implements OnDestroy{
       filter((ev: TouchEvent) => ev.touches.length > 1),
     )
 
-    this.touchEnd$ = fromEvent(this.el.nativeElement, 'touchend').pipe(
+    this.touchEnd$ = fromEvent(this.el.nativeElement, 'touchend', { capture: true }).pipe(
       map(ev => ev as TouchEvent),
     )
 
-    this.touchMove$ = fromEvent(this.el.nativeElement, 'touchmove')
+    this.touchMove$ = fromEvent(this.el.nativeElement, 'touchmove', { capture: true })
 
     const multiTouch$ = this.multiTouchStart$.pipe(
       // only tracks first 2 touches
       map((ev: TouchEvent) => [ this.findPanelIndex(ev.touches[0].target as HTMLElement), this.findPanelIndex(ev.touches[0].target as HTMLElement) ]),
       filter(indicies => indicies[0] >= 0 && indicies[0] === indicies[1]),
       map(indicies => indicies[0]),
-      switchMap(panelIndex => fromEvent(this.el.nativeElement, 'touchmove').pipe(
+      switchMap(panelIndex => fromEvent(this.el.nativeElement, 'touchmove', { capture: true }).pipe(
         filter((ev: TouchEvent) => ev.touches.length > 1),
         pairwise(),
         map(([ev0, ev1]) => {
@@ -256,7 +256,7 @@ export class NehubaViewerTouchDirective implements OnDestroy{
       ).subscribe(({ panelIndex, deltaX, deltaY }) => {
         if (isNaN(deltaX) || isNaN(deltaX)) return
         const { position } = this.ngViewer.navigationState
-        const pos = position.spatialCoordinates
+        const pos = position.value
         const { vec3 } = this.exportNehuba
         vec3.set(pos, deltaX, deltaY, 0)
         vec3.transformMat4(pos, pos, this.viewportToData[panelIndex])