Merge "[CSS] Overhaul of CSS and UX clean up."
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/HostIndexServlet.java b/gitiles-servlet/src/main/java/com/google/gitiles/HostIndexServlet.java
index aa2208a..d8aec26 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/HostIndexServlet.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/HostIndexServlet.java
@@ -126,7 +126,6 @@
     renderHtml(req, res, "gitiles.hostIndex", ImmutableMap.of(
         "hostName", hostName,
         "breadcrumbs", SoyData.createFromExistingData(breadcrumbs),
-        "baseUrl", urls.getBaseGitUrl(req),
         "prefix", prefix != null ? prefix + '/' : "",
         "repositories", repos));
   }
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/HtmlDiffFormatter.java b/gitiles-servlet/src/main/java/com/google/gitiles/HtmlDiffFormatter.java
index 84f6abf..efccc4a 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/HtmlDiffFormatter.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/HtmlDiffFormatter.java
@@ -37,15 +37,15 @@
 
 /** Formats a unified format patch as UTF-8 encoded HTML. */
 final class HtmlDiffFormatter extends DiffFormatter {
-  private static final byte[] DIFF_BEGIN = "<pre class=\"diff-unified\">".getBytes(UTF_8);
+  private static final byte[] DIFF_BEGIN = "<pre class=\"u-pre Diff-unified\">".getBytes(UTF_8);
   private static final byte[] DIFF_END = "</pre>".getBytes(UTF_8);
 
-  private static final byte[] HUNK_BEGIN = "<span class=\"h\">".getBytes(UTF_8);
+  private static final byte[] HUNK_BEGIN = "<span class=\"Diff-hunk\">".getBytes(UTF_8);
   private static final byte[] HUNK_END = "</span>".getBytes(UTF_8);
 
-  private static final byte[] LINE_INSERT_BEGIN = "<span class=\"i\">".getBytes(UTF_8);
-  private static final byte[] LINE_DELETE_BEGIN = "<span class=\"d\">".getBytes(UTF_8);
-  private static final byte[] LINE_CHANGE_BEGIN = "<span class=\"c\">".getBytes(UTF_8);
+  private static final byte[] LINE_INSERT_BEGIN = "<span class=\"Diff-insert\">".getBytes(UTF_8);
+  private static final byte[] LINE_DELETE_BEGIN = "<span class=\"Diff-delete\">".getBytes(UTF_8);
+  private static final byte[] LINE_CHANGE_BEGIN = "<span class=\"Diff-change\">".getBytes(UTF_8);
   private static final byte[] LINE_END = "</span>\n".getBytes(UTF_8);
 
   private final Renderer renderer;
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/LogSoyData.java b/gitiles-servlet/src/main/java/com/google/gitiles/LogSoyData.java
index 0508561..8a46db1 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/LogSoyData.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/LogSoyData.java
@@ -67,13 +67,13 @@
     out.flush();
 
     SoyTofu.Renderer entryRenderer = renderer.newRenderer("gitiles.logEntryWrapper");
-    boolean first = true;
+    boolean renderedEntries = false;
     for (RevCommit c : paginator) {
-      entryRenderer.setData(toEntrySoyData(paginator, c, df, first)).render(out);
+      entryRenderer.setData(toEntrySoyData(paginator, c, df)).render(out);
       out.flush();
-      first = false;
+      renderedEntries = true;
     }
-    if (first) {
+    if (!renderedEntries) {
       renderer.newRenderer("gitiles.emptyLog").render(out);
     }
 
@@ -83,8 +83,7 @@
   }
 
   private Map<String, Object> toHeaderSoyData(Paginator paginator, @Nullable String revision) {
-    Map<String, Object> data = Maps.newHashMapWithExpectedSize(5);
-    data.put("logEntryPretty", pretty);
+    Map<String, Object> data = Maps.newHashMapWithExpectedSize(1);
     ObjectId prev = paginator.getPreviousStart();
     if (prev != null) {
       GitilesView.Builder prevView = copyAndCanonicalizeView(revision);
@@ -96,16 +95,14 @@
     return data;
   }
 
-  private Map<String, Object> toEntrySoyData(Paginator paginator, RevCommit c, DateFormatter df,
-      boolean first) throws IOException {
+  private Map<String, Object> toEntrySoyData(Paginator paginator, RevCommit c, DateFormatter df)
+      throws IOException {
     if (csd == null) {
       csd = new CommitSoyData();
     }
 
-    Map<String, Object> entry = csd.setRevWalk(paginator.getWalk())
-        .toSoyData(req, c, fields, df);
+    Map<String, Object> entry = csd.setRevWalk(paginator.getWalk()).toSoyData(req, c, fields, df);
     return ImmutableMap.of(
-        "firstWithPrevious", first && paginator.getPreviousStart() != null,
         "variant", variant,
         "entry", entry);
   }
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/Renderer.java b/gitiles-servlet/src/main/java/com/google/gitiles/Renderer.java
index 7aec30f..9defb71 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/Renderer.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/Renderer.java
@@ -69,7 +69,7 @@
       "RepositoryIndex.soy");
 
   public static final Map<String, String> STATIC_URL_GLOBALS = ImmutableMap.of(
-      "gitiles.CSS_URL", "gitiles.css",
+      "gitiles.BASE_CSS_URL", "base.css",
       "gitiles.DOC_CSS_URL", "doc.css",
       "gitiles.PRETTIFY_CSS_URL", "prettify/prettify.css");
 
diff --git a/gitiles-servlet/src/main/java/com/google/gitiles/blame/BlameServlet.java b/gitiles-servlet/src/main/java/com/google/gitiles/blame/BlameServlet.java
index c8ba7be..7f18de2 100644
--- a/gitiles-servlet/src/main/java/com/google/gitiles/blame/BlameServlet.java
+++ b/gitiles-servlet/src/main/java/com/google/gitiles/blame/BlameServlet.java
@@ -188,7 +188,8 @@
     }
   }
 
