diff --git a/authority/jsapi/picker.css b/authority/jsapi/picker.css
index d8fac46cb0440134d19f53478fca54645047027e..5de639d084b8f0d11e533819c3a8b4a03a887a13 100644
--- a/authority/jsapi/picker.css
+++ b/authority/jsapi/picker.css
@@ -7,14 +7,14 @@ body {
     padding: 0;
     margin: 0;
 }
-.sitename {
+span.sitename, span.email {
     font-weight: bold;
 }
 .title {
     font-size: 2em;
     font-weight: bold;
     margin: auto;
-    margin-top: 2em;
+    margin-top: 1.5em;
     margin-bottom: 1em;
 }
 
@@ -53,8 +53,9 @@ body {
 #bottom-bar button {
     height: 25px;
     border: 1px solid rgb(145, 145, 145);
-    -moz-border-radius: 3px;
+    -moz-border-radius: 4px;
     -webkit-border-radius: 4px;
+    border-radius: 4px;
     background-color: rgb(242, 242, 242);
     padding-left: 2em;
     padding-right: 2em;
@@ -77,13 +78,17 @@ body {
 
 div.actions > div.action {
     float: left;
+}
+
+div.actions > div.action a {
     cursor: pointer;
+    color: rgb(65, 126, 208);
+    text-decoration: none;
 }
 
 div.actions {
     position: fixed;
     bottom: 68px;
-    color: rgb(65, 126, 208);
     font-size: .8em;
     margin-left: 79px;
 }
@@ -175,3 +180,25 @@ span.good {
 div.subtle {
     opacity: .7;
 }
+
+div.dialog div.attention, div.dialog div.attention_awesome  {
+    -moz-border-radius: 4px;
+    -webkit-border-radius: 4px;
+    border-radius: 4px;
+    width: 400px;
+    padding:13px;
+    margin: auto;
+    text-align: left;
+}
+
+div.dialog div.attention {
+    border: 1px solid rgb(219,231,238);
+    background-color: rgb(244,247,251);
+}
+
+div.dialog div.attention_awesome {
+    border: 1px solid rgb(0,161,51);
+    background-color: rgb(0,161,51);
+    color: white;
+    font-weight: bold;
+}
\ No newline at end of file
diff --git a/authority/jsapi/picker.html b/authority/jsapi/picker.html
index 5fae4682fd46bc0da4e71cb90adfa02f5df01cd3..18ea82a32c0393f0e101a4b984ed2524e734696f 100644
--- a/authority/jsapi/picker.html
+++ b/authority/jsapi/picker.html
@@ -7,10 +7,10 @@
 <div id="default_dialog" class="dialog">
   <div class="title"> Sign in with Firefox ID </div>
   <div class="content">
-    <div class="summary">Enter your email and Firefox ID password to log into <span class="sitename"></span>:</div>
+    <div class="summary">Enter your email and Firefox ID password to log into <span class="sitename bad"></span>:</div>
     <div class="input">
       <div class="label"> Email </div>
-      <div class="input"> <input type="text"></input></div> 
+      <div class="input"> <input type="text"></input></div>
     </div>
     <div class="input">
       <div class="label"> Password </div>
@@ -18,7 +18,7 @@
       <div class="note"> <a href="#">I forgot my password</a> </div>
     </div>
     <div class="actions">
-      <div class="action"> Create Your Firefox ID </div>
+      <div class="action"><a href="#">Create Your Firefox ID</a></div>
     </div>
   </div>
 </div>
@@ -28,7 +28,7 @@
     <div class="summary">Firefox ID makes logging in safer and easier.  To begin, please provide an email address and pick a password:</div>
     <div class="input">
       <div class="label"> Email </div>
-      <div class="input"> <input type="text"></input></div> 
+      <div class="input"> <input type="text"></input></div>
       <div class="note"></div>
     </div>
     <div class="input">
@@ -42,6 +42,27 @@
     </div>
   </div>
 </div>
+<div id="confirm_email_dialog" class="dialog">
+  <div class="title"> Confirm Your Email </div>
+  <div class="content">
+    <div class="summary">Welcome, <span class="email good"></span>.  You will receive a <strong>confirmation email</strong> in a few moments.  To activate your Firefox ID, please <strong>visit the link</strong> included in the email.</div>
+    <div class="attention">
+      Waiting for email confirmation... <span class="bad"> THIS ISN'T REAL!  JUST WAIT 5 SECONDS!</span>
+    </div>
+    <div class="actions">
+      <div class="action"> No email yet?  <a href="#">Resend it!</a></div>
+    </div>
+  </div>
+</div>
+<div id="confirmed_email_dialog" class="dialog">
+  <div class="title"> Confirm Your Email </div>
+  <div class="content">
+    <div class="summary">Welcome, <span class="email good"></span>.  You will receive a <strong>confirmation email</strong> in a few moments.  To activate your Firefox ID, please <strong>visit the link</strong> included in the email.</div>
+    <div class="attention_awesome ">
+      Your email has been confirmed and your Firefox ID created! </span>
+    </div>
+  </div>
+</div>
 <div id="ids_dialog" class="dialog">
   <div class="title"> Sign in with Firefox ID </div>
   <div class="content">
diff --git a/authority/jsapi/picker.js b/authority/jsapi/picker.js
index ac8fe7b19131a47434aca57603dcd9c00bc477a7..3a97fdc76d5af8baa518ccf32bbb0d04bdeec043 100644
--- a/authority/jsapi/picker.js
+++ b/authority/jsapi/picker.js
@@ -1,174 +1,266 @@
 // this is the picker code!  it runs in the identity provider's domain, and
 // fiddles the dom expressed by picker.html
+(function() {
+  var chan = Channel.build(
+    {
+      window: window.opener,
+      origin: "*",
+      scope: "mozid"
+    });
 
-var chan = Channel.build(
-  {
-    window: window.opener,
-    origin: "*",
-    scope: "mozid"
-  });
+  function runIDsDialog(cb) {
+    // iterate over all of the available identities and add a links to them
+    var list = document.getElementById('identities');
 
-function runIDsDialog(cb) {
-  // iterate over all of the available identities and add a links to them
-  var list = document.getElementById('identities');
-
-  var first = true;
-  [ "foo@bar.com", "baz@bing.com" ].forEach(function(i) {
-    var div = document.createElement("div");
-    var button = document.createElement("input");
-    button.setAttribute('type', 'radio');
-    button.checked = first;
-    first = false;
-    button.name = "id_selection";
-    button.value = i;
-    div.appendChild(button);
-    var label = document.createElement("div");
-    label.innerText = i;
-    label.addEventListener("click", function(evt) {
-      console.log("clicked label: ");
-      this.parentNode.firstChild.checked = true;
+    var first = true;
+    [ "foo@bar.com", "baz@bing.com" ].forEach(function(i) {
+      var div = document.createElement("div");
+      var button = document.createElement("input");
+      button.setAttribute('type', 'radio');
+      button.checked = first;
+      first = false;
+      button.name = "id_selection";
+      button.value = i;
+      div.appendChild(button);
+      var label = document.createElement("div");
+      label.innerText = i;
+      label.addEventListener("click", function(evt) {
+        console.log("clicked label: ");
+        this.parentNode.firstChild.checked = true;
+      });
+      div.appendChild(label);
+      list.appendChild(div);
     });
-    div.appendChild(label);
-    list.appendChild(div);
-  });
 
-  // now make the body visible...
-  document.getElementById("body").style.display = "block";
+    // now make the body visible...
+    document.getElementById("body").style.display = "block";
 
-  document.getElementById('signin').addEventListener("click", function(evt) {
-    var is = document.forms["identities"].elements['id_selection'];
-    var id = undefined;
-    for (var i = 0; i < is.length; i++) {
-      if (is[i].checked) {
-        id = is[i].value;
-        break;
+    document.getElementById('signin').addEventListener("click", function(evt) {
+      var is = document.forms["identities"].elements['id_selection'];
+      var id = undefined;
+      for (var i = 0; i < is.length; i++) {
+        if (is[i].checked) {
+          id = is[i].value;
+          break;
+        }
       }
-    }
-    if (id) {
-      trans.complete(id);
-      window.self.close();
-    } else {
+      if (id) {
+        trans.complete(id);
+        window.self.close();
+      } else {
+        trans.error("noSelection", "no id selected by user");
+        window.self.close();
+      }
+    });
+
+    document.getElementById('cancel').addEventListener("click", function(evt) {
       trans.error("noSelection", "no id selected by user");
       window.self.close();
-    }
-  });
+    });
+  }
 
-  document.getElementById('cancel').addEventListener("click", function(evt) {
-    trans.error("noSelection", "no id selected by user");
-    window.self.close();
-  });
-}
+  function runDefaultDialog(onsuccess, onerror) {
+    $(".dialog").hide();
+
+    $("#back").hide();
+    $("#cancel").show().unbind('click').click(function() {
+      onerror("canceled");
+    });
+    $("#submit").show().unbind('click').click(function() {
+      onerror("notImplemented");
+    }).text("Sign In");
+    $("#default_dialog div.note > a").unbind('click').click(function() {
+      onerror("notImplemented");
+    });
+    $("#default_dialog div.note > a").unbind('click').click(function() {
+      onerror("notImplemented");
+    });
+    $("#default_dialog div.actions div.action").unbind('click').click(function() {
+      runCreateDialog(onsuccess, onerror);
+    });
+    $("#default_dialog").fadeIn(500);
+  }
 
-function runDefaultDialog(onsuccess, onerror) {
-  $(".dialog").hide();
+  // a handle to a timeout of a running email check
+  var emailCheckState = undefined;
+  // the next email to check, if one is entered while a check is running
+  var nextEmailToCheck = undefined;
+  // a set of emails that we've checked for this session
+  var checkedEmails = {
 
-  $("#back").hide();
-  $("#cancel").show().unbind('click').click(function() {
-    onerror("canceled");
-  });
-  $("#submit").show().unbind('click').click(function() {
-    onerror("notImplemented");
-  }).text("Sign In");
-  $("#default_dialog div.note > a").unbind('click').click(function() {
-    onerror("notImplemented");
-  });
-  $("#default_dialog div.note > a").unbind('click').click(function() {
-    onerror("notImplemented");
-  });
-  $("#default_dialog div.actions div.action").unbind('click').click(function() {
-    runCreateDialog(onsuccess, onerror);
-  });
-  $("#default_dialog").fadeIn(500);
-}
+  };
 
-function runCreateDialog(onsuccess, onerror) {
-  $(".dialog").hide();
+  function runConfirmEmailDialog(email, onsuccess, onerror) {
+    $(".dialog").hide();
 
-  $("#back").show().unbind('click').click(function() {
-    runDefaultDialog(onsuccess, onerror);
-  });
-  $("#cancel").show().unbind('click').click(function() {
-    onerror("canceled");
-  });
-  $("#submit").show().unbind('click').click(function() {
-    onerror("notImplemented");
-  }).text("Continue").addClass("disabled");
-
-  function checkInput() {
-    $("#submit").removeClass("disabled");
-
-    // first we should check the email entry 
-    $("#create_dialog div.note:eq(0)").html($('<span class="warning"/>').text("Checking address"));
-    // (XXX)
-
-    // next let's check the password entry
-    var pass = $("#create_dialog input:eq(1)").val();
-    var match = pass === $("#create_dialog input:eq(2)").val();
-    if (!match) {
-      $("#submit").addClass("disabled");
-      $("#create_dialog div.note:eq(1)").html($('<span class="bad"/>').text("Passwords different"));
-    } else {
-      if (!pass) {
+    $("span.email").text(email);
+
+    // XXX: till we implement email confirmation, this is a faked up step.  just wait 5s
+    var fakeyTimeout = setTimeout(function() {
+      runConfirmedEmailDialog(email, onsuccess, onerror);
+    }, 5000);
+
+    $("#back").show().unbind('click').click(function() {
+      window.clearTimeout(fakeyTimeout);
+      runCreateDialog(onsuccess, onerror);
+    });
+
+    $("#cancel").show().unbind('click').click(function() {
+      window.clearTimeout(fakeyTimeout);
+      onerror("canceled");
+    });
+    $("#submit").hide();
+
+    $("#create_email_dialog div.actions div.action a").unbind('click').click(function() {
+      // XXX: resend the email!
+      return true;
+    });
+    $("#confirm_email_dialog").fadeIn(500);
+
+  }
+
+  function runConfirmedEmailDialog(email, onsuccess, onerror) {
+    $(".dialog").hide();
+
+    $("span.email").text(email);
+
+    $("#back").hide();
+
+    $("#cancel").show().unbind('click').click(function() {
+      onerror("canceled");
+    });
+    $("#submit").show().unbind('click').click(function() {
+      runIDsDialog(onsuccess, onerror);
+    }).text("Continue");
+
+    $("#confirmed_email_dialog").show();
+  }
+
+  function runCreateDialog(onsuccess, onerror) {
+    $(".dialog").hide();
+
+    $("#back").show().unbind('click').click(function() {
+      runDefaultDialog(onsuccess, onerror);
+    });
+    $("#cancel").show().unbind('click').click(function() {
+      onerror("canceled");
+    });
+    $("#submit").show().unbind('click').click(function() {
+      // ignore the click if we're disabled
+      if ($(this).hasClass('disabled')) return true;
+
+      // user wishes to create a firefox ID!  now let's validate the email flow
+      runConfirmEmailDialog($("#create_dialog input:eq(0)").val(), onsuccess, onerror);
+    }).text("Continue").addClass("disabled");
+
+
+    function checkInput() {
+      $("#submit").removeClass("disabled");
+
+      // check the email address
+      var email = $("#create_dialog input:eq(0)").val();
+      if (typeof email === 'string' && email.length) {
+        var valid = checkedEmails[email];
+        if (typeof valid === 'boolean') {
+          if (valid) {
+            $("#create_dialog div.note:eq(0)").html($('<span class="good"/>').text("Email is valid"));
+          } else {
+            $("#create_dialog div.note:eq(0)").html($('<span class="bad"/>').text("Email in use"));
+            $("#submit").addClass("disabled");
+          }
+        } else {
+          // this is an email that needs to be checked!
+          if (emailCheckState !== 'querying') {
+            if (emailCheckState) window.clearTimeout(emailCheckState);
+            emailCheckState = setTimeout(function() {
+              // XXX: this is where we should actually bounce off the server and enter the 'querying' state
+              // for now, we just call it valid
+              checkedEmails[nextEmailToCheck] = true;
+              emailCheckState = undefined;
+              checkInput();
+            }, 500);
+          }
+          nextEmailToCheck = email;
+          $("#submit").addClass("disabled");
+          $("#create_dialog div.note:eq(0)").html($('<span class="warning"/>').text("Checking address"));
+        }
+      } else {
+        $("#create_dialog div.note:eq(0)").empty();
         $("#submit").addClass("disabled");
-        $("#create_dialog div.note:eq(1)").html($('<span class="bad"/>').text("Enter a password"));
-      } else if (pass.length < 5) {
+      }
+
+      // next let's check the password entry
+      var pass = $("#create_dialog input:eq(1)").val();
+      var match = pass === $("#create_dialog input:eq(2)").val();
+      if (!match) {
         $("#submit").addClass("disabled");
-        $("#create_dialog div.note:eq(1)").html($('<span class="bad"/>').text("Password too short"));
+        $("#create_dialog div.note:eq(1)").html($('<span class="bad"/>').text("Passwords different"));
       } else {
-        $("#create_dialog div.note:eq(1)").html($('<span class="good"/>').text("Password OK"))
+        if (!pass) {
+          $("#submit").addClass("disabled");
+          $("#create_dialog div.note:eq(1)").html($('<span class="bad"/>').text("Enter a password"));
+        } else if (pass.length < 5) {
+          $("#submit").addClass("disabled");
+          $("#create_dialog div.note:eq(1)").html($('<span class="bad"/>').text("Password too short"));
+        } else {
+          $("#create_dialog div.note:eq(1)").html($('<span class="good"/>').text("Password OK"))
+        }
       }
     }
-  }
 
-  // watch input dialogs
-  $("#create_dialog input:first").unbind('keyup').bind('keyup', function() {
-    checkInput();
-  });
+    // watch input dialogs
+    $("#create_dialog input:first").unbind('keyup').bind('keyup', function() {
+      checkInput();
+    });
+
+    $("#create_dialog input:gt(0)").unbind('keyup').bind('keyup', checkInput);
 
-  $("#create_dialog input:gt(0)").unbind('keyup').bind('keyup', checkInput);
+    // do a check at load time, in case the user is using the back button (enables the continue button!)
+    checkInput();
 
-  $("#create_dialog").fadeIn(500);
-}
+    $("#create_dialog").fadeIn(500);
+  }
 
-runCreateDialog();
+  runCreateDialog();
 
-function errorOut(trans, code) {
-  function getVerboseMessage(code) {
-    var msgs = {
-      "canceled": "user canceled selection",
-      "notImplemented": "the user tried to invoke behavior that's not yet implemented"
-    };
-    var msg = msgs[code];
-    if (!msg) {
-      alert("need verbose message for " + code); 
-      msg = "unknown error"
+  function errorOut(trans, code) {
+    function getVerboseMessage(code) {
+      var msgs = {
+        "canceled": "user canceled selection",
+        "notImplemented": "the user tried to invoke behavior that's not yet implemented"
+      };
+      var msg = msgs[code];
+      if (!msg) {
+        alert("need verbose message for " + code); 
+        msg = "unknown error"
+      }
+      return msg;
     }
-    return msg;
+    trans.error(code, getVerboseMessage(code));
+    window.self.close();
   }
-  trans.error(code, getVerboseMessage(code));
-  window.self.close();
-}
 
-chan.bind("getVerifiedEmail", function(trans, s) {
-  trans.delayReturn(true);
+  chan.bind("getVerifiedEmail", function(trans, s) {
+    trans.delayReturn(true);
 
-  // set the requesting site
-  $(".sitename").text(trans.origin.replace(/^.*:\/\//, ""));
+    // set the requesting site
+    $(".sitename").text(trans.origin.replace(/^.*:\/\//, ""));
 
-  // XXX: check to see if there's any pubkeys stored in the browser
-  var haveIDs = false;
+    // XXX: check to see if there's any pubkeys stored in the browser
+    var haveIDs = false;
 
-  if (haveIDs) {
-    runIDs(function(rv) {
-      trans.complete(rv);
-    }, function(error) {
-      errorOut(trans, error);
-    });
-  } else {
-    runDefaultDialog(function(rv) {
-      trans.complete(rv);
-    }, function(error) {
-      errorOut(trans, error);
-    });
-  }
-});
+    if (haveIDs) {
+      runIDsDialog(function(rv) {
+        trans.complete(rv);
+      }, function(error) {
+        errorOut(trans, error);
+      });
+    } else {
+      runDefaultDialog(function(rv) {
+        trans.complete(rv);
+      }, function(error) {
+        errorOut(trans, error);
+      });
+    }
+  });
+})();
\ No newline at end of file