diff --git a/.eslintrc.yaml b/.eslintrc.yaml
index 5461bf1be63dc..ea21bc542faf4 100644
--- a/.eslintrc.yaml
+++ b/.eslintrc.yaml
@@ -50,6 +50,9 @@ overrides:
   - files: ["**/*.test.*", "web_src/js/test/setup.js"]
     env:
       vitest-globals/env: true
+  - files: ["web_src/js/modules/fetch.js", "web_src/js/standalone/**/*"]
+    rules:
+      no-restricted-syntax: [2, WithStatement, ForInStatement, LabeledStatement, SequenceExpression]
 
 rules:
   "@eslint-community/eslint-comments/disable-enable-pair": [2]
@@ -424,7 +427,7 @@ rules:
   no-restricted-exports: [0]
   no-restricted-globals: [2, addEventListener, blur, close, closed, confirm, defaultStatus, defaultstatus, error, event, external, find, focus, frameElement, frames, history, innerHeight, innerWidth, isFinite, isNaN, length, location, locationbar, menubar, moveBy, moveTo, name, onblur, onerror, onfocus, onload, onresize, onunload, open, opener, opera, outerHeight, outerWidth, pageXOffset, pageYOffset, parent, print, removeEventListener, resizeBy, resizeTo, screen, screenLeft, screenTop, screenX, screenY, scroll, scrollbars, scrollBy, scrollTo, scrollX, scrollY, self, status, statusbar, stop, toolbar, top, __dirname, __filename]
   no-restricted-imports: [0]
-  no-restricted-syntax: [2, WithStatement, ForInStatement, LabeledStatement, SequenceExpression]
+  no-restricted-syntax: [2, WithStatement, ForInStatement, LabeledStatement, SequenceExpression, {selector: "CallExpression[callee.name='fetch']", message: "use modules/fetch.js instead"}]
   no-return-assign: [0]
   no-script-url: [2]
   no-self-assign: [2, {props: true}]
diff --git a/docs/content/contributing/guidelines-frontend.en-us.md b/docs/content/contributing/guidelines-frontend.en-us.md
index 921c2b0233690..0d9e510e70039 100644
--- a/docs/content/contributing/guidelines-frontend.en-us.md
+++ b/docs/content/contributing/guidelines-frontend.en-us.md
@@ -95,7 +95,7 @@ Some lint rules and IDEs also have warnings if the returned Promise is not handl
 ### Fetching data
 
 To fetch data, use the wrapper functions `GET`, `POST` etc. from `modules/fetch.js`. They
