diff --git a/app/assets/images/common/button-background-active-border.png b/app/assets/images/common/button-background-active-border.png
new file mode 100644
index 000000000..42dec5b5a
Binary files /dev/null and b/app/assets/images/common/button-background-active-border.png differ
diff --git a/app/assets/images/common/button-background-active.png b/app/assets/images/common/button-background-active.png
new file mode 100644
index 000000000..aae72bb00
Binary files /dev/null and b/app/assets/images/common/button-background-active.png differ
diff --git a/app/assets/images/common/button-background-disabled-border.png b/app/assets/images/common/button-background-disabled-border.png
new file mode 100644
index 000000000..dbbe537cc
Binary files /dev/null and b/app/assets/images/common/button-background-disabled-border.png differ
diff --git a/app/assets/images/common/button-background-disabled.png b/app/assets/images/common/button-background-disabled.png
new file mode 100644
index 000000000..78fae8539
Binary files /dev/null and b/app/assets/images/common/button-background-disabled.png differ
diff --git a/app/assets/images/common/button-background-pressed-border.png b/app/assets/images/common/button-background-pressed-border.png
new file mode 100644
index 000000000..d9c173d64
Binary files /dev/null and b/app/assets/images/common/button-background-pressed-border.png differ
diff --git a/app/assets/images/common/button-background-pressed.png b/app/assets/images/common/button-background-pressed.png
new file mode 100644
index 000000000..b1433c3ff
Binary files /dev/null and b/app/assets/images/common/button-background-pressed.png differ
diff --git a/app/assets/images/level/code_editor_background_border.png b/app/assets/images/level/code_editor_background_border.png
new file mode 100644
index 000000000..9c860168f
Binary files /dev/null and b/app/assets/images/level/code_editor_background_border.png differ
diff --git a/app/assets/images/level/code_editor_top_bar_hinge.png b/app/assets/images/level/code_editor_top_bar_hinge.png
new file mode 100644
index 000000000..852df87fc
Binary files /dev/null and b/app/assets/images/level/code_editor_top_bar_hinge.png differ
diff --git a/app/assets/images/level/code_editor_top_bar_wood_background.png b/app/assets/images/level/code_editor_top_bar_wood_background.png
new file mode 100644
index 000000000..15d625b08
Binary files /dev/null and b/app/assets/images/level/code_editor_top_bar_wood_background.png differ
diff --git a/app/assets/images/level/code_palette_wood_background.png b/app/assets/images/level/code_palette_wood_background.png
new file mode 100644
index 000000000..dbdda5af6
Binary files /dev/null and b/app/assets/images/level/code_palette_wood_background.png differ
diff --git a/app/assets/images/level/code_toolbar_background.png b/app/assets/images/level/code_toolbar_background.png
new file mode 100644
index 000000000..f05972b5c
Binary files /dev/null and b/app/assets/images/level/code_toolbar_background.png differ
diff --git a/app/assets/images/level/code_toolbar_run_button_active.png b/app/assets/images/level/code_toolbar_run_button_active.png
new file mode 100644
index 000000000..ff3748d39
Binary files /dev/null and b/app/assets/images/level/code_toolbar_run_button_active.png differ
diff --git a/app/assets/images/level/code_toolbar_run_button_active_pressed.png b/app/assets/images/level/code_toolbar_run_button_active_pressed.png
new file mode 100644
index 000000000..b9c87d1ba
Binary files /dev/null and b/app/assets/images/level/code_toolbar_run_button_active_pressed.png differ
diff --git a/app/assets/images/level/code_toolbar_run_button_zazz.png b/app/assets/images/level/code_toolbar_run_button_zazz.png
new file mode 100644
index 000000000..8b0e94225
Binary files /dev/null and b/app/assets/images/level/code_toolbar_run_button_zazz.png differ
diff --git a/app/assets/images/level/code_toolbar_run_button_zazz_pressed.png b/app/assets/images/level/code_toolbar_run_button_zazz_pressed.png
new file mode 100644
index 000000000..b6d173515
Binary files /dev/null and b/app/assets/images/level/code_toolbar_run_button_zazz_pressed.png differ
diff --git a/app/assets/images/level/code_toolbar_submit_button_active.png b/app/assets/images/level/code_toolbar_submit_button_active.png
new file mode 100644
index 000000000..0913c4e28
Binary files /dev/null and b/app/assets/images/level/code_toolbar_submit_button_active.png differ
diff --git a/app/assets/images/level/code_toolbar_submit_button_active_pressed.png b/app/assets/images/level/code_toolbar_submit_button_active_pressed.png
new file mode 100644
index 000000000..100f085f4
Binary files /dev/null and b/app/assets/images/level/code_toolbar_submit_button_active_pressed.png differ
diff --git a/app/assets/images/level/code_toolbar_submit_button_zazz.png b/app/assets/images/level/code_toolbar_submit_button_zazz.png
new file mode 100644
index 000000000..ff9eeac0c
Binary files /dev/null and b/app/assets/images/level/code_toolbar_submit_button_zazz.png differ
diff --git a/app/assets/images/level/code_toolbar_submit_button_zazz_pressed.png b/app/assets/images/level/code_toolbar_submit_button_zazz_pressed.png
new file mode 100644
index 000000000..4875b697b
Binary files /dev/null and b/app/assets/images/level/code_toolbar_submit_button_zazz_pressed.png differ
diff --git a/app/assets/images/level/hud_hinge.png b/app/assets/images/level/hud_hinge.png
new file mode 100644
index 000000000..bfbd5bc64
Binary files /dev/null and b/app/assets/images/level/hud_hinge.png differ
diff --git a/app/assets/images/level/thang_avatar_frame.png b/app/assets/images/level/thang_avatar_frame.png
new file mode 100644
index 000000000..1b4fcc3d5
Binary files /dev/null and b/app/assets/images/level/thang_avatar_frame.png differ
diff --git a/app/locale/en.coffee b/app/locale/en.coffee
index db13244b3..fca690816 100644
--- a/app/locale/en.coffee
+++ b/app/locale/en.coffee
@@ -198,6 +198,7 @@
     failing: "Failing"
     action_timeline: "Action Timeline"
     click_to_select: "Click on a unit to select it."
+    reload: "Reload"
     reload_title: "Reload All Code?"
     reload_really: "Are you sure you want to reload this level back to the beginning?"
     reload_confirm: "Reload All"
@@ -447,7 +448,7 @@
     enter: "Enter"
     escape: "Escape"
     shift: "Shift"
-    cast_spell: "Cast current spell."
+    run_code: "Run current code."
     run_real_time: "Run in real time."
     continue_script: "Continue past current script."
     skip_scripts: "Skip past all skippable scripts."
diff --git a/app/schemas/subscriptions/tome.coffee b/app/schemas/subscriptions/tome.coffee
index d5e061eb5..82f0691e9 100644
--- a/app/schemas/subscriptions/tome.coffee
+++ b/app/schemas/subscriptions/tome.coffee
@@ -85,9 +85,6 @@ module.exports =
     problems: {type: 'array'}
     isCast: {type: 'boolean'}
 
-  'tome:thang-list-entry-popover-shown': c.object {title: 'Thang List Entry Popover Shown', description: 'Published when we show the popover for a thang in the master list', required: ['entry']},
-    entry: {type: 'object'}
-
   'tome:spell-shown': c.object {title: 'Spell Shown', description: 'Published when we show a spell', required: ['thang', 'spell']},
     thang: {type: 'object'}
     spell: {type: 'object'}
diff --git a/app/styles/base.sass b/app/styles/base.sass
index 4710b1eb7..7eaca0195 100644
--- a/app/styles/base.sass
+++ b/app/styles/base.sass
@@ -312,9 +312,56 @@ kbd
   .arrow
     display: none
 
+.btn.btn-illustrated
+  background: 0
+  border: 0
+  border-radius: 0
+  @include box-shadow(none)
+  border-image: url(/images/common/button-background-active-border.png) 14 20 20 20 fill round
+  border-width: 7px 10px 10px 10px
+  padding: 0
+  font-family: Open Sans Condensed
+  text-transform: uppercase
+  font-weight: bold
+  color: rgb(248, 197, 146)
+
+  &:active
+    border-image: url(/images/common/button-background-pressed-border.png) 14 16 16 20 fill round
+    padding: 2px 0 0 2px
+    border-width: 7px 8px 8px 10px
+
+  &.disabled, &:disabled
+    border-image: url(/images/common/button-background-disabled-border.png) 14 20 20 20 fill round
+    @include opacity(1)
+
+    > *
+      @include opacity(0.5)
+
+  > *
+    @include opacity(0.75)
+
+  &:hover > *
+    @include opacity(1)
+
+
 html.no-borderimage
   .popover
     border: 0
     background: transparent url(/images/level/popover_background.png)
     background-size: 100% 100%
     padding: 10px 20px