-  private static final ImmutableList<String> CLASSES = ImmutableList.of("bg1", "bg2");
+  private static final ImmutableList<String> CLASSES =
+      ImmutableList.of("Blame-region--bg1", "Blame-region--bg2");
   private static final ImmutableList<SoyMapData> NULLS;
   static {
     ImmutableList.Builder<SoyMapData> nulls = ImmutableList.builder();
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/static/base.css b/gitiles-servlet/src/main/resources/com/google/gitiles/static/base.css
new file mode 100644
index 0000000..3d21c70
--- /dev/null
+++ b/gitiles-servlet/src/main/resources/com/google/gitiles/static/base.css
@@ -0,0 +1,466 @@
+/**
+ * Copyright 2015 Google Inc. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/* Common styles and definitions. */
+
+@import "//fonts.googleapis.com/css?family=Open+Sans:300,400,700&subset=latin,cyrillic-ext,greek-ext,cyrillic,greek,vietnamese,latin-ext";
+
+*,
+*::after,
+*::before {
+  box-sizing: border-box;
+  margin: 0;
+  padding: 0;
+}
+h1, h2, h3, h4, h5, h6 {
+  font-weight: normal;
+  margin: .25em 0 .5em;
+}
+h1 {
+  font-size: 2em;
+}
+h2 {
+  font-size: 1.5em;
+}
+h3 {
+  font-size: 1.3em;
+}
+h4, h5, h6 {
+  font-size: 14px;
+  font-style: italic;
+}
+ul, ol {
+  list-style: none;
+}
+
+/* Utility classes */
+
+.u-sha1 {
+  background-color: #f1f2f3;
+  color: #000;
+  font-family: monospace;
+  font-size: 13px;
+}
+.u-pre {
+  font-size: 10pt;
+  font-family: monospace;
+  font-weight: 500;
+  white-space: pre;
+}
+.u-lineNum {
+  border-right: 1px solid #f1f2f3;
+  color: #666;
+  display: inline-block;
+  min-width: 3em;
+  text-align: right;
+}
+.u-noSelect {
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+
+/* Common.soy */
+
+.Site {
+  background: #fff;
+  color: #000;
+  display: flex;
+  font: 14px/1.54 'Open Sans', sans-serif;
+  min-height: 100vh;
+  flex-direction: column;
+}
+.Site-header,
+.Site-footer {
+  background: #eee;
+  flex: none;
+}
+.Site-content {
+  flex: 1 0 auto;
+  padding: 20px;
+}
+.Container {
+  margin: 0 auto;
+  max-width: 980px;
+}
+.Container--fullWidth {
+  max-width: none;
+}
+.Header,
+.Footer {
+  align-items: center;
+  display: flex;
+  padding: 20px;
+}
+.Header-title {
+  flex: 1;
+}
+.Header-menu {
+  display: flex;
+  justify-content: flex-end;
+}
+.Header-menuItem {
+  color: #00e;
+  display: inline-block;
+  margin-left: 15px;
+}
+.Header-menuItem--noAction {
+  color: inherit;
+}
+.Breadcrumbs {
+  font-size: 18px;
+  margin-bottom: 20px;
+}
+.Breadcrumbs-crumb {
+  color: #00e;
+}
+.Breadcrumbs-crumb:last-child {
+  color: #000;
+  font-weight: bold;
+}
+.Footer {
+  color: #666;
+}
+.Footer-poweredBy {
+  flex: 1;
+}
+.Footer-formats,
+.Footer-links {
+  display: flex;
+  justify-content: flex-end;
+}
+.Footer-formatsItem {
+  display: inline-block;
+  font-family: monospace;
+}
+.Footer-formatsItem:first-child {
+  margin-right: 20px;
+}
+.Footer-link {
+  display: inline-block;
+  margin-left: 10px;
+}
+.RepoList-item {
+  display: flex;
+  left: -10px;
+  padding: 5px 0 5px 10px;
+  position: relative;
+  white-space: nowrap;
+  width: calc(100% + 20px);
+}
+.RepoList-item:link,
+.RepoList-item:visited {
+  text-decoration: none;
+}
+.RepoList-item:hover {
+  background: #eee;
+}
+.RepoList-item--header {
+  font-weight: bold;
+  margin: 0;
+}
+.RepoList-item--header:hover {
+  background: #fff;
+}
+.RepoList-itemName,
+.RepoList-itemDescription {
+  display: inline-block;
+}
+.RepoList-itemName {
+  min-width: 25%;
+  text-decoration: underline;
+}
+.RepoList-item--header > .RepoList-itemName {
+  text-decoration: none;
+}
+.RepoList-itemDescription {
+  color: #000;
+  overflow: hidden;
+  text-overflow: ellipsis;
+}
+
+/* RepositoryIndex.soy */
+
+.RepoDescription {
+  margin: 10px 0;
+}
+.RepoMirroredFrom {
+  margin: 10px 0;
+  color: #666;
+}
+.CloneRepo {
+  background: #eee;
+  margin-bottom: 20px;
+  padding: 10px;
+}
+.CloneRepo-title {
+  margin-bottom: 2px;
+}
+.CloneRepo-command {
+  border: 1px solid #ccc;
+  border-radius: 4px;
+  display: block;
+  font-size: inherit;
+  font-family: monospace;
+  padding: 10px;
+  width: 100%;
+}
+.RepoShortlog {
+  display: flex;
+}
+.RepoShortlog-refs {
+  flex: none !important;
+  width: 20%;
+}
+.RepoShortlog-refs > .RefList:first-child {
+  margin: 0;
+}
+.RepoShortlog-log {
+  flex: 1;
+}
+.RepoIndexDoc {
+  border-top: 1px solid #ddd;
+  margin-top: 20px;
+  padding-top: 5px;
+}
+
+/* RefList.soy */
+
+.Refs {}
+.RefList {
+  margin: 15px 0;
+}
+.RefList-title {
+  margin: 0;
+}
+.RefList-items {}
+.RefList-item {
+  padding: 2px 0;
+}
+
+/* LogDetail.soy */
+
+.LogNav {
+  margin: 10px 0;
+  text-align: center;
+}
+.CommitLog {}
+.CommitLog-item {
+  padding: 2px 0;
+}
+.CommitLog-item--oneline:hover {
+  background: #eee;
+}
+.CommitLog-item--full {
+  margin-bottom: 20px;
+}
+.CommitLog-item--empty {
+  padding: 10px 0;
+  text-align: center;
+}
+.CommitLog-sha1 {
+  border-radius: 3px;
+  display: inline-block;
+  margin-right: 3px;
+  padding: 2px 4px;
+  text-align: center;
+}
+.CommitLog-time {
+  color: #666;
+}
+.CommitLog-branchLabel {
+  color: #dd4b39;
+}
+.CommitLog-tagLabel {
+  color: #093;
+}
+
+/* ObjectDetail.soy */
+
+.Metadata {
+  font-family: monospace;
+  margin-bottom: 15px;
+}
+.Metadata-title {
+  font-weight: bold;
+  padding-right: 10px;
+  text-align: right;
+}
+.MetadataMessage {
+  background-color: #fafafa;
+  border: 1px solid #ccc;
+  color: #000;
+  margin: 0;
+  padding: 12px;
+  white-space: pre-wrap;
+}
+.DiffTree {
+  margin: 10px 0 5px;
+}
+.DiffTree-action {
+  margin-left: .5em;
+}
+.DiffTree-action--add {
+  color: #060;
+}
+.DiffTree-action--delete {
+  color: #600;
+}
+.DiffTree-action--rename,
+.DiffTree-action--copy {
+  color: #006;
+}
+.DiffSummary {}
+.TreeDetail-sha1,
+.BlobSha1 {
+  margin: 10px 0;
+  padding: 5px 10px;
+}
+.FileList {
+  margin-left: 25px;
+}
+.FileList-item {
+  padding: 1px 0;
+  position: relative;
+}
+.FileList-item:hover {
+  background: #eee;
+}
+.FileList-item::before {
+  left: -22px;
+  position: absolute;
+  top: 4px;
+}
+.FileList-itemLink {
+  display: block;
+}
+/* Tree icons are taken from the public domain Tango icons:
+ * http://tango.freedesktop.org/Tango_Icon_Library
+ * Compressed with pngcrush -brute -rem tEXt -rem tIME -rem iTXt -rem zTXt */
+.FileList-item--gitTree::before {
+  /* places/folder.png */
+  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAAb5JREFUOMulkr1KA0EQgGdvTwwnYmER0gQsrFKmSy+pLESw9Qm0F/ICNnba+h6iEOuAEWslKJKTOyJJvIT72d1xZuOFC0giOLA77O7Mt/PnNptN+I+49Xr9GhH3f3mb0v1ht9vtLAUYYw5ItkgDL3KyD8PhcLvdbl/WarXT3DjLMnAcR/f7/YfxeKwtgC5RKQVhGILWeg4hQ6hUKjWyucmhLFEUuWR3QYBWAZABQ9i5CCmXy16pVALP80BKaaG+70MQBLvzFMjRKKXh8j6FSYKF7ITdEWLa4/ktokN74wiqjSMpnVcbQZqmEJHz+ckeCPFjWKwULpyspAqhdXVXdcnZcPjsIgn+2BsVA8jVYuWlgJ3yBj0icgq2uoK+lg4t+ZvLomSKamSQ4AI5BcMADtMhyNoSgNIISUaFNtwlazcDcBc4gjjVwCWid2usCWroYEhnaqbzFJLUzAHIXRDChXCcQP8zhkSZ5eNLgHAUzwDcRu4CoIRn/wsGUQIIy4Vr9TH6SYFCNzw4nALn5627K4vIttOUOwfa5YnrDYzt/9OLv9I5l8kk5hZ3XLO20b7tbR7zHLy/BX8G0IeBEM7ZN1NGIaFUaKLgAAAAAElFTkSuQmCC);
+}
+.FileList-item--symlink::before {
+  /* actions/edit-redo.png */
+  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAABZUlEQVQ4y2NgIAL4zWL7D8TGDOQCqAEg7Ey2Aes+58AMcSSkmB2I3YB4HhCfh9kOMoCgIUAJMyDe2D+b58jKe553133M+r/uU/b/zV+L/y97n/i/+JIYbkOAAl5AfGLNTde/69+n/1/4MuD/gtsqKBhkALIh5S0M1jDN2kC8a+UNt/8b36f+X3JP5f/0u1pwjeuvS8E1g3DpZQm4ITAD5s09ZPBq49uE/0vvq4E1gPCJC5z/yy+IoGgG4a5HJqjeCJ3Pc2vjy+T/ux4Y/j99Rfz/7GtK/xfeUkbBN+8pY9cMAkFzuT5uepPy/+w1lf+TF3L/Q4p3OD5zRQ67Zlg873vk9n/mMlaQ5EcgLgZiA2R5nJphCjbfNP8LVeCBJyUa40xpO+5afQXS/8jKC0DJg+uPKx+bOJf1HDYXEJPW46JW8LcduKYzbdZMph4gn4ccQxSAOAuIo4FYdvsKFpYdK1iYCekDACq5JXDHGJhDAAAAAElFTkSuQmCC);
+}
+.FileList-item--regularFile::before {
+  /* mimetypes/text-x-generic.png */
+  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAtElEQVQ4ja2TSw7CIBRFu0r3wyIYsAMHDl1CC92IDqC0wAbQi4Fo5VOMJGcAyT33vQEDY+xCCPGdnIZ48NB7kPkSLMvipZQBpVQC70Br7Y0xZQGC4zj6aZoCnPMPhBBtwb41NoN1XesCBHPNhyfI7fziFu6HJti3IgS0vrcFuZ3Btm2JpmC/M5jnOdEU5JoRstYmigKES80x7JyrC+IE7+1xAoSrgp//AqX02vsbn5nz8K/zAP9CzjbgFoHjAAAAAElFTkSuQmCC);
+}
+.FileList-item--executableFile::before {
+  /* mimetypes/text-x-script.png */
+  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA7ADsAOwdIxY2AAAACXBIWXMAAAsTAAALEwEAmpwYAAABOklEQVQ4T5WTTYqDQBBGPdKcZnIJdy7EVRByBQPi0iwHAlGT0YBHcG82kkV2VnffoKar7FYzIQYLPtqffq+rEJ04jn/CMMSV+XZs0YO1RcyLoO/7MdAD9gAI8wiK+CyYA0IDFABhrmFBAHNYbwYTIxFyWN8KwAiEmIEaknqVUposCoBBGE8cIGUipUKp5IJAzOe2JxI0pG1b3Gw2+Hg8FjoQzy0rLVAavt0GuGkaXrfb7avAzs0CNcHtDD4ejwzTve/7X/9GGFqn2QmkDmzbBJ9OJ8yyDNM0Rdd1J8mzgDqQPDNJLFwUBZ7PZ7xcLizwPI9gfj+NYAX2k+kx7vc7byrLEquqwuv1ivv9HpMk4ec6Uwfvqus63lzXNeZ5zoIRpoqiKP/09wVBwNDhcOB1t9v9OmuLTnw62dQfVIHPYx/I/0kAAAAASUVORK5CYII=);
+}
+.FileList-item--gitlink::before {
+  /* emblems/emblem-symbolic-link.png */
+  content: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAABO0lEQVQ4T7WT3U6EMBCF92m99yGMZuODGL01eueyXqjvwc+WUlooUPkfZxq3sQEvJLHJSQvlfDOnDbub/dUFCrZof3t9uaPF1kFeBwjD8E+apukfAVEUQRzHkCQJJKfEznES43tUGP0OIOMheIGn50e4f7izCo4H4GkKDEXPBIviCIZh8AFkfv94g5Qx4Jw7AOn4Grh1iqATdrUAEJmxFLIsgzzPQSnpQc4SIkMIh7ZtfQCjys6soNQlVFW1AEgpQWQCjDE+gHIKIaxZo7mu69UOiqJwRXxAxnFDQllS5XUzSeO+kmoJoOzUni41NE1tM9JBTdMII85d14FpjI2lihUA9wCNA8zzDOM4WkBjvgFqrQO8ulzmNgLl/8SPyTT0WL3vLLBGsNZ6HUBV1tT3vROd/Fk/AZt/Z/J+AUN8ayghXmezAAAAAElFTkSuQmCC);
+}
+.FileContents {
+  border-collapse: collapse;
+  border-spacing: 0;
+  margin: 10px 0;
+}
+.FileContents-line {
+  border: none;
+}
+.FileContents-lineNum {
+  padding-right: 10px;
+  width: 1%;
+}
+/* Used to prevent copying the line number. */
+.FileContents-lineNum::before {
+  color: #aaa;
+  content: attr(data-line-number);
+  cursor: pointer;
+}
+.FileContents-lineContents {
+  min-height: 1em;
+  padding-left: 10px;
+}
+.InlineReadme {
+  border-top: 1px solid #ddd;
+  margin: 10px 0;
+  padding: 7px 0;
+}
+.InlineReadme-path {
+  color: #666;
+}
+
+/* BlameDetail.soy */
+
+.Blame {
+  margin: 10px 0;
+}
+.Blame-region {
+  display: flex;
+}
+.Blame-leftCol {
+  font-size: 8pt;
+  width: 375px;
+}
+.Blame-rightCol {
+  flex: 1;
+  font-size: 8pt;
+}
+.Blame-sha1,
+.Blame-author,
+.Blame-time,
+.Blame-regionLink {
+  display: inline-block;
+  font-size: 8pt;
+}
+.Blame-lineNum {
+  margin-right: 10px;
+  min-width: 3.5em;
+  padding-right: 8px;
+  text-align: right;
+}
+.Blame-lineNum:hover {
+  text-decoration: underline;
+}
+.Blame-region--bg1 {
+  background: #fff;
+}
+.Blame-region--bg2 {
+  background: #f1f2f3;
+}
+
+/* DiffDetail.soy */
+
+.Diff {
+  margin: 10px 0;
+}
+.Diff-fileIndex {
+  color: #444;
+  font-weight: bold;
+}
+.Diff-unified {
+  border-bottom: 1px solid #ddd;
+  border-top: 1px solid #ddd;
+  padding: 10px 0;
+}
+.Diff-hunk {
+  color: #00c;
+}
+.Diff-delete {
+  color: #c00;
+}
+.Diff-insert {
+  color: #080;
+}
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/static/doc.css b/gitiles-servlet/src/main/resources/com/google/gitiles/static/doc.css
index 672797c..8d38cb3 100644
--- a/gitiles-servlet/src/main/resources/com/google/gitiles/static/doc.css
+++ b/gitiles-servlet/src/main/resources/com/google/gitiles/static/doc.css
@@ -14,161 +14,45 @@
  * limitations under the License.
  */
 
