diff --git a/images/connect-art.png b/images/connect-art.png
new file mode 100644
index 0000000000..49328bdbd8
Binary files /dev/null and b/images/connect-art.png differ
diff --git a/images/connect-art@2x.png b/images/connect-art@2x.png
new file mode 100644
index 0000000000..4132e5725e
Binary files /dev/null and b/images/connect-art@2x.png differ
diff --git a/images/inspection.png b/images/inspection.png
new file mode 100644
index 0000000000..68f66aef01
Binary files /dev/null and b/images/inspection.png differ
diff --git a/images/inspection@2x.png b/images/inspection@2x.png
new file mode 100644
index 0000000000..ecebe23041
Binary files /dev/null and b/images/inspection@2x.png differ
diff --git a/images/private.png b/images/private.png
new file mode 100644
index 0000000000..639f54f60a
Binary files /dev/null and b/images/private.png differ
diff --git a/images/private@2x.png b/images/private@2x.png
new file mode 100644
index 0000000000..3009a51614
Binary files /dev/null and b/images/private@2x.png differ
diff --git a/src/actions/AccountActions.js b/src/actions/AccountActions.js
index 059f956a17..938aa52e91 100644
--- a/src/actions/AccountActions.js
+++ b/src/actions/AccountActions.js
@@ -21,6 +21,11 @@ class AccountActions {
     this.dispatch({});
     hub.prompted(true);
   }
+
+  verify () {
+    this.dispatch({});
+    hub.verify();
+  }
 }
 
 export default alt.createActions(AccountActions);
diff --git a/src/actions/AccountServerActions.js b/src/actions/AccountServerActions.js
index 758a6adaae..e88dc56a1a 100644
--- a/src/actions/AccountServerActions.js
+++ b/src/actions/AccountServerActions.js
@@ -1,13 +1,13 @@
 import alt from '../alt';
 import router from '../router';
 
-
 class AccountServerActions {
   constructor () {
     this.generateActions(
       'loggedout',
       'prompted',
-      'errors'
+      'errors',
+      'verified'
     );
   }
 
@@ -19,7 +19,9 @@ class AccountServerActions {
   }
 
   signedup ({username}) {
-    router.get().transitionTo('search');
+    if (router.get()) {
+      router.get().goBack();
+    }
     this.dispatch({username});
   }
 }
diff --git a/src/actions/ContainerActions.js b/src/actions/ContainerActions.js
index e5fd4e1dae..fbb33a966d 100644
--- a/src/actions/ContainerActions.js
+++ b/src/actions/ContainerActions.js
@@ -1,5 +1,6 @@
 import alt from '../alt';
 import dockerUtil from '../utils/DockerUtil';
+import hubUtil from '../utils/HubUtil';
 
 class ContainerActions {
   start (name) {
@@ -32,7 +33,7 @@ class ContainerActions {
   }
 
   run (name, repo, tag) {
-    dockerUtil.run(name, repo, tag);
+    dockerUtil.run(hubUtil.config(), name, repo, tag);
   }
 }
 
diff --git a/src/actions/RepositoryActions.js b/src/actions/RepositoryActions.js
index 092430ca24..a2a71f9074 100644
--- a/src/actions/RepositoryActions.js
+++ b/src/actions/RepositoryActions.js
@@ -1,8 +1,25 @@
 import alt from '../alt';
+import regHubUtil from '../utils/RegHubUtil';
+import hubUtil from '../utils/HubUtil';
 
 class RepositoryActions {
-  fetch () {
+  recommended () {
     this.dispatch({});
+    regHubUtil.recommended();
+  }
+
+  search (query) {
+    this.dispatch({});
+    regHubUtil.search(query);
+  }
+
+  repos () {
+    this.dispatch({});
+    regHubUtil.repos(hubUtil.jwt());
+  }
+
+  tags () {
+    
   }
 }
 
diff --git a/src/actions/RepositoryServerActions.js b/src/actions/RepositoryServerActions.js
index ffb2e2166c..b49e4d60d6 100644
--- a/src/actions/RepositoryServerActions.js
+++ b/src/actions/RepositoryServerActions.js
@@ -3,9 +3,10 @@ import alt from '../alt';
 class RepositoryServerActions {
   constructor () {
     this.generateActions(
-      'searched',
-      'fetched',
-      'error'
+      'reposLoading',
+      'resultsUpdated',
+      'recommendedUpdated',
+      'reposUpdated'
     );
   }
 }
diff --git a/src/actions/TagActions.js b/src/actions/TagActions.js
new file mode 100644
index 0000000000..21da864666
--- /dev/null
+++ b/src/actions/TagActions.js
@@ -0,0 +1,12 @@
+import alt from '../alt';
+import regHubUtil from '../utils/RegHubUtil';
+import hubUtil from '../utils/HubUtil';
+
+class TagActions {
+  tags (repo) {
+    this.dispatch({repo});
+    regHubUtil.tags(hubUtil.jwt(), repo);
+  }
+}
+
+export default alt.createActions(TagActions);
diff --git a/src/actions/TagServerActions.js b/src/actions/TagServerActions.js
new file mode 100644
index 0000000000..4149b81cb4
--- /dev/null
+++ b/src/actions/TagServerActions.js
@@ -0,0 +1,11 @@
+import alt from '../alt';
+
+class TagServerActions {
+  constructor () {
+    this.generateActions(
+      'tagsUpdated'
+    );
+  }
+}
+
+export default alt.createActions(TagServerActions);
diff --git a/src/app.js b/src/app.js
index 243070d656..8d3aee73b6 100644
--- a/src/app.js
+++ b/src/app.js
@@ -18,15 +18,17 @@ var hub = require('./utils/HubUtil');
 var Router = require('react-router');
 var routes = require('./routes');
 var routerContainer = require('./router');
+var repositoryActions = require('./actions/RepositoryActions');
 
+hubUtil.init();
+repositoryActions.recommended();
+repositoryActions.repos();
 
 webUtil.addWindowSizeSaving();
 webUtil.addLiveReload();
 webUtil.addBugReporting();
 webUtil.disableGlobalBackspace();
 
-hubUtil.init();
-
 Menu.setApplicationMenu(Menu.buildFromTemplate(template()));
 
 metrics.track('Started App');
diff --git a/src/browser.js b/src/browser.js
index e033f86f75..1e5a6f1367 100644
--- a/src/browser.js
+++ b/src/browser.js
@@ -18,7 +18,6 @@ try {
   settingsjson = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'settings.json'), 'utf8'));
 } catch (err) {}
 
