diff --git a/browserid/static/dialog/controllers/authenticate_controller.js b/browserid/static/dialog/controllers/authenticate_controller.js
index 4a2de9cd19b175bd84d3274d8904e3dc96d03f9c..2c1f2145493ac3f5210e7658de404cb8f3dbc911 100644
--- a/browserid/static/dialog/controllers/authenticate_controller.js
+++ b/browserid/static/dialog/controllers/authenticate_controller.js
@@ -1,5 +1,5 @@
 /*jshint browser:true, jQuery: true, forin: true, laxbreak:true */
-/*global BrowserID, PageController: true */
+/*global BrowserID:true, PageController: true */
 /* ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
@@ -38,13 +38,14 @@
   "use strict";
 
   var ANIMATION_TIME = 250,
-      identities = BrowserID.Identities;
+      bid = BrowserID,
+      identities = bid.Identities;
 
   function checkEmail(el, event) {
-    cancelEvent(event);
-    var email = $("#email").val(), 
+    var email = $("#email").val(),
         self = this;
 
+    cancelEvent(event);
 
     if(!self.validateEmail(email)) {
       return;
@@ -80,7 +81,7 @@
       else {
         // XXX can't register this email address.
       }
-    }, self.getErrorDialog(BrowserID.Errors.createAccount));
+    }, self.getErrorDialog(bid.Errors.createAccount));
   }
 
   function authenticate(el, event) {
@@ -95,14 +96,14 @@
     }
 
     if(!pass) {
-      self.showTooltip("#password_required");
+      bid.Tooltip.showTooltip("#password_required");
       return;
     }
 
     identities.authenticateAndSync(email, pass, 
       function onAuthenticate(authenticated) {
         if (authenticated) {
-          self.doWait(BrowserID.Wait.authentication);
+          self.doWait(bid.Wait.authentication);
         } 
       },
       function onComplete(authenticated) {
@@ -111,10 +112,10 @@
             email: email 
           });
         } else {
-          self.showTooltip("#cannot_authenticate");
+          bid.Tooltip.showTooltip("#cannot_authenticate");
         }
       }, 
-      self.getErrorDialog(BrowserID.Errors.authentication)
+      self.getErrorDialog(bid.Errors.authentication)
     );
 
   }
diff --git a/browserid/static/dialog/controllers/page_controller.js b/browserid/static/dialog/controllers/page_controller.js
index 3d673ebb204cfca75d2707a4686dcb26a06cb03b..a63ea765c773d47204be28d0e671e12b18dc1bf0 100644
--- a/browserid/static/dialog/controllers/page_controller.js
+++ b/browserid/static/dialog/controllers/page_controller.js
@@ -1,4 +1,5 @@
 /*jshint browser:true, jQuery: true, forin: true, laxbreak:true */                                             