-html.doc-page, .doc {
-  font-family: arial,sans-serif;
-}
-.doc-page body {
-  margin: 0;
-}
-
-.banner {
-  min-height: 44px;
-  margin: 0;
-  padding: 14px 15px 13px;
-  border-bottom: 1px solid #eee;
-}
-.banner h1, .banner h2 {
-  float: left;
-  font-size: 32px;
-  font-weight: 300;
-  line-height: 1.375;
-  margin: 0;
-}
-.banner img {
-  margin: -1px 10px -4px 0px;
-  vertical-align: middle;
-}
-.banner a, .banner a:hover {
-  text-decoration: none;
-}
-.banner, .banner a:link, .banner a:visited {
-  color: #777;
-}
-.banner h2:before {
-  border-right: 1px solid #eee;
-  content: "";
-  float: left;
-  height: 44px;
-  margin: 0 12px 0 14px;
-}
-
-.nav, .footer-line {
-  color: #333;
-  padding: 0 15px;
-  background: #eee;
-}
-.nav ul {
-  list-style: none;
-  margin: 0;
-  padding: 6px 0;
-}
-.nav li {
-  float: left;
-  font-size: 14px;
-  line-height: 1.43;
-  margin: 0 20px 0 0;
-  padding: 6px 0;
-}
-.nav li a, .footer-line a {
-  color: #7a7af9;
-}
-.nav li a:hover {
-  color: #0000f9;
-}
-.banner:after, .nav ul:after, .cols:after {
-  clear: both;
-  content: "";
-  display: block;
-}
-
-.nav-aux, .doc {
-  max-width: 978px;
-}
-.nav-aux, .doc-page .doc {
-  margin: auto;
-}
-
-.footer-break {
-  clear: both;
-  margin: 120px 0 0 0;
-}
-.footer-line {
-  font-size: 13px;
-  line-height: 30px;
-  height: 30px;
-}
-.footer-line ul {
-  list-style: none;
-  margin: 0;
-  padding: 0;
-}
-.footer-line li {
-  display: inline;
-}
-.footer-line li+li:before {
-  content: "·";
-  padding: 0 5px;
-}
-.footer-line .nav-aux {
-  position: relative;
-}
-.gitiles-att {
-  color: #A0ADCC;
-  position: absolute;
-  top: 0;
-  right: 0;
-}
-.gitiles-att a {
-  font-style: italic;
-}
-
 /* Markdown rendered in /+doc/ or tree view page . */
 
