diff --git a/core/scope.js b/core/scope.js
index 71f63ee5edd8b19a25090d6fa637f9a378921f29..1e3d028811e5c7c686552b8227d409c0336143e2 100644
--- a/core/scope.js
+++ b/core/scope.js
@@ -46,7 +46,17 @@ export default function Scope(wrapper, tlv) {
     if ($(evt.target).is('.defcore')) {
       cm.defMenu(evt)
     } else {
-      cm.planeMenu(evt, tlv)
+      let tcontext
+      if($(evt.target).is('#wrapper')){
+        tcontext = tlv
+      } else if ($(evt.target).is('.subplane')){
+        tcontext = evt.target.handle
+      }
+      if(tcontext){
+        cm.planeMenu(evt, tcontext)
+      } else {
+        cm.errDisplay('no apparent context for this context-click', evt)
+      }
     }
   })
 
@@ -147,7 +157,7 @@ export default function Scope(wrapper, tlv) {
         dt.rmWire(opblock, floater)
         $(floater).remove()
       })
-    } else if ($(evt.target).is('#wrapper')) {
+    } else if ($(evt.target).is('#wrapper') || $(evt.target).is('.subplane')) {
       evt.preventDefault()
       evt.stopPropagation()
       dt.dragTool((drag) => {
diff --git a/style.css b/style.css
index 994c16af34900b375252eaae23b11aa216dffdbb..13671b999293646834a980d3540b21437c415afa 100644
--- a/style.css
+++ b/style.css
@@ -72,9 +72,13 @@ body {
 
 .subplane{
 	position: absolute;
-	background-color: #c1c1c1;
 	width: 1200px;
 	height: 800px;
+	background: #c1c1c1;
+	background-image:
+		linear-gradient(rgba(255, 255, 255, .2) 2px, transparent 2px),
+		linear-gradient(90deg, rgba(255, 255, 255, .2) 2px, transparent 2px);
+	background-size: 100px 100px;
 }
 
 .resizehandle{
diff --git a/view/contextmenu.js b/view/contextmenu.js
index 98b4239a5071606040b9c91da023780fc071b202..ba7634616e4682ce3152b48e087bca3255f2c380 100644
--- a/view/contextmenu.js
+++ b/view/contextmenu.js
@@ -16,6 +16,74 @@ import dt from './domtools.js'
 import blocks from './blocks.js'
 import gg from '../gogetter.js'
 
+let findOrBuild = (evt) => {
+  // ok, we either find this thing, or build a new one and place it in plane
+  // according to where the evt was fired from,
+  // if no event, top level plane,
+  // either find the menu, or make a new one at evt location (in wrapper), and
+  // write some text
+  let menu = $('#wrapper').find('.contextmenu').get(0)
+  if (!menu) {
+    let plane = {}
+    let pos = {}
+    if (evt) {
+      if ($(evt.target).is("#wrapper")) {
+        plane = window.tlv.plane
+        let pt = dt.readTransform(plane)
+        pos.s = 1 + ((1 / pt.s) - 1) * 0.5
+        pos.x = (evt.layerX - pt.x) * (1 / pt.s)
+        pos.y = (evt.layerY - pt.y) * (1 / pt.s)
+      } else {
+        if (!$(evt.target).is('.subplane')) console.error('poorly placed menu cominatcha')
+        plane = evt.target
+        pos.x = evt.layerX + 3
+        pos.y = evt.layerY - 29
+        pos.s = 1
+      }
+    } else {
+      // no event,
+      pos = { x: 250, y: 250, s: 1 }
+    }
+    menu = $('<div>').addClass('contextmenu').get(0)
+    dt.writeTransform(menu, pos)
+    $(plane).append(menu)
+  }
+  menu.addEventListener('wheel', (evt) => {
+    let mt = dt.readTransform(menu)
+    dt.writeTransform(menu, {
+      s: mt.s,
+      x: mt.x,
+      y: mt.y - evt.deltaY * 4
+    })
+    evt.preventDefault()
+    evt.stopPropagation()
+  })
+  return menu
+}
+
+let errDisplay = (msg, evt) => {
+  let menu = findOrBuild(evt)
+  // wipe it,
+  $(menu).children().remove()
+  $(menu).css('background-color', 'red')
+  let title = $(`<div>err</div>`).addClass('contextTitle').get(0)
+  $(title).text('error')
+  $(title).append(`<p>${msg}</p>`)
+  $(menu).append(title)
+}
+
+let successDisplay = (msg, evt) => {
+  let menu = findOrBuild(evt)
+  // wipe it,
+  $(menu).children().remove()
+  $(menu).css('background-color', 'green')
+  let title = $(`<div>ok</div>`).addClass('contextTitle').get(0)
+  $(title).text('success')
+  $(title).append(`<p>${msg}</p>`)
+  $(menu).append(title)
+  console.log(menu)
+}
+
 let addContextTitle = (text) => {
   $('#wrapper').find('.contextmenu').get(0).append($('<ul>' + text + '/</li>').get(0))
 }
@@ -95,18 +163,6 @@ let setupForSave = (se, callback) => {
   $(tinput).on('keyup', (ke) => {
     if (ke.keyCode == 13) {
       callback(tinput.value)
-      // this would present a download link
-      /*
-      let url = URL.createObjectURL(new Blob([JSON.stringify(obj, null, 2)], {
-        type: "application/json"
-      }))
-      // hack to trigger the download,
-      let anchor = $('<a>ok</a>').attr('href', url).attr('download', tinput.value + '.json').get(0)
-      $(ke.target).closest('li').append(anchor)
-      anchor.click()
-      // finally, rip
-      fadeOut(400)
-      */
     }
   })
 }
@@ -147,7 +203,7 @@ function defMenu(evt) {
     context.requestAddHunk(def.type).then((hnk) => {
       $(menu).remove()
     }).catch((err) => {
-      changeContextTitle('err adding another one of these... consoles ->')
+      errDisplay('err adding another one of these... consoles ->')
     })
   })
 
@@ -155,7 +211,7 @@ function defMenu(evt) {
     context.requestRemoveHunk(def.ind).then(() => {
       $(menu).remove()
     }).catch((err) => {
-      changeContextTitle("couldn't seem to rm this thing...")
+      errDisplay("couldn't seem to rm this thing...")
     })
   })
 
@@ -164,7 +220,7 @@ function defMenu(evt) {
       $(menu).remove()
     }).catch((err) => {
       console.error(err)
-      changeContextTitle("err while reloading...")
+      errDisplay("err while reloading...")
     })
   })
 