-accept a `data` option for the content, will automatically set CSFR token and return a
+accept a `data` option for the content, will automatically set CSRF token and return a
 Promise for a [Response](https://developer.mozilla.org/en-US/docs/Web/API/Response).
 
 ### HTML Attributes and `dataset`
diff --git a/docs/content/usage/actions/comparison.en-us.md b/docs/content/usage/actions/comparison.en-us.md
index 64a5eff4d5a7e..caec9d3dea3c7 100644
--- a/docs/content/usage/actions/comparison.en-us.md
+++ b/docs/content/usage/actions/comparison.en-us.md
@@ -91,12 +91,6 @@ As a workaround, you can use [go-hashfiles](https://gitea.com/actions/go-hashfil
 
 ## Missing features
 
-### Variables
-
-See [Variables](https://docs.github.com/en/actions/learn-github-actions/variables).
-
-It's under development.
-
 ### Problem Matchers
 
 Problem Matchers are a way to scan the output of actions for a specified regex pattern and surface that information prominently in the UI.
@@ -120,15 +114,17 @@ Pre and Post steps don't have their own section in the job log user interface.
 
 ### Downloading actions
 
-Gitea Actions doesn't download actions from GitHub by default.
-"By default" means that you don't specify the host in the `uses` field, like `uses: actions/checkout@v3`.
-As a contrast, `uses: https://github.com/actions/checkout@v3` has specified host.
+Previously (Pre 1.21.0), `[actions].DEFAULT_ACTIONS_URL` defaulted to `https://gitea.com`.
+We have since restricted this option to only allow two values (`github` and `self`).
+When set to `github`, the new default, Gitea will download non-fully-qualified actions from <https://github.com>.
+For example, if you use `uses: actions/checkout@v3`, it will download the checkout repository from <https://github.com/actions/checkout.git>.
+
+If you want to download an action from another git hoster, you can use an absolute URL, e.g. `uses: https://gitea.com/actions/checkout@v3`.
 
-The missing host will be filled with `https://gitea.com` if you don't configure it.
-That means `uses: actions/checkout@v3` will download the action from [gitea.com/actions/checkout](https://gitea.com/actions/checkout), instead of [github.com/actions/checkout](https://github.com/actions/checkout).
+If your Gitea instance is in an intranet or a restricted area, you can set the URL to `self` to only download actions from your own instance by default.
+Of course, you can still use absolute URLs in workflows.
 
-As mentioned, it's configurable.
-If you want your runners to download actions from GitHub or your own Gitea instance by default, you can configure it by setting `[actions].DEFAULT_ACTIONS_URL`. See [Configuration Cheat Sheet](administration/config-cheat-sheet.md#actions-actions).
+More details about the `[actions].DEFAULT_ACTIONS_URL` configuration can be found in the [Configuration Cheat Sheet](administration/config-cheat-sheet.md#actions-actions)。
 
 ### Context availability
 
diff --git a/docs/content/usage/actions/comparison.zh-cn.md b/docs/content/usage/actions/comparison.zh-cn.md
index cfea7970f7d0e..5dae75a44ba3a 100644
--- a/docs/content/usage/actions/comparison.zh-cn.md
+++ b/docs/content/usage/actions/comparison.zh-cn.md
@@ -120,15 +120,13 @@ Gitea Actions目前不支持此功能。
 
 ### 下载Actions
 
-Gitea Actions默认不从GitHub下载Actions。
-"默认" 意味着您在`uses` 字段中不指定主机,如`uses: actions/checkout@v3`。
-相反,`uses: https://github.com/actions/checkout@v3`是有指定主机的。
+当 `[actions].DEFAULT_ACTIONS_URL` 保持默认值为 `github` 时,Gitea将会从 https://github.com 下载相对路径的actions。比如:
+如果你使用 `uses: actions/checkout@v3`,Gitea将会从 https://github.com/actions/checkout.git 下载这个 actions 项目。
+如果你想要从另外一个 Git服务下载actions,你只需要使用绝对URL `uses: https://gitea.com/actions/checkout@v3` 来下载。
 
-如果您不进行配置,缺失的主机将填充为`https://gitea.com`。
-这意味着`uses: actions/checkout@v3`将从[gitea.com/actions/checkout](https://gitea.com/actions/checkout)下载该Action,而不是[github.com/actions/checkout](https://github.com/actions/checkout)。
+如果你的 Gitea 实例是部署在一个互联网限制的网络中,有可以使用绝对地址来下载 actions。你也可以讲配置项修改为 `[actions].DEFAULT_ACTIONS_URL = self`。这样所有的相对路径的actions引用,将不再会从 github.com 去下载,而会从这个 Gitea 实例自己的仓库中去下载。例如: `uses: actions/checkout@v3` 将会从 `[server].ROOT_URL`/actions/checkout.git 这个地址去下载 actions。
 
-正如前面提到的,这是可配置的。
-如果您希望您的运行程序默认从GitHub或您自己的Gitea实例下载动作,您可以通过设置`[actions].DEFAULT_ACTIONS_URL`进行配置。请参阅[配置备忘单](administration/config-cheat-sheet.md#actions-actions)。
+设置`[actions].DEFAULT_ACTIONS_URL`进行配置。请参阅[配置备忘单](administration/config-cheat-sheet.md#actions-actions)。
 
 ### 上下文可用性
 
diff --git a/docs/content/usage/actions/faq.en-us.md b/docs/content/usage/actions/faq.en-us.md
index 031509a033e1f..1d59872936a46 100644
--- a/docs/content/usage/actions/faq.en-us.md
+++ b/docs/content/usage/actions/faq.en-us.md
@@ -180,3 +180,6 @@ For events supported only by GitHub, see GitHub's [documentation](https://docs.g
 | pull_request_review_comment | `created`, `edited`                                                                                                      |
 | release                     | `published`, `edited`                                                                                                    |
 | registry_package            | `published`                                                                                                              |
+
+> For `pull_request` events, in [GitHub Actions](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request), the `ref` is `refs/pull/:prNumber/merge`, which is a reference to the merge commit preview. However, Gitea has no such reference.
+> Therefore, the `ref` in Gitea Actions is `refs/pull/:prNumber/head`, which points to the head of pull request rather than the preview of the merge commit.
diff --git a/docs/content/usage/actions/faq.zh-cn.md b/docs/content/usage/actions/faq.zh-cn.md
index f5dc8e179bdd1..7bb79d02fc4a8 100644
--- a/docs/content/usage/actions/faq.zh-cn.md
+++ b/docs/content/usage/actions/faq.zh-cn.md
@@ -180,3 +180,6 @@ defaults:
 | pull_request_review_comment | `created`, `edited`                                                                                                      |
 | release                     | `published`, `edited`                                                                                                    |
 | registry_package            | `published`                                                                                                              |
+
+> 对于 `pull_request` 事件,在 [GitHub Actions](https://docs.github.com/en/actions/using-workflows/events-that-trigger-workflows#pull_request) 中 `ref` 是 `refs/pull/:prNumber/merge`,它指向这个拉取请求合并提交的一个预览。但是 Gitea 没有这种 reference。
+> 因此,Gitea Actions 中 `ref` 是 `refs/pull/:prNumber/head`,它指向这个拉取请求的头分支而不是合并提交的预览。
diff --git a/models/fixtures/issue.yml b/models/fixtures/issue.yml
index fa72f9b647da0..ccc1fe41fbd97 100644
--- a/models/fixtures/issue.yml
+++ b/models/fixtures/issue.yml
@@ -321,3 +321,20 @@
   created_unix: 946684830
   updated_unix: 978307200
   is_locked: false
+
+-
+  id: 20
+  repo_id: 23
+  index: 1
+  poster_id: 2
+  original_author_id: 0
+  name: issue for pr
+  content: content
+  milestone_id: 0
+  priority: 0
+  is_closed: false
+  is_pull: true
+  num_comments: 0
+  created_unix: 978307210
+  updated_unix: 978307210
+  is_locked: false
diff --git a/models/fixtures/pull_request.yml b/models/fixtures/pull_request.yml
index e5589ac703d77..396bdba88cbc5 100644
--- a/models/fixtures/pull_request.yml
+++ b/models/fixtures/pull_request.yml
@@ -89,3 +89,12 @@
   base_branch: main
   merge_base: cbff181af4c9c7fee3cf6c106699e07d9a3f54e6
   has_merged: false
+
+-
+  id: 8
+  type: 0 # gitea pull request
+  status: 2 # mergable
+  issue_id: 20
+  index: 1
+  head_repo_id: 23
+  base_repo_id: 23
\ No newline at end of file
diff --git a/models/fixtures/repository.yml b/models/fixtures/repository.yml
index c63b7ebd48170..373c1caa6257a 100644
--- a/models/fixtures/repository.yml
+++ b/models/fixtures/repository.yml
@@ -679,7 +679,7 @@
   num_forks: 0
   num_issues: 0
   num_closed_issues: 0
-  num_pulls: 0
+  num_pulls: 1
   num_closed_pulls: 0
   num_milestones: 0
   num_closed_milestones: 0
diff --git a/models/fixtures/review.yml b/models/fixtures/review.yml
index dda13dc468e47..f964c6ac06412 100644
--- a/models/fixtures/review.yml
+++ b/models/fixtures/review.yml
@@ -132,3 +132,41 @@
   content: "singular review from org6 and final review for this pr"
   updated_unix: 946684831
   created_unix: 946684831
+
+- 
+  id: 16
+  type: 4
+  reviewer_id: 20
+  issue_id: 20
+  content: "review request for user20"
+  updated_unix: 946684832
+  created_unix: 946684832
+
+- 
+  id: 17
+  type: 1
+  reviewer_id: 20
+  issue_id: 20
+  content: "review approved by user20"
+  updated_unix: 946684833
+  created_unix: 946684833
+- 
+  id: 18
+  type: 4
+  reviewer_id: 0
+  reviewer_team_id: 5 
+  issue_id: 20
+  content: "review request for team5"
+  updated_unix: 946684834
+  created_unix: 946684834
+
+-
+  id: 19
+  type: 4
+  reviewer_id: 15
+  reviewer_team_id: 0
+  issue_id: 20
+  content: "review request for user15"
+  updated_unix: 946684835
+  created_unix: 946684835
+
diff --git a/models/fixtures/team.yml b/models/fixtures/team.yml
index 65326eedbf476..295e51e39ce94 100644
--- a/models/fixtures/team.yml
+++ b/models/fixtures/team.yml
@@ -93,7 +93,7 @@
   name: review_team
   authorize: 1 # read
   num_repos: 1
-  num_members: 2
+  num_members: 3
   includes_all_repositories: false
   can_create_org_repo: false
 
diff --git a/models/fixtures/team_user.yml b/models/fixtures/team_user.yml
index feace5f2a531d..a5f1e9fd92aaf 100644
--- a/models/fixtures/team_user.yml
+++ b/models/fixtures/team_user.yml
@@ -123,3 +123,9 @@
   org_id: 36
   team_id: 20
   uid: 5
+
+- 
+  id: 22
+  org_id: 17
+  team_id: 9
+  uid: 15
diff --git a/models/issues/issue_search.go b/models/issues/issue_search.go
index 5d40b447042c3..5c05ead6879e7 100644
--- a/models/issues/issue_search.go
+++ b/models/issues/issue_search.go
@@ -362,14 +362,21 @@ func applyReviewRequestedCondition(sess *xorm.Session, reviewRequestedID int64)
 		From("team_user").
 		Where(builder.Eq{"team_user.uid": reviewRequestedID})
 
+	// if the review is approved or rejected, it should not be shown in the review requested list
+	maxReview := builder.Select("MAX(r.id)").
+		From("review as r").
+		Where(builder.In("r.type", []ReviewType{ReviewTypeApprove, ReviewTypeReject, ReviewTypeRequest})).
+		GroupBy("r.issue_id, r.reviewer_id, r.reviewer_team_id")
+
 	subQuery := builder.Select("review.issue_id").
 		From("review").
 		Where(builder.And(
-			builder.In("review.type", []ReviewType{ReviewTypeRequest, ReviewTypeReject, ReviewTypeApprove}),
+			builder.Eq{"review.type": ReviewTypeRequest},
 			builder.Or(
 				builder.Eq{"review.reviewer_id": reviewRequestedID},
 				builder.In("review.reviewer_team_id", existInTeamQuery),
 			),
+			builder.In("review.id", maxReview),
 		))
 	return sess.Where("issue.poster_id <> ?", reviewRequestedID).
 		And(builder.In("issue.id", subQuery))
diff --git a/models/issues/issue_test.go b/models/issues/issue_test.go
index b7fa7eff1c150..513ae241bc9cc 100644
--- a/models/issues/issue_test.go
+++ b/models/issues/issue_test.go
@@ -403,7 +403,7 @@ func TestCountIssues(t *testing.T) {
 	assert.NoError(t, unittest.PrepareTestDatabase())
 	count, err := issues_model.CountIssues(db.DefaultContext, &issues_model.IssuesOptions{})
 	assert.NoError(t, err)
-	assert.EqualValues(t, 19, count)
+	assert.EqualValues(t, 20, count)
 }
 
 func TestIssueLoadAttributes(t *testing.T) {
diff --git a/models/issues/issue_user.go b/models/issues/issue_user.go
index d053b1d54350b..24bb74648d9ce 100644
--- a/models/issues/issue_user.go
+++ b/models/issues/issue_user.go
@@ -15,7 +15,7 @@ import (
 type IssueUser struct {
 	ID          int64 `xorm:"pk autoincr"`
 	UID         int64 `xorm:"INDEX"` // User ID.
-	IssueID     int64
+	IssueID     int64 `xorm:"INDEX"`
 	IsRead      bool
 	IsMentioned bool
 }
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go
index 3524077ea4b7c..38fff37bed066 100644
--- a/models/migrations/migrations.go
+++ b/models/migrations/migrations.go
@@ -534,6 +534,8 @@ var migrations = []Migration{
 	NewMigration("Add ScheduleID for ActionRun", v1_21.AddScheduleIDForActionRun),
 	// v276 -> v277
 	NewMigration("Add RemoteAddress to mirrors", v1_21.AddRemoteAddressToMirrors),
+	// v277 -> v278
+	NewMigration("Add Index to issue_user.issue_id", v1_21.AddIndexToIssueUserIssueID),
 }
 
 // GetCurrentDBVersion returns the current db version
diff --git a/models/migrations/v1_21/v276.go b/models/migrations/v1_21/v276.go
index 8746c8851e63a..ed1bc3bda5241 100644
--- a/models/migrations/v1_21/v276.go
+++ b/models/migrations/v1_21/v276.go
@@ -41,6 +41,8 @@ func migratePullMirrors(x *xorm.Engine) error {
 		ID            int64  `xorm:"pk autoincr"`
 		RepoID        int64  `xorm:"INDEX"`
 		RemoteAddress string `xorm:"VARCHAR(2048)"`
+		RepoOwner     string
+		RepoName      string
 	}
 
 	sess := x.NewSession()
@@ -59,7 +61,9 @@ func migratePullMirrors(x *xorm.Engine) error {
 
 	for {
 		var mirrors []Mirror
-		if err := sess.Limit(limit, start).Find(&mirrors); err != nil {
+		if err := sess.Select("mirror.id, mirror.repo_id, mirror.remote_address, repository.owner_name as repo_owner, repository.name as repo_name").
+			Join("INNER", "repository", "repository.id = mirror.repo_id").
+			Limit(limit, start).Find(&mirrors); err != nil {
 			return err
 		}
 
@@ -69,7 +73,7 @@ func migratePullMirrors(x *xorm.Engine) error {
 		start += len(mirrors)
 
 		for _, m := range mirrors {
-			remoteAddress, err := getRemoteAddress(sess, m.RepoID, "origin")
+			remoteAddress, err := getRemoteAddress(m.RepoOwner, m.RepoName, "origin")
 			if err != nil {
 				return err
 			}
@@ -100,6 +104,8 @@ func migratePushMirrors(x *xorm.Engine) error {
 		RepoID        int64 `xorm:"INDEX"`
 		RemoteName    string
 		RemoteAddress string `xorm:"VARCHAR(2048)"`
+		RepoOwner     string
+		RepoName      string
 	}
 
 	sess := x.NewSession()
@@ -118,7 +124,9 @@ func migratePushMirrors(x *xorm.Engine) error {
 
 	for {
 		var mirrors []PushMirror
-		if err := sess.Limit(limit, start).Find(&mirrors); err != nil {
+		if err := sess.Select("push_mirror.id, push_mirror.repo_id, push_mirror.remote_name, push_mirror.remote_address, repository.owner_name as repo_owner, repository.name as repo_name").
+			Join("INNER", "repository", "repository.id = push_mirror.repo_id").
+			Limit(limit, start).Find(&mirrors); err != nil {
 			return err
 		}
 
@@ -128,7 +136,7 @@ func migratePushMirrors(x *xorm.Engine) error {
 		start += len(mirrors)
 
 		for _, m := range mirrors {
-			remoteAddress, err := getRemoteAddress(sess, m.RepoID, m.RemoteName)
+			remoteAddress, err := getRemoteAddress(m.RepoOwner, m.RepoName, m.RemoteName)
 			if err != nil {
 				return err
 			}
@@ -153,25 +161,12 @@ func migratePushMirrors(x *xorm.Engine) error {
 	return sess.Commit()
 }
 
-func getRemoteAddress(sess *xorm.Session, repoID int64, remoteName string) (string, error) {
-	var ownerName string
-	var repoName string
-	has, err := sess.
-		Table("repository").
-		Cols("owner_name", "lower_name").
-		Where("id=?", repoID).
-		Get(&ownerName, &repoName)
-	if err != nil {
-		return "", err
-	} else if !has {
-		return "", fmt.Errorf("repository [%v] not found", repoID)
-	}
-
+func getRemoteAddress(ownerName, repoName, remoteName string) (string, error) {
 	repoPath := filepath.Join(setting.RepoRootPath, strings.ToLower(ownerName), strings.ToLower(repoName)+".git")
 
 	remoteURL, err := git.GetRemoteAddress(context.Background(), repoPath, remoteName)
 	if err != nil {
-		return "", err
+		return "", fmt.Errorf("get remote %s's address of %s/%s failed: %v", remoteName, ownerName, repoName, err)
 	}
 
 	u, err := giturl.Parse(remoteURL)
diff --git a/models/migrations/v1_21/v277.go b/models/migrations/v1_21/v277.go
new file mode 100644
index 0000000000000..12529160b754b
--- /dev/null
+++ b/models/migrations/v1_21/v277.go
@@ -0,0 +1,16 @@
+// Copyright 2023 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package v1_21 //nolint
+
+import (
+	"xorm.io/xorm"
+)
+
+func AddIndexToIssueUserIssueID(x *xorm.Engine) error {
+	type IssueUser struct {
+		IssueID int64 `xorm:"INDEX"`
+	}
+
+	return x.Sync(new(IssueUser))
+}
diff --git a/modules/indexer/issues/indexer_test.go b/modules/indexer/issues/indexer_test.go
index 0e36d21313737..7241f6313c891 100644
--- a/modules/indexer/issues/indexer_test.go
+++ b/modules/indexer/issues/indexer_test.go
@@ -180,6 +180,21 @@ func searchIssueByID(t *testing.T) {
 			},
 			[]int64{11, 6, 5, 3, 2, 1},
 		},
+		{
+			// issue 20 request user 15 and team 5 which user 15 belongs to
+			// the review request number of issue 20 should be 1
+			SearchOptions{
+				ReviewRequestedID: int64Pointer(15),
+			},
+			[]int64{12, 20},
+		},
+		{
+			// user 20 approved the issue 20, so return nothing
+			SearchOptions{
+				ReviewRequestedID: int64Pointer(20),
+			},
+			[]int64{},
+		},
 	}
 
 	for _, test := range tests {
@@ -206,7 +221,7 @@ func searchIssueIsPull(t *testing.T) {
 			SearchOptions{
 				IsPull: util.OptionalBoolTrue,
 			},
-			[]int64{12, 11, 19, 9, 8, 3, 2},
+			[]int64{12, 11, 20, 19, 9, 8, 3, 2},
 		},
 	}
 	for _, test := range tests {
@@ -227,7 +242,7 @@ func searchIssueIsClosed(t *testing.T) {
 			SearchOptions{
 				IsClosed: util.OptionalBoolFalse,
 			},
-			[]int64{17, 16, 15, 14, 13, 12, 11, 6, 19, 18, 10, 7, 9, 8, 3, 2, 1},
+			[]int64{17, 16, 15, 14, 13, 12, 11, 20, 6, 19, 18, 10, 7, 9, 8, 3, 2, 1},
 		},
 		{
 			SearchOptions{
@@ -293,7 +308,7 @@ func searchIssueByLabelID(t *testing.T) {
 			SearchOptions{
 				ExcludedLabelIDs: []int64{1},
 			},
-			[]int64{17, 16, 15, 14, 13, 12, 11, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3},
+			[]int64{17, 16, 15, 14, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3},
 		},
 	}
 	for _, test := range tests {
@@ -317,7 +332,7 @@ func searchIssueByTime(t *testing.T) {
 			SearchOptions{
 				UpdatedAfterUnix: int64Pointer(0),
 			},
-			[]int64{17, 16, 15, 14, 13, 12, 11, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2, 1},
+			[]int64{17, 16, 15, 14, 13, 12, 11, 20, 6, 5, 19, 18, 10, 7, 4, 9, 8, 3, 2, 1},
 		},
 	}
 	for _, test := range tests {
@@ -338,7 +353,7 @@ func searchIssueWithOrder(t *testing.T) {
 			SearchOptions{
 				SortBy: internal.SortByCreatedAsc,
 			},
-			[]int64{1, 2, 3, 8, 9, 4, 7, 10, 18, 19, 5, 6, 11, 12, 13, 14, 15, 16, 17},
+			[]int64{1, 2, 3, 8, 9, 4, 7, 10, 18, 19, 5, 6, 20, 11, 12, 13, 14, 15, 16, 17},
 		},
 	}
 	for _, test := range tests {
@@ -393,7 +408,7 @@ func searchIssueWithPaginator(t *testing.T) {
 				},
 			},
 			[]int64{17, 16, 15, 14, 13},
-			19,
+			20,
 		},
 	}
 	for _, test := range tests {
diff --git a/options/locale/locale_ja-JP.ini b/options/locale/locale_ja-JP.ini
index c78c6811b44b4..10e31697a76ce 100644
--- a/options/locale/locale_ja-JP.ini
+++ b/options/locale/locale_ja-JP.ini
@@ -2717,6 +2717,7 @@ dashboard.gc_lfs=LFSメタオブジェクトのガベージコレクション
 dashboard.stop_zombie_tasks=ゾンビタスクを停止
 dashboard.stop_endless_tasks=終わらないタスクを停止
 dashboard.cancel_abandoned_jobs=放置されたままのジョブをキャンセル
+dashboard.start_schedule_tasks=スケジュールタスクを開始
 
 users.user_manage_panel=ユーザーアカウント管理
 users.new_account=ユーザーアカウントを作成
@@ -2725,6 +2726,9 @@ users.full_name=フルネーム
 users.activated=アクティベート済み
 users.admin=管理者
 users.restricted=制限あり
+users.reserved=予約済み
+users.bot=Bot
+users.remote=リモート
 users.2fa=2FA
 users.repos=リポジトリ
 users.created=作成日
@@ -2771,6 +2775,7 @@ users.list_status_filter.is_prohibit_login=ログインを禁止
 users.list_status_filter.not_prohibit_login=ログインを許可
 users.list_status_filter.is_2fa_enabled=2要素認証有効
 users.list_status_filter.not_2fa_enabled=2要素認証無効
+users.details=ユーザーの詳細
 
 emails.email_manage_panel=ユーザーメールアドレスの管理
 emails.primary=プライマリー
@@ -2806,6 +2811,7 @@ repos.size=サイズ
 packages.package_manage_panel=パッケージ管理
 packages.total_size=合計サイズ: %s
 packages.unreferenced_size=非参照サイズ: %s
+packages.cleanup=期限切れデータを掃除する
 packages.owner=オーナー
 packages.creator=作成者
 packages.name=名前
@@ -2912,6 +2918,7 @@ auths.sspi_default_language=ユーザーのデフォルトの言語
 auths.sspi_default_language_helper=SSPI認証処理によって自動的に作成されるユーザーのデフォルトの言語です。 言語を自動検出する方が良い場合は空のままにしてください。
 auths.tips=ヒント
 auths.tips.oauth2.general=OAuth2認証
+auths.tips.oauth2.general.tip=新しいOAuth2認証を登録するときは、コールバック/リダイレクトURLは以下になります:
 auths.tip.oauth2_provider=OAuth2プロバイダー
 auths.tip.bitbucket=新しいOAuthコンシューマーを https://bitbucket.org/account/user/<あなたのユーザー名>/oauth-consumers/new から登録し、"アカウント" に "読み取り" 権限を追加してください。
 auths.tip.nextcloud=新しいOAuthコンシューマーを、インスタンスのメニュー "Settings -> Security -> OAuth 2.0 client" から登録してください。
@@ -2952,6 +2959,7 @@ config.disable_router_log=ルーターのログが無効
 config.run_user=実行ユーザー名
 config.run_mode=実行モード
 config.git_version=Gitバージョン
+config.app_data_path=Appデータパス
 config.repo_root_path=リポジトリのルートパス
 config.lfs_root_path=LFSルートパス
 config.log_file_root_path=ログの保存先パス
diff --git a/routers/api/v1/org/team.go b/routers/api/v1/org/team.go
index 519572ee51882..83cbfe68d0ff8 100644
--- a/routers/api/v1/org/team.go
+++ b/routers/api/v1/org/team.go
@@ -248,7 +248,7 @@ func CreateTeam(ctx *context.APIContext) {
 		return
 	}
 
-	apiTeam, err := convert.ToTeam(ctx, team)
+	apiTeam, err := convert.ToTeam(ctx, team, true)
 	if err != nil {
 		ctx.InternalServerError(err)
 		return
diff --git a/routers/web/user/profile.go b/routers/web/user/profile.go
index 71d10ab4c1251..d9a0124020c12 100644
--- a/routers/web/user/profile.go
+++ b/routers/web/user/profile.go
@@ -77,8 +77,9 @@ func userProfile(ctx *context.Context) {
 
 func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileGitRepo *git.Repository, profileReadme *git.Blob) {
 	// if there is a profile readme, default to "overview" page, otherwise, default to "repositories" page
+	// if there is not a profile readme, the overview tab should be treated as the repositories tab
 	tab := ctx.FormString("tab")
-	if tab == "" {
+	if tab == "" || tab == "overview" {
 		if profileReadme != nil {
 			tab = "overview"
 		} else {
@@ -157,10 +158,10 @@ func prepareUserProfileTabData(ctx *context.Context, showPrivate bool, profileGi
 	switch tab {
 	case "followers":
 		ctx.Data["Cards"] = followers
-		total = int(count)
+		total = int(numFollowers)
 	case "following":
 		ctx.Data["Cards"] = following
-		total = int(count)
+		total = int(numFollowing)
 	case "activity":
 		date := ctx.FormString("date")
 		pagingNum = setting.UI.FeedPagingNum
diff --git a/services/auth/source/oauth2/providers.go b/services/auth/source/oauth2/providers.go
index 7572aa20c0a13..e3a0cb0335dba 100644
--- a/services/auth/source/oauth2/providers.go
+++ b/services/auth/source/oauth2/providers.go
@@ -22,7 +22,7 @@ import (
 type Provider interface {
 	Name() string
 	DisplayName() string
-	IconHTML() template.HTML
+	IconHTML(size int) template.HTML
 	CustomURLSettings() *CustomURLSettings
 }
 
@@ -54,14 +54,16 @@ func (p *AuthSourceProvider) DisplayName() string {
 	return p.sourceName
 }
 
-func (p *AuthSourceProvider) IconHTML() template.HTML {
+func (p *AuthSourceProvider) IconHTML(size int) template.HTML {
 	if p.iconURL != "" {
-		img := fmt.Sprintf(`<img class="gt-object-contain gt-mr-3" width="20" height="20" src="%s" alt="%s">`,
+		img := fmt.Sprintf(`<img class="gt-object-contain gt-mr-3" width="%d" height="%d" src="%s" alt="%s">`,
+			size,
+			size,
 			html.EscapeString(p.iconURL), html.EscapeString(p.DisplayName()),
 		)
 		return template.HTML(img)
 	}
-	return p.GothProvider.IconHTML()
+	return p.GothProvider.IconHTML(size)
 }
 
 // Providers contains the map of registered OAuth2 providers in Gitea (based on goth)
diff --git a/services/auth/source/oauth2/providers_base.go b/services/auth/source/oauth2/providers_base.go
index 5ba06febaf70f..5b6694487bf98 100644
--- a/services/auth/source/oauth2/providers_base.go
+++ b/services/auth/source/oauth2/providers_base.go
@@ -27,7 +27,7 @@ func (b *BaseProvider) DisplayName() string {
 }
 
 // IconHTML returns icon HTML for this provider
-func (b *BaseProvider) IconHTML() template.HTML {
+func (b *BaseProvider) IconHTML(size int) template.HTML {
 	svgName := "gitea-" + b.name
 	switch b.name {
 	case "gplus":
@@ -35,10 +35,10 @@ func (b *BaseProvider) IconHTML() template.HTML {
 	case "github":
 		svgName = "octicon-mark-github"
 	}
-	svgHTML := svg.RenderHTML(svgName, 20, "gt-mr-3")
+	svgHTML := svg.RenderHTML(svgName, size, "gt-mr-3")
 	if svgHTML == "" {
 		log.Error("No SVG icon for oauth2 provider %q", b.name)
-		svgHTML = svg.RenderHTML("gitea-openid", 20, "gt-mr-3")
+		svgHTML = svg.RenderHTML("gitea-openid", size, "gt-mr-3")
 	}
 	return svgHTML
 }
diff --git a/services/auth/source/oauth2/providers_openid.go b/services/auth/source/oauth2/providers_openid.go
index 54530ae8a85b1..a4dcfcafc7e35 100644
--- a/services/auth/source/oauth2/providers_openid.go
+++ b/services/auth/source/oauth2/providers_openid.go
@@ -28,8 +28,8 @@ func (o *OpenIDProvider) DisplayName() string {
 }
 
 // IconHTML returns icon HTML for this provider
-func (o *OpenIDProvider) IconHTML() template.HTML {
-	return svg.RenderHTML("gitea-openid", 20, "gt-mr-3")
+func (o *OpenIDProvider) IconHTML(size int) template.HTML {
+	return svg.RenderHTML("gitea-openid", size, "gt-mr-3")
 }
 
 // CreateGothProvider creates a GothProvider from this Provider
diff --git a/services/gitdiff/gitdiff.go b/services/gitdiff/gitdiff.go
index 4cc093e65debd..fd0f32717c4b6 100644
--- a/services/gitdiff/gitdiff.go
+++ b/services/gitdiff/gitdiff.go
@@ -1343,7 +1343,7 @@ outer:
 		}
 	}
 
-	return diff, err
+	return diff, nil
 }
 
 // CommentAsDiff returns c.Patch as *Diff
diff --git a/services/wiki/wiki_test.go b/services/wiki/wiki_test.go
index 0621456f3e82d..81a688b046a7c 100644
--- a/services/wiki/wiki_test.go
+++ b/services/wiki/wiki_test.go
@@ -168,7 +168,9 @@ func TestRepository_AddWikiPage(t *testing.T) {
 			assert.NoError(t, AddWikiPage(git.DefaultContext, doer, repo, webPath, wikiContent, commitMsg))
 			// Now need to show that the page has been added:
 			gitRepo, err := git.OpenRepository(git.DefaultContext, repo.WikiPath())
-			assert.NoError(t, err)
+			if !assert.NoError(t, err) {
+				return
+			}
 			defer gitRepo.Close()
 			masterTree, err := gitRepo.GetTree(DefaultBranch)
 			assert.NoError(t, err)
@@ -238,7 +240,9 @@ func TestRepository_DeleteWikiPage(t *testing.T) {
 
 	// Now need to show that the page has been added:
 	gitRepo, err := git.OpenRepository(git.DefaultContext, repo.WikiPath())
-	assert.NoError(t, err)
+	if !assert.NoError(t, err) {
+		return
+	}
 	defer gitRepo.Close()
 	masterTree, err := gitRepo.GetTree(DefaultBranch)
 	assert.NoError(t, err)
@@ -251,8 +255,10 @@ func TestPrepareWikiFileName(t *testing.T) {
 	unittest.PrepareTestEnv(t)
 	repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
 	gitRepo, err := git.OpenRepository(git.DefaultContext, repo.WikiPath())
+	if !assert.NoError(t, err) {
+		return
+	}
 	defer gitRepo.Close()
-	assert.NoError(t, err)
 
 	tests := []struct {
 		name      string
@@ -303,8 +309,10 @@ func TestPrepareWikiFileName_FirstPage(t *testing.T) {
 	assert.NoError(t, err)
 
 	gitRepo, err := git.OpenRepository(git.DefaultContext, tmpDir)
+	if !assert.NoError(t, err) {
+		return
+	}
 	defer gitRepo.Close()
-	assert.NoError(t, err)
 
 	existence, newWikiPath, err := prepareGitPath(gitRepo, "Home")
 	assert.False(t, existence)
diff --git a/templates/admin/auth/edit.tmpl b/templates/admin/auth/edit.tmpl
index 6dfa86d9dd154..814bddd8a4555 100644
--- a/templates/admin/auth/edit.tmpl
+++ b/templates/admin/auth/edit.tmpl
@@ -428,7 +428,7 @@
 				</div>
 
 				<div class="field">
-					<button class="ui green button">{{.locale.Tr "admin.auths.update"}}</button>
+					<button class="ui primary button">{{.locale.Tr "admin.auths.update"}}</button>
 					<button class="ui red button delete-button" data-url="{{$.Link}}/delete" data-id="{{.Source.ID}}">{{.locale.Tr "admin.auths.delete"}}</button>
 				</div>
 			</form>
diff --git a/templates/admin/auth/new.tmpl b/templates/admin/auth/new.tmpl
index 37d1635c11df0..31efa62e713df 100644
--- a/templates/admin/auth/new.tmpl
+++ b/templates/admin/auth/new.tmpl
@@ -73,7 +73,7 @@
 				</div>
 
 				<div class="field">
-					<button class="ui green button">{{.locale.Tr "admin.auths.new"}}</button>
+					<button class="ui primary button">{{.locale.Tr "admin.auths.new"}}</button>
 				</div>
 			</form>
 		</div>
diff --git a/templates/admin/base/search.tmpl b/templates/admin/base/search.tmpl
index 19977f05a9bcc..865cc8830f308 100644
--- a/templates/admin/base/search.tmpl
+++ b/templates/admin/base/search.tmpl
@@ -9,8 +9,8 @@
 	<div class="ui dropdown type jump item gt-mr-0">
 		<span class="text">
 			{{.locale.Tr "repo.issues.filter_sort"}}
-			{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 		</span>
+		{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 		<div class="menu">
 			<a class="{{if or (eq .SortType "oldest") (not .SortType)}}active {{end}}item" href="{{$.Link}}?sort=oldest&q={{$.Keyword}}">{{.locale.Tr "repo.issues.filter_sort.oldest"}}</a>
 			<a class="{{if eq .SortType "newest"}}active {{end}}item" href="{{$.Link}}?sort=newest&q={{$.Keyword}}">{{.locale.Tr "repo.issues.filter_sort.latest"}}</a>
diff --git a/templates/admin/config.tmpl b/templates/admin/config.tmpl
index 36d9bcb8a5e2d..c29d1dbf30ef2 100644
--- a/templates/admin/config.tmpl
+++ b/templates/admin/config.tmpl
@@ -238,7 +238,7 @@
 							<div class="ui tiny input">
 								<input type="email" name="email" placeholder="{{.locale.Tr "admin.config.test_email_placeholder"}}" size="29" required>
 							</div>
-							<button class="ui tiny green button">{{.locale.Tr "admin.config.send_test_mail_submit"}}</button>
+							<button class="ui tiny primary button">{{.locale.Tr "admin.config.send_test_mail_submit"}}</button>
 						</form>
 					</dd>
 				{{end}}
diff --git a/templates/admin/cron.tmpl b/templates/admin/cron.tmpl
index c15461943512c..354cd18ed554d 100644
--- a/templates/admin/cron.tmpl
+++ b/templates/admin/cron.tmpl
@@ -20,7 +20,7 @@
 				<tbody>
 					{{range .Entries}}
 						<tr>
-							<td><button type="submit" class="ui green button" name="op" value="{{.Name}}" title="{{$.locale.Tr "admin.dashboard.operation_run"}}">{{svg "octicon-triangle-right"}}</button></td>
+							<td><button type="submit" class="ui primary button" name="op" value="{{.Name}}" title="{{$.locale.Tr "admin.dashboard.operation_run"}}">{{svg "octicon-triangle-right"}}</button></td>
 							<td>{{$.locale.Tr (printf "admin.dashboard.%s" .Name)}}</td>
 							<td>{{.Spec}}</td>
 							<td>{{DateTime "full" .Next}}</td>
diff --git a/templates/admin/dashboard.tmpl b/templates/admin/dashboard.tmpl
index 8312fba039aab..69c0376d6e041 100644
--- a/templates/admin/dashboard.tmpl
+++ b/templates/admin/dashboard.tmpl
@@ -15,55 +15,55 @@
 					<tbody>
 						<tr>
 							<td>{{.locale.Tr "admin.dashboard.delete_inactive_accounts"}}</td>
-							<td class="text right"><button type="submit" class="ui green button" name="op" value="delete_inactive_accounts">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
+							<td class="text right"><button type="submit" class="ui primary button" name="op" value="delete_inactive_accounts">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
 						</tr>
 						<tr>
 							<td>{{.locale.Tr "admin.dashboard.delete_repo_archives"}}</td>
-							<td class="text right"><button type="submit" class="ui green button" name="op" value="delete_repo_archives">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
+							<td class="text right"><button type="submit" class="ui primary button" name="op" value="delete_repo_archives">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
 						</tr>
 						<tr>
 							<td>{{.locale.Tr "admin.dashboard.delete_missing_repos"}}</td>
-							<td class="text right"><button type="submit" class="ui green button" name="op" value="delete_missing_repos">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
+							<td class="text right"><button type="submit" class="ui primary button" name="op" value="delete_missing_repos">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
 						</tr>
 						<tr>
 							<td>{{.locale.Tr "admin.dashboard.git_gc_repos"}}</td>
-							<td class="text right"><button type="submit" class="ui green button" name="op" value="git_gc_repos">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
+							<td class="text right"><button type="submit" class="ui primary button" name="op" value="git_gc_repos">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
 						</tr>
 						{{if and (not .SSH.Disabled) (not .SSH.StartBuiltinServer)}}
 							<tr>
 								<td>{{.locale.Tr "admin.dashboard.resync_all_sshkeys"}}<br>
 								{{.locale.Tr "admin.dashboard.resync_all_sshkeys.desc"}}</td>
-								<td class="text right"><button type="submit" class="ui green button" name="op" value="resync_all_sshkeys">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
+								<td class="text right"><button type="submit" class="ui primary button" name="op" value="resync_all_sshkeys">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
 							</tr>
 							<tr>
 								<td>{{.locale.Tr "admin.dashboard.resync_all_sshprincipals"}}<br>
 								{{.locale.Tr "admin.dashboard.resync_all_sshprincipals.desc"}}</td>
-								<td class="text right"><button type="submit" class="ui green button" name="op" value="resync_all_sshprincipals">{{svg "octicon-play" 16}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
+								<td class="text right"><button type="submit" class="ui primary button" name="op" value="resync_all_sshprincipals">{{svg "octicon-play" 16}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
 							</tr>
 						{{end}}
 						<tr>
 							<td>{{.locale.Tr "admin.dashboard.resync_all_hooks"}}</td>
-							<td class="text right"><button type="submit" class="ui green button" name="op" value="resync_all_hooks">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
+							<td class="text right"><button type="submit" class="ui primary button" name="op" value="resync_all_hooks">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
 						</tr>
 						<tr>
 							<td>{{.locale.Tr "admin.dashboard.reinit_missing_repos"}}</td>
-							<td class="text right"><button type="submit" class="ui green button" name="op" value="reinit_missing_repos">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
+							<td class="text right"><button type="submit" class="ui primary button" name="op" value="reinit_missing_repos">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
 						</tr>
 						<tr>
 							<td>{{.locale.Tr "admin.dashboard.sync_external_users"}}</td>
-							<td class="text right"><button type="submit" class="ui green button" name="op" value="sync_external_users">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
+							<td class="text right"><button type="submit" class="ui primary button" name="op" value="sync_external_users">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
 						</tr>
 						<tr>
 							<td>{{.locale.Tr "admin.dashboard.repo_health_check"}}</td>
-							<td class="text right"><button type="submit" class="ui green button" name="op" value="repo_health_check">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
+							<td class="text right"><button type="submit" class="ui primary button" name="op" value="repo_health_check">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
 						</tr>
 						<tr>
 							<td>{{.locale.Tr "admin.dashboard.delete_generated_repository_avatars"}}</td>
-							<td class="text right"><button type="submit" class="ui green button" name="op" value="delete_generated_repository_avatars">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
+							<td class="text right"><button type="submit" class="ui primary button" name="op" value="delete_generated_repository_avatars">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
 						</tr>
 						<tr>
 							<td>{{.locale.Tr "admin.dashboard.sync_repo_branches"}}</td>
-							<td class="text right"><button type="submit" class="ui green button" name="op" value="sync_repo_branches">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
+							<td class="text right"><button type="submit" class="ui primary button" name="op" value="sync_repo_branches">{{svg "octicon-play"}} {{.locale.Tr "admin.dashboard.operation_run"}}</button></td>
 						</tr>
 					</tbody>
 				</table>
diff --git a/templates/admin/emails/list.tmpl b/templates/admin/emails/list.tmpl
index 153877174bf49..445f57bfe3c4c 100644
--- a/templates/admin/emails/list.tmpl
+++ b/templates/admin/emails/list.tmpl
@@ -15,8 +15,8 @@
 				<div class="ui dropdown type jump item gt-mr-0">
 					<span class="text">
 						{{.locale.Tr "repo.issues.filter_sort"}}
-						{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 					</span>
+					{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 					<div class="menu">
 						<a class="{{if or (eq .SortType "email") (not .SortType)}}active {{end}}item" href="{{$.Link}}?sort=email&q={{$.Keyword}}">{{.locale.Tr "admin.emails.filter_sort.email"}}</a>
 						<a class="{{if eq .SortType "reverseemail"}}active {{end}}item" href="{{$.Link}}?sort=reverseemail&q={{$.Keyword}}">{{.locale.Tr "admin.emails.filter_sort.email_reverse"}}</a>
diff --git a/templates/admin/repo/search.tmpl b/templates/admin/repo/search.tmpl
index 0d98e3e4f27db..fa39e0b40a4c3 100644
--- a/templates/admin/repo/search.tmpl
+++ b/templates/admin/repo/search.tmpl
@@ -9,8 +9,8 @@
 	<div class="ui dropdown type jump item gt-mr-0">
 		<span class="text">
 			{{.locale.Tr "repo.issues.filter_sort"}}
-				{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 		</span>
+		{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 		<div class="menu">
 			<a class="{{if or (eq .SortType "oldest") (not .SortType)}}active {{end}}item" href="{{$.Link}}?sort=oldest&q={{$.Keyword}}">{{.locale.Tr "repo.issues.filter_sort.oldest"}}</a>
 			<a class="{{if eq .SortType "newest"}}active {{end}}item" href="{{$.Link}}?sort=newest&q={{$.Keyword}}">{{.locale.Tr "repo.issues.filter_sort.latest"}}</a>
diff --git a/templates/admin/repo/unadopted.tmpl b/templates/admin/repo/unadopted.tmpl
index 7b86b0defd76f..a903425b21252 100644
--- a/templates/admin/repo/unadopted.tmpl
+++ b/templates/admin/repo/unadopted.tmpl
@@ -23,7 +23,7 @@
 							<div class="item gt-df gt-ac">
 								<span class="gt-f1"> {{svg "octicon-file-directory-fill"}} {{$dir}}</span>
 								<div>
-									<button class="ui button green show-modal gt-p-3" data-modal="#adopt-unadopted-modal-{{$dirI}}">{{svg "octicon-plus"}} {{$.locale.Tr "repo.adopt_preexisting_label"}}</button>
+									<button class="ui button primary show-modal gt-p-3" data-modal="#adopt-unadopted-modal-{{$dirI}}">{{svg "octicon-plus"}} {{$.locale.Tr "repo.adopt_preexisting_label"}}</button>
 									<div class="ui g-modal-confirm modal" id="adopt-unadopted-modal-{{$dirI}}">
 										<div class="header">
 											<span class="label">{{$.locale.Tr "repo.adopt_preexisting"}}</span>
diff --git a/templates/admin/user/edit.tmpl b/templates/admin/user/edit.tmpl
index f7b70d8aff820..68945ef0f359e 100644
--- a/templates/admin/user/edit.tmpl
+++ b/templates/admin/user/edit.tmpl
@@ -147,7 +147,7 @@
 				<div class="divider"></div>
 
 				<div class="field">
-					<button class="ui green button">{{.locale.Tr "admin.users.update_profile"}}</button>
+					<button class="ui primary button">{{.locale.Tr "admin.users.update_profile"}}</button>
 					<button class="ui red button show-modal" data-modal="#delete-user-modal">{{.locale.Tr "admin.users.delete_account"}}</button>
 				</div>
 			</form>
@@ -185,7 +185,7 @@
 				</div>
 
 				<div class="field">
-					<button class="ui green button">{{$.locale.Tr "settings.update_avatar"}}</button>
+					<button class="ui primary button">{{$.locale.Tr "settings.update_avatar"}}</button>
 					<button class="ui red button link-action" data-url="./avatar/delete">{{$.locale.Tr "settings.delete_current_avatar"}}</button>
 				</div>
 			</form>
diff --git a/templates/admin/user/list.tmpl b/templates/admin/user/list.tmpl
index 7334828533e67..2c8d805177a71 100644
--- a/templates/admin/user/list.tmpl
+++ b/templates/admin/user/list.tmpl
@@ -13,7 +13,8 @@
 				<div class="ui right floated secondary filter menu">
 					<!-- Status Filter Menu Item -->
 					<div class="ui dropdown type jump item">
-						<span class="text">{{.locale.Tr "admin.users.list_status_filter.menu_text"}} {{svg "octicon-triangle-down" 14 "dropdown icon"}}</span>
+						<span class="text">{{.locale.Tr "admin.users.list_status_filter.menu_text"}}</span>
+						{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 						<div class="menu">
 							<a class="item j-reset-status-filter">{{.locale.Tr "admin.users.list_status_filter.reset"}}</a>
 							<div class="divider"></div>
@@ -37,8 +38,9 @@
 					<!-- Sort Menu Item -->
 					<div class="ui dropdown type jump item">
 						<span class="text">
-							{{.locale.Tr "repo.issues.filter_sort"}} {{svg "octicon-triangle-down" 14 "dropdown icon"}}
+							{{.locale.Tr "repo.issues.filter_sort"}}
 						</span>
+						{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 						<div class="menu">
 							<button class="item" name="sort" value="oldest">{{.locale.Tr "repo.issues.filter_sort.oldest"}}</button>
 							<button class="item" name="sort" value="newest">{{.locale.Tr "repo.issues.filter_sort.latest"}}</button>
diff --git a/templates/admin/user/new.tmpl b/templates/admin/user/new.tmpl
index 691d63aeade3e..d4bc742f76ca9 100644
--- a/templates/admin/user/new.tmpl
+++ b/templates/admin/user/new.tmpl
@@ -82,7 +82,7 @@
 				{{end}}
 
 				<div class="field">
-					<button class="ui green button">{{.locale.Tr "admin.users.new_account"}}</button>
+					<button class="ui primary button">{{.locale.Tr "admin.users.new_account"}}</button>
 				</div>
 			</form>
 		</div>
diff --git a/templates/base/modal_actions_confirm.tmpl b/templates/base/modal_actions_confirm.tmpl
index 6cf3ecbe3ed7f..5b5f211fb106b 100644
--- a/templates/base/modal_actions_confirm.tmpl
+++ b/templates/base/modal_actions_confirm.tmpl
@@ -4,7 +4,7 @@ Template Attributes:
 
 Two buttons (negative, positive):
 * ModalButtonTypes: "yes" (default) or "confirm"
-* ModalButtonColors: "green" (default) / "blue" / "yellow"
+* ModalButtonColors: "primary" (default) / "blue" / "yellow"
 * ModalButtonCancelText
 * ModalButtonOkText
 
@@ -26,13 +26,13 @@ The ".ok.button" and ".cancel.button" selectors are also used by Fomantic Modal
 		{{if .ModalButtonCancelText}}{{$textNegitive = .ModalButtonCancelText}}{{end}}
 		{{if .ModalButtonOkText}}{{$textPositive = .ModalButtonOkText}}{{end}}
 
-		{{$stylePositive := "green"}}
+		{{$stylePositive := "primary"}}
 		{{if eq .ModalButtonColors "blue"}}
 			{{$stylePositive = "blue"}}
 		{{else if eq .ModalButtonColors "yellow"}}
 			{{$stylePositive = "yellow"}}
 		{{end}}
-		<button class="ui basic cancel button">{{svg "octicon-x"}} {{$textNegitive}}</button>
+		<button class="ui cancel button">{{svg "octicon-x"}} {{$textNegitive}}</button>
 		<button class="ui {{$stylePositive}} ok button">{{svg "octicon-check"}} {{$textPositive}}</button>
 	{{end}}
 </div>
diff --git a/templates/devtest/flex-list.tmpl b/templates/devtest/flex-list.tmpl
index 80cd22440d48e..bbcbc4e816fb8 100644
--- a/templates/devtest/flex-list.tmpl
+++ b/templates/devtest/flex-list.tmpl
@@ -27,10 +27,10 @@
 					<button class="ui tiny red button">
 						{{svg "octicon-warning" 14}} CJK文本测试
 					</button>
-					<button class="ui tiny green button">
+					<button class="ui tiny primary button">
 						{{svg "octicon-info" 14}} Button
 					</button>
-					<button class="ui tiny green button">
+					<button class="ui tiny primary button">
 						Button with long text
 					</button>
 				</div>
diff --git a/templates/devtest/gitea-ui.tmpl b/templates/devtest/gitea-ui.tmpl
index b3b68c4dbade2..258b72f8cd5f0 100644
--- a/templates/devtest/gitea-ui.tmpl
+++ b/templates/devtest/gitea-ui.tmpl
@@ -31,8 +31,8 @@
 					<h2>Recommended colors:</h2>
 					<button class="ui red button">Red</button>
 					<button class="ui basic red button">Basic Red</button>
-					<button class="ui green button">Green</button>
-					<button class="ui basic green button">Basic Green</button>
+					<button class="ui primary button">Green</button>
+					<button class="ui basic primary button">Basic Green</button>
 					<button class="ui blue button">Blue</button>
 					<button class="ui basic blue button">Basic Blue</button>
 					<button class="ui orange button">Orange</button>
diff --git a/templates/explore/repo_search.tmpl b/templates/explore/repo_search.tmpl
index 0731368e85da2..e684d2a1c4aba 100644
--- a/templates/explore/repo_search.tmpl
+++ b/templates/explore/repo_search.tmpl
@@ -16,8 +16,8 @@
 	<div class="ui dropdown type jump item gt-mr-0">
 		<span class="text">
 			{{.locale.Tr "repo.issues.filter_sort"}}
-				{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 		</span>
+		{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 		<div class="menu">
 			<a class="{{if eq .SortType "newest"}}active {{end}}item" href="{{$.Link}}?tab={{$.TabName}}&sort=newest&q={{$.Keyword}}&language={{$.Language}}">{{.locale.Tr "repo.issues.filter_sort.latest"}}</a>
 			<a class="{{if eq .SortType "oldest"}}active {{end}}item" href="{{$.Link}}?tab={{$.TabName}}&sort=oldest&q={{$.Keyword}}&language={{$.Language}}">{{.locale.Tr "repo.issues.filter_sort.oldest"}}</a>
diff --git a/templates/explore/search.tmpl b/templates/explore/search.tmpl
index b0041ee3ce25e..1c35ee00fa74b 100644
--- a/templates/explore/search.tmpl
+++ b/templates/explore/search.tmpl
@@ -9,8 +9,8 @@
 	<div class="ui dropdown type jump item gt-mr-0">
 		<span class="text">
 			{{.locale.Tr "repo.issues.filter_sort"}}
-			{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 		</span>
+		{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 		<div class="menu">
 			<a class="{{if eq .SortType "newest"}}active {{end}}item" href="{{$.Link}}?sort=newest&q={{$.Keyword}}">{{.locale.Tr "repo.issues.filter_sort.latest"}}</a>
 			<a class="{{if eq .SortType "oldest"}}active {{end}}item" href="{{$.Link}}?sort=oldest&q={{$.Keyword}}">{{.locale.Tr "repo.issues.filter_sort.oldest"}}</a>
diff --git a/templates/org/create.tmpl b/templates/org/create.tmpl
index 966150aa93b92..cd2ffbb68e1eb 100644
--- a/templates/org/create.tmpl
+++ b/templates/org/create.tmpl
@@ -45,7 +45,7 @@
 
 					<div class="inline field">
 						<label></label>
-						<button class="ui green button">
+						<button class="ui primary button">
 							{{.locale.Tr "org.create_org"}}
 						</button>
 					</div>
diff --git a/templates/org/home.tmpl b/templates/org/home.tmpl
index 72be948650e45..18d5282a31315 100644
--- a/templates/org/home.tmpl
+++ b/templates/org/home.tmpl
@@ -47,9 +47,9 @@
 			<div class="ui five wide column">
 				{{if .CanCreateOrgRepo}}
 					<div class="center aligned">
-						<a class="ui green button" href="{{AppSubUrl}}/repo/create?org={{.Org.ID}}">{{.locale.Tr "new_repo"}}</a>
+						<a class="ui primary button" href="{{AppSubUrl}}/repo/create?org={{.Org.ID}}">{{.locale.Tr "new_repo"}}</a>
 						{{if not .DisableNewPullMirrors}}
-							<a class="ui green button" href="{{AppSubUrl}}/repo/migrate?org={{.Org.ID}}&mirror=1">{{.locale.Tr "new_migrate"}}</a>
+							<a class="ui primary button" href="{{AppSubUrl}}/repo/migrate?org={{.Org.ID}}&mirror=1">{{.locale.Tr "new_migrate"}}</a>
 						{{end}}
 					</div>
 					<div class="divider"></div>
diff --git a/templates/org/settings/labels.tmpl b/templates/org/settings/labels.tmpl
index 81dde1745507c..b38481fea3b73 100644
--- a/templates/org/settings/labels.tmpl
+++ b/templates/org/settings/labels.tmpl
@@ -4,7 +4,7 @@
 						<div class="gt-f1">
 							{{$.locale.Tr "org.settings.labels_desc" | Str2html}}
 						</div>
-						<button class="ui small green new-label button">{{.locale.Tr "repo.issues.new_label"}}</button>
+						<button class="ui small primary new-label button">{{.locale.Tr "repo.issues.new_label"}}</button>
 					</div>
 					<div class="divider"></div>
 					{{template "repo/issue/labels/label_new" .}}
diff --git a/templates/org/settings/options.tmpl b/templates/org/settings/options.tmpl
index ecc269481d9e1..0b138094c37ce 100644
--- a/templates/org/settings/options.tmpl
+++ b/templates/org/settings/options.tmpl
@@ -79,7 +79,7 @@
 						{{end}}
 
 						<div class="field">
-							<button class="ui green button">{{$.locale.Tr "org.settings.update_settings"}}</button>
+							<button class="ui primary button">{{$.locale.Tr "org.settings.update_settings"}}</button>
 						</div>
 					</form>
 
@@ -93,7 +93,7 @@
 						</div>
 
 						<div class="field">
-							<button class="ui green button">{{$.locale.Tr "settings.update_avatar"}}</button>
+							<button class="ui primary button">{{$.locale.Tr "settings.update_avatar"}}</button>
 							<button class="ui red button link-action" data-url="{{.Link}}/avatar/delete">{{$.locale.Tr "settings.delete_current_avatar"}}</button>
 						</div>
 					</form>
diff --git a/templates/org/team/invite.tmpl b/templates/org/team/invite.tmpl
index 60332a5f4070b..1b04c0cc2a711 100644
--- a/templates/org/team/invite.tmpl
+++ b/templates/org/team/invite.tmpl
@@ -14,7 +14,7 @@
 			<div class="extra content">
 				<form class="ui form" action="" method="post">
 					{{.CsrfTokenHtml}}
-					<button class="fluid ui green button">{{.locale.Tr "org.teams.join"}}</button>
+					<button class="fluid ui primary button">{{.locale.Tr "org.teams.join"}}</button>
 				</form>
 			</div>
 		</div>
diff --git a/templates/org/team/members.tmpl b/templates/org/team/members.tmpl
index cac0c1ce94744..7c2fab4b80798 100644
--- a/templates/org/team/members.tmpl
+++ b/templates/org/team/members.tmpl
@@ -17,7 +17,7 @@
 									<input class="prompt" name="uname" placeholder="{{.locale.Tr "repo.settings.search_user_placeholder"}}" autocomplete="off" required>
 								</div>
 							</div>
-							<button class="ui green button">{{.locale.Tr "org.teams.add_team_member"}}</button>
+							<button class="ui primary button">{{.locale.Tr "org.teams.add_team_member"}}</button>
 						</form>
 					</div>
 				{{end}}
diff --git a/templates/org/team/new.tmpl b/templates/org/team/new.tmpl
index 3702198ae0932..1d3556400772b 100644
--- a/templates/org/team/new.tmpl
+++ b/templates/org/team/new.tmpl
@@ -133,9 +133,9 @@
 
 						<div class="field">
 							{{if .PageIsOrgTeamsNew}}
-								<button class="ui green button">{{.locale.Tr "org.create_team"}}</button>
+								<button class="ui primary button">{{.locale.Tr "org.create_team"}}</button>
 							{{else}}
-								<button class="ui green button">{{.locale.Tr "org.teams.update_settings"}}</button>
+								<button class="ui primary button">{{.locale.Tr "org.teams.update_settings"}}</button>
 								{{if not (eq .Team.LowerName "owners")}}
 									<button class="ui red button delete-button" data-url="{{.OrgLink}}/teams/{{.Team.Name | PathEscape}}/delete">{{.locale.Tr "org.teams.delete_team"}}</button>
 								{{end}}
diff --git a/templates/org/team/repositories.tmpl b/templates/org/team/repositories.tmpl
index 44fb1ee083279..032a0f496a0ab 100644
--- a/templates/org/team/repositories.tmpl
+++ b/templates/org/team/repositories.tmpl
@@ -17,10 +17,10 @@
 									<input class="prompt" name="repo_name" placeholder="{{.locale.Tr "org.teams.search_repo_placeholder"}}" autocomplete="off" required>
 								</div>
 							</div>
-							<button class="ui green button gt-ml-3">{{.locale.Tr "add"}}</button>
+							<button class="ui primary button gt-ml-3">{{.locale.Tr "add"}}</button>
 						</form>
 						<div class="gt-dib">
-							<button class="ui green button link-action" data-modal-confirm="{{.locale.Tr "org.teams.add_all_repos_desc"}}" data-url="{{$.OrgLink}}/teams/{{$.Team.LowerName | PathEscape}}/action/repo/addall">{{.locale.Tr "add_all"}}</button>
+							<button class="ui primary button link-action" data-modal-confirm="{{.locale.Tr "org.teams.add_all_repos_desc"}}" data-url="{{$.OrgLink}}/teams/{{$.Team.LowerName | PathEscape}}/action/repo/addall">{{.locale.Tr "add_all"}}</button>
 							<button class="ui red button link-action" data-modal-confirm="{{.locale.Tr "org.teams.remove_all_repos_desc"}}" data-url="{{$.OrgLink}}/teams/{{$.Team.LowerName | PathEscape}}/action/repo/removeall">{{.locale.Tr "remove_all"}}</button>
 						</div>
 					</div>
diff --git a/templates/org/team/teams.tmpl b/templates/org/team/teams.tmpl
index a96dd7d6be603..0d7cc06ff9f2c 100644
--- a/templates/org/team/teams.tmpl
+++ b/templates/org/team/teams.tmpl
@@ -5,7 +5,7 @@
 		{{template "base/alert" .}}
 		{{if .IsOrganizationOwner}}
 			<div class="text right">
-				<a class="ui green button" href="{{.OrgLink}}/teams/new">{{svg "octicon-plus"}} {{.locale.Tr "org.create_new_team"}}</a>
+				<a class="ui primary button" href="{{.OrgLink}}/teams/new">{{svg "octicon-plus"}} {{.locale.Tr "org.create_new_team"}}</a>
 			</div>
 			<div class="divider"></div>
 		{{end}}
diff --git a/templates/package/settings.tmpl b/templates/package/settings.tmpl
index af543328f884a..d6c431de037bb 100644
--- a/templates/package/settings.tmpl
+++ b/templates/package/settings.tmpl
@@ -31,7 +31,7 @@
 					</div>
 				</div>
 				<div class="field">
-					<button class="ui green button">{{.locale.Tr "packages.settings.link.button"}}</button>
+					<button class="ui primary button">{{.locale.Tr "packages.settings.link.button"}}</button>
 				</div>
 			</form>
 		</div>
diff --git a/templates/package/shared/cargo.tmpl b/templates/package/shared/cargo.tmpl
index 8831cd8988eb6..9761cb2133c8a 100644
--- a/templates/package/shared/cargo.tmpl
+++ b/templates/package/shared/cargo.tmpl
@@ -8,14 +8,14 @@
 		</div>
 		<form class="field" action="{{.Link}}/cargo/initialize" method="post">
 			{{.CsrfTokenHtml}}
-			<button class="ui green button">{{$.locale.Tr "packages.owner.settings.cargo.initialize"}}</button>
+			<button class="ui primary button">{{$.locale.Tr "packages.owner.settings.cargo.initialize"}}</button>
 		</form>
 		<div class="field">
 			<label>{{$.locale.Tr "packages.owner.settings.cargo.rebuild.description"}}</label>
 		</div>
 		<form class="field" action="{{.Link}}/cargo/rebuild" method="post">
 			{{.CsrfTokenHtml}}
-			<button class="ui green button">{{$.locale.Tr "packages.owner.settings.cargo.rebuild"}}</button>
+			<button class="ui primary button">{{$.locale.Tr "packages.owner.settings.cargo.rebuild"}}</button>
 		</form>
 		<div class="field">
 			<label>{{.locale.Tr "packages.registry.documentation" "Cargo" "https://docs.gitea.com/usage/packages/cargo/" | Safe}}</label>
diff --git a/templates/package/shared/cleanup_rules/edit.tmpl b/templates/package/shared/cleanup_rules/edit.tmpl
index 295ac1a6a4d98..1bfa6260a1ca3 100644
--- a/templates/package/shared/cleanup_rules/edit.tmpl
+++ b/templates/package/shared/cleanup_rules/edit.tmpl
@@ -62,11 +62,11 @@
 		</div>
 		<div class="field">
 			{{if .IsEditRule}}
-			<button class="ui green button" name="action" value="save">{{.locale.Tr "save"}}</button>
+			<button class="ui primary button" name="action" value="save">{{.locale.Tr "save"}}</button>
 			<button class="ui red button" name="action" value="remove">{{.locale.Tr "remove"}}</button>
 			<a class="ui button" href="{{.Link}}/preview">{{.locale.Tr "packages.owner.settings.cleanuprules.preview"}}</a>
 			{{else}}
-			<button class="ui green button" name="action" value="save">{{.locale.Tr "add"}}</button>
+			<button class="ui primary button" name="action" value="save">{{.locale.Tr "add"}}</button>
 			{{end}}
 		</div>
 	</form>
diff --git a/templates/projects/list.tmpl b/templates/projects/list.tmpl
index 0cb619c066012..930cbca7e2015 100644
--- a/templates/projects/list.tmpl
+++ b/templates/projects/list.tmpl
@@ -11,7 +11,7 @@
 			</a>
 		</div>
 		<div class="gt-text-right">
-			<a class="ui small green button" href="{{$.Link}}/new">{{.locale.Tr "repo.projects.new"}}</a>
+			<a class="ui small primary button" href="{{$.Link}}/new">{{.locale.Tr "repo.projects.new"}}</a>
 		</div>
 	</div>
 {{end}}
@@ -33,8 +33,8 @@
 	<div class="list-header-sort ui small dropdown type jump item">
 		<span class="text">
 			{{.locale.Tr "repo.issues.filter_sort"}}
-			{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 		</span>
+		{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 		<div class="menu">
 			<a class="{{if eq .SortType "oldest"}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&sort=oldest&state={{$.State}}">{{.locale.Tr "repo.issues.filter_sort.oldest"}}</a>
 			<a class="{{if eq .SortType "recentupdate"}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&sort=recentupdate&state={{$.State}}">{{.locale.Tr "repo.issues.filter_sort.recentupdate"}}</a>
diff --git a/templates/repo/activity.tmpl b/templates/repo/activity.tmpl
index da4eca7525ed7..444f21e779f8c 100644
--- a/templates/repo/activity.tmpl
+++ b/templates/repo/activity.tmpl
@@ -7,10 +7,8 @@
 			<!-- Period -->
 			<div class="ui floating dropdown jump filter">
 				<div class="ui basic compact button">
-					<span class="text">
-						{{.locale.Tr "repo.activity.period.filter_label"}} <strong>{{.PeriodText}}</strong>
-						{{svg "octicon-triangle-down" 14 "dropdown icon"}}
-					</span>
+					{{.locale.Tr "repo.activity.period.filter_label"}} <strong>{{.PeriodText}}</strong>
+					{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 				</div>
 				<div class="menu">
 					<a class="{{if eq .Period "daily"}}active {{end}}item" href="{{$.RepoLink}}/activity/daily">{{.locale.Tr "repo.activity.period.daily"}}</a>
diff --git a/templates/repo/commit_page.tmpl b/templates/repo/commit_page.tmpl
index 8e56b435536b4..1663e76a4072a 100644
--- a/templates/repo/commit_page.tmpl
+++ b/templates/repo/commit_page.tmpl
@@ -75,7 +75,7 @@
 												<input type="hidden" name="ref" value="{{if $.BranchName}}{{$.BranchName}}{{else}}{{$.Repository.DefaultBranch}}{{end}}">
 												<input type="hidden" name="refType" value="branch">
 												<input type="hidden" id="cherry-pick-type" name="cherry-pick-type"><br>
-												<button type="submit" id="cherry-pick-submit" class="ui green button"></button>
+												<button type="submit" id="cherry-pick-submit" class="ui primary button"></button>
 											</form>
 										</div>
 									</div>
@@ -98,7 +98,7 @@
 
 												<div class="text right actions">
 													<button class="ui cancel button">{{.locale.Tr "settings.cancel"}}</button>
-													<button class="ui green button">{{.locale.Tr "repo.branch.confirm_create_branch"}}</button>
+													<button class="ui primary button">{{.locale.Tr "repo.branch.confirm_create_branch"}}</button>
 												</div>
 											</form>
 										</div>
@@ -123,7 +123,7 @@
 
 												<div class="text right actions">
 													<button class="ui cancel button">{{.locale.Tr "settings.cancel"}}</button>
-													<button class="ui green button">{{.locale.Tr "repo.tag.confirm_create_tag"}}</button>
+													<button class="ui primary button">{{.locale.Tr "repo.tag.confirm_create_tag"}}</button>
 												</div>
 											</form>
 										</div>
diff --git a/templates/repo/commits.tmpl b/templates/repo/commits.tmpl
index 3400dbd251d50..18bb78cb065ef 100644
--- a/templates/repo/commits.tmpl
+++ b/templates/repo/commits.tmpl
@@ -7,9 +7,7 @@
 			<div class="gt-df gt-ac">
 				{{template "repo/branch_dropdown" dict "root" . "ContainerClasses" "gt-mr-2"}}
 				<a href="{{.RepoLink}}/graph" class="ui basic small compact button">
-					<span class="text">
-						{{svg "octicon-git-branch"}}
-					</span>
+					{{svg "octicon-git-branch"}}
 					{{.locale.Tr "repo.commit_graph"}}
 				</a>
 			</div>
diff --git a/templates/repo/create.tmpl b/templates/repo/create.tmpl
index 0fcdf13f1e383..4125cb9c8fd0d 100644
--- a/templates/repo/create.tmpl
+++ b/templates/repo/create.tmpl
@@ -220,7 +220,7 @@
 					<br>
 					<div class="inline field">
 						<label></label>
-						<button class="ui green button{{if not .CanCreateRepo}} disabled{{end}}">
+						<button class="ui primary button{{if not .CanCreateRepo}} disabled{{end}}">
 							{{.locale.Tr "repo.create_repo"}}
 						</button>
 					</div>
diff --git a/templates/repo/diff/box.tmpl b/templates/repo/diff/box.tmpl
index 0b5bf8637140e..2e1461226aea4 100644
--- a/templates/repo/diff/box.tmpl
+++ b/templates/repo/diff/box.tmpl
@@ -232,8 +232,8 @@
 					"DropzoneParentContainer" ".ui.form"
 				)}}
 				<div class="text right edit buttons">
-					<button class="ui basic primary cancel button" tabindex="3">{{.locale.Tr "repo.issues.cancel"}}</button>
-					<button class="ui green save button" tabindex="2">{{.locale.Tr "repo.issues.save"}}</button>
+					<button class="ui cancel button" tabindex="3">{{.locale.Tr "repo.issues.cancel"}}</button>
+					<button class="ui primary save button" tabindex="2">{{.locale.Tr "repo.issues.save"}}</button>
 				</div>
 			</div>
 		</template>
diff --git a/templates/repo/diff/comment_form.tmpl b/templates/repo/diff/comment_form.tmpl
index 5aad8d9590267..dff030a0b41cb 100644
--- a/templates/repo/diff/comment_form.tmpl
+++ b/templates/repo/diff/comment_form.tmpl
@@ -24,14 +24,14 @@
 			<span class="markup-info">{{svg "octicon-markup"}} {{$.root.locale.Tr "repo.diff.comment.markdown_info"}}</span>
 			<div class="gt-text-right">
 				{{if $.reply}}
-					<button class="ui submit green tiny button btn-reply" type="submit">{{$.root.locale.Tr "repo.diff.comment.reply"}}</button>
+					<button class="ui submit primary tiny button btn-reply" type="submit">{{$.root.locale.Tr "repo.diff.comment.reply"}}</button>
 					<input type="hidden" name="reply" value="{{$.reply}}">
 					<input type="hidden" name="single_review" value="true">
 				{{else}}
 					{{if $.root.CurrentReview}}
-						<button name="pending_review" type="submit" class="ui submit green tiny button btn-add-comment">{{$.root.locale.Tr "repo.diff.comment.add_review_comment"}}</button>
+						<button name="pending_review" type="submit" class="ui submit primary tiny button btn-add-comment">{{$.root.locale.Tr "repo.diff.comment.add_review_comment"}}</button>
 					{{else}}
-						<button name="pending_review" type="submit" class="ui submit green tiny button btn-start-review">{{$.root.locale.Tr "repo.diff.comment.start_review"}}</button>
+						<button name="pending_review" type="submit" class="ui submit primary tiny button btn-start-review">{{$.root.locale.Tr "repo.diff.comment.start_review"}}</button>
 						<button name="single_review" value="true" type="submit" class="ui submit tiny basic button btn-add-single">{{$.root.locale.Tr "repo.diff.comment.add_single_comment"}}</button>
 					{{end}}
 				{{end}}
diff --git a/templates/repo/diff/compare.tmpl b/templates/repo/diff/compare.tmpl
index e4ae7d4dc8e76..4d57fd614855c 100644
--- a/templates/repo/diff/compare.tmpl
+++ b/templates/repo/diff/compare.tmpl
@@ -180,7 +180,7 @@
 		{{if and $.IsSigned $.AllowEmptyPr (not .Repository.IsArchived)}}
 			<div class="ui segment">{{.locale.Tr "repo.pulls.nothing_to_compare_and_allow_empty_pr"}}</div>
 			<div class="ui info message show-form-container {{if .Flash}}gt-hidden{{end}}">
-				<button class="ui button green show-form">{{.locale.Tr "repo.pulls.new"}}</button>
+				<button class="ui button primary show-form">{{.locale.Tr "repo.pulls.new"}}</button>
 			</div>
 			<div class="pullrequest-form {{if not .Flash}}gt-hidden{{end}}">
 				{{template "repo/issue/new_form" .}}
@@ -204,14 +204,14 @@
 				{{else if .Issue.IsClosed}}
 				<a href="{{Escape $.RepoLink}}/pulls/{{.PullRequest.Issue.Index}}" class="ui button red show-form">{{svg "octicon-issue-closed" 16}} {{.locale.Tr "repo.pulls.view"}}</a>
 				{{else}}
-				<a href="{{Escape $.RepoLink}}/pulls/{{.PullRequest.Issue.Index}}" class="ui button green show-form">{{svg "octicon-git-pull-request" 16}} {{.locale.Tr "repo.pulls.view"}}</a>
+				<a href="{{Escape $.RepoLink}}/pulls/{{.PullRequest.Issue.Index}}" class="ui button primary show-form">{{svg "octicon-git-pull-request" 16}} {{.locale.Tr "repo.pulls.view"}}</a>
 				{{end}}
 				</div>
 			</div>
 		{{else}}
 			{{if and $.IsSigned (not .Repository.IsArchived)}}
 				<div class="ui info message show-form-container {{if .Flash}}gt-hidden{{end}}">
-					<button class="ui button green show-form">{{.locale.Tr "repo.pulls.new"}}</button>
+					<button class="ui button primary show-form">{{.locale.Tr "repo.pulls.new"}}</button>
 				</div>
 			{{else if .Repository.IsArchived}}
 				<div class="ui warning message gt-text-center">
diff --git a/templates/repo/diff/conversation.tmpl b/templates/repo/diff/conversation.tmpl
index 639dd9cd040b6..c6ada10caf0bb 100644
--- a/templates/repo/diff/conversation.tmpl
+++ b/templates/repo/diff/conversation.tmpl
@@ -56,7 +56,7 @@
 				</button>
 			{{end}}
 			{{if and $.SignedUserID (not $.Repository.IsArchived)}}
-				<button class="comment-form-reply ui green tiny labeled icon button gt-ml-2 gt-mr-0">
+				<button class="comment-form-reply ui primary tiny labeled icon button gt-ml-2 gt-mr-0">
 					{{svg "octicon-reply" 16 "reply icon gt-mr-2"}}{{$.locale.Tr "repo.diff.comment.reply"}}
 				</button>
 			{{end}}
diff --git a/templates/repo/diff/new_review.tmpl b/templates/repo/diff/new_review.tmpl
index 6a3fa7a823273..908f488975243 100644
--- a/templates/repo/diff/new_review.tmpl
+++ b/templates/repo/diff/new_review.tmpl
@@ -1,5 +1,5 @@
 <div id="review-box">
-	<button class="ui tiny green button gt-pr-2 gt-df js-btn-review {{if not $.IsShowingAllCommits}}disabled{{end}}" {{if not $.IsShowingAllCommits}}data-tooltip-content="{{$.locale.Tr "repo.pulls.review_only_possible_for_full_diff"}}"{{end}}>
+	<button class="ui tiny primary button gt-pr-2 gt-df js-btn-review {{if not $.IsShowingAllCommits}}disabled{{end}}" {{if not $.IsShowingAllCommits}}data-tooltip-content="{{$.locale.Tr "repo.pulls.review_only_possible_for_full_diff"}}"{{end}}>
 		{{.locale.Tr "repo.diff.review"}}
 		<span class="ui small label review-comments-counter" data-pending-comment-number="{{.PendingCodeCommentNumber}}">{{.PendingCodeCommentNumber}}</span>
 		{{svg "octicon-triangle-down" 14 "dropdown icon"}}
@@ -33,10 +33,10 @@
 				{{$showSelfTooltip := (and $.IsSigned ($.Issue.IsPoster $.SignedUser.ID))}}
 				{{if $showSelfTooltip}}
 					<span class="gt-dib" data-tooltip-content="{{$.locale.Tr "repo.diff.review.self_approve"}}">
-						<button type="submit" name="type" value="approve" disabled class="ui submit green tiny button btn-submit">{{$.locale.Tr "repo.diff.review.approve"}}</button>
+						<button type="submit" name="type" value="approve" disabled class="ui submit primary tiny button btn-submit">{{$.locale.Tr "repo.diff.review.approve"}}</button>
 					</span>
 				{{else}}
-					<button type="submit" name="type" value="approve" class="ui submit green tiny button btn-submit">{{$.locale.Tr "repo.diff.review.approve"}}</button>
+					<button type="submit" name="type" value="approve" class="ui submit primary tiny button btn-submit">{{$.locale.Tr "repo.diff.review.approve"}}</button>
 				{{end}}
 				<button type="submit" name="type" value="comment" class="ui submit tiny basic button btn-submit">{{$.locale.Tr "repo.diff.review.comment"}}</button>
 				{{if $showSelfTooltip}}
diff --git a/templates/repo/editor/commit_form.tmpl b/templates/repo/editor/commit_form.tmpl
index b07059777fbc1..dd6537e1a008f 100644
--- a/templates/repo/editor/commit_form.tmpl
+++ b/templates/repo/editor/commit_form.tmpl
@@ -67,7 +67,7 @@
 			{{end}}
 		</div>
 	</div>
-	<button id="commit-button" type="submit" class="ui green button">
+	<button id="commit-button" type="submit" class="ui primary button">
 		{{if eq .commit_choice "commit-to-new-branch"}}{{.locale.Tr "repo.editor.propose_file_change"}}{{else}}{{.locale.Tr "repo.editor.commit_changes"}}{{end}}
 	</button>
 	<a class="ui button red" href="{{$.BranchLink}}/{{PathEscapeSegments .TreePath}}">{{.locale.Tr "repo.editor.cancel"}}</a>
diff --git a/templates/repo/editor/edit.tmpl b/templates/repo/editor/edit.tmpl
index 3b5a63f3aa854..2b303be97ccdb 100644
--- a/templates/repo/editor/edit.tmpl
+++ b/templates/repo/editor/edit.tmpl
@@ -61,11 +61,11 @@
 			<p>{{.locale.Tr "repo.editor.commit_empty_file_text"}}</p>
 		</div>
 		<div class="actions">
-			<button class="ui red cancel button">
+			<button class="ui cancel button">
 				{{svg "octicon-x"}}
 				{{.locale.Tr "repo.editor.cancel"}}
 			</button>
-			<button class="ui green ok button">
+			<button class="ui primary ok button">
 				{{svg "fontawesome-save"}}
 				{{.locale.Tr "repo.editor.commit_changes"}}
 			</button>
diff --git a/templates/repo/editor/patch.tmpl b/templates/repo/editor/patch.tmpl
index 1f948fbb1904e..57126c09abf77 100644
--- a/templates/repo/editor/patch.tmpl
+++ b/templates/repo/editor/patch.tmpl
@@ -43,11 +43,11 @@
 			<p>{{.locale.Tr "repo.editor.commit_empty_file_text"}}</p>
 		</div>
 		<div class="actions">
-			<button class="ui red cancel button">
+			<button class="ui cancel button">
 				{{svg "octicon-x"}}
 				{{.locale.Tr "repo.editor.cancel"}}
 			</button>
-			<button class="ui green ok button">
+			<button class="ui primary ok button">
 				{{svg "fontawesome-save"}}
 				{{.locale.Tr "repo.editor.commit_changes"}}
 			</button>
diff --git a/templates/repo/header.tmpl b/templates/repo/header.tmpl
index 935060816cb22..d0f24949c9b01 100644
--- a/templates/repo/header.tmpl
+++ b/templates/repo/header.tmpl
@@ -48,7 +48,7 @@
 						<form method="post" action="{{$.RepoLink}}/action/accept_transfer?redirect_to={{$.RepoLink}}">
 							{{$.CsrfTokenHtml}}
 							<div data-tooltip-content="{{if $.CanUserAcceptTransfer}}{{$.locale.Tr "repo.transfer.accept_desc" $.RepoTransfer.Recipient.DisplayName}}{{else}}{{$.locale.Tr "repo.transfer.no_permission_to_accept"}}{{end}}">
-								<button type="submit" class="ui basic button {{if $.CanUserAcceptTransfer}}green {{end}} ok small"{{if not $.CanUserAcceptTransfer}} disabled{{end}}>
+								<button type="submit" class="ui basic button {{if $.CanUserAcceptTransfer}}primary {{end}} ok small"{{if not $.CanUserAcceptTransfer}} disabled{{end}}>
 									{{$.locale.Tr "repo.transfer.accept"}}
 								</button>
 							</div>
diff --git a/templates/repo/issue/choose.tmpl b/templates/repo/issue/choose.tmpl
index 1bbfbbb2d1534..9cc666a4bd3e9 100644
--- a/templates/repo/issue/choose.tmpl
+++ b/templates/repo/issue/choose.tmpl
@@ -15,7 +15,7 @@
 						<br>{{.About | RenderEmojiPlain}}
 					</div>
 					<div class="column right aligned">
-						<a href="{{$.RepoLink}}/issues/new?template={{.FileName}}{{if $.milestone}}&milestone={{$.milestone}}{{end}}{{if $.project}}&project={{$.project}}{{end}}" class="ui green button">{{$.locale.Tr "repo.issues.choose.get_started"}}</a>
+						<a href="{{$.RepoLink}}/issues/new?template={{.FileName}}{{if $.milestone}}&milestone={{$.milestone}}{{end}}{{if $.project}}&project={{$.project}}{{end}}" class="ui primary button">{{$.locale.Tr "repo.issues.choose.get_started"}}</a>
 					</div>
 				</div>
 			</div>
@@ -28,7 +28,7 @@
 						<br>{{.About | RenderEmojiPlain}}
 					</div>
 					<div class="column right aligned">
-						<a href="{{.URL}}" class="ui green button">{{svg "octicon-link-external"}} {{$.locale.Tr "repo.issues.choose.open_external_link"}}</a>
+						<a href="{{.URL}}" class="ui primary button">{{svg "octicon-link-external"}} {{$.locale.Tr "repo.issues.choose.open_external_link"}}</a>
 					</div>
 				</div>
 			</div>
@@ -41,7 +41,7 @@
 						<br/>{{.locale.Tr "repo.issues.choose.blank_about"}}
 					</div>
 					<div class="column right aligned">
-						<a href="{{.RepoLink}}/issues/new?{{if .milestone}}&milestone={{.milestone}}{{end}}{{if $.project}}&project={{$.project}}{{end}}" class="ui green button">{{$.locale.Tr "repo.issues.choose.get_started"}}</a>
+						<a href="{{.RepoLink}}/issues/new?{{if .milestone}}&milestone={{.milestone}}{{end}}{{if $.project}}&project={{$.project}}{{end}}" class="ui primary button">{{$.locale.Tr "repo.issues.choose.get_started"}}</a>
 					</div>
 				</div>
 			</div>
diff --git a/templates/repo/issue/filters.tmpl b/templates/repo/issue/filters.tmpl
index 3bfced90d6a0f..1805a23e372a1 100644
--- a/templates/repo/issue/filters.tmpl
+++ b/templates/repo/issue/filters.tmpl
@@ -11,8 +11,8 @@
 			<div class="ui {{if not .Labels}}disabled{{end}} dropdown jump item label-filter">
 				<span class="text">
 					{{.locale.Tr "repo.issues.filter_label"}}
-					{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 				</span>
+				{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 				<div class="menu">
 					<div class="ui icon search input">
 						<i class="icon">{{svg "octicon-search" 16}}</i>
@@ -42,8 +42,8 @@
 			<div class="ui {{if not (or .OpenMilestones .ClosedMilestones)}}disabled{{end}} dropdown jump item">
 				<span class="text">
 					{{.locale.Tr "repo.issues.filter_milestone"}}
-					{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 				</span>
+				{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 				<div class="menu">
 					<div class="ui icon search input">
 						<i class="icon">{{svg "octicon-search" 16}}</i>
@@ -80,8 +80,8 @@
 			<div class="ui{{if not (or .OpenProjects .ClosedProjects)}} disabled{{end}} dropdown jump item">
 				<span class="text">
 					{{.locale.Tr "repo.issues.filter_project"}}
-					{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 				</span>
+				{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 				<div class="menu">
 					<div class="ui icon search input">
 						<i class="icon">{{svg "octicon-search" 16}}</i>
@@ -122,8 +122,8 @@
 			>
 				<span class="text">
 					{{.locale.Tr "repo.issues.filter_poster"}}
-					{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 				</span>
+				{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 				<div class="menu">
 					<div class="ui icon search input">
 						<i class="icon">{{svg "octicon-search" 16}}</i>
@@ -137,8 +137,8 @@
 			<div class="ui {{if not .Assignees}}disabled{{end}} dropdown jump item">
 				<span class="text">
 					{{.locale.Tr "repo.issues.filter_assignee"}}
-					{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 				</span>
+				{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 				<div class="menu">
 					<div class="ui icon search input">
 						<i class="icon">{{svg "octicon-search" 16}}</i>
@@ -160,8 +160,8 @@
 				<div class="ui dropdown type jump item">
 					<span class="text">
 						{{.locale.Tr "repo.issues.filter_type"}}
-						{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 					</span>
+					{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 					<div class="menu">
 						<a class="{{if eq .ViewType "all"}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type=all&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}">{{.locale.Tr "repo.issues.filter_type.all_issues"}}</a>
 						<a class="{{if eq .ViewType "assigned"}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type=assigned&sort={{$.SortType}}&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}">{{.locale.Tr "repo.issues.filter_type.assigned_to_you"}}</a>
@@ -179,8 +179,8 @@
 			<div class="list-header-sort ui small dropdown downward type jump item">
 				<span class="text">
 					{{.locale.Tr "repo.issues.filter_sort"}}
-					{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 				</span>
+				{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 				<div class="menu">
 					<a class="{{if or (eq .SortType "latest") (not .SortType)}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort=latest&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}">{{.locale.Tr "repo.issues.filter_sort.latest"}}</a>
 					<a class="{{if eq .SortType "oldest"}}active {{end}}item" href="{{$.Link}}?q={{$.Keyword}}&type={{$.ViewType}}&sort=oldest&state={{$.State}}&labels={{.SelectLabels}}&milestone={{$.MilestoneID}}&project={{$.ProjectID}}&assignee={{$.AssigneeID}}&poster={{$.PosterID}}">{{.locale.Tr "repo.issues.filter_sort.oldest"}}</a>
diff --git a/templates/repo/issue/labels.tmpl b/templates/repo/issue/labels.tmpl
index a34ce1bfbb51b..7de1b0f0baf3d 100644
--- a/templates/repo/issue/labels.tmpl
+++ b/templates/repo/issue/labels.tmpl
@@ -5,7 +5,7 @@
 		<div class="navbar gt-mb-4">
 			{{template "repo/issue/navbar" .}}
 			{{if and (or .CanWriteIssues .CanWritePulls) (not .Repository.IsArchived)}}
-				<button class="ui small green new-label button">{{.locale.Tr "repo.issues.new_label"}}</button>
+				<button class="ui small primary new-label button">{{.locale.Tr "repo.issues.new_label"}}</button>
 			{{end}}
 		</div>
 		{{if and (or .CanWriteIssues .CanWritePulls) (not .Repository.IsArchived)}}
diff --git a/templates/repo/issue/labels/label_list.tmpl b/templates/repo/issue/labels/label_list.tmpl
index d9addb439b840..b9d349cb2bc1e 100644
--- a/templates/repo/issue/labels/label_list.tmpl
+++ b/templates/repo/issue/labels/label_list.tmpl
@@ -1,14 +1,14 @@
 <h4 class="ui top attached header">
 	{{.locale.Tr "repo.issues.label_count" .NumLabels}}
 	<div class="ui right">
-		<div class="ui right floated secondary filter menu">
+		<div class="ui secondary menu">
 			<!-- Sort -->
-			<div class="ui dropdown type jump item">
+			<div class="item ui jump dropdown gt-py-3">
 				<span class="text">
 					{{.locale.Tr "repo.issues.filter_sort"}}
-					{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 				</span>
-				<div class="menu">
+				{{svg "octicon-triangle-down" 14 "dropdown icon"}}
+				<div class="left menu">
 					<a class="{{if or (eq .SortType "alphabetically") (not .SortType)}}active {{end}}item" href="{{$.Link}}?sort=alphabetically&state={{$.State}}">{{.locale.Tr "repo.issues.label.filter_sort.alphabetically"}}</a>
 					<a class="{{if eq .SortType "reversealphabetically"}}active {{end}}item" href="{{$.Link}}?sort=reversealphabetically&state={{$.State}}">{{.locale.Tr "repo.issues.label.filter_sort.reverse_alphabetically"}}</a>
 					<a class="{{if eq .SortType "leastissues"}}active {{end}}item" href="{{$.Link}}?sort=leastissues&state={{$.State}}">{{.locale.Tr "repo.milestones.filter_sort.least_issues"}}</a>
diff --git a/templates/repo/issue/labels/label_new.tmpl b/templates/repo/issue/labels/label_new.tmpl
index 1d3069f1bb798..8edd6d4e8a2b5 100644
--- a/templates/repo/issue/labels/label_new.tmpl
+++ b/templates/repo/issue/labels/label_new.tmpl
@@ -36,11 +36,11 @@
 	</div>
 
 	<div class="actions">
-		<button class="ui red basic cancel button">
+		<button class="ui cancel button">
 			{{svg "octicon-x"}}
 			{{.locale.Tr "cancel"}}
 		</button>
-		<button class="ui green basic ok button">
+		<button class="ui primary ok button">
 			{{svg "octicon-check"}}
 			{{.locale.Tr "repo.issues.create_label"}}
 		</button>
diff --git a/templates/repo/issue/list.tmpl b/templates/repo/issue/list.tmpl
index 789ba4020f706..cc8c647c1ef07 100644
--- a/templates/repo/issue/list.tmpl
+++ b/templates/repo/issue/list.tmpl
@@ -18,13 +18,13 @@
 			{{template "repo/issue/search" .}}
 			{{if not .Repository.IsArchived}}
 				{{if .PageIsIssueList}}
-					<a class="ui small green button issue-list-new" href="{{.RepoLink}}/issues/new{{if .NewIssueChooseTemplate}}/choose{{end}}">{{.locale.Tr "repo.issues.new"}}</a>
+					<a class="ui small primary button issue-list-new" href="{{.RepoLink}}/issues/new{{if .NewIssueChooseTemplate}}/choose{{end}}">{{.locale.Tr "repo.issues.new"}}</a>
 				{{else}}
-					<a class="ui small green button new-pr-button issue-list-new{{if not .PullRequestCtx.Allowed}} disabled{{end}}" href="{{if .PullRequestCtx.Allowed}}{{.Repository.Link}}/compare/{{.Repository.DefaultBranch | PathEscapeSegments}}...{{if ne .Repository.Owner.Name .PullRequestCtx.BaseRepo.Owner.Name}}{{PathEscape .Repository.Owner.Name}}:{{end}}{{.Repository.DefaultBranch | PathEscapeSegments}}{{end}}">{{.locale.Tr "repo.pulls.new"}}</a>
+					<a class="ui small primary button new-pr-button issue-list-new{{if not .PullRequestCtx.Allowed}} disabled{{end}}" href="{{if .PullRequestCtx.Allowed}}{{.Repository.Link}}/compare/{{.Repository.DefaultBranch | PathEscapeSegments}}...{{if ne .Repository.Owner.Name .PullRequestCtx.BaseRepo.Owner.Name}}{{PathEscape .Repository.Owner.Name}}:{{end}}{{.Repository.DefaultBranch | PathEscapeSegments}}{{end}}">{{.locale.Tr "repo.pulls.new"}}</a>
 				{{end}}
 			{{else}}
 				{{if not .PageIsIssueList}}
-					<a class="ui small green small button issue-list-new{{if not .PullRequestCtx.Allowed}} disabled{{end}}" href="{{if .PullRequestCtx.Allowed}}{{.PullRequestCtx.BaseRepo.Link}}/compare/{{.PullRequestCtx.BaseRepo.DefaultBranch | PathEscapeSegments}}...{{if ne .Repository.Owner.Name .PullRequestCtx.BaseRepo.Owner.Name}}{{PathEscape .Repository.Owner.Name}}:{{end}}{{.Repository.DefaultBranch | PathEscapeSegments}}{{end}}">{{$.locale.Tr "action.compare_commits_general"}}</a>
+					<a class="ui small primary small button issue-list-new{{if not .PullRequestCtx.Allowed}} disabled{{end}}" href="{{if .PullRequestCtx.Allowed}}{{.PullRequestCtx.BaseRepo.Link}}/compare/{{.PullRequestCtx.BaseRepo.DefaultBranch | PathEscapeSegments}}...{{if ne .Repository.Owner.Name .PullRequestCtx.BaseRepo.Owner.Name}}{{PathEscape .Repository.Owner.Name}}:{{end}}{{.Repository.DefaultBranch | PathEscapeSegments}}{{end}}">{{$.locale.Tr "action.compare_commits_general"}}</a>
 				{{end}}
 			{{end}}
 		</div>
@@ -40,7 +40,7 @@
 					{{if not .Repository.IsArchived}}
 					<!-- Action Button -->
 					{{if .IsShowClosed}}
-						<button class="ui green basic button issue-action" data-action="open" data-url="{{$.RepoLink}}/issues/status">{{.locale.Tr "repo.issues.action_open"}}</button>
+						<button class="ui primary basic button issue-action" data-action="open" data-url="{{$.RepoLink}}/issues/status">{{.locale.Tr "repo.issues.action_open"}}</button>
 					{{else}}
 						<button class="ui red basic button issue-action" data-action="close" data-url="{{$.RepoLink}}/issues/status">{{.locale.Tr "repo.issues.action_close"}}</button>
 					{{end}}
@@ -54,8 +54,8 @@
 					<div class="ui {{if not .Labels}}disabled{{end}} dropdown jump item">
 						<span class="text">
 							{{.locale.Tr "repo.issues.action_label"}}
-							{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 						</span>
+						{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 						<div class="menu">
 							<div class="item issue-action" data-action="clear" data-url="{{$.RepoLink}}/issues/labels">
 								{{.locale.Tr "repo.issues.new.clear_labels"}}
@@ -78,8 +78,8 @@
 					<div class="ui {{if not (or .OpenMilestones .ClosedMilestones)}}disabled{{end}} dropdown jump item">
 						<span class="text">
 							{{.locale.Tr "repo.issues.action_milestone"}}
-							{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 						</span>
+						{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 						<div class="menu">
 							<div class="item issue-action" data-element-id="0" data-url="{{$.Link}}/milestone">
 							{{.locale.Tr "repo.issues.action_milestone_no_select"}}
@@ -109,8 +109,8 @@
 					<div class="ui{{if not (or .OpenProjects .ClosedProjects)}} disabled{{end}} dropdown jump item">
 						<span class="text">
 							{{.locale.Tr "repo.project_board"}}
-							{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 						</span>
+						{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 						<div class="menu">
 							<div class="item issue-action" data-element-id="0" data-url="{{$.Link}}/projects">
 							{{.locale.Tr "repo.issues.new.clear_projects"}}
@@ -144,8 +144,8 @@
 					<div class="ui {{if not .Assignees}}disabled{{end}} dropdown jump item">
 						<span class="text">
 							{{.locale.Tr "repo.issues.action_assignee"}}
-							{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 						</span>
+						{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 						<div class="menu">
 							<div class="item issue-action" data-action="clear" data-url="{{$.Link}}/assignee">
 								{{.locale.Tr "repo.issues.new.clear_assignees"}}
diff --git a/templates/repo/issue/milestone_issues.tmpl b/templates/repo/issue/milestone_issues.tmpl
index dab6ef3de6529..aa3d9b94cdbdc 100644
--- a/templates/repo/issue/milestone_issues.tmpl
+++ b/templates/repo/issue/milestone_issues.tmpl
@@ -8,7 +8,7 @@
 				<div class="text right gt-f1">
 					{{if or .CanWriteIssues .CanWritePulls}}
 						{{if .Milestone.IsClosed}}
-							<a class="ui green basic button link-action" href data-url="{{$.RepoLink}}/milestones/{{.MilestoneID}}/open">{{$.locale.Tr "repo.milestones.open"}}
+							<a class="ui primary basic button link-action" href data-url="{{$.RepoLink}}/milestones/{{.MilestoneID}}/open">{{$.locale.Tr "repo.milestones.open"}}
 							</a>
 						{{else}}
 							<a class="ui red basic button link-action" href data-url="{{$.RepoLink}}/milestones/{{.MilestoneID}}/close">{{$.locale.Tr "repo.milestones.close"}}
diff --git a/templates/repo/issue/milestone_new.tmpl b/templates/repo/issue/milestone_new.tmpl
index 56450108509fc..47a3d93d2b4dc 100644
--- a/templates/repo/issue/milestone_new.tmpl
+++ b/templates/repo/issue/milestone_new.tmpl
@@ -6,7 +6,7 @@
 			{{template "repo/issue/navbar" .}}
 			{{if and (or .CanWriteIssues .CanWritePulls) .PageIsEditMilestone}}
 				<div class="ui right floated secondary menu">
-					<a class="ui green button" href="{{$.RepoLink}}/milestones/new">{{.locale.Tr "repo.milestones.new"}}</a>
+					<a class="ui primary button" href="{{$.RepoLink}}/milestones/new">{{.locale.Tr "repo.milestones.new"}}</a>
 				</div>
 			{{end}}
 		</div>
@@ -44,11 +44,11 @@
 						<a class="ui primary basic button" href="{{.RepoLink}}/milestones">
 							{{.locale.Tr "repo.milestones.cancel"}}
 						</a>
-						<button class="ui green button">
+						<button class="ui primary button">
 							{{.locale.Tr "repo.milestones.modify"}}
 						</button>
 					{{else}}
-						<button class="ui green button">
+						<button class="ui primary button">
 							{{.locale.Tr "repo.milestones.create"}}
 						</button>
 					{{end}}
diff --git a/templates/repo/issue/milestones.tmpl b/templates/repo/issue/milestones.tmpl
index 3f481c95e411d..c6693e35ccd44 100644
--- a/templates/repo/issue/milestones.tmpl
+++ b/templates/repo/issue/milestones.tmpl
@@ -5,7 +5,7 @@
 		<div class="navbar gt-mb-4">
 			{{template "repo/issue/navbar" .}}
 			{{if and (or .CanWriteIssues .CanWritePulls) (not .Repository.IsArchived)}}
-				<a class="ui small green button" href="{{$.Link}}/new">{{.locale.Tr "repo.milestones.new"}}</a>
+				<a class="ui small primary button" href="{{$.Link}}/new">{{.locale.Tr "repo.milestones.new"}}</a>
 			{{end}}
 		</div>
 		{{template "base/alert" .}}
@@ -37,8 +37,8 @@
 			<div class="list-header-sort ui small dropdown type jump item">
 				<span class="text">
 					{{.locale.Tr "repo.issues.filter_sort"}}
-					{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 				</span>
+				{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 				<div class="menu">
 					<a class="{{if or (eq .SortType "closestduedate") (not .SortType)}}active {{end}}item" href="{{$.Link}}?sort=closestduedate&state={{$.State}}&q={{$.Keyword}}">{{.locale.Tr "repo.milestones.filter_sort.earliest_due_data"}}</a>
 					<a class="{{if eq .SortType "furthestduedate"}}active {{end}}item" href="{{$.Link}}?sort=furthestduedate&state={{$.State}}&q={{$.Keyword}}">{{.locale.Tr "repo.milestones.filter_sort.latest_due_date"}}</a>
diff --git a/templates/repo/issue/new_form.tmpl b/templates/repo/issue/new_form.tmpl
index fc1a3d087f02f..9d0b666375102 100644
--- a/templates/repo/issue/new_form.tmpl
+++ b/templates/repo/issue/new_form.tmpl
@@ -35,7 +35,7 @@
 						{{template "repo/issue/comment_tab" .}}
 					{{end}}
 					<div class="text right">
-						<button class="ui green button">
+						<button class="ui primary button">
 							{{if .PageIsComparePull}}
 								{{.locale.Tr "repo.pulls.create"}}
 							{{else}}
diff --git a/templates/repo/issue/view_content.tmpl b/templates/repo/issue/view_content.tmpl
index 78587ac7b6e2a..2c7c7145741b9 100644
--- a/templates/repo/issue/view_content.tmpl
+++ b/templates/repo/issue/view_content.tmpl
@@ -92,7 +92,7 @@
 								<div class="text right">
 									{{if and (or .HasIssuesOrPullsWritePermission .IsIssuePoster) (not .DisableStatusChange)}}
 										{{if .Issue.IsClosed}}
-											<button id="status-button" class="ui green basic button" tabindex="6" data-status="{{.locale.Tr "repo.issues.reopen_issue"}}" data-status-and-comment="{{.locale.Tr "repo.issues.reopen_comment_issue"}}" name="status" value="reopen">
+											<button id="status-button" class="ui primary basic button" tabindex="6" data-status="{{.locale.Tr "repo.issues.reopen_issue"}}" data-status-and-comment="{{.locale.Tr "repo.issues.reopen_comment_issue"}}" name="status" value="reopen">
 												{{.locale.Tr "repo.issues.reopen_issue"}}
 											</button>
 										{{else}}
@@ -105,7 +105,7 @@
 											</button>
 										{{end}}
 									{{end}}
-									<button class="ui green button" tabindex="5">
+									<button class="ui primary button" tabindex="5">
 										{{.locale.Tr "repo.issues.create_comment"}}
 									</button>
 								</div>
diff --git a/templates/repo/issue/view_content/comments.tmpl b/templates/repo/issue/view_content/comments.tmpl
index d43979ff59bdb..cb897a692b82c 100644
--- a/templates/repo/issue/view_content/comments.tmpl
+++ b/templates/repo/issue/view_content/comments.tmpl
@@ -585,7 +585,7 @@
 													</button>
 												{{end}}
 												{{if and $.SignedUserID (not $.Repository.IsArchived)}}
-													<button class="comment-form-reply ui green tiny labeled icon button gt-ml-2 gt-mr-0">
+													<button class="comment-form-reply ui primary tiny labeled icon button gt-ml-2 gt-mr-0">
 														{{svg "octicon-reply" 16 "reply icon gt-mr-2"}}{{$.locale.Tr "repo.diff.comment.reply"}}
 													</button>
 												{{end}}
diff --git a/templates/repo/issue/view_content/reference_issue_dialog.tmpl b/templates/repo/issue/view_content/reference_issue_dialog.tmpl
index 861e7b97a4d6d..3df85e7b81f77 100644
--- a/templates/repo/issue/view_content/reference_issue_dialog.tmpl
+++ b/templates/repo/issue/view_content/reference_issue_dialog.tmpl
@@ -22,7 +22,7 @@
 					<textarea name="content" class="form-control"></textarea>
 				</div>
 				<div class="text right">
-					<button class="ui green button">{{.locale.Tr "repo.issues.create"}}</button>
+					<button class="ui primary button">{{.locale.Tr "repo.issues.create"}}</button>
 				</div>
 			</div>
 		</form>
diff --git a/templates/repo/issue/view_content/sidebar.tmpl b/templates/repo/issue/view_content/sidebar.tmpl
index 3d5be860bd5f6..6405a6e180e36 100644
--- a/templates/repo/issue/view_content/sidebar.tmpl
+++ b/templates/repo/issue/view_content/sidebar.tmpl
@@ -327,8 +327,8 @@
 								</form>
 							</div>
 							<div class="actions">
-								<button class="ui green approve button">{{.locale.Tr "repo.issues.add_time_short"}}</button>
-								<button class="ui red cancel button">{{.locale.Tr "repo.issues.add_time_cancel"}}</button>
+								<button class="ui primary approve button">{{.locale.Tr "repo.issues.add_time_short"}}</button>
+								<button class="ui cancel button">{{.locale.Tr "repo.issues.add_time_cancel"}}</button>
 							</div>
 						</div>
 						<button class="ui fluid button issue-add-time gt-mt-3" data-tooltip-content='{{.locale.Tr "repo.issues.add_time"}}'>
diff --git a/templates/repo/issue/view_title.tmpl b/templates/repo/issue/view_title.tmpl
index c1dd265e5837c..0ad408b8d9af7 100644
--- a/templates/repo/issue/view_title.tmpl
+++ b/templates/repo/issue/view_title.tmpl
@@ -17,7 +17,7 @@
 				<button id="edit-title" class="ui small basic button edit-button not-in-edit{{if .Issue.IsPull}} gt-mr-0{{end}}">{{.locale.Tr "repo.issues.edit"}}</button>
 			{{end}}
 			{{if not .Issue.IsPull}}
-				<a role="button" class="ui small green button new-issue-button gt-mr-0" href="{{.RepoLink}}/issues/new{{if .NewIssueChooseTemplate}}/choose{{end}}">{{.locale.Tr "repo.issues.new"}}</a>
+				<a role="button" class="ui small primary button new-issue-button gt-mr-0" href="{{.RepoLink}}/issues/new{{if .NewIssueChooseTemplate}}/choose{{end}}">{{.locale.Tr "repo.issues.new"}}</a>
 			{{end}}
 		</div>
 		{{if and (or .HasIssuesOrPullsWritePermission .IsIssuePoster) (not .Repository.IsArchived)}}
diff --git a/templates/repo/migrate/codebase.tmpl b/templates/repo/migrate/codebase.tmpl
index db607eebb4c75..394e7c2ecfbe7 100644
--- a/templates/repo/migrate/codebase.tmpl
+++ b/templates/repo/migrate/codebase.tmpl
@@ -104,7 +104,7 @@
 
 					<div class="inline field">
 						<label></label>
-						<button class="ui green button">
+						<button class="ui primary button">
 							{{.locale.Tr "repo.migrate_repo"}}
 						</button>
 					</div>
diff --git a/templates/repo/migrate/git.tmpl b/templates/repo/migrate/git.tmpl
index 42ae642d26679..1e449ae30e90f 100644
--- a/templates/repo/migrate/git.tmpl
+++ b/templates/repo/migrate/git.tmpl
@@ -78,7 +78,7 @@
 
 					<div class="inline field">
 						<label></label>
-						<button class="ui green button">
+						<button class="ui primary button">
 							{{.locale.Tr "repo.migrate_repo"}}
 						</button>
 					</div>
diff --git a/templates/repo/migrate/gitbucket.tmpl b/templates/repo/migrate/gitbucket.tmpl
index 372df0c2dba73..aa269e561ccaf 100644
--- a/templates/repo/migrate/gitbucket.tmpl
+++ b/templates/repo/migrate/gitbucket.tmpl
@@ -120,7 +120,7 @@
 
 					<div class="inline field">
 						<label></label>
-						<button class="ui green button">
+						<button class="ui primary button">
 							{{.locale.Tr "repo.migrate_repo"}}
 						</button>
 					</div>
diff --git a/templates/repo/migrate/gitea.tmpl b/templates/repo/migrate/gitea.tmpl
index 8022f63dc525d..e4d8c6273498d 100644
--- a/templates/repo/migrate/gitea.tmpl
+++ b/templates/repo/migrate/gitea.tmpl
@@ -116,7 +116,7 @@
 
 					<div class="inline field">
 						<label></label>
-						<button class="ui green button">
+						<button class="ui primary button">
 							{{.locale.Tr "repo.migrate_repo"}}
 						</button>
 					</div>
diff --git a/templates/repo/migrate/github.tmpl b/templates/repo/migrate/github.tmpl
index 0ccad3a3ea33c..d3f0e0b8bd33d 100644
--- a/templates/repo/migrate/github.tmpl
+++ b/templates/repo/migrate/github.tmpl
@@ -118,7 +118,7 @@
 
 					<div class="inline field">
 						<label></label>
-						<button class="ui green button">
+						<button class="ui primary button">
 							{{.locale.Tr "repo.migrate_repo"}}
 						</button>
 					</div>
diff --git a/templates/repo/migrate/gitlab.tmpl b/templates/repo/migrate/gitlab.tmpl
index af20fa38e2c79..e055cce19ed7a 100644
--- a/templates/repo/migrate/gitlab.tmpl
+++ b/templates/repo/migrate/gitlab.tmpl
@@ -115,7 +115,7 @@
 
 					<div class="inline field">
 						<label></label>
-						<button class="ui green button">
+						<button class="ui primary button">
 							{{.locale.Tr "repo.migrate_repo"}}
 						</button>
 					</div>
diff --git a/templates/repo/migrate/gogs.tmpl b/templates/repo/migrate/gogs.tmpl
index aeead61e412c0..2d6680060823b 100644
--- a/templates/repo/migrate/gogs.tmpl
+++ b/templates/repo/migrate/gogs.tmpl
@@ -118,7 +118,7 @@
 
 					<div class="inline field">
 						<label></label>
-						<button class="ui green button">
+						<button class="ui primary button">
 							{{.locale.Tr "repo.migrate_repo"}}
 						</button>
 					</div>
diff --git a/templates/repo/migrate/migrating.tmpl b/templates/repo/migrate/migrating.tmpl
index d1bdc5a90fb10..6effa05f97762 100644
--- a/templates/repo/migrate/migrating.tmpl
+++ b/templates/repo/migrate/migrating.tmpl
@@ -38,7 +38,7 @@
 									{{if .Failed}}
 										<button class="ui basic red show-modal button" data-modal="#delete-repo-modal">{{.locale.Tr "repo.settings.delete"}}</button>
 									{{else}}
-										<button class="ui basic red show-modal button" data-modal="#cancel-repo-modal">{{.locale.Tr "cancel"}}</button>
+										<button class="ui basic show-modal button" data-modal="#cancel-repo-modal">{{.locale.Tr "cancel"}}</button>
 									{{end}}
 									<button id="repo_migrating_retry" data-migrating-task-retry-url="{{.Link}}/settings/migrate/retry" class="ui basic button gt-hidden">{{.locale.Tr "retry"}}</button>
 								</div>
diff --git a/templates/repo/migrate/onedev.tmpl b/templates/repo/migrate/onedev.tmpl
index f5ba11ab065fe..818b23fddca64 100644
--- a/templates/repo/migrate/onedev.tmpl
+++ b/templates/repo/migrate/onedev.tmpl
@@ -104,7 +104,7 @@
 
 					<div class="inline field">
 						<label></label>
-						<button class="ui green button">
+						<button class="ui primary button">
 							{{.locale.Tr "repo.migrate_repo"}}
 						</button>
 					</div>
diff --git a/templates/repo/projects/view.tmpl b/templates/repo/projects/view.tmpl
index ac3d2cd77c153..3f2dd9a548b76 100644
--- a/templates/repo/projects/view.tmpl
+++ b/templates/repo/projects/view.tmpl
@@ -4,7 +4,7 @@
 	<div class="ui container padded">
 		<div class="gt-df gt-sb gt-ac gt-mb-4">
 			{{template "repo/issue/navbar" .}}
-			<a class="ui small green button" href="{{.RepoLink}}/issues/new/choose?project={{.Project.ID}}">{{ctx.Locale.Tr "repo.issues.new"}}</a>
+			<a class="ui small primary button" href="{{.RepoLink}}/issues/new/choose?project={{.Project.ID}}">{{ctx.Locale.Tr "repo.issues.new"}}</a>
 		</div>
 		{{template "projects/view" .}}
 	</div>
diff --git a/templates/repo/pulls/fork.tmpl b/templates/repo/pulls/fork.tmpl
index 15635074accb8..66b1c3a276649 100644
--- a/templates/repo/pulls/fork.tmpl
+++ b/templates/repo/pulls/fork.tmpl
@@ -58,7 +58,7 @@
 
 					<div class="inline field">
 						<label></label>
-						<button class="ui green button{{if not .CanForkRepo}} disabled{{end}}">
+						<button class="ui primary button{{if not .CanForkRepo}} disabled{{end}}">
 							{{.locale.Tr "repo.fork_repo"}}
 						</button>
 					</div>
diff --git a/templates/repo/release_tag_header.tmpl b/templates/repo/release_tag_header.tmpl
index ad42b9949f55b..89358e9dd4851 100644
--- a/templates/repo/release_tag_header.tmpl
+++ b/templates/repo/release_tag_header.tmpl
@@ -15,7 +15,7 @@
 			{{end}}
 		</div>
 		{{if and (not .PageIsTagList) .CanCreateRelease}}
-			<a class="ui small green button" href="{{$.RepoLink}}/releases/new">
+			<a class="ui small primary button" href="{{$.RepoLink}}/releases/new">
 				{{.locale.Tr "repo.release.new_release"}}
 			</a>
 		{{end}}
diff --git a/templates/repo/settings/branches.tmpl b/templates/repo/settings/branches.tmpl
index ef227ff4aa050..43203a7ad36e9 100644
--- a/templates/repo/settings/branches.tmpl
+++ b/templates/repo/settings/branches.tmpl
@@ -26,7 +26,7 @@
 								{{end}}
 							</div>
 						</div>
-						<button class="ui green button">{{$.locale.Tr "repo.settings.branches.update_default_branch"}}</button>
+						<button class="ui primary button">{{$.locale.Tr "repo.settings.branches.update_default_branch"}}</button>
 					{{end}}
 				</form>
 			</div>
diff --git a/templates/repo/settings/collaboration.tmpl b/templates/repo/settings/collaboration.tmpl
index c40265c6a61f7..290a1ae0935f9 100644
--- a/templates/repo/settings/collaboration.tmpl
+++ b/templates/repo/settings/collaboration.tmpl
@@ -44,7 +44,7 @@
 				<div id="search-user-box" class="ui search input gt-vm">
 					<input class="prompt" name="collaborator" placeholder="{{.locale.Tr "repo.settings.search_user_placeholder"}}" autocomplete="off" autofocus required>
 				</div>
-				<button class="ui green button">{{.locale.Tr "repo.settings.add_collaborator"}}</button>
+				<button class="ui primary button">{{.locale.Tr "repo.settings.add_collaborator"}}</button>
 			</form>
 		</div>
 
@@ -92,7 +92,7 @@
 					<div id="search-team-box" class="ui search input gt-vm" data-org-name="{{.OrgName}}">
 						<input class="prompt" name="team" placeholder="{{$.locale.Tr "repo.settings.search_team"}}" autocomplete="off" autofocus required>
 					</div>
-					<button class="ui green button">{{$.locale.Tr "repo.settings.add_team"}}</button>
+					<button class="ui primary button">{{$.locale.Tr "repo.settings.add_team"}}</button>
 				</form>
 			{{else}}
 				<div class="item">
diff --git a/templates/repo/settings/deploy_keys.tmpl b/templates/repo/settings/deploy_keys.tmpl
index b776848a5628f..a7b7dd651105c 100644
--- a/templates/repo/settings/deploy_keys.tmpl
+++ b/templates/repo/settings/deploy_keys.tmpl
@@ -34,7 +34,7 @@
 							<small style="padding-left: 26px;">{{$.locale.Tr "repo.settings.is_writable_info" | Str2html}}</small>
 						</div>
 					</div>
-					<button class="ui green button">
+					<button class="ui primary button">
 						{{.locale.Tr "repo.settings.add_deploy_key"}}
 					</button>
 					<button class="ui hide-panel button" data-panel="#add-deploy-key-panel">
diff --git a/templates/repo/settings/githook_edit.tmpl b/templates/repo/settings/githook_edit.tmpl
index 3d212b5ffd00c..c2fabd02ed61f 100644
--- a/templates/repo/settings/githook_edit.tmpl
+++ b/templates/repo/settings/githook_edit.tmpl
@@ -18,7 +18,7 @@
 						<div class="editor-loading is-loading"></div>
 					</div>
 					<div class="inline field">
-						<button class="ui green button">{{$.locale.Tr "repo.settings.update_githook"}}</button>
+						<button class="ui primary button">{{$.locale.Tr "repo.settings.update_githook"}}</button>
 					</div>
 				{{end}}
 			</form>
diff --git a/templates/repo/settings/lfs_pointers.tmpl b/templates/repo/settings/lfs_pointers.tmpl
index b6b58a37720a8..db3fdd2f85150 100644
--- a/templates/repo/settings/lfs_pointers.tmpl
+++ b/templates/repo/settings/lfs_pointers.tmpl
@@ -11,7 +11,7 @@
 								<input type="hidden" name="oid" value="{{.Oid}} {{.Size}}">
 							{{end}}
 						{{end}}
-						<button class="ui green button">{{$.locale.Tr "repo.settings.lfs_pointers.associateAccessible" $.NumAssociatable}}</button>
+						<button class="ui primary button">{{$.locale.Tr "repo.settings.lfs_pointers.associateAccessible" $.NumAssociatable}}</button>
 					</form>
 				</div>
 			{{end}}
diff --git a/templates/repo/settings/options.tmpl b/templates/repo/settings/options.tmpl
index 78700e05b7d8f..28841de4cd69d 100644
--- a/templates/repo/settings/options.tmpl
+++ b/templates/repo/settings/options.tmpl
@@ -45,7 +45,7 @@
 					<input id="website" name="website" type="url" maxlength="1024" value="{{.Repository.Website}}">
 				</div>
 				<div class="field">
-					<button class="ui green button">{{$.locale.Tr "repo.settings.update_settings"}}</button>
+					<button class="ui primary button">{{$.locale.Tr "repo.settings.update_settings"}}</button>
 				</div>
 			</form>
 
@@ -57,7 +57,7 @@
 					<input name="avatar" type="file" accept="image/png,image/jpeg,image/gif,image/webp">
 				</div>
 				<div class="field">
-					<button class="ui green button">{{$.locale.Tr "settings.update_avatar"}}</button>
+					<button class="ui primary button">{{$.locale.Tr "settings.update_avatar"}}</button>
 					<button class="ui red button link-action" data-url="{{.Link}}/avatar/delete">{{$.locale.Tr "settings.delete_current_avatar"}}</button>
 				</div>
 			</form>
@@ -189,7 +189,7 @@
 									</div>
 									{{end}}
 									<div class="field">
-										<button class="ui green button">{{$.locale.Tr "repo.settings.update_mirror_settings"}}</button>
+										<button class="ui primary button">{{$.locale.Tr "repo.settings.update_mirror_settings"}}</button>
 									</div>
 								</form>
 							</td>
@@ -271,7 +271,7 @@
 											<input id="push_mirror_interval" name="push_mirror_interval" value="{{if .push_mirror_interval}}{{.push_mirror_interval}}{{else}}{{.DefaultMirrorInterval}}{{end}}">
 										</div>
 										<div class="field">
-											<button class="ui green button">{{$.locale.Tr "repo.settings.mirror_settings.push_mirror.add"}}</button>
+											<button class="ui primary button">{{$.locale.Tr "repo.settings.mirror_settings.push_mirror.add"}}</button>
 										</div>
 									</form>
 								</td>
@@ -586,7 +586,7 @@
 
 				<div class="divider"></div>
 				<div class="field">
-					<button class="ui green button">{{$.locale.Tr "repo.settings.update_settings"}}</button>
+					<button class="ui primary button">{{$.locale.Tr "repo.settings.update_settings"}}</button>
 				</div>
 			</form>
 		</div>
@@ -632,7 +632,7 @@
 
 				<div class="divider"></div>
 				<div class="field">
-					<button class="ui green button">{{$.locale.Tr "repo.settings.update_settings"}}</button>
+					<button class="ui primary button">{{$.locale.Tr "repo.settings.update_settings"}}</button>
 				</div>
 			</form>
 		</div>
@@ -653,7 +653,7 @@
 				</div>
 
 				<div class="field">
-					<button class="ui green button">{{$.locale.Tr "repo.settings.update_settings"}}</button>
+					<button class="ui primary button">{{$.locale.Tr "repo.settings.update_settings"}}</button>
 				</div>
 			</form>
 
@@ -675,7 +675,7 @@
 							{{end}}
 						</span>
 						<div class="field">
-							<button class="ui green button" name="request_reindex_type" value="code">{{$.locale.Tr "repo.settings.reindex_button"}}</button>
+							<button class="ui primary button" name="request_reindex_type" value="code">{{$.locale.Tr "repo.settings.reindex_button"}}</button>
 						</div>
 					</div>
 				{{end}}
@@ -694,7 +694,7 @@
 						{{end}}
 					</span>
 					<div class="field">
-						<button class="ui green button" name="request_reindex_type" value="stats">{{$.locale.Tr "repo.settings.reindex_button"}}</button>
+						<button class="ui primary button" name="request_reindex_type" value="stats">{{$.locale.Tr "repo.settings.reindex_button"}}</button>
 					</div>
 				</div>
 			</form>
diff --git a/templates/repo/settings/protected_branch.tmpl b/templates/repo/settings/protected_branch.tmpl
index eb5baff59bd14..74cb84aba3c71 100644
--- a/templates/repo/settings/protected_branch.tmpl
+++ b/templates/repo/settings/protected_branch.tmpl
@@ -255,7 +255,7 @@
 				<div class="divider"></div>
 
 				<div class="field">
-					<button class="ui green button">{{$.locale.Tr "repo.settings.protected_branch.save_rule"}}</button>
+					<button class="ui primary button">{{$.locale.Tr "repo.settings.protected_branch.save_rule"}}</button>
 				</div>
 			</div>
 		</form>
diff --git a/templates/repo/settings/tags.tmpl b/templates/repo/settings/tags.tmpl
index c3d2fc38de013..48b67697c8ed5 100644
--- a/templates/repo/settings/tags.tmpl
+++ b/templates/repo/settings/tags.tmpl
@@ -57,14 +57,14 @@
 								{{end}}
 								<div class="field">
 									{{if .PageIsEditProtectedTag}}
-									<button class="ui green button">
+									<button class="ui primary button">
 										{{$.locale.Tr "save"}}
 									</button>
 									<a class="ui primary button" href="{{$.RepoLink}}/settings/tags">
 										{{$.locale.Tr "cancel"}}
 									</a>
 									{{else}}
-									<button class="ui green button">
+									<button class="ui primary button">
 										{{$.locale.Tr "repo.settings.tags.protection.create"}}
 									</button>
 									{{end}}
diff --git a/templates/repo/settings/webhook/settings.tmpl b/templates/repo/settings/webhook/settings.tmpl
index d84c8eb110632..a669d2c9a3d5d 100644
--- a/templates/repo/settings/webhook/settings.tmpl
+++ b/templates/repo/settings/webhook/settings.tmpl
@@ -278,9 +278,9 @@
 </div>
 <div class="field">
 	{{if $isNew}}
-		<button class="ui green button">{{.locale.Tr "repo.settings.add_webhook"}}</button>
+		<button class="ui primary button">{{.locale.Tr "repo.settings.add_webhook"}}</button>
 	{{else}}
-		<button class="ui green button">{{.locale.Tr "repo.settings.update_webhook"}}</button>
+		<button class="ui primary button">{{.locale.Tr "repo.settings.update_webhook"}}</button>
 		<a class="ui red delete-button button" data-url="{{.BaseLink}}/delete" data-id="{{.Webhook.ID}}">{{.locale.Tr "repo.settings.delete_webhook"}}</a>
 	{{end}}
 </div>
diff --git a/templates/repo/wiki/new.tmpl b/templates/repo/wiki/new.tmpl
index 2098a7675514c..d122ee5119f28 100644
--- a/templates/repo/wiki/new.tmpl
+++ b/templates/repo/wiki/new.tmpl
@@ -6,7 +6,7 @@
 		<div class="ui header flex-text-block gt-sb">
 			{{.locale.Tr "repo.wiki.new_page"}}
 			{{if .PageIsWikiEdit}}
-				<a class="ui green tiny button" href="{{.RepoLink}}/wiki?action=_new">{{.locale.Tr "repo.wiki.new_page_button"}}</a>
+				<a class="ui tiny primary button" href="{{.RepoLink}}/wiki?action=_new">{{.locale.Tr "repo.wiki.new_page_button"}}</a>
 			{{end}}
 		</div>
 		<form class="ui form" action="{{.Link}}?action={{if .PageIsWikiEdit}}_edit{{else}}_new{{end}}" method="post">
@@ -37,7 +37,7 @@
 			</div>
 			<div class="divider"></div>
 			<div class="text right">
-				<button class="ui green button">
+				<button class="ui primary button">
 					{{.locale.Tr "repo.wiki.save_page"}}
 				</button>
 			</div>
diff --git a/templates/repo/wiki/pages.tmpl b/templates/repo/wiki/pages.tmpl
index 6169109ce921e..c778933e8b44b 100644
--- a/templates/repo/wiki/pages.tmpl
+++ b/templates/repo/wiki/pages.tmpl
@@ -6,7 +6,7 @@
 			<span>{{.locale.Tr "repo.wiki.pages"}}</span>
 			<span>
 				{{if and .CanWriteWiki (not .Repository.IsMirror)}}
-					<a class="ui green small button" href="{{.RepoLink}}/wiki?action=_new">{{.locale.Tr "repo.wiki.new_page_button"}}</a>
+					<a class="ui small primary button" href="{{.RepoLink}}/wiki?action=_new">{{.locale.Tr "repo.wiki.new_page_button"}}</a>
 				{{end}}
 			</span>
 		</h2>
diff --git a/templates/repo/wiki/start.tmpl b/templates/repo/wiki/start.tmpl
index 4885042fd852e..dbe625c568b35 100644
--- a/templates/repo/wiki/start.tmpl
+++ b/templates/repo/wiki/start.tmpl
@@ -7,7 +7,7 @@
 			<h2>{{.locale.Tr "repo.wiki.welcome"}}</h2>
 			<p>{{.locale.Tr "repo.wiki.welcome_desc"}}</p>
 			{{if and .CanWriteWiki (not .Repository.IsMirror)}}
-				<a class="ui green button" href="{{.RepoLink}}/wiki?action=_new">{{.locale.Tr "repo.wiki.create_first_page"}}</a>
+				<a class="ui primary button" href="{{.RepoLink}}/wiki?action=_new">{{.locale.Tr "repo.wiki.create_first_page"}}</a>
 			{{end}}
 		</div>
 	</div>
diff --git a/templates/repo/wiki/view.tmpl b/templates/repo/wiki/view.tmpl
index be59064d2b147..4427a986dfd70 100644
--- a/templates/repo/wiki/view.tmpl
+++ b/templates/repo/wiki/view.tmpl
@@ -51,8 +51,8 @@
 					{{if and .CanWriteWiki (not .Repository.IsMirror)}}
 						<div class="ui right">
 							<a class="ui small button" href="{{.RepoLink}}/wiki/{{.PageURL}}?action=_edit">{{.locale.Tr "repo.wiki.edit_page_button"}}</a>
-							<a class="ui green small button" href="{{.RepoLink}}/wiki?action=_new">{{.locale.Tr "repo.wiki.new_page_button"}}</a>
-							<a class="ui red small button delete-button" href="" data-url="{{.RepoLink}}/wiki/{{.PageURL}}?action=_delete" data-id="{{.PageURL}}">{{.locale.Tr "repo.wiki.delete_page_button"}}</a>
+							<a class="ui small primary button" href="{{.RepoLink}}/wiki?action=_new">{{.locale.Tr "repo.wiki.new_page_button"}}</a>
+							<a class="ui small red button delete-button" href="" data-url="{{.RepoLink}}/wiki/{{.PageURL}}?action=_delete" data-id="{{.PageURL}}">{{.locale.Tr "repo.wiki.delete_page_button"}}</a>
 						</div>
 					{{end}}
 				</div>
diff --git a/templates/shared/actions/runner_edit.tmpl b/templates/shared/actions/runner_edit.tmpl
index e69583b9e499e..ec3c25ab87b24 100644
--- a/templates/shared/actions/runner_edit.tmpl
+++ b/templates/shared/actions/runner_edit.tmpl
@@ -39,7 +39,7 @@
 			<div class="divider"></div>
 
 			<div class="field">
-				<button class="ui green button" data-url="{{.Link}}">{{.locale.Tr "actions.runners.update_runner"}}</button>
+				<button class="ui primary button" data-url="{{.Link}}">{{.locale.Tr "actions.runners.update_runner"}}</button>
 				<button class="ui red button delete-button show-modal" data-url="{{.Link}}/delete" data-modal="#runner-delete-modal">
 					{{.locale.Tr "actions.runners.delete_runner"}}</button>
 			</div>
diff --git a/templates/shared/user/profile_big_avatar.tmpl b/templates/shared/user/profile_big_avatar.tmpl
index 44797ff4a75cc..e328c26e1f61c 100644
--- a/templates/shared/user/profile_big_avatar.tmpl
+++ b/templates/shared/user/profile_big_avatar.tmpl
@@ -112,7 +112,7 @@
 						{{svg "octicon-person"}} {{.locale.Tr "user.unfollow"}}
 					</button>
 				{{else}}
-					<button class="ui basic green button link-action" data-url="{{.ContextUser.HomeLink}}?action=follow">
+					<button class="ui basic primary button link-action" data-url="{{.ContextUser.HomeLink}}?action=follow">
 						{{svg "octicon-person"}} {{.locale.Tr "user.follow"}}
 					</button>
 				{{end}}
diff --git a/templates/shared/variables/variable_list.tmpl b/templates/shared/variables/variable_list.tmpl
index a9456321e4454..3a389ffaf823c 100644
--- a/templates/shared/variables/variable_list.tmpl
+++ b/templates/shared/variables/variable_list.tmpl
@@ -73,7 +73,7 @@
 					name="name"
 					id="dialog-variable-name"
 					value="{{.name}}"
-					pattern="^[a-zA-Z_][a-zA-Z0-9_]*$"
+					pattern="^(?!GITEA_|GITHUB_)[a-zA-Z_][a-zA-Z0-9_]*$"
 					placeholder="{{.locale.Tr "secrets.creation.name_placeholder"}}"
 				>
 			</div>
diff --git a/templates/user/auth/activate.tmpl b/templates/user/auth/activate.tmpl
index 9a2abd3cdfee6..3261836ee02e2 100644
--- a/templates/user/auth/activate.tmpl
+++ b/templates/user/auth/activate.tmpl
@@ -25,7 +25,7 @@
 							</div>
 							<div class="inline field">
 								<label></label>
-								<button class="ui green button">{{.locale.Tr "install.confirm_password"}}</button>
+								<button class="ui primary button">{{.locale.Tr "install.confirm_password"}}</button>
 							</div>
 							<input id="code" name="code" type="hidden" value="{{.Code}}">
 						{{else if .IsSendRegisterMail}}
diff --git a/templates/user/auth/change_passwd_inner.tmpl b/templates/user/auth/change_passwd_inner.tmpl
index 40281f8578e20..317a031f6b9f7 100644
--- a/templates/user/auth/change_passwd_inner.tmpl
+++ b/templates/user/auth/change_passwd_inner.tmpl
@@ -17,7 +17,7 @@
 			</div>
 			<div class="inline field">
 				<label></label>
-				<button class="ui green button">{{.locale.Tr "settings.change_password"}}</button>
+				<button class="ui primary button">{{.locale.Tr "settings.change_password"}}</button>
 			</div>
 			</form>
 		</div>
diff --git a/templates/user/auth/finalize_openid.tmpl b/templates/user/auth/finalize_openid.tmpl
index 2b833d9b3269b..e81a565507d70 100644
--- a/templates/user/auth/finalize_openid.tmpl
+++ b/templates/user/auth/finalize_openid.tmpl
@@ -29,7 +29,7 @@
 
 					<div class="inline field">
 						<label></label>
-						<button class="ui green button">{{.locale.Tr "sign_in"}}</button>
+						<button class="ui primary button">{{.locale.Tr "sign_in"}}</button>
 						<a href="{{AppSubUrl}}/user/forget_password">{{.locale.Tr "auth.forget_password"}}</a>
 					</div>
 					{{if .ShowRegistrationButton}}
diff --git a/templates/user/auth/signin_inner.tmpl b/templates/user/auth/signin_inner.tmpl
index 6b118b7a261f2..2b72f119cbbd8 100644
--- a/templates/user/auth/signin_inner.tmpl
+++ b/templates/user/auth/signin_inner.tmpl
@@ -35,7 +35,7 @@
 
 	<div class="inline field">
 		<label></label>
-		<button class="ui green button">
+		<button class="ui primary button">
 			{{if .LinkAccountMode}}
 				{{.locale.Tr "auth.oauth_signin_submit"}}
 			{{else}}
@@ -62,7 +62,7 @@
 				{{range $key := .OrderedOAuth2Names}}
 					{{$provider := index $.OAuth2Providers $key}}
 					<a class="{{$provider.Name}} ui button gt-df gt-ac gt-jc gt-py-3 oauth-login-link" href="{{AppSubUrl}}/user/oauth2/{{$key}}">
-						{{$provider.IconHTML}}
+						{{$provider.IconHTML 28}}
 						{{$.locale.Tr "sign_in_with_provider" $provider.DisplayName}}
 					</a>
 				{{end}}
diff --git a/templates/user/auth/signin_openid.tmpl b/templates/user/auth/signin_openid.tmpl
index 7a54589fd9e08..e1017dca28a5c 100644
--- a/templates/user/auth/signin_openid.tmpl
+++ b/templates/user/auth/signin_openid.tmpl
@@ -29,7 +29,7 @@
 			</div>
 			<div class="inline field">
 				<label></label>
-				<button class="ui green button">{{.locale.Tr "sign_in"}}</button>
+				<button class="ui primary button">{{.locale.Tr "sign_in"}}</button>
 			</div>
 			</form>
 		</div>
diff --git a/templates/user/auth/signup_inner.tmpl b/templates/user/auth/signup_inner.tmpl
index 184b8b88fe0b6..e3dd337837952 100644
--- a/templates/user/auth/signup_inner.tmpl
+++ b/templates/user/auth/signup_inner.tmpl
@@ -39,7 +39,7 @@
 
 				<div class="inline field">
 					<label></label>
-					<button class="ui green button">
+					<button class="ui primary button">
 						{{if .LinkAccountMode}}
 							{{.locale.Tr "auth.oauth_signup_submit"}}
 						{{else}}
@@ -66,7 +66,7 @@
 						{{range $key := .OrderedOAuth2Names}}
 							{{$provider := index $.OAuth2Providers $key}}
 							<a class="{{$provider.Name}} ui button gt-df gt-ac gt-jc gt-py-3 oauth-login-link" href="{{AppSubUrl}}/user/oauth2/{{$key}}">
-								{{$provider.IconHTML}}
+								{{$provider.IconHTML 28}}
 								{{$.locale.Tr "sign_in_with_provider" $provider.DisplayName}}
 							</a>
 						{{end}}
diff --git a/templates/user/auth/signup_openid_connect.tmpl b/templates/user/auth/signup_openid_connect.tmpl
index 89a2e410e89a6..1a470415c6992 100644
--- a/templates/user/auth/signup_openid_connect.tmpl
+++ b/templates/user/auth/signup_openid_connect.tmpl
@@ -26,7 +26,7 @@
 					</div>
 					<div class="inline field">
 						<label></label>
-						<button class="ui green button">{{.locale.Tr "auth.openid_connect_submit"}}</button>
+						<button class="ui primary button">{{.locale.Tr "auth.openid_connect_submit"}}</button>
 						<a href="{{AppSubUrl}}/user/forgot_password">{{.locale.Tr "auth.forgot_password"}}</a>
 					</div>
 					</form>
diff --git a/templates/user/auth/signup_openid_register.tmpl b/templates/user/auth/signup_openid_register.tmpl
index a490ea5a74d8f..9736c53ed830b 100644
--- a/templates/user/auth/signup_openid_register.tmpl
+++ b/templates/user/auth/signup_openid_register.tmpl
@@ -29,7 +29,7 @@
 					</div>
 					<div class="inline field">
 						<label></label>
-						<button class="ui green button">{{.locale.Tr "auth.create_new_account"}}</button>
+						<button class="ui primary button">{{.locale.Tr "auth.create_new_account"}}</button>
 					</div>
 					</form>
 				</div>
diff --git a/templates/user/auth/twofa.tmpl b/templates/user/auth/twofa.tmpl
index 4002266054e2d..e303580956581 100644
--- a/templates/user/auth/twofa.tmpl
+++ b/templates/user/auth/twofa.tmpl
@@ -16,7 +16,7 @@
 
 					<div class="inline field">
 						<label></label>
-						<button class="ui green button">{{.locale.Tr "auth.verify"}}</button>
+						<button class="ui primary button">{{.locale.Tr "auth.verify"}}</button>
 						<a href="{{AppSubUrl}}/user/two_factor/scratch">{{.locale.Tr "auth.use_scratch_code" | Str2html}}</a>
 					</div>
 				</div>
diff --git a/templates/user/auth/twofa_scratch.tmpl b/templates/user/auth/twofa_scratch.tmpl
index 4ed7fce55e9d3..58942050f5d09 100644
--- a/templates/user/auth/twofa_scratch.tmpl
+++ b/templates/user/auth/twofa_scratch.tmpl
@@ -16,7 +16,7 @@
 
 					<div class="inline field">
 						<label></label>
-						<button class="ui green button">{{.locale.Tr "auth.verify"}}</button>
+						<button class="ui primary button">{{.locale.Tr "auth.verify"}}</button>
 					</div>
 				</div>
 			</form>
diff --git a/templates/user/dashboard/issues.tmpl b/templates/user/dashboard/issues.tmpl
index 00c604bfc4a76..a973eb59e4bf8 100644
--- a/templates/user/dashboard/issues.tmpl
+++ b/templates/user/dashboard/issues.tmpl
@@ -101,9 +101,9 @@
 					</div>
 					{{if .SingleRepoLink}}
 						{{if eq .SingleRepoAction "issue"}}
-							<a class="ui green button gt-ml-4" href="{{.SingleRepoLink}}/issues/new/choose">{{.locale.Tr "repo.issues.new"}}</a>
+							<a class="ui primary button gt-ml-4" href="{{.SingleRepoLink}}/issues/new/choose">{{.locale.Tr "repo.issues.new"}}</a>
 						{{else if eq .SingleRepoAction "pull"}}
-							<a class="ui green button gt-ml-4" href="{{.SingleRepoLink}}/compare">{{.locale.Tr "repo.pulls.new"}}</a>
+							<a class="ui primary button gt-ml-4" href="{{.SingleRepoLink}}/compare">{{.locale.Tr "repo.pulls.new"}}</a>
 						{{end}}
 					{{end}}
 				</div>
diff --git a/templates/user/dashboard/milestones.tmpl b/templates/user/dashboard/milestones.tmpl
index d9921ab59bf89..d18ed3791099b 100644
--- a/templates/user/dashboard/milestones.tmpl
+++ b/templates/user/dashboard/milestones.tmpl
@@ -59,8 +59,8 @@
 					<div class="list-header-sort ui dropdown type jump item">
 						<span class="text">
 							{{.locale.Tr "repo.issues.filter_sort"}}
-							{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 						</span>
+						{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 						<div class="menu">
 							<a class="{{if or (eq .SortType "closestduedate") (not .SortType)}}active {{end}}item" href="{{$.Link}}?repos=[{{range $.RepoIDs}}{{.}}%2C{{end}}]&sort=closestduedate&state={{$.State}}&q={{$.Keyword}}">{{.locale.Tr "repo.milestones.filter_sort.closest_due_date"}}</a>
 							<a class="{{if eq .SortType "furthestduedate"}}active {{end}}item" href="{{$.Link}}?repos=[{{range $.RepoIDs}}{{.}}%2C{{end}}]&sort=furthestduedate&state={{$.State}}&q={{$.Keyword}}">{{.locale.Tr "repo.milestones.filter_sort.furthest_due_date"}}</a>
diff --git a/templates/user/dashboard/navbar.tmpl b/templates/user/dashboard/navbar.tmpl
index ee9e7e60adc06..f9c6a29513b40 100644
--- a/templates/user/dashboard/navbar.tmpl
+++ b/templates/user/dashboard/navbar.tmpl
@@ -53,8 +53,8 @@
 						{{else}}
 							{{.locale.Tr "org.teams"}}
 						{{end}}
-						{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 					</span>
+					{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 					<div class="context user overflow menu">
 						<div class="ui header">
 							{{.locale.Tr "home.filter_by_team_repositories"}}
diff --git a/templates/user/notification/notification_subscriptions.tmpl b/templates/user/notification/notification_subscriptions.tmpl
index ec93935874997..6d3f9759f82af 100644
--- a/templates/user/notification/notification_subscriptions.tmpl
+++ b/templates/user/notification/notification_subscriptions.tmpl
@@ -33,8 +33,8 @@
 								<div class="ui dropdown type jump item">
 									<span class="text">
 										{{.locale.Tr "repo.issues.filter_type"}}
-										{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 									</span>
+									{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 									<div class="menu">
 										<a class="{{if or (eq .IssueType "all") (not .IssueType)}}active {{end}}item" href="{{$.Link}}?sort={{$.SortType}}&state={{$.State}}&issueType=all&labels={{$.Labels}}">{{.locale.Tr "all"}}</a>
 										<a class="{{if eq .IssueType "issues"}}active {{end}}item" href="{{$.Link}}?sort={{$.SortType}}&state={{$.State}}&issueType=issues&labels={{$.Labels}}">{{.locale.Tr "issues"}}</a>
@@ -46,8 +46,8 @@
 							<div class="ui dropdown type jump item">
 								<span class="text">
 									{{.locale.Tr "repo.issues.filter_sort"}}
-									{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 								</span>
+								{{svg "octicon-triangle-down" 14 "dropdown icon"}}
 								<div class="menu">
 									<a class="{{if or (eq .SortType "latest") (not .SortType)}}active {{end}}item" href="{{$.Link}}?sort=latest&state={{$.State}}&issueType={{$.IssueType}}&labels={{$.Labels}}">{{.locale.Tr "repo.issues.filter_sort.latest"}}</a>
 									<a class="{{if eq .SortType "oldest"}}active {{end}}item" href="{{$.Link}}?sort=oldest&state={{$.State}}&issueType={{$.IssueType}}&labels={{$.Labels}}">{{.locale.Tr "repo.issues.filter_sort.oldest"}}</a>
diff --git a/templates/user/settings/account.tmpl b/templates/user/settings/account.tmpl
index 0b57720c96820..173cd5e991585 100644
--- a/templates/user/settings/account.tmpl
+++ b/templates/user/settings/account.tmpl
@@ -24,7 +24,7 @@
 				</div>
 
 				<div class="field">
-					<button class="ui green button">{{$.locale.Tr "settings.change_password"}}</button>
+					<button class="ui primary button">{{$.locale.Tr "settings.change_password"}}</button>
 					<a href="{{AppSubUrl}}/user/forgot_password?email={{.Email}}">{{.locale.Tr "auth.forgot_password"}}</a>
 				</div>
 			</form>
@@ -58,7 +58,7 @@
 									<div data-value="disabled" class="{{if eq .EmailNotificationsPreference "disabled"}}active selected {{end}}item">{{$.locale.Tr "settings.email_notifications.disable"}}</div>
 								</div>
 							</div>
-							<button class="ui green button">{{$.locale.Tr "settings.email_notifications.submit"}}</button>
+							<button class="ui primary button">{{$.locale.Tr "settings.email_notifications.submit"}}</button>
 						</div>
 					</form>
 				</div>
@@ -118,7 +118,7 @@
 					<label for="email">{{.locale.Tr "settings.add_new_email"}}</label>
 					<input id="email" name="email" type="email" required {{if not .CanAddEmails}}disabled{{end}}>
 				</div>
-				<button class="ui green button" {{if not .CanAddEmails}}disabled{{end}}>
+				<button class="ui primary button" {{if not .CanAddEmails}}disabled{{end}}>
 					{{.locale.Tr "settings.add_email"}}
 				</button>
 			</form>
diff --git a/templates/user/settings/appearance.tmpl b/templates/user/settings/appearance.tmpl
index 129fca26577f9..ca7ef15de5fe7 100644
--- a/templates/user/settings/appearance.tmpl
+++ b/templates/user/settings/appearance.tmpl
@@ -35,7 +35,7 @@
 					</div>
 
 				<div class="field">
-					<button class="ui green button">{{$.locale.Tr "settings.update_theme"}}</button>
+					<button class="ui primary button">{{$.locale.Tr "settings.update_theme"}}</button>
 				</div>
 			</form>
 			</div>
@@ -61,7 +61,7 @@
 					</div>
 				</div>
 				<div class="field">
-					<button class="ui green button">{{$.locale.Tr "settings.update_language"}}</button>
+					<button class="ui primary button">{{$.locale.Tr "settings.update_language"}}</button>
 				</div>
 			</form>
 		</div>
@@ -162,7 +162,7 @@
 					</div>
 				</div>
 				<div class="field">
-					<button class="ui green button">{{$.locale.Tr "save"}}</button>
+					<button class="ui primary button">{{$.locale.Tr "save"}}</button>
 				</div>
 			</form>
 		</div>
diff --git a/templates/user/settings/applications.tmpl b/templates/user/settings/applications.tmpl
index f142af3876048..bc7755eb77c62 100644
--- a/templates/user/settings/applications.tmpl
+++ b/templates/user/settings/applications.tmpl
@@ -86,7 +86,7 @@
 						></scoped-access-token-selector>
 					</div>
 				</details>
-				<button id="scoped-access-submit" class="ui green button">
+				<button id="scoped-access-submit" class="ui primary button">
 					{{.locale.Tr "settings.generate_token"}}
 				</button>
 			</form>{{/* Fomantic ".ui.form .warning.message" is hidden by default, so put the warning message out of the form*/}}
diff --git a/templates/user/settings/applications_oauth2_edit_form.tmpl b/templates/user/settings/applications_oauth2_edit_form.tmpl
index 74a0e13918879..1437277009546 100644
--- a/templates/user/settings/applications_oauth2_edit_form.tmpl
+++ b/templates/user/settings/applications_oauth2_edit_form.tmpl
@@ -45,7 +45,7 @@
 			<label>{{.locale.Tr "settings.oauth2_confidential_client"}}</label>
 			<input type="checkbox" name="confidential_client" {{if .App.ConfidentialClient}}checked{{end}}>
 		</div>
-		<button class="ui green button">
+		<button class="ui primary button">
 			{{.locale.Tr "settings.save_application"}}
 		</button>
 	</form>
diff --git a/templates/user/settings/applications_oauth2_list.tmpl b/templates/user/settings/applications_oauth2_list.tmpl
index 348bc82b4e8b9..a92909f77f47b 100644
--- a/templates/user/settings/applications_oauth2_list.tmpl
+++ b/templates/user/settings/applications_oauth2_list.tmpl
@@ -65,7 +65,7 @@
 			<label>{{.locale.Tr "settings.oauth2_confidential_client"}}</label>
 			<input type="checkbox" name="confidential_client" checked>
 		</div>
-		<button class="ui green button">
+		<button class="ui primary button">
 			{{.locale.Tr "settings.create_oauth2_application_button"}}
 		</button>
 	</form>
diff --git a/templates/user/settings/keys_gpg.tmpl b/templates/user/settings/keys_gpg.tmpl
index 2ecebcd7c01b6..467b275d35515 100644
--- a/templates/user/settings/keys_gpg.tmpl
+++ b/templates/user/settings/keys_gpg.tmpl
@@ -31,7 +31,7 @@
 				</div>
 			{{end}}
 			<input name="type" type="hidden" value="gpg">
-			<button class="ui green button">
+			<button class="ui primary button">
 				{{.locale.Tr "settings.add_key"}}
 			</button>
 			<button class="ui hide-panel button" data-panel="#add-gpg-key-panel">
@@ -99,7 +99,7 @@
 							<textarea id="gpg-key-signature" name="signature" placeholder="{{$.locale.Tr "settings.key_signature_gpg_placeholder"}}" required>{{$.signature}}</textarea>
 						</div>
 						<input name="type" type="hidden" value="verify_gpg">
-						<button class="ui green button">
+						<button class="ui primary button">
 							{{$.locale.Tr "settings.gpg_key_verify"}}
 						</button>
 						<a class="ui red button" href="{{$.Link}}">
diff --git a/templates/user/settings/keys_principal.tmpl b/templates/user/settings/keys_principal.tmpl
index 42c21373d53c1..d9cc8fb8237e8 100644
--- a/templates/user/settings/keys_principal.tmpl
+++ b/templates/user/settings/keys_principal.tmpl
@@ -49,7 +49,7 @@
 				</div>
 				<input name="title" type="hidden" value="principal">
 				<input name="type" type="hidden" value="principal">
-				<button class="ui green button">
+				<button class="ui primary button">
 					{{.locale.Tr "settings.add_new_principal"}}
 				</button>
 			</form>
diff --git a/templates/user/settings/keys_ssh.tmpl b/templates/user/settings/keys_ssh.tmpl
index 8419f72ff547c..626d34fd33c12 100644
--- a/templates/user/settings/keys_ssh.tmpl
+++ b/templates/user/settings/keys_ssh.tmpl
@@ -19,7 +19,7 @@
 				<textarea id="ssh-key-content" name="content" class="js-quick-submit" placeholder="{{.locale.Tr "settings.key_content_ssh_placeholder"}}" required>{{.content}}</textarea>
 			</div>
 			<input name="type" type="hidden" value="ssh">
-			<button class="ui green button">
+			<button class="ui primary button">
 				{{.locale.Tr "settings.add_key"}}
 			</button>
 			<button id="cancel-ssh-button" class="ui hide-panel button" data-panel="#add-ssh-key-panel">
@@ -87,7 +87,7 @@
 							<textarea id="ssh-key-signature" name="signature" class="js-quick-submit" placeholder="{{$.locale.Tr "settings.key_signature_ssh_placeholder"}}" required>{{$.signature}}</textarea>
 						</div>
 						<input name="type" type="hidden" value="verify_ssh">
-						<button class="ui green button">
+						<button class="ui primary button">
 							{{$.locale.Tr "settings.ssh_key_verify"}}
 						</button>
 						<a class="ui red button" href="{{$.Link}}">
diff --git a/templates/user/settings/packages.tmpl b/templates/user/settings/packages.tmpl
index 304940feb83ca..f4933d3dae480 100644
--- a/templates/user/settings/packages.tmpl
+++ b/templates/user/settings/packages.tmpl
@@ -13,7 +13,7 @@
 				</div>
 				<form class="field" action="{{.Link}}/chef/regenerate_keypair" method="post">
 					{{.CsrfTokenHtml}}
-					<button class="ui green button">{{$.locale.Tr "packages.owner.settings.chef.keypair"}}</button>
+					<button class="ui primary button">{{$.locale.Tr "packages.owner.settings.chef.keypair"}}</button>
 				</form>
 				<div class="field">
 					<label>{{.locale.Tr "packages.registry.documentation" "Chef" "https://docs.gitea.com/usage/packages/chef/" | Safe}}</label>
diff --git a/templates/user/settings/profile.tmpl b/templates/user/settings/profile.tmpl
index 6db58fe4db6c8..34c790065a018 100644
--- a/templates/user/settings/profile.tmpl
+++ b/templates/user/settings/profile.tmpl
@@ -88,7 +88,7 @@
 				<div class="divider"></div>
 
 				<div class="field">
-					<button class="ui green button">{{$.locale.Tr "settings.update_profile"}}</button>
+					<button class="ui primary button">{{$.locale.Tr "settings.update_profile"}}</button>
 				</div>
 			</form>
 		</div>
@@ -125,7 +125,7 @@
 				</div>
 
 				<div class="field">
-					<button class="ui green button">{{$.locale.Tr "settings.update_avatar"}}</button>
+					<button class="ui primary button">{{$.locale.Tr "settings.update_avatar"}}</button>
 					<button class="ui red button link-action" data-url="{{.Link}}/avatar/delete">{{$.locale.Tr "settings.delete_current_avatar"}}</button>
 				</div>
 			</form>
diff --git a/templates/user/settings/repos.tmpl b/templates/user/settings/repos.tmpl
index caee1135c5137..db912770d2979 100644
--- a/templates/user/settings/repos.tmpl
+++ b/templates/user/settings/repos.tmpl
@@ -34,7 +34,7 @@
 										<span class="name gt-dib gt-pt-3">{{$.ContextUser.Name}}/{{$dir}}</span>
 										<div class="gt-float-right">
 											{{if $.allowAdopt}}
-												<button class="ui button green show-modal gt-p-3" data-modal="#adopt-unadopted-modal-{{$dirI}}"><span class="icon">{{svg "octicon-plus"}}</span><span class="label">{{$.locale.Tr "repo.adopt_preexisting_label"}}</span></button>
+												<button class="ui button primary show-modal gt-p-3" data-modal="#adopt-unadopted-modal-{{$dirI}}"><span class="icon">{{svg "octicon-plus"}}</span><span class="label">{{$.locale.Tr "repo.adopt_preexisting_label"}}</span></button>
 												<div class="ui g-modal-confirm modal" id="adopt-unadopted-modal-{{$dirI}}">
 													<div class="header">
 														<span class="label">{{$.locale.Tr "repo.adopt_preexisting"}}</span>
diff --git a/templates/user/settings/security/accountlinks.tmpl b/templates/user/settings/security/accountlinks.tmpl
index f64277b5aff07..7fbd39cbd418b 100644
--- a/templates/user/settings/security/accountlinks.tmpl
+++ b/templates/user/settings/security/accountlinks.tmpl
@@ -10,7 +10,7 @@
 					{{range $key := .OrderedOAuth2Names}}
 						{{$provider := index $.OAuth2Providers $key}}
 						<a class="item" href="{{AppSubUrl}}/user/oauth2/{{$key}}">
-							{{$provider.IconHTML}}
+							{{$provider.IconHTML 20}}
 							{{$provider.DisplayName}}
 						</a>
 					{{end}}
diff --git a/templates/user/settings/security/openid.tmpl b/templates/user/settings/security/openid.tmpl
index 9563910ba9422..f22b02c8985fa 100644
--- a/templates/user/settings/security/openid.tmpl
+++ b/templates/user/settings/security/openid.tmpl
@@ -45,7 +45,7 @@
 			<label for="openid">{{.locale.Tr "settings.add_new_openid"}}</label>
 			<input id="openid" name="openid" type="text" required>
 		</div>
-		<button class="ui green button">
+		<button class="ui primary button">
 			{{.locale.Tr "settings.add_openid"}}
 		</button>
 	</form>
diff --git a/templates/user/settings/security/twofa.tmpl b/templates/user/settings/security/twofa.tmpl
index f10dbf0b68852..dbf395c4b1e6b 100644
--- a/templates/user/settings/security/twofa.tmpl
+++ b/templates/user/settings/security/twofa.tmpl
@@ -18,7 +18,7 @@
 	{{else}}
 	<p>{{.locale.Tr "settings.twofa_not_enrolled"}}</p>
 	<div class="inline field">
-		<a class="ui green button" href="{{AppSubUrl}}/user/settings/security/two_factor/enroll">{{$.locale.Tr "settings.twofa_enroll"}}</a>
+		<a class="ui primary button" href="{{AppSubUrl}}/user/settings/security/two_factor/enroll">{{$.locale.Tr "settings.twofa_enroll"}}</a>
 	</div>
 	{{end}}
 
diff --git a/templates/user/settings/security/twofa_enroll.tmpl b/templates/user/settings/security/twofa_enroll.tmpl
index 3c27c4d8fa073..9235e4f614cf1 100644
--- a/templates/user/settings/security/twofa_enroll.tmpl
+++ b/templates/user/settings/security/twofa_enroll.tmpl
@@ -16,7 +16,7 @@
 				</div>
 				<div class="inline field">
 					<label></label>
-					<button class="ui green button">{{.locale.Tr "auth.verify"}}</button>
+					<button class="ui primary button">{{.locale.Tr "auth.verify"}}</button>
 				</div>
 			</form>
 		</div>
diff --git a/templates/user/settings/security/webauthn.tmpl b/templates/user/settings/security/webauthn.tmpl
index 676754df5973c..6a74b8770a95e 100644
--- a/templates/user/settings/security/webauthn.tmpl
+++ b/templates/user/settings/security/webauthn.tmpl
@@ -25,7 +25,7 @@
 			<label for="nickname">{{.locale.Tr "settings.webauthn_nickname"}}</label>
 			<input id="nickname" name="nickname" type="text" required>
 		</div>
-		<button id="register-webauthn" class="ui green button">{{svg "octicon-key"}} {{.locale.Tr "settings.webauthn_register_key"}}</button>
+		<button id="register-webauthn" class="ui primary button">{{svg "octicon-key"}} {{.locale.Tr "settings.webauthn_register_key"}}</button>
 	</div>
 	<div class="ui g-modal-confirm delete modal" id="delete-registration">
 		<div class="header">
diff --git a/tests/e2e/example.test.e2e.js b/tests/e2e/example.test.e2e.js
index 870c28cc77a8d..c741663a38f20 100644
--- a/tests/e2e/example.test.e2e.js
+++ b/tests/e2e/example.test.e2e.js
@@ -20,7 +20,7 @@ test('Test Register Form', async ({page}, workerInfo) => {
   await page.type('input[name=email]', `e2e-test-${workerInfo.workerIndex}@test.com`);
   await page.type('input[name=password]', 'test123test123');
   await page.type('input[name=retype]', 'test123test123');
-  await page.click('form button.ui.green.button:visible');
+  await page.click('form button.ui.primary.button:visible');
   // Make sure we routed to the home page. Else login failed.
   await expect(page.url()).toBe(`${workerInfo.project.use.baseURL}/`);
   await expect(page.locator('.dashboard-navbar span>img.ui.avatar')).toBeVisible();
@@ -35,7 +35,7 @@ test('Test Login Form', async ({page}, workerInfo) => {
 
   await page.type('input[name=user_name]', `user2`);
   await page.type('input[name=password]', `password`);
-  await page.click('form button.ui.green.button:visible');
+  await page.click('form button.ui.primary.button:visible');
 
   await page.waitForLoadState('networkidle');
 
diff --git a/tests/e2e/utils_e2e.js b/tests/e2e/utils_e2e.js
index ca6bde8db7a76..fba13ab426279 100644
--- a/tests/e2e/utils_e2e.js
+++ b/tests/e2e/utils_e2e.js
@@ -18,7 +18,7 @@ export async function login_user(browser, workerInfo, user) {
   // Fill out form
   await page.type('input[name=user_name]', user);
   await page.type('input[name=password]', LOGIN_PASSWORD);
-  await page.click('form button.ui.green.button:visible');
+  await page.click('form button.ui.primary.button:visible');
 
   await page.waitForLoadState('networkidle');
 
diff --git a/tests/integration/api_issue_test.go b/tests/integration/api_issue_test.go
index 808d288356f60..29f09fa09e747 100644
--- a/tests/integration/api_issue_test.go
+++ b/tests/integration/api_issue_test.go
@@ -219,7 +219,7 @@ func TestAPISearchIssues(t *testing.T) {
 	token := getUserToken(t, "user2", auth_model.AccessTokenScopeReadIssue)
 
 	// as this API was used in the frontend, it uses UI page size
-	expectedIssueCount := 17 // from the fixtures
+	expectedIssueCount := 18 // from the fixtures
 	if expectedIssueCount > setting.UI.IssuePagingNum {
 		expectedIssueCount = setting.UI.IssuePagingNum
 	}
@@ -243,7 +243,7 @@ func TestAPISearchIssues(t *testing.T) {
 	req = NewRequest(t, "GET", link.String())
 	resp = MakeRequest(t, req, http.StatusOK)
 	DecodeJSON(t, resp, &apiIssues)
-	assert.Len(t, apiIssues, 10)
+	assert.Len(t, apiIssues, 11)
 	query.Del("since")
 	query.Del("before")
 
@@ -259,15 +259,15 @@ func TestAPISearchIssues(t *testing.T) {
 	req = NewRequest(t, "GET", link.String())
 	resp = MakeRequest(t, req, http.StatusOK)
 	DecodeJSON(t, resp, &apiIssues)
-	assert.EqualValues(t, "19", resp.Header().Get("X-Total-Count"))
-	assert.Len(t, apiIssues, 19)
+	assert.EqualValues(t, "20", resp.Header().Get("X-Total-Count"))
+	assert.Len(t, apiIssues, 20)
 
 	query.Add("limit", "10")
 	link.RawQuery = query.Encode()
 	req = NewRequest(t, "GET", link.String())
 	resp = MakeRequest(t, req, http.StatusOK)
 	DecodeJSON(t, resp, &apiIssues)
-	assert.EqualValues(t, "19", resp.Header().Get("X-Total-Count"))
+	assert.EqualValues(t, "20", resp.Header().Get("X-Total-Count"))
 	assert.Len(t, apiIssues, 10)
 
 	query = url.Values{"assigned": {"true"}, "state": {"all"}, "token": {token}}
@@ -317,7 +317,7 @@ func TestAPISearchIssuesWithLabels(t *testing.T) {
 	defer tests.PrepareTestEnv(t)()
 
 	// as this API was used in the frontend, it uses UI page size
-	expectedIssueCount := 17 // from the fixtures
+	expectedIssueCount := 18 // from the fixtures
 	if expectedIssueCount > setting.UI.IssuePagingNum {
 		expectedIssueCount = setting.UI.IssuePagingNum
 	}
diff --git a/tests/integration/api_nodeinfo_test.go b/tests/integration/api_nodeinfo_test.go
index a347ec5b3b1f9..4cbd25f5deab1 100644
--- a/tests/integration/api_nodeinfo_test.go
+++ b/tests/integration/api_nodeinfo_test.go
@@ -33,7 +33,7 @@ func TestNodeinfo(t *testing.T) {
 		assert.True(t, nodeinfo.OpenRegistrations)
 		assert.Equal(t, "gitea", nodeinfo.Software.Name)
 		assert.Equal(t, 25, nodeinfo.Usage.Users.Total)
-		assert.Equal(t, 19, nodeinfo.Usage.LocalPosts)
+		assert.Equal(t, 20, nodeinfo.Usage.LocalPosts)
 		assert.Equal(t, 2, nodeinfo.Usage.LocalComments)
 	})
 }
diff --git a/tests/integration/issue_test.go b/tests/integration/issue_test.go
index 4cae00f0bcb07..853e565b0fac8 100644
--- a/tests/integration/issue_test.go
+++ b/tests/integration/issue_test.go
@@ -356,7 +356,7 @@ func TestSearchIssues(t *testing.T) {
 
 	session := loginUser(t, "user2")
 
-	expectedIssueCount := 17 // from the fixtures
+	expectedIssueCount := 18 // from the fixtures
 	if expectedIssueCount > setting.UI.IssuePagingNum {
 		expectedIssueCount = setting.UI.IssuePagingNum
 	}
@@ -377,7 +377,7 @@ func TestSearchIssues(t *testing.T) {
 	req = NewRequest(t, "GET", link.String())
 	resp = session.MakeRequest(t, req, http.StatusOK)
 	DecodeJSON(t, resp, &apiIssues)
-	assert.Len(t, apiIssues, 10)
+	assert.Len(t, apiIssues, 11)
 	query.Del("since")
 	query.Del("before")
 
@@ -393,15 +393,15 @@ func TestSearchIssues(t *testing.T) {
 	req = NewRequest(t, "GET", link.String())
 	resp = session.MakeRequest(t, req, http.StatusOK)
 	DecodeJSON(t, resp, &apiIssues)
-	assert.EqualValues(t, "19", resp.Header().Get("X-Total-Count"))
-	assert.Len(t, apiIssues, 19)
+	assert.EqualValues(t, "20", resp.Header().Get("X-Total-Count"))
+	assert.Len(t, apiIssues, 20)
 
 	query.Add("limit", "5")
 	link.RawQuery = query.Encode()
 	req = NewRequest(t, "GET", link.String())
 	resp = session.MakeRequest(t, req, http.StatusOK)
 	DecodeJSON(t, resp, &apiIssues)
-	assert.EqualValues(t, "19", resp.Header().Get("X-Total-Count"))
+	assert.EqualValues(t, "20", resp.Header().Get("X-Total-Count"))
 	assert.Len(t, apiIssues, 5)
 
 	query = url.Values{"assigned": {"true"}, "state": {"all"}}
@@ -450,7 +450,7 @@ func TestSearchIssues(t *testing.T) {
 func TestSearchIssuesWithLabels(t *testing.T) {
 	defer tests.PrepareTestEnv(t)()
 
-	expectedIssueCount := 17 // from the fixtures
+	expectedIssueCount := 18 // from the fixtures
 	if expectedIssueCount > setting.UI.IssuePagingNum {
 		expectedIssueCount = setting.UI.IssuePagingNum
 	}
diff --git a/tests/integration/pull_merge_test.go b/tests/integration/pull_merge_test.go
index 0ef0969ab9021..adb0e982c0b09 100644
--- a/tests/integration/pull_merge_test.go
+++ b/tests/integration/pull_merge_test.go
@@ -54,7 +54,7 @@ func testPullCleanUp(t *testing.T, session *TestSession, user, repo, pullnum str
 	req := NewRequest(t, "GET", path.Join(user, repo, "pulls", pullnum))
 	resp := session.MakeRequest(t, req, http.StatusOK)
 
-	// Click the little green button to create a pull
+	// Click the little button to create a pull
 	htmlDoc := NewHTMLParser(t, resp.Body)
 	link, exists := htmlDoc.doc.Find(".timeline-item .delete-button").Attr("data-url")
 	assert.True(t, exists, "The template has changed, can not find delete button url")
diff --git a/web_src/css/base.css b/web_src/css/base.css
index a3057013326ba..6b33ec4111ec3 100644
--- a/web_src/css/base.css
+++ b/web_src/css/base.css
@@ -420,7 +420,6 @@ a.silenced:hover {
 }
 
 a.label,
-.repository-menu a,
 .ui.search .results a,
 .ui .menu a,
 .ui.cards a.card,
diff --git a/web_src/css/modules/button.css b/web_src/css/modules/button.css
index a6c3019b8d87e..f292231319b08 100644
--- a/web_src/css/modules/button.css
+++ b/web_src/css/modules/button.css
@@ -78,6 +78,13 @@ It needs some tricks to tweak the left/right borders with active state */
   border-left: none;
 }
 
+.ui.basic.buttons .button,
+.ui.basic.button,
+.ui.basic.buttons .button:hover,
+.ui.basic.button:hover {
+  box-shadow: none;
+}
+
 .ui.labeled.button.disabled > .button,
 .ui.basic.buttons .button,
 .ui.basic.button,
diff --git a/web_src/css/repo.css b/web_src/css/repo.css
index 8ec9908f731c0..b7b14f740791c 100644
--- a/web_src/css/repo.css
+++ b/web_src/css/repo.css
@@ -2044,7 +2044,7 @@
   border: none;
   display: flex;
   align-items: center;
-  padding: 0 0.5em; /* make the UI look better for narrow (mobile) view */
+  padding: 0;
   overflow: hidden;
 }
 
@@ -2056,7 +2056,8 @@
   align-items: center;
   justify-content: center;
   gap: 0.25em;
-  padding: 0 0.25em;
+  padding: 0 0.5em; /* make the UI look better for narrow (mobile) view */
+  text-decoration: none;
 }
 
 .repository .repository-summary .sub-menu .item.active {
diff --git a/web_src/js/components/DashboardRepoList.vue b/web_src/js/components/DashboardRepoList.vue
index 5b8075f07a067..5ff51168cbd9f 100644
--- a/web_src/js/components/DashboardRepoList.vue
+++ b/web_src/js/components/DashboardRepoList.vue
@@ -2,6 +2,7 @@
 import {createApp, nextTick} from 'vue';
 import $ from 'jquery';
 import {SvgIcon} from '../svg.js';
+import {GET} from '../modules/fetch.js';
 
 const {appSubUrl, assetUrlPrefix, pageData} = window.config;
 
@@ -233,11 +234,11 @@ const sfc = {
       try {
         if (!this.reposTotalCount) {
           const totalCountSearchURL = `${this.subUrl}/repo/search?count_only=1&uid=${this.uid}&team_id=${this.teamId}&q=&page=1&mode=`;
-          response = await fetch(totalCountSearchURL);
+          response = await GET(totalCountSearchURL);
           this.reposTotalCount = response.headers.get('X-Total-Count');
         }
 
-        response = await fetch(searchedURL);
+        response = await GET(searchedURL);
         json = await response.json();
       } catch {
         if (searchedURL === this.searchURL) {
diff --git a/web_src/js/components/DiffCommitSelector.vue b/web_src/js/components/DiffCommitSelector.vue
index 48dc9d72ff4af..3f7100d201db4 100644
--- a/web_src/js/components/DiffCommitSelector.vue
+++ b/web_src/js/components/DiffCommitSelector.vue
@@ -1,5 +1,6 @@
 <script>
 import {SvgIcon} from '../svg.js';
+import {GET} from '../modules/fetch.js';
 
 export default {
   components: {SvgIcon},
@@ -123,7 +124,7 @@ export default {
     },
     /** Load the commits to show in this dropdown */
     async fetchCommits() {
-      const resp = await fetch(`${this.issueLink}/commits/list`);
+      const resp = await GET(`${this.issueLink}/commits/list`);
       const results = await resp.json();
       this.commits.push(...results.commits.map((x) => {
         x.hovered = false;
diff --git a/web_src/js/components/PullRequestMergeForm.vue b/web_src/js/components/PullRequestMergeForm.vue
index cca8b9dd6e491..03d1f99683b20 100644
--- a/web_src/js/components/PullRequestMergeForm.vue
+++ b/web_src/js/components/PullRequestMergeForm.vue
@@ -29,8 +29,8 @@ export default {
   }),
   computed: {
     mergeButtonStyleClass() {
-      if (this.mergeForm.allOverridableChecksOk) return 'green';
-      return this.autoMergeWhenSucceed ? 'blue' : 'red';
+      if (this.mergeForm.allOverridableChecksOk) return 'primary';
+      return this.autoMergeWhenSucceed ? 'primary' : 'red';
     },
     forceMerge() {
       return this.mergeForm.canMergeNow && !this.mergeForm.allOverridableChecksOk;
@@ -135,7 +135,7 @@ export default {
 
     <div v-if="!showActionForm" class="gt-df">
       <!-- the merge button -->
-      <div class="ui buttons merge-button" :class="[mergeForm.emptyCommit ? 'grey' : mergeForm.allOverridableChecksOk ? 'green' : 'red']" @click="toggleActionForm(true)">
+      <div class="ui buttons merge-button" :class="[mergeForm.emptyCommit ? 'grey' : mergeForm.allOverridableChecksOk ? 'primary' : 'red']" @click="toggleActionForm(true)">
         <button class="ui button">
           <svg-icon name="octicon-git-merge"/>
           <span class="button-text">
diff --git a/web_src/js/components/RepoBranchTagSelector.vue b/web_src/js/components/RepoBranchTagSelector.vue
index 30bff6d23f1ce..bc7d979d9987d 100644
--- a/web_src/js/components/RepoBranchTagSelector.vue
+++ b/web_src/js/components/RepoBranchTagSelector.vue
@@ -4,6 +4,7 @@ import $ from 'jquery';
 import {SvgIcon} from '../svg.js';
 import {pathEscapeSegments} from '../utils/url.js';
 import {showErrorToast} from '../modules/toast.js';
+import {GET} from '../modules/fetch.js';
 
 const sfc = {
   components: {SvgIcon},
@@ -190,8 +191,7 @@ const sfc = {
       }
       this.isLoading = true;
       try {
-        const reqUrl = `${this.repoLink}/${this.mode}/list`;
-        const resp = await fetch(reqUrl);
+        const resp = await GET(`${this.repoLink}/${this.mode}/list`);
         const {results} = await resp.json();
         for (const result of results) {
           let selected = false;
diff --git a/web_src/js/features/common-global.js b/web_src/js/features/common-global.js
index b30e21d0c0847..bc775ae545296 100644
--- a/web_src/js/features/common-global.js
+++ b/web_src/js/features/common-global.js
@@ -11,6 +11,7 @@ import {htmlEscape} from 'escape-goat';
 import {showTemporaryTooltip} from '../modules/tippy.js';
 import {confirmModal} from './comp/ConfirmModal.js';
 import {showErrorToast} from '../modules/toast.js';
+import {request} from '../modules/fetch.js';
 
 const {appUrl, appSubUrl, csrfToken, i18n} = window.config;
 
@@ -81,7 +82,7 @@ function fetchActionDoRedirect(redirect) {
 
 async function fetchActionDoRequest(actionElem, url, opt) {
   try {
-    const resp = await fetch(url, opt);
+    const resp = await request(url, opt);
     if (resp.status === 200) {
       let {redirect} = await resp.json();
       redirect = redirect || actionElem.getAttribute('data-redirect');
@@ -127,7 +128,7 @@ async function formFetchAction(e) {
   }
 
   let reqUrl = formActionUrl;
-  const reqOpt = {method: formMethod.toUpperCase(), headers: {'X-Csrf-Token': csrfToken}};
+  const reqOpt = {method: formMethod.toUpperCase()};
   if (formMethod.toLowerCase() === 'get') {
     const params = new URLSearchParams();
     for (const [key, value] of formData) {
@@ -264,7 +265,7 @@ async function linkAction(e) {
   const url = el.getAttribute('data-url');
   const doRequest = async () => {
     el.disabled = true;
-    await fetchActionDoRequest(el, url, {method: 'POST', headers: {'X-Csrf-Token': csrfToken}});
+    await fetchActionDoRequest(el, url, {method: 'POST'});
     el.disabled = false;
   };
 
@@ -275,7 +276,7 @@ async function linkAction(e) {
   }
 
   const isRisky = el.classList.contains('red') || el.classList.contains('yellow') || el.classList.contains('orange') || el.classList.contains('negative');
-  if (await confirmModal({content: modalConfirmContent, buttonColor: isRisky ? 'orange' : 'green'})) {
+  if (await confirmModal({content: modalConfirmContent, buttonColor: isRisky ? 'orange' : 'primary'})) {
     await doRequest();
   }
 }
diff --git a/web_src/js/features/common-issue-list.js b/web_src/js/features/common-issue-list.js
index ecada11988cf5..3a28cf900ca5c 100644
--- a/web_src/js/features/common-issue-list.js
+++ b/web_src/js/features/common-issue-list.js
@@ -1,7 +1,8 @@
 import $ from 'jquery';
 import {isElemHidden, onInputDebounce, toggleElem} from '../utils/dom.js';
-const {appSubUrl} = window.config;
+import {GET} from '../modules/fetch.js';
 
+const {appSubUrl} = window.config;
 const reIssueIndex = /^(\d+)$/; // eg: "123"
 const reIssueSharpIndex = /^#(\d+)$/; // eg: "#123"
 const reIssueOwnerRepoIndex = /^([-.\w]+)\/([-.\w]+)#(\d+)$/;  // eg: "{owner}/{repo}#{index}"
@@ -54,7 +55,7 @@ export function initCommonIssueListQuickGoto() {
     // try to check whether the parsed goto link is valid
     let targetUrl = parseIssueListQuickGotoLink(repoLink, searchText);
     if (targetUrl) {
-      const res = await fetch(`${targetUrl}/info`);
+      const res = await GET(`${targetUrl}/info`);
       if (res.status !== 200) targetUrl = '';
     }
 
diff --git a/web_src/js/features/comp/ConfirmModal.js b/web_src/js/features/comp/ConfirmModal.js
index 1edcfd9522ba9..e64996a3529a7 100644
--- a/web_src/js/features/comp/ConfirmModal.js
+++ b/web_src/js/features/comp/ConfirmModal.js
@@ -4,14 +4,14 @@ import {htmlEscape} from 'escape-goat';
 
 const {i18n} = window.config;
 
-export async function confirmModal(opts = {content: '', buttonColor: 'green'}) {
+export async function confirmModal(opts = {content: '', buttonColor: 'primary'}) {
   return new Promise((resolve) => {
     const $modal = $(`
 <div class="ui g-modal-confirm modal">
   <div class="content">${htmlEscape(opts.content)}</div>
   <div class="actions">
-    <button class="ui basic cancel button">${svg('octicon-x')} ${i18n.modal_cancel}</button>
-    <button class="ui ${opts.buttonColor || 'green'} ok button">${svg('octicon-check')} ${i18n.modal_confirm}</button>
+    <button class="ui cancel button">${svg('octicon-x')} ${i18n.modal_cancel}</button>
+    <button class="ui ${opts.buttonColor || 'primary'} ok button">${svg('octicon-check')} ${i18n.modal_confirm}</button>
   </div>
 </div>
 `);
diff --git a/web_src/js/features/comp/ImagePaste.js b/web_src/js/features/comp/ImagePaste.js
index dc335495a310f..cae42f3d5f7c7 100644
--- a/web_src/js/features/comp/ImagePaste.js
+++ b/web_src/js/features/comp/ImagePaste.js
@@ -1,16 +1,11 @@
 import $ from 'jquery';
-
-const {csrfToken} = window.config;
+import {POST} from '../../modules/fetch.js';
 
 async function uploadFile(file, uploadUrl) {
   const formData = new FormData();
   formData.append('file', file, file.name);
 
-  const res = await fetch(uploadUrl, {
-    method: 'POST',
-    headers: {'X-Csrf-Token': csrfToken},
-    body: formData,
-  });
+  const res = await POST(uploadUrl, {data: formData});
   return await res.json();
 }
 
diff --git a/web_src/js/features/comp/ReactionSelector.js b/web_src/js/features/comp/ReactionSelector.js
index 336634a582fe2..76834f8844076 100644
--- a/web_src/js/features/comp/ReactionSelector.js
+++ b/web_src/js/features/comp/ReactionSelector.js
@@ -1,6 +1,5 @@
 import $ from 'jquery';
-
-const {csrfToken} = window.config;
+import {POST} from '../../modules/fetch.js';
 
 export function initCompReactionSelector($parent) {
   $parent.find(`.select-reaction .item.reaction, .comment-reaction-button`).on('click', async function (e) {
@@ -12,15 +11,8 @@ export function initCompReactionSelector($parent) {
     const reactionContent = $(this).attr('data-reaction-content');
     const hasReacted = $(this).closest('.ui.segment.reactions').find(`a[data-reaction-content="${reactionContent}"]`).attr('data-has-reacted') === 'true';
 
-    const res = await fetch(`${actionUrl}/${hasReacted ? 'unreact' : 'react'}`, {
-      method: 'POST',
-      headers: {
-        'content-type': 'application/x-www-form-urlencoded',
-      },
-      body: new URLSearchParams({
-        _csrf: csrfToken,
-        content: reactionContent,
-      }),
+    const res = await POST(`${actionUrl}/${hasReacted ? 'unreact' : 'react'}`, {
+      data: new URLSearchParams({content: reactionContent}),
     });
 
     const data = await res.json();
diff --git a/web_src/js/features/copycontent.js b/web_src/js/features/copycontent.js
index c1419a524bb5b..3d3b2a697ecbf 100644
--- a/web_src/js/features/copycontent.js
+++ b/web_src/js/features/copycontent.js
@@ -1,6 +1,7 @@
 import {clippie} from 'clippie';
 import {showTemporaryTooltip} from '../modules/tippy.js';
 import {convertImage} from '../utils.js';
+import {GET} from '../modules/fetch.js';
 
 const {i18n} = window.config;
 
@@ -20,7 +21,7 @@ export function initCopyContent() {
     if (link) {
       btn.classList.add('is-loading', 'small-loading-icon');
       try {
-        const res = await fetch(link, {credentials: 'include', redirect: 'follow'});
+        const res = await GET(link, {credentials: 'include', redirect: 'follow'});
         const contentType = res.headers.get('content-type');
 
         if (contentType.startsWith('image/') && !contentType.startsWith('image/svg')) {
diff --git a/web_src/js/features/install.js b/web_src/js/features/install.js
index 23122ca4c3834..9fda7f7d27f52 100644
--- a/web_src/js/features/install.js
+++ b/web_src/js/features/install.js
@@ -1,5 +1,6 @@
 import $ from 'jquery';
 import {hideElem, showElem} from '../utils/dom.js';
+import {GET} from '../modules/fetch.js';
 
 export function initInstall() {
   const $page = $('.page-content.install');
@@ -111,7 +112,7 @@ function initPostInstall() {
   const targetUrl = el.getAttribute('href');
   let tid = setInterval(async () => {
     try {
-      const resp = await fetch(targetUrl);
+      const resp = await GET(targetUrl);
       if (tid && resp.status === 200) {
         clearInterval(tid);
         tid = null;
diff --git a/web_src/js/features/pull-view-file.js b/web_src/js/features/pull-view-file.js
index 90ea805160781..86b65f68cfb76 100644
--- a/web_src/js/features/pull-view-file.js
+++ b/web_src/js/features/pull-view-file.js
@@ -1,7 +1,8 @@
 import {diffTreeStore} from '../modules/stores.js';
 import {setFileFolding} from './file-fold.js';
+import {POST} from '../modules/fetch.js';
 
-const {csrfToken, pageData} = window.config;
+const {pageData} = window.config;
 const prReview = pageData.prReview || {};
 const viewedStyleClass = 'viewed-file-checked-form';
 const viewedCheckboxSelector = '.viewed-file-form'; // Selector under which all "Viewed" checkbox forms can be found
@@ -68,11 +69,7 @@ export function initViewedCheckboxListenerFor() {
       const data = {files};
       const headCommitSHA = form.getAttribute('data-headcommit');
       if (headCommitSHA) data.headCommitSHA = headCommitSHA;
-      fetch(form.getAttribute('data-link'), {
-        method: 'POST',
-        headers: {'X-Csrf-Token': csrfToken},
-        body: JSON.stringify(data),
-      });
+      POST(form.getAttribute('data-link'), {data});
 
       // Fold the file accordingly
       const parentBox = form.closest('.diff-file-header');
diff --git a/web_src/js/features/repo-diff-commit.js b/web_src/js/features/repo-diff-commit.js
index bc591fa37d5f0..3d4f0f677ae15 100644
--- a/web_src/js/features/repo-diff-commit.js
+++ b/web_src/js/features/repo-diff-commit.js
@@ -1,9 +1,10 @@
 import {hideElem, showElem, toggleElem} from '../utils/dom.js';
+import {GET} from '../modules/fetch.js';
 
 async function loadBranchesAndTags(area, loadingButton) {
   loadingButton.classList.add('disabled');
   try {
-    const res = await fetch(loadingButton.getAttribute('data-fetch-url'));
+    const res = await GET(loadingButton.getAttribute('data-fetch-url'));
     const data = await res.json();
     hideElem(loadingButton);
     addTags(area, data.tags);
diff --git a/web_src/js/features/repo-issue-list.js b/web_src/js/features/repo-issue-list.js
index 64343a8d22aba..af4586121edc4 100644
--- a/web_src/js/features/repo-issue-list.js
+++ b/web_src/js/features/repo-issue-list.js
@@ -5,6 +5,7 @@ import {htmlEscape} from 'escape-goat';
 import {confirmModal} from './comp/ConfirmModal.js';
 import {showErrorToast} from '../modules/toast.js';
 import {createSortable} from '../modules/sortable.js';
+import {DELETE, POST} from '../modules/fetch.js';
 
 function initRepoIssueListCheckboxes() {
   const $issueSelectAll = $('.issue-checkbox-all');
@@ -146,13 +147,7 @@ function initPinRemoveButton() {
       const id = Number(el.getAttribute('data-issue-id'));
 
       // Send the unpin request
-      const response = await fetch(el.getAttribute('data-unpin-url'), {
-        method: 'delete',
-        headers: {
-          'X-Csrf-Token': window.config.csrfToken,
-          'Content-Type': 'application/json',
-        },
-      });
+      const response = await DELETE(el.getAttribute('data-unpin-url'));
       if (response.ok) {
         // Delete the tooltip
         el._tippy.destroy();
@@ -166,14 +161,7 @@ function initPinRemoveButton() {
 async function pinMoveEnd(e) {
   const url = e.item.getAttribute('data-move-url');
   const id = Number(e.item.getAttribute('data-issue-id'));
-  await fetch(url, {
-    method: 'post',
-    body: JSON.stringify({id, position: e.newIndex + 1}),
-    headers: {
-      'X-Csrf-Token': window.config.csrfToken,
-      'Content-Type': 'application/json',
-    },
-  });
+  await POST(url, {data: {id, position: e.newIndex + 1}});
 }
 
 async function initIssuePinSort() {
diff --git a/web_src/js/features/repo-migrate.js b/web_src/js/features/repo-migrate.js
index de9f7b023c1aa..cae28fdd1b1fc 100644
--- a/web_src/js/features/repo-migrate.js
+++ b/web_src/js/features/repo-migrate.js
@@ -1,7 +1,8 @@
 import $ from 'jquery';
 import {hideElem, showElem} from '../utils/dom.js';
+import {GET, POST} from '../modules/fetch.js';
 
-const {appSubUrl, csrfToken} = window.config;
+const {appSubUrl} = window.config;
 
 export function initRepoMigrationStatusChecker() {
   const $repoMigrating = $('#repo_migrating');
@@ -13,7 +14,7 @@ export function initRepoMigrationStatusChecker() {
 
   // returns true if the refresh still need to be called after a while
   const refresh = async () => {
-    const res = await fetch(`${appSubUrl}/user/task/${task}`);
+    const res = await GET(`${appSubUrl}/user/task/${task}`);
     if (res.status !== 200) return true; // continue to refresh if network error occurs
 
     const data = await res.json();
@@ -58,12 +59,6 @@ export function initRepoMigrationStatusChecker() {
 }
 
 async function doMigrationRetry(e) {
-  await fetch($(e.target).attr('data-migrating-task-retry-url'), {
-    method: 'post',
-    headers: {
-      'X-Csrf-Token': csrfToken,
-      'Content-Type': 'application/json',
-    },
-  });
+  await POST($(e.target).attr('data-migrating-task-retry-url'));
   window.location.reload();
 }
diff --git a/web_src/js/features/user-auth-webauthn.js b/web_src/js/features/user-auth-webauthn.js
index c4c2356cb3727..363e039760225 100644
--- a/web_src/js/features/user-auth-webauthn.js
+++ b/web_src/js/features/user-auth-webauthn.js
@@ -1,7 +1,8 @@
 import {encodeURLEncodedBase64, decodeURLEncodedBase64} from '../utils.js';
 import {showElem} from '../utils/dom.js';
+import {GET, POST} from '../modules/fetch.js';
 
-const {appSubUrl, csrfToken} = window.config;
+const {appSubUrl} = window.config;
 
 export async function initUserAuthWebAuthn() {
   const elPrompt = document.querySelector('.user.signin.webauthn-prompt');
@@ -13,7 +14,7 @@ export async function initUserAuthWebAuthn() {
     return;
   }
 
-  const res = await fetch(`${appSubUrl}/user/webauthn/assertion`);
+  const res = await GET(`${appSubUrl}/user/webauthn/assertion`);
   if (res.status !== 200) {
     webAuthnError('unknown');
     return;
@@ -53,12 +54,8 @@ async function verifyAssertion(assertedCredential) {
   const sig = new Uint8Array(assertedCredential.response.signature);
   const userHandle = new Uint8Array(assertedCredential.response.userHandle);
 
-  const res = await fetch(`${appSubUrl}/user/webauthn/assertion`, {
-    method: 'POST',
-    headers: {
-      'Content-Type': 'application/json; charset=utf-8'
-    },
-    body: JSON.stringify({
+  const res = await POST(`${appSubUrl}/user/webauthn/assertion`, {
+    data: {
       id: assertedCredential.id,
       rawId: encodeURLEncodedBase64(rawId),
       type: assertedCredential.type,
@@ -69,7 +66,7 @@ async function verifyAssertion(assertedCredential) {
         signature: encodeURLEncodedBase64(sig),
         userHandle: encodeURLEncodedBase64(userHandle),
       },
-    }),
+    },
   });
   if (res.status === 500) {
     webAuthnError('unknown');
@@ -88,13 +85,8 @@ async function webauthnRegistered(newCredential) {
   const clientDataJSON = new Uint8Array(newCredential.response.clientDataJSON);
   const rawId = new Uint8Array(newCredential.rawId);
 
-  const res = await fetch(`${appSubUrl}/user/settings/security/webauthn/register`, {
-    method: 'POST',
-    headers: {
-      'X-Csrf-Token': csrfToken,
-      'Content-Type': 'application/json; charset=utf-8',
-    },
-    body: JSON.stringify({
+  const res = await POST(`${appSubUrl}/user/settings/security/webauthn/register`, {
+    data: {
       id: newCredential.id,
       rawId: encodeURLEncodedBase64(rawId),
       type: newCredential.type,
@@ -102,7 +94,7 @@ async function webauthnRegistered(newCredential) {
         attestationObject: encodeURLEncodedBase64(attestationObject),
         clientDataJSON: encodeURLEncodedBase64(clientDataJSON),
       },
-    }),
+    },
   });
 
   if (res.status === 409) {
@@ -165,15 +157,11 @@ export function initUserAuthWebAuthnRegister() {
 async function webAuthnRegisterRequest() {
   const elNickname = document.getElementById('nickname');
 
-  const body = new FormData();
-  body.append('name', elNickname.value);
+  const formData = new FormData();
+  formData.append('name', elNickname.value);
 
-  const res = await fetch(`${appSubUrl}/user/settings/security/webauthn/request_register`, {
-    method: 'POST',
-    headers: {
-      'X-Csrf-Token': csrfToken,
-    },
-    body,
+  const res = await POST(`${appSubUrl}/user/settings/security/webauthn/request_register`, {
+    data: formData,
   });
 
   if (res.status === 409) {
diff --git a/web_src/js/modules/fetch.js b/web_src/js/modules/fetch.js
index 63732206c6b62..9fccf4a81ef5d 100644
--- a/web_src/js/modules/fetch.js
+++ b/web_src/js/modules/fetch.js
@@ -2,17 +2,18 @@ import {isObject} from '../utils.js';
 
 const {csrfToken} = window.config;
 
+// safe HTTP methods that don't need a csrf token
+const safeMethods = new Set(['GET', 'HEAD', 'OPTIONS', 'TRACE']);
+
 // fetch wrapper, use below method name functions and the `data` option to pass in data
-// which will automatically set an appropriate content-type header. For json content,
-// only object and array types are currently supported.
-function request(url, {headers, data, body, ...other} = {}) {
+// which will automatically set an appropriate headers. For json content, only object
+// and array types are currently supported.
+export function request(url, {method = 'GET', headers = {}, data, body, ...other} = {}) {
   let contentType;
   if (!body) {
     if (data instanceof FormData) {
-      contentType = 'multipart/form-data';
       body = data;
     } else if (data instanceof URLSearchParams) {
-      contentType = 'application/x-www-form-urlencoded';
       body = data;
     } else if (isObject(data) || Array.isArray(data)) {
       contentType = 'application/json';
@@ -20,12 +21,18 @@ function request(url, {headers, data, body, ...other} = {}) {
     }
   }
 
+  const headersMerged = new Headers({
+    ...(!safeMethods.has(method.toUpperCase()) && {'x-csrf-token': csrfToken}),
+    ...(contentType && {'content-type': contentType}),
+  });
+
+  for (const [name, value] of Object.entries(headers)) {
+    headersMerged.set(name, value);
+  }
+
   return fetch(url, {
-    headers: {
-      'x-csrf-token': csrfToken,
-      ...(contentType && {'content-type': contentType}),
-      ...headers,
-    },
+    method,
+    headers: headersMerged,
     ...(body && {body}),
     ...other,
   });