+
+  .btn.btn-illustrated
+    border: 0
+    background-image: url(/images/common/button-background-active.png)
+    background-size: 100% 100%
+    padding: 7px 10px 10px 10px
+    
+    &:active
+      background-image: url(/images/common/button-background-pressed.png)
+      padding: 9px 8px 8px 12px
+      border: 0
+
+    &.disabled, &:disabled
+      background-image: url(/images/common/button-background-disabled.png)
+
diff --git a/app/styles/play/level.sass b/app/styles/play/level.sass
index 7fb4e4726..2f878b51b 100644
--- a/app/styles/play/level.sass
+++ b/app/styles/play/level.sass
@@ -97,6 +97,7 @@ $level-resize-transition-time: 0.5s
     top: 0px
     bottom: 0
     @include transition(width $level-resize-transition-time ease-in-out, right $level-resize-transition-time ease-in-out)
+    overflow: hidden
     
   // Level Docs
   .ui-effects-transfer
diff --git a/app/styles/play/level/modal/editor_config.sass b/app/styles/play/level/modal/editor_config.sass
deleted file mode 100644
index 1d97d3965..000000000
--- a/app/styles/play/level/modal/editor_config.sass
+++ /dev/null
@@ -1,12 +0,0 @@
-#level-editor-config-modal
-  .select-group
-    display: block
-    min-height: 20px
-    margin-top: 10px
-    margin-bottom: 10px
-    padding-left: 20px
-    vertical-align: middle
-
-    label
-      font-weight: normal
-      margin-right: 20px
\ No newline at end of file
diff --git a/app/styles/play/level/thang_avatar.sass b/app/styles/play/level/thang_avatar.sass
index 0873eeee3..c81beb41f 100644
--- a/app/styles/play/level/thang_avatar.sass
+++ b/app/styles/play/level/thang_avatar.sass
@@ -28,9 +28,9 @@
 
     .avatar-frame
       position: absolute
-      left: -13%
-      top: -14%
-      width: 132%
+      left: -18%
+      top: -19%
+      width: 145%
 
     .badge
       $radius: 8px