-.doc {
-  color: #444;
-  font-size: 13px;
-  line-height: normal;
+.Site-Content--markdown {
+  padding-top: 0;
 }
-
 .doc h1, .doc h2, .doc h3, .doc h4, .doc h5, .doc h6 {
-  font-family: "open sans",arial,sans-serif;
-  font-weight: bold;
-  color: #444;
-  height: auto;
-  white-space: normal;
-  overflow: visible;
-  margin: 0.67em 0 0.67em 0;
+  font-weight: normal;
+  margin: 1.236em 0 .618em;
+}
+.doc.RepoIndexDoc h1 {
+  margin-top: .25em;
 }
 .doc h1 {
-  font-size: 20px;
-  margin: 0.67em 0 0.67em 0;
+  font-size: 2em;
 }
 .doc h2 {
-  font-size: 16px;
-  margin: 0.67em 0 0.67em 0;
+  font-size: 1.5em;
 }
 .doc h3 {
-  font-size: 14px;
-  margin: 0.67em 0 0.67em 0;
+  font-size: 1.3em;
 }
-.doc h4 {
-  font-size: 13px;
-  margin: 1em 0 1em 0;
-}
-.doc h5 {
-  font-size: 13px;
-  margin: 1.3em 0 1.3em 0;
-}
+.doc h4,
+.doc h5,
 .doc h6 {
-  font-size: 13px;
-  margin: 1.6em 0 1.6em 0;
+  font-size: 14px;
+  font-style: italic;
 }
-
-.doc a { text-decoration: none; }
-.doc a:link { color: #245dc1; }
-.doc a:visited { color: #7759ae; }
-.doc a:hover { text-decoration: underline; }
-
+.doc a {
+  text-decoration: none;
+}
+.doc a:link {
+  color: #245dc1;
+}
+.doc a:visited {
+  color: #7759ae;
+}
+.doc a:hover {
+  text-decoration: underline;
+}
 .doc a.h {
   display: inline-block;
   font-weight: normal;
@@ -178,9 +62,15 @@
   margin-bottom: -1em;
 }
 .doc a.h:link,
-.doc a.h:visited { color: #444; }
-.doc a.h:focus { outline: none; }
-.doc a.h:hover { text-decoration: none; }
+.doc a.h:visited {
+  color: #444;
+}
+.doc a.h:focus {
+  outline: none;
+}
+.doc a.h:hover {
+  text-decoration: none;
+}
 .doc a.h span {
   display: inline-block;
   width: 1.5em;
@@ -191,14 +81,36 @@
 .doc h4:hover a.h span:before,
 .doc h5:hover a.h span:before,
 .doc h6:hover a.h span:before {
-  content: '\1f517'; /* Unicode 'LINK SYMBOL' */
+  content: '#';
+  font-weight: normal;
+  color: #AAA;
 }
-
+.doc h1:hover a:hover.h span:before,
+.doc h2:hover a:hover.h span:before,
+.doc h3:hover a:hover.h span:before,
+.doc h4:hover a:hover.h span:before,
+.doc h5:hover a:hover.h span:before,
+.doc h6:hover a:hover.h span:before {
+  text-decoration: underline;
+}
+.doc h1:hover a:visited.h span:before,
+.doc h2:hover a:visited.h span:before,
+.doc h3:hover a:visited.h span:before,
+.doc h4:hover a:visited.h span:before,
+.doc h5:hover a:visited.h span:before,
+.doc h6:hover a:visited.h span:before {
+  color: #AAA;
+}
 .doc ul, .doc ol {
   margin: 10px 10px 10px 30px;
   padding: 0;
 }
-
+.doc ul {
+  list-style-type: disc;
+}
+.doc ol {
+  list-style-type: decimal;
+}
 .doc img {
   border: 0;
   max-width: 100%;
@@ -210,7 +122,6 @@
 iframe.noborder {
   border: 0;
 }
-
 .doc em {
   font-weight: normal;
   font-style: italic;
@@ -219,22 +130,28 @@
   font-weight: bold;
   color: inherit;
 }
-
+.doc p {
+  margin: 10px 0;
+}
 .doc pre {
-  border: 1px solid silver;
-  background: #fafafa;
-  margin: 0 2em 0 2em;
-  padding: 2px;
+  padding: 12px;
+  font-size: 10pt;
+  background-color: #fafafa;
+  border: 1px solid #ccc;
+  overflow-x: auto;
 }
-.doc code, .doc .code {
-  color: #060;
-  font: 13px/1.54 "courier new",courier,monospace;
+.doc code {
+  padding: 2px 4px;
+  background-color: #F5F5F5;
+  border: transparent;
+  border-radius: 4px;
 }
-
+.doc .code {
+  font-family: monospace;
+}
 .doc dl dt {
   margin-top: 1em;
 }
-
 .doc table {
   border-collapse: collapse;
   border-spacing: 0;
@@ -242,7 +159,8 @@
 .doc th {
   text-align: center;
 }
-.doc th, .doc td {
+.doc th,
+.doc td {
   border: 1px solid #eee;
   padding: 4px 12px;
   vertical-align: top;
@@ -250,31 +168,33 @@
 .doc th {
   background-color: #f5f5f5;
 }
-
 .toc {
   margin-top: 30px;
 }
 .toc-aux {
-  padding: 2px;
   background: #f9f9f9;
   border: 1px solid #f2f2f2;
-  border-radius: 4px;
 }
 .toc h2 {
   margin: 0 0 5px 0;
 }
 .toc ul {
-  margin: 0 0 0 30px;
+  margin: 10px 10px 10px 30px;
 }
 .toc ul li {
   margin-left: 0px;
   list-style: disc;
 }
+.toc ul ul {
+  margin-top: 0;
+  margin-bottom: 0;
+}
 .toc ul ul li {
   list-style: circle;
 }
-
-.note, .promo, .aside {
+.note,
+.promo,
+.aside {
   border: 1px solid;
   border-radius: 4px;
   margin: 10px 0;
@@ -302,7 +222,6 @@
 .aside p:last-child {
   margin-bottom: 0;
 }
-
 .cols {
   margin: 0 -1.533%;
   width: 103.067%;
@@ -324,6 +243,4 @@
 .col-10 { width: 80.357%; }
 .col-11 { width: 88.690%; }
 .col-12 { width: 97.024%; }
-.cols hr {
-  width: 80%;
-}
+.cols hr { width: 80%; }
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/static/gitiles.css b/gitiles-servlet/src/main/resources/com/google/gitiles/static/gitiles.css
deleted file mode 100644
index 26130ae..0000000
--- a/gitiles-servlet/src/main/resources/com/google/gitiles/static/gitiles.css
+++ /dev/null
@@ -1,453 +0,0 @@
-/**
- * Copyright 2012 Google Inc. All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-/* Common styles and definitions. */
-
-h1 {
-  position: absolute;
-  top: 0;
-  white-space: nowrap;
-  margin-top: 5px;
-}
-.menu {
-  position: absolute;
-  top: 0;
-  right: 0;
-  font-size: 10pt;
-  white-space: nowrap;
-  text-align: right;
-  margin-top: 5px;
-  margin-right: 5px;
-}
-.menu .entry {
-  padding-right: 5px;
-  border-right: 1px solid black;
-  margin-right: 0;
-}
-h2 {
-  margin-top: 3em;
-}
-.breadcrumbs {
-  margin-top: 3em;
-  font-size: 150%;
-  border-bottom: #ddd solid 1px; /* BORDER */
-}
-table.list {
-  margin-top: 1em;
-  width: 90%;
-}
-table.list tr.no-hover:hover {
-  background: #fff;
-}
-table.list tr:hover, ol.list li:hover, pre.prettyprint li:hover {
-  background: #eee; /* HOVER_BACKGROUND */
-}
-table.list td {
-  white-space: nowrap;
-  padding-top: 0.25em;
-  padding-bottom: 0.25em;
-}
-.log-link, .download-link {
-  margin-left: 0.5em
-}
-
-
-/* Styles for the host index page. */
-
-.instructions {
-  width: 45em;
-  margin-left: 1em;
-  margin-right: 1em;
-  border-top: 1px solid #555;
-  border-bottom: 1px solid #555;
-  color: #555;
-}
-.instructions pre {
-  display: block;
-  margin-left: 1em;
-  border-left: 2px solid #060;
-  padding-left: 1em;
-  white-space: nowrap;
-}
-
-.formats {
-  text-align: right;
-  background: clear;
-  right: 0;
-  clear: both;
-}
-
-.formats a {
-  font-weight: bold;
-  font-size: 70%;
-  color: white;
-  padding: 2px;
-  background-color: #A0ADCC;
-  border-top: #C0CFEE solid 1px;
-  border-left: #C0CFEE solid 1px;
-  border-right: #808A99 solid 1px;
-  border-bottom: #808A99 solid 1px;
-}
-
-.footer {
-  text-align: right;
-  color: #A0ADCC;
-  right: 0;
-  clear: both;
-}
-
-.footer a {
-  font-style: italic;
-}
-
-
-/* Styles for the repository index page. */
-
-.repository-description {
-  border-bottom: #ddd solid 1px; /* BORDER */
-  padding-bottom: 5px; /* VPADDING */
-}
-.repository-mirrored-from {
-  font-size: 85%;
-  font-style: italic;
-  padding-left: 1em;
-}
-.repository-refs {
-  float: left;
-  width: 200px;
-  margin-left: -100%;
-}
-.repository-shortlog-wrapper {
-  float: left;
-  width: 100%;
-}
-.repository-shortlog {
-  margin-top: 20px;
-  margin-left: 200px;
-}
-.clone-line {
-  background-color: #e5ecf9; /* BOX_BACKGROUND */
-  border: none;
-  margin: 5px /* VPADDING */ 0 0 0;
-  padding: 5px 2em; /* PADDING */
-  font-size: 9pt;
-}
-
-/* Styles for the ref detail page. */
-
-.refs-branches {
-  float: left;
-  width: 200px;
-}
-.refs-tags {
-  float: left;
-  width: 200px;
-}
-.refs-detail {
-  width: 500px;
-}
-.ref-list {
-  padding-left: 15px;
-  padding-right: 5px;
-}
-.ref-list li {
-  overflow: hidden;
-  text-overflow: ellipsis;
-  white-space: nowrap;
-}
-.ref-list li.head-ref {
-  font-weight: bold;
-}
-
-
-/* Styles for the object detail templates. */
-
-.sha1 {
-  color: #666;
-  font-size: 9pt;
-}
-div.sha1 {
-  padding-top: 5px; /* VPADDING */
-}
-
-.git-commit, .git-tag {
-  font-size: 9pt;
-  border-bottom: #ddd solid 1px; /* BORDER */
-  padding: 5px 2em; /* PADDING */
-}
-.git-commit table, .git-tag table {
-  margin: 0;
-}
-.git-commit table th, .git-tag table th {
-  text-align: right;
-}
-pre.commit-message, pre.tag-message {
-  padding: 5px 2em; /* PADDING */
-  color: #000;
-  font-size: 9pt;
-  margin: 0;
-}
-
-ul.diff-tree {
-  border-top: #ddd solid 1px; /* BORDER */
-  font-size: 9pt;
-  list-style-type: none;
-  margin: 0;
-  padding: 5px 2em; /* PADDING */
-}
-ul.diff-tree .add {
-  color: #060;
-}
-ul.diff-tree .delete {
-  color: #600;
-}
-ul.diff-tree .rename, ul.diff-tree .copy {
-  color: #006;
-}
-span.diff-link, ul.diff-tree .add, ul.diff-tree .modify, ul.diff-tree .delete,
-    ul.diff-tree .rename, ul.diff-tree .copy {
-  margin-left: 0.5em;
-}
-.diff-summary {
-  font-size: 9pt;
-  font-style: italic;
-  padding: 5px 2em; /* PADDING */
-  border-bottom: #ddd solid 1px; /* BORDER */
-}
-
-ol.files {
-  list-style-type: none;
-  margin-left: 1em;
-  font-size: 10pt;
-  line-height: normal;
-}
-
-/* Tree icons are taken from the public domain Tango icons:
- * http://tango.freedesktop.org/Tango_Icon_Library
- * Compressed with pngcrush -brute -rem tEXt -rem tIME -rem iTXt -rem zTXt */
-ol.files li.git-tree{
-  /* places/folder.png */
-  list-style-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAN1wAADdcBQiibeAAAAb5JREFUOMulkr1KA0EQgGdvTwwnYmER0gQsrFKmSy+pLESw9Qm0F/ICNnba+h6iEOuAEWslKJKTOyJJvIT72d1xZuOFC0giOLA77O7Mt/PnNptN+I+49Xr9GhH3f3mb0v1ht9vtLAUYYw5ItkgDL3KyD8PhcLvdbl/WarXT3DjLMnAcR/f7/YfxeKwtgC5RKQVhGILWeg4hQ6hUKjWyucmhLFEUuWR3QYBWAZABQ9i5CCmXy16pVALP80BKaaG+70MQBLvzFMjRKKXh8j6FSYKF7ITdEWLa4/ktokN74wiqjSMpnVcbQZqmEJHz+ckeCPFjWKwULpyspAqhdXVXdcnZcPjsIgn+2BsVA8jVYuWlgJ3yBj0icgq2uoK+lg4t+ZvLomSKamSQ4AI5BcMADtMhyNoSgNIISUaFNtwlazcDcBc4gjjVwCWid2usCWroYEhnaqbzFJLUzAHIXRDChXCcQP8zhkSZ5eNLgHAUzwDcRu4CoIRn/wsGUQIIy4Vr9TH6SYFCNzw4nALn5627K4vIttOUOwfa5YnrDYzt/9OLv9I5l8kk5hZ3XLO20b7tbR7zHLy/BX8G0IeBEM7ZN1NGIaFUaKLgAAAAAElFTkSuQmCC);
-}
-ol.files li.symlink{
-  /* actions/edit-redo.png */
-  list-style-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAABZUlEQVQ4y2NgIAL4zWL7D8TGDOQCqAEg7Ey2Aes+58AMcSSkmB2I3YB4HhCfh9kOMoCgIUAJMyDe2D+b58jKe553133M+r/uU/b/zV+L/y97n/i/+JIYbkOAAl5AfGLNTde/69+n/1/4MuD/gtsqKBhkALIh5S0M1jDN2kC8a+UNt/8b36f+X3JP5f/0u1pwjeuvS8E1g3DpZQm4ITAD5s09ZPBq49uE/0vvq4E1gPCJC5z/yy+IoGgG4a5HJqjeCJ3Pc2vjy+T/ux4Y/j99Rfz/7GtK/xfeUkbBN+8pY9cMAkFzuT5uepPy/+w1lf+TF3L/Q4p3OD5zRQ67Zlg873vk9n/mMlaQ5EcgLgZiA2R5nJphCjbfNP8LVeCBJyUa40xpO+5afQXS/8jKC0DJg+uPKx+bOJf1HDYXEJPW46JW8LcduKYzbdZMph4gn4ccQxSAOAuIo4FYdvsKFpYdK1iYCekDACq5JXDHGJhDAAAAAElFTkSuQmCC);
-}
-ol.files li.regular-file{
-  /* mimetypes/text-x-generic.png */
-  list-style-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAtElEQVQ4ja2TSw7CIBRFu0r3wyIYsAMHDl1CC92IDqC0wAbQi4Fo5VOMJGcAyT33vQEDY+xCCPGdnIZ48NB7kPkSLMvipZQBpVQC70Br7Y0xZQGC4zj6aZoCnPMPhBBtwb41NoN1XesCBHPNhyfI7fziFu6HJti3IgS0vrcFuZ3Btm2JpmC/M5jnOdEU5JoRstYmigKES80x7JyrC+IE7+1xAoSrgp//AqX02vsbn5nz8K/zAP9CzjbgFoHjAAAAAElFTkSuQmCC)
-}
-ol.files li.executable-file{
-  /* mimetypes/text-x-script.png */
-  list-style-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA7ADsAOwdIxY2AAAACXBIWXMAAAsTAAALEwEAmpwYAAABOklEQVQ4T5WTTYqDQBBGPdKcZnIJdy7EVRByBQPi0iwHAlGT0YBHcG82kkV2VnffoKar7FYzIQYLPtqffq+rEJ04jn/CMMSV+XZs0YO1RcyLoO/7MdAD9gAI8wiK+CyYA0IDFABhrmFBAHNYbwYTIxFyWN8KwAiEmIEaknqVUposCoBBGE8cIGUipUKp5IJAzOe2JxI0pG1b3Gw2+Hg8FjoQzy0rLVAavt0GuGkaXrfb7avAzs0CNcHtDD4ejwzTve/7X/9GGFqn2QmkDmzbBJ9OJ8yyDNM0Rdd1J8mzgDqQPDNJLFwUBZ7PZ7xcLizwPI9gfj+NYAX2k+kx7vc7byrLEquqwuv1ivv9HpMk4ec6Uwfvqus63lzXNeZ5zoIRpoqiKP/09wVBwNDhcOB1t9v9OmuLTnw62dQfVIHPYx/I/0kAAAAASUVORK5CYII=);
-}
-ol.files li.gitlink{
-  /* emblems/emblem-symbolic-link.png */
-  list-style-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAABO0lEQVQ4T7WT3U6EMBCF92m99yGMZuODGL01eueyXqjvwc+WUlooUPkfZxq3sQEvJLHJSQvlfDOnDbub/dUFCrZof3t9uaPF1kFeBwjD8E+apukfAVEUQRzHkCQJJKfEznES43tUGP0OIOMheIGn50e4f7izCo4H4GkKDEXPBIviCIZh8AFkfv94g5Qx4Jw7AOn4Grh1iqATdrUAEJmxFLIsgzzPQSnpQc4SIkMIh7ZtfQCjys6soNQlVFW1AEgpQWQCjDE+gHIKIaxZo7mu69UOiqJwRXxAxnFDQllS5XUzSeO+kmoJoOzUni41NE1tM9JBTdMII85d14FpjI2lihUA9wCNA8zzDOM4WkBjvgFqrQO8ulzmNgLl/8SPyTT0WL3vLLBGsNZ6HUBV1tT3vROd/Fk/AZt/Z/J+AUN8ayghXmezAAAAAElFTkSuQmCC);
-}
-
-
-/* Styles for the path detail page. */
-
-.symlink-detail, .gitlink-detail {
-  margin-left: 1em;
-  color: #666;
-  font-style: italic;
-  font-size: 10pt;
-}
-
-
-/* Styles for the log detail page. */
-
-ol.log {
-  list-style-type: none;
-  margin: 0;
-  padding-left: 0;
-}
-ol.oneline.log, ol.default.log {
-  padding: 5px 2em; /* PADDING */
-}
-ol.log > li {
-  border-bottom: #ddd solid 1px; /* BORDER */
-  padding-top: 2px;
-  padding-bottom: 2px;
-}
-ol.full.log > li, ol.fuller.log > li {
-  padding-top: 0;
-  padding-bottom: 5px;
-}
-ol.full.log .git-commit, ol.fuller.log .git-commit {
-  background: #eee;
-}
-ol.log > li.first {
-  border-top: #ddd solid 1px; /* BORDER */
-}
-ol.default.log > li:hover, ol.oneline.log > li:hover {
-  background: #eee; /* HOVER_BACKGROUND */
-}
-ol.log span.sha1 {
-  font-family: monospace;
-}
-ol.log ul.diff-tree {
-  margin-left: 2em;
-  padding: 5px 0 5px 0;
-}
-.log-nav {
-  margin-top: 5px;
-  text-align: center;
-}
-.author {
-  padding-left: 3px;
-}
-.time {
-  font-size: 9pt; /* SHORTLOG_SMALL_FONT_SIZE */
-  font-style: italic;
-  margin-right: 3px;
-}
-.branch-label, .tag-label {
-  font-size: 9pt; /* SHORTLOG_SMALL_FONT_SIZE */
-  margin-right: 3px;
-}
-a.branch-label {
-  color: #dd4b39;
-}
-a.tag-label {
-  color: #009933;
-}
-
-ol.log > li.empty:hover, ol.log > li.empty {
-  background: inherit;
-  padding: 0px;
-  border: 0px;
-}
-
-
-/* Styles for the diff detail template. */
-
-.diff-header {
-}
-.diff-git {
-  color: #444;
-  font-weight: bold;
-}
-a.diff-git:hover {
-  text-decoration: none;
-}
-.diff-header, .diff-unified {
-  color: #000;
-  font-size: 9pt;
-  margin: 0;
-  padding-left: 2em;
-}
-.diff-unified {
-  border-bottom: #ddd solid 1px; /* BORDER */
-}
-.diff-unified .h {
-  color: #0000cc;
-}
-.diff-unified .d {
-  color: #cc0000;
-}
-.diff-unified .i {
-  color: #008800;
-}
-
-
-/* Styles for the blame detail template. */
-
-#blame {
-  margin-top: 10px;
-  margin-bottom: 10px;
-  margin-left: 0px;
-  margin-right: 0px;
-  padding: 0;
-}
-#blame td {
-  line-height: 1.4;
-  padding: 0;
-  font-size: 8pt;
-  white-space: nowrap;
-}
-#blame .sha1, #blame .author, #blame .time {
-   /* TODO(dborowitz): Make 9pt values above more specific. */
-  font-size: 8pt;
-}
-#blame .sha1 {
-  color: inherit;
-  font-family: monospace;
-  padding-left: 3px;
-}
-#blame .author {
-  padding-left: 3px;
-  padding-right: 3px;
-}
-#blame .time {
-  padding-left: 5px;
-  padding-right: 5px;
-}
-#blame .linenum {
-  text-align: right;
-  padding-left: 5px;
-  padding-right: 5px;
-}
-#blame .regionLink {
-  padding-right: 3px;
-}
-
-#blame tr.bg1 {
-  background: #fff;
-}
-#blame tr.bg2 {
-  background: #f7f7f7;
-}
-
-/* Styles for pretty-print regions, including overriding some defaults from
- * prettify.css. */
-
-ol.prettyprint, #blame {
-  border-top: #ddd solid 1px; /* BORDER */
-  border-bottom: #ddd solid 1px; /* BORDER */
-  border-left: none;
-  border-right: none;
-  padding-left: 5em;
-  padding-bottom: 5px;
-}
-.prettyprint, #blame .linenum {
-  font-family: monospace;
-  font-size: 8pt;
-  white-space: pre !important;
-}
-
-/* Styles for README.md in tree view. */
-
-.readme-path {
-  border-top: #ddd solid 1px; /* BORDER */
-  color: #666;
-  font-size: 9pt;
-  padding-top: 5px; /* VPADDING */
-}
-.repository-index-doc {
-  border-top: #ddd solid 1px; /* BORDER */
-  margin-top: 5px; /* VPADDING */
-  padding-top: 5px; /* VPADDING */
-  margin-left: 200px;
-}
-.doc {
-  border-bottom: #ddd solid 1px; /* BORDER */
-}
-.doc h1 {
-  position: static;
-}
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/BlameDetail.soy b/gitiles-servlet/src/main/resources/com/google/gitiles/templates/BlameDetail.soy
index 124ed5a..5ccd8c3 100644
--- a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/BlameDetail.soy
+++ b/gitiles-servlet/src/main/resources/com/google/gitiles/templates/BlameDetail.soy
@@ -39,40 +39,41 @@
 {if $regions}
   {call .header data="all"}
     {param css: [gitiles.PRETTIFY_CSS_URL] /}
