Make metadata tables responsive

In commit 9b8a1eb9ea3a6945c82411ef6742637f11b6056f we made Gitiles
responsive so that it looked better in small screens. However, metadata
tables weren't made responsive due to some accessibility challenges.

This CL finishes the responsiveness refactor by also making metadata
tables responsive. We achieve this by changing the HTML table with a
description list styled with a grid layout and subgrids[1] that adapt to
the screen width.

We use description lists since they are more semantically accurate for
key-value metadata pairs than tables.[2]

The linked bug contains screenshots that show the change.

[1]: Subgrids achieved the Baseline status in 2023:
     https://web.dev/articles/css-subgrid.
[2]: https://html.spec.whatwg.org/multipage/grouping-content.html#the-dl-element

Bug: https://github.com/google/gitiles/issues/235
Change-Id: I83026d0fbe7df7601a07be5e6122cdbb2d27ec81
diff --git a/javatests/com/google/gitiles/LogServletTest.java b/javatests/com/google/gitiles/LogServletTest.java
index 0072e9c..3357470 100644
--- a/javatests/com/google/gitiles/LogServletTest.java
+++ b/javatests/com/google/gitiles/LogServletTest.java
@@ -37,9 +37,9 @@
 public class LogServletTest extends ServletTest {
   private static final TypeToken<Log> LOG = new TypeToken<Log>() {};
   private static final String MAIN = "main";
-  private static final String AUTHOR_METADATA_ELEMENT = "<th class=\"Metadata-title\">author</th>";
+  private static final String AUTHOR_METADATA_ELEMENT = "<dt class=\"Metadata-title\">author</dt>";
   private static final String COMMITTER_METADATA_ELEMENT =
-      "<th class=\"Metadata-title\">committer</th>";
+      "<dt class=\"Metadata-title\">committer</dt>";
 
   @Test
   public void basicLog() throws Exception {
diff --git a/resources/com/google/gitiles/static/base.css b/resources/com/google/gitiles/static/base.css
index f4ef52a..7653f84 100644
--- a/resources/com/google/gitiles/static/base.css
+++ b/resources/com/google/gitiles/static/base.css
@@ -374,11 +374,29 @@
 .Metadata {
   margin-bottom: 15px;
 }
+.Metadata-descriptionList {
+  display: grid;
+  grid-template-columns: max-content minmax(auto, max-content) auto;
+  gap: 2px 12px;
+}
+.Metadata-row {
+  grid-column: 1 / -1;
+  display: grid;
+  grid-template-columns: subgrid;
+}
 .Metadata-title {
+  grid-column: 1;
   font-weight: bold;
-  padding-right: 10px;
   text-align: right;
 }
+.Metadata-description {
+  grid-column: 2 / -1;
+  display: grid;
+  grid-template-columns: subgrid;
+}
+.Metadata-descriptionCell {
+  grid-column: auto;
+}
 .MetadataMessage {
   background-color: #fafafa;
   border: 1px solid #ccc;
@@ -485,6 +503,15 @@
   color: #666;
 }
 
+@media (max-width: 700px) {
+  .Metadata-descriptionList {
+    grid-template-columns: max-content auto;
+  }
+  .Metadata-descriptionCell {
+    grid-column: 2;
+  }
+}
+
 /* BlameDetail.soy */
 
 .Blame {
diff --git a/resources/com/google/gitiles/templates/LogDetail.soy b/resources/com/google/gitiles/templates/LogDetail.soy
index b82b2a4..05fc37c 100644
--- a/resources/com/google/gitiles/templates/LogDetail.soy
+++ b/resources/com/google/gitiles/templates/LogDetail.soy
@@ -254,62 +254,63 @@
       score: the similarity score of the rename or copy.
       */
 <div class="u-monospace Metadata">
-<table>
-  <tr>
-    <th class="Metadata-title">{msg desc="Header for commit SHA entry"}commit{/msg}</th>
-    <td class="sha1">
-      <a href="{$url}">{$sha}</a>
-    </td>
-    <td>
-      {if length($branches)}
-        {for $branch in $branches}
-          {sp}<a href="{$branch.url}" class="branch-label">{$branch.name}</a>
-        {/for}
-      {/if}
-      {if length($tags)}
-        {for $tag in $tags}
-          {sp}<a href="{$tag.url}" class="tag-label">{$tag.name}</a>
-        {/for}
-      {else}
-        {sp}
-      {/if}
-    </td>
-  </tr>
-  <tr>
-    <th class="Metadata-title">{msg desc="Header for commit author"}author{/msg}</th>
-    <td>
-      {call objDetail.person_ data="$author" /}
-    </td>
-    <td>{$author.time}</td>
-  </tr>
-  <tr>
-    <th class="Metadata-title">{msg desc="Header for committer"}committer{/msg}</th>
-    <td>
-      {call objDetail.person_ data="$committer" /}
-    </td>
-    <td>{$committer.time}</td>
-  </tr>
-  {if $rename}
-    <tr>
-      <td colspan="3">
-        <span class="CommitLog-rename">
-          [
-          {switch $rename.changeType}
-            {case 'RENAME'}
-              Renamed
-            {case 'COPY'}
-              Copied
-          {/switch}
-          {if $rename.score != 100}
-            {sp}({$rename.score}%)
-          {/if}
-          {sp}from {$rename.oldPath}]
-        </span>
-      </td>
-    </tr>
-  {/if}
-
-</table>
+<dl class="Metadata-descriptionList">
+  <div class="Metadata-row">
+    <dt class="Metadata-title">{msg desc="Header for commit SHA entry"}commit{/msg}</dt>
+    <dd class="Metadata-description">
+      <div class="sha1 Metadata-descriptionCell">
+        <a href="{$url}">{$sha}</a>
+      </div>
+      <div class="Metadata-descriptionCell">
+        {if length($branches)}
+          {for $branch in $branches}
+            {sp}<a href="{$branch.url}" class="branch-label">{$branch.name}</a>
+          {/for}
+        {/if}
+        {if length($tags)}
+          {for $tag in $tags}
+            {sp}<a href="{$tag.url}" class="tag-label">{$tag.name}</a>
+          {/for}
+        {else}
+          {sp}
+        {/if}
+      </div>
+    </dd>
+  </div>
+  <div class="Metadata-row">
+    <dt class="Metadata-title">{msg desc="Header for commit author"}author{/msg}</dt>
+    <dd class="Metadata-description">
+      <div class="Metadata-descriptionCell">
+        {call objDetail.person_ data="$author" /}
+      </div>
+      <div class="Metadata-descriptionCell">{$author.time}</div>
+    </dd>
+  </div>
+  <div class="Metadata-row">
+    <dt class="Metadata-title">{msg desc="Header for committer"}committer{/msg}</dt>
+    <dd class="Metadata-description">
+      <div class="Metadata-descriptionCell">
+        {call objDetail.person_ data="$committer" /}
+      </div>
+      <div class="Metadata-descriptionCell">{$committer.time}</div>
+    </dd>
+  </div>
+</dl>
+{if $rename}
+  <span class="CommitLog-rename">
+    [
+    {switch $rename.changeType}
+      {case 'RENAME'}
+        Renamed
+      {case 'COPY'}
+        Copied
+    {/switch}
+    {if $rename.score != 100}
+      {sp}({$rename.score}%)
+    {/if}
+    {sp}from {$rename.oldPath}]
+  </span>
+{/if}
 </div>
 <pre class="u-pre u-monospace MetadataMessage">
   {$message}
diff --git a/resources/com/google/gitiles/templates/ObjectDetail.soy b/resources/com/google/gitiles/templates/ObjectDetail.soy
index f7c0b0c..4fc83d8 100644
--- a/resources/com/google/gitiles/templates/ObjectDetail.soy
+++ b/resources/com/google/gitiles/templates/ObjectDetail.soy
@@ -44,52 +44,68 @@
   {@param archiveUrl: ?}  /** URL to a download link of this commit as an archive. */
   {@param archiveType: ?}  /** type of the archive to download. */
 <div class="u-monospace Metadata">
-  <table>
-    <tr>
-      <th class="Metadata-title">{msg desc="Header for commit SHA entry"}commit{/msg}</th>
-      <td>
-        {$sha}
-      </td>
-      <td>
-        <span>
-          [<a href="{$logUrl}">{msg desc="text for the log link"}log{/msg}</a>]
-        </span>
-        {sp}<span>[<a href="{$archiveUrl}">{$archiveType}</a>]</span>
-      </td>
-    </tr>
-    <tr>
-      <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 class="Metadata-title">{msg desc="Header for committer"}committer{/msg}</th>
-      <td>
-        {call person_ data="$committer" /}
-      </td>
-      <td>{$committer.time}</td>
-    </tr>
-    <tr>
-      <th class="Metadata-title">{msg desc="Header for tree SHA entry"}tree{/msg}</th>
-      <td><a href="{$treeUrl}">{$tree}</a></td>
-    </tr>
-    {for $parent in $parents}
-      <tr>
-        <th class="Metadata-title">{msg desc="Header for parent SHA"}parent{/msg}</th>
-        <td>
-          <a href="{$parent.url}">{$parent.sha}</a>
-          {sp}<span>
-            [<a href="{$parent.diffUrl}">{msg desc="text for the parent diff link"}diff{/msg}</a>]
-            {if $parent.blameUrl != null}
-              {sp}[<a href="{$parent.blameUrl}">{msg desc="text for the parent blame link"}blame{/msg}</a>]
-            {/if}
+  <dl class="Metadata-descriptionList">
+    <div class="Metadata-row">
+      <dt class="Metadata-title">{msg desc="Header for commit SHA entry"}commit{/msg}</dt>
+      <dd class="Metadata-description">
+        <div class="Metadata-descriptionCell">
+          {$sha}
+        </div>
+        <div class="Metadata-descriptionCell">
+          <span>
+            [<a href="{$logUrl}">{msg desc="text for the log link"}log{/msg}</a>]
           </span>
-        </td>
-      </tr>
+          {sp}<span>[<a href="{$archiveUrl}">{$archiveType}</a>]</span>
+        </div>
+      </dd>
+    </div>
+    <div class="Metadata-row">
+      <dt class="Metadata-title">{msg desc="Header for commit author"}author{/msg}</dt>
+      <dd class="Metadata-description">
+        <div class="Metadata-descriptionCell">
+          {call person_ data="$author" /}
+        </div>
+        <div class="Metadata-descriptionCell">
+          {$author.time}
+        </div>
+      </dd>
+    </div>
+    <div class="Metadata-row">
+      <dt class="Metadata-title">{msg desc="Header for committer"}committer{/msg}</dt>
+      <dd class="Metadata-description">
+        <div class="Metadata-descriptionCell">
+          {call person_ data="$committer" /}
+        </div>
+        <div class="Metadata-descriptionCell">
+          {$committer.time}
+        </div>
+      </dd>
+    </div>
+    <div class="Metadata-row">
+      <dt class="Metadata-title">{msg desc="Header for tree SHA entry"}tree{/msg}</dt>
+      <dd class="Metadata-description">
+        <div class="Metadata-descriptionCell">
+          <a href="{$treeUrl}">{$tree}</a>
+        </div>
+      </dd>
+    </div>
+    {for $parent in $parents}
+      <div class="Metadata-row">
+        <dt class="Metadata-title">{msg desc="Header for parent SHA"}parent{/msg}</dt>
+        <dd class="Metadata-description">
+          <div class="Metadata-descriptionCell">
+            <a href="{$parent.url}">{$parent.sha}</a>
+            {sp}<span>
+              [<a href="{$parent.diffUrl}">{msg desc="text for the parent diff link"}diff{/msg}</a>]
+              {if $parent.blameUrl != null}
+                {sp}[<a href="{$parent.blameUrl}">{msg desc="text for the parent blame link"}blame{/msg}</a>]
+              {/if}
+            </span>
+          </div>
+        </dd>
+      </div>
     {/for}
-  </table>
+  </dl>
 </div>
 {call message_}
   {param className: 'u-pre u-monospace MetadataMessage' /}
@@ -313,27 +329,33 @@
   {@param object: ?}  /** SHA of the object this tag points to. */
   {@param message: ?}  /** tag message. */
 <div class="u-monospace Metadata">
-  <table>
-    <tr>
-      <th class="Metadata-title">{msg desc="Header for tag SHA entry"}tag{/msg}</th>
-      <td class="sha">{$sha}</td>
-      <td>{sp}</td>
-    </tr>
+  <dl class="Metadata-descriptionList">
+    <div class="Metadata-row">
+      <dt class="Metadata-title">{msg desc="Header for tag SHA entry"}tag{/msg}</dt>
+      <dd class="Metadata-description">
+        <div class="sha Metadata-descriptionCell">{$sha}</div>
+        <div class="Metadata-descriptionCell">{sp}</div>
+      </dd>
+    </div>
     {if $tagger}
-      <tr>
-        <th class="Metadata-title">{msg desc="Header for tagger"}tagger{/msg}</th>
-        <td>
-          {call person_ data="$tagger" /}
-        </td>
-        <td>{$tagger.time}</td>
-      </tr>
+      <div class="Metadata-row">
+        <dt class="Metadata-title">{msg desc="Header for tagger"}tagger{/msg}</dt>
+        <dd class="Metadata-description">
+          <div class="Metadata-descriptionCell">
+            {call person_ data="$tagger" /}
+          </div>
+          <div class="Metadata-descriptionCell">{$tagger.time}</div>
+        </dd>
+      </div>
     {/if}
-    <tr>
-      <th class="Metadata-title">{msg desc="Header for tagged object SHA"}object{/msg}</th>
-      <td class="sha">{$object}</td>
-      <td>{sp}</td>
-    </tr>
-  </table>
+    <div class="Metadata-row">
+      <dt class="Metadata-title">{msg desc="Header for tagged object SHA"}object{/msg}</dt>
+      <dd class="Metadata-description">
+        <div class="sha Metadata-descriptionCell">{$object}</div>
+        <div class="Metadata-descriptionCell">{sp}</div>
+      </dd>
+    </div>
+  </dl>
 </div>
 {if $message && length($message)}
   {call message_}