diff --git a/app/styles/play/level/tome/cast_button.sass b/app/styles/play/level/tome/cast_button.sass
index edad12068..b00d99ca1 100644
--- a/app/styles/play/level/tome/cast_button.sass
+++ b/app/styles/play/level/tome/cast_button.sass
@@ -17,8 +17,8 @@
     @include box-shadow(0px 0px 8px #333)
     color: white
   50%
-    @include box-shadow(0px 0px 35px #87FFCE)
-    color: #87FFFF
+    @include box-shadow(0px 0px 35px #87CEFF)
+    color: #87CEFF
   to
     @include box-shadow(0px 0px 8px #333)
     color: white
@@ -31,40 +31,113 @@
   width: 100%
   border-radius: 6px
 
-  .btn
-    padding: 3px 10px
-    height: 40px
-    font-size: 22px
+  background: transparent url(/images/level/code_toolbar_background.png)
+  background-size: 100% 100%
+  left: -15px
+  right: 15px
+  height: 94px
+  margin-top: -8px
+  padding: 20px 2.8%
 
-  .submit-button
-    margin-left: 20px
-    min-width: 150px
+  .btn.btn-illustrated
+    height: 46px
+    font-size: 24px
+    line-height: 24px
+    width: 45%
+    width: -webkit-calc(50% - 10px)
+    width: calc(50% - 10px)
+    border-image: url(/images/level/code_toolbar_run_button_active.png) 14 20 20 20 fill round
+    border-width: 7px 10px 10px 10px
+
+    &:active
+      border-image: url(/images/level/code_toolbar_run_button_active_pressed.png) 14 20 20 20 fill round
+      padding: 2px 0 0 2px
+
+    &.submit-button
+      margin-left: 10px
+      border-image: url(/images/level/code_toolbar_submit_button_active.png) 14 20 20 20 fill round
+      
+      &:active
+        border-image: url(/images/level/code_toolbar_submit_button_active_pressed.png) 14 20 20 20 fill round
   
   .cast-button
-    margin-left: 10px
-    min-width: 150px
     @include opacity(0.77)
   
     &:hover, &.castable
       @include opacity(1)
+
+  .submit-button > *
+    @include opacity(0.9)
   
+    &:hover
+      @include opacity(1)
+
   &:not(.winnable)
 
-    .cast-button.castable
-      font-weight: bold
-      -webkit-animation-name: castablePulse
-      -webkit-animation-duration: 3s
-      -webkit-animation-iteration-count: infinite
+    .btn.btn-illustrated
 
-    .submit-button
-      font-size: 16px
+      &.cast-button.castable
+        font-weight: bold
+        @include animation(castablePulse 3s infinite)
+        border-image: url(/images/level/code_toolbar_run_button_zazz.png) 14 20 20 20 fill round
+
+        &:active
+          border-image: url(/images/level/code_toolbar_run_button_zazz_pressed.png) 14 20 20 20 fill round
+
+      &.submit-button
+        font-size: 16px
 
   &.winnable
-    .submit-button
-      font-weight: bold
-      -webkit-animation-name: winnablePulse
-      -webkit-animation-duration: 3s
-      -webkit-animation-iteration-count: infinite
 
-    .cast-button
-      font-size: 16px
+    .btn.btn-illustrated
+      &.submit-button
+        font-weight: bold
+        @include animation(winnablePulse 3s infinite)
+
+        border-image: url(/images/level/code_toolbar_submit_button_zazz.png) 14 20 20 20 fill round
+
+        &:active
+          border-image: url(/images/level/code_toolbar_submit_button_zazz_pressed.png) 14 20 20 20 fill round
+
+      &.cast-button
+        font-size: 16px
+
+html.no-borderimage #cast-button-view
+  .btn.btn-illustrated
+    border: 0
+    background-image: url(/images/level/code_toolbar_run_button_active.png)
+    background-size: 100% 100%
+    padding: 7px 10px 10px 10px
+  
+    &:active
+      background-image: url(/images/level/code_toolbar_run_button_active_pressed.png)
+      padding: 9px 8px 8px 12px
+      border: 0
+
+    &.submit-button
+      background-image: url(/images/level/code_toolbar_submit_button_active_pressed.png)
+      border: 0
+
+      &:active
+        background-image: url(/images/level/code_toolbar_submit_button_active_pressed.png)
+        border: 0
+
+  &:not(.winnable)
+    .btn.btn-illustrated
+      &.cast-button.castable
+        border: 0
+        background-image: url(/images/level/code_toolbar_run_button_zazz.png)
+
+        &:active
+          background-image: url(/images/level/code_toolbar_run_button_zazz_pressed.png)
+
+  &.winnable
+    .btn.btn-illustrated
+      &.submit-button
+        border: 0
+        background-image: url(/images/level/code_toolbar_submit_button_zazz.png)
+
+        &:active
+          border: 0
+          background-image: url(/images/level/code_toolbar_submit_button_zazz_pressed.png)
+          
diff --git a/app/styles/play/level/tome/spell.sass b/app/styles/play/level/tome/spell.sass
index 348633044..d2ab57bfd 100644
--- a/app/styles/play/level/tome/spell.sass
+++ b/app/styles/play/level/tome/spell.sass
@@ -2,38 +2,37 @@
 @import "app/styles/bootstrap/variables"
 
 @mixin editor-height($extraHeight)
-  @include box-sizing(border-box)
   width: 98%
   height: 83%
-  height: unquote("-webkit-calc(100% - 60px -")$extraHeight unquote(")")
-  height: unquote("calc(100% - 60px -")$extraHeight unquote(")")
+  height: unquote("-webkit-calc(100% - 100px -")$extraHeight unquote(")")
+  height: unquote("calc(100% - 100px -")$extraHeight unquote(")")
 
 #spell-view
-  position: absolute
-  left: 10px
-  top: 140px
-  //top: 48px
-  right: 10px
-  padding-bottom: 10px
-  z-index: 1
-  // Set z-index above palette
+  margin-top: 10px
+  padding-top: 20px
+  padding-left: 30px
+  padding-bottom: 95px
   display: none
+  position: relative
+  z-index: 1
 
   &.shown
     display: block
 
   .code-background
     position: absolute
-    top: 0
+    top: -68px
+    left: 0px
     height: 100%
-    width: 100%
+    right: -10px
     
   span.code-background
-    border-width: 40px
-    border-image: url(/images/level/code_editor_background.png) 40 fill round
+    border-width: 124px 76px 64px 40px
+    border-image: url(/images/level/code_editor_background_border.png) 124 76 64 40 fill round
 
   img.code-background
     display: none
+    width: 100%
 
   .save-status
     display: none
@@ -44,7 +43,7 @@
   .firepad
     // When Firepad is active, it wraps .ace_editor in .firepad.
     @include editor-height(0px)
-    width: 98%
+    width: 94%
 
     .ace_editor
       width: 100%
@@ -56,7 +55,7 @@
   .ace_editor
     // When Firepad isn't active, .ace_editor needs the width/height set itself.
     @include editor-height(0px)
-    width: 98%
+    width: 94%
     position: relative
     background-color: transparent
     line-height: 20px
@@ -70,14 +69,18 @@
         @include opacity(20)
 
     .ace_gutter
-      background-color: rgba(255, 255, 255, 0.25)
+      background-color: transparent
+      border-right: 1px solid rgb(195, 178, 156)
+      //background-color: rgba(255, 255, 255, 0.25)
       width: 47px
       margin-left: 4px
-      border-bottom: 1px dotted #2f261d
 
     .ace_scroller
       background-color: transparent
-      border-bottom: 1px dotted #2f261d
+      //padding-left: 10px  // Interrupts gutter and line highlighting
+
+    .ace_active-line, .ace_gutter-active-line
+      background-color: rgba(255, 255, 255, 0.4)
 
     .ace_content
       .executing, .executed, .problem-marker-info, .problem-marker-warning, .problem-marker-error
@@ -147,10 +150,10 @@
       .ace_searchbtn, .ace_replacebtn
         padding: 0px 4px
 
+
 html.no-borderimage
   #spell-view
     span.code-background
       display: none
     img.code-background
       display: block
-
diff --git a/app/styles/play/level/tome/spell_list_entry.sass b/app/styles/play/level/tome/spell_list_entry.sass
index 9ba38f450..888866876 100644
--- a/app/styles/play/level/tome/spell_list_entry.sass
+++ b/app/styles/play/level/tome/spell_list_entry.sass
@@ -13,7 +13,6 @@
   $height: 87px
   $paddingTop: 10px
   $paddingBottom: 25px
-  $childMargin: 2px
   $childSize: $height - $paddingTop - $paddingBottom
   width: 100%
   height: $height
@@ -22,6 +21,7 @@
   position: relative
   background: transparent url(/images/level/code_editor_top_bar_wood_background.png)
   background-size: 100% 100%
+  z-index: 2
 
   .hinge
     position: absolute
@@ -30,7 +30,6 @@
     width: 24px
     height: 20px
     background-size: contain
-    z-index: 100
 
   .hinge-0
     left: 20%
@@ -45,15 +44,24 @@
     background: linear-gradient(to bottom, rgba(0,0,0,0.5) 0%,rgba(0,0,0,0.5) 100%), url(/images/level/code_editor_top_bar_wood_background.png)
     background-size: 100% 100%
   
-  .spell-list-button, .thang-avatar-view, .reload-code, .beautify-code, .fullscreen-code
-    width: $childSize
-    height: $childSize
-    margin: 0 $childMargin
+  .thang-avatar-view
+    width: $childSize - 10px
+    margin: 5px
     display: inline-block
-
-  .spell-list-button, .thang-avatar-view
     float: left
 
+  .btn.btn-small
+    margin-top: 15px
+    margin-right: 15px
+    font-size: 18px
+
+    .glyphicon
+      font-size: 16px
+    
+  .btn.btn-small.spell-list-button
+    float: left
+    margin-top: 5px
+
   .spell-tool-buttons
     position: absolute
     right: 0px
@@ -69,43 +77,32 @@
   .fullscreen-code
     float: right
     &:not(.maximized)
-      .icon-resize-small
+      .glyphicon-resize-small
         display: none
     &.maximized
-      .icon-fullscreen
+      .glyphicon-fullscreen
         display: none
 
-  .btn.btn-small
-    background: transparent
-    padding: 0
-
-    &:not(:hover)
-      border-color: transparent
-      @include box-shadow(none)
-
-    .icon-chevron-down, .icon-repeat, .icon-magnet, .icon-fullscreen, .icon-resize-small
-      margin-top: 7px
-    
   .thang-avatar-wrapper
     border-width: 0
 
-  .method-label
+  .method-name-area
     margin-left: 10px
-    line-height: $childSize
-    font-size: 1vw
-    display: inline-block
-    font-weight: bold
-    color: white
+    margin-top: 10px
     text-transform: uppercase
+    display: inline-block
+    font-family: Open Sans Condensed
+    font-weight: bold
 
-  .method-signature
-    margin-left: 10px
-    line-height: $childSize
-    font-size: 1vw
-    display: inline-block
-    font-weight: bold
-    color: white
-    text-transform: uppercase
+    .method-label
+      font-size: 12px
+      color: rgb(243, 211, 59)
+      margin-bottom: -5px
+
+    .method-signature
+      color: white
+      font-size: 18px
+      padding: 0
 
 .spell-list-entry-view:not(.spell-tab)
   cursor: pointer
diff --git a/app/styles/play/level/tome/spell_palette.sass b/app/styles/play/level/tome/spell_palette.sass
index c6f7ff406..d8864eca1 100644
--- a/app/styles/play/level/tome/spell_palette.sass
+++ b/app/styles/play/level/tome/spell_palette.sass
@@ -3,55 +3,44 @@
 
 #spell-palette-view
   position: absolute
-  padding-bottom: 10px
   left: 10px
   right: 10px
-  //height: 140px
-  // Height relates to .tab-content height
-  padding-top: 35px
-  padding-left: 12px
-  padding-right: 4px
-  color: #333
-  // Get crazy with the backgrounds so that we can lower the opacity on the editor background above it, making a gradient of the disabled background color on the top around where it's usually covered
+  padding: 0 4px 10px 40px
   background-color: transparent
   background-size: 100% 100%
-  z-index: 0
+  z-index: 2
   //overflow-y: auto
-  
-  .code-palette-background
-    position: absolute
-    left: 0
-    top: 0
-    width: 100%
-    height: 100%
-    z-index: -1
-    
-  span.code-palette-background
-    border-width: 25px
-    border-image: url(/images/level/code_palette_background.png) 25 fill round
 
-  img.code-palette-background
-    display: none
+  .code-palette-background
+    width: 100%
+    position: absolute
+    left: 0px
+    z-index: -1
 
   &.disabled
     @include opacity(0.80)
 
   h4
-    color: #333
+    color: white
     font-size: 16px
     line-height: 16px
-    margin: 0 4px
+    margin: 25px 0 5px 2px
     font-weight: normal
+    text-transform: uppercase
 
   .nav > li > a
     padding: 2px 20px 0px 20px
     margin-bottom: 3px
 
   ul.nav.nav-pills
+    margin-top: 15px
+
+    h4
+      margin-top: 2px
     li.active a
       background-color: transparent
     &.multiple-tabs li.active a
-      background-color: lighten(rgb(230, 212, 146), 10%)
+      background-color: darken(rgb(230, 212, 146), 30%)
     &.multiple-tabs li:not(.active) a
       cursor: pointer
 
@@ -82,8 +71,9 @@
       @include flexbox()
       @include flex-wrap()
       @include flex-center()
-      outline: 1px dashed #b86
       position: relative
+      background-color: rgb(20, 13, 8)
+      margin: 1px
   
       img.item-image
         width: 38px
@@ -91,49 +81,11 @@
         position: absolute
 
       &:not(:hover) img.item-image
-        -webkit-filter: sepia(100%)
-        filter: sepia(100%)
+        -webkit-filter: contrast(50%) sepia(100%) saturate(500%) hue-rotate(7deg)
+        filter: contrast(50%) sepia(100%) saturate(1000%) hue-rotate(7deg)
   
       .spell-palette-entry-view
         margin-left: 38px
         width: 174px
         width: -webkit-calc(100% - 38px)
         width: calc(100% - 38px)
-
-  .code-language-logo
-    position: absolute
-    width: 16px
-    height: 16px
-    left: 16px
-    top: 36px
-    z-index: 10
-    background-color: transparent
-    background-repeat: no-repeat
-    background-size: contain
-    cursor: pointer
-
-    &.javascript
-      background-image: url(/images/common/code_languages/javascript_icon.png)
-    &.python
-      background-image: url(/images/common/code_languages/python_icon.png)
-    &.coffeescript
-      background-image: url(/images/common/code_languages/coffeescript_icon.png)
-    &.clojure
-      background-image: url(/images/common/code_languages/clojure_icon.png)
-    &.lua
-      background-image: url(/images/common/code_languages/lua_icon.png)
-    &.io
-      background-image: url(/images/common/code_languages/io_icon.png)
-
-    &:hover
-      outline: 1px outset #ccc
-
-      &:active
-        outline: 1px inset #ccc
-
-html.no-borderimage
-  #spell-palette-view
-    span.code-palette-background
-      display: none
-    img.code-palette-background
-      display: block
diff --git a/app/styles/play/level/tome/spell_palette_entry.sass b/app/styles/play/level/tome/spell_palette_entry.sass
index 66d2ce088..cb37378b5 100644
--- a/app/styles/play/level/tome/spell_palette_entry.sass
+++ b/app/styles/play/level/tome/spell_palette_entry.sass
@@ -25,20 +25,21 @@
     background-color: darken(#FFFFFF, 25%)
 
   // Originally pulled these colors from the most relevant textmate-theme classes, but then fudged them a lot.
-  &.function
-    color: black
-  &.object
-    color: rgb(6, 150, 14)
-  &.string
-    color: rgb(3, 106, 7)
-  &.number
-    color: rgb(0, 0, 205)
-  &.boolean
-    color: rgb(88, 92, 246)
-  &.snippet
-    color: blue
-  &.undefined
-    color: rgb(197, 6, 11)
+  //&.function
+  //  color: black
+  //&.object
+  //  color: rgb(6, 150, 14)
+  //&.string
+  //  color: rgb(3, 106, 7)
+  //&.number
+  //  color: rgb(0, 0, 205)
+  //&.boolean
+  //  color: rgb(88, 92, 246)
+  //&.snippet
+  //  color: blue
+  //&.undefined
+  //  color: rgb(197, 6, 11)
+  color: rgb(243, 169, 49)
 
 .spell-palette-popover.popover
   // Only those popovers which are our direct children (spell documentation)
diff --git a/app/styles/play/level/tome/thang_list.sass b/app/styles/play/level/tome/thang_list.sass
deleted file mode 100644
index a06613bd8..000000000
--- a/app/styles/play/level/tome/thang_list.sass
+++ /dev/null
@@ -1,22 +0,0 @@
-@import "app/styles/mixins"
-@import "app/styles/bootstrap/variables"
-
-#thang-list-view
-  margin: 50px 15px 15px 15px
-  overflow: auto
-  height: 80%
-  height: -webkit-calc(100% - 65px)
-  height: calc(100% - 65px)
-
-  h3
-    line-height: 25px
-    margin: 0
-    text-align: center
-    letter-spacing: 0.1em
-  
-  .thang-list-section
-    margin: 5px
-    padding: 5px
-    background-color: rgba(200, 200, 200, 0.25)
-    border-radius: 5px
-    overflow: hidden
diff --git a/app/styles/play/level/tome/thang_list_entry.sass b/app/styles/play/level/tome/thang_list_entry.sass
deleted file mode 100644
index e478d6b13..000000000
--- a/app/styles/play/level/tome/thang_list_entry.sass
+++ /dev/null
@@ -1,38 +0,0 @@
-@import "app/styles/mixins"
-@import "app/styles/bootstrap/variables"
-
-.thang-list-entry-view
-  @include opacity(0.90)
-  cursor: pointer
-  float: left
-  box-sizing: border-box
-  width: 20%
-  max-width: 100px
-  position: relative
-
-  &.dead
-    @include opacity(0.75)
-
-    &:after
-      content: "×"
-      font-size: 160px
-      color: red
-      @include opacity(0.75)
-      position: absolute
-      bottom: 0
-      height: 100%
-      width: 100%
-      text-align: center
-      line-height: 100px
-      font-family: monospace
-
-    .thang-name
-      text-decoration: line-through
-
-  &.disabled
-    @include opacity(0.25)
-    cursor: default
-
-  &:hover:not(.disabled)
-    @include opacity(1)
-
diff --git a/app/styles/play/level/tome/thang_list_entry_spells.sass b/app/styles/play/level/tome/thang_list_entry_spells.sass
deleted file mode 100644
index 312905d1d..000000000
--- a/app/styles/play/level/tome/thang_list_entry_spells.sass
+++ /dev/null
@@ -1,16 +0,0 @@
-@import "app/styles/mixins"
-@import "app/styles/bootstrap/variables"
-
-.thang-list-entry-spells
-
-  .thang-list-entry-spell
-    padding: 4px
-    cursor: pointer
-
-    &:hover
-      background-color: hsla(240, 40, 80, 0.25)
-
-  code
-    background-color: transparent
-    border: 0
-    font-size: 1.1em
diff --git a/app/templates/play/level/modal/editor_config.jade b/app/templates/play/level/modal/editor_config.jade
deleted file mode 100644
index bac960ed1..000000000
--- a/app/templates/play/level/modal/editor_config.jade
+++ /dev/null
@@ -1,55 +0,0 @@
-extends /templates/modal/modal_base
-
-block modal-header-content
-  h3(data-i18n="play_level.editor_config_title") Editor Configuration
-
-block modal-body-content
-  .form
-    .form-group.select-group
-      label.control-label(for="tome-session-language" data-i18n="play_level.editor_config_level_language_label") Language for This Level
-      select#tome-session-language(name="language")
-        for option in languages
-          option(value=option.id selected=(sessionLanguage === option.id))= option.name
-      span.help-block(data-i18n="play_level.editor_config_level_language_description") Define the programming language for this particular level.
-
-    .form-group.select-group
-      label.control-label(for="tome-language" data-i18n="play_level.editor_config_default_language_label") Default Programming Language
-      select#tome-language(name="language")
-        for option in languages
-          option(value=option.id selected=(language === option.id))= option.name
-      span.help-block(data-i18n="play_level.editor_config_default_language_description") Define the programming language you want to code in when starting new levels.
-
-    .form-group.select-group
-      label.control-label(for="tome-key-bindings" data-i18n="play_level.editor_config_keybindings_label") Key Bindings
-      select#tome-key-bindings(name="keyBindings")
-        option(value="default" selected=(keyBindings === "default") data-i18n="play_level.editor_config_keybindings_default") Default (Ace)
-        option(value="vim" selected=(keyBindings === "vim")) Vim
-        option(value="emacs" selected=(keyBindings === "emacs")) Emacs
-      span.help-block(data-i18n="play_level.editor_config_keybindings_description") Adds additional shortcuts known from the common editors.
-
-    .form-group.checkbox
-      label(for="tome-live-completion")
-        input#tome-live-completion(name="liveCompletion", type="checkbox", checked=liveCompletion)
-        span(data-i18n="play_level.editor_config_livecompletion_label") Live Autocompletion
-      span.help-block(data-i18n="play_level.editor_config_livecompletion_description") Displays autocomplete suggestions while typing.
-
-    .form-group.checkbox
-      label(for="tome-invisibles")
-        input#tome-invisibles(name="invisibles", type="checkbox", checked=invisibles)
-        span(data-i18n="play_level.editor_config_invisibles_label") Show Invisibles
-      span.help-block(data-i18n="play_level.editor_config_invisibles_description") Displays invisibles such as spaces or tabs.
-
-    .form-group.checkbox
-      label(for="tome-indent-guides")
-        input#tome-indent-guides(name="indentGuides", type="checkbox", checked=indentGuides)
-        span(data-i18n="play_level.editor_config_indentguides_label") Show Indent Guides
-      span.help-block(data-i18n="play_level.editor_config_indentguides_description") Displays vertical lines to see indentation better.
-
-    .form-group.checkbox
-      label(for="tome-behaviors")
-        input#tome-behaviors(name="behaviors", type="checkbox", checked=behaviors)
-        span(data-i18n="play_level.editor_config_behaviors_label") Smart Behaviors
-      span.help-block(data-i18n="play_level.editor_config_behaviors_description") Autocompletes brackets, braces, and quotes.
-
-block modal-footer-content
-  a(href='#', data-dismiss="modal", aria-hidden="true", data-i18n="modal.close").btn.btn-primary Close
diff --git a/app/templates/play/level/modal/keyboard_shortcuts.jade b/app/templates/play/level/modal/keyboard_shortcuts.jade
index f38fedaa0..961b595d1 100644
--- a/app/templates/play/level/modal/keyboard_shortcuts.jade
+++ b/app/templates/play/level/modal/keyboard_shortcuts.jade
@@ -19,7 +19,7 @@ block modal-body-content
   dl.dl-horizontal
     dt(title=shift + " " + enter)
       kbd ⇧ #{enter}
-    dd(data-i18n="keyboard_shortcuts.cast_spell") Cast current spell.
+    dd(data-i18n="keyboard_shortcuts.run_code") Run current code.
   dl.dl-horizontal
     dt(title=ctrlName + " " + shift + " " + enter)
       kbd #{ctrl} ⇧ #{enter}
diff --git a/app/templates/play/level/tome/cast_button.jade b/app/templates/play/level/tome/cast_button.jade
index a6290974c..a3a153656 100644
--- a/app/templates/play/level/tome/cast_button.jade
+++ b/app/templates/play/level/tome/cast_button.jade
@@ -1,6 +1,8 @@
-button.btn.btn-lg.btn-inverse.banner.cast-button(title=castVerbose, data-i18n="play_level.tome_run_button_ran") Ran
+button.btn.btn-lg.btn-illustrated.cast-button(title=castVerbose)
+  span(data-i18n="play_level.tome_run_button_ran") Ran
 
-if testSubmitText != null && testSubmitText.length > 0
-  button.btn.btn-lg.btn-success.banner.submit-button(title=castRealTimeVerbose) #{testSubmitText}
-else
-  button.btn.btn-lg.btn-success.banner.submit-button(title=castRealTimeVerbose, data-i18n="play_level.tome_submit_button") Submit
+button.btn.btn-lg.btn-illustrated.submit-button(title=castRealTimeVerbose)
+  if testSubmitText != null && testSubmitText.length > 0
+    span= testSubmitText
+  else
+    span(data-i18n="play_level.tome_submit_button") Submit
diff --git a/app/templates/play/level/tome/spell_list_tab_entry.jade b/app/templates/play/level/tome/spell_list_tab_entry.jade
index f3ff09860..e0e4f95b6 100644
--- a/app/templates/play/level/tome/spell_list_tab_entry.jade
+++ b/app/templates/play/level/tome/spell_list_tab_entry.jade
@@ -4,25 +4,27 @@
 .hinge.hinge-3
 
 if includeSpellList
-  .btn.btn-small.spell-list-button(data-i18n="[title]play_level.tome_see_all_methods", title="See all methods you can edit")
-    i.icon-chevron-down
+  .btn.btn-small.btn-illustrated.spell-list-button(data-i18n="[title]play_level.tome_see_all_methods", title="See all methods you can edit")
+    .glyphicon.glyphicon-chevron-down
 
 .thang-avatar-placeholder
 
-.method-label(data-i18n="play_level.tome_current_method") Current Method
-.method-signature #{methodSignature}
+.method-name-area
+  .method-label(data-i18n="play_level.tome_current_method") Current Method
+  .method-signature #{methodSignature}
 
 .spell-tool-buttons
-  if levelType !== 'hero'
-   .btn.btn-small.fullscreen-code(title=maximizeShortcutVerbose)
-     i.icon-fullscreen
-     i.icon-resize-small
-      
-  .btn.btn-small.reload-code(data-i18n="[title]play_level.tome_reload_method", title="Reload original code for this method")
-    i.icon-repeat
+  .btn.btn-small.btn-illustrated.reload-code(data-i18n="[title]play_level.tome_reload_method", title="Reload original code for this method")
+    .glyphicon.glyphicon-repeat
+    span.spl(data-i18n="play_level.reload") Reload
   
-  if codeLanguage === 'javascript'
-    .btn.btn-small.beautify-code(title=beautifyShortcutVerbose)
-      i.icon-magnet
+  if levelType !== 'hero' && levelType !== 'hero-ladder' && levelType !== 'hero-coop'
+   .btn.btn-small.btn-illustrated.fullscreen-code(title=maximizeShortcutVerbose)
+     .glyphicon.glyphicon-fullscreen
+     .glyphicon.glyphicon-resize-small
+      
+  if codeLanguage === 'javascript' && levelType !== 'hero' && levelType !== 'hero-ladder' && levelType !== 'hero-coop'
+    .btn.btn-small.btn-illustrated.beautify-code(title=beautifyShortcutVerbose)
+      .glyphicon.glyphicon-magnet
 
   .clearfix
\ No newline at end of file
diff --git a/app/templates/play/level/tome/spell_palette.jade b/app/templates/play/level/tome/spell_palette.jade
index 0b27aa90e..304ef1a64 100644
--- a/app/templates/play/level/tome/spell_palette.jade
+++ b/app/templates/play/level/tome/spell_palette.jade
@@ -1,8 +1,7 @@
-img(src="/images/level/code_palette_background.png").code-palette-background
+img(src="/images/level/code_palette_wood_background.png").code-palette-background
 span.code-palette-background
 if entryGroupSlugs
   // Non-hero; group by entry groups, or maybe nothing.
-  .code-language-logo
   ul(class="nav nav-pills" + (tabbed ? ' multiple-tabs' : ''))
     each slug, group in entryGroupSlugs
       li(class=group == "this" || slug == "available-spells" ? "active" : "")
diff --git a/app/templates/play/level/tome/thang_list.jade b/app/templates/play/level/tome/thang_list.jade
deleted file mode 100644
index 2d0140f05..000000000
--- a/app/templates/play/level/tome/thang_list.jade
+++ /dev/null
@@ -1,14 +0,0 @@
-#readwrite-thangs.thang-list-section
-  h3(data-i18n="play_level.tome_minion_spells") Your Minions' Spells
-  .thang-list
-  .clearfix
-
-#read-thangs.thang-list-section
-  h3(data-i18n="play_level.tome_read_only_spells") Read-Only Spells
-  .thang-list
-  .clearfix
-
-#muggle-thangs.thang-list-section
-  h3(data-i18n="play_level.tome_other_units") Other Units
-  .thang-list
-  .clearfix
diff --git a/app/templates/play/level/tome/thang_list_entry.jade b/app/templates/play/level/tome/thang_list_entry.jade
deleted file mode 100644
index e69de29bb..000000000
diff --git a/app/templates/play/level/tome/thang_list_entry_spells.jade b/app/templates/play/level/tome/thang_list_entry_spells.jade
deleted file mode 100644
index b95ca4d2a..000000000
--- a/app/templates/play/level/tome/thang_list_entry_spells.jade
+++ /dev/null
@@ -1,5 +0,0 @@
-h4.not-code(data-i18n="play_level.tome_select_spell") Select a Spell
-.thang-list-entry-spells
-  for spell in spells
-    div.thang-list-entry-spell
-      code(data-spell-name=spell.name) #{spell.name}(#{parameters})
\ No newline at end of file
diff --git a/app/templates/play/level/tome/tome.jade b/app/templates/play/level/tome/tome.jade
index f1d1d4dfb..c29f9e4f0 100644
--- a/app/templates/play/level/tome/tome.jade
+++ b/app/templates/play/level/tome/tome.jade
@@ -2,8 +2,6 @@
 
 #spell-list-view
 
-#thang-list-view
-
 #cast-button-view
 
 #spell-view
diff --git a/app/views/play/level/LevelPlaybackView.coffee b/app/views/play/level/LevelPlaybackView.coffee
index f913bec39..16e00516a 100644
--- a/app/views/play/level/LevelPlaybackView.coffee
+++ b/app/views/play/level/LevelPlaybackView.coffee
@@ -2,9 +2,6 @@ CocoView = require 'views/kinds/CocoView'
 template = require 'templates/play/level/playback'
 {me} = require 'lib/auth'
 
-EditorConfigModal = require './modal/EditorConfigModal'
-KeyboardShortcutsModal = require './modal/KeyboardShortcutsModal'
-
 module.exports = class LevelPlaybackView extends CocoView
   id: 'playback-view'
   template: template
diff --git a/app/views/play/level/modal/EditorConfigModal.coffee b/app/views/play/level/modal/EditorConfigModal.coffee
deleted file mode 100644
index f7c9ab857..000000000
--- a/app/views/play/level/modal/EditorConfigModal.coffee
+++ /dev/null
@@ -1,92 +0,0 @@
-ModalView = require 'views/kinds/ModalView'
-template = require 'templates/play/level/modal/editor_config'
-{me} = require 'lib/auth'
-
-module.exports = class EditorConfigModal extends ModalView
-  id: 'level-editor-config-modal'
-  template: template
-  aceConfig: {}
-
-  defaultConfig:
-    language: 'python'
-    keyBindings: 'default'
-    invisibles: false
-    indentGuides: false
-    behaviors: false
-    liveCompletion: true
-
-  events:
-    'change #tome-invisibles': 'updateInvisibles'
-    'change #tome-language': 'updateLanguage'
-    'change #tome-key-bindings': 'updateKeyBindings'
-    'change #tome-indent-guides': 'updateIndentGuides'
-    'change #tome-behaviors': 'updateBehaviors'
-    'change #tome-live-completion': 'updateLiveCompletion'
-
-  constructor: (options) ->
-    super(options)
-    @session = options.session
-
-  getRenderData: ->
-    @aceConfig = _.cloneDeep me.get('aceConfig') ? {}
-    @aceConfig = _.defaults @aceConfig, @defaultConfig
-    c = super()
-    c.languages = [
-      {id: 'python', name: 'Python'}
-      {id: 'javascript', name: 'JavaScript'}
-      {id: 'coffeescript', name: 'CoffeeScript'}
-      {id: 'clojure', name: 'Clojure (Experimental)'}
-      {id: 'lua', name: 'Lua (Experimental)'}
-      {id: 'io', name: 'Io (Experimental)'}
-    ]
-    c.sessionLanguage = @session.get('codeLanguage') ? @aceConfig.language
-    c.language = @aceConfig.language
-    c.keyBindings = @aceConfig.keyBindings
-    c.invisibles = @aceConfig.invisibles
-    c.indentGuides = @aceConfig.indentGuides
-    c.behaviors = @aceConfig.behaviors
-    c.liveCompletion = @aceConfig.liveCompletion
-    c
-
-  updateSessionLanguage: ->
-    @session.set 'codeLanguage', @$el.find('#tome-session-language').val()
-
-  updateLanguage: ->
-    @aceConfig.language = @$el.find('#tome-language').val()
-
-  updateInvisibles: ->
-    @aceConfig.invisibles = @$el.find('#tome-invisibles').prop('checked')
-
-  updateKeyBindings: ->
-    @aceConfig.keyBindings = @$el.find('#tome-key-bindings').val()
-
-  updateIndentGuides: ->
-    @aceConfig.indentGuides = @$el.find('#tome-indent-guides').prop('checked')
-
-  updateBehaviors: ->
-    @aceConfig.behaviors = @$el.find('#tome-behaviors').prop('checked')
-
-  updateLiveCompletion: ->
-    @aceConfig.liveCompletion = @$el.find('#tome-live-completion').prop('checked')
-
-  afterRender: ->
-    super()
-
-  onHidden: ->
-    oldLanguage = @session.get('codeLanguage') ? @aceConfig.language
-    newLanguage = @$el.find('#tome-session-language').val()
-    @session.set 'codeLanguage', newLanguage
-    @aceConfig.language = @$el.find('#tome-language').val()
-    @aceConfig.invisibles = @$el.find('#tome-invisibles').prop('checked')
-    @aceConfig.keyBindings = @$el.find('#tome-key-bindings').val()
-    @aceConfig.indentGuides = @$el.find('#tome-indent-guides').prop('checked')
-    @aceConfig.behaviors = @$el.find('#tome-behaviors').prop('checked')
-    @aceConfig.liveCompletion = @$el.find('#tome-live-completion').prop('checked')
-    me.set 'aceConfig', @aceConfig
-    Backbone.Mediator.publish 'tome:change-config', {}
-    Backbone.Mediator.publish 'tome:change-language', language: newLanguage unless newLanguage is oldLanguage
-    @session.save() unless newLanguage is oldLanguage
-    me.patch()
-
-  destroy: ->
-    super()
diff --git a/app/views/play/level/tome/CastButtonView.coffee b/app/views/play/level/tome/CastButtonView.coffee
index c49482806..d11c9ff4f 100644
--- a/app/views/play/level/tome/CastButtonView.coffee
+++ b/app/views/play/level/tome/CastButtonView.coffee
@@ -33,7 +33,7 @@ module.exports = class CastButtonView extends CocoView
     enter = $.i18n.t 'keyboard_shortcuts.enter'
     castShortcutVerbose = "#{shift}+#{enter}"
     castRealTimeShortcutVerbose = (if @isMac() then 'Cmd' else 'Ctrl') + '+' + castShortcutVerbose
-    context.castVerbose = castShortcutVerbose + ': ' + $.i18n.t('keyboard_shortcuts.cast_spell')
+    context.castVerbose = castShortcutVerbose + ': ' + $.i18n.t('keyboard_shortcuts.run_code')
     context.castRealTimeVerbose = castRealTimeShortcutVerbose + ': ' + $.i18n.t('keyboard_shortcuts.run_real_time')
     # A/B test submit button text
     context.testSubmitText = @testButtonsText.submit  if @testGroup? and @testGroup isnt 0
@@ -105,7 +105,7 @@ module.exports = class CastButtonView extends CocoView
     , (castable) =>
       Backbone.Mediator.publish 'tome:spell-has-changed-significantly-calculation', hasChangedSignificantly: castable
       @castButton.toggleClass('castable', castable).toggleClass('casting', @casting)
-      
+
       # A/B testing cast button text for en-US
       if $.i18n.lng() isnt 'en-US' or not @testGroup? or @testGroup is 0
         if @casting
@@ -160,5 +160,3 @@ module.exports = class CastButtonView extends CocoView
         Action: 'Loaded'
         levelID: @levelID
         castButtonText: @testButtonsText.run + ' ' + @testButtonsText.submit
-
-
diff --git a/app/views/play/level/tome/SpellListEntryView.coffee b/app/views/play/level/tome/SpellListEntryView.coffee
index d2d39edb1..befca0320 100644
--- a/app/views/play/level/tome/SpellListEntryView.coffee
+++ b/app/views/play/level/tome/SpellListEntryView.coffee
@@ -37,6 +37,7 @@ module.exports = class SpellListEntryView extends CocoView
     context
 
   createMethodSignature: ->
+    return @spell.name if @options.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop']
     parameters = (@spell.parameters or []).slice()
     if @spell.language in ['python', 'lua']
       parameters.unshift 'self'
diff --git a/app/views/play/level/tome/SpellListView.coffee b/app/views/play/level/tome/SpellListView.coffee
index 9bf6ece39..a2d9c3a39 100644
--- a/app/views/play/level/tome/SpellListView.coffee
+++ b/app/views/play/level/tome/SpellListView.coffee
@@ -61,7 +61,7 @@ module.exports = class SpellListView extends CocoView
       theseThangs = _.keys(spell.thangs)
       changedThangs = not lastThangs or not _.isEqual theseThangs, lastThangs
       lastThangs = theseThangs
-      newEntries.push entry = new SpellListEntryView spell: spell, showTopDivider: changedThangs, supermodel: @supermodel, includeSpellList: @spells.length > 1
+      newEntries.push entry = new SpellListEntryView spell: spell, showTopDivider: changedThangs, supermodel: @supermodel, includeSpellList: @spells.length > 1, level: @options.level
       @entries.push entry
     for entry in newEntries
       @$el.append entry.el
diff --git a/app/views/play/level/tome/SpellPaletteView.coffee b/app/views/play/level/tome/SpellPaletteView.coffee
index 8750c5f35..683beabbf 100644
--- a/app/views/play/level/tome/SpellPaletteView.coffee
+++ b/app/views/play/level/tome/SpellPaletteView.coffee
@@ -5,7 +5,6 @@ filters = require 'lib/image_filter'
 SpellPaletteEntryView = require './SpellPaletteEntryView'
 LevelComponent = require 'models/LevelComponent'
 ThangType = require 'models/ThangType'
-EditorConfigModal = require '../modal/EditorConfigModal'
 
 N_ROWS = 4
 
@@ -20,9 +19,6 @@ module.exports = class SpellPaletteView extends CocoView
     'surface:frame-changed': 'onFrameChanged'
     'tome:change-language': 'onTomeChangedLanguage'
 
-  events:
-    'click .code-language-logo': 'onEditEditorConfig'
-
   constructor: (options) ->
     super options
     @thang = options.thang
@@ -54,7 +50,7 @@ module.exports = class SpellPaletteView extends CocoView
       @entryGroupElements = {}
       for group, entries of @entryGroups
         @entryGroupElements[group] = itemGroup = $('<div class="property-entry-item-group"></div>').appendTo @$el.find('.properties')
-        itemGroup.append $('<img class="item-image"></img>').attr('src', entries[0].options.item.getPortraitURL()).css('top', Math.max(0, 19 * (entries.length - 2) / 2)) if entries[0].options.item?.getPortraitURL
+        itemGroup.append $('<img class="item-image"></img>').attr('src', entries[0].options.item.getPortraitURL()).css('top', Math.max(0, 19 * (entries.length - 2) / 2) + 2) if entries[0].options.item?.getPortraitURL
         for entry in entries
           itemGroup.append entry.el
           entry.render()  # Render after appending so that we can access parent container for popover
@@ -67,7 +63,6 @@ module.exports = class SpellPaletteView extends CocoView
 
   updateCodeLanguage: (language) ->
     @options.language = language
-    @$el.find('.code-language-logo').removeClass().addClass 'code-language-logo ' + language
 
   updateMaxHeight: ->
     return unless @isHero
@@ -266,9 +261,6 @@ module.exports = class SpellPaletteView extends CocoView
     @createPalette()
     @render()
 
-  onEditEditorConfig: (e) ->
-    @openModalView new EditorConfigModal session: @options.session
-
   destroy: ->
     entry.destroy() for entry in @entries
     @toggleBackground = null
diff --git a/app/views/play/level/tome/SpellView.coffee b/app/views/play/level/tome/SpellView.coffee
index 17477be54..0fc73947b 100644
--- a/app/views/play/level/tome/SpellView.coffee
+++ b/app/views/play/level/tome/SpellView.coffee
@@ -360,10 +360,10 @@ module.exports = class SpellView extends CocoView
       spellPaletteHeight = $('#spell-palette-view').outerHeight()
       maxHeight = tomeHeight - spellListTabEntryHeight - spellToolbarHeight - spellPaletteHeight
       linesAtMaxHeight = Math.floor(maxHeight / lineHeight)
-      lines = Math.max 8, Math.min(screenLineCount + 4, linesAtMaxHeight)
-      # 2 lines buffer is nice, but 4 leaves room to put problem alerts.
+      lines = Math.max 8, Math.min(screenLineCount + 2, linesAtMaxHeight)
+      # 2 lines buffer is nice
       @ace.setOptions minLines: lines, maxLines: lines
-      $('#spell-palette-view').css('top', 38 + 45 + lineHeight * lines)  # Move spell palette up, slightly underlapping us.
+      $('#spell-palette-view').css('top', 175 + lineHeight * lines)  # Move spell palette up, slightly overlapping us.
 
   onManualCast: (e) ->
     cast = @$el.parent().length
diff --git a/app/views/play/level/tome/ThangListEntryView.coffee b/app/views/play/level/tome/ThangListEntryView.coffee
deleted file mode 100644
index 75d03ac22..000000000
--- a/app/views/play/level/tome/ThangListEntryView.coffee
+++ /dev/null
@@ -1,178 +0,0 @@
-# TODO: be useful to add error indicator states to the spellsPopoverTemplate
-# TODO: reordering based on errors isn't working yet
-
-CocoView = require 'views/kinds/CocoView'
-ThangAvatarView = require 'views/play/level/ThangAvatarView'
-template = require 'templates/play/level/tome/thang_list_entry'
-spellsPopoverTemplate = require 'templates/play/level/tome/thang_list_entry_spells'
-{me} = require 'lib/auth'
-
-module.exports = class ThangListEntryView extends CocoView
-  tagName: 'div'  #'li'
-  className: 'thang-list-entry-view'
-  template: template
-  controlsEnabled: true
-  reasonsToBeDisabled: {}
-
-  subscriptions:
-    'tome:problems-updated': 'onProblemsUpdated'
-    'level:disable-controls': 'onDisableControls'
-    'level:enable-controls': 'onEnableControls'
-    'surface:frame-changed': 'onFrameChanged'
-    'level:set-letterbox': 'onSetLetterbox'
-    'tome:thang-list-entry-popover-shown': 'onThangListEntryPopoverShown'
-    'surface:coordinates-shown': 'onSurfaceCoordinatesShown'
-
-  events:
-    'click': 'onClick'
-    'mouseenter': 'onMouseEnter'
-    'mouseleave': 'onMouseLeave'
-
-  constructor: (options) ->
-    super options
-    @thang = options.thang
-    @spells = options.spells
-    @permission = options.permission
-    @reasonsToBeDisabled = {}
-    @sortSpells()
-
-  getRenderData: (context={}) ->
-    context = super context
-    context.thang = @thang
-    context.spell = @spells
-    context
-
-  afterRender: ->
-    super()
-    @avatar?.destroy()
-    @avatar = new ThangAvatarView thang: @thang, includeName: true, supermodel: @supermodel
-    @$el.append @avatar.el  # Before rendering, so render can use parent for popover
-    @avatar.render()
-    @avatar.setSharedThangs @spells.length  # A bit weird to call it sharedThangs; could refactor if we like this
-    @$el.toggle Boolean(@thang.exists)
-    @$el.popover(
-      animation: false
-      html: true
-      placement: 'bottom'
-      trigger: 'manual'
-      content: @getSpellListHTML()
-      container: @$el.parent().parent().parent()
-    )
-
-  sortSpells: ->
-    return if @sorted
-    # Keep only spells for which we have permissions
-    spells = _.filter @spells, (s) => @options.permission and me.team in s.permissions[@options.permission]
-    @spells = _.sortBy spells, @sortScoreForSpell
-    @sorted = true
-
-  sortScoreForSpell: (s) =>
-    # Sort by errored-out spells first, then spells shared with fewest other Thangs
-    # Lower comes first
-    score = 0
-    # My errors are highest priority
-    score -= 9001900190019001 * (s.thangs[@thang.id].aether?.getAllProblems().length or 0)
-    # Other shared Thangs errors are also high priority
-    score -= _.reduce s.thangs, (spellThang, num) -> 900190019001 * (spellThang.aether?.getAllProblems().length or 0)
-    # Read-only spells at the bottom
-    score += 90019001 unless s.canWrite()
-    # The more Thangs sharing a spell, the lower
-    score += 9001 * _.size(s.thangs)
-    score
-
-  select: ->
-    @sortSpells()
-    Backbone.Mediator.publish 'level:select-sprite', thangID: @thang.id, spellName: @spells[0]?.name
-
-  onClick: (e) ->
-    return unless @controlsEnabled
-    @select()
-
-  onMouseEnter: (e) ->
-    return unless @controlsEnabled and @spells.length
-    @clearTimeouts()
-    @showSpellsTimeout = _.delay @showSpells, 100
-
-  onMouseLeave: (e) ->
-    return unless @controlsEnabled and @spells.length
-    @clearTimeouts()
-    @hideSpellsTimeout = _.delay @hideSpells, 100
-
-  clearTimeouts: ->
-    clearTimeout @showSpellsTimeout if @showSpellsTimeout
-    clearTimeout @hideSpellsTimeout if @hideSpellsTimeout
-    @showSpellsTimeout = @hideSpellsTimeout = null
-
-  onThangListEntryPopoverShown: (e) ->
-    # I couldn't figure out how to get the mouseenter / mouseleave to always work, so this is a fallback
-    # to hide our popover if another Thang's popover gets shown.
-    return if e.entry is @
-    @hideSpells()
-
-  onSurfaceCoordinatesShown: (e) ->
-    # Definitely aren't hovering over this.
-    @hideSpells()
-
-  showSpells: =>
-    @clearTimeouts()
-    @sortSpells()
-    @$el.data('bs.popover').options.content = @getSpellListHTML()
-    @$el.popover('setContent').popover('show')
-    @$el.parent().parent().parent().i18n()
-    @popover = @$el.parent().parent().parent().find('.popover')
-    @popover.off 'mouseenter mouseleave'
-    @popover.mouseenter (e) => @showSpells() if @controlsEnabled
-    @popover.mouseleave (e) => @hideSpells()
-    thangID = @thang.id
-    @popover.find('code').click (e) ->
-      Backbone.Mediator.publish 'level:select-sprite', thangID: thangID, spellName: $(@).data 'spell-name'
-    Backbone.Mediator.publish 'tome:thang-list-entry-popover-shown', entry: @
-
-  hideSpells: =>
-    @clearTimeouts()
-    @$el.popover('hide')
-
-  getSpellListHTML: ->
-    spellsPopoverTemplate {spells: @spells}
-
-  onProblemsUpdated: (e) ->
-    return unless e.spell in @spells
-    @sorted = false
-
-  onSetLetterbox: (e) ->
-    if e.on then @reasonsToBeDisabled.letterbox = true else delete @reasonsToBeDisabled.letterbox
-    @updateControls()
-
-  onDisableControls: (e) ->
-    return if e.controls and not ('surface' in e.controls)  # disable selection?
-    @reasonsToBeDisabled.controls = true
-    @updateControls()
-
-  onEnableControls: (e) ->
-    delete @reasonsToBeDisabled.controls
-    @updateControls()
-
-  updateControls: ->
-    enabled = _.keys(@reasonsToBeDisabled).length is 0
-    return if enabled is @controlsEnabled
-    @controlsEnabled = enabled
-    @$el.toggleClass('disabled', not enabled)
-
-  onFrameChanged: (e) ->
-    # Optimize
-    return unless currentThang = e.world.thangMap[@thang.id]
-    exists = Boolean currentThang.exists
-    if @thangDidExist isnt exists
-      @$el.toggle exists
-      @thangDidExist = exists
-    dead = exists and currentThang.health <= 0
-    if @thangWasDead isnt dead
-      @$el.toggleClass 'dead', dead
-      @thangWasDead = dead
-
-  destroy: ->
-    @avatar?.destroy()
-    @popover?.remove()
-    @popover?.off 'mouseenter mouseleave'
-    @popover?.find('code').off 'click'
-    super()
diff --git a/app/views/play/level/tome/ThangListView.coffee b/app/views/play/level/tome/ThangListView.coffee
deleted file mode 100644
index f8b0cc9d0..000000000
--- a/app/views/play/level/tome/ThangListView.coffee
+++ /dev/null
@@ -1,95 +0,0 @@
-# The ThangListView lives in the code area behind the SpellView, so that when you don't have a spell, you can select any Thang.
-# It just ha a bunch of ThangListEntryViews (which are mostly ThangAvatarViews) in a few sections.
-
-CocoView = require 'views/kinds/CocoView'
-template = require 'templates/play/level/tome/thang_list'
-{me} = require 'lib/auth'
-ThangListEntryView = require './ThangListEntryView'
-
-module.exports = class ThangListView extends CocoView
-  className: 'thang-list-view'
-  id: 'thang-list-view'
-  template: template
-
-  constructor: (options) ->
-    super options
-    @spells = options.spells
-    @thangs = _.filter options.thangs, 'isSelectable'
-    @sortThangs()
-
-  sortThangs: ->
-    @readwriteThangs = _.sortBy _.filter(@thangs, (thang) =>
-      return true for spellKey, spell of @spells when thang.id of spell.thangs and spell.canWrite()
-      false
-    ), @sortScoreForThang
-    @readThangs = _.sortBy _.filter(@thangs, (thang) =>
-      return true for spellKey, spell of @spells when thang.id of spell.thangs and spell.canRead() and not spell.canWrite()
-      false
-    ), @sortScoreForThang
-    @muggleThangs = _.sortBy _.without(@thangs, @readwriteThangs..., @readThangs...), @sortScoreForThang
-    if @muggleThangs.length > 15
-      @muggleThangs = []  # Don't render a zillion of these. Slow, too long, maybe not useful.
-
-  sortScoreForThang: (t) =>
-    # Sort by my team, then most spells and fewest shared Thangs per spell,
-    # then by thang.spriteName alpha, then by thang.id alpha.
-    # Lower comes first
-    score = 0
-    # Thangs on my team are highest priority
-    score -= 9001900190019001 if t.team is me.team
-    # The more spells per Thang, the lower
-    score -= 900190019001 for spellKey, spell of @spells when t.id of spell.thangs and spell.canRead()
-    # The more Thangs per spell, the higher
-    score += 90019001 for t2 of spell.thangs for spellKey, spell of @spells when t.id of spell.thangs
-    alpha = (s) -> _.reduce [0 ... s.length], ((acc, i) -> acc + s.charCodeAt(i) / Math.pow(100, i)), 0
-    # Alpha by spriteName
-    score += 9001 * alpha t.spriteName
-    # Alpha by id
-    score += alpha t.id
-    score
-
-  afterRender: ->
-    super()
-    @addThangListEntries()
-
-  addThangListEntries: ->
-    @entries = []
-    for [thangs, section, permission] in [
-      [@readwriteThangs, '#readwrite-thangs', 'readwrite']  # Your Minions
-      [@readThangs, '#read-thangs', 'read']  # Read-Only
-      [@muggleThangs, '#muggle-thangs', null]  # Non-Castable
-    ]
-      section = @$el.find(section).toggle thangs.length > 0
-      for thang in thangs
-        spells = _.filter @spells, (s) -> thang.id of s.thangs
-        entry = new ThangListEntryView thang: thang, spells: spells, permission: permission, supermodel: @supermodel
-        section.find('.thang-list').append entry.el  # Render after appending so that we can access parent container for popover
-        entry.render()
-        @entries.push entry
-
-  topSpellForThang: (thang) ->
-    for entry in @entries when entry.thang.id is thang.id
-      return entry.spells[0]
-    null
-
-  selectPrimarySprite: ->
-    @entries[0]?.select()
-
-  adjustThangs: (spells, thangs) ->
-    # TODO: it would be nice to not have to do this any more, like if we migrate to the hero levels.
-    # Recreating all the ThangListEntryViews and their ThangAvatarViews is pretty slow.
-    # So they aren't even kept up-to-date during world streaming.
-    # Updating the existing subviews? Would be kind of complicated to get all the new thangs and spells propagated.
-    # I would do it, if I didn't think we were perhaps soon to not do the ThangList any more.
-    # Will temporary reduce the number of muggle thangs we're willing to draw.
-    @spells = @options.spells = spells
-    for entry in @entries
-      entry.$el.remove()
-      entry.destroy()
-    @thangs = @options.thangs = thangs
-    @sortThangs()
-    @addThangListEntries()
-
-  destroy: ->
-    entry.destroy() for entry in @entries
-    super()
diff --git a/app/views/play/level/tome/TomeView.coffee b/app/views/play/level/tome/TomeView.coffee
index d8335993b..453acd1bf 100644
--- a/app/views/play/level/tome/TomeView.coffee
+++ b/app/views/play/level/tome/TomeView.coffee
@@ -32,7 +32,6 @@ template = require 'templates/play/level/tome/tome'
 {me} = require 'lib/auth'
 Spell = require './Spell'
 SpellListView = require './SpellListView'
-ThangListView = require './ThangListView'
 SpellPaletteView = require './SpellPaletteView'
 CastButtonView = require './CastButtonView'
 
@@ -62,8 +61,7 @@ module.exports = class TomeView extends CocoView
     #programmableThangs = _.filter @options.thangs, (t) -> t.isProgrammable and t.spriteName isnt 'Hero Placeholder'
     programmableThangs = _.filter @options.thangs, 'isProgrammable'
     @createSpells programmableThangs, programmableThangs[0]?.world  # Do before spellList, thangList, and castButton
-    @spellList = @insertSubView new SpellListView spells: @spells, supermodel: @supermodel
-    @thangList = @insertSubView new ThangListView spells: @spells, thangs: @options.thangs, supermodel: @supermodel unless @options.level.get('type', true) is 'hero'
+    @spellList = @insertSubView new SpellListView spells: @spells, supermodel: @supermodel, level: @options.level
     @castButton = @insertSubView new CastButtonView spells: @spells, levelID: @options.levelID
     @teamSpellMap = @generateTeamSpellMap(@spells)
     unless programmableThangs.length
@@ -77,7 +75,6 @@ module.exports = class TomeView extends CocoView
     thangs = _.filter e.world.thangs, 'inThangList'
     programmableThangs = _.filter thangs, 'isProgrammable'
     @createSpells programmableThangs, e.world
-    @thangList?.adjustThangs @spells, thangs
     @spellList.adjustSpells @spells
 
   onCommentMyCode: (e) ->
@@ -187,7 +184,6 @@ module.exports = class TomeView extends CocoView
     @spellPaletteView = null
     @$el.find('#spell-palette-view').hide()
     @castButton?.$el.hide()
-    @thangList?.$el.show()
 
   onSpriteSelected: (e) ->
     return if @spellView and @options.level.get('type', true) in ['hero', 'hero-ladder', 'hero-coop']  # Never deselect the hero in the Tome.
@@ -207,7 +203,6 @@ module.exports = class TomeView extends CocoView
       @$el.find('#' + @spellView.id).after(@spellView.el).remove()
       @$el.find('#' + @spellTabView.id).after(@spellTabView.el).remove()
       @castButton.attachTo @spellView
-      @thangList?.$el.hide()
       Backbone.Mediator.publish 'tome:spell-shown', thang: thang, spell: spell
     @updateSpellPalette thang, spell
     @spellList.setThangAndSpell thang, spell
@@ -217,7 +212,7 @@ module.exports = class TomeView extends CocoView
   updateSpellPalette: (thang, spell) ->
     return unless thang and @spellPaletteView?.thang isnt thang and thang.programmableProperties or thang.apiProperties
     @spellPaletteView = @insertSubView new SpellPaletteView thang: thang, supermodel: @supermodel, programmable: spell?.canRead(), language: spell?.language ? @options.session.get('codeLanguage'), session: @options.session, level: @options.level
-    @spellPaletteView.toggleControls {}, spell.view.controlsEnabled if spell   # TODO: know when palette should have been disabled but didn't exist
+    @spellPaletteView.toggleControls {}, spell.view.controlsEnabled if spell?.view   # TODO: know when palette should have been disabled but didn't exist
 
   spellFor: (thang, spellName) ->
     return null unless thang?.isProgrammable
@@ -225,9 +220,6 @@ module.exports = class TomeView extends CocoView
     selectedThangSpells = (@spells[spellKey] for spellKey in @thangSpells[thang.id])
     if spellName
       spell = _.find selectedThangSpells, {name: spellName}
-    else if @thangList
-      spell = @thangList.topSpellForThang thang
-      #spell = selectedThangSpells[0]  # TODO: remember last selected spell for this thang
     else
       spell = _.find selectedThangSpells, (spell) -> true  # Just grab one
     spell
@@ -241,10 +233,8 @@ module.exports = class TomeView extends CocoView
     @cast()
 
   onSelectPrimarySprite: (e) ->
-    if @thangList
-      @thangList.selectPrimarySprite()
-    else
-      Backbone.Mediator.publish 'level:select-sprite', thangID: 'Hero Placeholder'
+    # TODO: this may not be correct
+    Backbone.Mediator.publish 'level:select-sprite', thangID: 'Hero Placeholder'
 
   destroy: ->
     spell.destroy() for spellKey, spell of @spells