diff --git a/actions/disfavor.php b/actions/disfavor.php
index 35cfd60707..6ac94d720a 100644
--- a/actions/disfavor.php
+++ b/actions/disfavor.php
@@ -37,17 +37,17 @@ class DisfavorAction extends Action {
 			return;
 		}
 
-		$token = $this->trimmed('token');
-
-		if (!$token || $token != common_session_token()) {
-			$this->client_error(_('There was a problem with your session token. Try again, please.'));
-			return;
-		}
-
 		$id = $this->trimmed('notice');
 
 		$notice = Notice::staticGet($id);
 
+		$token = $this->trimmed('token-'.$notice->id);
+
+		if (!$token || $token != common_session_token()) {
+			$this->client_error(_("There was a problem with your session token. Try again, please."));
+			return;
+		}
+
 		$fave = new Fave();
 		$fave->user_id = $this->id;
 		$fave->notice_id = $notice->id;
@@ -69,7 +69,7 @@ class DisfavorAction extends Action {
 		if ($this->boolean('ajax')) {
 			common_start_html('text/xml');
 			common_element_start('head');
-			common_element('title', _('Favor'));
+			common_element('title', null, _('Add to favorites'));
 			common_element_end('head');
 			common_element_start('body');
 			common_favor_form($notice);
diff --git a/actions/favor.php b/actions/favor.php
index dd61899e4b..82b70a35b2 100644
--- a/actions/favor.php
+++ b/actions/favor.php
@@ -38,17 +38,18 @@ class FavorAction extends Action {
 			return;
 		}
 
-		# CSRF protection
-
-		$token = $this->trimmed('token');
-		if (!$token || $token != common_session_token()) {
-			$this->client_error(_('There was a problem with your session token. Try again, please.'));
-			return;
-		}
 		$id = $this->trimmed('notice');
 
 		$notice = Notice::staticGet($id);
 
+		# CSRF protection
+
+		$token = $this->trimmed('token-'.$notice->id);
+		if (!$token || $token != common_session_token()) {
+			$this->client_error(_("There was a problem with your session token. Try again, please."));
+			return;
+		}
+
 		if ($user->hasFave($notice)) {
 			$this->client_error(_('This notice is already a favorite!'));
 			return;
@@ -67,7 +68,7 @@ class FavorAction extends Action {
 		if ($this->boolean('ajax')) {
 			common_start_html('text/xml');
 			common_element_start('head');
-			common_element('title', _('Disfavor'));
+			common_element('title', null, _('Disfavor favorite'));
 			common_element_end('head');
 			common_element_start('body');
 			common_disfavor_form($notice);
diff --git a/js/util.js b/js/util.js
index 111beef250..151c0d1114 100644
--- a/js/util.js
+++ b/js/util.js
@@ -17,94 +17,86 @@
  */
 
 $(document).ready(function(){
-        // count character on keyup
-        function counter(event){
-            var maxLength     = 140;
-            var currentLength = $("#status_textarea").val().length;
-            var remaining = maxLength - currentLength;
-            var counter   = $("#counter");
-            counter.text(remaining);
+	// count character on keyup
+	function counter(event){
+		var maxLength = 140;
+		var currentLength = $("#status_textarea").val().length;
+		var remaining = maxLength - currentLength;
+		var counter = $("#counter");
+		counter.text(remaining);
+		
+		if (remaining <= 0) {
+			counter.addClass("toomuch");
+		} else {
+			counter.removeClass("toomuch");
+		}
+	}
 
-            if (remaining <= 0) {
-                counter.attr("class", "toomuch");
-            } else {
-                counter.attr("class", "");
-            }
-        }
+	function submitonreturn(event) {
+		if (event.keyCode == 13) {
+			$("#status_form").submit();
+			event.preventDefault();
+			event.stopPropagation();
+			return false;
+		}
+		return true;
+	}
 
-        function submitonreturn(event) {
-             if (event.keyCode == 13) {
-                  $("#status_form").submit();
-                  event.preventDefault();
-                  event.stopPropagation();
-                  return false;
-             }
-             return true;
-        }
+	if ($("#status_textarea").length) {
+		$("#status_textarea").bind("keyup", counter);
+		$("#status_textarea").bind("keydown", submitonreturn);
+		
+		// run once in case there's something in there
+		counter();
+		
+		// set the focus
+		$("#status_textarea").focus();
+	}
 
-        if ($("#status_textarea").length) {
-             $("#status_textarea").bind("keyup", counter);
-             $("#status_textarea").bind("keydown", submitonreturn);
+	// XXX: refactor this code
 
-            // run once in case there's something in there
-            counter();
+	var favoptions = { dataType: 'xml',
+					   success: function(xml) { var new_form = document._importNode($('form', xml).get(0), true);
+												var dis = new_form.id;
+												var fav = dis.replace('disfavor', 'favor');
+												$('form#'+fav).replaceWith(new_form);
+												$('form#'+dis).ajaxForm(disoptions).each(addAjaxHidden);
+											  }
+					 };
 
-             // set the focus
-             $("#status_textarea").focus();
-        }
+	var disoptions = { dataType: 'xml',
+					   success: function(xml) { var new_form = document._importNode($('form', xml).get(0), true);
+												var fav = new_form.id;
+												var dis = fav.replace('favor', 'disfavor');
+												$('form#'+dis).replaceWith(new_form);
+												$('form#'+fav).ajaxForm(favoptions).each(addAjaxHidden);
+											  }
+					 };
 
-     // XXX: refactor this code
+	function addAjaxHidden() {
+		var ajax = document.createElement('input');
+		ajax.setAttribute('type', 'hidden');
+		ajax.setAttribute('name', 'ajax');
+		ajax.setAttribute('value', 1);
+		this.appendChild(ajax);
+	}
 
-     var favoptions = {dataType: 'xml',
-               success: function(xml) {
-                    var new_form = $('form.disfavor', xml).get(0);
-                    var dis = new_form.id;
-                    var fav = dis.replace('disfavor', 'favor');
-                    if (document.importNode) {
-                         new_form = document.importNode(new_form, true);
-                    }
-                    $('form#'+fav).replaceWith(new_form);
-                    $('form#'+dis).ajaxForm(disoptions).each(addAjaxHidden);
-               }};
-
-     var disoptions = {dataType: 'xml',
-               success: function(xml) {
-                    var new_form = $('form.favor', xml).get(0);
-                    var fav = new_form.id;
-                    var dis = fav.replace('favor', 'disfavor');
-                    if (document.importNode) {
-                         new_form = document.importNode(new_form, true);
-                    }
-                    $('form#'+dis).replaceWith(new_form);
-                    $('form#'+fav).ajaxForm(favoptions).each(addAjaxHidden);                    ;
-               }};
-
-     function addAjaxHidden() {
-          var ajax = document.createElement('input');
-          ajax.setAttribute('type', 'hidden');
-          ajax.setAttribute('name', 'ajax');
-          ajax.setAttribute('value', 1);
-          this.appendChild(ajax);
-     }
-
-     $("form.favor").ajaxForm(favoptions);
-     $("form.disfavor").ajaxForm(disoptions);
-
-     $("form.favor").each(addAjaxHidden);
-     $("form.disfavor").each(addAjaxHidden);
+	$("form.favor").ajaxForm(favoptions);
+	$("form.disfavor").ajaxForm(disoptions);
+	$("form.favor").each(addAjaxHidden);
+	$("form.disfavor").each(addAjaxHidden);
 });
 
 function doreply(nick,id) {
-     rgx_username = /^[0-9a-zA-Z\-_.]*$/;
-     if (nick.match(rgx_username)) {
-          replyto = "@" + nick + " ";
-          if ($("#status_textarea").length) {
-               $("#status_textarea").val(replyto);
-               $("form#status_form input#inreplyto").val(id);
-               $("#status_textarea").focus();
-			   return false;
-		  }
-     }
-     return true;
-}
-
+	rgx_username = /^[0-9a-zA-Z\-_.]*$/;
+	if (nick.match(rgx_username)) {
+		replyto = "@" + nick + " ";
+		if ($("#status_textarea").length) {
+			$("#status_textarea").val(replyto);
+			$("form#status_form input#inreplyto").val(id);
+			$("#status_textarea").focus();
+			return false;
+		}
+	}
+	return true;
+}
\ No newline at end of file
diff --git a/js/xbImportNode.js b/js/xbImportNode.js
new file mode 100644
index 0000000000..4ba332a68f
--- /dev/null
+++ b/js/xbImportNode.js
@@ -0,0 +1,46 @@
+/* is this stuff defined? */
+if (!document.ELEMENT_NODE) {
+	document.ELEMENT_NODE = 1;
+	document.ATTRIBUTE_NODE = 2;
+	document.TEXT_NODE = 3;
+	document.CDATA_SECTION_NODE = 4;
+	document.ENTITY_REFERENCE_NODE = 5;
+	document.ENTITY_NODE = 6;
+	document.PROCESSING_INSTRUCTION_NODE = 7;
+	document.COMMENT_NODE = 8;
+	document.DOCUMENT_NODE = 9;
+	document.DOCUMENT_TYPE_NODE = 10;
+	document.DOCUMENT_FRAGMENT_NODE = 11;
+	document.NOTATION_NODE = 12;
+}
+
+document._importNode = function(node, allChildren) {
+	/* find the node type to import */
+	switch (node.nodeType) {
+		case document.ELEMENT_NODE:
+			/* create a new element */
+			var newNode = document.createElement(node.nodeName);
+			/* does the node have any attributes to add? */
+			if (node.attributes && node.attributes.length > 0)
+				/* add all of the attributes */
+				for (var i = 0, il = node.attributes.length; i < il;) {
+					if (node.attributes[i].nodeName == 'class') {
+						newNode.className = node.getAttribute(node.attributes[i++].nodeName);
+					} else {
+						newNode.setAttribute(node.attributes[i].nodeName, node.getAttribute(node.attributes[i++].nodeName));
+					}
+				}
+			/* are we going after children too, and does the node have any? */
+			if (allChildren && node.childNodes && node.childNodes.length > 0)
+				/* recursively get all of the child nodes */
+				for (var i = 0, il = node.childNodes.length; i < il;)
+					newNode.appendChild(document._importNode(node.childNodes[i++], allChildren));
+			return newNode;
+			break;
+		case document.TEXT_NODE:
+		case document.CDATA_SECTION_NODE:
+		case document.COMMENT_NODE:
+			return document.createTextNode(node.nodeValue);
+			break;
+	}
+};
\ No newline at end of file
diff --git a/lib/util.php b/lib/util.php
index cfc95cc360..e958a87bab 100644
--- a/lib/util.php
+++ b/lib/util.php
@@ -180,6 +180,9 @@ function common_show_header($pagetitle, $callable=NULL, $data=NULL, $headercall=
 	common_element('script', array('type' => 'text/javascript',
 								   'src' => common_path('js/jquery.form.js')),
 				   ' ');
+	common_element('script', array('type' => 'text/javascript',
+								   'src' => common_path('js/xbImportNode.js')),
+				   ' ');
 	common_element('script', array('type' => 'text/javascript',
 								   'src' => common_path('js/util.js?version='.LACONICA_VERSION)),
 				   ' ');
@@ -1809,13 +1812,25 @@ function common_disfavor_form($notice) {
 									   'method' => 'post',
 									   'class' => 'disfavor',
 									   'action' => common_local_url('disfavor')));
-	common_hidden('token', common_session_token());
-	common_hidden('notice', $notice->id);
+
+	common_element('input', array('type' => 'hidden',
+								  'name' => 'token-'. $notice->id,
+								  'id' => 'token-'. $notice->id,
+								  'class' => 'token',
+								  'value' => common_session_token()));
+
+	common_element('input', array('type' => 'hidden',
+								  'name' => 'notice',
+								  'id' => 'notice-n'. $notice->id,
+								  'class' => 'notice',
+								  'value' => $notice->id));
+
 	common_element('input', array('type' => 'submit',
 								  'id' => 'disfavor-submit-' . $notice->id,
 								  'name' => 'disfavor-submit-' . $notice->id,
 								  'class' => 'disfavor',
-								  'value' => '♥'));
+								  'value' => 'Disfavor favorite',
+								  'title' => 'Remove this message from favorites'));
 	common_element_end('form');
 }
 
@@ -1824,13 +1839,25 @@ function common_favor_form($notice) {
 									   'method' => 'post',
 									   'class' => 'favor',
 									   'action' => common_local_url('favor')));