+/*global BrowserID: true*/
 /* ***** BEGIN LICENSE BLOCK *****
  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  *
@@ -12,7 +13,7 @@
  * for the specific language governing rights and limitations under the
  * License.
  *
- * The Original Code is Mozilla bid.
+ * The Original Code is Mozilla BrowserID.
  *
  * The Initial Developer of the Original Code is Mozilla.
  * Portions created by the Initial Developer are Copyright (C) 2011
@@ -36,60 +37,19 @@
 (function() {
 "use strict";
 
-  var ANIMATION_TIME = 250,
-      TOOLTIP_DISPLAY = 2000,
-      bid = BrowserID,  
+  var bid = BrowserID,  
       identities = bid.Identities;
 
-  function showTooltip(el) {
-    el = $(el);
-    var messageFor = el.attr("for");
-
-    if(messageFor) {
-      var contents = el.html();
-      var template = $("#templateTooltip").html();
-      _.templateSettings = {
-          interpolate : /\{\{(.+?)\}\}/g
-      };
-      var tooltip = $(_.template(template, {
-        contents: contents
-      })).appendTo("body");
-
-      var target = $("#" + messageFor);
-      var targetOffset = target.offset();
-      targetOffset.top -= tooltip.outerHeight();
-      targetOffset.left += 10;
-
-      tooltip.css(targetOffset);
-
-      show(tooltip, function() {
-        tooltip.remove();
-        tooltip = null;
-      });
-    }
-    else {
-      show(el);
-    }
-
-    function show(el, complete) {
-      el.fadeIn(ANIMATION_TIME, function() {
-        setTimeout(function() {
-          el.fadeOut(ANIMATION_TIME, complete);
-        }, TOOLTIP_DISPLAY);
-      });
-    }
-  }
 
   function validateEmail(email) {
-    var valid = true,
-        self = this;
+    var valid = true;
 
     if(!email) {
-      self.showTooltip("#email_required");
+      bid.Tooltip.showTooltip("#email_required");
       valid = false;
     }
     else if(!bid.verifyEmail(email)) {
-      self.showTooltip("#email_format");
+      bid.Tooltip.showTooltip("#email_format");
       valid = false;
     }
 
@@ -207,7 +167,6 @@
       this.close("start");
     },
 
-    showTooltip: showTooltip,
     validateEmail: validateEmail
   });
 
diff --git a/browserid/static/dialog/controllers/pickemail_controller.js b/browserid/static/dialog/controllers/pickemail_controller.js
index 77310c3a1d512c2f5e06e1b120a714c7303c5ec6..b0fd83c578048368ad8b76a6ba7e0f3bc7296c7f 100644
--- a/browserid/static/dialog/controllers/pickemail_controller.js
+++ b/browserid/static/dialog/controllers/pickemail_controller.js
@@ -38,7 +38,8 @@
   "use strict";
 
   var ANIMATION_TIME = 250,
-      identities = BrowserID.Identities;
+      bid = BrowserID,
+      identities = bid.Identities;
 
   function animateSwap(fadeOutSelector, fadeInSelector, callback) {
     // XXX instead of using jQuery here, think about using CSS animations.
@@ -123,7 +124,7 @@
 
     identities.emailRegistered(email, function onComplete(registered) {
       if(registered) {
-        self.showTooltip("#already_taken");
+        bid.Tooltip.showTooltip("#already_taken");
       }
       else {
         identities.addEmail(email, function(added) {
@@ -133,10 +134,10 @@
             });
           }
           else {
-            self.showTooltip("#could_not_add");
+            bid.Tooltip.showTooltip("#could_not_add");
           }
         }, function onFailure() {
-            self.showTooltip("#could_not_add");
+            bid.Tooltip.showTooltip("#could_not_add");
         });
       }
     });
diff --git a/browserid/static/dialog/css/popup.css b/browserid/static/dialog/css/popup.css
index 2ba7d8a8f22d0122d3102f450c4d160c60003570..fcdaac04c4d18919c7a72e1e4ce3409c7f81de92 100644
--- a/browserid/static/dialog/css/popup.css
+++ b/browserid/static/dialog/css/popup.css
@@ -484,10 +484,13 @@ html[xmlns] .cf {
   left: 10px;
   background: rgba(0,0,0,.7);
   color: #fff;
-  border-radius: 10px;
-  padding: 5px;
+  border-radius: 5px;
+  padding: 2px 15px;
   border: 2px solid #000;
+  font-weight: bold;
   display: none;
+  max-width: 275px;
+  z-index: 5;
 }
 
 .inputs {
diff --git a/browserid/static/dialog/dialog.js b/browserid/static/dialog/dialog.js
index 88e4066dc4ce6fcdcaf0a7b65be6d7b2554547b5..b163ea65e7a40f5dd986644ccaa53b6cbd91db03 100644
--- a/browserid/static/dialog/dialog.js
+++ b/browserid/static/dialog/dialog.js
@@ -53,6 +53,7 @@ steal.plugins(
                'channel',
                'browserid',
                'storage',
+               'tooltip',
                'browserid-extensions',
                'browserid-network',
                'browserid-identities',
diff --git a/browserid/static/dialog/resources/tooltip.js b/browserid/static/dialog/resources/tooltip.js
new file mode 100644
index 0000000000000000000000000000000000000000..8625595e44fb8dd760e8e63ce44d9dc671e53118
--- /dev/null
+++ b/browserid/static/dialog/resources/tooltip.js
@@ -0,0 +1,108 @@
+/*jshint browser:true, jQuery: true, forin: true, laxbreak:true */                                             
+/*globals BrowserID: true, _:true */
+/* ***** BEGIN LICENSE BLOCK *****
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is Mozilla bid.
+ *
+ * The Initial Developer of the Original Code is Mozilla.
+ * Portions created by the Initial Developer are Copyright (C) 2011
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either the GNU General Public License Version 2 or later (the "GPL"), or
+ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
+ * in which case the provisions of the GPL or the LGPL are applicable instead
+ * of those above. If you wish to allow use of your version of this file only
+ * under the terms of either the GPL or the LGPL, and not to allow others to
+ * use your version of this file under the terms of the MPL, indicate your
+ * decision by deleting the provisions above and replace them with the notice
+ * and other provisions required by the GPL or the LGPL. If you do not delete
+ * the provisions above, a recipient may use your version of this file under
+ * the terms of any one of the MPL, the GPL or the LGPL.
+ *
+ * ***** END LICENSE BLOCK ***** */
+
+BrowserID.Tooltip = (function() {
+  "use strict";
+
+  var ANIMATION_TIME = 250,
+      TOOLTIP_DISPLAY = 2000;
+
+  function createTooltip(el) {
+      var contents = el.html();
+      var template = $("#templateTooltip").html();
+      _.templateSettings = {
+          interpolate : /\{\{(.+?)\}\}/g
+      };
+      var tooltip = $(_.template(template, {
+        contents: contents
+      }));
+
+      return tooltip;
+  }
+
+  function positionTooltip(tooltip, target) {
+    var targetOffset = target.offset();
+    targetOffset.top -= (tooltip.outerHeight() + 5);
+    targetOffset.left += 10;
+
+    tooltip.css(targetOffset);
+  }
+
+  function animateTooltip(el, complete) {
+    el.fadeIn(ANIMATION_TIME, function() {
+      setTimeout(function() {
+        el.fadeOut(ANIMATION_TIME, complete);
+      }, TOOLTIP_DISPLAY);
+    });
+  }
+
+  function createAndShowRelatedTooltip(el, relatedTo) {
+      // This means create a copy of the tooltip element and position it in 
+      // relation to an element.  Right now we are putting the tooltip directly 
+      // above the element.  Once the tooltip is no longer needed, remove it 
+      // from the DOM.
+      var tooltip = createTooltip(el).appendTo("body");
+
+      var target = $("#" + relatedTo);
+      positionTooltip(tooltip, target);
+
+      animateTooltip(tooltip, function() {
+        tooltip.remove();
+        tooltip = null;
+      });
+  }
+
+  function showTooltip(el) {
+    el = $(el);
+    var messageFor = el.attr("for");
+
+    // First, see if we are "for" another element, if we are, create a copy of 
+    // the tooltip to attach to the element.
+    if(messageFor) {
+      createAndShowRelatedTooltip(el, messageFor);
+    }
+    else {
+      animateTooltip(el);
+    }
+  }
+
+
+ return {
+    showTooltip: showTooltip
+ };
+
+}());