diff --git a/res/css/structures/_RightPanel.scss b/res/css/structures/_RightPanel.scss
index b4dff612ed..554aabfcd1 100644
--- a/res/css/structures/_RightPanel.scss
+++ b/res/css/structures/_RightPanel.scss
@@ -55,6 +55,10 @@ limitations under the License.
     padding-bottom: 3px;
 }
 
+.mx_RightPanel_headerButton_badgeHighlight .mx_RightPanel_headerButton_badge {
+    color: $warning-color;
+}
+
 .mx_RightPanel_headerButton_highlight {
     width: 25px;
     height: 5px;
diff --git a/src/Notifier.js b/src/Notifier.js
index 80e8be1084..8550f3bf95 100644
--- a/src/Notifier.js
+++ b/src/Notifier.js
@@ -289,6 +289,11 @@ const Notifier = {
         const room = MatrixClientPeg.get().getRoom(ev.getRoomId());
         const actions = MatrixClientPeg.get().getPushActionsForEvent(ev);
         if (actions && actions.notify) {
+            dis.dispatch({
+                action: "event_notification",
+                event: ev,
+                room: room,
+            });
             if (this.isEnabled()) {
                 this._displayPopupNotification(ev, room);
             }
diff --git a/src/Tinter.js b/src/Tinter.js
index d24a4c3e74..9c2afd4fab 100644
--- a/src/Tinter.js
+++ b/src/Tinter.js
@@ -390,7 +390,7 @@ class Tinter {
     // XXX: we could just move this all into TintableSvg, but as it's so similar
     // to the CSS fixup stuff in Tinter (just that the fixups are stored in TintableSvg)
     // keeping it here for now.
-    calcSvgFixups(svgs) {
+    calcSvgFixups(svgs, forceColors) {
         // go through manually fixing up SVG colours.
         // we could do this by stylesheets, but keeping the stylesheets
         // updated would be a PITA, so just brute-force search for the
@@ -418,13 +418,21 @@ class Tinter {
                 const tag = tags[j];
                 for (let k = 0; k < this.svgAttrs.length; k++) {
                     const attr = this.svgAttrs[k];
-                    for (let l = 0; l < this.keyHex.length; l++) {
-                        if (tag.getAttribute(attr) &&
-                            tag.getAttribute(attr).toUpperCase() === this.keyHex[l]) {
+                    for (let m = 0; m < this.keyHex.length; m++) { // dev note: don't use L please.
+                        // We use a different attribute from the one we're setting
+                        // because we may also be using forceColors. If we were to
+                        // check the keyHex against a forceColors value, it may not
+                        // match and therefore not change when we need it to.
+                        const valAttrName = "mx-val-" + attr;
+                        let attribute = tag.getAttribute(valAttrName);
+                        if (!attribute) attribute = tag.getAttribute(attr); // fall back to the original
+                        if (attribute && (attribute.toUpperCase() === this.keyHex[m] || attribute.toLowerCase() === this.keyRgb[m])) {
                             fixups.push({
                                 node: tag,
                                 attr: attr,
-                                index: l,
+                                refAttr: valAttrName,
+                                index: m,
+                                forceColors: forceColors,
                             });
                         }
                     }
@@ -440,7 +448,9 @@ class Tinter {
         if (DEBUG) console.log("applySvgFixups start for " + fixups);
         for (let i = 0; i < fixups.length; i++) {
             const svgFixup = fixups[i];
-            svgFixup.node.setAttribute(svgFixup.attr, this.colors[svgFixup.index]);
+            const forcedColor = svgFixup.forceColors ? svgFixup.forceColors[svgFixup.index] : null;
+            svgFixup.node.setAttribute(svgFixup.attr, forcedColor ? forcedColor : this.colors[svgFixup.index]);
+            svgFixup.node.setAttribute(svgFixup.refAttr, this.colors[svgFixup.index]);
         }
         if (DEBUG) console.log("applySvgFixups end");
     }
diff --git a/src/components/structures/RightPanel.js b/src/components/structures/RightPanel.js
index 9017447a34..0870f085a5 100644
--- a/src/components/structures/RightPanel.js
+++ b/src/components/structures/RightPanel.js
@@ -30,6 +30,7 @@ import { showGroupInviteDialog, showGroupAddRoomDialog } from '../../GroupAddres
 import GroupStore from '../../stores/GroupStore';
 
 import { formatCount } from '../../utils/FormattingUtils';
+import MatrixClientPeg from "../../MatrixClientPeg";
 
 class HeaderButton extends React.Component {
     constructor() {
@@ -49,17 +50,26 @@ class HeaderButton extends React.Component {
         const TintableSvg = sdk.getComponent("elements.TintableSvg");
         const AccessibleButton = sdk.getComponent("elements.AccessibleButton");
 
+        // XXX: We really shouldn't be hardcoding colors here, but the way TintableSvg
+        // works kinda prevents us from using normal CSS tactics. We use $warning-color
+        // here.
+        // Note: This array gets passed along to the Tinter's forceColors eventually.
+        const tintableColors = this.props.badgeHighlight ? ["#ff0064"] : null;
+
+        const classNames = ["mx_RightPanel_headerButton"];
+        if (this.props.badgeHighlight) classNames.push("mx_RightPanel_headerButton_badgeHighlight");
+
         return <AccessibleButton
             aria-label={this.props.title}
             aria-expanded={this.props.isHighlighted}
             title={this.props.title}
-            className="mx_RightPanel_headerButton"
+            className={classNames.join(" ")}
             onClick={this.onClick} >
 
                 <div className="mx_RightPanel_headerButton_badge">
                     { this.props.badge ? this.props.badge : <span>&nbsp;</span> }
                 </div>
-                <TintableSvg src={this.props.iconSrc} width="25" height="25" />
+                <TintableSvg src={this.props.iconSrc} width="25" height="25" forceColors={tintableColors} />
                 { this.props.isHighlighted ? <div className="mx_RightPanel_headerButton_highlight" /> : <div /> }
 
             </AccessibleButton>;
@@ -76,6 +86,7 @@ HeaderButton.propTypes = {
 
     // The badge to display above the icon
     badge: PropTypes.node,
+    badgeHighlight: PropTypes.bool,
     // The parameters to track the click event
     analytics: PropTypes.arrayOf(PropTypes.string).isRequired,
 
@@ -205,7 +216,10 @@ module.exports = React.createClass({
     }, 500),
 
     onAction: function(payload) {
-        if (payload.action === "view_user") {
+        if (payload.action === "event_notification") {
+            // Try and re-caclulate any badge counts we might have
+            this.forceUpdate();
+        } else if (payload.action === "view_user") {
             dis.dispatch({
                 action: 'show_right_panel',
             });
@@ -308,6 +322,13 @@ module.exports = React.createClass({
 
         let headerButtons = [];
         if (this.props.roomId) {
+            let notifCountBadge;
+            let notifCount = 0;
+            MatrixClientPeg.get().getRooms().forEach(r => notifCount += (r.getUnreadNotificationCount('highlight') || 0));
+            if (notifCount > 0) {
+                notifCountBadge = <div title={_t("%counts Notifications")}>{ formatCount(notifCount) }</div>;
+            }
+
             headerButtons = [
                 <HeaderButton key="_membersButton" title={membersTitle} iconSrc="img/icons-people.svg"
                     isHighlighted={[this.Phase.RoomMemberList, this.Phase.RoomMemberInfo].includes(this.state.phase)}
@@ -323,6 +344,7 @@ module.exports = React.createClass({
                 <HeaderButton key="_notifsButton" title={_t('Notifications')} iconSrc="img/icons-notifications.svg"
                     isHighlighted={this.state.phase === this.Phase.NotificationPanel}
                     clickPhase={this.Phase.NotificationPanel}
+                    badge={notifCountBadge} badgeHighlight={notifCount > 0}
                     analytics={['Right Panel', 'Notification List Button', 'click']}
                 />,
             ];
diff --git a/src/components/views/elements/TintableSvg.js b/src/components/views/elements/TintableSvg.js
index e04bf87793..08628c8ca9 100644
--- a/src/components/views/elements/TintableSvg.js
+++ b/src/components/views/elements/TintableSvg.js
@@ -29,6 +29,7 @@ var TintableSvg = React.createClass({
         width: PropTypes.string.isRequired,
         height: PropTypes.string.isRequired,
         className: PropTypes.string,
+        forceColors: PropTypes.arrayOf(PropTypes.string),
     },
 
     statics: {
@@ -50,6 +51,12 @@ var TintableSvg = React.createClass({
         delete TintableSvg.mounts[this.id];
     },
 
+    componentDidUpdate: function(prevProps, prevState) {
+        if (prevProps.forceColors !== this.props.forceColors) {
+            this.calcAndApplyFixups(this.refs.svgContainer);
+        }
+    },
+
     tint: function() {
         // TODO: only bother running this if the global tint settings have changed
         // since we loaded!
@@ -57,8 +64,13 @@ var TintableSvg = React.createClass({
     },
 
     onLoad: function(event) {
-        // console.log("TintableSvg.onLoad for " + this.props.src);
-        this.fixups = Tinter.calcSvgFixups([event.target]);
+        this.calcAndApplyFixups(event.target);
+    },
+
+    calcAndApplyFixups: function(target) {
+        if (!target) return;
+        // console.log("TintableSvg.calcAndApplyFixups for " + this.props.src);
+        this.fixups = Tinter.calcSvgFixups([target], this.props.forceColors);
         Tinter.applySvgFixups(this.fixups);
     },
 
@@ -71,6 +83,7 @@ var TintableSvg = React.createClass({
                     height={this.props.height}
                     onLoad={this.onLoad}
                     tabIndex="-1"
+                    ref="svgContainer"
                 />
         );
     },