+    {param containerClass: 'Container--fullWidth' /}
   {/call}
 
   {call .blobHeader data="$data" /}
 
-  <table id="blame">
+  <div class="Blame">
     {foreach $line in $data.lines}
       {let $i: index($line) /}
       {let $region: $regions[$i] /}
-      <tr class="{$region.class}">
-        {if isNonnull($region.abbrevSha)}
-          <td class="author">{$region.author.name}</td>
-          <td class="time">{$region.author.time}</td>
-          <td class="sha1"><a href="{$region.commitUrl}">{$region.abbrevSha}</a></td>
-          <td class="regionLink">
-            [<a href="{$region.diffUrl}">{msg desc="text for diff URL"}diff{/msg}</a>]
-            [<a href="{$region.blameUrl}">{msg desc="text for blame URL"}blame{/msg}</a>]
-          </td>
-        {else}
-          <td colspan="4"></td>
-        {/if}
-        {let $n: $i + 1 /}
-        <td class="linenum"><a name="{$n}"></a>{$n}.</td>
-        <td class="prettyprint">
+      <div class="Blame-region {$region.class}">
+        <div class="Blame-leftCol">
+          {if isNonnull($region.abbrevSha)}
+            <span class="Blame-author">{$region.author.name}</span>
+            {sp}<a class="u-sha1 Blame-sha1" href="{$region.commitUrl}">{$region.abbrevSha}</a>
+            {sp}<span class="Blame-time">{$region.author.time}</span>
+            {sp}<span class="Blame-regionLink">
+              [<a href="{$region.diffUrl}">{msg desc="text for diff URL"}diff{/msg}</a>]
+              [<a href="{$region.blameUrl}">{msg desc="text for blame URL"}blame{/msg}</a>]
+            </span>
+          {/if}
+        </div>
+        <div class="u-pre Blame-rightCol">
+          {let $n: $i + 1 /}
+          <a class="u-lineNum Blame-lineNum" href="#{$n}" name="{$n}">{$n}</a>
           {foreach $span in $line}
             <span class="{$span.classes}">{$span.text}</span>
           {/foreach}
-        </td>
-      </tr>
+        </div>
+      </div>
     {/foreach}
-  </table>
+  </div>
 {else}
   {call .header data="all" /}
   {call .blobDetail data="$data" /}
-  <div class="file-binary">
+  <div class="FileContents-binary">
     {msg desc="blame not available for binary file"}
       No blame information available
     {/msg}
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/Common.soy b/gitiles-servlet/src/main/resources/com/google/gitiles/templates/Common.soy
index 1ec6540..7d523f6 100644
--- a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/Common.soy
+++ b/gitiles-servlet/src/main/resources/com/google/gitiles/templates/Common.soy
@@ -25,11 +25,13 @@
  * @param breadcrumbs navigation breadcrumbs for this page.
  * @param? css optional list of CSS URLs to include.
  * @param? js optional list of Javascript URLs to include.
+ * @param? containerClass optional class to append to the main container.
  */
 {template .header}
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html>
+<!DOCTYPE html>
+<html lang="en">
 <head>
+  <meta charset="utf-8">
   <title>
     {$title}
     {if $repositoryName}
@@ -37,68 +39,84 @@
     {/if}
     {sp}- {msg desc="name of the application"}{gitiles.SITE_TITLE}{/msg}
   </title>
-  <link rel="stylesheet" type="text/css" href="//www.google.com/css/go.css" />
 
+  <link rel="stylesheet" type="text/css" href="{gitiles.BASE_CSS_URL}">
   {if $css and length($css)}
     {foreach $url in $css}
-      <link rel="stylesheet" type="text/css" href="{$url}" />
+      <link rel="stylesheet" type="text/css" href="{$url}">
     {/foreach}
   {/if}
-  // Include default CSS after custom CSS so it can override defaults in third-
-  // party stylesheets (e.g. prettify).
-  <link rel="stylesheet" type="text/css" href="{gitiles.CSS_URL}" />
 
   {if $js and length($js)}
     {foreach $url in $js}
-      <script src="{$url}" type="text/javascript"></script>
+      <script src="{$url}"></script>
     {/foreach}
   {/if}
 </head>
-<body>
-  {delcall gitiles.customHeader variant="$headerVariant ?: 'default'" /}
+<body class="Site">
+  <header class="Site-header">
+    <div class="Header">
+      {delcall gitiles.customHeader variant="$headerVariant ?: 'default'" /}
 
-  {if $menuEntries and length($menuEntries)}
-    <div class="menu">
-    {foreach $entry in $menuEntries}
-      {sp}
-      {if $entry.url}
-        <a href="{$entry.url}"{if not isLast($entry)} class="entry"{/if}>{$entry.text}</a>
-      {else}
-        <span{if not isLast($entry)} class="entry"{/if}>{$entry.text}</span>
+      {if $menuEntries and length($menuEntries)}
+        <div class="Header-menu">
+        {foreach $entry in $menuEntries}
+          {sp}
+          {if $entry.url}
+            <a class="Header-menuItem" href="{$entry.url}">{$entry.text}</a>
+          {else}
+            <span class="Header-menuItem Header-menuItem--noAction">{$entry.text}</span>
+          {/if}
+        {/foreach}
+        {sp}
+        </div>
       {/if}
-    {/foreach}
-    {sp}
     </div>
-  {/if}
+  </header>
 