-	common_hidden('token', common_session_token());
-	common_hidden('notice', $notice->id);
+
+	common_element('input', array('type' => 'hidden',
+								  'name' => 'token-'. $notice->id,
+								  'id' => 'token-'. $notice->id,
+								  'class' => 'token',
+								  'value' => common_session_token()));
+
+	common_element('input', array('type' => 'hidden',
+								  'name' => 'notice',
+								  'id' => 'notice-n'. $notice->id,
+								  'class' => 'notice',
+								  'value' => $notice->id));
+	
 	common_element('input', array('type' => 'submit',
 								  'id' => 'favor-submit-' . $notice->id,
 								  'name' => 'favor-submit-' . $notice->id,
 								  'class' => 'favor',
-								  'value' => '♡'));
+								  'value' => 'Add to favorites',
+								  'title' => 'Add this message to favorites'));
 	common_element_end('form');
 }
 
diff --git a/theme/default/display.css b/theme/default/display.css
index 8408ecd8dd..91cc057fa0 100644
--- a/theme/default/display.css
+++ b/theme/default/display.css
@@ -179,6 +179,36 @@ padding-top:2px;
 padding-left:30px;
 }
 
+
+form#disfavor, form.disfavor,
+form#favor, form.favor  {
+	float: right;
+}
+
+/*favorites*/
+input#favor, input.favor,
+input#disfavor, input.disfavor  {
+	background-color:#fcfff5;
+	background-image:url(icon_heart-01.png);
+	background-repeat:no-repeat;
+	cursor: pointer;
+	border: 0;
+	width: 16px;
+	height:16px;
+	text-indent:-9999px;
+}
+
+input#disfavor, input.disfavor {
+	background-image:url(icon_heart-02.png);
+}
+
+.notice_single:hover input.favor,
+.notice_single:hover input.disfavor {
+	background-color:#f3f8ea;
+}
+
+
+
 /* ----- Nav Footer ----- */
 #nav_sub {
 	clear: both;
