diff --git a/modules/templates/helper.go b/modules/templates/helper.go
index e1c5d5d86..4e5c96cd0 100644
--- a/modules/templates/helper.go
+++ b/modules/templates/helper.go
@@ -256,31 +256,27 @@ func NewFuncMap() []template.FuncMap {
 		"DefaultTheme": func() string {
 			return setting.UI.DefaultTheme
 		},
+		// pass key-value pairs to a partial template which receives them as a dict
 		"dict": func(values ...interface{}) (map[string]interface{}, error) {
 			if len(values) == 0 {
 				return nil, errors.New("invalid dict call")
 			}
 
 			dict := make(map[string]interface{})
-
-			for i := 0; i < len(values); i++ {
-				switch key := values[i].(type) {
-				case string:
-					i++
-					if i == len(values) {
-						return nil, errors.New("specify the key for non array values")
-					}
-					dict[key] = values[i]
-				case map[string]interface{}:
-					m := values[i].(map[string]interface{})
-					for i, v := range m {
-						dict[i] = v
-					}
-				default:
-					return nil, errors.New("dict values must be maps")
-				}
+			return util.MergeInto(dict, values...)
+		},
+		/* like dict but merge key-value pairs into the first dict and return it */
+		"mergeinto": func(root map[string]interface{}, values ...interface{}) (map[string]interface{}, error) {
+			if len(values) == 0 {
+				return nil, errors.New("invalid mergeinto call")
 			}
-			return dict, nil
+
+			dict := make(map[string]interface{})
+			for key, value := range root {
+				dict[key] = value
+			}
+
+			return util.MergeInto(dict, values...)
 		},
 		"percentage": func(n int, values ...int) float32 {
 			var sum = 0
diff --git a/modules/util/util.go b/modules/util/util.go
index 6d02b5f52..9de1710ac 100644
--- a/modules/util/util.go
+++ b/modules/util/util.go
@@ -6,6 +6,7 @@ package util
 
 import (
 	"bytes"
+	"errors"
 	"strings"
 )
 
@@ -100,3 +101,26 @@ func NormalizeEOL(input []byte) []byte {
 	}
 	return tmp[:pos]
 }
+
+// MergeInto merges pairs of values into a "dict"
+func MergeInto(dict map[string]interface{}, values ...interface{}) (map[string]interface{}, error) {
+	for i := 0; i < len(values); i++ {
+		switch key := values[i].(type) {
+		case string:
+			i++
+			if i == len(values) {
+				return nil, errors.New("specify the key for non array values")
+			}
+			dict[key] = values[i]
+		case map[string]interface{}:
+			m := values[i].(map[string]interface{})
+			for i, v := range m {
+				dict[i] = v
+			}
+		default:
+			return nil, errors.New("dict values must be maps")
+		}
+	}
+
+	return dict, nil
+}
diff --git a/templates/repo/issue/list.tmpl b/templates/repo/issue/list.tmpl
index 78223ce56..49adcd08b 100644
--- a/templates/repo/issue/list.tmpl
+++ b/templates/repo/issue/list.tmpl
@@ -200,106 +200,7 @@
 				
 			
 		
-
-		
-			{{ $approvalCounts := .ApprovalCounts}}
-			{{range .Issues}}
-				
-					{{if $.CanWriteIssuesOrPulls}}
-					
-						 
-					
-					{{end}}
-					#{{.Index}}
-					{{RenderEmoji .Title}} 
-
-					{{if .IsPull }}
-						{{if (index $.CommitStatus .PullRequest.ID)}}
-							{{template "repo/commit_status" (index $.CommitStatus .PullRequest.ID)}}
-						{{end}}
-					{{end}}
-
-					{{range .Labels}}
-						{{.Name | RenderEmoji}} 
-					{{end}}
-
-					{{if .NumComments}}
-						
-					{{end}}
-
-					{{if .TotalTrackedTime}}
-						
-					{{end}}
-
-					
-						{{ $timeStr := TimeSinceUnix .GetLastEventTimestamp $.Lang }}
-						{{if .OriginalAuthor }}
-							{{$.i18n.Tr .GetLastEventLabelFake $timeStr .OriginalAuthor | Safe}}
-						{{else if gt .Poster.ID 0}}
-							{{$.i18n.Tr .GetLastEventLabel $timeStr .Poster.HomeLink (.Poster.GetDisplayName | Escape) | Safe}}
-						{{else}}
-							{{$.i18n.Tr .GetLastEventLabelFake $timeStr (.Poster.GetDisplayName | Escape) | Safe}}
-						{{end}}
-
-						{{if .Milestone}}
-							
-								{{svg "octicon-milestone"}} {{.Milestone.Name}}
-							 
-						{{end}}
-						{{if .Ref}}
-							
-								{{svg "octicon-git-branch"}} {{index $.IssueRefEndNames .ID}}
-							 
-						{{end}}
-						{{$tasks := .GetTasks}}
-						{{if gt $tasks 0}}
-							{{$tasksDone := .GetTasksDone}}
-							
-								{{svg "octicon-checklist"}} {{$tasksDone}} / {{$tasks}}  
-							 
-						{{end}}
-						{{if ne .DeadlineUnix 0}}
-							
-								{{svg "octicon-calendar"}}{{.DeadlineUnix.FormatShort}} 
-							 
-						{{end}}
-						{{range .Assignees}}
-							
-								 
-							 
-						{{end}}
-						{{if .IsPull}}
-							{{$approveOfficial := call $approvalCounts .ID "approve"}}
-							{{$rejectOfficial := call $approvalCounts .ID "reject"}}
-							{{$waitingOfficial := call $approvalCounts .ID "waiting"}}
-							{{if gt $approveOfficial 0}}
-								{{svg "octicon-check"}}
-									{{$.i18n.Tr (TrN $.i18n.Lang $approveOfficial "repo.pulls.approve_count_1" "repo.pulls.approve_count_n") $approveOfficial}}
-								 
-							{{end}}
-
-							{{if gt $rejectOfficial 0}}
-								{{svg "octicon-diff"}}
-									{{$.i18n.Tr (TrN $.i18n.Lang $rejectOfficial "repo.pulls.reject_count_1" "repo.pulls.reject_count_n") $rejectOfficial}}
-								 
-							{{end}}
-
-							{{if gt $waitingOfficial 0}}
-								{{svg "octicon-eye"}}
-									{{$.i18n.Tr (TrN $.i18n.Lang $waitingOfficial "repo.pulls.waiting_count_1" "repo.pulls.waiting_count_n") $waitingOfficial}}
-								 
-							{{end}}
-
-							{{if and (not .PullRequest.HasMerged) (gt (len .PullRequest.ConflictedFiles) 0)}}
-								{{svg "octicon-x"}} {{$.i18n.Tr (TrN $.i18n.Lang (len .PullRequest.ConflictedFiles) "repo.pulls.num_conflicting_files_1" "repo.pulls.num_conflicting_files_n") (len .PullRequest.ConflictedFiles)}} 
-							{{end}}
-						{{end}}
-					
-				 
-			{{end}}
-
-			{{template "base/paginate" .}}
-		
 
+		{{template "shared/issuelist" mergeinto . "listType" "repo"}}
 	
 
 {{template "base/footer" .}}
diff --git a/templates/repo/issue/milestone_issues.tmpl b/templates/repo/issue/milestone_issues.tmpl
index ad75411d8..9958efc07 100644
--- a/templates/repo/issue/milestone_issues.tmpl
+++ b/templates/repo/issue/milestone_issues.tmpl
@@ -177,127 +177,7 @@
 				
 			
 		
-
-		
-			{{ $approvalCounts := .ApprovalCounts}}
-			{{range .Issues}}
-				{{ $timeStr:= TimeSinceUnix .CreatedUnix $.Lang }}
-				
-					{{if or (and $.CanWriteIssues (not .IsPull)) (and $.CanWritePulls .IsPull)}}
-					
-						 
-					
-					{{end}}
-
-					{{if .IsClosed}}
-						{{if .IsPull}}
-							{{if .PullRequest.HasMerged}}
-								#{{.Index}}
-								{{svg "octicon-git-pull-request"}} 
-							{{else}}
-								#{{.Index}}
-								{{svg "octicon-git-pull-request"}} 
-							{{end}}
-						{{else}}
-							#{{.Index}}
-							{{svg "octicon-issue-closed"}} 
-						{{end}}
-					{{else}}
-						{{if .IsRead}}
-							#{{.Index}}
-						{{else}}
-							#{{.Index}}
-						{{end}}
-						{{if .IsPull}}
-							{{svg "octicon-git-pull-request"}} 
-						{{else}}
-							{{svg "octicon-issue-opened"}} 
-						{{end}}
-					{{end}}
-
-					{{.Title | RenderEmoji}} 
-
-					{{if .IsPull }}
-						{{if (index $.CommitStatus .PullRequest.ID)}}
-							{{template "repo/commit_status" (index $.CommitStatus .PullRequest.ID)}}
-						{{end}}
-					{{end}}
-
-					{{range .Labels}}
-						{{.Name | RenderEmoji}} 
-					{{end}}
-
-					{{if .NumComments}}
-						
-					{{end}}
-
-					{{if .TotalTrackedTime}}
-						
-					{{end}}
-
-					
-						{{ $timeStr := TimeSinceUnix .GetLastEventTimestamp $.Lang }}
-						{{if .OriginalAuthor }}
-							{{$.i18n.Tr .GetLastEventLabelFake $timeStr .OriginalAuthor | Safe}}
-						{{else if gt .Poster.ID 0}}
-							{{$.i18n.Tr .GetLastEventLabel $timeStr .Poster.HomeLink (.Poster.GetDisplayName | Escape) | Safe}}
-						{{else}}
-							{{$.i18n.Tr .GetLastEventLabelFake $timeStr (.Poster.GetDisplayName | Escape) | Safe}}
-						{{end}}
-
-						{{if .Ref}}
-							
-								{{svg "octicon-git-branch"}} {{index $.IssueRefEndNames .ID}}
-							 
-						{{end}}
-						{{$tasks := .GetTasks}}
-						{{if gt $tasks 0}}
-							{{$tasksDone := .GetTasksDone}}
-							
-								{{svg "octicon-checklist"}} {{$tasksDone}} / {{$tasks}}  
-							 
-						{{end}}
-						{{if ne .DeadlineUnix 0}}
-							{{svg "octicon-calendar"}}
-							{{.DeadlineUnix.FormatShort}} 
-						{{end}}
-						{{range .Assignees}}
-							
-								 
-							 
-						{{end}}
-						{{if .IsPull}}
-							{{$approveOfficial := call $approvalCounts .ID "approve"}}
-							{{$rejectOfficial := call $approvalCounts .ID "reject"}}
-							{{$waitingOfficial := call $approvalCounts .ID "waiting"}}
-							{{if gt $approveOfficial 0}}
-								{{svg "octicon-check"}}
-									{{$.i18n.Tr (TrN $.i18n.Lang $approveOfficial "repo.pulls.approve_count_1" "repo.pulls.approve_count_n") $approveOfficial}}
-								 
-							{{end}}
-
-							{{if gt $rejectOfficial 0}}
-								{{svg "octicon-diff"}}
-									{{$.i18n.Tr (TrN $.i18n.Lang $rejectOfficial "repo.pulls.reject_count_1" "repo.pulls.reject_count_n") $rejectOfficial}}
-								 
-							{{end}}
-
-							{{if gt $waitingOfficial 0}}
-								{{svg "octicon-eye"}}
-									{{$.i18n.Tr (TrN $.i18n.Lang $waitingOfficial "repo.pulls.waiting_count_1" "repo.pulls.waiting_count_n") $waitingOfficial}}
-								 
-							{{end}}
-
-							{{if and (not .PullRequest.HasMerged) (gt (len .PullRequest.ConflictedFiles) 0)}}
-								{{svg "octicon-x"}} {{$.i18n.Tr (TrN $.i18n.Lang (len .PullRequest.ConflictedFiles) "repo.pulls.num_conflicting_files_1" "repo.pulls.num_conflicting_files_n") (len .PullRequest.ConflictedFiles)}} 
-							{{end}}
-						{{end}}
-					
-				 
-			{{end}}
-
-			{{template "base/paginate" .}}
-		
 
+		{{template "shared/issuelist" mergeinto . "listType" "milestone"}}
 	
 
 {{template "base/footer" .}}
diff --git a/templates/shared/issuelist.tmpl b/templates/shared/issuelist.tmpl
new file mode 100644
index 000000000..939358386
--- /dev/null
+++ b/templates/shared/issuelist.tmpl
@@ -0,0 +1,134 @@
+
+	{{ $approvalCounts := .ApprovalCounts}}
+	{{range .Issues}}
+		
+			
+				{{if $.CanWriteIssuesOrPulls}}
+					
+						 
+						 
+					
+				{{end}}
+				
+					{{if .IsPull}}
+						{{if .PullRequest.HasMerged}}
+							{{svg "octicon-git-merge" 16 "text purple"}}
+						{{else}}
+							{{if .IsClosed}}
+								{{svg "octicon-git-pull-request" 16 "text red"}}
+							{{else}}
+								{{svg "octicon-git-pull-request" 16 "text green"}}
+							{{end}}
+						{{end}}
+					{{else}}
+						{{if .IsClosed}}
+							{{svg "octicon-issue-opened" 16 "text red"}}
+						{{else}}
+							{{svg "octicon-issue-closed" 16 "text green"}}
+						{{end}}
+					{{end}}
+				
+			
 
+			
+				
+					
{{RenderEmoji .Title}} 
+					{{if .IsPull }}
+						{{if (index $.CommitStatus .PullRequest.ID)}}
+							{{template "repo/commit_status" (index $.CommitStatus .PullRequest.ID)}}
+						{{end}}
+					{{end}}
+					{{range .Labels}}
+						
{{.Name | RenderEmoji}} 
+					{{end}}
+				
+				
+					
+						#{{.Index}}
+					 
+					{{ $timeStr := TimeSinceUnix .GetLastEventTimestamp $.Lang }}
+					{{if .OriginalAuthor }}
+						{{$.i18n.Tr .GetLastEventLabelFake $timeStr .OriginalAuthor | Safe}}
+					{{else if gt .Poster.ID 0}}
+						{{$.i18n.Tr .GetLastEventLabel $timeStr .Poster.HomeLink (.Poster.GetDisplayName | Escape) | Safe}}
+					{{else}}
+						{{$.i18n.Tr .GetLastEventLabelFake $timeStr (.Poster.GetDisplayName | Escape) | Safe}}
+					{{end}}
+					{{if and .Milestone (ne $.listType "milestone")}}
+						
+							{{svg "octicon-milestone" 14 "mr-2"}}{{.Milestone.Name}}
+						 
+					{{end}}
+					{{if .Ref}}
+						
+							{{svg "octicon-git-branch" 14 "mr-2"}}{{index $.IssueRefEndNames .ID}}
+						 
+					{{end}}
+					{{$tasks := .GetTasks}}
+					{{if gt $tasks 0}}
+						{{$tasksDone := .GetTasksDone}}
+						
+							{{svg "octicon-checklist" 14 "mr-2"}}{{$tasksDone}} / {{$tasks}}  
+						 
+					{{end}}
+					{{if ne .DeadlineUnix 0}}
+						
+							{{svg "octicon-calendar" 14 "mr-2"}}{{.DeadlineUnix.FormatShort}} 
+						 
+					{{end}}
+					{{if .IsPull}}
+						{{$approveOfficial := call $approvalCounts .ID "approve"}}
+						{{$rejectOfficial := call $approvalCounts .ID "reject"}}
+						{{$waitingOfficial := call $approvalCounts .ID "waiting"}}
+						{{if gt $approveOfficial 0}}
+							
+								{{svg "octicon-check" 14 "mr-2"}}
+								{{$.i18n.Tr (TrN $.i18n.Lang $approveOfficial "repo.pulls.approve_count_1" "repo.pulls.approve_count_n") $approveOfficial}}
+							 
+						{{end}}
+						{{if gt $rejectOfficial 0}}
+							
+								{{svg "octicon-diff" 14 "mr-2"}}
+								{{$.i18n.Tr (TrN $.i18n.Lang $rejectOfficial "repo.pulls.reject_count_1" "repo.pulls.reject_count_n") $rejectOfficial}}
+							 
+						{{end}}
+						{{if gt $waitingOfficial 0}}
+							
+								{{svg "octicon-eye" 14}}
+								{{$.i18n.Tr (TrN $.i18n.Lang $waitingOfficial "repo.pulls.waiting_count_1" "repo.pulls.waiting_count_n") $waitingOfficial}}
+							 
+						{{end}}
+						{{if and (not .PullRequest.HasMerged) (gt (len .PullRequest.ConflictedFiles) 0)}}
+							
+								{{svg "octicon-x" 14}}
+								{{$.i18n.Tr (TrN $.i18n.Lang (len .PullRequest.ConflictedFiles) "repo.pulls.num_conflicting_files_1" "repo.pulls.num_conflicting_files_n") (len .PullRequest.ConflictedFiles)}}
+							 
+						{{end}}
+					{{end}}
+				
+			
 
+			
+				
+					{{if .TotalTrackedTime}}
+						{{svg "octicon-clock" 16 "mr-2"}}
+						{{.TotalTrackedTime | Sec2Time}}
+					{{end}}
+				
+				
+					{{range .Assignees}}
+						
+							 
+						 
+					{{end}}
+				
+				
+			
 
+		 
+	{{end}}
+
 
+{{template "base/paginate" .}}
diff --git a/templates/user/dashboard/issues.tmpl b/templates/user/dashboard/issues.tmpl
index f035aed77..93ec2ed00 100644
--- a/templates/user/dashboard/issues.tmpl
+++ b/templates/user/dashboard/issues.tmpl
@@ -97,110 +97,7 @@
 						
 					
 				
-
-				
-					{{ $approvalCounts := .ApprovalCounts}}
-					{{range .Issues}}
-
-						{{ $timeStr:= TimeSinceUnix .CreatedUnix $.Lang }}
-						{{if .Repo}}
-						
-							{{.Repo.FullName}}#{{.Index}}
-							{{RenderEmoji .Title}} 
-
-							{{if .IsPull}}
-									{{if (index $.CommitStatus .PullRequest.ID)}}
-											{{template "repo/commit_status" (index $.CommitStatus .PullRequest.ID)}}
-									{{end}}
-							{{end}}
-
-							{{with .Labels}}
-								{{/* If we have any labels, we should show them
-								with a 2.5 line height, this way they don't look
-								awful and they don't stack on top of each other,
-								especially on mobile views. */}}
-								
-									{{range .}}
-										{{.Name | RenderEmoji}} 
-									{{end}}
-								 
-							{{end}}
-
-							{{if .NumComments}}
-								
-							{{end}}
-							{{if .TotalTrackedTime}}
-								
-							{{end}}
-
-							
-								{{if .OriginalAuthor}}
-									{{$.i18n.Tr .GetLastEventLabelFake $timeStr .OriginalAuthor | Safe}}
-								{{else if gt .Poster.ID 0}}
-									{{$.i18n.Tr .GetLastEventLabel $timeStr .Poster.HomeLink (.Poster.GetDisplayName|Escape) | Safe}}
-								{{else}}
-									{{$.i18n.Tr .GetLastEventLabelFake $timeStr (.Poster.GetDisplayName|Escape) | Safe}}
-								{{end}}
-								{{if .Milestone}}
-									
-										{{svg "octicon-milestone"}} {{.Milestone.Name}}
-									 
-								{{end}}
-								{{if .Ref}}
-									
-										{{svg "octicon-git-branch"}} {{index $.IssueRefEndNames .ID}}
-									 
-								{{end}}
-								{{range .Assignees}}
-									
-										 
-									 
-								{{end}}
-								{{$tasks := .GetTasks}}
-								{{if gt $tasks 0}}
-									{{$tasksDone := .GetTasksDone}}
-									
-										{{svg "octicon-checklist"}} {{$tasksDone}} / {{$tasks}}  
-									 
-								{{end}}
-								{{if ne .DeadlineUnix 0}}
-									
-										{{svg "octicon-calendar"}}{{.DeadlineUnix.FormatShort}} 
-									 
-								{{end}}
-								{{if .IsPull}}
-									{{$approveOfficial := call $approvalCounts .ID "approve"}}
-									{{$rejectOfficial := call $approvalCounts .ID "reject"}}
-									{{$waitingOfficial := call $approvalCounts .ID "waiting"}}
-									{{if gt $approveOfficial 0}}
-										{{svg "octicon-check"}}
-											{{$.i18n.Tr (TrN $.i18n.Lang $approveOfficial "repo.pulls.approve_count_1" "repo.pulls.approve_count_n") $approveOfficial}}
-										 
-									{{end}}
-
-									{{if gt $rejectOfficial 0}}
-										{{svg "octicon-diff"}}
-											{{$.i18n.Tr (TrN $.i18n.Lang $rejectOfficial "repo.pulls.reject_count_1" "repo.pulls.reject_count_n") $rejectOfficial}}
-										 
-									{{end}}
-
-									{{if gt $waitingOfficial 0}}
-										{{svg "octicon-eye"}}
-											{{$.i18n.Tr (TrN $.i18n.Lang $waitingOfficial "repo.pulls.waiting_count_1" "repo.pulls.waiting_count_n") $waitingOfficial}}
-										 
-									{{end}}
-
-									{{if and (not .PullRequest.HasMerged) (gt (len .PullRequest.ConflictedFiles) 0)}}
-										{{svg "octicon-x"}} {{$.i18n.Tr (TrN $.i18n.Lang (len .PullRequest.ConflictedFiles) "repo.pulls.num_conflicting_files_1" "repo.pulls.num_conflicting_files_n") (len .PullRequest.ConflictedFiles)}} 
-									{{end}}
-								{{end}}
-							
-						 
-						{{end}}
-					{{end}}
-
-					{{template "base/paginate" .}}
-				
 
+				{{template "shared/issuelist" mergeinto . "listType" "dashboard"}}
 			
 		
 	
diff --git a/web_src/less/_base.less b/web_src/less/_base.less
index 406247179..9af770e40 100644
--- a/web_src/less/_base.less
+++ b/web_src/less/_base.less
@@ -76,6 +76,7 @@
   /* target-based colors */
   --color-body: #ffffff;
   --color-text: #212121;
+  --color-text-light: #444444;
   --color-box-header: #f7f7f7;
   --color-box-body: #ffffff;
   --color-timeline: #ececec;
@@ -141,6 +142,15 @@ strong {
   font-weight: 500;
 }
 
+h1,
+h2,
+h3,
+h4,
+h5,
+h6 {
+  font-weight: 600;
+}
+
 body {
   background-color: var(--color-body);
   overflow-y: auto;
@@ -448,7 +458,7 @@ a:hover,
       color: var(--color-red) !important;
 
       a {
-        color: var(--color-red) !important;
+        color: inherit !important;
 
         &:hover {
           color: #e67777 !important;
@@ -457,19 +467,19 @@ a:hover,
     }
 
     &.blue {
-      color: var(--color-primary-dark-1) !important;
+      color: var(--color-primary) !important;
 
       a {
-        color: var(--color-primary) !important;
+        color: inherit !important;
 
         &:hover {
-          color: var(--color-primary-dark-2) !important;
+          color: var(--color-primary-dark-1) !important;
         }
       }
     }
 
     &.black {
-      color: #444444;
+      color: var(--color-body);
 
       &:hover {
         color: #000000;
@@ -477,13 +487,13 @@ a:hover,
     }
 
     &.grey {
-      color: var(--color-grey) !important;
+      color: var(--color-text-light) !important;
 
       a {
-        color: #444444 !important;
+        color: inherit !important;
 
         &:hover {
-          color: #000000 !important;
+          color: var(--color-primary) !important;
         }
       }
     }
diff --git a/web_src/less/_repository.less b/web_src/less/_repository.less
index dc0c718c1..1dbd741ee 100644
--- a/web_src/less/_repository.less
+++ b/web_src/less/_repository.less
@@ -2586,111 +2586,10 @@
   display: none;
 }
 
-.ui.checkbox.issue-checkbox {
-  vertical-align: middle;
-}
-
 .ui.menu .item > img:not(.ui) {
   width: auto;
 }
 
-.issue.list {
-  list-style: none;
-
-  > .item {
-    padding-top: 15px;
-    padding-bottom: 10px;
-    border-bottom: 1px dashed #aaaaaa;
-
-    .title {
-      color: #444444;
-      font-size: 15px;
-      font-weight: 500;
-      margin: 0 6px;
-
-      &:hover {
-        color: #000000;
-      }
-    }
-
-    .comment {
-      padding-right: 10px;
-      color: #666666;
-    }
-
-    .desc {
-      padding-top: 5px;
-      color: #999999;
-
-      .waiting,
-      .approvals,
-      .rejects {
-        padding-left: 5px;
-      }
-
-      .checklist {
-        padding-left: 5px;
-
-        .progress-bar {
-          margin-left: 2px;
-          width: 80px;
-          height: 6px;
-          display: inline-block;
-          background-color: #eeeeee;
-          overflow: hidden;
-          border-radius: 3px;
-          vertical-align: 2px !important;
-
-          .progress {
-            background-color: #cccccc;
-            display: block;
-            height: 100%;
-          }
-        }
-      }
-
-      .conflicting {
-        padding-left: 5px;
-      }
-
-      .due-date {
-        padding-left: 5px;
-      }
-
-      a.milestone {
-        margin-left: 5px;
-        color: #999999 !important;
-
-        &:hover {
-          color: #000000 !important;
-        }
-      }
-
-      a.ref {
-        margin-left: 8px;
-        color: #999999 !important;
-
-        &:hover {
-          color: #000000 !important;
-        }
-
-        span {
-          margin-right: -4px;
-        }
-      }
-
-      .assignee {
-        margin-top: -5px;
-        margin-right: 5px;
-      }
-
-      .overdue {
-        color: var(--color-red);
-      }
-    }
-  }
-}
-
 .page.buttons {
   padding-top: 15px;
 }
@@ -2975,15 +2874,31 @@
   flex-wrap: wrap;
 }
 
-.labels.list .item {
+.labels.list .item,
+.timeline-item .label {
   padding: .3em .5em !important;
   margin-left: 0;
   margin-right: 0;
   margin-bottom: 3px;
 }
 
-.labels.list .item + .item {
-  margin-left: 3px;
+.issue-item-top-row .label {
+  margin-left: 0;
+  margin-right: 0;
+  margin-top: 1.5px;
+  margin-bottom: 1.5px;
+}
+
+.labels.list .item,
+.timeline-item .label,
+.issue-item-top-row .label {
+  margin-right: 3px;
+  display: inline !important;
+}
+
+.timeline-item .label:last-of-type,
+.issue-item-top-row .label:last-of-type {
+  margin-right: 0;
 }
 
 tbody.commit-list {
diff --git a/web_src/less/helpers.less b/web_src/less/helpers.less
index d50aea026..60d50883c 100644
--- a/web_src/less/helpers.less
+++ b/web_src/less/helpers.less
@@ -6,6 +6,7 @@
 .sb { justify-content: space-between !important; }
 .fc { flex-direction: column !important; }
 .f1 { flex: 1 !important; }
+.fw { flex-wrap: wrap !important; }
 
 .mono {
   font-family: var(--fonts-monospace) !important;
diff --git a/web_src/less/index.less b/web_src/less/index.less
index 1b0701ae8..0d5ef8872 100644
--- a/web_src/less/index.less
+++ b/web_src/less/index.less
@@ -1,6 +1,7 @@
 @import "~font-awesome/css/font-awesome.css";
 
 @import "./variables.less";
+@import "./shared/issuelist.less";
 @import "./features/gitgraph.less";
 @import "./features/animations.less";
 @import "./features/heatmap.less";
diff --git a/web_src/less/shared/issuelist.less b/web_src/less/shared/issuelist.less
new file mode 100644
index 000000000..dec99e135
--- /dev/null
+++ b/web_src/less/shared/issuelist.less
@@ -0,0 +1,127 @@
+.issue.list {
+  list-style: none;
+  margin-top: 1rem;
+
+  a:not(.label):hover {
+    color: var(--color-primary) !important;
+  }
+
+  > .item {
+    .issue-checkbox {
+      margin-top: 1px;
+    }
+
+    .issue-item-icon svg {
+      margin-right: .75rem;
+    }
+
+    .issue-item-icons-right > * + * {
+      margin-left: .5rem;
+    }
+
+    .issue-item-main {
+      width: 100%;
+    }
+
+    .issue-item-top-row {
+      max-width: 100%;
+      color: var(--color-text);
+      font-size: 16px;
+      min-width: 0;
+      font-weight: 600;
+    }
+
+    .issue-item-bottom-row {
+      font-size: 13px;
+    }
+
+    .title {
+      color: var(--color-text);
+      word-break: break-word;
+    }
+
+    .issue-item-icon-right {
+      min-width: 2rem;
+    }
+
+    .assignee {
+      position: relative;
+      top: -2px;
+    }
+
+    .assignee img {
+      width: 20px;
+      height: 20px;
+      margin-right: 2px;
+    }
+
+    .desc {
+      color: #999999;
+
+      a {
+        color: inherit;
+      }
+
+      .time-since,
+      a {
+        margin-left: .25rem;
+        margin-right: .25rem;
+      }
+
+      .waiting,
+      .approvals,
+      .rejects {
+        padding-left: 5px;
+      }
+
+      .checklist {
+        padding-left: 5px;
+
+        .progress-bar {
+          margin-left: 2px;
+          width: 80px;
+          height: 6px;
+          display: inline-block;
+          background-color: #eeeeee;
+          overflow: hidden;
+          border-radius: 3px;
+          vertical-align: 2px !important;
+
+          .progress {
+            background-color: #cccccc;
+            display: block;
+            height: 100%;
+          }
+        }
+      }
+
+      .conflicting {
+        padding-left: 5px;
+      }
+
+      .due-date {
+        padding-left: 5px;
+      }
+
+      a.milestone {
+        margin-left: 5px;
+      }
+
+      a.ref {
+        margin-left: 8px;
+
+        span {
+          margin-right: -4px;
+        }
+      }
+
+      .overdue {
+        color: var(--color-red);
+      }
+    }
+  }
+
+  > .item + .item {
+    border-top: 1px solid var(--color-secondary);
+  }
+}
diff --git a/web_src/less/themes/theme-arc-green.less b/web_src/less/themes/theme-arc-green.less
index 57b00efe3..8c36944ec 100644
--- a/web_src/less/themes/theme-arc-green.less
+++ b/web_src/less/themes/theme-arc-green.less
@@ -73,6 +73,7 @@
   --color-box-header: #454a57;
   --color-box-body: #353945;
   --color-text: #b6bac5;
+  --color-text-light: #969aa5;
   --color-timeline: #4a505c;
   --color-input-text: #dcdcdc;
   --color-input-background: #2e323e;
@@ -680,18 +681,6 @@ a.ui.basic.label:hover {
   background-color: #383c4a;
 }
 
-.issue.list > .item .title {
-  color: #87ab63;
-}
-
-.issue.list > .item .title:hover {
-  color: #a0cc75;
-}
-
-.issue.list > .item {
-  border-bottom: 1px dashed #475767;
-}
-
 .ui.green.label,
 .ui.green.labels .label,
 .ui.basic.green.label {
@@ -708,10 +697,6 @@ a.ui.basic.green.label:hover {
   color: #fff !important;
 }
 
-.issue.list > .item .comment {
-  color: var(--color-secondary-dark-6);
-}
-
 .ui.basic.red.active.button,
 .ui.basic.red.buttons .active.button {
   box-shadow: 0 0 0 1px #b75252 inset !important;
@@ -1019,10 +1004,6 @@ a.ui.basic.green.label:hover {
   text-shadow: -2px 0 #383c4a, 0 2px #383c4a, 2px 0 #383c4a, 0 -2px #383c4a;
 }
 
-.ui .text.grey a {
-  color: #dbdbdb !important;
-}
-
 .repository.view.issue .comment-list .comment .content .header {
   color: #dbdbdb;
   background-color: var(--color-secondary);
@@ -1045,10 +1026,6 @@ a.ui.basic.green.label:hover {
   background: #353945;
 }
 
-.ui .text.grey a:hover {
-  color: #dbdbdb !important;
-}
-
 .ui.basic.green.active.button,
 .ui.basic.green.buttons .active.button {
   color: #87ab63 !important;