-  {if $breadcrumbs and length($breadcrumbs)}
-    <div class="breadcrumbs">
-      {foreach $entry in $breadcrumbs}
-        {if not isFirst($entry)}{sp}/{sp}{/if}
-        {if not isLast($entry)}
-          <a href="{$entry.url}">{$entry.text}</a>
-        {else}
-          {$entry.text}
-        {/if}
-      {/foreach}
-    </div>
-  {/if}
+  <div class="Site-content">
+    <div class="Container {if $containerClass}{$containerClass}{/if}">
+      {if $breadcrumbs and length($breadcrumbs)}
+        <div class="Breadcrumbs">
+          {foreach $entry in $breadcrumbs}
+            {if not isFirst($entry)}{sp}/{sp}{/if}
+            {if not isLast($entry)}
+              <a class="Breadcrumbs-crumb" href="{$entry.url}">{$entry.text}</a>
+            {else}
+              <span class="Breadcrumbs-crumb">{$entry.text}</span>
+            {/if}
+          {/foreach}
+        </div>
+      {/if}
 {/template}
 
 /**
  * Default custom header implementation for Gitiles.
  */
 {deltemplate gitiles.customHeader variant="'default'"}
-<h1>{msg desc="short name of the application"}{gitiles.SITE_TITLE}{/msg}</h1>
+<div class="Header-title">
+  {msg desc="short name of the application"}{gitiles.SITE_TITLE}{/msg}
+</div>
 {/deltemplate}
 
 /**
  * Standard footer.
  */
 {template .footer}
-  <div class="footer">
-      Powered by <a href="https://code.google.com/p/gitiles/">Gitiles</a>
-  </div>
+    </div> <!-- Container -->
+  </div> <!-- Site-content -->
+  <footer class="Site-footer">
+    <div class="Footer">
+      <span class="Footer-poweredBy">
+        Powered by <a href="https://code.google.com/p/gitiles/">Gitiles</a>
+      </span>
+      <span class="Footer-formats">
+        <a class="Footer-formatsItem" href="?format=TEXT">{msg desc="text format"}txt{/msg}</a>
+        {sp}
+        <a class="Footer-formatsItem" href="?format=JSON">{msg desc="JSON format"}json{/msg}</a>
+      </span>
+    </div>
+  </footer>
 </body>
 </html>
 {/template}
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/DiffDetail.soy b/gitiles-servlet/src/main/resources/com/google/gitiles/templates/DiffDetail.soy
index 7339f34..9f41298 100644
--- a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/DiffDetail.soy
+++ b/gitiles-servlet/src/main/resources/com/google/gitiles/templates/DiffDetail.soy
@@ -44,16 +44,16 @@
  * @param fileIndex position of the file within the difference.
  */
 {template .diffHeader}
-<pre class="diff-header">
-<a name="F{$fileIndex}" class="diff-git"></a>
-{foreach $part in $firstParts}
-  {if not isFirst($part)}{sp}{/if}
-  {if $part.url}
-    <a href="{$part.url}">{$part.text}</a>
-  {else}
-    {$part.text}
-  {/if}
-{/foreach}{\n}
-{$rest}
+<pre class="u-pre Diff">
+  <a name="F{$fileIndex}" class="Diff-fileIndex"></a>
+  {foreach $part in $firstParts}
+    {if not isFirst($part)}{sp}{/if}
+    {if $part.url}
+      <a href="{$part.url}">{$part.text}</a>
+    {else}
+      {$part.text}
+    {/if}
+  {/foreach}{\n}
+  {$rest}
 </pre>
 {/template}
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/Doc.soy b/gitiles-servlet/src/main/resources/com/google/gitiles/templates/Doc.soy
index b0daab3..d4da587 100644
--- a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/Doc.soy
+++ b/gitiles-servlet/src/main/resources/com/google/gitiles/templates/Doc.soy
@@ -28,53 +28,56 @@
  * @param bodyHtml safe html to embed into the body of the page.
  */
 {template .markdownDoc}
-<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
-<html class="doc-page">
+<!DOCTYPE html>
+<html lang="en">
 <head>
+  <meta charset="utf-8">
   <title>
     {if $siteTitle}{$siteTitle} -{sp}{/if}
     {$pageTitle}
   </title>
+  <link rel="stylesheet" type="text/css" href="{gitiles.BASE_CSS_URL}" />
   <link rel="stylesheet" type="text/css" href="{gitiles.DOC_CSS_URL}" />
   <link rel="stylesheet" type="text/css" href="{gitiles.PRETTIFY_CSS_URL}" />
 </head>
-<body>
-  {if $siteTitle}
-    <div class="banner" role="banner">
-      <div class="nav-aux">
-        <h1>
-          {if $homeUrl}<a href="{$homeUrl}">{/if}
-          {if $logoUrl}<img src="{$logoUrl}" alt="project logo" />{/if}
-          {$siteTitle}
-          {if $homeUrl}</a>{/if}
-        </h1>
-        <h2>{$pageTitle}</h2>
+<body class="Site">
+  <header class="Site-header">
+    <div class="Header">
+      <div class="Header-title">
+        {if $homeUrl}<a href="{$homeUrl}">{/if}
+        {if $logoUrl}<img src="{$logoUrl}" alt="project logo" />{/if}
+        {if $siteTitle}{$siteTitle}{/if}
+        {if $homeUrl}</a>{/if}
       </div>
     </div>
-  {/if}
-  {if $navbarHtml}
-    <div class="nav" role="navigation">
-    <div class="nav-aux">
-      {$navbarHtml}
+    {if $navbarHtml}
+      <div class="nav" role="navigation">
+        <div class="nav-aux">
+          {$navbarHtml}
+        </div>
+      </div>
+    {/if}
+  </header>
+  <div class="Site-content Site-Content--markdown">
+    <div class="Container">
+      <div class="doc">
+        {$bodyHtml}
+      </div>
     </div>
-    </div>
-  {/if}
-  <div class="doc">
-    {$bodyHtml}
   </div>
-  <div class="footer-break"></div>
-  <div class="footer-line">
-    <div class="nav-aux">
-      <ul>
-      {if $sourceUrl}<li><a href="{$sourceUrl}">{msg desc="text for the source link"}source{/msg}</a></li>{/if}
-      {if $logUrl}<li><a href="{$logUrl}">{msg desc="text for the log link"}log{/msg}</a></li>{/if}
-      {if $blameUrl}<li><a href="{$blameUrl}">{msg desc="text for the blame link"}blame{/msg}</a></li>{/if}
+  <footer class="Site-footer">
+    <div class="Footer">
+      <div class="Footer-poweredBy">
+        Powered by <a href="https://code.google.com/p/gitiles/">Gitiles</a>
+      </div>
+      <div class="Footer-links">
+        {if $sourceUrl}<a class="Footer-link" href="{$sourceUrl}">{msg desc="text for the source link"}source{/msg}</a>{/if}
+        {if $logUrl}<a class="Footer-link" href="{$logUrl}">{msg desc="text for the log link"}log{/msg}</a>{/if}
+        {if $blameUrl}<a class="Footer-link" href="{$blameUrl}">{msg desc="text for the blame link"}blame{/msg}</a>{/if}
       </ul>
-      <div class="gitiles-att">
-      Powered by <a href="https://code.google.com/p/gitiles/">Gitiles</a>
-      </div>
+
     </div>
-  </div>
+  </footer>
   {if $analyticsId}
     /* From https://developers.google.com/analytics/devguides/collection/analyticsjs/ */
     <script>
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/HostIndex.soy b/gitiles-servlet/src/main/resources/com/google/gitiles/templates/HostIndex.soy
index ec9553d..7ac3581 100644
--- a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/HostIndex.soy
+++ b/gitiles-servlet/src/main/resources/com/google/gitiles/templates/HostIndex.soy
@@ -21,7 +21,6 @@
  * @param? headerVariant variant name for custom header.
  * @param? prefix prefix path for matching repositories.
  * @param? breadcrumbs map of breadcrumbs for header.
- * @param baseUrl base URL for repositories.
  * @param repositories list of repository description maps with name, cloneUrl,
  *     and optional description values.
  */
@@ -35,49 +34,32 @@
 
 {if length($repositories)}
   {if not $breadcrumbs}
-    <h2>
+    <h1>
       {msg desc="Git repositories available on the host"}
-        {$hostName} Git repositories
+        Git repositories on {$hostName}
       {/msg}
-    </h2>
-  {else}
-    <br />
+    </h1>
   {/if}
 
-  <div class="instructions">
-    {msg desc="description on how to use this repository"}
-    To clone one of these repositories, install{sp}
-    <a href="http://www.git-scm.com/">git</a>, and run:
-    <pre>git clone {$baseUrl}{$prefix}<em>name</em></pre>
-    {/msg}
-  </div>
-
-  <table class="list">
-    <tr class="no-hover">
-      <th width="25%">
+  <div class="RepoList">
+    <div class="RepoList-item RepoList-item--header">
+      <span class="RepoList-itemName">
         {msg desc="column header for repository name"}
           Name
         {/msg}
-      </th>
-      <th>
+      </span>
+      <span class="RepoList-itemDescription">
         {msg desc="column header for repository description"}
           Description
         {/msg}
-      </th>
-    </tr>
+      </span>
+    </div>
     {foreach $repo in $repositories}
-      <tr>
-        <td>
-          <a href="{$repo.url}">{$repo.name}</a>
-        </td>
-        <td>{$repo.description}</td>
-      </tr>
+      <a class="RepoList-item" href="{$repo.url}">
+        <span class="RepoList-itemName">{$repo.name}</span>
+        <span class="RepoList-itemDescription">{$repo.description}</span>
+      </a>
     {/foreach}
-  </table>
-  <div class="formats">
-    <a href="?format=TEXT">{msg desc="text format"}TXT{/msg}</a>
-    {sp}
-    <a href="?format=JSON">{msg desc="JSON format"}JSON{/msg}</a>
   </div>
 {/if}
 {call .footer /}
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/LogDetail.soy b/gitiles-servlet/src/main/resources/com/google/gitiles/templates/LogDetail.soy
index 6c4de74..b5f1e08 100644
--- a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/LogDetail.soy
+++ b/gitiles-servlet/src/main/resources/com/google/gitiles/templates/LogDetail.soy
@@ -42,31 +42,27 @@
 /**
  * Header for list of log entries.
  *
- * @param? pretty base "pretty" format for the log entry template.
  * @param? previousUrl URL for the previous page of results.
  */
 {template .logEntriesHeader}
 {if $previousUrl}
-  <div class="log-nav">
-    <a href="{$previousUrl}">{msg desc="text for previous URL"}&laquo; Previous{/msg}</a>
-  </div>
+  <nav class="LogNav">
+    <a class="LogNav-prev" href="{$previousUrl}">{msg desc="text for previous URL"}&laquo; Previous{/msg}</a>
+  </nav>
 {/if}
 
