diff --git a/app/schemas/subscriptions/tome.coffee b/app/schemas/subscriptions/tome.coffee
index 74f77c66a..4d9f3e369 100644
--- a/app/schemas/subscriptions/tome.coffee
+++ b/app/schemas/subscriptions/tome.coffee
@@ -127,3 +127,5 @@ module.exports =
   'tome:show-problem-alert': c.object {title: 'Show Problem Alert', description: 'A problem alert needs to be shown.', required: ['problem']},
     problem: {type: 'object'}
     lineOffsetPx: {type: ['number', 'undefined']}
+
+  'tome:jiggle-problem-alert': c.object {title: 'Jiggle Problem Alert'}
diff --git a/app/styles/play/level/tome/problem_alert.sass b/app/styles/play/level/tome/problem_alert.sass
index 42c7be399..1926fecf3 100644
--- a/app/styles/play/level/tome/problem_alert.sass
+++ b/app/styles/play/level/tome/problem_alert.sass
@@ -18,6 +18,55 @@
   border-image: url(/images/level/code_editor_error_background.png) 16 20 fill round
   border-width: 16px 20px
 
+  // Jiggle animation
+  // TODO: Cleanup browser compat nonsense with sass mixin
+  // TODO: http://joshbroton.com/quick-fix-sass-mixins-for-css-keyframe-animations/
+  animation-duration: .4s
+  animation-name: jiggle
+  animation-play-state: running
+  animation-iteration-count: infinite
+  @keyframes jiggle
+    0%
+      transform: rotate(0deg)
+    25%
+      transform: rotate(1deg)
+    50%
+      transform: rotate(0deg)
+    75%
+      transform: rotate(-1deg)
+    100%
+      transform: rotate(0deg)
+  -moz-animation-duration: .4s
+  -moz-animation-name: jiggle
+  -moz-animation-play-state: running
+  -moz-animation-iteration-count: infinite
+  @-moz-keyframes jiggle
+    0%
+      -moz-transform: rotate(0deg)
+    25%
+      -moz-transform: rotate(1deg)
+    50%
+      -moz-transform: rotate(0deg)
+    75%
+      -moz-transform: rotate(-1deg)
+    100%
+      -moz-transform: rotate(0deg)
+  -webkit-animation-duration: .4s
+  -webkit-animation-name: jiggle
+  -webkit-animation-play-state: running
+  -webkit-animation-iteration-count: infinite
+  @-webkit-keyframes jiggle
+    0%
+      -webkit-transform: rotate(0deg)
+    25%
+      -webkit-transform: rotate(1deg)
+    50%
+      -webkit-transform: rotate(0deg)
+    75%
+      -webkit-transform: rotate(-1deg)
+    100%
+      -webkit-transform: rotate(0deg)
+
   &.no-hint
     // Since it's probably only one line, let's make it not look weird by being tiny.
     padding: 7px
diff --git a/app/views/play/level/tome/ProblemAlertView.coffee b/app/views/play/level/tome/ProblemAlertView.coffee
index e19163df9..c516bd40e 100644
--- a/app/views/play/level/tome/ProblemAlertView.coffee
+++ b/app/views/play/level/tome/ProblemAlertView.coffee
@@ -9,6 +9,7 @@ module.exports = class ProblemAlertView extends CocoView
 
   subscriptions:
     'tome:show-problem-alert': 'onShowProblemAlert'
+    'tome:jiggle-problem-alert': 'onJiggleProblemAlert'
     'tome:manual-cast': 'onHideProblemAlert'
     'real-time-multiplayer:manual-cast': 'onHideProblemAlert'
 
@@ -51,6 +52,18 @@ module.exports = class ProblemAlertView extends CocoView
     @$el.show()
     @onWindowResize()
     @render()
+    @onJiggleProblemAlert()
+
+  onJiggleProblemAlert: ->
+    if @$el.is(":visible")
+      @$el.css('animation-play-state', 'running')
+      @$el.css('-moz-animation-play-state', 'running')
+      @$el.css('-webkit-animation-play-state', 'running')
+      pauseJiggle = =>
+        @$el.css('animation-play-state', 'paused')
+        @$el.css('-moz-animation-play-state', 'paused')
+        @$el.css('-webkit-animation-play-state', 'paused')
+      _.delay pauseJiggle, 2000
 
   onHideProblemAlert: ->
     @onRemoveClicked()
diff --git a/app/views/play/level/tome/SpellView.coffee b/app/views/play/level/tome/SpellView.coffee
index a246f2a0a..eafc1473e 100644
--- a/app/views/play/level/tome/SpellView.coffee
+++ b/app/views/play/level/tome/SpellView.coffee
@@ -773,13 +773,7 @@ module.exports = class SpellView extends CocoView
 
   onAnnotationClick: ->
     # @ is the gutter element
-    msg = "Edit line #{$(@).index() + 1} to fix it."
-    alertBox = $("<div class='alert alert-info fade in'>#{msg}</div>")
-    offset = $(@).offset()
-    offset.left -= 162  # default width of the Bootstrap alert here
-    alertBox.css(offset).css('z-index', 500).css('position', 'absolute')
-    $('body').append(alertBox.alert())
-    _.delay (-> alertBox.alert('close')), 2500
+    Backbone.Mediator.publish 'tome:jiggle-problem-alert', {}
 
   onDisableControls: (e) -> @toggleControls e, false
   onEnableControls: (e) -> @toggleControls e, @writable