@@ -181,46 +237,7 @@ function defMenu(evt) {
 function planeMenu(evt, context) {
   // position from the evt is in wrapper-space (screen space)
   // but we are interested in this as well,
-  let pt = dt.readTransform(context.plane)
-  let pos = {}
-  if (evt) {
-    // a proper mouse event,
-    pos.x = evt.clientX + 3 * (1 / pt.s)
-    pos.y = evt.clientY - 29 * (1 / pt.s)
-    // one only,
-    evt.preventDefault()
-    evt.stopPropagation()
-  } else {
-    // probably keyboard triggered,
-    pos.x = 250
-    pos.y = 150
-  }
-  pos.s = 1 + ((1 / pt.s) - 1) * 0.5
-  pos.x = (pos.x - pt.x) * (1 / pt.s)
-  pos.y = (pos.y - pt.y) * (1 / pt.s)
-
-  // clear any existing menus from the dom,
-  $('#wrapper').find('.contextmenu').remove()
-
-  // make the menu,
-  let menu = $('<div>').addClass('contextmenu').get(0)
-  // lay it down in screen-space
-  dt.writeTransform(menu, {
-    s: pos.s,
-    x: pos.x, // (pt.s + -0.1 * (pt.s-1))),
-    y: pos.y //- 31 * 2 // + -0.1 * (pt.s-1)))
-  })
-  $(context.plane).append(menu)
-  menu.addEventListener('wheel', (evt) => {
-    let mt = dt.readTransform(menu)
-    dt.writeTransform(menu, {
-      s: mt.s,
-      x: mt.x,
-      y: mt.y - evt.deltaY * 4
-    })
-    evt.preventDefault()
-    evt.stopPropagation()
-  })
+  let menu = findOrBuild(evt)
 
   // hmmm
   changeContextTitle('do:  ')
@@ -233,7 +250,7 @@ function planeMenu(evt, context) {
     // this actually gets wiped when the first hunk arrives, so
     $(ce.target).closest('li').text('refreshing...')
     context.refresh().then(() => {
-      $(ce.target).closest('li').text(`refresh complete !`)
+      successDisplay('refresh ok')
       fadeOut(250)
     })
   })
@@ -241,8 +258,8 @@ function planeMenu(evt, context) {
   addContextOption(`<i class="em em-wave"></i> say hello`, (ce) => {
     $(ce.target).closest('li').text(`view says hello ...`)
     context.sayHelloToManager().then((ms) => {
-      $(ce.target).closest('li').text(`msg took ${ms}ms rtt from browser`)
-      fadeOut(250)
+      successDisplay(`msg took ${ms}ms rtt from browser`)
+      fadeOut(500)
     })
   })
 
@@ -283,13 +300,20 @@ function planeMenu(evt, context) {
           addContextOption(item, (ce) => {
             $(ce.target).closest('li').append(' > requested ... ')
             context.requestAddHunk(item).then((def) => {
-              def.position = { x: pos.x, y: pos.y }
+              let menu = $(context.plane).children('.contextmenu').get(0)
+              if (menu) {
+                let mp = dt.readTransform(menu)
+                def.position = { x: mp.x, y: mp.y }
+              } else {
+                def.position = { x: 250, y: 250 }
+              }
               blocks.repositionDef(def)
-              fadeOut(100)
+              successDisplay('hunk alive!')
+              fadeOut(500)
               //console.log('one hunk as promised', def)
             }).catch((err) => {
               console.log('err', err)
-              changeContextTitle('error, see consoles')
+              errDisplay('a bad time was had, see consoles')
               fadeOut(2000)
             })
           })
@@ -325,7 +349,7 @@ function planeMenu(evt, context) {
             console.error(res)
           } else {
             changeContextTitle(`saved to /save/systems/${name}`)
-            fadeOut(1500)
+            fadeOut(500)
           }
         }, 'json')
       })
@@ -426,21 +450,21 @@ function planeMenu(evt, context) {
             gg.getJson(`save/systems/${item}.json`).then((obj) => {
               // apparently, it's actually promises all the way down
               // 2nd arg is debug state
-              context.reinstate(obj, true).then((yikes) => {
+              context.reinstate(obj).then((yikes) => {
                 // trigger re-render? do we get heavy handed here and shut it down
                 // ... i.e. don't render anything until it's thru ?
-                changeContextTitle("system restore OK ...")
-                fadeOut(1500)
+                successDisplay('system restore success')
+                fadeOut(500)
               })
             }).catch((err) => {
-              console.error("error while retrieving this patch")
+              errDisplay("couldn't retrieve this patch, see consoles")
               console.error(err)
             })
           })
         }
       }
     }).catch((err) => {
-      console.error("coudn't retrieve list of systems")
+      errDisplay("couldn't retrieve a list of systems, see consoles")
       console.error(err)
     })
   })
@@ -449,5 +473,7 @@ function planeMenu(evt, context) {
 
 export default {
   planeMenu,
-  defMenu
+  defMenu,
+  errDisplay,
+  successDisplay
 }