-
 var openURL = null;
 app.on('open-url', function (event, url) {
   event.preventDefault();
@@ -27,9 +26,9 @@ app.on('open-url', function (event, url) {
 
 app.on('ready', function () {
   var mainWindow = new BrowserWindow({
-    width: size.width || 800,
+    width: size.width || 1000,
     height: size.height || 600,
-    'min-width': 800,
+    'min-width': 1000,
     'min-height': 600,
     'standard-window': false,
     resizable: true,
diff --git a/src/components/Account.react.js b/src/components/Account.react.js
index 1118d03948..ffb69fbece 100644
--- a/src/components/Account.react.js
+++ b/src/components/Account.react.js
@@ -40,13 +40,14 @@ module.exports = React.createClass({
 
   render: function () {
     let close = this.state.prompted ?
-        <a className="btn btn-action btn-close" onClick={this.handleClose}>Close</a> :
-        <a className="btn btn-action btn-skip" onClick={this.handleSkip}>Skip For Now</a>;
+        <a className="btn btn-action btn-close" disabled={this.state.loading} onClick={this.handleClose}>Close</a> :
+        <a className="btn btn-action btn-skip"  disabled={this.state.loading} onClick={this.handleSkip}>Skip For Now</a>;
 
     return (
       <div className="setup">
         <Header hideLogin={true}/>
         <div className="setup-content">
+          {close}
           <div className="form-section">
             <RetinaImage src={'connect-to-hub.png'} checkIfRetinaImgExists={false}/>
             <Router.RouteHandler errors={this.state.errors} loading={this.state.loading} {...this.props}/>
@@ -55,7 +56,6 @@ module.exports = React.createClass({
             <div className="content">
               <h1>Connect to Docker Hub</h1>
               <p>Pull and run private Docker Hub images by connecting your Docker Hub account to Kitematic.</p>
-              {close}
             </div>
           </div>
         </div>
diff --git a/src/components/ContainerListNewItem.react.js b/src/components/ContainerListNewItem.react.js
index 237e620c4a..55cebf975e 100644
--- a/src/components/ContainerListNewItem.react.js
+++ b/src/components/ContainerListNewItem.react.js
@@ -36,7 +36,7 @@ var ContainerListNewItem = React.createClass({
       );
     }
     return (
-      <Router.Link to="new">
+      <Router.Link to="search">
         <li className="new-container-item" onMouseEnter={this.handleItemMouseEnter} onMouseLeave={this.handleItemMouseLeave}>
           <div className="state state-new"></div>
           <div className="info">
diff --git a/src/components/Containers.react.js b/src/components/Containers.react.js
index 41e6ff7523..3862259c23 100644
--- a/src/components/Containers.react.js
+++ b/src/components/Containers.react.js
@@ -5,7 +5,6 @@ var Router = require('react-router');
 var containerStore = require('../stores/ContainerStore');
 var ContainerList = require('./ContainerList.react');
 var Header = require('./Header.react');
-var ipc = require('ipc');
 var metrics = require('../utils/MetricsUtil');
 var RetinaImage = require('react-retina-image');
 var shell = require('shell');
diff --git a/src/components/Header.react.js b/src/components/Header.react.js
index d6b043d88d..39b6ee4881 100644
--- a/src/components/Header.react.js
+++ b/src/components/Header.react.js
@@ -72,7 +72,12 @@ var Header = React.createClass({
   },
   handleUserClick: function (e) {
     let menu = new Menu();
-    menu.append(new MenuItem({ label: 'Sign Out', click: this.handleLogoutClick.bind(this)}));
+
+    if (!this.state.verified) {
+      menu.append(new MenuItem({ label: 'I\'ve Verified My Email Address', click: this.handleVerifyClick}));
+    }
+
+    menu.append(new MenuItem({ label: 'Sign Out', click: this.handleLogoutClick}));
     menu.popup(remote.getCurrentWindow(), e.currentTarget.offsetLeft, e.currentTarget.offsetTop + e.currentTarget.clientHeight + 10);
   },
   handleLoginClick: function () {
@@ -81,6 +86,9 @@ var Header = React.createClass({
   handleLogoutClick: function () {
     accountActions.logout();
   },
+  handleVerifyClick: function () {
+    accountActions.verify();
+  },
   render: function () {
     let updateWidget = this.state.updateAvailable ? <a className="btn btn-action small no-drag" onClick={this.handleAutoUpdateClick}>UPDATE NOW</a> : null;
     let buttons;
@@ -108,7 +116,7 @@ var Header = React.createClass({
     } else if (this.state.username) {
       username = (
         <span className="no-drag" onClick={this.handleUserClick}>
-          <RetinaImage src="user.png"/> {this.state.username} <RetinaImage src="userdropdown.png"/>
+          <RetinaImage src="user.png"/> {this.state.username} {this.state.verified ? null : '(Unverified)'} <RetinaImage src="userdropdown.png"/>
         </span>
       );
     } else {
diff --git a/src/components/ImageCard.react.js b/src/components/ImageCard.react.js
index 67a0a0a229..129b8ac1e1 100644
--- a/src/components/ImageCard.react.js
+++ b/src/components/ImageCard.react.js
@@ -1,13 +1,15 @@
 var $ = require('jquery');
 var React = require('react/addons');
 var Router = require('react-router');
+var shell = require('shell');
 var RetinaImage = require('react-retina-image');
 var metrics = require('../utils/MetricsUtil');
 var OverlayTrigger = require('react-bootstrap').OverlayTrigger;
 var Tooltip = require('react-bootstrap').Tooltip;
-var util = require('../utils/Util');
 var containerActions = require('../actions/ContainerActions');
 var containerStore = require('../stores/ContainerStore');
+var tagStore = require('../stores/TagStore');
+var tagActions = require('../actions/TagActions');
 
 var ImageCard = React.createClass({
   mixins: [Router.Navigation],
@@ -17,6 +19,23 @@ var ImageCard = React.createClass({
       chosenTag: 'latest'
     };
   },
+  componentDidMount: function () {
+    tagStore.listen(this.update);
+  },
+  componentWillUnmount: function () {
+    tagStore.unlisten(this.update);
+  },
+  update: function () {
+    let repo = this.props.image.namespace + '/' + this.props.image.name;
+    let state = tagStore.getState();
+    if (this.state.tags.length && !state.tags[repo]) {
+      $(this.getDOMNode()).find('.tag-overlay').fadeOut(300);
+    }
+    this.setState({
+      loading: tagStore.getState().loading[repo] || false,
+      tags: tagStore.getState().tags[repo] || []
+    });
+  },
   handleTagClick: function (tag) {
     this.setState({
       chosenTag: tag
@@ -33,64 +52,42 @@ var ImageCard = React.createClass({
     containerActions.run(name, repository, this.state.chosenTag);
     this.transitionTo('containerHome', {name});
   },
-  handleTagOverlayClick: function (name) {
-    var $tagOverlay = $(this.getDOMNode()).find('.tag-overlay');
+  handleTagOverlayClick: function () {
+    let $tagOverlay = $(this.getDOMNode()).find('.tag-overlay');
     $tagOverlay.fadeIn(300);
-    $.get('https://registry.hub.docker.com/v1/repositories/' + name + '/tags', result => {
-      this.setState({
-        tags: result
-      });
-    });
+    tagActions.tags(this.props.image.namespace + '/' + this.props.image.name);
   },
   handleCloseTagOverlay: function () {
     var $tagOverlay = $(this.getDOMNode()).find('.tag-overlay');
     $tagOverlay.fadeOut(300);
   },
   handleRepoClick: function () {
-    var $repoUri = 'https://registry.hub.docker.com/';
+    var repoUri = 'https://registry.hub.docker.com/';
     if (this.props.image.is_official) {
-      $repoUri = $repoUri + "_/";
+      repoUri = repoUri + '_/' + this.props.image.name;
     } else {
-      $repoUri = $repoUri + "u/";
+      repoUri = repoUri + 'u/' + this.props.image.namespace + '/' + this.props.image.name;
     }
-    util.exec(['open', $repoUri + this.props.image.name]);
-  },
-  componentDidMount: function() {
-    $.get('https://registry.hub.docker.com/v1/repositories/' + this.props.image.name + '/tags', result => {
-      this.setState({
-        tags: result,
-        chosenTag: result[0].name
-      });
-    });
+    shell.openExternal(repoUri);
   },
   render: function () {
     var self = this;
-    var name;
-    var imageNameTokens = this.props.image.name.split('/');
-    var namespace;
-    var repo;
-    if (imageNameTokens.length > 1) {
-      namespace = imageNameTokens[0];
-      repo = imageNameTokens[1];
-    } else {
-      namespace = "official";
-      repo = imageNameTokens[0];
-    }
-    if (this.props.image.is_official) {
+    let name;
+    if (this.props.image.namespace === 'library') {
       name = (
         <div>
-          <div className="namespace official">{namespace}</div>
+          <div className="namespace official">official</div>
           <OverlayTrigger placement="bottom" overlay={<Tooltip>View on Docker Hub</Tooltip>}>
-            <span className="repo" onClick={this.handleRepoClick}>{repo}</span>
+            <span className="repo" onClick={this.handleRepoClick}>{this.props.image.name}</span>
           </OverlayTrigger>
         </div>
       );
     } else {
       name = (
         <div>
-          <div className="namespace">{namespace}</div>
+          <div className="namespace">{this.props.image.namespace}</div>
           <OverlayTrigger placement="bottom" overlay={<Tooltip>View on Docker Hub</Tooltip>}>
-            <span className="repo" onClick={this.handleRepoClick}>{repo}</span>
+            <span className="repo" onClick={this.handleRepoClick}>{this.props.image.name}</span>
           </OverlayTrigger>
         </div>
       );
@@ -111,12 +108,16 @@ var ImageCard = React.createClass({
       imgsrc = 'http://kitematic.com/recommended/kitematic_html.png';
     }
     var tags;
-    if (self.state.tags.length > 0) {
+    if (self.state.loading) {
+      tags = <RetinaImage className="tags-loading" src="loading-white.png"/>;
+    } else if (self.state.tags.length === 0) {
+      tags = <span>No Tags</span>;
+    } else {
       var tagDisplay = self.state.tags.map(function (t) {
-        if (t.name === self.state.chosenTag) {
-          return <div className="tag active" key={t.name} onClick={self.handleTagClick.bind(self, t.name)}>{t.name}</div>;
+        if (t === self.state.chosenTag) {
+          return <div className="tag active" key={t} onClick={self.handleTagClick.bind(self, t)}>{t}</div>;
         } else {
-          return <div className="tag" key={t.name} onClick={self.handleTagClick.bind(self, t.name)}>{t.name}</div>;
+          return <div className="tag" key={t} onClick={self.handleTagClick.bind(self, t)}>{t}</div>;
         }
       });
       tags = (
@@ -124,13 +125,15 @@ var ImageCard = React.createClass({
           {tagDisplay}
         </div>
       );
-    } else {
-      tags = <RetinaImage className="tags-loading" src="loading-white.png"/>;
     }
-    var officialBadge;
-    if (this.props.image.is_official) {
-      officialBadge = (
-        <RetinaImage src="official.png" />
+    var badge = null;
+    if (this.props.image.namespace === 'library') {
+      badge = (
+        <RetinaImage src="official.png"/>
+      );
+    } else if (this.props.image.is_private) {
+      badge = (
+        <RetinaImage src="private.png"/>
       );
     }
     return (
@@ -143,7 +146,7 @@ var ImageCard = React.createClass({
         </div>
         <div className="card">
           <div className="badges">
-            {officialBadge}
+            {badge}
           </div>
           <div className="name">
             {name}
@@ -152,17 +155,13 @@ var ImageCard = React.createClass({
             {description}
           </div>
           <div className="actions">
-            <OverlayTrigger placement="bottom" overlay={<Tooltip>Favorites</Tooltip>}>
-              <div className="stars">
-                <span className="icon icon-star-9"></span>
-                <span className="text">{this.props.image.star_count}</span>
-              </div>
-            </OverlayTrigger>
+            <div className="stars">
+              <span className="icon icon-star-9"></span>
+              <span className="text">{this.props.image.star_count}</span>
+            </div>
             <div className="tags">
               <span className="icon icon-bookmark-2"></span>
-              <OverlayTrigger placement="bottom" overlay={<Tooltip>Change Tag</Tooltip>}>
-                <span className="text" onClick={self.handleTagOverlayClick.bind(self, this.props.image.name)} data-name={this.props.image.name}>{this.state.chosenTag}</span>
-              </OverlayTrigger>
+              <span className="text" onClick={self.handleTagOverlayClick.bind(self, this.props.image.name)} data-name={this.props.image.name}>{this.state.chosenTag}</span>
             </div>
             <div className="action">
               <a className="btn btn-action" onClick={self.handleClick.bind(self, this.props.image.name)}>Create</a>
diff --git a/src/components/NewContainerSearch.react.js b/src/components/NewContainerSearch.react.js
index ab81643b28..c44953b1cc 100644
--- a/src/components/NewContainerSearch.react.js
+++ b/src/components/NewContainerSearch.react.js
@@ -1,35 +1,57 @@
+var _ = require('underscore');
 var React = require('react/addons');
+var Router = require('react-router');
+var RetinaImage = require('react-retina-image');
 var ImageCard = require('./ImageCard.react');
 var Promise = require('bluebird');
 var metrics = require('../utils/MetricsUtil');
 var classNames = require('classnames');
+var repositoryActions = require('../actions/RepositoryActions');
+var repositoryStore = require('../stores/RepositoryStore');
+var accountStore = require('../stores/AccountStore');
+var accountActions = require('../actions/AccountActions');
 
-var _recommended = [];
 var _searchPromise = null;
 
 module.exports = React.createClass({
+  mixins: [Router.Navigation, Router.State],
   getInitialState: function () {
     return {
       query: '',
-      loading: false,
-      category: 'recommended',
-      recommendedrepos: [],
-      publicrepos: [],
-      userrepos: [],
-      results: [],
-      tab: 'all'
+      loading: repositoryStore.loading(),
+      repos: repositoryStore.all(),
+      username: accountStore.getState().username,
+      verified: accountStore.getState().verified,
+      accountLoading: accountStore.getState().loading,
+      error: repositoryStore.getState().error
     };
   },
   componentDidMount: function () {
-    // fetch recommended
-    // fetch public repos
-    // if logged in: my repos
     this.refs.searchInput.getDOMNode().focus();
+    repositoryStore.listen(this.update);
+    accountStore.listen(this.updateAccount);
+    repositoryActions.search();
   },
   componentWillUnmount: function () {
     if (_searchPromise) {
       _searchPromise.cancel();
     }
+
+    repositoryStore.unlisten(this.update);
+    accountStore.unlisten(this.updateAccount);
+  },
+  update: function () {
+    this.setState({
+      loading: repositoryStore.loading(),
+      repos: repositoryStore.all()
+    });
+  },
+  updateAccount: function () {
+    this.setState({
+      username: accountStore.getState().username,
+      verified: accountStore.getState().verified,
+      accountLoading: accountStore.getState().loading
+    });
   },
   search: function (query) {
     if (_searchPromise) {
@@ -37,15 +59,6 @@ module.exports = React.createClass({
       _searchPromise = null;
     }
 
-    if (!query.length) {
-      this.setState({
-        query: query,
-        results: _recommended,
-        loading: false
-      });
-      return;
-    }
-
     this.setState({
       query: query,
       loading: true
@@ -54,7 +67,7 @@ module.exports = React.createClass({
     _searchPromise = Promise.delay(200).cancellable().then(() => {
       metrics.track('Searched for Images');
       _searchPromise = null;
-      // TODO: call search action
+      repositoryActions.search(query);
     }).catch(Promise.CancellationError, () => {});
   },
   handleChange: function (e) {
@@ -64,38 +77,107 @@ module.exports = React.createClass({
     }
     this.search(query);
   },
+  handleFilter: function (filter) {
+
+    // If we're clicking on the filter again - refresh
+    if (filter === 'userrepos' && this.getQuery().filter === 'userrepos') {
+      repositoryActions.repos();
+    }
+
+    if (filter === 'recommended' && this.getQuery().filter === 'recommended') {
+      repositoryActions.recommended();
+    }
+
+    this.transitionTo('search', {}, {filter: filter});
+  },
+  handleCheckVerification: function () {
+    accountActions.verify();
+  },
   render: function () {
-    var data = this.state.recommendedrepos;
-    var results;
-    if (data.length) {
-      var items = data.map(function (image) {
-        return (
-          <ImageCard key={image.name} image={image} />
-        );
-      });
+    let filter = this.getQuery().filter || 'all';
+    let repos = _.values(this.state.repos)
+        .filter(repo => repo.name.indexOf(this.state.query) !== -1 || repo.namespace.indexOf(this.state.query) !== -1)
+        .filter(repo => filter === 'all' || (filter === 'recommended' && repo.is_recommended) || (filter === 'userrepos' && repo.is_user_repo));
+
+    let results;
+    if (this.state.error) {
+      results = (
+        <div className="no-results">
+          <h2>There was an error contacting Docker Hub.</h2>
+        </div>
+      );
+    } else if (filter === 'userrepos' && !accountStore.getState().username) {
+      results = (
+        <div className="no-results">
+          <h2><Router.Link to="login">Log In</Router.Link>  or  <Router.Link to="signup">Sign Up</Router.Link> to access your Docker Hub repositories.</h2>
+          <RetinaImage src="connect-art.png" checkIfRetinaImgExists={false}/>
+        </div>
+      );
+    } else if (filter === 'userrepos' && !accountStore.getState().verified) {
+      let spinner = this.state.accountLoading ? <div className="spinner la-ball-clip-rotate la-dark"><div></div></div> : null;
+      results = (
+        <div className="no-results">
+          <h2>Please verify your Docker Hub account email address</h2>
+          <div className="verify">
+            <button className="btn btn-primary btn-lg" onClick={this.handleCheckVerification}>{'I\'ve Verified my Email Address'}</button> {spinner}
+          </div>
+          <RetinaImage src="inspection.png" checkIfRetinaImgExists={false}/>
+        </div>
+      );
+    } else if (this.state.loading) {
+      results = (
+        <div className="no-results">
+          <div className="loader">
+            <h2>Loading Images</h2>
+            <div className="spinner la-ball-clip-rotate la-dark la-lg"><div></div></div>
+          </div>
+        </div>
+      );
+    } else if (repos.length) {
+      let recommendedItems = repos.filter(repo => repo.is_recommended).map(image => <ImageCard key={image.namespace + '/' + image.name} image={image} />);
+      let otherItems = repos.filter(repo => !repo.is_recommended && !repo.is_user_repo).map(image => <ImageCard key={image.namespace + '/' + image.name} image={image} />);
+
+      let recommendedResults = recommendedItems.length ? (
+        <div>
+          <h4>Recommended</h4>
+          <div className="result-grid">
+            {recommendedItems}
+          </div>
+        </div>
+      ) : null;
+
+      let userRepoItems = repos.filter(repo => repo.is_user_repo).map(image => <ImageCard key={image.namespace + '/' + image.name} image={image} />);
+      let userRepoResults = userRepoItems.length ? (
+        <div>
+          <h4>My Repositories</h4>
+          <div className="result-grid">
+            {userRepoItems}
+          </div>
+        </div>
+      ) : null;
+
+      let otherResults = otherItems.length ? (
+        <div>
+          <h4>Other Repositories</h4>
+          <div className="result-grid">
+            {otherItems}
+          </div>
+        </div>
+      ) : null;
 
       results = (
-        <div className="result-grid">
-          {items}
+        <div className="result-grids">
+          {userRepoResults}
+          {recommendedResults}
+          {otherResults}
         </div>
       );
     } else {
-      if (this.state.results.length === 0 && this.state.query === '') {
-        results = (
-          <div className="no-results">
-            <div className="loader">
-              <h2>Loading Images</h2>
-              <div className="spinner la-ball-clip-rotate la-dark la-lg"><div></div></div>
-            </div>
-          </div>
-        );
-      } else {
-        results = (
-          <div className="no-results">
-            <h1>Cannot find a matching image.</h1>
-          </div>
-        );
-      }
+      results = (
+        <div className="no-results">
+          <h2>Cannot find a matching image.</h2>
+        </div>
+      );
     }
 
     let loadingClasses = classNames({
@@ -114,16 +196,12 @@ module.exports = React.createClass({
       'search-icon': true
     });
 
-    let allTabClasses = classNames({
-      'results-filter': 
-    });
-
     return (
       <div className="details">
         <div className="new-container">
           <div className="new-container-header">
             <div className="text">
-              Select a Docker image to create a new container.
+              Select a Docker image to create a container.
             </div>
             <div className="search">
               <div className="search-bar">
@@ -136,9 +214,9 @@ module.exports = React.createClass({
           <div className="results">
             <div className="results-filters">
               <span className="results-filter results-filter-title">FILTER BY</span>
-              <span className="results-filter results-all tab">All</span>
-              <span className="results-filter results-recommended tab">Recommended</span>
-              <span className="results-filter results-userrepos tab">My Repositories</span>
+              <span className={`results-filter results-all tab ${filter === 'all' ? 'active' : ''}`} onClick={this.handleFilter.bind(this, 'all')}>All</span>
+              <span className={`results-filter results-recommended tab ${filter === 'recommended' ? 'active' : ''}`} onClick={this.handleFilter.bind(this, 'recommended')}>Recommended</span>
+              <span className={`results-filter results-userrepos tab ${filter === 'userrepos' ? 'active' : ''}`} onClick={this.handleFilter.bind(this, 'userrepos')}>My Repositories</span>
             </div>
             {results}
           </div>
diff --git a/src/routes.js b/src/routes.js
index d946cdbbda..8fcd2e3c8e 100644
--- a/src/routes.js
+++ b/src/routes.js
@@ -45,7 +45,7 @@ var routes = (
         </Route>
       </Route>
       <Route name="new" path="containers/new">
-        <DefaultRoute name="search" handler={NewContainerSearch}/>
+        <Route name="search" path="containers/new/search" handler={NewContainerSearch}></Route>
         <Route name="pull" path="containers/new/pull" handler={NewContainerPull}></Route>
       </Route>
       <Route name="preferences" path="/preferences" handler={Preferences}/>
diff --git a/src/stores/AccountStore.js b/src/stores/AccountStore.js
index fc2ce6c89d..7fd1e01044 100644
--- a/src/stores/AccountStore.js
+++ b/src/stores/AccountStore.js
@@ -44,16 +44,20 @@ class AccountStore {
     });
   }
 
-  loggedin ({username}) {
-    this.setState({username, errors: {}, loading: false});
+  loggedin ({username, verified}) {
+    this.setState({username, verified, errors: {}, loading: false});
   }
 
   signedup ({username}) {
     this.setState({username, errors: {}, loading: false});
   }
 
+  verify () {
+    this.setState({loading: true});
+  }
+
   verified ({verified}) {
-    this.setState({verified});
+    this.setState({verified, loading: false});
   }
 
   prompted ({prompted}) {
diff --git a/src/stores/RepositoryStore.js b/src/stores/RepositoryStore.js
index 4263b02671..dcaec5e1ba 100644
--- a/src/stores/RepositoryStore.js
+++ b/src/stores/RepositoryStore.js
@@ -1,30 +1,75 @@
+import _ from 'underscore';
 import alt from '../alt';
 import repositoryServerActions from '../actions/RepositoryServerActions';
+import repositoryActions from '../actions/RepositoryActions';
+import accountServerActions from '../actions/AccountServerActions';
+import accountStore from './AccountStore';
 
 class RepositoryStore {
   constructor () {
+    this.bindActions(repositoryActions);
     this.bindActions(repositoryServerActions);
-    this.repos = [];
+    this.bindActions(accountServerActions);
+    this.results = [];
     this.recommended = [];
-    this.userrepos = [];
-    this.loading = false;
+    this.repos = [];
+    this.reposLoading = false;
+    this.recommendedLoading = false;
+    this.resultsLoading = false;
     this.error = null;
   }
 
-  fetch () {
-    this.setState({
-      repos: [],
-      error: null,
-      loading: true
-    });
-  }
-
-  fetched ({repos}) {
-    this.setState({repos, loading: false});
-  }
-
   error ({error}) {
-    this.setState({error, loading: false});
+    this.setState({error: error, reposLoading: false, recommendedLoading: false, resultsLoading: false});
+  }
+
+  repos () {
+    this.setState({reposError: null, reposLoading: true});
+  }
+
+  reposLoading () {
+    this.setState({reposLoading: true});
+  }
+
+  reposUpdated ({repos}) {
+    let accountState = accountStore.getState();
+
+    if (accountState.username && accountState.verified) {
+      this.setState({repos, reposLoading: false});
+    } else {
+      this.setState({repos: [], reposLoading: false});
+    }
+  }
+
+  search () {
+    this.setState({error: null, resultsLoading: true});
+  }
+
+  resultsUpdated ({repos}) {
+    this.setState({results: repos, resultsLoading: false});
+  }
+
+  recommended () {
+    this.setState({error: null, recommendedLoading: true});
+  }
+
+  recommendedUpdated ({repos}) {
+    this.setState({recommended: repos, recommendedLoading: false});
+  }
+
+  loggedout () {
+    this.setState({repos: []});
+  }
+
+  static all () {
+    let state = this.getState();
+    let all = state.recommended.concat(state.repos).concat(state.results);
+    return _.uniq(all, false, repo => repo.namespace + '/' + repo.name);
+  }
+
+  static loading () {
+    let state = this.getState();
+    return state.recommendedLoading || state.resultsLoading || state.reposLoading;
   }
 }
 
diff --git a/src/stores/TagStore.js b/src/stores/TagStore.js
new file mode 100644
index 0000000000..9293bb16c6
--- /dev/null
+++ b/src/stores/TagStore.js
@@ -0,0 +1,43 @@
+import alt from '../alt';
+import tagActions from '../actions/TagActions';
+import tagServerActions from '../actions/TagServerActions';
+import accountServerActions from '../actions/AccountServerActions';
+
+class TagStore {
+  constructor () {
+    this.bindActions(tagActions);
+    this.bindActions(tagServerActions);
+    this.bindActions(accountServerActions);
+
+    // maps 'namespace/name' => [list of tags]
+    this.tags = {};
+
+    // maps 'namespace/name' => true / false
+    this.loading = {};
+  }
+
+  tags ({repo}) {
+    this.loading[repo] = true;
+    this.emitChange();
+  }
+
+  tagsUpdated ({repo, tags}) {
+    this.tags[repo] = tags;
+    this.loading[repo] = false;
+    this.emitChange();
+  }
+
+  remove ({repo}) {
+    delete this.tags[repo];
+    delete this.loading[repo];
+    this.emitChange();
+  }
+
+  loggedout () {
+    this.loading = {};
+    this.tags = {};
+    this.emitChange();
+  }
+}
+
+export default alt.createStore(TagStore);
diff --git a/src/utils/DockerUtil.js b/src/utils/DockerUtil.js
index ccc6cb8644..66a1499471 100644
--- a/src/utils/DockerUtil.js
+++ b/src/utils/DockerUtil.js
@@ -4,7 +4,6 @@ import path from 'path';
 import dockerode from 'dockerode';
 import _ from 'underscore';
 import util from './Util';
-import registry from '../utils/RegistryUtil';
 import metrics from '../utils/MetricsUtil';
 import containerServerActions from '../actions/ContainerServerActions';
 import Promise from 'bluebird';
@@ -145,7 +144,7 @@ export default {
     });
   },
 
-  run (name, repository, tag) {
+  run (auth, name, repository, tag) {
     tag = tag || 'latest';
     let imageName = repository + ':' + tag;
 
@@ -165,7 +164,7 @@ export default {
     this.placeholders[name] = placeholderData;
     localStorage.setItem('placeholders', JSON.stringify(this.placeholders));
 
-    this.pullImage(repository, tag, error => {
+    this.pullImage(auth, repository, tag, error => {
       if (error) {
         containerServerActions.error({name, error});
         return;
@@ -327,81 +326,66 @@ export default {
     });
   },
 
-  pullImage (repository, tag, callback, progressCallback, blockedCallback) {
-    registry.layers(repository, tag, (err, layerSizes) => {
+  pullImage (auth, repository, tag, callback, progressCallback, blockedCallback) {
+    // TODO: Support v2 registry API
+    // TODO: clean this up- It's messy to work with pulls from both the v1 and v2 registry APIs
+    // Use the per-layer pull progress % to update the total progress.
+    this.client.listImages({all: 1}, (err, images) => {
+      images = images || [];
 
-      // TODO: Support v2 registry API
-      // TODO: clean this up- It's messy to work with pulls from both the v1 and v2 registry APIs
-      // Use the per-layer pull progress % to update the total progress.
-      this.client.listImages({all: 1}, (err, images) => {
-        images = images || [];
+      this.client.pull(repository + ':' + tag, {authconfig: {key: auth}}, (err, stream) => {
+        if (err) {
+          callback(err);
+          return;
+        }
+        stream.setEncoding('utf8');
 
-        let existingIds = new Set(images.map(function (image) {
-          return image.Id.slice(0, 12);
-        }));
+        let timeout = null;
+        let layerProgress = {};
+        stream.on('data', str => {
+          var data = JSON.parse(str);
 
-        let layersToDownload = layerSizes.filter(function (layerSize) {
-          return !existingIds.has(layerSize.Id);
-        });
-
-        this.client.pull(repository + ':' + tag, (err, stream) => {
-          if (err) {
-            callback(err);
+          if (data.error) {
             return;
           }
-          stream.setEncoding('utf8');
 
-          let layerProgress = layersToDownload.reduce(function (r, layer) {
-            if (_.findWhere(images, {Id: layer.Id})) {
-              r[layer.Id] = 1;
+          if (data.status && (data.status === 'Pulling dependent layers' || data.status.indexOf('already being pulled by another client') !== -1)) {
+            blockedCallback();
+            return;
+          }
+
+          if (!layerProgress[data.id]) {
+            layerProgress[data.id] = 0;
+          }
+
+          if (data.status === 'Already exists') {
+            layerProgress[data.id] = 1;
+          } else if (data.status === 'Downloading') {
+            let current = data.progressDetail.current;
+            let total = data.progressDetail.total;
+
+            if (total <= 0) {
+              progressCallback(0);
+              return;
             } else {
-              r[layer.Id] = 0;
-            }
-            return r;
-          }, {});
-
-          let timeout = null;
-          stream.on('data', str => {
-            var data = JSON.parse(str);
-
-            if (data.error) {
-              return;
+              layerProgress[data.id] = current / total;
             }
 
-            if (data.status && (data.status === 'Pulling dependent layers' || data.status.indexOf('already being pulled by another client') !== -1)) {
-              blockedCallback();
-              return;
+            let sum = _.values(layerProgress).reduce((pv, sv) => pv + sv, 0);
+            let numlayers = _.keys(layerProgress).length;
+
+            var totalProgress = sum / numlayers * 100;
+
+            if (!timeout) {
+              progressCallback(totalProgress);
+              timeout = setTimeout(() => {
+                timeout = null;
+              }, 100);
             }
-
-            if (data.status === 'Already exists') {
-              layerProgress[data.id] = 1;
-            } else if (data.status === 'Downloading') {
-              let current = data.progressDetail.current;
-              let total = data.progressDetail.total;
-
-              if (total <= 0) {
-                progressCallback(0);
-                return;
-              } else {
-                layerProgress[data.id] = current / total;
-              }
-
-              let sum = _.values(layerProgress).reduce((pv, sv) => pv + sv, 0);
-              let numlayers = _.keys(layerProgress).length;
-
-              var totalProgress = sum / numlayers * 100;
-
-              if (!timeout) {
-                progressCallback(totalProgress);
-                timeout = setTimeout(() => {
-                  timeout = null;
-                }, 100);
-              }
-            }
-          });
-          stream.on('end', function () {
-            callback();
-          });
+          }
+        });
+        stream.on('end', function () {
+          callback();
         });
       });
     });
diff --git a/src/utils/HubUtil.js b/src/utils/HubUtil.js
index 99092da4f9..b803a7cccf 100644
--- a/src/utils/HubUtil.js
+++ b/src/utils/HubUtil.js
@@ -1,13 +1,13 @@
 var request = require('request');
 var accountServerActions = require('../actions/AccountServerActions');
+var regHubUtil = require('./RegHubUtil');
 
 module.exports = {
-
   init: function () {
     accountServerActions.prompted({prompted: localStorage.getItem('auth.prompted')});
-    if (this.jwt()) { // TODO: check for config too
-      let username = localStorage.getItem('auth.username');
-      let verified = localStorage.getItem('auth.verified');
+    let username = localStorage.getItem('auth.username');
+    let verified = localStorage.getItem('auth.verified') === 'true';
+    if (username) { // TODO: check for config too
       accountServerActions.loggedin({username, verified});
     }
   },
@@ -36,19 +36,23 @@ module.exports = {
   },
 
   refresh: function () {
-    // TODO: implement me
+    // TODO: implement me and wrap all jwt calls
+  },
+
+  loggedin: function () {
+    return this.jwt() && this.config();
   },
 
   logout: function () {
+    accountServerActions.loggedout();
     localStorage.removeItem('auth.jwt');
     localStorage.removeItem('auth.username');
     localStorage.removeItem('auth.verified');
     localStorage.removeItem('auth.config');
-    accountServerActions.loggedout();
   },
 
   // Places a token under ~/.dockercfg and saves a jwt to localstore
-  login: function (username, password) {
+  login: function (username, password, verifying) {
     request.post('https://hub.docker.com/v2/users/login/', {form: {username, password}}, (err, response, body) => {
       let data = JSON.parse(body);
       if (response.statusCode === 200) {
@@ -57,8 +61,15 @@ module.exports = {
         if (data.token) {
           localStorage.setItem('auth.jwt', data.token);
           localStorage.setItem('auth.username', username);
+          localStorage.setItem('auth.verified', true);
+          localStorage.setItem('auth.config', new Buffer(username + ':' + password).toString('base64'));
         }
-        accountServerActions.loggedin({username, verified: true});
+        if (verifying) {
+          accountServerActions.verified({username});
+        } else {
+          accountServerActions.loggedin({username, verified: true});
+        }
+        regHubUtil.repos(data.token);
       } else if (response.statusCode === 401) {
         if (data && data.detail && data.detail.indexOf('Account not active yet') !== -1) {
           accountServerActions.loggedin({username, verified: false});
@@ -69,6 +80,17 @@ module.exports = {
     });
   },
 
+  verify: function () {
+    let config = this.config();
+    if (!config) {
+      this.logout();
+      return;
+    }
+
+    let [username, password] = new Buffer(config, 'base64').toString().split(/:(.+)?/).slice(0, 2);
+    this.login(username, password, true);
+  },
+
   // Signs up and places a token under ~/.dockercfg and saves a jwt to localstore
   signup: function (username, password, email, subscribe) {
     request.post('https://hub.docker.com/v2/users/signup/', {
@@ -82,6 +104,9 @@ module.exports = {
       // TODO: save username to localstorage
       if (response.statusCode === 204) {
         accountServerActions.signedup({username, verified: false});
+        localStorage.setItem('auth.username', username);
+        localStorage.setItem('auth.verified', false);
+        localStorage.setItem('auth.config', new Buffer(username + ':' + password).toString('base64'));
       } else {
         let data = JSON.parse(body);
         let errors = {};
diff --git a/src/utils/RegHubUtil.js b/src/utils/RegHubUtil.js
index 72aacf99dc..662f090fd2 100644
--- a/src/utils/RegHubUtil.js
+++ b/src/utils/RegHubUtil.js
@@ -1,24 +1,44 @@
+var _ = require('underscore');
 var request = require('request');
 var async = require('async');
+var util = require('../utils/Util');
 var repositoryServerActions = require('../actions/RepositoryServerActions');
+var tagServerActions = require('../actions/TagServerActions');
 
 module.exports = {
-  search: function (query) {
+  // Normalizes results from search to v2 repository results
+  normalize: function (repo) {
+    let obj = _.clone(repo);
+    if (obj.is_official) {
+      obj.namespace = 'library';
+    } else {
+      let [namespace, name] = repo.name.split('/');
+      obj.namespace = namespace;
+      obj.name = name;
+    }
+
+    return obj;
+  },
+
+  search: function (query, page) {
     if (!query) {
-      return;
+      repositoryServerActions.resultsUpdated({repos: []});
     }
 
     request.get({
       url: 'https://registry.hub.docker.com/v1/search?',
-      qs: {q: query}
+      qs: {q: query, page}
     }, (error, response, body) => {
       if (error) {
-        // TODO: report search error
+        repositoryServerActions.searchError({error});
       }
 
       let data = JSON.parse(body);
+      let repos = _.map(data.results, result => {
+        return this.normalize(result);
+      });
       if (response.statusCode === 200) {
-        repositoryServerActions.searched({});
+        repositoryServerActions.resultsUpdated({repos});
       }
     });
   },
@@ -26,19 +46,63 @@ module.exports = {
   recommended: function () {
     request.get('https://kitematic.com/recommended.json', (error, response, body) => {
       if (error) {
-        // TODO: report search error
+        repositoryServerActions.recommendedError({error});
       }
 
       let data = JSON.parse(body);
-      console.log(data);
+      let repos = data.repos;
+      async.map(repos, (repo, cb) => {
+        let name = repo.repo;
+        if (util.isOfficialRepo(name)) {
+          name = 'library/' + name;
+        }
+        request.get({
+          url: `https://registry.hub.docker.com/v2/repositories/${name}`,
+        }, (error, response, body) => {
+          if (error) {
+            repositoryServerActions.error({error});
+            return;
+          }
+
+          if (response.statusCode === 200) {
+            let data = JSON.parse(body);
+            data.is_recommended = true;
+            _.extend(data, repo);
+            cb(null, data);
+          }
+        });
+      }, (error, repos) => {
+        repositoryServerActions.recommendedUpdated({repos});
+      });
+    });
+  },
+
+  tags: function (jwt, repo) {
+    let headers = jwt ? {
+      Authorization: `JWT ${jwt}`
+    } : null;
+
+    request.get({
+      url: `https://registry.hub.docker.com/v2/repositories/${repo}/tags`,
+      headers
+    }, (error, response, body) => {
       if (response.statusCode === 200) {
-        repositoryServerActions.recommended({});
+        let data = JSON.parse(body);
+        tagServerActions.tagsUpdated({repo, tags: data.tags});
+      } else if (response.statusCude === 401) {
+        return;
       }
     });
   },
 
   // Returns the base64 encoded index token or null if no token exists
   repos: function (jwt) {
+    if (!jwt) {
+      repositoryServerActions.reposUpdated({repos: []});
+      return;
+    }
+
+    repositoryServerActions.reposLoading({repos: []});
 
     // TODO: provide jwt
     request.get({
@@ -48,7 +112,8 @@ module.exports = {
       }
     }, (error, response, body) => {
       if (error) {
-        repositoryServerActions.error({error});
+        repositoryServerActions.reposError({error});
+        return;
       }
 
       let data = JSON.parse(body);
@@ -61,7 +126,7 @@ module.exports = {
           }
         }, (error, response, body) => {
             if (error) {
-              repositoryServerActions.error({error});
+              repositoryServerActions.reposError({error});
               return;
             }
 
@@ -73,7 +138,12 @@ module.exports = {
           for (let list of lists) {
             repos = repos.concat(list);
           }
-          repositoryServerActions.fetched({repos});
+
+          _.each(repos, repo => {
+            repo.is_user_repo = true;
+          });
+
+          repositoryServerActions.reposUpdated({repos});
       });
     });
   }
diff --git a/src/utils/RegistryUtil.js b/src/utils/RegistryUtil.js
deleted file mode 100644
index 8b4352d9f5..0000000000
--- a/src/utils/RegistryUtil.js
+++ /dev/null
@@ -1,84 +0,0 @@
-var async = require('async');
-var $ = require('jquery');
-
-var Registry = {
-  token: function(repository, callback) {
-    $.ajax({
-      url: 'https://registry.hub.docker.com/v1/repositories/' + repository + '/images',
-      headers: {
-        'X-Docker-Token': true,
-      },
-      success: function (res, status, xhr) {
-        callback(null, xhr.getResponseHeader('X-Docker-Token'));
-      },
-      error: function (err) {
-        callback(err);
-      }
-    });
-  },
-  ancestry: function (imageId, token, callback) {
-    $.ajax({
-      url: 'https://registry-1.docker.io/v1/images/' + imageId + '/ancestry',
-      headers: {
-        Authorization: 'Token ' + token
-      },
-      success: function (layers) {
-        callback(null, layers);
-      },
-      error: function (err) {
-        callback(err);
-      }
-    });
-  },
-  imageId: function (repository, tag, token, callback) {
-    $.ajax({
-      url: 'https://registry-1.docker.io/v1/repositories/' + repository + '/tags/' + tag,
-      headers: {
-        Authorization: 'Token ' + token
-      },
-      success: function (res) {
-        callback(null, res);
-      },
-      error: function (err) {
-        callback(err);
-      }
-    });
-  },
-
-  // Returns an array [{Id: <12 character image ID, size: size of layer in bytes}]
-  layers: function (repository, tag, callback) {
-    var self = this;
-    this.token(repository, function (err, token) {
-      self.imageId(repository, tag, token, function (err, imageId) {
-        self.ancestry(imageId, token, function (err, layers) {
-          async.map(layers, function (layer, callback) {
-            $.ajax({
-              url: 'https://registry-1.docker.io/v1/images/' + layer + '/json',
-              headers: {
-                Authorization: 'Token ' + token
-              },
-              success: function (res, status, xhr) {
-                var size = xhr.getResponseHeader('X-Docker-Size');
-                callback(null, {
-                  Id: layer.slice(0, 12),
-                  size: parseInt(size, 10)
-                });
-              },
-              error: function (err) {
-                callback(err);
-              }
-            });
-          }, function (err, results) {
-            if (err) {
-              callback('Could not sum' + err);
-              return;
-            }
-            callback(null, results);
-          });
-        });
-      });
-    });
-  }
-};
-
-module.exports = Registry;
diff --git a/styles/new-container.less b/styles/new-container.less
index e9f7407858..eac8d36df1 100644
--- a/styles/new-container.less
+++ b/styles/new-container.less
@@ -32,6 +32,11 @@
   flex: 1 auto;
   flex-direction: column;
   padding: 25px 20px 0 25px;
+
+  .spinner {
+    display: inline-block;
+  }
+
   .results {
     display: flex;
     flex-direction: column;
@@ -39,10 +44,13 @@
     color: @gray-normal;
 
     .results-filters {
+      flex: 0 auto;
+      flex-shrink: 0;
       display: flex;
       flex-direction: row;
       justify-content: flex-end;
       font-size: 13px;
+      margin-bottom: 10px;
 
       .results-filter {
         text-align: center;
@@ -60,27 +68,38 @@
     .no-results {
       flex: 1 auto;
       display: flex;
+      flex-direction: column;
       align-items: center;
+      justify-content: center;
+      flex-shrink: 0;
+
+      .verify {
+        margin: 15px 0;
+        position: relative;
+
+        .spinner {
+          position: absolute;
+          top: 0;
+          right: -50px;
+        }
+      }
+
       .loader {
-        flex: 1 auto;
         display: flex;
         flex-direction: column;
         align-items: center;
-
-        margin: 0 auto;
-        margin-top: -20%;
         text-align: center;
         width: 300px;
+        margin-top: -10%;
         h2 {
           color: @gray-normal;
           margin-bottom: 20px;
         }
       }
       h1 {
-        color: @gray-lightest;
+        color: @gray-lighter;
         font-size: 24px;
         margin: 0 auto;
-        margin-top: -20%;
       }
     }
   }
@@ -88,6 +107,7 @@
     margin-bottom: 8px;
     display: flex;
     flex: 0 auto;
+    flex-shrink: 0;
     .text {
       flex: 1 auto;
       width: 50%;
@@ -134,183 +154,186 @@
   }
 }
 
-.result-grid {
-  display: flex;
-  flex-flow: row wrap;
-  justify-content: flex-start;
-  margin-top: 10px;
+.result-grids {
+
   overflow: auto;
-  .image-item {
+  .result-grid {
     display: flex;
-    position: relative;
-    width: 320px;
-    height: 166px;
-    border-radius: 4px;
-    background-color: white;
-    margin-right: 20px;
-    margin-bottom: 20px;
-    .tag-overlay {
-      z-index: 999;
-      background-color: rgba(0,0,0,0.8);
-      border-radius: 4px;
+    flex-flow: row wrap;
+    justify-content: flex-start;
+    margin-top: 10px;
+    .image-item {
+      display: flex;
+      position: relative;
       width: 320px;
       height: 166px;
-      position: absolute;
-      color: white;
-      font-size: 13px;
-      display: none;
-      padding: 10px;
-      .tag-list {
-        display: flex;
-        flex-direction: row;
-        align-items: flex-start;
-        align-content: flex-start;
-        flex-flow: row wrap;
-        height: 140px;
-        overflow: auto;
-        .tag {
-          display: inline-block;
-          flex: 0 auto;
-          margin-right: 2px;
-          padding: 3px 5px;
-          &.active {
-            background-color: rgba(255,255,255,0.2);
-            border-radius: 20px;
-          }
-          &:hover {
-            background-color: rgba(255,255,255,0.2);
-            border-radius: 20px;
-          }
-        }
-      }
-      .tags-loading {
-        position: relative;
-        left: 42%;
-        top: 20%;
-        text-align: center;
-        margin: 14px auto;
-        -webkit-animation-name: spin;
-        -webkit-animation-duration: 1.8s;
-        -webkit-animation-iteration-count: infinite;
-        -webkit-animation-timing-function: linear;
-      }
-    }
-    .logo {
-      flex: 1 auto;
-      min-width: 90px;
-      background-color: @brand-action;
-      border-top-left-radius: 4px;
-      border-bottom-left-radius: 4px;
-      justify-content: center;
-      text-align: center;
-      box-shadow: inset 0px 0px 0px 1px rgba(0,0,0,0.2);
-      img {
-        margin-top: 15px;
-      }
-    }
-    .card {
-      padding: 10px 20px 10px 20px;
-      position: relative;
-      border: 1px solid @gray-lighter;
-      border-left: 0;
-      border-top-right-radius: 4px;
-      border-bottom-right-radius: 4px;
-      .badges {
+      border-radius: 4px;
+      background-color: white;
+      margin-right: 20px;
+      margin-bottom: 20px;
+      .tag-overlay {
+        z-index: 999;
+        background-color: rgba(0,0,0,0.8);
+        border-radius: 4px;
+        width: 320px;
+        height: 166px;
         position: absolute;
-        right: 15px;
-        top: 8px;
-      }
-      .name {
-        font-size: 18px;
-        color: @gray-darkest;
-        margin-bottom: 0px;
-        position: relative;
-        width: 190px;
-        .namespace {
-          font-size: 11px;
-          color: @gray-lighter;
-          margin-bottom: -3px;
-          &.official {
-            color: @brand-action;
-          }
-        }
-        .repo {
-          display: inline-block;
-          max-width: 190px;
-          overflow: hidden;
-          text-overflow: ellipsis;
-          white-space: nowrap;
-        }
-      }
-      .description {
-        font-size: 12px;
-        color: @gray-normal;
-        height: 50px;
-        width: 190px;
-        text-overflow: ellipsis;
-        overflow: hidden;
-        -webkit-box-orient: vertical;
-        -webkit-line-clamp: 3;
-        display: -webkit-box;
-        word-wrap: break-word;
-      }
-      .actions {
-        width: 190px;
-        position: absolute;
-        bottom: 8px;
-        .stars {
-          height: 15px;
-          font-size: 10px;
-          color: @gray-darker;
-          border-right: 1px solid @gray-lightest;
-          padding-right: 10px;
-          .icon {
-            position: relative;
-            font-size: 16px;
-            margin-right: 3px;
-            top: -1px;
-            color: @gray-darkest;
-          }
-          .text {
-            position: relative;
-            top: -6px;
-          }
-        }
-        .tags {
-          height: 15px;
-          font-size: 10px;
-          color: @gray-darker;
-          padding-left: 10px;
-          .icon {
-            position: relative;
-            font-size: 12px;
+        color: white;
+        font-size: 13px;
+        display: none;
+        padding: 10px;
+        .tag-list {
+          display: flex;
+          flex-direction: row;
+          align-items: flex-start;
+          align-content: flex-start;
+          flex-flow: row wrap;
+          height: 140px;
+          overflow: auto;
+          .tag {
+            display: inline-block;
+            flex: 0 auto;
             margin-right: 2px;
-            top: 2px;
-            color: @gray-darkest;
-          }
-          .text {
-            position: relative;
-            top: -2px;
             padding: 3px 5px;
-            text-decoration: underline;
+            &.active {
+              background-color: rgba(255,255,255,0.2);
+              border-radius: 20px;
+            }
             &:hover {
-              background-color: @brand-action;
-              color: white;
+              background-color: rgba(255,255,255,0.2);
               border-radius: 20px;
             }
           }
         }
-        .action {
-          flex: 1 auto;
-          .btn {
-            text-align: right;
-            position: relative;
-            float: right;
-            top: -7px;
+        .tags-loading {
+          position: relative;
+          left: 42%;
+          top: 20%;
+          text-align: center;
+          margin: 14px auto;
+          -webkit-animation-name: spin;
+          -webkit-animation-duration: 1.8s;
+          -webkit-animation-iteration-count: infinite;
+          -webkit-animation-timing-function: linear;
+        }
+      }
+      .logo {
+        flex: 1 auto;
+        min-width: 90px;
+        background-color: @brand-action;
+        border-top-left-radius: 4px;
+        border-bottom-left-radius: 4px;
+        justify-content: center;
+        text-align: center;
+        box-shadow: inset 0px 0px 0px 1px rgba(0,0,0,0.2);
+        img {
+          margin-top: 15px;
+        }
+      }
+      .card {
+        padding: 10px 20px 10px 20px;
+        position: relative;
+        border: 1px solid @gray-lighter;
+        border-left: 0;
+        border-top-right-radius: 4px;
+        border-bottom-right-radius: 4px;
+        .badges {
+          position: absolute;
+          right: 15px;
+          top: 8px;
+        }
+        .name {
+          font-size: 18px;
+          color: @gray-darkest;
+          margin-bottom: 0px;
+          position: relative;
+          width: 190px;
+          .namespace {
+            font-size: 11px;
+            color: @gray-lighter;
+            margin-bottom: -3px;
+            &.official {
+              color: @brand-action;
+            }
+          }
+          .repo {
+            display: inline-block;
+            max-width: 190px;
+            overflow: hidden;
+            text-overflow: ellipsis;
+            white-space: nowrap;
           }
         }
-        display: flex;
-        flex-direaction: row;
+        .description {
+          font-size: 12px;
+          color: @gray-normal;
+          height: 50px;
+          width: 190px;
+          text-overflow: ellipsis;
+          overflow: hidden;
+          -webkit-box-orient: vertical;
+          -webkit-line-clamp: 3;
+          display: -webkit-box;
+          word-wrap: break-word;
+        }
+        .actions {
+          width: 190px;
+          position: absolute;
+          bottom: 8px;
+          .stars {
+            height: 15px;
+            font-size: 10px;
+            color: @gray-darker;
+            border-right: 1px solid @gray-lightest;
+            padding-right: 10px;
+            .icon {
+              position: relative;
+              font-size: 16px;
+              margin-right: 3px;
+              top: -1px;
+              color: @gray-darkest;
+            }
+            .text {
+              position: relative;
+              top: -6px;
+            }
+          }
+          .tags {
+            height: 15px;
+            font-size: 10px;
+            color: @gray-darker;
+            padding-left: 10px;
+            .icon {
+              position: relative;
+              font-size: 12px;
+              margin-right: 2px;
+              top: 2px;
+              color: @gray-darkest;
+            }
+            .text {
+              position: relative;
+              top: -2px;
+              padding: 3px 5px;
+              text-decoration: underline;
+              &:hover {
+                background-color: @brand-action;
+                color: white;
+                border-radius: 20px;
+              }
+            }
+          }
+          .action {
+            flex: 1 auto;
+            .btn {
+              text-align: right;
+              position: relative;
+              float: right;
+              top: -7px;
+            }
+          }
+          display: flex;
+          flex-direaction: row;
+        }
       }
     }
   }