-<ol class="{$pretty ?: 'default'} log">
+<ol class="CommitLog">
 {/template}
 
 
 /**
  * Wrapper for a single log entry with pretty format and variant.
  *
- * @param firstWithPrevious whether this entry is the first in the current list,
- *     but also comes below a "Previous" link.
  * @param variant variant name for log entry template.
  * @param entry log entry; see .logEntry.
  */
 {template .logEntryWrapper}
-// TODO(dborowitz): Better CSS instead of this firstWithPrevious hack.
-<li{if $firstWithPrevious} class="first"{/if}>
+<li class="CommitLog-item CommitLog-item--{$variant}">
   {delcall gitiles.logEntry variant="$variant ?: 'default'" data="$entry" /}
 </li>
 {/template}
@@ -80,9 +76,9 @@
 {template .logEntriesFooter}
 </ol>
 {if $nextUrl}
-  <div class="log-nav">
-    <a href="{$nextUrl}">{msg desc="text for next URL"}Next &raquo;{/msg}</a>
-  </div>
+  <nav class="LogNav">
+    <a class="LogNav-next" href="{$nextUrl}">{msg desc="text for next URL"}Next &raquo;{/msg}</a>
+  </nav>
 {/if}
 {/template}
 
@@ -91,7 +87,7 @@
  * Single log entry indicating the full log is empty.
  */
 {template .emptyLog}
-<li class="empty">{msg desc="informational text for when the log is empty"}No commits.{/msg}</p>
+<li class="CommitLog-item CommitLog-item--empty">{msg desc="informational text for when the log is empty"}No commits.{/msg}</p>
 {/template}
 
 
@@ -112,25 +108,21 @@
  * @param diffTree unused in this variant.
  */
 {deltemplate gitiles.logEntry variant="'oneline'"}
-<a href="{$url}">
-  <span class="sha1">{$abbrevSha}</span>
-  // nbsp instad of CSS padding/margin because those cause a break in the
-  // underline.
-  &nbsp;
-  {sp}<span>{$shortMessage}</span>
-</a>
-{sp}<span class="author" title="{$author.email}">{msg desc="commit author name"}by {$author.name}{/msg}</span>
-{sp}<span class="time" title="{$author.time}">- {$author.relativeTime}</span>
+<a class="u-sha1 CommitLog-sha1" href="{$url}">{$abbrevSha}</a>
+{sp}<a href="{$url}">{$shortMessage}</a>
+{sp}<span class="CommitLog-author" title="{$author.email}">{msg desc="commit author name"}by {$author.name}{/msg}</span>
+{sp}<span class="CommitLog-time" title="{$author.time}">· {$author.relativeTime}</span>
 {if length($branches)}
   {foreach $branch in $branches}
-    {sp}<a href="{$branch.url}" class="branch-label">{$branch.name}</a>
+    {sp}<a class="CommitLog-branchLabel" href="{$branch.url}">{$branch.name}</a>
   {/foreach}
 {/if}
 {if length($tags)}
   {foreach $tag in $tags}
-    {sp}<a href="{$tag.url}" class="tag-label">{$tag.name}</a>
+    {sp}<a class="CommitLog-tagLabel" href="{$tag.url}">{$tag.name}</a>
   {/foreach}
 {/if}
+
 {/deltemplate}
 
 
@@ -172,10 +164,10 @@
  * @param diffTree unused in this variant.
  */
 {deltemplate gitiles.logEntry variant="'full'"}
-<div class="git-commit">
+<div class="Metadata">
 <table>
   <tr>
-    <th>{msg desc="Header for commit SHA entry"}commit{/msg}</th>
+    <th class="Metadata-title">{msg desc="Header for commit SHA entry"}commit{/msg}</th>
     <td class="sha1">
       <a href="{$url}">{$sha}</a>
     </td>
@@ -195,18 +187,18 @@
     </td>
   </tr>
   <tr>
-    <th>{msg desc="Header for commit author"}author{/msg}</th>
+    <th class="Metadata-title">{msg desc="Header for commit author"}author{/msg}</th>
     <td>{call .person_ data="$author" /}</td>
     <td>{$author.time}</td>
   </tr>
   <tr>
-    <th>{msg desc="Header for committer"}committer{/msg}</th>
+    <th class="Metadata-title">{msg desc="Header for committer"}committer{/msg}</th>
     <td>{call .person_ data="$committer" /}</td>
     <td>{$committer.time}</td>
   </tr>
 </table>
 </div>
-<pre class="commit-message">
+<pre class="MetadataMessage">
   {$message}
 </pre>
 {/deltemplate}
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/ObjectDetail.soy b/gitiles-servlet/src/main/resources/com/google/gitiles/templates/ObjectDetail.soy
index 6c87498..242f14b 100644
--- a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/ObjectDetail.soy
+++ b/gitiles-servlet/src/main/resources/com/google/gitiles/templates/ObjectDetail.soy
@@ -41,39 +41,40 @@
  * @param archiveType type of the archive to download.
  */
 {template .commitDetail}
-<div class="git-commit">
+<div class="Metadata">
   <table>
     <tr>
-      <th>{msg desc="Header for commit SHA entry"}commit{/msg}</th>
-      <td class="sha">
+      <th class="Metadata-title">{msg desc="Header for commit SHA entry"}commit{/msg}</th>
+      <td>
         {$sha}
-        <span class="log-link">
+      </td>
+      <td>
+        <span>
           [<a href="{$logUrl}">{msg desc="text for the log link"}log{/msg}</a>]
         </span>
-        <span class="download-link">[<a href="{$archiveUrl}">{$archiveType}</a>]</span>
+        {sp}<span>[<a href="{$archiveUrl}">{$archiveType}</a>]</span>
       </td>
-      <td>{sp}</td>
     </tr>
     <tr>
-      <th>{msg desc="Header for commit author"}author{/msg}</th>
+      <th class="Metadata-title">{msg desc="Header for commit author"}author{/msg}</th>
       <td>{call .person_ data="$author" /}</td>
       <td>{$author.time}</td>
     </tr>
     <tr>
-      <th>{msg desc="Header for committer"}committer{/msg}</th>
+      <th class="Metadata-title">{msg desc="Header for committer"}committer{/msg}</th>
       <td>{call .person_ data="$committer" /}</td>
       <td>{$committer.time}</td>
     </tr>
     <tr>
-      <th>{msg desc="Header for tree SHA entry"}tree{/msg}</th>
-      <td class="sha"><a href="{$treeUrl}">{$tree}</a></td>
+      <th class="Metadata-title">{msg desc="Header for tree SHA entry"}tree{/msg}</th>
+      <td><a href="{$treeUrl}">{$tree}</a></td>
     </tr>
     {foreach $parent in $parents}
       <tr>
-        <th>{msg desc="Header for parent SHA"}parent{/msg}</th>
+        <th class="Metadata-title">{msg desc="Header for parent SHA"}parent{/msg}</th>
         <td>
           <a href="{$parent.url}">{$parent.sha}</a>
-          <span class="diff-link">
+          {sp}<span>
             [<a href="{$parent.diffUrl}">{msg desc="text for the parent diff link"}diff{/msg}</a>]
             {if isNonnull($parent.blameUrl)}
               {sp}[<a href="{$parent.blameUrl}">{msg desc="text for the parent blame link"}blame{/msg}</a>]
@@ -85,42 +86,42 @@
   </table>
 </div>
 {call .message_}
-  {param className: 'commit-message' /}
+  {param className: 'u-pre MetadataMessage' /}
   {param message: $message /}
 {/call}
 
 {if $diffTree and length($diffTree)}
-  <ul class="diff-tree">
+  <ul class="DiffTree">
     {foreach $entry in $diffTree}
       <li>
         <a href="{$entry.url}">{$entry.path}</a>
         {switch $entry.changeType}
           {case 'ADD'}
-            <span class="add">
+            <span class="DiffTree-action DiffTree-action--add">
               {msg desc="Text for a new tree entry"}
                 [Added - <a href="{$entry.diffUrl}">diff</a>]
               {/msg}
             </span>
           {case 'MODIFY'}
-            <span class="modify">
+            <span class="DiffTree-action DiffTree-action--modify">
               {msg desc="Text for a modified tree entry"}
                 [<a href="{$entry.diffUrl}">diff</a>]
               {/msg}
             </span>
           {case 'DELETE'}
-            <span class="delete">
+            <span class="DiffTree-action DiffTree-action--delete">
               {msg desc="Text for a deleted tree entry"}
                 [Deleted - <a href="{$entry.diffUrl}">diff</a>]
               {/msg}
             </span>
           {case 'RENAME'}
-            <span class="rename">
+            <span class="DiffTree-action DiffTree-action--rename">
               {msg desc="Text for a renamed tree entry"}
                 [Renamed from {$entry.oldPath} - <a href="{$entry.diffUrl}">diff</a>]
               {/msg}
             </span>
           {case 'COPY'}
-            <span class="copy">
+            <span class="DiffTree-action DiffTree-action--copy">
               {msg desc="Text for a copied tree entry"}
                 [Copied from {$entry.oldPath} - <a href="{$entry.diffUrl}">diff</a>]
               {/msg}
@@ -130,7 +131,7 @@
       </li>
     {/foreach}
   </ul>
-  <div class="diff-summary">
+  <div class="DiffSummary">
     {if length($diffTree) == 1}
       {msg desc="1 file changed"}1 file changed{/msg}
     {else}
@@ -160,59 +161,63 @@
  * @param? readmeHtml optional rendered README.md contents.
  */
 {template .treeDetail}