@@ -686,44 +716,9 @@ input#openid_url {
 	line-height: 15px;
 }
 
-/* ----- favor/disfavor -----*/
 
-form#disfavor, form.disfavor  {
-	display: inline;
-	float: right;
-}
 
-input#disfavor, input.disfavor  {
-	display: inline;
-	color: #C15D42;
-	background-color: #FBF2D7;
-	cursor: pointer;
-	border: 0;
-	width: auto;
-	}
 
-form#favor, form.favor  {
-	display: inline;
-	float: right;
-}
-
-input#favor, input.favor  {
-	display: inline;
-	color: #C15D42;
-	background-color: #FBF2D7;
-	cursor: pointer;
-	border: 0;
-	width: auto;
-	}
-	
-input.favor:hover  {
-	background-color: #f7ebcc;
-}
-
-input.disfavor:hover  {
-	background-color: #f7ebcc;
-}
-	
 /* ----- direct message ----- */
 
 #message_form {
@@ -811,8 +806,8 @@ p.tagcloud a.smallest {
 font-size: 60%;
 }
 
-/* ----- Mailbox ----- */
 
+/* ----- Mailbox ----- */
 #messages {
 	clear: both;
 	margin: 0 auto;
@@ -844,4 +839,4 @@ font-size: 60%;
 	display: inline;
 	margin: 0;
 	padding: 0;
-	}
+	}
\ No newline at end of file
diff --git a/theme/default/icon_heart-01.png b/theme/default/icon_heart-01.png
new file mode 100644
index 0000000000..4e77720caa
Binary files /dev/null and b/theme/default/icon_heart-01.png differ
diff --git a/theme/default/icon_heart-02.png b/theme/default/icon_heart-02.png
new file mode 100644
index 0000000000..2fbdd7b6c5
Binary files /dev/null and b/theme/default/icon_heart-02.png differ
diff --git a/theme/default/ie7.css b/theme/default/ie7.css
index bbf52d5cfd..99bc4e79f1 100644
--- a/theme/default/ie7.css
+++ b/theme/default/ie7.css
@@ -1,6 +1,14 @@
 @charset "UTF-8";
 /* CSS Document */
 
+
+input.disfavor,
+input.favor {
+	text-indent:0;
+	text-align:right;
+	padding-left:25px;
+}
+
 #statistics dd {
 	clear: both;
 	}		
@@ -17,4 +25,4 @@ img.avatar.original, img.avatar.profile {
 #nav_pagination li a {
 	padding: 6px 15px;
 	line-height: 27px;
-	}
\ No newline at end of file
+	}
diff --git a/theme/identica/display.css b/theme/identica/display.css
index 9d6416fb0e..a3ef07f90b 100644
--- a/theme/identica/display.css
+++ b/theme/identica/display.css
@@ -57,6 +57,7 @@ a {
      border-top: 1px solid #D8E2D7;
      }
 
+
 .instructions p, .success, .error {
      border: 1px solid #91AA9D;
      color: #FCFFF5;
@@ -174,21 +175,6 @@ textarea:focus, input:focus {
     background-color: #F3F8EA;
     }
 
-input#disfavor, input.disfavor  {
-    background-color: white;
-    }
-
-input#favor, input.favor  {
-    background-color: white;
-    }
-
-input.favor:hover  {
-    background-color: #F3F8EA;
-    }
-		   
-input.disfavor:hover  {
-    background-color: #F3F8EA;
-    }
 
 #messages {
     border-top: 1px solid #D8E2D7;
@@ -200,21 +186,4 @@ input.disfavor:hover  {
 
 .message_single:hover {
     background-color: #F3F8EA;
-    }
-
-
-					
-		
-	  
-	     
-		
-					
-			     
-
-				  
-	
-		
-					  
-			 
-     
-				       
\ No newline at end of file
+    }
\ No newline at end of file
diff --git a/theme/identica/ie6.css b/theme/identica/ie6.css
index f7aebf1b08..a301f1dc5f 100644
--- a/theme/identica/ie6.css
+++ b/theme/identica/ie6.css
@@ -4,3 +4,11 @@
 #wrap {
 	background: url(bg-header.gif) repeat-x #FCFFF5;
 	}
+
+
+input.disfavor,
+input.favor {
+	text-indent:0px;
+	text-align:right;
+	padding-left:25px;
+}
\ No newline at end of file