-<div class="sha1">
-  {msg desc="SHA-1 for the path's tree"}tree: {$sha}{/msg}
-  {if $logUrl}{sp}[<a href="{$logUrl}">{msg desc="history for a path"}path history{/msg}</a>]{/if}
-  {if $archiveUrl}
-    <span class="download-link">[<a href="{$archiveUrl}">{$archiveType}</a>]</span>
+<div class="TreeDetail">
+  <div class="u-sha1 TreeDetail-sha1">
+    {msg desc="SHA-1 for the path's tree"}tree: {$sha}{/msg}
+    {if $logUrl}{sp}[<a href="{$logUrl}">{msg desc="history for a path"}path history{/msg}</a>]{/if}
+    {if $archiveUrl}
+      {sp}<span>[<a href="{$archiveUrl}">{$archiveType}</a>]</span>
+    {/if}
+  </div>
+
+  {if length($entries)}
+    <ol class="FileList">
+      {foreach $entry in $entries}
+        <li class="FileList-item{sp}
+              {switch $entry.type}
+                {case 'TREE'}FileList-item--gitTree
+                {case 'SYMLINK'}FileList-item--symlink
+                {case 'REGULAR_FILE'}FileList-item--regularFile
+                {case 'EXECUTABLE_FILE'}FileList-item--executableFile
+                {case 'GITLINK'}gitlink
+                {default}regular-file
+              {/switch}
+              " title="
+              {switch $entry.type}
+                {case 'TREE'}{msg desc="Alt text for tree icon"}Tree{/msg}
+                {case 'SYMLINK'}{msg desc="Alt text for symlink icon"}Symlink{/msg}
+                {case 'REGULAR_FILE'}{msg desc="Alt text for regular file icon"}Regular file{/msg}
+                {case 'EXECUTABLE_FILE'}
+                  {msg desc="Alt text for executable file icon"}Executable file{/msg}
+                {case 'GITLINK'}
+                  {msg desc="Alt text for git submodule link icon"}Git submodule link{/msg}
+                {default}{msg desc="Alt text for other file icon"}Other{/msg}
+              {/switch}
+              {sp}- {$entry.name}">
+          <a class="FileList-itemLink" href="{$entry.url}">{$entry.name}</a>
+          {if $entry.type == 'SYMLINK'}
+            {sp}&#x21e8;{sp}
+            {if $entry.targetUrl}
+              <a href="{$entry.targetUrl}">{$entry.targetName}</a>
+            {else}
+              {$entry.targetName}
+            {/if}
+          {/if}
+          // TODO(dborowitz): Something reasonable for gitlinks.
+        </li>
+      {/foreach}
+    </ol>
+  {else}
+    <p>{msg desc="Informational text for when a tree is empty"}This tree is empty.{/msg}</p>
+  {/if}
+
+  {if $readmeHtml}
+    <div class="InlineReadme">
+      <div class="InlineReadme-path">{$readmePath}</div>
+      <div class="doc">{$readmeHtml}</div>
+    </div>
   {/if}
 </div>
-
-{if length($entries)}
-  <ol class="list files">
-    {foreach $entry in $entries}
-      <li class="
-            {switch $entry.type}
-              {case 'TREE'}git-tree
-              {case 'SYMLINK'}symlink
-              {case 'REGULAR_FILE'}regular-file
-              {case 'EXECUTABLE_FILE'}executable-file
-              {case 'GITLINK'}gitlink
-              {default}regular-file
-            {/switch}
-            " title="
-            {switch $entry.type}
-              {case 'TREE'}{msg desc="Alt text for tree icon"}Tree{/msg}
-              {case 'SYMLINK'}{msg desc="Alt text for symlink icon"}Symlink{/msg}
-              {case 'REGULAR_FILE'}{msg desc="Alt text for regular file icon"}Regular file{/msg}
-              {case 'EXECUTABLE_FILE'}
-                {msg desc="Alt text for executable file icon"}Executable file{/msg}
-              {case 'GITLINK'}
-                {msg desc="Alt text for git submodule link icon"}Git submodule link{/msg}
-              {default}{msg desc="Alt text for other file icon"}Other{/msg}
-            {/switch}
-            - {$entry.name}">
-        <a href="{$entry.url}">{$entry.name}</a>
-        {if $entry.type == 'SYMLINK'}
-          {sp}&#x21e8;{sp}
-          {if $entry.targetUrl}
-            <a href="{$entry.targetUrl}">{$entry.targetName}</a>
-          {else}
-            {$entry.targetName}
-          {/if}
-        {/if}
-        // TODO(dborowitz): Something reasonable for gitlinks.
-      </li>
-    {/foreach}
-  </ol>
-{else}
-  <p>{msg desc="Informational text for when a tree is empty"}This tree is empty.{/msg}</p>
-{/if}
-
-{if $readmeHtml}
-  <div class="readme-path">{$readmePath}</div>
-  <div class="doc">{$readmeHtml}</div>
-{/if}
 {/template}
 
 /**
@@ -225,7 +230,7 @@
  * @param? docUrl optional URL to view rendered file.
  */
 {template .blobHeader}
-<div class="sha1">
+<div class="u-sha1 BlobSha1">
   {msg desc="SHA-1 for the file's blob"}blob: {$sha}{/msg}
   {if $fileUrl}{sp}[<a href="{$fileUrl}">{msg desc="detail view of a file"}file{/msg}</a>]{/if}
   {if $logUrl}{sp}[<a href="{$logUrl}">{msg desc="history for a file"}log{/msg}</a>]{/if}
@@ -250,21 +255,26 @@
 
   {if $lines != null}
     {if $lines}
-      <ol class="prettyprint">
+      <table class="FileContents">
         {foreach $line in $lines}
-          <li>
-            <a name="{index($line) + 1}"></a>
-            {foreach $span in $line}
-              <span class="{$span.classes}">{$span.text}</span>
-            {/foreach}
-          </li>
+          {let $n: index($line) + 1 /}
+          <tr class="u-pre FileContents-line">
+            <td class="u-lineNum u-noSelect FileContents-lineNum"
+                data-line-number="{$n}" onclick="window.location.hash='#{$n}'"></td>
+            <td class="FileContents-lineContents">
+              <a name="{$n}"></a>
+              {foreach $span in $line}
+                <span class="{$span.classes}">{$span.text}</span>
+              {/foreach}
+            </td>
+          </tr>
         {/foreach}
-      </ol>
+      </table>
     {else}
-      <div class="file-empty">Empty file</div>
+      <div class="FileContents-empty">Empty file</div>
     {/if}
   {else}
-    <div class="file-binary">
+    <div class="FileContents-binary">
       {msg desc="size of binary file in bytes"}{$size}-byte binary file{/msg}
     </div>
   {/if}
@@ -280,22 +290,22 @@
  * @param message tag message.
  */
 {template .tagDetail}
-<div class="git-tag">
+<div class="Metadata">
   <table>
     <tr>
-      <th>{msg desc="Header for tag SHA entry"}tag{/msg}</th>
+      <th class="Metadata-title">{msg desc="Header for tag SHA entry"}tag{/msg}</th>
       <td class="sha">{$sha}</td>
       <td>{sp}</td>
     </tr>
     {if $tagger}
       <tr>
-        <th>{msg desc="Header for tagger"}tagger{/msg}</th>
+        <th class="Metadata-title">{msg desc="Header for tagger"}tagger{/msg}</th>
         <td>{call .person_ data="$tagger" /}</td>
         <td>{$tagger.time}</td>
       </tr>
     {/if}
     <tr>
-      <th>{msg desc="Header for tagged object SHA"}object{/msg}</th>
+      <th class="Metadata-title">{msg desc="Header for tagged object SHA"}object{/msg}</th>
       <td class="sha">{$object}</td>
       <td>{sp}</td>
     </tr>
@@ -303,7 +313,7 @@
 </div>
 {if $message and length($message)}
   {call .message_}
-    {param className: 'tag-message' /}
+    {param className: 'u-pre MetadataMessage' /}
     {param message: $message /}
   {/call}
 {/if}
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/RefList.soy b/gitiles-servlet/src/main/resources/com/google/gitiles/templates/RefList.soy
index 57b1111..74f89d0 100644
--- a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/RefList.soy
+++ b/gitiles-servlet/src/main/resources/com/google/gitiles/templates/RefList.soy
@@ -33,23 +33,21 @@
   {param breadcrumbs: $breadcrumbs /}
 {/call}
 
-{if length($branches)}
-  <div class="refs-branches refs-detail">
+<div class="Refs">
+  {if length($branches)}
     {call .refList}
       {param type: 'Branches' /}
       {param refs: $branches /}
     {/call}
-  </div>
-{/if}
+  {/if}
 
-{if length($tags)}
-  <div class="refs-tags refs-detail">
+  {if length($tags)}
     {call .refList}
       {param type: 'Tags' /}
       {param refs: $tags /}
     {/call}
-  </div>
-{/if}
+  {/if}
+</div>
 
 {call .footer /}
 {/template}
@@ -61,10 +59,12 @@
  * @param refs list of branch objects with url, name, and optional isHead keys.
  */
 {template .refList}
-  <h3>{$type}</h3>
-  <ul class="ref-list">
-  {foreach $ref in $refs}
-    <li{if $ref.isHead} class="head-ref"{/if}><a href="{$ref.url}">{$ref.name}</a></li>
-  {/foreach}
-  </ul>
+  <div class="RefList">
+    <h3 class="RefList-title">{$type}</h3>
+    <ul class="RefList-items">
+    {foreach $ref in $refs}
+      <li class="RefList-item"><a href="{$ref.url}">{$ref.name}</a></li>
+    {/foreach}
+    </ul>
+  </div>
 {/template}
diff --git a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/RepositoryIndex.soy b/gitiles-servlet/src/main/resources/com/google/gitiles/templates/RepositoryIndex.soy
index 17b0053..787c15f 100644
--- a/gitiles-servlet/src/main/resources/com/google/gitiles/templates/RepositoryIndex.soy
+++ b/gitiles-servlet/src/main/resources/com/google/gitiles/templates/RepositoryIndex.soy
@@ -50,39 +50,39 @@
   {/call}
 {/if}
 
-{if $description or $mirroredFromUrl}
-  <div class="repository-description">
-  {$description}
-  {if $mirroredFromUrl}
-    <div class="repository-mirrored-from">
+{if $description}
+  <h2 class="RepoDescription">{$description}</h2>
+{/if}
+
+{if $mirroredFromUrl}
+  <div class="RepoMirroredFrom">
     {msg desc="Informational text describing source of repository"}
-    mirrored from {$mirroredFromUrl}
+      Mirrored from <a href="{$mirroredFromUrl}">{$mirroredFromUrl}</a>
     {/msg}
-    </div>
-  {/if}
   </div>
 {/if}
 
-<textarea rows="1" cols="150" class="clone-line"
-  onclick="this.focus();this.select();"
-  readonly="readonly">
-    git clone {$cloneUrl}
-</textarea>
+<div class="CloneRepo">
+  <div class="CloneRepo-title">Clone this repo:</div>
+  <input type="text" class="CloneRepo-command"
+         onclick="this.focus();this.select();"
+         readonly="readonly" value="git clone {$cloneUrl}">
+</div>
 
 {if $hasLog and (length($branches) or length($tags))}
-  <div class="repository-shortlog-wrapper">
-    <div class="repository-shortlog">
-      {call .streamingPlaceholder /}
+  <div class="RepoShortlog">
+    <div class="RepoShortlog-refs">
+      {call .branches_ data="all" /}
+      {call .tags_ data="all" /}
     </div>
-    {if $readmeHtml}
-      <div class="doc repository-index-doc">{$readmeHtml}</div>
-    {/if}
+    <div class="RepoShortlog-log">
+      {call .streamingPlaceholder /}
+      {if $readmeHtml}
+        <div class="doc RepoIndexDoc">{$readmeHtml}</div>
+      {/if}
+    </div>
   </div>
 
-  <div class="repository-refs">
-    {call .branches_ data="all" /}
-    {call .tags_ data="all" /}
-  </div>
 {elseif $hasLog}
   {call .streamingPlaceholder /}
 {elseif length($branches) or length($tags)}